Skip to content
This repository has been archived by the owner on Oct 15, 2021. It is now read-only.

Architecture design #1

Open
kisvegabor opened this issue Mar 4, 2019 · 119 comments
Open

Architecture design #1

kisvegabor opened this issue Mar 4, 2019 · 119 comments

Comments

@kisvegabor
Copy link
Member

In continue of lvgl/lvgl#601


So according to my current understanding, the concept is the following:

  • Use the Python or Micropython binding of LittlevGL to dynamically create a GUI on a canvas (the Micropython binding is more complete right now)
  • Via the binding instruct LittlevGL to create objects and modify their properties.
  • The script - which generated the currently visible GUI - can be easily converted back to C and exported. Or the script can be exported as it is.
  • For compatibility and platform independence the GUI builder can be in Python as well.

I expect that some extensions should be developed. For example one basic thing came to mind: when you click on the canvas to select an object to edit it, the object on that coordinate should be get and highlighted.

@embeddedt
Copy link
Member

@AGlass0fMilk

We can have the GUI builder automatically disable components that a design does not use at time of generation.

As long as this feature is by default, and not mandatory, I'm fine with that. I just don't want the GUI builder to restrict functionality, i.e. the user should easily be able to adjust lv_conf.h and make changes to the generated C code.

@AGlass0fMilk
Copy link
Collaborator

@embeddedt

As long as this feature is by default, and not mandatory, I'm fine with that. I just don't want the GUI builder to restrict functionality, i.e. the user should easily be able to adjust lv_conf.h and make changes to the generated C code.

Yes, I agree. It should be possible to manually modify the configuration and generated C code. One complication is: do these manual modifications need to propagate to the editor when a project is reopened? Can a project be imported from an exported code? If so, how? This may help argue the case for an intermediate (ie: XML) representation of the GUI.

@amirgon
Copy link

amirgon commented Mar 4, 2019

One complication is: do these manual modifications need to propagate to the editor when a project is reopened?

If you are using micropython, it is easy to know the configuration that was set in lv_conf.h. For example, if you want to know if some object was enabled, just check if there is such class in lvgl module. Python introspection is handy in such situations.

@AGlass0fMilk
Copy link
Collaborator

I have worked with pytkinter and wxPython before and haven't been very impressed with either.

I asked a colleague for recommendations for a GUI library with a Python binding and he suggested pyGObject/Gtk. It has a graphical GUI builder (Glade). I haven't used it before but I'm going to play around with it a bit.

It is cross-platform as well.

Does anyone have a preference for the GUI library?

@embeddedt
Copy link
Member

@AGlass0fMilk I think @amirgon wants to use LittlevGL as the GUI for the GUI builder.

@AGlass0fMilk
Copy link
Collaborator

AGlass0fMilk commented Mar 5, 2019

@AGlass0fMilk I think @amirgon wants to use LittlevGL as the GUI for the GUI builder.

From a performance standpoint that doesn't really make sense.

The pc_simulator project is fine for demoing and prototyping but the simulated mouse and lack of more complex built-in controls would make it a really annoying desktop application to use.

It would be a cool proof-of-concept or showcase project but I think it wouldn't perform very well as a tool.

@amirgon
Copy link

amirgon commented Mar 5, 2019

From a performance standpoint that doesn't really make sense.

The pc_simulator project is fine for demoing and prototyping but the simulated mouse and lack of more complex built-in controls would make it a really annoying desktop application to use.

It would be a cool proof-of-concept or showcase project but I think it wouldn't perform very well as a tool.

@AGlass0fMilk

I don't agree. There is no reason why you wouldn't get decent performance with lvgl as a GUI. If you are missing some "more complex built-in controls" then add them to lvgl and it would be a useful addition to lvgl in general.

It makes more sense to use lvgl as GUI since you want to display and manipulate lvgl components, and lvgl already contains all the logic of how to draw and manipulate them.

@kisvegabor
Copy link
Member Author

kisvegabor commented Mar 5, 2019

To decide it let's collect which controls are required to build up the GUI designer.

I have these in mind:
Simple ones:

  • Buttons
  • Texts
  • Text input
  • Dropdowns

Complex ones:

  • File browser
  • Menu system with submenus

It really would be great to create the GUI builder with LittlevGL because:

  • It sounds great that the designer is also built with LittlevGL.
  • Good for demonstration as it's a very complex UI
  • Good to test LittlevGL
  • The required extensions would be useful in real life projects

However, in this case, I think we should use the Python binding of LittlevGL (instead of Micropython) to enable to use of Python libraries.

@amirgon
Copy link

amirgon commented Mar 5, 2019

However, in this case, I think we should use the Python binding of LittlevGL (instead of Micropython) to enable to use of Python libraries.

@kisvegabor Which libraries did you have in mind?

@embeddedt
Copy link
Member

