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

[Slider] New library for input via sliders #2953

Merged
merged 105 commits into from
Oct 19, 2023

Conversation

thyttan
Copy link
Collaborator

@thyttan thyttan commented Aug 8, 2023

WIP

Companion PR to Gadgetbridge.

This is meant to become a flexible and as lightweight/performant implementation of ui with input sliders as I can manage.

https://thyttan.github.io/BangleApps/apps/slidertest/screenshot-1.png

To try it out:

  1. Install updated Android Integration to be able to send new vg command (vg = Volume Get level).
  2. Install the test app
  3. Start the app named "Slider test" from your watch's launcher.
  4. Optionally install and try this modified "Remote for Spotify" to see the library used in a proper app.
  5. Build Gadgetbridge from source with changes in Companion PR to Gadgetbridge included to see it handle the and vg command.

Still much to do:

  • - Many hardcoded values should depend on parameters.
  • - Refactor to split up logic and graphics better.
  • - initiate the border on first launch - don't draw it on every drag event?
  • - add ability to disable timeout.
  • - Ideally make the graphics nicer on low levels, but I don't want to introduce too much code.
  • - possibility to display multiple sliders simultaneously?
  • - optional auto incrementing level for persistent sliders (such as for a seek bar tracking a song)
  • - fix behavior when moving an auto progressing slider. Especially after it had reached the end. GOOD ENOUGH FOR NOW
  • - when using one persistent slider and one temporary, stop the persistent one not being redrawn when the temporary one goes away.
  • - Optimize data sent to Gadgetbridge for speed?
  • - Try to ensure backwards compatibility with older Android Integration versions - make sure nothing breaks at least. SEEMS TO NOT BREAK.
  • - Should it be compatible with Bangle.js 1? NOT FOR NOW AT LEAST
  • - maybe refine behavior so input to one slider stops input to the other one when drag is being propagated. ACHIEVABLE BY CHECKING FOR ACTIVE SLIDER DRAG HANDLERS.
  • - find out why I don't get position info for media tracks playing on my android phone.
  • - fix or remove lazy drawing? I DID BOTH.
  • - is using setClipRect a good or bad idea? FEELS PRETTY GOOD.
  • - make as many parts of the slider object as possible optional.
  • - redo/add logic for auto progressing sliders to use Date/getTime or similar? So it's not dependent on a timeout to keep track of correct current position. Would be good for battery maybe.
  • - Add documentation to Slider.md in modules folder. ADDED SOME. MORE CAN BE ADDED LATER.
  • - remove debug code/commits.
  • - check for ram leaks. I THINK IT LOOKS GOOD SO FAR. WILL LOOK AGAIN LATER.
  • - split the PR up in parts, one app per PR.
  • - relate configurations defaults to g.getwidth/height (e.g. outerBorderSize).
  • - make final decisions on names for vars, consts and functions.
  • - take cues from Layout module? E.g. adapt to using this?
  • - Try breaking the slider with configurations:
    • - fix width below 44 starts to give bad graphics on rounded sliders (e.g. the zero-level circle should be able to be smaller)
    • - when width is just a few pixels (depending on config) the bar can suddenly become very wide.
  • - follow the espruino coding style guide.
  • - look through the espruino performance notes and apply relevant tweaks?
  • - how do I make it easy to not mess up memory usage/ making it straight forward to not end up with ram leaks?
  • - think about the scoping/flow of vars/funcs etc.
  • - be more selective with sprinkling "ram" in functions? (Test app will use blocks of memory ca 3230 with vs 2930 without "ram", out of 12000 blocks. With "ram" a slider using map feels snappier, but it's not a super big difference.)

other considerations:

@gfwilliams
Copy link
Member

Thanks - do you think maybe the slider library should just be in modules rather than being a whole separate app with icon/etc? Seems like it's probably more sensible for such a small bit of code?

@thyttan
Copy link
Collaborator Author

thyttan commented Aug 8, 2023

do you think maybe the slider library should just be in modules rather than being a whole separate app with icon/etc?

I was wondering about that actually. Does it make sense to develop it like this and change it to that when it's ready for merge?

@gfwilliams
Copy link
Member

Does it make sense to develop it like this

Up to you really - whatever you find easier. If you're developing with just the IDE you can have two files open now, one of which is the module and one of which is the app, and that should work nicely.

@thyttan thyttan force-pushed the ui-slider-lib branch 3 times, most recently from 0f17a68 to 2cddc29 Compare August 9, 2023 08:54
@thyttan thyttan marked this pull request as draft August 9, 2023 14:34
@thyttan thyttan force-pushed the ui-slider-lib branch 2 times, most recently from eee024e to 8ca3772 Compare August 15, 2023 21:57
@thyttan thyttan force-pushed the ui-slider-lib branch 3 times, most recently from ba1d6f8 to 680dd9a Compare August 16, 2023 21:58
@thyttan thyttan changed the title [libslider] New library for input via sliders [SliderInput] New library for input via sliders Aug 16, 2023
@thyttan thyttan force-pushed the ui-slider-lib branch 2 times, most recently from c9b4f24 to 3e33fcd Compare August 17, 2023 01:16
@thyttan
Copy link
Collaborator Author

thyttan commented Aug 17, 2023

@gfwilliams would it make sense to make this compatible with Bangle.js 1? Or is the ram constraint too narrow so it isn't worth it to implement it?

@gfwilliams
Copy link
Member

The Bangle.js 1 doesn't provide any x/y touch input (it's just two areas) and there are no overlays so I don't think this makes sense.

