Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(color): allow all UI controls for widgets when full screen #5808

Merged
merged 25 commits into from
Feb 4, 2025

Conversation

philmoz
Copy link
Collaborator

@philmoz philmoz commented Jan 20, 2025

Extends the Lua LVGL API to allow buttons, text and number edit, sliders etc to be used on widgets when the widget is in full screen mode.

Example widget script:

local opts = {
}

local wgt
local exitApp = false

local function create(zone, opts)
  wgt = { zone=zone, opts=opts }
  return wgt
end

local function update(wgt, opts)
  wgt.opts = opts
  exitApp = false

  if lvgl == nil then return end

  lvgl.clear()

  local lyt

  if (lvgl.isFullScreen()) then
    lyt = {
      {type="button", text="Close", x=100, y=100,
          press=(
              function()
                  lvgl.confirm({title="Exit", message="Really exit?",
                      confirm=(function() exitApp = true end)
                  })
              end)},
    }
  else
    lyt = {
      {type="label", text="Enter full screen for UI", x=100, y=100},
    }
  end

  lvgl.build(lyt)
end

local function background(wgt)
end

local function refresh(wgt, event, touchState)
  if (exitApp) then
    lcd.exitFullScreen()
  end

  if lvgl == nil then
    lcd.drawText(0, 0, "Lvgl support required", COLOR_THEME_WARNING)
  end
end

return { name="Lvgl App", options=opts, create=create, update=update, refresh=refresh, background=background, useLvgl=true }

@philmoz philmoz added enhancement ✨ New feature or request color Related generally to color LCD radios lua-api Lua API related labels Jan 20, 2025
@philmoz philmoz added this to the 2.11 milestone Jan 20, 2025
@philmoz philmoz changed the title feat(color): allow all UI for App Mode widgets when full screen. feat(color): allow all UI controls for widgets when full screen. Jan 20, 2025
@philmoz philmoz marked this pull request as draft January 20, 2025 23:26
@pfeerick pfeerick changed the title feat(color): allow all UI controls for widgets when full screen. feat(color): allow all UI controls for widgets when full screen Jan 21, 2025
@philmoz philmoz marked this pull request as ready for review January 21, 2025 02:26
@philmoz philmoz force-pushed the philmoz/lua-lvgl-app-mode branch 2 times, most recently from 731932e to 8f861ec Compare January 22, 2025 05:45
@philmoz philmoz marked this pull request as draft January 22, 2025 22:35
@philmoz philmoz force-pushed the philmoz/lua-lvgl-app-mode branch from 9ef3bee to aa5a078 Compare January 23, 2025 00:53
@wimalopaan
Copy link
Contributor

wimalopaan commented Jan 23, 2025

Many thanks for your great work!

Most stuff was already discussed on discord.

Just not to get lost I mention the following issues I actually see:

  • slider: function get not called (only once the object gets visible)
  • toggle: function get not called (only once the object gets visible)
  • maybe new UI class momentaryButton as discussed: https://discord.com/channels/839849772864503828/842693696629899274/1331892836303638582
  • define a larger padding than PAD_LARGE: perhaps PAD_XL approx 2 * PAD_LARGE
  • The active function of UI class slider does not work.
  • The font property does not work for UI class button or momentaryButton
  • Add vertical slider option

@philmoz
Copy link
Collaborator Author

philmoz commented Jan 23, 2025

Slider and toggle switch fixed.
You can use any number in place of the PAD_xx constants so not sure a PAD_XL is really needed.

A note on the lvgl.getContext() function.
For widgets it returns the same table that was created with the first 'create()' function call. This allows functions that get or set properties in UI elements to access the internal script data without having to pass the table to every function call.
For stand alone scripts it returns nil.
This was requested by @offer-shmuely.

@wimalopaan
Copy link
Contributor

Slider and toggle switch fixed.

Confirm with my test app. Thanks!!!

You can use any number in place of the PAD_xx constants so not sure a PAD_XL is really needed.

Ok, maybe need only a docu fix then.

A note on the lvgl.getContext() function. For widgets it returns the same table that was created with the first 'create()' function call. This allows functions that get or set properties in UI elements to access the internal script data without having to pass the table to every function call. For stand alone scripts it returns nil. This was requested by @offer-shmuely.