@kisvegabor Is the Python binding complete enough to be usable within our timeframe? Ideally we could release the GUI builder alongside v6.0.

@AGlass0fMilk
Copy link
Collaborator

My suggestion is that we build a GUI builder tool targeted towards efficient desktop computer use.

Then, using the tool, we can build very complex, beautiful UI that is easy and efficient to create/design.

The UI we create with the tool can showcase the capabilities of LittlevGL.

Using a desktop-oriented GUI library to build this tool makes sense for a few reasons:

  1. Desktop UI will be more consistent and intuitive to desktop users
  2. Integration with Windows/Mac/Linux is already taken care of, which handles creating real/native windows, popups, input (no laggy simulated mouse cursor, scroll wheel for scrolling windows, right click), toolbars, color pickers, file dialogs, tooltips, etc
  3. LittlevGL is a library targeted towards simpler embedded systems. We don't need to build out extremely complex UI functionality that is more suited to desktop use. Let's keep it simple.

I just don't think LittlevGL is the right tool for desktop application development. It will just take longer to develop, run slower, and be more frustrating to use.

We can probably make a GUI builder with a desktop GUI framework and use the time we save to create some of the more complex widgets before V6.0 is released.

I have been playing with Gtk3 and Glade, I should have a "LittlevGL widget" working in it today or tomorrow.

@embeddedt
Copy link
Member

I agree with @AGlass0fMilk. It's probably simpler to make the GUI with a proven desktop tool.

@amirgon
Copy link

amirgon commented Mar 5, 2019

Personally, I liked the idea of lvgl-GUI-Builder-built-in-lvgl better.

In my opinion it has a larger potential to drive lvgl forward.
I just don't see how a desktop application that only outputs lvgl code can bring any improvement to the lvgl library itself.

I just don't think LittlevGL is the right tool for desktop application development. It will just take longer to develop, run slower, and be more frustrating to use.

I'm not sure any of these claims is true. lvgl is easy to develop with, can run fast enough and any time spent for adding a missing feature is a pure gain since it will help taking lvgl library forward.


One more thing. If we want to develop a modern application, why not a web application? Think of an online tool available on lvgl website that allows the users, with their web browser, design and run lvgl GUI! No need to install anything, no need for a precompiled version for each OS, etc.

We are half way there with lvgl/lvgl#687 and lvgl/lvgl#792. There might also be other ways to achieve this, by using JavaScript and some web framework.

@embeddedt
Copy link
Member

embeddedt commented Mar 5, 2019

@amirgon Please explain why you think using LittlevGL for the graphics library would be better.

I just don't see how a desktop application that only outputs lvgl code can bring any improvement to the lvgl library itself.

It brings a lot of improvement. With this the user no longer needs to spend time fiddling with the coordinates and sizes of objects on a display. Now they can just set everything up on their screen visually.

I'm not sure any of these claims is true.

@AGlass0fMilk already highlighted some problems which make sense:

  1. Desktop UI will be more consistent and intuitive to desktop users
  2. Integration with Windows/Mac/Linux is already taken care of, which handles creating real/native windows, popups, input (no laggy simulated mouse cursor, scroll wheel for scrolling windows, right click), toolbars, color pickers, file dialogs, tooltips, etc
  3. LittlevGL is a library targeted towards simpler embedded systems. We don't need to build out extremely complex UI functionality that is more suited to desktop use. Let's keep it simple.

@amirgon
Copy link

amirgon commented Mar 5, 2019

@embeddedt

Please explain why you think using LittlevGL for the graphics library would be better.

  • Because it will boost lvgl library itself forward, see my previous post.
  • Because it could enable running the GUI Builder as a web application.
  • Because someone who develops GUI in lvgl will understand lvgl better in order to create a GUI-Builder for lvgl
  • Because it will be easier to display and manipulate lvgl components on screen. If you are not using lvgl to build lvgl GUI, the lvgl components you display are not exactly the same as the true lvgl components, and might not behave exactly the same until you actually try to run the GUI on real lvgl.
  • Because eventually, non-lvgl GUI Builder might require more work not less.
    An example: Alignment rules. If you write a non-lvgl desktop application you need the GUI builder to be aware of lvgl align rules, in order to display everything the same way as lvgl. And you need to fix the GUI builder if the align rules change on the next version of lvgl. But if what you are running is the true lvgl, you don't need to worry about this.

It brings a lot of improvement. With this the user no longer needs to spend time fiddling with the coordinates and sizes of objects on a display. Now they can just set everything up on their screen visually.

How is it different from lvgl-GUI-Builder-built-in-lvgl? It will also let the users just set everything up on their screen visually. I just don't get your point.
Maybe you didn't understand my point - I didn't say lvgl users won't benefit from it, I said that lvgl library won't, it terms of new features, bugs, etc.

  • Desktop UI will be more consistent and intuitive to desktop users