Come to think of it, I see you using overlays here - is that really needed? Putting up an overlay is a lot slower than just updating the screen, so if there's a way of doing this without overlays it seems that'd be better.

@thyttan
Copy link
Collaborator Author

thyttan commented Aug 18, 2023

Thanks!

The Bangle.js 1 doesn't provide any x/y touch input (it's just two areas) and there are no overlays so I don't think this makes sense.

Ok, I was thinking of maybe using the LR-swipes on bangle 1.

Come to think of it, I see you using overlays here - is that really needed? Putting up an overlay is a lot slower than just updating the screen, so if there's a way of doing this without overlays it seems that'd be better.

Ok! I opted for overlays to not mess with the other graphics of the current app. So that when the slider times out and goes away the graphics behind is still there. But maybe that can be achieved without overlays also? Or otherwise, maybe it's better to expect the app to draw again when the slider timed out?

@gfwilliams
Copy link
Member

Thanks! I'm just a bit anxious that right now we assume that apps aren't using overlays - for instance if Messages Overlay or the widget_utils.swipeOn has call to use them and your slider is active, it'll probably just end up removing your overlay while all your touchscreen handlers stay active. I'd sort of assumed they would be used quite rarely so there's nothing implemented to handle stacking them or restoring old ones.

I might be better to assume the app will redraw. I recently added:

Bangle.setUI({
  mode : "custom",
  // ...
  redraw : function() {},
});

Which is in cutting edge builds (and will be released in 2v19) which showMenu/showPrompt/showScroller all implement - so if you're planning on using the slider from E.showMenu that could be a neat option?

Although it's probably not a big deal to just ask the caller to redraw in the callback, and it might be safer

@thyttan thyttan force-pushed the ui-slider-lib branch 4 times, most recently from 527125e to 3c1f36b Compare August 27, 2023 10:30
@thyttan
Copy link
Collaborator Author

thyttan commented Aug 27, 2023

  • when using one persistent slider and one temporary, stop the persistent one not being redrawn when the temporary one goes away.

One solution here would be to:

  1. remove the persistent slider when the temporary one goes away, similarly to how timeouts and event handlers can be removed by referencing them.
  2. reinitiate the persistent slider.

But I currently don't know how to achieve step 1.

Edit: I can probably refactor to do like the top answer here: https://stackoverflow.com/questions/25199343/javascript-calling-a-inner-function-from-outside. Don't know if it's the best route.

@thyttan thyttan force-pushed the ui-slider-lib branch 5 times, most recently from 6a08d31 to e196972 Compare September 2, 2023 14:18
thyttan pushed a commit to thyttan/BangleApps that referenced this pull request Oct 17, 2023
as per: espruino#2953 (comment)

To still be able to draw on top of the slider, in the callback wrap the extra drawing inside a `setTimeout(extraDraw,0)` or similar.

Thanks @bobrippling!
thyttan pushed a commit to thyttan/BangleApps that referenced this pull request Oct 17, 2023
as per: espruino#2953 (comment)

To still be able to draw on top of the slider, in the callback wrap the extra drawing inside a `setTimeout(extraDraw,0)` or similar.

Thanks @bobrippling!
@thyttan thyttan marked this pull request as ready for review October 17, 2023 23:07
@gfwilliams
Copy link
Member

gfwilliams commented Oct 18, 2023

Looks like you're still doing a bunch of work on this, so maybe I'll hold off merging until things calm down a bit?

@thyttan
Copy link
Collaborator Author

thyttan commented Oct 18, 2023

@gfwilliams, I think this is OK to merge, and would be happy to have it be so. The remaining checkboxes can be handled in another PR I think.

But also, I would be interested in what you think about the naming of things before the initial introduction to the main repo. If you see anything apparent regarding that it could be good to take it into account before merging.

@gfwilliams
Copy link
Member

Thanks! I had a look and as far as I'm concerned, that naming all looks pretty good.

Layout does use col/bgCol and this uses colorFG/colorBG but honestly I don't think that's really a big deal - it's not like the choices for layout were very clever, I was just trying to keep the names short so less space was used when you had lots of Layout objects (but chances are you'll only ever have a few sliders so that doesn't matter)

@gfwilliams gfwilliams merged commit 9da07b3 into espruino:master Oct 19, 2023
1 check passed
@thyttan
Copy link
Collaborator Author

thyttan commented Oct 19, 2023

Ok!

Thanks for the help on this @gfwilliams and @bobrippling 😊

@bobrippling
Copy link
Collaborator

My pleasure, glad to see this slider work finished! Thank you too!

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

Successfully merging this pull request may close these issues.

3 participants