Cool, will also have a look at that.

@philmoz
Copy link
Collaborator Author

philmoz commented Jan 24, 2025

Added 'momentaryButton' control:

{type="momentaryButton", text="Title", press=(function() end), release=(function() end)}

Shows in checked state while pressed.
'press' function is only called when first pressed.
'release' function is called when touch / key press ends.

@philmoz philmoz marked this pull request as ready for review January 24, 2025 02:51
@wimalopaan
Copy link
Contributor

Added 'momentaryButton' control:

Wow! Absolute great work. Many thanks.

First tests are successful ;-)

@wimalopaan
Copy link
Contributor

wimalopaan commented Jan 24, 2025

Just an idea for a small improvement (in my eyes):

the UI classes button and momentaryButton share the same screen layout - they are visually indistinguishable. I would prefer to have different looks for them, to say: the momentaryButton should get another layout (maybe italic font or not a rounded rectangle).

That said, I would it find useful to override the default colors (from theme). The color property for e.g. button is ignored. Maybe there could be textColor, fgColor, bgColor that override the theme defaults.

@offer-shmuely
Copy link
Contributor

offer-shmuely commented Jan 24, 2025 via email

@philmoz
Copy link
Collaborator Author

philmoz commented Jan 24, 2025

Great addition For ease of documentation, it will be better as buttonMomentarySo it will be sorted alphabetically

@wimalopaan - the momentary button was your idea, do you have any preference for how it is named? Now would be the time to change it.

@philmoz
Copy link
Collaborator Author

philmoz commented Jan 24, 2025

the UI classes button and momentaryButton share the same screen layout - they are visually indistinguishable. I would prefer to have different looks for them, to say: the momentaryButton should get another layout (maybe italic font or not a rounded rectangle).

@JimB40 - do you have any thoughts on this?

@wimalopaan
Copy link
Contributor

Great addition For ease of documentation, it will be better as buttonMomentarySo it will be sorted alphabetically

@wimalopaan - the momentary button was your idea, do you have any preference for how it is named? Now would be the time to change it.

I would still vote for momentaryButton.

@philmoz philmoz force-pushed the philmoz/lua-lvgl-app-mode branch from 8c192f2 to 0de975f Compare January 25, 2025 00:15
@wimalopaan
Copy link
Contributor

the UI classes button and momentaryButton share the same screen layout - they are visually indistinguishable. I would prefer to have different looks for them, to say: the momentaryButton should get another layout (maybe italic font or not a rounded rectangle).

@JimB40 - do you have any thoughts on this?

The momentaryButton is new and up to now not used in EdgeTx, so there would be no interference with existing UI code. And I think a (small) visual distinction would be useful.

@wimalopaan
Copy link
Contributor

That said, I would it find useful to override the default colors (from theme). The color property for e.g. button is ignored. Maybe there could be textColor, fgColor, bgColor that override the theme defaults.

Does this make sense?

@wimalopaan
Copy link
Contributor

wimalopaan commented Jan 27, 2025

I did some intensive tests with this PR and it looks really well!
The only caveat is that in widget-mode of TBS Agent Lite (0.99 for LUA 5.3, @JimB40 ) the roller does not work anymore (I used 8c192f2 for testing).

@wimalopaan
Copy link
Contributor

wimalopaan commented Jan 27, 2025

Since lcd.exitFullScreen() does not work for lvgl widgets: how can widgets leave fullscreen mode by themselves?

@philmoz philmoz force-pushed the philmoz/lua-lvgl-app-mode branch from 0de975f to 08bd2a0 Compare January 27, 2025 20:23
@philmoz
Copy link
Collaborator Author

philmoz commented Jan 27, 2025

I did some intensive tests with this PR and it looks really well! The only caveat is that in widget-mode of TBS Agent Lite (0.99 for LUA 5.3, @JimB40 ) the roller does not work anymore (I used 8c192f2 for testing).

Not sure what you mean - widgets only get rotary encoder events when in full screen mode.

@wimalopaan
Copy link
Contributor

The 'color' property on the slider control will now set the color of the inside part of the knob, it also sets the tick marks to the same color.

Perfect, works as expected.

@wimalopaan
Copy link
Contributor