But our target audience is not desktop users, it's embedded device users. Having GUI components that are not mocked but the real thing, look and behaves like the real thing, seems more important to me.

  • Integration with Windows/Mac/Linux is already taken care of, which handles creating real/native windows, popups, input (no laggy simulated mouse cursor, scroll wheel for scrolling windows, right click), toolbars, color pickers, file dialogs, tooltips, etc

lvgl already runs on many OSes and platforms, so lvgl-GUI-Builder-built-in-lvgl will too. This is also already taken care of.
All the other features (popups, tooltips, toolbars, dialogs etc.) could be a nice addition to lvgl library. Do we really need them all for the GUI builder?
Is the mouse cursor laggy?? if this is the case, maybe this should be addressed and solved, although I didn't experience this on my lvgl build.

  • LittlevGL is a library targeted towards simpler embedded systems. We don't need to build out extremely complex UI functionality that is more suited to desktop use. Let's keep it simple.

I agree that there are some complex GUI components that exist in desktop application and are not needed on lvgl. But let's try to list them. For each one, we need to ask ourselves:

  • Is it only needed on desktop applications and not on embedded applications?
  • Do we really need to use it on the GUI Builder?

Let's see how many such relevant complex component we find.

@AGlass0fMilk
Copy link
Collaborator

AGlass0fMilk commented Mar 5, 2019

Please explain why you think using LittlevGL for the graphics library would be better.

* Because it will boost lvgl library itself forward, see my previous post.

This feature/project pertains to a GUI builder for the lvgl library, not the lvgl library itself. You can still contribute to the lvgl core library in parallel.

* Because it could enable running the GUI Builder as a web application.

We are targeting embedded developers so I don't see much advantage to a web-based application. A desktop-based application will have more support for additional features (such as interacting with and uploading to attached target hardware). I think it would be more work to write a GUI builder application using a JavaScript wrapper for a Python wrapper for a C library.

Mbed-OS has an online IDE and compiler toolchain. It is great for hobbyists and beginners but I never use it. I have only ever been limited by the online IDE.

Embedded developers typically require finer control over their development toolchain and as such, desktop/CLI tools are pretty desirable. We could even provide command line utilities for integration into CI/CD pipelines if the need arises. This would be more difficult with a web application.

Also, a web application would be much harder to add custom (non-public) widgets to as well.

Additionally, we will have to host the web application, possibly provide online storage for users, perhaps authentication... complexities that don't have any measurable benefit for professional embedded developers.

* Because someone who develops GUI in lvgl will understand lvgl better in order to create a GUI-Builder for lvgl

This isn't very relevant. One will always have to be learning frameworks and libraries to stay current in this field.

* Because it will be easier to display and manipulate lvgl components on screen. If you are not using lvgl to build lvgl GUI, the lvgl components you display are not exactly the same as the true lvgl components, and might not behave exactly the same until you actually try to run the GUI on real lvgl.

Actually this isn't true. My idea is to use a generic canvas for displaying the LittlevGL rendering. We can port LittlevGL to write its display buffer out to this canvas. This will eliminate any inconsistencies in appearance (barring any bugs in the wrapper layers).

* Because eventually, non-lvgl GUI Builder might require **more** work not less.
  An example: Alignment rules. If you write a non-lvgl desktop application you need the GUI builder to be aware of lvgl align rules, in order to display everything the same way as lvgl. And you need to fix the GUI builder if the align rules change on the next version of lvgl. But if what you are running is the true lvgl, you don't need to worry about this.

The GUI builder will need to be aware of lvgl widget object properties in order to configure them. Thankfully, python introspection should take care of most of this, allowing us to enumerate properties and create the appropriate controls in a side-pane based on the property type.

As for the specific alignment issue -- there are only a few alignment types in lvgl that can be specified. The user can simply choose an alignment type from a drop-down list and see if it has the desired effect in the live-view GUI canvas.

It brings a lot of improvement. With this the user no longer needs to spend time fiddling with the coordinates and sizes of objects on a display. Now they can just set everything up on their screen visually.

How is it different from lvgl-GUI-Builder-built-in-lvgl? It will also let the users just set everything up on their screen visually. I just don't get your point.
Maybe you didn't understand my point - I didn't say lvgl users won't benefit from it, I said that lvgl library won't, it terms of new features, bugs, etc.

This feature/project pertains to a GUI builder for the lvgl library, not the lvgl library itself. You can still contribute to the lvgl core library in parallel.

Web-applications and desktop-grade widgets seem like scope creep to me.

  • Desktop UI will be more consistent and intuitive to desktop users

But our target audience is not desktop users, it's embedded device users. Having GUI components that are not mocked but the real thing, look and behaves like the real thing, seems more important to me.

Embedded developers use desktop applications for development. We can have the actual LittlevGL library render the live-view while using native UI for manipulation and control so that point is moot.

  • Integration with Windows/Mac/Linux is already taken care of, which handles creating real/native windows, popups, input (no laggy simulated mouse cursor, scroll wheel for scrolling windows, right click), toolbars, color pickers, file dialogs, tooltips, etc

lvgl already runs on many OSes and platforms, so lvgl-GUI-Builder-built-in-lvgl will too. This is also already taken care of.

Cross-platform GUI libraries/frameworks are plentiful, so this is a non-issue.

All the other features (popups, tooltips, toolbars, dialogs etc.) could be a nice addition to lvgl library. Do we really need them all for the GUI builder?
Is the mouse cursor laggy?? if this is the case, maybe this should be addressed and solved, although I didn't experience this on my lvgl build.

They would be familiar, intuitive additions to the GUI builder's interface that would help most developers learn how to use stuff without even reading documentation. These are also widgets/features that are not really needed by most applications of LittlevGL.

Yes the mouse cursor is laggy
peek 2019-03-05 15-34

  • LittlevGL is a library targeted towards simpler embedded systems. We don't need to build out extremely complex UI functionality that is more suited to desktop use. Let's keep it simple.

I agree that there are some complex GUI components that exist in desktop application and are not needed on lvgl. But let's try to list them. For each one, we need to ask ourselves:

* Is it only needed on desktop applications and not on embedded applications?

* Do we really need to use it on the GUI Builder?

Let's see how many such relevant complex component we find.

I have already mentioned a number of features that would be missing if we developed the lvgl builder with lvgl. See comments above.

@embeddedt
Copy link
Member

I fully agree with all of @AGlass0fMilk's comments. I see no reason to add additional work by making the GUI builder with LittlevGL.

@kisvegabor
Copy link
Member Author

I try to group the mentioned questions:

Use LittlevGL to create the builder itself or not?

  1. It really would have the benefit of adding nice things to LittlevGL
  2. It would slow the development of the builder
  3. The desktop GUI libraries have a well-known design and users are familiar with them
  4. The desktop GUI libraries are battle-tested for this purpose
  5. LittlevGL surely will have issues in this process. They probably can be fixed to make it more suitable as a desktop GUI library, but LittlevGL's goal is not to be a great desktop GUI library. Already there are huge and very feature rich tools for this purpose and we can't compete with them.

My conclusion It'd be interesting to use LittlevGL this way but I see more benefits of using an existing desktop GUI library.

Online or offline GUI builder?

  1. The online editor is really convenient and easy to get started with.
  2. However, I agree with @AGlass0fMilk, the online editor would be great to experiment things but for professional development, an offline tool is more suitable and expected
  3. In Python running offline, it would be natural to interact with LittlevGL's Python binding to draw things on a canvas.
  4. The increasing complexity with user authentication, data storage etc. are a disadvantage of the Online version

My conclusion I see more advantage in the offline editor

Python or Micropython binding?

  1. Micropython binding is more complete and @amirgon is doing a great work by improving it
  2. The Python binding is also working but some features might be missing. Need to follow up with @rreilink. I hope in v6.0 we can release the Python binding too.
  3. The Python binding can be imported into the GUI Python scripts and can be simply used. Using Micropython from Python seems complicated.

My conclusion Still there are open questions but if speaking about an offline desktop tool written in Python, the Python binding seems more rational.

@AGlass0fMilk
Copy link
Collaborator

The examples from pylvgl use pyQT5 as the backend. I used a similar process to create a GTK-based LVGL display. See screenshot below (just demo UI, not any kind of mockup). It's nice because GTK automatically scales the LittlevGL canvas up on my HiDPI 4k display. QT displays it at 1:1 resolution and it's kind of small and hard to see on my display. Though it does look a bit pixelated, there are options to change the scaling factor.

screenshot from 2019-03-05 23-01-26

The Python binding is nice, I'm a little weary of the "missing features" you mention @kisvegabor. I'll see what I can get working with the current binding.

@rreilink
Copy link

rreilink commented Mar 6, 2019

  1. The Python binding is also working but some features might be missing. Need to follow up with @rreilink. I hope in v6.0 we can release the Python binding too.

It has been a while, but I can start again spending some time on this. Now that there is a dev-6.0 branch, I can use that to integrate Python & MicroPython bindings, for which I already did quite some work a while ago. I can assist in focussing on specific things if they are required for the gui development.

The Python binding is nice, I'm a little weary of the "missing features" you mention @kisvegabor. I'll see what I can get working with the current binding.

@AGlass0fMilk if you have any specific requirements, let me know and I can focus on them.

@rreilink
Copy link

rreilink commented Mar 6, 2019

Regarding the architecture:

I'd agree with @kisvegabor 's conclusions.

I have been thinking about a GUI builder for a while (even before this discussion) and I would think of an offline Qt (or similar) Python application, which uses the lvgl Python bindings to draw the gui that is being designed on a canvas. The result can be exported as C, Python, or XML.

