lvgl / lv_gui_builder

[WIP] Drag end drop GUI designer for LVGL
25 stars 7 forks source link

Architecture design #1

Open kisvegabor opened 5 years ago

kisvegabor commented 5 years ago

In continue of https://github.com/littlevgl/lvgl/issues/601


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

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 commented 5 years ago

@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 commented 5 years ago

@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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

AGlass0fMilk commented 5 years ago

@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 commented 5 years ago

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 commented 5 years ago

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

I have these in mind: Simple ones:

Complex ones:

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

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 commented 5 years ago

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 commented 5 years ago

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

AGlass0fMilk commented 5 years ago

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 commented 5 years ago

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

amirgon commented 5 years ago

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 littlevgl/lvgl#687 and littlevgl/lvgl#792. There might also be other ways to achieve this, by using JavaScript and some web framework.

embeddedt commented 5 years ago

@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 commented 5 years ago

@embeddedt

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

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:

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

AGlass0fMilk commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago
  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 commented 5 years ago

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 commented 5 years ago

@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 commented 5 years ago

@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 commented 5 years ago

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

I just did :-)

AGlass0fMilk commented 5 years ago

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 commented 5 years ago

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

AGlass0fMilk commented 5 years ago

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 commented 5 years ago

Excellent! This is looking great thus far.

kisvegabor commented 5 years ago

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

AGlass0fMilk commented 5 years ago

Got some basic introspection working with lvgl objects. I have it automatically populating the widget list from classes discovered in the lvgl module that inherit from lvgl.Obj. This way, when we add new widgets there's no extra configuration to do... although the names aren't very user friendly.

My goal is to make basic functionality work without manually creating metadata for each new widget. This way people can easily add custom types. If you want to make the widget's presentation cleaner, we can have a directory of json files where widget metadata is stored. The code can look there for prettier display information but can always fall back to the raw class name.

Also have the lvgl object tree enumerating in the treeview.

Screenshot from 2019-05-23 07-20-42

kisvegabor commented 5 years ago

although the names aren't very user friendly.

We can add lv_obj_set/get_name which can be useful for debugging too. Finally, the lv_obj_set_name functions shouldn't be exported. What do you think?

This way people can easily add custom types. If you want to make the widget's presentation cleaner, we can have a directory of json files where widget metadata is stored. The code can look there for prettier display information but can always fall back to the raw class name.

Can you mention a few things what we can store here?

rreilink commented 5 years ago

We can add lv_obj_set/get_name which can be useful for debugging too. Finally, the lv_obj_set_name functions shouldn't be exported. What do you think?

Would it not make more sense to store the name of the object (which could become the variable name in the C/Python application if code is to be generated) in a dictionary in the GUI designer?

(actually, the dictionary could be a weakref.WeakKeyDictionary with the lvgl objects as keys and their names as values; using a WeakKeyDictionary causes the objects to automatically disappear from the dictionary when they cease to exist)

kisvegabor commented 5 years ago

Would it not make more sense to store the name of the object (which could become the variable name in the C/Python application if code is to be generated) in a dictionary in the GUI designer?

Great idea. It sounds better to me.

AGlass0fMilk commented 5 years ago

Yes, I agree. I made a custom QTreeItem class for the QTreeWidget. It stores a handle to the associated lv_obj pointer. We can associate extra data in this way.

The only thing is that the names of the actually classes are not so pretty. “Btn” should show as “Button” in the widget selection pane. We can have a directory of JSON files that store extra metadata about widget classes (like pretty name, icons to use, etc). If a new or custom widget doesn’t have this information the only consequence is that it won’t look “nice” in the UI pane. It will still be available though.

kisvegabor commented 5 years ago

We can have a directory of JSON files that store extra metadata about widget classes (like pretty name, icons to use, etc)

It's a good example of what can be stored in the metadata files. It seems a flexible and extensible method to store any extra data.

embeddedt commented 5 years ago

@AGlass0fMilk Have you made any more progress on this?

AGlass0fMilk commented 5 years ago

Yes I have done a bit more but I've been busy with other projects lately. I don't see having much time to work on this soon.

I wanted to get it to a starting point so other people could jump on and help. It's much easier to start with something rather than nothing.

Currently, I recall having it working well enough to select UI elements in the simulated screen (with double clicking allowing you to access nested UI components/text labels). The treeviews for the lvgl object tree and the editable attributes of a selected object are also being populated. There are still some bugs with the attribute editing that need to be worked out but you can currently edit things like text on labels.

Drag and drop is the next step I think. A simpler first approach could just have the user select the object they wish to be the parent and then double click a widget from the sidebar to insert as a child object.

I hope to be able to pick this back up again soon. If someone wants to help I can work closely with them to explain how the code works and what my design ideas were if they need.

I'll post some steps to get the builder running so you can play around with it and see where I left it.

EDIT: when I have my other laptop later I'll make sure to sync any uncommitted work (if any).

AGlass0fMilk commented 5 years ago

I'm running on Ubuntu 18.04, steps should be similar but slightly different for other operating systems.

Steps to get demo lvgl builder running:

1.) Set up python3 virtual environment: virtualenv -p python3 ~/python-lvgl 2.) Activate virtualenv: source ~/python-lvgl/bin/activate 3.) Install PyQt5: pip install PyQt5 4.) Install pylvgl: cd ~/Documents && git clone https://github.com/rreilink/pylvgl.git && python ~/Documents/pylvgl/setup.py install 5.) Run lvgl builder:

cd ~/Documents/
git clone git@github.com:littlevgl/lv_gui_builder.git && cd lv_gui_builder
git checkout initial-development
python main.py

EDIT: It looks like you can't edit parameters in the initial-development branch currently. I had that working so it must be unpushed right now. I'll push that stuff up later.

kisvegabor commented 5 years ago

@AGlass0fMilk Thank you for the update and the steps.

I'll try it and look into the code soon. Unfortunately, I can't continue your work but hopefully, somebody will be interested in it!

embeddedt commented 5 years ago

I'm interested in working on it at some point (once I learn enough Python :smile:).

AGlass0fMilk commented 5 years ago

I can work on it here and there but I’m pretty booked out until mid August at this point. @embeddedt let me know if you have any questions. Feel free to email me (see profile)

kaiakz commented 5 years ago

Hi, everyone! I am the author of lv_gui_desiner, a similar tool to lv_gui_builder but built with LittlevGL. @AGlass0fMilk Althought we are different in interface approching, we can still working together in code generation. :smile:
Now I working at project file generation. A project file should store all meta data. Editor can read and convert it into live view, and output the final C or Python code. There are two chioces for it: JSON and XML. I agree with you, XML may be better, according to the Qt Designer and Glade.

My first thought is to use an XML internal representation.

Can you or some guys explain how XML format design? In my idea, I think XML can represent parent-children layer.Just like:

<Screen1>
      <Win>
            <Button>
                  <Label>Example</Labell>
            </Button>
             <CheckBox></CheckBox>
      </Win>
</Screen1>

If you have any advice or good idea, please let me know. :smiley:

kisvegabor commented 5 years ago

@kaiakz Wouldn't it be too verbose in XML to describe so many parameters? (Position, sizes, draggable, clickable and the object type specific parameters and so on). For me, JSON seems more compact for this purpose.

kaiakz commented 5 years ago

XML has three parts: element、attribute and element content. Here are some example: Qt Creator's .ui file (format)

 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <widget class="QDialogButtonBox" name="buttonBox">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>240</y>
     <width>341</width>
     <height>41</height>
    </rect>
   </property>
   <property name="orientation">
    <enum>Qt::Horizontal</enum>
   </property>
   <property name="standardButtons">
    <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
   </property>
  </widget>
  <widget class="QTreeView" name="treeView">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>20</y>
     <width>256</width>
     <height>192</height>
    </rect>
   </property>
  </widget>
 </widget>

Glade creates XML-file .glade, it's said that gtk support CSS. (XML + CSS ?)

  <object class="GtkWindow">
    <property name="can_focus">False</property>
    <child>
      <placeholder/>
    </child>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkButton">
            <property name="label" translatable="yes">button</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkSwitch">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkModelButton">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
embeddedt commented 5 years ago

@kaiakz

<rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
</rect>

is much too verbose in my opinion. Borrowing ideas from HTML, why can't it be more like this?

<rect x="0" y="0" width="400" height="300" visible="false"></rect>
kaiakz commented 5 years ago

For me, JSON seems more compact for this purpose.

@kisvegabor Yes, JSON has the adventure to represent attributes, but it's weak to represent hierarchy(parent-children layer). I have tried to write two examples: In XML:

<win>
  <cont x="0" y="0" layout="COL_M">
    <label text="First"></label>
    <label></label>
  </cont>
  <btn width="400"></btn>
</win>

In JSON

{
  "type": "win",
  "children": [
    {
      "type": "cont",
      "x": 0,
      "y": 0,
      "layout": "COL_M"
      "children": [
        { "type": "label", "text": "First" },
        { "type": "label" },
      ]
    },
    {
      "type": "btn",
      "width": 400,
    },
  ],
}
kaiakz commented 5 years ago

@embeddedt that's a good idea. So it can be

<OBJ_TYPE ATTRIBUTE>...</OBJ_TYPE>

obj_type is btn, win, bar, etc. attribute has id(real name) ,position(x, y), sizes(h ,w), draggable, clickable and the object type-specific parameters , even event_cb(function name). If some attributes do not be customized, they won't appear.

<btn id="btn01" x="0" y="10" drag="true" event_cb="btn_cb">
    <label id="lb0100" text="Hello"></label>
</btn>

I am writing some code about XML2LiveDemo(load project file): Build a stack to store parent, when program meets , calls lv_obj_create(parent, NULL), it will choose the top of stack as parent. Use lv_obj_set_xx to set the attributes. Stack will pop the top when it meets . Loop......

kisvegabor commented 5 years ago

I also like the HTML-like format.

I am writing some code about XML2LiveDemo(load project file): Build a stack to store parent, when program meets , calls lv_obj_create(parent, NULL), it will choose the top of stack as parent. Use lv_obj_set_xx to set the attributes. Stack will pop the top when it meets . Loop......

Awesome! Curiously waiting to see it! :+1:

kaiakz commented 5 years ago

@kisvegabor @embeddedt I wrote a simple demo. It parses the XML file to the real interface by SAX and a stack. load Just type some XML tags: <BTN><LABEL>, X-Y attribute to determine all widgets. Maybe some tags name need to improve, such as <BUTTON> is better than <BTN>?

embeddedt commented 5 years ago

@kaiakz Since the XML is unlikely to be used directly by a user (and in the case that it does, btn would be familiar as it is the abbreviation used inside the library) I think we can stick with <BTN> for now.

But it's looking great already! I'm impressed by how far you've gotten so quickly.