ruflet 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ruflet/version.rb +1 -1
- data/lib/ruflet_ui/ruflet/app.rb +10 -14
- data/lib/ruflet_ui/ruflet/control.rb +120 -7
- data/lib/ruflet_ui/ruflet/dsl.rb +68 -4
- data/lib/ruflet_ui/ruflet/event.rb +15 -1
- data/lib/ruflet_ui/ruflet/events/gesture_events.rb +552 -0
- data/lib/ruflet_ui/ruflet/page.rb +558 -77
- data/lib/ruflet_ui/ruflet/types/geometry.rb +65 -0
- data/lib/ruflet_ui/ruflet/types/text_style.rb +191 -0
- data/lib/ruflet_ui/ruflet/ui/control_factory.rb +35 -5
- data/lib/ruflet_ui/ruflet/ui/control_methods.rb +1 -0
- data/lib/ruflet_ui/ruflet/ui/control_registry.rb +22 -2
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoactionsheet_control.rb +57 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoactionsheetaction_control.rb +58 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoactivityindicator_control.rb +57 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoalertdialog_control.rb +39 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoappbar_control.rb +44 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinobottomsheet_control.rb +38 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinobutton_control.rb +73 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinocheckbox_control.rb +70 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinocontextmenu_control.rb +34 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinocontextmenuaction_control.rb +36 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinodatepicker_control.rb +67 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinodialogaction_control.rb +35 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinofilledbutton_control.rb +73 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinolisttile_control.rb +67 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinonavigationbar_control.rb +61 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinopicker_control.rb +66 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoradio_control.rb +66 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinosegmentedbutton_control.rb +63 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoslider_control.rb +64 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoslidingsegmentedbutton_control.rb +60 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoswitch_control.rb +73 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinotextfield_control.rb +159 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinotimerpicker_control.rb +61 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinotintedbutton_control.rb +73 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/ruflet_controls.rb +89 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/alertdialog_control.rb +58 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/appbar_control.rb +53 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/audio_control.rb +36 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/autocomplete_control.rb +58 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/badge_control.rb +31 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/banner_control.rb +47 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/bottomappbar_control.rb +62 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/bottomsheet_control.rb +48 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/button_control.rb +69 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/card_control.rb +63 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/chart_controls.rb +321 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/checkbox_control.rb +76 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/chip_control.rb +88 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/circleavatar_control.rb +62 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/container_control.rb +81 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/contextmenu_control.rb +63 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/datacell_control.rb +38 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/datacolumn_control.rb +34 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/datarow_control.rb +35 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/datatable_control.rb +78 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/datepicker_control.rb +55 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/daterangepicker_control.rb +57 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/divider_control.rb +36 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/dropdown_control.rb +99 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/dropdownm2_control.rb +119 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/dropdownoption_control.rb +35 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/expansionpanel_control.rb +61 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/expansionpanellist_control.rb +60 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/expansiontile_control.rb +82 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/filledbutton_control.rb +69 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/fillediconbutton_control.rb +81 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/filledtonalbutton_control.rb +69 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/filledtonaliconbutton_control.rb +81 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/floatingactionbutton_control.rb +73 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/iconbutton_control.rb +81 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/listtile_control.rb +87 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/menubar_control.rb +33 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/menuitembutton_control.rb +67 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/navigationbar_control.rb +67 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/navigationbardestination_control.rb +35 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/navigationdrawer_control.rb +41 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/navigationdrawerdestination_control.rb +34 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/navigationrail_control.rb +70 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/navigationraildestination_control.rb +36 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/option_control.rb +35 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/outlinedbutton_control.rb +66 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/outlinediconbutton_control.rb +81 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/popupmenubutton_control.rb +74 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/popupmenuitem_control.rb +38 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/progressbar_control.rb +64 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/progressring_control.rb +65 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/radio_control.rb +70 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/radiogroup_control.rb +33 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/rangeslider_control.rb +67 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/reorderablelistview_control.rb +80 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/ruflet_controls.rb +252 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/searchbar_control.rb +94 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/segment_control.rb +33 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/segmentedbutton_control.rb +63 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/selectionarea_control.rb +32 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/slider_control.rb +76 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/snackbar_control.rb +51 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/submenubutton_control.rb +66 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/switch_control.rb +77 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/tab_control.rb +35 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/tabbar_control.rb +77 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/tabbarview_control.rb +57 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/tabs_control.rb +59 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/textbutton_control.rb +66 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/textfield_control.rb +148 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/timepicker_control.rb +50 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/verticaldivider_control.rb +36 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/video_control.rb +39 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/webview_control.rb +35 -0
- data/lib/ruflet_ui/ruflet/ui/controls/ruflet_controls.rb +447 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/animatedswitcher_control.rb +59 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/arc_control.rb +29 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/autofillgroup_control.rb +32 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/basepage_control.rb +44 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/browsercontextmenu_control.rb +21 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/canvas_control.rb +57 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/circle_control.rb +25 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/color_control.rb +23 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/column_control.rb +67 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/dialogs_control.rb +22 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/dismissible_control.rb +66 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/draggable_control.rb +39 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/dragtarget_control.rb +36 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/fill_control.rb +22 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/fletapp_control.rb +62 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/gesturedetector_control.rb +129 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/gridview_control.rb +71 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/hero_control.rb +56 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/icon_control.rb +64 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/image_control.rb +27 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/interactiveviewer_control.rb +69 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/keyboardlistener_control.rb +36 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/line_control.rb +26 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/listview_control.rb +71 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/markdown_control.rb +70 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/mergesemantics_control.rb +31 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/oval_control.rb +26 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/overlay_control.rb +22 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/page_control.rb +74 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/pagelet_control.rb +64 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/pageview_control.rb +64 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/path_control.rb +23 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/placeholder_control.rb +58 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/points_control.rb +24 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/rect_control.rb +27 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/reorderabledraghandle_control.rb +56 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/responsiverow_control.rb +61 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/row_control.rb +67 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/ruflet_controls.rb +140 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/safearea_control.rb +61 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/semantics_control.rb +79 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/serviceregistry_control.rb +21 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/shadermask_control.rb +57 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/shadow_control.rb +25 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/shimmer_control.rb +60 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/stack_control.rb +58 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/text_control.rb +32 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/textspan_control.rb +39 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/transparentpointer_control.rb +54 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/view_control.rb +77 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/window_control.rb +56 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/windowdragarea_control.rb +58 -0
- data/lib/ruflet_ui/ruflet/ui/cupertino_control_factory.rb +3 -30
- data/lib/ruflet_ui/ruflet/ui/material_control_factory.rb +3 -87
- data/lib/ruflet_ui/ruflet/ui/material_control_methods.rb +44 -2
- data/lib/ruflet_ui/ruflet/ui/material_control_registry.rb +26 -12
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/accelerometer_control.rb +26 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/barometer_control.rb +26 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/battery_control.rb +22 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/camera_control.rb +58 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/clipboard_control.rb +21 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/connectivity_control.rb +22 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/filepicker_control.rb +23 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/flashlight_control.rb +22 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/gyroscope_control.rb +26 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/hapticfeedback_control.rb +21 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/magnetometer_control.rb +26 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/screenbrightness_control.rb +23 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/screenshot_control.rb +31 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/semanticsservice_control.rb +21 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/shakedetector_control.rb +26 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/share_control.rb +21 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/sharedpreferences_control.rb +21 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/storagepaths_control.rb +21 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/urllauncher_control.rb +21 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/useraccelerometer_control.rb +26 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/wakelock_control.rb +21 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet_services.rb +66 -0
- data/lib/ruflet_ui/ruflet/ui/shared_control_forwarders.rb +41 -1
- data/lib/ruflet_ui/ruflet/ui/widget_builder.rb +9 -0
- data/lib/ruflet_ui.rb +14 -1
- metadata +178 -44
- data/lib/ruflet/manifest_compiler.rb +0 -62
- data/lib/ruflet_ui/ruflet/ui/controls/cupertino/cupertino_action_sheet_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/cupertino/cupertino_alert_dialog_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/cupertino/cupertino_button_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/cupertino/cupertino_dialog_action_control.rb +0 -24
- data/lib/ruflet_ui/ruflet/ui/controls/cupertino/cupertino_filled_button_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/cupertino/cupertino_navigation_bar_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/cupertino/cupertino_slider_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/cupertino/cupertino_switch_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/cupertino/cupertino_text_field_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/alert_dialog_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/app_bar_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/bottom_sheet_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/button_control.rb +0 -24
- data/lib/ruflet_ui/ruflet/ui/controls/material/checkbox_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/column_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/container_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/drag_target_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/draggable_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/elevated_button_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/filled_button_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/floating_action_button_control.rb +0 -28
- data/lib/ruflet_ui/ruflet/ui/controls/material/gesture_detector_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/grid_view_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/icon_button_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/icon_control.rb +0 -24
- data/lib/ruflet_ui/ruflet/ui/controls/material/image_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/markdown_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/navigation_bar_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/navigation_bar_destination_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/radio_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/radio_group_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/row_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/snack_bar_control.rb +0 -68
- data/lib/ruflet_ui/ruflet/ui/controls/material/stack_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/tab_bar_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/tab_bar_view_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/tab_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/tabs_control.rb +0 -63
- data/lib/ruflet_ui/ruflet/ui/controls/material/text_button_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/text_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/text_field_control.rb +0 -13
- data/lib/ruflet_ui/ruflet/ui/controls/material/view_control.rb +0 -13
|
@@ -4,6 +4,7 @@ require_relative "event"
|
|
|
4
4
|
require "ruflet_protocol"
|
|
5
5
|
require_relative "control"
|
|
6
6
|
require_relative "ui/widget_builder"
|
|
7
|
+
require_relative "ui/control_factory"
|
|
7
8
|
require_relative "icons/material_icon_lookup"
|
|
8
9
|
require_relative "icons/cupertino_icon_lookup"
|
|
9
10
|
require "set"
|
|
@@ -15,19 +16,11 @@ module Ruflet
|
|
|
15
16
|
class Page
|
|
16
17
|
PAGE_PROP_KEYS = %w[route title vertical_alignment horizontal_alignment scroll].freeze
|
|
17
18
|
DIALOG_PROP_KEYS = %w[dialog snack_bar bottom_sheet].freeze
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
alert_dialog alertdialog markdown icon image app_bar appbar floating_action_button snack_bar snackbar
|
|
24
|
-
bottom_sheet bottomsheet tabs tab tab_bar tabbar tab_bar_view tabbarview navigation_bar navigationbar
|
|
25
|
-
navigation_bar_destination navigationbardestination fab cupertino_button
|
|
26
|
-
cupertinobutton cupertino_filled_button cupertinofilledbutton cupertino_text_field cupertinotextfield
|
|
27
|
-
cupertino_switch cupertinoswitch cupertino_slider cupertinoslider cupertino_alert_dialog
|
|
28
|
-
cupertinoalertdialog cupertino_action_sheet cupertinoactionsheet cupertino_dialog_action
|
|
29
|
-
cupertinodialogaction cupertino_navigation_bar cupertinonavigationbar
|
|
30
|
-
].freeze
|
|
19
|
+
WIDGET_HELPER_METHODS = (
|
|
20
|
+
Ruflet::UI::MaterialControlMethods.instance_methods(false) +
|
|
21
|
+
Ruflet::UI::CupertinoControlMethods.instance_methods(false) +
|
|
22
|
+
%i[control widget]
|
|
23
|
+
).map(&:to_s).to_set.freeze
|
|
31
24
|
|
|
32
25
|
attr_reader :session_id, :client_details, :views
|
|
33
26
|
|
|
@@ -62,6 +55,7 @@ module Ruflet
|
|
|
62
55
|
controls: []
|
|
63
56
|
)
|
|
64
57
|
@invoke_waiters = {}
|
|
58
|
+
@invoke_callbacks = {}
|
|
65
59
|
@invoke_waiters_mutex = Mutex.new
|
|
66
60
|
refresh_overlay_container!
|
|
67
61
|
refresh_services_container!
|
|
@@ -161,6 +155,45 @@ module Ruflet
|
|
|
161
155
|
self
|
|
162
156
|
end
|
|
163
157
|
|
|
158
|
+
def remove_service(*value)
|
|
159
|
+
targets = value.flatten.compact
|
|
160
|
+
return self if targets.empty?
|
|
161
|
+
|
|
162
|
+
@services_container.props["_services"] = services.reject do |service|
|
|
163
|
+
targets.any? do |target|
|
|
164
|
+
case target
|
|
165
|
+
when Control
|
|
166
|
+
service.equal?(target) || (!target.id.nil? && service.id.to_s == target.id.to_s)
|
|
167
|
+
else
|
|
168
|
+
needle = target.to_s
|
|
169
|
+
service.id.to_s == needle || service.type.to_s.downcase == needle.downcase
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
refresh_services_container!
|
|
175
|
+
push_services_update!
|
|
176
|
+
self
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def service(type, **props)
|
|
180
|
+
mapped_props = normalize_props(props || {})
|
|
181
|
+
id = mapped_props.delete("id")
|
|
182
|
+
normalized_type = type.to_s.downcase
|
|
183
|
+
|
|
184
|
+
existing =
|
|
185
|
+
if id
|
|
186
|
+
services.find { |s| s.is_a?(Control) && s.id.to_s == id.to_s }
|
|
187
|
+
else
|
|
188
|
+
services.find { |s| s.is_a?(Control) && s.type.to_s.downcase == normalized_type }
|
|
189
|
+
end
|
|
190
|
+
return existing if existing
|
|
191
|
+
|
|
192
|
+
svc = Ruflet::UI::ControlFactory.build(type.to_s, id: id&.to_s, **mapped_props)
|
|
193
|
+
add_service(svc) unless services.include?(svc)
|
|
194
|
+
svc
|
|
195
|
+
end
|
|
196
|
+
|
|
164
197
|
def go(route, **query_params)
|
|
165
198
|
@page_props["route"] = build_route(route, query_params)
|
|
166
199
|
dispatch_page_event(name: "route_change", data: @page_props["route"])
|
|
@@ -233,80 +266,327 @@ module Ruflet
|
|
|
233
266
|
self
|
|
234
267
|
end
|
|
235
268
|
|
|
236
|
-
def invoke(control_or_id, method_name, args: nil, timeout: 10)
|
|
237
|
-
|
|
238
|
-
|
|
269
|
+
def invoke(control_or_id, method_name, args: nil, timeout: 10, on_result: nil)
|
|
270
|
+
control_id =
|
|
271
|
+
if page_control_target?(control_or_id)
|
|
272
|
+
1
|
|
273
|
+
else
|
|
274
|
+
control = resolve_control(control_or_id)
|
|
275
|
+
return nil unless control
|
|
276
|
+
control.wire_id
|
|
277
|
+
end
|
|
239
278
|
|
|
240
279
|
call_id = "call_#{Ruflet::Control.generate_id}"
|
|
241
|
-
|
|
242
|
-
|
|
280
|
+
if on_result.respond_to?(:call)
|
|
281
|
+
@invoke_waiters_mutex.synchronize { @invoke_callbacks[call_id] = on_result }
|
|
282
|
+
unless timeout.nil?
|
|
283
|
+
Thread.new(call_id, timeout.to_f) do |pending_call_id, invoke_timeout|
|
|
284
|
+
sleep([invoke_timeout, 0.0].max + 0.1)
|
|
285
|
+
callback = @invoke_waiters_mutex.synchronize { @invoke_callbacks.delete(pending_call_id) }
|
|
286
|
+
callback&.call(nil, "execution expired")
|
|
287
|
+
rescue StandardError => e
|
|
288
|
+
Kernel.warn("invoke timeout callback error: #{e.class}: #{e.message}")
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
payload = {
|
|
293
|
+
"control_id" => control_id,
|
|
243
294
|
"call_id" => call_id,
|
|
244
295
|
"name" => method_name.to_s,
|
|
245
|
-
"args" => args
|
|
246
|
-
|
|
247
|
-
|
|
296
|
+
"args" => args
|
|
297
|
+
}
|
|
298
|
+
payload["timeout"] = timeout unless timeout.nil?
|
|
299
|
+
send_message(Protocol::ACTIONS[:invoke_control_method], payload)
|
|
248
300
|
|
|
249
301
|
call_id
|
|
250
302
|
end
|
|
251
303
|
|
|
252
|
-
|
|
253
|
-
|
|
304
|
+
# Synchronous invoke for controls/services that must return a value
|
|
305
|
+
# before continuing (e.g. picker selection, camera discovery/init).
|
|
306
|
+
def invoke_sync(control_or_id, method_name, args: nil, timeout: 10)
|
|
307
|
+
invoke_and_wait(control_or_id, method_name, args: args, timeout: timeout)
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def launch_url(url, mode: nil, web_view_configuration: nil, browser_configuration: nil, web_only_window_name: nil, timeout: 10, on_result: nil)
|
|
311
|
+
url_launcher = ensure_url_launcher_service
|
|
312
|
+
args = { "url" => url }
|
|
313
|
+
args["mode"] = mode unless mode.nil?
|
|
314
|
+
args["web_view_configuration"] = web_view_configuration unless web_view_configuration.nil?
|
|
315
|
+
args["browser_configuration"] = browser_configuration unless browser_configuration.nil?
|
|
316
|
+
args["web_only_window_name"] = web_only_window_name unless web_only_window_name.nil?
|
|
254
317
|
invoke(
|
|
255
|
-
|
|
318
|
+
url_launcher,
|
|
256
319
|
"launch_url",
|
|
257
|
-
args:
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
"web_view_configuration" => web_view_configuration,
|
|
261
|
-
"browser_configuration" => browser_configuration,
|
|
262
|
-
"web_only_window_name" => web_only_window_name
|
|
263
|
-
}.compact,
|
|
264
|
-
timeout: timeout
|
|
320
|
+
args: args,
|
|
321
|
+
timeout: timeout,
|
|
322
|
+
on_result: on_result
|
|
265
323
|
)
|
|
266
324
|
end
|
|
267
325
|
|
|
268
326
|
def can_launch_url(url, timeout: 10)
|
|
269
|
-
|
|
270
|
-
invoke(
|
|
327
|
+
url_launcher = ensure_url_launcher_service
|
|
328
|
+
invoke(url_launcher, "can_launch_url", args: { "url" => url }, timeout: timeout)
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
# File picker helpers: create an ephemeral service, invoke method, and dispose it.
|
|
332
|
+
def pick_files(
|
|
333
|
+
dialog_title: nil,
|
|
334
|
+
initial_directory: nil,
|
|
335
|
+
file_type: "any",
|
|
336
|
+
allowed_extensions: nil,
|
|
337
|
+
allow_multiple: false,
|
|
338
|
+
with_data: false,
|
|
339
|
+
timeout: nil,
|
|
340
|
+
on_result: nil
|
|
341
|
+
)
|
|
342
|
+
invoke_file_picker(
|
|
343
|
+
"pick_files",
|
|
344
|
+
{
|
|
345
|
+
"dialog_title" => dialog_title,
|
|
346
|
+
"initial_directory" => initial_directory,
|
|
347
|
+
"file_type" => file_type,
|
|
348
|
+
"allowed_extensions" => allowed_extensions,
|
|
349
|
+
"allow_multiple" => allow_multiple,
|
|
350
|
+
"with_data" => with_data
|
|
351
|
+
},
|
|
352
|
+
timeout: timeout,
|
|
353
|
+
on_result: on_result
|
|
354
|
+
)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
def save_file(
|
|
358
|
+
dialog_title: nil,
|
|
359
|
+
file_name: nil,
|
|
360
|
+
initial_directory: nil,
|
|
361
|
+
file_type: "any",
|
|
362
|
+
allowed_extensions: nil,
|
|
363
|
+
src_bytes: nil,
|
|
364
|
+
timeout: nil,
|
|
365
|
+
on_result: nil
|
|
366
|
+
)
|
|
367
|
+
invoke_file_picker(
|
|
368
|
+
"save_file",
|
|
369
|
+
{
|
|
370
|
+
"dialog_title" => dialog_title,
|
|
371
|
+
"file_name" => file_name,
|
|
372
|
+
"initial_directory" => initial_directory,
|
|
373
|
+
"file_type" => file_type,
|
|
374
|
+
"allowed_extensions" => allowed_extensions,
|
|
375
|
+
"src_bytes" => src_bytes
|
|
376
|
+
},
|
|
377
|
+
timeout: timeout,
|
|
378
|
+
on_result: on_result
|
|
379
|
+
)
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def get_directory_path(dialog_title: nil, initial_directory: nil, timeout: nil, on_result: nil)
|
|
383
|
+
invoke_file_picker(
|
|
384
|
+
"get_directory_path",
|
|
385
|
+
{
|
|
386
|
+
"dialog_title" => dialog_title,
|
|
387
|
+
"initial_directory" => initial_directory
|
|
388
|
+
},
|
|
389
|
+
timeout: timeout,
|
|
390
|
+
on_result: on_result
|
|
391
|
+
)
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
def set_clipboard(value, timeout: nil, on_result: nil)
|
|
395
|
+
invoke_clipboard_method(
|
|
396
|
+
"set_data",
|
|
397
|
+
args: { "data" => value.to_s },
|
|
398
|
+
timeout: timeout,
|
|
399
|
+
on_result: on_result
|
|
400
|
+
)
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
def get_clipboard(timeout: nil, on_result: nil)
|
|
404
|
+
invoke_clipboard_method("get_data", timeout: timeout, on_result: on_result)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
def set_clipboard_files(files, timeout: nil, on_result: nil)
|
|
408
|
+
invoke_clipboard_method(
|
|
409
|
+
"set_files",
|
|
410
|
+
args: { "files" => Array(files).map(&:to_s) },
|
|
411
|
+
timeout: timeout,
|
|
412
|
+
on_result: on_result
|
|
413
|
+
)
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
def get_clipboard_files(timeout: nil, on_result: nil)
|
|
417
|
+
invoke_clipboard_method("get_files", timeout: timeout, on_result: on_result)
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
def set_clipboard_image(value, timeout: nil, on_result: nil)
|
|
421
|
+
invoke_clipboard_method(
|
|
422
|
+
"set_image",
|
|
423
|
+
args: { "data" => value },
|
|
424
|
+
timeout: timeout,
|
|
425
|
+
on_result: on_result
|
|
426
|
+
)
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
def get_clipboard_image(timeout: nil, on_result: nil)
|
|
430
|
+
invoke_clipboard_method("get_image", timeout: timeout, on_result: on_result)
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
def get_connectivity(timeout: nil, on_result: nil)
|
|
434
|
+
invoke_connectivity_method("get_connectivity", timeout: timeout, on_result: on_result)
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
def get_battery_level(timeout: nil, on_result: nil)
|
|
438
|
+
invoke_battery_method("get_battery_level", timeout: timeout, on_result: on_result)
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
def get_battery_state(timeout: nil, on_result: nil)
|
|
442
|
+
invoke_battery_method("get_battery_state", timeout: timeout, on_result: on_result)
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
def battery_save_mode?(timeout: nil, on_result: nil)
|
|
446
|
+
invoke_battery_method("is_in_battery_save_mode", timeout: timeout, on_result: on_result)
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
def get_application_cache_directory(timeout: nil, on_result: nil)
|
|
450
|
+
invoke_storage_paths("get_application_cache_directory", timeout: timeout, on_result: on_result)
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
def get_application_documents_directory(timeout: nil, on_result: nil)
|
|
454
|
+
invoke_storage_paths("get_application_documents_directory", timeout: timeout, on_result: on_result)
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
def get_application_support_directory(timeout: nil, on_result: nil)
|
|
458
|
+
invoke_storage_paths("get_application_support_directory", timeout: timeout, on_result: on_result)
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
def get_downloads_directory(timeout: nil, on_result: nil)
|
|
462
|
+
invoke_storage_paths("get_downloads_directory", timeout: timeout, on_result: on_result)
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def get_external_cache_directories(timeout: nil, on_result: nil)
|
|
466
|
+
invoke_storage_paths("get_external_cache_directories", timeout: timeout, on_result: on_result)
|
|
271
467
|
end
|
|
272
468
|
|
|
273
|
-
def
|
|
274
|
-
|
|
275
|
-
invoke(clipboard, "set", args: { "data" => value.to_s }, timeout: timeout)
|
|
469
|
+
def get_external_storage_directories(timeout: nil, on_result: nil)
|
|
470
|
+
invoke_storage_paths("get_external_storage_directories", timeout: timeout, on_result: on_result)
|
|
276
471
|
end
|
|
277
472
|
|
|
278
|
-
def
|
|
279
|
-
|
|
280
|
-
invoke(clipboard, "get", timeout: timeout)
|
|
473
|
+
def get_library_directory(timeout: nil, on_result: nil)
|
|
474
|
+
invoke_storage_paths("get_library_directory", timeout: timeout, on_result: on_result)
|
|
281
475
|
end
|
|
282
476
|
|
|
283
|
-
def
|
|
284
|
-
|
|
285
|
-
invoke(clipboard, "set_files", args: { "files" => Array(files).map(&:to_s) }, timeout: timeout)
|
|
477
|
+
def get_external_storage_directory(timeout: nil, on_result: nil)
|
|
478
|
+
invoke_storage_paths("get_external_storage_directory", timeout: timeout, on_result: on_result)
|
|
286
479
|
end
|
|
287
480
|
|
|
288
|
-
def
|
|
289
|
-
|
|
290
|
-
invoke(clipboard, "get_files", timeout: timeout)
|
|
481
|
+
def get_temporary_directory(timeout: nil, on_result: nil)
|
|
482
|
+
invoke_storage_paths("get_temporary_directory", timeout: timeout, on_result: on_result)
|
|
291
483
|
end
|
|
292
484
|
|
|
293
|
-
def
|
|
294
|
-
|
|
295
|
-
invoke(clipboard, "set_image", args: { "data" => value }, timeout: timeout)
|
|
485
|
+
def get_console_log_filename(timeout: nil, on_result: nil)
|
|
486
|
+
invoke_storage_paths("get_console_log_filename", timeout: timeout, on_result: on_result)
|
|
296
487
|
end
|
|
297
488
|
|
|
298
|
-
def
|
|
299
|
-
|
|
300
|
-
|
|
489
|
+
def share_text(
|
|
490
|
+
text:,
|
|
491
|
+
title: nil,
|
|
492
|
+
subject: nil,
|
|
493
|
+
preview_thumbnail: nil,
|
|
494
|
+
share_position_origin: nil,
|
|
495
|
+
download_fallback_enabled: true,
|
|
496
|
+
mail_to_fallback_enabled: true,
|
|
497
|
+
excluded_cupertino_activities: nil,
|
|
498
|
+
timeout: nil,
|
|
499
|
+
on_result: nil
|
|
500
|
+
)
|
|
501
|
+
share = ensure_share_service
|
|
502
|
+
invoke(
|
|
503
|
+
share,
|
|
504
|
+
"share_text",
|
|
505
|
+
args: {
|
|
506
|
+
"text" => text,
|
|
507
|
+
"title" => title,
|
|
508
|
+
"subject" => subject,
|
|
509
|
+
"preview_thumbnail" => preview_thumbnail,
|
|
510
|
+
"share_position_origin" => share_position_origin,
|
|
511
|
+
"download_fallback_enabled" => download_fallback_enabled,
|
|
512
|
+
"mail_to_fallback_enabled" => mail_to_fallback_enabled,
|
|
513
|
+
"excluded_cupertino_activities" => excluded_cupertino_activities
|
|
514
|
+
},
|
|
515
|
+
timeout: timeout,
|
|
516
|
+
on_result: on_result
|
|
517
|
+
)
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
def share_uri(
|
|
521
|
+
uri:,
|
|
522
|
+
share_position_origin: nil,
|
|
523
|
+
excluded_cupertino_activities: nil,
|
|
524
|
+
timeout: nil,
|
|
525
|
+
on_result: nil
|
|
526
|
+
)
|
|
527
|
+
share = ensure_share_service
|
|
528
|
+
invoke(
|
|
529
|
+
share,
|
|
530
|
+
"share_uri",
|
|
531
|
+
args: {
|
|
532
|
+
"uri" => uri,
|
|
533
|
+
"share_position_origin" => share_position_origin,
|
|
534
|
+
"excluded_cupertino_activities" => excluded_cupertino_activities
|
|
535
|
+
},
|
|
536
|
+
timeout: timeout,
|
|
537
|
+
on_result: on_result
|
|
538
|
+
)
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
def share_files(
|
|
542
|
+
files:,
|
|
543
|
+
text: nil,
|
|
544
|
+
title: nil,
|
|
545
|
+
subject: nil,
|
|
546
|
+
preview_thumbnail: nil,
|
|
547
|
+
share_position_origin: nil,
|
|
548
|
+
download_fallback_enabled: true,
|
|
549
|
+
mail_to_fallback_enabled: true,
|
|
550
|
+
excluded_cupertino_activities: nil,
|
|
551
|
+
timeout: nil,
|
|
552
|
+
on_result: nil
|
|
553
|
+
)
|
|
554
|
+
share = ensure_share_service
|
|
555
|
+
invoke(
|
|
556
|
+
share,
|
|
557
|
+
"share_files",
|
|
558
|
+
args: {
|
|
559
|
+
"files" => files,
|
|
560
|
+
"text" => text,
|
|
561
|
+
"title" => title,
|
|
562
|
+
"subject" => subject,
|
|
563
|
+
"preview_thumbnail" => preview_thumbnail,
|
|
564
|
+
"share_position_origin" => share_position_origin,
|
|
565
|
+
"download_fallback_enabled" => download_fallback_enabled,
|
|
566
|
+
"mail_to_fallback_enabled" => mail_to_fallback_enabled,
|
|
567
|
+
"excluded_cupertino_activities" => excluded_cupertino_activities
|
|
568
|
+
},
|
|
569
|
+
timeout: timeout,
|
|
570
|
+
on_result: on_result
|
|
571
|
+
)
|
|
301
572
|
end
|
|
302
573
|
|
|
303
574
|
def handle_invoke_method_result(payload)
|
|
304
575
|
call_id = payload["call_id"].to_s
|
|
305
576
|
waiter = @invoke_waiters_mutex.synchronize { @invoke_waiters[call_id] }
|
|
306
|
-
|
|
577
|
+
if waiter
|
|
578
|
+
waiter << payload
|
|
579
|
+
return true
|
|
580
|
+
end
|
|
307
581
|
|
|
308
|
-
|
|
582
|
+
callback = @invoke_waiters_mutex.synchronize { @invoke_callbacks.delete(call_id) }
|
|
583
|
+
return false unless callback
|
|
584
|
+
|
|
585
|
+
callback.call(payload["result"], payload["error"])
|
|
309
586
|
true
|
|
587
|
+
rescue StandardError => e
|
|
588
|
+
Kernel.warn("invoke callback error: #{e.class}: #{e.message}")
|
|
589
|
+
false
|
|
310
590
|
end
|
|
311
591
|
|
|
312
592
|
def pop_dialog
|
|
@@ -333,9 +613,16 @@ module Ruflet
|
|
|
333
613
|
|
|
334
614
|
control = resolve_control(control_or_id)
|
|
335
615
|
return self unless control
|
|
616
|
+
wire_id = control.wire_id
|
|
617
|
+
if wire_id.nil?
|
|
618
|
+
# Events can race with navigation/disposal; never emit patch_control with nil id.
|
|
619
|
+
refresh_control_indexes!
|
|
620
|
+
wire_id = control.wire_id
|
|
621
|
+
end
|
|
622
|
+
return self if wire_id.nil?
|
|
336
623
|
|
|
337
624
|
patch = normalize_props(props)
|
|
338
|
-
if
|
|
625
|
+
if text_maps_to_content?(control, patch)
|
|
339
626
|
patch["content"] = patch.delete("text")
|
|
340
627
|
end
|
|
341
628
|
|
|
@@ -351,7 +638,7 @@ module Ruflet
|
|
|
351
638
|
patch_ops = patch.map { |k, v| [0, 0, k, serialize_patch_value(v)] }
|
|
352
639
|
|
|
353
640
|
send_message(Protocol::ACTIONS[:patch_control], {
|
|
354
|
-
"id" =>
|
|
641
|
+
"id" => wire_id,
|
|
355
642
|
"patch" => [[0], *patch_ops]
|
|
356
643
|
})
|
|
357
644
|
|
|
@@ -400,8 +687,7 @@ module Ruflet
|
|
|
400
687
|
prop_name = method_name.delete_suffix("=")
|
|
401
688
|
|
|
402
689
|
if method_name.end_with?("=")
|
|
403
|
-
if
|
|
404
|
-
Kernel.warn("[DEPRECATION] `page.#{prop_name}(...)` is no longer supported.")
|
|
690
|
+
if widget_helper_method?(prop_name)
|
|
405
691
|
raise NoMethodError, "Use `#{prop_name}(...)` as a free widget helper, then attach with `page.add(...)`."
|
|
406
692
|
end
|
|
407
693
|
assign_split_prop(prop_name, normalize_value(prop_name, args.first))
|
|
@@ -414,8 +700,7 @@ module Ruflet
|
|
|
414
700
|
return instance_variable_get("@#{method_name}") if DIALOG_PROP_KEYS.include?(method_name)
|
|
415
701
|
end
|
|
416
702
|
|
|
417
|
-
if
|
|
418
|
-
Kernel.warn("[DEPRECATION] `page.#{name}(...)` is no longer supported.")
|
|
703
|
+
if widget_helper_method?(name)
|
|
419
704
|
raise NoMethodError, "Use `#{name}(...)` as a free widget helper, then attach with `page.add(...)`."
|
|
420
705
|
end
|
|
421
706
|
|
|
@@ -425,8 +710,8 @@ module Ruflet
|
|
|
425
710
|
def respond_to_missing?(name, include_private = false)
|
|
426
711
|
method_name = name.to_s
|
|
427
712
|
prop_name = method_name.delete_suffix("=")
|
|
428
|
-
|
|
429
|
-
|
|
713
|
+
widget_helper_method?(name) ||
|
|
714
|
+
widget_helper_method?(prop_name) ||
|
|
430
715
|
method_name.end_with?("=") ||
|
|
431
716
|
@page_props.key?(method_name) ||
|
|
432
717
|
@view_props.key?(method_name) ||
|
|
@@ -437,15 +722,21 @@ module Ruflet
|
|
|
437
722
|
private
|
|
438
723
|
|
|
439
724
|
def invoke_and_wait(control_or_id, method_name, args: nil, timeout: 10)
|
|
440
|
-
|
|
441
|
-
|
|
725
|
+
control_id =
|
|
726
|
+
if page_control_target?(control_or_id)
|
|
727
|
+
1
|
|
728
|
+
else
|
|
729
|
+
control = resolve_control(control_or_id)
|
|
730
|
+
return nil unless control
|
|
731
|
+
control.wire_id
|
|
732
|
+
end
|
|
442
733
|
|
|
443
734
|
call_id = "call_#{Ruflet::Control.generate_id}"
|
|
444
735
|
waiter = Queue.new
|
|
445
736
|
@invoke_waiters_mutex.synchronize { @invoke_waiters[call_id] = waiter }
|
|
446
737
|
|
|
447
738
|
send_message(Protocol::ACTIONS[:invoke_control_method], {
|
|
448
|
-
"control_id" =>
|
|
739
|
+
"control_id" => control_id,
|
|
449
740
|
"call_id" => call_id,
|
|
450
741
|
"name" => method_name.to_s,
|
|
451
742
|
"args" => args,
|
|
@@ -463,6 +754,14 @@ module Ruflet
|
|
|
463
754
|
|
|
464
755
|
def build_widget(type, **props, &block) = WidgetBuilder.new.control(type, **props, &block)
|
|
465
756
|
|
|
757
|
+
def widget_helper_method?(name)
|
|
758
|
+
WIDGET_HELPER_METHODS.include?(name.to_s)
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
def text_maps_to_content?(control, patch)
|
|
762
|
+
patch.key?("text") && control.type.end_with?("button")
|
|
763
|
+
end
|
|
764
|
+
|
|
466
765
|
def split_props(props)
|
|
467
766
|
props.each do |k, v|
|
|
468
767
|
assign_split_prop(k, v)
|
|
@@ -709,7 +1008,15 @@ module Ruflet
|
|
|
709
1008
|
end
|
|
710
1009
|
|
|
711
1010
|
def build_page_patch_ops
|
|
712
|
-
@page_props.
|
|
1011
|
+
@page_props.filter_map do |k, v|
|
|
1012
|
+
# Keep internal containers stable after initial mount.
|
|
1013
|
+
# Re-sending them as full objects can replace Control instances with
|
|
1014
|
+
# same IDs and detach service invoke listeners on the Flutter side.
|
|
1015
|
+
next nil if k == "_overlay" && @overlay_container.wire_id
|
|
1016
|
+
next nil if k == "_dialogs" && @dialogs_container.wire_id
|
|
1017
|
+
|
|
1018
|
+
[0, 0, k, serialize_patch_value(v)]
|
|
1019
|
+
end
|
|
713
1020
|
end
|
|
714
1021
|
|
|
715
1022
|
def resolve_icon_codepoint(value)
|
|
@@ -720,22 +1027,196 @@ module Ruflet
|
|
|
720
1027
|
codepoint
|
|
721
1028
|
end
|
|
722
1029
|
|
|
723
|
-
def ensure_url_launcher_service
|
|
724
|
-
launcher = services.find { |service| service.is_a?(Control) && service.type == "url_launcher" }
|
|
725
|
-
return launcher if launcher
|
|
726
|
-
|
|
727
|
-
launcher = build_widget(:url_launcher)
|
|
728
|
-
add_service(launcher)
|
|
729
|
-
launcher
|
|
730
|
-
end
|
|
731
|
-
|
|
732
1030
|
def ensure_clipboard_service
|
|
733
1031
|
clipboard = services.find { |service| service.is_a?(Control) && service.type == "clipboard" }
|
|
734
|
-
return clipboard if clipboard
|
|
1032
|
+
return [clipboard, false] if clipboard
|
|
735
1033
|
|
|
736
1034
|
clipboard = build_widget(:clipboard)
|
|
737
1035
|
add_service(clipboard)
|
|
738
|
-
clipboard
|
|
1036
|
+
[clipboard, true]
|
|
1037
|
+
end
|
|
1038
|
+
|
|
1039
|
+
def invoke_clipboard_method(method_name, args: nil, timeout:, on_result:)
|
|
1040
|
+
clipboard, created = ensure_clipboard_service
|
|
1041
|
+
send_view_patch if created
|
|
1042
|
+
sleep(0.05) if created
|
|
1043
|
+
invoke(
|
|
1044
|
+
clipboard,
|
|
1045
|
+
method_name,
|
|
1046
|
+
args: args,
|
|
1047
|
+
timeout: timeout,
|
|
1048
|
+
on_result: lambda { |result, error|
|
|
1049
|
+
message = error.to_s
|
|
1050
|
+
if message.include?("inexistent control")
|
|
1051
|
+
remove_service(clipboard)
|
|
1052
|
+
fresh_clipboard, = ensure_clipboard_service
|
|
1053
|
+
sleep(0.08)
|
|
1054
|
+
invoke(
|
|
1055
|
+
fresh_clipboard,
|
|
1056
|
+
method_name,
|
|
1057
|
+
args: args,
|
|
1058
|
+
timeout: timeout,
|
|
1059
|
+
on_result: on_result
|
|
1060
|
+
)
|
|
1061
|
+
else
|
|
1062
|
+
on_result&.call(result, error)
|
|
1063
|
+
end
|
|
1064
|
+
}
|
|
1065
|
+
)
|
|
1066
|
+
rescue StandardError => e
|
|
1067
|
+
on_result&.call(nil, e.message)
|
|
1068
|
+
end
|
|
1069
|
+
|
|
1070
|
+
def ensure_url_launcher_service
|
|
1071
|
+
url_launcher = services.find { |service| service.is_a?(Control) && %w[urllauncher url_launcher].include?(service.type) }
|
|
1072
|
+
return url_launcher if url_launcher
|
|
1073
|
+
|
|
1074
|
+
url_launcher = build_widget(:url_launcher)
|
|
1075
|
+
add_service(url_launcher)
|
|
1076
|
+
url_launcher
|
|
1077
|
+
end
|
|
1078
|
+
|
|
1079
|
+
def ensure_connectivity_service
|
|
1080
|
+
connectivity = services.find { |service| service.is_a?(Control) && service.type == "connectivity" }
|
|
1081
|
+
return [connectivity, false] if connectivity
|
|
1082
|
+
|
|
1083
|
+
connectivity = build_widget(:connectivity)
|
|
1084
|
+
add_service(connectivity)
|
|
1085
|
+
[connectivity, true]
|
|
1086
|
+
end
|
|
1087
|
+
|
|
1088
|
+
def invoke_connectivity_method(method_name, timeout:, on_result:)
|
|
1089
|
+
connectivity, created = ensure_connectivity_service
|
|
1090
|
+
send_view_patch if created
|
|
1091
|
+
sleep(0.05) if created
|
|
1092
|
+
invoke(
|
|
1093
|
+
connectivity,
|
|
1094
|
+
method_name,
|
|
1095
|
+
timeout: timeout,
|
|
1096
|
+
on_result: lambda { |result, error|
|
|
1097
|
+
message = error.to_s
|
|
1098
|
+
if message.include?("inexistent control")
|
|
1099
|
+
remove_service(connectivity)
|
|
1100
|
+
fresh_connectivity, = ensure_connectivity_service
|
|
1101
|
+
sleep(0.08)
|
|
1102
|
+
invoke(
|
|
1103
|
+
fresh_connectivity,
|
|
1104
|
+
method_name,
|
|
1105
|
+
timeout: timeout,
|
|
1106
|
+
on_result: on_result
|
|
1107
|
+
)
|
|
1108
|
+
else
|
|
1109
|
+
on_result&.call(result, error)
|
|
1110
|
+
end
|
|
1111
|
+
}
|
|
1112
|
+
)
|
|
1113
|
+
rescue StandardError => e
|
|
1114
|
+
on_result&.call(nil, e.message)
|
|
1115
|
+
end
|
|
1116
|
+
|
|
1117
|
+
def ensure_battery_service
|
|
1118
|
+
battery = services.find { |service| service.is_a?(Control) && service.type == "battery" }
|
|
1119
|
+
return [battery, false] if battery
|
|
1120
|
+
|
|
1121
|
+
battery = build_widget(:battery)
|
|
1122
|
+
add_service(battery)
|
|
1123
|
+
[battery, true]
|
|
1124
|
+
end
|
|
1125
|
+
|
|
1126
|
+
def ensure_share_service
|
|
1127
|
+
share = services.find { |service| service.is_a?(Control) && service.type == "share" }
|
|
1128
|
+
return share if share
|
|
1129
|
+
|
|
1130
|
+
share = build_widget(:share)
|
|
1131
|
+
add_service(share)
|
|
1132
|
+
share
|
|
1133
|
+
end
|
|
1134
|
+
|
|
1135
|
+
def invoke_battery_method(method_name, timeout:, on_result:)
|
|
1136
|
+
battery, created = ensure_battery_service
|
|
1137
|
+
send_view_patch if created
|
|
1138
|
+
sleep(0.05) if created
|
|
1139
|
+
invoke(
|
|
1140
|
+
battery,
|
|
1141
|
+
method_name,
|
|
1142
|
+
timeout: timeout,
|
|
1143
|
+
on_result: lambda { |result, error|
|
|
1144
|
+
message = error.to_s
|
|
1145
|
+
if message.include?("inexistent control")
|
|
1146
|
+
remove_service(battery)
|
|
1147
|
+
fresh_battery, = ensure_battery_service
|
|
1148
|
+
sleep(0.08)
|
|
1149
|
+
invoke(
|
|
1150
|
+
fresh_battery,
|
|
1151
|
+
method_name,
|
|
1152
|
+
timeout: timeout,
|
|
1153
|
+
on_result: on_result
|
|
1154
|
+
)
|
|
1155
|
+
else
|
|
1156
|
+
on_result&.call(result, error)
|
|
1157
|
+
end
|
|
1158
|
+
}
|
|
1159
|
+
)
|
|
1160
|
+
rescue StandardError => e
|
|
1161
|
+
on_result&.call(nil, e.message)
|
|
1162
|
+
end
|
|
1163
|
+
|
|
1164
|
+
def ensure_storage_paths_service
|
|
1165
|
+
storage_paths = services.find do |service|
|
|
1166
|
+
service.is_a?(Control) && %w[storage_paths storagepaths].include?(service.type.to_s)
|
|
1167
|
+
end
|
|
1168
|
+
return [storage_paths, false] if storage_paths
|
|
1169
|
+
|
|
1170
|
+
storage_paths = build_widget(:storage_paths)
|
|
1171
|
+
add_service(storage_paths)
|
|
1172
|
+
[storage_paths, true]
|
|
1173
|
+
end
|
|
1174
|
+
|
|
1175
|
+
def invoke_storage_paths(method_name, timeout:, on_result:)
|
|
1176
|
+
storage_paths, created = ensure_storage_paths_service
|
|
1177
|
+
send_view_patch if created
|
|
1178
|
+
sleep(0.05) if created
|
|
1179
|
+
invoke(
|
|
1180
|
+
storage_paths,
|
|
1181
|
+
method_name,
|
|
1182
|
+
timeout: timeout,
|
|
1183
|
+
on_result: lambda { |result, error|
|
|
1184
|
+
message = error.to_s
|
|
1185
|
+
if message.include?("inexistent control")
|
|
1186
|
+
remove_service(storage_paths)
|
|
1187
|
+
fresh_storage_paths, = ensure_storage_paths_service
|
|
1188
|
+
sleep(0.08)
|
|
1189
|
+
invoke(
|
|
1190
|
+
fresh_storage_paths,
|
|
1191
|
+
method_name,
|
|
1192
|
+
timeout: timeout,
|
|
1193
|
+
on_result: on_result
|
|
1194
|
+
)
|
|
1195
|
+
else
|
|
1196
|
+
on_result&.call(result, error)
|
|
1197
|
+
end
|
|
1198
|
+
}
|
|
1199
|
+
)
|
|
1200
|
+
rescue StandardError => e
|
|
1201
|
+
on_result&.call(nil, e.message)
|
|
1202
|
+
end
|
|
1203
|
+
|
|
1204
|
+
def invoke_file_picker(method_name, args, timeout:, on_result:)
|
|
1205
|
+
picker = build_widget(:file_picker)
|
|
1206
|
+
add_service(picker)
|
|
1207
|
+
invoke(
|
|
1208
|
+
picker,
|
|
1209
|
+
method_name,
|
|
1210
|
+
args: args,
|
|
1211
|
+
timeout: timeout,
|
|
1212
|
+
on_result: lambda { |result, error|
|
|
1213
|
+
remove_service(picker)
|
|
1214
|
+
on_result&.call(result, error)
|
|
1215
|
+
}
|
|
1216
|
+
)
|
|
1217
|
+
rescue StandardError => e
|
|
1218
|
+
remove_service(picker) if picker
|
|
1219
|
+
on_result&.call(nil, e.message)
|
|
739
1220
|
end
|
|
740
1221
|
end
|
|
741
1222
|
end
|