The user can interact with the canvas to move and select objects. There would be a property window and a parent/child tree that represent the current structure of the objects in LittlevGL and allow them to be modified, like the Qt Designer:

Qt designer property window Qt designer object inspector

The properties that each object has, and their datatypes, can easily be inferred using the Python introspection features, as @amirgon suggested.

@AGlass0fMilk
Copy link
Collaborator

@rreilink Yes, that's what I was thinking.

My first thought is to use an XML internal representation. Then, we can develop converters that take the XML and generate the appropriate code for whatever language is being used. GUI projects can then be saved in the XML format and imported. This wouldn't allow for code changes to be back propagated to the GUI design however.

The GUI designer could internally use XML and a corresponding Python converter to generate the live view. Probably should only process objects that change to prevent having to regenerate the entire live view code in real time.

I'm not 100% familiar with how things like argument lists and types propagate from C to a Python binding. It seems like not all the information is being supplied to the Python binding when I inspect members of the lvgl module.

For example, to build the edit widget parameters pane in the GUI builder, we could look at all the get and set methods of an lvgl class. I would like to be able to present an appropriate control based on the type of the parameter. If it is a color, we can show a color picker. If it is a string, we can give them a text edit box, etc.

When I look at lvgl module members in Python, I don't really find any of this information. I have tried dir, and inspect so far, maybe I'm missing something?

I have seen other Python bindings that have more information, like documentation in the help pages and argument lists that have more detail than "...". @rreilink Do you know how we could have this kind of information propagate from the C code to the Python binding?

I would also like to possibly have additional metadata from specially formatted comments (similar to doxygen). For example, Glade, the GTK editor, has a nice feature where tooltips pop up over widget properties to explain what that properties is/does. This would prevent a lot of instances where you have to look at the documentation for something that isn't completely clear. See example of this in screen capture below:

tooltips

See #3 for that discussion.

@kisvegabor
Copy link
Member Author

@rreilink I suggest opening an issue in lvgl repo to continue with the Python binding. Do you agree?

@AGlass0fMilk Let's discuss the details of tooltips and helps in #3

Having a layout design of the UI ( just a simple scratch) to see how the control elements are organized would be important already in this phase too.

@rreilink
Copy link

rreilink commented Mar 7, 2019

@rreilink I suggest opening an issue in lvgl repo to continue with the Python binding. Do you agree?

I just did :-)

@AGlass0fMilk
Copy link
Collaborator

Began work on PyQt-based GUI builder. Being somewhat blocked by the state of the pylvgl binding.

See the initial-development branch.

Screenshot from 2019-05-22 00-26-30

@kisvegabor
Copy link
Member Author

Awesome! Looks good. It seems it has everything we have discussed.

@AGlass0fMilk
Copy link
Collaborator

I have a basic lvgl simulator working with the newest release of pylvgl.

I decided to use QGraphicsView as the base class because it has a framework in place for translating between application and "scene" (LittlevGL) coordinates. It also handles drawing layers and multiple items.

Currently, the lvgl framebuffer is drawn as the background layer. This will allow us to overlay builder-related UI on the lvgl simulation (such as highlights on selected items, etc).

lvgl-builder

@embeddedt
Copy link
Member

Excellent! This is looking great thus far.

@kisvegabor
Copy link
Member Author

Wonderful! I'm very happy to see it working. :)

@amirgon
Copy link

amirgon commented Aug 22, 2019

So I find another way two days ago: .get_child(None).set_drag_parent(True). It works. Just a compromise.

Instead of dragging the element itself, how about painting the element on a canvas and dragging only the element's "image"? When the user places the element, you can create it there as a real element.
I never tried this but I think it could work, perhaps @kisvegabor or @embeddedt could comment on that.

@embeddedt
Copy link
Member

how about painting the element on a canvas and dragging only the element's "image"?

If you are referring to dragging the canvas object, that could work, but it would add additional complexity. I think the method that @kaiakz is using now is fine.

@AGlass0fMilk
Copy link
Collaborator

This gif shows where my implementation currently stands as a desktop/Qt-based application. All the editable parameters and placeable objects are inferred using python introspection so effort to support littlevgl updates and new widgets is minimized:

lvgl-beta

Still need to implement dragging and resizing objects using the mouse. Then saving and exporting to code.

@kaiakz
Copy link

kaiakz commented Aug 23, 2019

@AGlass0fMilk Congratulations!
About dragging, you can refer to my implement, or bind the QRect with the widget: when I drag the highlight rectangle, adjust the position and size(resize the rectangle) of the widget dynamically.
I noticed your project has highlight, that's what I also want to achieve. I have some way to implement in the issue
@kisvegabor @embeddedt Maybe you can give me some details about lvgl.

@kisvegabor
Copy link
Member Author

@amirgon