Sorry, I don't understand how this would apply to a slider control.

Well, you have to move the event-location (finger) a certain amount before the slider follows to the new postion. Like the distance from the detent-position is a measure of the force that drags the slider (like a spring).

But: no problem, was just an idea.

@wimalopaan
Copy link
Contributor

Unlikely, the event handling for the slider is buried within the lvgl code.

Ok.
Would it be possible to implement a double-tap event with a callback? Or simply move the slider to the neutral position if a double-tap happens?

@wimalopaan
Copy link
Contributor

Actually I get some problems when using two(!) instances of the same widget. After creating some UI pages the widgets stopped working correctly (e.g. button does not go into checked state) and the radio can't be switched off of model is still connected because the ENTER touch button does not work anymore.

I'll have to dig deeper into the problem ...

@wimalopaan
Copy link
Contributor

I'll have to dig deeper into the problem ...

Using a DEBUG Build the problem has gone. But I see LUA instructionsPercent 123% which might be the problem ...

@gagarinlg
Copy link
Member

I'll have to dig deeper into the problem ...

Using a DEBUG Build the problem has gone. But I see LUA instructionsPercent 123% which might be the problem ...

You can enable a debug function in lv_conf.h that shows which areas are redrawn. Maybe that helps debugging the high load

@wimalopaan
Copy link
Contributor

Ok, thanks für the info.

With a DEBUG I'm not able to reproduce the problem, but I see some LUA instruction percent up to 145%. That doen not look good. Maybe I have to split the page building into several passes and add the UI element-groups one after another ...

@philmoz
Copy link
Collaborator Author

philmoz commented Feb 1, 2025

Ok, thanks für the info.

With a DEBUG I'm not able to reproduce the problem, but I see some LUA instruction percent up to 145%. That doen not look good. Maybe I have to split the page building into several passes and add the UI element-groups one after another ...

Can you share the script code please.

@wimalopaan
Copy link
Contributor

wimalopaan commented Feb 1, 2025

Ok, thanks für the info.
With a DEBUG I'm not able to reproduce the problem, but I see some LUA instruction percent up to 145%. That doen not look good. Maybe I have to split the page building into several passes and add the UI element-groups one after another ...

Can you share the script code please.

The link to the widget: https://github.com/wimalopaan/LUA/tree/main/WIDGETS/lvglMultiSw
The directory name must be /WIDGETS/lvglMultiSw as in the repo.

Install 2 (or more) instances and alter the Address option.

The make them fullscreen, go to settings page and edit e.g. a name. After that try to tap and check a button on the controls page.

@philmoz
Copy link
Collaborator Author

philmoz commented Feb 1, 2025

Ok, thanks für the info.
With a DEBUG I'm not able to reproduce the problem, but I see some LUA instruction percent up to 145%. That doen not look good. Maybe I have to split the page building into several passes and add the UI element-groups one after another ...

Can you share the script code please.

The link to the widget: https://github.com/wimalopaan/LUA/tree/main/WIDGETS/lvglMultiSw The directory name must be /WIDGETS/lvglMultiSw as in the repo.

Install 2 (or more) instances and alter the Address option.

The make them fullscreen, go to settings page and edit e.g. a name. After that try to tap and check a button on the controls page.

Tested in simulator and on TX16S and T15 radios and it works fine for me.
Noticed a couple of things:

  • on initial setup both widgets are saving to the MODEL_xx_0.lua file so they overwrite each other. After reboot they switch to the correct file based on the address setting.
  • the button checked state is saved; but is not restored on re-entering full screen so all the buttons look unchecked even though internally you consider them checked. It takes two taps to get them showing checked again.

@wimalopaan
Copy link
Contributor

Tested in simulator and on TX16S and T15 radios and it works fine for me.

Did you test in a DEBUG build firmware?

  • on initial setup both widgets are saving to the MODEL_xx_0.lua file so they overwrite each other. After reboot they switch to the correct file based on the address setting.

Yes, and already fixed.

  • the button checked state is saved; but is not restored on re-entering full screen so all the buttons look unchecked even though internally you consider them checked. It takes two taps to get them showing checked again.

Thanks for reporting and testing.

