diff --git a/internal_filesystem/lib/mpos/ui.py b/internal_filesystem/lib/mpos/ui/__init__.py similarity index 82% rename from internal_filesystem/lib/mpos/ui.py rename to internal_filesystem/lib/mpos/ui/__init__.py index dc3bd4ef..c0e338da 100644 --- a/internal_filesystem/lib/mpos/ui.py +++ b/internal_filesystem/lib/mpos/ui/__init__.py @@ -2,6 +2,7 @@ import utime # for timing calls import lvgl as lv import mpos.apps +from mpos.ui.anim import WidgetAnimator th = None @@ -31,124 +32,6 @@ notification_bar = None foreground_app_name=None - -class WidgetAnimator: - def __init__(self): - self.animations = {} # Store animations for each widget - - # show_widget and hide_widget could have a (lambda) callback that sets the final state (eg: drawer_open) at the end - - def show_widget(self, widget, anim_type="fade", duration=500, delay=0): - """Show a widget with an animation (fade or slide).""" - # Clear HIDDEN flag to make widget visible for animation - widget.remove_flag(lv.obj.FLAG.HIDDEN) - - if anim_type == "fade": - # Create fade-in animation (opacity from 0 to 255) - anim = lv.anim_t() - anim.init() - anim.set_var(widget) - anim.set_values(0, 255) - anim.set_time(duration) - anim.set_delay(delay) - anim.set_custom_exec_cb(lambda anim, value: widget.set_style_opacity(value, 0)) - anim.set_path_cb(lv.anim_t.path_ease_in_out) - # Ensure opacity is reset after animation - anim.set_completed_cb(lambda *args: widget.set_style_opacity(255, 0)) - elif anim_type == "slide_down": - print("doing slide_down") - # Create slide-down animation (y from -height to original y) - original_y = widget.get_y() - height = widget.get_height() - anim = lv.anim_t() - anim.init() - anim.set_var(widget) - anim.set_values(original_y - height, original_y) - anim.set_time(duration) - anim.set_delay(delay) - anim.set_custom_exec_cb(lambda anim, value: widget.set_y(value)) - anim.set_path_cb(lv.anim_t.path_ease_in_out) - # Reset y position after animation - anim.set_completed_cb(lambda *args: widget.set_y(original_y)) - elif anim_type == "slide_up": - # Create slide-up animation (y from +height to original y) - original_y = widget.get_y() - height = widget.get_height() - anim = lv.anim_t() - anim.init() - anim.set_var(widget) - anim.set_values(original_y + height, original_y) - anim.set_time(duration) - anim.set_delay(delay) - anim.set_custom_exec_cb(lambda anim, value: widget.set_y(value)) - anim.set_path_cb(lv.anim_t.path_ease_in_out) - # Reset y position after animation - anim.set_completed_cb(lambda *args: widget.set_y(original_y)) - - # Store and start animation - self.animations[widget] = anim - anim.start() - - def hide_widget(self, widget, anim_type="fade", duration=500, delay=0): - """Hide a widget with an animation (fade or slide).""" - if anim_type == "fade": - # Create fade-out animation (opacity from 255 to 0) - anim = lv.anim_t() - anim.init() - anim.set_var(widget) - anim.set_values(255, 0) - anim.set_time(duration) - anim.set_delay(delay) - anim.set_custom_exec_cb(lambda anim, value: widget.set_style_opacity(value, 0)) - anim.set_path_cb(lv.anim_t.path_ease_in_out) - # Set HIDDEN flag after animation - anim.set_completed_cb(lambda *args: self.hide_complete_cb(widget, original_y)) - elif anim_type == "slide_down": - # Create slide-down animation (y from original y to +height) - original_y = widget.get_y() - height = widget.get_height() - anim = lv.anim_t() - anim.init() - anim.set_var(widget) - anim.set_values(original_y, original_y + height) - anim.set_time(duration) - anim.set_delay(delay) - anim.set_custom_exec_cb(lambda anim, value: widget.set_y(value)) - anim.set_path_cb(lv.anim_t.path_ease_in_out) - # Set HIDDEN flag after animation - anim.set_completed_cb(lambda *args: self.hide_complete_cb(widget, original_y)) - elif anim_type == "slide_up": - print("hide with slide_up") - # Create slide-up animation (y from original y to -height) - original_y = widget.get_y() - height = widget.get_height() - anim = lv.anim_t() - anim.init() - anim.set_var(widget) - anim.set_values(original_y, original_y - height) - anim.set_time(duration) - anim.set_delay(delay) - anim.set_custom_exec_cb(lambda anim, value: widget.set_y(value)) - anim.set_path_cb(lv.anim_t.path_ease_in_out) - # Set HIDDEN flag after animation - anim.set_completed_cb(lambda *args: self.hide_complete_cb(widget, original_y)) - - # Store and start animation - self.animations[widget] = anim - anim.start() - - def hide_complete_cb(self, widget, original_y): - #print("hide_complete_cb") - widget.add_flag(lv.obj.FLAG.HIDDEN) - widget.set_y(original_y) - - - def stop_animation(self, widget): - """Stop any running animation for the widget.""" - if widget in self.animations: - self.animations[widget].delete() - del self.animations[widget] - animator = WidgetAnimator() def get_pointer_xy(): diff --git a/internal_filesystem/lib/mpos/ui/anim.py b/internal_filesystem/lib/mpos/ui/anim.py new file mode 100644 index 00000000..1a52c979 --- /dev/null +++ b/internal_filesystem/lib/mpos/ui/anim.py @@ -0,0 +1,118 @@ +import lvgl as lv + +class WidgetAnimator: + def __init__(self): + self.animations = {} # Store animations for each widget + + # show_widget and hide_widget could have a (lambda) callback that sets the final state (eg: drawer_open) at the end + + def show_widget(self, widget, anim_type="fade", duration=500, delay=0): + """Show a widget with an animation (fade or slide).""" + # Clear HIDDEN flag to make widget visible for animation + widget.remove_flag(lv.obj.FLAG.HIDDEN) + + if anim_type == "fade": + # Create fade-in animation (opacity from 0 to 255) + anim = lv.anim_t() + anim.init() + anim.set_var(widget) + anim.set_values(0, 255) + anim.set_time(duration) + anim.set_delay(delay) + anim.set_custom_exec_cb(lambda anim, value: widget.set_style_opacity(value, 0)) + anim.set_path_cb(lv.anim_t.path_ease_in_out) + # Ensure opacity is reset after animation + anim.set_completed_cb(lambda *args: widget.set_style_opacity(255, 0)) + elif anim_type == "slide_down": + print("doing slide_down") + # Create slide-down animation (y from -height to original y) + original_y = widget.get_y() + height = widget.get_height() + anim = lv.anim_t() + anim.init() + anim.set_var(widget) + anim.set_values(original_y - height, original_y) + anim.set_time(duration) + anim.set_delay(delay) + anim.set_custom_exec_cb(lambda anim, value: widget.set_y(value)) + anim.set_path_cb(lv.anim_t.path_ease_in_out) + # Reset y position after animation + anim.set_completed_cb(lambda *args: widget.set_y(original_y)) + elif anim_type == "slide_up": + # Create slide-up animation (y from +height to original y) + original_y = widget.get_y() + height = widget.get_height() + anim = lv.anim_t() + anim.init() + anim.set_var(widget) + anim.set_values(original_y + height, original_y) + anim.set_time(duration) + anim.set_delay(delay) + anim.set_custom_exec_cb(lambda anim, value: widget.set_y(value)) + anim.set_path_cb(lv.anim_t.path_ease_in_out) + # Reset y position after animation + anim.set_completed_cb(lambda *args: widget.set_y(original_y)) + + # Store and start animation + self.animations[widget] = anim + anim.start() + + def hide_widget(self, widget, anim_type="fade", duration=500, delay=0): + """Hide a widget with an animation (fade or slide).""" + if anim_type == "fade": + # Create fade-out animation (opacity from 255 to 0) + anim = lv.anim_t() + anim.init() + anim.set_var(widget) + anim.set_values(255, 0) + anim.set_time(duration) + anim.set_delay(delay) + anim.set_custom_exec_cb(lambda anim, value: widget.set_style_opacity(value, 0)) + anim.set_path_cb(lv.anim_t.path_ease_in_out) + # Set HIDDEN flag after animation + anim.set_completed_cb(lambda *args: self.hide_complete_cb(widget, original_y)) + elif anim_type == "slide_down": + # Create slide-down animation (y from original y to +height) + original_y = widget.get_y() + height = widget.get_height() + anim = lv.anim_t() + anim.init() + anim.set_var(widget) + anim.set_values(original_y, original_y + height) + anim.set_time(duration) + anim.set_delay(delay) + anim.set_custom_exec_cb(lambda anim, value: widget.set_y(value)) + anim.set_path_cb(lv.anim_t.path_ease_in_out) + # Set HIDDEN flag after animation + anim.set_completed_cb(lambda *args: self.hide_complete_cb(widget, original_y)) + elif anim_type == "slide_up": + print("hide with slide_up") + # Create slide-up animation (y from original y to -height) + original_y = widget.get_y() + height = widget.get_height() + anim = lv.anim_t() + anim.init() + anim.set_var(widget) + anim.set_values(original_y, original_y - height) + anim.set_time(duration) + anim.set_delay(delay) + anim.set_custom_exec_cb(lambda anim, value: widget.set_y(value)) + anim.set_path_cb(lv.anim_t.path_ease_in_out) + # Set HIDDEN flag after animation + anim.set_completed_cb(lambda *args: self.hide_complete_cb(widget, original_y)) + + # Store and start animation + self.animations[widget] = anim + anim.start() + + def hide_complete_cb(self, widget, original_y): + #print("hide_complete_cb") + widget.add_flag(lv.obj.FLAG.HIDDEN) + widget.set_y(original_y) + + + def stop_animation(self, widget): + """Stop any running animation for the widget.""" + if widget in self.animations: + self.animations[widget].delete() + del self.animations[widget]