Instead of dragging the element itself, how about painting the element on a canvas and dragging only the element's "image"? When the user places the element, you can create it there as a real element.
I never tried this but I think it could work, perhaps @kisvegabor or @embeddedt could comment on that.

With multi-display support, it's possible to create a dummy screen whose buffer is the canvas thus after a refresh LittlevGL will draw objects there. If you are interested I can shaw an example.

@kaiakz
I've commented on the new issue.

@kaiakz
Copy link

kaiakz commented Aug 29, 2019

@kisvegabor @embeddedt @amirgon

With multi-display support, it's possible to create a dummy screen whose buffer is the canvas thus after a refresh LittlevGL will draw objects there. If you are interested I can show an example.

I am interested in it, for I want to support more feature.
Now you can try the online demo. Sorry for its ugly interface. 😅
Peek 2019-08-29 17-08

@embeddedt
Copy link
Member

@kaiakz Nice!

Instead of making the user download multiple files immediately, maybe it's better to let them preview the header and source files, and then choose to download them (or copy them).

You might want to indent child objects based on their position in the hierarchy. I was confused about why all my objects were being created as children of the button - until I realized that objects are created as children of whatever you have selected.

@kaiakz
Copy link

kaiakz commented Aug 29, 2019

You might want to indent child objects based on their position in the hierarchy. I was confused about why all my objects were being created as children of the button - until I realized that objects are created as children of whatever you have selected.

I think the title Select A Parent is better than Select A Widget 😃 I plan to change the web-UI with more widget(bootstrap has no treeview and switch).

Instead of making the user download multiple files immediately, maybe it's better to let them preview the header and source files, and then choose to download them (or copy them).

OK, I will add it to TODO. I think I can use monaco-editor to support the preview.

@kisvegabor
Copy link
Member Author

@kaiakz
Wow, that's really impressive! Congratulation!

I agree with @embeddedt about indentation of child objects. Maybe the attributes can be grouped somehow too. (obj, or text area attributes)

@amirgon
Copy link

amirgon commented Aug 31, 2019

Now you can try the online demo.

@kaiakz The demo doesn't work for me, tried both Chrome and FireFox. It just seems loading the page indefinitely. Am I missing something?

@embeddedt
Copy link
Member

embeddedt commented Aug 31, 2019

@amirgon It doesn't work for me either right now, but it was working 2 days ago. Chances are @kaiakz is working on it and it's not available right now.

@kaiakz
Copy link

kaiakz commented Sep 1, 2019

@amirgon @embeddedt

The demo doesn't work for me, tried both Chrome and FireFox. It just seems loading the page indefinitely. Am I missing something?

I am sorry for this. But I haven't changed the demo yet.
Recently, I have tried it on the IOS Safaris, and it also works. Maybe github-page has some problems at that time? The demo is just a github-page of the master branch, you can clone it and run index.html from your disk. Make sure that you are using the latest version browser. When we open the webpage, the browser needs to load the WASM. It may take a while when you open the page for the first time. If your browser forbids somethings or your network is slow, the demo will fail to load.
I met the same problem ten days ago, and I solved it by refreshing the webpage. I haven't found where the bug is yet (source code, network, browser). If you have the problem again and again, please open an issue to describe the detail(how does it appear?)

@embeddedt
Copy link
Member

embeddedt commented Sep 1, 2019

Working for me again now (online version). It was probably just an issue with GitHub Pages.

@amirgon
Copy link

amirgon commented Sep 1, 2019

@kaiakz It's working for me now. Very nice.

What would be the next step? What are your plans further?

  • How do you plan supporting functions with more than one parameter? For example - lv_bar_set_value receives both value and anim parameters. So today you can't set bar value on walv.
    It's not possible to check in Micropython (by introspection) the number of arguments a function expects, and their types.
    If it helps, I could generate this metadata from lvgl headers when generating the binding and provide it as a JSON file or whatever.
  • Any plans to handle object alignments?
  • Moving objects to foreground/background?
  • Many integers are actually enums, and their value makes more sense when selecting an enum member name instead of an integer value
  • Any plans to optionally generate Micropython code?

@kaiakz
Copy link

kaiakz commented Sep 3, 2019

How do you plan supporting functions with more than one parameter? For example - lv_bar_set_value receives both value and anim parameters. So today you can't set bar value on walv.
It's not possible to check in Micropython (by introspection) the number of arguments a function expects, and their types.
If it helps, I could generate this metadata from lvgl headers when generating the binding and provide it as a JSON file or whatever.

I think lv_mpy can add more information to JS port, not only parametres (how many? what) that store in Python tuple/list, but also more LittlevGL doc(It also could provide by JS parts). Luckily, Micropython has ujson for converting.
walv has not thought about the set_xxx yet. Maybe I should arrange the attribute at first, and store it as a JSON. Because walv now use dir to look up what get_xxx the obj has, and then eval the one parametre get_xxx function to get some information, if user set the attribute in the page, walv will eval the related set_xxx function(just change the prefix of get_xxx). But here are some problems, you know, some get_xxx doesn't has the set_xxx. So I plan to group the attribute, walv should display all the attributes like common(lv_obj's position, size, etc) and then special attributes(lv_xxx). Now, walv can't sort the attribute above. It would better that walv reads the sorted JSON, and eval the key and fill the value.