I had the problem on non-DEBUG TX16s and non-DEBUG X12s firmware, with DEBUG that never happens.

@wimalopaan
Copy link
Contributor

In a debug build the LUA instruction limit is disabled, so the error can not happen.

But in release build an error message should be displayed.

@philmoz
Copy link
Collaborator Author

philmoz commented Feb 1, 2025

Both radios were release builds.
Retested with the firmware built by this PR and both are fine.

I selected a simple model with no other scripts. Set the view layout to 2x1 and added the widget into both spots, set addresses to 20 and 40.

@wimalopaan
Copy link
Contributor

On my X12s the problem occurs in Release builds with two instances of this script and two other scripts.

I think, I shall decompose the page construction into several steps to reduce the LUA instruction counter.

@philmoz
Copy link
Collaborator Author

philmoz commented Feb 1, 2025

On my X12s the problem occurs in Release builds with two instances of this script and two other scripts.

I think, I shall decompose the page construction into several steps to reduce the LUA instruction counter.

I think this is a bug in the way the Lua instruction limit is being handled. Looking at it now.

@philmoz
Copy link
Collaborator Author

philmoz commented Feb 2, 2025

I've added a change for the instruction limit issue - can you see if it works better for you.

@wimalopaan
Copy link
Contributor

Thanks again!
Now, I don't see any instructionsPercent messages in DEBUG builds anymore, and no more hangs in release builds.

(The only thing that reaches too high instructionsPercent is TBS Agent Lite (as widget), which goes > 230%)

@wimalopaan
Copy link
Contributor

Unlikely, the event handling for the slider is buried within the lvgl code.

Ok. Would it be possible to implement a double-tap event with a callback? Or simply move the slider to the neutral position if a double-tap happens?

Do you see a chance to implement that?

@philmoz
Copy link
Collaborator Author

philmoz commented Feb 2, 2025

Unlikely, the event handling for the slider is buried within the lvgl code.

Ok. Would it be possible to implement a double-tap event with a callback? Or simply move the slider to the neutral position if a double-tap happens?

Do you see a chance to implement that?

There are no multi tap events in lvgl so unlikely. It might be possible to add a long press callback for the slider; but I need to look at the event handler to see.

@pfeerick
Copy link
Member

pfeerick commented Feb 2, 2025

Is this PR pretty much baked now? Anything major still outstanding?

@philmoz
Copy link
Collaborator Author

philmoz commented Feb 2, 2025

I think this is good to merge. If there are any more enhancements or bugs we can create a new PR.

@wimalopaan
Copy link
Contributor

Absolutely!

@pfeerick
Copy link
Member

pfeerick commented Feb 4, 2025

LGTM on TX16... will be great to see some new scripts using this. Thank you @wimalopaan for all your testing, and for the widget scripts you have worked on already making use of this :)

@pfeerick pfeerick merged commit 80d8318 into main Feb 4, 2025
51 checks passed
@pfeerick pfeerick deleted the philmoz/lua-lvgl-app-mode branch February 4, 2025 01:46
wimalopaan added a commit to wimalopaan/edgetx that referenced this pull request Feb 4, 2025
@wimalopaan
Copy link
Contributor

wimalopaan commented Feb 21, 2025

I have to come back to this wonderful PR ;-)

Actually I'm doing some more graphics intensive widgets: here, I like to draw some graphical primitives like rectangles and triangles and arcs with rapidly changing parameters. For the arc one could use values or functions to determine the parameters, for rectangle and triangle only values are possible.
I would find functions very handy in my situation, because it avoids using a name for each graphical primitive and then using the lvgl.set() function to modifiy the parameters. And it looks like it would be not too complicated to add this ... maybe symmetry in the API may also be an argument for that.

@philmoz
Copy link
Collaborator Author

philmoz commented Feb 21, 2025

Actually I'm doing some more graphics intensive widgets: here, I like to draw some graphical primitives like rectangles and triangles and arcs with rapidly changing parameters. For the arc one could use values or functions to determine the parameters, for rectangle and triangle only values are possible.

There is an open PR for Lua changes - #5926
Can you add a list of which properties you are wanting to change to that PR so they don't get lost please.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
color Related generally to color LCD radios enhancement ✨ New feature or request lua-api Lua API related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants