rmkit icon indicating copy to clipboard operation
rmkit copied to clipboard

[request] Scene stack

Open mrichards42 opened this issue 4 years ago • 1 comments

I'm trying to get a Dropdown inside a Dialog, but since there's only a single overlay allowed at a given time, setting the Dropdown overlay would remove the Dialog overlay (I think). It would be nice to have a stack of overlays so that this situation would work.

How this might work:

// show a dialog
// - events are directed at the dialog
// - tapping outside the dialog hides it
// - when this overlay is hidden, control returns to the main scene
ui::MainLoop::show_overlay(dialog_scene);

// show a dropdown on top of the dialog
// - events are directed at the dropdown
// - tapping outside the dropdown hides it (but does not hide the dialog)
// - when this overlay is hidden, control returns to the dialog
ui::MainLoop::show_overlay(dropdown_scene);

In fact, it might work to just have a single scene stack, where keyboard is just another overlay, and main_scene is always on the bottom of the stack.

The main issue I can think of is that currently hiding the overlay doesn't remove it from MainLoop (so it always stays alive, since Scene is a shared_ptr). The simplest version of the scene stack would push scenes on a std::stack, and hiding would actually pop the shared_ptr from the stack, which would decrease the refcount . . . so if you wanted to hold onto a hidden scene you'd have to retain the pointer yourself. And toggle_scene wouldn't really make sense with this setup.

mrichards42 avatar Feb 23 '21 01:02 mrichards42

sounds good to me!

i think every level needs to be redrawn in certain circumstances (or we make fb a little smarter). basically, as more levels are added, the perf will degrade.

raisjn avatar Feb 23 '21 02:02 raisjn

added in https://github.com/rmkit-dev/rmkit/commit/b255e425969d205ff2bc19d7c45f293f2649805f. it works mostly as you describe:

  • main scene is still separate variable in main_loop. set_scene(Scene) is used to set this scene (different than proposal)
  • there is a stack of scenes available in main_loop
  • keyboard is a scene in this stack with the scene attribute clear_under set to true
  • toggle_scene is still there, but not sure if it's useful any longer

show_overlay(Scene s, bool stack=false) will push the scene onto the stack if stack == true. otherwise, it clears the stack and sets the overlay as the scene.

hide_overlay(Scene s) now always takes a scene.

test plan:

  • tested remux dialogs
  • tested remarkable puzzles
  • tested harmony
  • tested input_demo and added a nested overlay scene
  • tested keyboard scene

raisjn avatar Sep 10 '23 01:09 raisjn