Many integers are actually enums, and their value makes more sense when selecting an enum member name instead of an integer value

Like above, store them first. For example, PROTECT has CHILD_CHG, CLICK_FOCUS, PRESS_LOST, etc. Store it as a key-value list, the list will display as HTML's drop-down selector so the user could easily change it.
@kisvegabor @embeddedt Maybe you can give me some help about generating the list of methods, enums. How can I arrange them? Which are necessary to show?

Any plans to handle object alignments?

A little, because a widget has two ways for alignment: X-Y position(drag&drop to decide), align to another widget. I will open an issue to discuss the alignment and layout.

Moving objects to foreground/background?

I develop a tree to represent the parent-children layout and foreground/background. It could adjust parent and foreground/background.

Any plans to optionally generate Micropython code?

Sure! Since walv always generate the mpy code at first, and then convert the code to C. It's not difficult to save mpy code. By the way, walv chooses the lv_mpy REPL as its console that provides another way to control walv. Use the walv, user will get in touch with lv_mpy.

@kisvegabor
Copy link
Member Author

Maybe you can give me some help about generating the list of methods, enums. How can I arrange them? Which are necessary to show?

Basically all public API functions are necessary but it's not trivial how to order them. In the C header files, I tried to order them as most important first but I don't know if this order is preserved in MicroPython.

@embeddedt
Copy link
Member

We could have a JSON file that stores the categories of properties, and if an unknown property is found, it just gets put at the bottom of the list.

But I wouldn't worry about order right now. Let's get the basic functionality working first.

@amirgon
Copy link

amirgon commented Sep 5, 2019

I think lv_mpy can add more information to JS port, not only parametres (how many? what) that store in Python tuple/list, but also more LittlevGL doc(It also could provide by JS parts). Luckily, Micropython has ujson for converting.

I can create a JSON "metadata" file that gives more information about lvgl objects, functions, parameters, enums etc.
However, I will not be able to include "LittlevGL doc" in it, at least not based on C comments, since the parser is reading the preprocessed C code where all comments and preprocessor directives were already removed.

You could, if you want, write some text processing script to extract comments from the code and put them in some JSON file, but that would be out of the scope of the lvgl binding script.

@amirgon
Copy link

amirgon commented Sep 6, 2019

The Micropython binding can now generate metadata, to allow full introspection.
Metadata is emitted as a JSON file and describes functions, argument names and types, enums, callbacks, etc.

Here is an example: https://raw.githubusercontent.com/littlevgl/lv_binding_micropython/master/gen/lv_mpy_example.json

I've enabled it on lv_micropython, so it's now generated automatically into the "build" directory of the port you are building (look for lv_mpy.json)

I didn't include metadata generation for structs because I think structs can be introspected in Micropython without the need for metadata (just recursively dir the struct instance and call type for each leaf member)

@embeddedt
Copy link
Member

@amirgon I had an idea for another LittlevGL project where I would want metadata like this, but not for use with Python. How hard would it be for me to modify your script to generate metadata for the C functions instead of Python functions? I should only need parameter types and return values.

@amirgon
Copy link

amirgon commented Sep 6, 2019

How hard would it be for me to modify your script to generate metadata for the C functions instead of Python functions?

@embeddedt The metadata generation is fed from internal data structures on the Micropython binding script, so I don't think that by itself it could help you for C.

But I suggest you use another approach: use pycparser directly.
The Micropython binding script uses pycparser internally to parse lvgl headers. You can think of pycparser outputs as metadata that describes your C code and use it directly for your purposes.

@kaiakz
Copy link

kaiakz commented Sep 19, 2019

@amirgon @embeddedt
I tried to compile the javascript port to wasm, and got firmware.js, firmware.wasm and micropython.js in /ports/javascript/build. When I executed the node micropython.js in the term, It shows

MicroPython v1.9.4-1626-g2940838bf-dirty on 2019-09-15; JS with Emscripten
Type "help()" for more information.
>>> import lvgl as lv
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: no module named 'lvgl'

Maybe the emsdk did not compile and link the something about lvgl, I don't know if some files miss. Due to some reason, I can not download git submoudle normally in CN network, it is too slow and always fails without VPN.
Now I have to choose the latest version lvgl_mp.js that you provides. I just replace the lvgl_mp.js with the latest version directly, the latest version is big(14.6M to old version 3.4M), and much slower in the browser(delays 1s or more). How can I optimize it?

@embeddedt
Copy link
Member

@kaiakz

  1. Are you using https://github.com/littlevgl/lv_micropython/tree/lvgl_javascript?
  2. You have to download the submodules or it won't build properly.
  3. Please install and activate Emscripten 1.38.25 (the newer versions haven't been tested yet).
  4. If you follow the instructions here, you should get a working HTML in the browser that can be opened.

@amirgon
Copy link

amirgon commented Sep 19, 2019

>>> import lvgl as lv
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: no module named 'lvgl'

@kaiakz - You are probably using the "master" branch and not the "lvgl_javascript" branch.

This is a recent change. Until recently the master branch included lvgl in the js port, but now we removed it and added lvgl only on "lvgl_javascript" branch - so you must switch to that branch.

@kaiakz
Copy link

kaiakz commented Sep 21, 2019

@embeddedt @amirgon
OK, I switch to lvgl_javascript branch. I tried to make /ports/javascript after finishing mpy_cross. But here are some error:

Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
GEN build/frozen.c
GEN build/genhdr/qstr.i.last
cc1: error: argument to ‘-O’ should be a non-negative integer, ‘g’, ‘s’ or ‘fast’
cc1: error: argument to ‘-O’ should be a non-negative integer, ‘g’, ‘s’ or ‘fast’
...
cc1: error: argument to ‘-O’ should be a non-negative integer, ‘g’, ‘s’ or ‘fast’
make: *** [../../py/mkrules.mk:75: build/genhdr/qstr.i.last] Error 1
make: *** Deleting file 'build/genhdr/qstr.i.last'

My env is :

Set the following tools as active:
   releases-fastcomp-3b8cff670e9233a6623563add831647e8689a86b-64bit
   node-12.9.1-64bit
   emscripten-tag-1.38.25-64bit

When I installed emsdk install clang-tag-e1.38.31-64bit and emscripten-tag-1.38.25-64bit, it shows, and I solved it by install cmake:

emsdk install clang-tag-e1.38.31-64bit 
Installing tool 'clang-tag-e1.38.31-64bit'..
The contents of file 'https://github.com/kripken/emscripten-fastcomp/archive/1.38.31.tar.gz' already exist in destination '/home/kai/Templates/emsdk/clang/tag-e1.38.31/src', skipping.
The contents of file 'https://github.com/kripken/emscripten-fastcomp-clang/archive/1.38.31.tar.gz' already exist in destination '/home/kai/Templates/emsdk/clang/tag-e1.38.31/src/tools/clang', skipping.
Running CMake: ['cmake', '-G', 'Unix Makefiles', '-DCMAKE_BUILD_TYPE=Release', '-DPYTHON_EXECUTABLE=/usr/bin/python3', '-DLLVM_TARGETS_TO_BUILD=X86;JSBackend', '-DLLVM_INCLUDE_EXAMPLES=OFF', '-DCLANG_INCLUDE_EXAMPLES=OFF', '-DLLVM_INCLUDE_TESTS=OFF', '-DCLANG_INCLUDE_TESTS=OFF', '-DLLVM_ENABLE_ASSERTIONS=OFF', '/home/kaiakz/Templates/emsdk/clang/tag-e1.38.31/src']
Traceback (most recent call last):
  File "/home/kaiakz/Templates/emsdk/emsdk.py", line 2891, in <module>
    sys.exit(main())
  File "/home/kaiakz/Templates/emsdk/emsdk.py", line 2871, in main
    success = tool.install()
  File "/home/kaiakz/Templates/emsdk/emsdk.py", line 1659, in install
    success = build_llvm_tool(self)
  File "/home/kaiakz/Templates/emsdk/emsdk.py", line 1081, in build_llvm_tool
    success = cmake_configure(cmake_generator, build_root, fastcomp_src_root, build_type, args)
  File "/home/kaiakz/Templates/emsdk/emsdk.py", line 979, in cmake_configure
    ret = subprocess.check_call(cmdline, cwd=build_root, env=build_env(CMAKE_GENERATOR))
  File "/usr/lib/python3.7/subprocess.py", line 342, in check_call
    retcode = call(*popenargs, **kwargs)
  File "/usr/lib/python3.7/subprocess.py", line 323, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/usr/lib/python3.7/subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.7/subprocess.py", line 1522, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
PermissionError: [Errno 13] Permission denied: 'cmake'

But make ports/javascrpt still shows the same errors. But now env is :

Set the following tools as active:
   clang-tag-e1.38.31-64bit
   node-12.9.1-64bit
   emscripten-tag-1.38.25-64bit

@embeddedt
Copy link
Member

You installed a different version of clang than Emscripten.

@kaiakz
Copy link

kaiakz commented Sep 22, 2019

You installed a different version of clang than Emscripten.

Thanks! All problem solve after I reboot my computer, and I finally got the completed js files with the environment above (though different version clang). The micropython.js is large and sometimes slow(than before), maybe it needs optimizing.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants