From 4418ee0e4ba03944c4a04b4a925e168c5cd7a92e Mon Sep 17 00:00:00 2001 From: Tsuki Date: Sat, 2 Mar 2024 00:19:08 +0800 Subject: [PATCH] add relm4 and target build --- Cargo.lock | 6 - Cargo.toml | 5 +- Relm4-0.6.2/CHANGES.md | 558 +++++ Relm4-0.6.2/Cargo.toml | 26 + Relm4-0.6.2/LICENSE-APACHE | 176 ++ Relm4-0.6.2/LICENSE-MIT | 23 + Relm4-0.6.2/README.md | 191 ++ Relm4-0.6.2/publish.sh | 17 + Relm4-0.6.2/relm4-components/Cargo.toml | 38 + Relm4-0.6.2/relm4-components/README.md | 6 + .../relm4-components/examples/.gitignore | 1 + .../relm4-components/examples/alert.rs | 148 ++ .../relm4-components/examples/file_dialogs.rs | 176 ++ .../relm4-components/examples/open_button.rs | 69 + .../relm4-components/examples/web_image.rs | 84 + Relm4-0.6.2/relm4-components/src/alert.rs | 129 + Relm4-0.6.2/relm4-components/src/lib.rs | 43 + .../src/open_button/factory.rs | 42 + .../relm4-components/src/open_button/mod.rs | 192 ++ .../relm4-components/src/open_dialog.rs | 181 ++ .../relm4-components/src/save_dialog.rs | 136 + .../relm4-components/src/simple_combo_box.rs | 117 + Relm4-0.6.2/relm4-components/src/web_image.rs | 143 ++ Relm4-0.6.2/relm4-macros/Cargo.toml | 43 + Relm4-0.6.2/relm4-macros/README.md | 6 + .../relm4-macros/src/additional_fields.rs | 24 + Relm4-0.6.2/relm4-macros/src/args.rs | 49 + Relm4-0.6.2/relm4-macros/src/attrs.rs | 77 + Relm4-0.6.2/relm4-macros/src/component/mod.rs | 192 ++ Relm4-0.6.2/relm4-macros/src/factory/mod.rs | 216 ++ Relm4-0.6.2/relm4-macros/src/lib.rs | 648 +++++ Relm4-0.6.2/relm4-macros/src/menu/gen.rs | 136 + Relm4-0.6.2/relm4-macros/src/menu/mod.rs | 49 + Relm4-0.6.2/relm4-macros/src/menu/parse.rs | 103 + Relm4-0.6.2/relm4-macros/src/token_streams.rs | 147 ++ Relm4-0.6.2/relm4-macros/src/util.rs | 135 + Relm4-0.6.2/relm4-macros/src/view.rs | 35 + Relm4-0.6.2/relm4-macros/src/visitors.rs | 479 ++++ .../relm4-macros/src/widget_template.rs | 95 + .../src/widgets/gen/assign/assign_property.rs | 135 + .../widgets/gen/assign/conditional_widget.rs | 57 + .../src/widgets/gen/assign/mod.rs | 37 + .../src/widgets/gen/assign/properties.rs | 13 + .../src/widgets/gen/assign/signal_handler.rs | 77 + .../src/widgets/gen/assign/widgets.rs | 100 + .../src/widgets/gen/conditional_init.rs | 207 ++ .../src/widgets/gen/destructure_fields.rs | 86 + .../relm4-macros/src/widgets/gen/error.rs | 77 + .../relm4-macros/src/widgets/gen/init.rs | 118 + .../relm4-macros/src/widgets/gen/mod.rs | 42 + .../src/widgets/gen/return_fields.rs | 80 + .../src/widgets/gen/struct_fields.rs | 117 + .../src/widgets/gen/update_view.rs | 231 ++ .../src/widgets/gen/util/has_struct_field.rs | 28 + .../src/widgets/gen/util/if_branch.rs | 33 + .../relm4-macros/src/widgets/gen/util/mod.rs | 5 + .../src/widgets/gen/util/property_name.rs | 37 + .../src/widgets/gen/util/widget.rs | 14 + .../src/widgets/gen/util/widget_func.rs | 112 + Relm4-0.6.2/relm4-macros/src/widgets/mod.rs | 218 ++ .../src/widgets/parse/assign_property.rs | 190 ++ .../src/widgets/parse/attributes.rs | 214 ++ .../src/widgets/parse/conditional_branches.rs | 31 + .../src/widgets/parse/conditional_widget.rs | 134 + .../src/widgets/parse/if_branch.rs | 43 + .../src/widgets/parse/if_condition.rs | 21 + .../src/widgets/parse/match_arm.rs | 45 + .../relm4-macros/src/widgets/parse/mod.rs | 17 + .../src/widgets/parse/properties.rs | 143 ++ .../src/widgets/parse/property.rs | 142 ++ .../src/widgets/parse/property_name.rs | 14 + .../src/widgets/parse/returned_widget.rs | 50 + .../src/widgets/parse/signal_handler.rs | 37 + .../src/widgets/parse/top_level_widget.rs | 66 + .../src/widgets/parse/view_widgets.rs | 39 + .../relm4-macros/src/widgets/parse/widget.rs | 285 +++ .../src/widgets/parse/widget_func.rs | 65 + .../src/widgets/parse/widget_func_method.rs | 25 + .../relm4-macros/src/widgets/parse_util.rs | 162 ++ .../relm4-macros/src/widgets/span/attr.rs | 25 + .../relm4-macros/src/widgets/span/mod.rs | 6 + .../src/widgets/span/property_name.rs | 14 + .../src/widgets/span/widget_func.rs | 10 + .../src/widgets/span/widget_func_method.rs | 23 + Relm4-0.6.2/relm4-macros/tests/builder.rs | 40 + .../relm4-macros/tests/codegen_order.rs | 34 + .../relm4-macros/tests/complex_func_path.rs | 46 + .../tests/component_missing_widgets.rs | 28 + Relm4-0.6.2/relm4-macros/tests/iife.rs | 39 + .../relm4-macros/tests/local_ref_container.rs | 44 + .../tests/pub_widget_templates.rs | 56 + .../relm4-macros/tests/redundant_clone.rs | 39 + .../relm4-macros/tests/returned_widgets.rs | 26 + Relm4-0.6.2/relm4-macros/tests/simple.rs | 77 + Relm4-0.6.2/relm4-macros/tests/skip_init.rs | 80 + .../tests/ui/compile-fail/bad_impl.rs | 32 + .../tests/ui/compile-fail/bad_impl.stderr | 29 + .../tests/ui/compile-fail/component-empty.rs | 10 + .../ui/compile-fail/component-empty.stderr | 20 + .../tests/ui/compile-fail/dead_code.rs | 34 + .../tests/ui/compile-fail/dead_code.stderr | 5 + .../compile-fail/factory-component-empty.rs | 11 + .../factory-component-empty.stderr | 24 + .../tests/ui/compile-fail/init-identifers.rs | 51 + .../ui/compile-fail/init-identifers.stderr | 19 + .../tests/ui/compile-fail/missing-view.rs | 18 + .../tests/ui/compile-fail/missing-view.stderr | 20 + .../tests/ui/compile-fail/no-view-output.rs | 29 + .../ui/compile-fail/no-view-output.stderr | 11 + .../tests/ui/compile-fail/pre-view-return.rs | 37 + .../ui/compile-fail/pre-view-return.stderr | 23 + .../relm4-macros/tests/widget_template.rs | 119 + .../tests/widget_template_nested_child.rs | 81 + Relm4-0.6.2/relm4/Cargo.toml | 84 + Relm4-0.6.2/relm4/benches/stress_test.rs | 120 + Relm4-0.6.2/relm4/examples | 1 + Relm4-0.6.2/relm4/src/actions/mod.rs | 276 +++ Relm4-0.6.2/relm4/src/actions/traits.rs | 84 + Relm4-0.6.2/relm4/src/app.rs | 189 ++ Relm4-0.6.2/relm4/src/binding/bindings.rs | 101 + Relm4-0.6.2/relm4/src/binding/mod.rs | 118 + Relm4-0.6.2/relm4/src/binding/widgets.rs | 59 + Relm4-0.6.2/relm4/src/channel/component.rs | 289 +++ Relm4-0.6.2/relm4/src/channel/mod.rs | 109 + .../relm4/src/channel/shutdown/attached.rs | 53 + Relm4-0.6.2/relm4/src/channel/shutdown/mod.rs | 22 + .../relm4/src/channel/shutdown/receiver.rs | 42 + .../relm4/src/channel/shutdown/sender.rs | 23 + .../relm4/src/component/async/builder.rs | 277 +++ .../relm4/src/component/async/connector.rs | 119 + .../relm4/src/component/async/controller.rs | 68 + Relm4-0.6.2/relm4/src/component/async/mod.rs | 19 + .../relm4/src/component/async/traits.rs | 277 +++ .../relm4/src/component/message_broker.rs | 90 + Relm4-0.6.2/relm4/src/component/mod.rs | 29 + .../relm4/src/component/sync/builder.rs | 298 +++ .../relm4/src/component/sync/connector.rs | 137 ++ .../relm4/src/component/sync/controller.rs | 89 + Relm4-0.6.2/relm4/src/component/sync/mod.rs | 32 + .../relm4/src/component/sync/state_watcher.rs | 48 + .../relm4/src/component/sync/stream.rs | 98 + .../relm4/src/component/sync/traits.rs | 237 ++ Relm4-0.6.2/relm4/src/component/worker.rs | 282 +++ Relm4-0.6.2/relm4/src/drawing.rs | 160 ++ Relm4-0.6.2/relm4/src/extensions/container.rs | 70 + .../relm4/src/extensions/iter_children.rs | 144 ++ Relm4-0.6.2/relm4/src/extensions/mod.rs | 200 ++ .../relm4/src/extensions/object_ext.rs | 47 + Relm4-0.6.2/relm4/src/extensions/remove.rs | 147 ++ Relm4-0.6.2/relm4/src/extensions/set_child.rs | 79 + Relm4-0.6.2/relm4/src/extensions/tests.rs | 163 ++ .../relm4/src/extensions/widget_ext.rs | 97 + .../relm4/src/factory/async/builder.rs | 229 ++ .../src/factory/async/collections/mod.rs | 20 + .../factory/async/collections/vec_deque.rs | 615 +++++ .../src/factory/async/component_storage.rs | 89 + .../relm4/src/factory/async/future_data.rs | 50 + Relm4-0.6.2/relm4/src/factory/async/handle.rs | 31 + Relm4-0.6.2/relm4/src/factory/async/mod.rs | 13 + Relm4-0.6.2/relm4/src/factory/async/traits.rs | 126 + Relm4-0.6.2/relm4/src/factory/data_guard.rs | 249 ++ .../relm4/src/factory/dynamic_index.rs | 113 + Relm4-0.6.2/relm4/src/factory/mod.rs | 26 + Relm4-0.6.2/relm4/src/factory/positions.rs | 24 + Relm4-0.6.2/relm4/src/factory/sync/builder.rs | 161 ++ .../src/factory/sync/collections/hashmap.rs | 267 ++ .../relm4/src/factory/sync/collections/mod.rs | 22 + .../src/factory/sync/collections/vec_deque.rs | 643 +++++ .../src/factory/sync/component_storage.rs | 81 + Relm4-0.6.2/relm4/src/factory/sync/handle.rs | 28 + Relm4-0.6.2/relm4/src/factory/sync/mod.rs | 11 + Relm4-0.6.2/relm4/src/factory/sync/traits.rs | 122 + Relm4-0.6.2/relm4/src/factory/widgets/gtk.rs | 372 +++ .../relm4/src/factory/widgets/libadwaita.rs | 300 +++ .../relm4/src/factory/widgets/libpanel.rs | 43 + Relm4-0.6.2/relm4/src/factory/widgets/mod.rs | 15 + .../relm4/src/factory/widgets/tests.rs | 281 +++ .../relm4/src/factory/widgets/traits.rs | 98 + Relm4-0.6.2/relm4/src/late_initialization.rs | 29 + Relm4-0.6.2/relm4/src/lib.rs | 240 ++ Relm4-0.6.2/relm4/src/loading_widgets.rs | 114 + Relm4-0.6.2/relm4/src/prelude.rs | 19 + Relm4-0.6.2/relm4/src/runtime_util.rs | 218 ++ .../safe_settings_and_actions/extensions.rs | 418 ++++ .../src/safe_settings_and_actions/mod.rs | 354 +++ Relm4-0.6.2/relm4/src/shared_state/mod.rs | 9 + Relm4-0.6.2/relm4/src/shared_state/reducer.rs | 264 ++ Relm4-0.6.2/relm4/src/shared_state/state.rs | 343 +++ .../relm4/src/typed_list_view/column_view.rs | 404 +++ Relm4-0.6.2/relm4/src/typed_list_view/mod.rs | 444 ++++ .../src/typed_list_view/relm_selection_ext.rs | 23 + Relm4-0.6.2/relm4/tests/drop_after_quit.rs | 49 + .../relm4/tests/shutdown_after_quit.rs | 47 + Relm4-0.6.2/rustfmt.toml | 18 + libadwaita-0.4.4/.cargo-ok | 1 + libadwaita-0.4.4/.cargo_vcs_info.json | 6 + libadwaita-0.4.4/Cargo.lock | 803 ++++++ libadwaita-0.4.4/Cargo.toml | 98 + libadwaita-0.4.4/Cargo.toml.orig | 80 + libadwaita-0.4.4/Gir.toml | 345 +++ libadwaita-0.4.4/LICENCE | 18 + libadwaita-0.4.4/README.md | 10 + libadwaita-0.4.4/src/application.rs | 53 + libadwaita-0.4.4/src/auto/about_window.rs | 1543 ++++++++++++ libadwaita-0.4.4/src/auto/action_row.rs | 747 ++++++ libadwaita-0.4.4/src/auto/animation.rs | 301 +++ libadwaita-0.4.4/src/auto/animation_target.rs | 25 + libadwaita-0.4.4/src/auto/application.rs | 161 ++ .../src/auto/application_window.rs | 548 +++++ libadwaita-0.4.4/src/auto/avatar.rs | 488 ++++ libadwaita-0.4.4/src/auto/banner.rs | 482 ++++ libadwaita-0.4.4/src/auto/bin.rs | 313 +++ libadwaita-0.4.4/src/auto/breakpoint.rs | 136 + libadwaita-0.4.4/src/auto/breakpoint_bin.rs | 382 +++ .../src/auto/breakpoint_condition.rs | 107 + libadwaita-0.4.4/src/auto/button_content.rs | 446 ++++ .../src/auto/callback_animation_target.rs | 52 + libadwaita-0.4.4/src/auto/carousel.rs | 725 ++++++ .../src/auto/carousel_indicator_dots.rs | 312 +++ .../src/auto/carousel_indicator_lines.rs | 316 +++ libadwaita-0.4.4/src/auto/clamp.rs | 449 ++++ libadwaita-0.4.4/src/auto/clamp_layout.rs | 225 ++ libadwaita-0.4.4/src/auto/clamp_scrollable.rs | 482 ++++ libadwaita-0.4.4/src/auto/combo_row.rs | 735 ++++++ libadwaita-0.4.4/src/auto/entry_row.rs | 858 +++++++ libadwaita-0.4.4/src/auto/enum_list_item.rs | 116 + libadwaita-0.4.4/src/auto/enum_list_model.rs | 45 + libadwaita-0.4.4/src/auto/enums.rs | 2187 +++++++++++++++++ libadwaita-0.4.4/src/auto/expander_row.rs | 832 +++++++ libadwaita-0.4.4/src/auto/flags.rs | 148 ++ libadwaita-0.4.4/src/auto/flap.rs | 931 +++++++ libadwaita-0.4.4/src/auto/functions.rs | 57 + libadwaita-0.4.4/src/auto/header_bar.rs | 647 +++++ libadwaita-0.4.4/src/auto/leaflet.rs | 950 +++++++ libadwaita-0.4.4/src/auto/leaflet_page.rs | 106 + libadwaita-0.4.4/src/auto/message_dialog.rs | 1025 ++++++++ libadwaita-0.4.4/src/auto/mod.rs | 426 ++++ libadwaita-0.4.4/src/auto/navigation_page.rs | 644 +++++ .../src/auto/navigation_split_view.rs | 695 ++++++ libadwaita-0.4.4/src/auto/navigation_view.rs | 593 +++++ .../src/auto/overlay_split_view.rs | 915 +++++++ .../src/auto/password_entry_row.rs | 405 +++ .../src/auto/preferences_group.rs | 476 ++++ libadwaita-0.4.4/src/auto/preferences_page.rs | 570 +++++ libadwaita-0.4.4/src/auto/preferences_row.rs | 554 +++++ .../src/auto/preferences_window.rs | 763 ++++++ .../src/auto/property_animation_target.rs | 73 + libadwaita-0.4.4/src/auto/spin_row.rs | 864 +++++++ libadwaita-0.4.4/src/auto/split_button.rs | 757 ++++++ libadwaita-0.4.4/src/auto/spring_animation.rs | 451 ++++ libadwaita-0.4.4/src/auto/spring_params.rs | 55 + libadwaita-0.4.4/src/auto/squeezer.rs | 747 ++++++ libadwaita-0.4.4/src/auto/squeezer_page.rs | 70 + libadwaita-0.4.4/src/auto/status_page.rs | 477 ++++ libadwaita-0.4.4/src/auto/style_manager.rs | 197 ++ libadwaita-0.4.4/src/auto/swipe_tracker.rs | 502 ++++ libadwaita-0.4.4/src/auto/swipeable.rs | 98 + libadwaita-0.4.4/src/auto/switch_row.rs | 408 +++ libadwaita-0.4.4/src/auto/tab_bar.rs | 733 ++++++ libadwaita-0.4.4/src/auto/tab_button.rs | 379 +++ libadwaita-0.4.4/src/auto/tab_overview.rs | 967 ++++++++ libadwaita-0.4.4/src/auto/tab_page.rs | 599 +++++ libadwaita-0.4.4/src/auto/tab_view.rs | 1009 ++++++++ libadwaita-0.4.4/src/auto/timed_animation.rs | 409 +++ libadwaita-0.4.4/src/auto/toast.rs | 452 ++++ libadwaita-0.4.4/src/auto/toast_overlay.rs | 87 + libadwaita-0.4.4/src/auto/toolbar_view.rs | 726 ++++++ libadwaita-0.4.4/src/auto/versions.txt | 3 + libadwaita-0.4.4/src/auto/view_stack.rs | 559 +++++ libadwaita-0.4.4/src/auto/view_stack_page.rs | 307 +++ libadwaita-0.4.4/src/auto/view_switcher.rs | 341 +++ .../src/auto/view_switcher_bar.rs | 341 +++ .../src/auto/view_switcher_title.rs | 489 ++++ libadwaita-0.4.4/src/auto/window.rs | 530 ++++ libadwaita-0.4.4/src/auto/window_title.rs | 346 +++ libadwaita-0.4.4/src/breakpoint.rs | 35 + libadwaita-0.4.4/src/builders.rs | 3 + libadwaita-0.4.4/src/carousel.rs | 13 + libadwaita-0.4.4/src/functions.rs | 11 + libadwaita-0.4.4/src/lib.rs | 138 ++ libadwaita-0.4.4/src/message_dialog.rs | 113 + libadwaita-0.4.4/src/prelude.rs | 8 + libadwaita-0.4.4/src/spin_row.rs | 42 + libadwaita-0.4.4/src/subclass/action_row.rs | 44 + libadwaita-0.4.4/src/subclass/application.rs | 7 + .../src/subclass/application_window.rs | 6 + libadwaita-0.4.4/src/subclass/bin.rs | 7 + .../src/subclass/breakpoint_bin.rs | 7 + libadwaita-0.4.4/src/subclass/combo_row.rs | 7 + libadwaita-0.4.4/src/subclass/entry_row.rs | 8 + libadwaita-0.4.4/src/subclass/expander_row.rs | 7 + .../src/subclass/message_dialog.rs | 53 + libadwaita-0.4.4/src/subclass/mod.rs | 54 + .../src/subclass/navigation_page.rs | 136 + .../src/subclass/preferences_group.rs | 7 + .../src/subclass/preferences_page.rs | 7 + .../src/subclass/preferences_row.rs | 7 + .../src/subclass/preferences_window.rs | 7 + libadwaita-0.4.4/src/subclass/spin_row.rs | 8 + libadwaita-0.4.4/src/subclass/swipeable.rs | 200 ++ libadwaita-0.4.4/src/subclass/window.rs | 6 + libadwaita-0.4.4/src/tab_bar.rs | 57 + libadwaita-0.4.4/src/tab_view.rs | 18 + libadwaita-0.4.4/src/toast.rs | 18 + src/components/alg_page.rs | 1 + src/components/app.rs | 1 + src/config.rs | 2 +- 307 files changed, 59784 insertions(+), 9 deletions(-) create mode 100644 Relm4-0.6.2/CHANGES.md create mode 100644 Relm4-0.6.2/Cargo.toml create mode 100644 Relm4-0.6.2/LICENSE-APACHE create mode 100644 Relm4-0.6.2/LICENSE-MIT create mode 100644 Relm4-0.6.2/README.md create mode 100644 Relm4-0.6.2/publish.sh create mode 100644 Relm4-0.6.2/relm4-components/Cargo.toml create mode 100644 Relm4-0.6.2/relm4-components/README.md create mode 100644 Relm4-0.6.2/relm4-components/examples/.gitignore create mode 100644 Relm4-0.6.2/relm4-components/examples/alert.rs create mode 100644 Relm4-0.6.2/relm4-components/examples/file_dialogs.rs create mode 100644 Relm4-0.6.2/relm4-components/examples/open_button.rs create mode 100644 Relm4-0.6.2/relm4-components/examples/web_image.rs create mode 100644 Relm4-0.6.2/relm4-components/src/alert.rs create mode 100644 Relm4-0.6.2/relm4-components/src/lib.rs create mode 100644 Relm4-0.6.2/relm4-components/src/open_button/factory.rs create mode 100644 Relm4-0.6.2/relm4-components/src/open_button/mod.rs create mode 100644 Relm4-0.6.2/relm4-components/src/open_dialog.rs create mode 100644 Relm4-0.6.2/relm4-components/src/save_dialog.rs create mode 100644 Relm4-0.6.2/relm4-components/src/simple_combo_box.rs create mode 100644 Relm4-0.6.2/relm4-components/src/web_image.rs create mode 100644 Relm4-0.6.2/relm4-macros/Cargo.toml create mode 100644 Relm4-0.6.2/relm4-macros/README.md create mode 100644 Relm4-0.6.2/relm4-macros/src/additional_fields.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/args.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/attrs.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/component/mod.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/factory/mod.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/lib.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/menu/gen.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/menu/mod.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/menu/parse.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/token_streams.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/util.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/view.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/visitors.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widget_template.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/assign_property.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/conditional_widget.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/mod.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/properties.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/signal_handler.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/widgets.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/conditional_init.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/destructure_fields.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/error.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/init.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/mod.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/return_fields.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/struct_fields.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/update_view.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/util/has_struct_field.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/util/if_branch.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/util/mod.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/util/property_name.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/util/widget.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/gen/util/widget_func.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/mod.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/assign_property.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/attributes.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/conditional_branches.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/conditional_widget.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/if_branch.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/if_condition.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/match_arm.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/mod.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/properties.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/property.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/property_name.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/returned_widget.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/signal_handler.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/top_level_widget.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/view_widgets.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/widget.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/widget_func.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse/widget_func_method.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/parse_util.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/span/attr.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/span/mod.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/span/property_name.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/span/widget_func.rs create mode 100644 Relm4-0.6.2/relm4-macros/src/widgets/span/widget_func_method.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/builder.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/codegen_order.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/complex_func_path.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/component_missing_widgets.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/iife.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/local_ref_container.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/pub_widget_templates.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/redundant_clone.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/returned_widgets.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/simple.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/skip_init.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/bad_impl.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/bad_impl.stderr create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/component-empty.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/component-empty.stderr create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/dead_code.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/dead_code.stderr create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/factory-component-empty.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/factory-component-empty.stderr create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/init-identifers.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/init-identifers.stderr create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/missing-view.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/missing-view.stderr create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/no-view-output.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/no-view-output.stderr create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/pre-view-return.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/pre-view-return.stderr create mode 100644 Relm4-0.6.2/relm4-macros/tests/widget_template.rs create mode 100644 Relm4-0.6.2/relm4-macros/tests/widget_template_nested_child.rs create mode 100644 Relm4-0.6.2/relm4/Cargo.toml create mode 100644 Relm4-0.6.2/relm4/benches/stress_test.rs create mode 100644 Relm4-0.6.2/relm4/examples create mode 100644 Relm4-0.6.2/relm4/src/actions/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/actions/traits.rs create mode 100644 Relm4-0.6.2/relm4/src/app.rs create mode 100644 Relm4-0.6.2/relm4/src/binding/bindings.rs create mode 100644 Relm4-0.6.2/relm4/src/binding/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/binding/widgets.rs create mode 100644 Relm4-0.6.2/relm4/src/channel/component.rs create mode 100644 Relm4-0.6.2/relm4/src/channel/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/channel/shutdown/attached.rs create mode 100644 Relm4-0.6.2/relm4/src/channel/shutdown/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/channel/shutdown/receiver.rs create mode 100644 Relm4-0.6.2/relm4/src/channel/shutdown/sender.rs create mode 100644 Relm4-0.6.2/relm4/src/component/async/builder.rs create mode 100644 Relm4-0.6.2/relm4/src/component/async/connector.rs create mode 100644 Relm4-0.6.2/relm4/src/component/async/controller.rs create mode 100644 Relm4-0.6.2/relm4/src/component/async/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/component/async/traits.rs create mode 100644 Relm4-0.6.2/relm4/src/component/message_broker.rs create mode 100644 Relm4-0.6.2/relm4/src/component/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/component/sync/builder.rs create mode 100644 Relm4-0.6.2/relm4/src/component/sync/connector.rs create mode 100644 Relm4-0.6.2/relm4/src/component/sync/controller.rs create mode 100644 Relm4-0.6.2/relm4/src/component/sync/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/component/sync/state_watcher.rs create mode 100644 Relm4-0.6.2/relm4/src/component/sync/stream.rs create mode 100644 Relm4-0.6.2/relm4/src/component/sync/traits.rs create mode 100644 Relm4-0.6.2/relm4/src/component/worker.rs create mode 100644 Relm4-0.6.2/relm4/src/drawing.rs create mode 100644 Relm4-0.6.2/relm4/src/extensions/container.rs create mode 100644 Relm4-0.6.2/relm4/src/extensions/iter_children.rs create mode 100644 Relm4-0.6.2/relm4/src/extensions/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/extensions/object_ext.rs create mode 100644 Relm4-0.6.2/relm4/src/extensions/remove.rs create mode 100644 Relm4-0.6.2/relm4/src/extensions/set_child.rs create mode 100644 Relm4-0.6.2/relm4/src/extensions/tests.rs create mode 100644 Relm4-0.6.2/relm4/src/extensions/widget_ext.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/async/builder.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/async/collections/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/async/collections/vec_deque.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/async/component_storage.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/async/future_data.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/async/handle.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/async/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/async/traits.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/data_guard.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/dynamic_index.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/positions.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/sync/builder.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/sync/collections/hashmap.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/sync/collections/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/sync/collections/vec_deque.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/sync/component_storage.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/sync/handle.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/sync/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/sync/traits.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/widgets/gtk.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/widgets/libadwaita.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/widgets/libpanel.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/widgets/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/widgets/tests.rs create mode 100644 Relm4-0.6.2/relm4/src/factory/widgets/traits.rs create mode 100644 Relm4-0.6.2/relm4/src/late_initialization.rs create mode 100644 Relm4-0.6.2/relm4/src/lib.rs create mode 100644 Relm4-0.6.2/relm4/src/loading_widgets.rs create mode 100644 Relm4-0.6.2/relm4/src/prelude.rs create mode 100644 Relm4-0.6.2/relm4/src/runtime_util.rs create mode 100644 Relm4-0.6.2/relm4/src/safe_settings_and_actions/extensions.rs create mode 100644 Relm4-0.6.2/relm4/src/safe_settings_and_actions/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/shared_state/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/shared_state/reducer.rs create mode 100644 Relm4-0.6.2/relm4/src/shared_state/state.rs create mode 100644 Relm4-0.6.2/relm4/src/typed_list_view/column_view.rs create mode 100644 Relm4-0.6.2/relm4/src/typed_list_view/mod.rs create mode 100644 Relm4-0.6.2/relm4/src/typed_list_view/relm_selection_ext.rs create mode 100644 Relm4-0.6.2/relm4/tests/drop_after_quit.rs create mode 100644 Relm4-0.6.2/relm4/tests/shutdown_after_quit.rs create mode 100644 Relm4-0.6.2/rustfmt.toml create mode 100644 libadwaita-0.4.4/.cargo-ok create mode 100644 libadwaita-0.4.4/.cargo_vcs_info.json create mode 100644 libadwaita-0.4.4/Cargo.lock create mode 100644 libadwaita-0.4.4/Cargo.toml create mode 100644 libadwaita-0.4.4/Cargo.toml.orig create mode 100644 libadwaita-0.4.4/Gir.toml create mode 100644 libadwaita-0.4.4/LICENCE create mode 100644 libadwaita-0.4.4/README.md create mode 100644 libadwaita-0.4.4/src/application.rs create mode 100644 libadwaita-0.4.4/src/auto/about_window.rs create mode 100644 libadwaita-0.4.4/src/auto/action_row.rs create mode 100644 libadwaita-0.4.4/src/auto/animation.rs create mode 100644 libadwaita-0.4.4/src/auto/animation_target.rs create mode 100644 libadwaita-0.4.4/src/auto/application.rs create mode 100644 libadwaita-0.4.4/src/auto/application_window.rs create mode 100644 libadwaita-0.4.4/src/auto/avatar.rs create mode 100644 libadwaita-0.4.4/src/auto/banner.rs create mode 100644 libadwaita-0.4.4/src/auto/bin.rs create mode 100644 libadwaita-0.4.4/src/auto/breakpoint.rs create mode 100644 libadwaita-0.4.4/src/auto/breakpoint_bin.rs create mode 100644 libadwaita-0.4.4/src/auto/breakpoint_condition.rs create mode 100644 libadwaita-0.4.4/src/auto/button_content.rs create mode 100644 libadwaita-0.4.4/src/auto/callback_animation_target.rs create mode 100644 libadwaita-0.4.4/src/auto/carousel.rs create mode 100644 libadwaita-0.4.4/src/auto/carousel_indicator_dots.rs create mode 100644 libadwaita-0.4.4/src/auto/carousel_indicator_lines.rs create mode 100644 libadwaita-0.4.4/src/auto/clamp.rs create mode 100644 libadwaita-0.4.4/src/auto/clamp_layout.rs create mode 100644 libadwaita-0.4.4/src/auto/clamp_scrollable.rs create mode 100644 libadwaita-0.4.4/src/auto/combo_row.rs create mode 100644 libadwaita-0.4.4/src/auto/entry_row.rs create mode 100644 libadwaita-0.4.4/src/auto/enum_list_item.rs create mode 100644 libadwaita-0.4.4/src/auto/enum_list_model.rs create mode 100644 libadwaita-0.4.4/src/auto/enums.rs create mode 100644 libadwaita-0.4.4/src/auto/expander_row.rs create mode 100644 libadwaita-0.4.4/src/auto/flags.rs create mode 100644 libadwaita-0.4.4/src/auto/flap.rs create mode 100644 libadwaita-0.4.4/src/auto/functions.rs create mode 100644 libadwaita-0.4.4/src/auto/header_bar.rs create mode 100644 libadwaita-0.4.4/src/auto/leaflet.rs create mode 100644 libadwaita-0.4.4/src/auto/leaflet_page.rs create mode 100644 libadwaita-0.4.4/src/auto/message_dialog.rs create mode 100644 libadwaita-0.4.4/src/auto/mod.rs create mode 100644 libadwaita-0.4.4/src/auto/navigation_page.rs create mode 100644 libadwaita-0.4.4/src/auto/navigation_split_view.rs create mode 100644 libadwaita-0.4.4/src/auto/navigation_view.rs create mode 100644 libadwaita-0.4.4/src/auto/overlay_split_view.rs create mode 100644 libadwaita-0.4.4/src/auto/password_entry_row.rs create mode 100644 libadwaita-0.4.4/src/auto/preferences_group.rs create mode 100644 libadwaita-0.4.4/src/auto/preferences_page.rs create mode 100644 libadwaita-0.4.4/src/auto/preferences_row.rs create mode 100644 libadwaita-0.4.4/src/auto/preferences_window.rs create mode 100644 libadwaita-0.4.4/src/auto/property_animation_target.rs create mode 100644 libadwaita-0.4.4/src/auto/spin_row.rs create mode 100644 libadwaita-0.4.4/src/auto/split_button.rs create mode 100644 libadwaita-0.4.4/src/auto/spring_animation.rs create mode 100644 libadwaita-0.4.4/src/auto/spring_params.rs create mode 100644 libadwaita-0.4.4/src/auto/squeezer.rs create mode 100644 libadwaita-0.4.4/src/auto/squeezer_page.rs create mode 100644 libadwaita-0.4.4/src/auto/status_page.rs create mode 100644 libadwaita-0.4.4/src/auto/style_manager.rs create mode 100644 libadwaita-0.4.4/src/auto/swipe_tracker.rs create mode 100644 libadwaita-0.4.4/src/auto/swipeable.rs create mode 100644 libadwaita-0.4.4/src/auto/switch_row.rs create mode 100644 libadwaita-0.4.4/src/auto/tab_bar.rs create mode 100644 libadwaita-0.4.4/src/auto/tab_button.rs create mode 100644 libadwaita-0.4.4/src/auto/tab_overview.rs create mode 100644 libadwaita-0.4.4/src/auto/tab_page.rs create mode 100644 libadwaita-0.4.4/src/auto/tab_view.rs create mode 100644 libadwaita-0.4.4/src/auto/timed_animation.rs create mode 100644 libadwaita-0.4.4/src/auto/toast.rs create mode 100644 libadwaita-0.4.4/src/auto/toast_overlay.rs create mode 100644 libadwaita-0.4.4/src/auto/toolbar_view.rs create mode 100644 libadwaita-0.4.4/src/auto/versions.txt create mode 100644 libadwaita-0.4.4/src/auto/view_stack.rs create mode 100644 libadwaita-0.4.4/src/auto/view_stack_page.rs create mode 100644 libadwaita-0.4.4/src/auto/view_switcher.rs create mode 100644 libadwaita-0.4.4/src/auto/view_switcher_bar.rs create mode 100644 libadwaita-0.4.4/src/auto/view_switcher_title.rs create mode 100644 libadwaita-0.4.4/src/auto/window.rs create mode 100644 libadwaita-0.4.4/src/auto/window_title.rs create mode 100644 libadwaita-0.4.4/src/breakpoint.rs create mode 100644 libadwaita-0.4.4/src/builders.rs create mode 100644 libadwaita-0.4.4/src/carousel.rs create mode 100644 libadwaita-0.4.4/src/functions.rs create mode 100644 libadwaita-0.4.4/src/lib.rs create mode 100644 libadwaita-0.4.4/src/message_dialog.rs create mode 100644 libadwaita-0.4.4/src/prelude.rs create mode 100644 libadwaita-0.4.4/src/spin_row.rs create mode 100644 libadwaita-0.4.4/src/subclass/action_row.rs create mode 100644 libadwaita-0.4.4/src/subclass/application.rs create mode 100644 libadwaita-0.4.4/src/subclass/application_window.rs create mode 100644 libadwaita-0.4.4/src/subclass/bin.rs create mode 100644 libadwaita-0.4.4/src/subclass/breakpoint_bin.rs create mode 100644 libadwaita-0.4.4/src/subclass/combo_row.rs create mode 100644 libadwaita-0.4.4/src/subclass/entry_row.rs create mode 100644 libadwaita-0.4.4/src/subclass/expander_row.rs create mode 100644 libadwaita-0.4.4/src/subclass/message_dialog.rs create mode 100644 libadwaita-0.4.4/src/subclass/mod.rs create mode 100644 libadwaita-0.4.4/src/subclass/navigation_page.rs create mode 100644 libadwaita-0.4.4/src/subclass/preferences_group.rs create mode 100644 libadwaita-0.4.4/src/subclass/preferences_page.rs create mode 100644 libadwaita-0.4.4/src/subclass/preferences_row.rs create mode 100644 libadwaita-0.4.4/src/subclass/preferences_window.rs create mode 100644 libadwaita-0.4.4/src/subclass/spin_row.rs create mode 100644 libadwaita-0.4.4/src/subclass/swipeable.rs create mode 100644 libadwaita-0.4.4/src/subclass/window.rs create mode 100644 libadwaita-0.4.4/src/tab_bar.rs create mode 100644 libadwaita-0.4.4/src/tab_view.rs create mode 100644 libadwaita-0.4.4/src/toast.rs diff --git a/Cargo.lock b/Cargo.lock index 296605f..a5aa65b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1154,8 +1154,6 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libadwaita" version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ab9c0843f9f23ff25634df2743690c3a1faffe0a190e60c490878517eb81abf" dependencies = [ "bitflags 1.3.2", "gdk-pixbuf", @@ -1626,8 +1624,6 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "relm4" version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c16f3fad883034773b7f5af4d7e865532b8f3641e5a8bab2a34561a8d960d81" dependencies = [ "async-trait", "flume", @@ -1654,8 +1650,6 @@ dependencies = [ [[package]] name = "relm4-macros" version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9340e2553c0a184a80a0bfa1dcf73c47f3d48933aa6be90724b202f9fbd24735" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 88ddfc5..f3a773b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,8 +7,9 @@ edition = "2021" [dependencies] gtk = { version = "0.6.6", package = "gtk4", features = ["v4_8"] } -adw = { version = "0.4.3", package = "libadwaita", features = ["v1_4"]} -relm4 = { version = "0.6.2", features = ["libadwaita"]} +libadwaita = {package="libadwaita", version = "0.4.4", path="./libadwaita-0.4.4", features = ["v1_4"]} +# relm4 = { version = "0.6.2", features = ["libadwaita"]} +relm4 = {package = "relm4", version="0.6.2", path="./Relm4-0.6.2/relm4", features=["libadwaita"]} relm4-icons = { version = "0.6.0", features = ["add-filled"] } chrono = "0.4.34" tracker = "0.2.1" diff --git a/Relm4-0.6.2/CHANGES.md b/Relm4-0.6.2/CHANGES.md new file mode 100644 index 0000000..788c043 --- /dev/null +++ b/Relm4-0.6.2/CHANGES.md @@ -0,0 +1,558 @@ +# Changelog + +## Unreleased + +## 0.6.2 - 2023-9-27 + +### Fixed + ++ macros: Add support for accessing nested template children + +## 0.6.1 - 2023-8-9 + +### Added + ++ core: Add `TypedColumnView` as a typed wrapper for `gtk::ColumnView` ++ core: Add `set_margin_vertical` and `set_margin_horizontal` to RelmWidgetExt + +### Fixed + ++ core: Don't panic when dropping components from asynchronous contexts ++ core: Fix an issue with using `connect_open` on `gtk::Application` ++ core: Use GNOME 42 as baseline feature to help with Ubuntu 22.04 ++ core: Fix compiler error when not using the "macros" feature ++ macros: Allow trailing commas in view! ++ macros: Allow multiple instances of the same template children ++ components: Disable default features of relm4 ++ examples: Fix libadwaita tab examples + +### Changed + ++ examples: Add a separator to the libadwaita leaflet example. + +## 0.6.0 - 2023-5-31 + +### Added + ++ core: Implemented `RelmRemoveExt` for `adw::ExpanderRow`. ++ core: Implemented `ContainerChild` for `adw::ExpanderRow`. ++ core: Add `TypedListView` as idiomatic wrapper over `gtk::ListView` + +### Fixed + ++ macros: Improve error messages for non-identifier parameter patterns + +## 0.6.0-beta.1 - 2023-4-19 + +### Added + ++ core: Introduce setting and action safeties ++ core: Implement `RelmSetChildExt` for `gtk::AspectFrame` ++ core: Add `FactoryHashMap` as alternative to `FactoryVecDeque` ++ core: Add gnome_44 feature flag for GNOME 44 ++ core: Documentation and better support for data bindings ++ core: Add `set_tooltip` method to `RelmWidgetExt` ++ core: Add `main_adw_application` method to retrieve the `adw::Application` when the libadwaita feature is enabled ++ macros: Add `skip_init` option for watch and track attributes to skip their initialization ++ examples: Introduce setting and action safeties ++ examples: Example for using relm4-icons + +### Changed + ++ core: Replace `FactoryVecDeque`'s associated function `from_vec` with `from_iter` ++ core: Added `Index` type to the `FactoryComponent` trait ++ core: Rename factory component traits `output_to_parent_input` method to `forward_to_parent` ++ core: Improved `RelmActionGroup` API ++ all: Increase MSRV to 1.65 to match the dependencies + +### Fixed + ++ all: Fix doc links ++ core: Improve worker docs + +### Removed + ++ core: Remove the deprecated `send!` macro + +## 0.6.0-alpha.2 - 2023-3-13 + +### Added + ++ core: Add data bindings ++ core: Implement `FactoryView` for `adw::Leaflet` ++ components: WebImage as component for easily loading images from the web + +### Fixed + ++ macros: Support template children of templates that are root widgets ++ macros: Fix order of assignment and connect statements + +## 0.6.0-alpha.1 - 2023-2-29 + +### Added + ++ core: Add `RelmApp` builder methods `with_args` and `with_broker` ++ core: Add `MessageBroker` support for `AsyncComponent` + +### Changed + ++ core: Change `MessageBroker` generic type parameter to message type ++ core: Rename `RelmApp` method `with_app` to `from_app` ++ core: Deprecate `RelmApp` methods `run_with_args` and `run_async_with_args` + +## 0.5.0 - 2023-2-17 + +### Added + ++ core: Implement `RelmSetChildExt` for `gtk::Expander` ++ macros: Support submenus in menu! macro ++ macros: Support widget templates as root widgets of components and factories ++ macros: Implement `Clone` for widget templates + +### Changed + ++ all: Use docs.rs to host the documentation. The documentation on the website will be deprecated. + +### Fixed + ++ core: Call shutdown on components even on application shutdown ++ core: Clearing and dropping a factory properly calls the shutdown method of its elements ++ components: Fix doc links to examples on GitHub ++ macros: Fix panic on incorrect root type syntax ++ macros: Fix incorrect type generation for generics ++ macros: Allow mutably root widgets + +## 0.5.0-rc.2 - 2023-2-5 + +### Changed + ++ core: Increase MSRV to 1.64 to match the gtk4 crate ++ all: Move examples into the corresponding crates + +### Added + ++ core: Add `broadcast` to `FactoryVecDeque` + +### Fixed + ++ core: Don't crash when the application is started multiple times ++ core: Support tokio also on local futures ++ core: Prevent leaking `CommandSenderInner` struct ++ core: Improve error message when sending input messages to dropped components ++ core: Fix scaping of examples on docs.rs ++ core: Fix crash caused by UID overflow with very large or frequently changing factories ++ macros: Fix clippy warning triggered by the view macro in some edge cases ++ macros: Import `relm4::ComponentSender` isn’t longer required + +## 0.5.0-rc.1 - 2022-12-21 + +### Added + ++ core: Add `try_read` and `try_write` methods to `SharedState` ++ core: Allow initializing `FactoryVecDeque` from a `Vec` and make it cloneable ++ core: Support factories with `adw::PreferencePage` + +### Changed + ++ core: Pass `&self` to the `Position::position()` function for positioning widgets ++ core: Take `&str` instead of `&[u8]` in `set_global_css()` ++ macros: Allow expressions for names of menu entries + +### Fixed + ++ core: Initialize GTK when calling `RelmApp::new()` + +## 0.5.0-beta.5 - 2022-11-26 + +### Added + ++ core: Add asynchronous components including macro support ++ core: Add asynchronous factories including macro support ++ core: Temporary widget initialization for async components and factories ++ core: Add `LoadingWidgets` to help with temporary loading widgets in async factories and components ++ core: Add `Reducer` as message based alternative to `SharedState` ++ core: Synchronous API for commands ++ core: Remove async-broadcast dependency ++ core: Runtimes of `Component`s and `AsyncComponents` can now be detached for a static lifetime ++ core: Add `ComponentStream` as alternative to `Controller` that implements `Stream` for async message handling ++ core: Add `gnome_42` and `gnome_43` feature flags ++ core: Implement `RelmContainerExt` for `adw::Squeezer` ++ core: Implement `RelmSetChildExt` for `gtk::WindowHandle` ++ macros: Auto-generate the name of the `Widgets` type if possible + +### Changed + ++ core: Rename `FactoryComponentSender` to `FactorySender` and `AsyncFactoryComponentSender` to `AsyncFactorySender` ++ core: The sender API now supports proper error handling ++ core: Pass `Root` during `update` and `update_cmd` for `Component` and `AsyncComponent` ++ core: Rename `OnDestroy` to `RelmObjectExt` ++ core: Remove `EmptyRoot` in favor of the unit type ++ macros: Allow using methods calls as widget initializers in the `view` macro ++ macros: Explicitly using `visibility` as attribute name is no longer supported + +### Fixed + ++ all: Fix doc builds on docs.rs and add a CI job to prevent future doc failures ++ core: Fix various bugs related to component shutdown ++ core: `shutdown` on `Component` now works as expected ++ core: `shutdown` on `FactoryComponent` now works as expected ++ core: `transient_for` on `ComponentBuilder` now works properly when called after the application has been initialized ++ macros: Mark template children of public widget templates as public as well ++ macros: Only get template children in scope when they are actually used ++ macros: Fix type parsing after arrow operator in widget assignments + +## 0.5.0-beta.4 - 2022-10-24 + +### Added + ++ core: Added `dox` feature to be able to build the docs without the dependencies ++ core: Added widget templates ++ core: Allow changing the priority of event loops of components ++ core: Impl `ContainerChild` and `RelmSetChildExt` for `adw::ToastOverlay` ++ components: Added `dox` feature to be able to build the docs without the dependencies ++ examples: Add libadwaita Leaflet sidebar example ++ examples: Port entry, actions and popover examples to 0.5 + +### Changed + ++ core: Improved `DrawHandler` ++ core: Made the `macros` feature a default feature ++ core: Remove async-oneshot dependency and replace it with tokio's oneshot channel ++ core: Remove WidgetPlus in favor of RelmWidgetExt ++ core: Add convenience getter-methods to Controller ++ core: `add_action` of `RelmActionGroup` now takes a reference to a `RelmAction` as a parameter ++ examples: Many improvements ++ macros: `parse_with_path`, `update_stream`, `inject_view_code` and `generate_tokens` take references for some of their parameters ++ artwork: Update logo + +### Fixed + ++ macros: Fix usage of RelmContainerExt with local_ref attribute ++ macros: Report RelmContainerExt error at the correct span + +## 0.5.0-beta.3 - 2022-9-28 + +### Added + ++ core: Add `iter_mut` to `FactoryVecDeque` ++ core: Impl extension traits and `FactoryView` for `adw::PreferencesGroup` ++ core: Add a `prelude` module that contains commonly imported traits and types ++ core: Implement RelmContainerExt for Leaflet, Carousel and TabView ++ core: Add `iter()` method to `FactoryVecDeque` ++ core: Add getter for global application to simplify graceful shutdown of applications ++ core: Add MessageBroker type to allow communication between components on different levels ++ core: Return a clone of the `DynamicIndex` after inserting into a factory ++ macros: Add shorthand syntax for simple input messages ++ macros: Add chain attribute for properties ++ components: Add `SimpleComboBox` type as a more idiomatic wrapper around `gtk::ComboBoxText` ++ components: Port `OpenButton` to 0.5 ++ book: Many chapters ported to 0.5 + +### Changed + ++ core: Improve `SharedState` interface and prefer method names related to `RwLock` ++ core: Remove Debug requirement for FactoryComponent ++ core: Remove `input` and `output` fields on `ComponentSender` and `FactoryComponentSender` in favor of `input_sender` and `output_sender` methods ++ core: Make `ComponentSender` and `FactoryComponentSender` structs instead of type aliases ++ core: Increase MSRV to 1.63 to match the gtk4 crate ++ core: Rename `ParentMsg` and `output_to_parent_msg` to `ParentInput` and `output_to_parent_input`, respectively. ++ core: Do not call `gtk_init` and `adw_init` in favor of the application startup handler ++ core: Remove `Application` type alias in favor of `gtk::Application` ++ core: Make `app` field on `RelmApp` private ++ core: Use late initialization for transient_for and its native variant ++ core: Rename InitParams to Init in SimpleComponent and Worker too ++ macros: Don't generate dead code in the widgets struct ++ macros: Improve error reporting on invalid trait implementations + +### Fixed + ++ core: Append children for `gtk::Dialog` to its content area instead of using `set_child` ++ macros: Fix returned widgets assignment in the view macro + +### Misc + ++ all: Use more clippy lints and clean up the code in general + +## 0.5.0-beta.2 - 2022-8-12 + +### Added + ++ core: Add oneshot_command method to ComponentSender ++ core: Implement FactoryView for adw::Carousel ++ components: Complete port to 0.5 ++ examples: More examples ported to 0.5 + +### Changed + ++ core: Rename InitParams to Init ++ core: Pass senders by value ++ core: Make factories use FactoryComponentSender instead of individual senders for input and output ++ core: Remove generics from FactoryComponent + +### Fixed + ++ macros: Fix unsoundness with thread local memory + +## 0.5.0-beta.1 - 2022-7-26 + +### Added + ++ core: Introduce commands + +### Changed + ++ core: The Component trait replaces AppUpdate, ComponentUpdate, AsyncComponentUpdate, MessageHandler, MicroModel, MicroWidgets, Components and Widgets ++ core: Replace FactoryPrototype with FactoryComponent ++ core: Drop FactoryVec and make FactoryVecDeque easier to use ++ core: Improved component initialization and lifecycle ++ macros: Replace iterate, track and watch with attributes ++ macros: Replace args! with only parenthesis ++ macros: Improved macro syntax ++ examples: Many rewrites for the new version + +## 0.4.4 - 2022-3-30 + +### Changed + ++ all: Repositories were transferred to the Relm4 organization + +### Fixed + ++ macros: Don't interpret expr != expr as macro ++ core: Always initialize GTK/Libadwaita before running apps ++ macros: Some doc link fixes + +## 0.4.3 - 2022-3-13 + +### Added + ++ core: Add WidgetRef trait to make AsRef easier accessible for widgets ++ macros: Destructure widgets in Widgets::view + +### Fixed + ++ macros: Use correct widget type in derive macro for components ++ macros: Fix parsing of `property: value == other,` expressions ++ core: Fixed the position type for TabView ++ core: Fixed state changes in FactoryVec (by [V02460](https://github.com/V02460)) ++ macros: Parse whole expressions instead of just literals + +## 0.4.2 - 2022-2-4 + +### Added + ++ macros: The view macro now allows dereferencing widgets with * + +### Fixed + ++ core: Fixed clear method of FactoryVec ++ macros: The micro_component macro now parses post_view correctly ++ macros: Fix the ordering of properties in the view macro ++ macros: Fix the ordering of widget assignments in the view macro + +## 0.4.1 - 2022-1-17 + +### Added + ++ macros: Improved documentation + +### Fixed + ++ core: Action macros now include the required traits themselves ++ macros: Allow connecting events in the view macro + +## 0.4.0 - 2022-1-16 + +### Added + ++ all: Update gtk4-rs to v0.4 ++ core: Introduce the "macro" feature as alternative to using relm4-macros separately ++ macros: Add a macros for MicroComponents and Factories ++ macros: Add a post_view function to execute code after the view code of the macro ++ macros: Allow using the view and menu macros independently from the widget macro ++ macros: Allow using mutable widgets in view ++ macros: Improve error messages for anonymous widgets + +### Changed + ++ core: Renamed methods of the FactoryPrototype trait to better match with the rest of Relm4 ++ macros: manual_view is now called pre_view ++ book: Reworked introduction and first chapter + +### Fixed + ++ core: Fix panic caused by the clear method of FactoryVecDeque + +## 0.4.0-beta.3 - 2021-12-28 + +### Added + ++ core: A factory view implementation for libadwaita's StackView ++ macros: Allow early returns in manual_view (by [euclio](https://github.com/euclio)) + +### Changed + ++ core: Make GTK's command line argument handling optional (by [euclio](https://github.com/euclio)) ++ core: DynamicIndex now implements Send but panics when used on other threads + +## 0.4.0-beta.2 - 2021-11-26 + ++ macros: Add optional returned widget syntax + +## 0.4.0-beta.1 - 2021-11-21 + +### Added + ++ core: Micro components ++ core: Type safe actions API ++ macros: Menu macro for creating menus ++ macros: New returned widget syntax ++ examples Micro components example + +### Changed + ++ core: Initialize widgets from the outermost components to the app ++ macros: component! removed and parent! was added instead + +### Removed + ++ core: RelmComponent::with_new_thread + +## 0.2.1 - 2021-10-17 + +### Added + ++ core: Added sender method to RelmComponent ++ macros: New shorthand tracker syntax ++ macros: Allow generic function parameters in properties + +### Changed + ++ core: Use adw::Application when "libadwaita" feature is active + +## 0.2.0 - 2021-10-09 + +### Changed + ++ core: Pass model in connect_components function of the Widgets trait ++ core: Mini rework of factories ++ core: Removed DefaultWidgets trait in favor of Default implementations in gkt4-rs ++ book: Many book improvements by [tronta](https://github.com/tronta) + +### Added + ++ core: Added with_app method that allows passing an existing gtk::Application to Relm4 ++ core: Methods to access the widgets of components ++ core: Re-export for gtk ++ macros: Support named arguments in the widget macro (by [mskorkowski](https://github.com/mskorkowski)) ++ macros: Support usage of re-export paths in the widget macro (by [mskorkowski](https://github.com/mskorkowski)) ++ macros: Added error message when confusing `=` and `:` ++ macros: Allow usage of visibilities other than pub ++ macros: New pre_connect_components and post_connect_components for manual components code + +### Fixed + ++ macros: Parsing the first widget should now always work as expected ++ macros: [#20](https://github.com/Relm4/relm4/issues/20) Fix wrong order when using components in the widget macro + +## 0.1.0 - 2021-09-06 + +### Added + ++ core: Added message handler type ++ core: More methods for factory data structures ++ macros: Add syntax for connecting events with components ++ examples: Stack example ++ book: Added macro expansion chapter + +### Changed + ++ book: Added message handler chapter and reworked the threads and async chapter ++ book: Many book improvements by [tronta](https://github.com/tronta) ++ core: The send! macro no longer clones the sender ++ macros: Make fields of public widgets public ++ components: Use &'static str instead of String for configurations ++ examples: Many improvements + +### Fixed + ++ macros: Use fully qualified syntax for factories ++ macros: Passing additional arguments now works for components and other properties, too. + +## 0.1.0-beta.9 - 2021-08-24 + +### Added + ++ components: Open button with automatic recent files list ++ components: Removed trait duplication and added more docs ++ core: Iterators added to factory data structures ++ core: More widgets added as FactoryView + +### Changed + ++ book: Many book improvements by [tronta](https://github.com/tronta) ++ core: Removed class name methods from WidgetPlus [#14](https://github.com/Relm4/relm4/pull/14) + +### Fixed + ++ macros: Parsing additional fields should be more stable now ++ macros: Widgets can not include comments at the top + +## 0.1.0-beta.8 - 2021-08-20 + +### Added + ++ core: Support for libadwaita 🎉 ++ macros: Fully qualified syntax for trait disambiguation ++ macros: Allow passing additional arguments to widget initialization (useful e.g. for grids) ++ book: Reusable components and widget macro reference chapters + +### Changed + ++ macros: Improved error messages + +## 0.1.0-beta.7 - 2021-08-19 + +### Added + ++ book: Factory, components, worker and thread + async chapters + +### Changed + ++ core: get and get_mut of FactoryVec and FactoryVecDeque now return an Option to prevent panics + +### Fixed + ++ macros: Fixed components ++ core: Fixed unsound removal of elements in FactoryVecDeque + + +## 0.1.0-beta.6 - 2021-08-18 + +### Changed + ++ core: Improved and adjusted the FactoryPrototype trait + +### Added + ++ core: Added the FactoryListView trait for more flexibility ++ core: Added a FactoryVecDeque container ++ core: Implemented FactoryView and FactoryListView for more widgets ++ examples: More examples + +### Fixed + ++ macros: Fixed the factory! macro + +## 0.1.0-beta.5 - 2021-08-15 + +### Added + ++ core: Drawing handler for gtk::DrawingArea ++ core: New CSS methods in WidgetPlus trait ++ examples: Many new examples + +### Changed + ++ core: Many doc improvements ++ macros: Improved tracker! macro diff --git a/Relm4-0.6.2/Cargo.toml b/Relm4-0.6.2/Cargo.toml new file mode 100644 index 0000000..2da3e09 --- /dev/null +++ b/Relm4-0.6.2/Cargo.toml @@ -0,0 +1,26 @@ +[workspace] +resolver = "2" +members = [ + "relm4", + "relm4-components", + "relm4-macros", +] +exclude = [ + "examples", + "examples/libadwaita", +] + +[workspace.package] +version = "0.6.2" +authors = ["Aaron Erhardt "] +edition = "2021" +rust-version = "1.65" +readme = "README.md" +license = "Apache-2.0 OR MIT" +description = "An idiomatic GUI library inspired by Elm and based on gtk4-rs" + +homepage = "https://relm4.org" +repository = "https://github.com/Relm4/Relm4" + +keywords = ["gui", "gtk", "gtk4", "elm"] +categories = ["gui"] diff --git a/Relm4-0.6.2/LICENSE-APACHE b/Relm4-0.6.2/LICENSE-APACHE new file mode 100644 index 0000000..1b5ec8b --- /dev/null +++ b/Relm4-0.6.2/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/Relm4-0.6.2/LICENSE-MIT b/Relm4-0.6.2/LICENSE-MIT new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/Relm4-0.6.2/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/Relm4-0.6.2/README.md b/Relm4-0.6.2/README.md new file mode 100644 index 0000000..9f1419e --- /dev/null +++ b/Relm4-0.6.2/README.md @@ -0,0 +1,191 @@ +

+ + Relm4 + +

+ +[![CI](https://github.com/Relm4/Relm4/actions/workflows/rust.yml/badge.svg)](https://github.com/Relm4/Relm4/actions/workflows/rust.yml) +[![Matrix](https://img.shields.io/matrix/relm4:matrix.org?label=matrix%20chat)](https://matrix.to/#/#relm4:matrix.org) +[![Relm4 on crates.io](https://img.shields.io/crates/v/relm4.svg)](https://crates.io/crates/relm4) +[![Relm4 docs](https://img.shields.io/badge/rust-documentation-blue)](https://docs.rs/relm4/) +[![Relm4 book](https://img.shields.io/badge/rust-book-fc0060)](https://relm4.org/book/stable/) +![Minimum Rust version 1.65](https://img.shields.io/badge/rustc-1.65+-06a096.svg) +[![dependency status](https://deps.rs/repo/github/Relm4/Relm4/status.svg)](https://deps.rs/repo/github/Relm4/Relm4) + +An idiomatic GUI library inspired by [Elm](https://elm-lang.org/) and based on [gtk4-rs](https://crates.io/crates/gtk4). +Relm4 is a new version of [relm](https://github.com/antoyo/relm) that's built from scratch and is compatible with [GTK4](https://www.gtk.org/) and [libadwaita](https://gitlab.gnome.org/GNOME/libadwaita). + +## Why Relm4 + +We believe that GUI development should be easy, productive and delightful. +The [gtk4-rs](https://crates.io/crates/gtk4) crate already provides everything you need to write modern, beautiful and cross-platform applications. +Built on top of this foundation, Relm4 makes developing more idiomatic, simpler and faster and enables you to become productive in just a few hours. + +## Our goals + ++ ⏱️ **Productivity** ++ ✨ **Simplicity** ++ 📎 **Outstanding documentation** ++ 🔧 **Maintainability** + +## Documentation + ++ 📖 **[The Relm4 book](https://relm4.org/book/stable/)** ++ 📜 **[Rust documentation](https://docs.rs/relm4/)** + +## Dependencies + +Relm4 depends on GTK4: [How to install GTK4 and Rust](https://gtk-rs.org/gtk4-rs/git/book/installation.html) + +## Ecosystem + ++ [relm4-macros](https://crates.io/crates/relm4-macros) - several macros for declarative UI definitions. ++ [relm4-components](https://crates.io/crates/relm4-components) - a collections of reusable components. ++ [relm4-icons](https://crates.io/crates/relm4-icons) - icons for your application. ++ [relm4-template](https://github.com/Relm4/relm4-template) - a starter template for creating Relm4 applications in the Flatpak package format. ++ [relm4-snippets](https://github.com/Relm4/vscode-relm4-snippets) - code snippets to speed up your development. + +Use this in to your `Cargo.toml`: + +```toml +# Core library +relm4 = "0.6.2" +# Optional: reusable components +relm4-components = "0.6.2" +# Optional: icons +relm4-icons = { version = "0.6.0", features = ["plus"] } +``` + +### Features + +The `relm4` crate has four feature flags: + +| Flag | Purpose | Default | +| :--- | :------ | :-----: | +| `macros` | Enable macros by re-exporting [`relm4-macros`](https://crates.io/crates/relm4-macros) | ✅ | +| `libadwaita` | Improved support for [libadwaita](https://gitlab.gnome.org/World/Rust/libadwaita-rs) | - | +| `libpanel` | Improved support for [libpanel](https://gitlab.gnome.org/World/Rust/libpanel-rs) | - | +| `dox` | Linking to the underlying C libraries is skipped to allow building the docs without dependencies | - | +| `gnome_44` | Enable all version feature flags of all dependencies to match the GNOME 44 SDK | - | +| `gnome_43` | Enable all version feature flags of all dependencies to match the GNOME 43 SDK | - | +| `gnome_42` | Enable all version feature flags of all dependencies to match the GNOME 42 SDK | - | + +The `macros` feature is a default feature. + +## Examples + +Several example applications are available at [examples/](examples/). + +#### [📸 Screenshots from the example apps](assets/screenshots) + +### A simple counter app + +![Simple app screenshot light](assets/screenshots/simple-light.png) +![Simple app screenshot dark](assets/screenshots/simple-dark.png) + +```rust +use gtk::prelude::*; +use relm4::prelude::*; + +struct App { + counter: u8, +} + +#[derive(Debug)] +enum Msg { + Increment, + Decrement, +} + +#[relm4::component] +impl SimpleComponent for App { + type Init = u8; + type Input = Msg; + type Output = (); + + view! { + gtk::Window { + set_title: Some("Simple app"), + set_default_size: (300, 100), + + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_spacing: 5, + set_margin_all: 5, + + gtk::Button { + set_label: "Increment", + connect_clicked => Msg::Increment, + }, + + gtk::Button { + set_label: "Decrement", + connect_clicked => Msg::Decrement, + }, + + gtk::Label { + #[watch] + set_label: &format!("Counter: {}", model.counter), + set_margin_all: 5, + } + } + } + } + + // Initialize the component. + fn init( + counter: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = App { counter }; + + // Insert the code generation of the view! macro here + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, msg: Self::Input, _sender: ComponentSender) { + match msg { + Msg::Increment => { + self.counter = self.counter.wrapping_add(1); + } + Msg::Decrement => { + self.counter = self.counter.wrapping_sub(1); + } + } + } +} + +fn main() { + let app = RelmApp::new("relm4.example.simple"); + app.run::(0); +} +``` + +## Projects using Relm4 + +- [fm](https://github.com/euclio/fm) — A small, general-purpose file manager. +- [Done](https://github.com/edfloreshz/done) - A simple and versatile to do app. +- [Reovim](https://github.com/songww/reovim) - GUI frontend for neovim. +- [NixOS Configuration Editor](https://github.com/vlinkz/nixos-conf-editor) - A graphical configuration editor for [NixOS](https://nixos.org). +- [Rhino Setup](https://github.com/rhino-linux/rhino-setup) - Setup wizard for [Rolling Rhino](https://rhinolinux.org/) +- [Lemoa](https://github.com/lemmy-gtk/lemoa) - Desktop client for Lemmy + +## License + +Licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any +additional terms or conditions. + +**Feedback and contributions are highly appreciated!** diff --git a/Relm4-0.6.2/publish.sh b/Relm4-0.6.2/publish.sh new file mode 100644 index 0000000..976f6d0 --- /dev/null +++ b/Relm4-0.6.2/publish.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# Exit on error +set -e + +# Check the code +cargo update +cargo fmt --all -- --check +cargo clippy --all-targets -- --deny warnings +cargo clippy --features "all" -- --deny warnings +cargo clippy --examples -- --deny warnings +cargo test + +# Publish and pass all arguments to cargo +cargo publish -p relm4-macros +cargo publish -p relm4 +cargo publish -p relm4-components \ No newline at end of file diff --git a/Relm4-0.6.2/relm4-components/Cargo.toml b/Relm4-0.6.2/relm4-components/Cargo.toml new file mode 100644 index 0000000..4a5b755 --- /dev/null +++ b/Relm4-0.6.2/relm4-components/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "relm4-components" +readme = "README.md" +documentation = "https://docs.rs/relm4_components/" + +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +description.workspace = true + +homepage.workspace = true +repository.workspace = true + +keywords.workspace = true +categories.workspace = true + +[package.metadata.docs.rs] +all-features = true +# enable unstable features in the documentation +rustc-args = ["--cfg", "docsrs"] +cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"] + +[dependencies] +once_cell = "1.18" +relm4 = { version = "0.6.2", path = "../relm4", default-features = false, features = ["macros"] } +reqwest = { version = "0.11.18", optional = true } +tracker = "0.2.1" + +[features] +default = [] +dox = ["relm4/dox", "web"] +web = ["reqwest"] + +[[example]] +name = "web_image" +required-features = ["web"] diff --git a/Relm4-0.6.2/relm4-components/README.md b/Relm4-0.6.2/relm4-components/README.md new file mode 100644 index 0000000..a56affa --- /dev/null +++ b/Relm4-0.6.2/relm4-components/README.md @@ -0,0 +1,6 @@ +# Relm4 components + +[![Relm4-components on crates.io](https://img.shields.io/crates/v/relm4-components.svg)](https://crates.io/crates/relm4-components) +[![Relm4-components docs](https://img.shields.io/badge/rust-documentation-blue)](https://docs.rs/relm4_components/) + +A collection of reusable components that can easily be integrated into Relm4 applications. diff --git a/Relm4-0.6.2/relm4-components/examples/.gitignore b/Relm4-0.6.2/relm4-components/examples/.gitignore new file mode 100644 index 0000000..a8b531a --- /dev/null +++ b/Relm4-0.6.2/relm4-components/examples/.gitignore @@ -0,0 +1 @@ +.recent_files diff --git a/Relm4-0.6.2/relm4-components/examples/alert.rs b/Relm4-0.6.2/relm4-components/examples/alert.rs new file mode 100644 index 0000000..5e5aa53 --- /dev/null +++ b/Relm4-0.6.2/relm4-components/examples/alert.rs @@ -0,0 +1,148 @@ +use gtk::prelude::*; +use relm4::{ + gtk, Component, ComponentController, ComponentParts, ComponentSender, Controller, RelmApp, + RelmWidgetExt, SimpleComponent, +}; +use relm4_components::alert::{Alert, AlertMsg, AlertResponse, AlertSettings}; + +struct App { + counter: u8, + alert_toggle: bool, + dialog: Controller, + second_dialog: Controller, +} + +#[derive(Debug)] +enum AppMsg { + Increment, + Decrement, + CloseRequest, + Save, + Close, + Ignore, +} + +#[relm4::component] +impl SimpleComponent for App { + type Init = (); + type Input = AppMsg; + type Output = (); + + view! { + main_window = gtk::ApplicationWindow { + set_title: Some("Alert example"), + set_default_size: (300, 100), + + connect_close_request[sender] => move |_| { + sender.input(AppMsg::CloseRequest); + gtk::Inhibit(true) + }, + + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_margin_all: 5, + set_spacing: 5, + + append = >k::Button { + set_label: "Increment", + connect_clicked => AppMsg::Increment, + }, + append = >k::Button { + set_label: "Decrement", + connect_clicked => AppMsg::Decrement, + }, + append = >k::Label { + set_margin_all: 5, + #[watch] + set_label: &format!("Counter: {}", model.counter), + }, + append = >k::Button { + set_label: "Close", + connect_clicked => AppMsg::CloseRequest, + }, + }, + } + } + + fn update(&mut self, msg: AppMsg, _sender: ComponentSender) { + match msg { + AppMsg::Increment => { + self.counter = self.counter.wrapping_add(1); + } + AppMsg::Decrement => { + self.counter = self.counter.wrapping_sub(1); + } + AppMsg::CloseRequest => { + if self.counter == 42 { + relm4::main_application().quit(); + } else { + self.alert_toggle = !self.alert_toggle; + if self.alert_toggle { + self.dialog.emit(AlertMsg::Show); + } else { + self.second_dialog.emit(AlertMsg::Show); + } + } + } + AppMsg::Save => { + println!("* Open save dialog here *"); + } + AppMsg::Close => { + relm4::main_application().quit(); + } + AppMsg::Ignore => (), + } + } + + fn init( + _: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = App { + counter: 0, + alert_toggle: false, + dialog: Alert::builder() + .transient_for(root) + .launch(AlertSettings { + text: String::from("Do you want to quit without saving? (First alert)"), + secondary_text: Some(String::from("Your counter hasn't reached 42 yet")), + confirm_label: String::from("Close without saving"), + cancel_label: String::from("Cancel"), + option_label: Some(String::from("Save")), + is_modal: true, + destructive_accept: true, + }) + .forward(sender.input_sender(), convert_alert_response), + second_dialog: Alert::builder() + .transient_for(root) + .launch(AlertSettings { + text: String::from("Do you want to quit without saving? (Second alert)"), + secondary_text: Some(String::from("Your counter hasn't reached 42 yet")), + confirm_label: String::from("Close without saving"), + cancel_label: String::from("Cancel"), + option_label: Some(String::from("Save")), + is_modal: true, + destructive_accept: true, + }) + .forward(sender.input_sender(), convert_alert_response), + }; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } +} + +fn convert_alert_response(response: AlertResponse) -> AppMsg { + match response { + AlertResponse::Confirm => AppMsg::Close, + AlertResponse::Cancel => AppMsg::Ignore, + AlertResponse::Option => AppMsg::Save, + } +} + +fn main() { + let app = RelmApp::new("relm4.example.alert"); + app.run::(()); +} diff --git a/Relm4-0.6.2/relm4-components/examples/file_dialogs.rs b/Relm4-0.6.2/relm4-components/examples/file_dialogs.rs new file mode 100644 index 0000000..c9abeb7 --- /dev/null +++ b/Relm4-0.6.2/relm4-components/examples/file_dialogs.rs @@ -0,0 +1,176 @@ +use gtk::prelude::*; +use relm4::{ + gtk, Component, ComponentController, ComponentParts, ComponentSender, Controller, RelmApp, + RelmWidgetExt, SimpleComponent, +}; +use relm4_components::{open_dialog::*, save_dialog::*}; + +use std::path::PathBuf; + +struct App { + open_dialog: Controller, + save_dialog: Controller, + buffer: gtk::TextBuffer, + file_name: Option, + message: Option, +} + +#[derive(Debug)] +enum Input { + OpenRequest, + OpenResponse(PathBuf), + SaveRequest, + SaveResponse(PathBuf), + ShowMessage(String), + ResetMessage, + Ignore, +} + +#[relm4::component] +impl SimpleComponent for App { + type Init = (); + type Input = Input; + type Output = (); + + view! { + root = gtk::ApplicationWindow { + set_default_size: (600, 400), + + #[watch] + set_title: Some(model.file_name.as_deref().unwrap_or_default()), + + #[wrap(Some)] + set_titlebar = >k::HeaderBar { + pack_start = >k::Button { + set_label: "Open", + connect_clicked => Input::OpenRequest, + }, + pack_end = >k::Button { + set_label: "Save As", + connect_clicked => Input::SaveRequest, + + #[watch] + set_sensitive: model.file_name.is_some(), + } + }, + + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_margin_all: 5, + + gtk::ScrolledWindow { + set_min_content_height: 380, + + #[wrap(Some)] + set_child = >k::TextView { + set_buffer: Some(&model.buffer), + + #[watch] + set_visible: model.file_name.is_some(), + }, + }, + } + } + } + + fn post_view() { + if let Some(text) = &model.message { + let dialog = gtk::MessageDialog::builder() + .text(text) + .use_markup(true) + .transient_for(&widgets.root) + .modal(true) + .buttons(gtk::ButtonsType::Ok) + .build(); + dialog.connect_response(|dialog, _| dialog.destroy()); + dialog.set_visible(true); + sender.input(Input::ResetMessage); + } + } + + fn init( + _: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let open_dialog = OpenDialog::builder() + .transient_for_native(root) + .launch(OpenDialogSettings::default()) + .forward(sender.input_sender(), |response| match response { + OpenDialogResponse::Accept(path) => Input::OpenResponse(path), + OpenDialogResponse::Cancel => Input::Ignore, + }); + + let save_dialog = SaveDialog::builder() + .transient_for_native(root) + .launch(SaveDialogSettings::default()) + .forward(sender.input_sender(), |response| match response { + SaveDialogResponse::Accept(path) => Input::SaveResponse(path), + SaveDialogResponse::Cancel => Input::Ignore, + }); + + let model = App { + open_dialog, + save_dialog, + buffer: gtk::TextBuffer::new(None), + file_name: None, + message: None, + }; + + let widgets = view_output!(); + + sender.input(Input::ShowMessage(String::from( + "A simple text editor showing the usage of\nOpenFileDialog and SaveFileDialog components.\n\nStart by clicking Open on the header bar.", + ))); + + ComponentParts { model, widgets } + } + + fn update(&mut self, message: Self::Input, sender: ComponentSender) { + match message { + Input::OpenRequest => self.open_dialog.emit(OpenDialogMsg::Open), + Input::OpenResponse(path) => match std::fs::read_to_string(&path) { + Ok(contents) => { + self.buffer.set_text(&contents); + self.file_name = Some( + path.file_name() + .expect("The path has no file name") + .to_str() + .expect("Cannot convert file name to string") + .to_string(), + ); + } + Err(e) => sender.input(Input::ShowMessage(e.to_string())), + }, + Input::SaveRequest => self + .save_dialog + .emit(SaveDialogMsg::SaveAs(self.file_name.clone().unwrap())), + Input::SaveResponse(path) => match std::fs::write( + &path, + self.buffer + .text(&self.buffer.start_iter(), &self.buffer.end_iter(), false), + ) { + Ok(_) => { + sender.input(Input::ShowMessage(format!( + "File saved successfully at {path:?}" + ))); + self.buffer.set_text(""); + self.file_name = None; + } + Err(e) => sender.input(Input::ShowMessage(e.to_string())), + }, + Input::ShowMessage(message) => { + self.message = Some(message); + } + Input::ResetMessage => { + self.message = None; + } + Input::Ignore => {} + } + } +} + +fn main() { + let app = RelmApp::new("relm4.example.file_dialogs"); + app.run::(()); +} diff --git a/Relm4-0.6.2/relm4-components/examples/open_button.rs b/Relm4-0.6.2/relm4-components/examples/open_button.rs new file mode 100644 index 0000000..051b0d1 --- /dev/null +++ b/Relm4-0.6.2/relm4-components/examples/open_button.rs @@ -0,0 +1,69 @@ +use std::path::PathBuf; + +use gtk::prelude::*; +use relm4::{ + gtk, Component, ComponentController, ComponentParts, ComponentSender, Controller, RelmApp, + SimpleComponent, +}; +use relm4_components::open_button::{OpenButton, OpenButtonSettings}; +use relm4_components::open_dialog::OpenDialogSettings; + +#[derive(Debug)] +enum AppMsg { + Open(PathBuf), +} + +struct App { + open_button: Controller, +} + +#[relm4::component] +impl SimpleComponent for App { + type Init = (); + type Input = AppMsg; + type Output = (); + + view! { + gtk::ApplicationWindow { + set_default_size: (300, 100), + + #[wrap(Some)] + set_titlebar = >k::HeaderBar { + pack_start: model.open_button.widget(), + } + } + } + + fn update(&mut self, msg: Self::Input, _: ComponentSender) { + match msg { + AppMsg::Open(path) => { + println!("* Opened file {path:?} *"); + } + } + } + + fn init( + _: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let open_button = OpenButton::builder() + .launch(OpenButtonSettings { + dialog_settings: OpenDialogSettings::default(), + text: "Open file", + recently_opened_files: Some(".recent_files"), + max_recent_files: 10, + }) + .forward(sender.input_sender(), AppMsg::Open); + let model = App { open_button }; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } +} + +fn main() { + let app = RelmApp::new("relm4.example.open_button"); + app.run::(()); +} diff --git a/Relm4-0.6.2/relm4-components/examples/web_image.rs b/Relm4-0.6.2/relm4-components/examples/web_image.rs new file mode 100644 index 0000000..9651753 --- /dev/null +++ b/Relm4-0.6.2/relm4-components/examples/web_image.rs @@ -0,0 +1,84 @@ +use gtk::prelude::*; +use relm4::{ + gtk, Component, ComponentController, ComponentParts, ComponentSender, Controller, RelmApp, + SimpleComponent, +}; +use relm4_components::web_image::{WebImage, WebImageMsg}; + +const IMAGES: &[&str] = &[ + "https://raw.githubusercontent.com/Relm4/Relm4/main/assets/Relm_logo_with_text.png", + "https://raw.githubusercontent.com/Relm4/Relm4/main/assets/Relm_logo.png", + "https://raw.githubusercontent.com/gtk-rs/gtk-rs.github.io/master/logo/gtk-rs.ico", + "https://avatars.githubusercontent.com/u/5430905", +]; + +#[derive(Debug)] +enum AppMsg { + Next, + Unload, +} + +struct App { + image: Controller, + idx: usize, +} + +#[relm4::component] +impl SimpleComponent for App { + type Init = (); + type Input = AppMsg; + type Output = (); + + view! { + gtk::ApplicationWindow { + set_default_size: (300, 300), + + #[wrap(Some)] + set_titlebar = >k::HeaderBar { + pack_start = >k::Button { + set_label: "Next image", + connect_clicked => AppMsg::Next, + }, + pack_start = >k::Button { + set_label: "Unload image", + connect_clicked => AppMsg::Unload, + } + }, + + gtk::Box { + #[local_ref] + image -> gtk::Box {} + } + } + } + + fn update(&mut self, msg: Self::Input, _: ComponentSender) { + match msg { + AppMsg::Next => { + self.idx = (self.idx + 1) % IMAGES.len(); + self.image + .emit(WebImageMsg::LoadImage(IMAGES[self.idx].to_owned())); + } + AppMsg::Unload => self.image.emit(WebImageMsg::Unload), + } + } + + fn init( + _: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let image = WebImage::builder().launch(IMAGES[0].to_owned()).detach(); + let model = App { image, idx: 0 }; + + let image = model.image.widget(); + let widgets = view_output!(); + + ComponentParts { model, widgets } + } +} + +fn main() { + let app = RelmApp::new("relm4.example.open_button"); + app.run::(()); +} diff --git a/Relm4-0.6.2/relm4-components/src/alert.rs b/Relm4-0.6.2/relm4-components/src/alert.rs new file mode 100644 index 0000000..a4b256e --- /dev/null +++ b/Relm4-0.6.2/relm4-components/src/alert.rs @@ -0,0 +1,129 @@ +//! Reusable and easily configurable alert component. +//! +//! **[Example implementation](https://github.com/AaronErhardt/relm4/blob/main/relm4-examples/examples/alert.rs)** + +use gtk::prelude::{DialogExt, GtkWindowExt, WidgetExt}; +use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + +/// Configuration for the alert dialog component +#[derive(Debug)] +pub struct AlertSettings { + /// Large text + pub text: String, + /// Optional secondary, smaller text + pub secondary_text: Option, + /// Modal dialogs freeze other windows as long they are visible + pub is_modal: bool, + /// Sets color of the accept button to red if the theme supports it + pub destructive_accept: bool, + /// Text for confirm button + pub confirm_label: String, + /// Text for cancel button + pub cancel_label: String, + /// Text for third option button. If [`None`] the third button won't be created. + pub option_label: Option, +} + +/// Alert dialog component. +#[derive(Debug)] +pub struct Alert { + settings: AlertSettings, + is_active: bool, +} + +/// Messages that can be sent to the alert dialog component +#[derive(Debug)] +pub enum AlertMsg { + /// Message sent by the parent to view the dialog + Show, + + #[doc(hidden)] + Response(gtk::ResponseType), +} + +/// User action performed on the alert dialog. +#[derive(Debug)] +pub enum AlertResponse { + /// User clicked confirm button. + Confirm, + + /// User clicked cancel button. + Cancel, + + /// User clicked user-supplied option. + Option, +} + +/// Widgets of the alert dialog component. +#[relm4::component(pub)] +impl SimpleComponent for Alert { + type Init = AlertSettings; + type Input = AlertMsg; + type Output = AlertResponse; + + view! { + #[name(dialog)] + gtk::MessageDialog { + set_message_type: gtk::MessageType::Question, + #[watch] + set_visible: model.is_active, + connect_response[sender] => move |_, response| { + sender.input(AlertMsg::Response(response)); + }, + + // Apply configuration + set_text: Some(&model.settings.text), + set_secondary_text: model.settings.secondary_text.as_deref(), + set_modal: model.settings.is_modal, + add_button: (&model.settings.confirm_label, gtk::ResponseType::Accept), + add_button: (&model.settings.cancel_label, gtk::ResponseType::Cancel), + } + } + + fn init( + settings: AlertSettings, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = Alert { + settings, + is_active: false, + }; + + let widgets = view_output!(); + + if let Some(option_label) = &model.settings.option_label { + widgets + .dialog + .add_button(option_label, gtk::ResponseType::Other(0)); + } + + if model.settings.destructive_accept { + let accept_widget = widgets + .dialog + .widget_for_response(gtk::ResponseType::Accept) + .expect("No button for accept response set"); + accept_widget.add_css_class("destructive-action"); + } + + ComponentParts { model, widgets } + } + + fn update(&mut self, input: AlertMsg, sender: ComponentSender) { + match input { + AlertMsg::Show => { + self.is_active = true; + } + AlertMsg::Response(ty) => { + self.is_active = false; + sender + .output(match ty { + gtk::ResponseType::Accept => AlertResponse::Confirm, + gtk::ResponseType::Other(_) => AlertResponse::Option, + _ => AlertResponse::Cancel, + }) + .unwrap(); + } + } + } +} diff --git a/Relm4-0.6.2/relm4-components/src/lib.rs b/Relm4-0.6.2/relm4-components/src/lib.rs new file mode 100644 index 0000000..a74abe1 --- /dev/null +++ b/Relm4-0.6.2/relm4-components/src/lib.rs @@ -0,0 +1,43 @@ +//! Collection of reusable and easily configurable components for Relm4. +//! +//! Docs of related crates: +//! [relm4](https://docs.rs/relm4) +//! | [relm4-macros](https://docs.rs/relm4_macros) +//! | [relm4-components](https://docs.rs/relm4_components) +//! | [gtk4-rs](https://gtk-rs.org/gtk4-rs/git/docs) +//! | [gtk-rs-core](https://gtk-rs.org/gtk-rs-core/git/docs) +//! | [libadwaita-rs](https://world.pages.gitlab.gnome.org/Rust/libadwaita-rs/git/docs/libadwaita) +//! | [libpanel-rs](https://world.pages.gitlab.gnome.org/Rust/libpanel-rs/git/docs/libpanel) +//! +//! [GitHub](https://github.com/Relm4/Relm4) +//! | [Website](https://relm4.org) +//! | [Book](https://relm4.org/book/stable/) +//! | [Blog](https://relm4.org/blog) + +#![doc(html_logo_url = "https://relm4.org/icons/relm4_logo.svg")] +#![doc(html_favicon_url = "https://relm4.org/icons/relm4_org.svg")] +#![warn( + missing_debug_implementations, + missing_docs, + rust_2018_idioms, + unreachable_pub, + unused_qualifications, + clippy::cargo, + clippy::must_use_candidate +)] +// Configuration for doc builds on the nightly toolchain. +#![cfg_attr(docsrs, feature(doc_cfg))] +// Ignore GTK 4.10 deprecations. +// Most deprecated features can only be replaced with new 4.10 APIs and +// we don't want to lift the minimum requirement GTK4 version for Relm4 yet. +#![allow(deprecated)] + +pub mod alert; +pub mod open_button; +pub mod open_dialog; +pub mod save_dialog; +pub mod simple_combo_box; + +#[cfg(feature = "web")] +#[cfg_attr(docsrs, doc(cfg(feature = "web")))] +pub mod web_image; diff --git a/Relm4-0.6.2/relm4-components/src/open_button/factory.rs b/Relm4-0.6.2/relm4-components/src/open_button/factory.rs new file mode 100644 index 0000000..aa33810 --- /dev/null +++ b/Relm4-0.6.2/relm4-components/src/open_button/factory.rs @@ -0,0 +1,42 @@ +use gtk::prelude::*; +use relm4::factory::{DynamicIndex, FactoryComponent, FactorySender}; +use relm4::{gtk, RelmWidgetExt}; + +use super::OpenButtonMsg; + +use std::path::PathBuf; + +#[derive(Debug)] +pub(crate) struct FileListItem { + pub(crate) path: PathBuf, +} + +#[relm4::factory(pub(crate))] +impl FactoryComponent for FileListItem { + type ParentInput = OpenButtonMsg; + type CommandOutput = (); + type Input = (); + type Init = PathBuf; + type ParentWidget = gtk::Box; + type Output = OpenButtonMsg; + + view! { + gtk::ListBoxRow { + gtk::Button { + set_label: self.path.iter().last().expect("Empty path").to_str().unwrap(), + set_margin_all: 0, + connect_clicked[sender, index] => move |_| { + sender.output(OpenButtonMsg::OpenRecent(index.clone())); + } + } + } + } + + fn forward_to_parent(output: Self::Output) -> Option { + Some(output) + } + + fn init_model(init: Self::Init, _: &DynamicIndex, _: FactorySender) -> Self { + Self { path: init } + } +} diff --git a/Relm4-0.6.2/relm4-components/src/open_button/mod.rs b/Relm4-0.6.2/relm4-components/src/open_button/mod.rs new file mode 100644 index 0000000..5456c89 --- /dev/null +++ b/Relm4-0.6.2/relm4-components/src/open_button/mod.rs @@ -0,0 +1,192 @@ +//! Reusable and easily configurable open button dialog component. +//! +//! **[Example implementation](https://github.com/Relm4/Relm4/blob/main/relm4-components/examples/open_button.rs)** +use relm4::factory::{DynamicIndex, FactoryVecDeque}; +use relm4::gtk::prelude::*; +use relm4::{ + gtk, Component, ComponentController, ComponentParts, ComponentSender, Controller, + SimpleComponent, +}; + +use crate::open_dialog::{OpenDialog, OpenDialogMsg, OpenDialogResponse, OpenDialogSettings}; + +use std::fs; +use std::path::PathBuf; + +mod factory; + +use factory::FileListItem; + +/// Open button component. +/// +/// Creates a button with custom text that can be used to open a file chooser dialog. If a file is +/// chosen, then it will be emitted as an output. The component can also optionally display a +/// popover list of open files if [`OpenButtonSettings::recently_opened_files`] is set to a value. +#[tracker::track] +#[derive(Debug)] +pub struct OpenButton { + #[do_not_track] + config: OpenButtonSettings, + #[do_not_track] + dialog: Controller, + #[do_not_track] + recent_files: Option>, + initialized: bool, + #[do_not_track] + reset_popover: bool, +} + +#[derive(Debug)] +/// Configuration for the open button component +pub struct OpenButtonSettings { + /// Settings for the open file dialog. + pub dialog_settings: OpenDialogSettings, + /// Text of the open button. + pub text: &'static str, + /// Path to a file where recent files should be stored. + /// This list is updated fully automatically. + pub recently_opened_files: Option<&'static str>, + /// Maximum amount of recent files to store. + /// This is only used if a path for storing the recently opened files was set. + pub max_recent_files: usize, +} + +#[doc(hidden)] +#[derive(Debug)] +pub enum OpenButtonMsg { + Open(PathBuf), + OpenRecent(DynamicIndex), + ShowDialog, + Ignore, +} + +/// Widgets of the open button component +#[relm4::component(pub)] +impl SimpleComponent for OpenButton { + type Init = OpenButtonSettings; + type Input = OpenButtonMsg; + type Output = PathBuf; + + view! { + gtk::Box { + add_css_class: "linked", + gtk::Button { + set_label: model.config.text, + connect_clicked => OpenButtonMsg::ShowDialog, + }, + gtk::MenuButton { + set_visible: model.config.recently_opened_files.is_some(), + + #[wrap(Some)] + #[name(popover)] + set_popover = >k::Popover { + gtk::ScrolledWindow { + set_hscrollbar_policy: gtk::PolicyType::Never, + set_min_content_width: 100, + set_min_content_height: 100, + set_min_content_height: 300, + + #[name(recent_files_list)] + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_vexpand: true, + set_hexpand: true, + } + } + } + } + } + } + + fn update(&mut self, msg: Self::Input, sender: ComponentSender) { + self.reset_popover = false; + + match msg { + OpenButtonMsg::ShowDialog => { + self.dialog.emit(OpenDialogMsg::Open); + } + OpenButtonMsg::Open(path) => { + sender.output(path.clone()).unwrap(); + self.reset_popover = true; + + if let Some(recent_files) = &mut self.recent_files { + let index = recent_files.iter().position(|item| item.path == path); + + if let Some(index) = index { + recent_files.guard().remove(index); + } + + if recent_files.len() < self.config.max_recent_files { + recent_files.guard().push_front(path); + } + + let contents = recent_files + .iter() + .filter_map(|recent_path| { + recent_path.path.to_str().map(|s| format!("{s}\n")) + }) + .collect::(); + + let _ = fs::write(self.config.recently_opened_files.unwrap(), contents); + } + } + OpenButtonMsg::OpenRecent(index) => { + if let Some(item) = self + .recent_files + .as_ref() + .and_then(|recent_files| recent_files.get(index.current_index())) + { + sender.input(OpenButtonMsg::Open(PathBuf::from(&item.path))); + } + } + OpenButtonMsg::Ignore => (), + } + } + + fn pre_view() { + if self.reset_popover { + popover.popdown(); + } + } + + fn init( + settings: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let dialog = OpenDialog::builder() + .transient_for_native(root) + .launch(settings.dialog_settings.clone()) + .forward(sender.input_sender(), |response| match response { + OpenDialogResponse::Accept(path) => OpenButtonMsg::Open(path), + OpenDialogResponse::Cancel => OpenButtonMsg::Ignore, + }); + + let mut model = Self { + config: settings, + dialog, + initialized: false, + recent_files: None, + reset_popover: false, + tracker: 0, + }; + + let widgets = view_output!(); + + if let Some(filename) = model.config.recently_opened_files { + let mut factory = + FactoryVecDeque::new(widgets.recent_files_list.clone(), sender.input_sender()); + + if let Ok(entries) = fs::read_to_string(filename) { + let mut guard = factory.guard(); + for entry in entries.lines() { + guard.push_back(PathBuf::from(entry)); + } + } + + model.recent_files = Some(factory); + } + + ComponentParts { model, widgets } + } +} diff --git a/Relm4-0.6.2/relm4-components/src/open_dialog.rs b/Relm4-0.6.2/relm4-components/src/open_dialog.rs new file mode 100644 index 0000000..a2c1ae2 --- /dev/null +++ b/Relm4-0.6.2/relm4-components/src/open_dialog.rs @@ -0,0 +1,181 @@ +//! Reusable and easily configurable open dialog component. +//! +//! **[Example implementation](https://github.com/Relm4/Relm4/blob/main/relm4-components/examples/file_dialogs.rs)** +use gtk::prelude::{Cast, FileChooserExt, FileExt, ListModelExt, NativeDialogExt}; +use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + +use std::{fmt::Debug, marker::PhantomData, path::PathBuf}; + +/// A component that prompts the user to choose a file. +/// +/// The user would be able to select a single file. If you'd like to select multiple, use [`OpenDialogMulti`]. +pub type OpenDialog = OpenDialogInner; + +/// A component that prompts the user to choose a file. +/// +/// The user would be able to select multiple files. If you'd like to select just one, use [`OpenDialog`]. +pub type OpenDialogMulti = OpenDialogInner; + +/// Type of selection used for the open dialog. +pub trait Select: Debug { + /// Output of the selection. + type Selection: Debug; + /// Whether to select multiple files inside the dialog. + const SELECT_MULTIPLE: bool; + /// Construct selection from the file chooser. + fn select(dialog: >k::FileChooserNative) -> Self::Selection; +} + +/// A type of selection where only one file can be chosen at a time. +#[derive(Debug)] +pub struct SingleSelection; + +impl Select for SingleSelection { + type Selection = PathBuf; + const SELECT_MULTIPLE: bool = false; + fn select(dialog: >k::FileChooserNative) -> Self::Selection { + dialog + .file() + .expect("No file selected") + .path() + .expect("No path") + } +} + +/// A type of selection where multiple types can be chosen at a time. +#[derive(Debug)] +pub struct MultiSelection; +impl Select for MultiSelection { + type Selection = Vec; + const SELECT_MULTIPLE: bool = true; + fn select(dialog: >k::FileChooserNative) -> Self::Selection { + let list_model = dialog.files(); + (0..list_model.n_items()) + .filter_map(|index| list_model.item(index)) + .filter_map(|obj| obj.downcast::().ok()) + .filter_map(|file| file.path()) + .collect() + } +} + +#[derive(Clone, Debug)] +/// Configuration for the open dialog component +pub struct OpenDialogSettings { + /// Select folders instead of files + pub folder_mode: bool, + /// Label for cancel button + pub cancel_label: String, + /// Label for accept button + pub accept_label: String, + /// Allow or disallow creating folders + pub create_folders: bool, + /// Freeze other windows while the dialog is open + pub is_modal: bool, + /// Filter for MIME types or other patterns + pub filters: Vec, +} + +impl Default for OpenDialogSettings { + fn default() -> Self { + OpenDialogSettings { + folder_mode: false, + accept_label: String::from("Open"), + cancel_label: String::from("Cancel"), + create_folders: true, + is_modal: true, + filters: Vec::new(), + } + } +} + +#[derive(Debug)] +/// Model for the open dialog component +pub struct OpenDialogInner { + visible: bool, + _phantom: PhantomData, +} + +/// Messages that can be sent to the open dialog component +#[derive(Debug, Clone)] +pub enum OpenDialogMsg { + /// Show the dialog + Open, + #[doc(hidden)] + Hide, +} + +/// Messages that can be sent from the open dialog component +#[derive(Debug, Clone)] +pub enum OpenDialogResponse { + /// User clicked accept button. + Accept(S::Selection), + /// User clicked cancel button. + Cancel, +} + +/// Widgets of the open dialog component. +#[relm4::component(pub)] +impl SimpleComponent for OpenDialogInner { + type Init = OpenDialogSettings; + type Input = OpenDialogMsg; + type Output = OpenDialogResponse; + + view! { + gtk::FileChooserNative { + set_action: if settings.folder_mode { + gtk::FileChooserAction::SelectFolder + } else { + gtk::FileChooserAction::Open + }, + + set_select_multiple: S::SELECT_MULTIPLE, + set_create_folders: settings.create_folders, + set_modal: settings.is_modal, + set_accept_label: Some(&settings.accept_label), + set_cancel_label: Some(&settings.cancel_label), + #[iterate] + add_filter: &settings.filters, + + #[watch] + set_visible: model.visible, + + connect_response[sender] => move |dialog, res_ty| { + match res_ty { + gtk::ResponseType::Accept => { + let selection = S::select(dialog); + sender.output(OpenDialogResponse::Accept(selection)).unwrap(); + } + _ => sender.output(OpenDialogResponse::Cancel).unwrap(), + } + + sender.input(OpenDialogMsg::Hide); + } + } + } + + fn init( + settings: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = OpenDialogInner { + visible: false, + _phantom: PhantomData, + }; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, message: Self::Input, _sender: ComponentSender) { + match message { + OpenDialogMsg::Open => { + self.visible = true; + } + OpenDialogMsg::Hide => { + self.visible = false; + } + } + } +} diff --git a/Relm4-0.6.2/relm4-components/src/save_dialog.rs b/Relm4-0.6.2/relm4-components/src/save_dialog.rs new file mode 100644 index 0000000..693c28a --- /dev/null +++ b/Relm4-0.6.2/relm4-components/src/save_dialog.rs @@ -0,0 +1,136 @@ +//! Reusable and easily configurable save dialog component. +//! +//! **[Example implementation](https://github.com/Relm4/Relm4/blob/main/relm4-components/examples/file_dialogs.rs)** +use gtk::prelude::{FileChooserExt, FileExt, NativeDialogExt}; +use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + +use std::path::PathBuf; + +#[derive(Clone, Debug)] +/// Configuration for the save dialog component +pub struct SaveDialogSettings { + /// Label for cancel button + pub cancel_label: String, + /// Label for accept button + pub accept_label: String, + /// Allow or disallow creating folders + pub create_folders: bool, + /// Freeze other windows while the dialog is open + pub is_modal: bool, + /// Filter for MIME types or other patterns + pub filters: Vec, +} + +impl Default for SaveDialogSettings { + fn default() -> Self { + SaveDialogSettings { + accept_label: String::from("Save"), + cancel_label: String::from("Cancel"), + create_folders: true, + is_modal: true, + filters: Vec::new(), + } + } +} + +#[derive(Debug)] +/// A model for the save dialog component +pub struct SaveDialog { + current_name: String, + visible: bool, +} + +/// Messages that can be sent to the save dialog component +#[derive(Debug, Clone)] +pub enum SaveDialogMsg { + /// Show the dialog + Save, + /// Show the dialog, with a suggested file name + SaveAs(String), + #[doc(hidden)] + Hide, +} + +/// Messages that can be sent from the save dialog component +#[derive(Debug, Clone)] +pub enum SaveDialogResponse { + /// User clicked accept button. + Accept(PathBuf), + /// User clicked cancel button. + Cancel, +} + +/// Widgets of the save dialog component. +#[relm4::component(pub)] +impl SimpleComponent for SaveDialog { + type Init = SaveDialogSettings; + + type Input = SaveDialogMsg; + type Output = SaveDialogResponse; + + view! { + gtk::FileChooserNative { + set_action: gtk::FileChooserAction::Save, + + set_create_folders: settings.create_folders, + set_modal: settings.is_modal, + set_accept_label: Some(&settings.accept_label), + set_cancel_label: Some(&settings.cancel_label), + #[iterate] + add_filter: &settings.filters, + + #[watch] + set_current_name: &model.current_name, + #[watch] + set_visible: model.visible, + + connect_response[sender] => move |dialog, res_ty| { + match res_ty { + gtk::ResponseType::Accept => { + if let Some(file) = dialog.file() { + if let Some(path) = file.path() { + sender.output(SaveDialogResponse::Accept(path)).unwrap(); + sender.input(SaveDialogMsg::Hide); + return; + } + } + sender.output(SaveDialogResponse::Cancel).unwrap(); + } + _ => sender.output(SaveDialogResponse::Cancel).unwrap(), + } + sender.input(SaveDialogMsg::Hide); + } + } + } + + fn init( + settings: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = SaveDialog { + current_name: String::new(), + visible: false, + }; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, message: Self::Input, _sender: ComponentSender) { + match message { + SaveDialogMsg::Save => { + self.current_name = String::new(); + self.visible = true; + } + SaveDialogMsg::SaveAs(file_name) => { + self.current_name = file_name; + self.visible = true; + } + SaveDialogMsg::Hide => { + self.visible = false; + } + } + } +} diff --git a/Relm4-0.6.2/relm4-components/src/simple_combo_box.rs b/Relm4-0.6.2/relm4-components/src/simple_combo_box.rs new file mode 100644 index 0000000..dc827bb --- /dev/null +++ b/Relm4-0.6.2/relm4-components/src/simple_combo_box.rs @@ -0,0 +1,117 @@ +//! A wrapper around [`gtk::ComboBoxText`] that makes it easier to use +//! from regular Rust code. + +use std::fmt::Debug; + +use relm4::gtk::prelude::{ComboBoxExt, ComboBoxExtManual}; +use relm4::{gtk, ComponentSender}; +use relm4::{Component, ComponentParts}; + +#[derive(Debug, Clone, PartialEq, Eq)] +/// A simple wrapper around [`gtk::ComboBox`]. +/// +/// This can be used with enums, [`String`]s or any custom type you want. +/// The only requirement is that the inner type implements [`ToString`] and [`Debug`]. +/// +/// To get notified when the selection changed, you can use +/// [`Connector::forward()`](relm4::component::Connector::forward()) +/// after launching the component. +pub struct SimpleComboBox { + /// The variants that can be selected. + pub variants: Vec, + /// The index of the active element or [`None`] is nothing is selected. + pub active_index: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +/// The message type of [`SimpleComboBox`]. +pub enum SimpleComboBoxMsg { + /// Overwrite the current values. + UpdateData(SimpleComboBox), + /// Set the index of the active element. + SetActiveIdx(usize), + #[doc(hidden)] + UpdateIndex(usize), +} + +impl Component for SimpleComboBox +where + E: ToString + 'static + Debug, +{ + type CommandOutput = (); + type Input = SimpleComboBoxMsg; + type Output = usize; + type Init = Self; + type Root = gtk::ComboBoxText; + type Widgets = gtk::ComboBoxText; + + fn init_root() -> Self::Root { + gtk::ComboBoxText::default() + } + + fn init( + model: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let widgets = root.clone(); + + model.render(&widgets); + + widgets.connect_changed(move |combo_box| { + if let Some(active_idx) = combo_box.active() { + sender.input(Self::Input::UpdateIndex(active_idx as usize)); + } + }); + + ComponentParts { model, widgets } + } + + fn update_with_view( + &mut self, + widgets: &mut Self::Widgets, + input: Self::Input, + sender: ComponentSender, + _root: &Self::Root, + ) { + match input { + SimpleComboBoxMsg::UpdateIndex(idx) => { + // Ignore send errors because the component might + // be detached. + sender.output(idx).ok(); + self.active_index = Some(idx); + } + SimpleComboBoxMsg::SetActiveIdx(idx) => { + if idx < self.variants.len() { + self.active_index = Some(idx); + widgets.set_active(u32::try_from(idx).ok()); + } + } + SimpleComboBoxMsg::UpdateData(data) => { + *self = data; + self.render(widgets); + } + } + } +} + +impl SimpleComboBox +where + E: ToString, +{ + fn render(&self, combo_box: >k::ComboBoxText) { + combo_box.remove_all(); + + for (idx, e) in self.variants.iter().enumerate() { + combo_box.insert_text(idx as i32, &e.to_string()); + } + + combo_box.set_active(self.active_index.and_then(|val| u32::try_from(val).ok())); + } + + /// Return the value of the currently selected element or [`None`] if nothing is selected. + #[must_use] + pub fn get_active_elem(&self) -> Option<&E> { + self.active_index.map(|idx| &self.variants[idx]) + } +} diff --git a/Relm4-0.6.2/relm4-components/src/web_image.rs b/Relm4-0.6.2/relm4-components/src/web_image.rs new file mode 100644 index 0000000..9867a4e --- /dev/null +++ b/Relm4-0.6.2/relm4-components/src/web_image.rs @@ -0,0 +1,143 @@ +//! Reusable and easily configurable component for loading images from the web. + +use std::collections::VecDeque; +use std::fmt::Debug; + +use relm4::gtk::prelude::{BoxExt, Cast, WidgetExt}; +use relm4::{gtk, Component, ComponentParts, ComponentSender}; + +#[derive(Debug, Clone, PartialEq, Eq)] +/// Reusable component for loading images from the web. +pub struct WebImage { + current_id: usize, + current_widget: gtk::Widget, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +/// Load or unload a web image. +pub enum WebImageMsg { + /// Load an image from an url. + LoadImage(String), + /// Unload the current image. + Unload, +} + +impl Component for WebImage { + type CommandOutput = Option<(usize, VecDeque)>; + type Input = WebImageMsg; + type Output = (); + type Init = String; + type Root = gtk::Box; + type Widgets = (); + + fn init_root() -> Self::Root { + gtk::Box::default() + } + + fn init( + url: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let widget = gtk::Box::default(); + root.append(&widget); + let current_widget = Self::set_spinner(root, widget.upcast_ref()); + + let model = Self { + current_id: 0, + current_widget, + }; + + model.load_image(&sender, url); + + ComponentParts { model, widgets: () } + } + + fn update(&mut self, input: Self::Input, sender: ComponentSender, root: &Self::Root) { + self.current_widget = Self::set_spinner(root, &self.current_widget); + self.current_id = self.current_id.wrapping_add(1); + + match input { + WebImageMsg::LoadImage(url) => { + self.load_image(&sender, url); + } + WebImageMsg::Unload => (), + } + } + + fn update_cmd( + &mut self, + message: Self::CommandOutput, + sender: ComponentSender, + root: &Self::Root, + ) { + if let Some((id, data)) = message { + if id == self.current_id { + if let Some(img) = Self::generate_image(data) { + self.current_widget = Self::set_image(root, &self.current_widget, &img); + sender.output(()).ok(); + } + } + } + } +} + +impl WebImage { + #[must_use] + fn set_spinner(root: &::Root, widget: >k::Widget) -> gtk::Widget { + root.remove(widget); + relm4::view! { + #[local_ref] + root -> gtk::Box { + set_halign: gtk::Align::Center, + set_valign: gtk::Align::Center, + + #[name(spinner)] + gtk::Spinner { + start: (), + set_hexpand: true, + set_vexpand: true, + } + } + } + spinner.upcast() + } + + #[must_use] + fn set_image( + root: &::Root, + widget: >k::Widget, + img: >k::Image, + ) -> gtk::Widget { + root.remove(widget); + relm4::view! { + #[local_ref] + root -> gtk::Box { + set_halign: gtk::Align::Fill, + set_valign: gtk::Align::Fill, + + #[local_ref] + img -> gtk::Image { + set_hexpand: true, + set_vexpand: true, + } + } + } + img.clone().upcast() + } + + fn load_image(&self, sender: &ComponentSender, url: String) { + sender.oneshot_command(Self::get_img_data(self.current_id, url)); + } + + fn generate_image(data: VecDeque) -> Option { + let pixbuf = gtk::gdk_pixbuf::Pixbuf::from_read(data).ok()?; + Some(gtk::Image::from_pixbuf(Some(&pixbuf))) + } + + async fn get_img_data(id: usize, url: String) -> Option<(usize, VecDeque)> { + let response = reqwest::get(url).await.ok()?; + let bytes = response.bytes().await.ok()?; + Some((id, bytes.into_iter().collect())) + } +} diff --git a/Relm4-0.6.2/relm4-macros/Cargo.toml b/Relm4-0.6.2/relm4-macros/Cargo.toml new file mode 100644 index 0000000..6d3f8ef --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "relm4-macros" +readme = "README.md" +keywords = ["gui", "gtk", "gtk4", "elm", "view"] +documentation = "https://docs.rs/relm4_macros/" + +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +description.workspace = true + +homepage.workspace = true +repository.workspace = true + +categories.workspace = true + +[lib] +proc-macro = true + +[features] +default = ["relm4"] + +# Without the default "relm4" feature, all imports of gtk will +# be `use gtk;` instead of `use relm4::gtk;` thus making it +# easier to use this crate without Relm4. +relm4 = [] + +[dependencies] +proc-macro2 = "1.0" +quote = "1.0" +syn = { version = "2.0", features = [ + "full", + "extra-traits", + "visit", + "visit-mut", +] } + +[dev-dependencies] +relm4 = { path = "../relm4" } +rustversion = "1" +trybuild = "1.0.80" diff --git a/Relm4-0.6.2/relm4-macros/README.md b/Relm4-0.6.2/relm4-macros/README.md new file mode 100644 index 0000000..a741e41 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/README.md @@ -0,0 +1,6 @@ +# Relm4-macros + +[![Relm4-macros on crates.io](https://img.shields.io/crates/v/relm4-macros.svg)](https://crates.io/crates/relm4-macros) +[![Relm4-macros docs](https://img.shields.io/badge/rust-documentation-blue)](https://docs.rs/relm4_macros/) + +A macro to easily generate UIs for Relm4 applications. diff --git a/Relm4-0.6.2/relm4-macros/src/additional_fields.rs b/Relm4-0.6.2/relm4-macros/src/additional_fields.rs new file mode 100644 index 0000000..8648a23 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/additional_fields.rs @@ -0,0 +1,24 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::ToTokens; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::{Field, Result, Token}; + +#[derive(Debug)] +pub(super) struct AdditionalFields { + pub(super) inner: Punctuated, +} + +impl Parse for AdditionalFields { + fn parse(input: ParseStream<'_>) -> Result { + Ok(AdditionalFields { + inner: input.parse_terminated(Field::parse_named, Token![,])?, + }) + } +} + +impl ToTokens for AdditionalFields { + fn to_tokens(&self, tokens: &mut TokenStream2) { + tokens.extend(self.inner.to_token_stream()); + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/args.rs b/Relm4-0.6.2/relm4-macros/src/args.rs new file mode 100644 index 0000000..8edf0b4 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/args.rs @@ -0,0 +1,49 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote_spanned, ToTokens}; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::{Pair, Punctuated}; +use syn::spanned::Spanned; +use syn::{Error, Result, Token}; + +#[derive(Debug)] +pub(super) struct Args +where + T: Parse + ToTokens, +{ + pub(super) inner: Vec, +} + +impl Parse for Args +where + T: Parse + ToTokens, +{ + fn parse(input: ParseStream<'_>) -> Result { + let punct: Punctuated = input.call(Punctuated::parse_terminated)?; + if punct.is_empty() { + return Err(Error::new(input.span(), "Expected at least one element. This is probably caused by empty arguments and macros.")); + } + let inner = punct.into_pairs().map(Pair::into_value).collect(); + + Ok(Args { inner }) + } +} + +impl ToTokens for Args +where + T: Parse + ToTokens, +{ + fn to_tokens(&self, out: &mut TokenStream2) { + let mut iter = self.inner.iter(); + + let first = iter.next().unwrap(); + out.extend(quote_spanned! { + first.span() => #first + }); + + for expr in iter { + out.extend(quote_spanned! { + expr.span() => ,#expr + }); + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/attrs.rs b/Relm4-0.6.2/relm4-macros/src/attrs.rs new file mode 100644 index 0000000..89b0ac7 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/attrs.rs @@ -0,0 +1,77 @@ +use syn::parse::{Parse, ParseStream}; +use syn::spanned::Spanned; +use syn::token::Async; +use syn::{Error, Result, Token, Visibility}; + +pub(super) struct Attrs { + /// Keeps information about visibility of the widget + pub(super) visibility: Option, + /// Whether an async trait is used or not + pub(super) asyncness: Option, +} + +pub(super) struct SyncOnlyAttrs { + /// Keeps information about visibility of the widget + pub(super) visibility: Option, +} + +impl Parse for SyncOnlyAttrs { + fn parse(input: ParseStream<'_>) -> Result { + let Attrs { + visibility, + asyncness, + } = input.parse()?; + + if let Some(async_token) = asyncness { + Err(syn::Error::new( + async_token.span, + "this macro doesn't support async traits", + )) + } else { + Ok(Self { visibility }) + } + } +} + +impl Parse for Attrs { + fn parse(input: ParseStream<'_>) -> Result { + let mut attrs = Attrs { + visibility: None, + asyncness: None, + }; + + while !input.is_empty() { + if input.peek(Async) { + let new_asyncness: Async = input.parse()?; + if attrs.asyncness.is_some() { + return Err(syn::Error::new( + new_asyncness.span, + "cannot specify asyncness twice", + )); + } else { + attrs.asyncness = Some(new_asyncness); + } + } else { + let new_vis: Visibility = input.parse()?; + if attrs.visibility.is_some() { + return Err(syn::Error::new( + new_vis.span(), + "cannot specify visibility twice", + )); + } else { + attrs.visibility = Some(new_vis); + } + } + + if input.peek(Token![,]) { + let comma: Token![,] = input.parse()?; + if input.is_empty() { + // We've just consumed last token in stream (which is comma) and that's wrong + return Err(Error::new(comma.span, "expected visibility or `async`")); + } + } + } + + Ok(attrs) + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/component/mod.rs b/Relm4-0.6.2/relm4-macros/src/component/mod.rs new file mode 100644 index 0000000..025e032 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/component/mod.rs @@ -0,0 +1,192 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, quote_spanned, ToTokens}; +use syn::parse_quote; +use syn::visit_mut::VisitMut; + +use crate::attrs::Attrs; +use crate::token_streams::{TokenStreams, TraitImplDetails}; +use crate::util; +use crate::visitors::{ComponentVisitor, PreAndPostView, ViewOutputExpander}; + +pub(crate) fn generate_tokens( + global_attributes: Attrs, + mut component_impl: syn::ItemImpl, +) -> TokenStream2 { + let Attrs { + visibility, + asyncness, + } = global_attributes; + + let mut errors = vec![]; + + let mut component_visitor = ComponentVisitor::new(&mut errors); + + component_visitor.visit_item_impl_mut(&mut component_impl); + + let additional_fields = component_visitor.additional_fields.take(); + + let menus_stream = component_visitor + .menus + .take() + .map(|menus| menus.menus_stream()); + + let mut struct_fields = None; + + match &component_visitor.view_widgets { + None => component_visitor.errors.push(syn::Error::new_spanned( + &component_impl, + "expected `view!` macro invocation", + )), + Some(Err(e)) => component_visitor.errors.push(e.clone()), + _ => (), + } + + if let ComponentVisitor { + view_widgets: Some(Ok(view_widgets)), + model_name: Some(model_name), + root_name: Some(root_name), + sender_name: Some(sender_name), + errors, + .. + } = component_visitor + { + let trait_impl_details = TraitImplDetails { + vis: visibility.clone(), + model_name, + sender_name, + root_name: Some(root_name), + }; + + let TokenStreams { + error, + init_root, + rename_root, + struct_fields: struct_fields_stream, + init: init_widgets, + assign, + return_fields, + destructure_fields, + update_view, + } = view_widgets.generate_streams(&trait_impl_details, false); + + let model_name = trait_impl_details.model_name; + + struct_fields = Some(struct_fields_stream); + let root_widget_type = view_widgets.root_type(); + + // Extract identifiers from additional fields for struct initialization: "test: u8" => "test" + let additional_fields_return_stream = if let Some(fields) = &additional_fields { + let mut tokens = TokenStream2::new(); + for field in fields.inner.pairs() { + tokens.extend(field.value().ident.to_token_stream()); + tokens.extend(quote! {,}); + } + tokens + } else { + TokenStream2::new() + }; + + let view_code = quote! { + #rename_root + #menus_stream + #init_widgets + #assign + { + #error + } + }; + + let widgets_return_code = parse_quote! { + Self::Widgets { + #return_fields + #additional_fields_return_stream + } + }; + + ViewOutputExpander::expand(&mut component_impl, view_code, widgets_return_code, errors); + + component_impl.items.push(parse_quote! { + type Root = #root_widget_type; + }); + + let ty: syn::Type = parse_quote!(Self::Root); + let init_root = util::verbatim_impl_item_fn("init_root", Vec::new(), ty, init_root); + component_impl.items.push(init_root); + + let PreAndPostView { + pre_view, + post_view, + .. + } = PreAndPostView::extract(&mut component_impl, errors); + + let sender_ty: syn::TypePath = if asyncness.is_some() { + parse_quote! { relm4::AsyncComponentSender } + } else { + parse_quote! { relm4::ComponentSender } + }; + + component_impl.items.push(parse_quote! { + /// Update the view to represent the updated model. + fn update_view( + &self, + widgets: &mut Self::Widgets, + sender: #sender_ty, + ) { + struct __DoNotReturnManually; + + let _no_manual_return: __DoNotReturnManually = (move || { + #[allow(unused_variables)] + let Self::Widgets { + #destructure_fields + #additional_fields_return_stream + } = widgets; + + #[allow(unused_variables)] + let #model_name = self; + + #(#pre_view)* + #update_view + // In post_view returning early is ok + (move || { #(#post_view)* })(); + + __DoNotReturnManually + })(); + } + }); + } + + // Use the widget type if used. + let widgets_name = util::generate_widgets_type( + component_visitor.widgets_ty, + &mut component_impl, + &mut errors, + ); + + let widgets_struct = widgets_name.map(|widgets_name| { + let outer_attrs = &component_impl.attrs; + quote! { + #[allow(dead_code)] + #(#outer_attrs)* + #[derive(Debug)] + #visibility struct #widgets_name { + #struct_fields + #additional_fields + } + } + }); + + let errors = errors.iter().map(syn::Error::to_compile_error); + + let async_trait = asyncness.map( + |async_token| quote_spanned!(async_token.span => #[relm4::async_trait::async_trait(?Send)]), + ); + + quote! { + #widgets_struct + + #async_trait + #component_impl + + #(#errors)* + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/factory/mod.rs b/Relm4-0.6.2/relm4-macros/src/factory/mod.rs new file mode 100644 index 0000000..df2c8bd --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/factory/mod.rs @@ -0,0 +1,216 @@ +use proc_macro2::{Span as Span2, TokenStream as TokenStream2}; +use quote::{quote, quote_spanned, ToTokens}; +use syn::visit_mut::VisitMut; +use syn::{parse_quote, Ident}; + +use crate::attrs::Attrs; +use crate::token_streams::{TokenStreams, TraitImplDetails}; +use crate::util; +use crate::visitors::{FactoryComponentVisitor, PreAndPostView, ViewOutputExpander}; + +pub(crate) fn generate_tokens( + global_attributes: Attrs, + mut factory_impl: syn::ItemImpl, +) -> TokenStream2 { + let Attrs { + visibility, + asyncness, + } = global_attributes; + + let mut errors = vec![]; + + let mut factory_visitor = FactoryComponentVisitor::new(&mut errors); + factory_visitor.visit_item_impl_mut(&mut factory_impl); + + let additional_fields = factory_visitor.additional_fields.take(); + + let menus_stream = factory_visitor.menus.take().map(|m| m.menus_stream()); + + let mut struct_fields = None; + + match &factory_visitor.view_widgets { + None => factory_visitor.errors.push(syn::Error::new_spanned( + &factory_impl, + "expected `view!` macro invocation", + )), + Some(Err(e)) => factory_visitor.errors.push(e.clone()), + _ => (), + } + + // Insert default index type for sync variants + // if it wasn't specified by the user. + if factory_visitor.index_ty.is_none() && asyncness.is_none() { + factory_impl.items.push(parse_quote! { + type Index = relm4::factory::DynamicIndex; + }); + } + + if let FactoryComponentVisitor { + view_widgets: Some(Ok(view_widgets)), + root_name, + init_widgets, + errors, + .. + } = factory_visitor + { + let TokenStreams { + error, + init_root, + rename_root, + struct_fields: struct_fields_stream, + init, + assign, + return_fields, + destructure_fields, + update_view, + } = view_widgets.generate_streams( + &TraitImplDetails { + vis: visibility.clone(), + model_name: Ident::new("self", Span2::call_site()), + root_name: Some( + root_name.unwrap_or_else(|| Ident::new("root", Span2::call_site())), + ), + sender_name: Ident::new("sender", Span2::call_site()), + }, + false, + ); + + struct_fields = Some(struct_fields_stream); + + let root_widget_type = view_widgets.root_type(); + + // Extract identifiers from additional fields for struct initialization: "test: u8" => "test" + let additional_fields_return_stream = if let Some(fields) = &additional_fields { + let mut tokens = TokenStream2::new(); + for field in fields.inner.pairs() { + tokens.extend(field.value().ident.to_token_stream()); + tokens.extend(quote! {,}); + } + tokens + } else { + TokenStream2::new() + }; + + let view_code = quote! { + #rename_root + #menus_stream + #init + #assign + { + #error + } + }; + + let widgets_return_code = parse_quote! { + Self::Widgets { + #return_fields + #additional_fields_return_stream + } + }; + + let sender_ty: Ident = if asyncness.is_some() { + parse_quote! { AsyncFactorySender } + } else { + parse_quote! { FactorySender } + }; + + let index_ty: syn::TypePath = if asyncness.is_some() { + parse_quote! { relm4::factory::DynamicIndex } + } else { + parse_quote! { Self::Index } + }; + + if init_widgets.is_some() { + ViewOutputExpander::expand(&mut factory_impl, view_code, widgets_return_code, errors); + } else { + factory_impl.items.push(parse_quote! { + fn init_widgets( + &mut self, + index: & #index_ty, + root: &Self::Root, + returned_widget: &::ReturnedWidget, + sender: relm4::factory::#sender_ty, + ) -> Self::Widgets { + #view_code + #widgets_return_code + } + }); + } + + factory_impl.items.push(parse_quote! { + type Root = #root_widget_type; + }); + + let ty: syn::Type = parse_quote!(Self::Root); + factory_impl.items.push(if asyncness.is_some() { + util::verbatim_impl_item_fn("init_root", Vec::new(), ty, init_root) + } else { + let args = vec![parse_quote! { &self}]; + util::verbatim_impl_item_fn("init_root", args, ty, init_root) + }); + + let PreAndPostView { + pre_view, + post_view, + .. + } = PreAndPostView::extract(&mut factory_impl, errors); + + factory_impl.items.push(parse_quote! { + // Update the view to represent the updated model. + fn update_view( + &self, + widgets: &mut Self::Widgets, + sender: relm4::factory::#sender_ty, + ) { + struct __DoNotReturnManually; + + let _no_manual_return: __DoNotReturnManually = (move || { + #[allow(unused_variables)] + let Self::Widgets { + #destructure_fields + #additional_fields_return_stream + } = widgets; + + #(#pre_view)* + #update_view + // In post_view returning early is ok + (move || { #(#post_view)* })(); + + __DoNotReturnManually + })(); + } + }); + } + + // Use the widget type if used. + let widgets_name = + util::generate_widgets_type(factory_visitor.widgets_ty, &mut factory_impl, &mut errors); + + let widgets_struct = widgets_name.map(|ty| { + let outer_attrs = &factory_impl.attrs; + quote! { + #[allow(dead_code)] + #(#outer_attrs)* + #[derive(Debug)] + #visibility struct #ty { + #struct_fields + #additional_fields + } + } + }); + + let errors = errors.iter().map(syn::Error::to_compile_error); + + let async_trait = asyncness.map( + |async_token| quote_spanned!(async_token.span => #[relm4::async_trait::async_trait(?Send)]), + ); + + quote! { + #widgets_struct + + #async_trait + #factory_impl + + #(#errors)* + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/lib.rs b/Relm4-0.6.2/relm4-macros/src/lib.rs new file mode 100644 index 0000000..4398a78 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/lib.rs @@ -0,0 +1,648 @@ +//! A collection of macros for gtk-rs, Relm4 and Rust in general. +//! +//! Docs of related crates: +//! [relm4](https://docs.rs/relm4) +//! | [relm4-macros](https://docs.rs/relm4_macros) +//! | [relm4-components](https://docs.rs/relm4_components) +//! | [gtk4-rs](https://gtk-rs.org/gtk4-rs/git/docs) +//! | [gtk-rs-core](https://gtk-rs.org/gtk-rs-core/git/docs) +//! | [libadwaita-rs](https://world.pages.gitlab.gnome.org/Rust/libadwaita-rs/git/docs/libadwaita) +//! | [libpanel-rs](https://world.pages.gitlab.gnome.org/Rust/libpanel-rs/git/docs/libpanel) +//! +//! [GitHub](https://github.com/Relm4/Relm4) +//! | [Website](https://relm4.org) +//! | [Book](https://relm4.org/book/stable/) +//! | [Blog](https://relm4.org/blog) + +#![doc(html_logo_url = "https://relm4.org/icons/relm4_logo.svg")] +#![doc(html_favicon_url = "https://relm4.org/icons/relm4_org.svg")] +#![warn( + missing_debug_implementations, + missing_docs, + rust_2018_idioms, + unreachable_pub, + unused_qualifications, + clippy::cargo, + clippy::must_use_candidate +)] + +use proc_macro::TokenStream; +use syn::{parse_macro_input, ItemImpl}; + +mod additional_fields; +mod args; +mod attrs; +mod component; +mod menu; +mod view; +mod visitors; +mod widgets; + +#[macro_use] +mod util; +mod factory; +mod token_streams; +mod widget_template; + +use attrs::{Attrs, SyncOnlyAttrs}; +use menu::Menus; + +fn gtk_import() -> syn::Path { + if cfg!(feature = "relm4") { + util::strings_to_path(&["relm4", "gtk"]) + } else { + util::strings_to_path(&["gtk"]) + } +} + +/// Macro that implements `relm4::Component` or `relm4::SimpleComponent` +/// and generates the corresponding widgets struct. +/// +/// # Attributes +/// +/// To create public struct use `#[component(pub)]` or `#[component(visibility = pub)]`. +/// +/// # Example +/// +/// ``` +/// use relm4::prelude::*; +/// use gtk::prelude::*; +/// +/// #[derive(Default)] +/// struct App { +/// counter: u8, +/// } +/// +/// #[derive(Debug)] +/// enum Msg { +/// Increment, +/// Decrement, +/// } +/// +/// #[relm4_macros::component(pub)] +/// impl SimpleComponent for App { +/// type Init = u8; +/// type Input = Msg; +/// type Output = (); +/// +/// view! { +/// gtk::Window { +/// set_title: Some("Simple app"), +/// set_default_size: (300, 100), +/// gtk::Box { +/// set_orientation: gtk::Orientation::Vertical, +/// set_margin_all: 5, +/// set_spacing: 5, +/// +/// gtk::Button { +/// set_label: "Increment", +/// connect_clicked => Msg::Increment, +/// }, +/// gtk::Button { +/// set_label: "Decrement", +/// connect_clicked[sender] => move |_| { +/// sender.input(Msg::Decrement); +/// }, +/// }, +/// gtk::Label { +/// set_margin_all: 5, +/// #[watch] +/// set_label: &format!("Counter: {}", model.counter), +/// } +/// }, +/// } +/// } +/// +/// fn init( +/// counter: Self::Init, +/// root: &Self::Root, +/// sender: ComponentSender, +/// ) -> ComponentParts { +/// let model = Self { counter }; +/// +/// let widgets = view_output!(); +/// +/// ComponentParts { model, widgets } +/// } +/// +/// fn update(&mut self, msg: Msg, _sender: ComponentSender) { +/// match msg { +/// Msg::Increment => { +/// self.counter = self.counter.wrapping_add(1); +/// } +/// Msg::Decrement => { +/// self.counter = self.counter.wrapping_sub(1); +/// } +/// } +/// } +/// } +/// ``` +/// +/// # Notes on `pre_view` +/// +/// Using `return` in `pre_view` will cause a compiler warning. +/// In general, you don't want to use `return` in `pre_view` as it will +/// cause all following update functionality to be skipped. +/// +/// ```compile_fail +/// # use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt}; +/// # use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent, RelmWidgetExt}; +/// # +/// struct App {} +/// +/// #[relm4_macros::component] +/// impl SimpleComponent for App { +/// /* Code omitted */ +/// # type Init = (); +/// # type Input = (); +/// # type Output = (); +/// # +/// # view! { +/// # gtk::Window {} +/// # } +/// +/// fn pre_view() { +/// return; +/// } +/// # +/// # fn init( +/// # counter: Self::Init, +/// # root: &Self::Root, +/// # sender: ComponentSender, +/// # ) -> ComponentParts { +/// # let model = Self {}; +/// # +/// # let widgets = view_output!(); +/// # +/// # ComponentParts { model, widgets } +/// # } +/// } +/// ``` +#[proc_macro_attribute] +pub fn component(attributes: TokenStream, input: TokenStream) -> TokenStream { + let global_attributes: Attrs = parse_macro_input!(attributes); + let backup_input = input.clone(); + let component_impl_res = syn::parse::(input); + + match component_impl_res { + Ok(component_impl) => component::generate_tokens(global_attributes, component_impl).into(), + Err(_) => util::item_impl_error(backup_input), + } +} + +/// Macro that implements `relm4::factory::FactoryComponent` and generates the corresponding widgets struct. +/// +/// # Attributes +/// +/// To create public struct use `#[factory(pub)]` or `#[factory(visibility = pub)]`. +/// +/// # Example +/// +/// ``` +/// use relm4::prelude::*; +/// use relm4::factory::*; +/// use gtk::prelude::*; +/// +/// # #[derive(Debug)] +/// # enum AppMsg { +/// # AddCounter, +/// # RemoveCounter, +/// # SendFront(DynamicIndex) +/// # } +/// +/// #[derive(Debug)] +/// struct Counter { +/// value: u8, +/// } +/// +/// #[derive(Debug)] +/// enum CounterMsg { +/// Increment, +/// Decrement, +/// } +/// +/// #[derive(Debug)] +/// enum CounterOutput { +/// SendFront(DynamicIndex), +/// } +/// +/// #[relm4_macros::factory(pub)] +/// impl FactoryComponent for Counter { +/// type CommandOutput = (); +/// type Init = u8; +/// type Input = CounterMsg; +/// type Output = CounterOutput; +/// type ParentInput = AppMsg; +/// type ParentWidget = gtk::Box; +/// +/// +/// view! { +/// root = gtk::Box { +/// set_orientation: gtk::Orientation::Horizontal, +/// set_spacing: 10, +/// +/// #[name(label)] +/// gtk::Label { +/// #[watch] +/// set_label: &self.value.to_string(), +/// set_width_chars: 3, +/// }, +/// +/// #[name(add_button)] +/// gtk::Button { +/// set_label: "+", +/// connect_clicked => CounterMsg::Increment, +/// }, +/// +/// #[name(remove_button)] +/// gtk::Button { +/// set_label: "-", +/// connect_clicked => CounterMsg::Decrement, +/// }, +/// +/// #[name(to_front_button)] +/// gtk::Button { +/// set_label: "To start", +/// connect_clicked[sender, index] => move |_| { +/// sender.output(CounterOutput::SendFront(index.clone())) +/// } +/// } +/// } +/// } +/// +/// fn forward_to_parent(output: Self::Output) -> Option { +/// Some(match output { +/// CounterOutput::SendFront(index) => AppMsg::SendFront(index), +/// }) +/// } +/// +/// fn init_model( +/// value: Self::Init, +/// _index: &DynamicIndex, +/// _sender: FactorySender, +/// ) -> Self { +/// Self { value } +/// } +/// +/// fn update(&mut self, msg: Self::Input, _sender: FactorySender) { +/// match msg { +/// CounterMsg::Increment => { +/// self.value = self.value.wrapping_add(1); +/// } +/// CounterMsg::Decrement => { +/// self.value = self.value.wrapping_sub(1); +/// } +/// } +/// } +/// } +/// ``` +#[proc_macro_attribute] +pub fn factory(attributes: TokenStream, input: TokenStream) -> TokenStream { + let attrs = parse_macro_input!(attributes); + let backup_input = input.clone(); + let factory_impl_res = syn::parse::(input); + + match factory_impl_res { + Ok(factory_impl) => factory::generate_tokens(attrs, factory_impl).into(), + Err(_) => util::item_impl_error(backup_input), + } +} + +/// A macro to create menus. +/// +/// Use +/// +/// + `"Label text" => ActionType,` to create new entries. +/// + `"Label text" => ActionType(value),` to create new entries with action value. +/// + `custom => "widget_id",` add a placeholder for custom widgets you can add later with [`set_attribute_name`](https://gtk-rs.org/gtk-rs-core/stable/0.15/docs/gio/struct.MenuItem.html#method.set_attribute_value). +/// + `section! { ... }` to create new sections. +/// +/// # Example +/// +/// ``` +/// # fn gettext(string: &str) -> String { +/// # string.to_owned() +/// # } +/// # +/// // Define some actions +/// relm4::new_action_group!(WindowActionGroup, "win"); +/// relm4::new_stateless_action!(TestAction, WindowActionGroup, "test"); +/// relm4::new_stateful_action!(TestU8Action, WindowActionGroup, "test2", u8, u8); +/// +/// // Create a `MenuModel` called `menu_model` +/// relm4_macros::menu! { +/// main_menu: { +/// custom: "my_widget", +/// // Translate with gettext-rs, for example. +/// &gettext("Test") => TestAction, +/// "Test2" => TestAction, +/// "Test toggle" => TestU8Action(1_u8), +/// section! { +/// "Section test" => TestAction, +/// "Test toggle" => TestU8Action(1_u8), +/// }, +/// section! { +/// "Test" => TestAction, +/// "Test2" => TestAction, +/// "Test Value" => TestU8Action(1_u8), +/// } +/// } +/// }; +/// ``` +/// +/// # Macro expansion +/// +/// The code generation for the example above looks like this (plus comments): +/// +/// ``` +/// # fn gettext(string: &str) -> String { +/// # string.to_owned() +/// # } +/// # +/// struct WindowActionGroup; +/// impl relm4::actions::ActionGroupName for WindowActionGroup { +/// const NAME: &'static str = "win"; +/// } +/// +/// struct TestAction; +/// impl relm4::actions::ActionName for TestAction { +/// type Group = WindowActionGroup; +/// type State = (); +/// type Target = (); +/// +/// const NAME: &'static str = "test"; +/// } +/// +/// struct TestU8Action; +/// impl relm4::actions::ActionName for TestU8Action { +/// type Group = WindowActionGroup; +/// type State = u8; +/// type Target = u8; +/// +/// const NAME: &'static str = "test2"; +/// } +/// +/// // Main menu +/// let main_menu = relm4::gtk::gio::Menu::new(); +/// +/// // Placeholder for custom widget +/// let new_entry = relm4::gtk::gio::MenuItem::new(None, None); +/// let variant = relm4::gtk::glib::variant::ToVariant::to_variant("my_widget"); +/// new_entry.set_attribute_value("custom", Some(&variant)); +/// main_menu.append_item(&new_entry); +/// +/// let new_entry = relm4::actions::RelmAction::::to_menu_item(&gettext("Test")); +/// main_menu.append_item(&new_entry); +/// let new_entry = relm4::actions::RelmAction::::to_menu_item("Test2"); +/// main_menu.append_item(&new_entry); +/// let new_entry = relm4::actions::RelmAction::::to_menu_item_with_target_value( +/// "Test toggle", +/// &1_u8, +/// ); +/// main_menu.append_item(&new_entry); +/// +/// // Section 0 +/// let _section_0 = relm4::gtk::gio::Menu::new(); +/// main_menu.append_section(None, &_section_0); +/// let new_entry = relm4::actions::RelmAction::::to_menu_item("Section test"); +/// _section_0.append_item(&new_entry); +/// let new_entry = relm4::actions::RelmAction::::to_menu_item_with_target_value( +/// "Test toggle", +/// &1_u8, +/// ); +/// _section_0.append_item(&new_entry); +/// +/// // Section 1 +/// let _section_1 = relm4::gtk::gio::Menu::new(); +/// main_menu.append_section(None, &_section_1); +/// let new_entry = relm4::actions::RelmAction::::to_menu_item("Test"); +/// _section_1.append_item(&new_entry); +/// let new_entry = relm4::actions::RelmAction::::to_menu_item("Test2"); +/// _section_1.append_item(&new_entry); +/// let new_entry = relm4::actions::RelmAction::::to_menu_item_with_target_value( +/// "Test Value", +/// &1_u8, +/// ); +/// _section_1.append_item(&new_entry); +/// ``` +#[proc_macro] +pub fn menu(input: TokenStream) -> TokenStream { + let menus = parse_macro_input!(input as Menus); + menus.menus_stream().into() +} + +/// The [`view!`] macro allows you to construct your UI easily and cleanly. +/// +/// It does the same as inside the [`macro@component`] attribute macro, +/// but with less features. +/// +/// You can even use the `relm4-macros` crate independently from Relm4 to build your GTK4 UI. +/// +/// ```no_run +/// use gtk::prelude::{BoxExt, ButtonExt}; +/// use relm4::gtk; +/// +/// // Creating a box with a button inside. +/// relm4_macros::view! { +/// vbox = gtk::Box { +/// gtk::Button { +/// set_label: "Click me!", +/// connect_clicked => |_| { +/// println!("Hello world!"); +/// } +/// }, +/// prepend: my_label = >k::Label::builder() +/// .label("The view macro works!") +/// .build(), +/// } +/// } +/// +/// // You can simply use the vbox created in the macro. +/// let spacing = vbox.spacing(); +/// ``` +/// +/// Also, the macro doesn't rely on any special gtk4-rs features +/// so you can even use the macro for other purposes. +/// +/// In this example, we use it to construct a [`Command`](std::process::Command). +/// +/// ``` +/// use std::process::Command; +/// +/// let path = "/"; +/// +/// relm4_macros::view! { +/// mut process = Command::new("ls") { +/// args: ["-la"], +/// current_dir = mut &String { +/// push_str: path, +/// }, +/// env: ("HOME", "/home/relm4"), +/// } +/// } +/// +/// // Output of "ls -la" at "/" +/// dbg!(process.output()); +/// ``` +/// # Macro expansion +/// +/// Let's have a look the this example: +/// +/// ```no_run +/// # use gtk::prelude::{BoxExt, ButtonExt}; +/// # use relm4::gtk; +/// // Creating a box with a button inside. +/// relm4_macros::view! { +/// vbox = gtk::Box { +/// gtk::Button { +/// set_label: "Click me!", +/// connect_clicked => |_| { +/// println!("Hello world!"); +/// } +/// }, +/// prepend: my_label = >k::Label::builder() +/// .label("The view macro works!") +/// .build(), +/// } +/// } +/// ``` +/// +/// The code generation for this example looks like this (plus comments): +/// +/// ```no_run +/// # use gtk::prelude::{BoxExt, ButtonExt}; +/// # use relm4::gtk; +/// +/// // We've just used `gtk::Box` so we assume it has a `default()` method +/// let vbox = gtk::Box::default(); +/// // `vbox` was named, yet the button doesn't have an explicit name and gets a generated one instead. +/// let _gtk_button_5 = gtk::Button::default(); +/// // For the label, we used a manual constructor method, so no `default()` method is required. +/// let my_label = gtk::Label::builder().label("The view macro works!").build(); +/// +/// // Connect the signal +/// { +/// _gtk_button_5.connect_clicked(|_| { +/// println!("Hello world!"); +/// }); +/// } +/// +/// // The button was added without any further instructions, so we assume `container_add()` will work. +/// relm4::RelmContainerExt::container_add(&vbox, &_gtk_button_5); +/// _gtk_button_5.set_label("Click me!"); +/// // For the label, we used the `prepend` method, so we don't need `container_add()` here. +/// vbox.prepend(&my_label); +/// ``` +/// +/// The widgets are first initialized, then signals are connected and then +/// properties and widgets are assigned to each other. +/// +/// The nested structure of the UI is translated into regular Rust code. +#[proc_macro] +pub fn view(input: TokenStream) -> TokenStream { + view::generate_tokens(input) +} + +/// A macro to generate widget templates. +/// +/// This macro generates a new type that implements `relm4::WidgetTemplate`. +/// +/// # Example +/// +/// ``` +/// use relm4::prelude::*; +/// use gtk::prelude::*; +/// +/// #[relm4::widget_template] +/// impl WidgetTemplate for MyBox { +/// view! { +/// gtk::Box { +/// set_margin_all: 10, +/// // Make the boxes visible +/// inline_css: "border: 2px solid blue", +/// } +/// } +/// } +/// ``` +/// +/// The template allows you the generate deeply nested +/// structures. All named items will be directly accessible +/// as a child of the template, even if they are nested. +/// In this example the "child_label" is a template child. +/// +/// ``` +/// # use relm4::prelude::*; +/// # use gtk::prelude::*; +/// # +/// # #[relm4::widget_template] +/// # impl WidgetTemplate for MyBox { +/// # view! { +/// # gtk::Box { +/// # set_margin_all: 10, +/// # // Make the boxes visible +/// # inline_css: "border: 2px solid blue", +/// # } +/// # } +/// # } +/// # +/// #[relm4::widget_template] +/// impl WidgetTemplate for MySpinner { +/// view! { +/// gtk::Spinner { +/// set_spinning: true, +/// } +/// } +/// } +/// +/// #[relm4::widget_template] +/// impl WidgetTemplate for CustomBox { +/// view! { +/// gtk::Box { +/// set_orientation: gtk::Orientation::Vertical, +/// set_margin_all: 5, +/// set_spacing: 5, +/// +/// #[template] +/// MyBox { +/// #[template] +/// MySpinner, +/// +/// #[template] +/// MyBox { +/// #[template] +/// MySpinner, +/// +/// #[template] +/// MyBox { +/// #[template] +/// MySpinner, +/// +/// // Deeply nested! +/// #[name = "child_label"] +/// gtk::Label { +/// set_label: "This is a test", +/// } +/// } +/// } +/// } +/// } +/// } +/// } +/// ``` +#[proc_macro_attribute] +pub fn widget_template(attributes: TokenStream, input: TokenStream) -> TokenStream { + let SyncOnlyAttrs { visibility } = parse_macro_input!(attributes); + + let item_impl = parse_macro_input!(input as ItemImpl); + widget_template::generate_tokens(visibility, item_impl).into() +} + +#[cfg(test)] +#[rustversion::all(stable, since(1.69))] +mod test { + #[test] + fn ui() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/compile-fail/**/*.rs"); + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/menu/gen.rs b/Relm4-0.6.2/relm4-macros/src/menu/gen.rs new file mode 100644 index 0000000..5c4d9e7 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/menu/gen.rs @@ -0,0 +1,136 @@ +use proc_macro2::{Span as Span2, TokenStream as TokenStream2}; +use quote::{quote, quote_spanned}; +use syn::{spanned::Spanned, Ident, LitStr}; + +use super::{Menu, MenuElement, MenuEntry, MenuItem, MenuSection, Menus, SubMenu}; + +impl Menus { + pub(crate) fn menus_stream(&self) -> TokenStream2 { + let mut menu_stream = TokenStream2::new(); + + for item in &self.items { + menu_stream.extend(item.menu_stream()); + } + + menu_stream + } +} + +impl Menu { + fn menu_stream(&self) -> TokenStream2 { + let name = &self.name; + let gtk_import = crate::gtk_import(); + + // Create new menu + let mut menu_stream = quote_spanned! { + name.span() => + let #name = #gtk_import ::gio::Menu::new(); + }; + + // Add items + for item in &self.items { + menu_stream.extend(item.item_stream(name)); + } + + menu_stream + } +} + +impl MenuElement { + fn item_stream(&self, parent_ident: &Ident) -> TokenStream2 { + let mut item_stream = TokenStream2::new(); + + item_stream.extend(match self { + Self::Item(entry) => entry.item_stream(parent_ident), + Self::Section(section) => section.section_stream(parent_ident), + Self::Custom(id) => custom_stream(parent_ident, id), + }); + + item_stream + } +} + +fn custom_stream(parent_ident: &Ident, id: &LitStr) -> TokenStream2 { + let gtk_import = crate::gtk_import(); + quote_spanned! { + id.span() => + let new_entry = #gtk_import::gio::MenuItem::new(None, None); + let variant = #gtk_import::glib::variant::ToVariant::to_variant(#id); + new_entry.set_attribute_value("custom", Some(&variant)); + #parent_ident.append_item(&new_entry); + } +} + +impl MenuItem { + fn item_stream(&self, parent_ident: &Ident) -> TokenStream2 { + match self { + Self::Entry(entry) => entry.entry_stream(parent_ident), + Self::SubMenu(sub_menu) => sub_menu.submenu_stream(parent_ident), + } + } +} + +impl SubMenu { + fn submenu_stream(&self, parent_ident: &Ident) -> TokenStream2 { + let name = Ident::new(&format!("_{parent_ident}"), Span2::call_site()); + let gtk_import = crate::gtk_import(); + let expr = &self.expr; + + // Create new sub-menu + let mut item_stream = quote_spanned! { + expr.span() => + let #name = #gtk_import ::gio::Menu::new(); + #parent_ident.append_submenu(Some(#expr), &#name); + }; + + // Add items + for item in &self.items { + item_stream.extend(item.item_stream(&name)); + } + + // Wrap the generated code in a new scope to avoid side-effects + quote! { + { + #item_stream + } + } + } +} + +impl MenuEntry { + fn entry_stream(&self, parent_ident: &Ident) -> TokenStream2 { + let expr = &self.expr; + let ty = &self.action_ty; + + if let Some(value) = &self.value { + quote_spanned! { + expr.span() => + let new_entry = relm4::actions::RelmAction::<#ty>::to_menu_item_with_target_value(#expr, &#value); + #parent_ident.append_item(&new_entry); + } + } else { + quote_spanned! { + expr.span() => + let new_entry = relm4::actions::RelmAction::<#ty>::to_menu_item(#expr); + #parent_ident.append_item(&new_entry); + } + } + } +} + +impl MenuSection { + fn section_stream(&self, parent_ident: &Ident) -> TokenStream2 { + let name = &self.name; + let gtk_import = crate::gtk_import(); + let mut section_stream = quote! { + let #name = #gtk_import::gio::Menu::new(); + #parent_ident.append_section(None, &#name); + }; + + for item in &self.items { + section_stream.extend(item.item_stream(name)); + } + + section_stream + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/menu/mod.rs b/Relm4-0.6.2/relm4-macros/src/menu/mod.rs new file mode 100644 index 0000000..031da0e --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/menu/mod.rs @@ -0,0 +1,49 @@ +use syn::punctuated::Punctuated; +use syn::token::Comma; +use syn::{Expr, Ident, LitStr, Path}; + +mod gen; +mod parse; + +#[derive(Debug)] +pub(crate) struct Menus { + items: Punctuated, +} + +#[derive(Debug)] +struct Menu { + name: Ident, + items: Punctuated, +} + +#[derive(Debug)] +enum MenuElement { + Item(Box), + Custom(LitStr), + Section(MenuSection), +} + +#[derive(Debug)] +enum MenuItem { + Entry(Box), + SubMenu(Box), +} + +#[derive(Debug)] +struct MenuEntry { + expr: Expr, + action_ty: Path, + value: Option, +} + +#[derive(Debug)] +struct SubMenu { + expr: Expr, + items: Punctuated, +} + +#[derive(Debug)] +struct MenuSection { + name: Ident, + items: Punctuated, +} diff --git a/Relm4-0.6.2/relm4-macros/src/menu/parse.rs b/Relm4-0.6.2/relm4-macros/src/menu/parse.rs new file mode 100644 index 0000000..6ba0353 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/menu/parse.rs @@ -0,0 +1,103 @@ +use proc_macro2::Span as Span2; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::{braced, parenthesized, token, Ident, Path, Result, Token}; + +use crate::menu::SubMenu; + +use super::{Menu, MenuElement, MenuEntry, MenuItem, MenuSection, Menus}; + +syn::custom_keyword!(custom); + +impl Parse for Menus { + fn parse(input: ParseStream<'_>) -> Result { + let items = input.call(Punctuated::parse_separated_nonempty)?; + + Ok(Menus { items }) + } +} + +impl Parse for Menu { + fn parse(input: ParseStream<'_>) -> Result { + let name = input.parse()?; + let _colon: Token![:] = input.parse()?; + + let braced_input; + braced!(braced_input in input); + + let items = braced_input.call(Punctuated::parse_terminated)?; + + Ok(Menu { name, items }) + } +} + +impl Parse for MenuItem { + fn parse(input: ParseStream<'_>) -> Result { + let expr = input.parse()?; + + Ok(if input.peek(Token![=>]) { + let _arrow: Token![=>] = input.parse()?; + let action_ty = input.call(Path::parse_mod_style)?; + + let value = if input.peek(token::Paren) { + let paren_input; + parenthesized!(paren_input in input); + Some(paren_input.parse()?) + } else { + None + }; + + Self::Entry(Box::new(MenuEntry { + expr, + action_ty, + value, + })) + } else { + let braced_input; + braced!(braced_input in input); + + let items = braced_input.call(Punctuated::parse_terminated)?; + + Self::SubMenu(Box::new(SubMenu { expr, items })) + }) + } +} + +impl Parse for MenuElement { + fn parse(input: ParseStream<'_>) -> Result { + Ok(if input.peek(custom) { + let _custom: custom = input.parse()?; + let _colon: Token![:] = input.parse()?; + input.parse().map(MenuElement::Custom)? + } else if input.peek2(Token![!]) { + input.parse().map(MenuElement::Section)? + } else { + input.parse().map(MenuElement::Item)? + }) + } +} + +impl Parse for MenuSection { + fn parse(input: ParseStream<'_>) -> Result { + let name: Ident = input.parse()?; + assert!(name == "section"); + let _excl: Token![!] = input.parse()?; + + let braced_input; + braced!(braced_input in input); + + let items = braced_input.call(Punctuated::parse_terminated)?; + let name = section_name(); + + Ok(MenuSection { name, items }) + } +} + +fn section_name() -> Ident { + use std::sync::atomic::{AtomicU8, Ordering}; + static COUNTER: AtomicU8 = AtomicU8::new(0); + + let value = COUNTER.fetch_add(1, Ordering::Relaxed); + + Ident::new(&format!("_section_{value}"), Span2::call_site()) +} diff --git a/Relm4-0.6.2/relm4-macros/src/token_streams.rs b/Relm4-0.6.2/relm4-macros/src/token_streams.rs new file mode 100644 index 0000000..c7d697b --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/token_streams.rs @@ -0,0 +1,147 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, ToTokens}; +use syn::{Error, Ident, Visibility}; + +use crate::widgets::{TopLevelWidget, ViewWidgets, Widget}; + +#[derive(Default)] +pub(super) struct TokenStreams { + /// Parsing errors + pub(super) error: TokenStream2, + /// Initialize the root widget. + pub(super) init_root: TokenStream2, + /// Rename root to the actual widget name. + pub(super) rename_root: TokenStream2, + /// The tokens for the struct fields -> name: Type, + pub(super) struct_fields: TokenStream2, + /// The tokens initializing the widgets. + pub(super) init: TokenStream2, + /// The tokens initializing the properties. + pub(super) assign: TokenStream2, + /// The tokens for the returned struct fields -> name, + pub(super) return_fields: TokenStream2, + /// For destructuring the widget struct field + pub(super) destructure_fields: TokenStream2, + /// The view tokens (watch! macro) + pub(super) update_view: TokenStream2, +} + +pub(super) struct TraitImplDetails { + /// The visibility of the widgets struct. + pub(super) vis: Option, + /// The name of the model. + pub(super) model_name: Ident, + /// The name of the root widget. + pub(super) root_name: Option, + /// The name of the sender used in the init function. + pub(super) sender_name: Ident, +} + +impl ViewWidgets { + pub(super) fn generate_streams( + &self, + trait_impl_details: &TraitImplDetails, + standalone_view: bool, + ) -> TokenStreams { + let mut streams = TokenStreams::default(); + + for top_level_widget in &self.top_level_widgets { + top_level_widget.generate_streams(&mut streams, trait_impl_details, standalone_view); + } + + streams + } + + /// Get the root widget + pub(super) fn get_root_widget(&self) -> syn::Result<&Widget> { + self.top_level_widgets + .iter() + .find(|w| w.root_attr.is_some()) + .map(|w| &w.inner) + .ok_or_else(|| { + Error::new( + self.span, + "You need to specify the root widget using the `#[root]` attribute.", + ) + }) + } + + /// Generate root type for `Root` parameter in `Component` impl + pub(super) fn root_type(&self) -> TokenStream2 { + match self.get_root_widget() { + Ok(root_widget) => root_widget.func_type_token_stream(), + Err(err) => err.to_compile_error(), + } + } + + /// Get the name of the root widget + pub(super) fn root_name(&self) -> TokenStream2 { + match self.get_root_widget() { + Ok(root_widget) => root_widget.name.to_token_stream(), + Err(err) => err.to_compile_error(), + } + } +} + +impl TopLevelWidget { + fn generate_streams( + &self, + streams: &mut TokenStreams, + trait_impl_details: &TraitImplDetails, + standalone_view: bool, + ) { + let generate_init_root_stream = !standalone_view && self.root_attr.is_some(); + self.inner + .init_token_generation(streams, trait_impl_details, generate_init_root_stream); + } +} + +impl Widget { + pub(super) fn init_token_generation( + &self, + streams: &mut TokenStreams, + trait_impl_details: &TraitImplDetails, + generate_root_init_stream: bool, + ) { + let TraitImplDetails { + vis, + model_name, + root_name, + sender_name, + } = trait_impl_details; + + let name = &self.name; + + // Initialize the root + if generate_root_init_stream { + // For the `component` macro + self.init_root_init_streams(&mut streams.init_root, &mut streams.init); + } else { + // For the `view!` macro + self.init_stream(&mut streams.init); + } + + #[cfg(feature = "relm4")] + streams.assign.extend(quote::quote! { + use relm4::RelmContainerExt as _; + }); + + self.error_stream(&mut streams.error); + self.start_assign_stream(&mut streams.assign, sender_name); + self.init_conditional_init_stream(&mut streams.assign, model_name); + self.struct_fields_stream(&mut streams.struct_fields, vis); + self.return_stream(&mut streams.return_fields); + self.destructure_stream(&mut streams.destructure_fields); + self.init_update_view_stream(&mut streams.update_view, model_name); + + // Rename the `root` to the actual widget name + if generate_root_init_stream { + let mut_token = self.mutable.as_ref(); + if let Some(root_name) = root_name { + streams.rename_root.extend(quote! { + let #mut_token #name = #root_name.clone(); + }); + } + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/util.rs b/Relm4-0.6.2/relm4-macros/src/util.rs new file mode 100644 index 0000000..a18fd2d --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/util.rs @@ -0,0 +1,135 @@ +use proc_macro::TokenStream; +use proc_macro2::{Span as Span2, TokenStream as TokenStream2}; +use syn::punctuated::Punctuated; + +use syn::spanned::Spanned; +use syn::{FnArg, Ident, ImplItem, ItemImpl, Path, PathArguments, PathSegment, Type, TypePath}; + +pub(super) fn generate_widgets_type( + widgets_ty: Option, + component_impl: &mut ItemImpl, + errors: &mut Vec, +) -> Option { + // Use the widget type if used. + if let Some(ty) = widgets_ty { + Some(ty) + } + // Try to generate the type from the self type name. + else if let Type::Path(self_ty) = &*component_impl.self_ty { + let (path, impl_item) = self_ty_to_widgets_ty(self_ty); + component_impl.items.push(impl_item); + Some(path) + } + // Error: No Widget type found or generated. + else { + let msg = "no `Widgets` type found and the type if `Self` in not a path. \ + Please use a path for `Self` or use `type Widgets = WidgetsName;` to name the widgets type."; + errors.push(syn::Error::new( + component_impl + .items + .first() + .map(|i| i.span()) + .unwrap_or_else(|| component_impl.self_ty.span()), + msg, + )); + None + } +} + +pub(super) fn self_ty_to_widgets_ty(self_ty: &TypePath) -> (Type, ImplItem) { + // Retrieve path, remove any generics and append "Widgets" to the last segment. + let mut self_path = self_ty.clone(); + let last_seg = self_path.path.segments.last_mut().unwrap(); + last_seg.arguments = Default::default(); + last_seg.ident = Ident::new(&format!("{}Widgets", last_seg.ident), last_seg.span()); + + // Generate impl item for the trait impl + let impl_item = syn::parse_quote_spanned! { + self_path.span() => type Widgets = #self_path; + }; + + (Type::Path(self_path), impl_item) +} + +pub(super) fn strings_to_path(strings: &[&str]) -> Path { + let path_segments: Vec = strings + .iter() + .map(|string| -> PathSegment { + PathSegment { + ident: Ident::new(string, Span2::call_site()), + arguments: PathArguments::None, + } + }) + .collect(); + Path { + leading_colon: None, + segments: Punctuated::from_iter(path_segments), + } +} + +pub(super) fn item_impl_error(original_input: TokenStream) -> TokenStream { + let macro_impls = quote::quote! { + macro_rules! view_output { + () => { () }; + } + macro_rules! view { + () => {}; + ($tt:tt) => {}; + ($tt:tt $($y:tt)+) => {} + } + } + .into(); + vec![macro_impls, original_input].into_iter().collect() +} + +pub(super) fn verbatim_impl_item_fn( + name: &str, + args: Vec, + ty: Type, + tokens: TokenStream2, +) -> ImplItem { + ImplItem::Fn(syn::ImplItemFn { + attrs: Vec::new(), + vis: syn::Visibility::Inherited, + defaultness: None, + sig: syn::Signature { + constness: None, + asyncness: None, + unsafety: None, + abi: None, + fn_token: syn::token::Fn::default(), + ident: Ident::new(name, Span2::call_site()), + generics: syn::Generics { + lt_token: None, + params: Punctuated::default(), + gt_token: None, + where_clause: None, + }, + paren_token: syn::token::Paren::default(), + inputs: Punctuated::from_iter(args), + variadic: None, + output: syn::ReturnType::Type(syn::token::RArrow::default(), Box::new(ty)), + }, + block: syn::Block { + brace_token: syn::token::Brace::default(), + stmts: vec![syn::Stmt::Expr(syn::Expr::Verbatim(tokens), None)], + }, + }) +} + +/// Returns the identifier for a parameter if it is a binding with an identifier pattern. +pub(super) fn extract_arg_ident(arg: &FnArg) -> syn::Result<&Ident> { + match arg { + syn::FnArg::Typed(pat_type) => match &*pat_type.pat { + syn::Pat::Ident(ident) => Ok(&ident.ident), + pat => Err(syn::Error::new_spanned( + pat, + "parameter binding must be an identifier", + )), + }, + syn::FnArg::Receiver(_) => Err(syn::Error::new_spanned( + arg, + "parameter binding must be an identifier", + )), + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/view.rs b/Relm4-0.6.2/relm4-macros/src/view.rs new file mode 100644 index 0000000..890c2f3 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/view.rs @@ -0,0 +1,35 @@ +use proc_macro::TokenStream; +use proc_macro2::Span as Span2; +use quote::quote; +use syn::{parse_macro_input, Ident}; + +use crate::token_streams::{TokenStreams, TraitImplDetails}; +use crate::widgets::ViewWidgets; + +pub(super) fn generate_tokens(input: TokenStream) -> TokenStream { + let view_widgets: ViewWidgets = parse_macro_input!(input); + + let TokenStreams { + error, + init, + assign, + .. + } = view_widgets.generate_streams( + &TraitImplDetails { + vis: None, + model_name: Ident::new("_", Span2::call_site()), + sender_name: Ident::new("sender", Span2::call_site()), + root_name: None, + }, + true, + ); + + let output = quote! { + #init + #assign + { + #error + } + }; + output.into() +} diff --git a/Relm4-0.6.2/relm4-macros/src/visitors.rs b/Relm4-0.6.2/relm4-macros/src/visitors.rs new file mode 100644 index 0000000..aa685b1 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/visitors.rs @@ -0,0 +1,479 @@ +use std::mem; + +use proc_macro2::TokenStream; +use quote::quote; +use syn::visit::{self, Visit}; +use syn::visit_mut::{self, VisitMut}; +use syn::LocalInit; + +use crate::additional_fields::AdditionalFields; +use crate::menu::Menus; +use crate::util; +use crate::widgets::ViewWidgets; + +#[derive(Debug)] +pub(super) struct ComponentVisitor<'errors> { + pub(super) view_widgets: Option>, + pub(super) widgets_ty: Option, + pub(super) root_name: Option, + pub(super) model_name: Option, + pub(super) sender_name: Option, + pub(super) additional_fields: Option, + pub(super) menus: Option, + pub(super) errors: &'errors mut Vec, +} + +impl<'errors> ComponentVisitor<'errors> { + pub(super) fn new(errors: &'errors mut Vec) -> Self { + ComponentVisitor { + view_widgets: None, + widgets_ty: None, + root_name: None, + model_name: None, + sender_name: None, + additional_fields: None, + menus: None, + errors, + } + } +} + +impl VisitMut for ComponentVisitor<'_> { + fn visit_impl_item_mut(&mut self, item: &mut syn::ImplItem) { + let mut remove = false; + + match item { + syn::ImplItem::Macro(mac) => { + match mac.mac.path.get_ident().map(ToString::to_string).as_deref() { + Some("view") => { + if self.view_widgets.is_some() { + self.errors + .push(syn::Error::new_spanned(&mac, "duplicate view macro")); + } + + self.view_widgets.replace(mac.mac.parse_body()); + + remove = true; + } + Some("additional_fields") => { + match mac.mac.parse_body::() { + Ok(fields) => { + let existing = self.additional_fields.replace(fields); + + if existing.is_some() { + self.errors.push(syn::Error::new_spanned( + mac, + "duplicate additional_fields macro", + )); + } + } + Err(e) => { + self.errors.push(e); + } + }; + + remove = true; + } + Some("menu") => { + match mac.mac.parse_body::() { + Ok(menu) => { + let existing = self.menus.replace(menu); + + if existing.is_some() { + self.errors + .push(syn::Error::new_spanned(mac, "duplicate menu macro")); + } + } + Err(e) => { + self.errors.push(e); + } + }; + remove = true; + } + _ => (), + } + } + syn::ImplItem::Fn(func) => { + if &*func.sig.ident.to_string() == "init" { + let mut init_fn_visitor = InitFnVisitor::default(); + init_fn_visitor.visit_impl_item_fn(func); + + self.model_name = init_fn_visitor.model_name; + self.sender_name = init_fn_visitor.sender_name; + self.root_name = init_fn_visitor.root_name; + self.errors.append(&mut init_fn_visitor.errors); + } + } + _ => (), + } + + if remove { + *item = null_item(); + } + + visit_mut::visit_impl_item_mut(self, item); + } + + fn visit_impl_item_type_mut(&mut self, ty: &mut syn::ImplItemType) { + if ty.ident == "Widgets" { + self.widgets_ty = Some(ty.ty.clone()); + } + } +} + +#[derive(Debug)] +pub(super) struct FactoryComponentVisitor<'errors> { + pub(super) view_widgets: Option>, + pub(super) widgets_ty: Option, + pub(super) index_ty: Option, + pub(super) init_widgets: Option, + pub(super) root_name: Option, + pub(super) additional_fields: Option, + pub(super) menus: Option, + pub(super) errors: &'errors mut Vec, +} + +impl<'errors> FactoryComponentVisitor<'errors> { + pub(super) fn new(errors: &'errors mut Vec) -> Self { + FactoryComponentVisitor { + view_widgets: None, + widgets_ty: None, + index_ty: None, + init_widgets: None, + root_name: None, + additional_fields: None, + menus: None, + errors, + } + } +} + +impl VisitMut for FactoryComponentVisitor<'_> { + fn visit_impl_item_mut(&mut self, item: &mut syn::ImplItem) { + let mut remove = false; + + match item { + syn::ImplItem::Macro(mac) => { + match mac.mac.path.get_ident().map(ToString::to_string).as_deref() { + Some("view") => { + if self.view_widgets.is_some() { + self.errors + .push(syn::Error::new_spanned(&mac, "duplicate view macro")); + } + + self.view_widgets.replace(mac.mac.parse_body()); + + remove = true; + } + Some("additional_fields") => { + match mac.mac.parse_body::() { + Ok(fields) => { + let existing = self.additional_fields.replace(fields); + + if existing.is_some() { + self.errors.push(syn::Error::new_spanned( + mac, + "duplicate additional_fields macro", + )); + } + } + Err(e) => { + self.errors.push(e); + } + }; + + remove = true; + } + Some("menu") => { + match mac.mac.parse_body::() { + Ok(menu) => { + let existing = self.menus.replace(menu); + + if existing.is_some() { + self.errors + .push(syn::Error::new_spanned(mac, "duplicate menu macro")); + } + } + Err(e) => { + self.errors.push(e); + } + }; + remove = true; + } + _ => (), + } + } + syn::ImplItem::Fn(func) => { + if &*func.sig.ident.to_string() == "init_widgets" { + let mut init_fn_visitor = InitWidgetsFnVisitor::default(); + init_fn_visitor.visit_impl_item_fn(func); + + self.root_name = init_fn_visitor.root_name; + self.errors.append(&mut init_fn_visitor.errors); + + let existing = self.init_widgets.replace(func.clone()); + if existing.is_some() { + self.errors.push(syn::Error::new_spanned( + func, + "duplicate init_widgets function", + )); + } + } + } + _ => (), + } + + if remove { + *item = null_item(); + } + + visit_mut::visit_impl_item_mut(self, item); + } + + fn visit_impl_item_type_mut(&mut self, ty: &mut syn::ImplItemType) { + if ty.ident == "Widgets" { + self.widgets_ty = Some(ty.ty.clone()); + } else if ty.ident == "Root" { + self.errors.push(syn::Error::new_spanned( + ty, + "`Root` type is defined by `view!` macro", + )); + } else if ty.ident == "Index" { + self.index_ty = Some(ty.ty.clone()); + } + } +} + +#[derive(Debug, Default)] +struct InitFnVisitor { + root_name: Option, + model_name: Option, + sender_name: Option, + errors: Vec, +} + +impl<'ast> Visit<'ast> for InitFnVisitor { + fn visit_impl_item_fn(&mut self, func: &'ast syn::ImplItemFn) { + let Some(root_arg) = func.sig.inputs.iter().nth(1) else { + return; + }; + let root_name = util::extract_arg_ident(root_arg); + + match root_name { + Ok(root_name) => self.root_name = Some(root_name.clone()), + Err(e) => self.errors.push(e), + } + + let Some(sender_arg) = func.sig.inputs.iter().nth(2) else { + return; + }; + let sender_name = util::extract_arg_ident(sender_arg); + + match sender_name { + Ok(sender_name) => self.sender_name = Some(sender_name.clone()), + Err(e) => self.errors.push(e), + } + + visit::visit_impl_item_fn(self, func); + } + + fn visit_expr_struct(&mut self, expr_struct: &'ast syn::ExprStruct) { + let ident = &expr_struct.path.segments.last().unwrap().ident; + if ident == "ComponentParts" || ident == "AsyncComponentParts" { + for field in &expr_struct.fields { + let member_name = match &field.member { + syn::Member::Named(ident) => Some(ident.to_string()), + syn::Member::Unnamed(_) => None, + }; + + if member_name.as_deref() == Some("model") { + let model_name = match &field.expr { + syn::Expr::Path(path) => { + if let Some(ident) = path.path.get_ident() { + Ok(ident.clone()) + } else { + Err(syn::Error::new_spanned( + path, + "unable to determine model name", + )) + } + } + _ => Err(syn::Error::new_spanned( + &field.expr, + "unable to determine model name", + )), + }; + + match model_name { + Ok(model_name) => self.model_name = Some(model_name), + Err(e) => self.errors.push(e), + } + } + } + } + + visit::visit_expr_struct(self, expr_struct); + } +} + +#[derive(Debug, Default)] +struct InitWidgetsFnVisitor { + root_name: Option, + errors: Vec, +} + +impl<'ast> Visit<'ast> for InitWidgetsFnVisitor { + fn visit_impl_item_fn(&mut self, func: &'ast syn::ImplItemFn) { + let Some(root_arg) = func.sig.inputs.iter().nth(2) else { + return; + }; + let root_name = util::extract_arg_ident(root_arg); + + match root_name { + Ok(root_name) => self.root_name = Some(root_name.clone()), + Err(e) => self.errors.push(e), + } + + visit::visit_impl_item_fn(self, func); + } +} + +#[derive(Debug)] +pub(super) struct PreAndPostView<'errors> { + pub(super) pre_view: Vec, + pub(super) post_view: Vec, + errors: &'errors mut Vec, +} + +impl<'errors> PreAndPostView<'errors> { + pub(super) fn extract(impl_: &mut syn::ItemImpl, errors: &'errors mut Vec) -> Self { + let mut visitor = PreAndPostView { + pre_view: vec![], + post_view: vec![], + errors, + }; + + visitor.visit_item_impl_mut(impl_); + + visitor + } +} + +impl VisitMut for PreAndPostView<'_> { + fn visit_impl_item_mut(&mut self, item: &mut syn::ImplItem) { + if let syn::ImplItem::Fn(func) = item { + match &*func.sig.ident.to_string() { + "pre_view" => { + if !self.pre_view.is_empty() { + self.errors.push(syn::Error::new_spanned( + &func, + "duplicate pre_view function", + )); + } + + self.pre_view = func.block.stmts.clone(); + *item = null_item(); + } + "post_view" => { + if !self.post_view.is_empty() { + self.errors.push(syn::Error::new_spanned( + &func, + "duplicate post_view function", + )); + } + + self.post_view = func.block.stmts.clone(); + *item = null_item(); + } + _ => (), + } + } + + visit_mut::visit_impl_item_mut(self, item); + } +} + +/// Expands the `view_output!` macro expression in the `init` function. +pub(crate) struct ViewOutputExpander<'errors> { + /// Whether a `view_output!` macro expression has been successfully expanded. + expanded: bool, + + /// View initialization code to inject before the view output. + view_code: TokenStream, + + /// Widgets struct initialization. + widgets_init: Box, + + errors: &'errors mut Vec, +} + +impl ViewOutputExpander<'_> { + pub(crate) fn expand( + item_impl: &mut syn::ItemImpl, + view_code: TokenStream, + widgets_init: Box, + errors: &mut Vec, + ) { + let mut expander = ViewOutputExpander { + expanded: false, + view_code, + widgets_init, + errors, + }; + + expander.visit_item_impl_mut(item_impl); + } +} + +impl VisitMut for ViewOutputExpander<'_> { + fn visit_impl_item_fn_mut(&mut self, method: &mut syn::ImplItemFn) { + if method.sig.ident == "init" || method.sig.ident == "init_widgets" { + visit_mut::visit_impl_item_fn_mut(self, method); + + if !self.expanded { + self.errors.push(syn::Error::new_spanned(method, "expected an injection point for the view macro. Try using `let widgets = view_output!();`")); + } + } + } + + fn visit_stmt_mut(&mut self, stmt: &mut syn::Stmt) { + let mut expand = false; + + if let syn::Stmt::Local(syn::Local { + init: Some(LocalInit { expr, .. }), + .. + }) = stmt + { + if let syn::Expr::Macro(mac) = &**expr { + if mac.mac.path.is_ident("view_output") { + expand = true; + } + } + + if expand { + // Replace the macro invocation with the widget initialization code. Perform the + // swap in-place to avoid a clone. + mem::swap(expr, &mut self.widgets_init); + } + } + + if expand { + let view_code = &self.view_code; + + *stmt = syn::Stmt::Expr( + syn::Expr::Verbatim(quote! { + #view_code + #stmt + }), + None, + ); + + self.expanded = true; + } + } +} + +/// Returns an empty impl item that can be used to remove an existing item in a mutable visitor. +fn null_item() -> syn::ImplItem { + syn::ImplItem::Verbatim(quote! {}) +} diff --git a/Relm4-0.6.2/relm4-macros/src/widget_template.rs b/Relm4-0.6.2/relm4-macros/src/widget_template.rs new file mode 100644 index 0000000..4c6712b --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widget_template.rs @@ -0,0 +1,95 @@ +use proc_macro2::{Span as Span2, TokenStream as TokenStream2}; +use quote::quote; +use syn::{spanned::Spanned, Error, Ident, ImplItem, ItemImpl, Visibility}; + +use crate::{ + token_streams::{TokenStreams, TraitImplDetails}, + widgets::ViewWidgets, +}; + +pub(crate) fn generate_tokens(vis: Option, mut item_impl: ItemImpl) -> TokenStream2 { + if item_impl.items.len() != 1 { + return Error::new( + item_impl.span(), + "Expected only one view macro and nothing else", + ) + .into_compile_error(); + } + + let item = item_impl.items.pop().unwrap(); + + if let ImplItem::Macro(mac) = item { + if Some("view") == mac.mac.path.get_ident().map(|i| i.to_string()).as_deref() { + match syn::parse::(mac.mac.tokens.into()) { + Ok(mut view_widgets) => { + view_widgets.mark_root_as_used(); + + let TokenStreams { + error, + init, + assign, + struct_fields, + return_fields, + .. + } = view_widgets.generate_streams( + &TraitImplDetails { + vis: vis.clone(), + model_name: Ident::new("_", Span2::call_site()), + sender_name: Ident::new("sender", Span2::call_site()), + root_name: None, + }, + true, + ); + + let view_output = quote! { + #init + #assign + { + #error + } + }; + + let root_widget_type = view_widgets.root_type(); + item_impl.items.push(ImplItem::Verbatim(quote! { + type Root = #root_widget_type; + })); + + let root_name = view_widgets.root_name(); + + item_impl.items.push(ImplItem::Verbatim(quote! { + fn init() -> Self { + #view_output + Self { + #return_fields + } + } + })); + + let type_name = &item_impl.self_ty; + + quote! { + #[derive(Debug, Clone)] + #vis struct #type_name { + #struct_fields + } + + impl ::std::ops::Deref for #type_name { + type Target = #root_widget_type; + + fn deref(&self) -> &Self::Target { + &self.#root_name + } + } + + #item_impl + } + } + Err(err) => err.to_compile_error(), + } + } else { + Error::new(mac.mac.path.span(), "Expected a view macro").into_compile_error() + } + } else { + Error::new(item.span(), "Expected a macro").into_compile_error() + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/assign_property.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/assign_property.rs new file mode 100644 index 0000000..7aeaa25 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/assign_property.rs @@ -0,0 +1,135 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, quote_spanned, ToTokens}; +use syn::spanned::Spanned; +use syn::Expr; + +use crate::widgets::{AssignProperty, AssignPropertyAttr, PropertyName}; + +use super::AssignInfo; + +impl AssignProperty { + pub(crate) fn conditional_assign_stream( + &self, + info: &mut AssignInfo<'_>, + p_name: &PropertyName, + init: bool, + ) { + // If the code gen path is behind a conditional widgets, handle `watch` and `track` later. + // Normally, those would be initialized right away, but they might need access to + // variables from a pattern, for example `Some(variable)` so they are moved inside the + // match arm or if expression. + if !info.is_conditional + || !matches!( + self.attr, + AssignPropertyAttr::Track { .. } | AssignPropertyAttr::Watch { .. } + ) + { + self.assign_stream(info, p_name, init); + } + } + + pub(crate) fn assign_stream( + &self, + info: &mut AssignInfo<'_>, + p_name: &PropertyName, + init: bool, + ) { + if init && self.attr.should_skip_init() { + return; + } + + let assign_fn = p_name.assign_fn_stream(info); + let self_assign_args = p_name.assign_args_stream(info.widget_name); + let span = p_name.span(); + + let args = self.args.as_ref().map(|args| { + quote! { + , #args + } + }); + + // Destructure tuples + let assign = if let Expr::Tuple(tuple) = &self.expr { + tuple.elems.to_token_stream() + } else { + self.expr.to_token_stream() + }; + + let chain = self.chain.as_ref().map(|chain| { + quote_spanned! { + chain.span() => .#chain + } + }); + + let (block_stream, unblock_stream) = if init || self.block_signals.is_empty() { + (None, None) + } else { + let mut block_stream = TokenStream2::default(); + let mut unblock_stream = TokenStream2::default(); + let gtk_import = crate::gtk_import(); + + let w_name = info.widget_name; + for signal_handler in &self.block_signals { + block_stream.extend(quote_spanned! { + signal_handler.span() => + { + use relm4::WidgetRef; + #[allow(clippy::needless_borrow)] + #gtk_import::prelude::ObjectExt::block_signal(#w_name.widget_ref(), &#signal_handler); + } + }); + unblock_stream.extend(quote_spanned! { + signal_handler.span() => + { + use relm4::WidgetRef; + #[allow(clippy::needless_borrow)] + #gtk_import::prelude::ObjectExt::unblock_signal(#w_name.widget_ref(), &#signal_handler); + } + }); + } + (Some(block_stream), Some(unblock_stream)) + }; + + info.stream + .extend(match (self.optional_assign, self.iterative) { + (false, false) => { + quote_spanned! { span => + #block_stream + #assign_fn(#self_assign_args #assign #args) #chain; + #unblock_stream + } + } + (true, false) => { + quote_spanned! { + span => if let Some(__p_assign) = #assign { + #block_stream + #assign_fn(#self_assign_args __p_assign #args) #chain; + #unblock_stream + } + } + } + (false, true) => { + quote_spanned! { + span => + #block_stream + for __elem in #assign { + #assign_fn(#self_assign_args __elem #args) #chain; + } + #unblock_stream + } + } + (true, true) => { + quote_spanned! { + span => + #block_stream + for __elem in #assign { + if let Some(__p_assign) = __elem { + #assign_fn(#self_assign_args __p_assign #args) #chain; + } + } + #unblock_stream + } + } + }); + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/conditional_widget.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/conditional_widget.rs new file mode 100644 index 0000000..02b44c6 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/conditional_widget.rs @@ -0,0 +1,57 @@ +use quote::{quote, quote_spanned}; +use syn::Ident; + +use crate::widgets::{ConditionalBranches, ConditionalWidget, PropertyName}; + +use super::AssignInfo; + +impl ConditionalWidget { + pub(super) fn assign_stream<'a>( + &'a self, + info: &mut AssignInfo<'a>, + p_name: &PropertyName, + sender_name: &'a Ident, + ) { + let assign_fn = p_name.assign_fn_stream(info); + let self_assign_args = p_name.assign_args_stream(info.widget_name); + let span = p_name.span(); + + let args = self.args.as_ref().map(|args| { + quote! { + , #args + } + }); + + let w_name = &self.name; + let assign_args = if let Some(assign_wrapper) = &self.assign_wrapper { + quote! { #assign_wrapper (&#w_name ) } + } else { + quote_spanned! { w_name.span() => &#w_name } + }; + + info.stream.extend(quote_spanned! { + span => #assign_fn(#self_assign_args #assign_args #args); + }); + + let mut info = AssignInfo { + stream: info.stream, + widget_name: &self.name, + template_path: None, + is_conditional: true, + }; + match &self.branches { + ConditionalBranches::If(if_branches) => { + for branch in if_branches { + let p_name = PropertyName::Ident(Ident::new("add_named", p_name.span())); + branch.widget.assign_stream(&mut info, &p_name, sender_name); + } + } + ConditionalBranches::Match((_, _, match_arms)) => { + for arm in match_arms { + let p_name = PropertyName::Ident(Ident::new("add_named", p_name.span())); + arm.widget.assign_stream(&mut info, &p_name, sender_name); + } + } + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/mod.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/mod.rs new file mode 100644 index 0000000..d8d71d7 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/mod.rs @@ -0,0 +1,37 @@ +use proc_macro2::TokenStream as TokenStream2; +use syn::{punctuated::Punctuated, token, Ident}; + +use crate::widgets::{Property, PropertyType}; + +mod assign_property; +mod conditional_widget; +mod properties; +mod signal_handler; +mod widgets; + +pub(crate) struct AssignInfo<'a> { + pub(crate) stream: &'a mut TokenStream2, + pub(crate) widget_name: &'a Ident, + pub(crate) template_path: Option>, + pub(crate) is_conditional: bool, +} + +impl Property { + fn assign_stream<'a>(&'a self, info: &mut AssignInfo<'a>, sender_name: &'a Ident) { + match &self.ty { + PropertyType::Assign(assign) => { + assign.conditional_assign_stream(info, &self.name, true); + } + PropertyType::Widget(widget) => { + widget.assign_stream(info, &self.name, sender_name); + } + PropertyType::ConditionalWidget(cond_widget) => { + cond_widget.assign_stream(info, &self.name, sender_name); + } + PropertyType::SignalHandler(signal_handler) => { + signal_handler.connect_signals_stream(info, &self.name, sender_name); + } + PropertyType::ParseError(_) => (), + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/properties.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/properties.rs new file mode 100644 index 0000000..2bd6ea6 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/properties.rs @@ -0,0 +1,13 @@ +use syn::Ident; + +use crate::widgets::Properties; + +use super::AssignInfo; + +impl Properties { + pub(super) fn assign_stream<'a>(&'a self, info: &mut AssignInfo<'a>, sender_name: &'a Ident) { + for prop in &self.properties { + prop.assign_stream(info, sender_name); + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/signal_handler.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/signal_handler.rs new file mode 100644 index 0000000..361c377 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/signal_handler.rs @@ -0,0 +1,77 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote_spanned, ToTokens}; +use syn::Expr; +use syn::{spanned::Spanned, Ident}; + +use crate::widgets::{PropertyName, SignalHandler, SignalHandlerVariant}; + +use super::AssignInfo; + +impl SignalHandler { + pub(super) fn connect_signals_stream( + &self, + info: &mut AssignInfo<'_>, + p_name: &PropertyName, + sender_name: &Ident, + ) { + let span = p_name.span(); + let assign_fn = p_name.assign_fn_stream(info); + let self_assign_args = p_name.assign_args_stream(info.widget_name); + + let (clone_stream, assignment) = match &self.inner { + SignalHandlerVariant::Expr(expr) => ( + quote_spanned! { span => + #[allow(clippy::redundant_clone)] + let sender = #sender_name.clone(); + }, + quote_spanned! { + span => move |_| { + sender.input(#expr) + } + }, + ), + SignalHandlerVariant::Closure(inner) => { + let mut clone_stream = TokenStream2::new(); + if let Some(args) = &inner.args { + for arg in &args.inner { + if let Expr::Path(path) = arg { + if let Some(ident) = path.path.get_ident() { + // Just an ident was used. Simply clone it. + clone_stream.extend(quote_spanned! { arg.span() => + #[allow(clippy::redundant_clone)] + #[allow(clippy::clone_on_copy)] + let #ident = #ident.clone(); + }); + continue; + } + } + // Allow more complex expressions such as `value = data.sender()` + clone_stream.extend(quote_spanned! { arg.span() => + #[allow(clippy::redundant_clone)] + #[allow(clippy::clone_on_copy)] + let #arg; + }); + } + } + (clone_stream, inner.closure.to_token_stream()) + } + }; + + info.stream + .extend(if let Some(signal_handler_id) = &self.handler_id { + quote_spanned! { + span => let #signal_handler_id = { + #clone_stream + #assign_fn(#self_assign_args #assignment) + }; + } + } else { + quote_spanned! { + span => { + #clone_stream + #assign_fn(#self_assign_args #assignment); + } + } + }); + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/widgets.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/widgets.rs new file mode 100644 index 0000000..2d1e4b2 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/assign/widgets.rs @@ -0,0 +1,100 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, quote_spanned}; +use syn::spanned::Spanned; +use syn::Ident; + +use crate::widgets::{PropertyName, ReturnedWidget, Widget, WidgetTemplateAttr}; + +use super::AssignInfo; + +impl ReturnedWidget { + fn return_assign_tokens(&self) -> TokenStream2 { + let name = &self.name; + + if let Some(ty) = &self.ty { + quote! { + let #name : #ty + } + } else { + quote! { + let #name + } + } + } +} + +impl Widget { + pub(crate) fn start_assign_stream<'a>( + &'a self, + stream: &'a mut TokenStream2, + sender_name: &'a Ident, + ) { + let w_name = &self.name; + let mut info = AssignInfo { + stream, + widget_name: w_name, + template_path: None, + is_conditional: false, + }; + self.properties.assign_stream(&mut info, sender_name); + } + + pub(super) fn assign_stream<'a>( + &'a self, + info: &mut AssignInfo<'a>, + p_name: &PropertyName, + sender_name: &'a Ident, + ) { + // Recursively generate code for properties + { + let template_path = (self.template_attr == WidgetTemplateAttr::TemplateChild) + .then_some(self.func.widget_template_path(info.widget_name, &self.name)); + + let mut info = AssignInfo { + stream: info.stream, + widget_name: &self.name, + template_path, + is_conditional: info.is_conditional, + }; + self.properties.assign_stream(&mut info, sender_name); + } + + // Template children are already assigned by the template. + if self.template_attr != WidgetTemplateAttr::TemplateChild { + let assign_fn = p_name.assign_fn_stream(info); + let self_assign_args = p_name.assign_args_stream(info.widget_name); + let assign = self.widget_assignment(); + let span = p_name.span(); + + let args = self.args.as_ref().map(|args| { + quote_spanned! { + args.span() => ,#args + } + }); + + info.stream.extend(if let Some(ret_widget) = &self.returned_widget { + let return_assign_stream = ret_widget.return_assign_tokens(); + let unwrap = ret_widget.is_optional.then(|| quote! { .unwrap() }); + quote_spanned! { + span => #return_assign_stream = #assign_fn(#self_assign_args #assign #args) #unwrap; + } + } else { + quote_spanned! { + span => #assign_fn(#self_assign_args #assign #args); + } + }); + } + + if let Some(returned_widget) = &self.returned_widget { + let mut info = AssignInfo { + stream: info.stream, + widget_name: &returned_widget.name, + template_path: None, + is_conditional: info.is_conditional, + }; + returned_widget + .properties + .assign_stream(&mut info, sender_name); + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/conditional_init.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/conditional_init.rs new file mode 100644 index 0000000..c77d5f4 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/conditional_init.rs @@ -0,0 +1,207 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, quote_spanned}; +use syn::spanned::Spanned; +use syn::Ident; + +use crate::widgets::{ + AssignProperty, AssignPropertyAttr, ConditionalBranches, ConditionalWidget, MatchArm, + Properties, Property, PropertyName, PropertyType, ReturnedWidget, Widget, +}; + +use super::assign::AssignInfo; + +impl Property { + fn conditional_init_stream( + &self, + stream: &mut TokenStream2, + w_name: &Ident, + model_name: &Ident, + is_conditional: bool, + ) { + match &self.ty { + PropertyType::Assign(assign) => assign.conditional_init_stream( + stream, + &self.name, + w_name, + model_name, + is_conditional, + ), + PropertyType::Widget(widget) => { + widget.conditional_init_stream(stream, model_name, is_conditional); + } + PropertyType::ConditionalWidget(cond_widget) => { + cond_widget.conditional_init_stream(stream, model_name); + } + PropertyType::SignalHandler(_) | PropertyType::ParseError(_) => (), + } + } +} + +impl Properties { + fn conditional_init_stream( + &self, + stream: &mut TokenStream2, + w_name: &Ident, + model_name: &Ident, + is_conditional: bool, + ) { + for prop in &self.properties { + prop.conditional_init_stream(stream, w_name, model_name, is_conditional); + } + } +} + +impl Widget { + pub(crate) fn init_conditional_init_stream( + &self, + stream: &mut TokenStream2, + model_name: &Ident, + ) { + self.conditional_init_stream(stream, model_name, false); + } + + fn conditional_init_stream( + &self, + stream: &mut TokenStream2, + model_name: &Ident, + is_conditional: bool, + ) { + let w_name = &self.name; + self.properties + .conditional_init_stream(stream, w_name, model_name, is_conditional); + if let Some(returned_widget) = &self.returned_widget { + returned_widget.conditional_init_stream(stream, model_name, is_conditional); + } + } +} + +impl ConditionalWidget { + fn conditional_init_stream(&self, stream: &mut TokenStream2, model_name: &Ident) { + let brach_stream = match &self.branches { + ConditionalBranches::If(if_branches) => { + let mut stream = TokenStream2::new(); + + for (index, branch) in if_branches.iter().enumerate() { + let mut inner_update_stream = TokenStream2::new(); + branch.widget.conditional_init_stream( + &mut inner_update_stream, + model_name, + true, + ); + branch.update_stream(&mut stream, &inner_update_stream, index); + } + stream + } + ConditionalBranches::Match((match_token, expr, match_arms)) => { + let mut inner_tokens = TokenStream2::new(); + + for (index, match_arm) in match_arms.iter().enumerate() { + let mut inner_update_stream = TokenStream2::new(); + match_arm.widget.conditional_init_stream( + &mut inner_update_stream, + model_name, + true, + ); + + let MatchArm { + pattern, + guard, + arrow, + .. + } = match_arm; + + let (guard_if, guard_expr) = if let Some((guard_if, guard_expr)) = guard { + (Some(guard_if), Some(guard_expr)) + } else { + (None, None) + }; + + let index = index.to_string(); + inner_tokens.extend(quote! { + #pattern #guard_if #guard_expr #arrow { + #inner_update_stream + #index + }, + }); + } + quote! { + #match_token #expr { + #inner_tokens + } + } + } + }; + + let w_name = &self.name; + stream.extend(quote! { + let __current_page = ""; + #w_name.set_visible_child_name(#brach_stream); + }); + } +} + +impl ReturnedWidget { + fn conditional_init_stream( + &self, + stream: &mut TokenStream2, + model_name: &Ident, + is_conditional: bool, + ) { + let w_name = &self.name; + self.properties + .conditional_init_stream(stream, w_name, model_name, is_conditional); + } +} + +impl AssignProperty { + fn conditional_init_stream( + &self, + stream: &mut TokenStream2, + p_name: &PropertyName, + widget_name: &Ident, + model_name: &Ident, + is_conditional: bool, + ) { + // Unconditional code is handled in the "normal" init stream + if is_conditional { + match &self.attr { + AssignPropertyAttr::None => (), + AssignPropertyAttr::Watch { skip_init } => { + if skip_init.is_none() { + let mut info = AssignInfo { + stream, + widget_name, + template_path: None, + is_conditional, + }; + self.assign_stream(&mut info, p_name, true); + } + } + AssignPropertyAttr::Track { + track_expr, + paste_model, + skip_init, + } => { + if skip_init.is_none() { + let mut assign_stream = TokenStream2::new(); + let mut info = AssignInfo { + stream: &mut assign_stream, + widget_name, + template_path: None, + is_conditional, + }; + + self.assign_stream(&mut info, p_name, true); + let model = paste_model.then(|| model_name); + + stream.extend(quote_spanned! { + track_expr.span() => if #model #track_expr { + #assign_stream + } + }); + } + } + } + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/destructure_fields.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/destructure_fields.rs new file mode 100644 index 0000000..63237a0 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/destructure_fields.rs @@ -0,0 +1,86 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; + +use crate::widgets::{ + ConditionalBranches, ConditionalWidget, Properties, Property, PropertyType, ReturnedWidget, + SignalHandler, Widget, +}; + +impl Property { + fn destructure_stream(&self, stream: &mut TokenStream2) { + match &self.ty { + PropertyType::Widget(widget) => widget.destructure_stream(stream), + PropertyType::SignalHandler(signal_handler) => { + signal_handler.destructure_stream(stream); + } + PropertyType::ConditionalWidget(cond_widget) => { + cond_widget.destructure_stream(stream); + } + PropertyType::Assign(_) | PropertyType::ParseError(_) => (), + } + } +} + +impl Properties { + fn destructure_stream(&self, stream: &mut TokenStream2) { + for prop in &self.properties { + prop.destructure_stream(stream); + } + } +} + +impl Widget { + pub(crate) fn destructure_stream(&self, stream: &mut TokenStream2) { + if self.has_struct_field() { + let name = &self.name; + + stream.extend(quote! { #name, }); + } + + self.properties.destructure_stream(stream); + } +} + +impl ConditionalWidget { + fn destructure_stream(&self, stream: &mut TokenStream2) { + let name = &self.name; + + stream.extend(quote! { #name, }); + + match &self.branches { + ConditionalBranches::If(if_branches) => { + for branch in if_branches { + branch.widget.destructure_stream(stream); + } + } + ConditionalBranches::Match((_, _, match_arms)) => { + for arm in match_arms { + arm.widget.destructure_stream(stream); + } + } + } + } +} + +impl ReturnedWidget { + pub(super) fn destructure_stream(&self, stream: &mut TokenStream2) { + if self.ty.is_some() { + let name = &self.name; + stream.extend(quote! { + #name, + }); + } + + self.properties.destructure_stream(stream); + } +} + +impl SignalHandler { + pub(super) fn destructure_stream(&self, stream: &mut TokenStream2) { + if let Some(signal_handler_id) = &self.handler_id { + stream.extend(quote! { + #signal_handler_id, + }); + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/error.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/error.rs new file mode 100644 index 0000000..57b6a54 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/error.rs @@ -0,0 +1,77 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, ToTokens}; +use syn::Ident; + +use crate::widgets::{ + ConditionalBranches, ConditionalWidget, ParseError, Properties, Property, PropertyType, + ReturnedWidget, Widget, +}; + +impl Property { + fn error_stream(&self, stream: &mut TokenStream2, w_name: &Ident) { + match &self.ty { + PropertyType::ParseError(error) => error.error_stream(stream, w_name), + PropertyType::SignalHandler(_) | PropertyType::Assign(_) => (), + PropertyType::Widget(widget) => widget.error_stream(stream), + PropertyType::ConditionalWidget(cond_widget) => cond_widget.error_stream(stream), + } + } +} + +impl Properties { + fn error_stream(&self, stream: &mut TokenStream2, w_name: &Ident) { + for prop in &self.properties { + prop.error_stream(stream, w_name); + } + } +} + +impl ParseError { + fn error_stream(&self, stream: &mut TokenStream2, w_name: &Ident) { + match self { + ParseError::Ident((ident, tokens)) => stream.extend(quote! { + #tokens + #w_name.#ident ; + }), + ParseError::Path((path, tokens)) => stream.extend(quote! { + #tokens + #path ; + }), + ParseError::Generic(generic_error) => generic_error.to_tokens(stream), + } + } +} + +impl Widget { + pub(crate) fn error_stream(&self, stream: &mut TokenStream2) { + let w_name = &self.name; + self.properties.error_stream(stream, w_name); + if let Some(returned_widget) = &self.returned_widget { + returned_widget.error_stream(stream); + } + } +} + +impl ConditionalWidget { + fn error_stream(&self, stream: &mut TokenStream2) { + match &self.branches { + ConditionalBranches::If(if_branches) => { + for branch in if_branches { + branch.widget.error_stream(stream); + } + } + ConditionalBranches::Match((_, _, match_arms)) => { + for arm in match_arms { + arm.widget.error_stream(stream); + } + } + } + } +} + +impl ReturnedWidget { + fn error_stream(&self, stream: &mut TokenStream2) { + let w_name = &self.name; + self.properties.error_stream(stream, w_name); + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/init.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/init.rs new file mode 100644 index 0000000..2bdaa79 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/init.rs @@ -0,0 +1,118 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, quote_spanned}; + +use crate::widgets::{ + ConditionalBranches, ConditionalWidget, Properties, Property, PropertyType, Widget, WidgetAttr, + WidgetTemplateAttr, +}; + +impl Property { + fn init_stream(&self, stream: &mut TokenStream2) { + match &self.ty { + PropertyType::Widget(widget) => { + widget.init_stream(stream); + } + PropertyType::ConditionalWidget(cond_widget) => { + cond_widget.init_stream(stream); + } + _ => (), + } + } +} + +impl Properties { + fn init_stream(&self, stream: &mut TokenStream2) { + for prop in &self.properties { + prop.init_stream(stream); + } + } +} + +impl Widget { + pub(crate) fn init_stream(&self, stream: &mut TokenStream2) { + self.self_init_stream(stream); + self.other_init_stream(stream); + } + + pub(crate) fn init_root_init_streams( + &self, + init_root_stream: &mut TokenStream2, + init_stream: &mut TokenStream2, + ) { + // Init function as return value + init_root_stream.extend(match self.template_attr { + WidgetTemplateAttr::None | WidgetTemplateAttr::TemplateChild => { + self.func.func_token_stream() + } + WidgetTemplateAttr::Template => { + let widget_ty = &self.func.path; + quote! { + <#widget_ty as relm4::WidgetTemplate>::init() + } + } + }); + + self.other_init_stream(init_stream); + } + + fn self_init_stream(&self, stream: &mut TokenStream2) { + let mutability = &self.mutable; + let name = &self.name; + + let ty = self.func.ty.as_ref().map(|ty| quote! {: #ty}); + if self.attr == WidgetAttr::None { + match self.template_attr { + WidgetTemplateAttr::None => { + let func = self.func.func_token_stream(); + stream.extend(quote! { + let #mutability #name #ty = #func; + }); + } + WidgetTemplateAttr::Template => { + let widget_ty = &self.func.path; + stream.extend(quote! { + let #mutability #name #ty = <#widget_ty as relm4::WidgetTemplate>::init(); + }); + } + // Template children are already initialized by their template. + WidgetTemplateAttr::TemplateChild => (), + } + } + } + + fn other_init_stream(&self, stream: &mut TokenStream2) { + self.properties.init_stream(stream); + } +} + +impl ConditionalWidget { + fn init_stream(&self, stream: &mut TokenStream2) { + let name = &self.name; + let gtk_import = crate::gtk_import(); + + stream.extend(quote_spanned! { + name.span() => + let #name = #gtk_import::Stack::default(); + }); + + if let Some(transition) = &self.transition { + stream.extend(quote_spanned! { + transition.span() => + #name.set_transition_type(#gtk_import::StackTransitionType:: #transition); + }); + } + + match &self.branches { + ConditionalBranches::If(if_branches) => { + for branch in if_branches { + branch.widget.init_stream(stream); + } + } + ConditionalBranches::Match((_, _, match_arms)) => { + for arm in match_arms { + arm.widget.init_stream(stream); + } + } + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/mod.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/mod.rs new file mode 100644 index 0000000..3ca6a9e --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/mod.rs @@ -0,0 +1,42 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, quote_spanned}; +use syn::{spanned::Spanned, token}; + +use super::{PropertyName, ReturnedWidget, Widget, WidgetTemplateAttr}; + +/// Utility methods and functions. +mod util; + +/// Generate struct fields. +mod struct_fields; + +/// Fields of the returned widget struct. +mod return_fields; + +mod assign; +mod conditional_init; +mod destructure_fields; +mod error; +mod init; +mod update_view; + +impl Widget { + pub(super) fn widget_assignment(&self) -> TokenStream2 { + let w_name = &self.name; + + let ref_token = &self.ref_token; + let deref_token = &self.deref_token; + let template_deref = + (self.template_attr == WidgetTemplateAttr::Template).then(token::Star::default); + + let out_stream = quote! { #ref_token #deref_token #template_deref #w_name }; + + if let Some(wrapper) = &self.assign_wrapper { + quote_spanned! { + wrapper.span() => #wrapper(#out_stream) + } + } else { + out_stream + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/return_fields.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/return_fields.rs new file mode 100644 index 0000000..e9c6878 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/return_fields.rs @@ -0,0 +1,80 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; + +use crate::widgets::{ + ConditionalBranches, ConditionalWidget, Properties, Property, PropertyType, ReturnedWidget, + SignalHandler, Widget, WidgetAttr, +}; + +impl Property { + fn return_stream(&self, stream: &mut TokenStream2) { + match &self.ty { + PropertyType::Widget(widget) => widget.return_stream(stream), + PropertyType::SignalHandler(signal_handler) => signal_handler.return_stream(stream), + PropertyType::ConditionalWidget(cond_widget) => cond_widget.return_stream(stream), + PropertyType::Assign(_) | PropertyType::ParseError(_) => (), + } + } +} + +impl Properties { + fn return_stream(&self, stream: &mut TokenStream2) { + for prop in &self.properties { + prop.return_stream(stream); + } + } +} + +impl Widget { + pub(crate) fn return_stream(&self, stream: &mut TokenStream2) { + if self.has_struct_field() { + let name = &self.name; + + stream.extend(if self.attr == WidgetAttr::LocalRef { + // The local reference must be cloned first + quote! { #name: #name.clone(), } + } else { + quote! { #name, } + }); + } + + self.properties.return_stream(stream); + if let Some(returned_widget) = &self.returned_widget { + returned_widget.return_stream(stream); + } + } +} + +impl ConditionalWidget { + fn return_stream(&self, stream: &mut TokenStream2) { + let name = &self.name; + + stream.extend(quote! { #name, }); + + match &self.branches { + ConditionalBranches::If(if_branches) => { + for branch in if_branches { + branch.widget.return_stream(stream); + } + } + ConditionalBranches::Match((_, _, match_arms)) => { + for arm in match_arms { + arm.widget.return_stream(stream); + } + } + } + } +} + +impl ReturnedWidget { + fn return_stream(&self, stream: &mut TokenStream2) { + self.destructure_stream(stream); + self.properties.return_stream(stream); + } +} + +impl SignalHandler { + fn return_stream(&self, stream: &mut TokenStream2) { + self.destructure_stream(stream); + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/struct_fields.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/struct_fields.rs new file mode 100644 index 0000000..0ece60b --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/struct_fields.rs @@ -0,0 +1,117 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, quote_spanned}; +use syn::Visibility; + +use super::{ReturnedWidget, Widget}; +use crate::widgets::{ + ConditionalBranches, ConditionalWidget, Properties, Property, PropertyType, SignalHandler, +}; + +impl Property { + fn struct_fields_stream(&self, stream: &mut TokenStream2, vis: &Option) { + match &self.ty { + PropertyType::Widget(widget) => widget.struct_fields_stream(stream, vis), + PropertyType::SignalHandler(signal_handler) => { + signal_handler.struct_fields_stream(stream, vis); + } + PropertyType::ConditionalWidget(cond_widget) => { + cond_widget.struct_fields_stream(stream, vis); + } + PropertyType::Assign(_) | PropertyType::ParseError(_) => (), + } + } +} + +impl Properties { + fn struct_fields_stream(&self, stream: &mut TokenStream2, vis: &Option) { + for prop in &self.properties { + prop.struct_fields_stream(stream, vis); + } + } +} + +impl Widget { + pub(crate) fn struct_fields_stream(&self, stream: &mut TokenStream2, vis: &Option) { + if self.has_struct_field() { + let name = &self.name; + let ty = self.func_type_token_stream(); + + stream.extend(if let Some(docs) = &self.doc_attr { + quote! { + #[doc = #docs] + #vis #name: #ty, + } + } else { + quote! { + #[allow(missing_docs)] + #vis #name: #ty, + } + }); + } + + self.properties.struct_fields_stream(stream, vis); + if let Some(returned_widget) = &self.returned_widget { + returned_widget.struct_fields_stream(stream, vis); + } + } +} + +impl ConditionalWidget { + fn struct_fields_stream(&self, stream: &mut TokenStream2, vis: &Option) { + let name = &self.name; + let gtk_import = crate::gtk_import(); + + stream.extend(if let Some(docs) = &self.doc_attr { + quote_spanned! { + name.span() => + #[doc = #docs] + #vis #name: #gtk_import::Stack, + } + } else { + quote_spanned! { + name.span() => + #[allow(missing_docs)] + #vis #name: #gtk_import::Stack, + } + }); + + match &self.branches { + ConditionalBranches::If(if_branches) => { + for branch in if_branches { + branch.widget.struct_fields_stream(stream, vis); + } + } + ConditionalBranches::Match((_, _, match_arms)) => { + for arm in match_arms { + arm.widget.struct_fields_stream(stream, vis); + } + } + } + } +} + +impl ReturnedWidget { + fn struct_fields_stream(&self, stream: &mut TokenStream2, vis: &Option) { + if let Some(ty) = &self.ty { + let name = &self.name; + stream.extend(quote! { + #[allow(missing_docs)] + #vis #name: #ty, + }); + } + self.properties.struct_fields_stream(stream, vis); + } +} + +impl SignalHandler { + fn struct_fields_stream(&self, stream: &mut TokenStream2, vis: &Option) { + if let Some(signal_handler_id) = &self.handler_id { + let gtk_import = crate::gtk_import(); + stream.extend(quote_spanned! { + signal_handler_id.span() => + #[allow(missing_docs)] + #vis #signal_handler_id: #gtk_import::glib::signal::SignalHandlerId, + }); + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/update_view.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/update_view.rs new file mode 100644 index 0000000..28caa95 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/update_view.rs @@ -0,0 +1,231 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, quote_spanned}; +use syn::{punctuated::Punctuated, token, Ident}; + +use crate::widgets::{ + AssignProperty, AssignPropertyAttr, ConditionalBranches, ConditionalWidget, MatchArm, + Properties, Property, PropertyName, PropertyType, ReturnedWidget, Widget, WidgetTemplateAttr, +}; + +use super::assign::AssignInfo; + +impl Property { + fn update_view_stream( + &self, + stream: &mut TokenStream2, + widget_name: &Ident, + template_path: Option>, + model_name: &Ident, + conditional_branch: bool, + ) { + match &self.ty { + PropertyType::Assign(assign) => assign.update_view_stream( + stream, + &self.name, + widget_name, + template_path, + model_name, + conditional_branch, + ), + PropertyType::Widget(widget) => { + widget.update_view_stream( + stream, + Some(widget_name), + model_name, + conditional_branch, + ); + } + PropertyType::ConditionalWidget(cond_widget) => { + cond_widget.update_view_stream(stream, model_name); + } + PropertyType::SignalHandler(_) | PropertyType::ParseError(_) => (), + } + } +} + +impl Properties { + fn update_view_stream( + &self, + stream: &mut TokenStream2, + widget_name: &Ident, + template_path: Option>, + model_name: &Ident, + conditional_branch: bool, + ) { + for prop in &self.properties { + prop.update_view_stream( + stream, + widget_name, + template_path.clone(), + model_name, + conditional_branch, + ); + } + } +} + +impl Widget { + pub(crate) fn init_update_view_stream(&self, stream: &mut TokenStream2, model_name: &Ident) { + self.update_view_stream(stream, None, model_name, false); + } + + fn update_view_stream( + &self, + stream: &mut TokenStream2, + parent_widget_name: Option<&Ident>, + model_name: &Ident, + conditional_branch: bool, + ) { + let widget_name = &self.name; + let template_path = if self.template_attr == WidgetTemplateAttr::TemplateChild { + parent_widget_name.map(|parent_widget_name| { + self.func + .widget_template_path(parent_widget_name, &self.name) + }) + } else { + None + }; + + self.properties.update_view_stream( + stream, + widget_name, + template_path, + model_name, + conditional_branch, + ); + if let Some(returned_widget) = &self.returned_widget { + returned_widget.update_view_stream(stream, model_name, conditional_branch); + } + } +} + +impl ConditionalWidget { + fn update_view_stream(&self, stream: &mut TokenStream2, model_name: &Ident) { + let brach_stream = match &self.branches { + ConditionalBranches::If(if_branches) => { + let mut stream = TokenStream2::new(); + + for (index, branch) in if_branches.iter().enumerate() { + let mut inner_update_stream = TokenStream2::new(); + branch.widget.update_view_stream( + &mut inner_update_stream, + None, + model_name, + true, + ); + branch.update_stream(&mut stream, &inner_update_stream, index); + } + stream + } + ConditionalBranches::Match((match_token, expr, match_arms)) => { + let mut inner_tokens = TokenStream2::new(); + for (index, match_arm) in match_arms.iter().enumerate() { + let mut inner_update_stream = TokenStream2::new(); + match_arm.widget.update_view_stream( + &mut inner_update_stream, + None, + model_name, + true, + ); + let MatchArm { + pattern, + guard, + arrow, + .. + } = match_arm; + let (guard_if, guard_expr) = if let Some((guard_if, guard_expr)) = guard { + (Some(guard_if), Some(guard_expr)) + } else { + (None, None) + }; + + let index = index.to_string(); + inner_tokens.extend(quote! { + #pattern #guard_if #guard_expr #arrow { + let __page_active: bool = (__current_page == #index); + #inner_update_stream + #index + }, + }); + } + quote! { + #match_token #expr { + #inner_tokens + } + } + } + }; + + let w_name = &self.name; + stream.extend(quote_spanned! { + w_name.span() => + let __current_page = #w_name.visible_child_name().map_or("".to_string(), |s| s.as_str().to_string()); + #w_name.set_visible_child_name(#brach_stream); + }); + } +} + +impl ReturnedWidget { + fn update_view_stream( + &self, + stream: &mut TokenStream2, + model_name: &Ident, + conditional_branch: bool, + ) { + let w_name = &self.name; + self.properties + .update_view_stream(stream, w_name, None, model_name, conditional_branch); + } +} + +impl AssignProperty { + fn update_view_stream( + &self, + stream: &mut TokenStream2, + p_name: &PropertyName, + widget_name: &Ident, + template_path: Option>, + model_name: &Ident, + conditional_branch: bool, + ) { + match &self.attr { + AssignPropertyAttr::None => (), + AssignPropertyAttr::Watch { .. } => { + let mut info = AssignInfo { + stream, + widget_name, + template_path, + is_conditional: false, + }; + self.assign_stream(&mut info, p_name, false); + } + AssignPropertyAttr::Track { + track_expr, + paste_model, + .. + } => { + let mut assign_stream = TokenStream2::new(); + let mut info = AssignInfo { + stream: &mut assign_stream, + widget_name, + template_path: None, + is_conditional: false, + }; + self.assign_stream(&mut info, p_name, false); + let model = paste_model.then(|| model_name); + let page_switch = conditional_branch.then(|| { + quote_spanned! { + p_name.span() => + !__page_active || + } + }); + + stream.extend(quote! { + if #page_switch (#model #track_expr) { + #assign_stream + } + }); + } + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/has_struct_field.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/has_struct_field.rs new file mode 100644 index 0000000..8d715ce --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/has_struct_field.rs @@ -0,0 +1,28 @@ +use crate::widgets::{AssignPropertyAttr, Properties, PropertyType, Widget, WidgetTemplateAttr}; + +impl Widget { + /// Don't generate any fields if the widget wasn't named by the user and + /// isn't used for any property updates either. + pub(crate) fn has_struct_field(&self) -> bool { + match self.template_attr { + WidgetTemplateAttr::None => { + self.name_assigned_by_user || self.properties.are_properties_updated() + } + WidgetTemplateAttr::Template => true, + WidgetTemplateAttr::TemplateChild => false, + } + } +} + +impl Properties { + pub(crate) fn are_properties_updated(&self) -> bool { + // Is there any property with watch or track attribute? + self.properties.iter().any(|prop| match &prop.ty { + PropertyType::Assign(assign_prop) => matches!( + &assign_prop.attr, + AssignPropertyAttr::Track { .. } | AssignPropertyAttr::Watch { .. } + ), + _ => false, + }) + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/if_branch.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/if_branch.rs new file mode 100644 index 0000000..5515fd1 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/if_branch.rs @@ -0,0 +1,33 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; + +use crate::widgets::{IfBranch, IfCondition}; + +impl IfBranch { + pub(crate) fn update_stream( + &self, + stream: &mut TokenStream2, + inner_update_tokens: &TokenStream2, + index: usize, + ) { + let index = index.to_string(); + stream.extend(match &self.cond { + IfCondition::If(if_token, expr) => quote! { + #if_token #expr + }, + IfCondition::ElseIf(else_token, if_token, expr) => quote! { + #else_token #if_token #expr + }, + IfCondition::Else(else_token) => quote! { + #else_token + }, + }); + stream.extend(quote! { + { + let __page_active: bool = (__current_page == #index); + #inner_update_tokens + #index + } + }); + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/mod.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/mod.rs new file mode 100644 index 0000000..d6bca9c --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/mod.rs @@ -0,0 +1,5 @@ +mod has_struct_field; +mod if_branch; +mod property_name; +mod widget; +mod widget_func; diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/property_name.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/property_name.rs new file mode 100644 index 0000000..a1884ea --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/property_name.rs @@ -0,0 +1,37 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, quote_spanned, ToTokens}; +use syn::Ident; + +use crate::widgets::gen::{assign::AssignInfo, PropertyName}; + +impl PropertyName { + pub(crate) fn assign_fn_stream(&self, info: &mut AssignInfo<'_>) -> TokenStream2 { + let AssignInfo { + widget_name, + template_path, + .. + } = info; + let widget_name = if let Some(template_path) = template_path { + quote! { #template_path } + } else { + quote! { #widget_name } + }; + + match self { + PropertyName::Ident(ident) => { + quote! { #widget_name.#ident } + } + PropertyName::Path(path) => path.to_token_stream(), + PropertyName::RelmContainerExtAssign(span) => { + quote_spanned! { *span => #widget_name.container_add } + } + } + } + + pub(crate) fn assign_args_stream(&self, w_name: &Ident) -> Option { + match self { + PropertyName::RelmContainerExtAssign(_) | PropertyName::Ident(_) => None, + PropertyName::Path(_) => Some(quote_spanned! { w_name.span() => & #w_name, }), + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/widget.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/widget.rs new file mode 100644 index 0000000..a3cd4f8 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/widget.rs @@ -0,0 +1,14 @@ +use crate::widgets::ViewWidgets; + +impl ViewWidgets { + /// Get a mutable reference to the root widget + pub(crate) fn mark_root_as_used(&mut self) { + if let Some(root_widget) = self + .top_level_widgets + .iter_mut() + .find(|w| w.root_attr.is_some()) + { + root_widget.inner.name_assigned_by_user = true; + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/widget_func.rs b/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/widget_func.rs new file mode 100644 index 0000000..07fc1e2 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/gen/util/widget_func.rs @@ -0,0 +1,112 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, quote_spanned, ToTokens}; +use syn::punctuated::Punctuated; +use syn::{spanned::Spanned, Ident}; +use syn::{token, Error}; + +use crate::widgets::{Widget, WidgetFunc}; + +impl Widget { + /// Get tokens for the widget's type. + pub(crate) fn func_type_token_stream(&self) -> TokenStream2 { + let is_local = self.attr.is_local_attr(); + let func = &self.func; + let path = &self.func.path; + let mut tokens = TokenStream2::new(); + + // If type was specified, use it + let (type_segments, num_of_segments) = if let Some(ty) = &func.ty { + return ty.to_token_stream(); + } else if is_local { + return Error::new(func.span().unwrap().into(), + format!("You need to specify the type of the local variable. Use this instead: {} -> Type {{ ...", + self.name)).into_compile_error(); + } else if func.args.is_some() { + // If for example gtk::Box::new() was used, ignore ::new() + // and use gtk::Box as type. + let len = path.segments.len(); + if len == 0 { + unreachable!("Path can't be empty"); + } else if len == 1 { + return Error::new(func.span().unwrap().into(), + format!("You need to specify a type of your function. Use this instead: {}() -> Type {{ ...", + path.to_token_stream())).into_compile_error(); + } else { + (&path.segments, len - 1) + } + } else { + (&path.segments, path.segments.len()) + }; + + let mut seg_iter = type_segments.iter().take(num_of_segments); + let first = if let Some(first) = seg_iter.next() { + first + } else { + return Error::new( + func.span().unwrap().into(), + "No path segments in WidgetFunc.", + ) + .into_compile_error(); + }; + tokens.extend(first.to_token_stream()); + + for segment in seg_iter { + tokens.extend(quote! {::}); + tokens.extend(segment.to_token_stream()); + } + + tokens + } +} + +impl WidgetFunc { + /// Get the tokens of the widget's function. + pub(crate) fn func_token_stream(&self) -> TokenStream2 { + let WidgetFunc { + path, + args, + method_chain, + .. + } = &self; + + let mut stream = if let Some(args) = args { + quote! { #path(#args) } + } else if method_chain.is_some() { + path.to_token_stream() + } else { + quote_spanned! { + path.span() => #path::default() + } + }; + + if let Some(method_chain) = method_chain { + stream.extend(quote! { + .#method_chain + }); + } + + stream + } + + pub(crate) fn widget_template_path( + &self, + template_widget_name: &Ident, + widget_name: &Ident, + ) -> Punctuated { + let mut template_path = Punctuated::new(); + template_path.push(template_widget_name.clone()); + template_path.push(widget_name.clone()); + if let Some(chain) = &self.method_chain { + for method in chain { + if method.turbofish.is_some() || method.args.is_some() { + break; + } else { + template_path.push(method.ident.clone()); + } + } + template_path + } else { + template_path + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/mod.rs b/Relm4-0.6.2/relm4-macros/src/widgets/mod.rs new file mode 100644 index 0000000..605dcf0 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/mod.rs @@ -0,0 +1,218 @@ +use proc_macro2::{Span as Span2, TokenStream as TokenStream2}; +use syn::punctuated::Punctuated; +use syn::token::{Else, FatArrow, If, Match, Mut}; +use syn::{token, AngleBracketedGenericArguments, Expr, ExprClosure, Ident, Pat, Path, Type}; + +use crate::args::Args; + +mod gen; +mod parse; +mod parse_util; +mod span; + +#[derive(Debug)] +pub(super) struct ViewWidgets { + pub(super) span: Span2, + pub(super) top_level_widgets: Vec, +} + +#[derive(Debug)] +pub(super) struct TopLevelWidget { + pub(super) root_attr: Option, + pub(super) inner: Widget, +} + +#[derive(Debug)] +enum PropertyType { + Assign(AssignProperty), + SignalHandler(SignalHandler), + Widget(Widget), + ConditionalWidget(ConditionalWidget), + ParseError(ParseError), +} + +#[derive(Debug)] +enum ParseError { + Ident((Ident, TokenStream2)), + Path((Path, TokenStream2)), + Generic(TokenStream2), +} + +#[derive(Debug)] +enum AssignPropertyAttr { + None, + Watch { + skip_init: Option, + }, + Track { + track_expr: TokenStream2, + skip_init: Option, + paste_model: bool, + }, +} + +#[derive(Debug)] +struct AssignProperty { + attr: AssignPropertyAttr, + /// Optional arguments like param_name[arg1, arg2, ...] + args: Option>, + expr: Expr, + /// Assign with an ? + optional_assign: bool, + /// Iterate through elements to generate tokens + iterative: bool, + block_signals: Vec, + chain: Option>, +} + +#[derive(Debug)] +struct SignalHandler { + inner: SignalHandlerVariant, + handler_id: Option, +} + +#[derive(Debug)] +enum SignalHandlerVariant { + Expr(Expr), + Closure(ClosureSignalHandler), +} + +#[derive(Debug)] +struct ClosureSignalHandler { + closure: ExprClosure, + args: Option>, +} + +#[derive(Debug)] +enum PropertyName { + Ident(Ident), + Path(Path), + RelmContainerExtAssign(Span2), +} + +#[derive(Debug)] +struct Property { + /// Either a path or just an ident + name: PropertyName, + ty: PropertyType, +} + +#[derive(Debug, Default)] +struct Properties { + properties: Vec, +} + +/// The function that initializes the widget. +/// +/// This might be a real function or just something like `gtk::Label`. +#[derive(Debug)] +struct WidgetFunc { + path: Path, + args: Option>, + method_chain: Option>, + ty: Option>, +} + +#[derive(Debug)] +struct WidgetFuncMethod { + ident: Ident, + turbofish: Option, + args: Option>, +} + +#[derive(Debug)] +pub(super) struct Widget { + doc_attr: Option, + attr: WidgetAttr, + template_attr: WidgetTemplateAttr, + pub(super) mutable: Option, + pub(super) name: Ident, + name_assigned_by_user: bool, + func: WidgetFunc, + args: Option>, + properties: Properties, + assign_wrapper: Option, + ref_token: Option, + deref_token: Option, + returned_widget: Option, +} + +#[derive(Debug, PartialEq)] +enum WidgetAttr { + None, + Local, + LocalRef, +} + +#[derive(Debug, PartialEq)] +enum WidgetTemplateAttr { + None, + Template, + TemplateChild, +} + +#[derive(Debug)] +struct ReturnedWidget { + name: Ident, + ty: Option, + properties: Properties, + is_optional: bool, +} + +#[derive(Debug)] +struct ConditionalWidget { + doc_attr: Option, + transition: Option, + assign_wrapper: Option, + name: Ident, + args: Option>, + branches: ConditionalBranches, +} + +#[derive(Debug)] +enum ConditionalBranches { + If(Vec), + Match((Match, Box, Vec)), +} + +#[derive(Debug)] +enum IfCondition { + If(If, Expr), + ElseIf(Else, If, Expr), + Else(Else), +} + +#[derive(Debug)] +struct IfBranch { + cond: IfCondition, + widget: Widget, +} + +#[derive(Debug)] +struct MatchArm { + pattern: Pat, + guard: Option<(If, Box)>, + arrow: FatArrow, + widget: Widget, +} + +enum Attr { + Doc(TokenStream2), + Local(Ident), + LocalRef(Ident), + Root(Ident), + Iterate(Ident), + Watch(Ident, Option), + Track(Ident, Option, Option>), + BlockSignal(Ident, Vec), + Name(Ident, Ident), + Transition(Ident, Ident), + Wrap(Ident, Path), + Chain(Ident, Box), + Template(Ident), + TemplateChild(Ident), +} + +struct Attrs { + inner: Vec, +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/assign_property.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/assign_property.rs new file mode 100644 index 0000000..a3b774e --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/assign_property.rs @@ -0,0 +1,190 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote_spanned, ToTokens}; +use syn::parse::ParseStream; +use syn::spanned::Spanned; +use syn::{Error, Expr, ExprCall, ExprField, Ident, Member, Result, Token}; + +use crate::args::Args; +use crate::widgets::parse_util::attr_twice_error; +use crate::widgets::{AssignProperty, AssignPropertyAttr, Attr, Attrs}; + +struct ProcessedAttrs { + watch: AssignPropertyAttr, + iterative: bool, + block_signals: Vec, + chain: Option>, +} + +impl AssignProperty { + pub(super) fn parse( + input: ParseStream<'_>, + attributes: Option, + args: Option>, + ) -> Result { + let optional_assign = input.parse::().is_ok(); + let colon: Token! [:] = input.parse()?; + let colon_span = colon.span(); + + let expr = match input.parse() { + Ok(expr) => expr, + Err(parse_err) => { + let mut err = Error::new(colon_span, "Did you confuse `=` with`:`?"); + err.combine(parse_err); + return Err(err); + } + }; + + let ProcessedAttrs { + watch, + iterative, + block_signals, + chain, + } = Self::process_attributes(&expr, attributes)?; + + Ok(Self { + attr: watch, + expr, + args, + optional_assign, + iterative, + block_signals, + chain, + }) + } + + fn process_attributes(assign_expr: &Expr, attrs: Option) -> Result { + if let Some(attrs) = attrs { + let mut iterative = false; + let mut watch = AssignPropertyAttr::None; + let mut block_signals = Vec::with_capacity(0); + let mut chain = None; + + for attr in attrs.inner { + let span = attr.span(); + match attr { + Attr::Iterate(_) => { + if iterative { + return Err(attr_twice_error(span)); + } + iterative = true; + } + Attr::Watch(_, skip_init) => { + if watch == AssignPropertyAttr::None { + watch = AssignPropertyAttr::Watch { skip_init } + } else { + return Err(attr_twice_error(span)); + } + } + Attr::Track(_, skip_init, expr) => { + if watch == AssignPropertyAttr::None { + watch = if let Some(expr) = expr { + AssignPropertyAttr::Track { + track_expr: expr.to_token_stream(), + skip_init, + paste_model: false, + } + } else { + AssignPropertyAttr::Track { + track_expr: generate_tracker_from_expression(assign_expr)?, + skip_init, + paste_model: true, + } + }; + } else { + return Err(attr_twice_error(span)); + } + } + Attr::BlockSignal(_, idents) => { + if block_signals.is_empty() { + block_signals = idents; + } else { + return Err(attr_twice_error(span)); + } + } + Attr::Chain(_, expr) => { + if chain.is_none() { + chain = Some(expr); + } else { + return Err(attr_twice_error(span)); + } + } + _ => { + return Err(Error::new( + attr.span(), + "Properties can only have `watch`, `track` or `iterative` as attribute.", + )); + } + } + } + Ok(ProcessedAttrs { + watch, + iterative, + block_signals, + chain, + }) + } else { + Ok(ProcessedAttrs { + watch: AssignPropertyAttr::None, + iterative: false, + block_signals: Vec::with_capacity(0), + chain: None, + }) + } + } +} + +/// Helper function for the tracker attribute. +fn expr_field_from_expr_call(call_expr: &ExprCall) -> Option<&ExprField> { + let first_expr = call_expr.args.iter().next()?; + if let Expr::Field(expr_field) = first_expr { + Some(expr_field) + } else { + None + } +} + +fn generate_tracker_from_expression(expression: &Expr) -> Result { + let error_fn = move |span, msg: &str| { + let error_msg = + "Unable to generate tracker function. Please pass a condition as string value of the `track` attribute.\n\ + Usage: #[track = \"TRACK_CONDITION\"]"; + Err(Error::new(span, format!("{error_msg}\nHint: {msg}"))) + }; + + let unref_expr: &Expr = if let Expr::Reference(expr_ref) = expression { + &expr_ref.expr + } else { + expression + }; + + let expr_field_opt = match unref_expr { + Expr::Call(call_expr) => expr_field_from_expr_call(call_expr), + Expr::MethodCall(expr_method_call) => { + if let Expr::Field(ref expr_field) = *expr_method_call.receiver { + Some(expr_field) + } else { + None + } + } + Expr::Field(field_expr) => Some(field_expr), + _ => None, + }; + + let expr_field = if let Some(expr_field) = expr_field_opt { + expr_field + } else { + return error_fn( + unref_expr.span(), + "Couldn't find find a call or method expression.", + ); + }; + + let ident = if let Member::Named(ident) = &expr_field.member { + ident.clone() + } else { + return error_fn(expr_field.member.span(), "Expected a named member"); + }; + + let bool_stream = quote_spanned! { expr_field.span() => .changed(Self::#ident()) }; + Ok(bool_stream) +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/attributes.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/attributes.rs new file mode 100644 index 0000000..f3ae6ce --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/attributes.rs @@ -0,0 +1,214 @@ +use quote::ToTokens; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::spanned::Spanned; +use syn::{bracketed, parenthesized, token, Error, Expr, Ident, Lit, LitStr, Path, Result, Token}; + +use crate::widgets::{Attr, Attrs}; + +impl Parse for Attrs { + fn parse(input: ParseStream<'_>) -> Result { + let mut attrs = Vec::new(); + + while input.peek(Token![#]) { + let _sharp: Token![#] = input.parse()?; + let attr_tokens; + bracketed!(attr_tokens in input); + let path: Path = attr_tokens.parse()?; + + // Name attribute + attrs.push(if attr_tokens.is_empty() { + if let Some(ident) = path.get_ident() { + if ident == "local" { + Attr::Local(ident.clone()) + } else if ident == "local_ref" { + Attr::LocalRef(ident.clone()) + } else if ident == "root" { + Attr::Root(ident.clone()) + } else if ident == "watch" { + Attr::Watch(ident.clone(), None) + } else if ident == "track" { + Attr::Track(ident.clone(), None, None) + } else if ident == "iterate" { + Attr::Iterate(ident.clone()) + } else if ident == "template" { + Attr::Template(ident.clone()) + } else if ident == "template_child" { + Attr::TemplateChild(ident.clone()) + } else { + return Err(unexpected_attr_name(ident)); + } + } else { + return Err(Error::new(path.span(), "Expected identifier.")); + } + + // List attribute: `#[name(item1, item2)] + } else if attr_tokens.peek(token::Paren) { + let paren_input; + parenthesized!(paren_input in attr_tokens); + let nested: Punctuated = + Punctuated::parse_terminated(&paren_input)?; + + if let Some(ident) = path.get_ident() { + if ident == "block_signal" { + let mut signal_idents = Vec::with_capacity(nested.len()); + for expr in nested { + let ident = expect_ident_from_expr(&expr)?; + signal_idents.push(ident); + } + Attr::BlockSignal(ident.clone(), signal_idents) + } else if ident == "watch" { + let expr = expect_one_nested_expr(&nested)?; + if let Some(skip_init) = expr_to_skip_init_ident(expr) { + Attr::Watch(ident.clone(), Some(skip_init)) + } else { + return Err(Error::new(nested.span(), "Expected `skip_init`.")); + } + } else if ident == "track" { + let (skip_init, expr) = parse_track(&nested)?; + Attr::Track(ident.clone(), skip_init, expr.map(Box::new)) + } else if ident == "transition" { + let expr = expect_one_nested_expr(&nested)?; + let ident = expect_ident_from_expr(expr)?; + Attr::Transition(ident.clone(), ident) + } else if ident == "name" { + let expr = expect_one_nested_expr(&nested)?; + let ident = expect_ident_from_expr(expr)?; + Attr::Name(ident.clone(), ident) + } else if ident == "wrap" { + let expr = expect_one_nested_expr(&nested)?; + let path = expect_path_from_expr(expr)?; + Attr::Wrap(ident.clone(), path) + } else if ident == "chain" { + let expr = expect_one_nested_expr(&nested)?; + Attr::Chain(ident.clone(), Box::new(expr.clone())) + } else { + return Err(unexpected_attr_name(ident)); + } + } else { + return Err(Error::new(path.span(), "Expected identifier.")); + } + + // Value attribute: `#[name = literal)] + } else if attr_tokens.peek(Token![=]) { + let _eq: Token![=] = attr_tokens.parse()?; + let lit = attr_tokens.parse()?; + + if let Some(ident) = path.get_ident() { + if ident == "track" { + let string = expect_string_lit(&lit)?; + Attr::Track(ident.clone(), None, Some(string.parse()?)) + } else if ident == "doc" { + Attr::Doc(lit.into_token_stream()) + } else if ident == "transition" { + let string = expect_string_lit(&lit)?; + Attr::Transition(ident.clone(), string.parse()?) + } else if ident == "name" { + let string = expect_string_lit(&lit)?; + Attr::Name(ident.clone(), string.parse()?) + } else { + return Err(unexpected_attr_name(ident)); + } + } else { + return Err(Error::new(path.span(), "Expected identifier.")); + } + } else { + return Err(Error::new(attr_tokens.span(), "Expected `]`, `(` or `=`.")); + }); + } + + Ok(Attrs { inner: attrs }) + } +} + +fn unexpected_attr_name(ident: &Ident) -> Error { + Error::new( + ident.span(), + format!("Unexpected attribute name `{ident}`."), + ) +} + +fn expect_string_lit(lit: &Lit) -> Result<&LitStr> { + if let Lit::Str(string) = lit { + Ok(string) + } else { + Err(Error::new( + lit.span(), + "Expected string literal. Try this: `\"value\"`.", + )) + } +} + +fn expect_path_from_expr(expr: &Expr) -> Result { + if let Expr::Path(path) = expr { + Ok(path.path.clone()) + } else { + Err(Error::new( + expr.span(), + format!("Expected path `{}`.", expr.to_token_stream()), + )) + } +} + +fn expect_ident_from_expr(expr: &Expr) -> Result { + if let Expr::Path(path) = expr { + expect_ident_from_path(&path.path) + } else { + Err(Error::new( + expr.span(), + format!("Expected identifier `{}`.", expr.to_token_stream()), + )) + } +} + +fn expect_ident_from_path(path: &Path) -> Result { + if let Some(ident) = path.get_ident() { + Ok(ident.clone()) + } else { + Err(Error::new(path.span(), "Expected identifier.")) + } +} + +fn expect_one_nested_expr(nested: &Punctuated) -> Result<&Expr> { + if nested.len() == 1 { + Ok(nested.first().unwrap()) + } else { + Err(Error::new(nested.span(), "Expected only one expression.")) + } +} + +fn parse_track(nested: &Punctuated) -> Result<(Option, Option)> { + let len = nested.len(); + if len == 1 { + if let Some(skip_ident) = expr_to_skip_init_ident(&nested[0]) { + Ok((Some(skip_ident), None)) + } else { + Ok((None, Some(nested[0].clone()))) + } + } else if len == 2 { + if let Some(skip_ident) = expr_to_skip_init_ident(&nested[0]) { + Ok((Some(skip_ident), Some(nested.last().unwrap().clone()))) + } else { + Err(Error::new( + nested.span(), + "Expected `skip_init` and an expression.", + )) + } + } else { + Err(Error::new( + nested.span(), + "Expected exactly one or two expressions.", + )) + } +} + +fn expr_to_skip_init_ident(expr: &Expr) -> Option { + if let Expr::Path(path) = &expr { + if let Some(ident) = path.path.get_ident() { + if ident == "skip_init" { + return Some(ident.clone()); + } + } + } + None +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/conditional_branches.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/conditional_branches.rs new file mode 100644 index 0000000..9f9fb8d --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/conditional_branches.rs @@ -0,0 +1,31 @@ +use syn::parse::ParseStream; +use syn::{Expr, Token}; + +use crate::widgets::{parse_util, ConditionalBranches, IfBranch, MatchArm, ParseError}; + +impl ConditionalBranches { + pub(super) fn parse_if(input: ParseStream<'_>) -> Result { + let mut if_branches = Vec::new(); + let mut index = 0_usize; + while input.peek(Token![if]) || input.peek(Token![else]) { + if_branches.push(IfBranch::parse(input, index)?); + index += 1; + } + Ok(Self::If(if_branches)) + } + + pub(super) fn parse_match(input: ParseStream<'_>) -> Result { + let match_token = input.parse()?; + let expr = Box::new(Expr::parse_without_eager_brace(input)?); + + let braced = parse_util::braces(input)?; + + let mut match_arms = Vec::new(); + let mut index = 0_usize; + while !braced.is_empty() { + match_arms.push(MatchArm::parse(&braced, index)?); + index += 1; + } + Ok(Self::Match((match_token, expr, match_arms))) + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/conditional_widget.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/conditional_widget.rs new file mode 100644 index 0000000..32ba79b --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/conditional_widget.rs @@ -0,0 +1,134 @@ +use proc_macro2::TokenStream as TokenStream2; +use syn::parse::ParseStream; +use syn::{Error, Expr, Ident, Path, Token}; + +use crate::args::Args; +use crate::widgets::parse_util::{self, attr_twice_error}; +use crate::widgets::{Attr, Attrs, ConditionalBranches, ConditionalWidget, ParseError}; + +type ConditionalAttrs = ( + Option, + Option, + Option, + Option, +); + +impl ConditionalWidget { + pub(super) fn parse( + input: ParseStream<'_>, + attrs: Option, + args: Option>, + ) -> Result { + let name = if input.peek2(Token![=]) && !input.peek2(Token![==]) && !input.peek(Token![!]) { + let name = input.parse()?; + let _assign: Token![=] = input.parse()?; + Some(name) + } else { + None + }; + Self::parse_with_name(input, name, attrs, args) + } + + pub(super) fn parse_with_name( + input: ParseStream<'_>, + name: Option, + attrs: Option, + args: Option>, + ) -> Result { + let (transition, attr_name, doc_attr, assign_wrapper) = Self::process_attrs(attrs)?; + + if attr_name.is_some() { + if let Some(name) = &name { + return Err(Error::new( + name.span(), + "Name defined as attribute and redefined here.", + ) + .into()); + } + } + + let name = if let Some(name) = name { + name + } else if let Some(name) = attr_name { + name + } else { + parse_util::idents_to_snake_case( + [Ident::new("conditional_widget", input.span())].iter(), + input.span(), + ) + }; + + if input.peek(Token![if]) { + let branches = ConditionalBranches::parse_if(input)?; + Ok(Self { + doc_attr, + transition, + assign_wrapper, + name, + args, + branches, + }) + } else if input.peek(Token![match]) { + let branches = ConditionalBranches::parse_match(input)?; + Ok(Self { + doc_attr, + transition, + assign_wrapper, + name, + args, + branches, + }) + } else { + Err(input.error("Expected `if` or `match`").into()) + } + } + + fn process_attrs(attrs: Option) -> Result { + let mut transition = None; + let mut name = None; + let mut doc_attr: Option = None; + let mut assign_wrapper = None; + + if let Some(attrs) = attrs { + for attr in attrs.inner { + let span = attr.span(); + match attr { + Attr::Transition(_, transition_value) => { + if transition.is_none() { + transition = Some(transition_value); + } else { + return Err(attr_twice_error(span).into()); + } + } + Attr::Name(_, name_value) => { + if name.is_none() { + name = Some(name_value); + } else { + return Err(attr_twice_error(span).into()); + } + } + Attr::Wrap(_, path) => { + if assign_wrapper.is_some() { + return Err(attr_twice_error(span).into()); + } + assign_wrapper = Some(path.clone()); + } + Attr::Doc(tokens) => { + if let Some(doc_tokens) = &mut doc_attr { + doc_tokens.extend(tokens); + } else { + doc_attr = Some(tokens); + } + } + _ => { + return Err(Error::new( + attr.span(), + "Conditional widgets can only have docs and `name` or `transition` as attribute.", + ).into()); + } + } + } + } + Ok((transition, name, doc_attr, assign_wrapper)) + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/if_branch.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/if_branch.rs new file mode 100644 index 0000000..7c627f4 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/if_branch.rs @@ -0,0 +1,43 @@ +use proc_macro2::Span as Span2; +use syn::parse::ParseStream; +use syn::punctuated::Punctuated; +use syn::token::{And, Paren}; +use syn::{Expr, ExprCall, ExprLit, ExprPath, Ident, Lit, LitStr}; + +use crate::args::Args; +use crate::widgets::{parse_util, IfBranch, ParseError, Widget}; + +impl IfBranch { + pub(super) fn parse(input: ParseStream<'_>, index: usize) -> Result { + let cond = input.parse()?; + + let braced = parse_util::braces(input)?; + + let attributes = braced.parse().ok(); + let args = args_from_index(index, input.span()); + let mut widget = Widget::parse(&braced, attributes, Some(args))?; + widget.ref_token = Some(And { + spans: [Span2::call_site()], + }); + + Ok(Self { cond, widget }) + } +} + +pub(super) fn args_from_index(index: usize, span: Span2) -> Args { + Args { + inner: vec![Expr::Call(ExprCall { + attrs: Vec::new(), + func: Box::new(Expr::Path(ExprPath { + attrs: Vec::new(), + qself: None, + path: Ident::new("Some", span).into(), + })), + paren_token: Paren(span), + args: Punctuated::from_iter(vec![Expr::Lit(ExprLit { + attrs: Vec::new(), + lit: Lit::Str(LitStr::new(&format!("{index}"), span)), + })]), + })], + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/if_condition.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/if_condition.rs new file mode 100644 index 0000000..88eb3db --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/if_condition.rs @@ -0,0 +1,21 @@ +use syn::parse::{Parse, ParseStream}; +use syn::{Result, Token}; + +use crate::widgets::IfCondition; + +impl Parse for IfCondition { + fn parse(input: ParseStream<'_>) -> Result { + if input.peek(Token![if]) { + Ok(Self::If(input.parse()?, input.parse()?)) + } else if input.peek(Token![else]) { + let else_token = input.parse()?; + if input.peek(Token![if]) { + Ok(Self::ElseIf(else_token, input.parse()?, input.parse()?)) + } else { + Ok(Self::Else(else_token)) + } + } else { + Err(input.error("Expected `if`, `if else` or `else`")) + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/match_arm.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/match_arm.rs new file mode 100644 index 0000000..064f57a --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/match_arm.rs @@ -0,0 +1,45 @@ +use syn::parse::ParseStream; +use syn::token::And; +use syn::{token, Token}; + +use crate::widgets::parse::if_branch::args_from_index; +use crate::widgets::{parse_util, MatchArm, ParseError, Widget}; + +impl MatchArm { + pub(super) fn parse(input: ParseStream<'_>, index: usize) -> Result { + if input.peek(Token![,]) { + let _comma: Token![,] = input.parse()?; + } + + let pattern = syn::Pat::parse_multi_with_leading_vert(input)?; + let guard = if input.peek(token::FatArrow) { + None + } else { + Some((input.parse()?, input.parse()?)) + }; + + let arrow = input.parse()?; + + let braced; + let inner_tokens = if input.peek(token::Brace) { + braced = parse_util::braces(input)?; + &braced + } else { + input + }; + + let attributes = inner_tokens.parse().ok(); + let args = args_from_index(index, input.span()); + + let ref_span = input.span(); + let mut widget = Widget::parse(inner_tokens, attributes, Some(args))?; + widget.ref_token = Some(And { spans: [ref_span] }); + + Ok(Self { + pattern, + guard, + arrow, + widget, + }) + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/mod.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/mod.rs new file mode 100644 index 0000000..e1f8e6b --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/mod.rs @@ -0,0 +1,17 @@ +mod assign_property; +mod attributes; +mod conditional_branches; +mod conditional_widget; +mod if_branch; +mod if_condition; +mod match_arm; +mod properties; +mod property; +mod property_name; +mod returned_widget; +mod signal_handler; +mod top_level_widget; +mod view_widgets; +mod widget; +mod widget_func; +mod widget_func_method; diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/properties.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/properties.rs new file mode 100644 index 0000000..b480f74 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/properties.rs @@ -0,0 +1,143 @@ +use proc_macro2::{Literal, Punct}; +use syn::ext::IdentExt; +use syn::parse::discouraged::Speculative; +use syn::parse::ParseStream; +use syn::punctuated::{Pair, Punctuated}; +use syn::token::{And, At, Caret, Colon, Dot, Gt, Lt, Or, Question, Slash, Tilde, Underscore}; +use syn::{braced, bracketed, parenthesized, token, Ident, Lifetime, Token}; + +use crate::widgets::{parse_util, ParseError, Properties, Property, PropertyName, PropertyType}; + +impl Properties { + pub(super) fn parse(input: ParseStream<'_>) -> Self { + let mut props: Punctuated = Punctuated::new(); + loop { + if input.is_empty() { + break; + } + let parse_input = input.fork(); + let (prop, contains_error) = Property::parse(&parse_input); + props.push(prop); + + // Everything worked, advance input + if !contains_error { + input.advance_to(&parse_input); + } + + if input.is_empty() { + break; + } + + if let Err(prop) = parse_comma_error(input) { + // If there's already an error, ignore the additional comma error + if contains_error { + // Skip to next token to start with "fresh" and hopefully correct syntax. + while !parse_next_token(input).unwrap() { + let next_input = input.fork(); + let (prop, contains_error) = Property::parse(&next_input); + if !contains_error { + // Point with correct syntax was found! + props.push(prop); + input.advance_to(&next_input); + + // Now we should definitely have a comma + if let Err(prop) = parse_comma_error(input) { + props.push(prop); + } + break; + } + } + } else { + props.push(prop); + } + } + } + + let properties = props.into_pairs().map(Pair::into_value).collect(); + Properties { properties } + } +} + +fn parse_comma_error(input: ParseStream<'_>) -> Result<(), Property> { + let lookahead = input.lookahead1(); + if lookahead.peek(Token![,]) { + input.parse::().unwrap(); + Ok(()) + } else { + let err = lookahead.error(); + Err(Property { + name: PropertyName::Ident(parse_util::string_to_snake_case("comma_error")), + ty: PropertyType::ParseError(ParseError::Generic(err.to_compile_error())), + }) + } +} + +macro_rules! parse_type { + ($input:ident, $ty:ty) => { + let _: $ty = $input.parse()?; + return Ok(false); + }; +} + +fn skip_inner_tokens(input: ParseStream<'_>) -> Result<(), syn::Error> { + while !input.is_empty() { + parse_next_token(input)?; + } + Ok(()) +} + +fn parse_next_token(input: ParseStream<'_>) -> Result { + let inner_tokens; + if input.is_empty() { + Ok(true) + } else if input.peek(Token![,]) { + let _comma: Token![,] = input.parse()?; + Ok(true) + } else if input.peek(token::Paren) { + parenthesized!(inner_tokens in input); + skip_inner_tokens(&inner_tokens)?; + Ok(false) + } else if input.peek(token::Bracket) { + bracketed!(inner_tokens in input); + skip_inner_tokens(&inner_tokens)?; + Ok(false) + } else if input.peek(token::Brace) { + braced!(inner_tokens in input); + skip_inner_tokens(&inner_tokens)?; + Ok(false) + } else if Ident::parse_any(input).is_ok() { + Ok(false) + } else if input.peek(And) { + parse_type!(input, And); + } else if input.peek(At) { + parse_type!(input, At); + } else if input.peek(Colon) { + parse_type!(input, Colon); + } else if input.peek(Slash) { + parse_type!(input, Slash); + } else if input.peek(syn::token::Eq) { + parse_type!(input, syn::token::Eq); + } else if input.peek(Gt) { + parse_type!(input, Gt); + } else if input.peek(Lt) { + parse_type!(input, Lt); + } else if input.peek(Or) { + parse_type!(input, Or); + } else if input.peek(Tilde) { + parse_type!(input, Tilde); + } else if input.peek(Caret) { + parse_type!(input, Caret); + } else if input.peek(Underscore) { + parse_type!(input, Underscore); + } else if input.peek(Question) { + parse_type!(input, Question); + } else if input.peek(Dot) { + parse_type!(input, Dot); + } else if input.peek(Lifetime) { + parse_type!(input, Lifetime); + } else if input.parse::().is_ok() || input.parse::().is_ok() { + Ok(false) + } else { + unreachable!("Every possible token should be covered. Please report this error at Relm4! \nContext: '''{input}''' \n"); + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/property.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/property.rs new file mode 100644 index 0000000..b92e07d --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/property.rs @@ -0,0 +1,142 @@ +use syn::parse::ParseStream; +use syn::spanned::Spanned; +use syn::{token, Error, Ident, Token}; + +use crate::widgets::{ + parse_util, AssignProperty, Attrs, ConditionalWidget, ParseError, Property, PropertyName, + PropertyType, SignalHandler, Widget, WidgetFunc, +}; + +impl Property { + pub(super) fn parse(input: ParseStream<'_>) -> (Self, bool) { + match Self::parse_failing(input) { + Ok(prop) => (prop, false), + Err(err) => ( + Self { + name: PropertyName::Ident(parse_util::string_to_snake_case("invalid_property")), + ty: PropertyType::ParseError(err), + }, + true, + ), + } + } + + fn parse_failing(input: ParseStream<'_>) -> Result { + // Handle `#[attrs]` + let mut attributes: Option = if input.peek(Token![#]) { + Some(input.parse()?) + } else { + None + }; + + // parse `if something { WIDGET } else { WIDGET}` or a similar match expression. + if input.peek(Token![if]) || input.peek(Token![match]) { + return Ok(Property { + name: PropertyName::RelmContainerExtAssign(input.span()), + ty: PropertyType::ConditionalWidget(ConditionalWidget::parse_with_name( + input, + None, + attributes.take(), + None, + )?), + }); + } + + // Parse path, ident or function + let func = WidgetFunc::parse(input)?; + + // `gtk::Box { ... }`, `data.init_widget() -> gtk::Button { ... }` or `gtk::Box,` + if input.peek(token::Brace) || input.peek(Token![->]) || input.peek(Token![,]) { + let span = func.span(); + let ty = + PropertyType::Widget(Widget::parse_for_container_ext(input, func, attributes)?); + + Ok(Property { + name: PropertyName::RelmContainerExtAssign(span), + ty, + }) + } else { + let name = func.into_property_name()?; + + // check for property[a, b, c]: ... + let mut args = if input.peek(token::Bracket) { + let paren_input = parse_util::brackets(input)?; + Some(paren_input.parse()?) + } else { + None + }; + + // look for event handlers: signal[cloned_data, ...] => move |a, ...| { ... } + let ty = if input.peek(Token! [=>]) { + let _arrow: Token![=>] = input.parse()?; + PropertyType::SignalHandler(SignalHandler::parse_with_args(input, args.take())?) + } + // look for widgets + else if (input.peek(Token![=]) + || input.peek3(Token![=]) + || (input.peek(Token![:]) && input.peek2(Token![mut]) && input.peek3(Ident))) + // Don't interpret `property: value == other,` as a widget + && !input.peek3(Token![==]) + { + let is_conditional = if input.peek(Token![=]) { + let _token: Token![=] = input.parse()?; + input.peek(Token![if]) || input.peek(Token![match]) + } else { + let _colon: Token![:] = input.parse()?; + input.peek3(Token![if]) || input.peek3(Token![match]) + }; + // match expression + if is_conditional { + PropertyType::ConditionalWidget(ConditionalWidget::parse( + input, + attributes.take(), + args.take(), + )?) + } else { + PropertyType::Widget(Widget::parse(input, attributes.take(), args.take())?) + } + } + // look for properties or optional properties (?) + else if input.peek(Token! [:]) || input.peek(Token! [?]) { + // look for ? at beginning for optional assign + PropertyType::Assign(AssignProperty::parse( + input, + attributes.take(), + args.take(), + )?) + } else { + return Err(input.error("Unexpected syntax.").into()); + }; + + // Attributes must have been set to `None` by `take()` + if let Some(attrs) = attributes { + if let Some(first_attr) = attrs.inner.first() { + return Err(Error::new( + first_attr.span(), + "No attributes allowed in the following expression.", + ) + .into()); + } + } + + // Arguments must have been set to `None` by `take()` + if let Some(args) = args { + if let Some(first_arg) = args.inner.first() { + return Err(Error::new( + first_arg.span(), + "No arguments allowed in this expression.", + ) + .into()); + } + } + + if !input.is_empty() && !input.peek(Token![,]) { + Err(input + .error("expected `,`. Did you confuse `=` with`:`?") + .into()) + } else { + Ok(Property { name, ty }) + } + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/property_name.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/property_name.rs new file mode 100644 index 0000000..caf306e --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/property_name.rs @@ -0,0 +1,14 @@ +use syn::parse::{Parse, ParseStream}; +use syn::{Result, Token}; + +use crate::widgets::PropertyName; + +impl Parse for PropertyName { + fn parse(input: ParseStream<'_>) -> Result { + Ok(if input.peek(Token![::]) || input.peek2(Token! [::]) { + PropertyName::Path(input.parse()?) + } else { + PropertyName::Ident(input.parse()?) + }) + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/returned_widget.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/returned_widget.rs new file mode 100644 index 0000000..ff8631b --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/returned_widget.rs @@ -0,0 +1,50 @@ +use syn::parse::{Parse, ParseStream}; +use syn::spanned::Spanned; +use syn::{braced, Ident, Result, Token}; + +use crate::widgets::{parse_util, Properties, ReturnedWidget}; + +impl Parse for ReturnedWidget { + fn parse(input: ParseStream<'_>) -> Result { + let mut is_optional = false; + + let (name, ty) = if input.peek(Ident) { + let name = input.parse()?; + + let _colon: Token![:] = input.parse()?; + let ty = input.parse()?; + + if input.peek(Token![?]) { + let _mark: Token![?] = input.parse()?; + is_optional = true; + } + + (Some(name), Some(ty)) + } else { + if input.peek(Token![?]) { + let _mark: Token![?] = input.parse()?; + is_optional = true; + } + + (None, None) + }; + + let name = name.unwrap_or_else(|| { + parse_util::idents_to_snake_case( + [Ident::new("_returned_widget", input.span())].iter(), + ty.span(), + ) + }); + + let inner; + let _token = braced!(inner in input); + let properties = Properties::parse(&inner); + + Ok(ReturnedWidget { + name, + ty, + properties, + is_optional, + }) + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/signal_handler.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/signal_handler.rs new file mode 100644 index 0000000..54df392 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/signal_handler.rs @@ -0,0 +1,37 @@ +use syn::parse::ParseStream; +use syn::{Expr, Result, Token}; + +use crate::widgets::{Args, ClosureSignalHandler, SignalHandler, SignalHandlerVariant}; + +impl SignalHandler { + pub(super) fn parse_with_args( + input: ParseStream<'_>, + args: Option>, + ) -> Result { + let inner = if args.is_some() || input.peek(Token![move]) || input.peek(Token![|]) { + ClosureSignalHandler::parse_with_args(input, args).map(SignalHandlerVariant::Closure) + } else { + input.parse().map(SignalHandlerVariant::Expr) + }?; + + let handler_id = if input.peek(Token![@]) { + let _arrow: Token![@] = input.parse()?; + input.parse()? + } else { + None + }; + + Ok(Self { inner, handler_id }) + } +} + +impl ClosureSignalHandler { + pub(super) fn parse_with_args( + input: ParseStream<'_>, + args: Option>, + ) -> Result { + let closure = input.parse()?; + + Ok(Self { closure, args }) + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/top_level_widget.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/top_level_widget.rs new file mode 100644 index 0000000..41db210 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/top_level_widget.rs @@ -0,0 +1,66 @@ +use syn::parse::ParseStream; + +use crate::util; +use crate::widgets::{ + parse_util, Attr, Attrs, Properties, Property, PropertyName, PropertyType, TopLevelWidget, + Widget, WidgetAttr, WidgetFunc, WidgetTemplateAttr, +}; + +impl TopLevelWidget { + pub(super) fn parse(input: ParseStream<'_>) -> Self { + let attributes: Option = input.parse().ok(); + + // Look for #[root] attribute and remove it from the list if it exists + let (attributes, root_attr) = if let Some(prev_attributes) = attributes { + let mut attributes = Attrs { + inner: Vec::with_capacity(prev_attributes.inner.len()), + }; + let mut root_attr = None; + for attr in prev_attributes.inner { + match attr { + Attr::Root(ident) => { + // Save root attribute and don't push it to the new list + root_attr = Some(ident); + } + _ => attributes.inner.push(attr), + } + } + (Some(attributes), root_attr) + } else { + (None, None) + }; + + let inner = match Widget::parse(input, attributes, None) { + Ok(inner) => inner, + Err(err) => Widget { + doc_attr: None, + attr: WidgetAttr::None, + template_attr: WidgetTemplateAttr::None, + mutable: None, + name: parse_util::string_to_snake_case("incorrect_top_level_widget"), + name_assigned_by_user: false, + func: WidgetFunc { + path: util::strings_to_path(&["gtk", "Box"]), + args: None, + method_chain: None, + ty: None, + }, + args: None, + properties: Properties { + properties: vec![Property { + name: PropertyName::Ident(parse_util::string_to_snake_case( + "invalid_property", + )), + ty: PropertyType::ParseError(err), + }], + }, + assign_wrapper: None, + ref_token: None, + deref_token: None, + returned_widget: None, + }, + }; + + Self { root_attr, inner } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/view_widgets.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/view_widgets.rs new file mode 100644 index 0000000..fd9b794 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/view_widgets.rs @@ -0,0 +1,39 @@ +use syn::parse::{Parse, ParseStream, Result}; +use syn::{Error, Ident, Token}; + +use crate::widgets::{TopLevelWidget, ViewWidgets}; + +impl Parse for ViewWidgets { + fn parse(input: ParseStream<'_>) -> Result { + let span = input.span(); + + let first_widget = TopLevelWidget::parse(input); + let mut root_exists = first_widget.root_attr.is_some(); + let mut top_level_widgets = vec![first_widget]; + + // Parse colon between widgets and look for more + while input.parse::().is_ok() && !input.is_empty() { + let widget = TopLevelWidget::parse(input); + if let Some(root_attr) = &widget.root_attr { + if root_exists { + return Err(Error::new(root_attr.span(), "You cannot have two roots.")); + } + root_exists = true; + } + top_level_widgets.push(widget); + } + + if !root_exists && top_level_widgets.len() == 1 { + top_level_widgets[0].root_attr = Some(Ident::new("root", input.span())); + } + + if input.is_empty() { + Ok(Self { + span, + top_level_widgets, + }) + } else { + Err(input.error("Unexpected end of input. Maybe a missing comma `,`?")) + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/widget.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/widget.rs new file mode 100644 index 0000000..5477d07 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/widget.rs @@ -0,0 +1,285 @@ +use proc_macro2::TokenStream as TokenStream2; +use syn::parse::ParseStream; +use syn::spanned::Spanned; +use syn::token::{And, Star}; +use syn::{Error, Expr, Ident, Path, Token}; + +use crate::args::Args; +use crate::widgets::parse_util::{self, attr_twice_error}; +use crate::widgets::{ + Attr, Attrs, ParseError, Properties, PropertyType, Widget, WidgetAttr, WidgetFunc, + WidgetTemplateAttr, +}; + +type WidgetFuncInfo = (Option, Option, WidgetFunc, Properties); + +type AttributeInfo = ( + WidgetAttr, + Option, + Option, + Option, + WidgetTemplateAttr, +); + +impl Widget { + pub(super) fn parse( + input: ParseStream<'_>, + attributes: Option, + args: Option>, + ) -> Result { + let (attr, doc_attr, new_name, assign_wrapper, template_attr) = + Self::process_attributes(attributes)?; + // Check if first token is `mut` + let mutable = input.parse().ok(); + + // Look for name = Widget syntax + let name_opt: Option = if input.peek2(Token![=]) { + if attr.is_local_attr() || template_attr == WidgetTemplateAttr::TemplateChild { + return Err(input.error("When using the `local`, `local_ref` or `template_child` attributes you cannot rename the existing local variable.").into()); + } + let name = input.parse()?; + let _token: Token![=] = input.parse()?; + Some(name) + } else { + None + }; + + let (ref_token, deref_token, func, properties) = Self::parse_widget_func(input)?; + + // Make sure that the name is only defined one. + let mut name_set = name_opt.is_some(); + if new_name.is_some() { + if name_set { + return Err(Error::new(name_opt.unwrap().span(), "Widget name is specified more than once (attribute, assignment or local attribute).").into()); + } + name_set = true; + } + + if name_set && (attr.is_local_attr() || template_attr == WidgetTemplateAttr::TemplateChild) + { + return Err(Error::new(input.span(), "Widget name is specified more than once (attribute, assignment or local attribute).").into()); + } + + // Generate a name if no name was given. + let (name, name_assigned_by_user) = if let Some(name) = name_opt.or(new_name) { + (name, true) + } else if attr.is_local_attr() || template_attr == WidgetTemplateAttr::TemplateChild { + (Self::local_attr_name(&func)?, true) + } else { + (func.snake_case_name(), false) + }; + + let returned_widget = if input.peek(Token![->]) { + let _arrow: Token![->] = input.parse()?; + Some(input.parse()?) + } else { + None + }; + + Self::check_props(&properties, &template_attr)?; + + Ok(Widget { + doc_attr, + attr, + template_attr, + mutable, + name, + name_assigned_by_user, + func, + args, + properties, + assign_wrapper, + ref_token, + deref_token, + returned_widget, + }) + } + + pub(super) fn parse_for_container_ext( + input: ParseStream<'_>, + func: WidgetFunc, + attributes: Option, + ) -> Result { + let (attr, doc_attr, new_name, assign_wrapper, template_attr) = + Self::process_attributes(attributes)?; + + if let Some(wrapper) = assign_wrapper { + return Err(Error::new( + wrapper.span(), + "Can't use wrapper types in container assignment.", + ) + .into()); + } + + let properties = if input.peek(Token![,]) { + Properties::default() + } else { + let inner = parse_util::braces(input)?; + Properties::parse(&inner) + }; + + // Make sure that the name is only defined one. + if attr.is_local_attr() || template_attr == WidgetTemplateAttr::TemplateChild { + if let Some(name) = &new_name { + return Err(Error::new(name.span(), "Widget name is specified more than once (attribute, assignment or local attribute).").into()); + } + } + + // Generate a name + let (name, name_assigned_by_user) = if let Some(name) = new_name { + (name, true) + } else if attr.is_local_attr() || template_attr == WidgetTemplateAttr::TemplateChild { + (Self::local_attr_name(&func)?, true) + } else { + (func.snake_case_name(), false) + }; + + let ref_token = Some(And::default()); + + Self::check_props(&properties, &template_attr)?; + + Ok(Widget { + doc_attr, + attr, + template_attr, + mutable: None, + name, + name_assigned_by_user, + func, + args: None, + properties, + assign_wrapper, + ref_token, + deref_token: None, + returned_widget: None, + }) + } + + fn check_props( + props: &Properties, + template_attr: &WidgetTemplateAttr, + ) -> Result<(), ParseError> { + // Make sure template_child is only used in a valid context. + if template_attr != &WidgetTemplateAttr::Template { + for prop in &props.properties { + if let PropertyType::Widget(widget) = &prop.ty { + if widget.template_attr == WidgetTemplateAttr::TemplateChild { + return Err(ParseError::Generic( + syn::Error::new( + widget.name.span(), + "You can't use a template child if the parent is not a template.", + ) + .to_compile_error(), + )); + } + } + } + } + Ok(()) + } + + fn process_attributes(attrs: Option) -> Result { + if let Some(attrs) = attrs { + let mut widget_attr = WidgetAttr::None; + let mut doc_attr: Option = None; + let mut name = None; + let mut assign_wrapper = None; + let mut template_attr = WidgetTemplateAttr::None; + + for attr in attrs.inner { + let span = attr.span(); + match attr { + Attr::Local(_) => { + if widget_attr == WidgetAttr::None { + widget_attr = WidgetAttr::Local; + } else { + return Err(attr_twice_error(span).into()); + } + } + Attr::LocalRef(_) => { + if widget_attr == WidgetAttr::None { + widget_attr = WidgetAttr::LocalRef; + } else { + return Err(attr_twice_error(span).into()); + } + } + Attr::Doc(tokens) => { + if let Some(doc_tokens) = &mut doc_attr { + doc_tokens.extend(tokens); + } else { + doc_attr = Some(tokens); + } + } + Attr::Name(_, name_value) => { + if name.is_some() { + return Err(attr_twice_error(span).into()); + } + name = Some(name_value); + } + Attr::Wrap(_, path) => { + if assign_wrapper.is_some() { + return Err(attr_twice_error(span).into()); + } + assign_wrapper = Some(path.clone()); + } + Attr::Template(_) => { + if template_attr != WidgetTemplateAttr::None { + return Err(attr_twice_error(span).into()); + } + template_attr = WidgetTemplateAttr::Template; + } + Attr::TemplateChild(_) => { + if template_attr != WidgetTemplateAttr::None { + return Err(attr_twice_error(span).into()); + } + template_attr = WidgetTemplateAttr::TemplateChild; + } + _ => { + return Err(Error::new( + attr.span(), + "Widgets can only have docs and `local`, `local_ref`, `wrap`, `name`, `template`, `template_child` or `root` as attribute.", + ).into()); + } + } + } + + Ok((widget_attr, doc_attr, name, assign_wrapper, template_attr)) + } else { + Ok((WidgetAttr::None, None, None, None, WidgetTemplateAttr::None)) + } + } + + // Make sure that the widget function is just a single identifier of the + // local variable if a local attribute was set. + fn local_attr_name(func: &WidgetFunc) -> Result { + if let Some(name) = func.path.get_ident() { + Ok(name.clone()) + } else { + Err(Error::new( + func.path.span(), + "Expected identifier due to the `local`, `local_ref` or `template_child` attribute.", + ) + .into()) + } + } + + /// Parse information related to the widget function. + fn parse_widget_func(input: ParseStream<'_>) -> Result { + // Look for & + let ref_token = input.parse().ok(); + + // Look for * + let deref_token = input.parse().ok(); + + let func = WidgetFunc::parse(input)?; + + let properties = if input.peek(Token![,]) { + Properties::default() + } else { + let inner = parse_util::braces(input)?; + Properties::parse(&inner) + }; + + Ok((ref_token, deref_token, func, properties)) + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/widget_func.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/widget_func.rs new file mode 100644 index 0000000..9bf9344 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/widget_func.rs @@ -0,0 +1,65 @@ +use syn::parse::ParseStream; +use syn::punctuated::Punctuated; +use syn::spanned::Spanned; +use syn::{token, Ident, Path, Token}; + +use crate::widgets::{parse_util, ParseError, WidgetFunc}; + +impl WidgetFunc { + pub(super) fn parse_with_path(input: ParseStream<'_>, path: &Path) -> Result { + match Self::parse_with_path_internal(input, path) { + Ok(func) => Ok(func), + Err(err) => Err(err.add_path(path)), + } + } + + fn parse_with_path_internal(input: ParseStream<'_>, path: &Path) -> Result { + if input.peek(Ident) { + return Err(ParseError::Generic( + syn::Error::new( + path.span() + .join(input.span()) + .unwrap_or_else(|| input.span()), + "A path must not be followed by an identifier", + ) + .into_compile_error(), + ) + .add_path(path)); + } + + let args = if input.peek(token::Paren) { + let paren_input = parse_util::parens(input)?; + Some(paren_input.call(Punctuated::parse_terminated)?) + } else { + None + }; + + let method_chain = if input.peek(token::Dot) { + let _dot: token::Dot = input.parse()?; + Some(Punctuated::parse_separated_nonempty(input)?) + } else { + None + }; + + let ty = if input.peek(Token! [->]) { + let _token: Token! [->] = input.parse()?; + Some(input.parse()?) + } else { + None + }; + + Ok(WidgetFunc { + path: path.clone(), + args, + method_chain, + ty, + }) + } +} + +impl WidgetFunc { + pub(super) fn parse(input: ParseStream<'_>) -> Result { + let path = &input.parse()?; + Self::parse_with_path(input, path) + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse/widget_func_method.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse/widget_func_method.rs new file mode 100644 index 0000000..e3e0c54 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse/widget_func_method.rs @@ -0,0 +1,25 @@ +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::{parenthesized, token, Result}; + +use crate::widgets::WidgetFuncMethod; + +impl Parse for WidgetFuncMethod { + fn parse(input: ParseStream<'_>) -> Result { + let ident = input.parse()?; + let turbofish = input.parse().ok(); + let args = if input.peek(token::Paren) { + let inner_input; + parenthesized!(inner_input in input); + Some(Punctuated::parse_terminated(&inner_input)?) + } else { + None + }; + + Ok(Self { + ident, + turbofish, + args, + }) + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/parse_util.rs b/Relm4-0.6.2/relm4-macros/src/widgets/parse_util.rs new file mode 100644 index 0000000..a83e7a2 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/parse_util.rs @@ -0,0 +1,162 @@ +use std::sync::atomic::{AtomicU16, Ordering}; + +use proc_macro2::Span as Span2; +use syn::parse::ParseBuffer; +use syn::spanned::Spanned; +use syn::{braced, bracketed, parenthesized, Error, Ident, Path}; + +use super::{ParseError, PropertyName}; +use crate::widgets::{AssignPropertyAttr, WidgetAttr, WidgetFunc}; + +pub(super) fn attr_twice_error(span: Span2) -> Error { + Error::new(span, "Cannot use the same attribute twice.") +} + +impl From for ParseError { + fn from(error: Error) -> Self { + Self::Generic(error.to_compile_error()) + } +} + +impl ParseError { + pub(super) fn add_path(self, path: &Path) -> Self { + if let ParseError::Generic(tokens) = self { + if let Some(ident) = path.get_ident() { + ParseError::Ident((ident.clone(), tokens)) + } else { + ParseError::Path((path.clone(), tokens)) + } + } else { + self + } + } +} + +impl WidgetFunc { + pub(super) fn into_property_name(self) -> Result { + if let Some(methods) = &self.method_chain { + Err(Error::new( + methods.span(), + "Can't use method calls in property assignments", + )) + } else if let Some(args) = &self.args { + Err(Error::new( + args.span(), + "Can't use function arguments in property assignments", + )) + } else { + Ok(if let Some(ident) = self.path.get_ident() { + PropertyName::Ident(ident.clone()) + } else { + PropertyName::Path(self.path) + }) + } + } +} + +impl WidgetFunc { + pub(super) fn snake_case_name(&self) -> Ident { + idents_to_snake_case( + self.path.segments.iter().map(|seg| &seg.ident), + self.path.span(), + ) + } +} + +impl WidgetAttr { + pub(super) fn is_local_attr(&self) -> bool { + matches!(self, Self::Local | Self::LocalRef) + } +} + +impl AssignPropertyAttr { + pub(super) fn should_skip_init(&self) -> bool { + match self { + Self::None => false, + Self::Watch { skip_init } | Self::Track { skip_init, .. } => skip_init.is_some(), + } + } +} + +impl PartialEq for AssignPropertyAttr { + fn eq(&self, other: &Self) -> bool { + core::mem::discriminant(self) == core::mem::discriminant(other) + } +} + +pub(crate) fn string_to_snake_case(string: &str) -> Ident { + idents_to_snake_case( + [Ident::new(string, Span2::call_site())].iter(), + Span2::call_site(), + ) +} + +pub(crate) fn idents_to_snake_case<'a, I: Iterator>( + idents: I, + span: Span2, +) -> Ident { + static COUNTER: AtomicU16 = AtomicU16::new(0); + let val = COUNTER.fetch_add(1, Ordering::Relaxed); + let index_str = val.to_string(); + + let segments: Vec = idents + .map(|ident| ident.to_string().to_lowercase()) + .collect(); + let length: usize = + segments.iter().map(|seg| seg.len() + 1).sum::() + index_str.len() + 1; + let mut name: String = String::with_capacity(length); + + for seg in &segments { + name.push('_'); + name.push_str(seg); + } + name.push('_'); + name.push_str(&index_str); + + Ident::new(&name, span) +} + +/// Weird hack to work around syn's awkward macros +/// that always return [`syn::Error`] and are worse +/// in every aspect compared to regular Rust code. +/// +/// Sadly, the regular Rust API won't be made public, +/// see [#1190](https://github.com/dtolnay/syn/issues/1190). +pub(super) fn parens<'a>(input: &'a ParseBuffer<'_>) -> Result, ParseError> { + let content = (move || { + let content; + parenthesized!(content in input); + Ok(content) + })(); + Ok(content?) +} + +/// Weird hack to work around syn's awkward macros +/// that always return [`syn::Error`] and are worse +/// in every aspect compared to regular Rust code. +/// +/// Sadly, the regular Rust API won't be made public, +/// see [#1190](https://github.com/dtolnay/syn/issues/1190). +pub(super) fn braces<'a>(input: &'a ParseBuffer<'_>) -> Result, ParseError> { + let content = (move || { + let content; + braced!(content in input); + Ok(content) + })(); + Ok(content?) +} + +/// Weird hack to work around syn's awkward macros +/// that always return [`syn::Error`] and are worse +/// in every aspect compared to regular Rust code. +/// +/// Sadly, the regular Rust API won't be made public, +/// see [#1190](https://github.com/dtolnay/syn/issues/1190). +pub(super) fn brackets<'a>(input: &'a ParseBuffer<'_>) -> Result, ParseError> { + let content = (move || { + let content; + bracketed!(content in input); + Ok(content) + })(); + Ok(content?) +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/span/attr.rs b/Relm4-0.6.2/relm4-macros/src/widgets/span/attr.rs new file mode 100644 index 0000000..71f4bbd --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/span/attr.rs @@ -0,0 +1,25 @@ +use proc_macro2::Span as Span2; +use syn::spanned::Spanned; + +use crate::widgets::Attr; + +impl Attr { + pub(crate) fn span(&self) -> Span2 { + match self { + Self::Doc(tokens) => tokens.span(), + Self::Local(ident) + | Self::LocalRef(ident) + | Self::Root(ident) + | Self::Iterate(ident) + | Self::Watch(ident, _) + | Self::Track(ident, _, _) + | Self::BlockSignal(ident, _) + | Self::Name(ident, _) + | Self::Transition(ident, _) + | Self::Chain(ident, _) + | Self::Template(ident) + | Self::TemplateChild(ident) + | Self::Wrap(ident, _) => ident.span(), + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/span/mod.rs b/Relm4-0.6.2/relm4-macros/src/widgets/span/mod.rs new file mode 100644 index 0000000..9764824 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/span/mod.rs @@ -0,0 +1,6 @@ +//! Span implementations + +mod attr; +mod property_name; +mod widget_func; +mod widget_func_method; diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/span/property_name.rs b/Relm4-0.6.2/relm4-macros/src/widgets/span/property_name.rs new file mode 100644 index 0000000..93db0da --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/span/property_name.rs @@ -0,0 +1,14 @@ +use proc_macro2::Span as Span2; +use syn::spanned::Spanned; + +use crate::widgets::PropertyName; + +impl PropertyName { + pub(crate) fn span(&self) -> Span2 { + match self { + PropertyName::Ident(ident) => ident.span(), + PropertyName::Path(path) => path.span(), + PropertyName::RelmContainerExtAssign(span) => *span, + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/span/widget_func.rs b/Relm4-0.6.2/relm4-macros/src/widgets/span/widget_func.rs new file mode 100644 index 0000000..0245fce --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/span/widget_func.rs @@ -0,0 +1,10 @@ +use proc_macro2::Span as Span2; +use syn::spanned::Spanned; + +use crate::widgets::WidgetFunc; + +impl WidgetFunc { + pub(crate) fn span(&self) -> Span2 { + self.path.span() + } +} diff --git a/Relm4-0.6.2/relm4-macros/src/widgets/span/widget_func_method.rs b/Relm4-0.6.2/relm4-macros/src/widgets/span/widget_func_method.rs new file mode 100644 index 0000000..6a34fb6 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/src/widgets/span/widget_func_method.rs @@ -0,0 +1,23 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, ToTokens}; + +use crate::widgets::WidgetFuncMethod; + +impl ToTokens for WidgetFuncMethod { + fn to_tokens(&self, tokens: &mut TokenStream2) { + let WidgetFuncMethod { + ident, + turbofish, + args, + } = &self; + tokens.extend(if let Some(args) = args { + quote! { + #ident #turbofish (#args) + } + } else { + quote! { + #ident #turbofish + } + }); + } +} diff --git a/Relm4-0.6.2/relm4-macros/tests/builder.rs b/Relm4-0.6.2/relm4-macros/tests/builder.rs new file mode 100644 index 0000000..b31c37f --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/builder.rs @@ -0,0 +1,40 @@ +use gtk::prelude::GtkWindowExt; +use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + +#[derive(Default)] +struct App; + +#[relm4_macros::component] +impl SimpleComponent for App { + type Init = (); + type Input = (); + type Output = (); + type Widgets = AppWidgets; + + view! { + gtk::Window { + set_title: Some("Simple app"), + set_default_size: (300, 100), + + gtk::Box { + gtk::Builder::from_string("") + .object::("label") + .unwrap() -> gtk::Label {}, + }, + } + } + + fn init( + _init: Self::Init, + _root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, _msg: Self::Input, _sender: ComponentSender) {} +} diff --git a/Relm4-0.6.2/relm4-macros/tests/codegen_order.rs b/Relm4-0.6.2/relm4-macros/tests/codegen_order.rs new file mode 100644 index 0000000..5f76e05 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/codegen_order.rs @@ -0,0 +1,34 @@ +use relm4::{ComponentParts, ComponentSender, SimpleComponent}; + +#[derive(Default)] +struct App; + +#[relm4_macros::component] +impl SimpleComponent for App { + type Init = (); + type Input = (); + type Output = (); + + view! { + mut Vec::> { + push = mut Vec { + push: 0, + push: 1, + } + } + } + + fn init( + _init: Self::Init, + _root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, _msg: Self::Input, _sender: ComponentSender) {} +} diff --git a/Relm4-0.6.2/relm4-macros/tests/complex_func_path.rs b/Relm4-0.6.2/relm4-macros/tests/complex_func_path.rs new file mode 100644 index 0000000..4ba7043 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/complex_func_path.rs @@ -0,0 +1,46 @@ +use gtk::prelude::{GtkWindowExt, OrientableExt}; +use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + +#[derive(Default)] +struct App; + +trait TestType { + type Test; +} + +impl TestType for App { + type Test = gtk::Box; +} + +#[relm4_macros::component] +impl SimpleComponent for App { + type Init = (); + type Input = (); + type Output = (); + type Widgets = AppWidgets; + + view! { + gtk::Window { + set_title: Some("Simple app"), + set_default_size: (300, 100), + + gtk::Box::default() -> ::Test { + set_orientation: gtk::Orientation::Vertical, + }, + } + } + + fn init( + _: Self::Init, + root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, _msg: (), _sender: ComponentSender) {} +} diff --git a/Relm4-0.6.2/relm4-macros/tests/component_missing_widgets.rs b/Relm4-0.6.2/relm4-macros/tests/component_missing_widgets.rs new file mode 100644 index 0000000..b391b61 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/component_missing_widgets.rs @@ -0,0 +1,28 @@ +use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + +struct TestComponent; + +#[relm4_macros::component] +impl SimpleComponent for TestComponent { + type Init = (); + type Input = (); + type Output = (); + + view! { + gtk::Window {} + } + + fn init( + _: Self::Init, + root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } +} + +fn main() {} diff --git a/Relm4-0.6.2/relm4-macros/tests/iife.rs b/Relm4-0.6.2/relm4-macros/tests/iife.rs new file mode 100644 index 0000000..f59d476 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/iife.rs @@ -0,0 +1,39 @@ +use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + +struct App; + +#[relm4_macros::component] +impl SimpleComponent for App { + type Init = (); + type Input = (); + type Output = (); + + view! { + gtk::Window { + gtk::Label { + #[watch] + set_label: &format!("Counter: {counter}"), + } + } + } + + fn pre_view() { + // Only works if pre_view isn't wrapped inside an IIFE + // because the local variable counter is used in the + // update_view method. + let counter = 1; + } + + fn init( + _counter: Self::Init, + root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self; + + let counter = 1; + let widgets = view_output!(); + + ComponentParts { model, widgets } + } +} diff --git a/Relm4-0.6.2/relm4-macros/tests/local_ref_container.rs b/Relm4-0.6.2/relm4-macros/tests/local_ref_container.rs new file mode 100644 index 0000000..d9c9623 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/local_ref_container.rs @@ -0,0 +1,44 @@ +use gtk::prelude::GtkWindowExt; +use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + +#[derive(Default)] +struct AppModel; + +#[relm4_macros::component] +impl SimpleComponent for AppModel { + type Init = (); + type Input = (); + type Output = (); + + view! { + gtk::Window { + set_title: Some("Simple app"), + set_default_width: 300, + set_default_height: 100, + + #[local_ref] + my_box_ref -> gtk::Box { + gtk::Label { + set_label: "This should compile", + } + }, + } + } + + fn init( + _init: Self::Init, + _root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self; + + let my_box = gtk::Box::default(); + let my_box_ref = &my_box; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, _msg: (), _sender: ComponentSender) {} +} diff --git a/Relm4-0.6.2/relm4-macros/tests/pub_widget_templates.rs b/Relm4-0.6.2/relm4-macros/tests/pub_widget_templates.rs new file mode 100644 index 0000000..247a633 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/pub_widget_templates.rs @@ -0,0 +1,56 @@ +use gtk::prelude::GtkWindowExt; +use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + +pub mod templates { + use relm4::{gtk, WidgetTemplate}; + + #[relm4::widget_template(pub)] + impl WidgetTemplate for TestTemplate { + view! { + gtk::Box { + #[name(test_child)] + gtk::Label {} + } + } + } +} + +#[derive(Default)] +struct AppModel; + +#[relm4_macros::component] +impl SimpleComponent for AppModel { + type Init = (); + type Input = (); + type Output = (); + type Widgets = AppWidgets; + + view! { + gtk::Window { + set_title: Some("Simple app"), + set_default_size: (300, 100), + + #[template] + templates::TestTemplate { + #[template_child] + test_child -> gtk::Label { + set_label: "It works!", + } + } + } + } + + fn init( + _: Self::Init, + root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, _msg: (), _sender: ComponentSender) {} +} diff --git a/Relm4-0.6.2/relm4-macros/tests/redundant_clone.rs b/Relm4-0.6.2/relm4-macros/tests/redundant_clone.rs new file mode 100644 index 0000000..40142b4 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/redundant_clone.rs @@ -0,0 +1,39 @@ +use relm4::{ + component::{AsyncComponent, AsyncComponentParts, AsyncComponentSender}, + gtk, +}; + +struct App; + +#[relm4::component(pub async)] +impl AsyncComponent for App { + type Init = (); + type Input = (); + type Output = (); + type CommandOutput = (); + + view! { + gtk::Window {} + } + + // Initialize the component. + async fn init( + _init: Self::Init, + root: Self::Root, + _sender: AsyncComponentSender, + ) -> AsyncComponentParts { + let model = Self; + + let widgets = view_output!(); + + AsyncComponentParts { model, widgets } + } + + async fn update( + &mut self, + _msg: Self::Input, + _sender: AsyncComponentSender, + _root: &Self::Root, + ) { + } +} diff --git a/Relm4-0.6.2/relm4-macros/tests/returned_widgets.rs b/Relm4-0.6.2/relm4-macros/tests/returned_widgets.rs new file mode 100644 index 0000000..1e1e6bc --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/returned_widgets.rs @@ -0,0 +1,26 @@ +use relm4::gtk; + +fn widget() -> gtk::Separator { + // Mimic component.widget() call + gtk::Separator::default() +} + +fn main() { + let local_widget = widget(); + relm4_macros::view! { + gtk::Stack { + add_child = >k::Separator::default() { } + -> { set_needs_attention: false }, + add_child = >k::Separator::default() { } + -> page: gtk::StackPage { set_needs_attention: false }, + add_child = &widget() {} -> { + set_needs_attention: false + }, + add_child: &widget(), + #[local_ref] + add_child = &local_widget {} -> { + set_needs_attention: false + }, + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/tests/simple.rs b/Relm4-0.6.2/relm4-macros/tests/simple.rs new file mode 100644 index 0000000..d11be0e --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/simple.rs @@ -0,0 +1,77 @@ +use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt}; +use relm4::{gtk, ComponentParts, ComponentSender, RelmWidgetExt, SimpleComponent}; + +#[derive(Default)] +struct App { + counter: u8, +} + +#[derive(Debug)] +enum AppMsg { + Increment, + Decrement, +} + +#[relm4_macros::component] +impl SimpleComponent for App { + type Init = u8; + type Input = AppMsg; + type Output = (); + + view! { + gtk::Window { + set_title: Some("Simple app"), + set_default_size: (300, 100), + + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_margin_all: 5, + set_spacing: 5, + + append = >k::Button { + set_label: "Increment", + connect_clicked => AppMsg::Increment, + }, + append = >k::Button { + set_label: "Decrement", + connect_clicked => AppMsg::Decrement, + }, + append = >k::Label { + set_margin_all: 5, + #[watch] + set_label: &format!("Counter: {}", model.counter), + } + }, + } + } + + fn init( + counter: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = Self { counter }; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, msg: AppMsg, _sender: ComponentSender) { + match msg { + AppMsg::Increment => { + self.counter = self.counter.wrapping_add(1); + } + AppMsg::Decrement => { + self.counter = self.counter.wrapping_sub(1); + } + } + } +} + +fn assert_debug_impl() {} + +#[test] +fn assert_widgets_impl_debug() { + assert_debug_impl::(); +} diff --git a/Relm4-0.6.2/relm4-macros/tests/skip_init.rs b/Relm4-0.6.2/relm4-macros/tests/skip_init.rs new file mode 100644 index 0000000..58d3b9d --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/skip_init.rs @@ -0,0 +1,80 @@ +use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt}; +use relm4::{gtk, ComponentParts, ComponentSender, RelmWidgetExt, SimpleComponent}; + +#[derive(Default)] +struct App { + counter: u8, +} + +#[derive(Debug)] +enum AppMsg { + Increment, + Decrement, +} + +#[relm4_macros::component] +impl SimpleComponent for App { + type Init = u8; + type Input = AppMsg; + type Output = (); + + view! { + gtk::Window { + set_title: Some("Simple app"), + set_default_size: (300, 100), + + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_margin_all: 5, + set_spacing: 5, + + append = >k::Button { + set_label: "Increment", + connect_clicked => AppMsg::Increment, + }, + append = >k::Button { + set_label: "Decrement", + connect_clicked => AppMsg::Decrement, + }, + append = >k::Label { + set_margin_all: 5, + #[watch(skip_init)] + set_label: &format!("Counter: {}{value}", model.counter), + #[track(skip_init, test)] + set_label: value, + } + }, + } + } + + fn pre_view() { + // These values are not available in init + // so we can make sure "skip_init" works + // by accessing the variables. + let test = true; + let value = "value"; + } + + fn init( + counter: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = Self { counter }; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, msg: AppMsg, _sender: ComponentSender) { + match msg { + AppMsg::Increment => { + self.counter = self.counter.wrapping_add(1); + } + AppMsg::Decrement => { + self.counter = self.counter.wrapping_sub(1); + } + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/bad_impl.rs b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/bad_impl.rs new file mode 100644 index 0000000..4050196 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/bad_impl.rs @@ -0,0 +1,32 @@ +use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + +#[derive(Default)] +struct TestComponent; + +#[relm4_macros::component] +impl SimpleComponent for TestComponent { + type Init = (); + type Input = (); + type Output = (); + + view! { + gtk::Window {} + } + + fn init( + _init: Self::Init, + _root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self::default(); + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + // Incorrect impl + fn +} + +fn main() {} diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/bad_impl.stderr b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/bad_impl.stderr new file mode 100644 index 0000000..e3efd79 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/bad_impl.stderr @@ -0,0 +1,29 @@ +error: expected identifier, found `}` + --> tests/ui/compile-fail/bad_impl.rs:30:1 + | +7 | impl SimpleComponent for TestComponent { + | - while parsing this item list starting here +... +30 | } + | ^ + | | + | expected identifier + | the item list ends here + +warning: unused import: `gtk` + --> tests/ui/compile-fail/bad_impl.rs:1:13 + | +1 | use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + | ^^^ + | + = note: `#[warn(unused_imports)]` on by default + +error[E0046]: not all trait items implemented, missing: `Root`, `Widgets`, `init_root` + --> tests/ui/compile-fail/bad_impl.rs:7:1 + | +7 | impl SimpleComponent for TestComponent { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Root`, `Widgets`, `init_root` in implementation + | + = help: implement the missing item: `type Root = /* Type */;` + = help: implement the missing item: `type Widgets = /* Type */;` + = help: implement the missing item: `fn init_root() -> ::Root { todo!() }` diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/component-empty.rs b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/component-empty.rs new file mode 100644 index 0000000..f59045a --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/component-empty.rs @@ -0,0 +1,10 @@ +use relm4::SimpleComponent; + +struct TestComponent; + +#[relm4_macros::component] +impl SimpleComponent for TestComponent { + +} + +fn main() {} diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/component-empty.stderr b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/component-empty.stderr new file mode 100644 index 0000000..3300598 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/component-empty.stderr @@ -0,0 +1,20 @@ +error: expected `view!` macro invocation + --> tests/ui/compile-fail/component-empty.rs:6:1 + | +6 | / impl SimpleComponent for TestComponent { +7 | | +8 | | } + | |_^ + +error[E0046]: not all trait items implemented, missing: `Input`, `Output`, `Init`, `Root`, `init_root`, `init` + --> tests/ui/compile-fail/component-empty.rs:6:1 + | +6 | impl SimpleComponent for TestComponent { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Input`, `Output`, `Init`, `Root`, `init_root`, `init` in implementation + | + = help: implement the missing item: `type Input = /* Type */;` + = help: implement the missing item: `type Output = /* Type */;` + = help: implement the missing item: `type Init = /* Type */;` + = help: implement the missing item: `type Root = /* Type */;` + = help: implement the missing item: `fn init_root() -> ::Root { todo!() }` + = help: implement the missing item: `fn init(_: ::Init, _: &::Root, _: ComponentSender) -> ComponentParts { todo!() }` diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/dead_code.rs b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/dead_code.rs new file mode 100644 index 0000000..d03a3c9 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/dead_code.rs @@ -0,0 +1,34 @@ +use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + +struct TestComponent; + +#[relm4_macros::component] +impl SimpleComponent for TestComponent { + type Init = (); + type Input = (); + type Output = (); + + view! { + gtk::Window {} + } + + fn init( + _init: Self::Init, + _root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self; + + let widgets = view_output!(); + + // This would compile before 0.5.0-beta.3 + // but shouldn't because the window isn't used + // and doesn't need to be part of the widgets + // struct. + let _window = &widgets._gtk_window_0; + + ComponentParts { model, widgets } + } +} + +fn main() {} diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/dead_code.stderr b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/dead_code.stderr new file mode 100644 index 0000000..2d77d3c --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/dead_code.stderr @@ -0,0 +1,5 @@ +error[E0609]: no field `_gtk_window_0` on type `TestComponentWidgets` + --> tests/ui/compile-fail/dead_code.rs:28:32 + | +28 | let _window = &widgets._gtk_window_0; + | ^^^^^^^^^^^^^ unknown field diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/factory-component-empty.rs b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/factory-component-empty.rs new file mode 100644 index 0000000..7b24fce --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/factory-component-empty.rs @@ -0,0 +1,11 @@ +use relm4::factory::FactoryComponent; + +#[derive(Debug)] +struct TestFactoryComponent; + +#[relm4_macros::factory] +impl FactoryComponent for TestFactoryComponent { + +} + +fn main() {} diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/factory-component-empty.stderr b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/factory-component-empty.stderr new file mode 100644 index 0000000..8d4aef3 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/factory-component-empty.stderr @@ -0,0 +1,24 @@ +error: expected `view!` macro invocation + --> tests/ui/compile-fail/factory-component-empty.rs:7:1 + | +7 | / impl FactoryComponent for TestFactoryComponent { +8 | | +9 | | } + | |_^ + +error[E0046]: not all trait items implemented, missing: `ParentWidget`, `ParentInput`, `CommandOutput`, `Input`, `Output`, `Init`, `Root`, `init_model`, `init_root`, `init_widgets` + --> tests/ui/compile-fail/factory-component-empty.rs:7:1 + | +7 | impl FactoryComponent for TestFactoryComponent { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ParentWidget`, `ParentInput`, `CommandOutput`, `Input`, `Output`, `Init`, `Root`, `init_model`, `init_root`, `init_widgets` in implementation + | + = help: implement the missing item: `type ParentWidget = /* Type */;` + = help: implement the missing item: `type ParentInput = /* Type */;` + = help: implement the missing item: `type CommandOutput = /* Type */;` + = help: implement the missing item: `type Input = /* Type */;` + = help: implement the missing item: `type Output = /* Type */;` + = help: implement the missing item: `type Init = /* Type */;` + = help: implement the missing item: `type Root = /* Type */;` + = help: implement the missing item: `fn init_model(_: ::Init, _: &::Index, _: FactorySender) -> Self { todo!() }` + = help: implement the missing item: `fn init_root(&self) -> ::Root { todo!() }` + = help: implement the missing item: `fn init_widgets(&mut self, _: &::Index, _: &::Root, _: &<::ParentWidget as FactoryView>::ReturnedWidget, _: FactorySender) -> ::Widgets { todo!() }` diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/init-identifers.rs b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/init-identifers.rs new file mode 100644 index 0000000..141c37d --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/init-identifers.rs @@ -0,0 +1,51 @@ +use relm4::prelude::*; + +struct ComponentInitBadIdentifiers; + +#[relm4_macros::component] +impl SimpleComponent for ComponentInitBadIdentifiers { + type Init = (); + type Input = (); + type Output = (); + type Root = (i32, i32); + + view! { + gtk::Window {} + } + + fn init( + _: Self::Init, + (a, b): &Self::Root, + _: ComponentSender, + ) -> ComponentParts { + todo!(); + } + + fn init_root() -> Self::Root { + todo!(); + } +} + +struct ComponentInitNoArgs; + +#[relm4_macros::component] +impl SimpleComponent for ComponentInitNoArgs { + type Init = (); + type Input = (); + type Output = (); + type Root = (); + + view! { + gtk::Window {} + } + + fn init() -> ComponentParts { + todo!(); + } + + fn init_root() -> Self::Root { + todo!(); + } +} + +fn main() {} diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/init-identifers.stderr b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/init-identifers.stderr new file mode 100644 index 0000000..c2c4cdb --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/init-identifers.stderr @@ -0,0 +1,19 @@ +error: parameter binding must be an identifier + --> tests/ui/compile-fail/init-identifers.rs:18:9 + | +18 | (a, b): &Self::Root, + | ^^^^^^ + +error: parameter binding must be an identifier + --> tests/ui/compile-fail/init-identifers.rs:19:9 + | +19 | _: ComponentSender, + | ^ + +error[E0050]: method `init` has 0 parameters but the declaration in trait `relm4::SimpleComponent::init` has 3 + --> tests/ui/compile-fail/init-identifers.rs:42:5 + | +42 | fn init() -> ComponentParts { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 3 parameters, found 0 + | + = note: `init` from trait: `fn(::Init, &::Root, relm4::ComponentSender) -> relm4::ComponentParts` diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/missing-view.rs b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/missing-view.rs new file mode 100644 index 0000000..d02974e --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/missing-view.rs @@ -0,0 +1,18 @@ +use relm4::prelude::*; + +struct App; + +#[relm4_macros::component] +impl SimpleComponent for App { + type Init = (); + type Input = (); + type Output = (); + + fn init(_: (), root: &Self::Root, sender: ComponentSender) -> ComponentParts { + todo!(); + } +} + +fn main() { + +} diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/missing-view.stderr b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/missing-view.stderr new file mode 100644 index 0000000..f92b3ea --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/missing-view.stderr @@ -0,0 +1,20 @@ +error: expected `view!` macro invocation + --> tests/ui/compile-fail/missing-view.rs:6:1 + | +6 | / impl SimpleComponent for App { +7 | | type Init = (); +8 | | type Input = (); +9 | | type Output = (); +... | +13 | | } +14 | | } + | |_^ + +error[E0046]: not all trait items implemented, missing: `Root`, `init_root` + --> tests/ui/compile-fail/missing-view.rs:6:1 + | +6 | impl SimpleComponent for App { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Root`, `init_root` in implementation + | + = help: implement the missing item: `type Root = /* Type */;` + = help: implement the missing item: `fn init_root() -> ::Root { todo!() }` diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/no-view-output.rs b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/no-view-output.rs new file mode 100644 index 0000000..5299d89 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/no-view-output.rs @@ -0,0 +1,29 @@ +use relm4::prelude::*; + +struct AppModel; + +#[relm4_macros::component] +impl SimpleComponent for AppModel { + type Init = (); + type Input = (); + type Output = (); + + view! { + gtk::Window {} + } + + #[allow(unreachable_code)] + fn init( + _: (), + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = Self; + + let widgets = todo!(); + + ComponentParts { model, widgets } + } +} + +fn main() {} diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/no-view-output.stderr b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/no-view-output.stderr new file mode 100644 index 0000000..0d03931 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/no-view-output.stderr @@ -0,0 +1,11 @@ +error: expected an injection point for the view macro. Try using `let widgets = view_output!();` + --> tests/ui/compile-fail/no-view-output.rs:15:5 + | +15 | / #[allow(unreachable_code)] +16 | | fn init( +17 | | _: (), +18 | | root: &Self::Root, +... | +25 | | ComponentParts { model, widgets } +26 | | } + | |_____^ diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/pre-view-return.rs b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/pre-view-return.rs new file mode 100644 index 0000000..67baac2 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/pre-view-return.rs @@ -0,0 +1,37 @@ +use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent}; + +#[derive(Default)] +struct TestComponent { + counter: u8, +} + +#[relm4_macros::component] +impl SimpleComponent for TestComponent { + type Init = (); + type Input = (); + type Output = (); + + view! { + gtk::Window {} + } + + fn pre_view() { + if model.counter == 0 { + return; + } + } + + fn init( + _init: Self::Init, + _root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self::default(); + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } +} + +fn main() {} diff --git a/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/pre-view-return.stderr b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/pre-view-return.stderr new file mode 100644 index 0000000..d684853 --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/ui/compile-fail/pre-view-return.stderr @@ -0,0 +1,23 @@ +error[E0308]: mismatched types + --> tests/ui/compile-fail/pre-view-return.rs:8:1 + | +8 | #[relm4_macros::component] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `__DoNotReturnManually` + | +note: return type inferred to be `()` here + --> tests/ui/compile-fail/pre-view-return.rs:20:13 + | +20 | return; + | ^^^^^^ + = note: this error originates in the attribute macro `relm4_macros::component` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> tests/ui/compile-fail/pre-view-return.rs:8:1 + | +8 | #[relm4_macros::component] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected `__DoNotReturnManually`, found `()` + | expected due to this + | + = note: this error originates in the attribute macro `relm4_macros::component` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/Relm4-0.6.2/relm4-macros/tests/widget_template.rs b/Relm4-0.6.2/relm4-macros/tests/widget_template.rs new file mode 100644 index 0000000..1ce318d --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/widget_template.rs @@ -0,0 +1,119 @@ +use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt}; +use relm4::{gtk, ComponentParts, ComponentSender, RelmWidgetExt, SimpleComponent, WidgetTemplate}; + +#[relm4_macros::widget_template] +impl WidgetTemplate for CustomBox { + view! { + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_margin_all: 5, + set_spacing: 5, + + #[name = "child_label"] + gtk::Label { + set_label: "This is a test", + } + } + } +} + +#[relm4_macros::widget_template] +impl WidgetTemplate for CustomWindow { + view! { + gtk::Window { + set_title: Some("Simple app"), + set_default_width: 300, + set_default_height: 100, + + #[name = "test_label"] + gtk::Label {} + } + } +} + +#[derive(Default)] +struct App { + counter: u8, +} + +#[derive(Debug)] +enum AppMsg { + Increment, + Decrement, +} + +#[relm4_macros::component] +impl SimpleComponent for App { + type Init = u8; + type Input = AppMsg; + type Output = (); + + view! { + #[template] + CustomWindow { + set_title: Some("Simple app"), + set_default_width: 300, + set_default_height: 100, + + // Make sure that using template children works + #[template_child] + test_label { + set_label: "It works", + }, + + #[template] + CustomBox { + gtk::Button { + set_label: "Increment", + connect_clicked[sender] => move |_| { + sender.input(AppMsg::Increment); + }, + }, + gtk::Button { + set_label: "Decrement", + connect_clicked[sender] => move |_| { + sender.input(AppMsg::Decrement); + }, + }, + #[template_child] + child_label { + set_margin_all: 5, + #[watch] + set_label: &format!("Counter: {}", model.counter), + }, + #[template] + CustomBox { + #[template_child] + child_label { + set_margin_all: 5, + #[watch] + set_label: &format!("Alternative counter : {}", model.counter), + } + }, + }, + } + } + + fn init( + counter: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = Self { counter }; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, msg: AppMsg, _sender: ComponentSender) { + match msg { + AppMsg::Increment => { + self.counter = self.counter.wrapping_add(1); + } + AppMsg::Decrement => { + self.counter = self.counter.wrapping_sub(1); + } + } + } +} diff --git a/Relm4-0.6.2/relm4-macros/tests/widget_template_nested_child.rs b/Relm4-0.6.2/relm4-macros/tests/widget_template_nested_child.rs new file mode 100644 index 0000000..2fad7cc --- /dev/null +++ b/Relm4-0.6.2/relm4-macros/tests/widget_template_nested_child.rs @@ -0,0 +1,81 @@ +use gtk::prelude::{BoxExt, GtkWindowExt, OrientableExt}; +use relm4::{gtk, ComponentParts, ComponentSender, RelmWidgetExt, SimpleComponent, WidgetTemplate}; + +#[relm4_macros::widget_template] +impl WidgetTemplate for CustomBox { + view! { + gtk::Box { + set_margin_all: 5, + set_spacing: 5, + + #[name = "label"] + gtk::Label { + set_label: "Is it working?", + } + } + } +} + +#[relm4_macros::widget_template] +impl WidgetTemplate for CustomWindow { + view! { + gtk::Window { + set_title: Some("Simple app"), + set_default_width: 300, + set_default_height: 100, + + #[template] + #[name = "custom_box"] + CustomBox { + set_orientation: gtk::Orientation::Vertical, + } + } + } +} + +#[derive(Default)] +struct App { + counter: u8, +} + +#[derive(Debug)] +enum AppMsg {} + +#[relm4_macros::component] +impl SimpleComponent for App { + type Init = u8; + type Input = AppMsg; + type Output = (); + + view! { + #[template] + CustomWindow { + set_title: Some("Simple app"), + set_default_width: 300, + set_default_height: 100, + + // Nested template child + #[template_child] + custom_box.label { + #[watch] + set_label: "It works!", + }, + } + } + + fn init( + counter: Self::Init, + root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + let model = Self { counter }; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, _msg: AppMsg, _sender: ComponentSender) { + self.counter += 1; + } +} diff --git a/Relm4-0.6.2/relm4/Cargo.toml b/Relm4-0.6.2/relm4/Cargo.toml new file mode 100644 index 0000000..82a64b2 --- /dev/null +++ b/Relm4-0.6.2/relm4/Cargo.toml @@ -0,0 +1,84 @@ +[package] +name = "relm4" +documentation = "https://docs.rs/relm4/" + +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +readme.workspace = true +license.workspace = true +description.workspace = true + +homepage.workspace = true +repository.workspace = true + +keywords.workspace = true +categories.workspace = true + +[package.metadata.docs.rs] +all-features = true +rustc-args = ["--cfg", "docsrs"] +cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"] +# enable unstable features in the documentation +rustdoc-args = ["--cfg", "docsrs"] + +[features] +default = ["macros", "gnome_42"] +# The dox feature can be used for building the docs without the dependencies and requires Rust Nightly +dox = ["gtk/dox", "adw/dox"] +libadwaita = ["adw"] +# libpanel = ["panel"] +macros = ["relm4-macros"] + +gnome_44 = ["gnome_43", "gtk/gnome_44", "adw/v1_3"] +gnome_43 = ["gnome_42", "gtk/gnome_43", "adw/v1_2"] +gnome_42 = ["gtk/gnome_42"] + +# All features except docs. This is also used in the CI +all = ["macros", "libadwaita"] #, "panel"] + +[dependencies] +adw = { version = "0.4", optional = true, package = "libadwaita", path="../../libadwaita-0.4.4" } + +flume = "0.10.14" +futures = "0.3.28" +fragile = "2.0.0" +gtk = { version = "0.6", package = "gtk4" } +once_cell = "1.18" +# Wait for libpanel 0.3 release +# panel = { version = "0.3", optional = true, package = "libpanel" } +tokio = { version = "1.28", features = ["rt", "rt-multi-thread", "sync"] } + +relm4-macros = { version = "0.6.2", path = "../relm4-macros", optional = true } +tracing = "0.1.37" +async-trait = "0.1.68" + +[dev-dependencies] +relm4-macros = { path = "../relm4-macros" } + +# For the benchmarks +criterion = { version = "0.5", default-features = false } + +# For the examples +relm4-icons = { version = "0.6.0", features = ["plus", "minus"]} +tokio = { version = "1.28", features = [ + "rt", + "macros", + "time", + "rt-multi-thread", +] } +rand = "0.8.5" +tracker = "0.2" +reqwest = "0.11.18" +tracing-subscriber = "0.3.17" + +[[bench]] +name = "stress_test" +harness = false + +# Make sure that the examples are scraped +[[example]] +name = "simple" +path = "examples/simple.rs" +doc-scrape-examples = true diff --git a/Relm4-0.6.2/relm4/benches/stress_test.rs b/Relm4-0.6.2/relm4/benches/stress_test.rs new file mode 100644 index 0000000..be4df9a --- /dev/null +++ b/Relm4-0.6.2/relm4/benches/stress_test.rs @@ -0,0 +1,120 @@ +use std::time::Duration; + +use criterion::{criterion_group, criterion_main, Criterion}; +use gtk::gio::ApplicationFlags; +use gtk::glib::clone; +use gtk::prelude::{ApplicationExt, BoxExt, ButtonExt, GtkWindowExt}; +use relm4::{gtk, ComponentParts, ComponentSender, RelmApp, RelmWidgetExt, SimpleComponent}; + +// Iteration count that appear to be reasonable. +// Constant delays like GTK's runtime are negligible at this number. +const ITERATIONS: u32 = 200000; + +struct AppModel { + counter: u32, + application: gtk::Application, +} + +#[derive(Debug)] +enum AppMsg { + Increment, +} + +struct AppWidgets { + label: gtk::Label, +} + +impl SimpleComponent for AppModel { + type Init = gtk::Application; + type Input = AppMsg; + type Output = (); + type Root = gtk::Window; + type Widgets = AppWidgets; + + fn init_root() -> Self::Root { + gtk::Window::builder() + .title("Stress test benchmark") + .default_width(300) + .default_height(100) + .build() + } + + fn init( + application: Self::Init, + window: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = AppModel { + counter: 0, + application, + }; + + let vbox = gtk::Box::builder() + .orientation(gtk::Orientation::Vertical) + .spacing(5) + .build(); + + let stress_test_button = gtk::Button::with_label("Increment"); + + let label = gtk::Label::new(Some(&format!("Counter: {}", model.counter))); + label.set_margin_all(5); + + window.set_child(Some(&vbox)); + vbox.set_margin_all(5); + vbox.append(&stress_test_button); + vbox.append(&label); + + stress_test_button.connect_clicked(clone!(@strong sender => move |_| { + for _ in 0..=ITERATIONS { + sender.input(AppMsg::Increment); + } + })); + + let widgets = AppWidgets { label }; + + stress_test_button.emit_clicked(); + ComponentParts { model, widgets } + } + + fn update(&mut self, msg: Self::Input, _sender: ComponentSender) { + match msg { + AppMsg::Increment => { + self.counter = self.counter.wrapping_add(1); + } + } + if self.counter == ITERATIONS { + self.application.quit(); + } + } + + /// Update the view to represent the updated model. + fn update_view(&self, widgets: &mut Self::Widgets, _sender: ComponentSender) { + widgets + .label + .set_label(&format!("Counter: {}", self.counter)); + } +} + +criterion_group! { + name = benches; + config = Criterion::default() + .warm_up_time(Duration::from_millis(100)) + .sample_size(20); + targets = benchmark +} +criterion_main!(benches); + +fn benchmark(c: &mut Criterion) { + c.bench_function("stress_test", move |b| { + let application = gtk::Application::new( + Some("relm4.bench.stress_test"), + ApplicationFlags::FLAGS_NONE, + ); + + b.iter(move || { + let app = RelmApp::from_app(application.clone()); + let application = application.clone(); + app.run::(application); + }) + }); +} diff --git a/Relm4-0.6.2/relm4/examples b/Relm4-0.6.2/relm4/examples new file mode 100644 index 0000000..a6573af --- /dev/null +++ b/Relm4-0.6.2/relm4/examples @@ -0,0 +1 @@ +../examples \ No newline at end of file diff --git a/Relm4-0.6.2/relm4/src/actions/mod.rs b/Relm4-0.6.2/relm4/src/actions/mod.rs new file mode 100644 index 0000000..4d10932 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/actions/mod.rs @@ -0,0 +1,276 @@ +//! Action utility. + +use gtk::gio; +use gtk::glib::FromVariant; +use gtk::prelude::{ActionExt, ActionMapExt, StaticVariantType, ToVariant, WidgetExt}; + +use std::marker::PhantomData; + +/// Type safe traits for interacting with actions. +pub mod traits; +pub use traits::*; + +#[macro_export] +/// Create a new type that implements [`ActionGroupName`]. +macro_rules! new_action_group { + ($vis:vis $ty:ident, $name:expr) => { + $vis struct $ty; + + impl relm4::actions::ActionGroupName for $ty { + const NAME: &'static str = $name; + } + }; +} + +#[macro_export] +/// Create a new type that implements [`ActionName`] without state or target type. +macro_rules! new_stateless_action { + ($vis:vis $ty:ident, $group:ty, $name:expr) => { + $vis struct $ty; + + impl relm4::actions::ActionName for $ty { + type Group = $group; + type Target = (); + type State = (); + + const NAME: &'static str = $name; + } + }; +} + +#[macro_export] +/// Create a new type that implements [`ActionName`] with state and target type. +/// +/// The state stores the state of this action and the target type is passed by callers of the action. +macro_rules! new_stateful_action { + ($vis:vis $ty:ident, $group:ty, $name:expr, $value:ty, $state:ty) => { + $vis struct $ty; + + impl relm4::actions::ActionName for $ty { + type Group = $group; + type Target = $value; + type State = $state; + + const NAME: &'static str = $name; + } + }; +} + +/// A type safe action that wraps around [`gio::SimpleAction`]. +#[derive(Debug, Clone)] +pub struct RelmAction { + name: PhantomData, + action: gio::SimpleAction, +} + +impl From> for gio::SimpleAction { + fn from(value: RelmAction) -> Self { + value.action + } +} + +impl RelmAction +where + Name::State: ToVariant + FromVariant, + Name::Target: ToVariant + FromVariant, +{ + /// Create a new stateful action with target value. + pub fn new_stateful_with_target_value< + Callback: Fn(&gio::SimpleAction, &mut Name::State, Name::Target) + 'static, + >( + start_value: &Name::State, + callback: Callback, + ) -> Self { + let ty = Name::Target::static_variant_type(); + + let action = + gio::SimpleAction::new_stateful(Name::NAME, Some(&ty), start_value.to_variant()); + + action.connect_activate(move |action, variant| { + let value = variant.unwrap().get().unwrap(); + let mut state = action.state().unwrap().get().unwrap(); + + callback(action, &mut state, value); + action.set_state(state.to_variant()); + }); + + Self { + name: PhantomData, + action, + } + } +} + +impl RelmAction +where + Name::State: ToVariant + FromVariant, + Name::Target: EmptyType, +{ + /// Create a new stateful action. + pub fn new_stateful( + start_value: &Name::State, + callback: Callback, + ) -> Self { + let action = gio::SimpleAction::new_stateful(Name::NAME, None, start_value.to_variant()); + + action.connect_activate(move |action, _variant| { + let mut state = action.state().unwrap().get().unwrap(); + callback(action, &mut state); + action.set_state(state.to_variant()); + }); + + Self { + name: PhantomData, + action, + } + } +} + +impl RelmAction +where + Name::State: EmptyType, + Name::Target: ToVariant + FromVariant, +{ + /// Create a new stateless action with a target value. + pub fn new_with_target_value( + callback: Callback, + ) -> Self { + let ty = Name::Target::static_variant_type(); + + let action = gio::SimpleAction::new(Name::NAME, Some(&ty)); + + action.connect_activate(move |action, variant| { + let value = variant.unwrap().get().unwrap(); + callback(action, value); + }); + + Self { + name: PhantomData, + action, + } + } +} + +impl RelmAction +where + Name::Target: EmptyType, + Name::State: EmptyType, +{ + /// Create a new stateless action. + pub fn new_stateless(callback: Callback) -> Self { + let action = gio::SimpleAction::new(Name::NAME, None); + + action.connect_activate(move |action, _variant| { + callback(action); + }); + + Self { + name: PhantomData, + action, + } + } +} + +impl RelmAction +where + Name::Target: ToVariant + FromVariant, +{ + /// Create a menu item for this action with the target value sent to the action on activation. + pub fn to_menu_item_with_target_value( + label: &str, + target_value: &Name::Target, + ) -> gio::MenuItem { + let menu_item = gio::MenuItem::new(Some(label), Some(&Name::action_name())); + menu_item.set_action_and_target_value( + Some(&Name::action_name()), + Some(&target_value.to_variant()), + ); + + menu_item + } +} + +impl RelmAction +where + Name::Target: EmptyType, +{ + /// Create a menu item for this action. + #[must_use] + pub fn to_menu_item(label: &str) -> gio::MenuItem { + gio::MenuItem::new(Some(label), Some(&Name::action_name())) + } +} + +#[derive(Debug)] +/// A type-safe action group that wraps around [`gio::SimpleActionGroup`]. +pub struct RelmActionGroup { + group_name: PhantomData, + actions: Vec, +} + +impl RelmActionGroup { + /// Create a new [`RelmActionGroup`]. + #[must_use] + pub fn new() -> Self { + Self::default() + } + + /// Add an action to the group. + pub fn add_action(&mut self, action: RelmAction) { + self.actions.push(action.action); + } + + /// Register the added actions at application level. + pub fn register_for_main_application(self) { + let app = crate::main_application(); + for action in self.actions { + app.add_action(&action); + } + } + + /// Register the added actions for a certain widget. + pub fn register_for_widget(self, widget: W) + where + W: AsRef, + { + let group = self.into_action_group(); + widget + .as_ref() + .insert_action_group(GroupName::NAME, Some(&group)); + } + + /// Convert [`RelmActionGroup`] into a [`gio::SimpleActionGroup`]. + #[must_use] + pub fn into_action_group(self) -> gio::SimpleActionGroup { + let group = gio::SimpleActionGroup::new(); + for action in self.actions { + group.add_action(&action); + } + group + } +} + +impl FromIterator for RelmActionGroup +where + A: Into, + GroupName: ActionGroupName, +{ + fn from_iter(iter: I) -> Self + where + I: IntoIterator, + { + Self { + group_name: PhantomData, + actions: iter.into_iter().map(Into::into).collect(), + } + } +} + +impl Default for RelmActionGroup { + fn default() -> Self { + Self { + group_name: PhantomData, + actions: Vec::new(), + } + } +} diff --git a/Relm4-0.6.2/relm4/src/actions/traits.rs b/Relm4-0.6.2/relm4/src/actions/traits.rs new file mode 100644 index 0000000..be56fda --- /dev/null +++ b/Relm4-0.6.2/relm4/src/actions/traits.rs @@ -0,0 +1,84 @@ +use gtk::prelude::ToVariant; + +/// Trait used to specify the group name in [`ActionName`]. +pub trait ActionGroupName { + /// The name of the group. + const NAME: &'static str; +} + +/// Trait for marking stateless actions. +pub trait EmptyType {} + +impl EmptyType for () {} + +/// Define the name of an action. +pub trait ActionName { + /// The group of this action. + type Group: ActionGroupName; + + /// Target value type for passing values to this action. + /// + /// Use [`()`] for actions without target value. + type Target; + + /// State type of this action. + /// + /// Use [`()`] for stateless actions. + type State; + + /// The name of the action. + const NAME: &'static str; + + /// The full action name (group.action). + #[must_use] + fn action_name() -> String { + format!("{}.{}", Self::Group::NAME, Self::NAME) + } +} + +/// Type safe interface for [`gtk::prelude::ActionableExt`]. +pub trait ActionablePlus { + /// Set a new stateful action with a default state value. + fn set_action(&self, value: A::Target) + where + A::Target: ToVariant; + + /// Set a new stateless action. + fn set_stateless_action(&self, unit_type: &()) + where + A::Target: EmptyType; +} + +impl ActionablePlus for W { + fn set_action(&self, value: A::Target) + where + A::Target: ToVariant, + { + self.set_action_name(Some(A::action_name().as_str())); + self.set_action_target_value(Some(&value.to_variant())); + } + + fn set_stateless_action(&self, _unit_type: &()) + where + A::Target: EmptyType, + { + self.set_action_name(Some(A::action_name().as_str())); + } +} + +/// Safe interface for [`gtk::prelude::GtkApplicationExt`]. +pub trait AccelsPlus { + /// Set keyboard accelerator for a certain action. + fn set_accelerators_for_action(&self, value: &[&str]) + where + A::Target: EmptyType; +} + +impl AccelsPlus for W { + fn set_accelerators_for_action(&self, accel_codes: &[&str]) + where + A::Target: EmptyType, + { + self.set_accels_for_action(A::action_name().as_str(), accel_codes); + } +} diff --git a/Relm4-0.6.2/relm4/src/app.rs b/Relm4-0.6.2/relm4/src/app.rs new file mode 100644 index 0000000..527818c --- /dev/null +++ b/Relm4-0.6.2/relm4/src/app.rs @@ -0,0 +1,189 @@ +use gtk::glib; +use gtk::prelude::{ApplicationExt, ApplicationExtManual, Cast, GtkApplicationExt, IsA, WidgetExt}; +use std::fmt::Debug; + +use crate::component::{AsyncComponent, AsyncComponentBuilder, AsyncComponentController}; +use crate::runtime_util::shutdown_all; +use crate::{Component, ComponentBuilder, ComponentController, MessageBroker, RUNTIME}; + +use std::cell::Cell; + +/// An app that runs the main application. +#[derive(Debug)] +pub struct RelmApp { + /// The [`gtk::Application`] that's used internally to setup + /// and run your application. + app: gtk::Application, + broker: Option<&'static MessageBroker>, + args: Option>, +} + +impl RelmApp { + /// Create a new Relm4 application. + /// + /// This function will create a new [`gtk::Application`] object if necessary. + /// + /// If the `libadwaita` feature is enabled, then the created [`gtk::Application`] will be an + /// instance of [`adw::Application`]. This can be overridden by passing your own application + /// object to [`RelmApp::from_app`]. + #[must_use] + pub fn new(app_id: &str) -> Self { + crate::init(); + let app = crate::main_application(); + app.set_application_id(Some(app_id)); + + Self { + app, + broker: None, + args: None, + } + } + + /// Create a Relm4 application with a provided [`gtk::Application`]. + pub fn from_app(app: impl IsA) -> Self { + let app = app.upcast(); + crate::set_main_application(app.clone()); + + Self { + app, + broker: None, + args: None, + } + } + + /// Add [`MessageBroker`] to the top-level component. + #[must_use] + pub fn with_broker(mut self, broker: &'static MessageBroker) -> Self { + self.broker = Some(broker); + self + } + + /// Add command line arguments to run with. + #[must_use] + pub fn with_args(mut self, args: Vec) -> Self { + self.args = Some(args); + self + } + + /// Runs the application, returns once the application is closed. + pub fn run(self, payload: C::Init) + where + C: Component, + C::Root: IsA + WidgetExt, + { + let Self { app, broker, args } = self; + + let payload = Cell::new(Some(payload)); + + app.connect_activate(move |app| { + if let Some(payload) = payload.take() { + assert!( + app.is_registered(), + "App should be already registered when activated" + ); + + let builder = ComponentBuilder::::default(); + let connector = match broker { + Some(broker) => builder.launch_with_broker(payload, broker), + None => builder.launch(payload), + }; + + // Run late initialization for transient windows for example. + crate::late_initialization::run_late_init(); + + let mut controller = connector.detach(); + let window = controller.widget().clone(); + + controller.detach_runtime(); + + app.add_window(window.as_ref()); + window.set_visible(true); + } + }); + + let _guard = RUNTIME.enter(); + if let Some(args) = args { + app.run_with_args(&args); + } else { + app.run(); + } + + // Make sure everything is shut down + shutdown_all(); + glib::MainContext::ref_thread_default().iteration(true); + } + + /// Runs the application with the provided command-line arguments, returns once the application + /// is closed. + #[deprecated] + pub fn run_with_args(self, payload: C::Init, args: &[S]) + where + C: Component, + C::Root: IsA + WidgetExt, + S: AsRef, + { + let args = args.iter().map(|a| a.as_ref().to_string()).collect(); + self.with_args(args).run::(payload); + } + + /// Runs the application, returns once the application is closed. + pub fn run_async(self, payload: C::Init) + where + C: AsyncComponent, + C::Root: IsA + WidgetExt, + { + let Self { app, broker, args } = self; + + let payload = Cell::new(Some(payload)); + + app.connect_activate(move |app| { + if let Some(payload) = payload.take() { + assert!( + app.is_registered(), + "App should be already registered when activated" + ); + + let builder = AsyncComponentBuilder::::default(); + let connector = match broker { + Some(broker) => builder.launch_with_broker(payload, broker), + None => builder.launch(payload), + }; + + // Run late initialization for transient windows for example. + crate::late_initialization::run_late_init(); + + let mut controller = connector.detach(); + let window = controller.widget().clone(); + + controller.detach_runtime(); + + app.add_window(window.as_ref()); + window.set_visible(true); + } + }); + + let _guard = RUNTIME.enter(); + if let Some(args) = args { + app.run_with_args(&args); + } else { + app.run(); + } + + // Make sure everything is shut down + shutdown_all(); + glib::MainContext::ref_thread_default().iteration(true); + } + + /// Runs the application with the provided command-line arguments, returns once the application + /// is closed. + #[deprecated] + pub fn run_async_with_args(self, payload: C::Init, args: &[S]) + where + C: AsyncComponent, + C::Root: IsA + WidgetExt, + S: AsRef, + { + let args = args.iter().map(|a| a.as_ref().to_string()).collect(); + self.with_args(args).run_async::(payload) + } +} diff --git a/Relm4-0.6.2/relm4/src/binding/bindings.rs b/Relm4-0.6.2/relm4/src/binding/bindings.rs new file mode 100644 index 0000000..15f70a6 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/binding/bindings.rs @@ -0,0 +1,101 @@ +use gtk::glib; + +use crate::binding::Binding; + +macro_rules! binding { + ($name:ident, $obj_name:literal, $ty:ty, $mod:ident) => { + glib::wrapper! { + #[doc = "A data binding storing a value of type [`"] + #[doc = stringify!($ty)] + #[doc = "`]"] + pub struct $name(ObjectSubclass<$mod::$name>); + } + + impl $name { + #[doc = "Create a new [`"] + #[doc = stringify!($name)] + #[doc = "`]."] + pub fn new>(value: T) -> Self { + let this: Self = glib::Object::new(); + this.set_value(value.into()); + this + } + } + + impl Default for $name { + fn default() -> Self { + glib::Object::new() + } + } + + impl Binding for $name { + type Target = $ty; + + fn get(&self) -> Self::Target { + self.value() + } + + fn set(&self, value: Self::Target) { + self.set_value(value) + } + } + + #[allow(missing_docs)] + mod $mod { + use std::cell::RefCell; + + use glib::prelude::*; + use glib::{ParamSpec, Properties, Value}; + use gtk::subclass::prelude::ObjectImpl; + use gtk::{ + glib, + subclass::prelude::{DerivedObjectProperties, ObjectSubclass}, + }; + + #[derive(Default, Properties, Debug)] + #[properties(wrapper_type = super::$name)] + /// Inner type of the data binding. + pub struct $name { + #[property(get, set)] + /// The primary value. + value: RefCell<$ty>, + } + + impl ObjectImpl for $name { + fn properties() -> &'static [ParamSpec] { + Self::derived_properties() + } + fn set_property(&self, id: usize, value: &Value, pspec: &ParamSpec) { + self.derived_set_property(id, value, pspec) + } + fn property(&self, id: usize, pspec: &ParamSpec) -> Value { + self.derived_property(id, pspec) + } + } + + #[glib::object_subclass] + impl ObjectSubclass for $name { + const NAME: &'static str = $obj_name; + type Type = super::$name; + } + } + }; +} + +// Bool +binding!(BoolBinding, "BoolBinding", bool, imp_bool); + +// Integers +binding!(U64Binding, "U64Binding", u64, imp_u64); +binding!(I64Binding, "I64Binding", i64, imp_i64); +binding!(U32Binding, "U32Binding", u32, imp_u32); +binding!(I32Binding, "I32Binding", i32, imp_i32); +binding!(U8Binding, "U8Binding", u8, imp_u8); +binding!(I8Binding, "I8Binding", i8, imp_i8); + +// Floats +binding!(F64Binding, "F64Binding", f64, imp_f64); +binding!(F32Binding, "F32Binding", f32, imp_f32); + +// String +binding!(StringBinding, "StringBinding", String, imp_string); diff --git a/Relm4-0.6.2/relm4/src/binding/mod.rs b/Relm4-0.6.2/relm4/src/binding/mod.rs new file mode 100644 index 0000000..e838039 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/binding/mod.rs @@ -0,0 +1,118 @@ +//! Easy data bindings between objects. +//! +//! Particularly, this module provides types and traits +//! that simplify connecting with the primary property of an object. +//! In this context, *primary* means that the property is the most important and +//! most accessed value stored by the object. +//! Usually, this is very easy to figure out, such as the *active* property for [`gtk::ToggleButton`]. +//! In any case, the primary property type are always documented. +//! +//! To find out which widgets are currently supported and which property is considered as primary, +//! please look at the list implementors for [`ConnectBinding`]. +//! Contributions to add support for more widgets are always welcome. + +mod bindings; +mod widgets; + +pub use bindings::*; + +use std::ops::{Deref, DerefMut}; + +use gtk::{glib, prelude::IsA}; + +/// A trait that allows type-safe bindings between to the primary properties of two objects. +pub trait ConnectBinding { + /// The type of the primary property. + type Target; + + /// Create a type-safe bidirectional between the primary property of an object + /// and a [`Binding`]. + fn bind>(&self, binding: &B); +} + +/// Extension for [`ConnectBinding`]. +/// This trait is not implemented manually, but through +/// automatically implemented for all types that implement +/// [`ConnectBinding`]. +pub trait ConnectBindingExt { + /// The type of the primary property. + /// Inherited from [`ConnectBinding::Target`]. + type Target; + + /// Create an object and immediately connect it with a [`Binding`]. + fn with_binding>(binding: &B) -> Self; +} + +impl ConnectBindingExt for T +where + T: Default + ConnectBinding, +{ + type Target = ::Target; + + fn with_binding>(binding: &B) -> Self { + let obj = Self::default(); + obj.bind(binding); + obj + } +} + +#[derive(Debug)] +/// A RAII-guard that stores a value to +/// a [`Binding`]. +/// +/// Once dropped, it will automatically update +/// the value of the primary property. +pub struct BindingGuard { + value: Option, + inner: B, +} + +impl Deref for BindingGuard { + type Target = ::Target; + + fn deref(&self) -> &Self::Target { + self.value.as_ref().unwrap() + } +} + +impl DerefMut for BindingGuard { + fn deref_mut(&mut self) -> &mut Self::Target { + self.value.as_mut().unwrap() + } +} + +impl Drop for BindingGuard { + fn drop(&mut self) { + self.inner.set(self.value.take().unwrap()); + } +} + +/// A [`glib::Object`] with one primary property. +pub trait Binding: Clone + IsA { + /// The type of the primary property. + type Target; + + #[must_use] + /// The name of the primary property. + fn property_name() -> &'static str { + "value" + } + + /// Get a new [`BindingGuard`] from the object. + /// + /// Once dropped, the [`BindingGuard`] will + /// automatically update the value of the + /// primary property. + fn guard(&self) -> BindingGuard { + BindingGuard { + value: Some(self.get()), + inner: self.clone(), + } + } + + /// Get the value of the primary property. + fn get(&self) -> Self::Target; + + /// Set the value of the primary property. + fn set(&self, value: Self::Target); +} diff --git a/Relm4-0.6.2/relm4/src/binding/widgets.rs b/Relm4-0.6.2/relm4/src/binding/widgets.rs new file mode 100644 index 0000000..56c2f46 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/binding/widgets.rs @@ -0,0 +1,59 @@ +use crate::RelmObjectExt; + +use super::{Binding, ConnectBinding}; + +macro_rules! impl_connect_binding { + ($ty:ty, $target:ty, $primary_prop:literal, $mod:ident) => { + impl_connect_binding!($ty, $target, $primary_prop, $mod, gtk::glib::Object::new()); + }; + ($ty:ty, $target:ty, $primary_prop:literal, $mod:ident, $test_init:expr) => { + #[doc = "Create a data binding to the primary property `"] + #[doc = $primary_prop] + #[doc = "` with type [`"] + #[doc = stringify!($target)] + #[doc = "`]."] + impl ConnectBinding for $ty { + type Target = $target; + + fn bind>(&self, binding: &B) { + self.add_binding(binding, $primary_prop); + } + } + + #[cfg(test)] + mod $mod { + use gtk::prelude::ObjectExt; + + #[gtk::test] + /// Test whether the property name and type are correct. + fn test() { + let obj: $ty = $test_init; + let data: $target = Default::default(); + obj.set_property($primary_prop, data); + } + } + }; +} + +// bool bindings +impl_connect_binding!(gtk::ToggleButton, bool, "active", toggle_button); +impl_connect_binding!(gtk::Switch, bool, "active", switch); +impl_connect_binding!(gtk::Spinner, bool, "spinning", spinner); +impl_connect_binding!(gtk::Popover, bool, "visible", popover); +impl_connect_binding!(gtk::Revealer, bool, "reveal-child", revealer); + +// f64 bindings +impl_connect_binding!(gtk::SpinButton, f64, "value", spin_button); +impl_connect_binding!(gtk::Adjustment, f64, "value", adjustment); +impl_connect_binding!(gtk::ScaleButton, f64, "value", scale_button); + +// String bindings +impl_connect_binding!(gtk::Label, String, "label", label); +impl_connect_binding!(gtk::Button, String, "label", button); +impl_connect_binding!(gtk::LinkButton, String, "uri", link_button); +impl_connect_binding!(gtk::MenuButton, String, "label", menu_button); +impl_connect_binding!(gtk::Image, String, "icon-name", image); +impl_connect_binding!(gtk::StackPage, String, "name", stack_page, { + let stack = gtk::Stack::default(); + stack.add_child(>k::Label::default()) +}); diff --git a/Relm4-0.6.2/relm4/src/channel/component.rs b/Relm4-0.6.2/relm4/src/channel/component.rs new file mode 100644 index 0000000..ea63824 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/channel/component.rs @@ -0,0 +1,289 @@ +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +//! Contains various flavors of channels to send messages between components and workers. + +use std::fmt::Debug; +use std::future::Future; +use std::sync::Arc; + +use crate::component::AsyncComponent; +use crate::factory::{AsyncFactoryComponent, FactoryComponent}; +use crate::{Component, Sender, ShutdownReceiver}; + +// Contains senders used by components and factories internally. +#[derive(Debug)] +struct ComponentSenderInner +where + Input: Debug, + CommandOutput: Send + 'static, +{ + /// Emits component inputs. + input: Sender, + /// Emits component outputs. + output: Sender, + /// Emits command outputs. + command: Sender, + shutdown: ShutdownReceiver, +} + +impl ComponentSenderInner +where + Input: Debug, + CommandOutput: Send + 'static, +{ + /// Retrieve the sender for input messages. + /// + /// Useful to forward inputs from another component. If you just need to send input messages, + /// [`input()`][Self::input] is more concise. + #[must_use] + fn input_sender(&self) -> &Sender { + &self.input + } + + /// Retrieve the sender for output messages. + /// + /// Useful to forward outputs from another component. If you just need to send output messages, + /// [`output()`][Self::output] is more concise. + #[must_use] + fn output_sender(&self) -> &Sender { + &self.output + } + + /// Retrieve the sender for command output messages. + /// + /// Useful to forward outputs from another component. If you just need to send output messages, + /// [`command()`][Self::command] is more concise. + #[must_use] + fn command_sender(&self) -> &Sender { + &self.command + } + + /// Emit an input to the component. + fn input(&self, message: Input) { + // Input messages should always be safe to send + // because the runtime keeps the receiver alive. + self.input.send(message).expect("The runtime of the component was shutdown. Maybe you accidentally dropped a controller?"); + } + + /// This is not public because factories can unwrap the result + /// because they keep the output receiver alive internally. + fn output(&self, message: Output) -> Result<(), Output> { + self.output.send(message) + } + + /// Spawns an asynchronous command. + /// You can bind the the command to the lifetime of the component + /// by using a [`ShutdownReceiver`]. + fn command(&self, cmd: Cmd) + where + Cmd: FnOnce(Sender, ShutdownReceiver) -> Fut + Send + 'static, + Fut: Future + Send, + { + let recipient = self.shutdown.clone(); + let sender = self.command.clone(); + crate::spawn(async move { + cmd(sender, recipient).await; + }); + } + + /// Spawns a synchronous command. + /// + /// This is particularly useful for CPU-intensive background jobs that + /// need to run on a thread-pool in the background. + /// + /// If you expect the component to be dropped while + /// the command is running take care while sending messages! + fn spawn_command(&self, cmd: Cmd) + where + Cmd: FnOnce(Sender) + Send + 'static, + { + let sender = self.command.clone(); + crate::spawn_blocking(move || cmd(sender)); + } + + /// Spawns a future that will be dropped as soon as the factory component is shut down. + /// + /// Essentially, this is a simpler version of [`Self::command()`]. + fn oneshot_command(&self, future: Fut) + where + Fut: Future + Send + 'static, + { + // Async closures would be awesome here... + self.command(move |out, shutdown| { + shutdown + .register(async move { out.send(future.await) }) + .drop_on_shutdown() + }); + } + + /// Spawns a synchronous command that will be dropped as soon as the factory component is shut down. + /// + /// Essentially, this is a simpler version of [`Self::spawn_command()`]. + fn spawn_oneshot_command(&self, cmd: Cmd) + where + Cmd: FnOnce() -> CommandOutput + Send + 'static, + { + let handle = crate::spawn_blocking(cmd); + self.oneshot_command(async move { handle.await.unwrap() }) + } +} + +macro_rules! sender_impl { + ($name:ident, $trait:ident) => { + /// Contains senders to send and receive messages from a [`Component`]. + #[derive(Debug)] + pub struct $name { + shared: Arc>, + } + + impl $name { + pub(crate) fn new( + input: Sender, + output: Sender, + command: Sender, + shutdown: ShutdownReceiver, + ) -> Self { + Self { + shared: Arc::new(ComponentSenderInner { + input, + output, + command, + shutdown, + }), + } + } + + /// Retrieve the sender for input messages. + /// + /// Useful to forward inputs from another component. If you just need to send input messages, + /// [`input()`][Self::input] is more concise. + #[must_use] + pub fn input_sender(&self) -> &Sender { + self.shared.input_sender() + } + + /// Retrieve the sender for output messages. + /// + /// Useful to forward outputs from another component. If you just need to send output messages, + /// [`output()`][Self::output] is more concise. + #[must_use] + pub fn output_sender(&self) -> &Sender { + self.shared.output_sender() + } + + /// Retrieve the sender for command output messages. + /// + /// Useful to forward outputs from another component. If you just need to send output messages, + /// [`command()`][Self::command] is more concise. + #[must_use] + pub fn command_sender(&self) -> &Sender { + self.shared.command_sender() + } + + /// Emit an input to the component. + pub fn input(&self, message: C::Input) { + self.shared.input(message); + } + + /// Spawns an asynchronous command. + /// You can bind the the command to the lifetime of the component + /// by using a [`ShutdownReceiver`]. + pub fn command(&self, cmd: Cmd) + where + Cmd: FnOnce(Sender, ShutdownReceiver) -> Fut + Send + 'static, + Fut: Future + Send, + { + self.shared.command(cmd) + } + + /// Spawns a synchronous command. + /// + /// This is particularly useful for CPU-intensive background jobs that + /// need to run on a thread-pool in the background. + /// + /// If you expect the component to be dropped while + /// the command is running take care while sending messages! + pub fn spawn_command(&self, cmd: Cmd) + where + Cmd: FnOnce(Sender) + Send + 'static, + { + self.shared.spawn_command(cmd) + } + + /// Spawns a future that will be dropped as soon as the factory component is shut down. + /// + /// Essentially, this is a simpler version of [`Self::command()`]. + pub fn oneshot_command(&self, future: Fut) + where + Fut: Future + Send + 'static, + { + self.shared.oneshot_command(future) + } + + /// Spawns a synchronous command that will be dropped as soon as the factory component is shut down. + /// + /// Essentially, this is a simpler version of [`Self::spawn_command()`]. + pub fn spawn_oneshot_command(&self, cmd: Cmd) + where + Cmd: FnOnce() -> C::CommandOutput + Send + 'static, + { + self.shared.spawn_oneshot_command(cmd) + } + } + + impl Clone for $name { + fn clone(&self) -> Self { + Self { + shared: Arc::clone(&self.shared), + } + } + } + }; +} + +sender_impl!(ComponentSender, Component); + +impl ComponentSender { + /// Emit an output to the component. + /// + /// Returns [`Err`] if all receivers were dropped, + /// for example by [`detach`]. + /// + /// [`detach`]: crate::component::Connector::detach + pub fn output(&self, message: C::Output) -> Result<(), C::Output> { + self.shared.output(message) + } +} + +sender_impl!(AsyncComponentSender, AsyncComponent); + +impl AsyncComponentSender { + /// Emit an output to the component. + /// + /// Returns [`Err`] if all receivers were dropped, + /// for example by [`detach`]. + /// + /// [`detach`]: crate::component::AsyncConnector::detach + pub fn output(&self, message: C::Output) -> Result<(), C::Output> { + self.shared.output(message) + } +} + +sender_impl!(FactorySender, FactoryComponent); + +impl FactorySender { + /// Emit an output to the component. + pub fn output(&self, message: C::Output) { + self.shared.output(message).unwrap() + } +} + +sender_impl!(AsyncFactorySender, AsyncFactoryComponent); + +impl AsyncFactorySender { + /// Emit an output to the component. + pub fn output(&self, message: C::Output) { + self.shared.output(message).unwrap() + } +} diff --git a/Relm4-0.6.2/relm4/src/channel/mod.rs b/Relm4-0.6.2/relm4/src/channel/mod.rs new file mode 100644 index 0000000..77c2155 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/channel/mod.rs @@ -0,0 +1,109 @@ +mod component; +/// Cancellation mechanism used by Relm4. +pub mod shutdown; + +pub use component::{AsyncComponentSender, AsyncFactorySender, ComponentSender, FactorySender}; + +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use std::fmt; + +use flume::r#async::RecvStream; + +/// Create an unbounded channel to send messages +/// between different parts of you application. +#[must_use] +pub fn channel() -> (Sender, Receiver) { + let (tx, rx) = flume::unbounded(); + (Sender(tx), Receiver(rx)) +} + +/// A Relm4 sender sends messages to a component or worker. +pub struct Sender(pub(crate) flume::Sender); + +impl From> for Sender { + fn from(sender: flume::Sender) -> Self { + Self(sender) + } +} + +impl Sender { + /// Sends a message through the channel. + /// + /// **This method ignores errors.** + /// Only a log message will appear when sending fails. + pub fn emit(&self, message: T) { + if self.send(message).is_err() { + tracing::warn!("Receiver was dropped"); + } + } + + /// Sends a message through the channel. + /// + /// If all receivers where dropped, [`Err`] is returned + /// with the content of the message. + pub fn send(&self, message: T) -> Result<(), T> { + self.0.send(message).map_err(|e| e.into_inner()) + } +} + +impl Clone for Sender { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl fmt::Debug for Sender { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("Sender").field(&self.0).finish() + } +} + +/// A Relm4 receiver receives messages from a component or worker. +pub struct Receiver(pub(crate) flume::Receiver); + +impl Receiver { + /// Receives a message from a component or worker. + /// + /// Returns [`None`] if all senders have been disconnected. + pub async fn recv(&self) -> Option { + self.0.recv_async().await.ok() + } + + /// Receives a message synchronously from a component or worker. + /// + /// Returns [`None`] if all senders have been disconnected. + #[must_use] + pub fn recv_sync(&self) -> Option { + self.0.recv().ok() + } + + #[must_use] + pub(crate) fn into_stream(self) -> RecvStream<'static, T> { + self.0.into_stream() + } + + /// Forwards an event from one channel to another. + pub async fn forward( + self, + sender: impl Into>, + transformer: Transformer, + ) where + Transformer: (Fn(T) -> Output) + 'static, + Output: 'static, + { + let sender = sender.into(); + while let Some(event) = self.recv().await { + if sender.send(transformer(event)).is_err() { + return; + } + } + } +} + +impl fmt::Debug for Receiver { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("Receiver").field(&self.0).finish() + } +} diff --git a/Relm4-0.6.2/relm4/src/channel/shutdown/attached.rs b/Relm4-0.6.2/relm4/src/channel/shutdown/attached.rs new file mode 100644 index 0000000..da0c338 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/channel/shutdown/attached.rs @@ -0,0 +1,53 @@ +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use super::ShutdownReceiver; +use futures::future::Either; +use std::future::Future; + +/// A future attached to a shutdown receiver. +#[derive(Debug)] +pub struct AttachedShutdown { + pub(super) receiver: ShutdownReceiver, + pub(super) future: F, +} + +impl AttachedShutdown +where + F: Future, +{ + /// Creates a future which will resolve to this on shutdown. + pub async fn on_shutdown(self, shutdown: S) -> Out + where + S: Future, + { + match self.wait().await { + Either::Left(_) => shutdown.await, + Either::Right(out) => out, + } + } + + /// Waits until a shutdown signal is received. + /// + /// - `Either::Left(())` on cancellation. + /// - `Either::Right(Out)` on registered future completion. + pub async fn wait(self) -> Either<(), Out> { + let Self { receiver, future } = self; + + let cancel = receiver.wait(); + futures::pin_mut!(cancel); + futures::pin_mut!(future); + + match futures::future::select(cancel, future).await { + Either::Left(_) => Either::Left(()), + Either::Right((out, _)) => Either::Right(out), + } + } + + /// Waits until a shutdown signal is received. + /// + /// Ignores any output when we don't care about it. + pub async fn drop_on_shutdown(self) { + let _ = self.wait().await; + } +} diff --git a/Relm4-0.6.2/relm4/src/channel/shutdown/mod.rs b/Relm4-0.6.2/relm4/src/channel/shutdown/mod.rs new file mode 100644 index 0000000..f7fa129 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/channel/shutdown/mod.rs @@ -0,0 +1,22 @@ +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +mod attached; +mod receiver; +mod sender; + +use tokio::sync::broadcast; + +pub use attached::AttachedShutdown; +pub use receiver::ShutdownReceiver; +pub use sender::ShutdownSender; + +/// Creates a broadcasting shutdown channel. +/// +/// The sending side is responsible for initiating a shutdown. +/// The receiving side is responsible for responding to shutdowns. +#[must_use] +pub fn channel() -> (ShutdownSender, ShutdownReceiver) { + let (sender, receiver) = broadcast::channel(1); + (ShutdownSender { sender }, ShutdownReceiver { receiver }) +} diff --git a/Relm4-0.6.2/relm4/src/channel/shutdown/receiver.rs b/Relm4-0.6.2/relm4/src/channel/shutdown/receiver.rs new file mode 100644 index 0000000..643cd89 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/channel/shutdown/receiver.rs @@ -0,0 +1,42 @@ +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use super::broadcast::Receiver; +use super::AttachedShutdown; + +#[cfg(test)] +use super::broadcast::error::TryRecvError; + +/// Listens to shutdown signals and constructs shutdown futures. +#[derive(Debug)] +pub struct ShutdownReceiver { + pub(super) receiver: Receiver<()>, +} + +impl ShutdownReceiver { + /// Create a future which will be cancelled on shutdown. + pub fn register(self, future: F) -> AttachedShutdown { + AttachedShutdown { + receiver: self, + future, + } + } + + /// Waits until a shutdown signal is received. + pub async fn wait(mut self) { + let _ = self.receiver.recv().await; + } + + #[cfg(test)] + pub(crate) fn try_recv(&mut self) -> Result<(), TryRecvError> { + self.receiver.try_recv() + } +} + +impl Clone for ShutdownReceiver { + fn clone(&self) -> Self { + Self { + receiver: self.receiver.resubscribe(), + } + } +} diff --git a/Relm4-0.6.2/relm4/src/channel/shutdown/sender.rs b/Relm4-0.6.2/relm4/src/channel/shutdown/sender.rs new file mode 100644 index 0000000..3b743fc --- /dev/null +++ b/Relm4-0.6.2/relm4/src/channel/shutdown/sender.rs @@ -0,0 +1,23 @@ +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use super::broadcast; + +/// Sends shutdown signals to receivers. +#[derive(Debug)] +pub struct ShutdownSender { + pub(super) sender: broadcast::Sender<()>, +} + +impl ShutdownSender { + /// Broadcasts a shutdown signal to listening receivers. + pub(crate) fn shutdown(self) { + drop(self); + } +} + +impl Drop for ShutdownSender { + fn drop(&mut self) { + let _ = self.sender.send(()); + } +} diff --git a/Relm4-0.6.2/relm4/src/component/async/builder.rs b/Relm4-0.6.2/relm4/src/component/async/builder.rs new file mode 100644 index 0000000..bf2ee15 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/async/builder.rs @@ -0,0 +1,277 @@ +// Copyright 2021-2022 Aaron Erhardt +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use super::super::MessageBroker; +use super::{AsyncComponent, AsyncComponentParts, AsyncConnector}; +use crate::channel::AsyncComponentSender; +use crate::{ + late_initialization, GuardedReceiver, Receiver, RelmContainerExt, RelmWidgetExt, + RuntimeSenders, Sender, +}; +use gtk::glib; +use gtk::prelude::{GtkWindowExt, NativeDialogExt}; +use std::any; +use std::marker::PhantomData; +use tokio::sync::oneshot; +use tracing::info_span; + +/// A component that is ready for docking and launch. +#[derive(Debug)] +pub struct AsyncComponentBuilder { + /// The root widget of the component. + pub root: C::Root, + priority: glib::Priority, + + pub(super) component: PhantomData, +} + +impl Default for AsyncComponentBuilder { + /// Prepares a component for initialization. + fn default() -> Self { + Self { + root: C::init_root(), + priority: glib::Priority::default(), + component: PhantomData, + } + } +} + +impl AsyncComponentBuilder { + /// Configure the root widget before launching. + #[must_use] + pub fn update_root(mut self, func: F) -> Self { + func(&mut self.root); + self + } + + /// Access the root widget before the component is initialized. + pub const fn widget(&self) -> &C::Root { + &self.root + } + + /// Change the priority at which the messages of this component + /// are handled. + /// + /// + Use [`glib::PRIORITY_HIGH`] for high priority event sources. + /// + Use [`glib::PRIORITY_LOW`] for very low priority background tasks. + /// + Use [`glib::PRIORITY_DEFAULT_IDLE`] for default priority idle functions. + /// + Use [`glib::PRIORITY_HIGH_IDLE`] for high priority idle functions. + pub fn priority(mut self, priority: glib::Priority) -> Self { + self.priority = priority; + self + } +} + +impl AsyncComponentBuilder +where + C::Root: AsRef, +{ + /// Attach the component's root widget to a given container. + #[must_use] + pub fn attach_to(self, container: &impl RelmContainerExt) -> Self { + container.container_add(self.root.as_ref()); + + self + } +} + +impl AsyncComponentBuilder +where + C::Root: AsRef + Clone, +{ + /// Set the component's root widget transient for a given window. + /// This function doesn't require a [`gtk::Window`] as parameter, + /// but instead uses [`RelmWidgetExt::toplevel_window()`] to retrieve the toplevel + /// window of any [`gtk::Widget`]. + /// Therefore, you don't have to pass a window to every component. + /// + /// If the root widget is a native dialog, such as [`gtk::FileChooserNative`], + /// you should use [`transient_for_native`][AsyncComponentBuilder::transient_for_native] instead. + #[must_use] + pub fn transient_for(self, widget: impl AsRef) -> Self { + let widget = widget.as_ref().clone(); + let root = self.root.clone(); + late_initialization::register_callback(Box::new(move || { + if let Some(window) = widget.toplevel_window() { + root.as_ref().set_transient_for(Some(&window)); + } else { + tracing::error!("Couldn't find root of transient widget"); + } + })); + + self + } +} + +impl AsyncComponentBuilder +where + C::Root: AsRef + Clone, +{ + /// Set the component's root widget transient for a given window. + /// This function doesn't require a [`gtk::Window`] as parameter, + /// but instead uses [`RelmWidgetExt::toplevel_window()`] to retrieve the toplevel + /// window of any [`gtk::Widget`]. + /// Therefore, you don't have to pass a window to every component. + /// + /// Applicable to native dialogs only, such as [`gtk::FileChooserNative`]. + /// If the root widget is a non-native dialog, + /// you should use [`transient_for`][AsyncComponentBuilder::transient_for] instead. + #[must_use] + pub fn transient_for_native(self, widget: impl AsRef) -> Self { + let widget = widget.as_ref().clone(); + let root = self.root.clone(); + late_initialization::register_callback(Box::new(move || { + if let Some(window) = widget.toplevel_window() { + root.as_ref().set_transient_for(Some(&window)); + } else { + tracing::error!("Couldn't find root of transient widget"); + } + })); + + self + } +} + +impl AsyncComponentBuilder { + /// Starts the component, passing ownership to a future attached to a [gtk::glib::MainContext]. + pub fn launch(self, payload: C::Init) -> AsyncConnector { + // Used for all events to be processed by this component's internal service. + let (input_sender, input_receiver) = crate::channel::(); + + self.launch_with_input_channel(payload, input_sender, input_receiver) + } + + /// Similar to [`launch()`](AsyncComponentBuilder::launch) but also initializes a [`MessageBroker`]. + /// + /// # Panics + /// + /// This method panics if the message broker was already initialized in another launch. + pub fn launch_with_broker( + self, + payload: C::Init, + broker: &MessageBroker, + ) -> AsyncConnector { + let (input_sender, input_receiver) = broker.get_channel(); + self.launch_with_input_channel( + payload, + input_sender, + input_receiver.expect("Message broker launched multiple times"), + ) + } + + fn launch_with_input_channel( + self, + payload: C::Init, + input_sender: Sender, + input_receiver: Receiver, + ) -> AsyncConnector { + let Self { + mut root, priority, .. + } = self; + let temp_widgets = C::init_loading_widgets(&mut root); + + let RuntimeSenders { + output_sender, + output_receiver, + cmd_sender, + cmd_receiver, + shutdown_notifier, + shutdown_recipient, + shutdown_on_drop: destroy_on_drop, + mut shutdown_event, + } = RuntimeSenders::::new(); + + // Encapsulates the senders used by component methods. + let component_sender = AsyncComponentSender::new( + input_sender.clone(), + output_sender.clone(), + cmd_sender, + shutdown_recipient, + ); + + let (source_id_sender, source_id_receiver) = + oneshot::channel::>(); + + let rt_root = root.clone(); + + // Spawns the component's service. It will receive both `Self::Input` and + // `Self::CommandOutput` messages. It will spawn commands as requested by + // updates, and send `Self::Output` messages externally. + let handle = crate::spawn_local_with_priority(priority, async move { + let id = source_id_receiver.await.unwrap().into_source_id().unwrap(); + let mut state = C::init(payload, rt_root.clone(), component_sender.clone()).await; + drop(temp_widgets); + + let mut cmd = GuardedReceiver::new(cmd_receiver); + let mut input = GuardedReceiver::new(input_receiver); + + loop { + futures::select!( + // Performs the model update, checking if the update requested a command. + // Runs that command asynchronously in the background using tokio. + message = input => { + let AsyncComponentParts { + model, + widgets, + } = &mut state; + + let span = info_span!( + "update_with_view", + input=?message, + component=any::type_name::(), + id=model.id(), + ); + let _enter = span.enter(); + + model.update_with_view(widgets, message, component_sender.clone(), &rt_root).await; + } + + // Handles responses from a command. + message = cmd => { + let AsyncComponentParts { + model, + widgets, + } = &mut state; + + let span = info_span!( + "update_cmd_with_view", + cmd_output=?message, + component=any::type_name::(), + id=model.id(), + ); + let _enter = span.enter(); + + model.update_cmd_with_view(widgets, message, component_sender.clone(), &rt_root).await; + } + + // Triggered when the component is destroyed + _ = shutdown_event => { + let AsyncComponentParts { + model, + widgets, + } = &mut state; + + model.shutdown(widgets, output_sender); + + shutdown_notifier.shutdown(); + + id.remove(); + + return; + } + ); + } + }); + + source_id_sender.send(handle).unwrap(); + + // Give back a type for controlling the component service. + AsyncConnector { + widget: root, + sender: input_sender, + receiver: output_receiver, + shutdown_on_drop: destroy_on_drop, + } + } +} diff --git a/Relm4-0.6.2/relm4/src/component/async/connector.rs b/Relm4-0.6.2/relm4/src/component/async/connector.rs new file mode 100644 index 0000000..3367ce0 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/async/connector.rs @@ -0,0 +1,119 @@ +// Copyright 2021-2022 Aaron Erhardt +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use super::{AsyncComponent, AsyncComponentController, AsyncController}; +use crate::{Receiver, Sender, ShutdownOnDrop}; +use std::fmt::{self, Debug}; + +/// Contains the post-launch input sender and output receivers with the root widget. +/// +/// The receiver can be separated from the `Fairing` by choosing a method for handling it. +pub struct AsyncConnector { + /// The widget that this component manages. + pub(super) widget: C::Root, + + /// Used for emitting events to the component. + pub(super) sender: Sender, + + /// The outputs being received by the component. + pub(super) receiver: Receiver, + + /// Type used to destroy the async component when it's dropped. + pub(super) shutdown_on_drop: ShutdownOnDrop, +} + +impl AsyncConnector { + /// Forwards output events to the designated sender. + pub fn forward X) + 'static>( + self, + sender_: &Sender, + transform: F, + ) -> AsyncController { + let Self { + widget, + sender, + receiver, + shutdown_on_drop, + } = self; + + crate::spawn_local(receiver.forward(sender_.clone(), transform)); + + AsyncController { + widget, + sender, + shutdown_on_drop, + } + } + + /// Given a mutable closure, captures the receiver for handling. + pub fn connect_receiver, C::Output) + 'static>( + self, + mut func: F, + ) -> AsyncController { + let Self { + widget, + sender, + receiver, + shutdown_on_drop, + } = self; + + let mut sender_ = sender.clone(); + crate::spawn_local(async move { + while let Some(event) = receiver.recv().await { + func(&mut sender_, event); + } + }); + + AsyncController { + widget, + sender, + shutdown_on_drop, + } + } + + /// Ignore outputs from the component and take the handle. + pub fn detach(self) -> AsyncController { + let Self { + widget, + sender, + shutdown_on_drop, + .. + } = self; + + AsyncController { + widget, + sender, + shutdown_on_drop, + } + } +} + +impl AsyncComponentController for AsyncConnector { + fn sender(&self) -> &Sender { + &self.sender + } + + fn widget(&self) -> &C::Root { + &self.widget + } + + fn detach_runtime(&mut self) { + self.shutdown_on_drop.deactivate(); + } +} + +impl Debug for AsyncConnector +where + C: AsyncComponent + Debug, + C::Widgets: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Connector") + .field("widget", &self.widget) + .field("sender", &self.sender) + .field("receiver", &self.receiver) + .field("shutdown_on_drop", &self.shutdown_on_drop) + .finish() + } +} diff --git a/Relm4-0.6.2/relm4/src/component/async/controller.rs b/Relm4-0.6.2/relm4/src/component/async/controller.rs new file mode 100644 index 0000000..f0b4d72 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/async/controller.rs @@ -0,0 +1,68 @@ +// Copyright 2021-2022 Aaron Erhardt +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use std::fmt::{self, Debug}; + +use crate::{Sender, ShutdownOnDrop}; + +use super::AsyncComponent; + +/// Shared behavior of component controller types. +pub trait AsyncComponentController { + /// Emits an input to the component. + fn emit(&self, event: C::Input) { + self.sender().send(event).unwrap(); + } + + /// Provides access to the component's sender. + fn sender(&self) -> &Sender; + + /// Returns the root widget of the component. + fn widget(&self) -> &C::Root; + + /// Dropping this type will usually stop the runtime of the component. + /// With this method you can give the runtime a static lifetime. + /// In other words, dropping the controller or connector will not stop + /// the runtime anymore, instead it will run until the app is closed. + fn detach_runtime(&mut self); +} + +/// Controls the component from afar. +pub struct AsyncController { + /// The widget that this component manages. + pub(super) widget: C::Root, + + /// Used for emitting events to the component. + pub(super) sender: Sender, + + /// Type used to destroy the async component when it's dropped. + pub(super) shutdown_on_drop: ShutdownOnDrop, +} + +impl AsyncComponentController for AsyncController { + fn sender(&self) -> &Sender { + &self.sender + } + + fn widget(&self) -> &C::Root { + &self.widget + } + + fn detach_runtime(&mut self) { + self.shutdown_on_drop.deactivate(); + } +} + +impl Debug for AsyncController +where + C: AsyncComponent + Debug, + C::Widgets: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Controller") + .field("widget", &self.widget) + .field("sender", &self.sender) + .finish() + } +} diff --git a/Relm4-0.6.2/relm4/src/component/async/mod.rs b/Relm4-0.6.2/relm4/src/component/async/mod.rs new file mode 100644 index 0000000..d4592d7 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/async/mod.rs @@ -0,0 +1,19 @@ +mod builder; +mod connector; +mod controller; +mod traits; + +pub use builder::AsyncComponentBuilder; +pub use connector::AsyncConnector; +pub use controller::{AsyncComponentController, AsyncController}; +pub use traits::AsyncComponent; +pub use traits::SimpleAsyncComponent; + +/// Contains the initial model and widgets being docked into a component. +#[derive(Debug)] +pub struct AsyncComponentParts { + /// The model of the component. + pub model: C, + /// The widgets created for the view. + pub widgets: C::Widgets, +} diff --git a/Relm4-0.6.2/relm4/src/component/async/traits.rs b/Relm4-0.6.2/relm4/src/component/async/traits.rs new file mode 100644 index 0000000..0bf35a2 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/async/traits.rs @@ -0,0 +1,277 @@ +// Copyright 2021-2022 Aaron Erhardt +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use std::fmt::Debug; + +use crate::channel::{AsyncComponentSender, Sender}; +use crate::loading_widgets::LoadingWidgets; + +use super::{AsyncComponentBuilder, AsyncComponentParts}; + +/// Asynchronous variant of [`Component`](crate::Component). +/// +/// `AsyncComponent` is powerful and flexible, but for many use-cases the [`SimpleAsyncComponent`] +/// convenience trait will suffice. +#[async_trait::async_trait(?Send)] +pub trait AsyncComponent: Sized + 'static { + /// Messages which are received from commands executing in the background. + type CommandOutput: Debug + Send + 'static; + + /// The message type that the component accepts as inputs. + type Input: Debug + 'static; + + /// The message type that the component provides as outputs. + type Output: Debug + 'static; + + /// The parameter used to initialize the component. + type Init; + + /// The top-level widget of the component. + type Root: Debug + Clone; + + /// The type that's used for storing widgets created for this component. + type Widgets: 'static; + + /// Create a builder for this component. + #[must_use] + fn builder() -> AsyncComponentBuilder { + AsyncComponentBuilder::::default() + } + + /// Initializes the root widget + #[must_use] + fn init_root() -> Self::Root; + + /// Allows you to initialize the root widget with a temporary value + /// as a placeholder until the [`init()`](AsyncComponent::init) + /// future completes. + /// + /// This method does nothing by default. + #[must_use] + fn init_loading_widgets(_root: &mut Self::Root) -> Option { + None + } + + /// Creates the initial model and view, docking it into the component. + async fn init( + init: Self::Init, + root: Self::Root, + sender: AsyncComponentSender, + ) -> AsyncComponentParts; + + /// Processes inputs received by the component. + #[allow(unused)] + async fn update( + &mut self, + message: Self::Input, + sender: AsyncComponentSender, + root: &Self::Root, + ) { + } + + /// Defines how the component should respond to command updates. + #[allow(unused)] + async fn update_cmd( + &mut self, + message: Self::CommandOutput, + sender: AsyncComponentSender, + root: &Self::Root, + ) { + } + + /// Updates the model and view upon completion of a command. + /// + /// Overriding this method is helpful if you need access to the widgets while processing a + /// command output. + /// + /// The default implementation of this method calls [`update_cmd`] followed by [`update_view`]. + /// If you override this method while using the [`component`] macro, you must remember to call + /// [`update_view`] in your implementation. Otherwise, the view will not reflect the updated + /// model. + /// + /// [`update_cmd`]: Self::update_cmd + /// [`update_view`]: Self::update_view + /// [`component`]: relm4_macros::component + async fn update_cmd_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::CommandOutput, + sender: AsyncComponentSender, + root: &Self::Root, + ) { + self.update_cmd(message, sender.clone(), root).await; + self.update_view(widgets, sender); + } + + /// Updates the view after the model has been updated. + #[allow(unused)] + fn update_view(&self, widgets: &mut Self::Widgets, sender: AsyncComponentSender) {} + + /// Updates the model and view when a new input is received. + /// + /// Overriding this method is helpful if you need access to the widgets while processing an + /// input. + /// + /// The default implementation of this method calls [`update`] followed by [`update_view`]. If + /// you override this method while using the [`component`] macro, you must remember to + /// call [`update_view`] in your implementation. Otherwise, the view will not reflect the + /// updated model. + /// + /// [`update`]: Self::update + /// [`update_view`]: Self::update_view + /// [`component`]: relm4_macros::component + async fn update_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::Input, + sender: AsyncComponentSender, + root: &Self::Root, + ) { + self.update(message, sender.clone(), root).await; + self.update_view(widgets, sender); + } + + /// Last method called before a component is shut down. + /// + /// This method is guaranteed to be called even when the entire application is shut down. + #[allow(unused)] + fn shutdown(&mut self, widgets: &mut Self::Widgets, output: Sender) {} + + /// An identifier for the component used for debug logging. + /// + /// The default implementation of this method uses the address of the component, but + /// implementations are free to provide more meaningful identifiers. + #[must_use] + fn id(&self) -> String { + format!("{:p}", &self) + } +} + +/// Asynchronous variant of [`SimpleComponent`](crate::SimpleComponent). +#[async_trait::async_trait(?Send)] +pub trait SimpleAsyncComponent: Sized + 'static { + /// The message type that the component accepts as inputs. + type Input: Debug + 'static; + + /// The message type that the component provides as outputs. + type Output: Debug + 'static; + + /// The parameter used to initialize the component. + type Init; + + /// The top-level widget of the component. + type Root: Debug + Clone; + + /// The type that's used for storing widgets created for this component. + type Widgets: 'static; + + /// Initializes the root widget + #[must_use] + fn init_root() -> Self::Root; + + /// Allows you to initialize the root widget with a temporary value + /// as a placeholder until the [`init()`](AsyncComponent::init) + /// future completes. + /// + /// This method does nothing by default. + #[must_use] + fn init_loading_widgets(_root: &mut Self::Root) -> Option { + None + } + + /// Creates the initial model and view, docking it into the component. + async fn init( + init: Self::Init, + root: Self::Root, + sender: AsyncComponentSender, + ) -> AsyncComponentParts; + + /// Processes inputs received by the component. + #[allow(unused)] + async fn update(&mut self, message: Self::Input, sender: AsyncComponentSender) {} + + /// Defines how the component should respond to command updates. + #[allow(unused)] + async fn update_cmd(&mut self, input: &Sender, output: Sender) {} + + /// Updates the view after the model has been updated. + #[allow(unused)] + fn update_view(&self, widgets: &mut Self::Widgets, sender: AsyncComponentSender) {} + + /// Last method called before a component is shut down. + /// + /// This method is guaranteed to be called even when the entire application is shut down. + #[allow(unused)] + fn shutdown(&mut self, widgets: &mut Self::Widgets, output: Sender) {} +} + +#[async_trait::async_trait(?Send)] +impl AsyncComponent for C +where + C: SimpleAsyncComponent, +{ + type Init = C::Init; + type Input = C::Input; + type Output = C::Output; + type Root = C::Root; + type Widgets = C::Widgets; + + type CommandOutput = (); + + fn init_root() -> Self::Root { + C::init_root() + } + + fn init_loading_widgets(root: &mut Self::Root) -> Option { + C::init_loading_widgets(root) + } + + async fn init( + init: Self::Init, + root: Self::Root, + sender: AsyncComponentSender, + ) -> AsyncComponentParts { + C::init(init, root, sender).await + } + + async fn update( + &mut self, + message: Self::Input, + sender: AsyncComponentSender, + _root: &Self::Root, + ) { + C::update(self, message, sender).await; + } + + fn update_view(&self, widgets: &mut Self::Widgets, sender: AsyncComponentSender) { + C::update_view(self, widgets, sender); + } + + fn shutdown(&mut self, widgets: &mut Self::Widgets, output: Sender) { + self.shutdown(widgets, output); + } +} + +/// An empty, non-interactive component as a placeholder for tests. +#[async_trait::async_trait(?Send)] +impl SimpleAsyncComponent for () { + type Input = (); + type Output = (); + type Init = (); + type Root = (); + type Widgets = (); + + fn init_root() -> Self::Root {} + + async fn init( + _init: Self::Init, + _root: Self::Root, + _sender: AsyncComponentSender, + ) -> AsyncComponentParts { + AsyncComponentParts { + model: (), + widgets: (), + } + } +} diff --git a/Relm4-0.6.2/relm4/src/component/message_broker.rs b/Relm4-0.6.2/relm4/src/component/message_broker.rs new file mode 100644 index 0000000..50448f8 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/message_broker.rs @@ -0,0 +1,90 @@ +use std::sync::Mutex; + +use crate::{Receiver, Sender}; +use once_cell::sync::Lazy; +use std::fmt::Debug; + +#[derive(Debug)] +/// A type that can be used in static variables to pass messages to components. +/// +/// The primary use-case for this type is to communicate between components on different levels. +/// +/// Imagine you have three components: A, B and C. +/// A and B are children of the main application, but C is a child of B. +/// If C wants to pass a message to A, it relies on B to forward that message to A. +/// This is not great because B has nothing to do this message but has to implement additional +/// logic only to pass the message through. +/// [`MessageBroker`] allows you to use statics to remove this limitation. +/// +/// # Note +/// +/// [`MessageBroker`] will not forward any messages until you initialize them with +/// [`ComponentBuilder::launch_with_broker()`](crate::ComponentBuilder::launch_with_broker()). +/// +/// **Only initialize the message broker once!** +/// +/// ``` +/// use relm4::{MessageBroker, Component}; +/// # type MyComponent = (); +/// +/// static MY_COMPONENT: MessageBroker<()> = MessageBroker::new(); +/// +/// // Initialize the component and the message broker with `launch_with_broker`. +/// let controller = MyComponent::builder().launch_with_broker((), &MY_COMPONENT).detach(); +/// ``` +pub struct MessageBroker { + inner: Lazy>, +} + +impl MessageBroker { + /// Creates a new [`MessageBroker`]. + /// + /// The returned message broker will not forward messages until it's initialized. + #[must_use] + pub const fn new() -> Self { + let inner: Lazy> = Lazy::new(|| MessageBrokerInner::::new()); + Self { inner } + } + + /// Get the input sender of the component. + pub fn sender(&self) -> &Sender { + &self.inner.sender + } + + /// Send an input message to the component. + pub fn send(&self, input: M) { + self.inner.sender.send(input).unwrap(); + } + + pub(super) fn get_channel(&self) -> (Sender, Option>) { + let inner = &self.inner; + ( + inner.sender.clone(), + inner.input_receiver.lock().unwrap().take(), + ) + } +} + +struct MessageBrokerInner { + sender: Sender, + input_receiver: Mutex>>, +} + +impl MessageBrokerInner { + fn new() -> Self { + // Used for all events to be processed by this component's internal service. + let (sender, input_receiver) = crate::channel::(); + Self { + sender, + input_receiver: Mutex::new(Some(input_receiver)), + } + } +} + +impl Debug for MessageBrokerInner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("MessageBrokerInner") + .field("sender", &self.sender) + .finish() + } +} diff --git a/Relm4-0.6.2/relm4/src/component/mod.rs b/Relm4-0.6.2/relm4/src/component/mod.rs new file mode 100644 index 0000000..54162d8 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/mod.rs @@ -0,0 +1,29 @@ +//! Components are smaller mostly independent parts of +//! your application. + +/// Types and traits used for regular (synchronous) components. +mod sync; + +/// Types and traits used for async components. +mod r#async; + +/// Message broker +mod message_broker; + +/// A simpler version of components that does work +/// in the background. +pub mod worker; + +pub use message_broker::MessageBroker; + +pub use sync::{ + CommandFuture, Component, ComponentBuilder, ComponentController, ComponentParts, + ComponentStream, Connector, Controller, SimpleComponent, StateWatcher, +}; + +pub use r#async::{ + AsyncComponent, AsyncComponentBuilder, AsyncComponentController, AsyncComponentParts, + AsyncConnector, AsyncController, SimpleAsyncComponent, +}; + +pub use crate::channel::AsyncComponentSender; diff --git a/Relm4-0.6.2/relm4/src/component/sync/builder.rs b/Relm4-0.6.2/relm4/src/component/sync/builder.rs new file mode 100644 index 0000000..9c3fa38 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/sync/builder.rs @@ -0,0 +1,298 @@ +// Copyright 2021-2022 Aaron Erhardt +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use super::super::MessageBroker; +use super::{Component, ComponentParts, Connector, StateWatcher}; +use crate::{ + late_initialization, ComponentSender, GuardedReceiver, Receiver, RelmContainerExt, + RelmWidgetExt, RuntimeSenders, Sender, +}; +use gtk::glib; +use gtk::prelude::{GtkWindowExt, NativeDialogExt}; +use std::any; +use std::cell::RefCell; +use std::marker::PhantomData; +use std::rc::Rc; +use tokio::sync::oneshot; +use tracing::info_span; + +/// A component that is ready for docking and launch. +#[derive(Debug)] +pub struct ComponentBuilder { + /// The root widget of the component. + pub root: C::Root, + priority: glib::Priority, + + pub(super) component: PhantomData, +} + +impl Default for ComponentBuilder { + /// Prepares a component for initialization. + fn default() -> Self { + Self { + root: C::init_root(), + priority: glib::Priority::default(), + component: PhantomData, + } + } +} + +impl ComponentBuilder { + /// Configure the root widget before launching. + #[must_use] + pub fn update_root(mut self, func: F) -> Self { + func(&mut self.root); + self + } + + /// Access the root widget before the component is initialized. + pub const fn widget(&self) -> &C::Root { + &self.root + } + + /// Change the priority at which the messages of this component + /// are handled. + /// + /// + Use [`glib::PRIORITY_HIGH`] for high priority event sources. + /// + Use [`glib::PRIORITY_LOW`] for very low priority background tasks. + /// + Use [`glib::PRIORITY_DEFAULT_IDLE`] for default priority idle functions. + /// + Use [`glib::PRIORITY_HIGH_IDLE`] for high priority idle functions. + pub fn priority(mut self, priority: glib::Priority) -> Self { + self.priority = priority; + self + } +} + +impl ComponentBuilder +where + C::Root: AsRef, +{ + /// Attach the component's root widget to a given container. + #[must_use] + pub fn attach_to(self, container: &impl RelmContainerExt) -> Self { + container.container_add(self.root.as_ref()); + + self + } +} + +impl ComponentBuilder +where + C::Root: AsRef + Clone, +{ + /// Set the component's root widget transient for a given window. + /// This function doesn't require a [`gtk::Window`] as parameter, + /// but instead uses [`RelmWidgetExt::toplevel_window()`] to retrieve the toplevel + /// window of any [`gtk::Widget`]. + /// Therefore, you don't have to pass a window to every component. + /// + /// If the root widget is a native dialog, such as [`gtk::FileChooserNative`], + /// you should use [`transient_for_native`][ComponentBuilder::transient_for_native] instead. + #[must_use] + pub fn transient_for(self, widget: impl AsRef) -> Self { + let widget = widget.as_ref().clone(); + let root = self.root.clone(); + late_initialization::register_callback(Box::new(move || { + if let Some(window) = widget.toplevel_window() { + root.as_ref().set_transient_for(Some(&window)); + } else { + tracing::error!("Couldn't find root of transient widget"); + } + })); + + self + } +} + +impl ComponentBuilder +where + C::Root: AsRef + Clone, +{ + /// Set the component's root widget transient for a given window. + /// This function doesn't require a [`gtk::Window`] as parameter, + /// but instead uses [`RelmWidgetExt::toplevel_window()`] to retrieve the toplevel + /// window of any [`gtk::Widget`]. + /// Therefore, you don't have to pass a window to every component. + /// + /// Applicable to native dialogs only, such as [`gtk::FileChooserNative`]. + /// If the root widget is a non-native dialog, + /// you should use [`transient_for`][ComponentBuilder::transient_for] instead. + #[must_use] + pub fn transient_for_native(self, widget: impl AsRef) -> Self { + let widget = widget.as_ref().clone(); + let root = self.root.clone(); + late_initialization::register_callback(Box::new(move || { + if let Some(window) = widget.toplevel_window() { + root.as_ref().set_transient_for(Some(&window)); + } else { + tracing::error!("Couldn't find root of transient widget"); + } + })); + + self + } +} + +impl ComponentBuilder { + /// Starts the component, passing ownership to a future attached to a [gtk::glib::MainContext]. + pub fn launch(self, payload: C::Init) -> Connector { + // Used for all events to be processed by this component's internal service. + let (input_sender, input_receiver) = crate::channel::(); + + self.launch_with_input_channel(payload, input_sender, input_receiver) + } + + /// Similar to [`launch()`](ComponentBuilder::launch) but also initializes a [`MessageBroker`]. + /// + /// # Panics + /// + /// This method panics if the message broker was already initialized in another launch. + pub fn launch_with_broker( + self, + payload: C::Init, + broker: &MessageBroker, + ) -> Connector { + let (input_sender, input_receiver) = broker.get_channel(); + self.launch_with_input_channel( + payload, + input_sender, + input_receiver.expect("Message broker launched multiple times"), + ) + } + + fn launch_with_input_channel( + self, + payload: C::Init, + input_sender: Sender, + input_receiver: Receiver, + ) -> Connector { + let Self { root, priority, .. } = self; + + let RuntimeSenders { + output_sender, + output_receiver, + cmd_sender, + cmd_receiver, + shutdown_notifier, + shutdown_recipient, + shutdown_on_drop, + mut shutdown_event, + } = RuntimeSenders::::new(); + + // Gets notifications when a component's model and view is updated externally. + let (notifier, notifier_receiver) = crate::channel(); + + let (source_id_sender, source_id_receiver) = + oneshot::channel::>(); + + // Encapsulates the senders used by component methods. + let component_sender = ComponentSender::new( + input_sender.clone(), + output_sender.clone(), + cmd_sender, + shutdown_recipient, + ); + + // Constructs the initial model and view with the initial payload. + let state = Rc::new(RefCell::new(C::init( + payload, + &root, + component_sender.clone(), + ))); + let watcher = StateWatcher { + state, + notifier, + shutdown_on_drop, + }; + + let rt_state = watcher.state.clone(); + let rt_root = root.clone(); + + // Spawns the component's service. It will receive both `Self::Input` and + // `Self::CommandOutput` messages. It will spawn commands as requested by + // updates, and send `Self::Output` messages externally. + let handle = crate::spawn_local_with_priority(priority, async move { + let id = source_id_receiver.await.unwrap().into_source_id().unwrap(); + let mut notifier = GuardedReceiver::new(notifier_receiver); + let mut cmd = GuardedReceiver::new(cmd_receiver); + let mut input = GuardedReceiver::new(input_receiver); + loop { + futures::select!( + // Performs the model update, checking if the update requested a command. + // Runs that command asynchronously in the background using tokio. + message = input => { + let ComponentParts { + model, + widgets, + } = &mut *rt_state.borrow_mut(); + + let span = info_span!( + "update_with_view", + input=?message, + component=any::type_name::(), + id=model.id(), + ); + let _enter = span.enter(); + + model.update_with_view(widgets, message, component_sender.clone(), &rt_root); + } + + // Handles responses from a command. + message = cmd => { + let ComponentParts { + model, + widgets, + } = &mut *rt_state.borrow_mut(); + + let span = info_span!( + "update_cmd_with_view", + cmd_output=?message, + component=any::type_name::(), + id=model.id(), + ); + let _enter = span.enter(); + + model.update_cmd_with_view(widgets, message, component_sender.clone(), &rt_root); + } + + // Triggered when the model and view have been updated externally. + _ = notifier => { + let ComponentParts { + model, + widgets, + } = &mut *rt_state.borrow_mut(); + + model.update_view(widgets, component_sender.clone()); + } + + // Triggered when the component is destroyed + _ = shutdown_event => { + let ComponentParts { + model, + widgets, + } = &mut *rt_state.borrow_mut(); + + model.shutdown(widgets, output_sender); + + shutdown_notifier.shutdown(); + + id.remove(); + + return; + } + ); + } + }); + + source_id_sender.send(handle).unwrap(); + + // Give back a type for controlling the component service. + Connector { + state: watcher, + widget: root, + sender: input_sender, + receiver: output_receiver, + } + } +} diff --git a/Relm4-0.6.2/relm4/src/component/sync/connector.rs b/Relm4-0.6.2/relm4/src/component/sync/connector.rs new file mode 100644 index 0000000..33d0b1a --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/sync/connector.rs @@ -0,0 +1,137 @@ +// Copyright 2021-2022 Aaron Erhardt +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use super::stream::ComponentStream; +use super::{Component, ComponentController, Controller, StateWatcher}; +use crate::{Receiver, Sender}; +use std::fmt::{self, Debug}; + +/// Contains the post-launch input sender and output receivers with the root widget. +/// +/// The receiver can be separated from the [`Connector`] by choosing a method for handling it. +pub struct Connector { + /// The models and widgets maintained by the component. + pub(super) state: StateWatcher, + + /// The widget that this component manages. + pub(super) widget: C::Root, + + /// Used for emitting events to the component. + pub(super) sender: Sender, + + /// The outputs being received by the component. + pub(super) receiver: Receiver, +} + +impl Connector { + /// Forwards output events to the designated sender. + pub fn forward X) + 'static>( + self, + sender_: &Sender, + transform: F, + ) -> Controller { + let Self { + state, + widget, + sender, + receiver, + } = self; + + crate::spawn_local(receiver.forward(sender_.clone(), transform)); + + Controller { + state, + widget, + sender, + } + } + + /// Given a mutable closure, captures the receiver for handling. + pub fn connect_receiver, C::Output) + 'static>( + self, + mut func: F, + ) -> Controller { + let Self { + state, + widget, + sender, + receiver, + } = self; + + let mut sender_ = sender.clone(); + crate::spawn_local(async move { + while let Some(event) = receiver.recv().await { + func(&mut sender_, event); + } + }); + + Controller { + state, + widget, + sender, + } + } + + /// Ignore outputs from the component and take the handle. + pub fn detach(self) -> Controller { + let Self { + state, + widget, + sender, + .. + } = self; + + Controller { + state, + widget, + sender, + } + } + + /// Convert his type into a [`Stream`](futures::Stream) that yields output events + /// as futures. + pub fn into_stream(self) -> ComponentStream { + let Self { + receiver, state, .. + } = self; + + ComponentStream { + stream: receiver.into_stream(), + shutdown_on_drop: state.shutdown_on_drop, + } + } +} + +impl ComponentController for Connector { + fn sender(&self) -> &Sender { + &self.sender + } + + fn state(&self) -> &StateWatcher { + &self.state + } + + fn widget(&self) -> &C::Root { + &self.widget + } + + fn detach_runtime(&mut self) { + self.state.detach_runtime(); + } +} + +impl Debug for Connector +where + C: Component + Debug, + C::Widgets: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Connector") + .field("state", &self.state) + .field("widget", &self.widget) + .field("sender", &self.sender) + .field("receiver", &self.receiver) + .finish() + } +} diff --git a/Relm4-0.6.2/relm4/src/component/sync/controller.rs b/Relm4-0.6.2/relm4/src/component/sync/controller.rs new file mode 100644 index 0000000..61e71ae --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/sync/controller.rs @@ -0,0 +1,89 @@ +// Copyright 2021-2022 Aaron Erhardt +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use std::cell::Ref; +use std::fmt::{self, Debug}; + +use crate::Sender; + +use super::{Component, StateWatcher}; + +/// Shared behavior of component controller types. +pub trait ComponentController { + /// Emits an input to the component. + fn emit(&self, event: C::Input) { + self.sender().send(event).unwrap(); + } + + /// Provides access to the component's sender. + fn sender(&self) -> &Sender; + + /// Provides access to the state of a component. + fn state(&self) -> &StateWatcher; + + /// Returns a reference to the [`Component`]. + fn model(&self) -> Ref<'_, C> { + let part_ref = self.state().get(); + Ref::map(part_ref, |part| &part.model) + } + + /// Returns a reference to the [`Component::Widgets`]. + fn widgets(&self) -> Ref<'_, C::Widgets> { + let part_ref = self.state().get(); + Ref::map(part_ref, |part| &part.widgets) + } + + /// Returns the root widget of the component. + fn widget(&self) -> &C::Root; + + /// Dropping this type will usually stop the runtime of the component. + /// With this method you can give the runtime a static lifetime. + /// In other words, dropping the controller or connector will not stop + /// the runtime anymore, instead it will run until the app is closed. + fn detach_runtime(&mut self); +} + +/// Controls the component from afar. +pub struct Controller { + /// The models and widgets maintained by the component. + pub(super) state: StateWatcher, + + /// The widget that this component manages. + pub(super) widget: C::Root, + + /// Used for emitting events to the component. + pub(super) sender: Sender, +} + +impl ComponentController for Controller { + fn sender(&self) -> &Sender { + &self.sender + } + + fn state(&self) -> &StateWatcher { + &self.state + } + + fn widget(&self) -> &C::Root { + &self.widget + } + + fn detach_runtime(&mut self) { + self.state.detach_runtime(); + } +} + +impl Debug for Controller +where + C: Component + Debug, + C::Widgets: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Controller") + .field("state", &self.state) + .field("widget", &self.widget) + .field("sender", &self.sender) + .finish() + } +} diff --git a/Relm4-0.6.2/relm4/src/component/sync/mod.rs b/Relm4-0.6.2/relm4/src/component/sync/mod.rs new file mode 100644 index 0000000..2789c51 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/sync/mod.rs @@ -0,0 +1,32 @@ +// Copyright 2021-2022 Aaron Erhardt +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +mod builder; +mod connector; +mod controller; +mod state_watcher; +mod stream; +mod traits; + +pub use builder::ComponentBuilder; +pub use connector::Connector; +pub use controller::{ComponentController, Controller}; +pub use state_watcher::StateWatcher; +pub use stream::ComponentStream; +pub use traits::{Component, SimpleComponent}; + +use std::future::Future; +use std::pin::Pin; + +/// A future returned by a component's command method. +pub type CommandFuture = Pin + Send>>; + +/// Contains the initial model and widgets being docked into a component. +#[derive(Debug)] +pub struct ComponentParts { + /// The model of the component. + pub model: C, + /// The widgets created for the view. + pub widgets: C::Widgets, +} diff --git a/Relm4-0.6.2/relm4/src/component/sync/state_watcher.rs b/Relm4-0.6.2/relm4/src/component/sync/state_watcher.rs new file mode 100644 index 0000000..b249bf5 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/sync/state_watcher.rs @@ -0,0 +1,48 @@ +use crate::{Component, ComponentParts, ShutdownOnDrop}; + +use std::cell::{Ref, RefCell, RefMut}; +use std::fmt::{self, Debug}; +use std::rc::Rc; + +/// Keeps track of a components model and view. +/// +/// Borrowing the model and view will notify the component to check for updates. +pub struct StateWatcher { + /// The models and widgets maintained by the component. + pub(super) state: Rc>>, + pub(super) notifier: crate::Sender<()>, + pub(super) shutdown_on_drop: ShutdownOnDrop, +} + +impl StateWatcher { + /// Borrows the model and view of a component. + #[must_use] + pub fn get(&self) -> Ref<'_, ComponentParts> { + self.state.borrow() + } + + /// Borrows the model and view of a component, and notifies the component to check for updates. + #[must_use] + pub fn get_mut(&self) -> RefMut<'_, ComponentParts> { + self.notifier.send(()).unwrap(); + self.state.borrow_mut() + } + + pub(super) fn detach_runtime(&mut self) { + self.shutdown_on_drop.deactivate() + } +} + +impl Debug for StateWatcher +where + C: Component + Debug, + C::Widgets: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("StateWatcher") + .field("state", &self.state) + .field("notifier", &self.notifier) + .field("shutdown_on_drop", &self.shutdown_on_drop) + .finish() + } +} diff --git a/Relm4-0.6.2/relm4/src/component/sync/stream.rs b/Relm4-0.6.2/relm4/src/component/sync/stream.rs new file mode 100644 index 0000000..7505181 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/sync/stream.rs @@ -0,0 +1,98 @@ +use std::fmt::Debug; +use std::pin::Pin; +use std::task::{Context, Poll}; + +use flume::r#async::RecvStream; +use futures::{pin_mut, Stream, StreamExt}; + +use crate::{Component, ShutdownOnDrop}; + +/// Yields [`Component::Output`] values as a stream and contains the +/// input sender and the root widget. +/// +/// Use this as alternative to [`Controller`](crate::Controller) when +/// you prefer a stream of futures or want to unlock the potential of +/// [`StreamExt`](futures::StreamExt). +/// Also, this type implements [`Send`] so using it in commands is +/// possible. +pub struct ComponentStream { + /// The outputs being received by the component. + pub(super) stream: RecvStream<'static, C::Output>, + pub(super) shutdown_on_drop: ShutdownOnDrop, +} + +impl Stream for ComponentStream { + type Item = C::Output; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let stream = &mut self.stream; + pin_mut!(stream); + stream.poll_next(cx) + } +} + +impl ComponentStream { + /// Receive one message and drop the component afterwards. + /// This can be used for dialogs. + pub async fn recv_one(mut self) -> Option { + self.stream.next().await + } +} + +impl ComponentStream { + /// Dropping this type will usually stop the runtime of the worker. + /// With this method you can give the runtime a static lifetime. + /// In other words, dropping the controller or connector will not stop + /// the runtime anymore, instead it will run until the app is closed. + pub fn detach_runtime(&mut self) { + self.shutdown_on_drop.deactivate(); + } +} + +impl Debug for ComponentStream { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ComponentStream") + .field("stream", &"") + .finish() + } +} + +#[cfg(test)] +mod test { + use std::rc::Rc; + + use crate::{Component, ComponentParts, SimpleComponent}; + + fn assert_send(_stream: T) {} + + struct Test(Rc<()>); + + impl SimpleComponent for Test { + type Input = (); + type Output = (); + type Init = (); + type Root = Rc<()>; + type Widgets = Rc<()>; + + fn init_root() -> Self::Root { + Rc::default() + } + + fn init( + _init: Self::Init, + _root: &Self::Root, + _sender: crate::ComponentSender, + ) -> ComponentParts { + ComponentParts { + model: Test(Rc::default()), + widgets: Rc::default(), + } + } + } + + #[gtk::test] + fn stream_is_send() { + let stream = Test::builder().launch(()).into_stream(); + assert_send(stream); + } +} diff --git a/Relm4-0.6.2/relm4/src/component/sync/traits.rs b/Relm4-0.6.2/relm4/src/component/sync/traits.rs new file mode 100644 index 0000000..6aec238 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/sync/traits.rs @@ -0,0 +1,237 @@ +// Copyright 2021-2022 Aaron Erhardt +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use std::fmt::Debug; + +use crate::{ComponentBuilder, ComponentParts, ComponentSender, Sender}; + +/// The fundamental building block of a Relm4 application. +/// +/// A `Component` is an element of an application that defines initialization, state, behavior and +/// communication as a modular unit. +/// +/// `Component` is powerful and flexible, but for many use-cases the [`SimpleComponent`] +/// convenience trait will suffice. [`SimpleComponent`] enforces separation between model and view +/// updates, and provides no-op implementations for advanced features that are not relevant for most +/// use-cases. +pub trait Component: Sized + 'static { + /// Messages which are received from commands executing in the background. + type CommandOutput: Debug + Send + 'static; + + /// The message type that the component accepts as inputs. + type Input: Debug + 'static; + + /// The message type that the component provides as outputs. + type Output: Debug + 'static; + + /// The parameter used to initialize the component. + type Init; + + /// The top-level widget of the component. + type Root: Debug + Clone; + + /// The type that's used for storing widgets created for this component. + type Widgets: 'static; + + /// Create a builder for this component. + #[must_use] + fn builder() -> ComponentBuilder { + ComponentBuilder::::default() + } + + /// Initializes the root widget. + fn init_root() -> Self::Root; + + /// Creates the initial model and view, docking it into the component. + fn init( + init: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts; + + /// Processes inputs received by the component. + #[allow(unused)] + fn update(&mut self, message: Self::Input, sender: ComponentSender, root: &Self::Root) {} + + /// Defines how the component should respond to command updates. + #[allow(unused)] + fn update_cmd( + &mut self, + message: Self::CommandOutput, + sender: ComponentSender, + root: &Self::Root, + ) { + } + + /// Updates the model and view upon completion of a command. + /// + /// Overriding this method is helpful if you need access to the widgets while processing a + /// command output. + /// + /// The default implementation of this method calls [`update_cmd`] followed by [`update_view`]. + /// If you override this method while using the [`component`] macro, you must remember to call + /// [`update_view`] in your implementation. Otherwise, the view will not reflect the updated + /// model. + /// + /// [`update_cmd`]: Self::update_cmd + /// [`update_view`]: Self::update_view + /// [`component`]: relm4_macros::component + fn update_cmd_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::CommandOutput, + sender: ComponentSender, + root: &Self::Root, + ) { + self.update_cmd(message, sender.clone(), root); + self.update_view(widgets, sender); + } + + /// Updates the view after the model has been updated. + #[allow(unused)] + fn update_view(&self, widgets: &mut Self::Widgets, sender: ComponentSender) {} + + /// Updates the model and view when a new input is received. + /// + /// Overriding this method is helpful if you need access to the widgets while processing an + /// input. + /// + /// The default implementation of this method calls [`update`] followed by [`update_view`]. If + /// you override this method while using the [`component`] macro, you must remember to + /// call [`update_view`] in your implementation. Otherwise, the view will not reflect the + /// updated model. + /// + /// [`update`]: Self::update + /// [`update_view`]: Self::update_view + /// [`component`]: relm4_macros::component + fn update_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::Input, + sender: ComponentSender, + root: &Self::Root, + ) { + self.update(message, sender.clone(), root); + self.update_view(widgets, sender); + } + + /// Last method called before a component is shut down. + /// + /// This method is guaranteed to be called even when the entire application is shut down. + #[allow(unused)] + fn shutdown(&mut self, widgets: &mut Self::Widgets, output: Sender) {} + + /// An identifier for the component used for debug logging. + /// + /// The default implementation of this method uses the address of the component, but + /// implementations are free to provide more meaningful identifiers. + fn id(&self) -> String { + format!("{:p}", &self) + } +} + +/// Elm-style variant of a [`Component`] with view updates separated from input updates. +pub trait SimpleComponent: Sized + 'static { + /// The message type that the component accepts as inputs. + type Input: Debug + 'static; + + /// The message type that the component provides as outputs. + type Output: Debug + 'static; + + /// The parameter used to initialize the component. + type Init; + + /// The top-level widget of the component. + type Root: Debug + Clone; + + /// The type that's used for storing widgets created for this component. + type Widgets: 'static; + + /// Initializes the root widget + fn init_root() -> Self::Root; + + /// Creates the initial model and view, docking it into the component. + fn init( + init: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts; + + /// Processes inputs received by the component. + #[allow(unused)] + fn update(&mut self, message: Self::Input, sender: ComponentSender) {} + + /// Defines how the component should respond to command updates. + #[allow(unused)] + fn update_cmd(&mut self, input: &Sender, output: Sender) {} + + /// Updates the view after the model has been updated. + #[allow(unused)] + fn update_view(&self, widgets: &mut Self::Widgets, sender: ComponentSender) {} + + /// Last method called before a component is shut down. + /// + /// This method is guaranteed to be called even when the entire application is shut down. + #[allow(unused)] + fn shutdown(&mut self, widgets: &mut Self::Widgets, output: Sender) {} +} + +impl Component for C +where + C: SimpleComponent, +{ + type Init = C::Init; + type Input = C::Input; + type Output = C::Output; + type Root = C::Root; + type Widgets = C::Widgets; + + type CommandOutput = (); + + fn init_root() -> Self::Root { + C::init_root() + } + + fn init( + init: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + C::init(init, root, sender) + } + + fn update(&mut self, message: Self::Input, sender: ComponentSender, _root: &Self::Root) { + C::update(self, message, sender); + } + + fn update_view(&self, widgets: &mut Self::Widgets, sender: ComponentSender) { + C::update_view(self, widgets, sender); + } + + fn shutdown(&mut self, widgets: &mut Self::Widgets, output: Sender) { + self.shutdown(widgets, output); + } +} + +/// An empty, non-interactive component as a placeholder for tests. +impl SimpleComponent for () { + type Input = (); + type Output = (); + type Init = (); + type Root = (); + type Widgets = (); + + fn init_root() -> Self::Root {} + + fn init( + _init: Self::Init, + _root: &Self::Root, + _sender: ComponentSender, + ) -> ComponentParts { + ComponentParts { + model: (), + widgets: (), + } + } +} diff --git a/Relm4-0.6.2/relm4/src/component/worker.rs b/Relm4-0.6.2/relm4/src/component/worker.rs new file mode 100644 index 0000000..24e081e --- /dev/null +++ b/Relm4-0.6.2/relm4/src/component/worker.rs @@ -0,0 +1,282 @@ +// Copyright 2021-2022 Aaron Erhardt +// Copyright 2022 System76 +// SPDX-License-Identifier: MIT or Apache-2.0 + +use gtk::glib; +use tracing::info_span; + +use crate::{ + Component, ComponentBuilder, ComponentParts, ComponentSender, GuardedReceiver, Receiver, + RuntimeSenders, Sender, ShutdownOnDrop, SimpleComponent, +}; +use std::fmt::Debug; +use std::{any, thread}; + +/// Receives inputs and outputs in the background. +/// +/// All types that implement [`Worker`] will also implement +/// [`Component`] automatically. +/// +/// If you need more flexibility when using workers, you can +/// simply implement [`Component`] instead and set the [`Component::Widgets`] +/// and [`Component::Root`] types both to `()`. +/// This will still allow you to use all worker related methods because internally +/// a worker is just seen as a [`Component`] without widgets. +pub trait Worker: Sized + Send + 'static { + /// The initial parameters that will be used to build the worker state. + type Init: 'static + Send; + /// The type of inputs that this worker shall receive. + type Input: 'static + Send + Debug; + /// The type of outputs that this worker shall send. + type Output: 'static + Send + Debug; + + /// Defines the initial state of the worker. + fn init(init: Self::Init, sender: ComponentSender) -> Self; + + /// Defines how inputs will bep processed + fn update(&mut self, message: Self::Input, sender: ComponentSender); +} + +impl SimpleComponent for T +where + T: Worker + 'static, +{ + type Root = (); + type Widgets = (); + + type Init = ::Init; + type Input = ::Input; + type Output = ::Output; + + fn init_root() -> Self::Root {} + + fn init( + init: Self::Init, + _root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = Self::init(init, sender); + ComponentParts { model, widgets: () } + } + + fn update(&mut self, message: Self::Input, sender: ComponentSender) { + Self::update(self, message, sender); + } +} + +impl ComponentBuilder +where + C: Component + Send, + C::Input: Send, + C::Output: Send, + C::CommandOutput: Send, +{ + /// Starts a worker on a separate thread, + /// passing ownership to a future attached to a [gtk::glib::MainContext]. + pub fn detach_worker(self, payload: C::Init) -> WorkerHandle { + let Self { root, .. } = self; + + // Used for all events to be processed by this component's internal service. + let (input_sender, input_receiver) = crate::channel::(); + + let RuntimeSenders { + output_sender, + output_receiver, + cmd_sender, + cmd_receiver, + shutdown_notifier, + shutdown_recipient, + shutdown_on_drop, + mut shutdown_event, + } = RuntimeSenders::::new(); + + // Encapsulates the senders used by component methods. + let component_sender = ComponentSender::new( + input_sender.clone(), + output_sender.clone(), + cmd_sender, + shutdown_recipient, + ); + + let mut state = C::init(payload, &root, component_sender.clone()); + + thread::spawn(move || { + let context = glib::MainContext::thread_default().unwrap_or_default(); + + // Spawns the component's service. It will receive both `Self::Input` and + // `Self::CommandOutput` messages. It will spawn commands as requested by + // updates, and send `Self::Output` messages externally. + context.block_on(async move { + let mut cmd = GuardedReceiver::new(cmd_receiver); + let mut input = GuardedReceiver::new(input_receiver); + + loop { + futures::select!( + // Performs the model update, checking if the update requested a command. + // Runs that command asynchronously in the background using tokio. + message = input => { + let ComponentParts { + model, + widgets, + } = &mut state; + + let span = info_span!( + "update_with_view", + input=?message, + component=any::type_name::(), + id=model.id(), + ); + let _enter = span.enter(); + + model.update_with_view(widgets, message, component_sender.clone(), &root); + } + + // Handles responses from a command. + message = cmd => { + let ComponentParts { + model, + widgets, + } = &mut state; + + let span = info_span!( + "update_cmd_with_view", + cmd_output=?message, + component=any::type_name::(), + id=model.id(), + ); + let _enter = span.enter(); + + model.update_cmd_with_view(widgets, message, component_sender.clone(), &root); + }, + + // Triggered when the component is destroyed + _ = shutdown_event => { + let ComponentParts { + model, + widgets, + } = &mut state; + + model.shutdown(widgets, output_sender); + + shutdown_notifier.shutdown(); + + return; + } + ); + } + }); + }); + + // Give back a type for controlling the component service. + WorkerHandle { + sender: input_sender, + receiver: output_receiver, + shutdown_on_drop, + } + } +} + +#[derive(Debug)] +/// Handle to a worker task in the background +pub struct WorkerHandle { + // Sends inputs to the worker. + sender: Sender, + // Where the worker will send its outputs to. + receiver: Receiver, + // Shutdown the worker when this is dropped + shutdown_on_drop: ShutdownOnDrop, +} + +impl WorkerHandle +where + W::Input: 'static, + W::Output: 'static, +{ + /// Given a mutable closure, captures the receiver for handling. + pub fn connect_receiver, W::Output) + 'static>( + self, + mut func: F, + ) -> WorkerController { + let Self { + sender, + receiver, + shutdown_on_drop, + } = self; + + let mut sender_ = sender.clone(); + crate::spawn_local(async move { + while let Some(event) = receiver.recv().await { + func(&mut sender_, event); + } + }); + + WorkerController { + sender, + shutdown_on_drop, + } + } + + /// Forwards output events to the designated sender. + pub fn forward X) + 'static>( + self, + sender: &Sender, + transform: F, + ) -> WorkerController { + let Self { + sender: own_sender, + receiver, + shutdown_on_drop, + } = self; + + crate::spawn_local(receiver.forward(sender.clone(), transform)); + WorkerController { + sender: own_sender, + shutdown_on_drop, + } + } + + /// Ignore outputs from the component and take the handle. + #[must_use] + pub fn detach(self) -> WorkerController { + let Self { + sender, + shutdown_on_drop, + .. + } = self; + + WorkerController { + sender, + shutdown_on_drop, + } + } +} + +/// Sends inputs to a worker. On drop, shuts down the worker. +#[derive(Debug)] +pub struct WorkerController { + // Sends inputs to the worker. + sender: Sender, + // Shutdown the worker when this is dropped + shutdown_on_drop: ShutdownOnDrop, +} + +impl WorkerController { + /// Emits an input to the component. + pub fn emit(&self, event: W::Input) { + self.sender.send(event).unwrap(); + } + + /// Provides access to the component's sender. + #[must_use] + pub const fn sender(&self) -> &Sender { + &self.sender + } + + /// Dropping this type will usually stop the runtime of the worker. + /// With this method you can give the runtime a static lifetime. + /// In other words, dropping the [`WorkerController`] will not stop + /// the runtime anymore, it will run until the app is closed. + pub fn detach_runtime(&mut self) { + self.shutdown_on_drop.deactivate(); + } +} diff --git a/Relm4-0.6.2/relm4/src/drawing.rs b/Relm4-0.6.2/relm4/src/drawing.rs new file mode 100644 index 0000000..f938db4 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/drawing.rs @@ -0,0 +1,160 @@ +//! Utility to help drawing on a [`gtk::DrawingArea`] in a Relm4 application. +//! Create a [`DrawHandler`], initialize it, and get its context when handling a message (that could be +//! sent from the draw signal). + +// TODO: check if clip has the intended behavior. + +use std::cell::RefCell; +use std::ops::Deref; +use std::rc::Rc; + +use gtk::cairo::{Context, Format, ImageSurface}; +use gtk::prelude::{DrawingAreaExtManual, WidgetExt}; + +#[derive(Clone, Debug)] +struct Surface { + surface: Rc>, +} + +impl Surface { + fn new(surface: ImageSurface) -> Self { + Self { + surface: Rc::new(RefCell::new(surface)), + } + } + + fn get(&self) -> ImageSurface { + self.surface.borrow().clone() + } + + fn set(&self, surface: &ImageSurface) { + *self.surface.borrow_mut() = surface.clone(); + } +} + +#[derive(Debug)] +/// Context returned by [`DrawHandler`] that stores a [`Context`] along +/// with additional data required for drawing. +pub struct DrawContext { + context: Context, + draw_surface: Surface, + edit_surface: ImageSurface, + drawing_area: gtk::DrawingArea, +} + +impl DrawContext { + fn new( + draw_surface: &Surface, + edit_surface: &ImageSurface, + drawing_area: >k::DrawingArea, + ) -> Self { + Self { + context: Context::new(edit_surface).unwrap(), + draw_surface: draw_surface.clone(), + edit_surface: edit_surface.clone(), + drawing_area: drawing_area.clone(), + } + } +} + +impl Deref for DrawContext { + type Target = Context; + + fn deref(&self) -> &Self::Target { + &self.context + } +} + +impl Drop for DrawContext { + fn drop(&mut self) { + self.draw_surface.set(&self.edit_surface); + self.drawing_area.queue_draw(); + } +} + +/// Manager for drawing operations. +#[derive(Debug)] +#[must_use] +pub struct DrawHandler { + draw_surface: Surface, + edit_surface: ImageSurface, + drawing_area: gtk::DrawingArea, +} + +impl Default for DrawHandler { + fn default() -> Self { + Self::new() + } +} + +impl DrawHandler { + /// Create a new [`DrawHandler`]. + pub fn new() -> Self { + Self::new_with_drawing_area(gtk::DrawingArea::default()) + } + + /// Create a new [`DrawHandler`] with an existing [`gtk::DrawingArea`]. + pub fn new_with_drawing_area(drawing_area: gtk::DrawingArea) -> Self { + let draw_surface = Surface::new(ImageSurface::create(Format::ARgb32, 100, 100).unwrap()); + let edit_surface = ImageSurface::create(Format::ARgb32, 100, 100).unwrap(); + + use gtk::glib; + drawing_area.set_draw_func( + glib::clone!(@strong draw_surface => move |_, context, _, _| { + // TODO: only copy the area that was exposed? + if let Err(error) = context.set_source_surface(&draw_surface.get(), 0.0, 0.0) { + tracing::error!("Cannot set source surface: {:?}", error); + } + + if let Err(error) = context.paint() { + tracing::error!("Cannot paint: {:?}", error); + } + }), + ); + + Self { + draw_surface, + edit_surface, + drawing_area, + } + } + + /// Get the drawing context to draw on a [`gtk::DrawingArea`]. + /// If the size of the [`gtk::DrawingArea`] changed, the contents of the + /// surface will be replaced by a new, empty surface. + pub fn get_context(&mut self) -> DrawContext { + let allocation = self.drawing_area.allocation(); + let scale = self.drawing_area.scale_factor(); + let width = allocation.width() * scale; + let height = allocation.height() * scale; + + if (width, height) != (self.edit_surface.width(), self.edit_surface.height()) { + match ImageSurface::create(Format::ARgb32, width, height) { + Ok(surface) => { + surface.set_device_scale(f64::from(scale), f64::from(scale)); + self.edit_surface = surface; + } + Err(error) => tracing::error!("Cannot resize image surface: {:?}", error), + } + } + DrawContext::new(&self.draw_surface, &self.edit_surface, &self.drawing_area) + } + + /// Get the height of the [`DrawHandler`]. + #[must_use] + pub fn height(&self) -> i32 { + self.edit_surface.height() + } + + /// Get the width of the [`DrawHandler`]. + #[must_use] + pub fn width(&self) -> i32 { + self.edit_surface.width() + } + + /// Get the [`gtk::DrawingArea`] of the [`DrawHandler`]. + #[must_use] + pub fn drawing_area(&self) -> >k::DrawingArea { + &self.drawing_area + } +} diff --git a/Relm4-0.6.2/relm4/src/extensions/container.rs b/Relm4-0.6.2/relm4/src/extensions/container.rs new file mode 100644 index 0000000..6653d3b --- /dev/null +++ b/Relm4-0.6.2/relm4/src/extensions/container.rs @@ -0,0 +1,70 @@ +use gtk::prelude::*; + +use crate::RelmSetChildExt; + +/// Widget types which can have widgets attached to them. +pub trait RelmContainerExt { + /// Add widget as child to container. + fn container_add(&self, widget: &impl AsRef); +} + +impl RelmContainerExt for T { + fn container_add(&self, widget: &impl AsRef) { + self.container_set_child(Some(widget)); + } +} + +#[allow(deprecated)] +impl RelmContainerExt for gtk::Dialog { + fn container_add(&self, widget: &impl AsRef) { + self.content_area().append(widget.as_ref()); + } +} + +macro_rules! append_impl { + ($($type:ty),+) => { + $( + impl RelmContainerExt for $type { + fn container_add(&self, widget: &impl AsRef) { + self.append(widget.as_ref()); + } + } + )+ + } +} + +macro_rules! add_child_impl { + ($($type:ty),+) => { + $( + #[allow(deprecated)] + impl RelmContainerExt for $type { + fn container_add(&self, widget: &impl AsRef) { + self.add_child(widget.as_ref()); + } + } + )+ + } +} + +append_impl!(gtk::Box, gtk::ListBox); +add_child_impl!(gtk::InfoBar, gtk::Stack); + +#[cfg(feature = "libadwaita")] +#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))] +mod libadwaita { + use super::RelmContainerExt; + append_impl!(adw::Leaflet, adw::Carousel, adw::TabView); + + impl RelmContainerExt for adw::PreferencesGroup { + fn container_add(&self, widget: &impl AsRef) { + use adw::prelude::PreferencesGroupExt; + self.add(widget.as_ref()); + } + } + + impl RelmContainerExt for adw::Squeezer { + fn container_add(&self, widget: &impl AsRef) { + self.add(widget.as_ref()); + } + } +} diff --git a/Relm4-0.6.2/relm4/src/extensions/iter_children.rs b/Relm4-0.6.2/relm4/src/extensions/iter_children.rs new file mode 100644 index 0000000..765a690 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/extensions/iter_children.rs @@ -0,0 +1,144 @@ +use super::ContainerChild; +use crate::gtk; +use gtk::prelude::{Cast, GridExt, IsA, WidgetExt}; + +/// An iterator over container children. +#[derive(Debug)] +struct ChildrenIterator { + start: Option, + end: Option, + done: bool, +} + +impl ChildrenIterator { + /// Create a new iterator over children of `widget`. + fn new(widget: &T) -> Self { + let start = widget.first_child().map(|child| { + child + .downcast::() + .expect("The type of children does not match.") + }); + let end = widget.last_child().map(|child| { + child + .downcast::() + .expect("The type of children does not match.") + }); + let done = start.is_none(); + Self { start, end, done } + } +} + +impl Iterator for ChildrenIterator { + type Item = T::Child; + fn next(&mut self) -> Option { + if self.done { + None + } else { + // Handle cases where only one child exists and + // when all but one widget were consumed + if self.start == self.end { + self.done = true; + self.start.clone() + } else if let Some(start) = self.start.take() { + // "Increment" the start child + self.start = start.next_sibling().map(|child| { + child + .downcast::() + .expect("The type of children does not match.") + }); + // Just to make sure the iterator ends next time + // because all widgets were consumed + self.done = self.start.is_none(); + Some(start) + } else { + None + } + } + } +} + +impl DoubleEndedIterator for ChildrenIterator { + fn next_back(&mut self) -> Option { + if self.done { + None + } else { + // Handle cases where only one child exists and + // when all but one widget were consumed + if self.start == self.end { + self.done = true; + self.end.clone() + } else if let Some(end) = self.end.take() { + // "Decrement" the end child + self.end = end.prev_sibling().map(|child| { + child + .downcast::() + .expect("The type of children does not match.") + }); + // Just to make sure the iterator ends next time + // because all widgets were consumed + self.done = self.end.is_none(); + Some(end) + } else { + None + } + } + } +} + +/// Widget types which allow iteration over their children. +pub trait RelmIterChildrenExt: ContainerChild + IsA { + /// Returns an iterator over container children. + fn iter_children(&self) -> Box> { + Box::new(ChildrenIterator::new(self)) + } +} + +impl RelmIterChildrenExt for gtk::Box {} +impl RelmIterChildrenExt for gtk::ListBox {} +impl RelmIterChildrenExt for gtk::FlowBox {} +impl RelmIterChildrenExt for gtk::Grid { + // `gtk::Grid` places children in the order they were added to the grid. + // + // We have to provide a separate implementation that would sort children + // depending on their position. + fn iter_children(&self) -> Box> { + let mut vec = Vec::new(); + let mut widget = self.first_child(); + while let Some(child) = widget { + widget = child.next_sibling(); + let (column, row, _, _) = self.query_child(&child); + vec.push((column, row, child)); + } + + vec.sort_by(|(col_a, row_a, _), (col_b, row_b, _)| { + if row_a == row_b { + col_a.cmp(col_b) + } else { + row_a.cmp(row_b) + } + }); + + Box::new(vec.into_iter().map(|(_, _, child)| child)) + } +} +impl RelmIterChildrenExt for gtk::Stack {} + +#[cfg(feature = "libadwaita")] +#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))] +mod libadwaita { + use super::RelmIterChildrenExt; + use crate::gtk; + use gtk::prelude::{Cast, ListModelExt}; + + impl RelmIterChildrenExt for adw::TabView { + fn iter_children(&self) -> Box> { + let pages = self.pages(); + Box::new( + (0..pages.n_items()) + .filter_map(move |index| pages.item(index)) + .filter_map(|item| item.downcast::().ok()) + .map(|page| page.child()), + ) + } + } +} diff --git a/Relm4-0.6.2/relm4/src/extensions/mod.rs b/Relm4-0.6.2/relm4/src/extensions/mod.rs new file mode 100644 index 0000000..852ddc8 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/extensions/mod.rs @@ -0,0 +1,200 @@ +mod container; +mod iter_children; +mod object_ext; +mod remove; +mod set_child; + +#[cfg(test)] +mod tests; +mod widget_ext; + +pub use container::RelmContainerExt; +pub use iter_children::RelmIterChildrenExt; +pub use object_ext::RelmObjectExt; +pub use remove::{RelmRemoveAllExt, RelmRemoveExt}; +pub use set_child::RelmSetChildExt; +pub use widget_ext::RelmWidgetExt; + +use gtk::prelude::{ + ApplicationExt, ApplicationExtManual, Cast, IsA, ListBoxRowExt, StaticType, WidgetExt, +}; + +/// Get a reference to a widget. +/// +/// This trait is an extension of [`AsRef`] +/// that always returns `&`[`gtk::Widget`]. +pub trait WidgetRef { + /// Returns a reference to a widget. + /// + /// Like [`AsRef::as_ref`] it will auto-dereference. + fn widget_ref(&self) -> >k::Widget; +} + +impl> WidgetRef for T { + fn widget_ref(&self) -> >k::Widget { + self.as_ref() + } +} + +/// A trait that describes a widget template. +/// +/// Widget templates can be created manually by implementing this trait +/// or by using the [`widget_template`](crate::widget_template) macro. +pub trait WidgetTemplate: Sized + std::fmt::Debug + std::ops::Deref { + /// The root of the template. + type Root; + + /// Initializes the template. + fn init() -> Self; +} + +/// Additional methods for `gtk::builders::ApplicationBuilder` +pub trait ApplicationBuilderExt { + /// Convenience method for launching an application and initializing the window. + fn launch(self, init: F) + where + F: Fn(gtk::Application, gtk::ApplicationWindow) + 'static; +} + +impl ApplicationBuilderExt for gtk::builders::ApplicationBuilder { + fn launch(self, init: F) + where + F: Fn(gtk::Application, gtk::ApplicationWindow) + 'static, + { + let app = self.build(); + + app.connect_activate(move |app| { + let window = gtk::ApplicationWindow::new(app); + + init(app.clone(), window.clone()); + + window.set_visible(true); + }); + + app.run(); + } +} + +/// Additional methods for `gtk::ListBox`. +pub trait RelmListBoxExt { + /// Get the index of a widget attached to a listbox. + fn index_of_child(&self, widget: &impl AsRef) -> Option; + + /// Remove the row of a child attached a listbox. + fn remove_row_of_child(&self, widget: &impl AsRef); + + /// Get the row of a widget attached to a listbox. + fn row_of_child(&self, widget: &impl AsRef) -> Option; +} + +impl RelmListBoxExt for gtk::ListBox { + fn index_of_child(&self, widget: &impl AsRef) -> Option { + self.row_of_child(widget).map(|row| row.index()) + } + + fn remove_row_of_child(&self, widget: &impl AsRef) { + if let Some(row) = self.row_of_child(widget) { + row.set_child(None::<>k::Widget>); + self.remove(&row); + } + } + + fn row_of_child(&self, widget: &impl AsRef) -> Option { + if let Some(row) = widget.as_ref().ancestor(gtk::ListBoxRow::static_type()) { + if let Some(row) = row.downcast_ref::() { + if let Some(parent_widget) = row.parent() { + if let Some(parent_box) = parent_widget.downcast_ref::() { + if parent_box == self { + return Some(row.clone()); + } + } + } + } + } + + None + } +} + +/// Type of children inside a container. +/// +/// For example, `gtk::ListBox` only contains `gtk::ListBoxRow` widgets +/// as children. If you add any other kind of widget, a row is automatically +/// inserted between the list box and the widget. +/// +/// For simple widgets like `gtk::Box`, the children type will be `gtk::Widget`, +/// meaning that it can be any widget type. +pub trait ContainerChild { + /// Type of container children. + type Child: IsA; +} + +macro_rules! container_child_impl { + ($($type:ty: $child:ty), +) => { + $( + impl ContainerChild for $type { + type Child = $child; + } + )+ + }; + ($($type:ty), +) => { + $( + #[allow(deprecated)] + impl ContainerChild for $type { + type Child = gtk::Widget; + } + )+ + }; +} + +container_child_impl! { + gtk::Box, + gtk::Fixed, + gtk::Grid, + gtk::ActionBar, + gtk::Stack, + gtk::HeaderBar, + gtk::InfoBar, + gtk::Button, + gtk::ComboBox, + gtk::FlowBoxChild, + gtk::Frame, + gtk::Popover, + gtk::Window, + gtk::ApplicationWindow, + gtk::ListBoxRow, + gtk::ScrolledWindow, + gtk::Dialog, + gtk::LinkButton, + gtk::ToggleButton, + gtk::Overlay, + gtk::Revealer, + gtk::WindowHandle, + gtk::Expander, + gtk::AspectFrame +} + +container_child_impl! { + gtk::ListBox: gtk::ListBoxRow, + gtk::FlowBox: gtk::FlowBoxChild +} + +#[cfg(feature = "libadwaita")] +#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))] +mod libadwaita { + use super::ContainerChild; + + container_child_impl! { + adw::TabView, + adw::Window, + adw::Bin, + adw::ApplicationWindow, + adw::Clamp, + adw::ClampScrollable, + adw::SplitButton, + adw::StatusPage, + adw::PreferencesGroup, + adw::ToastOverlay, + adw::ExpanderRow + } +} diff --git a/Relm4-0.6.2/relm4/src/extensions/object_ext.rs b/Relm4-0.6.2/relm4/src/extensions/object_ext.rs new file mode 100644 index 0000000..d5dc404 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/extensions/object_ext.rs @@ -0,0 +1,47 @@ +use glib::prelude::ObjectExt; +use gtk::glib; + +use crate::binding::Binding; + +/// Trait that extends [`gtk::prelude::ObjectExt`]. +pub trait RelmObjectExt { + /// Runs the given function when the object is destroyed. + fn on_destroy(&self, func: F); + + /// Bind a data binding to a property of an object. + /// + /// This is similar to [`glib::ObjectExt::bind_property`] and + /// always bidirectional. + fn add_binding(&self, binding: &B, property_name: &str); + + /// Bind a data binding to a property of an object with + /// uni-directional access, so values can only be written but are not synced + /// in the other direction. + fn add_write_only_binding(&self, binding: &B, property_name: &str); +} + +impl> RelmObjectExt for T { + fn on_destroy(&self, func: F) { + let func = std::cell::RefCell::new(Some(func)); + self.as_ref().add_weak_ref_notify_local(move || { + if let Some(func) = func.take() { + func(); + } + }); + } + + fn add_binding(&self, binding: &B, property_name: &str) { + binding + .bind_property(B::property_name(), self, property_name) + .bidirectional() + .sync_create() + .build(); + } + + fn add_write_only_binding(&self, binding: &B, property_name: &str) { + binding + .bind_property(B::property_name(), self, property_name) + .sync_create() + .build(); + } +} diff --git a/Relm4-0.6.2/relm4/src/extensions/remove.rs b/Relm4-0.6.2/relm4/src/extensions/remove.rs new file mode 100644 index 0000000..eccf6dd --- /dev/null +++ b/Relm4-0.6.2/relm4/src/extensions/remove.rs @@ -0,0 +1,147 @@ +use crate::{ContainerChild, RelmSetChildExt}; +use gtk::prelude::*; + +/// Widget types which can have widgets removed from them. +pub trait RelmRemoveExt: ContainerChild { + /// Removes the widget from the container + /// if it is a child of the container. + fn container_remove(&self, child: &impl AsRef); +} + +impl RelmRemoveExt for T { + fn container_remove(&self, child: &impl AsRef) { + if let Some(current_child) = self.container_get_child() { + let remove_child = child.as_ref().upcast_ref(); + if remove_child == ¤t_child { + self.container_set_child(None::<>k::Widget>); + } + } + } +} + +impl RelmRemoveExt for gtk::ListBox { + fn container_remove(&self, widget: &impl AsRef) { + let row = widget.as_ref(); + row.set_child(None::<>k::Widget>); + self.remove(row); + } +} + +impl RelmRemoveExt for gtk::FlowBox { + fn container_remove(&self, widget: &impl AsRef) { + let child = widget.as_ref(); + child.set_child(None::<>k::Widget>); + self.remove(widget.as_ref()); + } +} + +#[cfg(feature = "libadwaita")] +#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))] +impl RelmRemoveExt for adw::PreferencesGroup { + fn container_remove(&self, widget: &impl AsRef) { + use adw::prelude::PreferencesGroupExt; + self.remove(widget.as_ref()); + } +} + +#[cfg(feature = "libadwaita")] +#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))] +impl RelmRemoveExt for adw::ExpanderRow { + fn container_remove(&self, widget: &impl AsRef) { + let child = widget.as_ref(); + self.remove(child); + } +} + +macro_rules! remove_impl { + ($($type:ty),+) => { + $( + impl RelmRemoveExt for $type { + fn container_remove(&self, widget: &impl AsRef) { + self.remove(widget.as_ref()); + } + } + )+ + } +} + +macro_rules! remove_child_impl { + ($($type:ty),+) => { + $( + #[allow(deprecated)] + impl RelmRemoveExt for $type { + fn container_remove(&self, widget: &impl AsRef) { + self.remove_child(widget.as_ref()); + } + } + )+ + } +} + +remove_impl!( + gtk::Box, + gtk::Fixed, + gtk::Grid, + gtk::ActionBar, + gtk::Stack, + gtk::HeaderBar +); +remove_child_impl!(gtk::InfoBar); + +/// Widget types that allow removal of all their children. +pub trait RelmRemoveAllExt { + /// Remove all children from the container. + fn remove_all(&self); +} + +impl RelmRemoveAllExt for T { + fn remove_all(&self) { + self.container_set_child(None::<>k::Widget>); + } +} + +macro_rules! remove_all_impl { + ($($type:ty),+) => { + $( + impl RelmRemoveAllExt for $type { + fn remove_all(&self) { + while let Some(child) = self.last_child() { + self.remove(&child); + } + } + } + )+ + } +} + +remove_all_impl!(gtk::Box, gtk::FlowBox, gtk::Stack, gtk::Grid); + +impl RelmRemoveAllExt for gtk::ListBox { + fn remove_all(&self) { + while let Some(child) = self.last_child() { + let row = child + .downcast::() + .expect("The child of `ListBox` is not a `ListBoxRow`."); + row.set_child(None::<>k::Widget>); + self.remove(&row); + } + } +} + +#[cfg(feature = "libadwaita")] +#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))] +use adw::traits::ExpanderRowExt; + +#[cfg(feature = "libadwaita")] +#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))] +impl RelmRemoveAllExt for adw::ExpanderRow { + fn remove_all(&self) { + while let Some(child) = self.last_child() { + let row = child + .downcast::() + .expect("The child of `ExpanderRow` is not a `ListBoxRow`."); + row.set_child(None::<>k::Widget>); + self.remove(&row); + } + } +} diff --git a/Relm4-0.6.2/relm4/src/extensions/set_child.rs b/Relm4-0.6.2/relm4/src/extensions/set_child.rs new file mode 100644 index 0000000..6396178 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/extensions/set_child.rs @@ -0,0 +1,79 @@ +use super::ContainerChild; +use gtk::prelude::*; + +/// Widget types which allow to set or unset their child. +pub trait RelmSetChildExt: ContainerChild { + /// Set a child for the container or remove it using [`None`]. + fn container_set_child(&self, widget: Option<&impl AsRef>); + + /// Get the child of a container. + /// Returns [`None`] if the container has no child. + fn container_get_child(&self) -> Option; +} + +macro_rules! set_child_impl { + ($($type:ty), +) => { + $( + impl RelmSetChildExt for $type { + fn container_set_child(&self, widget: Option<&impl AsRef>) { + self.set_child(widget.map(|w| w.as_ref())); + } + + fn container_get_child(&self) -> Option { + self.child() + } + } + )+ + } +} + +set_child_impl!( + gtk::Button, + gtk::LinkButton, + gtk::ToggleButton, + gtk::FlowBoxChild, + gtk::Frame, + gtk::ListBoxRow, + gtk::Popover, + gtk::Window, + gtk::ScrolledWindow, + gtk::ApplicationWindow, + gtk::Overlay, + gtk::Revealer, + gtk::WindowHandle, + gtk::Expander, + gtk::AspectFrame +); + +#[cfg(feature = "libadwaita")] +#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))] +mod libadwaita { + use super::RelmSetChildExt; + use adw::prelude::{AdwApplicationWindowExt, AdwWindowExt, BinExt}; + + macro_rules! set_child_content_impl { + ($($type:ty),+) => { + $( + impl RelmSetChildExt for $type { + fn container_set_child(&self, widget: Option<&impl AsRef>) { + self.set_content(widget.map(|w| w.as_ref())); + } + + fn container_get_child(&self) -> Option { + self.content() + } + } + )+ + } + } + + set_child_content_impl!(adw::Window, adw::ApplicationWindow); + set_child_impl!( + adw::Bin, + adw::Clamp, + adw::ClampScrollable, + adw::SplitButton, + adw::StatusPage, + adw::ToastOverlay + ); +} diff --git a/Relm4-0.6.2/relm4/src/extensions/tests.rs b/Relm4-0.6.2/relm4/src/extensions/tests.rs new file mode 100644 index 0000000..7d717d5 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/extensions/tests.rs @@ -0,0 +1,163 @@ +use crate::{gtk, RelmIterChildrenExt, RelmListBoxExt, RelmRemoveAllExt}; +use gtk::prelude::{BoxExt, GridExt, WidgetExt}; + +// A set of widgets for tests +#[derive(Default)] +struct TestWidgets(gtk::Label, gtk::Switch, gtk::Box); + +impl TestWidgets { + fn assert_parent(&self) { + assert!(self.0.parent().is_some()); + assert!(self.1.parent().is_some()); + assert!(self.2.parent().is_some()); + } +} + +// Returns whether two optional widgets are the same. +fn same_widgets( + first: Option>, + second: Option>, +) -> bool { + match (first, second) { + (Some(first), Some(second)) => first.as_ref() == second.as_ref(), + (None, None) => true, + _ => false, + } +} + +#[gtk::test] +fn box_extension_traits() { + let gtk_box = gtk::Box::default(); + let widgets = TestWidgets::default(); + + gtk_box.append(&widgets.1); + gtk_box.prepend(&widgets.0); + gtk_box.append(&widgets.2); + + widgets.assert_parent(); + + let mut children = gtk_box.iter_children(); + assert!(same_widgets(children.next(), Some(&widgets.0))); + assert!(same_widgets(children.next_back(), Some(&widgets.2))); + assert!(same_widgets(children.next(), Some(&widgets.1))); + assert_eq!(children.next(), None); + assert_eq!(children.next_back(), None); + + gtk_box.remove_all(); + + assert_eq!(gtk_box.iter_children().next(), None); +} + +#[gtk::test] +fn list_box_extension_traits() { + let list_box = gtk::ListBox::default(); + let widgets = TestWidgets::default(); + + list_box.append(&widgets.1); + list_box.prepend(&widgets.0); + list_box.append(&widgets.2); + + widgets.assert_parent(); + + assert_eq!(list_box.index_of_child(&widgets.0), Some(0)); + assert_eq!(list_box.index_of_child(&widgets.1), Some(1)); + assert_eq!(list_box.index_of_child(&widgets.2), Some(2)); + + let mut rows = list_box.iter_children(); + assert!(same_widgets(rows.next_back(), widgets.2.parent())); + assert!(same_widgets(rows.next(), widgets.0.parent())); + assert!(same_widgets(rows.next(), widgets.1.parent())); + assert_eq!(rows.next(), None); + assert_eq!(rows.next_back(), None); + + list_box.remove_all(); + + assert_eq!(list_box.iter_children().next(), None); + + list_box.append(&widgets.0); + list_box.append(&widgets.1); + list_box.append(&widgets.2); + + widgets.assert_parent(); + + list_box.remove_row_of_child(&widgets.0); + list_box.remove_row_of_child(&widgets.1); + list_box.remove_row_of_child(&widgets.2); + + assert_eq!(list_box.iter_children().next(), None); + + assert_eq!(list_box.index_of_child(&widgets.0), None); + assert_eq!(list_box.index_of_child(&widgets.1), None); + assert_eq!(list_box.index_of_child(&widgets.2), None); +} + +#[gtk::test] +fn flow_box_extension_traits() { + let flow_box = gtk::FlowBox::default(); + let widgets = TestWidgets::default(); + + flow_box.insert(&widgets.1, -1); + flow_box.insert(&widgets.0, 0); + flow_box.insert(&widgets.2, -1); + + widgets.assert_parent(); + + let mut flow_children = flow_box.iter_children(); + assert!(same_widgets(flow_children.next(), widgets.0.parent())); + assert!(same_widgets(flow_children.next(), widgets.1.parent())); + assert!(same_widgets(flow_children.next(), widgets.2.parent())); + assert_eq!(flow_children.next_back(), None); + assert_eq!(flow_children.next(), None); + + flow_box.remove_all(); + + assert_eq!(flow_box.iter_children().next(), None); +} + +#[gtk::test] +fn grid_extension_traits() { + let grid = gtk::Grid::default(); + let widgets = TestWidgets::default(); + + grid.attach(&widgets.0, 0, 0, 1, 1); + grid.attach(&widgets.2, 2, 2, 2, 2); + grid.attach(&widgets.1, 1, 0, 1, 1); + + widgets.assert_parent(); + + let mut children = grid.iter_children(); + assert!(same_widgets(children.next(), Some(&widgets.0))); + assert!(same_widgets(children.next(), Some(&widgets.1))); + assert!(same_widgets(children.next(), Some(&widgets.2))); + assert_eq!(children.next(), None); + assert_eq!(children.next_back(), None); + + grid.remove_all(); + + assert!(widgets.0.parent().is_none()); + assert!(widgets.1.parent().is_none()); + assert!(widgets.2.parent().is_none()); +} + +#[gtk::test] +fn stack_extension_traits() { + let stack = gtk::Stack::default(); + let widgets = TestWidgets::default(); + + stack.add_child(&widgets.0); + stack.add_child(&widgets.1); + stack.add_child(&widgets.2); + + widgets.assert_parent(); + + let mut children = stack.iter_children(); + assert!(same_widgets(children.next(), Some(&widgets.0))); + assert!(same_widgets(children.next(), Some(&widgets.1))); + assert!(same_widgets(children.next(), Some(&widgets.2))); + assert_eq!(children.next_back(), None); + assert_eq!(children.next(), None); + + stack.remove_all(); + + assert_eq!(stack.iter_children().next(), None); +} diff --git a/Relm4-0.6.2/relm4/src/extensions/widget_ext.rs b/Relm4-0.6.2/relm4/src/extensions/widget_ext.rs new file mode 100644 index 0000000..3631126 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/extensions/widget_ext.rs @@ -0,0 +1,97 @@ +use gtk::prelude::{Cast, StaticType, WidgetExt}; + +/// Trait that extends [`gtk::prelude::WidgetExt`]. +/// +/// This trait's main goal is to reduce redundant code and +/// to provide helpful methods for the widgets macro of relm4-macros. +pub trait RelmWidgetExt { + /// Attach widget to a `gtk::SizeGroup`. + fn set_size_group(&self, size_group: >k::SizeGroup); + + /// Locate the top level window this widget is attached to. + /// + /// Equivalent to `widget.ancestor(gtk::Window::static_type())`, then casting. + fn toplevel_window(&self) -> Option; + + /// Set margin at start, end, top and bottom all at once. + fn set_margin_all(&self, margin: i32) { + self.set_margin_horizontal(margin); + self.set_margin_vertical(margin); + } + + /// Set margin at top and bottom at once. + fn set_margin_vertical(&self, margin: i32); + + /// Set margin at start and end at once. + fn set_margin_horizontal(&self, margin: i32); + + /// Add class name if active is [`true`] and + /// remove class name if active is [`false`] + fn set_class_active(&self, class: &str, active: bool); + + /// Add inline CSS instructions to a widget. + /// ``` + /// # use relm4::RelmWidgetExt; + /// # gtk::init().unwrap(); + /// # let widget = gtk::Button::new(); + /// widget.inline_css("border: 1px solid red"); + /// ``` + fn inline_css(&self, style: &str); + + /// Sets the tooltip text of a widget and enables is. + /// + /// This is basically, the same as using [`WidgetExt::set_has_tooltip()`] + /// and [`WidgetExt::set_tooltip_text()`], but with fewer steps. + fn set_tooltip(&self, test: &str); +} + +impl> RelmWidgetExt for T { + fn set_size_group(&self, size_group: >k::SizeGroup) { + size_group.add_widget(self); + } + + fn toplevel_window(&self) -> Option { + self.ancestor(gtk::Window::static_type()) + .and_then(|widget| widget.dynamic_cast::().ok()) + } + + fn set_margin_vertical(&self, margin: i32) { + self.set_margin_top(margin); + self.set_margin_bottom(margin); + } + + fn set_margin_horizontal(&self, margin: i32) { + self.set_margin_start(margin); + self.set_margin_end(margin); + } + + fn set_class_active(&self, class: &str, active: bool) { + if active { + self.add_css_class(class); + } else { + self.remove_css_class(class); + } + } + + #[allow(deprecated)] + fn inline_css(&self, style: &str) { + use gtk::prelude::StyleContextExt; + + let context = self.style_context(); + let provider = gtk::CssProvider::new(); + + let data = if style.ends_with(';') { + ["*{", style, "}"].concat() + } else { + ["*{", style, ";}"].concat() + }; + + provider.load_from_data(&data); + context.add_provider(&provider, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION + 1); + } + + fn set_tooltip(&self, text: &str) { + self.set_has_tooltip(true); + self.set_tooltip_text(Some(text)); + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/async/builder.rs b/Relm4-0.6.2/relm4/src/factory/async/builder.rs new file mode 100644 index 0000000..93ba993 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/async/builder.rs @@ -0,0 +1,229 @@ +use std::any; + +use tracing::info_span; + +use super::future_data::AsyncData; +use super::{AsyncFactoryComponent, AsyncFactoryHandle}; + +use crate::channel::AsyncFactorySender; +use crate::factory::{DataGuard, DynamicIndex, FactoryView}; +use crate::runtime_util::GuardedReceiver; +use crate::shutdown::ShutdownSender; +use crate::{shutdown, Receiver, Sender}; + +pub(super) struct AsyncFactoryBuilder { + init: C::Init, + pub(super) root_widget: C::Root, + pub(super) component_sender: AsyncFactorySender, + input_receiver: Receiver, + output_receiver: Receiver, + cmd_receiver: Receiver, + shutdown_notifier: ShutdownSender, +} + +impl AsyncFactoryBuilder +where + ::ReturnedWidget: Clone, +{ + pub(super) fn new(init: C::Init) -> Self { + // Used for all events to be processed by this component's internal service. + let (input_sender, input_receiver) = crate::channel::(); + + // Used by this component to send events to be handled externally by the caller. + let (output_sender, output_receiver) = crate::channel::(); + + // Sends messages from commands executed from the background. + let (cmd_sender, cmd_receiver) = crate::channel::(); + + // Notifies the component's child commands that it is now deceased. + let (shutdown_notifier, shutdown_receiver) = shutdown::channel(); + + // Encapsulates the senders used by component methods. + let component_sender = + AsyncFactorySender::new(input_sender, output_sender, cmd_sender, shutdown_receiver); + + let root_widget = C::init_root(); + + Self { + init, + root_widget, + component_sender, + input_receiver, + output_receiver, + cmd_receiver, + shutdown_notifier, + } + } + + /// Starts the component, passing ownership to a future attached to a [gtk::glib::MainContext]. + pub(super) fn launch( + self, + index: &DynamicIndex, + returned_widget: ::ReturnedWidget, + parent_sender: &Sender, + transform: Transform, + ) -> AsyncFactoryHandle + where + Transform: Fn(C::Output) -> Option + 'static, + { + let Self { + mut root_widget, + component_sender, + input_receiver, + output_receiver, + cmd_receiver, + shutdown_notifier, + init, + } = self; + + let forward_sender = parent_sender.0.clone(); + crate::spawn_local(async move { + while let Some(msg) = output_receiver.recv().await { + if let Some(new_msg) = transform(msg) { + if forward_sender.send(new_msg).is_err() { + break; + } + } + } + }); + + // Gets notifications when a component's model and view is updated externally. + let (notifier, notifier_receiver) = crate::channel(); + + let input_sender = component_sender.input_sender().clone(); + + let loading_widgets = C::init_loading_widgets(&mut root_widget); + + let future_receiver = { + let index = index.clone(); + let (future_sender, future_receiver) = crate::channel(); + + let future_data = FutureData { + shutdown_notifier, + index: index.clone(), + component_sender: component_sender.clone(), + root: root_widget.clone(), + returned_widget: returned_widget.clone(), + input_receiver, + cmd_receiver, + notifier_receiver, + }; + + crate::spawn_local(async move { + let data = C::init_model(init, &index, component_sender).await; + drop(loading_widgets); + let data_guard = future_data.start_runtime(data); + future_sender.send(data_guard).unwrap(); + }); + future_receiver + }; + + let data = AsyncData::new(future_receiver); + + // Give back a type for controlling the component service. + AsyncFactoryHandle { + data, + root_widget, + returned_widget, + input: input_sender, + notifier, + } + } +} + +impl std::fmt::Debug for AsyncFactoryBuilder { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("AsyncFactoryBuilder") + .field("init", &"") + .field("root_widget", &self.root_widget) + .field("component_sender", &">") + .field("input_receiver", &self.input_receiver) + .field("output_receiver", &self.output_receiver) + .field("cmd_receiver", &self.cmd_receiver) + .field("shutdown_notifier", &self.shutdown_notifier) + .finish() + } +} + +struct FutureData { + shutdown_notifier: ShutdownSender, + index: DynamicIndex, + component_sender: AsyncFactorySender, + root: C::Root, + returned_widget: ::ReturnedWidget, + input_receiver: Receiver, + cmd_receiver: Receiver, + notifier_receiver: Receiver<()>, +} + +impl FutureData { + fn start_runtime(self, data: C) -> DataGuard { + let Self { + shutdown_notifier, + index, + component_sender, + root, + returned_widget, + cmd_receiver, + input_receiver, + notifier_receiver, + } = self; + + let mut data = Box::new(data); + let widgets = + Box::new(data.init_widgets(&index, &root, &returned_widget, component_sender.clone())); + + let output_sender = component_sender.output_sender().clone(); + + // Spawns the component's service. It will receive both `Self::Input` and + // `Self::CommandOutput` messages. It will spawn commands as requested by + // updates, and send `Self::Output` messages externally. + DataGuard::new( + data, + widgets, + shutdown_notifier, + output_sender, + |mut model, mut widgets| async move { + let mut notifier = GuardedReceiver::new(notifier_receiver); + let mut cmd = GuardedReceiver::new(cmd_receiver); + let mut input = GuardedReceiver::new(input_receiver); + loop { + futures::select!( + // Performs the model update, checking if the update requested a command. + // Runs that command asynchronously in the background using tokio. + message = input => { + let span = info_span!( + "update_with_view", + input=?message, + component=any::type_name::(), + id=model.id(), + ); + let _enter = span.enter(); + + model.update_with_view(&mut widgets, message, component_sender.clone()).await; + } + + // Handles responses from a command. + message = cmd => { + let span = info_span!( + "update_cmd_with_view", + cmd_output=?message, + component=any::type_name::(), + id=model.id(), + ); + let _enter = span.enter(); + + model.update_cmd_with_view(&mut widgets, message, component_sender.clone()).await; + } + + // Triggered when the model and view have been updated externally. + _ = notifier => { + model.update_view(&mut widgets, component_sender.clone()); + } + ); + } + }, + C::shutdown, + ) + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/async/collections/mod.rs b/Relm4-0.6.2/relm4/src/factory/async/collections/mod.rs new file mode 100644 index 0000000..e5ff67b --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/async/collections/mod.rs @@ -0,0 +1,20 @@ +//! Containers similar to [`std::collections`] that can be used to store factory data. + +mod vec_deque; +pub use vec_deque::{AsyncFactoryVecDeque, AsyncFactoryVecDequeGuard}; + +use crate::factory::DynamicIndex; + +#[derive(Debug)] +struct RenderedState { + uid: usize, + #[cfg(feature = "libadwaita")] + widget_hash: u64, +} + +#[derive(Debug)] +struct ModelStateValue { + index: DynamicIndex, + uid: usize, + changed: bool, +} diff --git a/Relm4-0.6.2/relm4/src/factory/async/collections/vec_deque.rs b/Relm4-0.6.2/relm4/src/factory/async/collections/vec_deque.rs new file mode 100644 index 0000000..63fa414 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/async/collections/vec_deque.rs @@ -0,0 +1,615 @@ +use crate::Sender; + +use crate::factory::r#async::component_storage::AsyncComponentStorage; +use crate::factory::r#async::traits::AsyncFactoryComponent; +use crate::factory::r#async::AsyncFactoryBuilder; +use crate::factory::{DynamicIndex, FactoryView}; + +use super::{ModelStateValue, RenderedState}; + +use std::collections::hash_map::DefaultHasher; +use std::collections::VecDeque; +use std::hash::Hash; +use std::iter::FusedIterator; +use std::ops::Deref; + +#[cfg(feature = "libadwaita")] +use gtk::prelude::Cast; + +#[cfg(feature = "libadwaita")] +use std::hash::Hasher; + +/// Provides methods to edit the underlying [`AsyncFactoryVecDeque`]. +/// +/// The changes will be rendered on the widgets after the guard goes out of scope. +#[derive(Debug)] +#[must_use] +pub struct AsyncFactoryVecDequeGuard<'a, C: AsyncFactoryComponent> +where + ::ReturnedWidget: Clone, +{ + inner: &'a mut AsyncFactoryVecDeque, +} + +impl<'a, C: AsyncFactoryComponent> Drop for AsyncFactoryVecDequeGuard<'a, C> +where + ::ReturnedWidget: Clone, +{ + fn drop(&mut self) { + self.inner.render_changes(); + } +} + +impl<'a, C: AsyncFactoryComponent> AsyncFactoryVecDequeGuard<'a, C> +where + ::ReturnedWidget: Clone, +{ + fn new(inner: &'a mut AsyncFactoryVecDeque) -> Self { + #[allow(unused_mut)] + #[allow(clippy::let_and_return)] + let mut guard = AsyncFactoryVecDequeGuard { inner }; + + #[cfg(feature = "libadwaita")] + guard.apply_external_updates(); + + guard + } + + /// Drops the guard and renders all changes. + /// + /// Use this to transfer full ownership back to the [`AsyncFactoryVecDeque`]. + pub fn drop(self) { + drop(self); + } + + /// Apply external updates that happened between the last render. + /// + /// [`AsyncFactoryVecDeque`] should not be edited between calling [`Self::render_changes`] + /// and this method, as it might cause undefined behaviour. This shouldn't be possible + /// because the method is called in [`FactoryVecDequeGuard::new`]. + #[cfg(feature = "libadwaita")] + fn apply_external_updates(&mut self) { + if let Some(tab_view) = self.inner.widget().dynamic_cast_ref::() { + let length = tab_view.n_pages(); + let mut hash_values: Vec = Vec::with_capacity(usize::try_from(length).unwrap()); + + for i in 0..length { + let page = tab_view.nth_page(i); + let mut hasher = DefaultHasher::default(); + page.hash(&mut hasher); + hash_values.push(hasher.finish()); + } + + // Tab rearrangement + for (index, hash) in hash_values.iter().enumerate() { + if self + .inner + .rendered_state + .get(index) + .map(|state| state.widget_hash) + == Some(*hash) + { + let old_position = self + .inner + .rendered_state + .iter() + .position(|state| state.widget_hash == *hash) + .expect("A new widget was added"); + + let elem = self.inner.rendered_state.remove(old_position).unwrap(); + self.inner.rendered_state.insert(index, elem); + + self.move_to(old_position, index); + } + } + + // Closed tabs + let mut index = 0; + while index < self.inner.rendered_state.len() { + let hash = self.inner.rendered_state[index].widget_hash; + if hash_values.contains(&hash) { + index += 1; + } else { + self.inner.rendered_state.remove(index); + + self.remove(index); + } + } + } + } + + /// Tries to get a mutable reference to + /// the model of one element. + /// + /// Returns [`None`] if `index` is invalid or the async [`init_model()`] method + /// hasn't returned yet. + /// + /// [`init_model()`]: AsyncFactoryComponent::init_model + pub fn get_mut(&mut self, index: usize) -> Option<&mut C> { + // Mark as modified + if let Some(state) = self.inner.model_state.get_mut(index) { + state.changed = true; + } + self.inner + .components + .get_mut(index) + .and_then(AsyncComponentStorage::get_mut) + } + + /// Provides a mutable reference to the model of the back element. + /// + /// Returns [`None`] if the deque is empty or the async [`init_model()`] method + /// of the last element hasn't returned yet. + /// + /// [`init_model()`]: AsyncFactoryComponent::init_model + pub fn back_mut(&mut self) -> Option<&mut C> { + self.get_mut(self.len().wrapping_sub(1)) + } + + /// Provides a mutable reference to the model of the front element. + /// + /// Returns [`None`] if the deque is empty or the async [`init_model()`] method + /// of the first element hasn't returned yet. + /// + /// [`init_model()`]: AsyncFactoryComponent::init_model + pub fn front_mut(&mut self) -> Option<&mut C> { + self.get_mut(0) + } + + /// Removes the last element from the [`AsyncFactoryVecDeque`] and returns it, + /// or [`None`] if it is empty or the async [`init_model()`] method + /// of the element hasn't returned yet. + /// + /// [`init_model()`]: AsyncFactoryComponent::init_model + pub fn pop_back(&mut self) -> Option { + if self.is_empty() { + None + } else { + self.remove(self.len() - 1) + } + } + + /// Removes the first element from the [`AsyncFactoryVecDeque`] and returns it, + /// or [`None`] if it is empty or the async [`init_model()`] method + /// of the element hasn't returned yet. + /// + /// [`init_model()`]: AsyncFactoryComponent::init_model + pub fn pop_front(&mut self) -> Option { + self.remove(0) + } + + /// Removes and returns the element at index from the [`AsyncFactoryVecDeque`]. + /// or [`None`] if it is empty or the async [`init_model()`] method + /// of the element hasn't returned yet. + /// + /// Element at index 0 is the front of the queue. + /// + /// [`init_model()`]: AsyncFactoryComponent::init_model + pub fn remove(&mut self, index: usize) -> Option { + self.inner.model_state.remove(index); + let component = self.inner.components.remove(index); + + // Decrement the indexes of the following elements. + for states in self.inner.model_state.iter_mut().skip(index) { + states.index.decrement(); + } + + if let Some(comp) = &component { + if let Some(widget) = &comp.returned_widget() { + self.widget.factory_remove(widget); + } + } + + component.and_then(AsyncComponentStorage::extract) + } + + /// Appends an element at the end of the [`AsyncFactoryVecDeque`]. + pub fn push_back(&mut self, init: C::Init) -> DynamicIndex { + let index = self.len(); + self.insert(index, init) + } + + /// Prepends an element to the [`AsyncFactoryVecDeque`]. + pub fn push_front(&mut self, init: C::Init) -> DynamicIndex { + self.insert(0, init) + } + + /// Inserts an element at index within the [`AsyncFactoryVecDeque`], + /// shifting all elements with indices greater than or equal + /// to index towards the back. + /// + /// Element at index 0 is the front of the queue. + /// + /// # Panics + /// + /// Panics if index is greater than [`AsyncFactoryVecDeque`]’s length. + pub fn insert(&mut self, index: usize, init: C::Init) -> DynamicIndex { + let dyn_index = DynamicIndex::new(index); + + // Increment the indexes of the following elements. + for states in self.inner.model_state.iter_mut().skip(index) { + states.index.increment(); + } + + let builder = AsyncFactoryBuilder::new(init); + + self.inner + .components + .insert(index, AsyncComponentStorage::Builder(builder)); + self.inner.model_state.insert( + index, + ModelStateValue { + index: dyn_index.clone(), + uid: self.uid_counter, + changed: false, + }, + ); + self.inner.uid_counter += 1; + + dyn_index + } + + /// Swaps elements at indices `first` and `second`. + /// + /// `first` and `second` may be equal. + /// + /// Element at index 0 is the front of the queue. + /// + /// # Panics + /// + /// Panics if either index is out of bounds. + pub fn swap(&mut self, first: usize, second: usize) { + // Don't update anything if both are equal + if first != second { + self.inner.model_state.swap(first, second); + self.inner.components.swap(first, second); + + // Update indexes. + self.model_state[first].index.set_value(first); + self.model_state[second].index.set_value(second); + } + } + + /// Moves an element at index `current_position` to `target`, + /// shifting all elements between these positions. + /// + /// `current_position` and `target` may be equal. + /// + /// Element at index 0 is the front of the queue. + /// + /// # Panics + /// + /// Panics if either index is out of bounds. + pub fn move_to(&mut self, current_position: usize, target: usize) { + // Don't update anything if both are equal + if current_position != target { + let elem = self.inner.model_state.remove(current_position).unwrap(); + // Set new index + elem.index.set_value(target); + self.inner.model_state.insert(target, elem); + + let comp = self.inner.components.remove(current_position).unwrap(); + self.inner.components.insert(target, comp); + + // Update indexes. + if current_position > target { + // Move down -> shift elements in between up. + for state in self + .inner + .model_state + .iter_mut() + .skip(target + 1) + .take(current_position - target) + { + state.index.increment(); + } + } else { + // Move up -> shift elements in between down. + for state in self + .inner + .model_state + .iter_mut() + .skip(current_position) + .take(target - current_position) + { + state.index.decrement(); + } + } + } + } + + /// Moves an element at index `current_position` to the front, + /// shifting all elements between these positions. + /// + /// # Panics + /// + /// Panics if index is out of bounds. + pub fn move_front(&mut self, current_position: usize) { + self.move_to(current_position, 0); + } + + /// Moves an element at index `current_position` to the back, + /// shifting all elements between these positions. + /// + /// # Panics + /// + /// Panics if index is out of bounds. + pub fn move_back(&mut self, current_position: usize) { + self.move_to(current_position, self.len() - 1); + } + + /// Remove all components from the [`AsyncFactoryVecDeque`]. + pub fn clear(&mut self) { + self.inner.model_state.clear(); + + for component in self.inner.components.drain(..) { + // Remove all widgets + if let Some(widget) = component.returned_widget() { + self.inner.widget.factory_remove(widget); + } + + // Make sure the component is shutdown properly + component.extract(); + } + + self.inner.rendered_state.clear(); + + self.inner.uid_counter = 1; + } + + /// Returns an iterator over the components that returns mutable references. + /// + /// Each item will be [`Some`] if the async [`init_model()`] method + /// of the item returned and otherwise [`None`]. + /// + /// [`init_model()`]: AsyncFactoryComponent::init_model + pub fn iter_mut( + &mut self, + ) -> impl Iterator> + DoubleEndedIterator + ExactSizeIterator + FusedIterator + { + self.inner + .components + .iter_mut() + .zip(self.inner.model_state.iter_mut()) + .map(|(component, state)| { + state.changed = true; + component.get_mut() + }) + } +} + +impl<'a, C: AsyncFactoryComponent> Deref for AsyncFactoryVecDequeGuard<'a, C> +where + ::ReturnedWidget: Clone, +{ + type Target = AsyncFactoryVecDeque; + + fn deref(&self) -> &Self::Target { + self.inner + } +} + +/// A container similar to [`VecDeque`] that can be used to store +/// data associated with components that implement [`AsyncFactoryComponent`]. +/// +/// To access mutable methods of the factory, create a guard using [`Self::guard`]. +#[derive(Debug)] +pub struct AsyncFactoryVecDeque +where + ::ReturnedWidget: Clone, +{ + widget: C::ParentWidget, + parent_sender: Sender, + components: VecDeque>, + model_state: VecDeque, + rendered_state: VecDeque, + uid_counter: usize, +} + +impl Drop for AsyncFactoryVecDeque +where + ::ReturnedWidget: Clone, +{ + fn drop(&mut self) { + self.guard().clear(); + } +} + +impl AsyncFactoryVecDeque +where + ::ReturnedWidget: Clone, +{ + /// Creates a new [`AsyncFactoryVecDeque`]. + #[must_use] + pub fn new(widget: C::ParentWidget, parent_sender: &Sender) -> Self { + Self { + widget, + parent_sender: parent_sender.clone(), + components: VecDeque::new(), + model_state: VecDeque::new(), + rendered_state: VecDeque::new(), + // 0 is always an invalid uid + uid_counter: 1, + } + } + + /// Provides a [`AsyncFactoryVecDequeGuard`] that can be used to edit the factory. + /// + /// The changes will be rendered on the widgets after the guard goes out of scope. + pub fn guard(&mut self) -> AsyncFactoryVecDequeGuard<'_, C> { + AsyncFactoryVecDequeGuard::new(self) + } + + /// Updates the widgets according to the changes made to the factory. + /// All updates accumulate until this method is called and are handled + /// efficiently. + /// + /// For example, swapping two elements twice will only swap the data twice, + /// but won't cause any UI updates. + /// + /// Also, only modified elements will be updated. + fn render_changes(&mut self) { + let mut first_position_change_idx = None; + + let components = &mut self.components; + let rendered_state = &mut self.rendered_state; + for (index, state) in self.model_state.iter().enumerate() { + if state.uid == rendered_state.front().map(|r| r.uid).unwrap_or_default() { + // Remove item from previously rendered list + rendered_state.pop_front(); + + if state.changed { + // Update component + components[index].state_change_notify(); + } + } else if let Some(rendered_index) = + rendered_state.iter().position(|r| r.uid == state.uid) + { + if first_position_change_idx.is_none() { + first_position_change_idx = Some(index); + } + + // Remove item from previously rendered list + rendered_state.remove(rendered_index); + + // Detach and re-attach item + let widget = components[index].returned_widget().unwrap(); + if index == 0 { + self.widget.factory_move_start(widget); + } else { + let previous_widget = components[index - 1].returned_widget().unwrap(); + self.widget.factory_move_after(widget, previous_widget); + } + + if state.changed { + // Update component + components[index].state_change_notify(); + } + } else { + if first_position_change_idx.is_none() { + first_position_change_idx = Some(index); + } + + // The element doesn't exist yet + let insert_widget = components[index].widget(); + let position = C::position(index); + let returned_widget = if index == 0 { + self.widget.factory_prepend(insert_widget, &position) + } else { + let previous_widget = components[index - 1].returned_widget().unwrap(); + self.widget + .factory_insert_after(insert_widget, &position, previous_widget) + }; + let component = components.remove(index).unwrap(); + let dyn_index = &self.model_state[index].index; + let component = component + .launch(dyn_index, returned_widget, &self.parent_sender) + .unwrap(); + components.insert(index, component); + } + } + + // Reset change tracker + self.model_state.iter_mut().for_each(|s| s.changed = false); + + // Set rendered state to the state of the model + // because everything should be up-to-date now. + self.rendered_state = self + .model_state + .iter() + .zip(components.iter()) + .map(|(s, c)| { + let mut hasher = DefaultHasher::default(); + c.returned_widget().unwrap().hash(&mut hasher); + + RenderedState { + uid: s.uid, + #[cfg(feature = "libadwaita")] + widget_hash: hasher.finish(), + } + }) + .collect(); + + if let Some(change_index) = first_position_change_idx { + for (index, comp) in components.iter().enumerate().skip(change_index) { + let position = C::position(index); + self.widget + .factory_update_position(comp.returned_widget().unwrap(), &position); + } + } + } + + /// Returns the number of elements in the [`AsyncFactoryVecDeque`]. + pub fn len(&self) -> usize { + self.components.len() + } + + /// Returns true if the [`AsyncFactoryVecDeque`] is empty. + pub fn is_empty(&self) -> bool { + self.components.is_empty() + } + + /// Send a message to one of the elements. + pub fn send(&self, index: usize, msg: C::Input) { + self.components[index].send(msg); + } + + /// Send clone of a message to all of the elements. + pub fn broadcast(&self, msg: C::Input) + where + C::Input: Clone, + { + self.components.iter().for_each(|c| c.send(msg.clone())); + } + + /// Tries to get an immutable reference to + /// the model of one element. + /// + /// Returns [`None`] if `index` is invalid or the async [`init_model()`] method + /// hasn't returned yet. + /// + /// [`init_model()`]: AsyncFactoryComponent::init_model + pub fn get(&self, index: usize) -> Option<&C> { + self.components + .get(index) + .and_then(AsyncComponentStorage::get) + } + + /// Provides a reference to the model of the back element. + /// + /// Returns [`None`] if `index` is invalid or the async [`init_model()`] method + /// of the last element hasn't returned yet. + /// + /// [`init_model()`]: AsyncFactoryComponent::init_model + pub fn back(&self) -> Option<&C> { + self.get(self.len().wrapping_sub(1)) + } + + /// Provides a reference to the model of the front element. + /// + /// Returns [`None`] if `index` is invalid or the async [`init_model()`] method + /// of the first element hasn't returned yet. + /// + /// [`init_model()`]: AsyncFactoryComponent::init_model + pub fn front(&self) -> Option<&C> { + self.get(0) + } + + /// Returns the widget all components are attached to. + pub const fn widget(&self) -> &C::ParentWidget { + &self.widget + } + + /// Returns an iterator over the components. + /// + /// Each item will be [`Some`] if the async [`init_model()`] method + /// of the item returned and otherwise [`None`]. + /// + /// [`init_model()`]: AsyncFactoryComponent::init_model + pub fn iter( + &self, + ) -> impl Iterator> + DoubleEndedIterator + ExactSizeIterator + FusedIterator + { + self.components.iter().map(AsyncComponentStorage::get) + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/async/component_storage.rs b/Relm4-0.6.2/relm4/src/factory/async/component_storage.rs new file mode 100644 index 0000000..9b190d7 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/async/component_storage.rs @@ -0,0 +1,89 @@ +use crate::factory::{DynamicIndex, FactoryView}; +use crate::Sender; + +use super::traits::AsyncFactoryComponent; +use super::AsyncFactoryBuilder; +use super::AsyncFactoryHandle; + +#[derive(Debug)] +pub(super) enum AsyncComponentStorage +where + ::ReturnedWidget: Clone, +{ + Builder(AsyncFactoryBuilder), + Final(AsyncFactoryHandle), +} + +impl AsyncComponentStorage +where + ::ReturnedWidget: Clone, +{ + pub(super) fn get(&self) -> Option<&C> { + match self { + Self::Builder(_) => None, + Self::Final(handle) => handle.data.get(), + } + } + + pub(super) fn get_mut(&mut self) -> Option<&mut C> { + match self { + Self::Builder(_) => None, + Self::Final(handle) => handle.data.get_mut(), + } + } + + pub(super) const fn widget(&self) -> &C::Root { + match self { + Self::Builder(builder) => &builder.root_widget, + Self::Final(handle) => &handle.root_widget, + } + } + + pub(super) fn send(&self, msg: C::Input) { + match self { + Self::Builder(builder) => builder.component_sender.input(msg), + Self::Final(handle) => handle.input.send(msg).unwrap(), + } + } + + pub(super) fn state_change_notify(&self) { + if let Self::Final(handle) = self { + handle.notifier.send(()).unwrap(); + } + } + + pub(super) fn extract(self) -> Option { + match self { + Self::Builder(_) => None, + Self::Final(handle) => handle.data.into_inner(), + } + } + + pub(super) fn launch( + self, + index: &DynamicIndex, + returned_widget: ::ReturnedWidget, + parent_sender: &Sender, + ) -> Option { + if let Self::Builder(builder) = self { + Some(Self::Final(builder.launch( + index, + returned_widget, + parent_sender, + C::forward_to_parent, + ))) + } else { + None + } + } + + pub(super) const fn returned_widget( + &self, + ) -> Option<&::ReturnedWidget> { + if let Self::Final(handle) = self { + Some(&handle.returned_widget) + } else { + None + } + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/async/future_data.rs b/Relm4-0.6.2/relm4/src/factory/async/future_data.rs new file mode 100644 index 0000000..e51511d --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/async/future_data.rs @@ -0,0 +1,50 @@ +use std::cell::RefCell; + +use once_cell::unsync::OnceCell; + +use super::AsyncFactoryComponent; +use crate::factory::data_guard::DataGuard; +use crate::Receiver; + +type DataReceiver = RefCell>>; + +pub(super) struct AsyncData { + future: DataReceiver>, + data: OnceCell>, +} + +impl AsyncData { + pub(super) fn new(data: Receiver>) -> Self { + Self { + future: RefCell::new(Some(data)), + data: OnceCell::new(), + } + } +} + +impl AsyncData { + pub(super) fn get(&self) -> Option<&C> { + self.update(); + self.data.get().map(|g| g.get()) + } + + pub(super) fn get_mut(&mut self) -> Option<&mut C> { + self.update(); + self.data.get_mut().map(|g| g.get_mut()) + } + + pub(super) fn into_inner(self) -> Option { + self.update(); + self.data.into_inner().map(|g| g.into_inner()) + } + + fn update(&self) { + let future = &mut *self.future.borrow_mut(); + if future.is_some() { + if let Ok(data) = future.as_ref().unwrap().0.try_recv() { + *future = None; + self.data.set(data).ok().unwrap(); + } + } + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/async/handle.rs b/Relm4-0.6.2/relm4/src/factory/async/handle.rs new file mode 100644 index 0000000..348ecbd --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/async/handle.rs @@ -0,0 +1,31 @@ +use super::AsyncData; +use super::AsyncFactoryComponent; + +use std::fmt; + +use crate::factory::FactoryView; +use crate::Sender; + +/// Don't allow public access to a [`FactoryHandle`]. +/// +/// It might be unsafe to extract `data` or `runtime`. +/// Inside this type, it is guaranteed that extracting `data` will drop `runtime` before to +/// comply with all required safety guarantees. +pub(super) struct AsyncFactoryHandle { + pub(super) data: AsyncData, + pub(super) root_widget: C::Root, + pub(super) returned_widget: ::ReturnedWidget, + pub(super) input: Sender, + pub(super) notifier: Sender<()>, +} + +impl fmt::Debug for AsyncFactoryHandle { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FactoryHandle") + .field("data", &"") + .field("root_widget", &self.root_widget) + .field("input", &self.input) + .field("notifier", &self.notifier) + .finish() + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/async/mod.rs b/Relm4-0.6.2/relm4/src/factory/async/mod.rs new file mode 100644 index 0000000..155c7c7 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/async/mod.rs @@ -0,0 +1,13 @@ +mod builder; +mod collections; +mod component_storage; +mod future_data; +mod handle; +mod traits; + +use builder::AsyncFactoryBuilder; +use future_data::AsyncData; +use handle::AsyncFactoryHandle; + +pub use collections::{AsyncFactoryVecDeque, AsyncFactoryVecDequeGuard}; +pub use traits::AsyncFactoryComponent; diff --git a/Relm4-0.6.2/relm4/src/factory/async/traits.rs b/Relm4-0.6.2/relm4/src/factory/async/traits.rs new file mode 100644 index 0000000..de65fa6 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/async/traits.rs @@ -0,0 +1,126 @@ +//! Traits for for managing and updating factories. + +use crate::channel::AsyncFactorySender; +use crate::factory::{AsyncPosition, DynamicIndex, FactoryView}; +use crate::loading_widgets::LoadingWidgets; +use crate::Sender; + +use std::fmt::Debug; + +/// A component that's stored inside a factory. +/// Similar to [`Component`](crate::Component) but adjusted to fit the life cycle +/// of factories. +#[async_trait::async_trait(?Send)] +pub trait AsyncFactoryComponent: + AsyncPosition<::Position> + Sized + 'static +{ + /// Container widget to which all widgets of the factory will be added. + type ParentWidget: FactoryView + 'static; + + /// Input messages sent to the parent component. + type ParentInput: Debug + 'static; + + /// Messages which are received from commands executing in the background. + type CommandOutput: Debug + Send + 'static; + + /// The message type that the factory component accepts as inputs. + type Input: Debug + 'static; + + /// The message type that the factory component provides as outputs. + type Output: Debug + 'static; + + /// The parameter used to initialize the factory component. + type Init; + + /// The top-level widget of the factory component. + type Root: AsRef<::Children> + Debug + Clone; + + /// The type that's used for storing widgets created for this factory component. + type Widgets: 'static; + + /// Initializes the model. + async fn init_model( + init: Self::Init, + index: &DynamicIndex, + sender: AsyncFactorySender, + ) -> Self; + + /// Initializes the root widget + fn init_root() -> Self::Root; + + /// Allows you to initialize the root widget with a temporary value + /// as a placeholder until the [`init_model()`] future completes. + /// + /// This method does nothing by default. + /// + /// [`init_model()`]: AsyncFactoryComponent::init_model + #[must_use] + fn init_loading_widgets(_root: &mut Self::Root) -> Option { + None + } + + /// Initializes the widgets. + fn init_widgets( + &mut self, + index: &DynamicIndex, + root: &Self::Root, + returned_widget: &::ReturnedWidget, + sender: AsyncFactorySender, + ) -> Self::Widgets; + + /// Optionally convert an output message from this component to an input message for the + /// parent component. By default this method does nothing, you must overwrite it to + /// forward messages. + /// + /// If [`None`] is returned, nothing is forwarded. + fn forward_to_parent(_output: Self::Output) -> Option { + None + } + + /// Processes inputs received by the component. + #[allow(unused)] + async fn update(&mut self, message: Self::Input, sender: AsyncFactorySender) {} + + /// Defines how the component should respond to command updates. + #[allow(unused)] + async fn update_cmd(&mut self, message: Self::CommandOutput, sender: AsyncFactorySender) { + } + + /// Handles updates from a command. + async fn update_cmd_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::CommandOutput, + sender: AsyncFactorySender, + ) { + self.update_cmd(message, sender.clone()).await; + self.update_view(widgets, sender); + } + + /// Updates the view after the model has been updated. + #[allow(unused)] + fn update_view(&self, widgets: &mut Self::Widgets, sender: AsyncFactorySender) {} + + /// Updates the model and view. Optionally returns a command to run. + async fn update_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::Input, + sender: AsyncFactorySender, + ) { + self.update(message, sender.clone()).await; + self.update_view(widgets, sender); + } + + /// Last method called before a factory component is shut down. + #[allow(unused)] + fn shutdown(&mut self, widgets: &mut Self::Widgets, output: Sender) {} + + /// An identifier for the component used for debug logging. + /// + /// The default implementation of this method uses the address of the component, but + /// implementations are free to provide more meaningful identifiers. + fn id(&self) -> String { + format!("{:p}", &self) + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/data_guard.rs b/Relm4-0.6.2/relm4/src/factory/data_guard.rs new file mode 100644 index 0000000..ffb9513 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/data_guard.rs @@ -0,0 +1,249 @@ +use std::mem::ManuallyDrop; + +use futures::Future; +use gtk::glib; + +use crate::{shutdown::ShutdownSender, Sender}; + +type DynShutdownFn = dyn Fn(&mut C, &mut Widgets, Sender); + +/// # SAFETY +/// +/// This type is a safe wrapper that prevent's misuse, +/// except if you move the data passed to the runtime outside +/// of the runtime (through senders for example). +pub(super) struct DataGuard { + data: Box, + widgets: Box, + rt_dropper: RuntimeDropper, + output_sender: Sender, + shutdown_notifier: ShutdownSender, + shutdown_fn: Box>, +} + +impl DataGuard { + /// DO NOT MOVE THE DATA PASSED TO THE CLOSURE OUTSIDE OF THE RUNTIME! + /// SAFETY IS ONLY GUARANTEED BECAUSE THE DATA IS BOUND TO THE LIFETIME OF THE RUNTIME! + pub(super) fn new( + data: Box, + widgets: Box, + shutdown_notifier: ShutdownSender, + output_sender: Sender, + f: F, + shutdown_fn: ShutdownFn, + ) -> Self + where + Fut: Future + 'static, + F: FnOnce(ManuallyDrop>, ManuallyDrop>) -> Fut, + ShutdownFn: Fn(&mut C, &mut Widgets, Sender) + 'static, + { + // Duplicate the references to `data` + // + // # SAFETY + // + // This is safe because: + // 1. The first reference never calls the destructor (being wrapped in ManuallyDrop) + // 2. The first reference is always dropped first. This is guaranteed by types like + // `RuntimeDropper` and `FactoryHandle` that wrap the data and the runtime ID + // in a safe API that makes sure the runtime (and with it the first reference) is + // dropped before the second reference is dropped or extracted. + // 3. The second reference can only be extracted or dropped AFTER the first one + // was dropped. The second reference can then safely behave like a normal `Box`. + // + // Unsoundness only occurs when data that was moved into the runtime is moved out on + // purpose. This would allow the first reference to outlive the second one, becoming + // a dangling pointer. + let (data, runtime_data) = unsafe { + let raw = Box::into_raw(data); + let data = Box::from_raw(raw); + let runtime_data = ManuallyDrop::new(Box::from_raw(raw)); + (data, runtime_data) + }; + let (widgets, runtime_widgets) = unsafe { + let raw = Box::into_raw(widgets); + let widgets = Box::from_raw(raw); + let runtime_widgets = ManuallyDrop::new(Box::from_raw(raw)); + (widgets, runtime_widgets) + }; + + let future = f(runtime_data, runtime_widgets); + let rt_dropper = RuntimeDropper(Some(crate::spawn_local(future).into_source_id().unwrap())); + let shutdown_fn = Box::new(shutdown_fn); + + Self { + data, + widgets, + output_sender, + shutdown_notifier, + rt_dropper, + shutdown_fn, + } + } + + pub(super) const fn get(&self) -> &C { + &self.data + } + + pub(super) fn get_mut(&mut self) -> &mut C { + &mut self.data + } + + pub(super) fn into_inner(mut self) -> C { + drop(self.rt_dropper); + self.shutdown_notifier.shutdown(); + (self.shutdown_fn)( + &mut self.data, + &mut self.widgets, + self.output_sender.clone(), + ); + drop(self.widgets); + *self.data + } +} + +impl std::fmt::Debug for DataGuard { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("DataGuard") + .field("data", &"") + .field("widgets", &"") + .field("rt_dropper", &self.rt_dropper) + .field("output_sender", &self.output_sender) + .field("shutdown_notifier", &self.shutdown_notifier) + .field("shutdown_fn", &"") + .finish() + } +} + +#[derive(Debug)] +struct RuntimeDropper(Option); + +/// A type that will drop a runtime behind a shared reference +/// when it is dropped. +impl Drop for RuntimeDropper { + fn drop(&mut self) { + if let Some(id) = self.0.take() { + id.remove(); + } + } +} + +#[cfg(test)] +mod test { + use gtk::glib::MainContext; + + use crate::{prelude::FactoryComponent, shutdown}; + + use super::DataGuard; + + #[derive(Debug)] + struct DontDropBelow4(u8); + + impl DontDropBelow4 { + fn value(&self) -> u8 { + self.0 + } + + fn add(&mut self) { + self.0 += 1; + } + } + + impl Drop for DontDropBelow4 { + fn drop(&mut self) { + if self.0 < 4 { + panic!() + } + } + } + + impl FactoryComponent for DontDropBelow4 { + type ParentWidget = gtk::Box; + type ParentInput = (); + type CommandOutput = (); + type Input = (); + type Output = (); + type Init = (); + type Root = gtk::Box; + type Widgets = (); + type Index = crate::prelude::DynamicIndex; + + fn init_model( + _: Self::Init, + _: &crate::prelude::DynamicIndex, + _: crate::prelude::FactorySender, + ) -> Self { + Self(0) + } + + fn init_root(&self) -> Self::Root { + gtk::Box::default() + } + + fn init_widgets( + &mut self, + _: &crate::prelude::DynamicIndex, + _: &Self::Root, + _: &::ReturnedWidget, + _: crate::prelude::FactorySender, + ) -> Self::Widgets { + } + + fn shutdown(&mut self, _: &mut Self::Widgets, _: crate::Sender) { + self.add(); + } + } + + #[test] + #[should_panic] + fn test_drop_panic() { + let _data = Box::new(DontDropBelow4(0_u8)); + } + + #[gtk::test] + fn test_data_guard_drop() { + let data = Box::new(DontDropBelow4(0_u8)); + let widgets = Box::new(()); + let (shutdown_notifier, mut shutdown_receiver) = shutdown::channel(); + let (output_sender, _) = crate::channel(); + let (tx, rx) = flume::unbounded(); + + let data = DataGuard::new( + data, + widgets, + shutdown_notifier, + output_sender, + |mut rt_data, _| async move { + while (rx.recv_async().await).is_ok() { + rt_data.add(); + } + }, + DontDropBelow4::shutdown, + ); + + let main_ctx = MainContext::default(); + + main_ctx.iteration(false); + assert_eq!(data.get().value(), 0); + + tx.send(()).unwrap(); + tx.send(()).unwrap(); + main_ctx.iteration(false); + + assert_eq!(data.get().value(), 2); + + let mut data = data.into_inner(); + // Make sure the shutdown is called with yet another increment. + assert_eq!(data.value(), 3); + // Make sure the shutdown receiver was notified. + shutdown_receiver.try_recv().unwrap(); + + main_ctx.iteration(false); + + // Make sure the destructor doesn't panic + data.add(); + assert_eq!(data.value(), 4); + + tx.send(()).unwrap_err(); + main_ctx.iteration(false); + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/dynamic_index.rs b/Relm4-0.6.2/relm4/src/factory/dynamic_index.rs new file mode 100644 index 0000000..84596f3 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/dynamic_index.rs @@ -0,0 +1,113 @@ +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; + +/// A dynamic index that updates automatically when items are shifted inside a factory container. +/// +/// For example a [`FactoryVecDeque`](super::FactoryVecDeque) has an [`insert`](super::FactoryVecDequeGuard::insert) +/// method that allows users to insert data at arbitrary positions. +/// If we insert at the front all following widgets will be moved by one which would +/// invalidate their indices. +/// To allow widgets in a factory container to send messages with valid indices +/// this type ensures that the indices is always up to date. +/// +/// Never send an index as [`usize`] but always as [`DynamicIndex`] +/// to the update function because messages can be queued up and stale by the time they are handled. +/// +/// [`DynamicIndex`] is a smart pointer so cloning will work similar to [`std::rc::Rc`] and will create +/// a pointer to the same data. +/// +/// In short: only call [`current_index`](DynamicIndex::current_index) from the update function +/// where you actually need the index as [`usize`]. +#[derive(Debug)] +pub struct DynamicIndex { + inner: Arc, +} + +impl PartialEq for DynamicIndex { + fn eq(&self, other: &Self) -> bool { + self.current_index().eq(&other.current_index()) + } +} + +impl Eq for DynamicIndex {} + +impl Clone for DynamicIndex { + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + } + } +} + +impl DynamicIndex { + /// Get the current index number. + /// + /// This value is updated by the factory container and might change after each update function. + #[must_use] + pub fn current_index(&self) -> usize { + self.inner.load(Ordering::Relaxed) + } + + // Creates a [`WeakDynamicIndex`] for sending in messages. + // pub fn downgrade(&self) -> WeakDynamicIndex { + // WeakDynamicIndex { + // inner: Arc::downgrade(&self.inner), + // } + // } + + pub(super) fn increment(&self) { + self.inner.fetch_add(1, Ordering::Relaxed); + } + + pub(super) fn decrement(&self) { + self.inner.fetch_sub(1, Ordering::Relaxed); + } + + pub(super) fn set_value(&self, new_value: usize) { + self.inner.store(new_value, Ordering::Relaxed); + } + + pub(super) fn new(index: usize) -> Self { + Self { + inner: Arc::new(AtomicUsize::new(index)), + } + } +} + +// A weak version of [`DynamicIndex`]. +// +// Use this to send messages to the update function and call [`upgrade`](WeakDynamicIndex::upgrade) +// to receive the actual [`DynamicIndex`]. +// +// A weak index is preferred for sending in messages because messages can be stale by the time they +// are handled and the element already deleted. A weak reference doesn't keep the index alive +// if the element was deleted which allows you to properly handle invalid indices. +// +// # Panics +// +// Sending a [`WeakDynamicIndex`] to a different thread and accessing it will panic. +// #[derive(Debug)] +// pub struct WeakDynamicIndex { +// inner: Weak>, +// } + +// impl Clone for WeakDynamicIndex { +// fn clone(&self) -> Self { +// WeakDynamicIndex { +// inner: self.inner.clone(), +// } +// } +// } + +// impl WeakDynamicIndex { +// Attempts to upgrade the [`WeakDynamicIndex`] to a [`DynamicIndex`]. +// +// Returns [`None`] if the index has since been dropped. +// pub fn upgrade(&self) -> Option { +// Weak::upgrade(&self.inner).map(|inner| { +// DynamicIndex { +// inner, +// } +// }) +// } +// } diff --git a/Relm4-0.6.2/relm4/src/factory/mod.rs b/Relm4-0.6.2/relm4/src/factory/mod.rs new file mode 100644 index 0000000..d341a35 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/mod.rs @@ -0,0 +1,26 @@ +//! Defines traits and data types to generate widgets from collections efficiently. + +mod dynamic_index; + +/// Traits and implementations used for factories to interact with widgets. +pub mod widgets; + +/// Implementation of asynchronous factories. +mod r#async; +pub mod positions; + +/// Implementation of regular factories. +mod sync; + +mod data_guard; +use data_guard::DataGuard; + +pub use r#async::{AsyncFactoryComponent, AsyncFactoryVecDeque, AsyncFactoryVecDequeGuard}; +pub use sync::{ + CloneableFactoryComponent, FactoryComponent, FactoryHashMap, FactoryVecDeque, + FactoryVecDequeGuard, +}; + +pub use crate::channel::{AsyncFactorySender, FactorySender}; +pub use dynamic_index::DynamicIndex; +pub use widgets::traits::*; diff --git a/Relm4-0.6.2/relm4/src/factory/positions.rs b/Relm4-0.6.2/relm4/src/factory/positions.rs new file mode 100644 index 0000000..cbb53ca --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/positions.rs @@ -0,0 +1,24 @@ +//! Position types for various widgets. + +/// Storing information about where new widgets can be placed +/// inside a [`gtk::Grid`]. +#[derive(Debug)] +pub struct GridPosition { + /// The number of the column. + pub column: i32, + /// The number of the row. + pub row: i32, + /// The amount of columns the widget should take. + pub width: i32, + /// The amount of rows the widget should take. + pub height: i32, +} + +#[derive(Debug)] +/// Position used for [`gtk::Fixed`]. +pub struct FixedPosition { + /// Position on the x-axis. + pub x: f64, + /// Position on the y-axis. + pub y: f64, +} diff --git a/Relm4-0.6.2/relm4/src/factory/sync/builder.rs b/Relm4-0.6.2/relm4/src/factory/sync/builder.rs new file mode 100644 index 0000000..1f8dbba --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/sync/builder.rs @@ -0,0 +1,161 @@ +use super::{FactoryComponent, FactoryHandle}; + +use crate::factory::{DataGuard, FactorySender, FactoryView}; +use crate::shutdown::ShutdownSender; +use crate::{shutdown, GuardedReceiver, Receiver, Sender}; + +use std::any; + +use tracing::info_span; + +#[derive(Debug)] +pub(super) struct FactoryBuilder { + pub(super) data: Box, + pub(super) root_widget: C::Root, + pub(super) component_sender: FactorySender, + pub(super) input_receiver: Receiver, + pub(super) output_receiver: Receiver, + pub(super) cmd_receiver: Receiver, + pub(super) shutdown_notifier: ShutdownSender, +} + +impl FactoryBuilder { + pub(super) fn new(index: &C::Index, init: C::Init) -> Self { + // Used for all events to be processed by this component's internal service. + let (input_sender, input_receiver) = crate::channel::(); + + // Used by this component to send events to be handled externally by the caller. + let (output_sender, output_receiver) = crate::channel::(); + + // Sends messages from commands executed from the background. + let (cmd_sender, cmd_receiver) = crate::channel::(); + + // Notifies the component's child commands that it is now deceased. + let (shutdown_notifier, shutdown_receiver) = shutdown::channel(); + + // Encapsulates the senders used by component methods. + let component_sender = + FactorySender::new(input_sender, output_sender, cmd_sender, shutdown_receiver); + + let data = Box::new(C::init_model(init, index, component_sender.clone())); + let root_widget = data.init_root(); + + Self { + data, + root_widget, + component_sender, + input_receiver, + output_receiver, + cmd_receiver, + shutdown_notifier, + } + } + + /// Starts the component, passing ownership to a future attached to a [gtk::glib::MainContext]. + pub(super) fn launch( + self, + index: &C::Index, + returned_widget: ::ReturnedWidget, + parent_sender: &Sender, + transform: Transform, + ) -> FactoryHandle + where + Transform: Fn(C::Output) -> Option + 'static, + { + let Self { + mut data, + root_widget, + component_sender, + input_receiver, + output_receiver, + cmd_receiver, + shutdown_notifier, + } = self; + + let forward_sender = parent_sender.0.clone(); + crate::spawn_local(async move { + while let Some(msg) = output_receiver.recv().await { + if let Some(new_msg) = transform(msg) { + if forward_sender.send(new_msg).is_err() { + break; + } + } + } + }); + + // Gets notifications when a component's model and view is updated externally. + let (notifier, notifier_receiver) = crate::channel(); + + let widgets = Box::new(data.init_widgets( + index, + &root_widget, + &returned_widget, + component_sender.clone(), + )); + + let input_sender = component_sender.input_sender().clone(); + let output_sender = component_sender.output_sender().clone(); + + // Spawns the component's service. It will receive both `Self::Input` and + // `Self::CommandOutput` messages. It will spawn commands as requested by + // updates, and send `Self::Output` messages externally. + let data = DataGuard::new( + data, + widgets, + shutdown_notifier, + output_sender, + |mut model, mut widgets| { + async move { + let mut notifier = GuardedReceiver::new(notifier_receiver); + let mut cmd = GuardedReceiver::new(cmd_receiver); + let mut input = GuardedReceiver::new(input_receiver); + loop { + futures::select!( + // Performs the model update, checking if the update requested a command. + // Runs that command asynchronously in the background using tokio. + message = input => { + let span = info_span!( + "update_with_view", + input=?message, + component=any::type_name::(), + id=model.id(), + ); + let _enter = span.enter(); + + model.update_with_view(&mut widgets, message, component_sender.clone()); + } + + // Handles responses from a command. + message = cmd => { + let span = info_span!( + "update_cmd_with_view", + cmd_output=?message, + component=any::type_name::(), + id=model.id(), + ); + let _enter = span.enter(); + + model.update_cmd_with_view(&mut widgets, message, component_sender.clone()); + } + + // Triggered when the model and view have been updated externally. + _ = notifier => { + model.update_view(&mut widgets, component_sender.clone()); + } + ); + } + } + }, + C::shutdown, + ); + + // Give back a type for controlling the component service. + FactoryHandle { + data, + root_widget, + returned_widget, + input: input_sender, + notifier, + } + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/sync/collections/hashmap.rs b/Relm4-0.6.2/relm4/src/factory/sync/collections/hashmap.rs new file mode 100644 index 0000000..30b4384 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/sync/collections/hashmap.rs @@ -0,0 +1,267 @@ +use crate::Sender; + +use crate::factory::sync::builder::FactoryBuilder; +use crate::factory::sync::handle::FactoryHandle; +use crate::factory::{CloneableFactoryComponent, FactoryComponent, FactoryView}; + +use std::collections::hash_map::RandomState; +use std::collections::HashMap; +use std::hash::{BuildHasher, Hash}; +use std::iter::FusedIterator; +use std::ops; + +#[derive(Debug)] +#[must_use] +pub struct FactoryElementGuard<'a, C> +where + C: FactoryComponent, +{ + inner: &'a mut FactoryHandle, +} + +impl<'a, C> ops::Deref for FactoryElementGuard<'a, C> +where + C: FactoryComponent, +{ + type Target = C; + + fn deref(&self) -> &Self::Target { + self.inner.data.get() + } +} + +impl<'a, C> ops::DerefMut for FactoryElementGuard<'a, C> +where + C: FactoryComponent, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + self.inner.data.get_mut() + } +} + +impl<'a, C> Drop for FactoryElementGuard<'a, C> +where + C: FactoryComponent, +{ + fn drop(&mut self) { + self.inner.notifier.send(()).unwrap() + } +} + +/// A container similar to [`HashMap`] that can be used to store +/// values of type [`FactoryComponent`]. +#[derive(Debug)] +pub struct FactoryHashMap { + widget: C::ParentWidget, + parent_sender: Sender, + inner: HashMap, S>, +} + +impl Drop for FactoryHashMap +where + C: FactoryComponent, +{ + fn drop(&mut self) { + self.clear(); + } +} + +impl ops::Index<&K> for FactoryHashMap +where + C: FactoryComponent, + K: Hash + Eq, + S: BuildHasher, +{ + type Output = C; + + fn index(&self, key: &K) -> &Self::Output { + self.get(key).expect("Called `get` on an invalid key") + } +} + +impl FactoryHashMap +where + C: FactoryComponent, +{ + /// Creates a new [`FactoryHashMap`]. + #[must_use] + pub fn new(widget: C::ParentWidget, parent_sender: &Sender) -> Self { + Self { + widget, + parent_sender: parent_sender.clone(), + inner: HashMap::new(), + } + } +} + +impl FactoryHashMap +where + C: FactoryComponent, +{ + /// Creates a new [`FactoryHashMap`]. + #[must_use] + pub fn width_hasher( + widget: C::ParentWidget, + parent_sender: &Sender, + hash_builder: S, + ) -> Self { + Self { + widget, + parent_sender: parent_sender.clone(), + inner: HashMap::with_hasher(hash_builder), + } + } + + /// Returns the number of elements in the [`FactoryHashMap`]. + pub fn len(&self) -> usize { + self.inner.len() + } + + /// Returns true if the [`FactoryHashMap`] is empty. + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } + + /// Send clone of a message to all of the elements. + pub fn broadcast(&self, msg: C::Input) + where + C::Input: Clone, + { + self.inner.values().for_each(|c| c.input.emit(msg.clone())); + } + + /// Returns the widget all components are attached to. + pub const fn widget(&self) -> &C::ParentWidget { + &self.widget + } + + /// An iterator visiting all key-value pairs in arbitrary order. + pub fn iter(&self) -> impl Iterator + ExactSizeIterator + FusedIterator { + self.inner.iter().map(|(k, c)| (k, c.data.get())) + } + + /// Returns an iterator over the factory components. + pub fn values(&self) -> impl Iterator + ExactSizeIterator + FusedIterator { + self.inner.values().map(|c| c.data.get()) + } + + /// Returns an iterator over the keys of the hash map. + pub fn keys(&self) -> impl Iterator + ExactSizeIterator + FusedIterator { + self.inner.keys() + } + + /// Clears the map, removing all factory components. + pub fn clear(&mut self) { + for (_, handle) in self.inner.drain() { + self.widget.factory_remove(&handle.returned_widget); + } + } +} + +impl FactoryHashMap +where + C: FactoryComponent, + K: Hash + Eq, +{ + /// Creates a [`FactoryHashMap`] from a [`Vec`]. + pub fn from_vec( + component_vec: Vec<(K, C::Init)>, + widget: C::ParentWidget, + parent_sender: &Sender, + ) -> Self { + let mut output = Self::new(widget, parent_sender); + for (key, init) in component_vec { + output.insert(key, init); + } + output + } +} + +impl FactoryHashMap +where + C: FactoryComponent, + K: Hash + Eq, + S: BuildHasher, +{ + /// Send a mage to one of the elements. + pub fn send(&self, key: &K, msg: C::Input) { + self.inner[key].input.emit(msg); + } + + /// Tries to get an immutable reference to + /// the model of one element. + /// + /// Returns [`None`] if `key` is invalid. + pub fn get(&self, key: &K) -> Option<&C> { + self.inner.get(key).map(|c| c.data.get()) + } + + /// Tries to get a mutable reference to + /// the model of one element. + /// + /// Returns [`None`] if `key` is invalid. + pub fn get_mut(&mut self, key: &K) -> Option> { + self.inner + .get_mut(key) + .map(|c| FactoryElementGuard { inner: c }) + } + + /// Inserts a new factory component into the map. + /// + /// If the map did not have this key present, None is returned. + /// + /// If the map did have this key present, the value is updated, and the old value is returned. + /// The key is not updated, though; this matters for types that can be == without being identical. See the module-level documentation for more. + pub fn insert(&mut self, key: K, init: C::Init) -> Option { + let existing = self.remove(&key); + + let builder = FactoryBuilder::new(&key, init); + + let position = C::position(&builder.data, &key); + let returned_widget = self + .widget + .factory_append(builder.root_widget.clone(), &position); + + let component = builder.launch( + &key, + returned_widget, + &self.parent_sender, + C::forward_to_parent, + ); + + assert!(self.inner.insert(key, component).is_none()); + + existing + } + + /// Removes a key from the map, returning the factory component at the key if the key was previously in the map. + pub fn remove(&mut self, key: &K) -> Option { + if let Some(handle) = self.inner.remove(key) { + self.widget.factory_remove(&handle.returned_widget); + Some(handle.data.into_inner()) + } else { + None + } + } +} + +/// Implements the Clone Trait for [`FactoryHashMap`] if the component implements [`CloneableFactoryComponent`]. +impl Clone for FactoryHashMap +where + C: CloneableFactoryComponent, + K: Clone + Hash + Eq, + C: FactoryComponent, +{ + fn clone(&self) -> Self { + // Create a new, empty FactoryHashMap. + let mut clone = FactoryHashMap::new(self.widget.clone(), &self.parent_sender.clone()); + // Iterate over the items in the original FactoryHashMap. + for (k, item) in self.iter() { + // Clone each item and push it onto the new FactoryHashMap. + let init = C::get_init(item); + clone.insert(k.clone(), init); + } + // Return the new, cloned FactoryHashMap. + clone + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/sync/collections/mod.rs b/Relm4-0.6.2/relm4/src/factory/sync/collections/mod.rs new file mode 100644 index 0000000..576c552 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/sync/collections/mod.rs @@ -0,0 +1,22 @@ +//! Containers similar to [`std::collections`] that can be used to store factory data. + +mod hashmap; +mod vec_deque; +pub use hashmap::FactoryHashMap; +pub use vec_deque::{FactoryVecDeque, FactoryVecDequeGuard}; + +use crate::factory::DynamicIndex; + +#[derive(Debug)] +struct RenderedState { + uid: usize, + #[cfg(feature = "libadwaita")] + widget_hash: u64, +} + +#[derive(Debug)] +struct ModelStateValue { + index: DynamicIndex, + uid: usize, + changed: bool, +} diff --git a/Relm4-0.6.2/relm4/src/factory/sync/collections/vec_deque.rs b/Relm4-0.6.2/relm4/src/factory/sync/collections/vec_deque.rs new file mode 100644 index 0000000..63c4c54 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/sync/collections/vec_deque.rs @@ -0,0 +1,643 @@ +use crate::Sender; + +use crate::factory::sync::builder::FactoryBuilder; +use crate::factory::sync::component_storage::ComponentStorage; +use crate::factory::sync::traits::CloneableFactoryComponent; +use crate::factory::{DynamicIndex, FactoryComponent, FactoryView}; + +use super::{ModelStateValue, RenderedState}; + +use std::collections::hash_map::DefaultHasher; +use std::collections::VecDeque; +use std::hash::Hash; +use std::iter::FusedIterator; +use std::ops::{Deref, Index, IndexMut}; + +#[cfg(feature = "libadwaita")] +use gtk::prelude::Cast; + +#[cfg(feature = "libadwaita")] +use std::hash::Hasher; + +/// Provides methods to edit the underlying [`FactoryVecDeque`]. +/// +/// The changes will be rendered on the widgets after the guard goes out of scope. +#[derive(Debug)] +#[must_use] +pub struct FactoryVecDequeGuard<'a, C> +where + C: FactoryComponent, +{ + inner: &'a mut FactoryVecDeque, +} + +impl<'a, C> Drop for FactoryVecDequeGuard<'a, C> +where + C: FactoryComponent, +{ + fn drop(&mut self) { + self.inner.render_changes(); + } +} + +impl<'a, C> FactoryVecDequeGuard<'a, C> +where + C: FactoryComponent, +{ + fn new(inner: &'a mut FactoryVecDeque) -> Self { + #[allow(unused_mut)] + #[allow(clippy::let_and_return)] + let mut guard = FactoryVecDequeGuard { inner }; + + #[cfg(feature = "libadwaita")] + guard.apply_external_updates(); + + guard + } + + /// Drops the guard and renders all changes. + /// + /// Use this to transfer full ownership back to the [`FactoryVecDeque`]. + pub fn drop(self) { + drop(self); + } + + /// Apply external updates that happened between the last render. + /// + /// [`FactoryVecDeque`] should not be edited between calling [`Self::render_changes`] + /// and this method, as it might cause undefined behaviour. This shouldn't be possible + /// because the method is called in [`FactoryVecDequeGuard::new`]. + #[cfg(feature = "libadwaita")] + fn apply_external_updates(&mut self) { + if let Some(tab_view) = self.inner.widget().dynamic_cast_ref::() { + let length = tab_view.n_pages(); + let mut hash_values: Vec = Vec::with_capacity(usize::try_from(length).unwrap()); + + for i in 0..length { + let page = tab_view.nth_page(i); + let mut hasher = DefaultHasher::default(); + page.hash(&mut hasher); + hash_values.push(hasher.finish()); + } + + // Tab rearrangement + for (index, hash) in hash_values.iter().enumerate() { + if self + .inner + .rendered_state + .get(index) + .map(|state| state.widget_hash) + == Some(*hash) + { + let old_position = self + .inner + .rendered_state + .iter() + .position(|state| state.widget_hash == *hash) + .expect("A new widget was added"); + + let elem = self.inner.rendered_state.remove(old_position).unwrap(); + self.inner.rendered_state.insert(index, elem); + + self.move_to(old_position, index); + } + } + + // Closed tabs + let mut index = 0; + while index < self.inner.rendered_state.len() { + let hash = self.inner.rendered_state[index].widget_hash; + if hash_values.contains(&hash) { + index += 1; + } else { + self.inner.rendered_state.remove(index); + + self.remove(index); + } + } + } + } + + /// Tries to get a mutable reference to + /// the model of one element. + /// + /// Returns [`None`] if `index` is invalid. + pub fn get_mut(&mut self, index: usize) -> Option<&mut C> { + // Mark as modified + if let Some(state) = self.inner.model_state.get_mut(index) { + state.changed = true; + } + self.inner + .components + .get_mut(index) + .map(ComponentStorage::get_mut) + } + + /// Provides a mutable reference to the model of the back element. + /// + /// Returns [`None`] if the deque is empty. + pub fn back_mut(&mut self) -> Option<&mut C> { + self.get_mut(self.len().wrapping_sub(1)) + } + + /// Provides a mutable reference to the model of the front element. + /// + /// Returns [`None`] if the deque is empty. + pub fn front_mut(&mut self) -> Option<&mut C> { + self.get_mut(0) + } + + /// Removes the last element from the [`FactoryVecDeque`] and returns it, + /// or [`None`] if it is empty. + pub fn pop_back(&mut self) -> Option { + if self.is_empty() { + None + } else { + self.remove(self.len() - 1) + } + } + + /// Removes the first element from the [`FactoryVecDeque`] and returns it, + /// or [`None`] if it is empty. + pub fn pop_front(&mut self) -> Option { + self.remove(0) + } + + /// Removes and returns the element at index from the [`FactoryVecDeque`]. + /// Returns [`None`] if index is out of bounds. + /// + /// Element at index 0 is the front of the queue. + pub fn remove(&mut self, index: usize) -> Option { + self.inner.model_state.remove(index); + let component = self.inner.components.remove(index); + + // Decrement the indexes of the following elements. + for states in self.inner.model_state.iter_mut().skip(index) { + states.index.decrement(); + } + + if let Some(comp) = &component { + if let Some(widget) = &comp.returned_widget() { + self.widget.factory_remove(widget); + } + } + + component.map(ComponentStorage::extract) + } + + /// Appends an element at the end of the [`FactoryVecDeque`]. + pub fn push_back(&mut self, init: C::Init) -> DynamicIndex { + let index = self.len(); + self.insert(index, init) + } + + /// Prepends an element to the [`FactoryVecDeque`]. + pub fn push_front(&mut self, init: C::Init) -> DynamicIndex { + self.insert(0, init) + } + + /// Inserts an element at index within the [`FactoryVecDeque`], + /// shifting all elements with indices greater than or equal + /// to index towards the back. + /// + /// Element at index 0 is the front of the queue. + /// + /// # Panics + /// + /// Panics if index is greater than [`FactoryVecDeque`]’s length. + pub fn insert(&mut self, index: usize, init: C::Init) -> DynamicIndex { + let dyn_index = DynamicIndex::new(index); + + // Increment the indexes of the following elements. + for states in self.inner.model_state.iter_mut().skip(index) { + states.index.increment(); + } + + let builder = FactoryBuilder::new(&dyn_index, init); + + self.inner + .components + .insert(index, ComponentStorage::Builder(builder)); + self.inner.model_state.insert( + index, + ModelStateValue { + index: dyn_index.clone(), + uid: self.uid_counter, + changed: false, + }, + ); + self.inner.uid_counter += 1; + + dyn_index + } + + /// Swaps elements at indices `first` and `second`. + /// + /// `first` and `second` may be equal. + /// + /// Element at index 0 is the front of the queue. + /// + /// # Panics + /// + /// Panics if either index is out of bounds. + pub fn swap(&mut self, first: usize, second: usize) { + // Don't update anything if both are equal + if first != second { + self.inner.model_state.swap(first, second); + self.inner.components.swap(first, second); + + // Update indexes. + self.model_state[first].index.set_value(first); + self.model_state[second].index.set_value(second); + } + } + + /// Moves an element at index `current_position` to `target`, + /// shifting all elements between these positions. + /// + /// `current_position` and `target` may be equal. + /// + /// Element at index 0 is the front of the queue. + /// + /// # Panics + /// + /// Panics if either index is out of bounds. + pub fn move_to(&mut self, current_position: usize, target: usize) { + // Don't update anything if both are equal + if current_position != target { + let elem = self.inner.model_state.remove(current_position).unwrap(); + // Set new index + elem.index.set_value(target); + self.inner.model_state.insert(target, elem); + + let comp = self.inner.components.remove(current_position).unwrap(); + self.inner.components.insert(target, comp); + + // Update indexes. + if current_position > target { + // Move down -> shift elements in between up. + for state in self + .inner + .model_state + .iter_mut() + .skip(target + 1) + .take(current_position - target) + { + state.index.increment(); + } + } else { + // Move up -> shift elements in between down. + for state in self + .inner + .model_state + .iter_mut() + .skip(current_position) + .take(target - current_position) + { + state.index.decrement(); + } + } + } + } + + /// Moves an element at index `current_position` to the front, + /// shifting all elements between these positions. + /// + /// # Panics + /// + /// Panics if index is out of bounds. + pub fn move_front(&mut self, current_position: usize) { + self.move_to(current_position, 0); + } + + /// Moves an element at index `current_position` to the back, + /// shifting all elements between these positions. + /// + /// # Panics + /// + /// Panics if index is out of bounds. + pub fn move_back(&mut self, current_position: usize) { + self.move_to(current_position, self.len() - 1); + } + + /// Remove all components from the [`FactoryVecDeque`]. + pub fn clear(&mut self) { + self.inner.model_state.clear(); + + for component in self.inner.components.drain(..) { + // Remove all widgets + if let Some(widget) = component.returned_widget() { + self.inner.widget.factory_remove(widget); + } + + // Make sure the component is shutdown properly + component.extract(); + } + + self.inner.rendered_state.clear(); + self.inner.uid_counter = 1; + } + + /// Returns an iterator over the components that returns mutable references. + pub fn iter_mut( + &mut self, + ) -> impl Iterator + DoubleEndedIterator + ExactSizeIterator + FusedIterator + { + self.inner + .components + .iter_mut() + .zip(self.inner.model_state.iter_mut()) + .map(|(component, state)| { + state.changed = true; + component.get_mut() + }) + } +} + +impl<'a, C> Deref for FactoryVecDequeGuard<'a, C> +where + C: FactoryComponent, +{ + type Target = FactoryVecDeque; + + fn deref(&self) -> &Self::Target { + self.inner + } +} + +impl<'a, C> Index for FactoryVecDequeGuard<'a, C> +where + C: FactoryComponent, +{ + type Output = C; + + fn index(&self, index: usize) -> &Self::Output { + self.inner.index(index) + } +} + +impl<'a, C> IndexMut for FactoryVecDequeGuard<'a, C> +where + C: FactoryComponent, +{ + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + self.get_mut(index) + .expect("Called `get_mut` on an invalid index") + } +} + +/// A container similar to [`VecDeque`] that can be used to store +/// data associated with components that implement [`FactoryComponent`]. +/// +/// To access mutable methods of the factory, create a guard using [`Self::guard`]. +#[derive(Debug)] +pub struct FactoryVecDeque +where + C: FactoryComponent, +{ + widget: C::ParentWidget, + parent_sender: Sender, + components: VecDeque>, + model_state: VecDeque, + rendered_state: VecDeque, + uid_counter: usize, +} + +impl Drop for FactoryVecDeque +where + C: FactoryComponent, +{ + fn drop(&mut self) { + self.guard().clear(); + } +} + +impl Index for FactoryVecDeque +where + C: FactoryComponent, +{ + type Output = C; + + fn index(&self, index: usize) -> &Self::Output { + self.get(index).expect("Called `get` on an invalid index") + } +} + +impl FactoryVecDeque +where + C: FactoryComponent, +{ + /// Creates a new [`FactoryVecDeque`]. + #[must_use] + pub fn new(widget: C::ParentWidget, parent_sender: &Sender) -> Self { + Self { + widget, + parent_sender: parent_sender.clone(), + components: VecDeque::new(), + model_state: VecDeque::new(), + rendered_state: VecDeque::new(), + // 0 is always an invalid uid + uid_counter: 1, + } + } + + /// Provides a [`FactoryVecDequeGuard`] that can be used to edit the factory. + /// + /// The changes will be rendered on the widgets after the guard goes out of scope. + pub fn guard(&mut self) -> FactoryVecDequeGuard<'_, C> { + FactoryVecDequeGuard::new(self) + } + + /// Updates the widgets according to the changes made to the factory. + /// All updates accumulate until this method is called and are handled + /// efficiently. + /// + /// For example, swapping two elements twice will only swap the data twice, + /// but won't cause any UI updates. + /// + /// Also, only modified elements will be updated. + fn render_changes(&mut self) { + let mut first_position_change_idx = None; + + let components = &mut self.components; + let rendered_state = &mut self.rendered_state; + for (index, state) in self.model_state.iter().enumerate() { + if state.uid == rendered_state.front().map(|r| r.uid).unwrap_or_default() { + // Remove item from previously rendered list + rendered_state.pop_front(); + + if state.changed { + // Update component + components[index].state_change_notify(); + } + } else if let Some(rendered_index) = + rendered_state.iter().position(|r| r.uid == state.uid) + { + if first_position_change_idx.is_none() { + first_position_change_idx = Some(index); + } + + // Remove item from previously rendered list + rendered_state.remove(rendered_index); + + // Detach and re-attach item + let widget = components[index].returned_widget().unwrap(); + if index == 0 { + self.widget.factory_move_start(widget); + } else { + let previous_widget = components[index - 1].returned_widget().unwrap(); + self.widget.factory_move_after(widget, previous_widget); + } + + if state.changed { + // Update component + components[index].state_change_notify(); + } + } else { + if first_position_change_idx.is_none() { + first_position_change_idx = Some(index); + } + + // The element doesn't exist yet + let comp = &components[index]; + let insert_widget = comp.widget(); + let position = C::position(comp.get(), &state.index); + let returned_widget = if index == 0 { + self.widget.factory_prepend(insert_widget, &position) + } else { + let previous_widget = components[index - 1].returned_widget().unwrap(); + self.widget + .factory_insert_after(insert_widget, &position, previous_widget) + }; + let component = components.remove(index).unwrap(); + let dyn_index = &self.model_state[index].index; + let component = component + .launch(dyn_index, returned_widget, &self.parent_sender) + .unwrap(); + components.insert(index, component); + } + } + + // Reset change tracker + self.model_state.iter_mut().for_each(|s| s.changed = false); + + // Set rendered state to the state of the model + // because everything should be up-to-date now. + self.rendered_state = self + .model_state + .iter() + .zip(components.iter()) + .map(|(s, c)| { + let mut hasher = DefaultHasher::default(); + c.returned_widget().unwrap().hash(&mut hasher); + + RenderedState { + uid: s.uid, + #[cfg(feature = "libadwaita")] + widget_hash: hasher.finish(), + } + }) + .collect(); + + if let Some(change_index) = first_position_change_idx { + for (index, comp) in components.iter().enumerate().skip(change_index) { + let position = C::position(comp.get(), &self.model_state[index].index); + self.widget + .factory_update_position(comp.returned_widget().unwrap(), &position); + } + } + } + + /// Returns the number of elements in the [`FactoryVecDeque`]. + pub fn len(&self) -> usize { + self.components.len() + } + + /// Returns true if the [`FactoryVecDeque`] is empty. + pub fn is_empty(&self) -> bool { + self.components.is_empty() + } + + /// Send a message to one of the elements. + pub fn send(&self, index: usize, msg: C::Input) { + self.components[index].send(msg); + } + + /// Send clone of a message to all of the elements. + pub fn broadcast(&self, msg: C::Input) + where + C::Input: Clone, + { + self.components.iter().for_each(|c| c.send(msg.clone())); + } + + /// Tries to get an immutable reference to + /// the model of one element. + /// + /// Returns [`None`] if `index` is invalid. + pub fn get(&self, index: usize) -> Option<&C> { + self.components.get(index).map(ComponentStorage::get) + } + + /// Provides a reference to the model of the back element. + /// + /// Returns [`None`] if the deque is empty. + pub fn back(&self) -> Option<&C> { + self.get(self.len().wrapping_sub(1)) + } + + /// Provides a reference to the model of the front element. + /// + /// Returns [`None`] if the deque is empty. + pub fn front(&self) -> Option<&C> { + self.get(0) + } + + /// Returns the widget all components are attached to. + pub const fn widget(&self) -> &C::ParentWidget { + &self.widget + } + + /// Returns an iterator over the components. + pub fn iter( + &self, + ) -> impl Iterator + DoubleEndedIterator + ExactSizeIterator + FusedIterator { + self.components.iter().map(ComponentStorage::get) + } + + /// Creates a FactoryVecDeque from any IntoIterator + pub fn from_iter( + component_iter: impl IntoIterator, + widget: C::ParentWidget, + parent_sender: &Sender, + ) -> Self { + let mut output = Self::new(widget, parent_sender); + { + let mut edit = output.guard(); + for component in component_iter { + edit.push_back(component); + } + edit.drop(); + } + output + } +} + +///Implements the Clone Trait for `FactoryVecDeque` where C is Cloneable +impl Clone for FactoryVecDeque +where + C: CloneableFactoryComponent + FactoryComponent, +{ + fn clone(&self) -> Self { + // Create a new, empty FactoryVecDeque. + let mut clone = FactoryVecDeque::new(self.widget.clone(), &self.parent_sender.clone()); + // Iterate over the items in the original FactoryVecDeque. + for item in self.iter() { + // Clone each item and push it onto the new FactoryVecDeque. + let init = C::get_init(item); + clone.guard().push_back(init); + } + // Return the new, cloned FactoryVecDeque. + clone + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/sync/component_storage.rs b/Relm4-0.6.2/relm4/src/factory/sync/component_storage.rs new file mode 100644 index 0000000..7eb9397 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/sync/component_storage.rs @@ -0,0 +1,81 @@ +use crate::factory::{FactoryComponent, FactoryView}; +use crate::Sender; + +use super::{FactoryBuilder, FactoryHandle}; + +#[derive(Debug)] +pub(super) enum ComponentStorage { + Builder(FactoryBuilder), + Final(FactoryHandle), +} + +impl ComponentStorage { + pub(super) const fn get(&self) -> &C { + match self { + Self::Builder(builder) => &builder.data, + Self::Final(handle) => handle.data.get(), + } + } + + pub(super) fn get_mut(&mut self) -> &mut C { + match self { + Self::Builder(builder) => &mut builder.data, + Self::Final(handle) => handle.data.get_mut(), + } + } + + pub(super) const fn widget(&self) -> &C::Root { + match self { + Self::Builder(builder) => &builder.root_widget, + Self::Final(handle) => &handle.root_widget, + } + } + + pub(super) fn send(&self, msg: C::Input) { + match self { + Self::Builder(builder) => builder.component_sender.input(msg), + Self::Final(handle) => handle.input.send(msg).unwrap(), + } + } + + pub(super) fn state_change_notify(&self) { + if let Self::Final(handle) = self { + handle.notifier.send(()).unwrap(); + } + } + + pub(super) fn extract(self) -> C { + match self { + Self::Builder(builder) => *builder.data, + Self::Final(handle) => handle.data.into_inner(), + } + } + + pub(super) fn launch( + self, + index: &C::Index, + returned_widget: ::ReturnedWidget, + parent_sender: &Sender, + ) -> Option { + if let Self::Builder(builder) = self { + Some(Self::Final(builder.launch( + index, + returned_widget, + parent_sender, + C::forward_to_parent, + ))) + } else { + None + } + } + + pub(super) const fn returned_widget( + &self, + ) -> Option<&::ReturnedWidget> { + if let Self::Final(handle) = self { + Some(&handle.returned_widget) + } else { + None + } + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/sync/handle.rs b/Relm4-0.6.2/relm4/src/factory/sync/handle.rs new file mode 100644 index 0000000..e53fcca --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/sync/handle.rs @@ -0,0 +1,28 @@ +use std::fmt; + +use crate::factory::{DataGuard, FactoryComponent, FactoryView}; +use crate::Sender; + +/// Don't allow public access to a [`FactoryHandle`]. +/// +/// It might be unsafe to extract `data` or `runtime`. +/// Inside this type, it is guaranteed that extracting `data` will drop `runtime` before to +/// comply with all required safety guarantees. +pub(super) struct FactoryHandle { + pub(super) data: DataGuard, + pub(super) root_widget: C::Root, + pub(super) returned_widget: ::ReturnedWidget, + pub(super) input: Sender, + pub(super) notifier: Sender<()>, +} + +impl fmt::Debug for FactoryHandle { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FactoryHandle") + .field("data", &"") + .field("root_widget", &self.root_widget) + .field("input", &self.input) + .field("notifier", &self.notifier) + .finish() + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/sync/mod.rs b/Relm4-0.6.2/relm4/src/factory/sync/mod.rs new file mode 100644 index 0000000..a5581ec --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/sync/mod.rs @@ -0,0 +1,11 @@ +mod builder; +mod collections; +mod component_storage; +mod handle; +mod traits; + +use builder::FactoryBuilder; +use handle::FactoryHandle; + +pub use collections::{FactoryHashMap, FactoryVecDeque, FactoryVecDequeGuard}; +pub use traits::{CloneableFactoryComponent, FactoryComponent}; diff --git a/Relm4-0.6.2/relm4/src/factory/sync/traits.rs b/Relm4-0.6.2/relm4/src/factory/sync/traits.rs new file mode 100644 index 0000000..869650e --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/sync/traits.rs @@ -0,0 +1,122 @@ +//! Traits for for managing and updating factories. + +use crate::factory::{FactorySender, FactoryView, Position}; +use crate::Sender; + +use std::fmt::Debug; + +/// A component that's stored inside a factory. +/// Similar to [`Component`](crate::Component) but adjusted to fit the life cycle +/// of factories. +pub trait FactoryComponent: + Position<::Position, Self::Index> + Sized + 'static +{ + /// Container widget to which all widgets of the factory will be added. + type ParentWidget: FactoryView + 'static; + + /// Input messages sent to the parent component. + type ParentInput: Debug + 'static; + + /// Messages which are received from commands executing in the background. + type CommandOutput: Debug + Send + 'static; + + /// The message type that the factory component accepts as inputs. + type Input: Debug + 'static; + + /// The message type that the factory component provides as outputs. + type Output: Debug + 'static; + + /// The parameter used to initialize the factory component. + type Init; + + /// The top-level widget of the factory component. + type Root: AsRef<::Children> + Debug + Clone; + + /// The type that's used for storing widgets created for this factory component. + type Widgets: 'static; + + /// The type that's used by a factory collection as index. + /// + /// For example, for [`FactoryVecDeque`](crate::factory::FactoryVecDeque), this type + /// is [`DynamicIndex`](crate::factory::DynamicIndex). + /// For [`FactoryHashMap`](crate::factory::FactoryHashMap), this type is equal to the key + /// you use for inserting values. + type Index; + + /// Initializes the model. + fn init_model(init: Self::Init, index: &Self::Index, sender: FactorySender) -> Self; + + /// Initializes the root widget + fn init_root(&self) -> Self::Root; + + /// Initializes the widgets. + fn init_widgets( + &mut self, + index: &Self::Index, + root: &Self::Root, + returned_widget: &::ReturnedWidget, + sender: FactorySender, + ) -> Self::Widgets; + + /// Optionally convert an output message from this component to an input message for the + /// parent component. By default this method does nothing, you must overwrite it to + /// forward messages. + /// + /// If [`None`] is returned, nothing is forwarded. + fn forward_to_parent(_output: Self::Output) -> Option { + None + } + + /// Processes inputs received by the component. + #[allow(unused)] + fn update(&mut self, message: Self::Input, sender: FactorySender) {} + + /// Defines how the component should respond to command updates. + #[allow(unused)] + fn update_cmd(&mut self, message: Self::CommandOutput, sender: FactorySender) {} + + /// Handles updates from a command. + fn update_cmd_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::CommandOutput, + sender: FactorySender, + ) { + self.update_cmd(message, sender.clone()); + self.update_view(widgets, sender); + } + + /// Updates the view after the model has been updated. + #[allow(unused)] + fn update_view(&self, widgets: &mut Self::Widgets, sender: FactorySender) {} + + /// Updates the model and view. Optionally returns a command to run. + fn update_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::Input, + sender: FactorySender, + ) { + self.update(message, sender.clone()); + self.update_view(widgets, sender); + } + + /// Last method called before a component is shut down. + #[allow(unused)] + fn shutdown(&mut self, widgets: &mut Self::Widgets, output: Sender) {} + + /// An identifier for the component used for debug logging. + /// + /// The default implementation of this method uses the address of the component, but + /// implementations are free to provide more meaningful identifiers. + fn id(&self) -> String { + format!("{:p}", &self) + } +} + +/// Extension for [`FactoryComponent`] that makes elements cloneable. +pub trait CloneableFactoryComponent: FactoryComponent { + /// Retrieve the initialization data from an initialized factory component. + /// This is necessary for cloning the factory. + fn get_init(&self) -> Self::Init; +} diff --git a/Relm4-0.6.2/relm4/src/factory/widgets/gtk.rs b/Relm4-0.6.2/relm4/src/factory/widgets/gtk.rs new file mode 100644 index 0000000..59f97f1 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/widgets/gtk.rs @@ -0,0 +1,372 @@ +use gtk::prelude::{BoxExt, Cast, FlowBoxChildExt, GridExt, ListBoxRowExt, WidgetExt}; + +use crate::factory::{positions, FactoryView}; + +impl FactoryView for gtk::Box { + type Children = gtk::Widget; + type ReturnedWidget = gtk::Widget; + type Position = (); + + fn factory_remove(&self, widget: &Self::ReturnedWidget) { + self.remove(widget); + } + + fn factory_append( + &self, + widget: impl AsRef, + _position: &(), + ) -> Self::ReturnedWidget { + self.append(widget.as_ref()); + widget.as_ref().clone() + } + + fn factory_prepend( + &self, + widget: impl AsRef, + _position: &(), + ) -> Self::ReturnedWidget { + self.prepend(widget.as_ref()); + widget.as_ref().clone() + } + + fn factory_insert_after( + &self, + widget: impl AsRef, + _position: &(), + other: &Self::ReturnedWidget, + ) -> Self::ReturnedWidget { + self.insert_child_after(widget.as_ref(), Some(other)); + widget.as_ref().clone() + } + + fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children { + returned_widget.clone() + } + + fn factory_move_after(&self, widget: &Self::ReturnedWidget, other: &Self::ReturnedWidget) { + self.reorder_child_after(widget, Some(other)); + } + + fn factory_move_start(&self, widget: &Self::ReturnedWidget) { + self.reorder_child_after(widget, None::<>k::Widget>); + } +} + +impl FactoryView for gtk::Grid { + type Children = gtk::Widget; + type ReturnedWidget = gtk::Widget; + type Position = positions::GridPosition; + + fn factory_remove(&self, widget: &Self::ReturnedWidget) { + self.remove(widget); + } + + fn factory_append( + &self, + widget: impl AsRef, + position: &Self::Position, + ) -> Self::ReturnedWidget { + self.attach( + widget.as_ref(), + position.column, + position.row, + position.width, + position.height, + ); + widget.as_ref().clone() + } + + fn factory_prepend( + &self, + widget: impl AsRef, + position: &Self::Position, + ) -> Self::ReturnedWidget { + self.factory_append(widget, position) + } + + fn factory_insert_after( + &self, + widget: impl AsRef, + position: &Self::Position, + _other: &Self::ReturnedWidget, + ) -> Self::ReturnedWidget { + self.factory_append(widget, position) + } + + fn factory_move_after(&self, _widget: &Self::ReturnedWidget, _other: &Self::ReturnedWidget) {} + + fn factory_move_start(&self, _widget: &Self::ReturnedWidget) {} + + fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children { + returned_widget.clone() + } + + fn factory_update_position(&self, widget: &Self::ReturnedWidget, position: &Self::Position) { + self.factory_remove(widget); + self.factory_append(widget, position); + } +} + +impl FactoryView for gtk::Stack { + type Children = gtk::Widget; + type ReturnedWidget = gtk::StackPage; + type Position = (); + + fn factory_remove(&self, widget: &Self::ReturnedWidget) { + self.remove(&widget.child()); + } + + fn factory_append( + &self, + widget: impl AsRef, + _position: &Self::Position, + ) -> Self::ReturnedWidget { + self.add_child(widget.as_ref()) + } + + fn factory_prepend( + &self, + widget: impl AsRef, + _position: &(), + ) -> Self::ReturnedWidget { + self.add_child(widget.as_ref()) + } + + fn factory_insert_after( + &self, + widget: impl AsRef, + _position: &(), + _other: &Self::ReturnedWidget, + ) -> Self::ReturnedWidget { + self.add_child(widget.as_ref()) + } + + fn factory_move_after(&self, _widget: &Self::ReturnedWidget, _other: &Self::ReturnedWidget) {} + + fn factory_move_start(&self, _widget: &Self::ReturnedWidget) {} + + fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children { + returned_widget.child() + } +} + +impl FactoryView for gtk::ListBox { + type Children = gtk::Widget; + type ReturnedWidget = gtk::ListBoxRow; + type Position = (); + + fn factory_remove(&self, widget: &Self::ReturnedWidget) { + widget.set_child(None::<>k::Widget>); + self.remove(widget); + } + + fn factory_append( + &self, + widget: impl AsRef, + _position: &(), + ) -> Self::ReturnedWidget { + let widget = widget.as_ref(); + + self.append(widget); + + match widget.downcast_ref::() { + Some(row) => row.clone(), + None => widget.parent().unwrap().downcast().unwrap(), + } + } + + fn factory_prepend( + &self, + widget: impl AsRef, + _position: &(), + ) -> Self::ReturnedWidget { + let widget = widget.as_ref(); + + self.prepend(widget); + + match widget.downcast_ref::() { + Some(row) => row.clone(), + None => widget.parent().unwrap().downcast().unwrap(), + } + } + + fn factory_insert_after( + &self, + widget: impl AsRef, + _position: &(), + other: &Self::ReturnedWidget, + ) -> Self::ReturnedWidget { + let widget = widget.as_ref(); + + self.insert(widget, other.index() + 1); + + match widget.downcast_ref::() { + Some(row) => row.clone(), + None => widget.parent().unwrap().downcast().unwrap(), + } + } + + fn factory_move_after(&self, widget: &Self::ReturnedWidget, other: &Self::ReturnedWidget) { + self.remove(widget); + self.insert(widget, other.index() + 1); + } + + fn factory_move_start(&self, widget: &Self::ReturnedWidget) { + self.remove(widget); + self.prepend(widget); + } + + fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children { + returned_widget + .child() + .unwrap_or_else(|| returned_widget.upcast_ref::().clone()) + } +} + +impl FactoryView for gtk::FlowBox { + type Children = gtk::Widget; + type ReturnedWidget = gtk::FlowBoxChild; + type Position = (); + + fn factory_remove(&self, widget: &Self::ReturnedWidget) { + widget.set_child(None::<>k::Widget>); + self.remove(widget); + } + + fn factory_append( + &self, + widget: impl AsRef, + _position: &(), + ) -> Self::ReturnedWidget { + let widget = widget.as_ref(); + + self.insert(widget, -1); + + match widget.downcast_ref::() { + Some(child) => child.clone(), + None => widget.parent().unwrap().downcast().unwrap(), + } + } + + fn factory_prepend( + &self, + widget: impl AsRef, + _position: &(), + ) -> Self::ReturnedWidget { + let widget = widget.as_ref(); + + self.insert(widget, 0); + + match widget.downcast_ref::() { + Some(child) => child.clone(), + None => widget.parent().unwrap().downcast().unwrap(), + } + } + + fn factory_insert_after( + &self, + widget: impl AsRef, + _position: &(), + other: &Self::ReturnedWidget, + ) -> Self::ReturnedWidget { + let widget = widget.as_ref(); + + self.insert(widget, other.index() + 1); + + match widget.downcast_ref::() { + Some(child) => child.clone(), + None => widget.parent().unwrap().downcast().unwrap(), + } + } + + fn factory_move_after(&self, widget: &Self::ReturnedWidget, other: &Self::ReturnedWidget) { + self.remove(widget); + self.insert(widget, other.index() + 1); + } + + fn factory_move_start(&self, widget: &Self::ReturnedWidget) { + self.remove(widget); + self.insert(widget, 0); + } + + fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children { + returned_widget + .child() + .unwrap_or_else(|| returned_widget.upcast_ref::().clone()) + } +} + +// impl FactoryView for gtk::TreeView { +// type Position = (); +// type Root = gtk::TreeViewColumn; + +// fn add(&self, widget: >k::TreeViewColumn, _position: &()) -> gtk::TreeViewColumn { +// self.insert_column(widget, -1); +// widget.clone() +// } + +// fn remove(&self, widget: >k::TreeViewColumn) { +// self.remove_column(widget); +// } +// } + +// impl FactoryView for gtk::Stack +// where +// Widget: glib::IsA, +// { +// type Position = StackPageInfo; +// type Root = Widget; + +// fn add(&self, widget: &Widget, position: &StackPageInfo) -> Widget { +// if let Some(title) = &position.title { +// self.add_titled(widget, position.name.as_deref(), title); +// } else { +// self.add_named(widget, position.name.as_deref()); +// } +// widget.clone() +// } + +// fn remove(&self, widget: &Widget) { +// self.remove(widget); +// } +// } + +// impl FactoryView for gtk::Fixed +// where +// Widget: glib::IsA, +// { +// type Position = FixedPosition; +// type Root = Widget; + +// fn add(&self, widget: &Widget, position: &FixedPosition) -> Widget { +// gtk::prelude::FixedExt::put(self, widget, position.x, position.y); +// widget.clone() +// } + +// fn remove(&self, widget: &Widget) { +// gtk::prelude::FixedExt::remove(self, widget); +// } +// } + +// impl FactoryView for gtk::Grid +// where +// Widget: glib::IsA, +// { +// type Position = GridPosition; +// type Root = Widget; + +// fn add(&self, widget: &Widget, position: &GridPosition) -> Widget { +// self.attach( +// widget, +// position.column, +// position.row, +// position.width, +// position.height, +// ); +// widget.clone() +// } + +// fn remove(&self, widget: &Widget) { +// GridExt::remove(self, widget); +// } +// } diff --git a/Relm4-0.6.2/relm4/src/factory/widgets/libadwaita.rs b/Relm4-0.6.2/relm4/src/factory/widgets/libadwaita.rs new file mode 100644 index 0000000..6311fb0 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/widgets/libadwaita.rs @@ -0,0 +1,300 @@ +use adw::prelude::*; + +use crate::factory::FactoryView; + +impl FactoryView for adw::TabView { + type Children = gtk::Widget; + type ReturnedWidget = adw::TabPage; + + type Position = (); + + fn factory_remove(&self, widget: &Self::ReturnedWidget) { + self.close_page(widget); + self.close_page_finish(widget, true); + } + + fn factory_append( + &self, + widget: impl AsRef, + _position: &Self::Position, + ) -> Self::ReturnedWidget { + self.append(widget.as_ref()) + } + + fn factory_prepend( + &self, + widget: impl AsRef, + _position: &(), + ) -> Self::ReturnedWidget { + self.prepend(widget.as_ref()) + } + + fn factory_insert_after( + &self, + widget: impl AsRef, + _position: &(), + other: &Self::ReturnedWidget, + ) -> Self::ReturnedWidget { + let new_position = self.page_position(other) + 1; + self.insert(widget.as_ref(), new_position) + } + + fn returned_widget_to_child(root_child: &Self::ReturnedWidget) -> Self::Children { + root_child.child() + } + + fn factory_move_after(&self, widget: &Self::ReturnedWidget, other: &Self::ReturnedWidget) { + let new_position = self.page_position(other) + 1; + if new_position == self.n_pages() { + self.reorder_last(widget); + } else { + self.reorder_page(widget, new_position); + } + } + + fn factory_move_start(&self, widget: &Self::ReturnedWidget) { + self.reorder_first(widget); + } +} + +impl FactoryView for adw::PreferencesPage { + type Children = adw::PreferencesGroup; + type ReturnedWidget = adw::PreferencesGroup; + + type Position = (); + + fn factory_remove(&self, widget: &Self::ReturnedWidget) { + self.remove(widget); + } + + fn factory_append( + &self, + widget: impl AsRef, + _position: &Self::Position, + ) -> Self::ReturnedWidget { + self.add(widget.as_ref()); + widget.as_ref().clone() + } + + fn factory_prepend( + &self, + widget: impl AsRef, + _position: &(), + ) -> Self::ReturnedWidget { + self.factory_append(widget, _position) + } + + fn factory_insert_after( + &self, + widget: impl AsRef, + _position: &(), + _other: &Self::ReturnedWidget, + ) -> Self::ReturnedWidget { + self.factory_append(widget, _position) + } + + fn returned_widget_to_child(root_child: &Self::ReturnedWidget) -> Self::Children { + root_child.clone() + } + + fn factory_move_after(&self, _widget: &Self::ReturnedWidget, _other: &Self::ReturnedWidget) {} + + fn factory_move_start(&self, _widget: &Self::ReturnedWidget) {} +} + +impl FactoryView for adw::ExpanderRow { + type Children = gtk::Widget; + type ReturnedWidget = gtk::Widget; + type Position = (); + + fn factory_remove(&self, widget: &Self::ReturnedWidget) { + self.remove(widget); + } + + fn factory_append( + &self, + widget: impl AsRef, + _: &Self::Position, + ) -> Self::ReturnedWidget { + self.add_row(widget.as_ref()); + widget.as_ref().clone() + } + + fn factory_prepend( + &self, + widget: impl AsRef, + position: &Self::Position, + ) -> Self::ReturnedWidget { + self.factory_append(widget, position) + } + + fn factory_insert_after( + &self, + widget: impl AsRef, + position: &Self::Position, + _other: &Self::ReturnedWidget, + ) -> Self::ReturnedWidget { + self.factory_append(widget, position) + } + + fn factory_move_after(&self, _widget: &Self::ReturnedWidget, _other: &Self::ReturnedWidget) {} + + fn factory_move_start(&self, _widget: &Self::ReturnedWidget) {} + + fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children { + returned_widget.clone() + } + + fn factory_update_position(&self, widget: &Self::ReturnedWidget, position: &Self::Position) { + self.factory_remove(widget); + self.factory_append(widget, position); + } +} + +impl FactoryView for adw::Carousel { + type Children = gtk::Widget; + type ReturnedWidget = gtk::Widget; + type Position = (); + + fn factory_remove(&self, widget: &Self::ReturnedWidget) { + self.remove(widget); + } + + fn factory_append( + &self, + widget: impl AsRef, + _: &Self::Position, + ) -> Self::ReturnedWidget { + self.append(widget.as_ref()); + widget.as_ref().clone() + } + + fn factory_prepend( + &self, + widget: impl AsRef, + _position: &(), + ) -> Self::ReturnedWidget { + self.prepend(widget.as_ref()); + widget.as_ref().clone() + } + + fn factory_insert_after( + &self, + widget: impl AsRef, + position: &(), + _other: &Self::ReturnedWidget, + ) -> Self::ReturnedWidget { + self.factory_append(widget.as_ref(), position); + widget.as_ref().clone() + } + + fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children { + returned_widget.clone() + } + + fn factory_move_after(&self, widget: &Self::ReturnedWidget, other: &Self::ReturnedWidget) { + for i in 0..self.n_pages() { + if self.nth_page(i).eq(other) { + self.reorder(widget, (i + 1) as i32); + return; + } + } + } + + fn factory_move_start(&self, widget: &Self::ReturnedWidget) { + self.reorder(widget, 0); + } +} + +impl FactoryView for adw::PreferencesGroup { + type Children = gtk::Widget; + type ReturnedWidget = gtk::Widget; + type Position = (); + + fn factory_remove(&self, widget: &Self::ReturnedWidget) { + self.remove(widget); + } + + fn factory_append( + &self, + widget: impl AsRef, + _: &Self::Position, + ) -> Self::ReturnedWidget { + self.add(widget.as_ref()); + widget.as_ref().clone() + } + + fn factory_prepend( + &self, + widget: impl AsRef, + _position: &(), + ) -> Self::ReturnedWidget { + self.add(widget.as_ref()); + widget.as_ref().clone() + } + + fn factory_insert_after( + &self, + widget: impl AsRef, + _position: &(), + _other: &Self::ReturnedWidget, + ) -> Self::ReturnedWidget { + self.add(widget.as_ref()); + widget.as_ref().clone() + } + + fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children { + returned_widget.clone() + } + + fn factory_move_after(&self, _widget: &Self::ReturnedWidget, _other: &Self::ReturnedWidget) {} + + fn factory_move_start(&self, _widget: &Self::ReturnedWidget) {} +} + +impl FactoryView for adw::Leaflet { + type Children = gtk::Widget; + type ReturnedWidget = adw::LeafletPage; + type Position = (); + + fn factory_remove(&self, widget: &Self::ReturnedWidget) { + self.remove(&widget.child()); + } + + fn factory_append( + &self, + widget: impl AsRef, + _position: &Self::Position, + ) -> Self::ReturnedWidget { + self.append(widget.as_ref()) + } + + fn factory_prepend( + &self, + widget: impl AsRef, + _position: &(), + ) -> Self::ReturnedWidget { + self.prepend(widget.as_ref()) + } + + fn factory_insert_after( + &self, + widget: impl AsRef, + _position: &(), + other: &Self::ReturnedWidget, + ) -> Self::ReturnedWidget { + self.insert_child_after(widget.as_ref(), Some(&other.child())) + } + + fn factory_move_after(&self, widget: &Self::ReturnedWidget, other: &Self::ReturnedWidget) { + self.reorder_child_after(&widget.child(), Some(&other.child())) + } + + fn factory_move_start(&self, widget: &Self::ReturnedWidget) { + self.reorder_child_after(&widget.child(), None::<>k::Widget>); + } + + fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children { + returned_widget.child() + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/widgets/libpanel.rs b/Relm4-0.6.2/relm4/src/factory/widgets/libpanel.rs new file mode 100644 index 0000000..2fcaede --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/widgets/libpanel.rs @@ -0,0 +1,43 @@ +use crate::factory::FactoryView; + +impl FactoryView for panel::Paned { + type Children = gtk::Widget; + type ReturnedWidget = gtk::Widget; + type Position = (); + + fn factory_remove(&self, widget: >k::Widget) { + self.remove(widget); + } + + fn factory_append(&self, widget: impl AsRef, _: &()) -> gtk::Widget { + self.append(widget.as_ref()); + widget.as_ref().clone() + } + + fn factory_prepend(&self, widget: impl AsRef, _: &()) -> gtk::Widget { + self.prepend(widget.as_ref()); + widget.as_ref().clone() + } + + fn factory_insert_after( + &self, + widget: impl AsRef, + _: &(), + other: >k::Widget, + ) -> gtk::Widget { + self.insert_after(widget.as_ref(), other); + widget.as_ref().clone() + } + + fn returned_widget_to_child(root_child: >k::Widget) -> gtk::Widget { + root_child.clone() + } + + fn factory_move_after(&self, widget: >k::Widget, other: >k::Widget) { + self.insert_after(widget, other); + } + + fn factory_move_start(&self, widget: >k::Widget) { + self.insert(0, widget); + } +} diff --git a/Relm4-0.6.2/relm4/src/factory/widgets/mod.rs b/Relm4-0.6.2/relm4/src/factory/widgets/mod.rs new file mode 100644 index 0000000..45db290 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/widgets/mod.rs @@ -0,0 +1,15 @@ +mod gtk; + +#[cfg(feature = "libadwaita")] +mod libadwaita; + +#[cfg(feature = "libpanel")] +mod libpanel; + +#[cfg(test)] +mod tests; + +/// Trait used for factories to interact with widgets. +pub mod traits; + +pub use traits::*; diff --git a/Relm4-0.6.2/relm4/src/factory/widgets/tests.rs b/Relm4-0.6.2/relm4/src/factory/widgets/tests.rs new file mode 100644 index 0000000..10f5d80 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/widgets/tests.rs @@ -0,0 +1,281 @@ +use crate::{ + factory::{positions::GridPosition, FactoryView}, + gtk, RelmIterChildrenExt, WidgetRef, +}; +use gtk::prelude::{FlowBoxChildExt, ListBoxRowExt}; + +/// Assert the exact ordering of widget children. The container must implement `RelmIterChildrenExt`. +macro_rules! assert_children { + ($container:ident: None) => { + if let Some(child) = $container.iter_children().next() { + panic!("Container expected be empty, but there is at least one child: {child:?}"); + } + }; + ($container:ident: $($child:ident),*) => { + { + let mut actual_children = $container.iter_children(); + let mut index = 0; + $( + let actual = actual_children.next(); + let expected = &$child; + if actual.as_ref().map(|widget| widget.widget_ref()) != Some(expected.widget_ref()) { + panic!( + "Children at index {index} does not match; expected: Some({expected:?}), actual: {actual:?}" + ) + } + index += 1; + )+ + if let Some(actual) = actual_children.next() { + panic!("Children at index {index} does not match; expected: None, actual: {actual:?}"); + } + } + }; +} + +#[gtk::test] +fn box_factory_view() { + let gtk_box = gtk::Box::default(); + + let widget1 = gtk::Label::default(); + let widget2 = gtk::Switch::default(); + let widget3 = gtk::Entry::default(); + + let w2 = gtk_box.factory_append(&widget2, &()); + let w3 = gtk_box.factory_insert_after(&widget3, &(), &w2); + let w1 = gtk_box.factory_prepend(&widget1, &()); + + assert_eq!(widget1, w1); + assert_eq!(widget2, w2); + assert_eq!(widget3, w3); + + assert_eq!(gtk::Box::returned_widget_to_child(&w1), widget1); + assert_eq!(gtk::Box::returned_widget_to_child(&w2), widget2); + assert_eq!(gtk::Box::returned_widget_to_child(&w3), widget3); + + assert_children!(gtk_box: w1, w2, w3); + + gtk_box.factory_move_after(&w3, &w1); + assert_children!(gtk_box: w1, w3, w2); + + gtk_box.factory_move_after(&w1, &w2); + assert_children!(gtk_box: w3, w2, w1); + + gtk_box.factory_move_start(&w2); + assert_children!(gtk_box: w2, w3, w1); + + gtk_box.factory_move_start(&w1); + assert_children!(gtk_box: w1, w2, w3); + + gtk_box.factory_remove(&w3); + assert_children!(gtk_box: w1, w2); + + gtk_box.factory_remove(&w2); + assert_children!(gtk_box: w1); + + gtk_box.factory_remove(&w1); + assert_children!(gtk_box: None); +} + +#[gtk::test] +fn grid_factory_view() { + let grid = gtk::Grid::default(); + + let widget1 = gtk::Label::default(); + let widget2 = gtk::Switch::default(); + let widget3 = gtk::Entry::default(); + + let pos1 = GridPosition { + column: 0, + row: 0, + width: 1, + height: 1, + }; + let pos2 = GridPosition { + column: 1, + row: 0, + width: 1, + height: 2, + }; + let pos3 = GridPosition { + column: 0, + row: 1, + width: 1, + height: 1, + }; + + let w2 = grid.factory_append(&widget2, &pos2); + let w3 = grid.factory_append(&widget3, &pos3); + let w1 = grid.factory_append(&widget1, &pos1); + + assert_eq!(widget1, w1); + assert_eq!(widget2, w2); + assert_eq!(widget3, w3); + + assert_eq!(gtk::Grid::returned_widget_to_child(&w1), widget1); + assert_eq!(gtk::Grid::returned_widget_to_child(&w2), widget2); + assert_eq!(gtk::Grid::returned_widget_to_child(&w3), widget3); + + assert_children!(grid: w1, w2, w3); + + grid.factory_remove(&w3); + assert_children!(grid: w1, w2); + + grid.factory_remove(&w2); + assert_children!(grid: w1); + + grid.factory_remove(&w1); + assert_children!(grid: None); +} + +#[gtk::test] +fn stack_factory_view() { + let stack = gtk::Stack::default(); + + let widget1 = gtk::Label::default(); + let widget2 = gtk::Switch::default(); + let widget3 = gtk::Entry::default(); + + let page1 = stack.factory_append(&widget1, &()); + let page2 = stack.factory_append(&widget2, &()); + let page3 = stack.factory_append(&widget3, &()); + + assert_eq!(page1.child(), widget1); + assert_eq!(page2.child(), widget2); + assert_eq!(page3.child(), widget3); + + assert_eq!(gtk::Stack::returned_widget_to_child(&page1), widget1); + assert_eq!(gtk::Stack::returned_widget_to_child(&page2), widget2); + assert_eq!(gtk::Stack::returned_widget_to_child(&page3), widget3); + + assert_children!(stack: widget1, widget2, widget3); + + stack.factory_remove(&page2); + assert_children!(stack: widget1, widget3); + + stack.factory_remove(&page3); + assert_children!(stack: widget1); + + stack.factory_remove(&page1); + assert_children!(stack: None); +} + +#[gtk::test] +fn list_box_factory_view() { + let list_box = gtk::ListBox::default(); + + let widget1 = gtk::Label::default(); + let widget2 = gtk::ListBoxRow::default(); + let widget3 = gtk::Entry::default(); + + let row2 = list_box.factory_append(&widget2, &()); + let row3 = list_box.factory_insert_after(&widget3, &(), &row2); + let row1 = list_box.factory_prepend(&widget1, &()); + + assert_eq!(row1.child().as_ref(), Some(widget1.as_ref())); + assert_eq!(row2, widget2); + assert_eq!(row3.child().as_ref(), Some(widget3.as_ref())); + + assert_eq!(gtk::ListBox::returned_widget_to_child(&row1), widget1); + assert_eq!(gtk::ListBox::returned_widget_to_child(&row2), widget2); + assert_eq!(gtk::ListBox::returned_widget_to_child(&row3), widget3); + + assert_children!(list_box: row1, row2, row3); + + list_box.factory_move_after(&row3, &row1); + assert_children!(list_box: row1, row3, row2); + + list_box.factory_move_after(&row1, &row2); + assert_children!(list_box: row3, row2, row1); + + list_box.factory_move_start(&row2); + assert_children!(list_box: row2, row3, row1); + + list_box.factory_move_start(&row1); + assert_children!(list_box: row1, row2, row3); + + list_box.factory_remove(&row3); + assert_children!(list_box: row1, row2); + + list_box.factory_remove(&row2); + assert_children!(list_box: row1); + + list_box.factory_remove(&row1); + assert_children!(list_box: None); +} + +#[gtk::test] +fn flow_box_factory_view() { + let flow_box = gtk::FlowBox::default(); + + let widget1 = gtk::Label::default(); + let widget2 = gtk::FlowBoxChild::default(); + let widget3 = gtk::Entry::default(); + + let child2 = flow_box.factory_append(&widget2, &()); + let child3 = flow_box.factory_insert_after(&widget3, &(), &child2); + let child1 = flow_box.factory_prepend(&widget1, &()); + + assert_eq!(child1.child().as_ref(), Some(widget1.as_ref())); + assert_eq!(child2, widget2); + assert_eq!(child3.child().as_ref(), Some(widget3.as_ref())); + + assert_eq!(gtk::FlowBox::returned_widget_to_child(&child1), widget1); + assert_eq!(gtk::FlowBox::returned_widget_to_child(&child2), widget2); + assert_eq!(gtk::FlowBox::returned_widget_to_child(&child3), widget3); + + assert_children!(flow_box: child1, child2, child3); + + flow_box.factory_move_after(&child3, &child1); + assert_children!(flow_box: child1, child3, child2); + + flow_box.factory_move_after(&child1, &child2); + assert_children!(flow_box: child3, child2, child1); + + flow_box.factory_move_start(&child2); + assert_children!(flow_box: child2, child3, child1); + + flow_box.factory_move_start(&child1); + assert_children!(flow_box: child1, child2, child3); + + flow_box.factory_remove(&child3); + assert_children!(flow_box: child1, child2); + + flow_box.factory_remove(&child2); + assert_children!(flow_box: child1); + + flow_box.factory_remove(&child1); + assert_children!(flow_box: None); +} + +#[gtk::test] +#[cfg(feature = "libadwaita")] +fn tab_view_factory_view() { + let tab_view = adw::TabView::default(); + + let widget1 = gtk::Label::default(); + let widget2 = gtk::Switch::default(); + let widget3 = gtk::Entry::default(); + + let page2 = tab_view.factory_append(&widget2, &()); + let page3 = tab_view.factory_insert_after(&widget3, &(), &page2); + let page1 = tab_view.factory_prepend(&widget1, &()); + + assert_eq!(page1.child(), widget1); + assert_eq!(page2.child(), widget2); + assert_eq!(page3.child(), widget3); + + assert_eq!(adw::TabView::returned_widget_to_child(&page1), widget1); + assert_eq!(adw::TabView::returned_widget_to_child(&page2), widget2); + assert_eq!(adw::TabView::returned_widget_to_child(&page3), widget3); + + assert_children!(tab_view: widget1, widget2, widget3); + + tab_view.factory_move_after(&page3, &page1); + assert_children!(tab_view: widget1, widget3, widget2); + + tab_view.factory_move_after(&page1, &page2); + assert_children!(tab_view: widget3, widget2, widget1); + + tab_view.factory_move_start(&page2); + assert_children!(tab_view: widget2, widget3, widget1); +} diff --git a/Relm4-0.6.2/relm4/src/factory/widgets/traits.rs b/Relm4-0.6.2/relm4/src/factory/widgets/traits.rs new file mode 100644 index 0000000..5e72f2a --- /dev/null +++ b/Relm4-0.6.2/relm4/src/factory/widgets/traits.rs @@ -0,0 +1,98 @@ +use gtk::prelude::IsA; +use std::fmt::Debug; + +/// A trait implemented for GTK4 widgets that allows a factory to create and remove widgets. +pub trait FactoryView: IsA { + /// The widget returned when inserting a widget. + /// + /// This doesn't matter on containers like [`gtk::Box`]. + /// However, widgets such as [`gtk::Stack`] return a [`gtk::StackPage`] + /// which might be used to set additional parameters. + /// + /// Therefore, this "returned widget" is explicitly handled here. + type ReturnedWidget: Debug + std::hash::Hash; + + /// Widget type that is attached to the container + /// and also the root of the components. + type Children: Debug + AsRef; + + /// Position type used by this widget. + /// + /// For example [`GridPosition`] for [`gtk::Grid`] or `()` for [`gtk::Box`] + /// + /// [`GridPosition`]: crate::factory::positions::GridPosition + type Position; + + /// Removes a widget. + fn factory_remove(&self, widget: &Self::ReturnedWidget); + /// Adds a new widget to self at the end. + fn factory_append( + &self, + widget: impl AsRef, + position: &Self::Position, + ) -> Self::ReturnedWidget; + + /// Add an widget to the front. + fn factory_prepend( + &self, + widget: impl AsRef, + position: &Self::Position, + ) -> Self::ReturnedWidget; + + /// Insert a widget after another widget. + fn factory_insert_after( + &self, + widget: impl AsRef, + position: &Self::Position, + other: &Self::ReturnedWidget, + ) -> Self::ReturnedWidget; + + /// Converts a returned widget to the children type. + /// + fn returned_widget_to_child(root_child: &Self::ReturnedWidget) -> Self::Children; + + /// Move an item after another item. + fn factory_move_after(&self, widget: &Self::ReturnedWidget, other: &Self::ReturnedWidget); + + /// Move an item to the start. + fn factory_move_start(&self, widget: &Self::ReturnedWidget); + + /// Update the position inside positioned containers like [`gtk::Grid`]. + fn factory_update_position(&self, _widget: &Self::ReturnedWidget, _position: &Self::Position) {} +} + +/// Returns the position of an element inside a +/// container like [`gtk::Grid`] where the position isn't +/// clearly defined by the index. +pub trait Position { + /// Returns the position. + /// + /// This function can be called very often + /// if widgets are moved a lot, so it should + /// be cheap to call. + fn position(&self, index: &Index) -> Pos; +} + +impl Position<(), I> for C { + fn position(&self, _index: &I) {} +} + +/// Returns the position of an element inside a +/// container like [`gtk::Grid`] where the position isn't +/// clearly defined by the index. +/// +/// Unlike [`Position`], this trait doesn't get access to self, +/// because the model might not be initialized when the widgets +/// are updated in the factory. +pub trait AsyncPosition { + /// Returns the position. + /// + /// This function can be called very often + /// if widgets are moved a lot, so it should + /// be cheap to call. + fn position(index: usize) -> Pos; +} + +impl AsyncPosition<()> for C { + fn position(_index: usize) {} +} diff --git a/Relm4-0.6.2/relm4/src/late_initialization.rs b/Relm4-0.6.2/relm4/src/late_initialization.rs new file mode 100644 index 0000000..3dcdc08 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/late_initialization.rs @@ -0,0 +1,29 @@ +use std::cell::RefCell; + +use fragile::Fragile; +use once_cell::sync::Lazy; + +type Callback = Box; + +static LATE_INIT: Lazy>>> = Lazy::new(Fragile::default); + +pub(super) fn register_callback(func: Callback) { + if let Some(inner) = Lazy::get(&LATE_INIT) { + // If `Lazy` was initialized and is not empty, + // this means that `run_late_init` has run already. + // In this case, we need to call the callback immediately, + // otherwise it will never be executed. + if inner.get().borrow().is_empty() { + return func(); + } + } + LATE_INIT.get().borrow_mut().push(func); +} + +pub(super) fn run_late_init() { + LATE_INIT + .get() + .borrow_mut() + .drain(..) + .for_each(|func| func()); +} diff --git a/Relm4-0.6.2/relm4/src/lib.rs b/Relm4-0.6.2/relm4/src/lib.rs new file mode 100644 index 0000000..4d7a86c --- /dev/null +++ b/Relm4-0.6.2/relm4/src/lib.rs @@ -0,0 +1,240 @@ +//! An idiomatic GUI library inspired by Elm and based on gtk4-rs. +//! +//! Docs of related crates: +//! [relm4](https://docs.rs/relm4) +//! | [relm4-macros](https://docs.rs/relm4_macros) +//! | [relm4-components](https://docs.rs/relm4_components) +//! | [gtk4-rs](https://gtk-rs.org/gtk4-rs/git/docs) +//! | [gtk-rs-core](https://gtk-rs.org/gtk-rs-core/git/docs) +//! | [libadwaita-rs](https://world.pages.gitlab.gnome.org/Rust/libadwaita-rs/git/docs/libadwaita) +//! | [libpanel-rs](https://world.pages.gitlab.gnome.org/Rust/libpanel-rs/git/docs/libpanel) +//! +//! [GitHub](https://github.com/Relm4/Relm4) +//! | [Website](https://relm4.org) +//! | [Book](https://relm4.org/book/stable/) +//! | [Blog](https://relm4.org/blog) + +#![doc(html_logo_url = "https://relm4.org/icons/relm4_logo.svg")] +#![doc(html_favicon_url = "https://relm4.org/icons/relm4_org.svg")] +#![warn( + missing_debug_implementations, + missing_docs, + rust_2018_idioms, + unreachable_pub, + unused_qualifications, + clippy::cargo, + clippy::must_use_candidate +)] +#![allow(clippy::multiple_crate_versions)] +// Configuration for doc builds on the nightly toolchain. +#![cfg_attr(docsrs, feature(doc_cfg))] + +mod app; +mod channel; +mod extensions; +pub(crate) mod late_initialization; +mod runtime_util; + +pub mod actions; +pub mod binding; +pub mod component; +pub mod drawing; +pub mod factory; +pub mod loading_widgets; +pub mod safe_settings_and_actions; +pub mod shared_state; +pub mod typed_list_view; + +pub use channel::ComponentSender; +pub use channel::*; +pub use component::worker::{Worker, WorkerController, WorkerHandle}; +pub use component::{ + Component, ComponentBuilder, ComponentController, ComponentParts, Controller, MessageBroker, + SimpleComponent, +}; +pub use extensions::*; +pub use shared_state::{Reducer, Reducible, SharedState}; +pub use shutdown::ShutdownReceiver; + +pub use app::RelmApp; +pub use tokio::task::JoinHandle; + +use gtk::prelude::{Cast, IsA}; +use once_cell::sync::{Lazy, OnceCell}; +use runtime_util::{GuardedReceiver, RuntimeSenders, ShutdownOnDrop}; +use std::cell::Cell; +use std::future::Future; +use tokio::runtime::Runtime; + +/// Defines how many threads that Relm4 should use for background tasks. +/// +/// NOTE: The default thread count is 1. +pub static RELM_THREADS: OnceCell = OnceCell::new(); + +/// Defines the maximum number of background threads to spawn for handling blocking tasks. +/// +/// NOTE: The default max is 512. +pub static RELM_BLOCKING_THREADS: OnceCell = OnceCell::new(); + +pub mod prelude; + +/// Re-export of gtk4 +pub use gtk; + +// Re-exports +#[cfg(feature = "macros")] +#[cfg_attr(docsrs, doc(cfg(feature = "macros")))] +pub use relm4_macros::*; + +#[cfg(feature = "libadwaita")] +#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))] +/// Re-export of libadwaita +pub use adw; + +#[cfg(feature = "libpanel")] +#[cfg_attr(docsrs, doc(cfg(feature = "libpanel")))] +/// Re-export of libpanel +pub use panel; + +pub use async_trait; +pub use once_cell; +pub use tokio; + +thread_local! { + static MAIN_APPLICATION: Cell> = Cell::default(); +} + +fn set_main_application(app: impl IsA) { + MAIN_APPLICATION.with(move |cell| cell.set(Some(app.upcast()))); +} + +fn init() { + gtk::init().unwrap(); + #[cfg(feature = "libadwaita")] + adw::init().unwrap(); +} + +/// Returns the global [`gtk::Application`] that's used internally +/// by [`RelmApp`]. +/// +/// Retrieving this value can be useful for graceful shutdown +/// by calling [`ApplicationExt::quit()`][gtk::prelude::ApplicationExt::quit] on it. +/// +/// Note: The global application can be overwritten by calling +/// [`RelmApp::from_app()`]. +#[must_use] +pub fn main_application() -> gtk::Application { + #[cfg(feature = "libadwaita")] + fn new_application() -> gtk::Application { + adw::Application::default().upcast() + } + + #[cfg(not(feature = "libadwaita"))] + fn new_application() -> gtk::Application { + gtk::Application::default() + } + + MAIN_APPLICATION.with(|cell| { + let app = cell.take().unwrap_or_else(new_application); + cell.set(Some(app.clone())); + app + }) +} + +#[cfg(feature = "libadwaita")] +#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))] +/// Returns the global [`adw::Application`] that's used internally +/// by [`RelmApp`] if the `libadwaita` feature is enabled. +/// +/// Note: The global application can be overwritten by calling +/// [`RelmApp::from_app()`]. +#[must_use] +pub fn main_adw_application() -> adw::Application { + main_application().downcast().unwrap() +} + +/// Sets a custom global stylesheet. +/// +/// # Panics +/// +/// This function panics if [`RelmApp::new`] wasn't called before +/// or this function is not called on the thread that also called [`RelmApp::new`]. +pub fn set_global_css(style_data: &str) { + let display = gtk::gdk::Display::default().unwrap(); + let provider = gtk::CssProvider::new(); + provider.load_from_data(style_data); + + #[allow(deprecated)] + gtk::StyleContext::add_provider_for_display( + &display, + &provider, + gtk::STYLE_PROVIDER_PRIORITY_APPLICATION, + ); +} + +/// Sets a custom global stylesheet from a file. +/// +/// If the file doesn't exist a [`tracing::error`] message will be emitted. +/// +/// # Panics +/// +/// This function panics if [`RelmApp::new`] wasn't called before +/// or this function is not called on the thread that also called [`RelmApp::new`]. +pub fn set_global_css_from_file>(path: P) { + match std::fs::read_to_string(path) { + Ok(bytes) => { + set_global_css(&bytes); + } + Err(err) => { + tracing::error!("Couldn't load global CSS from file: {}", err); + } + } +} + +/// Spawns a thread-local future on GLib's executor, for non-[`Send`] futures. +pub fn spawn_local(func: F) -> gtk::glib::JoinHandle +where + F: Future + 'static, + Out: 'static, +{ + gtk::glib::MainContext::ref_thread_default().spawn_local(func) +} + +/// Spawns a thread-local future on GLib's executor, for non-[`Send`] futures. +pub fn spawn_local_with_priority( + priority: gtk::glib::Priority, + func: F, +) -> gtk::glib::JoinHandle +where + F: Future + 'static, + Out: 'static, +{ + gtk::glib::MainContext::ref_thread_default().spawn_local_with_priority(priority, func) +} + +static RUNTIME: Lazy = Lazy::new(|| { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .worker_threads(*RELM_THREADS.get_or_init(|| 1)) + .max_blocking_threads(*RELM_BLOCKING_THREADS.get_or_init(|| 512)) + .build() + .unwrap() +}); + +/// Spawns a [`Send`]-able future to the shared component runtime. +pub fn spawn(future: F) -> JoinHandle +where + F: Future + Send + 'static, + F::Output: Send + 'static, +{ + RUNTIME.spawn(future) +} + +/// Spawns a blocking task in a background thread pool. +pub fn spawn_blocking(func: F) -> JoinHandle +where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, +{ + RUNTIME.spawn_blocking(func) +} diff --git a/Relm4-0.6.2/relm4/src/loading_widgets.rs b/Relm4-0.6.2/relm4/src/loading_widgets.rs new file mode 100644 index 0000000..78e9106 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/loading_widgets.rs @@ -0,0 +1,114 @@ +//! Utilities for removing temporary widgets from +//! async factories or components. + +use crate::RelmRemoveExt; + +trait RemoveTempChild { + fn remove(&mut self); +} + +struct TempWidgetsInner { + container: C, + children: Vec, +} + +impl RemoveTempChild for TempWidgetsInner +where + C::Child: AsRef, +{ + fn remove(&mut self) { + for child in &mut self.children { + self.container.container_remove(&child); + } + } +} + +/// A type that stores widget containers and their child +/// widgets and removes all children automatically when dropped. +/// +/// This mechanism is used by async components and factories +/// to show widgets while the async init function isn't completed. +/// Once the actual widgets are initialized, the temporary loading +/// widgets can be removed again, which is simply done with this type. +pub struct LoadingWidgets { + containers: Vec>, +} + +impl std::fmt::Debug for LoadingWidgets { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("LoadingWidgets") + .field("containers", &self.containers.len()) + .finish() + } +} + +impl Drop for LoadingWidgets { + fn drop(&mut self) { + for child in &mut self.containers { + child.remove(); + } + } +} + +impl LoadingWidgets { + fn temp_child(container: &C, children: &[W]) -> Box + where + C: RelmRemoveExt + Clone + 'static, + W: AsRef, + C::Child: Clone + AsRef, + { + let container = container.clone(); + let children = children.iter().map(|c| c.as_ref().clone()).collect(); + let temp_child: TempWidgetsInner = TempWidgetsInner { + container, + children, + }; + + Box::new(temp_child) + } + + /// Create new [`LoadingWidgets`] with one child. + pub fn new(container: &C, child: W) -> Self + where + C: RelmRemoveExt + Clone + 'static, + W: AsRef, + C::Child: Clone + AsRef, + { + Self::with_children(container, &[child]) + } + + /// Create new [`LoadingWidgets`] with multiple children. + pub fn with_children(container: &C, children: &[W]) -> Self + where + C: RelmRemoveExt + Clone + 'static, + W: AsRef, + C::Child: Clone + AsRef, + { + let temp_child = Self::temp_child(container, children); + Self { + containers: vec![temp_child], + } + } + + /// Add another child to the temporary loading widgets. + pub fn push(&mut self, container: &C, child: W) + where + C: RelmRemoveExt + Clone + 'static, + W: AsRef, + C::Child: Clone + AsRef, + { + let temp_child = Self::temp_child(container, &[child]); + self.containers.push(temp_child); + } + + /// Add many children to the temporary loading widgets. + pub fn add_many(&mut self, container: &C, children: &[W]) + where + C: RelmRemoveExt + Clone + 'static, + W: AsRef, + C::Child: Clone + AsRef, + { + let temp_child = Self::temp_child(container, children); + self.containers.push(temp_child); + } +} diff --git a/Relm4-0.6.2/relm4/src/prelude.rs b/Relm4-0.6.2/relm4/src/prelude.rs new file mode 100644 index 0000000..283b821 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/prelude.rs @@ -0,0 +1,19 @@ +//! Commonly-imported traits and types. +//! +//! Modules that contain components can glob import this module to bring all needed types and +//! traits into scope. + +pub use crate::factory::{DynamicIndex, FactoryComponent, FactorySender}; +pub use crate::{ + Component, ComponentController, ComponentParts, ComponentSender, Controller, RelmApp, + RelmWidgetExt, SimpleComponent, WidgetRef, WidgetTemplate, +}; + +#[cfg(feature = "libadwaita")] +#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))] +pub use adw; +pub use gtk; + +#[cfg(feature = "libpanel")] +#[cfg_attr(docsrs, doc(cfg(feature = "libpanel")))] +pub use panel; diff --git a/Relm4-0.6.2/relm4/src/runtime_util.rs b/Relm4-0.6.2/relm4/src/runtime_util.rs new file mode 100644 index 0000000..e683b1e --- /dev/null +++ b/Relm4-0.6.2/relm4/src/runtime_util.rs @@ -0,0 +1,218 @@ +use std::task::Poll; + +use flume::r#async::RecvStream; +use futures::{future::FusedFuture, pin_mut, Future, Stream}; +use once_cell::sync::Lazy; +use std::sync::Mutex; +use tokio::sync::mpsc; + +use crate::{ + shutdown::{self, ShutdownSender}, + Receiver, Sender, ShutdownReceiver, +}; + +/// Stores the shutdown senders of all components ever created during +/// the runtime of the application. +static SHUTDOWN_SENDERS: Lazy>>> = Lazy::new(Mutex::default); + +/// On application shutdown, components won't trigger their shutdown +/// method automatically, so we make sure they are shutdown by sending +/// a shutdown message to all components. +pub(crate) fn shutdown_all() { + let mut guard = SHUTDOWN_SENDERS.lock().unwrap(); + for sender in guard.drain(..) { + sender.blocking_send(()).ok(); + } +} + +/// A type that destroys an [`AsyncComponent`](crate::async_component::AsyncComponent) +/// as soon as it is dropped. +#[derive(Debug)] +pub(super) struct ShutdownOnDrop { + /// Sender used to indicate that the async component should shut down. + shutdown_event_sender: Option>, +} + +impl ShutdownOnDrop { + /// Creates a new [`DestroyOnDrop`] type. + /// + /// When this type is dropped, a message will be sent through the channel. + pub(crate) fn new(shutdown_event_sender: mpsc::Sender<()>) -> Self { + Self { + shutdown_event_sender: Some(shutdown_event_sender), + } + } + + pub(crate) fn deactivate(&mut self) { + self.shutdown_event_sender = None; + } +} + +impl Drop for ShutdownOnDrop { + fn drop(&mut self) { + if let Some(sender) = self.shutdown_event_sender.take() { + sender.try_send(()).ok(); + } + } +} + +pub(super) struct RuntimeSenders { + pub(super) output_sender: Sender, + pub(super) output_receiver: Receiver, + pub(super) cmd_sender: Sender, + pub(super) cmd_receiver: Receiver, + pub(super) shutdown_notifier: ShutdownSender, + pub(super) shutdown_recipient: ShutdownReceiver, + pub(super) shutdown_on_drop: ShutdownOnDrop, + pub(super) shutdown_event: ShutdownEvent, +} + +impl RuntimeSenders { + pub(super) fn new() -> Self { + // Used by this component to send events to be handled externally by the caller. + let (output_sender, output_receiver) = crate::channel::(); + + // Sends messages from commands executed from the background. + let (cmd_sender, cmd_receiver) = crate::channel::(); + + // Notifies the component's child commands that it is being shut down. + let (shutdown_notifier, shutdown_recipient) = shutdown::channel(); + + // Cannel to tell the component to shutdown. + // Use a capacity of 2 to prevent blocking when the runtime is dropped while app shutdown is running as well. + // This rare case will emit 2 messages (but certainly not more). + let (shutdown_event_sender, shutdown_event_receiver) = mpsc::channel(2); + + SHUTDOWN_SENDERS + .lock() + .unwrap() + .push(shutdown_event_sender.clone()); + + let shutdown_on_drop = ShutdownOnDrop::new(shutdown_event_sender); + let shutdown_event = ShutdownEvent::new(shutdown_event_receiver); + + Self { + output_sender, + output_receiver, + cmd_sender, + cmd_receiver, + shutdown_notifier, + shutdown_recipient, + shutdown_on_drop, + shutdown_event, + } + } +} + +/// A type that wraps around a shutdown event receiver. +/// +/// This type is a future that will only resolve if the +/// shutdown event was transmitted successfully. +/// If the runtime is detached, the receiver will resolve +/// with an error, but this catches the error and returns +/// [`Poll::Pending`] instead so the shutdown isn't triggered. +pub(super) struct ShutdownEvent { + shutdown_receiver: mpsc::Receiver<()>, + detached: bool, +} + +impl ShutdownEvent { + fn new(shutdown_receiver: mpsc::Receiver<()>) -> Self { + Self { + shutdown_receiver, + detached: false, + } + } +} + +impl Future for ShutdownEvent { + type Output = (); + + fn poll( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll { + if self.detached { + Poll::Pending + } else { + let receiver = &mut self.shutdown_receiver; + pin_mut!(receiver); + + match receiver.poll_recv(cx) { + Poll::Ready(result) => { + if result.is_some() { + Poll::Ready(()) + } else { + self.detached = true; + Poll::Pending + } + } + Poll::Pending => Poll::Pending, + } + } + } +} + +impl FusedFuture for ShutdownEvent { + fn is_terminated(&self) -> bool { + self.detached + } +} + +/// A type that wraps around receivers. +/// +/// This type is a stream that will only yield items +/// until the sender is dropped. +pub(super) struct GuardedReceiver<'a, T> +where + T: 'static, +{ + receive_stream: RecvStream<'a, T>, + sender_dropped: bool, +} + +impl<'a, T> GuardedReceiver<'a, T> +where + T: 'static, +{ + pub(super) fn new(receiver: Receiver) -> Self { + Self { + receive_stream: receiver.into_stream(), + sender_dropped: false, + } + } +} + +impl<'a, T> Future for GuardedReceiver<'a, T> +where + T: 'static, +{ + type Output = T; + + fn poll( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll { + if self.sender_dropped { + Poll::Pending + } else { + let stream = &mut self.receive_stream; + pin_mut!(stream); + + match stream.poll_next(cx) { + Poll::Ready(Some(value)) => Poll::Ready(value), + Poll::Ready(None) => { + self.sender_dropped = true; + Poll::Pending + } + Poll::Pending => Poll::Pending, + } + } + } +} + +impl<'a, T> FusedFuture for GuardedReceiver<'a, T> { + fn is_terminated(&self) -> bool { + self.sender_dropped + } +} diff --git a/Relm4-0.6.2/relm4/src/safe_settings_and_actions/extensions.rs b/Relm4-0.6.2/relm4/src/safe_settings_and_actions/extensions.rs new file mode 100644 index 0000000..a97b3dc --- /dev/null +++ b/Relm4-0.6.2/relm4/src/safe_settings_and_actions/extensions.rs @@ -0,0 +1,418 @@ +/* + * SPDX-FileCopyrightText: 2023 Eduardo Javier Alvarado Aarón + * + * SPDX-License-Identifier: (Apache-2.0 or MIT) + */ + +//! Traits that extend types that use settings or actions to make them compatible with +//! the types generated by [`safe_settings_and_actions!`](crate::safe_settings_and_actions!). + +use super::*; +use gio::prelude::{ActionExt, IsA, SettingsExt, SettingsExtManual, ToVariant}; +use gtk::{gio, glib}; + +/// Trait that extends [`gio::Action`] with action safety methods. +#[allow(unused_qualifications)] +pub trait SafeAction: gio::prelude::ActionExt { + /// Safe version of [`state`](gio::prelude::ActionExt::state) for stateful action safeties. + fn state_safe<'a, T: ActionSafety + Stateful<'a>>(&self, _safety: T) -> T::Owned { + self.state().unwrap().get().unwrap() + } + + /// Safe version of [`state`](gio::prelude::ActionExt::state) for action safeties with variants. + fn state_safe_enum WithValue<'a> + DetailableAction>(&self) -> T { + T::from_variant(&self.state().unwrap()) + } + + /// Safe version of [`connect_state_notify`](gio::prelude::ActionExt::connect_state_notify) for stateful action safeties. + fn connect_state_notify_safe(&self, callback: F) -> glib::SignalHandlerId + where + T: ActionSafety + for<'a> Stateful<'a>, + F: Fn(T, &Self, >::Mapping) + 'static, + { + self.connect_state_notify(move |this| { + callback(T::SELF, this, T::map(&this.state().unwrap())) + }) + } + + /// Safe version of [`connect_state_notify`](gio::prelude::ActionExt::connect_state_notify) for action safeties with variants. + fn connect_state_notify_safe_enum(&self, callback: F) -> glib::SignalHandlerId + where + T: for<'a> WithValue<'a> + DetailableAction, + F: Fn(&Self, T) + 'static, + { + self.connect_state_notify(move |this| { + callback(this, T::from_variant(&this.state().unwrap())) + }) + } +} + +impl> SafeAction for T {} + +/// Trait that extends [`gtk::Actionable`] with action safety methods. +pub trait SafeActionable: gtk::prelude::ActionableExt { + /// Appropriately assigns the [name][n] and [target value][t] of an action + /// according to an action safety with variants or without value nor variants. + /// + /// [n]: gtk::prelude::ActionableExt::set_action_name + /// [t]: gtk::prelude::ActionableExt::set_action_target_value + fn set_action_safe(&self, safety: T) { + // self.set_detailed_action_name(safety.detailed_action_name()); + self.set_action_name(Some(T::FULL_NAME)); + self.set_action_target_value(safety.to_variant().as_ref()); + } + + /// Appropriately assigns the [name][n] and [target value][t] of an + /// action according to an action safety with value and without variants. + /// + /// [n]: gtk::prelude::ActionableExt::set_action_name + /// [t]: gtk::prelude::ActionableExt::set_action_target_value + fn set_target_safe<'a, T: WithValue<'a>>(&self, _safety: T, target: T::Value) + where + T: ActionSafety + NotDetailable, + { + self.set_action_name(Some(T::FULL_NAME)); + self.set_action_target_value(Some(&target.to_variant())) + } +} + +impl> SafeActionable for T {} + +/// Trait that extends [`gio::ActionMap`] with action safety methods. +pub trait SafeActionMap: gio::prelude::ActionMapExt { + /// Safe version of [`lookup_action`](gio::prelude::ActionMapExt::lookup_action) for action safeties. + fn lookup_action_safe(&self, _safety: T) -> Option { + self.lookup_action(T::NAME) + } + + /// Safe version of [`remove_action`](gio::prelude::ActionMapExt::remove_action) for action safeties. + fn remove_action_safe(&self, _safety: T) { + self.remove_action(T::NAME) + } +} + +impl> SafeActionMap for T {} + +/// Trait that extends [`gtk::Application`] with action safety methods. +pub trait SafeApplication: gtk::prelude::GtkApplicationExt { + /// Safe version of [`accels_for_action`](gtk::prelude::GtkApplicationExt::accels_for_action) + /// for action safeties with variants or without value nor variants. + fn accels_for_action_safe(&self, safety: T) -> Vec { + self.accels_for_action(safety.detailed_action_name()) + } + + /// Safe version of [`set_accels_for_action`](gtk::prelude::GtkApplicationExt::set_accels_for_action) + /// for action safeties with variants or without value nor variants. + fn set_accels_for_action_safe(&self, safety: T, accels: &[&str]) { + self.set_accels_for_action(safety.detailed_action_name(), accels) + } +} + +impl> SafeApplication for T {} + +#[cfg(feature = "macros")] +/// Trait that extends [`gio::Menu`] with methods compatible with [`relm4_macros::view!`] and action safety methods. +pub trait RelmMenu: IsA { + /// Adds a menu item for an action safety with variants or without value nor variants. + fn action(&self, safety: T, label: &str); + + /// Adds a menu item for an action safety with value and without variants. + fn target<'a, T: WithValue<'a>>(&self, safety: T, target: T::Value, label: &str) + where + T: ActionSafety + NotDetailable; + + /// Adds a menu item for a detailed action name. + fn detailed(&self, action: &str, label: &str); + + /// Adds a section. + fn section(&self, model: &impl IsA, label: &str); + + /// Adds a submenu. + fn submenu(&self, model: &impl IsA, label: &str); + + /// Adds a placeholder for a widget. + fn widget(&self, label: &str); +} + +#[cfg(feature = "macros")] +impl RelmMenu for gio::Menu { + fn action(&self, safety: T, label: &str) { + // self.append(Some(label), Some(safety.detailed_action_name())); + let item = gio::MenuItem::new(Some(label), None); + item.set_action_and_target_value(Some(T::FULL_NAME), safety.to_variant().as_ref()); + self.append_item(&item); + } + + fn target<'a, T: WithValue<'a>>(&self, _safety: T, target: T::Value, label: &str) + where + T: ActionSafety, + { + let item = gio::MenuItem::new(Some(label), None); + item.set_action_and_target_value(Some(T::FULL_NAME), Some(&target.to_variant())); + self.append_item(&item); + } + + fn detailed(&self, action: &str, label: &str) { + self.append(Some(label), Some(action)); + } + + fn section(&self, model: &impl IsA, label: &str) { + self.append_section((!label.is_empty()).then_some(label), model); + } + + fn submenu(&self, model: &impl IsA, label: &str) { + self.append_submenu(Some(label), model); + } + + fn widget(&self, name: &str) { + let item = gio::MenuItem::new(None, None); + item.set_attribute_value("custom", Some(&name.to_variant())); + self.append_item(&item); + } +} + +/// Trait that extends [`gio::Settings`] with action safety methods. +pub trait SafeSettings: IsA { + /// Safe version of [`create_action`](gio::prelude::SettingsExt::create_action) + /// for action safeties with variants or without value nor variants. + fn create_action_safe(&self) -> gio::Action { + self.create_action(T::NAME) + } + + /// Safe version of [`bind`](gio::prelude::SettingsExtManual::bind) + /// for setting safeties with variants or without value nor variants. + fn bind_safe<'a, T: DetailableSetting>( + &'a self, + object: &'a impl IsA, + property: &'a str, + ) -> gio::BindingBuilder<'a> { + self.bind(T::NAME, object, property) + } + + /// Safe version of [`set`](gio::prelude::SettingsExtManual::set) for stateful setting safeties without value. + fn set_safe<'a, T: WithoutValue + Stateful<'a>>( + &self, + _safety: T, + state: T::State, + ) -> Result<(), glib::BoolError> { + self.set(T::NAME, state.to_variant()) + } + + /// Safe version of [`set_value`](gio::prelude::SettingsExt::set_value) for setting safeties with variants. + fn set_safe_enum(&self, safety: T) -> Result<(), glib::BoolError> + where + T: for<'a> WithValue<'a> + DetailableSetting, + { + self.set_value(T::NAME, &safety.to_variant().unwrap()) // NOTE could be unwrap_unchecked() + } + + /// Safe version of [`get`](gio::prelude::SettingsExtManual::get) for stateful setting safeties without value. + fn get_safe<'a, T: WithoutValue + Stateful<'a>>(&self, _safety: T) -> T::Owned { + self.get(T::NAME) + } + + /// Safe version of [`value`](gio::prelude::SettingsExt::value) for setting safeties with variants. + fn get_safe_enum WithValue<'a> + DetailableSetting>(&self) -> T { + T::from_variant(&self.value(T::NAME)) + } +} + +impl> SafeSettings for T {} + +/// Trait that extends [`gio::SimpleAction`] with action safety methods. +pub trait SafeSimpleAction: IsA { + /// Safe version of [`new`](gio::SimpleAction::new) for stateless action safeties. + fn new_safe() -> Self; + + /// Safe version of [`new_stateful`](gio::SimpleAction::new_stateful) for stateful action safeties. + fn new_stateful_safe<'a, T: ActionSafety + Stateful<'a>>(state: T::State) -> Self; + + /// Safe version of [`connect_activate`](gio::SimpleAction::connect_activate) for stateless action safeties without value. + fn connect_activate_safe(&self, callback: F) -> glib::SignalHandlerId + where + T: ActionSafety + WithoutValue + Stateless, + F: Fn(T, &Self) + 'static; + + /// Safe version of [`connect_activate`](gio::SimpleAction::connect_activate) + /// for stateless action safeties with value and without variants. + fn connect_activate_safe_with_target(&self, callback: F) -> glib::SignalHandlerId + where + T: ActionSafety + for<'a> WithValue<'a> + Stateless + NotDetailable, + F: Fn(T, &Self, >::Mapping) + 'static; + + /// Safe version of [`connect_activate`](gio::SimpleAction::connect_activate) + /// for stateful action safeties without value. + fn connect_activate_safe_with_state(&self, callback: F) -> glib::SignalHandlerId + where + T: ActionSafety + WithoutValue + for<'a> Stateful<'a>, + F: Fn(T, &Self, >::Mapping) + 'static; + + /// Safe version of [`connect_activate`](gio::SimpleAction::connect_activate) + /// to conveniently mutate state for stateful action safeties without value. + fn connect_activate_safe_with_mut_state(&self, callback: F) -> glib::SignalHandlerId + where + T: ActionSafety + WithoutValue + for<'a> Stateful<'a>, + F: Fn(T, &Self, &mut >::Owned) + 'static; + + /// Safe version of [`connect_activate`](gio::SimpleAction::connect_activate) + /// for stateful action safeties with value and without variants. + fn connect_activate_safe_with_target_and_state( + &self, + callback: F, + ) -> glib::SignalHandlerId + where + for<'a> T: ActionSafety + WithValue<'a> + Stateful<'a> + NotDetailable, + F: Fn(T, &Self, >::Mapping, >::Mapping) + 'static; + + /// Safe version of [`connect_activate`](gio::SimpleAction::connect_activate) + /// to conveniently mutate state for stateful action safeties with value and without variants. + fn connect_activate_safe_with_target_and_mut_state( + &self, + callback: F, + ) -> glib::SignalHandlerId + where + for<'a> T: ActionSafety + WithValue<'a> + Stateful<'a> + NotDetailable, + F: Fn(T, &Self, >::Mapping, &mut >::Owned) + 'static; + + /// Safe version of [`connect_activate`](gio::SimpleAction::connect_activate) + /// for action safeties with variants. + fn connect_activate_safe_enum(&self, callback: F) -> glib::SignalHandlerId + where + T: ActionSafety + for<'a> WithValue<'a> + DetailableAction, + F: Fn(&Self, T) + 'static; +} + +impl SafeSimpleAction for gio::SimpleAction { + fn new_safe() -> Self { + gio::SimpleAction::new(T::NAME, T::variant_type().as_deref()) + } + + fn new_stateful_safe<'a, T: Stateful<'a>>(state: T::State) -> Self { + gio::SimpleAction::new_stateful(T::NAME, T::variant_type().as_deref(), state.to_variant()) + } + + fn connect_activate_safe(&self, callback: F) -> glib::SignalHandlerId + where + T: ActionSafety, + F: Fn(T, &Self) + 'static, + { + self.connect_activate(move |this, _| callback(T::SELF, this)) + } + + fn connect_activate_safe_with_target(&self, callback: F) -> glib::SignalHandlerId + where + T: ActionSafety + for<'a> WithValue<'a>, + F: Fn(T, &Self, >::Mapping) + 'static, + { + self.connect_activate(move |this, variant| { + callback(T::SELF, this, T::map(variant.unwrap())) + }) + } + + fn connect_activate_safe_with_state(&self, callback: F) -> glib::SignalHandlerId + where + T: ActionSafety + for<'a> Stateful<'a>, + F: Fn(T, &Self, >::Mapping) + 'static, + { + self.connect_activate(move |this, _| { + callback(T::SELF, this, T::map(&this.state().unwrap())) + }) + } + + fn connect_activate_safe_with_mut_state(&self, callback: F) -> glib::SignalHandlerId + where + T: ActionSafety + for<'a> Stateful<'a>, + F: Fn(T, &Self, &mut >::Owned) + 'static, + { + self.connect_activate(move |this, _| { + let mut state = this.state().unwrap().get().unwrap(); + callback(T::SELF, this, &mut state); + this.set_state(state.to_variant()); + }) + } + + fn connect_activate_safe_with_target_and_state( + &self, + callback: F, + ) -> glib::SignalHandlerId + where + for<'a> T: ActionSafety + WithValue<'a> + Stateful<'a>, + F: Fn(T, &Self, >::Mapping, >::Mapping) + 'static, + { + self.connect_activate(move |this, variant| { + callback( + T::SELF, + this, + ::map(variant.unwrap()), + ::map(&this.state().unwrap()), + ) + }) + } + + fn connect_activate_safe_with_target_and_mut_state( + &self, + callback: F, + ) -> glib::SignalHandlerId + where + for<'a> T: ActionSafety + WithValue<'a> + Stateful<'a>, + F: Fn(T, &Self, >::Mapping, &mut >::Owned) + 'static, + { + self.connect_activate(move |this, variant| { + let mut state = this.state().unwrap().get().unwrap(); + callback( + T::SELF, + this, + ::map(variant.unwrap()), + &mut state, + ); + this.set_state(state.to_variant()); + }) + } + + fn connect_activate_safe_enum(&self, callback: F) -> glib::SignalHandlerId + where + T: for<'a> WithValue<'a> + DetailableAction, + F: Fn(&Self, T) + 'static, + { + self.connect_activate(move |this, variant| { + callback(this, T::from_variant(variant.unwrap())) + }) + } +} + +#[cfg(feature = "libadwaita")] +/// Trait that extends [`adw::Toast`] with action safety methods. +pub trait SafeToast { + /// Appropriately assigns the [name][n] and [target value][t] of an action + /// according to an action safety with variants or without value nor variants. + /// + /// [n]: adw::Toast::set_action_name + /// [t]: adw::Toast::set_action_target_value + fn set_action_safe(&self, safety: T); + + /// Appropriately assigns the [name][n] and [target value][t] of an + /// action according to an action safety with value and without variants. + /// + /// [n]: adw::Toast::set_action_name + /// [t]: adw::Toast::set_action_target_value + fn set_target_safe<'a, T: WithValue<'a>>(&self, _safety: T, target: T::Value) + where + T: ActionSafety + NotDetailable; +} + +#[cfg(feature = "libadwaita")] +impl SafeToast for adw::Toast { + fn set_action_safe(&self, safety: T) { + // self.set_detailed_action_name(safety.detailed_action_name()); + self.set_action_name(Some(T::FULL_NAME)); + self.set_action_target_value(safety.to_variant().as_ref()); + } + + fn set_target_safe<'a, T: WithValue<'a>>(&self, _safety: T, target: T::Value) + where + T: ActionSafety + NotDetailable, + { + self.set_action_name(Some(T::FULL_NAME)); + self.set_action_target_value(Some(&target.to_variant())) + } +} diff --git a/Relm4-0.6.2/relm4/src/safe_settings_and_actions/mod.rs b/Relm4-0.6.2/relm4/src/safe_settings_and_actions/mod.rs new file mode 100644 index 0000000..098ba5c --- /dev/null +++ b/Relm4-0.6.2/relm4/src/safe_settings_and_actions/mod.rs @@ -0,0 +1,354 @@ +/* + * SPDX-FileCopyrightText: 2023 Eduardo Javier Alvarado Aarón + * + * SPDX-License-Identifier: (Apache-2.0 or MIT) + */ + +//! Utilities to safely manage actions and settings. + +pub mod extensions; + +use gtk::glib; + +/// The basic trait for declaring setting safeties. +pub trait SettingSafety { + /// The name of the setting or action. + /// + /// The macro [`safe_settings_and_actions!`](crate::safe_settings_and_actions!) + /// automatically implements [`Display`](std::fmt::Display) using this value, + /// so it is not necessary to use it directly for logging and similar cases. + const NAME: &'static str; + + // NOTE: This method should be inside ActionSafety, but macro_rules! won't let me. + /// The `Variant` type concerning the [`Value`](WithValue::Value) of this safety. + fn variant_type() -> Option>; +} + +/// The basic trait for declaring action safeties. +pub trait ActionSafety: SettingSafety { + /// The action name plus the group, as follows: `group.name` + const FULL_NAME: &'static str; + + /// A self value. + const SELF: Self; +} + +/// A trait that extends [`SettingSafety`] for safeties without value. +/// +/// Any type that implements it must be [`DetailableSetting`] and must not implement [`WithValue`]. +pub trait WithoutValue: DetailableSetting {} + +/// A trait that extends [`SettingSafety`] for safeties with value. +/// +/// Any type that implements it must not implement [`WithoutValue`]. +pub trait WithValue<'a>: SettingSafety { + /// Type used as parameter in safe methods. + type Value: glib::ToVariant + Into; + + /// Type used to receive the value on signals. + type Mapping; + + /// Function to convert [`struct@glib::Variant`] to the [`Mapping`](WithValue::Mapping) type. + fn map(variant: &'a glib::Variant) -> Self::Mapping; +} + +/// A trait that extends [`SettingSafety`] for safeties without state. +/// +/// Any type that implements it must not implement [`Stateful`]. +pub trait Stateless: SettingSafety {} + +/// A trait that extends [`SettingSafety`] for safeties with state. +/// +/// Any type that implements it must not implement [`Stateless`]. +pub trait Stateful<'a>: SettingSafety { + /// Type used as parameter in safe methods. + type State: glib::ToVariant; + + /// Owned version of the [`State`](Stateful::State) type, used by getters or methods that mutate state. + type Owned: glib::ToVariant + glib::FromVariant; + + /// Type used to receive the state on signals. + type Mapping; + + /// Function to convert [`struct@glib::Variant`] to the [`Mapping`](Stateful::Mapping) type. + fn map(variant: &'a glib::Variant) -> Self::Mapping; +} + +/// Trait for setting or action safeties with value and without variants. +/// +/// Any type that implements it must not implement [`DetailableSetting`]. +pub trait NotDetailable: SettingSafety {} + +/// Trait for setting safeties with variants, or without value and variants. +/// +/// Detailable setting safeties facilitate settings maintenance. +/// +/// Any type that implements it must not implement [`NotDetailable`]. +/// +/// ### Example: +/// ~~~ +/// use relm4::gtk::prelude::{StaticVariantType, ToVariant}; +/// +/// relm4::safe_settings_and_actions! { +/// // Implements DetailableSetting: +/// @state(param: bool) +/// MySetting(name: "my-setting"); +/// +/// // Implements DetailableSetting: +/// @value(param: &'a str, map: ) +/// ColorScheme(name: "color-scheme") { +/// System = ("System"), +/// Light = ("Light"), +/// Dark = ("Dark"), +/// } +/// +/// // Does not implement DetailableSetting: +/// @value(param: i32) +/// NotDetailable(name: "not-detailable"); +/// } +/// ~~~ +/// See also: [`safe_settings_and_actions!`](crate::safe_settings_and_actions!), [`NotDetailable`]. +pub trait DetailableSetting: SettingSafety { + /// Function to convert [`struct@glib::Variant`] to `Self`, especially when `Self` is an `enum`. + fn from_variant(variant: &glib::Variant) -> Self + where + Self: for<'a> WithValue<'a>; + + /// Function to convert `Self` to [`struct@glib::Variant`], especially when `Self` is an `enum`. + fn to_variant(&self) -> Option; +} + +/// Trait for action safeties with variants, or without value and variants. +/// +/// Detailable action safeties facilitate keyboard accelerators and settings maintenance. +/// +/// Any type that implements it must not implement [`NotDetailable`]. +/// +/// ### Example: +/// ~~~ +/// use relm4::gtk::prelude::{StaticVariantType, ToVariant}; +/// +/// relm4::safe_settings_and_actions! { +/// // Implements DetailableAction: +/// MyAction(group: "win", name: "my-action"); +/// +/// // Implements DetailableAction: +/// @state(param: bool) +/// MySetting(group: "win", name: "my-setting"); +/// +/// // Implements DetailableAction: +/// @value(param: &'a str, map: ) +/// ColorScheme(group: "win", name: "color-scheme") { +/// System = ("System"), +/// Light = ("Light"), +/// Dark = ("Dark"), +/// } +/// +/// // Does not implement DetailableAction: +/// @value(param: i32) +/// NotDetailable(group: "win", name: "not-detailable"); +/// } +/// ~~~ +/// See also: [`safe_settings_and_actions!`](crate::safe_settings_and_actions!), [`NotDetailable`]. +pub trait DetailableAction: ActionSafety + DetailableSetting { + /// Gets the [detailed action name](https://docs.gtk.org/gio/type_func.Action.parse_detailed_name.html). + fn detailed_action_name(&self) -> &'static str; +} + +#[macro_export] +/// A macro to create unit structs or enums that implement [`SettingSafety`] / [`ActionSafety`], +/// and depending on their characteristics also implements [`WithValue`] or [`WithoutValue`], +/// [`Stateful`] or [`Stateless`], and [`DetailableSetting`] / [`DetailableAction`] or [`NotDetailable`]. +/// +/// Safeties can have a `@value`, which refers to the target value of +/// some actionable methods or to settings values, as well as a `@state`. +/// +/// `@value` and `@state` have the following parameters: +/// 1. `param`: specifies the main data type and is used as a parameter of some safe methods. It is mandatory. +/// 2. `owned`: an owned version of the param type. If not specified, the same as param is used. +/// 3. `map`: a method of [`struct@glib::Variant`] to convert it to the correct type data, used to receive the +/// `@value` or `@state` in signals, or to retrieve an enumerated variant from [`struct@glib::Variant`]. +/// +/// Unlike `param` and `owned`, `map` is specified as follows: ` ReturnType`. +/// If not specified, it falls back to: ` OwnedType`. +/// If only the method and not the return type is specified, falls back to: ` ParamType`. +/// +/// In the case of `@value` it is not necessary `owned` if `map` is specified. +/// +/// ## Example +/// ~~~ +/// use relm4::gtk::prelude::{StaticVariantType, ToVariant}; +/// +/// relm4::safe_settings_and_actions! { +/// // Action safeties must specify the group parameter. +/// UnitStruct(group: "action-group", name: "action-or-setting-name"); +/// +/// // If a lifetime is necessary, use 'a. +/// @value(param: &'a str, owned: String, map: &'a str) +/// @state(param: &'a str, owned: String, map: &'a str) +/// pub Enum(name: "setting-name") { +/// Variant = ("literal-value"), // ... Variants require @value. +/// // In the case of string literals, they must always be enclosed +/// // in parens for keyboard accelerators and settings to work. +/// } +/// } +/// ~~~ +macro_rules! safe_settings_and_actions { + (fallback! @($($foo:tt)+) ) => { $($foo)+ }; + (fallback! @($($foo:tt)+) $($bar:tt)+) => { $($bar)+ }; + + ( value: $value:literal ) => { $value }; + ( value: ( $value:literal )) => { $value }; + ( value: [ $($value:tt),+ $(,)? ]) => { &[$($crate::safe_settings_and_actions!(value: $value)),+] }; + ( value: ( $($value:tt),+ $(,)? )) => { ($($crate::safe_settings_and_actions!(value: $value)),+) }; + (detail: $value:literal ) => { $value }; + (detail: ( $value:literal )) => { concat!("'", $value, "'") }; + (detail: [ $($value:tt),+ $(,)? ]) => { concat!("[" $(,$crate::safe_settings_and_actions!(detail: $value),)','+ "]") }; + (detail: ( $($value:tt),+ $(,)? )) => { concat!("(" $(,$crate::safe_settings_and_actions!(detail: $value),)','+ ")") }; + + (setting: $name:literal;) => { + fn from_variant(_: &$crate::gtk::glib::Variant) -> Self { Self } + fn to_variant(&self) -> Option<$crate::gtk::glib::Variant> { None } + }; + (action: $group:literal $name:literal;) => { + fn detailed_action_name(&self) -> &'static str { + ::FULL_NAME + } + }; + (setting: $name:literal { $($variant:ident = $value:tt),+ $(,)? }) => { + fn from_variant(variant: &$crate::gtk::glib::Variant) -> Self { + match ::map(&variant) { + $($crate::safe_settings_and_actions!(value: $value) => Self::$variant,)+ + _ => unreachable!() + } + } + fn to_variant(&self) -> Option<$crate::gtk::glib::Variant> { + Some(match self { + $(Self::$variant => $crate::safe_settings_and_actions!(value: $value).to_variant()),+ + }) + } + }; + (action: $group:literal $name:literal { $($variant:ident = $value:tt),+ $(,)? }) => { + fn detailed_action_name(&self) -> &'static str { + match self { + $(Self::$variant => concat!($group, '.', $name, '(', $crate::safe_settings_and_actions!(detail: $value), ')')),+ + } + } + }; + + (safety! + $(#[$attr:meta])* + $(@value( + param: $target_param:ty $(, + owned: $target_owned:ty)? $(, + map: <$target_map:ident> $($target_mapping:ty)?)? $(,)? + ))? + $(@state( + param: $state_param:ty $(, + owned: $state_owned:ty)? $(, + map: <$state_map:ident> $state_mapping:ty)? $(,)? + ))? + $vis:vis $type:ident($(group: $group:literal,)? name: $name:literal $(,)?) $variants:tt + ) => { + $crate::safe_settings_and_actions!(self_type! $(#[$attr])* $vis $type $variants); + + impl $crate::safe_settings_and_actions::SettingSafety for $type { + const NAME: &'static str = $name; + fn variant_type<'a>() -> Option> { + $crate::safe_settings_and_actions!(fallback! @(None) $(Some(<$target_param>::static_variant_type()))?) + } + } + + impl std::fmt::Display for $type { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", <$type as $crate::safe_settings_and_actions::SettingSafety>::NAME) + } + } + + $(impl $crate::safe_settings_and_actions::ActionSafety for $type { + const FULL_NAME: &'static str = concat!($group, '.', $name); + const SELF: Self = $crate::safe_settings_and_actions!(self_constant! $type $variants); + })? + + $crate::safe_settings_and_actions! { fallback! + @(impl $crate::safe_settings_and_actions::WithoutValue for $type { }) + $(impl<'a> $crate::safe_settings_and_actions::WithValue<'a> for $type { + type Value = $target_param; + type Mapping = $crate::safe_settings_and_actions!(fallback! @( + $crate::safe_settings_and_actions!(fallback! @($target_param) $($target_owned)?) + ) $($($target_mapping)?)?); + + $crate::safe_settings_and_actions! { fallback! + @(fn map(variant: &'a $crate::gtk::glib::Variant) -> $crate::safe_settings_and_actions! { + fallback! @($target_param) $($target_owned)? + } { variant.get().unwrap() }) + + $(fn map(variant: &'a $crate::gtk::glib::Variant) -> Self::Mapping { + variant.$target_map().unwrap() + })? + } + })? + } + + $crate::safe_settings_and_actions! { fallback! + @(impl $crate::safe_settings_and_actions::Stateless for $type { }) + $(impl<'a> $crate::safe_settings_and_actions::Stateful<'a> for $type { + type State = $state_param; + type Owned = $crate::safe_settings_and_actions!(fallback! @($state_param) $($state_owned)?); + type Mapping = $crate::safe_settings_and_actions!(fallback! @(Self::Owned) $($state_mapping)?); + + $crate::safe_settings_and_actions! { fallback! + @(fn map(variant: &'a $crate::gtk::glib::Variant) -> $crate::safe_settings_and_actions! { + fallback! @($state_param) $($state_owned)? + } { variant.get().unwrap() }) + + $(fn map(variant: &'a $crate::gtk::glib::Variant) -> Self::Mapping { + variant.$state_map().unwrap() + })? + } + })? + } + + $crate::safe_settings_and_actions! { detailable_or_not! + $type [$($target_param)?] [$variants] + impl $crate::safe_settings_and_actions::DetailableSetting for $type { + $crate::safe_settings_and_actions!(setting: $name $variants); + } + $(impl $crate::safe_settings_and_actions::DetailableAction for $type { + $crate::safe_settings_and_actions!(action: $group $name $variants); + })? + #[allow(dead_code)] + impl $type { + $crate::safe_settings_and_actions!(value! $( + $crate::safe_settings_and_actions!(fallback! @($target_param) $($($target_mapping)?)?) + )? $variants); + } + } + }; + + (self_type! $(#[$attr:meta])* $vis:vis $type:ident;) => { $(#[$attr])* $vis struct $type; }; + (self_type! $(#[$attr:meta])* $vis:vis $type:ident { $($variant:ident = $value:tt),* $(,)? }) => { + $(#[$attr])* $vis enum $type { $($variant),* } + }; + + (self_constant! $type:ident;) => { $type }; + (self_constant! $type:ident { $variant:ident = $value:tt $(,$variants:ident = $values:tt)* $(,)? }) => { $type::$variant }; + + (detailable_or_not! $type:ty [$target:ty] [ ; ] $($impl:tt)+) => { impl $crate::safe_settings_and_actions::NotDetailable for $type { } }; + (detailable_or_not! $type:ty [ ] [ ; ] $($impl:tt)+) => { $($impl)+ }; + (detailable_or_not! $type:ty [$target:ty] [$variants:tt] $($impl:tt)+) => { $($impl)+ }; + + (value! ;) => { }; + (value! $target:ty { $($variant:ident = $value:tt),+ $(,)? }) => { + const fn value<'a>(&self) -> $target { + match self { $(Self::$variant => $crate::safe_settings_and_actions!(value: $value)),+ } + } + const fn some<'a>(&self) -> Option<$target> { + Some(match self { $(Self::$variant => $crate::safe_settings_and_actions!(value: $value)),+ }) + } + }; + + ($($(#[$attr:meta])* $(@$keyword:tt $params:tt)* $vis:vis $type:ident $naming:tt $variants:tt)*) => { + $($crate::safe_settings_and_actions!(safety! $(#[$attr])* $(@$keyword $params)* $vis $type $naming $variants);)* + }; +} diff --git a/Relm4-0.6.2/relm4/src/shared_state/mod.rs b/Relm4-0.6.2/relm4/src/shared_state/mod.rs new file mode 100644 index 0000000..91219c5 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/shared_state/mod.rs @@ -0,0 +1,9 @@ +//! Shared state that can be accessed by many components. + +mod reducer; +mod state; + +type SubscriberFn = Box bool + 'static + Send + Sync>; + +pub use reducer::{Reducer, Reducible}; +pub use state::{SharedState, SharedStateReadGuard, SharedStateWriteGuard}; diff --git a/Relm4-0.6.2/relm4/src/shared_state/reducer.rs b/Relm4-0.6.2/relm4/src/shared_state/reducer.rs new file mode 100644 index 0000000..2d6f510 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/shared_state/reducer.rs @@ -0,0 +1,264 @@ +use std::sync::{Arc, RwLock}; + +use once_cell::sync::Lazy; + +use crate::{Sender, RUNTIME}; + +use super::SubscriberFn; + +/// A trait that implements a reducer function. +/// +/// For more information, see [`Reducer`]. +pub trait Reducible { + /// The input message type used to modify the data. + type Input; + + /// Initialize the data. + fn init() -> Self; + + /// Process the input message and update the state. + /// + /// Return [`true`] to notify all subscribers. + /// Return [`false`] to ignore all subscribers. + /// + /// For example, it makes sense to return [`false`] to indicate + /// that the message had no (noteworthy) effect on the data and + /// the subscribers don't need to be notified. + fn reduce(&mut self, input: Self::Input) -> bool; +} + +struct ReducerInner { + sender: Sender, + subscribers: Arc>>>, +} + +impl Default for ReducerInner +where + Data: Reducible + Send + 'static, + Data::Input: Send, +{ + fn default() -> Self { + let (sender, receiver) = crate::channel(); + let subscribers: Arc>>> = Arc::default(); + + let rt_subscribers = subscribers.clone(); + RUNTIME.spawn(async move { + let mut data = Data::init(); + while let Some(input) = receiver.recv().await { + if data.reduce(input) { + // Remove all elements which had their senders dropped. + rt_subscribers + .write() + .unwrap() + .retain(|subscriber| subscriber(&data)); + } + } + }); + + Self { + sender, + subscribers, + } + } +} + +impl std::fmt::Debug for ReducerInner +where + Data: std::fmt::Debug + Reducible, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ReducerInner") + .field("sender", &self.sender) + .field("subscribers", &self.subscribers.try_read().map(|s| s.len())) + .finish() + } +} + +/// A type that allows you to share information across your +/// application easily. +/// +/// Reducers receive messages, update their state accordingly +/// and notify their subscribers. +/// +/// Unlike [`SharedState`](super::SharedState), this type doesn't +/// allow direct access to the internal data. +/// Instead, it updates its state after receiving messages, similar to components. +/// After the message is processed, all subscribers will be notified. +/// +/// # Example +/// +/// ``` +/// use relm4::{Reducer, Reducible}; +/// +/// struct CounterReducer(u8); +/// +/// enum CounterInput { +/// Increment, +/// Decrement, +/// } +/// +/// impl Reducible for CounterReducer { +/// type Input = CounterInput; +/// +/// fn init() -> Self { +/// Self(0) +/// } +/// +/// fn reduce(&mut self, input: Self::Input) -> bool { +/// match input { +/// CounterInput::Increment => { +/// self.0 += 1; +/// } +/// CounterInput::Decrement => { +/// self.0 -= 1; +/// } +/// } +/// true +/// } +/// } +/// +/// // Create the reducer. +/// static REDUCER: Reducer = Reducer::new(); +/// +/// // Update the reducer. +/// REDUCER.emit(CounterInput::Increment); +/// # use std::time::Duration; +/// # std::thread::sleep(Duration::from_millis(10)); +/// +/// // Create a channel and subscribe to changes. +/// let (sender, receiver) = relm4::channel(); +/// REDUCER.subscribe(&sender, |data| data.0); +/// +/// // Count up to 2. +/// REDUCER.emit(CounterInput::Increment); +/// assert_eq!(receiver.recv_sync().unwrap(), 2); +/// ``` +#[derive(Debug)] +pub struct Reducer { + inner: Lazy>, +} + +impl Reducer +where + Data: Reducible + Send + 'static, + Data::Input: Send, +{ + /// Create a new [`Reducer`] variable. + /// + /// The data will be initialized lazily on the first access. + #[must_use] + pub const fn new() -> Self { + Self { + inner: Lazy::new(ReducerInner::default), + } + } + + /// Subscribe to a [`Reducer`]. + /// Any subscriber will be notified with a message every time + /// you modify the reducer (by calling [`Self::emit()`]). + pub fn subscribe(&self, sender: &Sender, f: F) + where + F: Fn(&Data) -> Msg + 'static + Send + Sync, + Msg: Send + 'static, + { + let sender = sender.clone(); + self.inner + .subscribers + .write() + .unwrap() + .push(Box::new(move |data: &Data| { + let msg = f(data); + sender.send(msg).is_ok() + })); + } + + /// An alternative version of [`subscribe()`](Self::subscribe()) that only send a message if + /// the closure returns [`Some`]. + pub fn subscribe_optional(&self, sender: &Sender, f: F) + where + F: Fn(&Data) -> Option + 'static + Send + Sync, + Msg: Send + 'static, + { + let sender = sender.clone(); + self.inner + .subscribers + .write() + .unwrap() + .push(Box::new(move |data: &Data| { + if let Some(msg) = f(data) { + sender.send(msg).is_ok() + } else { + true + } + })); + } + + /// Sends a message to the reducer to update its state. + /// + /// If the [`Reducible::reduce()`] method returns [`true`], + /// all subscribers will be notified. + pub fn emit(&self, input: Data::Input) { + assert!( + self.inner.sender.send(input).is_ok(), + "Reducer runtime was dropped. Maybe a subscriber or the update function panicked?" + ); + } +} + +#[cfg(test)] +mod test { + use std::time::Duration; + + use super::{Reducer, Reducible}; + + struct CounterReducer(u8); + + enum CounterInput { + Increment, + Decrement, + } + + impl Reducible for CounterReducer { + type Input = CounterInput; + + fn init() -> Self { + Self(0) + } + + fn reduce(&mut self, input: Self::Input) -> bool { + match input { + CounterInput::Increment => { + self.0 += 1; + } + CounterInput::Decrement => { + self.0 -= 1; + } + } + true + } + } + + static REDUCER: Reducer = Reducer::new(); + + #[test] + fn shared_state() { + // Count up to 3 and wait for events to be processed. + REDUCER.emit(CounterInput::Increment); + REDUCER.emit(CounterInput::Increment); + REDUCER.emit(CounterInput::Increment); + std::thread::sleep(Duration::from_millis(10)); + + let (sender, receiver) = crate::channel(); + + REDUCER.subscribe(&sender, |data| data.0); + + // Count up to 4 with receiver. + REDUCER.emit(CounterInput::Increment); + assert_eq!(receiver.recv_sync().unwrap(), 4); + + // Count down to 3. + REDUCER.emit(CounterInput::Decrement); + + assert_eq!(receiver.recv_sync().unwrap(), 3); + } +} diff --git a/Relm4-0.6.2/relm4/src/shared_state/state.rs b/Relm4-0.6.2/relm4/src/shared_state/state.rs new file mode 100644 index 0000000..b99a59e --- /dev/null +++ b/Relm4-0.6.2/relm4/src/shared_state/state.rs @@ -0,0 +1,343 @@ +use std::{ + ops::{Deref, DerefMut}, + sync::{RwLock, RwLockReadGuard, RwLockWriteGuard, TryLockError}, +}; + +use once_cell::sync::Lazy; + +use crate::Sender; + +use super::SubscriberFn; + +/// A type that allows you to share information across your +/// application easily. +/// Get immutable and mutable access to the data and subscribe to changes. +/// +/// # Panics +/// +/// [`SharedState`] uses a [`RwLock`] internally. +/// If you use [`Self::read()`] and [`Self::write()`] in the same scope +/// your code might be stuck in a deadlock or panic. +pub struct SharedState { + data: Lazy>, + subscribers: Lazy>>>, +} + +impl std::fmt::Debug for SharedState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SharedState") + .field("data", &self.data) + .field("subscribers", &self.subscribers.try_read().map(|s| s.len())) + .finish() + } +} + +impl SharedState +where + Data: Default, +{ + /// Create a new [`SharedState`] variable. + /// + /// The data will be initialized lazily on the first access. + /// + /// # Example + /// + /// ``` + /// # #[derive(Default)] + /// # struct MyData; + /// use relm4::SharedState; + /// static STATE: SharedState = SharedState::new(); + /// ``` + #[must_use] + pub const fn new() -> Self { + Self { + data: Lazy::new(RwLock::default), + subscribers: Lazy::new(RwLock::default), + } + } + + /// Subscribe to a shared state type. + /// Any subscriber will be notified with a message every time + /// you modify the shared state using [`Self::get_mut()`]. + /// + /// ``` + /// use relm4::SharedState; + /// static STATE: SharedState = SharedState::new(); + /// + /// let (sender, receiver) = relm4::channel(); + /// + /// // Every time we modify the data, we will receive + /// // the updated value as a message. + /// STATE.subscribe(&sender, |data| *data); + /// + /// { + /// let mut data = STATE.write(); + /// *data += 1; + /// } + /// + /// assert_eq!(receiver.recv_sync().unwrap(), 1); + /// ``` + pub fn subscribe(&self, sender: &Sender, f: F) + where + F: Fn(&Data) -> Msg + 'static + Send + Sync, + Msg: Send + 'static, + { + let sender = sender.clone(); + self.subscribers + .write() + .unwrap() + .push(Box::new(move |data: &Data| { + let msg = f(data); + sender.send(msg).is_ok() + })); + } + + /// An alternative version of [`subscribe()`](Self::subscribe()) that only send a message if + /// the closure returns [`Some`]. + pub fn subscribe_optional(&self, sender: &Sender, f: F) + where + F: Fn(&Data) -> Option + 'static + Send + Sync, + Msg: Send + 'static, + { + let sender = sender.clone(); + self.subscribers + .write() + .unwrap() + .push(Box::new(move |data: &Data| { + if let Some(msg) = f(data) { + sender.send(msg).is_ok() + } else { + true + } + })); + } + + /// Get immutable access to the shared data. + /// + /// Returns a RAII guard which will release this thread’s shared access + /// once it is dropped. + /// + /// The calling thread will be blocked until there are no more writers + /// which hold the lock (see [`RwLock`]). + /// + /// # Panics + /// + /// This function will panic if the internal [`RwLock`] is poisoned. + /// A [`RwLock`] is poisoned whenever a writer panics while holding an exclusive lock. + /// The failure will occur immediately after the lock has been acquired. + /// + /// Also, this function might panic when called if the lock is already + /// held by the current thread. + pub fn read(&self) -> SharedStateReadGuard<'_, Data> { + SharedStateReadGuard { + inner: self.data.read().unwrap(), + } + } + + /// Get immutable access to the shared data. + /// + /// Similar to [`read`](Self::read), but doesn't block so this function simply + /// returns an [`Err`] if the data is already locked (or poisoned). + pub fn try_read( + &self, + ) -> Result, TryLockError>> { + Ok(SharedStateReadGuard { + inner: self.data.try_read()?, + }) + } + + /// Get mutable access to the shared data. + /// + /// Returns a RAII guard which will **notify all subscribers** and + /// release this thread’s shared access once it is dropped. + /// + /// This function will not return while other writers or other readers + /// currently have access to the internal lock (see [`RwLock`]). + /// + /// # Panics + /// + /// This function will panic if the internal [`RwLock`] is poisoned. + /// A [`RwLock`] is poisoned whenever a writer panics while holding an exclusive lock. + /// The failure will occur immediately after the lock has been acquired. + /// + /// Also, this function might panic when called if the lock is already + /// held by the current thread. + /// + /// # Example + /// + /// ``` + /// # use relm4::SharedState; + /// static STATE: SharedState = SharedState::new(); + /// + /// // Overwrite the current value with 1 + /// *STATE.write() = 1; + /// ``` + /// + /// # Panic example + /// + /// ```no_run + /// # use relm4::SharedState; + /// static STATE: SharedState = SharedState::new(); + /// + /// let read_guard = STATE.read(); + /// + /// // This is fine + /// let another_read_guard = STATE.read(); + /// + /// // This might panic or result in a dead lock + /// // because you cannot read and write at the same time. + /// // To solve this, drop all read guards on this thread first. + /// let another_write_guard = STATE.write(); + /// ``` + pub fn write(&self) -> SharedStateWriteGuard<'_, Data> { + let subscribers = self.subscribers.write().unwrap(); + let data = self.data.write().unwrap(); + + SharedStateWriteGuard { data, subscribers } + } + + /// Get mutable access to the shared data. + /// + /// Similar to [`write`](Self::write), but doesn't block so this function simply + /// returns an [`Err`] if the data is already locked (or poisoned). + pub fn try_write( + &self, + ) -> Result, TryLockError>> { + let data = self.data.try_write()?; + let subscribers = self.subscribers.write().unwrap(); + + Ok(SharedStateWriteGuard { data, subscribers }) + } + + /// Get mutable access to the shared data. + /// Since this call borrows the [`SharedState`] mutably, + /// no actual locking needs to take place, but the mutable + /// borrow statically guarantees no locks exist. + /// + /// **This method will not notify any subscribers!** + /// + /// # Panics + /// + /// This function will panic if the internal [`RwLock`] is poisoned. + /// A [`RwLock`] is poisoned whenever a writer panics while holding an exclusive lock. + /// The failure will occur immediately after the lock has been acquired. + pub fn get_mut(&mut self) -> &mut Data { + self.data.get_mut().unwrap() + } + + /// Get immutable access to the shared data. + /// + /// **This method will not notify any subscribers!** + /// + /// # Panics + /// + /// This function will panic if the internal [`RwLock`] is poisoned. + /// A [`RwLock`] is poisoned whenever a writer panics while holding an exclusive lock. + /// The failure will occur immediately after the lock has been acquired. + /// + /// Also, this function might panic when called if the lock is already + /// held by the current thread. + pub fn read_inner(&self) -> RwLockReadGuard<'_, Data> { + self.data.read().unwrap() + } + + /// Get mutable access to the shared data. + /// + /// **This method will not notify any subscribers!** + /// + /// # Panics + /// + /// This function will panic if the internal [`RwLock`] is poisoned. + /// A [`RwLock`] is poisoned whenever a writer panics while holding an exclusive lock. + /// The failure will occur immediately after the lock has been acquired. + /// + /// Also, this function might panic when called if the lock is already + /// held by the current thread. + pub fn write_inner(&self) -> RwLockWriteGuard<'_, Data> { + self.data.write().unwrap() + } +} + +#[derive(Debug)] +/// A guard that immutably dereferences `Data`. +pub struct SharedStateReadGuard<'a, Data> { + inner: RwLockReadGuard<'a, Data>, +} + +impl<'a, Data> Deref for SharedStateReadGuard<'a, Data> { + type Target = Data; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +/// A guard that mutably dereferences `Data`. +/// Once dropped all subscribers of the [`SharedState`] will be notified. +pub struct SharedStateWriteGuard<'a, Data> { + data: RwLockWriteGuard<'a, Data>, + subscribers: RwLockWriteGuard<'a, Vec>>, +} + +impl<'a, Data: std::fmt::Debug> std::fmt::Debug for SharedStateWriteGuard<'a, Data> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SharedStateWriteGuard") + .field("data", &self.data) + .field("subscribers", &self.subscribers.len()) + .finish() + } +} + +impl<'a, Data> Deref for SharedStateWriteGuard<'a, Data> { + type Target = Data; + + fn deref(&self) -> &Self::Target { + &self.data + } +} + +impl<'a, Data> DerefMut for SharedStateWriteGuard<'a, Data> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.data + } +} + +impl<'a, Data> Drop for SharedStateWriteGuard<'a, Data> { + // Notify subscribers + fn drop(&mut self) { + let data = &*self.data; + // Remove all elements which had their senders dropped. + self.subscribers.retain(|subscriber| subscriber(data)); + } +} + +#[cfg(test)] +mod test { + use super::SharedState; + + static STATE: SharedState = SharedState::new(); + + #[test] + fn shared_state() { + assert_eq!(*STATE.read(), 0); + + { + let mut data = STATE.write(); + *data += 1; + } + + assert_eq!(*STATE.read(), 1); + + let (sender, receiver) = crate::channel(); + + STATE.subscribe(&sender, |data| *data); + + { + let mut data = STATE.write(); + *data += 1; + } + + assert_eq!(receiver.recv_sync().unwrap(), 2); + assert_eq!(*STATE.read(), 2); + } +} diff --git a/Relm4-0.6.2/relm4/src/typed_list_view/column_view.rs b/Relm4-0.6.2/relm4/src/typed_list_view/column_view.rs new file mode 100644 index 0000000..1c16ae5 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/typed_list_view/column_view.rs @@ -0,0 +1,404 @@ +use super::*; +use gtk::{ + gio, glib, + prelude::{Cast, CastNone, IsA, ListModelExt, ObjectExt, StaticType}, +}; +use std::{ + any::Any, + cmp::Ordering, + collections::HashMap, + fmt::{Debug, Display}, + marker::PhantomData, +}; + +/// Sort function for a column. +pub type ColumnSortFn = Box Ordering + 'static>; + +/// An item of a [`TypedColumnView`]. +pub trait RelmColumn: Any { + /// The top-level widget for the list item. + type Root: IsA; + + /// The widgets created for the list item. + type Widgets; + + /// Item whose data is shown in this column. + type Item: Any; + + /// The columns created for this list item. + const COLUMN_NAME: &'static str; + + /// Construct the widgets. + fn setup(list_item: >k::ListItem) -> (Self::Root, Self::Widgets); + + /// Bind the widgets to match the data of the list item. + fn bind(_item: &mut Self::Item, _widgets: &mut Self::Widgets, _root: &mut Self::Root) {} + + /// Undo the steps of [`RelmColumn::bind()`] if necessary. + fn unbind(_item: &mut Self::Item, _widgets: &mut Self::Widgets, _root: &mut Self::Root) {} + + /// Undo the steps of [`RelmColumn::setup()`] if necessary. + fn teardown(_list_item: >k::ListItem) {} + + /// Sorter for column. + #[must_use] + fn sort_fn() -> Option> { + None + } +} + +/// Simplified trait for creating columns with only one `gtk::Label` widget per-entry (i.e. a text cell) +pub trait LabelColumn: 'static { + /// Item of the model + type Item: Any; + /// Value of the column + type Value: PartialOrd + Display; + + /// Name of the column + const COLUMN_NAME: &'static str; + /// Whether to enable the sorting for this column + const ENABLE_SORT: bool; + + /// Get the value that this column represents. + fn get_cell_value(item: &Self::Item) -> Self::Value; + /// Format the value for presentation in the text cell. + fn format_cell_value(value: &Self::Value) -> String { + value.to_string() + } +} + +impl RelmColumn for C +where + C: LabelColumn, +{ + type Root = gtk::Label; + type Widgets = (); + type Item = C::Item; + + const COLUMN_NAME: &'static str = C::COLUMN_NAME; + + fn setup(_: >k::ListItem) -> (Self::Root, Self::Widgets) { + (gtk::Label::new(None), ()) + } + + fn bind(item: &mut Self::Item, _: &mut Self::Widgets, label: &mut Self::Root) { + label.set_label(&C::format_cell_value(&C::get_cell_value(item))); + } + + fn sort_fn() -> Option> { + if C::ENABLE_SORT { + Some(Box::new(|a, b| { + let a = C::get_cell_value(a); + let b = C::get_cell_value(b); + a.partial_cmp(&b).unwrap_or(Ordering::Equal) + })) + } else { + None + } + } +} + +/// A high-level wrapper around [`gio::ListStore`], +/// [`gtk::SignalListItemFactory`] and [`gtk::ColumnView`]. +/// +/// [`TypedColumnView`] aims at keeping nearly the same functionality and +/// flexibility of the raw bindings while introducing a more idiomatic +/// and type-safe interface. +pub struct TypedColumnView { + /// The internal list view. + pub view: gtk::ColumnView, + /// The internal selection model. + pub selection_model: S, + columns: HashMap<&'static str, gtk::ColumnViewColumn>, + store: gio::ListStore, + filters: Vec, + active_model: gio::ListModel, + base_model: gio::ListModel, + _ty: PhantomData<*const T>, +} + +impl Debug for TypedColumnView +where + T: Debug, + S: Debug, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("TypedColumnView") + .field("store", &self.store) + .field("view", &self.view) + .field("filters", &">") + .field("active_model", &self.active_model) + .field("base_model", &self.base_model) + .field("selection_model", &self.selection_model) + .finish() + } +} + +impl Default for TypedColumnView +where + T: Any, + S: RelmSelectionExt, +{ + fn default() -> Self { + Self::new() + } +} + +impl TypedColumnView +where + T: Any, + S: RelmSelectionExt, +{ + /// Create a new, empty [`TypedColumnView`]. + #[must_use] + pub fn new() -> Self { + let store = gio::ListStore::new(glib::BoxedAnyObject::static_type()); + + let model: gio::ListModel = store.clone().upcast(); + + let b = gtk::SortListModel::new(Some(model), None::); + + let base_model: gio::ListModel = b.clone().upcast(); + + let selection_model = S::new_model(base_model.clone()); + let view = gtk::ColumnView::new(Some(selection_model.clone())); + b.set_sorter(view.sorter().as_ref()); + + Self { + store, + view, + columns: HashMap::new(), + filters: Vec::new(), + active_model: base_model.clone(), + base_model, + _ty: PhantomData, + selection_model, + } + } + + /// Append column to this typed view + pub fn append_column(&mut self) + where + C: RelmColumn, + { + let factory = gtk::SignalListItemFactory::new(); + factory.connect_setup(move |_, list_item| { + let list_item = list_item + .downcast_ref::() + .expect("Needs to be ListItem"); + + let (root, widgets) = C::setup(list_item); + unsafe { root.set_data("widgets", widgets) }; + list_item.set_child(Some(&root)); + }); + + #[inline] + fn modify_widgets( + list_item: &glib::Object, + f: impl FnOnce(&mut T, &mut C::Widgets, &mut C::Root), + ) where + T: Any, + C: RelmColumn, + { + let list_item = list_item + .downcast_ref::() + .expect("Needs to be ListItem"); + + let widget = list_item.child(); + + let obj = list_item.item().unwrap(); + let mut obj = get_mut_value::(&obj); + + let mut root = widget.and_downcast::().unwrap(); + + let mut widgets = unsafe { root.steal_data("widgets") }.unwrap(); + (f)(&mut *obj, &mut widgets, &mut root); + unsafe { root.set_data("widgets", widgets) }; + } + + factory.connect_bind(move |_, list_item| { + modify_widgets::(list_item.upcast_ref(), |obj, widgets, root| { + C::bind(obj, widgets, root); + }); + }); + + factory.connect_unbind(move |_, list_item| { + modify_widgets::(list_item.upcast_ref(), |obj, widgets, root| { + C::unbind(obj, widgets, root); + }); + }); + + factory.connect_teardown(move |_, list_item| { + let list_item = list_item + .downcast_ref::() + .expect("Needs to be ListItem"); + + C::teardown(list_item); + }); + + let sort_fn = C::sort_fn(); + + let c = gtk::ColumnViewColumn::new(Some(C::COLUMN_NAME), Some(factory)); + + if let Some(sort_fn) = sort_fn { + c.set_sorter(Some(>k::CustomSorter::new(move |first, second| { + let first = get_value::(first); + let second = get_value::(second); + + sort_fn(&first, &second).into() + }))) + } + + self.view.append_column(&c); + self.columns.insert(C::COLUMN_NAME, c); + } + + /// Add a function to filter the stored items. + /// Returning `false` will simply hide the item. + /// + /// Note that several filters can be added on top of each other. + pub fn add_filter bool + 'static>(&mut self, f: F) { + let filter = gtk::CustomFilter::new(move |obj| { + let value = get_value::(obj); + f(&value) + }); + let filter_model = + gtk::FilterListModel::new(Some(self.active_model.clone()), Some(filter.clone())); + self.active_model = filter_model.clone().upcast(); + self.selection_model.set_list_model(&self.active_model); + self.filters.push(Filter { + filter, + model: filter_model, + }); + } + + /// Get columns currently associated with this view. + pub fn get_columns(&self) -> &HashMap<&'static str, gtk::ColumnViewColumn> { + &self.columns + } + + /// Returns the amount of filters that were added. + pub fn filters_len(&self) -> usize { + self.filters.len() + } + + /// Set a certain filter as active or inactive. + pub fn set_filter_status(&mut self, idx: usize, active: bool) -> bool { + if let Some(filter) = self.filters.get(idx) { + if active { + filter.model.set_filter(Some(&filter.filter)); + } else { + filter.model.set_filter(None::<>k::CustomFilter>); + } + true + } else { + false + } + } + + /// Remove the last filter. + pub fn pop_filter(&mut self) { + let filter = self.filters.pop(); + if let Some(filter) = filter { + self.active_model = filter.model.model().unwrap(); + self.selection_model.set_list_model(&self.active_model); + } + } + + /// Remove all filters. + pub fn clear_filters(&mut self) { + self.filters.clear(); + self.active_model = self.base_model.clone(); + self.selection_model.set_list_model(&self.active_model); + } + + /// Add a new item at the end of the list. + pub fn append(&mut self, value: T) { + self.store.append(&glib::BoxedAnyObject::new(value)); + } + + /// Add new items from an iterator the the end of the list. + pub fn extend_from_iter>(&mut self, init: I) { + let objects: Vec = + init.into_iter().map(glib::BoxedAnyObject::new).collect(); + self.store.extend_from_slice(&objects); + } + + #[cfg(feature = "gnome_43")] + #[cfg_attr(docsrs, doc(cfg(feature = "gnome_43")))] + /// Find the index of the first item that matches a certain function. + pub fn find bool>(&self, mut equal_func: F) -> Option { + self.store.find_with_equal_func(move |obj| { + let value = get_value::(obj); + equal_func(&value) + }) + } + + /// Returns true if the list is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Returns the length of the list (without filters). + pub fn len(&self) -> u32 { + self.store.n_items() + } + + /// Get the [`TypedListItem`] at the specified position. + /// + /// Returns [`None`] if the position is invalid. + pub fn get(&self, position: u32) -> Option> { + if let Some(obj) = self.store.item(position) { + let wrapper = obj.downcast::().unwrap(); + Some(TypedListItem::new(wrapper)) + } else { + None + } + } + + /// Get the visible [`TypedListItem`] at the specified position, + /// (the item at the given position after filtering and sorting). + /// + /// Returns [`None`] if the position is invalid. + pub fn get_visible(&self, position: u32) -> Option> { + if let Some(obj) = self.active_model.item(position) { + let wrapper = obj.downcast::().unwrap(); + Some(TypedListItem::new(wrapper)) + } else { + None + } + } + + /// Insert an item at a specific position. + pub fn insert(&mut self, position: u32, value: T) { + self.store + .insert(position, &glib::BoxedAnyObject::new(value)); + } + + /// Insert an item into the list and calculate its position from + /// a sorting function. + pub fn insert_sorted(&self, value: T, mut compare_func: F) -> u32 + where + F: FnMut(&T, &T) -> Ordering, + { + let item = glib::BoxedAnyObject::new(value); + + let compare = move |first: &glib::Object, second: &glib::Object| -> Ordering { + let first = get_value::(first); + let second = get_value::(second); + compare_func(&first, &second) + }; + + self.store.insert_sorted(&item, compare) + } + + /// Remove an item at a specific position. + pub fn remove(&mut self, position: u32) { + self.store.remove(position); + } + + /// Remove all items. + pub fn clear(&mut self) { + self.store.remove_all(); + } +} diff --git a/Relm4-0.6.2/relm4/src/typed_list_view/mod.rs b/Relm4-0.6.2/relm4/src/typed_list_view/mod.rs new file mode 100644 index 0000000..a1ece31 --- /dev/null +++ b/Relm4-0.6.2/relm4/src/typed_list_view/mod.rs @@ -0,0 +1,444 @@ +//! Idiomatic and high-level abstraction over [`gtk::ListView`]. + +mod column_view; +mod relm_selection_ext; + +use std::{ + any::Any, + cell::{Ref, RefMut}, + cmp::Ordering, + marker::PhantomData, +}; + +use gtk::{ + gio, glib, + prelude::{Cast, CastNone, IsA, ListModelExt, ObjectExt, StaticType}, +}; + +use relm_selection_ext::RelmSelectionExt; + +pub use column_view::{ColumnSortFn, LabelColumn, RelmColumn, TypedColumnView}; + +pub(crate) fn get_value(obj: &glib::Object) -> Ref<'_, T> { + let wrapper = obj.downcast_ref::().unwrap(); + wrapper.borrow() +} + +pub(crate) fn get_mut_value(obj: &glib::Object) -> RefMut<'_, T> { + let wrapper = obj.downcast_ref::().unwrap(); + wrapper.borrow_mut() +} + +/// An item of a [`TypedListView`]. +pub trait RelmListItem: Any { + /// The top-level widget for the list item. + type Root: IsA; + + /// The widgets created for the list item. + type Widgets; + + /// Construct the widgets. + fn setup(list_item: >k::ListItem) -> (Self::Root, Self::Widgets); + + /// Bind the widgets to match the data of the list item. + fn bind(&mut self, _widgets: &mut Self::Widgets, _root: &mut Self::Root) {} + + /// Undo the steps of [`RelmListItem::bind()`] if necessary. + fn unbind(&mut self, _widgets: &mut Self::Widgets, _root: &mut Self::Root) {} + + /// Undo the steps of [`RelmListItem::setup()`] if necessary. + fn teardown(_list_item: >k::ListItem) {} +} + +/// A high-level wrapper around [`gio::ListStore`], +/// [`gtk::SignalListItemFactory`] and [`gtk::ListView`]. +/// +/// [`TypedListView`] aims at keeping nearly the same functionality and +/// flexibility of the raw bindings while introducing a more idiomatic +/// and type-safe interface. +pub struct TypedListView { + /// The internal list view. + pub view: gtk::ListView, + /// The internal selection model. + pub selection_model: S, + store: gio::ListStore, + filters: Vec, + active_model: gio::ListModel, + base_model: gio::ListModel, + _ty: PhantomData<*const T>, +} + +impl std::fmt::Debug for TypedListView { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("TypedListView") + .field("store", &self.store) + .field("view", &self.view) + .field("filters", &">") + .field("active_model", &self.active_model) + .field("base_model", &self.base_model) + .field("selection_model", &self.selection_model) + .finish() + } +} + +impl TypedListView +where + T: RelmListItem + Ord, + S: RelmSelectionExt, +{ + /// Create a new [`TypedListView`] that sorts the items + /// based on the [`Ord`] trait. + #[must_use] + pub fn with_sorting() -> Self { + Self::init(Some(Box::new(T::cmp))) + } +} + +struct Filter { + filter: gtk::CustomFilter, + model: gtk::FilterListModel, +} + +type OrdFn = Option Ordering>>; + +impl Default for TypedListView +where + T: RelmListItem, + S: RelmSelectionExt, +{ + fn default() -> Self { + Self::new() + } +} + +impl TypedListView +where + T: RelmListItem, + S: RelmSelectionExt, +{ + /// Create a new, empty [`TypedListView`]. + #[must_use] + pub fn new() -> Self { + Self::init(None) + } + + fn init(sort_fn: OrdFn) -> Self { + let store = gio::ListStore::new(glib::BoxedAnyObject::static_type()); + + let factory = gtk::SignalListItemFactory::new(); + factory.connect_setup(move |_, list_item| { + let list_item = list_item + .downcast_ref::() + .expect("Needs to be ListItem"); + + let (root, widgets) = T::setup(list_item); + unsafe { root.set_data("widgets", widgets) }; + list_item.set_child(Some(&root)); + }); + + factory.connect_bind(move |_, list_item| { + let list_item = list_item + .downcast_ref::() + .expect("Needs to be ListItem"); + + let widget = list_item + .downcast_ref::() + .expect("Needs to be ListItem") + .child(); + + let obj = list_item.item().unwrap(); + let mut obj = get_mut_value::(&obj); + + let mut root = widget.and_downcast::().unwrap(); + + let mut widgets = unsafe { root.steal_data("widgets") }.unwrap(); + obj.bind(&mut widgets, &mut root); + unsafe { root.set_data("widgets", widgets) }; + }); + + factory.connect_unbind(move |_, list_item| { + let list_item = list_item + .downcast_ref::() + .expect("Needs to be ListItem"); + + let widget = list_item + .downcast_ref::() + .expect("Needs to be ListItem") + .child(); + + let obj = list_item.item().unwrap(); + let mut obj = get_mut_value::(&obj); + + let mut root = widget.and_downcast::().unwrap(); + + let mut widgets = unsafe { root.steal_data("widgets") }.unwrap(); + obj.unbind(&mut widgets, &mut root); + unsafe { root.set_data("widgets", widgets) }; + }); + + factory.connect_teardown(move |_, list_item| { + let list_item = list_item + .downcast_ref::() + .expect("Needs to be ListItem"); + + T::teardown(list_item); + }); + + let model: gio::ListModel = store.clone().upcast(); + + let base_model = if let Some(sort_fn) = sort_fn { + let sorter = gtk::CustomSorter::new(move |first, second| { + let first = get_value::(first); + let second = get_value::(second); + match sort_fn(&first, &second) { + Ordering::Less => gtk::Ordering::Smaller, + Ordering::Equal => gtk::Ordering::Equal, + Ordering::Greater => gtk::Ordering::Larger, + } + }); + + gtk::SortListModel::new(Some(model), Some(sorter)).upcast() + } else { + model + }; + + let selection_model = S::new_model(base_model.clone()); + let view = gtk::ListView::new(Some(selection_model.clone()), Some(factory)); + + Self { + store, + view, + filters: Vec::new(), + active_model: base_model.clone(), + base_model, + _ty: PhantomData, + selection_model, + } + } + + /// Add a function to filter the stored items. + /// Returning `false` will simply hide the item. + /// + /// Note that several filters can be added on top of each other. + pub fn add_filter bool + 'static>(&mut self, f: F) { + let filter = gtk::CustomFilter::new(move |obj| { + let value = get_value::(obj); + f(&value) + }); + let filter_model = + gtk::FilterListModel::new(Some(self.active_model.clone()), Some(filter.clone())); + self.active_model = filter_model.clone().upcast(); + self.selection_model.set_list_model(&self.active_model); + self.filters.push(Filter { + filter, + model: filter_model, + }); + } + + /// Returns the amount of filters that were added. + pub fn filters_len(&self) -> usize { + self.filters.len() + } + + /// Set a certain filter as active or inactive. + pub fn set_filter_status(&mut self, idx: usize, active: bool) -> bool { + if let Some(filter) = self.filters.get(idx) { + if active { + filter.model.set_filter(Some(&filter.filter)); + } else { + filter.model.set_filter(None::<>k::CustomFilter>); + } + true + } else { + false + } + } + + /// Remove the last filter. + pub fn pop_filter(&mut self) { + let filter = self.filters.pop(); + if let Some(filter) = filter { + self.active_model = filter.model.model().unwrap(); + self.selection_model.set_list_model(&self.active_model); + } + } + + /// Remove all filters. + pub fn clear_filters(&mut self) { + self.filters.clear(); + self.active_model = self.base_model.clone(); + self.selection_model.set_list_model(&self.active_model); + } + + /// Add a new item at the end of the list. + pub fn append(&mut self, value: T) { + self.store.append(&glib::BoxedAnyObject::new(value)); + } + + /// Add new items from an iterator the the end of the list. + pub fn extend_from_iter>(&mut self, init: I) { + let objects: Vec = + init.into_iter().map(glib::BoxedAnyObject::new).collect(); + self.store.extend_from_slice(&objects); + } + + #[cfg(feature = "gnome_43")] + #[cfg_attr(docsrs, doc(cfg(feature = "gnome_43")))] + /// Find the index of the first item that matches a certain function. + pub fn find bool>(&self, mut equal_func: F) -> Option { + self.store.find_with_equal_func(move |obj| { + let value = get_value::(obj); + equal_func(&value) + }) + } + + /// Returns true if the list is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Returns the length of the list (without filters). + pub fn len(&self) -> u32 { + self.store.n_items() + } + + /// Get the [`TypedListItem`] at the specified position. + /// + /// Returns [`None`] if the position is invalid. + pub fn get(&self, position: u32) -> Option> { + if let Some(obj) = self.store.item(position) { + let wrapper = obj.downcast::().unwrap(); + Some(TypedListItem::new(wrapper)) + } else { + None + } + } + + /// Get the visible [`TypedListItem`] at the specified position, + /// (the item at the given position after filtering and sorting). + /// + /// Returns [`None`] if the position is invalid. + pub fn get_visible(&self, position: u32) -> Option> { + if let Some(obj) = self.active_model.item(position) { + let wrapper = obj.downcast::().unwrap(); + Some(TypedListItem::new(wrapper)) + } else { + None + } + } + + /// Insert an item at a specific position. + pub fn insert(&mut self, position: u32, value: T) { + self.store + .insert(position, &glib::BoxedAnyObject::new(value)); + } + + /// Insert an item into the list and calculate its position from + /// a sorting function. + pub fn insert_sorted Ordering>( + &self, + value: T, + mut compare_func: F, + ) -> u32 { + let item = glib::BoxedAnyObject::new(value); + + let compare = move |first: &glib::Object, second: &glib::Object| -> Ordering { + let first = get_value::(first); + let second = get_value::(second); + compare_func(&first, &second) + }; + + self.store.insert_sorted(&item, compare) + } + + /// Remove an item at a specific position. + pub fn remove(&mut self, position: u32) { + self.store.remove(position); + } + + /// Remove all items. + pub fn clear(&mut self) { + self.store.remove_all(); + } +} + +/// And item of a [`TypedListView`]. +/// +/// The interface is very similar to [`std::cell::RefCell`]. +/// Ownership is calculated at runtime, so you have to borrow the +/// value explicitly which might panic if done incorrectly. +#[derive(Debug, Clone)] +pub struct TypedListItem { + inner: glib::BoxedAnyObject, + _ty: PhantomData<*const T>, +} + +impl TypedListItem { + fn new(inner: glib::BoxedAnyObject) -> Self { + Self { + inner, + _ty: PhantomData, + } + } + + /* + // rustdoc-stripper-ignore-next + /// Immutably borrows the wrapped value, returning an error if the value is currently mutably + /// borrowed or if it's not of type `T`. + /// + /// The borrow lasts until the returned `Ref` exits scope. Multiple immutable borrows can be + /// taken out at the same time. + /// + /// This is the non-panicking variant of [`borrow`](#method.borrow). + pub fn try_borrow(&self) -> Result, BorrowError> { + self.inner.try_borrow() + } + + // rustdoc-stripper-ignore-next + /// Mutably borrows the wrapped value, returning an error if the value is currently borrowed. + /// or if it's not of type `T`. + /// + /// The borrow lasts until the returned `RefMut` or all `RefMut`s derived + /// from it exit scope. The value cannot be borrowed while this borrow is + /// active. + /// + /// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut). + pub fn try_borrow_mut(&mut self) -> Result, BorrowMutError> { + self.inner.try_borrow_mut() + } */ + + // rustdoc-stripper-ignore-next + /// Immutably borrows the wrapped value. + /// + /// The borrow lasts until the returned `Ref` exits scope. Multiple + /// immutable borrows can be taken out at the same time. + /// + /// # Panics + /// + /// Panics if the value is currently mutably borrowed. + /// + /// For a non-panicking variant, use + /// [`try_borrow`](#method.try_borrow). + #[must_use] + pub fn borrow(&self) -> Ref<'_, T> { + self.inner.borrow() + } + + // rustdoc-stripper-ignore-next + /// Mutably borrows the wrapped value. + /// + /// The borrow lasts until the returned `RefMut` or all `RefMut`s derived + /// from it exit scope. The value cannot be borrowed while this borrow is + /// active. + /// + /// # Panics + /// + /// Panics if the value is currently borrowed. + /// + /// For a non-panicking variant, use + /// [`try_borrow_mut`](#method.try_borrow_mut). + #[must_use] + pub fn borrow_mut(&self) -> RefMut<'_, T> { + self.inner.borrow_mut() + } +} diff --git a/Relm4-0.6.2/relm4/src/typed_list_view/relm_selection_ext.rs b/Relm4-0.6.2/relm4/src/typed_list_view/relm_selection_ext.rs new file mode 100644 index 0000000..e8d470a --- /dev/null +++ b/Relm4-0.6.2/relm4/src/typed_list_view/relm_selection_ext.rs @@ -0,0 +1,23 @@ +use gtk::{gio, prelude::IsA}; + +pub trait RelmSelectionExt: IsA { + fn new_model(model: gio::ListModel) -> Self; + fn set_list_model(&mut self, model: &gio::ListModel); +} + +macro_rules! impl_selection ( + ($ty:ty) => { + impl RelmSelectionExt for $ty { + fn new_model(model: gio::ListModel) -> Self { + Self::new(Some(model)) + } + fn set_list_model(&mut self, model: &gio::ListModel) { + self.set_model(Some(model)); + } + } + } +); + +impl_selection!(gtk::SingleSelection); +impl_selection!(gtk::MultiSelection); +impl_selection!(gtk::NoSelection); diff --git a/Relm4-0.6.2/relm4/tests/drop_after_quit.rs b/Relm4-0.6.2/relm4/tests/drop_after_quit.rs new file mode 100644 index 0000000..cff8cd0 --- /dev/null +++ b/Relm4-0.6.2/relm4/tests/drop_after_quit.rs @@ -0,0 +1,49 @@ +use std::sync::atomic::{AtomicBool, Ordering}; + +use gtk::prelude::*; +use relm4::{main_application, prelude::*}; + +static APP_DROPPED: AtomicBool = AtomicBool::new(false); + +struct App; + +impl Drop for App { + fn drop(&mut self) { + APP_DROPPED.store(true, Ordering::SeqCst); + } +} + +#[relm4::component] +impl SimpleComponent for App { + type Init = (); + type Input = (); + type Output = (); + + view! { + gtk::Window {} + } + + fn init( + _init: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = App; + let widgets = view_output!(); + + sender.input(()); + + ComponentParts { model, widgets } + } + + fn update(&mut self, _msg: Self::Input, _sender: ComponentSender) { + main_application().quit(); + } +} + +#[test] +fn drop_after_quit() { + let app = RelmApp::new("relm4.test.dropAfterQuit"); + app.run::(()); + assert!(APP_DROPPED.load(Ordering::SeqCst)); +} diff --git a/Relm4-0.6.2/relm4/tests/shutdown_after_quit.rs b/Relm4-0.6.2/relm4/tests/shutdown_after_quit.rs new file mode 100644 index 0000000..542a5e7 --- /dev/null +++ b/Relm4-0.6.2/relm4/tests/shutdown_after_quit.rs @@ -0,0 +1,47 @@ +use std::sync::atomic::{AtomicBool, Ordering}; + +use gtk::prelude::*; +use relm4::{main_application, prelude::*}; + +static SHUTDOWN_CALLED: AtomicBool = AtomicBool::new(false); + +struct App; + +#[relm4::component] +impl SimpleComponent for App { + type Init = (); + type Input = (); + type Output = (); + + view! { + gtk::Window {} + } + + fn init( + _init: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = App; + let widgets = view_output!(); + + sender.input(()); + + ComponentParts { model, widgets } + } + + fn update(&mut self, _msg: Self::Input, _sender: ComponentSender) { + main_application().quit(); + } + + fn shutdown(&mut self, _widgets: &mut Self::Widgets, _output: relm4::Sender) { + SHUTDOWN_CALLED.store(true, Ordering::SeqCst); + } +} + +#[test] +fn shutdown_after_quit() { + let app = RelmApp::new("relm4.test.shutdownAfterQuit"); + app.run::(()); + assert!(SHUTDOWN_CALLED.load(Ordering::SeqCst)); +} diff --git a/Relm4-0.6.2/rustfmt.toml b/Relm4-0.6.2/rustfmt.toml new file mode 100644 index 0000000..994f54d --- /dev/null +++ b/Relm4-0.6.2/rustfmt.toml @@ -0,0 +1,18 @@ +# Always use unix newline +newline_style = "Unix" + +# Use field init shorthand when possible +use_field_init_shorthand = true + +# NIGHTLY OPTIONS: ENABLE AS SOON AS THEY BECOME STABLE +# Reorder types and consts before methods +# reorder_impl_items = true + +# Format doc comments as well +# format_code_in_doc_comments = true + +# Change import granularity +# imports_granularity = "Module" + +# Sort group imports +# group_imports = "StdExternalCrate" \ No newline at end of file diff --git a/libadwaita-0.4.4/.cargo-ok b/libadwaita-0.4.4/.cargo-ok new file mode 100644 index 0000000..5f8b795 --- /dev/null +++ b/libadwaita-0.4.4/.cargo-ok @@ -0,0 +1 @@ +{"v":1} \ No newline at end of file diff --git a/libadwaita-0.4.4/.cargo_vcs_info.json b/libadwaita-0.4.4/.cargo_vcs_info.json new file mode 100644 index 0000000..f041cab --- /dev/null +++ b/libadwaita-0.4.4/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "beb81614439d8774e64bb7f09995ddda6840b451" + }, + "path_in_vcs": "libadwaita" +} \ No newline at end of file diff --git a/libadwaita-0.4.4/Cargo.lock b/libadwaita-0.4.4/Cargo.lock new file mode 100644 index 0000000..5eda971 --- /dev/null +++ b/libadwaita-0.4.4/Cargo.lock @@ -0,0 +1,803 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cairo-rs" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3603c4028a5e368d09b51c8b624b9a46edcd7c3778284077a6125af73c9f0a" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "freetype-rs", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "691d0c66b1fb4881be80a760cb8fe76ea97218312f9dfe2c9cc0f496ca279cb1" +dependencies = [ + "glib-sys", + "libc", + "system-deps", + "x11", +] + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-expr" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70d3ad08698a0568b0562f22710fe6bfc1f4a61a367c77d0398c562eadd453a" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "freetype-rs" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59c337e64822dd56a3a83ed75a662a470736bdb3a9fabfb588dff276b94a4e0" +dependencies = [ + "bitflags", + "freetype-sys", + "libc", +] + +[[package]] +name = "freetype-sys" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643148ca6cbad6bec384b52fbe1968547d578c4efe83109e035c43a71734ff88" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "695d6bc846438c5708b07007537b9274d883373dd30858ca881d7d71b5540717" +dependencies = [ + "bitflags", + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", + "once_cell", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9285ec3c113c66d7d0ab5676599176f1f42f4944ca1b581852215bf5694870cb" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3abf96408a26e3eddf881a7f893a1e111767137136e347745e8ea6ed12731ff" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc92aa1608c089c49393d014c38ac0390d01e4841e1fedaa75dbcef77aaed64" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gio" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6973e92937cf98689b6a054a9e56c657ed4ff76de925e36fc331a15f0c5d30a" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ccf87c30a12c469b6d958950f6a9c09f2be20b7773f7e70d20b867fdf2628c3" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fad45ba8d4d2cea612b432717e834f48031cd8853c8aaf43b2c79fec8d144b" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "log", + "memchr", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "glib-macros" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca5c79337338391f1ab8058d6698125034ce8ef31b72a442437fa6c8580de26" +dependencies = [ + "anyhow", + "heck", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "glib-sys" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d80aa6ea7bba0baac79222204aa786a6293078c210abe69ef1336911d4bdc4f0" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd34c3317740a6358ec04572c1bcfd3ac0b5b6529275fae255b237b314bb8062" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def4bb01265b59ed548b05455040d272d989b3012c42d4c1bbd39083cb9b40d9" +dependencies = [ + "glib", + "graphene-sys", + "libc", +] + +[[package]] +name = "graphene-sys" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1856fc817e6a6675e36cea0bd9a3afe296f5d9709d1e2d3182803ac77f0ab21d" +dependencies = [ + "glib-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f01ef44fa7cac15e2da9978529383e6bee03e570ba5bf7036b4c10a15cc3a3c" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07a84fb4dcf1323d29435aa85e2f5f58bef564342bef06775ec7bd0da1f01b0" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b28a32a04cd75cef14a0983f8b0c669e0fe152a0a7725accdeb594e2c764c88b" +dependencies = [ + "bitflags", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "once_cell", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a4d6b61570f76d3ee542d984da443b1cd69b6105264c61afec3abed08c2500f" +dependencies = [ + "anyhow", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "gtk4-sys" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f8283f707b07e019e76c7f2934bdd4180c277e08aa93f4c0d8dd07b7a34e22f" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "libadwaita" +version = "0.4.4" +dependencies = [ + "bitflags", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "gtk4", + "libadwaita-sys", + "libc", + "pango", +] + +[[package]] +name = "libadwaita-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf83ec83c0fc9449b139c721e6f9958137dd7a1d7d47136e4eec929e3bd5265" +dependencies = [ + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "libc" +version = "0.2.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" + +[[package]] +name = "log" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" + +[[package]] +name = "pango" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35be456fc620e61f62dff7ff70fbd54dcbaf0a4b920c0f16de1107c47d921d48" +dependencies = [ + "bitflags", + "gio", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da69f9f3850b0d8990d462f8c709561975e95f689c1cdf0fecdebde78b35195" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" + +[[package]] +name = "serde" +version = "1.0.163" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" + +[[package]] +name = "serde_spanned" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93107647184f6027e3b7dcb2e11034cf95ffa1e3a682c67951963ac69c1c007d" +dependencies = [ + "serde", +] + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5fa6fb9ee296c0dc2df41a656ca7948546d061958115ddb0bcaae43ad0d17d2" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "toml" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6135d499e69981f9ff0ef2167955a5333c35e36f6937d382974566b3d5b94ec" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "unicode-ident" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" + +[[package]] +name = "version-compare" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "winnow" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +dependencies = [ + "memchr", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] diff --git a/libadwaita-0.4.4/Cargo.toml b/libadwaita-0.4.4/Cargo.toml new file mode 100644 index 0000000..06858ad --- /dev/null +++ b/libadwaita-0.4.4/Cargo.toml @@ -0,0 +1,98 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +name = "libadwaita" +version = "0.4.4" +authors = ["Bilal Elmoussaoui "] +description = "Rust bindings for libadwaita" +homepage = "https://world.pages.gitlab.gnome.org/Rust/libadwaita-rs/" +documentation = "https://world.pages.gitlab.gnome.org/Rust/libadwaita-rs/stable/latest/docs/libadwaita" +readme = "README.md" +keywords = [ + "gtk4-rs", + "gnome", + "adwaita", + "GUI", +] +categories = [ + "api-bindings", + "gui", +] +license = "MIT" +repository = "https://gitlab.gnome.org/World/Rust/libadwaita-rs" +resolver = "1" + +[package.metadata.docs.rs] +features = ["dox"] + +[lib] +name = "libadwaita" + +[dependencies.bitflags] +version = "1.0" + +[dependencies.ffi] +version = "0.4" +package = "libadwaita-sys" + +[dependencies.gdk] +version = "0.6" +package = "gdk4" + +[dependencies.gdk-pixbuf] +version = "0.17" + +[dependencies.gio] +version = "0.17" + +[dependencies.glib] +version = "0.17" + +[dependencies.gtk] +version = "0.6" +package = "gtk4" + +[dependencies.libc] +version = "0.2" + +[dependencies.pango] +version = "0.17" + +[features] +dox = [ + "glib/dox", + "gio/dox", + "gdk-pixbuf/dox", + "pango/dox", + "gdk/dox", + "gtk/dox", + "ffi/dox", +] +gtk_v4_10 = ["gtk_v4_8"] +gtk_v4_2 = [] +gtk_v4_4 = ["gtk_v4_2"] +gtk_v4_6 = ["gtk_v4_4"] +gtk_v4_8 = ["gtk_v4_6"] +v1_1 = ["ffi/v1_1"] +v1_2 = [ + "v1_1", + "ffi/v1_2", +] +v1_3 = [ + "v1_2", + "ffi/v1_3", +] +v1_4 = [ + "v1_3", + "ffi/v1_4", +] diff --git a/libadwaita-0.4.4/Cargo.toml.orig b/libadwaita-0.4.4/Cargo.toml.orig new file mode 100644 index 0000000..777cdc7 --- /dev/null +++ b/libadwaita-0.4.4/Cargo.toml.orig @@ -0,0 +1,80 @@ +[package] +name = "libadwaita" +version = "0.4.4" +authors = ["Bilal Elmoussaoui "] +edition = "2021" +readme = "../README.md" +homepage = "https://world.pages.gitlab.gnome.org/Rust/libadwaita-rs/" +description = "Rust bindings for libadwaita" +license = "MIT" +repository = "https://gitlab.gnome.org/World/Rust/libadwaita-rs" +documentation = "https://world.pages.gitlab.gnome.org/Rust/libadwaita-rs/stable/latest/docs/libadwaita" +categories = ["api-bindings", "gui"] +keywords = ["gtk4-rs", "gnome", "adwaita", "GUI"] + +[lib] +name = "libadwaita" + +[features] +dox = [ + "glib/dox", + "gio/dox", + "gdk-pixbuf/dox", + "pango/dox", + "gdk/dox", + "gtk/dox", + "ffi/dox", +] +gtk_v4_2 = [] +gtk_v4_4 = ["gtk_v4_2"] +gtk_v4_6 = ["gtk_v4_4"] +gtk_v4_8 = ["gtk_v4_6"] +gtk_v4_10 = ["gtk_v4_8"] +v1_1 = ["ffi/v1_1"] +v1_2 = ["v1_1", "ffi/v1_2"] +v1_3 = ["v1_2", "ffi/v1_3"] +v1_4 = ["v1_3", "ffi/v1_4"] + +[package.metadata.docs.rs] +features = ["dox"] + +[dependencies] +bitflags = '1.0' +libc = '0.2' + +[dependencies.glib] +git = "https://github.com/gtk-rs/gtk-rs-core" +version = "0.17" +branch = "0.17" + +[dependencies.gio] +git = "https://github.com/gtk-rs/gtk-rs-core" +version = "0.17" +branch = "0.17" + +[dependencies.gdk-pixbuf] +git = "https://github.com/gtk-rs/gtk-rs-core" +version = "0.17" +branch = "0.17" + +[dependencies.pango] +git = "https://github.com/gtk-rs/gtk-rs-core" +version = "0.17" +branch = "0.17" + +[dependencies.gdk] +package = "gdk4" +git = "https://github.com/gtk-rs/gtk4-rs" +version = "0.6" +branch = "0.6" + +[dependencies.gtk] +package = "gtk4" +git = "https://github.com/gtk-rs/gtk4-rs" +version = "0.6" +branch = "0.6" + +[dependencies.ffi] +package = "libadwaita-sys" +path = './sys' +version = "0.4" diff --git a/libadwaita-0.4.4/Gir.toml b/libadwaita-0.4.4/Gir.toml new file mode 100644 index 0000000..26cd064 --- /dev/null +++ b/libadwaita-0.4.4/Gir.toml @@ -0,0 +1,345 @@ +[external_libraries] +Gio = {min_version = "2.66"} +[options] +girs_directories = ["../gir-files", "../"] +library = "Adw" +version = "1" +min_cfg_version = "1" +target_path = "." +use_gi_docgen = true +work_mode = "normal" +generate_safety_asserts = true +deprecate_by_min_version = true +# with this option enabled, versions for gir and gir-files saved only to one file to minimize noise +single_version_file = true +generate_builder = true +trust_return_value_nullability = true + +external_libraries = [ + "GLib", + "GObject", + "Gdk", + "GdkPixbuf", + "Gtk", + "Pango", +] + +generate = [ + "Adw.AboutWindow", + "Adw.ActionRow", + "Adw.AnimationState", + "Adw.Avatar", + "Adw.Banner", + "Adw.Bin", + "Adw.BreakpointBin", + "Adw.BreakpointConditionLengthType", + "Adw.BreakpointConditionRatioType", + "Adw.ButtonContent", + "Adw.CarouselIndicatorDots", + "Adw.CarouselIndicatorLines", + "Adw.CenteringPolicy", + "Adw.Clamp", + "Adw.ClampLayout", + "Adw.ClampScrollable", + "Adw.ColorScheme", + "Adw.ComboRow", + "Adw.Easing", + "Adw.EntryRow", + "Adw.ExpanderRow", + "Adw.FoldThresholdPolicy", + "Adw.Flap", + "Adw.FlapFoldPolicy", + "Adw.FlapTransitionType", + "Adw.EnumListItem", + "Adw.HeaderBar", + "Adw.Leaflet", + "Adw.LeafletTransitionType", + "Adw.LengthUnit", + "Adw.NavigationDirection", + "Adw.NavigationPage", + "Adw.NavigationSplitView", + "Adw.NavigationView", + "Adw.OverlaySplitView", + "Adw.PasswordEntryRow", + "Adw.PreferencesGroup", + "Adw.PreferencesPage", + "Adw.PreferencesRow", + "Adw.PreferencesWindow", + "Adw.ResponseAppearance", + "Adw.SplitButton", + "Adw.SpringAnimation", + "Adw.SpringParams", + "Adw.Squeezer", + "Adw.SqueezerTransitionType", + "Adw.StatusPage", + "Adw.SwipeTracker", + "Adw.SwitchRow", + "Adw.Swipeable", + "Adw.TabButton", + "Adw.TabOverview", + "Adw.TabViewShortcuts", + "Adw.TimedAnimation", + "Adw.ToastPriority", + "Adw.ToolbarStyle", + "Adw.ToolbarView", + "Adw.ViewStack", + "Adw.ViewSwitcher", + "Adw.ViewSwitcherBar", + "Adw.ViewSwitcherPolicy", + "Adw.ViewSwitcherTitle", + "Adw.WindowTitle", +] + +manual = [ + "GLib.Variant", + "GObject.Object", + "GObject.ParamSpec", + "GObject.Value", + "Gdk.Cursor", + "Gdk.Display", + "Gdk.DragAction", + "Gdk.Paintable", + "Gdk.Rectangle", + "Gdk.Texture", + "Gio.Application", + "Gio.ApplicationFlags", + "Gio.ActionGroup", + "Gio.ActionMap", + "Gio.Cancellable", + "Gio.Icon", + "Gio.ListModel", + "Gio.MenuModel", + "Gtk.Accessible", + "Gtk.AccessibleRole", + "Gtk.Actionable", + "Gtk.Adjustment", + "Gtk.Align", + "Gtk.Application", + "Gtk.ApplicationWindow", + "Gtk.ArrowType", + "Gtk.Buildable", + "Gtk.ConstraintTarget", + "Gtk.Editable", + "Gtk.Entry", + "Gtk.Expression", + "Gtk.HeaderBar", + "Gtk.InputHints", + "Gtk.InputPurpose", + "Gtk.LayoutManager", + "Gtk.License", + "Gtk.ListBoxRow", + "Gtk.ListItemFactory", + "Gtk.ListView", + "Gtk.Native", + "Gtk.Orientable", + "Gtk.Orientation", + "Gtk.Overflow", + "Gtk.PackType", + "Gtk.Popover", + "Gtk.Root", + "Gtk.Scrollable", + "Gtk.ScrollablePolicy", + "Gtk.ScrolledWindow", + "Gtk.SelectionModel", + "Gtk.Settings", + "Gtk.ShortcutManager", + "Gtk.SpinButtonUpdatePolicy", + "Gtk.Stack", + "Gtk.Widget", + "Pango.AttrList", + "Pango.EllipsizeMode", +] + +[[object]] +name = "Gtk.Window" +status = "manual" +trait_name = "GtkWindowExt" + [[object.property]] + name = "child" + # adw use content not child, using it could result in a crash + ignore = true + +[[object]] +name = "Adw.*" +status = "generate" + [[object.constant]] + name = "VERSION_S" + ignore = true + [[object.function]] + name = "get_enable_animations" + rename = "is_animations_enabled" + [[object.function]] + name = "init" + manual = true + [[object.function]] + name = "show_about_window" + ignore = true # C only function, replaced by AboutWindow::builder + +[[object]] +name = "Adw.Animation" +status = "generate" +generate_builder = false + +[[object]] +name = "Adw.AnimationTarget" +status = "generate" +generate_builder = false + +[[object]] +name = "Adw.Application" +status = "generate" +builder_postprocess = "Application::register_startup_hook(&ret);" +trait_name = "AdwApplicationExt" + [[object.function]] + name = "new" + manual = true + +[[object]] +name = "Adw.ApplicationWindow" +status = "generate" +trait_name = "AdwApplicationWindowExt" + +[[object]] +name = "Adw.Breakpoint" +status = "generate" +generate_builder = false + [[object.function]] + pattern = "(add_setters_valist|add_setters)" + ignore = true # C only functions, add_setters replaced by add_settersv + [[object.function]] + name = "add_settersv" + rename = "add_setters" + manual = true + [[object.function]] + name = "set_condition" + [[object.function.parameter]] + name = "condition" + const = true # iter shouldn't be mutable here + +[[object]] +name = "Adw.BreakpointCondition" +status = "generate" + [[object.function]] + name = "to_string" + [[object.function.parameter]] + name = "self" + const = true # iter shouldn't be mutable here + [[object.function]] + name = "parse" + [object.function.return] + nullable = true + nullable_return_is_error = "Invalid condition" + +[[object]] +name = "Adw.CallbackAnimationTarget" +status = "generate" +generate_builder = false + +[[object]] +name = "Adw.Carousel" +status = "generate" + [[object.function]] + name = "get_nth_page" + manual = true # assert n < n_pages + +[[object]] +name = "Adw.EnumListModel" +status = "generate" +generate_builder = false + +[[object]] +name = "Adw.LeafletPage" +status = "generate" +generate_builder = false + +[[object]] +name = "Adw.MessageDialog" +status = "generate" +manual_traits = ["MessageDialogExtManual"] + [[object.function]] + name = "add_responses" + manual = true + [[object.function]] + pattern = "(format_body|format_body_markup|format_heading|format_heading_markup)" + ignore = true # C only function + [[object.function]] + name = "get_response_label" + manual = true # assert has_response + [[object.function]] + name = "choose" + manual = true + +[[object]] +name = "Adw.PropertyAnimationTarget" +status = "generate" +generate_builder = false + +[[object]] +name = "Adw.SpinRow" +status = "generate" + [[object.signal]] + name = "input" + manual = true + +[[object]] +name = "Adw.StyleManager" +status = "generate" +generate_builder = false + [[object.function]] + name = "get_system_supports_color_schemes" + rename = "system_supports_color_schemes" + +[[object]] +name = "Adw.SqueezerPage" +status = "generate" +generate_builder = false + +[[object]] +name = "Adw.TabBar" +status = "generate" + [[object.function]] + name = "setup_extra_drop_target" + manual = true # somehow gir fails to handle functions that have a array with a specific length + [[object.signal]] + name = "extra-drag-drop" + ignore = true # manual: *mut gobject_ffi::GValue doesn't implement glib::from_glib_borrow + +[[object]] +name = "Adw.TabView" +status = "generate" + [[object.function]] + name = "get_nth_page" + manual = true # assert n < n_pages + +[[object]] +name = "Adw.Toast" +status = "generate" + [[object.function]] + name = "new_format" + ignore = true # C only function + [[object.function]] + name = "set_action_target" + manual = true + [[object.property]] + name = "action-target" + generate = ["notify"] + +[[object]] +name = "Adw.ToastOverlay" +status = "generate" +generate_builder = false + +[[object]] +name = "Adw.TabPage" +status = "generate" +generate_builder = false + +[[object]] +name = "Adw.ViewStackPage" +status = "generate" +generate_builder = false + +[[object]] +name = "Adw.Window" +status = "generate" +trait_name = "AdwWindowExt" diff --git a/libadwaita-0.4.4/LICENCE b/libadwaita-0.4.4/LICENCE new file mode 100644 index 0000000..64a801a --- /dev/null +++ b/libadwaita-0.4.4/LICENCE @@ -0,0 +1,18 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/libadwaita-0.4.4/README.md b/libadwaita-0.4.4/README.md new file mode 100644 index 0000000..db307b3 --- /dev/null +++ b/libadwaita-0.4.4/README.md @@ -0,0 +1,10 @@ +# libadwaita-rs + +The Rust bindings of [libadwaita](https://gitlab.gnome.org/GNOME/libadwaita) + +Website: + +## Documentation + +- libadwaita: +- libadwaita-sys: diff --git a/libadwaita-0.4.4/src/application.rs b/libadwaita-0.4.4/src/application.rs new file mode 100644 index 0000000..dda081d --- /dev/null +++ b/libadwaita-0.4.4/src/application.rs @@ -0,0 +1,53 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::Application; + +use glib::translate::*; + +use std::cell::RefCell; +use std::rc::Rc; + +use glib::signal::SignalHandlerId; +use gtk::prelude::*; + +impl Application { + #[doc(alias = "adw_application_new")] + pub fn new(application_id: Option<&str>, flags: gio::ApplicationFlags) -> Self { + skip_assert_initialized!(); + let app = unsafe { + from_glib_full(ffi::adw_application_new( + application_id.to_glib_none().0, + flags.into_glib(), + )) + }; + Self::register_startup_hook(&app); + app + } + + pub(crate) fn register_startup_hook(app: &Self) { + skip_assert_initialized!(); + let signalid: Rc>> = Rc::new(RefCell::new(None)); + { + let signalid_ = signalid.clone(); + + let id = app.connect_startup(move |app| { + app.disconnect( + signalid_ + .borrow_mut() + .take() + .expect("Signal ID went missing"), + ); + gtk::init().expect("Failed to initalize gtk4"); + }); + *signalid.borrow_mut() = Some(id); + } + } +} + +impl Default for Application { + fn default() -> Self { + let app = glib::object::Object::new::(); + Self::register_startup_hook(&app); + app + } +} diff --git a/libadwaita-0.4.4/src/auto/about_window.rs b/libadwaita-0.4.4/src/auto/about_window.rs new file mode 100644 index 0000000..97d70d3 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/about_window.rs @@ -0,0 +1,1543 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::Window; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwAboutWindow")] + pub struct AboutWindow(Object) @extends Window, gtk::Window, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager; + + match fn { + type_ => || ffi::adw_about_window_get_type(), + } +} + +impl AboutWindow { + #[doc(alias = "adw_about_window_new")] + pub fn new() -> AboutWindow { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_about_window_new()).unsafe_cast() } + } + + // #[cfg(any(feature = "v1_4", feature = "dox"))] + // #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + // #[cfg(target_os = "linux")] + // #[doc(alias = "adw_about_window_new_from_appdata")] + // #[doc(alias = "new_from_appdata")] + // pub fn from_appdata(resource_path: &str, release_notes_version: Option<&str>) -> AboutWindow { + // assert_initialized_main_thread!(); + // unsafe { + // gtk::Widget::from_glib_none(ffi::adw_about_window_new_from_appdata( + // resource_path.to_glib_none().0, + // release_notes_version.to_glib_none().0, + // )) + // .unsafe_cast() + // } + // } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`AboutWindow`] objects. + /// + /// This method returns an instance of [`AboutWindowBuilder`](crate::builders::AboutWindowBuilder) which can be used to create [`AboutWindow`] objects. + pub fn builder() -> AboutWindowBuilder { + AboutWindowBuilder::new() + } + + #[doc(alias = "adw_about_window_add_acknowledgement_section")] + pub fn add_acknowledgement_section(&self, name: Option<&str>, people: &[&str]) { + unsafe { + ffi::adw_about_window_add_acknowledgement_section( + self.to_glib_none().0, + name.to_glib_none().0, + people.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_add_credit_section")] + pub fn add_credit_section(&self, name: Option<&str>, people: &[&str]) { + unsafe { + ffi::adw_about_window_add_credit_section( + self.to_glib_none().0, + name.to_glib_none().0, + people.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_add_legal_section")] + pub fn add_legal_section( + &self, + title: &str, + copyright: Option<&str>, + license_type: gtk::License, + license: Option<&str>, + ) { + unsafe { + ffi::adw_about_window_add_legal_section( + self.to_glib_none().0, + title.to_glib_none().0, + copyright.to_glib_none().0, + license_type.into_glib(), + license.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_add_link")] + pub fn add_link(&self, title: &str, url: &str) { + unsafe { + ffi::adw_about_window_add_link( + self.to_glib_none().0, + title.to_glib_none().0, + url.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_get_application_icon")] + #[doc(alias = "get_application_icon")] + pub fn application_icon(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_about_window_get_application_icon( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_about_window_get_application_name")] + #[doc(alias = "get_application_name")] + pub fn application_name(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_about_window_get_application_name( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_about_window_get_artists")] + #[doc(alias = "get_artists")] + pub fn artists(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_none(ffi::adw_about_window_get_artists( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_about_window_get_comments")] + #[doc(alias = "get_comments")] + pub fn comments(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_about_window_get_comments(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_about_window_get_copyright")] + #[doc(alias = "get_copyright")] + pub fn copyright(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_about_window_get_copyright(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_about_window_get_debug_info")] + #[doc(alias = "get_debug_info")] + pub fn debug_info(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_about_window_get_debug_info(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_about_window_get_debug_info_filename")] + #[doc(alias = "get_debug_info_filename")] + pub fn debug_info_filename(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_about_window_get_debug_info_filename( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_about_window_get_designers")] + #[doc(alias = "get_designers")] + pub fn designers(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_none(ffi::adw_about_window_get_designers( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_about_window_get_developer_name")] + #[doc(alias = "get_developer_name")] + pub fn developer_name(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_about_window_get_developer_name( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_about_window_get_developers")] + #[doc(alias = "get_developers")] + pub fn developers(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_none(ffi::adw_about_window_get_developers( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_about_window_get_documenters")] + #[doc(alias = "get_documenters")] + pub fn documenters(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_none(ffi::adw_about_window_get_documenters( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_about_window_get_issue_url")] + #[doc(alias = "get_issue_url")] + pub fn issue_url(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_about_window_get_issue_url(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_about_window_get_license")] + #[doc(alias = "get_license")] + pub fn license(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_about_window_get_license(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_about_window_get_license_type")] + #[doc(alias = "get_license_type")] + pub fn license_type(&self) -> gtk::License { + unsafe { + from_glib(ffi::adw_about_window_get_license_type( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_about_window_get_release_notes")] + #[doc(alias = "get_release_notes")] + pub fn release_notes(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_about_window_get_release_notes( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_about_window_get_release_notes_version")] + #[doc(alias = "get_release_notes_version")] + pub fn release_notes_version(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_about_window_get_release_notes_version( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_about_window_get_support_url")] + #[doc(alias = "get_support_url")] + pub fn support_url(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_about_window_get_support_url(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_about_window_get_translator_credits")] + #[doc(alias = "get_translator_credits")] + pub fn translator_credits(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_about_window_get_translator_credits( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_about_window_get_version")] + #[doc(alias = "get_version")] + pub fn version(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_about_window_get_version(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_about_window_get_website")] + #[doc(alias = "get_website")] + pub fn website(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_about_window_get_website(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_about_window_set_application_icon")] + pub fn set_application_icon(&self, application_icon: &str) { + unsafe { + ffi::adw_about_window_set_application_icon( + self.to_glib_none().0, + application_icon.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_set_application_name")] + pub fn set_application_name(&self, application_name: &str) { + unsafe { + ffi::adw_about_window_set_application_name( + self.to_glib_none().0, + application_name.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_set_artists")] + pub fn set_artists(&self, artists: &[&str]) { + unsafe { + ffi::adw_about_window_set_artists(self.to_glib_none().0, artists.to_glib_none().0); + } + } + + #[doc(alias = "adw_about_window_set_comments")] + pub fn set_comments(&self, comments: &str) { + unsafe { + ffi::adw_about_window_set_comments(self.to_glib_none().0, comments.to_glib_none().0); + } + } + + #[doc(alias = "adw_about_window_set_copyright")] + pub fn set_copyright(&self, copyright: &str) { + unsafe { + ffi::adw_about_window_set_copyright(self.to_glib_none().0, copyright.to_glib_none().0); + } + } + + #[doc(alias = "adw_about_window_set_debug_info")] + pub fn set_debug_info(&self, debug_info: &str) { + unsafe { + ffi::adw_about_window_set_debug_info( + self.to_glib_none().0, + debug_info.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_set_debug_info_filename")] + pub fn set_debug_info_filename(&self, filename: &str) { + unsafe { + ffi::adw_about_window_set_debug_info_filename( + self.to_glib_none().0, + filename.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_set_designers")] + pub fn set_designers(&self, designers: &[&str]) { + unsafe { + ffi::adw_about_window_set_designers(self.to_glib_none().0, designers.to_glib_none().0); + } + } + + #[doc(alias = "adw_about_window_set_developer_name")] + pub fn set_developer_name(&self, developer_name: &str) { + unsafe { + ffi::adw_about_window_set_developer_name( + self.to_glib_none().0, + developer_name.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_set_developers")] + pub fn set_developers(&self, developers: &[&str]) { + unsafe { + ffi::adw_about_window_set_developers( + self.to_glib_none().0, + developers.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_set_documenters")] + pub fn set_documenters(&self, documenters: &[&str]) { + unsafe { + ffi::adw_about_window_set_documenters( + self.to_glib_none().0, + documenters.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_set_issue_url")] + pub fn set_issue_url(&self, issue_url: &str) { + unsafe { + ffi::adw_about_window_set_issue_url(self.to_glib_none().0, issue_url.to_glib_none().0); + } + } + + #[doc(alias = "adw_about_window_set_license")] + pub fn set_license(&self, license: &str) { + unsafe { + ffi::adw_about_window_set_license(self.to_glib_none().0, license.to_glib_none().0); + } + } + + #[doc(alias = "adw_about_window_set_license_type")] + pub fn set_license_type(&self, license_type: gtk::License) { + unsafe { + ffi::adw_about_window_set_license_type(self.to_glib_none().0, license_type.into_glib()); + } + } + + #[doc(alias = "adw_about_window_set_release_notes")] + pub fn set_release_notes(&self, release_notes: &str) { + unsafe { + ffi::adw_about_window_set_release_notes( + self.to_glib_none().0, + release_notes.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_set_release_notes_version")] + pub fn set_release_notes_version(&self, version: &str) { + unsafe { + ffi::adw_about_window_set_release_notes_version( + self.to_glib_none().0, + version.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_set_support_url")] + pub fn set_support_url(&self, support_url: &str) { + unsafe { + ffi::adw_about_window_set_support_url( + self.to_glib_none().0, + support_url.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_set_translator_credits")] + pub fn set_translator_credits(&self, translator_credits: &str) { + unsafe { + ffi::adw_about_window_set_translator_credits( + self.to_glib_none().0, + translator_credits.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_about_window_set_version")] + pub fn set_version(&self, version: &str) { + unsafe { + ffi::adw_about_window_set_version(self.to_glib_none().0, version.to_glib_none().0); + } + } + + #[doc(alias = "adw_about_window_set_website")] + pub fn set_website(&self, website: &str) { + unsafe { + ffi::adw_about_window_set_website(self.to_glib_none().0, website.to_glib_none().0); + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "activate-link")] + pub fn connect_activate_link bool + 'static>( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn activate_link_trampoline< + F: Fn(&AboutWindow, &str) -> bool + 'static, + >( + this: *mut ffi::AdwAboutWindow, + uri: *mut libc::c_char, + f: glib::ffi::gpointer, + ) -> glib::ffi::gboolean { + let f: &F = &*(f as *const F); + f( + &from_glib_borrow(this), + &glib::GString::from_glib_borrow(uri), + ) + .into_glib() + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"activate-link\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + activate_link_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "application-icon")] + pub fn connect_application_icon_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_application_icon_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::application-icon\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_application_icon_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "application-name")] + pub fn connect_application_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_application_name_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::application-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_application_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "artists")] + pub fn connect_artists_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_artists_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::artists\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_artists_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "comments")] + pub fn connect_comments_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_comments_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::comments\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_comments_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "copyright")] + pub fn connect_copyright_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_copyright_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::copyright\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_copyright_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "debug-info")] + pub fn connect_debug_info_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_debug_info_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::debug-info\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_debug_info_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "debug-info-filename")] + pub fn connect_debug_info_filename_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_debug_info_filename_trampoline< + F: Fn(&AboutWindow) + 'static, + >( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::debug-info-filename\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_debug_info_filename_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "designers")] + pub fn connect_designers_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_designers_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::designers\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_designers_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "developer-name")] + pub fn connect_developer_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_developer_name_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::developer-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_developer_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "developers")] + pub fn connect_developers_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_developers_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::developers\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_developers_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "documenters")] + pub fn connect_documenters_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_documenters_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::documenters\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_documenters_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "issue-url")] + pub fn connect_issue_url_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_issue_url_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::issue-url\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_issue_url_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "license")] + pub fn connect_license_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_license_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::license\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_license_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "license-type")] + pub fn connect_license_type_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_license_type_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::license-type\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_license_type_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "release-notes")] + pub fn connect_release_notes_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_release_notes_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::release-notes\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_release_notes_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "release-notes-version")] + pub fn connect_release_notes_version_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_release_notes_version_trampoline< + F: Fn(&AboutWindow) + 'static, + >( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::release-notes-version\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_release_notes_version_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "support-url")] + pub fn connect_support_url_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_support_url_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::support-url\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_support_url_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "translator-credits")] + pub fn connect_translator_credits_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_translator_credits_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::translator-credits\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_translator_credits_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "version")] + pub fn connect_version_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_version_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::version\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_version_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "website")] + pub fn connect_website_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_website_trampoline( + this: *mut ffi::AdwAboutWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::website\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_website_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl Default for AboutWindow { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`AboutWindow`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct AboutWindowBuilder { + builder: glib::object::ObjectBuilder<'static, AboutWindow>, +} + +impl AboutWindowBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn application_icon(self, application_icon: impl Into) -> Self { + Self { + builder: self + .builder + .property("application-icon", application_icon.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn application_name(self, application_name: impl Into) -> Self { + Self { + builder: self + .builder + .property("application-name", application_name.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn artists(self, artists: impl Into) -> Self { + Self { + builder: self.builder.property("artists", artists.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn comments(self, comments: impl Into) -> Self { + Self { + builder: self.builder.property("comments", comments.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn copyright(self, copyright: impl Into) -> Self { + Self { + builder: self.builder.property("copyright", copyright.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn debug_info(self, debug_info: impl Into) -> Self { + Self { + builder: self.builder.property("debug-info", debug_info.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn debug_info_filename(self, debug_info_filename: impl Into) -> Self { + Self { + builder: self + .builder + .property("debug-info-filename", debug_info_filename.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn designers(self, designers: impl Into) -> Self { + Self { + builder: self.builder.property("designers", designers.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn developer_name(self, developer_name: impl Into) -> Self { + Self { + builder: self + .builder + .property("developer-name", developer_name.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn developers(self, developers: impl Into) -> Self { + Self { + builder: self.builder.property("developers", developers.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn documenters(self, documenters: impl Into) -> Self { + Self { + builder: self.builder.property("documenters", documenters.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn issue_url(self, issue_url: impl Into) -> Self { + Self { + builder: self.builder.property("issue-url", issue_url.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn license(self, license: impl Into) -> Self { + Self { + builder: self.builder.property("license", license.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn license_type(self, license_type: gtk::License) -> Self { + Self { + builder: self.builder.property("license-type", license_type), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn release_notes(self, release_notes: impl Into) -> Self { + Self { + builder: self.builder.property("release-notes", release_notes.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn release_notes_version(self, release_notes_version: impl Into) -> Self { + Self { + builder: self + .builder + .property("release-notes-version", release_notes_version.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn support_url(self, support_url: impl Into) -> Self { + Self { + builder: self.builder.property("support-url", support_url.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn translator_credits(self, translator_credits: impl Into) -> Self { + Self { + builder: self + .builder + .property("translator-credits", translator_credits.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn version(self, version: impl Into) -> Self { + Self { + builder: self.builder.property("version", version.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn website(self, website: impl Into) -> Self { + Self { + builder: self.builder.property("website", website.into()), + } + } + + pub fn content(self, content: &impl IsA) -> Self { + Self { + builder: self.builder.property("content", content.clone().upcast()), + } + } + + pub fn application(self, application: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("application", application.clone().upcast()), + } + } + + pub fn decorated(self, decorated: bool) -> Self { + Self { + builder: self.builder.property("decorated", decorated), + } + } + + pub fn default_height(self, default_height: i32) -> Self { + Self { + builder: self.builder.property("default-height", default_height), + } + } + + pub fn default_widget(self, default_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("default-widget", default_widget.clone().upcast()), + } + } + + pub fn default_width(self, default_width: i32) -> Self { + Self { + builder: self.builder.property("default-width", default_width), + } + } + + pub fn deletable(self, deletable: bool) -> Self { + Self { + builder: self.builder.property("deletable", deletable), + } + } + + pub fn destroy_with_parent(self, destroy_with_parent: bool) -> Self { + Self { + builder: self + .builder + .property("destroy-with-parent", destroy_with_parent), + } + } + + pub fn display(self, display: &gdk::Display) -> Self { + Self { + builder: self.builder.property("display", display.clone()), + } + } + + pub fn focus_visible(self, focus_visible: bool) -> Self { + Self { + builder: self.builder.property("focus-visible", focus_visible), + } + } + + pub fn focus_widget(self, focus_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("focus-widget", focus_widget.clone().upcast()), + } + } + + pub fn fullscreened(self, fullscreened: bool) -> Self { + Self { + builder: self.builder.property("fullscreened", fullscreened), + } + } + + #[cfg(any(feature = "gtk_v4_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "gtk_v4_2")))] + pub fn handle_menubar_accel(self, handle_menubar_accel: bool) -> Self { + Self { + builder: self + .builder + .property("handle-menubar-accel", handle_menubar_accel), + } + } + + pub fn hide_on_close(self, hide_on_close: bool) -> Self { + Self { + builder: self.builder.property("hide-on-close", hide_on_close), + } + } + + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn maximized(self, maximized: bool) -> Self { + Self { + builder: self.builder.property("maximized", maximized), + } + } + + pub fn mnemonics_visible(self, mnemonics_visible: bool) -> Self { + Self { + builder: self + .builder + .property("mnemonics-visible", mnemonics_visible), + } + } + + pub fn modal(self, modal: bool) -> Self { + Self { + builder: self.builder.property("modal", modal), + } + } + + pub fn resizable(self, resizable: bool) -> Self { + Self { + builder: self.builder.property("resizable", resizable), + } + } + + pub fn startup_id(self, startup_id: impl Into) -> Self { + Self { + builder: self.builder.property("startup-id", startup_id.into()), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "gtk_v4_6", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "gtk_v4_6")))] + pub fn titlebar(self, titlebar: &impl IsA) -> Self { + Self { + builder: self.builder.property("titlebar", titlebar.clone().upcast()), + } + } + + pub fn transient_for(self, transient_for: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("transient-for", transient_for.clone().upcast()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`AboutWindow`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> AboutWindow { + self.builder.build() + } +} + +impl fmt::Display for AboutWindow { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("AboutWindow") + } +} diff --git a/libadwaita-0.4.4/src/auto/action_row.rs b/libadwaita-0.4.4/src/auto/action_row.rs new file mode 100644 index 0000000..005d01e --- /dev/null +++ b/libadwaita-0.4.4/src/auto/action_row.rs @@ -0,0 +1,747 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT +#![allow(deprecated)] + +use crate::PreferencesRow; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwActionRow")] + pub struct ActionRow(Object) @extends PreferencesRow, gtk::ListBoxRow, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable; + + match fn { + type_ => || ffi::adw_action_row_get_type(), + } +} + +impl ActionRow { + pub const NONE: Option<&'static ActionRow> = None; + + #[doc(alias = "adw_action_row_new")] + pub fn new() -> ActionRow { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_action_row_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`ActionRow`] objects. + /// + /// This method returns an instance of [`ActionRowBuilder`](crate::builders::ActionRowBuilder) which can be used to create [`ActionRow`] objects. + pub fn builder() -> ActionRowBuilder { + ActionRowBuilder::new() + } +} + +impl Default for ActionRow { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`ActionRow`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ActionRowBuilder { + builder: glib::object::ObjectBuilder<'static, ActionRow>, +} + +impl ActionRowBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn activatable_widget(self, activatable_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("activatable-widget", activatable_widget.clone().upcast()), + } + } + + #[cfg_attr(feature = "v1_3", deprecated = "Since 1.3")] + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn subtitle(self, subtitle: impl Into) -> Self { + Self { + builder: self.builder.property("subtitle", subtitle.into()), + } + } + + pub fn subtitle_lines(self, subtitle_lines: i32) -> Self { + Self { + builder: self.builder.property("subtitle-lines", subtitle_lines), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn subtitle_selectable(self, subtitle_selectable: bool) -> Self { + Self { + builder: self + .builder + .property("subtitle-selectable", subtitle_selectable), + } + } + + pub fn title_lines(self, title_lines: i32) -> Self { + Self { + builder: self.builder.property("title-lines", title_lines), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + pub fn title_selectable(self, title_selectable: bool) -> Self { + Self { + builder: self.builder.property("title-selectable", title_selectable), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn use_markup(self, use_markup: bool) -> Self { + Self { + builder: self.builder.property("use-markup", use_markup), + } + } + + pub fn use_underline(self, use_underline: bool) -> Self { + Self { + builder: self.builder.property("use-underline", use_underline), + } + } + + pub fn activatable(self, activatable: bool) -> Self { + Self { + builder: self.builder.property("activatable", activatable), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn selectable(self, selectable: bool) -> Self { + Self { + builder: self.builder.property("selectable", selectable), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn action_name(self, action_name: impl Into) -> Self { + Self { + builder: self.builder.property("action-name", action_name.into()), + } + } + + pub fn action_target(self, action_target: &glib::Variant) -> Self { + Self { + builder: self + .builder + .property("action-target", action_target.clone()), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`ActionRow`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> ActionRow { + self.builder.build() + } +} + +pub trait ActionRowExt: 'static { + #[doc(alias = "adw_action_row_activate")] + fn activate(&self); + + #[doc(alias = "adw_action_row_add_prefix")] + fn add_prefix(&self, widget: &impl IsA); + + #[doc(alias = "adw_action_row_add_suffix")] + fn add_suffix(&self, widget: &impl IsA); + + #[doc(alias = "adw_action_row_get_activatable_widget")] + #[doc(alias = "get_activatable_widget")] + fn activatable_widget(&self) -> Option; + + #[cfg_attr(feature = "v1_3", deprecated = "Since 1.3")] + #[allow(deprecated)] + #[doc(alias = "adw_action_row_get_icon_name")] + #[doc(alias = "get_icon_name")] + fn icon_name(&self) -> Option; + + #[doc(alias = "adw_action_row_get_subtitle")] + #[doc(alias = "get_subtitle")] + fn subtitle(&self) -> Option; + + #[doc(alias = "adw_action_row_get_subtitle_lines")] + #[doc(alias = "get_subtitle_lines")] + fn subtitle_lines(&self) -> i32; + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_action_row_get_subtitle_selectable")] + #[doc(alias = "get_subtitle_selectable")] + fn is_subtitle_selectable(&self) -> bool; + + #[doc(alias = "adw_action_row_get_title_lines")] + #[doc(alias = "get_title_lines")] + fn title_lines(&self) -> i32; + + #[doc(alias = "adw_action_row_remove")] + fn remove(&self, widget: &impl IsA); + + #[doc(alias = "adw_action_row_set_activatable_widget")] + fn set_activatable_widget(&self, widget: Option<&impl IsA>); + + #[cfg_attr(feature = "v1_3", deprecated = "Since 1.3")] + #[allow(deprecated)] + #[doc(alias = "adw_action_row_set_icon_name")] + fn set_icon_name(&self, icon_name: Option<&str>); + + #[doc(alias = "adw_action_row_set_subtitle")] + fn set_subtitle(&self, subtitle: &str); + + #[doc(alias = "adw_action_row_set_subtitle_lines")] + fn set_subtitle_lines(&self, subtitle_lines: i32); + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_action_row_set_subtitle_selectable")] + fn set_subtitle_selectable(&self, subtitle_selectable: bool); + + #[doc(alias = "adw_action_row_set_title_lines")] + fn set_title_lines(&self, title_lines: i32); + + #[doc(alias = "activated")] + fn connect_activated(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "activatable-widget")] + fn connect_activatable_widget_notify(&self, f: F) -> SignalHandlerId; + + #[cfg_attr(feature = "v1_3", deprecated = "Since 1.3")] + #[doc(alias = "icon-name")] + fn connect_icon_name_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "subtitle")] + fn connect_subtitle_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "subtitle-lines")] + fn connect_subtitle_lines_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "subtitle-selectable")] + fn connect_subtitle_selectable_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "title-lines")] + fn connect_title_lines_notify(&self, f: F) -> SignalHandlerId; +} + +impl> ActionRowExt for O { + fn activate(&self) { + unsafe { + ffi::adw_action_row_activate(self.as_ref().to_glib_none().0); + } + } + + fn add_prefix(&self, widget: &impl IsA) { + unsafe { + ffi::adw_action_row_add_prefix( + self.as_ref().to_glib_none().0, + widget.as_ref().to_glib_none().0, + ); + } + } + + fn add_suffix(&self, widget: &impl IsA) { + unsafe { + ffi::adw_action_row_add_suffix( + self.as_ref().to_glib_none().0, + widget.as_ref().to_glib_none().0, + ); + } + } + + fn activatable_widget(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_action_row_get_activatable_widget( + self.as_ref().to_glib_none().0, + )) + } + } + + #[allow(deprecated)] + fn icon_name(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_action_row_get_icon_name( + self.as_ref().to_glib_none().0, + )) + } + } + + fn subtitle(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_action_row_get_subtitle( + self.as_ref().to_glib_none().0, + )) + } + } + + fn subtitle_lines(&self) -> i32 { + unsafe { ffi::adw_action_row_get_subtitle_lines(self.as_ref().to_glib_none().0) } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn is_subtitle_selectable(&self) -> bool { + unsafe { + from_glib(ffi::adw_action_row_get_subtitle_selectable( + self.as_ref().to_glib_none().0, + )) + } + } + + fn title_lines(&self) -> i32 { + unsafe { ffi::adw_action_row_get_title_lines(self.as_ref().to_glib_none().0) } + } + + fn remove(&self, widget: &impl IsA) { + unsafe { + ffi::adw_action_row_remove( + self.as_ref().to_glib_none().0, + widget.as_ref().to_glib_none().0, + ); + } + } + + fn set_activatable_widget(&self, widget: Option<&impl IsA>) { + unsafe { + ffi::adw_action_row_set_activatable_widget( + self.as_ref().to_glib_none().0, + widget.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[allow(deprecated)] + fn set_icon_name(&self, icon_name: Option<&str>) { + unsafe { + ffi::adw_action_row_set_icon_name( + self.as_ref().to_glib_none().0, + icon_name.to_glib_none().0, + ); + } + } + + fn set_subtitle(&self, subtitle: &str) { + unsafe { + ffi::adw_action_row_set_subtitle( + self.as_ref().to_glib_none().0, + subtitle.to_glib_none().0, + ); + } + } + + fn set_subtitle_lines(&self, subtitle_lines: i32) { + unsafe { + ffi::adw_action_row_set_subtitle_lines(self.as_ref().to_glib_none().0, subtitle_lines); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn set_subtitle_selectable(&self, subtitle_selectable: bool) { + unsafe { + ffi::adw_action_row_set_subtitle_selectable( + self.as_ref().to_glib_none().0, + subtitle_selectable.into_glib(), + ); + } + } + + fn set_title_lines(&self, title_lines: i32) { + unsafe { + ffi::adw_action_row_set_title_lines(self.as_ref().to_glib_none().0, title_lines); + } + } + + fn connect_activated(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn activated_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwActionRow, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ActionRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"activated\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + activated_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_activatable_widget_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_activatable_widget_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwActionRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ActionRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::activatable-widget\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_activatable_widget_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_icon_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_icon_name_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwActionRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ActionRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::icon-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_icon_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_subtitle_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_subtitle_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwActionRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ActionRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::subtitle\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_subtitle_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_subtitle_lines_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_subtitle_lines_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwActionRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ActionRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::subtitle-lines\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_subtitle_lines_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn connect_subtitle_selectable_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_subtitle_selectable_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwActionRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ActionRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::subtitle-selectable\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_subtitle_selectable_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_title_lines_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_lines_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwActionRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ActionRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title-lines\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_lines_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for ActionRow { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ActionRow") + } +} diff --git a/libadwaita-0.4.4/src/auto/animation.rs b/libadwaita-0.4.4/src/auto/animation.rs new file mode 100644 index 0000000..d90548e --- /dev/null +++ b/libadwaita-0.4.4/src/auto/animation.rs @@ -0,0 +1,301 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{AnimationState, AnimationTarget}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwAnimation")] + pub struct Animation(Object); + + match fn { + type_ => || ffi::adw_animation_get_type(), + } +} + +impl Animation { + pub const NONE: Option<&'static Animation> = None; +} + +pub trait AnimationExt: 'static { + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_animation_get_follow_enable_animations_setting")] + #[doc(alias = "get_follow_enable_animations_setting")] + fn follows_enable_animations_setting(&self) -> bool; + + #[doc(alias = "adw_animation_get_state")] + #[doc(alias = "get_state")] + fn state(&self) -> AnimationState; + + #[doc(alias = "adw_animation_get_target")] + #[doc(alias = "get_target")] + fn target(&self) -> AnimationTarget; + + #[doc(alias = "adw_animation_get_value")] + #[doc(alias = "get_value")] + fn value(&self) -> f64; + + #[doc(alias = "adw_animation_get_widget")] + #[doc(alias = "get_widget")] + fn widget(&self) -> gtk::Widget; + + #[doc(alias = "adw_animation_pause")] + fn pause(&self); + + #[doc(alias = "adw_animation_play")] + fn play(&self); + + #[doc(alias = "adw_animation_reset")] + fn reset(&self); + + #[doc(alias = "adw_animation_resume")] + fn resume(&self); + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_animation_set_follow_enable_animations_setting")] + fn set_follow_enable_animations_setting(&self, setting: bool); + + #[doc(alias = "adw_animation_set_target")] + fn set_target(&self, target: &impl IsA); + + #[doc(alias = "adw_animation_skip")] + fn skip(&self); + + #[doc(alias = "done")] + fn connect_done(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "follow-enable-animations-setting")] + fn connect_follow_enable_animations_setting_notify( + &self, + f: F, + ) -> SignalHandlerId; + + #[doc(alias = "state")] + fn connect_state_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "target")] + fn connect_target_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "value")] + fn connect_value_notify(&self, f: F) -> SignalHandlerId; +} + +impl> AnimationExt for O { + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn follows_enable_animations_setting(&self) -> bool { + unsafe { + from_glib(ffi::adw_animation_get_follow_enable_animations_setting( + self.as_ref().to_glib_none().0, + )) + } + } + + fn state(&self) -> AnimationState { + unsafe { from_glib(ffi::adw_animation_get_state(self.as_ref().to_glib_none().0)) } + } + + fn target(&self) -> AnimationTarget { + unsafe { + from_glib_none(ffi::adw_animation_get_target( + self.as_ref().to_glib_none().0, + )) + } + } + + fn value(&self) -> f64 { + unsafe { ffi::adw_animation_get_value(self.as_ref().to_glib_none().0) } + } + + fn widget(&self) -> gtk::Widget { + unsafe { + from_glib_none(ffi::adw_animation_get_widget( + self.as_ref().to_glib_none().0, + )) + } + } + + fn pause(&self) { + unsafe { + ffi::adw_animation_pause(self.as_ref().to_glib_none().0); + } + } + + fn play(&self) { + unsafe { + ffi::adw_animation_play(self.as_ref().to_glib_none().0); + } + } + + fn reset(&self) { + unsafe { + ffi::adw_animation_reset(self.as_ref().to_glib_none().0); + } + } + + fn resume(&self) { + unsafe { + ffi::adw_animation_resume(self.as_ref().to_glib_none().0); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn set_follow_enable_animations_setting(&self, setting: bool) { + unsafe { + ffi::adw_animation_set_follow_enable_animations_setting( + self.as_ref().to_glib_none().0, + setting.into_glib(), + ); + } + } + + fn set_target(&self, target: &impl IsA) { + unsafe { + ffi::adw_animation_set_target( + self.as_ref().to_glib_none().0, + target.as_ref().to_glib_none().0, + ); + } + } + + fn skip(&self) { + unsafe { + ffi::adw_animation_skip(self.as_ref().to_glib_none().0); + } + } + + fn connect_done(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn done_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwAnimation, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(Animation::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"done\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + done_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn connect_follow_enable_animations_setting_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_follow_enable_animations_setting_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(Animation::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::follow-enable-animations-setting\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_follow_enable_animations_setting_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_state_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_state_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(Animation::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::state\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_state_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_target_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_target_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(Animation::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::target\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_target_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_value_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_value_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(Animation::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::value\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_value_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for Animation { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Animation") + } +} diff --git a/libadwaita-0.4.4/src/auto/animation_target.rs b/libadwaita-0.4.4/src/auto/animation_target.rs new file mode 100644 index 0000000..3c5b9f9 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/animation_target.rs @@ -0,0 +1,25 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use std::fmt; + +glib::wrapper! { + #[doc(alias = "AdwAnimationTarget")] + pub struct AnimationTarget(Object); + + match fn { + type_ => || ffi::adw_animation_target_get_type(), + } +} + +impl AnimationTarget { + pub const NONE: Option<&'static AnimationTarget> = None; +} + +impl fmt::Display for AnimationTarget { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("AnimationTarget") + } +} diff --git a/libadwaita-0.4.4/src/auto/application.rs b/libadwaita-0.4.4/src/auto/application.rs new file mode 100644 index 0000000..366d2b8 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/application.rs @@ -0,0 +1,161 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::StyleManager; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwApplication")] + pub struct Application(Object) @extends gtk::Application, gio::Application, @implements gio::ActionGroup, gio::ActionMap; + + match fn { + type_ => || ffi::adw_application_get_type(), + } +} + +impl Application { + pub const NONE: Option<&'static Application> = None; + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`Application`] objects. + /// + /// This method returns an instance of [`ApplicationBuilder`](crate::builders::ApplicationBuilder) which can be used to create [`Application`] objects. + pub fn builder() -> ApplicationBuilder { + ApplicationBuilder::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`Application`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ApplicationBuilder { + builder: glib::object::ObjectBuilder<'static, Application>, +} + +impl ApplicationBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn menubar(self, menubar: &impl IsA) -> Self { + Self { + builder: self.builder.property("menubar", menubar.clone().upcast()), + } + } + + pub fn register_session(self, register_session: bool) -> Self { + Self { + builder: self.builder.property("register-session", register_session), + } + } + + pub fn action_group(self, action_group: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("action-group", action_group.clone().upcast()), + } + } + + pub fn application_id(self, application_id: impl Into) -> Self { + Self { + builder: self + .builder + .property("application-id", application_id.into()), + } + } + + pub fn flags(self, flags: gio::ApplicationFlags) -> Self { + Self { + builder: self.builder.property("flags", flags), + } + } + + pub fn inactivity_timeout(self, inactivity_timeout: u32) -> Self { + Self { + builder: self + .builder + .property("inactivity-timeout", inactivity_timeout), + } + } + + pub fn resource_base_path(self, resource_base_path: impl Into) -> Self { + Self { + builder: self + .builder + .property("resource-base-path", resource_base_path.into()), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`Application`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> Application { + let ret = self.builder.build(); + { + Application::register_startup_hook(&ret); + } + ret + } +} + +pub trait AdwApplicationExt: 'static { + #[doc(alias = "adw_application_get_style_manager")] + #[doc(alias = "get_style_manager")] + fn style_manager(&self) -> StyleManager; + + #[doc(alias = "style-manager")] + fn connect_style_manager_notify(&self, f: F) -> SignalHandlerId; +} + +impl> AdwApplicationExt for O { + fn style_manager(&self) -> StyleManager { + unsafe { + from_glib_none(ffi::adw_application_get_style_manager( + self.as_ref().to_glib_none().0, + )) + } + } + + fn connect_style_manager_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_style_manager_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwApplication, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(Application::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::style-manager\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_style_manager_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for Application { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Application") + } +} diff --git a/libadwaita-0.4.4/src/auto/application_window.rs b/libadwaita-0.4.4/src/auto/application_window.rs new file mode 100644 index 0000000..f20584b --- /dev/null +++ b/libadwaita-0.4.4/src/auto/application_window.rs @@ -0,0 +1,548 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +use crate::Breakpoint; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwApplicationWindow")] + pub struct ApplicationWindow(Object) @extends gtk::ApplicationWindow, gtk::Window, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager, gio::ActionGroup, gio::ActionMap; + + match fn { + type_ => || ffi::adw_application_window_get_type(), + } +} + +impl ApplicationWindow { + pub const NONE: Option<&'static ApplicationWindow> = None; + + #[doc(alias = "adw_application_window_new")] + pub fn new(app: &impl IsA) -> ApplicationWindow { + assert_initialized_main_thread!(); + unsafe { + gtk::Widget::from_glib_none(ffi::adw_application_window_new( + app.as_ref().to_glib_none().0, + )) + .unsafe_cast() + } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`ApplicationWindow`] objects. + /// + /// This method returns an instance of [`ApplicationWindowBuilder`](crate::builders::ApplicationWindowBuilder) which can be used to create [`ApplicationWindow`] objects. + pub fn builder() -> ApplicationWindowBuilder { + ApplicationWindowBuilder::new() + } +} + +impl Default for ApplicationWindow { + fn default() -> Self { + glib::object::Object::new::() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`ApplicationWindow`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ApplicationWindowBuilder { + builder: glib::object::ObjectBuilder<'static, ApplicationWindow>, +} + +impl ApplicationWindowBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn content(self, content: &impl IsA) -> Self { + Self { + builder: self.builder.property("content", content.clone().upcast()), + } + } + + pub fn show_menubar(self, show_menubar: bool) -> Self { + Self { + builder: self.builder.property("show-menubar", show_menubar), + } + } + + pub fn application(self, application: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("application", application.clone().upcast()), + } + } + + pub fn decorated(self, decorated: bool) -> Self { + Self { + builder: self.builder.property("decorated", decorated), + } + } + + pub fn default_height(self, default_height: i32) -> Self { + Self { + builder: self.builder.property("default-height", default_height), + } + } + + pub fn default_widget(self, default_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("default-widget", default_widget.clone().upcast()), + } + } + + pub fn default_width(self, default_width: i32) -> Self { + Self { + builder: self.builder.property("default-width", default_width), + } + } + + pub fn deletable(self, deletable: bool) -> Self { + Self { + builder: self.builder.property("deletable", deletable), + } + } + + pub fn destroy_with_parent(self, destroy_with_parent: bool) -> Self { + Self { + builder: self + .builder + .property("destroy-with-parent", destroy_with_parent), + } + } + + pub fn display(self, display: &gdk::Display) -> Self { + Self { + builder: self.builder.property("display", display.clone()), + } + } + + pub fn focus_visible(self, focus_visible: bool) -> Self { + Self { + builder: self.builder.property("focus-visible", focus_visible), + } + } + + pub fn focus_widget(self, focus_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("focus-widget", focus_widget.clone().upcast()), + } + } + + pub fn fullscreened(self, fullscreened: bool) -> Self { + Self { + builder: self.builder.property("fullscreened", fullscreened), + } + } + + #[cfg(any(feature = "gtk_v4_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "gtk_v4_2")))] + pub fn handle_menubar_accel(self, handle_menubar_accel: bool) -> Self { + Self { + builder: self + .builder + .property("handle-menubar-accel", handle_menubar_accel), + } + } + + pub fn hide_on_close(self, hide_on_close: bool) -> Self { + Self { + builder: self.builder.property("hide-on-close", hide_on_close), + } + } + + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn maximized(self, maximized: bool) -> Self { + Self { + builder: self.builder.property("maximized", maximized), + } + } + + pub fn mnemonics_visible(self, mnemonics_visible: bool) -> Self { + Self { + builder: self + .builder + .property("mnemonics-visible", mnemonics_visible), + } + } + + pub fn modal(self, modal: bool) -> Self { + Self { + builder: self.builder.property("modal", modal), + } + } + + pub fn resizable(self, resizable: bool) -> Self { + Self { + builder: self.builder.property("resizable", resizable), + } + } + + pub fn startup_id(self, startup_id: impl Into) -> Self { + Self { + builder: self.builder.property("startup-id", startup_id.into()), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "gtk_v4_6", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "gtk_v4_6")))] + pub fn titlebar(self, titlebar: &impl IsA) -> Self { + Self { + builder: self.builder.property("titlebar", titlebar.clone().upcast()), + } + } + + pub fn transient_for(self, transient_for: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("transient-for", transient_for.clone().upcast()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`ApplicationWindow`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> ApplicationWindow { + self.builder.build() + } +} + +pub trait AdwApplicationWindowExt: 'static { + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_application_window_add_breakpoint")] + fn add_breakpoint(&self, breakpoint: Breakpoint); + + #[doc(alias = "adw_application_window_get_content")] + #[doc(alias = "get_content")] + fn content(&self) -> Option; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_application_window_get_current_breakpoint")] + #[doc(alias = "get_current_breakpoint")] + fn current_breakpoint(&self) -> Option; + + #[doc(alias = "adw_application_window_set_content")] + fn set_content(&self, content: Option<&impl IsA>); + + #[doc(alias = "content")] + fn connect_content_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "current-breakpoint")] + fn connect_current_breakpoint_notify(&self, f: F) -> SignalHandlerId; +} + +impl> AdwApplicationWindowExt for O { + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn add_breakpoint(&self, breakpoint: Breakpoint) { + unsafe { + ffi::adw_application_window_add_breakpoint( + self.as_ref().to_glib_none().0, + breakpoint.into_glib_ptr(), + ); + } + } + + fn content(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_application_window_get_content( + self.as_ref().to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn current_breakpoint(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_application_window_get_current_breakpoint( + self.as_ref().to_glib_none().0, + )) + } + } + + fn set_content(&self, content: Option<&impl IsA>) { + unsafe { + ffi::adw_application_window_set_content( + self.as_ref().to_glib_none().0, + content.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + fn connect_content_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_content_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwApplicationWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ApplicationWindow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::content\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_content_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_current_breakpoint_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_current_breakpoint_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwApplicationWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ApplicationWindow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::current-breakpoint\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_current_breakpoint_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for ApplicationWindow { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ApplicationWindow") + } +} diff --git a/libadwaita-0.4.4/src/auto/avatar.rs b/libadwaita-0.4.4/src/auto/avatar.rs new file mode 100644 index 0000000..2a88af0 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/avatar.rs @@ -0,0 +1,488 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwAvatar")] + pub struct Avatar(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_avatar_get_type(), + } +} + +impl Avatar { + #[doc(alias = "adw_avatar_new")] + pub fn new(size: i32, text: Option<&str>, show_initials: bool) -> Avatar { + assert_initialized_main_thread!(); + unsafe { + gtk::Widget::from_glib_none(ffi::adw_avatar_new( + size, + text.to_glib_none().0, + show_initials.into_glib(), + )) + .unsafe_cast() + } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`Avatar`] objects. + /// + /// This method returns an instance of [`AvatarBuilder`](crate::builders::AvatarBuilder) which can be used to create [`Avatar`] objects. + pub fn builder() -> AvatarBuilder { + AvatarBuilder::new() + } + + #[doc(alias = "adw_avatar_draw_to_texture")] + pub fn draw_to_texture(&self, scale_factor: i32) -> gdk::Texture { + unsafe { + from_glib_full(ffi::adw_avatar_draw_to_texture( + self.to_glib_none().0, + scale_factor, + )) + } + } + + #[doc(alias = "adw_avatar_get_custom_image")] + #[doc(alias = "get_custom_image")] + pub fn custom_image(&self) -> Option { + unsafe { from_glib_none(ffi::adw_avatar_get_custom_image(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_avatar_get_icon_name")] + #[doc(alias = "get_icon_name")] + pub fn icon_name(&self) -> Option { + unsafe { from_glib_none(ffi::adw_avatar_get_icon_name(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_avatar_get_show_initials")] + #[doc(alias = "get_show_initials")] + pub fn shows_initials(&self) -> bool { + unsafe { from_glib(ffi::adw_avatar_get_show_initials(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_avatar_get_size")] + #[doc(alias = "get_size")] + pub fn size(&self) -> i32 { + unsafe { ffi::adw_avatar_get_size(self.to_glib_none().0) } + } + + #[doc(alias = "adw_avatar_get_text")] + #[doc(alias = "get_text")] + pub fn text(&self) -> Option { + unsafe { from_glib_none(ffi::adw_avatar_get_text(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_avatar_set_custom_image")] + pub fn set_custom_image(&self, custom_image: Option<&impl IsA>) { + unsafe { + ffi::adw_avatar_set_custom_image( + self.to_glib_none().0, + custom_image.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_avatar_set_icon_name")] + pub fn set_icon_name(&self, icon_name: Option<&str>) { + unsafe { + ffi::adw_avatar_set_icon_name(self.to_glib_none().0, icon_name.to_glib_none().0); + } + } + + #[doc(alias = "adw_avatar_set_show_initials")] + pub fn set_show_initials(&self, show_initials: bool) { + unsafe { + ffi::adw_avatar_set_show_initials(self.to_glib_none().0, show_initials.into_glib()); + } + } + + #[doc(alias = "adw_avatar_set_size")] + pub fn set_size(&self, size: i32) { + unsafe { + ffi::adw_avatar_set_size(self.to_glib_none().0, size); + } + } + + #[doc(alias = "adw_avatar_set_text")] + pub fn set_text(&self, text: Option<&str>) { + unsafe { + ffi::adw_avatar_set_text(self.to_glib_none().0, text.to_glib_none().0); + } + } + + #[doc(alias = "custom-image")] + pub fn connect_custom_image_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_custom_image_trampoline( + this: *mut ffi::AdwAvatar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::custom-image\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_custom_image_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "icon-name")] + pub fn connect_icon_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_icon_name_trampoline( + this: *mut ffi::AdwAvatar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::icon-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_icon_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "show-initials")] + pub fn connect_show_initials_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_show_initials_trampoline( + this: *mut ffi::AdwAvatar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::show-initials\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_show_initials_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "size")] + pub fn connect_size_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_size_trampoline( + this: *mut ffi::AdwAvatar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::size\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_size_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "text")] + pub fn connect_text_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_text_trampoline( + this: *mut ffi::AdwAvatar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::text\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_text_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for Avatar { + fn default() -> Self { + glib::object::Object::new::() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`Avatar`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct AvatarBuilder { + builder: glib::object::ObjectBuilder<'static, Avatar>, +} + +impl AvatarBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn custom_image(self, custom_image: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("custom-image", custom_image.clone().upcast()), + } + } + + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn show_initials(self, show_initials: bool) -> Self { + Self { + builder: self.builder.property("show-initials", show_initials), + } + } + + pub fn size(self, size: i32) -> Self { + Self { + builder: self.builder.property("size", size), + } + } + + pub fn text(self, text: impl Into) -> Self { + Self { + builder: self.builder.property("text", text.into()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`Avatar`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> Avatar { + self.builder.build() + } +} + +impl fmt::Display for Avatar { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Avatar") + } +} diff --git a/libadwaita-0.4.4/src/auto/banner.rs b/libadwaita-0.4.4/src/auto/banner.rs new file mode 100644 index 0000000..c44fc30 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/banner.rs @@ -0,0 +1,482 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwBanner")] + pub struct Banner(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable; + + match fn { + type_ => || ffi::adw_banner_get_type(), + } +} + +impl Banner { + #[doc(alias = "adw_banner_new")] + pub fn new(title: &str) -> Banner { + assert_initialized_main_thread!(); + unsafe { + gtk::Widget::from_glib_none(ffi::adw_banner_new(title.to_glib_none().0)).unsafe_cast() + } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`Banner`] objects. + /// + /// This method returns an instance of [`BannerBuilder`](crate::builders::BannerBuilder) which can be used to create [`Banner`] objects. + pub fn builder() -> BannerBuilder { + BannerBuilder::new() + } + + #[doc(alias = "adw_banner_get_button_label")] + #[doc(alias = "get_button_label")] + pub fn button_label(&self) -> Option { + unsafe { from_glib_none(ffi::adw_banner_get_button_label(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_banner_get_revealed")] + #[doc(alias = "get_revealed")] + pub fn is_revealed(&self) -> bool { + unsafe { from_glib(ffi::adw_banner_get_revealed(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_banner_get_title")] + #[doc(alias = "get_title")] + pub fn title(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_banner_get_title(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_banner_get_use_markup")] + #[doc(alias = "get_use_markup")] + pub fn uses_markup(&self) -> bool { + unsafe { from_glib(ffi::adw_banner_get_use_markup(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_banner_set_button_label")] + pub fn set_button_label(&self, label: Option<&str>) { + unsafe { + ffi::adw_banner_set_button_label(self.to_glib_none().0, label.to_glib_none().0); + } + } + + #[doc(alias = "adw_banner_set_revealed")] + pub fn set_revealed(&self, revealed: bool) { + unsafe { + ffi::adw_banner_set_revealed(self.to_glib_none().0, revealed.into_glib()); + } + } + + #[doc(alias = "adw_banner_set_title")] + pub fn set_title(&self, title: &str) { + unsafe { + ffi::adw_banner_set_title(self.to_glib_none().0, title.to_glib_none().0); + } + } + + #[doc(alias = "adw_banner_set_use_markup")] + pub fn set_use_markup(&self, use_markup: bool) { + unsafe { + ffi::adw_banner_set_use_markup(self.to_glib_none().0, use_markup.into_glib()); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "button-clicked")] + pub fn connect_button_clicked(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn button_clicked_trampoline( + this: *mut ffi::AdwBanner, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"button-clicked\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + button_clicked_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "button-label")] + pub fn connect_button_label_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_button_label_trampoline( + this: *mut ffi::AdwBanner, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::button-label\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_button_label_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "revealed")] + pub fn connect_revealed_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_revealed_trampoline( + this: *mut ffi::AdwBanner, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::revealed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_revealed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "title")] + pub fn connect_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_trampoline( + this: *mut ffi::AdwBanner, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "use-markup")] + pub fn connect_use_markup_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_use_markup_trampoline( + this: *mut ffi::AdwBanner, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::use-markup\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_use_markup_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +#[cfg(any(feature = "v1_3", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] +impl Default for Banner { + fn default() -> Self { + glib::object::Object::new::() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`Banner`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct BannerBuilder { + builder: glib::object::ObjectBuilder<'static, Banner>, +} + +impl BannerBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn button_label(self, button_label: impl Into) -> Self { + Self { + builder: self.builder.property("button-label", button_label.into()), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn revealed(self, revealed: bool) -> Self { + Self { + builder: self.builder.property("revealed", revealed), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn use_markup(self, use_markup: bool) -> Self { + Self { + builder: self.builder.property("use-markup", use_markup), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn action_name(self, action_name: impl Into) -> Self { + Self { + builder: self.builder.property("action-name", action_name.into()), + } + } + + pub fn action_target(self, action_target: &glib::Variant) -> Self { + Self { + builder: self + .builder + .property("action-target", action_target.clone()), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`Banner`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> Banner { + self.builder.build() + } +} + +impl fmt::Display for Banner { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Banner") + } +} diff --git a/libadwaita-0.4.4/src/auto/bin.rs b/libadwaita-0.4.4/src/auto/bin.rs new file mode 100644 index 0000000..cd39185 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/bin.rs @@ -0,0 +1,313 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwBin")] + pub struct Bin(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_bin_get_type(), + } +} + +impl Bin { + pub const NONE: Option<&'static Bin> = None; + + #[doc(alias = "adw_bin_new")] + pub fn new() -> Bin { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_bin_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`Bin`] objects. + /// + /// This method returns an instance of [`BinBuilder`](crate::builders::BinBuilder) which can be used to create [`Bin`] objects. + pub fn builder() -> BinBuilder { + BinBuilder::new() + } +} + +impl Default for Bin { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`Bin`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct BinBuilder { + builder: glib::object::ObjectBuilder<'static, Bin>, +} + +impl BinBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`Bin`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> Bin { + self.builder.build() + } +} + +pub trait BinExt: 'static { + #[doc(alias = "adw_bin_get_child")] + #[doc(alias = "get_child")] + fn child(&self) -> Option; + + #[doc(alias = "adw_bin_set_child")] + fn set_child(&self, child: Option<&impl IsA>); + + #[doc(alias = "child")] + fn connect_child_notify(&self, f: F) -> SignalHandlerId; +} + +impl> BinExt for O { + fn child(&self) -> Option { + unsafe { from_glib_none(ffi::adw_bin_get_child(self.as_ref().to_glib_none().0)) } + } + + fn set_child(&self, child: Option<&impl IsA>) { + unsafe { + ffi::adw_bin_set_child( + self.as_ref().to_glib_none().0, + child.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + fn connect_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_child_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwBin, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(Bin::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for Bin { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Bin") + } +} diff --git a/libadwaita-0.4.4/src/auto/breakpoint.rs b/libadwaita-0.4.4/src/auto/breakpoint.rs new file mode 100644 index 0000000..ce9f3b6 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/breakpoint.rs @@ -0,0 +1,136 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::BreakpointCondition; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwBreakpoint")] + pub struct Breakpoint(Object) @implements gtk::Buildable; + + match fn { + type_ => || ffi::adw_breakpoint_get_type(), + } +} + +impl Breakpoint { + #[doc(alias = "adw_breakpoint_new")] + pub fn new(condition: BreakpointCondition) -> Breakpoint { + assert_initialized_main_thread!(); + unsafe { from_glib_full(ffi::adw_breakpoint_new(condition.into_glib_ptr())) } + } + + #[doc(alias = "adw_breakpoint_add_setter")] + pub fn add_setter(&self, object: &impl IsA, property: &str, value: &glib::Value) { + unsafe { + ffi::adw_breakpoint_add_setter( + self.to_glib_none().0, + object.as_ref().to_glib_none().0, + property.to_glib_none().0, + value.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_breakpoint_get_condition")] + #[doc(alias = "get_condition")] + pub fn condition(&self) -> Option { + unsafe { from_glib_none(ffi::adw_breakpoint_get_condition(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_breakpoint_set_condition")] + pub fn set_condition(&self, condition: Option<&BreakpointCondition>) { + unsafe { + ffi::adw_breakpoint_set_condition( + self.to_glib_none().0, + mut_override(condition.to_glib_none().0), + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "apply")] + pub fn connect_apply(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn apply_trampoline( + this: *mut ffi::AdwBreakpoint, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"apply\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + apply_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "unapply")] + pub fn connect_unapply(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn unapply_trampoline( + this: *mut ffi::AdwBreakpoint, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"unapply\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + unapply_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "condition")] + pub fn connect_condition_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_condition_trampoline( + this: *mut ffi::AdwBreakpoint, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::condition\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_condition_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for Breakpoint { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Breakpoint") + } +} diff --git a/libadwaita-0.4.4/src/auto/breakpoint_bin.rs b/libadwaita-0.4.4/src/auto/breakpoint_bin.rs new file mode 100644 index 0000000..b87ec71 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/breakpoint_bin.rs @@ -0,0 +1,382 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::Breakpoint; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwBreakpointBin")] + pub struct BreakpointBin(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_breakpoint_bin_get_type(), + } +} + +impl BreakpointBin { + pub const NONE: Option<&'static BreakpointBin> = None; + + #[doc(alias = "adw_breakpoint_bin_new")] + pub fn new() -> BreakpointBin { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_breakpoint_bin_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`BreakpointBin`] objects. + /// + /// This method returns an instance of [`BreakpointBinBuilder`](crate::builders::BreakpointBinBuilder) which can be used to create [`BreakpointBin`] objects. + pub fn builder() -> BreakpointBinBuilder { + BreakpointBinBuilder::new() + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl Default for BreakpointBin { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`BreakpointBin`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct BreakpointBinBuilder { + builder: glib::object::ObjectBuilder<'static, BreakpointBin>, +} + +impl BreakpointBinBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`BreakpointBin`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> BreakpointBin { + self.builder.build() + } +} + +pub trait BreakpointBinExt: 'static { + #[doc(alias = "adw_breakpoint_bin_add_breakpoint")] + fn add_breakpoint(&self, breakpoint: Breakpoint); + + #[doc(alias = "adw_breakpoint_bin_get_child")] + #[doc(alias = "get_child")] + fn child(&self) -> Option; + + #[doc(alias = "adw_breakpoint_bin_get_current_breakpoint")] + #[doc(alias = "get_current_breakpoint")] + fn current_breakpoint(&self) -> Option; + + #[doc(alias = "adw_breakpoint_bin_set_child")] + fn set_child(&self, child: Option<&impl IsA>); + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "child")] + fn connect_child_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "current-breakpoint")] + fn connect_current_breakpoint_notify(&self, f: F) -> SignalHandlerId; +} + +impl> BreakpointBinExt for O { + fn add_breakpoint(&self, breakpoint: Breakpoint) { + unsafe { + ffi::adw_breakpoint_bin_add_breakpoint( + self.as_ref().to_glib_none().0, + breakpoint.into_glib_ptr(), + ); + } + } + + fn child(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_breakpoint_bin_get_child( + self.as_ref().to_glib_none().0, + )) + } + } + + fn current_breakpoint(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_breakpoint_bin_get_current_breakpoint( + self.as_ref().to_glib_none().0, + )) + } + } + + fn set_child(&self, child: Option<&impl IsA>) { + unsafe { + ffi::adw_breakpoint_bin_set_child( + self.as_ref().to_glib_none().0, + child.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_child_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwBreakpointBin, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(BreakpointBin::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_current_breakpoint_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_current_breakpoint_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwBreakpointBin, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(BreakpointBin::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::current-breakpoint\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_current_breakpoint_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for BreakpointBin { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("BreakpointBin") + } +} diff --git a/libadwaita-0.4.4/src/auto/breakpoint_condition.rs b/libadwaita-0.4.4/src/auto/breakpoint_condition.rs new file mode 100644 index 0000000..05401e5 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/breakpoint_condition.rs @@ -0,0 +1,107 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{BreakpointConditionLengthType, BreakpointConditionRatioType, LengthUnit}; +use glib::translate::*; +use std::fmt; + +glib::wrapper! { + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct BreakpointCondition(Boxed); + + match fn { + copy => |ptr| ffi::adw_breakpoint_condition_copy(mut_override(ptr)), + free => |ptr| ffi::adw_breakpoint_condition_free(ptr), + type_ => || ffi::adw_breakpoint_condition_get_type(), + } +} + +impl BreakpointCondition { + #[doc(alias = "adw_breakpoint_condition_new_and")] + pub fn new_and( + condition_1: BreakpointCondition, + condition_2: BreakpointCondition, + ) -> BreakpointCondition { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::adw_breakpoint_condition_new_and( + condition_1.into_glib_ptr(), + condition_2.into_glib_ptr(), + )) + } + } + + #[doc(alias = "adw_breakpoint_condition_new_length")] + pub fn new_length( + type_: BreakpointConditionLengthType, + value: f64, + unit: LengthUnit, + ) -> BreakpointCondition { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::adw_breakpoint_condition_new_length( + type_.into_glib(), + value, + unit.into_glib(), + )) + } + } + + #[doc(alias = "adw_breakpoint_condition_new_or")] + pub fn new_or( + condition_1: BreakpointCondition, + condition_2: BreakpointCondition, + ) -> BreakpointCondition { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::adw_breakpoint_condition_new_or( + condition_1.into_glib_ptr(), + condition_2.into_glib_ptr(), + )) + } + } + + #[doc(alias = "adw_breakpoint_condition_new_ratio")] + pub fn new_ratio( + type_: BreakpointConditionRatioType, + width: i32, + height: i32, + ) -> BreakpointCondition { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::adw_breakpoint_condition_new_ratio( + type_.into_glib(), + width, + height, + )) + } + } + + #[doc(alias = "adw_breakpoint_condition_to_string")] + #[doc(alias = "to_string")] + pub fn to_str(&self) -> glib::GString { + unsafe { + from_glib_full(ffi::adw_breakpoint_condition_to_string(mut_override( + self.to_glib_none().0, + ))) + } + } + + #[doc(alias = "adw_breakpoint_condition_parse")] + pub fn parse(str: &str) -> Result { + assert_initialized_main_thread!(); + unsafe { + Option::<_>::from_glib_full(ffi::adw_breakpoint_condition_parse(str.to_glib_none().0)) + .ok_or_else(|| glib::bool_error!("Invalid condition")) + } + } +} + +impl fmt::Display for BreakpointCondition { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.to_str()) + } +} diff --git a/libadwaita-0.4.4/src/auto/button_content.rs b/libadwaita-0.4.4/src/auto/button_content.rs new file mode 100644 index 0000000..5b44de7 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/button_content.rs @@ -0,0 +1,446 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwButtonContent")] + pub struct ButtonContent(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_button_content_get_type(), + } +} + +impl ButtonContent { + #[doc(alias = "adw_button_content_new")] + pub fn new() -> ButtonContent { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_button_content_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`ButtonContent`] objects. + /// + /// This method returns an instance of [`ButtonContentBuilder`](crate::builders::ButtonContentBuilder) which can be used to create [`ButtonContent`] objects. + pub fn builder() -> ButtonContentBuilder { + ButtonContentBuilder::new() + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_button_content_get_can_shrink")] + #[doc(alias = "get_can_shrink")] + pub fn can_shrink(&self) -> bool { + unsafe { + from_glib(ffi::adw_button_content_get_can_shrink( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_button_content_get_icon_name")] + #[doc(alias = "get_icon_name")] + pub fn icon_name(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_button_content_get_icon_name(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_button_content_get_label")] + #[doc(alias = "get_label")] + pub fn label(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_button_content_get_label(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_button_content_get_use_underline")] + #[doc(alias = "get_use_underline")] + pub fn uses_underline(&self) -> bool { + unsafe { + from_glib(ffi::adw_button_content_get_use_underline( + self.to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_button_content_set_can_shrink")] + pub fn set_can_shrink(&self, can_shrink: bool) { + unsafe { + ffi::adw_button_content_set_can_shrink(self.to_glib_none().0, can_shrink.into_glib()); + } + } + + #[doc(alias = "adw_button_content_set_icon_name")] + pub fn set_icon_name(&self, icon_name: &str) { + unsafe { + ffi::adw_button_content_set_icon_name( + self.to_glib_none().0, + icon_name.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_button_content_set_label")] + pub fn set_label(&self, label: &str) { + unsafe { + ffi::adw_button_content_set_label(self.to_glib_none().0, label.to_glib_none().0); + } + } + + #[doc(alias = "adw_button_content_set_use_underline")] + pub fn set_use_underline(&self, use_underline: bool) { + unsafe { + ffi::adw_button_content_set_use_underline( + self.to_glib_none().0, + use_underline.into_glib(), + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "can-shrink")] + pub fn connect_can_shrink_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_can_shrink_trampoline( + this: *mut ffi::AdwButtonContent, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::can-shrink\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_can_shrink_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "icon-name")] + pub fn connect_icon_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_icon_name_trampoline( + this: *mut ffi::AdwButtonContent, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::icon-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_icon_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "label")] + pub fn connect_label_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_label_trampoline( + this: *mut ffi::AdwButtonContent, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::label\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_label_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "use-underline")] + pub fn connect_use_underline_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_use_underline_trampoline( + this: *mut ffi::AdwButtonContent, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::use-underline\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_use_underline_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for ButtonContent { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`ButtonContent`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ButtonContentBuilder { + builder: glib::object::ObjectBuilder<'static, ButtonContent>, +} + +impl ButtonContentBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn can_shrink(self, can_shrink: bool) -> Self { + Self { + builder: self.builder.property("can-shrink", can_shrink), + } + } + + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn label(self, label: impl Into) -> Self { + Self { + builder: self.builder.property("label", label.into()), + } + } + + pub fn use_underline(self, use_underline: bool) -> Self { + Self { + builder: self.builder.property("use-underline", use_underline), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`ButtonContent`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> ButtonContent { + self.builder.build() + } +} + +impl fmt::Display for ButtonContent { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ButtonContent") + } +} diff --git a/libadwaita-0.4.4/src/auto/callback_animation_target.rs b/libadwaita-0.4.4/src/auto/callback_animation_target.rs new file mode 100644 index 0000000..2ec830f --- /dev/null +++ b/libadwaita-0.4.4/src/auto/callback_animation_target.rs @@ -0,0 +1,52 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::AnimationTarget; +use glib::{prelude::*, translate::*}; +use std::{boxed::Box as Box_, fmt}; + +glib::wrapper! { + #[doc(alias = "AdwCallbackAnimationTarget")] + pub struct CallbackAnimationTarget(Object) @extends AnimationTarget; + + match fn { + type_ => || ffi::adw_callback_animation_target_get_type(), + } +} + +impl CallbackAnimationTarget { + #[doc(alias = "adw_callback_animation_target_new")] + pub fn new(callback: P) -> CallbackAnimationTarget { + assert_initialized_main_thread!(); + let callback_data: Box_

= Box_::new(callback); + unsafe extern "C" fn callback_func( + value: libc::c_double, + user_data: glib::ffi::gpointer, + ) { + let callback: &P = &*(user_data as *mut _); + (*callback)(value) + } + let callback = Some(callback_func::

as _); + unsafe extern "C" fn destroy_func(data: glib::ffi::gpointer) { + let _callback: Box_

= Box_::from_raw(data as *mut _); + } + let destroy_call2 = Some(destroy_func::

as _); + let super_callback0: Box_

= callback_data; + unsafe { + AnimationTarget::from_glib_full(ffi::adw_callback_animation_target_new( + callback, + Box_::into_raw(super_callback0) as *mut _, + destroy_call2, + )) + .unsafe_cast() + } + } +} + +impl fmt::Display for CallbackAnimationTarget { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("CallbackAnimationTarget") + } +} diff --git a/libadwaita-0.4.4/src/auto/carousel.rs b/libadwaita-0.4.4/src/auto/carousel.rs new file mode 100644 index 0000000..8034841 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/carousel.rs @@ -0,0 +1,725 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{SpringParams, Swipeable}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwCarousel")] + pub struct Carousel(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, Swipeable, gtk::Orientable; + + match fn { + type_ => || ffi::adw_carousel_get_type(), + } +} + +impl Carousel { + #[doc(alias = "adw_carousel_new")] + pub fn new() -> Carousel { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_carousel_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`Carousel`] objects. + /// + /// This method returns an instance of [`CarouselBuilder`](crate::builders::CarouselBuilder) which can be used to create [`Carousel`] objects. + pub fn builder() -> CarouselBuilder { + CarouselBuilder::new() + } + + #[doc(alias = "adw_carousel_append")] + pub fn append(&self, child: &impl IsA) { + unsafe { + ffi::adw_carousel_append(self.to_glib_none().0, child.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_carousel_get_allow_long_swipes")] + #[doc(alias = "get_allow_long_swipes")] + pub fn allows_long_swipes(&self) -> bool { + unsafe { + from_glib(ffi::adw_carousel_get_allow_long_swipes( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_carousel_get_allow_mouse_drag")] + #[doc(alias = "get_allow_mouse_drag")] + pub fn allows_mouse_drag(&self) -> bool { + unsafe { + from_glib(ffi::adw_carousel_get_allow_mouse_drag( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_carousel_get_allow_scroll_wheel")] + #[doc(alias = "get_allow_scroll_wheel")] + pub fn allows_scroll_wheel(&self) -> bool { + unsafe { + from_glib(ffi::adw_carousel_get_allow_scroll_wheel( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_carousel_get_interactive")] + #[doc(alias = "get_interactive")] + pub fn is_interactive(&self) -> bool { + unsafe { from_glib(ffi::adw_carousel_get_interactive(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_carousel_get_n_pages")] + #[doc(alias = "get_n_pages")] + pub fn n_pages(&self) -> u32 { + unsafe { ffi::adw_carousel_get_n_pages(self.to_glib_none().0) } + } + + #[doc(alias = "adw_carousel_get_position")] + #[doc(alias = "get_position")] + pub fn position(&self) -> f64 { + unsafe { ffi::adw_carousel_get_position(self.to_glib_none().0) } + } + + #[doc(alias = "adw_carousel_get_reveal_duration")] + #[doc(alias = "get_reveal_duration")] + pub fn reveal_duration(&self) -> u32 { + unsafe { ffi::adw_carousel_get_reveal_duration(self.to_glib_none().0) } + } + + #[doc(alias = "adw_carousel_get_scroll_params")] + #[doc(alias = "get_scroll_params")] + pub fn scroll_params(&self) -> SpringParams { + unsafe { from_glib_full(ffi::adw_carousel_get_scroll_params(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_carousel_get_spacing")] + #[doc(alias = "get_spacing")] + pub fn spacing(&self) -> u32 { + unsafe { ffi::adw_carousel_get_spacing(self.to_glib_none().0) } + } + + #[doc(alias = "adw_carousel_insert")] + pub fn insert(&self, child: &impl IsA, position: i32) { + unsafe { + ffi::adw_carousel_insert( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + position, + ); + } + } + + #[doc(alias = "adw_carousel_prepend")] + pub fn prepend(&self, child: &impl IsA) { + unsafe { + ffi::adw_carousel_prepend(self.to_glib_none().0, child.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_carousel_remove")] + pub fn remove(&self, child: &impl IsA) { + unsafe { + ffi::adw_carousel_remove(self.to_glib_none().0, child.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_carousel_reorder")] + pub fn reorder(&self, child: &impl IsA, position: i32) { + unsafe { + ffi::adw_carousel_reorder( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + position, + ); + } + } + + #[doc(alias = "adw_carousel_scroll_to")] + pub fn scroll_to(&self, widget: &impl IsA, animate: bool) { + unsafe { + ffi::adw_carousel_scroll_to( + self.to_glib_none().0, + widget.as_ref().to_glib_none().0, + animate.into_glib(), + ); + } + } + + #[doc(alias = "adw_carousel_set_allow_long_swipes")] + pub fn set_allow_long_swipes(&self, allow_long_swipes: bool) { + unsafe { + ffi::adw_carousel_set_allow_long_swipes( + self.to_glib_none().0, + allow_long_swipes.into_glib(), + ); + } + } + + #[doc(alias = "adw_carousel_set_allow_mouse_drag")] + pub fn set_allow_mouse_drag(&self, allow_mouse_drag: bool) { + unsafe { + ffi::adw_carousel_set_allow_mouse_drag( + self.to_glib_none().0, + allow_mouse_drag.into_glib(), + ); + } + } + + #[doc(alias = "adw_carousel_set_allow_scroll_wheel")] + pub fn set_allow_scroll_wheel(&self, allow_scroll_wheel: bool) { + unsafe { + ffi::adw_carousel_set_allow_scroll_wheel( + self.to_glib_none().0, + allow_scroll_wheel.into_glib(), + ); + } + } + + #[doc(alias = "adw_carousel_set_interactive")] + pub fn set_interactive(&self, interactive: bool) { + unsafe { + ffi::adw_carousel_set_interactive(self.to_glib_none().0, interactive.into_glib()); + } + } + + #[doc(alias = "adw_carousel_set_reveal_duration")] + pub fn set_reveal_duration(&self, reveal_duration: u32) { + unsafe { + ffi::adw_carousel_set_reveal_duration(self.to_glib_none().0, reveal_duration); + } + } + + #[doc(alias = "adw_carousel_set_scroll_params")] + pub fn set_scroll_params(&self, params: &SpringParams) { + unsafe { + ffi::adw_carousel_set_scroll_params(self.to_glib_none().0, params.to_glib_none().0); + } + } + + #[doc(alias = "adw_carousel_set_spacing")] + pub fn set_spacing(&self, spacing: u32) { + unsafe { + ffi::adw_carousel_set_spacing(self.to_glib_none().0, spacing); + } + } + + #[doc(alias = "page-changed")] + pub fn connect_page_changed(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn page_changed_trampoline( + this: *mut ffi::AdwCarousel, + index: libc::c_uint, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), index) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"page-changed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + page_changed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "allow-long-swipes")] + pub fn connect_allow_long_swipes_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_allow_long_swipes_trampoline( + this: *mut ffi::AdwCarousel, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::allow-long-swipes\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_allow_long_swipes_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "allow-mouse-drag")] + pub fn connect_allow_mouse_drag_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_allow_mouse_drag_trampoline( + this: *mut ffi::AdwCarousel, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::allow-mouse-drag\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_allow_mouse_drag_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "allow-scroll-wheel")] + pub fn connect_allow_scroll_wheel_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_allow_scroll_wheel_trampoline( + this: *mut ffi::AdwCarousel, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::allow-scroll-wheel\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_allow_scroll_wheel_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "interactive")] + pub fn connect_interactive_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_interactive_trampoline( + this: *mut ffi::AdwCarousel, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::interactive\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_interactive_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "n-pages")] + pub fn connect_n_pages_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_n_pages_trampoline( + this: *mut ffi::AdwCarousel, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::n-pages\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_n_pages_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "position")] + pub fn connect_position_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_position_trampoline( + this: *mut ffi::AdwCarousel, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::position\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_position_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "reveal-duration")] + pub fn connect_reveal_duration_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_reveal_duration_trampoline( + this: *mut ffi::AdwCarousel, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::reveal-duration\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_reveal_duration_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "scroll-params")] + pub fn connect_scroll_params_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_scroll_params_trampoline( + this: *mut ffi::AdwCarousel, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::scroll-params\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_scroll_params_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "spacing")] + pub fn connect_spacing_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_spacing_trampoline( + this: *mut ffi::AdwCarousel, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::spacing\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_spacing_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for Carousel { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`Carousel`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct CarouselBuilder { + builder: glib::object::ObjectBuilder<'static, Carousel>, +} + +impl CarouselBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn allow_long_swipes(self, allow_long_swipes: bool) -> Self { + Self { + builder: self + .builder + .property("allow-long-swipes", allow_long_swipes), + } + } + + pub fn allow_mouse_drag(self, allow_mouse_drag: bool) -> Self { + Self { + builder: self.builder.property("allow-mouse-drag", allow_mouse_drag), + } + } + + pub fn allow_scroll_wheel(self, allow_scroll_wheel: bool) -> Self { + Self { + builder: self + .builder + .property("allow-scroll-wheel", allow_scroll_wheel), + } + } + + pub fn interactive(self, interactive: bool) -> Self { + Self { + builder: self.builder.property("interactive", interactive), + } + } + + pub fn reveal_duration(self, reveal_duration: u32) -> Self { + Self { + builder: self.builder.property("reveal-duration", reveal_duration), + } + } + + pub fn scroll_params(self, scroll_params: &SpringParams) -> Self { + Self { + builder: self + .builder + .property("scroll-params", scroll_params.clone()), + } + } + + pub fn spacing(self, spacing: u32) -> Self { + Self { + builder: self.builder.property("spacing", spacing), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn orientation(self, orientation: gtk::Orientation) -> Self { + Self { + builder: self.builder.property("orientation", orientation), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`Carousel`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> Carousel { + self.builder.build() + } +} + +impl fmt::Display for Carousel { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Carousel") + } +} diff --git a/libadwaita-0.4.4/src/auto/carousel_indicator_dots.rs b/libadwaita-0.4.4/src/auto/carousel_indicator_dots.rs new file mode 100644 index 0000000..23a3cc9 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/carousel_indicator_dots.rs @@ -0,0 +1,312 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::Carousel; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwCarouselIndicatorDots")] + pub struct CarouselIndicatorDots(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable; + + match fn { + type_ => || ffi::adw_carousel_indicator_dots_get_type(), + } +} + +impl CarouselIndicatorDots { + #[doc(alias = "adw_carousel_indicator_dots_new")] + pub fn new() -> CarouselIndicatorDots { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_carousel_indicator_dots_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`CarouselIndicatorDots`] objects. + /// + /// This method returns an instance of [`CarouselIndicatorDotsBuilder`](crate::builders::CarouselIndicatorDotsBuilder) which can be used to create [`CarouselIndicatorDots`] objects. + pub fn builder() -> CarouselIndicatorDotsBuilder { + CarouselIndicatorDotsBuilder::new() + } + + #[doc(alias = "adw_carousel_indicator_dots_get_carousel")] + #[doc(alias = "get_carousel")] + pub fn carousel(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_carousel_indicator_dots_get_carousel( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_carousel_indicator_dots_set_carousel")] + pub fn set_carousel(&self, carousel: Option<&Carousel>) { + unsafe { + ffi::adw_carousel_indicator_dots_set_carousel( + self.to_glib_none().0, + carousel.to_glib_none().0, + ); + } + } + + #[doc(alias = "carousel")] + pub fn connect_carousel_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_carousel_trampoline( + this: *mut ffi::AdwCarouselIndicatorDots, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::carousel\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_carousel_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for CarouselIndicatorDots { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`CarouselIndicatorDots`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct CarouselIndicatorDotsBuilder { + builder: glib::object::ObjectBuilder<'static, CarouselIndicatorDots>, +} + +impl CarouselIndicatorDotsBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn carousel(self, carousel: &Carousel) -> Self { + Self { + builder: self.builder.property("carousel", carousel.clone()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn orientation(self, orientation: gtk::Orientation) -> Self { + Self { + builder: self.builder.property("orientation", orientation), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`CarouselIndicatorDots`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> CarouselIndicatorDots { + self.builder.build() + } +} + +impl fmt::Display for CarouselIndicatorDots { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("CarouselIndicatorDots") + } +} diff --git a/libadwaita-0.4.4/src/auto/carousel_indicator_lines.rs b/libadwaita-0.4.4/src/auto/carousel_indicator_lines.rs new file mode 100644 index 0000000..eafd952 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/carousel_indicator_lines.rs @@ -0,0 +1,316 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::Carousel; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwCarouselIndicatorLines")] + pub struct CarouselIndicatorLines(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable; + + match fn { + type_ => || ffi::adw_carousel_indicator_lines_get_type(), + } +} + +impl CarouselIndicatorLines { + #[doc(alias = "adw_carousel_indicator_lines_new")] + pub fn new() -> CarouselIndicatorLines { + assert_initialized_main_thread!(); + unsafe { + gtk::Widget::from_glib_none(ffi::adw_carousel_indicator_lines_new()).unsafe_cast() + } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`CarouselIndicatorLines`] objects. + /// + /// This method returns an instance of [`CarouselIndicatorLinesBuilder`](crate::builders::CarouselIndicatorLinesBuilder) which can be used to create [`CarouselIndicatorLines`] objects. + pub fn builder() -> CarouselIndicatorLinesBuilder { + CarouselIndicatorLinesBuilder::new() + } + + #[doc(alias = "adw_carousel_indicator_lines_get_carousel")] + #[doc(alias = "get_carousel")] + pub fn carousel(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_carousel_indicator_lines_get_carousel( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_carousel_indicator_lines_set_carousel")] + pub fn set_carousel(&self, carousel: Option<&Carousel>) { + unsafe { + ffi::adw_carousel_indicator_lines_set_carousel( + self.to_glib_none().0, + carousel.to_glib_none().0, + ); + } + } + + #[doc(alias = "carousel")] + pub fn connect_carousel_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_carousel_trampoline< + F: Fn(&CarouselIndicatorLines) + 'static, + >( + this: *mut ffi::AdwCarouselIndicatorLines, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::carousel\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_carousel_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for CarouselIndicatorLines { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`CarouselIndicatorLines`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct CarouselIndicatorLinesBuilder { + builder: glib::object::ObjectBuilder<'static, CarouselIndicatorLines>, +} + +impl CarouselIndicatorLinesBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn carousel(self, carousel: &Carousel) -> Self { + Self { + builder: self.builder.property("carousel", carousel.clone()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn orientation(self, orientation: gtk::Orientation) -> Self { + Self { + builder: self.builder.property("orientation", orientation), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`CarouselIndicatorLines`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> CarouselIndicatorLines { + self.builder.build() + } +} + +impl fmt::Display for CarouselIndicatorLines { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("CarouselIndicatorLines") + } +} diff --git a/libadwaita-0.4.4/src/auto/clamp.rs b/libadwaita-0.4.4/src/auto/clamp.rs new file mode 100644 index 0000000..aeef5e6 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/clamp.rs @@ -0,0 +1,449 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +use crate::LengthUnit; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwClamp")] + pub struct Clamp(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable; + + match fn { + type_ => || ffi::adw_clamp_get_type(), + } +} + +impl Clamp { + #[doc(alias = "adw_clamp_new")] + pub fn new() -> Clamp { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_clamp_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`Clamp`] objects. + /// + /// This method returns an instance of [`ClampBuilder`](crate::builders::ClampBuilder) which can be used to create [`Clamp`] objects. + pub fn builder() -> ClampBuilder { + ClampBuilder::new() + } + + #[doc(alias = "adw_clamp_get_child")] + #[doc(alias = "get_child")] + pub fn child(&self) -> Option { + unsafe { from_glib_none(ffi::adw_clamp_get_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_clamp_get_maximum_size")] + #[doc(alias = "get_maximum_size")] + pub fn maximum_size(&self) -> i32 { + unsafe { ffi::adw_clamp_get_maximum_size(self.to_glib_none().0) } + } + + #[doc(alias = "adw_clamp_get_tightening_threshold")] + #[doc(alias = "get_tightening_threshold")] + pub fn tightening_threshold(&self) -> i32 { + unsafe { ffi::adw_clamp_get_tightening_threshold(self.to_glib_none().0) } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_clamp_get_unit")] + #[doc(alias = "get_unit")] + pub fn unit(&self) -> LengthUnit { + unsafe { from_glib(ffi::adw_clamp_get_unit(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_clamp_set_child")] + pub fn set_child(&self, child: Option<&impl IsA>) { + unsafe { + ffi::adw_clamp_set_child( + self.to_glib_none().0, + child.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_clamp_set_maximum_size")] + pub fn set_maximum_size(&self, maximum_size: i32) { + unsafe { + ffi::adw_clamp_set_maximum_size(self.to_glib_none().0, maximum_size); + } + } + + #[doc(alias = "adw_clamp_set_tightening_threshold")] + pub fn set_tightening_threshold(&self, tightening_threshold: i32) { + unsafe { + ffi::adw_clamp_set_tightening_threshold(self.to_glib_none().0, tightening_threshold); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_clamp_set_unit")] + pub fn set_unit(&self, unit: LengthUnit) { + unsafe { + ffi::adw_clamp_set_unit(self.to_glib_none().0, unit.into_glib()); + } + } + + #[doc(alias = "child")] + pub fn connect_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_child_trampoline( + this: *mut ffi::AdwClamp, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "maximum-size")] + pub fn connect_maximum_size_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_maximum_size_trampoline( + this: *mut ffi::AdwClamp, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::maximum-size\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_maximum_size_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "tightening-threshold")] + pub fn connect_tightening_threshold_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_tightening_threshold_trampoline( + this: *mut ffi::AdwClamp, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::tightening-threshold\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_tightening_threshold_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "unit")] + pub fn connect_unit_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_unit_trampoline( + this: *mut ffi::AdwClamp, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::unit\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_unit_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for Clamp { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`Clamp`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ClampBuilder { + builder: glib::object::ObjectBuilder<'static, Clamp>, +} + +impl ClampBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn maximum_size(self, maximum_size: i32) -> Self { + Self { + builder: self.builder.property("maximum-size", maximum_size), + } + } + + pub fn tightening_threshold(self, tightening_threshold: i32) -> Self { + Self { + builder: self + .builder + .property("tightening-threshold", tightening_threshold), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn unit(self, unit: LengthUnit) -> Self { + Self { + builder: self.builder.property("unit", unit), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn orientation(self, orientation: gtk::Orientation) -> Self { + Self { + builder: self.builder.property("orientation", orientation), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`Clamp`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> Clamp { + self.builder.build() + } +} + +impl fmt::Display for Clamp { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Clamp") + } +} diff --git a/libadwaita-0.4.4/src/auto/clamp_layout.rs b/libadwaita-0.4.4/src/auto/clamp_layout.rs new file mode 100644 index 0000000..6084b93 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/clamp_layout.rs @@ -0,0 +1,225 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +use crate::LengthUnit; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwClampLayout")] + pub struct ClampLayout(Object) @extends gtk::LayoutManager, @implements gtk::Orientable; + + match fn { + type_ => || ffi::adw_clamp_layout_get_type(), + } +} + +impl ClampLayout { + #[doc(alias = "adw_clamp_layout_new")] + pub fn new() -> ClampLayout { + assert_initialized_main_thread!(); + unsafe { gtk::LayoutManager::from_glib_full(ffi::adw_clamp_layout_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`ClampLayout`] objects. + /// + /// This method returns an instance of [`ClampLayoutBuilder`](crate::builders::ClampLayoutBuilder) which can be used to create [`ClampLayout`] objects. + pub fn builder() -> ClampLayoutBuilder { + ClampLayoutBuilder::new() + } + + #[doc(alias = "adw_clamp_layout_get_maximum_size")] + #[doc(alias = "get_maximum_size")] + pub fn maximum_size(&self) -> i32 { + unsafe { ffi::adw_clamp_layout_get_maximum_size(self.to_glib_none().0) } + } + + #[doc(alias = "adw_clamp_layout_get_tightening_threshold")] + #[doc(alias = "get_tightening_threshold")] + pub fn tightening_threshold(&self) -> i32 { + unsafe { ffi::adw_clamp_layout_get_tightening_threshold(self.to_glib_none().0) } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_clamp_layout_get_unit")] + #[doc(alias = "get_unit")] + pub fn unit(&self) -> LengthUnit { + unsafe { from_glib(ffi::adw_clamp_layout_get_unit(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_clamp_layout_set_maximum_size")] + pub fn set_maximum_size(&self, maximum_size: i32) { + unsafe { + ffi::adw_clamp_layout_set_maximum_size(self.to_glib_none().0, maximum_size); + } + } + + #[doc(alias = "adw_clamp_layout_set_tightening_threshold")] + pub fn set_tightening_threshold(&self, tightening_threshold: i32) { + unsafe { + ffi::adw_clamp_layout_set_tightening_threshold( + self.to_glib_none().0, + tightening_threshold, + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_clamp_layout_set_unit")] + pub fn set_unit(&self, unit: LengthUnit) { + unsafe { + ffi::adw_clamp_layout_set_unit(self.to_glib_none().0, unit.into_glib()); + } + } + + #[doc(alias = "maximum-size")] + pub fn connect_maximum_size_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_maximum_size_trampoline( + this: *mut ffi::AdwClampLayout, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::maximum-size\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_maximum_size_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "tightening-threshold")] + pub fn connect_tightening_threshold_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_tightening_threshold_trampoline< + F: Fn(&ClampLayout) + 'static, + >( + this: *mut ffi::AdwClampLayout, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::tightening-threshold\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_tightening_threshold_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "unit")] + pub fn connect_unit_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_unit_trampoline( + this: *mut ffi::AdwClampLayout, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::unit\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_unit_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for ClampLayout { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`ClampLayout`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ClampLayoutBuilder { + builder: glib::object::ObjectBuilder<'static, ClampLayout>, +} + +impl ClampLayoutBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn maximum_size(self, maximum_size: i32) -> Self { + Self { + builder: self.builder.property("maximum-size", maximum_size), + } + } + + pub fn tightening_threshold(self, tightening_threshold: i32) -> Self { + Self { + builder: self + .builder + .property("tightening-threshold", tightening_threshold), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn unit(self, unit: LengthUnit) -> Self { + Self { + builder: self.builder.property("unit", unit), + } + } + + pub fn orientation(self, orientation: gtk::Orientation) -> Self { + Self { + builder: self.builder.property("orientation", orientation), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`ClampLayout`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> ClampLayout { + self.builder.build() + } +} + +impl fmt::Display for ClampLayout { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ClampLayout") + } +} diff --git a/libadwaita-0.4.4/src/auto/clamp_scrollable.rs b/libadwaita-0.4.4/src/auto/clamp_scrollable.rs new file mode 100644 index 0000000..211c6f0 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/clamp_scrollable.rs @@ -0,0 +1,482 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +use crate::LengthUnit; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwClampScrollable")] + pub struct ClampScrollable(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable, gtk::Scrollable; + + match fn { + type_ => || ffi::adw_clamp_scrollable_get_type(), + } +} + +impl ClampScrollable { + #[doc(alias = "adw_clamp_scrollable_new")] + pub fn new() -> ClampScrollable { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_clamp_scrollable_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`ClampScrollable`] objects. + /// + /// This method returns an instance of [`ClampScrollableBuilder`](crate::builders::ClampScrollableBuilder) which can be used to create [`ClampScrollable`] objects. + pub fn builder() -> ClampScrollableBuilder { + ClampScrollableBuilder::new() + } + + #[doc(alias = "adw_clamp_scrollable_get_child")] + #[doc(alias = "get_child")] + pub fn child(&self) -> Option { + unsafe { from_glib_none(ffi::adw_clamp_scrollable_get_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_clamp_scrollable_get_maximum_size")] + #[doc(alias = "get_maximum_size")] + pub fn maximum_size(&self) -> i32 { + unsafe { ffi::adw_clamp_scrollable_get_maximum_size(self.to_glib_none().0) } + } + + #[doc(alias = "adw_clamp_scrollable_get_tightening_threshold")] + #[doc(alias = "get_tightening_threshold")] + pub fn tightening_threshold(&self) -> i32 { + unsafe { ffi::adw_clamp_scrollable_get_tightening_threshold(self.to_glib_none().0) } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_clamp_scrollable_get_unit")] + #[doc(alias = "get_unit")] + pub fn unit(&self) -> LengthUnit { + unsafe { from_glib(ffi::adw_clamp_scrollable_get_unit(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_clamp_scrollable_set_child")] + pub fn set_child(&self, child: Option<&impl IsA>) { + unsafe { + ffi::adw_clamp_scrollable_set_child( + self.to_glib_none().0, + child.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_clamp_scrollable_set_maximum_size")] + pub fn set_maximum_size(&self, maximum_size: i32) { + unsafe { + ffi::adw_clamp_scrollable_set_maximum_size(self.to_glib_none().0, maximum_size); + } + } + + #[doc(alias = "adw_clamp_scrollable_set_tightening_threshold")] + pub fn set_tightening_threshold(&self, tightening_threshold: i32) { + unsafe { + ffi::adw_clamp_scrollable_set_tightening_threshold( + self.to_glib_none().0, + tightening_threshold, + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_clamp_scrollable_set_unit")] + pub fn set_unit(&self, unit: LengthUnit) { + unsafe { + ffi::adw_clamp_scrollable_set_unit(self.to_glib_none().0, unit.into_glib()); + } + } + + #[doc(alias = "child")] + pub fn connect_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_child_trampoline( + this: *mut ffi::AdwClampScrollable, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "maximum-size")] + pub fn connect_maximum_size_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_maximum_size_trampoline( + this: *mut ffi::AdwClampScrollable, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::maximum-size\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_maximum_size_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "tightening-threshold")] + pub fn connect_tightening_threshold_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_tightening_threshold_trampoline< + F: Fn(&ClampScrollable) + 'static, + >( + this: *mut ffi::AdwClampScrollable, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::tightening-threshold\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_tightening_threshold_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "unit")] + pub fn connect_unit_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_unit_trampoline( + this: *mut ffi::AdwClampScrollable, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::unit\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_unit_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for ClampScrollable { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`ClampScrollable`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ClampScrollableBuilder { + builder: glib::object::ObjectBuilder<'static, ClampScrollable>, +} + +impl ClampScrollableBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn maximum_size(self, maximum_size: i32) -> Self { + Self { + builder: self.builder.property("maximum-size", maximum_size), + } + } + + pub fn tightening_threshold(self, tightening_threshold: i32) -> Self { + Self { + builder: self + .builder + .property("tightening-threshold", tightening_threshold), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn unit(self, unit: LengthUnit) -> Self { + Self { + builder: self.builder.property("unit", unit), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn orientation(self, orientation: gtk::Orientation) -> Self { + Self { + builder: self.builder.property("orientation", orientation), + } + } + + pub fn hadjustment(self, hadjustment: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("hadjustment", hadjustment.clone().upcast()), + } + } + + pub fn hscroll_policy(self, hscroll_policy: gtk::ScrollablePolicy) -> Self { + Self { + builder: self.builder.property("hscroll-policy", hscroll_policy), + } + } + + pub fn vadjustment(self, vadjustment: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("vadjustment", vadjustment.clone().upcast()), + } + } + + pub fn vscroll_policy(self, vscroll_policy: gtk::ScrollablePolicy) -> Self { + Self { + builder: self.builder.property("vscroll-policy", vscroll_policy), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`ClampScrollable`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> ClampScrollable { + self.builder.build() + } +} + +impl fmt::Display for ClampScrollable { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ClampScrollable") + } +} diff --git a/libadwaita-0.4.4/src/auto/combo_row.rs b/libadwaita-0.4.4/src/auto/combo_row.rs new file mode 100644 index 0000000..cfc1acd --- /dev/null +++ b/libadwaita-0.4.4/src/auto/combo_row.rs @@ -0,0 +1,735 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{ActionRow, PreferencesRow}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwComboRow")] + pub struct ComboRow(Object) @extends ActionRow, PreferencesRow, gtk::ListBoxRow, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable; + + match fn { + type_ => || ffi::adw_combo_row_get_type(), + } +} + +impl ComboRow { + pub const NONE: Option<&'static ComboRow> = None; + + #[doc(alias = "adw_combo_row_new")] + pub fn new() -> ComboRow { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_combo_row_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`ComboRow`] objects. + /// + /// This method returns an instance of [`ComboRowBuilder`](crate::builders::ComboRowBuilder) which can be used to create [`ComboRow`] objects. + pub fn builder() -> ComboRowBuilder { + ComboRowBuilder::new() + } +} + +impl Default for ComboRow { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`ComboRow`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ComboRowBuilder { + builder: glib::object::ObjectBuilder<'static, ComboRow>, +} + +impl ComboRowBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn expression(self, expression: impl AsRef) -> Self { + Self { + builder: self + .builder + .property("expression", expression.as_ref().clone()), + } + } + + pub fn factory(self, factory: &impl IsA) -> Self { + Self { + builder: self.builder.property("factory", factory.clone().upcast()), + } + } + + pub fn list_factory(self, list_factory: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("list-factory", list_factory.clone().upcast()), + } + } + + pub fn model(self, model: &impl IsA) -> Self { + Self { + builder: self.builder.property("model", model.clone().upcast()), + } + } + + pub fn selected(self, selected: u32) -> Self { + Self { + builder: self.builder.property("selected", selected), + } + } + + pub fn use_subtitle(self, use_subtitle: bool) -> Self { + Self { + builder: self.builder.property("use-subtitle", use_subtitle), + } + } + + pub fn activatable_widget(self, activatable_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("activatable-widget", activatable_widget.clone().upcast()), + } + } + + #[cfg_attr(feature = "v1_3", deprecated = "Since 1.3")] + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn subtitle(self, subtitle: impl Into) -> Self { + Self { + builder: self.builder.property("subtitle", subtitle.into()), + } + } + + pub fn subtitle_lines(self, subtitle_lines: i32) -> Self { + Self { + builder: self.builder.property("subtitle-lines", subtitle_lines), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn subtitle_selectable(self, subtitle_selectable: bool) -> Self { + Self { + builder: self + .builder + .property("subtitle-selectable", subtitle_selectable), + } + } + + pub fn title_lines(self, title_lines: i32) -> Self { + Self { + builder: self.builder.property("title-lines", title_lines), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + pub fn title_selectable(self, title_selectable: bool) -> Self { + Self { + builder: self.builder.property("title-selectable", title_selectable), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn use_markup(self, use_markup: bool) -> Self { + Self { + builder: self.builder.property("use-markup", use_markup), + } + } + + pub fn use_underline(self, use_underline: bool) -> Self { + Self { + builder: self.builder.property("use-underline", use_underline), + } + } + + pub fn activatable(self, activatable: bool) -> Self { + Self { + builder: self.builder.property("activatable", activatable), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn selectable(self, selectable: bool) -> Self { + Self { + builder: self.builder.property("selectable", selectable), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn action_name(self, action_name: impl Into) -> Self { + Self { + builder: self.builder.property("action-name", action_name.into()), + } + } + + pub fn action_target(self, action_target: &glib::Variant) -> Self { + Self { + builder: self + .builder + .property("action-target", action_target.clone()), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`ComboRow`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> ComboRow { + self.builder.build() + } +} + +pub trait ComboRowExt: 'static { + #[doc(alias = "adw_combo_row_get_expression")] + #[doc(alias = "get_expression")] + fn expression(&self) -> Option; + + #[doc(alias = "adw_combo_row_get_factory")] + #[doc(alias = "get_factory")] + fn factory(&self) -> Option; + + #[doc(alias = "adw_combo_row_get_list_factory")] + #[doc(alias = "get_list_factory")] + fn list_factory(&self) -> Option; + + #[doc(alias = "adw_combo_row_get_model")] + #[doc(alias = "get_model")] + fn model(&self) -> Option; + + #[doc(alias = "adw_combo_row_get_selected")] + #[doc(alias = "get_selected")] + fn selected(&self) -> u32; + + #[doc(alias = "adw_combo_row_get_selected_item")] + #[doc(alias = "get_selected_item")] + fn selected_item(&self) -> Option; + + #[doc(alias = "adw_combo_row_get_use_subtitle")] + #[doc(alias = "get_use_subtitle")] + fn uses_subtitle(&self) -> bool; + + #[doc(alias = "adw_combo_row_set_expression")] + fn set_expression(&self, expression: Option>); + + #[doc(alias = "adw_combo_row_set_factory")] + fn set_factory(&self, factory: Option<&impl IsA>); + + #[doc(alias = "adw_combo_row_set_list_factory")] + fn set_list_factory(&self, factory: Option<&impl IsA>); + + #[doc(alias = "adw_combo_row_set_model")] + fn set_model(&self, model: Option<&impl IsA>); + + #[doc(alias = "adw_combo_row_set_selected")] + fn set_selected(&self, position: u32); + + #[doc(alias = "adw_combo_row_set_use_subtitle")] + fn set_use_subtitle(&self, use_subtitle: bool); + + #[doc(alias = "expression")] + fn connect_expression_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "factory")] + fn connect_factory_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "list-factory")] + fn connect_list_factory_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "model")] + fn connect_model_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "selected")] + fn connect_selected_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "selected-item")] + fn connect_selected_item_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "use-subtitle")] + fn connect_use_subtitle_notify(&self, f: F) -> SignalHandlerId; +} + +impl> ComboRowExt for O { + fn expression(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_combo_row_get_expression( + self.as_ref().to_glib_none().0, + )) + } + } + + fn factory(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_combo_row_get_factory( + self.as_ref().to_glib_none().0, + )) + } + } + + fn list_factory(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_combo_row_get_list_factory( + self.as_ref().to_glib_none().0, + )) + } + } + + fn model(&self) -> Option { + unsafe { from_glib_none(ffi::adw_combo_row_get_model(self.as_ref().to_glib_none().0)) } + } + + fn selected(&self) -> u32 { + unsafe { ffi::adw_combo_row_get_selected(self.as_ref().to_glib_none().0) } + } + + fn selected_item(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_combo_row_get_selected_item( + self.as_ref().to_glib_none().0, + )) + } + } + + fn uses_subtitle(&self) -> bool { + unsafe { + from_glib(ffi::adw_combo_row_get_use_subtitle( + self.as_ref().to_glib_none().0, + )) + } + } + + fn set_expression(&self, expression: Option>) { + unsafe { + ffi::adw_combo_row_set_expression( + self.as_ref().to_glib_none().0, + expression.as_ref().map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + fn set_factory(&self, factory: Option<&impl IsA>) { + unsafe { + ffi::adw_combo_row_set_factory( + self.as_ref().to_glib_none().0, + factory.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + fn set_list_factory(&self, factory: Option<&impl IsA>) { + unsafe { + ffi::adw_combo_row_set_list_factory( + self.as_ref().to_glib_none().0, + factory.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + fn set_model(&self, model: Option<&impl IsA>) { + unsafe { + ffi::adw_combo_row_set_model( + self.as_ref().to_glib_none().0, + model.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + fn set_selected(&self, position: u32) { + unsafe { + ffi::adw_combo_row_set_selected(self.as_ref().to_glib_none().0, position); + } + } + + fn set_use_subtitle(&self, use_subtitle: bool) { + unsafe { + ffi::adw_combo_row_set_use_subtitle( + self.as_ref().to_glib_none().0, + use_subtitle.into_glib(), + ); + } + } + + fn connect_expression_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_expression_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwComboRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ComboRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::expression\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_expression_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_factory_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_factory_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwComboRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ComboRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::factory\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_factory_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_list_factory_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_list_factory_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwComboRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ComboRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::list-factory\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_list_factory_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_model_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_model_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwComboRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ComboRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::model\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_model_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_selected_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_selected_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwComboRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ComboRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::selected\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_selected_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_selected_item_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_selected_item_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwComboRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ComboRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::selected-item\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_selected_item_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_use_subtitle_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_use_subtitle_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwComboRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ComboRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::use-subtitle\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_use_subtitle_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for ComboRow { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ComboRow") + } +} diff --git a/libadwaita-0.4.4/src/auto/entry_row.rs b/libadwaita-0.4.4/src/auto/entry_row.rs new file mode 100644 index 0000000..2ed4aa8 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/entry_row.rs @@ -0,0 +1,858 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::PreferencesRow; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwEntryRow")] + pub struct EntryRow(Object) @extends PreferencesRow, gtk::ListBoxRow, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable, gtk::Editable; + + match fn { + type_ => || ffi::adw_entry_row_get_type(), + } +} + +impl EntryRow { + pub const NONE: Option<&'static EntryRow> = None; + + #[doc(alias = "adw_entry_row_new")] + pub fn new() -> EntryRow { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_entry_row_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`EntryRow`] objects. + /// + /// This method returns an instance of [`EntryRowBuilder`](crate::builders::EntryRowBuilder) which can be used to create [`EntryRow`] objects. + pub fn builder() -> EntryRowBuilder { + EntryRowBuilder::new() + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl Default for EntryRow { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`EntryRow`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct EntryRowBuilder { + builder: glib::object::ObjectBuilder<'static, EntryRow>, +} + +impl EntryRowBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn activates_default(self, activates_default: bool) -> Self { + Self { + builder: self + .builder + .property("activates-default", activates_default), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn attributes(self, attributes: &pango::AttrList) -> Self { + Self { + builder: self.builder.property("attributes", attributes.clone()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn enable_emoji_completion(self, enable_emoji_completion: bool) -> Self { + Self { + builder: self + .builder + .property("enable-emoji-completion", enable_emoji_completion), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn input_hints(self, input_hints: gtk::InputHints) -> Self { + Self { + builder: self.builder.property("input-hints", input_hints), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn input_purpose(self, input_purpose: gtk::InputPurpose) -> Self { + Self { + builder: self.builder.property("input-purpose", input_purpose), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn show_apply_button(self, show_apply_button: bool) -> Self { + Self { + builder: self + .builder + .property("show-apply-button", show_apply_button), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + pub fn title_selectable(self, title_selectable: bool) -> Self { + Self { + builder: self.builder.property("title-selectable", title_selectable), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn use_markup(self, use_markup: bool) -> Self { + Self { + builder: self.builder.property("use-markup", use_markup), + } + } + + pub fn use_underline(self, use_underline: bool) -> Self { + Self { + builder: self.builder.property("use-underline", use_underline), + } + } + + pub fn activatable(self, activatable: bool) -> Self { + Self { + builder: self.builder.property("activatable", activatable), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn selectable(self, selectable: bool) -> Self { + Self { + builder: self.builder.property("selectable", selectable), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn action_name(self, action_name: impl Into) -> Self { + Self { + builder: self.builder.property("action-name", action_name.into()), + } + } + + pub fn action_target(self, action_target: &glib::Variant) -> Self { + Self { + builder: self + .builder + .property("action-target", action_target.clone()), + } + } + + pub fn editable(self, editable: bool) -> Self { + Self { + builder: self.builder.property("editable", editable), + } + } + + pub fn enable_undo(self, enable_undo: bool) -> Self { + Self { + builder: self.builder.property("enable-undo", enable_undo), + } + } + + pub fn max_width_chars(self, max_width_chars: i32) -> Self { + Self { + builder: self.builder.property("max-width-chars", max_width_chars), + } + } + + pub fn text(self, text: impl Into) -> Self { + Self { + builder: self.builder.property("text", text.into()), + } + } + + pub fn width_chars(self, width_chars: i32) -> Self { + Self { + builder: self.builder.property("width-chars", width_chars), + } + } + + pub fn xalign(self, xalign: f32) -> Self { + Self { + builder: self.builder.property("xalign", xalign), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`EntryRow`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> EntryRow { + self.builder.build() + } +} + +pub trait EntryRowExt: 'static { + #[doc(alias = "adw_entry_row_add_prefix")] + fn add_prefix(&self, widget: &impl IsA); + + #[doc(alias = "adw_entry_row_add_suffix")] + fn add_suffix(&self, widget: &impl IsA); + + #[doc(alias = "adw_entry_row_get_activates_default")] + #[doc(alias = "get_activates_default")] + fn activates_default(&self) -> bool; + + #[doc(alias = "adw_entry_row_get_attributes")] + #[doc(alias = "get_attributes")] + fn attributes(&self) -> Option; + + #[doc(alias = "adw_entry_row_get_enable_emoji_completion")] + #[doc(alias = "get_enable_emoji_completion")] + fn enables_emoji_completion(&self) -> bool; + + #[doc(alias = "adw_entry_row_get_input_hints")] + #[doc(alias = "get_input_hints")] + fn input_hints(&self) -> gtk::InputHints; + + #[doc(alias = "adw_entry_row_get_input_purpose")] + #[doc(alias = "get_input_purpose")] + fn input_purpose(&self) -> gtk::InputPurpose; + + #[doc(alias = "adw_entry_row_get_show_apply_button")] + #[doc(alias = "get_show_apply_button")] + fn shows_apply_button(&self) -> bool; + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_entry_row_grab_focus_without_selecting")] + fn grab_focus_without_selecting(&self) -> bool; + + #[doc(alias = "adw_entry_row_remove")] + fn remove(&self, widget: &impl IsA); + + #[doc(alias = "adw_entry_row_set_activates_default")] + fn set_activates_default(&self, activates: bool); + + #[doc(alias = "adw_entry_row_set_attributes")] + fn set_attributes(&self, attributes: Option<&pango::AttrList>); + + #[doc(alias = "adw_entry_row_set_enable_emoji_completion")] + fn set_enable_emoji_completion(&self, enable_emoji_completion: bool); + + #[doc(alias = "adw_entry_row_set_input_hints")] + fn set_input_hints(&self, hints: gtk::InputHints); + + #[doc(alias = "adw_entry_row_set_input_purpose")] + fn set_input_purpose(&self, purpose: gtk::InputPurpose); + + #[doc(alias = "adw_entry_row_set_show_apply_button")] + fn set_show_apply_button(&self, show_apply_button: bool); + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "apply")] + fn connect_apply(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "entry-activated")] + fn connect_entry_activated(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "activates-default")] + fn connect_activates_default_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "attributes")] + fn connect_attributes_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "enable-emoji-completion")] + fn connect_enable_emoji_completion_notify( + &self, + f: F, + ) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "input-hints")] + fn connect_input_hints_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "input-purpose")] + fn connect_input_purpose_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "show-apply-button")] + fn connect_show_apply_button_notify(&self, f: F) -> SignalHandlerId; +} + +impl> EntryRowExt for O { + fn add_prefix(&self, widget: &impl IsA) { + unsafe { + ffi::adw_entry_row_add_prefix( + self.as_ref().to_glib_none().0, + widget.as_ref().to_glib_none().0, + ); + } + } + + fn add_suffix(&self, widget: &impl IsA) { + unsafe { + ffi::adw_entry_row_add_suffix( + self.as_ref().to_glib_none().0, + widget.as_ref().to_glib_none().0, + ); + } + } + + fn activates_default(&self) -> bool { + unsafe { + from_glib(ffi::adw_entry_row_get_activates_default( + self.as_ref().to_glib_none().0, + )) + } + } + + fn attributes(&self) -> Option { + unsafe { + from_glib_full(ffi::adw_entry_row_get_attributes( + self.as_ref().to_glib_none().0, + )) + } + } + + fn enables_emoji_completion(&self) -> bool { + unsafe { + from_glib(ffi::adw_entry_row_get_enable_emoji_completion( + self.as_ref().to_glib_none().0, + )) + } + } + + fn input_hints(&self) -> gtk::InputHints { + unsafe { + from_glib(ffi::adw_entry_row_get_input_hints( + self.as_ref().to_glib_none().0, + )) + } + } + + fn input_purpose(&self) -> gtk::InputPurpose { + unsafe { + from_glib(ffi::adw_entry_row_get_input_purpose( + self.as_ref().to_glib_none().0, + )) + } + } + + fn shows_apply_button(&self) -> bool { + unsafe { + from_glib(ffi::adw_entry_row_get_show_apply_button( + self.as_ref().to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn grab_focus_without_selecting(&self) -> bool { + unsafe { + from_glib(ffi::adw_entry_row_grab_focus_without_selecting( + self.as_ref().to_glib_none().0, + )) + } + } + + fn remove(&self, widget: &impl IsA) { + unsafe { + ffi::adw_entry_row_remove( + self.as_ref().to_glib_none().0, + widget.as_ref().to_glib_none().0, + ); + } + } + + fn set_activates_default(&self, activates: bool) { + unsafe { + ffi::adw_entry_row_set_activates_default( + self.as_ref().to_glib_none().0, + activates.into_glib(), + ); + } + } + + fn set_attributes(&self, attributes: Option<&pango::AttrList>) { + unsafe { + ffi::adw_entry_row_set_attributes( + self.as_ref().to_glib_none().0, + attributes.to_glib_none().0, + ); + } + } + + fn set_enable_emoji_completion(&self, enable_emoji_completion: bool) { + unsafe { + ffi::adw_entry_row_set_enable_emoji_completion( + self.as_ref().to_glib_none().0, + enable_emoji_completion.into_glib(), + ); + } + } + + fn set_input_hints(&self, hints: gtk::InputHints) { + unsafe { + ffi::adw_entry_row_set_input_hints(self.as_ref().to_glib_none().0, hints.into_glib()); + } + } + + fn set_input_purpose(&self, purpose: gtk::InputPurpose) { + unsafe { + ffi::adw_entry_row_set_input_purpose( + self.as_ref().to_glib_none().0, + purpose.into_glib(), + ); + } + } + + fn set_show_apply_button(&self, show_apply_button: bool) { + unsafe { + ffi::adw_entry_row_set_show_apply_button( + self.as_ref().to_glib_none().0, + show_apply_button.into_glib(), + ); + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_apply(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn apply_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwEntryRow, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(EntryRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"apply\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + apply_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_entry_activated(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn entry_activated_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwEntryRow, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(EntryRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"entry-activated\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + entry_activated_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_activates_default_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_activates_default_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwEntryRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(EntryRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::activates-default\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_activates_default_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_attributes_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_attributes_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwEntryRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(EntryRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::attributes\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_attributes_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_enable_emoji_completion_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_enable_emoji_completion_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwEntryRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(EntryRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::enable-emoji-completion\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_enable_emoji_completion_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_input_hints_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_input_hints_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwEntryRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(EntryRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::input-hints\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_input_hints_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_input_purpose_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_input_purpose_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwEntryRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(EntryRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::input-purpose\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_input_purpose_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_show_apply_button_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_show_apply_button_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwEntryRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(EntryRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::show-apply-button\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_show_apply_button_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for EntryRow { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("EntryRow") + } +} diff --git a/libadwaita-0.4.4/src/auto/enum_list_item.rs b/libadwaita-0.4.4/src/auto/enum_list_item.rs new file mode 100644 index 0000000..2128bac --- /dev/null +++ b/libadwaita-0.4.4/src/auto/enum_list_item.rs @@ -0,0 +1,116 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwEnumListItem")] + pub struct EnumListItem(Object); + + match fn { + type_ => || ffi::adw_enum_list_item_get_type(), + } +} + +impl EnumListItem { + #[doc(alias = "adw_enum_list_item_get_name")] + #[doc(alias = "get_name")] + pub fn name(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_enum_list_item_get_name(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_enum_list_item_get_nick")] + #[doc(alias = "get_nick")] + pub fn nick(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_enum_list_item_get_nick(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_enum_list_item_get_value")] + #[doc(alias = "get_value")] + pub fn value(&self) -> i32 { + unsafe { ffi::adw_enum_list_item_get_value(self.to_glib_none().0) } + } + + #[doc(alias = "name")] + pub fn connect_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_name_trampoline( + this: *mut ffi::AdwEnumListItem, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "nick")] + pub fn connect_nick_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_nick_trampoline( + this: *mut ffi::AdwEnumListItem, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::nick\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_nick_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "value")] + pub fn connect_value_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_value_trampoline( + this: *mut ffi::AdwEnumListItem, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::value\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_value_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for EnumListItem { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.name()) + } +} diff --git a/libadwaita-0.4.4/src/auto/enum_list_model.rs b/libadwaita-0.4.4/src/auto/enum_list_model.rs new file mode 100644 index 0000000..e198fb6 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/enum_list_model.rs @@ -0,0 +1,45 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::translate::*; +use std::fmt; + +glib::wrapper! { + #[doc(alias = "AdwEnumListModel")] + pub struct EnumListModel(Object) @implements gio::ListModel; + + match fn { + type_ => || ffi::adw_enum_list_model_get_type(), + } +} + +impl EnumListModel { + #[doc(alias = "adw_enum_list_model_new")] + pub fn new(enum_type: glib::types::Type) -> EnumListModel { + assert_initialized_main_thread!(); + unsafe { from_glib_full(ffi::adw_enum_list_model_new(enum_type.into_glib())) } + } + + #[doc(alias = "adw_enum_list_model_find_position")] + pub fn find_position(&self, value: i32) -> u32 { + unsafe { ffi::adw_enum_list_model_find_position(self.to_glib_none().0, value) } + } + + #[doc(alias = "adw_enum_list_model_get_enum_type")] + #[doc(alias = "get_enum_type")] + pub fn enum_type(&self) -> glib::types::Type { + unsafe { + from_glib(ffi::adw_enum_list_model_get_enum_type( + self.to_glib_none().0, + )) + } + } +} + +impl fmt::Display for EnumListModel { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("EnumListModel") + } +} diff --git a/libadwaita-0.4.4/src/auto/enums.rs b/libadwaita-0.4.4/src/auto/enums.rs new file mode 100644 index 0000000..4069d6f --- /dev/null +++ b/libadwaita-0.4.4/src/auto/enums.rs @@ -0,0 +1,2187 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{translate::*, value::FromValue, value::ToValue, StaticType, Type}; +use std::fmt; + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwAnimationState")] +pub enum AnimationState { + #[doc(alias = "ADW_ANIMATION_IDLE")] + Idle, + #[doc(alias = "ADW_ANIMATION_PAUSED")] + Paused, + #[doc(alias = "ADW_ANIMATION_PLAYING")] + Playing, + #[doc(alias = "ADW_ANIMATION_FINISHED")] + Finished, + #[doc(hidden)] + __Unknown(i32), +} + +impl fmt::Display for AnimationState { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "AnimationState::{}", + match *self { + Self::Idle => "Idle", + Self::Paused => "Paused", + Self::Playing => "Playing", + Self::Finished => "Finished", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for AnimationState { + type GlibType = ffi::AdwAnimationState; + + #[inline] + fn into_glib(self) -> ffi::AdwAnimationState { + match self { + Self::Idle => ffi::ADW_ANIMATION_IDLE, + Self::Paused => ffi::ADW_ANIMATION_PAUSED, + Self::Playing => ffi::ADW_ANIMATION_PLAYING, + Self::Finished => ffi::ADW_ANIMATION_FINISHED, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for AnimationState { + #[inline] + unsafe fn from_glib(value: ffi::AdwAnimationState) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_ANIMATION_IDLE => Self::Idle, + ffi::ADW_ANIMATION_PAUSED => Self::Paused, + ffi::ADW_ANIMATION_PLAYING => Self::Playing, + ffi::ADW_ANIMATION_FINISHED => Self::Finished, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for AnimationState { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_animation_state_get_type()) } + } +} + +impl glib::HasParamSpec for AnimationState { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +impl glib::value::ValueType for AnimationState { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for AnimationState { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for AnimationState { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: AnimationState) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwBreakpointConditionLengthType")] +pub enum BreakpointConditionLengthType { + #[doc(alias = "ADW_BREAKPOINT_CONDITION_MIN_WIDTH")] + MinWidth, + #[doc(alias = "ADW_BREAKPOINT_CONDITION_MAX_WIDTH")] + MaxWidth, + #[doc(alias = "ADW_BREAKPOINT_CONDITION_MIN_HEIGHT")] + MinHeight, + #[doc(alias = "ADW_BREAKPOINT_CONDITION_MAX_HEIGHT")] + MaxHeight, + #[doc(hidden)] + __Unknown(i32), +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl fmt::Display for BreakpointConditionLengthType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "BreakpointConditionLengthType::{}", + match *self { + Self::MinWidth => "MinWidth", + Self::MaxWidth => "MaxWidth", + Self::MinHeight => "MinHeight", + Self::MaxHeight => "MaxHeight", + _ => "Unknown", + } + ) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +#[doc(hidden)] +impl IntoGlib for BreakpointConditionLengthType { + type GlibType = ffi::AdwBreakpointConditionLengthType; + + #[inline] + fn into_glib(self) -> ffi::AdwBreakpointConditionLengthType { + match self { + Self::MinWidth => ffi::ADW_BREAKPOINT_CONDITION_MIN_WIDTH, + Self::MaxWidth => ffi::ADW_BREAKPOINT_CONDITION_MAX_WIDTH, + Self::MinHeight => ffi::ADW_BREAKPOINT_CONDITION_MIN_HEIGHT, + Self::MaxHeight => ffi::ADW_BREAKPOINT_CONDITION_MAX_HEIGHT, + Self::__Unknown(value) => value, + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +#[doc(hidden)] +impl FromGlib for BreakpointConditionLengthType { + #[inline] + unsafe fn from_glib(value: ffi::AdwBreakpointConditionLengthType) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_BREAKPOINT_CONDITION_MIN_WIDTH => Self::MinWidth, + ffi::ADW_BREAKPOINT_CONDITION_MAX_WIDTH => Self::MaxWidth, + ffi::ADW_BREAKPOINT_CONDITION_MIN_HEIGHT => Self::MinHeight, + ffi::ADW_BREAKPOINT_CONDITION_MAX_HEIGHT => Self::MaxHeight, + value => Self::__Unknown(value), + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl StaticType for BreakpointConditionLengthType { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_breakpoint_condition_length_type_get_type()) } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl glib::HasParamSpec for BreakpointConditionLengthType { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl glib::value::ValueType for BreakpointConditionLengthType { + type Type = Self; +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +unsafe impl<'a> FromValue<'a> for BreakpointConditionLengthType { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl ToValue for BreakpointConditionLengthType { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl From for glib::Value { + #[inline] + fn from(v: BreakpointConditionLengthType) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwBreakpointConditionRatioType")] +pub enum BreakpointConditionRatioType { + #[doc(alias = "ADW_BREAKPOINT_CONDITION_MIN_ASPECT_RATIO")] + MinAspectRatio, + #[doc(alias = "ADW_BREAKPOINT_CONDITION_MAX_ASPECT_RATIO")] + MaxAspectRatio, + #[doc(hidden)] + __Unknown(i32), +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl fmt::Display for BreakpointConditionRatioType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "BreakpointConditionRatioType::{}", + match *self { + Self::MinAspectRatio => "MinAspectRatio", + Self::MaxAspectRatio => "MaxAspectRatio", + _ => "Unknown", + } + ) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +#[doc(hidden)] +impl IntoGlib for BreakpointConditionRatioType { + type GlibType = ffi::AdwBreakpointConditionRatioType; + + #[inline] + fn into_glib(self) -> ffi::AdwBreakpointConditionRatioType { + match self { + Self::MinAspectRatio => ffi::ADW_BREAKPOINT_CONDITION_MIN_ASPECT_RATIO, + Self::MaxAspectRatio => ffi::ADW_BREAKPOINT_CONDITION_MAX_ASPECT_RATIO, + Self::__Unknown(value) => value, + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +#[doc(hidden)] +impl FromGlib for BreakpointConditionRatioType { + #[inline] + unsafe fn from_glib(value: ffi::AdwBreakpointConditionRatioType) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_BREAKPOINT_CONDITION_MIN_ASPECT_RATIO => Self::MinAspectRatio, + ffi::ADW_BREAKPOINT_CONDITION_MAX_ASPECT_RATIO => Self::MaxAspectRatio, + value => Self::__Unknown(value), + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl StaticType for BreakpointConditionRatioType { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_breakpoint_condition_ratio_type_get_type()) } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl glib::HasParamSpec for BreakpointConditionRatioType { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl glib::value::ValueType for BreakpointConditionRatioType { + type Type = Self; +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +unsafe impl<'a> FromValue<'a> for BreakpointConditionRatioType { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl ToValue for BreakpointConditionRatioType { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl From for glib::Value { + #[inline] + fn from(v: BreakpointConditionRatioType) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwCenteringPolicy")] +pub enum CenteringPolicy { + #[doc(alias = "ADW_CENTERING_POLICY_LOOSE")] + Loose, + #[doc(alias = "ADW_CENTERING_POLICY_STRICT")] + Strict, + #[doc(hidden)] + __Unknown(i32), +} + +impl fmt::Display for CenteringPolicy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "CenteringPolicy::{}", + match *self { + Self::Loose => "Loose", + Self::Strict => "Strict", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for CenteringPolicy { + type GlibType = ffi::AdwCenteringPolicy; + + #[inline] + fn into_glib(self) -> ffi::AdwCenteringPolicy { + match self { + Self::Loose => ffi::ADW_CENTERING_POLICY_LOOSE, + Self::Strict => ffi::ADW_CENTERING_POLICY_STRICT, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for CenteringPolicy { + #[inline] + unsafe fn from_glib(value: ffi::AdwCenteringPolicy) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_CENTERING_POLICY_LOOSE => Self::Loose, + ffi::ADW_CENTERING_POLICY_STRICT => Self::Strict, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for CenteringPolicy { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_centering_policy_get_type()) } + } +} + +impl glib::HasParamSpec for CenteringPolicy { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +impl glib::value::ValueType for CenteringPolicy { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for CenteringPolicy { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for CenteringPolicy { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: CenteringPolicy) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwColorScheme")] +pub enum ColorScheme { + #[doc(alias = "ADW_COLOR_SCHEME_DEFAULT")] + Default, + #[doc(alias = "ADW_COLOR_SCHEME_FORCE_LIGHT")] + ForceLight, + #[doc(alias = "ADW_COLOR_SCHEME_PREFER_LIGHT")] + PreferLight, + #[doc(alias = "ADW_COLOR_SCHEME_PREFER_DARK")] + PreferDark, + #[doc(alias = "ADW_COLOR_SCHEME_FORCE_DARK")] + ForceDark, + #[doc(hidden)] + __Unknown(i32), +} + +impl fmt::Display for ColorScheme { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "ColorScheme::{}", + match *self { + Self::Default => "Default", + Self::ForceLight => "ForceLight", + Self::PreferLight => "PreferLight", + Self::PreferDark => "PreferDark", + Self::ForceDark => "ForceDark", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for ColorScheme { + type GlibType = ffi::AdwColorScheme; + + #[inline] + fn into_glib(self) -> ffi::AdwColorScheme { + match self { + Self::Default => ffi::ADW_COLOR_SCHEME_DEFAULT, + Self::ForceLight => ffi::ADW_COLOR_SCHEME_FORCE_LIGHT, + Self::PreferLight => ffi::ADW_COLOR_SCHEME_PREFER_LIGHT, + Self::PreferDark => ffi::ADW_COLOR_SCHEME_PREFER_DARK, + Self::ForceDark => ffi::ADW_COLOR_SCHEME_FORCE_DARK, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for ColorScheme { + #[inline] + unsafe fn from_glib(value: ffi::AdwColorScheme) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_COLOR_SCHEME_DEFAULT => Self::Default, + ffi::ADW_COLOR_SCHEME_FORCE_LIGHT => Self::ForceLight, + ffi::ADW_COLOR_SCHEME_PREFER_LIGHT => Self::PreferLight, + ffi::ADW_COLOR_SCHEME_PREFER_DARK => Self::PreferDark, + ffi::ADW_COLOR_SCHEME_FORCE_DARK => Self::ForceDark, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for ColorScheme { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_color_scheme_get_type()) } + } +} + +impl glib::HasParamSpec for ColorScheme { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +impl glib::value::ValueType for ColorScheme { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for ColorScheme { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for ColorScheme { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: ColorScheme) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwEasing")] +pub enum Easing { + #[doc(alias = "ADW_LINEAR")] + Linear, + #[doc(alias = "ADW_EASE_IN_QUAD")] + EaseInQuad, + #[doc(alias = "ADW_EASE_OUT_QUAD")] + EaseOutQuad, + #[doc(alias = "ADW_EASE_IN_OUT_QUAD")] + EaseInOutQuad, + #[doc(alias = "ADW_EASE_IN_CUBIC")] + EaseInCubic, + #[doc(alias = "ADW_EASE_OUT_CUBIC")] + EaseOutCubic, + #[doc(alias = "ADW_EASE_IN_OUT_CUBIC")] + EaseInOutCubic, + #[doc(alias = "ADW_EASE_IN_QUART")] + EaseInQuart, + #[doc(alias = "ADW_EASE_OUT_QUART")] + EaseOutQuart, + #[doc(alias = "ADW_EASE_IN_OUT_QUART")] + EaseInOutQuart, + #[doc(alias = "ADW_EASE_IN_QUINT")] + EaseInQuint, + #[doc(alias = "ADW_EASE_OUT_QUINT")] + EaseOutQuint, + #[doc(alias = "ADW_EASE_IN_OUT_QUINT")] + EaseInOutQuint, + #[doc(alias = "ADW_EASE_IN_SINE")] + EaseInSine, + #[doc(alias = "ADW_EASE_OUT_SINE")] + EaseOutSine, + #[doc(alias = "ADW_EASE_IN_OUT_SINE")] + EaseInOutSine, + #[doc(alias = "ADW_EASE_IN_EXPO")] + EaseInExpo, + #[doc(alias = "ADW_EASE_OUT_EXPO")] + EaseOutExpo, + #[doc(alias = "ADW_EASE_IN_OUT_EXPO")] + EaseInOutExpo, + #[doc(alias = "ADW_EASE_IN_CIRC")] + EaseInCirc, + #[doc(alias = "ADW_EASE_OUT_CIRC")] + EaseOutCirc, + #[doc(alias = "ADW_EASE_IN_OUT_CIRC")] + EaseInOutCirc, + #[doc(alias = "ADW_EASE_IN_ELASTIC")] + EaseInElastic, + #[doc(alias = "ADW_EASE_OUT_ELASTIC")] + EaseOutElastic, + #[doc(alias = "ADW_EASE_IN_OUT_ELASTIC")] + EaseInOutElastic, + #[doc(alias = "ADW_EASE_IN_BACK")] + EaseInBack, + #[doc(alias = "ADW_EASE_OUT_BACK")] + EaseOutBack, + #[doc(alias = "ADW_EASE_IN_OUT_BACK")] + EaseInOutBack, + #[doc(alias = "ADW_EASE_IN_BOUNCE")] + EaseInBounce, + #[doc(alias = "ADW_EASE_OUT_BOUNCE")] + EaseOutBounce, + #[doc(alias = "ADW_EASE_IN_OUT_BOUNCE")] + EaseInOutBounce, + #[doc(hidden)] + __Unknown(i32), +} + +impl Easing { + #[doc(alias = "adw_easing_ease")] + pub fn ease(self, value: f64) -> f64 { + assert_initialized_main_thread!(); + unsafe { ffi::adw_easing_ease(self.into_glib(), value) } + } +} + +impl fmt::Display for Easing { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "Easing::{}", + match *self { + Self::Linear => "Linear", + Self::EaseInQuad => "EaseInQuad", + Self::EaseOutQuad => "EaseOutQuad", + Self::EaseInOutQuad => "EaseInOutQuad", + Self::EaseInCubic => "EaseInCubic", + Self::EaseOutCubic => "EaseOutCubic", + Self::EaseInOutCubic => "EaseInOutCubic", + Self::EaseInQuart => "EaseInQuart", + Self::EaseOutQuart => "EaseOutQuart", + Self::EaseInOutQuart => "EaseInOutQuart", + Self::EaseInQuint => "EaseInQuint", + Self::EaseOutQuint => "EaseOutQuint", + Self::EaseInOutQuint => "EaseInOutQuint", + Self::EaseInSine => "EaseInSine", + Self::EaseOutSine => "EaseOutSine", + Self::EaseInOutSine => "EaseInOutSine", + Self::EaseInExpo => "EaseInExpo", + Self::EaseOutExpo => "EaseOutExpo", + Self::EaseInOutExpo => "EaseInOutExpo", + Self::EaseInCirc => "EaseInCirc", + Self::EaseOutCirc => "EaseOutCirc", + Self::EaseInOutCirc => "EaseInOutCirc", + Self::EaseInElastic => "EaseInElastic", + Self::EaseOutElastic => "EaseOutElastic", + Self::EaseInOutElastic => "EaseInOutElastic", + Self::EaseInBack => "EaseInBack", + Self::EaseOutBack => "EaseOutBack", + Self::EaseInOutBack => "EaseInOutBack", + Self::EaseInBounce => "EaseInBounce", + Self::EaseOutBounce => "EaseOutBounce", + Self::EaseInOutBounce => "EaseInOutBounce", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for Easing { + type GlibType = ffi::AdwEasing; + + fn into_glib(self) -> ffi::AdwEasing { + match self { + Self::Linear => ffi::ADW_LINEAR, + Self::EaseInQuad => ffi::ADW_EASE_IN_QUAD, + Self::EaseOutQuad => ffi::ADW_EASE_OUT_QUAD, + Self::EaseInOutQuad => ffi::ADW_EASE_IN_OUT_QUAD, + Self::EaseInCubic => ffi::ADW_EASE_IN_CUBIC, + Self::EaseOutCubic => ffi::ADW_EASE_OUT_CUBIC, + Self::EaseInOutCubic => ffi::ADW_EASE_IN_OUT_CUBIC, + Self::EaseInQuart => ffi::ADW_EASE_IN_QUART, + Self::EaseOutQuart => ffi::ADW_EASE_OUT_QUART, + Self::EaseInOutQuart => ffi::ADW_EASE_IN_OUT_QUART, + Self::EaseInQuint => ffi::ADW_EASE_IN_QUINT, + Self::EaseOutQuint => ffi::ADW_EASE_OUT_QUINT, + Self::EaseInOutQuint => ffi::ADW_EASE_IN_OUT_QUINT, + Self::EaseInSine => ffi::ADW_EASE_IN_SINE, + Self::EaseOutSine => ffi::ADW_EASE_OUT_SINE, + Self::EaseInOutSine => ffi::ADW_EASE_IN_OUT_SINE, + Self::EaseInExpo => ffi::ADW_EASE_IN_EXPO, + Self::EaseOutExpo => ffi::ADW_EASE_OUT_EXPO, + Self::EaseInOutExpo => ffi::ADW_EASE_IN_OUT_EXPO, + Self::EaseInCirc => ffi::ADW_EASE_IN_CIRC, + Self::EaseOutCirc => ffi::ADW_EASE_OUT_CIRC, + Self::EaseInOutCirc => ffi::ADW_EASE_IN_OUT_CIRC, + Self::EaseInElastic => ffi::ADW_EASE_IN_ELASTIC, + Self::EaseOutElastic => ffi::ADW_EASE_OUT_ELASTIC, + Self::EaseInOutElastic => ffi::ADW_EASE_IN_OUT_ELASTIC, + Self::EaseInBack => ffi::ADW_EASE_IN_BACK, + Self::EaseOutBack => ffi::ADW_EASE_OUT_BACK, + Self::EaseInOutBack => ffi::ADW_EASE_IN_OUT_BACK, + Self::EaseInBounce => ffi::ADW_EASE_IN_BOUNCE, + Self::EaseOutBounce => ffi::ADW_EASE_OUT_BOUNCE, + Self::EaseInOutBounce => ffi::ADW_EASE_IN_OUT_BOUNCE, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for Easing { + unsafe fn from_glib(value: ffi::AdwEasing) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_LINEAR => Self::Linear, + ffi::ADW_EASE_IN_QUAD => Self::EaseInQuad, + ffi::ADW_EASE_OUT_QUAD => Self::EaseOutQuad, + ffi::ADW_EASE_IN_OUT_QUAD => Self::EaseInOutQuad, + ffi::ADW_EASE_IN_CUBIC => Self::EaseInCubic, + ffi::ADW_EASE_OUT_CUBIC => Self::EaseOutCubic, + ffi::ADW_EASE_IN_OUT_CUBIC => Self::EaseInOutCubic, + ffi::ADW_EASE_IN_QUART => Self::EaseInQuart, + ffi::ADW_EASE_OUT_QUART => Self::EaseOutQuart, + ffi::ADW_EASE_IN_OUT_QUART => Self::EaseInOutQuart, + ffi::ADW_EASE_IN_QUINT => Self::EaseInQuint, + ffi::ADW_EASE_OUT_QUINT => Self::EaseOutQuint, + ffi::ADW_EASE_IN_OUT_QUINT => Self::EaseInOutQuint, + ffi::ADW_EASE_IN_SINE => Self::EaseInSine, + ffi::ADW_EASE_OUT_SINE => Self::EaseOutSine, + ffi::ADW_EASE_IN_OUT_SINE => Self::EaseInOutSine, + ffi::ADW_EASE_IN_EXPO => Self::EaseInExpo, + ffi::ADW_EASE_OUT_EXPO => Self::EaseOutExpo, + ffi::ADW_EASE_IN_OUT_EXPO => Self::EaseInOutExpo, + ffi::ADW_EASE_IN_CIRC => Self::EaseInCirc, + ffi::ADW_EASE_OUT_CIRC => Self::EaseOutCirc, + ffi::ADW_EASE_IN_OUT_CIRC => Self::EaseInOutCirc, + ffi::ADW_EASE_IN_ELASTIC => Self::EaseInElastic, + ffi::ADW_EASE_OUT_ELASTIC => Self::EaseOutElastic, + ffi::ADW_EASE_IN_OUT_ELASTIC => Self::EaseInOutElastic, + ffi::ADW_EASE_IN_BACK => Self::EaseInBack, + ffi::ADW_EASE_OUT_BACK => Self::EaseOutBack, + ffi::ADW_EASE_IN_OUT_BACK => Self::EaseInOutBack, + ffi::ADW_EASE_IN_BOUNCE => Self::EaseInBounce, + ffi::ADW_EASE_OUT_BOUNCE => Self::EaseOutBounce, + ffi::ADW_EASE_IN_OUT_BOUNCE => Self::EaseInOutBounce, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for Easing { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_easing_get_type()) } + } +} + +impl glib::HasParamSpec for Easing { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +impl glib::value::ValueType for Easing { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for Easing { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for Easing { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: Easing) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwFlapFoldPolicy")] +pub enum FlapFoldPolicy { + #[doc(alias = "ADW_FLAP_FOLD_POLICY_NEVER")] + Never, + #[doc(alias = "ADW_FLAP_FOLD_POLICY_ALWAYS")] + Always, + #[doc(alias = "ADW_FLAP_FOLD_POLICY_AUTO")] + Auto, + #[doc(hidden)] + __Unknown(i32), +} + +impl fmt::Display for FlapFoldPolicy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "FlapFoldPolicy::{}", + match *self { + Self::Never => "Never", + Self::Always => "Always", + Self::Auto => "Auto", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for FlapFoldPolicy { + type GlibType = ffi::AdwFlapFoldPolicy; + + #[inline] + fn into_glib(self) -> ffi::AdwFlapFoldPolicy { + match self { + Self::Never => ffi::ADW_FLAP_FOLD_POLICY_NEVER, + Self::Always => ffi::ADW_FLAP_FOLD_POLICY_ALWAYS, + Self::Auto => ffi::ADW_FLAP_FOLD_POLICY_AUTO, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for FlapFoldPolicy { + #[inline] + unsafe fn from_glib(value: ffi::AdwFlapFoldPolicy) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_FLAP_FOLD_POLICY_NEVER => Self::Never, + ffi::ADW_FLAP_FOLD_POLICY_ALWAYS => Self::Always, + ffi::ADW_FLAP_FOLD_POLICY_AUTO => Self::Auto, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for FlapFoldPolicy { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_flap_fold_policy_get_type()) } + } +} + +impl glib::HasParamSpec for FlapFoldPolicy { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +impl glib::value::ValueType for FlapFoldPolicy { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for FlapFoldPolicy { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for FlapFoldPolicy { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: FlapFoldPolicy) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwFlapTransitionType")] +pub enum FlapTransitionType { + #[doc(alias = "ADW_FLAP_TRANSITION_TYPE_OVER")] + Over, + #[doc(alias = "ADW_FLAP_TRANSITION_TYPE_UNDER")] + Under, + #[doc(alias = "ADW_FLAP_TRANSITION_TYPE_SLIDE")] + Slide, + #[doc(hidden)] + __Unknown(i32), +} + +impl fmt::Display for FlapTransitionType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "FlapTransitionType::{}", + match *self { + Self::Over => "Over", + Self::Under => "Under", + Self::Slide => "Slide", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for FlapTransitionType { + type GlibType = ffi::AdwFlapTransitionType; + + #[inline] + fn into_glib(self) -> ffi::AdwFlapTransitionType { + match self { + Self::Over => ffi::ADW_FLAP_TRANSITION_TYPE_OVER, + Self::Under => ffi::ADW_FLAP_TRANSITION_TYPE_UNDER, + Self::Slide => ffi::ADW_FLAP_TRANSITION_TYPE_SLIDE, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for FlapTransitionType { + #[inline] + unsafe fn from_glib(value: ffi::AdwFlapTransitionType) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_FLAP_TRANSITION_TYPE_OVER => Self::Over, + ffi::ADW_FLAP_TRANSITION_TYPE_UNDER => Self::Under, + ffi::ADW_FLAP_TRANSITION_TYPE_SLIDE => Self::Slide, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for FlapTransitionType { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_flap_transition_type_get_type()) } + } +} + +impl glib::HasParamSpec for FlapTransitionType { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +impl glib::value::ValueType for FlapTransitionType { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for FlapTransitionType { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for FlapTransitionType { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: FlapTransitionType) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwFoldThresholdPolicy")] +pub enum FoldThresholdPolicy { + #[doc(alias = "ADW_FOLD_THRESHOLD_POLICY_MINIMUM")] + Minimum, + #[doc(alias = "ADW_FOLD_THRESHOLD_POLICY_NATURAL")] + Natural, + #[doc(hidden)] + __Unknown(i32), +} + +impl fmt::Display for FoldThresholdPolicy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "FoldThresholdPolicy::{}", + match *self { + Self::Minimum => "Minimum", + Self::Natural => "Natural", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for FoldThresholdPolicy { + type GlibType = ffi::AdwFoldThresholdPolicy; + + #[inline] + fn into_glib(self) -> ffi::AdwFoldThresholdPolicy { + match self { + Self::Minimum => ffi::ADW_FOLD_THRESHOLD_POLICY_MINIMUM, + Self::Natural => ffi::ADW_FOLD_THRESHOLD_POLICY_NATURAL, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for FoldThresholdPolicy { + #[inline] + unsafe fn from_glib(value: ffi::AdwFoldThresholdPolicy) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_FOLD_THRESHOLD_POLICY_MINIMUM => Self::Minimum, + ffi::ADW_FOLD_THRESHOLD_POLICY_NATURAL => Self::Natural, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for FoldThresholdPolicy { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_fold_threshold_policy_get_type()) } + } +} + +impl glib::HasParamSpec for FoldThresholdPolicy { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +impl glib::value::ValueType for FoldThresholdPolicy { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for FoldThresholdPolicy { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for FoldThresholdPolicy { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: FoldThresholdPolicy) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwLeafletTransitionType")] +pub enum LeafletTransitionType { + #[doc(alias = "ADW_LEAFLET_TRANSITION_TYPE_OVER")] + Over, + #[doc(alias = "ADW_LEAFLET_TRANSITION_TYPE_UNDER")] + Under, + #[doc(alias = "ADW_LEAFLET_TRANSITION_TYPE_SLIDE")] + Slide, + #[doc(hidden)] + __Unknown(i32), +} + +impl fmt::Display for LeafletTransitionType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "LeafletTransitionType::{}", + match *self { + Self::Over => "Over", + Self::Under => "Under", + Self::Slide => "Slide", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for LeafletTransitionType { + type GlibType = ffi::AdwLeafletTransitionType; + + #[inline] + fn into_glib(self) -> ffi::AdwLeafletTransitionType { + match self { + Self::Over => ffi::ADW_LEAFLET_TRANSITION_TYPE_OVER, + Self::Under => ffi::ADW_LEAFLET_TRANSITION_TYPE_UNDER, + Self::Slide => ffi::ADW_LEAFLET_TRANSITION_TYPE_SLIDE, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for LeafletTransitionType { + #[inline] + unsafe fn from_glib(value: ffi::AdwLeafletTransitionType) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_LEAFLET_TRANSITION_TYPE_OVER => Self::Over, + ffi::ADW_LEAFLET_TRANSITION_TYPE_UNDER => Self::Under, + ffi::ADW_LEAFLET_TRANSITION_TYPE_SLIDE => Self::Slide, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for LeafletTransitionType { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_leaflet_transition_type_get_type()) } + } +} + +impl glib::HasParamSpec for LeafletTransitionType { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +impl glib::value::ValueType for LeafletTransitionType { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for LeafletTransitionType { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for LeafletTransitionType { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: LeafletTransitionType) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwLengthUnit")] +pub enum LengthUnit { + #[doc(alias = "ADW_LENGTH_UNIT_PX")] + Px, + #[doc(alias = "ADW_LENGTH_UNIT_PT")] + Pt, + #[doc(alias = "ADW_LENGTH_UNIT_SP")] + Sp, + #[doc(hidden)] + __Unknown(i32), +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl LengthUnit { + #[doc(alias = "adw_length_unit_from_px")] + pub fn from_px(self, value: f64, settings: Option<>k::Settings>) -> f64 { + assert_initialized_main_thread!(); + unsafe { ffi::adw_length_unit_from_px(self.into_glib(), value, settings.to_glib_none().0) } + } + + #[doc(alias = "adw_length_unit_to_px")] + pub fn to_px(self, value: f64, settings: Option<>k::Settings>) -> f64 { + assert_initialized_main_thread!(); + unsafe { ffi::adw_length_unit_to_px(self.into_glib(), value, settings.to_glib_none().0) } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl fmt::Display for LengthUnit { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "LengthUnit::{}", + match *self { + Self::Px => "Px", + Self::Pt => "Pt", + Self::Sp => "Sp", + _ => "Unknown", + } + ) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +#[doc(hidden)] +impl IntoGlib for LengthUnit { + type GlibType = ffi::AdwLengthUnit; + + #[inline] + fn into_glib(self) -> ffi::AdwLengthUnit { + match self { + Self::Px => ffi::ADW_LENGTH_UNIT_PX, + Self::Pt => ffi::ADW_LENGTH_UNIT_PT, + Self::Sp => ffi::ADW_LENGTH_UNIT_SP, + Self::__Unknown(value) => value, + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +#[doc(hidden)] +impl FromGlib for LengthUnit { + #[inline] + unsafe fn from_glib(value: ffi::AdwLengthUnit) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_LENGTH_UNIT_PX => Self::Px, + ffi::ADW_LENGTH_UNIT_PT => Self::Pt, + ffi::ADW_LENGTH_UNIT_SP => Self::Sp, + value => Self::__Unknown(value), + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl StaticType for LengthUnit { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_length_unit_get_type()) } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl glib::HasParamSpec for LengthUnit { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl glib::value::ValueType for LengthUnit { + type Type = Self; +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +unsafe impl<'a> FromValue<'a> for LengthUnit { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl ToValue for LengthUnit { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl From for glib::Value { + #[inline] + fn from(v: LengthUnit) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwNavigationDirection")] +pub enum NavigationDirection { + #[doc(alias = "ADW_NAVIGATION_DIRECTION_BACK")] + Back, + #[doc(alias = "ADW_NAVIGATION_DIRECTION_FORWARD")] + Forward, + #[doc(hidden)] + __Unknown(i32), +} + +impl fmt::Display for NavigationDirection { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "NavigationDirection::{}", + match *self { + Self::Back => "Back", + Self::Forward => "Forward", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for NavigationDirection { + type GlibType = ffi::AdwNavigationDirection; + + #[inline] + fn into_glib(self) -> ffi::AdwNavigationDirection { + match self { + Self::Back => ffi::ADW_NAVIGATION_DIRECTION_BACK, + Self::Forward => ffi::ADW_NAVIGATION_DIRECTION_FORWARD, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for NavigationDirection { + #[inline] + unsafe fn from_glib(value: ffi::AdwNavigationDirection) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_NAVIGATION_DIRECTION_BACK => Self::Back, + ffi::ADW_NAVIGATION_DIRECTION_FORWARD => Self::Forward, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for NavigationDirection { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_navigation_direction_get_type()) } + } +} + +impl glib::HasParamSpec for NavigationDirection { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +impl glib::value::ValueType for NavigationDirection { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for NavigationDirection { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for NavigationDirection { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: NavigationDirection) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwResponseAppearance")] +pub enum ResponseAppearance { + #[doc(alias = "ADW_RESPONSE_DEFAULT")] + Default, + #[doc(alias = "ADW_RESPONSE_SUGGESTED")] + Suggested, + #[doc(alias = "ADW_RESPONSE_DESTRUCTIVE")] + Destructive, + #[doc(hidden)] + __Unknown(i32), +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl fmt::Display for ResponseAppearance { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "ResponseAppearance::{}", + match *self { + Self::Default => "Default", + Self::Suggested => "Suggested", + Self::Destructive => "Destructive", + _ => "Unknown", + } + ) + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +#[doc(hidden)] +impl IntoGlib for ResponseAppearance { + type GlibType = ffi::AdwResponseAppearance; + + #[inline] + fn into_glib(self) -> ffi::AdwResponseAppearance { + match self { + Self::Default => ffi::ADW_RESPONSE_DEFAULT, + Self::Suggested => ffi::ADW_RESPONSE_SUGGESTED, + Self::Destructive => ffi::ADW_RESPONSE_DESTRUCTIVE, + Self::__Unknown(value) => value, + } + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +#[doc(hidden)] +impl FromGlib for ResponseAppearance { + #[inline] + unsafe fn from_glib(value: ffi::AdwResponseAppearance) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_RESPONSE_DEFAULT => Self::Default, + ffi::ADW_RESPONSE_SUGGESTED => Self::Suggested, + ffi::ADW_RESPONSE_DESTRUCTIVE => Self::Destructive, + value => Self::__Unknown(value), + } + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl StaticType for ResponseAppearance { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_response_appearance_get_type()) } + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl glib::HasParamSpec for ResponseAppearance { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl glib::value::ValueType for ResponseAppearance { + type Type = Self; +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +unsafe impl<'a> FromValue<'a> for ResponseAppearance { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl ToValue for ResponseAppearance { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl From for glib::Value { + #[inline] + fn from(v: ResponseAppearance) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwSqueezerTransitionType")] +pub enum SqueezerTransitionType { + #[doc(alias = "ADW_SQUEEZER_TRANSITION_TYPE_NONE")] + None, + #[doc(alias = "ADW_SQUEEZER_TRANSITION_TYPE_CROSSFADE")] + Crossfade, + #[doc(hidden)] + __Unknown(i32), +} + +impl fmt::Display for SqueezerTransitionType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "SqueezerTransitionType::{}", + match *self { + Self::None => "None", + Self::Crossfade => "Crossfade", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for SqueezerTransitionType { + type GlibType = ffi::AdwSqueezerTransitionType; + + #[inline] + fn into_glib(self) -> ffi::AdwSqueezerTransitionType { + match self { + Self::None => ffi::ADW_SQUEEZER_TRANSITION_TYPE_NONE, + Self::Crossfade => ffi::ADW_SQUEEZER_TRANSITION_TYPE_CROSSFADE, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for SqueezerTransitionType { + #[inline] + unsafe fn from_glib(value: ffi::AdwSqueezerTransitionType) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_SQUEEZER_TRANSITION_TYPE_NONE => Self::None, + ffi::ADW_SQUEEZER_TRANSITION_TYPE_CROSSFADE => Self::Crossfade, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for SqueezerTransitionType { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_squeezer_transition_type_get_type()) } + } +} + +impl glib::HasParamSpec for SqueezerTransitionType { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +impl glib::value::ValueType for SqueezerTransitionType { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for SqueezerTransitionType { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for SqueezerTransitionType { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: SqueezerTransitionType) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwToastPriority")] +pub enum ToastPriority { + #[doc(alias = "ADW_TOAST_PRIORITY_NORMAL")] + Normal, + #[doc(alias = "ADW_TOAST_PRIORITY_HIGH")] + High, + #[doc(hidden)] + __Unknown(i32), +} + +impl fmt::Display for ToastPriority { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "ToastPriority::{}", + match *self { + Self::Normal => "Normal", + Self::High => "High", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for ToastPriority { + type GlibType = ffi::AdwToastPriority; + + #[inline] + fn into_glib(self) -> ffi::AdwToastPriority { + match self { + Self::Normal => ffi::ADW_TOAST_PRIORITY_NORMAL, + Self::High => ffi::ADW_TOAST_PRIORITY_HIGH, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for ToastPriority { + #[inline] + unsafe fn from_glib(value: ffi::AdwToastPriority) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_TOAST_PRIORITY_NORMAL => Self::Normal, + ffi::ADW_TOAST_PRIORITY_HIGH => Self::High, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for ToastPriority { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_toast_priority_get_type()) } + } +} + +impl glib::HasParamSpec for ToastPriority { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +impl glib::value::ValueType for ToastPriority { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for ToastPriority { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for ToastPriority { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: ToastPriority) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwToolbarStyle")] +pub enum ToolbarStyle { + #[doc(alias = "ADW_TOOLBAR_FLAT")] + Flat, + #[doc(alias = "ADW_TOOLBAR_RAISED")] + Raised, + #[doc(hidden)] + __Unknown(i32), +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl fmt::Display for ToolbarStyle { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "ToolbarStyle::{}", + match *self { + Self::Flat => "Flat", + Self::Raised => "Raised", + _ => "Unknown", + } + ) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +#[doc(hidden)] +impl IntoGlib for ToolbarStyle { + type GlibType = ffi::AdwToolbarStyle; + + #[inline] + fn into_glib(self) -> ffi::AdwToolbarStyle { + match self { + Self::Flat => ffi::ADW_TOOLBAR_FLAT, + Self::Raised => ffi::ADW_TOOLBAR_RAISED, + Self::__Unknown(value) => value, + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +#[doc(hidden)] +impl FromGlib for ToolbarStyle { + #[inline] + unsafe fn from_glib(value: ffi::AdwToolbarStyle) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_TOOLBAR_FLAT => Self::Flat, + ffi::ADW_TOOLBAR_RAISED => Self::Raised, + value => Self::__Unknown(value), + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl StaticType for ToolbarStyle { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_toolbar_style_get_type()) } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl glib::HasParamSpec for ToolbarStyle { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl glib::value::ValueType for ToolbarStyle { + type Type = Self; +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +unsafe impl<'a> FromValue<'a> for ToolbarStyle { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl ToValue for ToolbarStyle { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl From for glib::Value { + #[inline] + fn from(v: ToolbarStyle) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "AdwViewSwitcherPolicy")] +pub enum ViewSwitcherPolicy { + #[doc(alias = "ADW_VIEW_SWITCHER_POLICY_NARROW")] + Narrow, + #[doc(alias = "ADW_VIEW_SWITCHER_POLICY_WIDE")] + Wide, + #[doc(hidden)] + __Unknown(i32), +} + +impl fmt::Display for ViewSwitcherPolicy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "ViewSwitcherPolicy::{}", + match *self { + Self::Narrow => "Narrow", + Self::Wide => "Wide", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for ViewSwitcherPolicy { + type GlibType = ffi::AdwViewSwitcherPolicy; + + #[inline] + fn into_glib(self) -> ffi::AdwViewSwitcherPolicy { + match self { + Self::Narrow => ffi::ADW_VIEW_SWITCHER_POLICY_NARROW, + Self::Wide => ffi::ADW_VIEW_SWITCHER_POLICY_WIDE, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for ViewSwitcherPolicy { + #[inline] + unsafe fn from_glib(value: ffi::AdwViewSwitcherPolicy) -> Self { + skip_assert_initialized!(); + + match value { + ffi::ADW_VIEW_SWITCHER_POLICY_NARROW => Self::Narrow, + ffi::ADW_VIEW_SWITCHER_POLICY_WIDE => Self::Wide, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for ViewSwitcherPolicy { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_view_switcher_policy_get_type()) } + } +} + +impl glib::HasParamSpec for ViewSwitcherPolicy { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name, default_value| Self::ParamSpec::builder_with_default(name, default_value) + } +} + +impl glib::value::ValueType for ViewSwitcherPolicy { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for ViewSwitcherPolicy { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for ViewSwitcherPolicy { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: ViewSwitcherPolicy) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} diff --git a/libadwaita-0.4.4/src/auto/expander_row.rs b/libadwaita-0.4.4/src/auto/expander_row.rs new file mode 100644 index 0000000..ac556f5 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/expander_row.rs @@ -0,0 +1,832 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT +#![allow(deprecated)] + +use crate::PreferencesRow; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwExpanderRow")] + pub struct ExpanderRow(Object) @extends PreferencesRow, gtk::ListBoxRow, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable; + + match fn { + type_ => || ffi::adw_expander_row_get_type(), + } +} + +impl ExpanderRow { + pub const NONE: Option<&'static ExpanderRow> = None; + + #[doc(alias = "adw_expander_row_new")] + pub fn new() -> ExpanderRow { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_expander_row_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`ExpanderRow`] objects. + /// + /// This method returns an instance of [`ExpanderRowBuilder`](crate::builders::ExpanderRowBuilder) which can be used to create [`ExpanderRow`] objects. + pub fn builder() -> ExpanderRowBuilder { + ExpanderRowBuilder::new() + } +} + +impl Default for ExpanderRow { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`ExpanderRow`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ExpanderRowBuilder { + builder: glib::object::ObjectBuilder<'static, ExpanderRow>, +} + +impl ExpanderRowBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn enable_expansion(self, enable_expansion: bool) -> Self { + Self { + builder: self.builder.property("enable-expansion", enable_expansion), + } + } + + pub fn expanded(self, expanded: bool) -> Self { + Self { + builder: self.builder.property("expanded", expanded), + } + } + + #[cfg_attr(feature = "v1_3", deprecated = "Since 1.3")] + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn show_enable_switch(self, show_enable_switch: bool) -> Self { + Self { + builder: self + .builder + .property("show-enable-switch", show_enable_switch), + } + } + + pub fn subtitle(self, subtitle: impl Into) -> Self { + Self { + builder: self.builder.property("subtitle", subtitle.into()), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn subtitle_lines(self, subtitle_lines: i32) -> Self { + Self { + builder: self.builder.property("subtitle-lines", subtitle_lines), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn title_lines(self, title_lines: i32) -> Self { + Self { + builder: self.builder.property("title-lines", title_lines), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + pub fn title_selectable(self, title_selectable: bool) -> Self { + Self { + builder: self.builder.property("title-selectable", title_selectable), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn use_markup(self, use_markup: bool) -> Self { + Self { + builder: self.builder.property("use-markup", use_markup), + } + } + + pub fn use_underline(self, use_underline: bool) -> Self { + Self { + builder: self.builder.property("use-underline", use_underline), + } + } + + pub fn activatable(self, activatable: bool) -> Self { + Self { + builder: self.builder.property("activatable", activatable), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn selectable(self, selectable: bool) -> Self { + Self { + builder: self.builder.property("selectable", selectable), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn action_name(self, action_name: impl Into) -> Self { + Self { + builder: self.builder.property("action-name", action_name.into()), + } + } + + pub fn action_target(self, action_target: &glib::Variant) -> Self { + Self { + builder: self + .builder + .property("action-target", action_target.clone()), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`ExpanderRow`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> ExpanderRow { + self.builder.build() + } +} + +pub trait ExpanderRowExt: 'static { + #[cfg_attr(feature = "v1_4", deprecated = "Since 1.4")] + #[allow(deprecated)] + #[doc(alias = "adw_expander_row_add_action")] + fn add_action(&self, widget: &impl IsA); + + #[doc(alias = "adw_expander_row_add_prefix")] + fn add_prefix(&self, widget: &impl IsA); + + #[doc(alias = "adw_expander_row_add_row")] + fn add_row(&self, child: &impl IsA); + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_expander_row_add_suffix")] + fn add_suffix(&self, widget: &impl IsA); + + #[doc(alias = "adw_expander_row_get_enable_expansion")] + #[doc(alias = "get_enable_expansion")] + fn enables_expansion(&self) -> bool; + + #[doc(alias = "adw_expander_row_get_expanded")] + #[doc(alias = "get_expanded")] + fn is_expanded(&self) -> bool; + + #[cfg_attr(feature = "v1_3", deprecated = "Since 1.3")] + #[allow(deprecated)] + #[doc(alias = "adw_expander_row_get_icon_name")] + #[doc(alias = "get_icon_name")] + fn icon_name(&self) -> Option; + + #[doc(alias = "adw_expander_row_get_show_enable_switch")] + #[doc(alias = "get_show_enable_switch")] + fn shows_enable_switch(&self) -> bool; + + #[doc(alias = "adw_expander_row_get_subtitle")] + #[doc(alias = "get_subtitle")] + fn subtitle(&self) -> glib::GString; + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_expander_row_get_subtitle_lines")] + #[doc(alias = "get_subtitle_lines")] + fn is_subtitle_lines(&self) -> bool; + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_expander_row_get_title_lines")] + #[doc(alias = "get_title_lines")] + fn is_title_lines(&self) -> bool; + + #[doc(alias = "adw_expander_row_remove")] + fn remove(&self, child: &impl IsA); + + #[doc(alias = "adw_expander_row_set_enable_expansion")] + fn set_enable_expansion(&self, enable_expansion: bool); + + #[doc(alias = "adw_expander_row_set_expanded")] + fn set_expanded(&self, expanded: bool); + + #[cfg_attr(feature = "v1_3", deprecated = "Since 1.3")] + #[allow(deprecated)] + #[doc(alias = "adw_expander_row_set_icon_name")] + fn set_icon_name(&self, icon_name: Option<&str>); + + #[doc(alias = "adw_expander_row_set_show_enable_switch")] + fn set_show_enable_switch(&self, show_enable_switch: bool); + + #[doc(alias = "adw_expander_row_set_subtitle")] + fn set_subtitle(&self, subtitle: &str); + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_expander_row_set_subtitle_lines")] + fn set_subtitle_lines(&self, subtitle_lines: i32); + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_expander_row_set_title_lines")] + fn set_title_lines(&self, title_lines: i32); + + #[doc(alias = "enable-expansion")] + fn connect_enable_expansion_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "expanded")] + fn connect_expanded_notify(&self, f: F) -> SignalHandlerId; + + #[cfg_attr(feature = "v1_3", deprecated = "Since 1.3")] + #[doc(alias = "icon-name")] + fn connect_icon_name_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "show-enable-switch")] + fn connect_show_enable_switch_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "subtitle")] + fn connect_subtitle_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "subtitle-lines")] + fn connect_subtitle_lines_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "title-lines")] + fn connect_title_lines_notify(&self, f: F) -> SignalHandlerId; +} + +impl> ExpanderRowExt for O { + #[allow(deprecated)] + fn add_action(&self, widget: &impl IsA) { + unsafe { + ffi::adw_expander_row_add_action( + self.as_ref().to_glib_none().0, + widget.as_ref().to_glib_none().0, + ); + } + } + + fn add_prefix(&self, widget: &impl IsA) { + unsafe { + ffi::adw_expander_row_add_prefix( + self.as_ref().to_glib_none().0, + widget.as_ref().to_glib_none().0, + ); + } + } + + fn add_row(&self, child: &impl IsA) { + unsafe { + ffi::adw_expander_row_add_row( + self.as_ref().to_glib_none().0, + child.as_ref().to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn add_suffix(&self, widget: &impl IsA) { + unsafe { + ffi::adw_expander_row_add_suffix( + self.as_ref().to_glib_none().0, + widget.as_ref().to_glib_none().0, + ); + } + } + + fn enables_expansion(&self) -> bool { + unsafe { + from_glib(ffi::adw_expander_row_get_enable_expansion( + self.as_ref().to_glib_none().0, + )) + } + } + + fn is_expanded(&self) -> bool { + unsafe { + from_glib(ffi::adw_expander_row_get_expanded( + self.as_ref().to_glib_none().0, + )) + } + } + + #[allow(deprecated)] + fn icon_name(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_expander_row_get_icon_name( + self.as_ref().to_glib_none().0, + )) + } + } + + fn shows_enable_switch(&self) -> bool { + unsafe { + from_glib(ffi::adw_expander_row_get_show_enable_switch( + self.as_ref().to_glib_none().0, + )) + } + } + + fn subtitle(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_expander_row_get_subtitle( + self.as_ref().to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn is_subtitle_lines(&self) -> bool { + unsafe { + from_glib(ffi::adw_expander_row_get_subtitle_lines( + self.as_ref().to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn is_title_lines(&self) -> bool { + unsafe { + from_glib(ffi::adw_expander_row_get_title_lines( + self.as_ref().to_glib_none().0, + )) + } + } + + fn remove(&self, child: &impl IsA) { + unsafe { + ffi::adw_expander_row_remove( + self.as_ref().to_glib_none().0, + child.as_ref().to_glib_none().0, + ); + } + } + + fn set_enable_expansion(&self, enable_expansion: bool) { + unsafe { + ffi::adw_expander_row_set_enable_expansion( + self.as_ref().to_glib_none().0, + enable_expansion.into_glib(), + ); + } + } + + fn set_expanded(&self, expanded: bool) { + unsafe { + ffi::adw_expander_row_set_expanded( + self.as_ref().to_glib_none().0, + expanded.into_glib(), + ); + } + } + + #[allow(deprecated)] + fn set_icon_name(&self, icon_name: Option<&str>) { + unsafe { + ffi::adw_expander_row_set_icon_name( + self.as_ref().to_glib_none().0, + icon_name.to_glib_none().0, + ); + } + } + + fn set_show_enable_switch(&self, show_enable_switch: bool) { + unsafe { + ffi::adw_expander_row_set_show_enable_switch( + self.as_ref().to_glib_none().0, + show_enable_switch.into_glib(), + ); + } + } + + fn set_subtitle(&self, subtitle: &str) { + unsafe { + ffi::adw_expander_row_set_subtitle( + self.as_ref().to_glib_none().0, + subtitle.to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn set_subtitle_lines(&self, subtitle_lines: i32) { + unsafe { + ffi::adw_expander_row_set_subtitle_lines( + self.as_ref().to_glib_none().0, + subtitle_lines, + ); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn set_title_lines(&self, title_lines: i32) { + unsafe { + ffi::adw_expander_row_set_title_lines(self.as_ref().to_glib_none().0, title_lines); + } + } + + fn connect_enable_expansion_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_enable_expansion_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwExpanderRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ExpanderRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::enable-expansion\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_enable_expansion_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_expanded_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_expanded_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwExpanderRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ExpanderRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::expanded\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_expanded_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_icon_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_icon_name_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwExpanderRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ExpanderRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::icon-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_icon_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_show_enable_switch_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_show_enable_switch_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwExpanderRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ExpanderRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::show-enable-switch\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_show_enable_switch_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_subtitle_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_subtitle_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwExpanderRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ExpanderRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::subtitle\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_subtitle_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn connect_subtitle_lines_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_subtitle_lines_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwExpanderRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ExpanderRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::subtitle-lines\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_subtitle_lines_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn connect_title_lines_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_lines_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwExpanderRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(ExpanderRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title-lines\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_lines_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for ExpanderRow { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ExpanderRow") + } +} diff --git a/libadwaita-0.4.4/src/auto/flags.rs b/libadwaita-0.4.4/src/auto/flags.rs new file mode 100644 index 0000000..2573a2f --- /dev/null +++ b/libadwaita-0.4.4/src/auto/flags.rs @@ -0,0 +1,148 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +use bitflags::bitflags; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +use glib::{translate::*, value::FromValue, value::ToValue, StaticType, Type}; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +use std::fmt; + +#[cfg(any(feature = "v1_2", feature = "dox"))] +bitflags! { + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "AdwTabViewShortcuts")] + pub struct TabViewShortcuts: u32 { + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_NONE")] + const NONE = ffi::ADW_TAB_VIEW_SHORTCUT_NONE as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_CONTROL_TAB")] + const CONTROL_TAB = ffi::ADW_TAB_VIEW_SHORTCUT_CONTROL_TAB as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_CONTROL_SHIFT_TAB")] + const CONTROL_SHIFT_TAB = ffi::ADW_TAB_VIEW_SHORTCUT_CONTROL_SHIFT_TAB as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_CONTROL_PAGE_UP")] + const CONTROL_PAGE_UP = ffi::ADW_TAB_VIEW_SHORTCUT_CONTROL_PAGE_UP as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_CONTROL_PAGE_DOWN")] + const CONTROL_PAGE_DOWN = ffi::ADW_TAB_VIEW_SHORTCUT_CONTROL_PAGE_DOWN as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_CONTROL_HOME")] + const CONTROL_HOME = ffi::ADW_TAB_VIEW_SHORTCUT_CONTROL_HOME as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_CONTROL_END")] + const CONTROL_END = ffi::ADW_TAB_VIEW_SHORTCUT_CONTROL_END as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_CONTROL_SHIFT_PAGE_UP")] + const CONTROL_SHIFT_PAGE_UP = ffi::ADW_TAB_VIEW_SHORTCUT_CONTROL_SHIFT_PAGE_UP as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_CONTROL_SHIFT_PAGE_DOWN")] + const CONTROL_SHIFT_PAGE_DOWN = ffi::ADW_TAB_VIEW_SHORTCUT_CONTROL_SHIFT_PAGE_DOWN as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_CONTROL_SHIFT_HOME")] + const CONTROL_SHIFT_HOME = ffi::ADW_TAB_VIEW_SHORTCUT_CONTROL_SHIFT_HOME as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_CONTROL_SHIFT_END")] + const CONTROL_SHIFT_END = ffi::ADW_TAB_VIEW_SHORTCUT_CONTROL_SHIFT_END as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_ALT_DIGITS")] + const ALT_DIGITS = ffi::ADW_TAB_VIEW_SHORTCUT_ALT_DIGITS as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_ALT_ZERO")] + const ALT_ZERO = ffi::ADW_TAB_VIEW_SHORTCUT_ALT_ZERO as _; + #[doc(alias = "ADW_TAB_VIEW_SHORTCUT_ALL_SHORTCUTS")] + const ALL_SHORTCUTS = ffi::ADW_TAB_VIEW_SHORTCUT_ALL_SHORTCUTS as _; + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl fmt::Display for TabViewShortcuts { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + ::fmt(self, f) + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +#[doc(hidden)] +impl IntoGlib for TabViewShortcuts { + type GlibType = ffi::AdwTabViewShortcuts; + + #[inline] + fn into_glib(self) -> ffi::AdwTabViewShortcuts { + self.bits() + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +#[doc(hidden)] +impl FromGlib for TabViewShortcuts { + #[inline] + unsafe fn from_glib(value: ffi::AdwTabViewShortcuts) -> Self { + skip_assert_initialized!(); + Self::from_bits_truncate(value) + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl StaticType for TabViewShortcuts { + #[inline] + fn static_type() -> Type { + unsafe { from_glib(ffi::adw_tab_view_shortcuts_get_type()) } + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl glib::HasParamSpec for TabViewShortcuts { + type ParamSpec = glib::ParamSpecFlags; + type SetValue = Self; + type BuilderFn = fn(&str) -> glib::ParamSpecFlagsBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + |name| Self::ParamSpec::builder(name) + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl glib::value::ValueType for TabViewShortcuts { + type Type = Self; +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +unsafe impl<'a> FromValue<'a> for TabViewShortcuts { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_flags(value.to_glib_none().0)) + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl ToValue for TabViewShortcuts { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_flags(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl From for glib::Value { + #[inline] + fn from(v: TabViewShortcuts) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} diff --git a/libadwaita-0.4.4/src/auto/flap.rs b/libadwaita-0.4.4/src/auto/flap.rs new file mode 100644 index 0000000..1e6350a --- /dev/null +++ b/libadwaita-0.4.4/src/auto/flap.rs @@ -0,0 +1,931 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{FlapFoldPolicy, FlapTransitionType, FoldThresholdPolicy, SpringParams, Swipeable}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwFlap")] + pub struct Flap(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, Swipeable, gtk::Orientable; + + match fn { + type_ => || ffi::adw_flap_get_type(), + } +} + +impl Flap { + #[doc(alias = "adw_flap_new")] + pub fn new() -> Flap { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_flap_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`Flap`] objects. + /// + /// This method returns an instance of [`FlapBuilder`](crate::builders::FlapBuilder) which can be used to create [`Flap`] objects. + pub fn builder() -> FlapBuilder { + FlapBuilder::new() + } + + #[doc(alias = "adw_flap_get_content")] + #[doc(alias = "get_content")] + pub fn content(&self) -> Option { + unsafe { from_glib_none(ffi::adw_flap_get_content(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_get_flap")] + #[doc(alias = "get_flap")] + pub fn flap(&self) -> Option { + unsafe { from_glib_none(ffi::adw_flap_get_flap(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_get_flap_position")] + #[doc(alias = "get_flap_position")] + pub fn flap_position(&self) -> gtk::PackType { + unsafe { from_glib(ffi::adw_flap_get_flap_position(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_get_fold_duration")] + #[doc(alias = "get_fold_duration")] + pub fn fold_duration(&self) -> u32 { + unsafe { ffi::adw_flap_get_fold_duration(self.to_glib_none().0) } + } + + #[doc(alias = "adw_flap_get_fold_policy")] + #[doc(alias = "get_fold_policy")] + pub fn fold_policy(&self) -> FlapFoldPolicy { + unsafe { from_glib(ffi::adw_flap_get_fold_policy(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_get_fold_threshold_policy")] + #[doc(alias = "get_fold_threshold_policy")] + pub fn fold_threshold_policy(&self) -> FoldThresholdPolicy { + unsafe { + from_glib(ffi::adw_flap_get_fold_threshold_policy( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_flap_get_folded")] + #[doc(alias = "get_folded")] + pub fn is_folded(&self) -> bool { + unsafe { from_glib(ffi::adw_flap_get_folded(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_get_locked")] + #[doc(alias = "get_locked")] + pub fn is_locked(&self) -> bool { + unsafe { from_glib(ffi::adw_flap_get_locked(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_get_modal")] + #[doc(alias = "get_modal")] + pub fn is_modal(&self) -> bool { + unsafe { from_glib(ffi::adw_flap_get_modal(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_get_reveal_flap")] + #[doc(alias = "get_reveal_flap")] + pub fn reveals_flap(&self) -> bool { + unsafe { from_glib(ffi::adw_flap_get_reveal_flap(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_get_reveal_params")] + #[doc(alias = "get_reveal_params")] + pub fn reveal_params(&self) -> SpringParams { + unsafe { from_glib_full(ffi::adw_flap_get_reveal_params(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_get_reveal_progress")] + #[doc(alias = "get_reveal_progress")] + pub fn reveal_progress(&self) -> f64 { + unsafe { ffi::adw_flap_get_reveal_progress(self.to_glib_none().0) } + } + + #[doc(alias = "adw_flap_get_separator")] + #[doc(alias = "get_separator")] + pub fn separator(&self) -> Option { + unsafe { from_glib_none(ffi::adw_flap_get_separator(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_get_swipe_to_close")] + #[doc(alias = "get_swipe_to_close")] + pub fn is_swipe_to_close(&self) -> bool { + unsafe { from_glib(ffi::adw_flap_get_swipe_to_close(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_get_swipe_to_open")] + #[doc(alias = "get_swipe_to_open")] + pub fn is_swipe_to_open(&self) -> bool { + unsafe { from_glib(ffi::adw_flap_get_swipe_to_open(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_get_transition_type")] + #[doc(alias = "get_transition_type")] + pub fn transition_type(&self) -> FlapTransitionType { + unsafe { from_glib(ffi::adw_flap_get_transition_type(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_flap_set_content")] + pub fn set_content(&self, content: Option<&impl IsA>) { + unsafe { + ffi::adw_flap_set_content( + self.to_glib_none().0, + content.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_flap_set_flap")] + pub fn set_flap(&self, flap: Option<&impl IsA>) { + unsafe { + ffi::adw_flap_set_flap( + self.to_glib_none().0, + flap.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_flap_set_flap_position")] + pub fn set_flap_position(&self, position: gtk::PackType) { + unsafe { + ffi::adw_flap_set_flap_position(self.to_glib_none().0, position.into_glib()); + } + } + + #[doc(alias = "adw_flap_set_fold_duration")] + pub fn set_fold_duration(&self, duration: u32) { + unsafe { + ffi::adw_flap_set_fold_duration(self.to_glib_none().0, duration); + } + } + + #[doc(alias = "adw_flap_set_fold_policy")] + pub fn set_fold_policy(&self, policy: FlapFoldPolicy) { + unsafe { + ffi::adw_flap_set_fold_policy(self.to_glib_none().0, policy.into_glib()); + } + } + + #[doc(alias = "adw_flap_set_fold_threshold_policy")] + pub fn set_fold_threshold_policy(&self, policy: FoldThresholdPolicy) { + unsafe { + ffi::adw_flap_set_fold_threshold_policy(self.to_glib_none().0, policy.into_glib()); + } + } + + #[doc(alias = "adw_flap_set_locked")] + pub fn set_locked(&self, locked: bool) { + unsafe { + ffi::adw_flap_set_locked(self.to_glib_none().0, locked.into_glib()); + } + } + + #[doc(alias = "adw_flap_set_modal")] + pub fn set_modal(&self, modal: bool) { + unsafe { + ffi::adw_flap_set_modal(self.to_glib_none().0, modal.into_glib()); + } + } + + #[doc(alias = "adw_flap_set_reveal_flap")] + pub fn set_reveal_flap(&self, reveal_flap: bool) { + unsafe { + ffi::adw_flap_set_reveal_flap(self.to_glib_none().0, reveal_flap.into_glib()); + } + } + + #[doc(alias = "adw_flap_set_reveal_params")] + pub fn set_reveal_params(&self, params: &SpringParams) { + unsafe { + ffi::adw_flap_set_reveal_params(self.to_glib_none().0, params.to_glib_none().0); + } + } + + #[doc(alias = "adw_flap_set_separator")] + pub fn set_separator(&self, separator: Option<&impl IsA>) { + unsafe { + ffi::adw_flap_set_separator( + self.to_glib_none().0, + separator.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_flap_set_swipe_to_close")] + pub fn set_swipe_to_close(&self, swipe_to_close: bool) { + unsafe { + ffi::adw_flap_set_swipe_to_close(self.to_glib_none().0, swipe_to_close.into_glib()); + } + } + + #[doc(alias = "adw_flap_set_swipe_to_open")] + pub fn set_swipe_to_open(&self, swipe_to_open: bool) { + unsafe { + ffi::adw_flap_set_swipe_to_open(self.to_glib_none().0, swipe_to_open.into_glib()); + } + } + + #[doc(alias = "adw_flap_set_transition_type")] + pub fn set_transition_type(&self, transition_type: FlapTransitionType) { + unsafe { + ffi::adw_flap_set_transition_type(self.to_glib_none().0, transition_type.into_glib()); + } + } + + #[doc(alias = "content")] + pub fn connect_content_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_content_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::content\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_content_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "flap")] + pub fn connect_flap_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_flap_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::flap\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_flap_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "flap-position")] + pub fn connect_flap_position_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_flap_position_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::flap-position\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_flap_position_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "fold-duration")] + pub fn connect_fold_duration_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_fold_duration_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::fold-duration\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_fold_duration_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "fold-policy")] + pub fn connect_fold_policy_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_fold_policy_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::fold-policy\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_fold_policy_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "fold-threshold-policy")] + pub fn connect_fold_threshold_policy_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_fold_threshold_policy_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::fold-threshold-policy\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_fold_threshold_policy_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "folded")] + pub fn connect_folded_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_folded_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::folded\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_folded_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "locked")] + pub fn connect_locked_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_locked_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::locked\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_locked_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "modal")] + pub fn connect_modal_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_modal_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::modal\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_modal_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "reveal-flap")] + pub fn connect_reveal_flap_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_reveal_flap_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::reveal-flap\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_reveal_flap_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "reveal-params")] + pub fn connect_reveal_params_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_reveal_params_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::reveal-params\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_reveal_params_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "reveal-progress")] + pub fn connect_reveal_progress_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_reveal_progress_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::reveal-progress\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_reveal_progress_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "separator")] + pub fn connect_separator_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_separator_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::separator\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_separator_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "swipe-to-close")] + pub fn connect_swipe_to_close_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_swipe_to_close_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::swipe-to-close\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_swipe_to_close_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "swipe-to-open")] + pub fn connect_swipe_to_open_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_swipe_to_open_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::swipe-to-open\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_swipe_to_open_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "transition-type")] + pub fn connect_transition_type_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_transition_type_trampoline( + this: *mut ffi::AdwFlap, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::transition-type\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_transition_type_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for Flap { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`Flap`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct FlapBuilder { + builder: glib::object::ObjectBuilder<'static, Flap>, +} + +impl FlapBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn content(self, content: &impl IsA) -> Self { + Self { + builder: self.builder.property("content", content.clone().upcast()), + } + } + + pub fn flap(self, flap: &impl IsA) -> Self { + Self { + builder: self.builder.property("flap", flap.clone().upcast()), + } + } + + pub fn flap_position(self, flap_position: gtk::PackType) -> Self { + Self { + builder: self.builder.property("flap-position", flap_position), + } + } + + pub fn fold_duration(self, fold_duration: u32) -> Self { + Self { + builder: self.builder.property("fold-duration", fold_duration), + } + } + + pub fn fold_policy(self, fold_policy: FlapFoldPolicy) -> Self { + Self { + builder: self.builder.property("fold-policy", fold_policy), + } + } + + pub fn fold_threshold_policy(self, fold_threshold_policy: FoldThresholdPolicy) -> Self { + Self { + builder: self + .builder + .property("fold-threshold-policy", fold_threshold_policy), + } + } + + pub fn locked(self, locked: bool) -> Self { + Self { + builder: self.builder.property("locked", locked), + } + } + + pub fn modal(self, modal: bool) -> Self { + Self { + builder: self.builder.property("modal", modal), + } + } + + pub fn reveal_flap(self, reveal_flap: bool) -> Self { + Self { + builder: self.builder.property("reveal-flap", reveal_flap), + } + } + + pub fn reveal_params(self, reveal_params: &SpringParams) -> Self { + Self { + builder: self + .builder + .property("reveal-params", reveal_params.clone()), + } + } + + pub fn separator(self, separator: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("separator", separator.clone().upcast()), + } + } + + pub fn swipe_to_close(self, swipe_to_close: bool) -> Self { + Self { + builder: self.builder.property("swipe-to-close", swipe_to_close), + } + } + + pub fn swipe_to_open(self, swipe_to_open: bool) -> Self { + Self { + builder: self.builder.property("swipe-to-open", swipe_to_open), + } + } + + pub fn transition_type(self, transition_type: FlapTransitionType) -> Self { + Self { + builder: self.builder.property("transition-type", transition_type), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn orientation(self, orientation: gtk::Orientation) -> Self { + Self { + builder: self.builder.property("orientation", orientation), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`Flap`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> Flap { + self.builder.build() + } +} + +impl fmt::Display for Flap { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Flap") + } +} diff --git a/libadwaita-0.4.4/src/auto/functions.rs b/libadwaita-0.4.4/src/auto/functions.rs new file mode 100644 index 0000000..781773d --- /dev/null +++ b/libadwaita-0.4.4/src/auto/functions.rs @@ -0,0 +1,57 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{prelude::*, translate::*}; + +#[doc(alias = "adw_get_enable_animations")] +#[doc(alias = "get_enable_animations")] +pub fn is_animations_enabled(widget: &impl IsA) -> bool { + assert_initialized_main_thread!(); + unsafe { + from_glib(ffi::adw_get_enable_animations( + widget.as_ref().to_glib_none().0, + )) + } +} + +#[doc(alias = "adw_get_major_version")] +#[doc(alias = "get_major_version")] +pub fn major_version() -> u32 { + assert_initialized_main_thread!(); + unsafe { ffi::adw_get_major_version() } +} + +#[doc(alias = "adw_get_micro_version")] +#[doc(alias = "get_micro_version")] +pub fn micro_version() -> u32 { + assert_initialized_main_thread!(); + unsafe { ffi::adw_get_micro_version() } +} + +#[doc(alias = "adw_get_minor_version")] +#[doc(alias = "get_minor_version")] +pub fn minor_version() -> u32 { + assert_initialized_main_thread!(); + unsafe { ffi::adw_get_minor_version() } +} + +#[doc(alias = "adw_is_initialized")] +pub fn is_initialized() -> bool { + assert_initialized_main_thread!(); + unsafe { from_glib(ffi::adw_is_initialized()) } +} + +#[doc(alias = "adw_lerp")] +pub fn lerp(a: f64, b: f64, t: f64) -> f64 { + assert_initialized_main_thread!(); + unsafe { ffi::adw_lerp(a, b, t) } +} + +//#[cfg(any(feature = "v1_4", feature = "dox"))] +//#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +//#[doc(alias = "adw_show_about_window_from_appdata")] +//pub fn show_about_window_from_appdata(parent: Option<&impl IsA>, resource_path: &str, release_notes_version: Option<&str>, first_property_name: &str, : /*Unknown conversion*//*Unimplemented*/Basic: VarArgs) { +// unsafe { TODO: call ffi:adw_show_about_window_from_appdata() } +//} diff --git a/libadwaita-0.4.4/src/auto/header_bar.rs b/libadwaita-0.4.4/src/auto/header_bar.rs new file mode 100644 index 0000000..57875ba --- /dev/null +++ b/libadwaita-0.4.4/src/auto/header_bar.rs @@ -0,0 +1,647 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::CenteringPolicy; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwHeaderBar")] + pub struct HeaderBar(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_header_bar_get_type(), + } +} + +impl HeaderBar { + #[doc(alias = "adw_header_bar_new")] + pub fn new() -> HeaderBar { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_header_bar_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`HeaderBar`] objects. + /// + /// This method returns an instance of [`HeaderBarBuilder`](crate::builders::HeaderBarBuilder) which can be used to create [`HeaderBar`] objects. + pub fn builder() -> HeaderBarBuilder { + HeaderBarBuilder::new() + } + + #[doc(alias = "adw_header_bar_get_centering_policy")] + #[doc(alias = "get_centering_policy")] + pub fn centering_policy(&self) -> CenteringPolicy { + unsafe { + from_glib(ffi::adw_header_bar_get_centering_policy( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_header_bar_get_decoration_layout")] + #[doc(alias = "get_decoration_layout")] + pub fn decoration_layout(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_header_bar_get_decoration_layout( + self.to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_header_bar_get_show_back_button")] + #[doc(alias = "get_show_back_button")] + pub fn shows_back_button(&self) -> bool { + unsafe { + from_glib(ffi::adw_header_bar_get_show_back_button( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_header_bar_get_show_end_title_buttons")] + #[doc(alias = "get_show_end_title_buttons")] + pub fn shows_end_title_buttons(&self) -> bool { + unsafe { + from_glib(ffi::adw_header_bar_get_show_end_title_buttons( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_header_bar_get_show_start_title_buttons")] + #[doc(alias = "get_show_start_title_buttons")] + pub fn shows_start_title_buttons(&self) -> bool { + unsafe { + from_glib(ffi::adw_header_bar_get_show_start_title_buttons( + self.to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_header_bar_get_show_title")] + #[doc(alias = "get_show_title")] + pub fn shows_title(&self) -> bool { + unsafe { from_glib(ffi::adw_header_bar_get_show_title(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_header_bar_get_title_widget")] + #[doc(alias = "get_title_widget")] + pub fn title_widget(&self) -> Option { + unsafe { from_glib_none(ffi::adw_header_bar_get_title_widget(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_header_bar_pack_end")] + pub fn pack_end(&self, child: &impl IsA) { + unsafe { + ffi::adw_header_bar_pack_end(self.to_glib_none().0, child.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_header_bar_pack_start")] + pub fn pack_start(&self, child: &impl IsA) { + unsafe { + ffi::adw_header_bar_pack_start(self.to_glib_none().0, child.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_header_bar_remove")] + pub fn remove(&self, child: &impl IsA) { + unsafe { + ffi::adw_header_bar_remove(self.to_glib_none().0, child.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_header_bar_set_centering_policy")] + pub fn set_centering_policy(&self, centering_policy: CenteringPolicy) { + unsafe { + ffi::adw_header_bar_set_centering_policy( + self.to_glib_none().0, + centering_policy.into_glib(), + ); + } + } + + #[doc(alias = "adw_header_bar_set_decoration_layout")] + pub fn set_decoration_layout(&self, layout: Option<&str>) { + unsafe { + ffi::adw_header_bar_set_decoration_layout( + self.to_glib_none().0, + layout.to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_header_bar_set_show_back_button")] + pub fn set_show_back_button(&self, show_back_button: bool) { + unsafe { + ffi::adw_header_bar_set_show_back_button( + self.to_glib_none().0, + show_back_button.into_glib(), + ); + } + } + + #[doc(alias = "adw_header_bar_set_show_end_title_buttons")] + pub fn set_show_end_title_buttons(&self, setting: bool) { + unsafe { + ffi::adw_header_bar_set_show_end_title_buttons( + self.to_glib_none().0, + setting.into_glib(), + ); + } + } + + #[doc(alias = "adw_header_bar_set_show_start_title_buttons")] + pub fn set_show_start_title_buttons(&self, setting: bool) { + unsafe { + ffi::adw_header_bar_set_show_start_title_buttons( + self.to_glib_none().0, + setting.into_glib(), + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_header_bar_set_show_title")] + pub fn set_show_title(&self, show_title: bool) { + unsafe { + ffi::adw_header_bar_set_show_title(self.to_glib_none().0, show_title.into_glib()); + } + } + + #[doc(alias = "adw_header_bar_set_title_widget")] + pub fn set_title_widget(&self, title_widget: Option<&impl IsA>) { + unsafe { + ffi::adw_header_bar_set_title_widget( + self.to_glib_none().0, + title_widget.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "centering-policy")] + pub fn connect_centering_policy_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_centering_policy_trampoline( + this: *mut ffi::AdwHeaderBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::centering-policy\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_centering_policy_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "decoration-layout")] + pub fn connect_decoration_layout_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_decoration_layout_trampoline( + this: *mut ffi::AdwHeaderBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::decoration-layout\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_decoration_layout_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "show-back-button")] + pub fn connect_show_back_button_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_show_back_button_trampoline( + this: *mut ffi::AdwHeaderBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::show-back-button\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_show_back_button_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "show-end-title-buttons")] + pub fn connect_show_end_title_buttons_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_show_end_title_buttons_trampoline< + F: Fn(&HeaderBar) + 'static, + >( + this: *mut ffi::AdwHeaderBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::show-end-title-buttons\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_show_end_title_buttons_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "show-start-title-buttons")] + pub fn connect_show_start_title_buttons_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_show_start_title_buttons_trampoline< + F: Fn(&HeaderBar) + 'static, + >( + this: *mut ffi::AdwHeaderBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::show-start-title-buttons\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_show_start_title_buttons_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "show-title")] + pub fn connect_show_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_show_title_trampoline( + this: *mut ffi::AdwHeaderBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::show-title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_show_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "title-widget")] + pub fn connect_title_widget_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_widget_trampoline( + this: *mut ffi::AdwHeaderBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title-widget\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_widget_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for HeaderBar { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`HeaderBar`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct HeaderBarBuilder { + builder: glib::object::ObjectBuilder<'static, HeaderBar>, +} + +impl HeaderBarBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn centering_policy(self, centering_policy: CenteringPolicy) -> Self { + Self { + builder: self.builder.property("centering-policy", centering_policy), + } + } + + pub fn decoration_layout(self, decoration_layout: impl Into) -> Self { + Self { + builder: self + .builder + .property("decoration-layout", decoration_layout.into()), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn show_back_button(self, show_back_button: bool) -> Self { + Self { + builder: self.builder.property("show-back-button", show_back_button), + } + } + + pub fn show_end_title_buttons(self, show_end_title_buttons: bool) -> Self { + Self { + builder: self + .builder + .property("show-end-title-buttons", show_end_title_buttons), + } + } + + pub fn show_start_title_buttons(self, show_start_title_buttons: bool) -> Self { + Self { + builder: self + .builder + .property("show-start-title-buttons", show_start_title_buttons), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn show_title(self, show_title: bool) -> Self { + Self { + builder: self.builder.property("show-title", show_title), + } + } + + pub fn title_widget(self, title_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("title-widget", title_widget.clone().upcast()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`HeaderBar`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> HeaderBar { + self.builder.build() + } +} + +impl fmt::Display for HeaderBar { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("HeaderBar") + } +} diff --git a/libadwaita-0.4.4/src/auto/leaflet.rs b/libadwaita-0.4.4/src/auto/leaflet.rs new file mode 100644 index 0000000..251e264 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/leaflet.rs @@ -0,0 +1,950 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{ + FoldThresholdPolicy, LeafletPage, LeafletTransitionType, NavigationDirection, SpringParams, + Swipeable, +}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwLeaflet")] + pub struct Leaflet(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, Swipeable, gtk::Orientable; + + match fn { + type_ => || ffi::adw_leaflet_get_type(), + } +} + +impl Leaflet { + #[doc(alias = "adw_leaflet_new")] + pub fn new() -> Leaflet { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_leaflet_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`Leaflet`] objects. + /// + /// This method returns an instance of [`LeafletBuilder`](crate::builders::LeafletBuilder) which can be used to create [`Leaflet`] objects. + pub fn builder() -> LeafletBuilder { + LeafletBuilder::new() + } + + #[doc(alias = "adw_leaflet_append")] + pub fn append(&self, child: &impl IsA) -> LeafletPage { + unsafe { + from_glib_none(ffi::adw_leaflet_append( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_leaflet_get_adjacent_child")] + #[doc(alias = "get_adjacent_child")] + pub fn adjacent_child(&self, direction: NavigationDirection) -> Option { + unsafe { + from_glib_none(ffi::adw_leaflet_get_adjacent_child( + self.to_glib_none().0, + direction.into_glib(), + )) + } + } + + #[doc(alias = "adw_leaflet_get_can_navigate_back")] + #[doc(alias = "get_can_navigate_back")] + pub fn can_navigate_back(&self) -> bool { + unsafe { + from_glib(ffi::adw_leaflet_get_can_navigate_back( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_leaflet_get_can_navigate_forward")] + #[doc(alias = "get_can_navigate_forward")] + pub fn can_navigate_forward(&self) -> bool { + unsafe { + from_glib(ffi::adw_leaflet_get_can_navigate_forward( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_leaflet_get_can_unfold")] + #[doc(alias = "get_can_unfold")] + pub fn can_unfold(&self) -> bool { + unsafe { from_glib(ffi::adw_leaflet_get_can_unfold(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_leaflet_get_child_by_name")] + #[doc(alias = "get_child_by_name")] + pub fn child_by_name(&self, name: &str) -> Option { + unsafe { + from_glib_none(ffi::adw_leaflet_get_child_by_name( + self.to_glib_none().0, + name.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_leaflet_get_child_transition_params")] + #[doc(alias = "get_child_transition_params")] + pub fn child_transition_params(&self) -> SpringParams { + unsafe { + from_glib_full(ffi::adw_leaflet_get_child_transition_params( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_leaflet_get_child_transition_running")] + #[doc(alias = "get_child_transition_running")] + pub fn is_child_transition_running(&self) -> bool { + unsafe { + from_glib(ffi::adw_leaflet_get_child_transition_running( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_leaflet_get_fold_threshold_policy")] + #[doc(alias = "get_fold_threshold_policy")] + pub fn fold_threshold_policy(&self) -> FoldThresholdPolicy { + unsafe { + from_glib(ffi::adw_leaflet_get_fold_threshold_policy( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_leaflet_get_folded")] + #[doc(alias = "get_folded")] + pub fn is_folded(&self) -> bool { + unsafe { from_glib(ffi::adw_leaflet_get_folded(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_leaflet_get_homogeneous")] + #[doc(alias = "get_homogeneous")] + pub fn is_homogeneous(&self) -> bool { + unsafe { from_glib(ffi::adw_leaflet_get_homogeneous(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_leaflet_get_mode_transition_duration")] + #[doc(alias = "get_mode_transition_duration")] + pub fn mode_transition_duration(&self) -> u32 { + unsafe { ffi::adw_leaflet_get_mode_transition_duration(self.to_glib_none().0) } + } + + #[doc(alias = "adw_leaflet_get_page")] + #[doc(alias = "get_page")] + pub fn page(&self, child: &impl IsA) -> LeafletPage { + unsafe { + from_glib_none(ffi::adw_leaflet_get_page( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_leaflet_get_pages")] + #[doc(alias = "get_pages")] + pub fn pages(&self) -> gtk::SelectionModel { + unsafe { from_glib_full(ffi::adw_leaflet_get_pages(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_leaflet_get_transition_type")] + #[doc(alias = "get_transition_type")] + pub fn transition_type(&self) -> LeafletTransitionType { + unsafe { from_glib(ffi::adw_leaflet_get_transition_type(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_leaflet_get_visible_child")] + #[doc(alias = "get_visible_child")] + pub fn visible_child(&self) -> Option { + unsafe { from_glib_none(ffi::adw_leaflet_get_visible_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_leaflet_get_visible_child_name")] + #[doc(alias = "get_visible_child_name")] + pub fn visible_child_name(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_leaflet_get_visible_child_name( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_leaflet_insert_child_after")] + pub fn insert_child_after( + &self, + child: &impl IsA, + sibling: Option<&impl IsA>, + ) -> LeafletPage { + unsafe { + from_glib_none(ffi::adw_leaflet_insert_child_after( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + sibling.map(|p| p.as_ref()).to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_leaflet_navigate")] + pub fn navigate(&self, direction: NavigationDirection) -> bool { + unsafe { + from_glib(ffi::adw_leaflet_navigate( + self.to_glib_none().0, + direction.into_glib(), + )) + } + } + + #[doc(alias = "adw_leaflet_prepend")] + pub fn prepend(&self, child: &impl IsA) -> LeafletPage { + unsafe { + from_glib_none(ffi::adw_leaflet_prepend( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_leaflet_remove")] + pub fn remove(&self, child: &impl IsA) { + unsafe { + ffi::adw_leaflet_remove(self.to_glib_none().0, child.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_leaflet_reorder_child_after")] + pub fn reorder_child_after( + &self, + child: &impl IsA, + sibling: Option<&impl IsA>, + ) { + unsafe { + ffi::adw_leaflet_reorder_child_after( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + sibling.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_leaflet_set_can_navigate_back")] + pub fn set_can_navigate_back(&self, can_navigate_back: bool) { + unsafe { + ffi::adw_leaflet_set_can_navigate_back( + self.to_glib_none().0, + can_navigate_back.into_glib(), + ); + } + } + + #[doc(alias = "adw_leaflet_set_can_navigate_forward")] + pub fn set_can_navigate_forward(&self, can_navigate_forward: bool) { + unsafe { + ffi::adw_leaflet_set_can_navigate_forward( + self.to_glib_none().0, + can_navigate_forward.into_glib(), + ); + } + } + + #[doc(alias = "adw_leaflet_set_can_unfold")] + pub fn set_can_unfold(&self, can_unfold: bool) { + unsafe { + ffi::adw_leaflet_set_can_unfold(self.to_glib_none().0, can_unfold.into_glib()); + } + } + + #[doc(alias = "adw_leaflet_set_child_transition_params")] + pub fn set_child_transition_params(&self, params: &SpringParams) { + unsafe { + ffi::adw_leaflet_set_child_transition_params( + self.to_glib_none().0, + params.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_leaflet_set_fold_threshold_policy")] + pub fn set_fold_threshold_policy(&self, policy: FoldThresholdPolicy) { + unsafe { + ffi::adw_leaflet_set_fold_threshold_policy(self.to_glib_none().0, policy.into_glib()); + } + } + + #[doc(alias = "adw_leaflet_set_homogeneous")] + pub fn set_homogeneous(&self, homogeneous: bool) { + unsafe { + ffi::adw_leaflet_set_homogeneous(self.to_glib_none().0, homogeneous.into_glib()); + } + } + + #[doc(alias = "adw_leaflet_set_mode_transition_duration")] + pub fn set_mode_transition_duration(&self, duration: u32) { + unsafe { + ffi::adw_leaflet_set_mode_transition_duration(self.to_glib_none().0, duration); + } + } + + #[doc(alias = "adw_leaflet_set_transition_type")] + pub fn set_transition_type(&self, transition: LeafletTransitionType) { + unsafe { + ffi::adw_leaflet_set_transition_type(self.to_glib_none().0, transition.into_glib()); + } + } + + #[doc(alias = "adw_leaflet_set_visible_child")] + pub fn set_visible_child(&self, visible_child: &impl IsA) { + unsafe { + ffi::adw_leaflet_set_visible_child( + self.to_glib_none().0, + visible_child.as_ref().to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_leaflet_set_visible_child_name")] + pub fn set_visible_child_name(&self, name: &str) { + unsafe { + ffi::adw_leaflet_set_visible_child_name(self.to_glib_none().0, name.to_glib_none().0); + } + } + + #[doc(alias = "can-navigate-back")] + pub fn connect_can_navigate_back_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_can_navigate_back_trampoline( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::can-navigate-back\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_can_navigate_back_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "can-navigate-forward")] + pub fn connect_can_navigate_forward_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_can_navigate_forward_trampoline( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::can-navigate-forward\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_can_navigate_forward_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "can-unfold")] + pub fn connect_can_unfold_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_can_unfold_trampoline( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::can-unfold\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_can_unfold_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "child-transition-params")] + pub fn connect_child_transition_params_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_child_transition_params_trampoline< + F: Fn(&Leaflet) + 'static, + >( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::child-transition-params\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_child_transition_params_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "child-transition-running")] + pub fn connect_child_transition_running_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_child_transition_running_trampoline< + F: Fn(&Leaflet) + 'static, + >( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::child-transition-running\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_child_transition_running_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "fold-threshold-policy")] + pub fn connect_fold_threshold_policy_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_fold_threshold_policy_trampoline( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::fold-threshold-policy\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_fold_threshold_policy_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "folded")] + pub fn connect_folded_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_folded_trampoline( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::folded\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_folded_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "homogeneous")] + pub fn connect_homogeneous_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_homogeneous_trampoline( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::homogeneous\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_homogeneous_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "mode-transition-duration")] + pub fn connect_mode_transition_duration_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_mode_transition_duration_trampoline< + F: Fn(&Leaflet) + 'static, + >( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::mode-transition-duration\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_mode_transition_duration_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "pages")] + pub fn connect_pages_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_pages_trampoline( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::pages\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_pages_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "transition-type")] + pub fn connect_transition_type_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_transition_type_trampoline( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::transition-type\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_transition_type_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "visible-child")] + pub fn connect_visible_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_visible_child_trampoline( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::visible-child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_visible_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "visible-child-name")] + pub fn connect_visible_child_name_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_visible_child_name_trampoline( + this: *mut ffi::AdwLeaflet, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::visible-child-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_visible_child_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for Leaflet { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`Leaflet`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct LeafletBuilder { + builder: glib::object::ObjectBuilder<'static, Leaflet>, +} + +impl LeafletBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn can_navigate_back(self, can_navigate_back: bool) -> Self { + Self { + builder: self + .builder + .property("can-navigate-back", can_navigate_back), + } + } + + pub fn can_navigate_forward(self, can_navigate_forward: bool) -> Self { + Self { + builder: self + .builder + .property("can-navigate-forward", can_navigate_forward), + } + } + + pub fn can_unfold(self, can_unfold: bool) -> Self { + Self { + builder: self.builder.property("can-unfold", can_unfold), + } + } + + pub fn child_transition_params(self, child_transition_params: &SpringParams) -> Self { + Self { + builder: self + .builder + .property("child-transition-params", child_transition_params.clone()), + } + } + + pub fn fold_threshold_policy(self, fold_threshold_policy: FoldThresholdPolicy) -> Self { + Self { + builder: self + .builder + .property("fold-threshold-policy", fold_threshold_policy), + } + } + + pub fn homogeneous(self, homogeneous: bool) -> Self { + Self { + builder: self.builder.property("homogeneous", homogeneous), + } + } + + pub fn mode_transition_duration(self, mode_transition_duration: u32) -> Self { + Self { + builder: self + .builder + .property("mode-transition-duration", mode_transition_duration), + } + } + + pub fn transition_type(self, transition_type: LeafletTransitionType) -> Self { + Self { + builder: self.builder.property("transition-type", transition_type), + } + } + + pub fn visible_child(self, visible_child: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("visible-child", visible_child.clone().upcast()), + } + } + + pub fn visible_child_name(self, visible_child_name: impl Into) -> Self { + Self { + builder: self + .builder + .property("visible-child-name", visible_child_name.into()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn orientation(self, orientation: gtk::Orientation) -> Self { + Self { + builder: self.builder.property("orientation", orientation), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`Leaflet`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> Leaflet { + self.builder.build() + } +} + +impl fmt::Display for Leaflet { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Leaflet") + } +} diff --git a/libadwaita-0.4.4/src/auto/leaflet_page.rs b/libadwaita-0.4.4/src/auto/leaflet_page.rs new file mode 100644 index 0000000..4cce613 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/leaflet_page.rs @@ -0,0 +1,106 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwLeafletPage")] + pub struct LeafletPage(Object); + + match fn { + type_ => || ffi::adw_leaflet_page_get_type(), + } +} + +impl LeafletPage { + #[doc(alias = "adw_leaflet_page_get_child")] + #[doc(alias = "get_child")] + pub fn child(&self) -> gtk::Widget { + unsafe { from_glib_none(ffi::adw_leaflet_page_get_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_leaflet_page_get_name")] + #[doc(alias = "get_name")] + pub fn name(&self) -> Option { + unsafe { from_glib_none(ffi::adw_leaflet_page_get_name(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_leaflet_page_get_navigatable")] + #[doc(alias = "get_navigatable")] + pub fn is_navigatable(&self) -> bool { + unsafe { from_glib(ffi::adw_leaflet_page_get_navigatable(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_leaflet_page_set_name")] + pub fn set_name(&self, name: Option<&str>) { + unsafe { + ffi::adw_leaflet_page_set_name(self.to_glib_none().0, name.to_glib_none().0); + } + } + + #[doc(alias = "adw_leaflet_page_set_navigatable")] + pub fn set_navigatable(&self, navigatable: bool) { + unsafe { + ffi::adw_leaflet_page_set_navigatable(self.to_glib_none().0, navigatable.into_glib()); + } + } + + #[doc(alias = "name")] + pub fn connect_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_name_trampoline( + this: *mut ffi::AdwLeafletPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "navigatable")] + pub fn connect_navigatable_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_navigatable_trampoline( + this: *mut ffi::AdwLeafletPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::navigatable\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_navigatable_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for LeafletPage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("LeafletPage") + } +} diff --git a/libadwaita-0.4.4/src/auto/message_dialog.rs b/libadwaita-0.4.4/src/auto/message_dialog.rs new file mode 100644 index 0000000..9080585 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/message_dialog.rs @@ -0,0 +1,1025 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::ResponseAppearance; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwMessageDialog")] + pub struct MessageDialog(Object) @extends gtk::Window, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager; + + match fn { + type_ => || ffi::adw_message_dialog_get_type(), + } +} + +impl MessageDialog { + pub const NONE: Option<&'static MessageDialog> = None; + + #[doc(alias = "adw_message_dialog_new")] + pub fn new( + parent: Option<&impl IsA>, + heading: Option<&str>, + body: Option<&str>, + ) -> MessageDialog { + assert_initialized_main_thread!(); + unsafe { + gtk::Widget::from_glib_none(ffi::adw_message_dialog_new( + parent.map(|p| p.as_ref()).to_glib_none().0, + heading.to_glib_none().0, + body.to_glib_none().0, + )) + .unsafe_cast() + } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`MessageDialog`] objects. + /// + /// This method returns an instance of [`MessageDialogBuilder`](crate::builders::MessageDialogBuilder) which can be used to create [`MessageDialog`] objects. + pub fn builder() -> MessageDialogBuilder { + MessageDialogBuilder::new() + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl Default for MessageDialog { + fn default() -> Self { + glib::object::Object::new::() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`MessageDialog`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct MessageDialogBuilder { + builder: glib::object::ObjectBuilder<'static, MessageDialog>, +} + +impl MessageDialogBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn body(self, body: impl Into) -> Self { + Self { + builder: self.builder.property("body", body.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn body_use_markup(self, body_use_markup: bool) -> Self { + Self { + builder: self.builder.property("body-use-markup", body_use_markup), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn close_response(self, close_response: impl Into) -> Self { + Self { + builder: self + .builder + .property("close-response", close_response.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn default_response(self, default_response: impl Into) -> Self { + Self { + builder: self + .builder + .property("default-response", default_response.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn extra_child(self, extra_child: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("extra-child", extra_child.clone().upcast()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn heading(self, heading: impl Into) -> Self { + Self { + builder: self.builder.property("heading", heading.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn heading_use_markup(self, heading_use_markup: bool) -> Self { + Self { + builder: self + .builder + .property("heading-use-markup", heading_use_markup), + } + } + + pub fn application(self, application: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("application", application.clone().upcast()), + } + } + + pub fn decorated(self, decorated: bool) -> Self { + Self { + builder: self.builder.property("decorated", decorated), + } + } + + pub fn default_height(self, default_height: i32) -> Self { + Self { + builder: self.builder.property("default-height", default_height), + } + } + + pub fn default_widget(self, default_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("default-widget", default_widget.clone().upcast()), + } + } + + pub fn default_width(self, default_width: i32) -> Self { + Self { + builder: self.builder.property("default-width", default_width), + } + } + + pub fn deletable(self, deletable: bool) -> Self { + Self { + builder: self.builder.property("deletable", deletable), + } + } + + pub fn destroy_with_parent(self, destroy_with_parent: bool) -> Self { + Self { + builder: self + .builder + .property("destroy-with-parent", destroy_with_parent), + } + } + + pub fn display(self, display: &gdk::Display) -> Self { + Self { + builder: self.builder.property("display", display.clone()), + } + } + + pub fn focus_visible(self, focus_visible: bool) -> Self { + Self { + builder: self.builder.property("focus-visible", focus_visible), + } + } + + pub fn focus_widget(self, focus_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("focus-widget", focus_widget.clone().upcast()), + } + } + + pub fn fullscreened(self, fullscreened: bool) -> Self { + Self { + builder: self.builder.property("fullscreened", fullscreened), + } + } + + #[cfg(any(feature = "gtk_v4_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "gtk_v4_2")))] + pub fn handle_menubar_accel(self, handle_menubar_accel: bool) -> Self { + Self { + builder: self + .builder + .property("handle-menubar-accel", handle_menubar_accel), + } + } + + pub fn hide_on_close(self, hide_on_close: bool) -> Self { + Self { + builder: self.builder.property("hide-on-close", hide_on_close), + } + } + + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn maximized(self, maximized: bool) -> Self { + Self { + builder: self.builder.property("maximized", maximized), + } + } + + pub fn mnemonics_visible(self, mnemonics_visible: bool) -> Self { + Self { + builder: self + .builder + .property("mnemonics-visible", mnemonics_visible), + } + } + + pub fn modal(self, modal: bool) -> Self { + Self { + builder: self.builder.property("modal", modal), + } + } + + pub fn resizable(self, resizable: bool) -> Self { + Self { + builder: self.builder.property("resizable", resizable), + } + } + + pub fn startup_id(self, startup_id: impl Into) -> Self { + Self { + builder: self.builder.property("startup-id", startup_id.into()), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "gtk_v4_6", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "gtk_v4_6")))] + pub fn titlebar(self, titlebar: &impl IsA) -> Self { + Self { + builder: self.builder.property("titlebar", titlebar.clone().upcast()), + } + } + + pub fn transient_for(self, transient_for: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("transient-for", transient_for.clone().upcast()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`MessageDialog`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> MessageDialog { + self.builder.build() + } +} + +pub trait MessageDialogExt: 'static { + #[doc(alias = "adw_message_dialog_add_response")] + fn add_response(&self, id: &str, label: &str); + + #[doc(alias = "adw_message_dialog_get_body")] + #[doc(alias = "get_body")] + fn body(&self) -> glib::GString; + + #[doc(alias = "adw_message_dialog_get_body_use_markup")] + #[doc(alias = "get_body_use_markup")] + fn is_body_use_markup(&self) -> bool; + + #[doc(alias = "adw_message_dialog_get_close_response")] + #[doc(alias = "get_close_response")] + fn close_response(&self) -> glib::GString; + + #[doc(alias = "adw_message_dialog_get_default_response")] + #[doc(alias = "get_default_response")] + fn default_response(&self) -> Option; + + #[doc(alias = "adw_message_dialog_get_extra_child")] + #[doc(alias = "get_extra_child")] + fn extra_child(&self) -> Option; + + #[doc(alias = "adw_message_dialog_get_heading")] + #[doc(alias = "get_heading")] + fn heading(&self) -> Option; + + #[doc(alias = "adw_message_dialog_get_heading_use_markup")] + #[doc(alias = "get_heading_use_markup")] + fn is_heading_use_markup(&self) -> bool; + + #[doc(alias = "adw_message_dialog_get_response_appearance")] + #[doc(alias = "get_response_appearance")] + fn response_appearance(&self, response: &str) -> ResponseAppearance; + + #[doc(alias = "adw_message_dialog_get_response_enabled")] + #[doc(alias = "get_response_enabled")] + fn is_response_enabled(&self, response: &str) -> bool; + + #[doc(alias = "adw_message_dialog_has_response")] + fn has_response(&self, response: &str) -> bool; + + #[doc(alias = "adw_message_dialog_response")] + fn response(&self, response: &str); + + #[doc(alias = "adw_message_dialog_set_body")] + fn set_body(&self, body: &str); + + #[doc(alias = "adw_message_dialog_set_body_use_markup")] + fn set_body_use_markup(&self, use_markup: bool); + + #[doc(alias = "adw_message_dialog_set_close_response")] + fn set_close_response(&self, response: &str); + + #[doc(alias = "adw_message_dialog_set_default_response")] + fn set_default_response(&self, response: Option<&str>); + + #[doc(alias = "adw_message_dialog_set_extra_child")] + fn set_extra_child(&self, child: Option<&impl IsA>); + + #[doc(alias = "adw_message_dialog_set_heading")] + fn set_heading(&self, heading: Option<&str>); + + #[doc(alias = "adw_message_dialog_set_heading_use_markup")] + fn set_heading_use_markup(&self, use_markup: bool); + + #[doc(alias = "adw_message_dialog_set_response_appearance")] + fn set_response_appearance(&self, response: &str, appearance: ResponseAppearance); + + #[doc(alias = "adw_message_dialog_set_response_enabled")] + fn set_response_enabled(&self, response: &str, enabled: bool); + + #[doc(alias = "adw_message_dialog_set_response_label")] + fn set_response_label(&self, response: &str, label: &str); + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "response")] + fn connect_response( + &self, + detail: Option<&str>, + f: F, + ) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "body")] + fn connect_body_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "body-use-markup")] + fn connect_body_use_markup_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "close-response")] + fn connect_close_response_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "default-response")] + fn connect_default_response_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "extra-child")] + fn connect_extra_child_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "heading")] + fn connect_heading_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "heading-use-markup")] + fn connect_heading_use_markup_notify(&self, f: F) -> SignalHandlerId; +} + +impl> MessageDialogExt for O { + fn add_response(&self, id: &str, label: &str) { + unsafe { + ffi::adw_message_dialog_add_response( + self.as_ref().to_glib_none().0, + id.to_glib_none().0, + label.to_glib_none().0, + ); + } + } + + fn body(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_message_dialog_get_body( + self.as_ref().to_glib_none().0, + )) + } + } + + fn is_body_use_markup(&self) -> bool { + unsafe { + from_glib(ffi::adw_message_dialog_get_body_use_markup( + self.as_ref().to_glib_none().0, + )) + } + } + + fn close_response(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_message_dialog_get_close_response( + self.as_ref().to_glib_none().0, + )) + } + } + + fn default_response(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_message_dialog_get_default_response( + self.as_ref().to_glib_none().0, + )) + } + } + + fn extra_child(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_message_dialog_get_extra_child( + self.as_ref().to_glib_none().0, + )) + } + } + + fn heading(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_message_dialog_get_heading( + self.as_ref().to_glib_none().0, + )) + } + } + + fn is_heading_use_markup(&self) -> bool { + unsafe { + from_glib(ffi::adw_message_dialog_get_heading_use_markup( + self.as_ref().to_glib_none().0, + )) + } + } + + fn response_appearance(&self, response: &str) -> ResponseAppearance { + unsafe { + from_glib(ffi::adw_message_dialog_get_response_appearance( + self.as_ref().to_glib_none().0, + response.to_glib_none().0, + )) + } + } + + fn is_response_enabled(&self, response: &str) -> bool { + unsafe { + from_glib(ffi::adw_message_dialog_get_response_enabled( + self.as_ref().to_glib_none().0, + response.to_glib_none().0, + )) + } + } + + fn has_response(&self, response: &str) -> bool { + unsafe { + from_glib(ffi::adw_message_dialog_has_response( + self.as_ref().to_glib_none().0, + response.to_glib_none().0, + )) + } + } + + fn response(&self, response: &str) { + unsafe { + ffi::adw_message_dialog_response( + self.as_ref().to_glib_none().0, + response.to_glib_none().0, + ); + } + } + + fn set_body(&self, body: &str) { + unsafe { + ffi::adw_message_dialog_set_body(self.as_ref().to_glib_none().0, body.to_glib_none().0); + } + } + + fn set_body_use_markup(&self, use_markup: bool) { + unsafe { + ffi::adw_message_dialog_set_body_use_markup( + self.as_ref().to_glib_none().0, + use_markup.into_glib(), + ); + } + } + + fn set_close_response(&self, response: &str) { + unsafe { + ffi::adw_message_dialog_set_close_response( + self.as_ref().to_glib_none().0, + response.to_glib_none().0, + ); + } + } + + fn set_default_response(&self, response: Option<&str>) { + unsafe { + ffi::adw_message_dialog_set_default_response( + self.as_ref().to_glib_none().0, + response.to_glib_none().0, + ); + } + } + + fn set_extra_child(&self, child: Option<&impl IsA>) { + unsafe { + ffi::adw_message_dialog_set_extra_child( + self.as_ref().to_glib_none().0, + child.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + fn set_heading(&self, heading: Option<&str>) { + unsafe { + ffi::adw_message_dialog_set_heading( + self.as_ref().to_glib_none().0, + heading.to_glib_none().0, + ); + } + } + + fn set_heading_use_markup(&self, use_markup: bool) { + unsafe { + ffi::adw_message_dialog_set_heading_use_markup( + self.as_ref().to_glib_none().0, + use_markup.into_glib(), + ); + } + } + + fn set_response_appearance(&self, response: &str, appearance: ResponseAppearance) { + unsafe { + ffi::adw_message_dialog_set_response_appearance( + self.as_ref().to_glib_none().0, + response.to_glib_none().0, + appearance.into_glib(), + ); + } + } + + fn set_response_enabled(&self, response: &str, enabled: bool) { + unsafe { + ffi::adw_message_dialog_set_response_enabled( + self.as_ref().to_glib_none().0, + response.to_glib_none().0, + enabled.into_glib(), + ); + } + } + + fn set_response_label(&self, response: &str, label: &str) { + unsafe { + ffi::adw_message_dialog_set_response_label( + self.as_ref().to_glib_none().0, + response.to_glib_none().0, + label.to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_response( + &self, + detail: Option<&str>, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn response_trampoline< + P: IsA, + F: Fn(&P, &str) + 'static, + >( + this: *mut ffi::AdwMessageDialog, + response: *mut libc::c_char, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f( + MessageDialog::from_glib_borrow(this).unsafe_cast_ref(), + &glib::GString::from_glib_borrow(response), + ) + } + unsafe { + let f: Box_ = Box_::new(f); + let detailed_signal_name = detail.map(|name| format!("response::{name}\0")); + let signal_name: &[u8] = detailed_signal_name + .as_ref() + .map_or(&b"response\0"[..], |n| n.as_bytes()); + connect_raw( + self.as_ptr() as *mut _, + signal_name.as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + response_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_body_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_body_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwMessageDialog, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(MessageDialog::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::body\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_body_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_body_use_markup_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_body_use_markup_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwMessageDialog, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(MessageDialog::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::body-use-markup\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_body_use_markup_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_close_response_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_close_response_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwMessageDialog, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(MessageDialog::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::close-response\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_close_response_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_default_response_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_default_response_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwMessageDialog, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(MessageDialog::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::default-response\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_default_response_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_extra_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_extra_child_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwMessageDialog, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(MessageDialog::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::extra-child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_extra_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_heading_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_heading_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwMessageDialog, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(MessageDialog::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::heading\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_heading_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_heading_use_markup_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_heading_use_markup_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwMessageDialog, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(MessageDialog::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::heading-use-markup\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_heading_use_markup_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for MessageDialog { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("MessageDialog") + } +} diff --git a/libadwaita-0.4.4/src/auto/mod.rs b/libadwaita-0.4.4/src/auto/mod.rs new file mode 100644 index 0000000..65d6b5d --- /dev/null +++ b/libadwaita-0.4.4/src/auto/mod.rs @@ -0,0 +1,426 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +mod about_window; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +pub use self::about_window::AboutWindow; + +mod action_row; +pub use self::action_row::ActionRow; + +mod animation; +pub use self::animation::Animation; + +mod animation_target; +pub use self::animation_target::AnimationTarget; + +mod application; +pub use self::application::Application; + +mod application_window; +pub use self::application_window::ApplicationWindow; + +mod avatar; +pub use self::avatar::Avatar; + +#[cfg(any(feature = "v1_3", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] +mod banner; +#[cfg(any(feature = "v1_3", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] +pub use self::banner::Banner; + +mod bin; +pub use self::bin::Bin; + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +mod breakpoint; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::breakpoint::Breakpoint; + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +mod breakpoint_bin; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::breakpoint_bin::BreakpointBin; + +mod button_content; +pub use self::button_content::ButtonContent; + +mod callback_animation_target; +pub use self::callback_animation_target::CallbackAnimationTarget; + +mod carousel; +pub use self::carousel::Carousel; + +mod carousel_indicator_dots; +pub use self::carousel_indicator_dots::CarouselIndicatorDots; + +mod carousel_indicator_lines; +pub use self::carousel_indicator_lines::CarouselIndicatorLines; + +mod clamp; +pub use self::clamp::Clamp; + +mod clamp_layout; +pub use self::clamp_layout::ClampLayout; + +mod clamp_scrollable; +pub use self::clamp_scrollable::ClampScrollable; + +mod combo_row; +pub use self::combo_row::ComboRow; + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +mod entry_row; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +pub use self::entry_row::EntryRow; + +mod enum_list_item; +pub use self::enum_list_item::EnumListItem; + +mod enum_list_model; +pub use self::enum_list_model::EnumListModel; + +mod expander_row; +pub use self::expander_row::ExpanderRow; + +mod flap; +pub use self::flap::Flap; + +mod header_bar; +pub use self::header_bar::HeaderBar; + +mod leaflet; +pub use self::leaflet::Leaflet; + +mod leaflet_page; +pub use self::leaflet_page::LeafletPage; + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +mod message_dialog; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +pub use self::message_dialog::MessageDialog; + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +mod navigation_page; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::navigation_page::NavigationPage; + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +mod navigation_split_view; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::navigation_split_view::NavigationSplitView; + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +mod navigation_view; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::navigation_view::NavigationView; + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +mod overlay_split_view; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::overlay_split_view::OverlaySplitView; + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +mod password_entry_row; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +pub use self::password_entry_row::PasswordEntryRow; + +mod preferences_group; +pub use self::preferences_group::PreferencesGroup; + +mod preferences_page; +pub use self::preferences_page::PreferencesPage; + +mod preferences_row; +pub use self::preferences_row::PreferencesRow; + +mod preferences_window; +pub use self::preferences_window::PreferencesWindow; + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +mod property_animation_target; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +pub use self::property_animation_target::PropertyAnimationTarget; + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +mod spin_row; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::spin_row::SpinRow; + +mod split_button; +pub use self::split_button::SplitButton; + +mod spring_animation; +pub use self::spring_animation::SpringAnimation; + +mod squeezer; +pub use self::squeezer::Squeezer; + +mod squeezer_page; +pub use self::squeezer_page::SqueezerPage; + +mod status_page; +pub use self::status_page::StatusPage; + +mod style_manager; +pub use self::style_manager::StyleManager; + +mod swipe_tracker; +pub use self::swipe_tracker::SwipeTracker; + +mod swipeable; +pub use self::swipeable::Swipeable; + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +mod switch_row; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::switch_row::SwitchRow; + +mod tab_bar; +pub use self::tab_bar::TabBar; + +#[cfg(any(feature = "v1_3", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] +mod tab_button; +#[cfg(any(feature = "v1_3", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] +pub use self::tab_button::TabButton; + +#[cfg(any(feature = "v1_3", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] +mod tab_overview; +#[cfg(any(feature = "v1_3", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] +pub use self::tab_overview::TabOverview; + +mod tab_page; +pub use self::tab_page::TabPage; + +mod tab_view; +pub use self::tab_view::TabView; + +mod timed_animation; +pub use self::timed_animation::TimedAnimation; + +mod toast; +pub use self::toast::Toast; + +mod toast_overlay; +pub use self::toast_overlay::ToastOverlay; + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +mod toolbar_view; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::toolbar_view::ToolbarView; + +mod view_stack; +pub use self::view_stack::ViewStack; + +mod view_stack_page; +pub use self::view_stack_page::ViewStackPage; + +mod view_switcher; +pub use self::view_switcher::ViewSwitcher; + +mod view_switcher_bar; +pub use self::view_switcher_bar::ViewSwitcherBar; + +mod view_switcher_title; +pub use self::view_switcher_title::ViewSwitcherTitle; + +mod window; +pub use self::window::Window; + +mod window_title; +pub use self::window_title::WindowTitle; + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +mod breakpoint_condition; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::breakpoint_condition::BreakpointCondition; + +mod spring_params; +pub use self::spring_params::SpringParams; + +mod enums; +pub use self::enums::AnimationState; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::enums::BreakpointConditionLengthType; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::enums::BreakpointConditionRatioType; +pub use self::enums::CenteringPolicy; +pub use self::enums::ColorScheme; +pub use self::enums::Easing; +pub use self::enums::FlapFoldPolicy; +pub use self::enums::FlapTransitionType; +pub use self::enums::FoldThresholdPolicy; +pub use self::enums::LeafletTransitionType; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::enums::LengthUnit; +pub use self::enums::NavigationDirection; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +pub use self::enums::ResponseAppearance; +pub use self::enums::SqueezerTransitionType; +pub use self::enums::ToastPriority; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub use self::enums::ToolbarStyle; +pub use self::enums::ViewSwitcherPolicy; + +mod flags; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +pub use self::flags::TabViewShortcuts; + +pub mod functions; + +#[doc(hidden)] +pub mod traits { + pub use super::action_row::ActionRowExt; + pub use super::animation::AnimationExt; + pub use super::application::AdwApplicationExt; + pub use super::application_window::AdwApplicationWindowExt; + pub use super::bin::BinExt; + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub use super::breakpoint_bin::BreakpointBinExt; + pub use super::combo_row::ComboRowExt; + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub use super::entry_row::EntryRowExt; + pub use super::expander_row::ExpanderRowExt; + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub use super::message_dialog::MessageDialogExt; + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub use super::navigation_page::NavigationPageExt; + pub use super::preferences_group::PreferencesGroupExt; + pub use super::preferences_page::PreferencesPageExt; + pub use super::preferences_row::PreferencesRowExt; + pub use super::preferences_window::PreferencesWindowExt; + pub use super::swipeable::SwipeableExt; + pub use super::window::AdwWindowExt; +} +#[doc(hidden)] +pub mod builders { + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub use super::about_window::AboutWindowBuilder; + pub use super::action_row::ActionRowBuilder; + pub use super::application::ApplicationBuilder; + pub use super::application_window::ApplicationWindowBuilder; + pub use super::avatar::AvatarBuilder; + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub use super::banner::BannerBuilder; + pub use super::bin::BinBuilder; + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub use super::breakpoint_bin::BreakpointBinBuilder; + pub use super::button_content::ButtonContentBuilder; + pub use super::carousel::CarouselBuilder; + pub use super::carousel_indicator_dots::CarouselIndicatorDotsBuilder; + pub use super::carousel_indicator_lines::CarouselIndicatorLinesBuilder; + pub use super::clamp::ClampBuilder; + pub use super::clamp_layout::ClampLayoutBuilder; + pub use super::clamp_scrollable::ClampScrollableBuilder; + pub use super::combo_row::ComboRowBuilder; + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub use super::entry_row::EntryRowBuilder; + pub use super::expander_row::ExpanderRowBuilder; + pub use super::flap::FlapBuilder; + pub use super::header_bar::HeaderBarBuilder; + pub use super::leaflet::LeafletBuilder; + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub use super::message_dialog::MessageDialogBuilder; + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub use super::navigation_page::NavigationPageBuilder; + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub use super::navigation_split_view::NavigationSplitViewBuilder; + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub use super::navigation_view::NavigationViewBuilder; + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub use super::overlay_split_view::OverlaySplitViewBuilder; + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub use super::password_entry_row::PasswordEntryRowBuilder; + pub use super::preferences_group::PreferencesGroupBuilder; + pub use super::preferences_page::PreferencesPageBuilder; + pub use super::preferences_row::PreferencesRowBuilder; + pub use super::preferences_window::PreferencesWindowBuilder; + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub use super::spin_row::SpinRowBuilder; + pub use super::split_button::SplitButtonBuilder; + pub use super::spring_animation::SpringAnimationBuilder; + pub use super::squeezer::SqueezerBuilder; + pub use super::status_page::StatusPageBuilder; + pub use super::swipe_tracker::SwipeTrackerBuilder; + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub use super::switch_row::SwitchRowBuilder; + pub use super::tab_bar::TabBarBuilder; + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub use super::tab_button::TabButtonBuilder; + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub use super::tab_overview::TabOverviewBuilder; + pub use super::tab_view::TabViewBuilder; + pub use super::timed_animation::TimedAnimationBuilder; + pub use super::toast::ToastBuilder; + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub use super::toolbar_view::ToolbarViewBuilder; + pub use super::view_stack::ViewStackBuilder; + pub use super::view_switcher::ViewSwitcherBuilder; + pub use super::view_switcher_bar::ViewSwitcherBarBuilder; + pub use super::view_switcher_title::ViewSwitcherTitleBuilder; + pub use super::window::WindowBuilder; + pub use super::window_title::WindowTitleBuilder; +} diff --git a/libadwaita-0.4.4/src/auto/navigation_page.rs b/libadwaita-0.4.4/src/auto/navigation_page.rs new file mode 100644 index 0000000..cabe857 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/navigation_page.rs @@ -0,0 +1,644 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwNavigationPage")] + pub struct NavigationPage(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_navigation_page_get_type(), + } +} + +impl NavigationPage { + pub const NONE: Option<&'static NavigationPage> = None; + + #[doc(alias = "adw_navigation_page_new")] + pub fn new(child: &impl IsA, title: &str) -> NavigationPage { + assert_initialized_main_thread!(); + unsafe { + from_glib_none(ffi::adw_navigation_page_new( + child.as_ref().to_glib_none().0, + title.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_page_new_with_tag")] + #[doc(alias = "new_with_tag")] + pub fn with_tag(child: &impl IsA, title: &str, tag: &str) -> NavigationPage { + assert_initialized_main_thread!(); + unsafe { + from_glib_none(ffi::adw_navigation_page_new_with_tag( + child.as_ref().to_glib_none().0, + title.to_glib_none().0, + tag.to_glib_none().0, + )) + } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`NavigationPage`] objects. + /// + /// This method returns an instance of [`NavigationPageBuilder`](crate::builders::NavigationPageBuilder) which can be used to create [`NavigationPage`] objects. + pub fn builder() -> NavigationPageBuilder { + NavigationPageBuilder::new() + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl Default for NavigationPage { + fn default() -> Self { + glib::object::Object::new::() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`NavigationPage`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct NavigationPageBuilder { + builder: glib::object::ObjectBuilder<'static, NavigationPage>, +} + +impl NavigationPageBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn can_pop(self, can_pop: bool) -> Self { + Self { + builder: self.builder.property("can-pop", can_pop), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn tag(self, tag: impl Into) -> Self { + Self { + builder: self.builder.property("tag", tag.into()), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`NavigationPage`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> NavigationPage { + self.builder.build() + } +} + +pub trait NavigationPageExt: 'static { + #[doc(alias = "adw_navigation_page_get_can_pop")] + #[doc(alias = "get_can_pop")] + fn can_pop(&self) -> bool; + + #[doc(alias = "adw_navigation_page_get_child")] + #[doc(alias = "get_child")] + fn child(&self) -> Option; + + #[doc(alias = "adw_navigation_page_get_tag")] + #[doc(alias = "get_tag")] + fn tag(&self) -> Option; + + #[doc(alias = "adw_navigation_page_get_title")] + #[doc(alias = "get_title")] + fn title(&self) -> glib::GString; + + #[doc(alias = "adw_navigation_page_set_can_pop")] + fn set_can_pop(&self, can_pop: bool); + + #[doc(alias = "adw_navigation_page_set_child")] + fn set_child(&self, child: Option<&impl IsA>); + + #[doc(alias = "adw_navigation_page_set_tag")] + fn set_tag(&self, tag: Option<&str>); + + #[doc(alias = "adw_navigation_page_set_title")] + fn set_title(&self, title: &str); + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "hidden")] + fn connect_hidden(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "hiding")] + fn connect_hiding(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "showing")] + fn connect_showing(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "shown")] + fn connect_shown(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "can-pop")] + fn connect_can_pop_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "child")] + fn connect_child_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "tag")] + fn connect_tag_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "title")] + fn connect_title_notify(&self, f: F) -> SignalHandlerId; +} + +impl> NavigationPageExt for O { + fn can_pop(&self) -> bool { + unsafe { + from_glib(ffi::adw_navigation_page_get_can_pop( + self.as_ref().to_glib_none().0, + )) + } + } + + fn child(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_navigation_page_get_child( + self.as_ref().to_glib_none().0, + )) + } + } + + fn tag(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_navigation_page_get_tag( + self.as_ref().to_glib_none().0, + )) + } + } + + fn title(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_navigation_page_get_title( + self.as_ref().to_glib_none().0, + )) + } + } + + fn set_can_pop(&self, can_pop: bool) { + unsafe { + ffi::adw_navigation_page_set_can_pop( + self.as_ref().to_glib_none().0, + can_pop.into_glib(), + ); + } + } + + fn set_child(&self, child: Option<&impl IsA>) { + unsafe { + ffi::adw_navigation_page_set_child( + self.as_ref().to_glib_none().0, + child.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + fn set_tag(&self, tag: Option<&str>) { + unsafe { + ffi::adw_navigation_page_set_tag(self.as_ref().to_glib_none().0, tag.to_glib_none().0); + } + } + + fn set_title(&self, title: &str) { + unsafe { + ffi::adw_navigation_page_set_title( + self.as_ref().to_glib_none().0, + title.to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_hidden(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn hidden_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwNavigationPage, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(NavigationPage::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"hidden\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + hidden_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_hiding(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn hiding_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwNavigationPage, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(NavigationPage::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"hiding\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + hiding_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_showing(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn showing_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwNavigationPage, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(NavigationPage::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"showing\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + showing_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_shown(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn shown_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwNavigationPage, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(NavigationPage::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"shown\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + shown_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_can_pop_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_can_pop_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwNavigationPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(NavigationPage::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::can-pop\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_can_pop_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_child_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwNavigationPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(NavigationPage::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_tag_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_tag_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwNavigationPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(NavigationPage::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::tag\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_tag_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwNavigationPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(NavigationPage::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for NavigationPage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("NavigationPage") + } +} diff --git a/libadwaita-0.4.4/src/auto/navigation_split_view.rs b/libadwaita-0.4.4/src/auto/navigation_split_view.rs new file mode 100644 index 0000000..6adc189 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/navigation_split_view.rs @@ -0,0 +1,695 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{LengthUnit, NavigationPage}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwNavigationSplitView")] + pub struct NavigationSplitView(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_navigation_split_view_get_type(), + } +} + +impl NavigationSplitView { + #[doc(alias = "adw_navigation_split_view_new")] + pub fn new() -> NavigationSplitView { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_navigation_split_view_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`NavigationSplitView`] objects. + /// + /// This method returns an instance of [`NavigationSplitViewBuilder`](crate::builders::NavigationSplitViewBuilder) which can be used to create [`NavigationSplitView`] objects. + pub fn builder() -> NavigationSplitViewBuilder { + NavigationSplitViewBuilder::new() + } + + #[doc(alias = "adw_navigation_split_view_get_collapsed")] + #[doc(alias = "get_collapsed")] + pub fn is_collapsed(&self) -> bool { + unsafe { + from_glib(ffi::adw_navigation_split_view_get_collapsed( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_split_view_get_content")] + #[doc(alias = "get_content")] + pub fn content(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_navigation_split_view_get_content( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_split_view_get_max_sidebar_width")] + #[doc(alias = "get_max_sidebar_width")] + pub fn max_sidebar_width(&self) -> f64 { + unsafe { ffi::adw_navigation_split_view_get_max_sidebar_width(self.to_glib_none().0) } + } + + #[doc(alias = "adw_navigation_split_view_get_min_sidebar_width")] + #[doc(alias = "get_min_sidebar_width")] + pub fn min_sidebar_width(&self) -> f64 { + unsafe { ffi::adw_navigation_split_view_get_min_sidebar_width(self.to_glib_none().0) } + } + + #[doc(alias = "adw_navigation_split_view_get_show_content")] + #[doc(alias = "get_show_content")] + pub fn shows_content(&self) -> bool { + unsafe { + from_glib(ffi::adw_navigation_split_view_get_show_content( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_split_view_get_sidebar")] + #[doc(alias = "get_sidebar")] + pub fn sidebar(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_navigation_split_view_get_sidebar( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_split_view_get_sidebar_width_fraction")] + #[doc(alias = "get_sidebar_width_fraction")] + pub fn sidebar_width_fraction(&self) -> f64 { + unsafe { ffi::adw_navigation_split_view_get_sidebar_width_fraction(self.to_glib_none().0) } + } + + #[doc(alias = "adw_navigation_split_view_get_sidebar_width_unit")] + #[doc(alias = "get_sidebar_width_unit")] + pub fn sidebar_width_unit(&self) -> LengthUnit { + unsafe { + from_glib(ffi::adw_navigation_split_view_get_sidebar_width_unit( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_split_view_set_collapsed")] + pub fn set_collapsed(&self, collapsed: bool) { + unsafe { + ffi::adw_navigation_split_view_set_collapsed( + self.to_glib_none().0, + collapsed.into_glib(), + ); + } + } + + #[doc(alias = "adw_navigation_split_view_set_content")] + pub fn set_content(&self, content: Option<&impl IsA>) { + unsafe { + ffi::adw_navigation_split_view_set_content( + self.to_glib_none().0, + content.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_navigation_split_view_set_max_sidebar_width")] + pub fn set_max_sidebar_width(&self, width: f64) { + unsafe { + ffi::adw_navigation_split_view_set_max_sidebar_width(self.to_glib_none().0, width); + } + } + + #[doc(alias = "adw_navigation_split_view_set_min_sidebar_width")] + pub fn set_min_sidebar_width(&self, width: f64) { + unsafe { + ffi::adw_navigation_split_view_set_min_sidebar_width(self.to_glib_none().0, width); + } + } + + #[doc(alias = "adw_navigation_split_view_set_show_content")] + pub fn set_show_content(&self, show_content: bool) { + unsafe { + ffi::adw_navigation_split_view_set_show_content( + self.to_glib_none().0, + show_content.into_glib(), + ); + } + } + + #[doc(alias = "adw_navigation_split_view_set_sidebar")] + pub fn set_sidebar(&self, sidebar: Option<&impl IsA>) { + unsafe { + ffi::adw_navigation_split_view_set_sidebar( + self.to_glib_none().0, + sidebar.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_navigation_split_view_set_sidebar_width_fraction")] + pub fn set_sidebar_width_fraction(&self, fraction: f64) { + unsafe { + ffi::adw_navigation_split_view_set_sidebar_width_fraction( + self.to_glib_none().0, + fraction, + ); + } + } + + #[doc(alias = "adw_navigation_split_view_set_sidebar_width_unit")] + pub fn set_sidebar_width_unit(&self, unit: LengthUnit) { + unsafe { + ffi::adw_navigation_split_view_set_sidebar_width_unit( + self.to_glib_none().0, + unit.into_glib(), + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "collapsed")] + pub fn connect_collapsed_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_collapsed_trampoline( + this: *mut ffi::AdwNavigationSplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::collapsed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_collapsed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "content")] + pub fn connect_content_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_content_trampoline( + this: *mut ffi::AdwNavigationSplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::content\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_content_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "max-sidebar-width")] + pub fn connect_max_sidebar_width_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_max_sidebar_width_trampoline< + F: Fn(&NavigationSplitView) + 'static, + >( + this: *mut ffi::AdwNavigationSplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::max-sidebar-width\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_max_sidebar_width_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "min-sidebar-width")] + pub fn connect_min_sidebar_width_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_min_sidebar_width_trampoline< + F: Fn(&NavigationSplitView) + 'static, + >( + this: *mut ffi::AdwNavigationSplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::min-sidebar-width\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_min_sidebar_width_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "show-content")] + pub fn connect_show_content_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_show_content_trampoline< + F: Fn(&NavigationSplitView) + 'static, + >( + this: *mut ffi::AdwNavigationSplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::show-content\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_show_content_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "sidebar")] + pub fn connect_sidebar_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_sidebar_trampoline( + this: *mut ffi::AdwNavigationSplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::sidebar\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_sidebar_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "sidebar-width-fraction")] + pub fn connect_sidebar_width_fraction_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_sidebar_width_fraction_trampoline< + F: Fn(&NavigationSplitView) + 'static, + >( + this: *mut ffi::AdwNavigationSplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::sidebar-width-fraction\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_sidebar_width_fraction_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "sidebar-width-unit")] + pub fn connect_sidebar_width_unit_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_sidebar_width_unit_trampoline< + F: Fn(&NavigationSplitView) + 'static, + >( + this: *mut ffi::AdwNavigationSplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::sidebar-width-unit\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_sidebar_width_unit_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl Default for NavigationSplitView { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`NavigationSplitView`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct NavigationSplitViewBuilder { + builder: glib::object::ObjectBuilder<'static, NavigationSplitView>, +} + +impl NavigationSplitViewBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn collapsed(self, collapsed: bool) -> Self { + Self { + builder: self.builder.property("collapsed", collapsed), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn content(self, content: &impl IsA) -> Self { + Self { + builder: self.builder.property("content", content.clone().upcast()), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn max_sidebar_width(self, max_sidebar_width: f64) -> Self { + Self { + builder: self + .builder + .property("max-sidebar-width", max_sidebar_width), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn min_sidebar_width(self, min_sidebar_width: f64) -> Self { + Self { + builder: self + .builder + .property("min-sidebar-width", min_sidebar_width), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn show_content(self, show_content: bool) -> Self { + Self { + builder: self.builder.property("show-content", show_content), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn sidebar(self, sidebar: &impl IsA) -> Self { + Self { + builder: self.builder.property("sidebar", sidebar.clone().upcast()), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn sidebar_width_fraction(self, sidebar_width_fraction: f64) -> Self { + Self { + builder: self + .builder + .property("sidebar-width-fraction", sidebar_width_fraction), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn sidebar_width_unit(self, sidebar_width_unit: LengthUnit) -> Self { + Self { + builder: self + .builder + .property("sidebar-width-unit", sidebar_width_unit), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`NavigationSplitView`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> NavigationSplitView { + self.builder.build() + } +} + +impl fmt::Display for NavigationSplitView { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("NavigationSplitView") + } +} diff --git a/libadwaita-0.4.4/src/auto/navigation_view.rs b/libadwaita-0.4.4/src/auto/navigation_view.rs new file mode 100644 index 0000000..f132aac --- /dev/null +++ b/libadwaita-0.4.4/src/auto/navigation_view.rs @@ -0,0 +1,593 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{NavigationPage, Swipeable}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwNavigationView")] + pub struct NavigationView(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, Swipeable; + + match fn { + type_ => || ffi::adw_navigation_view_get_type(), + } +} + +impl NavigationView { + #[doc(alias = "adw_navigation_view_new")] + pub fn new() -> NavigationView { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_navigation_view_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`NavigationView`] objects. + /// + /// This method returns an instance of [`NavigationViewBuilder`](crate::builders::NavigationViewBuilder) which can be used to create [`NavigationView`] objects. + pub fn builder() -> NavigationViewBuilder { + NavigationViewBuilder::new() + } + + #[doc(alias = "adw_navigation_view_add")] + pub fn add(&self, page: &impl IsA) { + unsafe { + ffi::adw_navigation_view_add(self.to_glib_none().0, page.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_navigation_view_find_page")] + pub fn find_page(&self, tag: &str) -> Option { + unsafe { + from_glib_none(ffi::adw_navigation_view_find_page( + self.to_glib_none().0, + tag.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_view_get_animate_transitions")] + #[doc(alias = "get_animate_transitions")] + pub fn is_animate_transitions(&self) -> bool { + unsafe { + from_glib(ffi::adw_navigation_view_get_animate_transitions( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_view_get_navigation_stack")] + #[doc(alias = "get_navigation_stack")] + pub fn navigation_stack(&self) -> gio::ListModel { + unsafe { + from_glib_full(ffi::adw_navigation_view_get_navigation_stack( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_view_get_previous_page")] + #[doc(alias = "get_previous_page")] + pub fn previous_page(&self, page: &impl IsA) -> Option { + unsafe { + from_glib_none(ffi::adw_navigation_view_get_previous_page( + self.to_glib_none().0, + page.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_view_get_visible_page")] + #[doc(alias = "get_visible_page")] + pub fn visible_page(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_navigation_view_get_visible_page( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_view_pop")] + pub fn pop(&self) -> bool { + unsafe { from_glib(ffi::adw_navigation_view_pop(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_navigation_view_pop_to_page")] + pub fn pop_to_page(&self, page: &impl IsA) -> bool { + unsafe { + from_glib(ffi::adw_navigation_view_pop_to_page( + self.to_glib_none().0, + page.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_view_pop_to_tag")] + pub fn pop_to_tag(&self, tag: &str) -> bool { + unsafe { + from_glib(ffi::adw_navigation_view_pop_to_tag( + self.to_glib_none().0, + tag.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_navigation_view_push")] + pub fn push(&self, page: &impl IsA) { + unsafe { + ffi::adw_navigation_view_push(self.to_glib_none().0, page.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_navigation_view_push_by_tag")] + pub fn push_by_tag(&self, tag: &str) { + unsafe { + ffi::adw_navigation_view_push_by_tag(self.to_glib_none().0, tag.to_glib_none().0); + } + } + + #[doc(alias = "adw_navigation_view_remove")] + pub fn remove(&self, page: &impl IsA) { + unsafe { + ffi::adw_navigation_view_remove(self.to_glib_none().0, page.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_navigation_view_replace")] + pub fn replace(&self, pages: &[NavigationPage]) { + let n_pages = pages.len() as _; + unsafe { + ffi::adw_navigation_view_replace( + self.to_glib_none().0, + pages.to_glib_none().0, + n_pages, + ); + } + } + + #[doc(alias = "adw_navigation_view_replace_with_tags")] + pub fn replace_with_tags(&self, tags: &[&str]) { + let n_tags = tags.len() as _; + unsafe { + ffi::adw_navigation_view_replace_with_tags( + self.to_glib_none().0, + tags.to_glib_none().0, + n_tags, + ); + } + } + + #[doc(alias = "adw_navigation_view_set_animate_transitions")] + pub fn set_animate_transitions(&self, animate_transitions: bool) { + unsafe { + ffi::adw_navigation_view_set_animate_transitions( + self.to_glib_none().0, + animate_transitions.into_glib(), + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "get-next-page")] + pub fn connect_get_next_page Option + 'static>( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn get_next_page_trampoline< + F: Fn(&NavigationView) -> Option + 'static, + >( + this: *mut ffi::AdwNavigationView, + f: glib::ffi::gpointer, + ) -> *mut ffi::AdwNavigationPage { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)).to_glib_full() + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"get-next-page\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + get_next_page_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "popped")] + pub fn connect_popped(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn popped_trampoline< + F: Fn(&NavigationView, &NavigationPage) + 'static, + >( + this: *mut ffi::AdwNavigationView, + page: *mut ffi::AdwNavigationPage, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), &from_glib_borrow(page)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"popped\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + popped_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "pushed")] + pub fn connect_pushed(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn pushed_trampoline( + this: *mut ffi::AdwNavigationView, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"pushed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + pushed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "replaced")] + pub fn connect_replaced(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn replaced_trampoline( + this: *mut ffi::AdwNavigationView, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"replaced\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + replaced_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "animate-transitions")] + pub fn connect_animate_transitions_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_animate_transitions_trampoline< + F: Fn(&NavigationView) + 'static, + >( + this: *mut ffi::AdwNavigationView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::animate-transitions\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_animate_transitions_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "navigation-stack")] + pub fn connect_navigation_stack_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_navigation_stack_trampoline< + F: Fn(&NavigationView) + 'static, + >( + this: *mut ffi::AdwNavigationView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::navigation-stack\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_navigation_stack_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "visible-page")] + pub fn connect_visible_page_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_visible_page_trampoline( + this: *mut ffi::AdwNavigationView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::visible-page\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_visible_page_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl Default for NavigationView { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`NavigationView`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct NavigationViewBuilder { + builder: glib::object::ObjectBuilder<'static, NavigationView>, +} + +impl NavigationViewBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn animate_transitions(self, animate_transitions: bool) -> Self { + Self { + builder: self + .builder + .property("animate-transitions", animate_transitions), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`NavigationView`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> NavigationView { + self.builder.build() + } +} + +impl fmt::Display for NavigationView { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("NavigationView") + } +} diff --git a/libadwaita-0.4.4/src/auto/overlay_split_view.rs b/libadwaita-0.4.4/src/auto/overlay_split_view.rs new file mode 100644 index 0000000..d89c21f --- /dev/null +++ b/libadwaita-0.4.4/src/auto/overlay_split_view.rs @@ -0,0 +1,915 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{LengthUnit, Swipeable}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwOverlaySplitView")] + pub struct OverlaySplitView(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, Swipeable; + + match fn { + type_ => || ffi::adw_overlay_split_view_get_type(), + } +} + +impl OverlaySplitView { + #[doc(alias = "adw_overlay_split_view_new")] + pub fn new() -> OverlaySplitView { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_overlay_split_view_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`OverlaySplitView`] objects. + /// + /// This method returns an instance of [`OverlaySplitViewBuilder`](crate::builders::OverlaySplitViewBuilder) which can be used to create [`OverlaySplitView`] objects. + pub fn builder() -> OverlaySplitViewBuilder { + OverlaySplitViewBuilder::new() + } + + #[doc(alias = "adw_overlay_split_view_get_collapsed")] + #[doc(alias = "get_collapsed")] + pub fn is_collapsed(&self) -> bool { + unsafe { + from_glib(ffi::adw_overlay_split_view_get_collapsed( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_overlay_split_view_get_content")] + #[doc(alias = "get_content")] + pub fn content(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_overlay_split_view_get_content( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_overlay_split_view_get_enable_hide_gesture")] + #[doc(alias = "get_enable_hide_gesture")] + pub fn enables_hide_gesture(&self) -> bool { + unsafe { + from_glib(ffi::adw_overlay_split_view_get_enable_hide_gesture( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_overlay_split_view_get_enable_show_gesture")] + #[doc(alias = "get_enable_show_gesture")] + pub fn enables_show_gesture(&self) -> bool { + unsafe { + from_glib(ffi::adw_overlay_split_view_get_enable_show_gesture( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_overlay_split_view_get_max_sidebar_width")] + #[doc(alias = "get_max_sidebar_width")] + pub fn max_sidebar_width(&self) -> f64 { + unsafe { ffi::adw_overlay_split_view_get_max_sidebar_width(self.to_glib_none().0) } + } + + #[doc(alias = "adw_overlay_split_view_get_min_sidebar_width")] + #[doc(alias = "get_min_sidebar_width")] + pub fn min_sidebar_width(&self) -> f64 { + unsafe { ffi::adw_overlay_split_view_get_min_sidebar_width(self.to_glib_none().0) } + } + + #[doc(alias = "adw_overlay_split_view_get_pin_sidebar")] + #[doc(alias = "get_pin_sidebar")] + pub fn is_pin_sidebar(&self) -> bool { + unsafe { + from_glib(ffi::adw_overlay_split_view_get_pin_sidebar( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_overlay_split_view_get_show_sidebar")] + #[doc(alias = "get_show_sidebar")] + pub fn shows_sidebar(&self) -> bool { + unsafe { + from_glib(ffi::adw_overlay_split_view_get_show_sidebar( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_overlay_split_view_get_sidebar")] + #[doc(alias = "get_sidebar")] + pub fn sidebar(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_overlay_split_view_get_sidebar( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_overlay_split_view_get_sidebar_position")] + #[doc(alias = "get_sidebar_position")] + pub fn sidebar_position(&self) -> gtk::PackType { + unsafe { + from_glib(ffi::adw_overlay_split_view_get_sidebar_position( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_overlay_split_view_get_sidebar_width_fraction")] + #[doc(alias = "get_sidebar_width_fraction")] + pub fn sidebar_width_fraction(&self) -> f64 { + unsafe { ffi::adw_overlay_split_view_get_sidebar_width_fraction(self.to_glib_none().0) } + } + + #[doc(alias = "adw_overlay_split_view_get_sidebar_width_unit")] + #[doc(alias = "get_sidebar_width_unit")] + pub fn sidebar_width_unit(&self) -> LengthUnit { + unsafe { + from_glib(ffi::adw_overlay_split_view_get_sidebar_width_unit( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_overlay_split_view_set_collapsed")] + pub fn set_collapsed(&self, collapsed: bool) { + unsafe { + ffi::adw_overlay_split_view_set_collapsed(self.to_glib_none().0, collapsed.into_glib()); + } + } + + #[doc(alias = "adw_overlay_split_view_set_content")] + pub fn set_content(&self, content: Option<&impl IsA>) { + unsafe { + ffi::adw_overlay_split_view_set_content( + self.to_glib_none().0, + content.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_overlay_split_view_set_enable_hide_gesture")] + pub fn set_enable_hide_gesture(&self, enable_hide_gesture: bool) { + unsafe { + ffi::adw_overlay_split_view_set_enable_hide_gesture( + self.to_glib_none().0, + enable_hide_gesture.into_glib(), + ); + } + } + + #[doc(alias = "adw_overlay_split_view_set_enable_show_gesture")] + pub fn set_enable_show_gesture(&self, enable_show_gesture: bool) { + unsafe { + ffi::adw_overlay_split_view_set_enable_show_gesture( + self.to_glib_none().0, + enable_show_gesture.into_glib(), + ); + } + } + + #[doc(alias = "adw_overlay_split_view_set_max_sidebar_width")] + pub fn set_max_sidebar_width(&self, width: f64) { + unsafe { + ffi::adw_overlay_split_view_set_max_sidebar_width(self.to_glib_none().0, width); + } + } + + #[doc(alias = "adw_overlay_split_view_set_min_sidebar_width")] + pub fn set_min_sidebar_width(&self, width: f64) { + unsafe { + ffi::adw_overlay_split_view_set_min_sidebar_width(self.to_glib_none().0, width); + } + } + + #[doc(alias = "adw_overlay_split_view_set_pin_sidebar")] + pub fn set_pin_sidebar(&self, pin_sidebar: bool) { + unsafe { + ffi::adw_overlay_split_view_set_pin_sidebar( + self.to_glib_none().0, + pin_sidebar.into_glib(), + ); + } + } + + #[doc(alias = "adw_overlay_split_view_set_show_sidebar")] + pub fn set_show_sidebar(&self, show_sidebar: bool) { + unsafe { + ffi::adw_overlay_split_view_set_show_sidebar( + self.to_glib_none().0, + show_sidebar.into_glib(), + ); + } + } + + #[doc(alias = "adw_overlay_split_view_set_sidebar")] + pub fn set_sidebar(&self, sidebar: Option<&impl IsA>) { + unsafe { + ffi::adw_overlay_split_view_set_sidebar( + self.to_glib_none().0, + sidebar.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_overlay_split_view_set_sidebar_position")] + pub fn set_sidebar_position(&self, position: gtk::PackType) { + unsafe { + ffi::adw_overlay_split_view_set_sidebar_position( + self.to_glib_none().0, + position.into_glib(), + ); + } + } + + #[doc(alias = "adw_overlay_split_view_set_sidebar_width_fraction")] + pub fn set_sidebar_width_fraction(&self, fraction: f64) { + unsafe { + ffi::adw_overlay_split_view_set_sidebar_width_fraction(self.to_glib_none().0, fraction); + } + } + + #[doc(alias = "adw_overlay_split_view_set_sidebar_width_unit")] + pub fn set_sidebar_width_unit(&self, unit: LengthUnit) { + unsafe { + ffi::adw_overlay_split_view_set_sidebar_width_unit( + self.to_glib_none().0, + unit.into_glib(), + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "collapsed")] + pub fn connect_collapsed_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_collapsed_trampoline( + this: *mut ffi::AdwOverlaySplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::collapsed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_collapsed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "content")] + pub fn connect_content_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_content_trampoline( + this: *mut ffi::AdwOverlaySplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::content\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_content_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "enable-hide-gesture")] + pub fn connect_enable_hide_gesture_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_enable_hide_gesture_trampoline< + F: Fn(&OverlaySplitView) + 'static, + >( + this: *mut ffi::AdwOverlaySplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::enable-hide-gesture\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_enable_hide_gesture_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "enable-show-gesture")] + pub fn connect_enable_show_gesture_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_enable_show_gesture_trampoline< + F: Fn(&OverlaySplitView) + 'static, + >( + this: *mut ffi::AdwOverlaySplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::enable-show-gesture\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_enable_show_gesture_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "max-sidebar-width")] + pub fn connect_max_sidebar_width_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_max_sidebar_width_trampoline< + F: Fn(&OverlaySplitView) + 'static, + >( + this: *mut ffi::AdwOverlaySplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::max-sidebar-width\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_max_sidebar_width_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "min-sidebar-width")] + pub fn connect_min_sidebar_width_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_min_sidebar_width_trampoline< + F: Fn(&OverlaySplitView) + 'static, + >( + this: *mut ffi::AdwOverlaySplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::min-sidebar-width\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_min_sidebar_width_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "pin-sidebar")] + pub fn connect_pin_sidebar_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_pin_sidebar_trampoline( + this: *mut ffi::AdwOverlaySplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::pin-sidebar\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_pin_sidebar_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "show-sidebar")] + pub fn connect_show_sidebar_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_show_sidebar_trampoline( + this: *mut ffi::AdwOverlaySplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::show-sidebar\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_show_sidebar_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "sidebar")] + pub fn connect_sidebar_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_sidebar_trampoline( + this: *mut ffi::AdwOverlaySplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::sidebar\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_sidebar_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "sidebar-position")] + pub fn connect_sidebar_position_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_sidebar_position_trampoline< + F: Fn(&OverlaySplitView) + 'static, + >( + this: *mut ffi::AdwOverlaySplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::sidebar-position\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_sidebar_position_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "sidebar-width-fraction")] + pub fn connect_sidebar_width_fraction_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_sidebar_width_fraction_trampoline< + F: Fn(&OverlaySplitView) + 'static, + >( + this: *mut ffi::AdwOverlaySplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::sidebar-width-fraction\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_sidebar_width_fraction_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "sidebar-width-unit")] + pub fn connect_sidebar_width_unit_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_sidebar_width_unit_trampoline< + F: Fn(&OverlaySplitView) + 'static, + >( + this: *mut ffi::AdwOverlaySplitView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::sidebar-width-unit\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_sidebar_width_unit_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl Default for OverlaySplitView { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`OverlaySplitView`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct OverlaySplitViewBuilder { + builder: glib::object::ObjectBuilder<'static, OverlaySplitView>, +} + +impl OverlaySplitViewBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn collapsed(self, collapsed: bool) -> Self { + Self { + builder: self.builder.property("collapsed", collapsed), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn content(self, content: &impl IsA) -> Self { + Self { + builder: self.builder.property("content", content.clone().upcast()), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn enable_hide_gesture(self, enable_hide_gesture: bool) -> Self { + Self { + builder: self + .builder + .property("enable-hide-gesture", enable_hide_gesture), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn enable_show_gesture(self, enable_show_gesture: bool) -> Self { + Self { + builder: self + .builder + .property("enable-show-gesture", enable_show_gesture), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn max_sidebar_width(self, max_sidebar_width: f64) -> Self { + Self { + builder: self + .builder + .property("max-sidebar-width", max_sidebar_width), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn min_sidebar_width(self, min_sidebar_width: f64) -> Self { + Self { + builder: self + .builder + .property("min-sidebar-width", min_sidebar_width), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn pin_sidebar(self, pin_sidebar: bool) -> Self { + Self { + builder: self.builder.property("pin-sidebar", pin_sidebar), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn show_sidebar(self, show_sidebar: bool) -> Self { + Self { + builder: self.builder.property("show-sidebar", show_sidebar), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn sidebar(self, sidebar: &impl IsA) -> Self { + Self { + builder: self.builder.property("sidebar", sidebar.clone().upcast()), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn sidebar_position(self, sidebar_position: gtk::PackType) -> Self { + Self { + builder: self.builder.property("sidebar-position", sidebar_position), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn sidebar_width_fraction(self, sidebar_width_fraction: f64) -> Self { + Self { + builder: self + .builder + .property("sidebar-width-fraction", sidebar_width_fraction), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn sidebar_width_unit(self, sidebar_width_unit: LengthUnit) -> Self { + Self { + builder: self + .builder + .property("sidebar-width-unit", sidebar_width_unit), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`OverlaySplitView`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> OverlaySplitView { + self.builder.build() + } +} + +impl fmt::Display for OverlaySplitView { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("OverlaySplitView") + } +} diff --git a/libadwaita-0.4.4/src/auto/password_entry_row.rs b/libadwaita-0.4.4/src/auto/password_entry_row.rs new file mode 100644 index 0000000..9da762e --- /dev/null +++ b/libadwaita-0.4.4/src/auto/password_entry_row.rs @@ -0,0 +1,405 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{EntryRow, PreferencesRow}; +use glib::{prelude::*, translate::*}; +use std::fmt; + +glib::wrapper! { + #[doc(alias = "AdwPasswordEntryRow")] + pub struct PasswordEntryRow(Object) @extends EntryRow, PreferencesRow, gtk::ListBoxRow, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable, gtk::Editable; + + match fn { + type_ => || ffi::adw_password_entry_row_get_type(), + } +} + +impl PasswordEntryRow { + #[doc(alias = "adw_password_entry_row_new")] + pub fn new() -> PasswordEntryRow { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_password_entry_row_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`PasswordEntryRow`] objects. + /// + /// This method returns an instance of [`PasswordEntryRowBuilder`](crate::builders::PasswordEntryRowBuilder) which can be used to create [`PasswordEntryRow`] objects. + pub fn builder() -> PasswordEntryRowBuilder { + PasswordEntryRowBuilder::new() + } +} + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +impl Default for PasswordEntryRow { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`PasswordEntryRow`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct PasswordEntryRowBuilder { + builder: glib::object::ObjectBuilder<'static, PasswordEntryRow>, +} + +impl PasswordEntryRowBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn activates_default(self, activates_default: bool) -> Self { + Self { + builder: self + .builder + .property("activates-default", activates_default), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn attributes(self, attributes: &pango::AttrList) -> Self { + Self { + builder: self.builder.property("attributes", attributes.clone()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn enable_emoji_completion(self, enable_emoji_completion: bool) -> Self { + Self { + builder: self + .builder + .property("enable-emoji-completion", enable_emoji_completion), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn input_hints(self, input_hints: gtk::InputHints) -> Self { + Self { + builder: self.builder.property("input-hints", input_hints), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn input_purpose(self, input_purpose: gtk::InputPurpose) -> Self { + Self { + builder: self.builder.property("input-purpose", input_purpose), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn show_apply_button(self, show_apply_button: bool) -> Self { + Self { + builder: self + .builder + .property("show-apply-button", show_apply_button), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + pub fn title_selectable(self, title_selectable: bool) -> Self { + Self { + builder: self.builder.property("title-selectable", title_selectable), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn use_markup(self, use_markup: bool) -> Self { + Self { + builder: self.builder.property("use-markup", use_markup), + } + } + + pub fn use_underline(self, use_underline: bool) -> Self { + Self { + builder: self.builder.property("use-underline", use_underline), + } + } + + pub fn activatable(self, activatable: bool) -> Self { + Self { + builder: self.builder.property("activatable", activatable), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn selectable(self, selectable: bool) -> Self { + Self { + builder: self.builder.property("selectable", selectable), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn action_name(self, action_name: impl Into) -> Self { + Self { + builder: self.builder.property("action-name", action_name.into()), + } + } + + pub fn action_target(self, action_target: &glib::Variant) -> Self { + Self { + builder: self + .builder + .property("action-target", action_target.clone()), + } + } + + pub fn editable(self, editable: bool) -> Self { + Self { + builder: self.builder.property("editable", editable), + } + } + + pub fn enable_undo(self, enable_undo: bool) -> Self { + Self { + builder: self.builder.property("enable-undo", enable_undo), + } + } + + pub fn max_width_chars(self, max_width_chars: i32) -> Self { + Self { + builder: self.builder.property("max-width-chars", max_width_chars), + } + } + + pub fn text(self, text: impl Into) -> Self { + Self { + builder: self.builder.property("text", text.into()), + } + } + + pub fn width_chars(self, width_chars: i32) -> Self { + Self { + builder: self.builder.property("width-chars", width_chars), + } + } + + pub fn xalign(self, xalign: f32) -> Self { + Self { + builder: self.builder.property("xalign", xalign), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`PasswordEntryRow`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> PasswordEntryRow { + self.builder.build() + } +} + +impl fmt::Display for PasswordEntryRow { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("PasswordEntryRow") + } +} diff --git a/libadwaita-0.4.4/src/auto/preferences_group.rs b/libadwaita-0.4.4/src/auto/preferences_group.rs new file mode 100644 index 0000000..f69407e --- /dev/null +++ b/libadwaita-0.4.4/src/auto/preferences_group.rs @@ -0,0 +1,476 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwPreferencesGroup")] + pub struct PreferencesGroup(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_preferences_group_get_type(), + } +} + +impl PreferencesGroup { + pub const NONE: Option<&'static PreferencesGroup> = None; + + #[doc(alias = "adw_preferences_group_new")] + pub fn new() -> PreferencesGroup { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_preferences_group_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`PreferencesGroup`] objects. + /// + /// This method returns an instance of [`PreferencesGroupBuilder`](crate::builders::PreferencesGroupBuilder) which can be used to create [`PreferencesGroup`] objects. + pub fn builder() -> PreferencesGroupBuilder { + PreferencesGroupBuilder::new() + } +} + +impl Default for PreferencesGroup { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`PreferencesGroup`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct PreferencesGroupBuilder { + builder: glib::object::ObjectBuilder<'static, PreferencesGroup>, +} + +impl PreferencesGroupBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn description(self, description: impl Into) -> Self { + Self { + builder: self.builder.property("description", description.into()), + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + pub fn header_suffix(self, header_suffix: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("header-suffix", header_suffix.clone().upcast()), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`PreferencesGroup`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> PreferencesGroup { + self.builder.build() + } +} + +pub trait PreferencesGroupExt: 'static { + #[doc(alias = "adw_preferences_group_add")] + fn add(&self, child: &impl IsA); + + #[doc(alias = "adw_preferences_group_get_description")] + #[doc(alias = "get_description")] + fn description(&self) -> Option; + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + #[doc(alias = "adw_preferences_group_get_header_suffix")] + #[doc(alias = "get_header_suffix")] + fn header_suffix(&self) -> Option; + + #[doc(alias = "adw_preferences_group_get_title")] + #[doc(alias = "get_title")] + fn title(&self) -> glib::GString; + + #[doc(alias = "adw_preferences_group_remove")] + fn remove(&self, child: &impl IsA); + + #[doc(alias = "adw_preferences_group_set_description")] + fn set_description(&self, description: Option<&str>); + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + #[doc(alias = "adw_preferences_group_set_header_suffix")] + fn set_header_suffix(&self, suffix: Option<&impl IsA>); + + #[doc(alias = "adw_preferences_group_set_title")] + fn set_title(&self, title: &str); + + #[doc(alias = "description")] + fn connect_description_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + #[doc(alias = "header-suffix")] + fn connect_header_suffix_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "title")] + fn connect_title_notify(&self, f: F) -> SignalHandlerId; +} + +impl> PreferencesGroupExt for O { + fn add(&self, child: &impl IsA) { + unsafe { + ffi::adw_preferences_group_add( + self.as_ref().to_glib_none().0, + child.as_ref().to_glib_none().0, + ); + } + } + + fn description(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_preferences_group_get_description( + self.as_ref().to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + fn header_suffix(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_preferences_group_get_header_suffix( + self.as_ref().to_glib_none().0, + )) + } + } + + fn title(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_preferences_group_get_title( + self.as_ref().to_glib_none().0, + )) + } + } + + fn remove(&self, child: &impl IsA) { + unsafe { + ffi::adw_preferences_group_remove( + self.as_ref().to_glib_none().0, + child.as_ref().to_glib_none().0, + ); + } + } + + fn set_description(&self, description: Option<&str>) { + unsafe { + ffi::adw_preferences_group_set_description( + self.as_ref().to_glib_none().0, + description.to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + fn set_header_suffix(&self, suffix: Option<&impl IsA>) { + unsafe { + ffi::adw_preferences_group_set_header_suffix( + self.as_ref().to_glib_none().0, + suffix.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + fn set_title(&self, title: &str) { + unsafe { + ffi::adw_preferences_group_set_title( + self.as_ref().to_glib_none().0, + title.to_glib_none().0, + ); + } + } + + fn connect_description_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_description_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesGroup, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesGroup::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::description\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_description_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + fn connect_header_suffix_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_header_suffix_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesGroup, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesGroup::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::header-suffix\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_header_suffix_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesGroup, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesGroup::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for PreferencesGroup { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("PreferencesGroup") + } +} diff --git a/libadwaita-0.4.4/src/auto/preferences_page.rs b/libadwaita-0.4.4/src/auto/preferences_page.rs new file mode 100644 index 0000000..621491f --- /dev/null +++ b/libadwaita-0.4.4/src/auto/preferences_page.rs @@ -0,0 +1,570 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::PreferencesGroup; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwPreferencesPage")] + pub struct PreferencesPage(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_preferences_page_get_type(), + } +} + +impl PreferencesPage { + pub const NONE: Option<&'static PreferencesPage> = None; + + #[doc(alias = "adw_preferences_page_new")] + pub fn new() -> PreferencesPage { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_preferences_page_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`PreferencesPage`] objects. + /// + /// This method returns an instance of [`PreferencesPageBuilder`](crate::builders::PreferencesPageBuilder) which can be used to create [`PreferencesPage`] objects. + pub fn builder() -> PreferencesPageBuilder { + PreferencesPageBuilder::new() + } +} + +impl Default for PreferencesPage { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`PreferencesPage`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct PreferencesPageBuilder { + builder: glib::object::ObjectBuilder<'static, PreferencesPage>, +} + +impl PreferencesPageBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn description(self, description: impl Into) -> Self { + Self { + builder: self.builder.property("description", description.into()), + } + } + + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + pub fn use_underline(self, use_underline: bool) -> Self { + Self { + builder: self.builder.property("use-underline", use_underline), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`PreferencesPage`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> PreferencesPage { + self.builder.build() + } +} + +pub trait PreferencesPageExt: 'static { + #[doc(alias = "adw_preferences_page_add")] + fn add(&self, group: &impl IsA); + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_preferences_page_get_description")] + #[doc(alias = "get_description")] + fn description(&self) -> glib::GString; + + #[doc(alias = "adw_preferences_page_get_icon_name")] + #[doc(alias = "get_icon_name")] + fn icon_name(&self) -> Option; + + #[doc(alias = "adw_preferences_page_get_name")] + #[doc(alias = "get_name")] + fn name(&self) -> Option; + + #[doc(alias = "adw_preferences_page_get_title")] + #[doc(alias = "get_title")] + fn title(&self) -> glib::GString; + + #[doc(alias = "adw_preferences_page_get_use_underline")] + #[doc(alias = "get_use_underline")] + fn uses_underline(&self) -> bool; + + #[doc(alias = "adw_preferences_page_remove")] + fn remove(&self, group: &impl IsA); + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_preferences_page_scroll_to_top")] + fn scroll_to_top(&self); + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_preferences_page_set_description")] + fn set_description(&self, description: &str); + + #[doc(alias = "adw_preferences_page_set_icon_name")] + fn set_icon_name(&self, icon_name: Option<&str>); + + #[doc(alias = "adw_preferences_page_set_name")] + fn set_name(&self, name: Option<&str>); + + #[doc(alias = "adw_preferences_page_set_title")] + fn set_title(&self, title: &str); + + #[doc(alias = "adw_preferences_page_set_use_underline")] + fn set_use_underline(&self, use_underline: bool); + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "description")] + fn connect_description_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "icon-name")] + fn connect_icon_name_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "title")] + fn connect_title_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "use-underline")] + fn connect_use_underline_notify(&self, f: F) -> SignalHandlerId; +} + +impl> PreferencesPageExt for O { + fn add(&self, group: &impl IsA) { + unsafe { + ffi::adw_preferences_page_add( + self.as_ref().to_glib_none().0, + group.as_ref().to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn description(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_preferences_page_get_description( + self.as_ref().to_glib_none().0, + )) + } + } + + fn icon_name(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_preferences_page_get_icon_name( + self.as_ref().to_glib_none().0, + )) + } + } + + fn name(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_preferences_page_get_name( + self.as_ref().to_glib_none().0, + )) + } + } + + fn title(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_preferences_page_get_title( + self.as_ref().to_glib_none().0, + )) + } + } + + fn uses_underline(&self) -> bool { + unsafe { + from_glib(ffi::adw_preferences_page_get_use_underline( + self.as_ref().to_glib_none().0, + )) + } + } + + fn remove(&self, group: &impl IsA) { + unsafe { + ffi::adw_preferences_page_remove( + self.as_ref().to_glib_none().0, + group.as_ref().to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn scroll_to_top(&self) { + unsafe { + ffi::adw_preferences_page_scroll_to_top(self.as_ref().to_glib_none().0); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn set_description(&self, description: &str) { + unsafe { + ffi::adw_preferences_page_set_description( + self.as_ref().to_glib_none().0, + description.to_glib_none().0, + ); + } + } + + fn set_icon_name(&self, icon_name: Option<&str>) { + unsafe { + ffi::adw_preferences_page_set_icon_name( + self.as_ref().to_glib_none().0, + icon_name.to_glib_none().0, + ); + } + } + + fn set_name(&self, name: Option<&str>) { + unsafe { + ffi::adw_preferences_page_set_name( + self.as_ref().to_glib_none().0, + name.to_glib_none().0, + ); + } + } + + fn set_title(&self, title: &str) { + unsafe { + ffi::adw_preferences_page_set_title( + self.as_ref().to_glib_none().0, + title.to_glib_none().0, + ); + } + } + + fn set_use_underline(&self, use_underline: bool) { + unsafe { + ffi::adw_preferences_page_set_use_underline( + self.as_ref().to_glib_none().0, + use_underline.into_glib(), + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_description_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_description_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesPage::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::description\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_description_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_icon_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_icon_name_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesPage::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::icon-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_icon_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesPage::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_use_underline_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_use_underline_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesPage::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::use-underline\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_use_underline_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for PreferencesPage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("PreferencesPage") + } +} diff --git a/libadwaita-0.4.4/src/auto/preferences_row.rs b/libadwaita-0.4.4/src/auto/preferences_row.rs new file mode 100644 index 0000000..8c5c4c4 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/preferences_row.rs @@ -0,0 +1,554 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwPreferencesRow")] + pub struct PreferencesRow(Object) @extends gtk::ListBoxRow, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable; + + match fn { + type_ => || ffi::adw_preferences_row_get_type(), + } +} + +impl PreferencesRow { + pub const NONE: Option<&'static PreferencesRow> = None; + + #[doc(alias = "adw_preferences_row_new")] + pub fn new() -> PreferencesRow { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_preferences_row_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`PreferencesRow`] objects. + /// + /// This method returns an instance of [`PreferencesRowBuilder`](crate::builders::PreferencesRowBuilder) which can be used to create [`PreferencesRow`] objects. + pub fn builder() -> PreferencesRowBuilder { + PreferencesRowBuilder::new() + } +} + +impl Default for PreferencesRow { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`PreferencesRow`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct PreferencesRowBuilder { + builder: glib::object::ObjectBuilder<'static, PreferencesRow>, +} + +impl PreferencesRowBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + pub fn title_selectable(self, title_selectable: bool) -> Self { + Self { + builder: self.builder.property("title-selectable", title_selectable), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn use_markup(self, use_markup: bool) -> Self { + Self { + builder: self.builder.property("use-markup", use_markup), + } + } + + pub fn use_underline(self, use_underline: bool) -> Self { + Self { + builder: self.builder.property("use-underline", use_underline), + } + } + + pub fn activatable(self, activatable: bool) -> Self { + Self { + builder: self.builder.property("activatable", activatable), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn selectable(self, selectable: bool) -> Self { + Self { + builder: self.builder.property("selectable", selectable), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn action_name(self, action_name: impl Into) -> Self { + Self { + builder: self.builder.property("action-name", action_name.into()), + } + } + + pub fn action_target(self, action_target: &glib::Variant) -> Self { + Self { + builder: self + .builder + .property("action-target", action_target.clone()), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`PreferencesRow`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> PreferencesRow { + self.builder.build() + } +} + +pub trait PreferencesRowExt: 'static { + #[doc(alias = "adw_preferences_row_get_title")] + #[doc(alias = "get_title")] + fn title(&self) -> glib::GString; + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + #[doc(alias = "adw_preferences_row_get_title_selectable")] + #[doc(alias = "get_title_selectable")] + fn is_title_selectable(&self) -> bool; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_preferences_row_get_use_markup")] + #[doc(alias = "get_use_markup")] + fn uses_markup(&self) -> bool; + + #[doc(alias = "adw_preferences_row_get_use_underline")] + #[doc(alias = "get_use_underline")] + fn uses_underline(&self) -> bool; + + #[doc(alias = "adw_preferences_row_set_title")] + fn set_title(&self, title: &str); + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + #[doc(alias = "adw_preferences_row_set_title_selectable")] + fn set_title_selectable(&self, title_selectable: bool); + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_preferences_row_set_use_markup")] + fn set_use_markup(&self, use_markup: bool); + + #[doc(alias = "adw_preferences_row_set_use_underline")] + fn set_use_underline(&self, use_underline: bool); + + #[doc(alias = "title")] + fn connect_title_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + #[doc(alias = "title-selectable")] + fn connect_title_selectable_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "use-markup")] + fn connect_use_markup_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "use-underline")] + fn connect_use_underline_notify(&self, f: F) -> SignalHandlerId; +} + +impl> PreferencesRowExt for O { + fn title(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_preferences_row_get_title( + self.as_ref().to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + fn is_title_selectable(&self) -> bool { + unsafe { + from_glib(ffi::adw_preferences_row_get_title_selectable( + self.as_ref().to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn uses_markup(&self) -> bool { + unsafe { + from_glib(ffi::adw_preferences_row_get_use_markup( + self.as_ref().to_glib_none().0, + )) + } + } + + fn uses_underline(&self) -> bool { + unsafe { + from_glib(ffi::adw_preferences_row_get_use_underline( + self.as_ref().to_glib_none().0, + )) + } + } + + fn set_title(&self, title: &str) { + unsafe { + ffi::adw_preferences_row_set_title( + self.as_ref().to_glib_none().0, + title.to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + fn set_title_selectable(&self, title_selectable: bool) { + unsafe { + ffi::adw_preferences_row_set_title_selectable( + self.as_ref().to_glib_none().0, + title_selectable.into_glib(), + ); + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn set_use_markup(&self, use_markup: bool) { + unsafe { + ffi::adw_preferences_row_set_use_markup( + self.as_ref().to_glib_none().0, + use_markup.into_glib(), + ); + } + } + + fn set_use_underline(&self, use_underline: bool) { + unsafe { + ffi::adw_preferences_row_set_use_underline( + self.as_ref().to_glib_none().0, + use_underline.into_glib(), + ); + } + } + + fn connect_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + fn connect_title_selectable_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_selectable_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title-selectable\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_selectable_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + fn connect_use_markup_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_use_markup_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::use-markup\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_use_markup_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_use_underline_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_use_underline_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesRow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::use-underline\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_use_underline_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for PreferencesRow { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("PreferencesRow") + } +} diff --git a/libadwaita-0.4.4/src/auto/preferences_window.rs b/libadwaita-0.4.4/src/auto/preferences_window.rs new file mode 100644 index 0000000..6ee0d53 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/preferences_window.rs @@ -0,0 +1,763 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT +#![allow(deprecated)] + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +use crate::NavigationPage; +use crate::{PreferencesPage, Toast, Window}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwPreferencesWindow")] + pub struct PreferencesWindow(Object) @extends Window, gtk::Window, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager; + + match fn { + type_ => || ffi::adw_preferences_window_get_type(), + } +} + +impl PreferencesWindow { + pub const NONE: Option<&'static PreferencesWindow> = None; + + #[doc(alias = "adw_preferences_window_new")] + pub fn new() -> PreferencesWindow { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_preferences_window_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`PreferencesWindow`] objects. + /// + /// This method returns an instance of [`PreferencesWindowBuilder`](crate::builders::PreferencesWindowBuilder) which can be used to create [`PreferencesWindow`] objects. + pub fn builder() -> PreferencesWindowBuilder { + PreferencesWindowBuilder::new() + } +} + +impl Default for PreferencesWindow { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`PreferencesWindow`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct PreferencesWindowBuilder { + builder: glib::object::ObjectBuilder<'static, PreferencesWindow>, +} + +impl PreferencesWindowBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg_attr(feature = "v1_4", deprecated = "Since 1.4")] + pub fn can_navigate_back(self, can_navigate_back: bool) -> Self { + Self { + builder: self + .builder + .property("can-navigate-back", can_navigate_back), + } + } + + pub fn search_enabled(self, search_enabled: bool) -> Self { + Self { + builder: self.builder.property("search-enabled", search_enabled), + } + } + + pub fn visible_page(self, visible_page: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("visible-page", visible_page.clone().upcast()), + } + } + + pub fn visible_page_name(self, visible_page_name: impl Into) -> Self { + Self { + builder: self + .builder + .property("visible-page-name", visible_page_name.into()), + } + } + + pub fn content(self, content: &impl IsA) -> Self { + Self { + builder: self.builder.property("content", content.clone().upcast()), + } + } + + pub fn application(self, application: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("application", application.clone().upcast()), + } + } + + pub fn decorated(self, decorated: bool) -> Self { + Self { + builder: self.builder.property("decorated", decorated), + } + } + + pub fn default_height(self, default_height: i32) -> Self { + Self { + builder: self.builder.property("default-height", default_height), + } + } + + pub fn default_widget(self, default_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("default-widget", default_widget.clone().upcast()), + } + } + + pub fn default_width(self, default_width: i32) -> Self { + Self { + builder: self.builder.property("default-width", default_width), + } + } + + pub fn deletable(self, deletable: bool) -> Self { + Self { + builder: self.builder.property("deletable", deletable), + } + } + + pub fn destroy_with_parent(self, destroy_with_parent: bool) -> Self { + Self { + builder: self + .builder + .property("destroy-with-parent", destroy_with_parent), + } + } + + pub fn display(self, display: &gdk::Display) -> Self { + Self { + builder: self.builder.property("display", display.clone()), + } + } + + pub fn focus_visible(self, focus_visible: bool) -> Self { + Self { + builder: self.builder.property("focus-visible", focus_visible), + } + } + + pub fn focus_widget(self, focus_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("focus-widget", focus_widget.clone().upcast()), + } + } + + pub fn fullscreened(self, fullscreened: bool) -> Self { + Self { + builder: self.builder.property("fullscreened", fullscreened), + } + } + + #[cfg(any(feature = "gtk_v4_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "gtk_v4_2")))] + pub fn handle_menubar_accel(self, handle_menubar_accel: bool) -> Self { + Self { + builder: self + .builder + .property("handle-menubar-accel", handle_menubar_accel), + } + } + + pub fn hide_on_close(self, hide_on_close: bool) -> Self { + Self { + builder: self.builder.property("hide-on-close", hide_on_close), + } + } + + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn maximized(self, maximized: bool) -> Self { + Self { + builder: self.builder.property("maximized", maximized), + } + } + + pub fn mnemonics_visible(self, mnemonics_visible: bool) -> Self { + Self { + builder: self + .builder + .property("mnemonics-visible", mnemonics_visible), + } + } + + pub fn modal(self, modal: bool) -> Self { + Self { + builder: self.builder.property("modal", modal), + } + } + + pub fn resizable(self, resizable: bool) -> Self { + Self { + builder: self.builder.property("resizable", resizable), + } + } + + pub fn startup_id(self, startup_id: impl Into) -> Self { + Self { + builder: self.builder.property("startup-id", startup_id.into()), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "gtk_v4_6", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "gtk_v4_6")))] + pub fn titlebar(self, titlebar: &impl IsA) -> Self { + Self { + builder: self.builder.property("titlebar", titlebar.clone().upcast()), + } + } + + pub fn transient_for(self, transient_for: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("transient-for", transient_for.clone().upcast()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`PreferencesWindow`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> PreferencesWindow { + self.builder.build() + } +} + +pub trait PreferencesWindowExt: 'static { + #[doc(alias = "adw_preferences_window_add")] + fn add(&self, page: &impl IsA); + + #[doc(alias = "adw_preferences_window_add_toast")] + fn add_toast(&self, toast: Toast); + + #[cfg_attr(feature = "v1_4", deprecated = "Since 1.4")] + #[allow(deprecated)] + #[doc(alias = "adw_preferences_window_close_subpage")] + fn close_subpage(&self); + + #[cfg_attr(feature = "v1_4", deprecated = "Since 1.4")] + #[allow(deprecated)] + #[doc(alias = "adw_preferences_window_get_can_navigate_back")] + #[doc(alias = "get_can_navigate_back")] + fn can_navigate_back(&self) -> bool; + + #[doc(alias = "adw_preferences_window_get_search_enabled")] + #[doc(alias = "get_search_enabled")] + fn is_search_enabled(&self) -> bool; + + #[doc(alias = "adw_preferences_window_get_visible_page")] + #[doc(alias = "get_visible_page")] + fn visible_page(&self) -> Option; + + #[doc(alias = "adw_preferences_window_get_visible_page_name")] + #[doc(alias = "get_visible_page_name")] + fn visible_page_name(&self) -> Option; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_preferences_window_pop_subpage")] + fn pop_subpage(&self) -> bool; + + #[cfg_attr(feature = "v1_4", deprecated = "Since 1.4")] + #[allow(deprecated)] + #[doc(alias = "adw_preferences_window_present_subpage")] + fn present_subpage(&self, subpage: &impl IsA); + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_preferences_window_push_subpage")] + fn push_subpage(&self, page: &impl IsA); + + #[doc(alias = "adw_preferences_window_remove")] + fn remove(&self, page: &impl IsA); + + #[cfg_attr(feature = "v1_4", deprecated = "Since 1.4")] + #[allow(deprecated)] + #[doc(alias = "adw_preferences_window_set_can_navigate_back")] + fn set_can_navigate_back(&self, can_navigate_back: bool); + + #[doc(alias = "adw_preferences_window_set_search_enabled")] + fn set_search_enabled(&self, search_enabled: bool); + + #[doc(alias = "adw_preferences_window_set_visible_page")] + fn set_visible_page(&self, page: &impl IsA); + + #[doc(alias = "adw_preferences_window_set_visible_page_name")] + fn set_visible_page_name(&self, name: &str); + + #[cfg_attr(feature = "v1_4", deprecated = "Since 1.4")] + #[doc(alias = "can-navigate-back")] + fn connect_can_navigate_back_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "search-enabled")] + fn connect_search_enabled_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "visible-page")] + fn connect_visible_page_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "visible-page-name")] + fn connect_visible_page_name_notify(&self, f: F) -> SignalHandlerId; +} + +impl> PreferencesWindowExt for O { + fn add(&self, page: &impl IsA) { + unsafe { + ffi::adw_preferences_window_add( + self.as_ref().to_glib_none().0, + page.as_ref().to_glib_none().0, + ); + } + } + + fn add_toast(&self, toast: Toast) { + unsafe { + ffi::adw_preferences_window_add_toast( + self.as_ref().to_glib_none().0, + toast.into_glib_ptr(), + ); + } + } + + #[allow(deprecated)] + fn close_subpage(&self) { + unsafe { + ffi::adw_preferences_window_close_subpage(self.as_ref().to_glib_none().0); + } + } + + #[allow(deprecated)] + fn can_navigate_back(&self) -> bool { + unsafe { + from_glib(ffi::adw_preferences_window_get_can_navigate_back( + self.as_ref().to_glib_none().0, + )) + } + } + + fn is_search_enabled(&self) -> bool { + unsafe { + from_glib(ffi::adw_preferences_window_get_search_enabled( + self.as_ref().to_glib_none().0, + )) + } + } + + fn visible_page(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_preferences_window_get_visible_page( + self.as_ref().to_glib_none().0, + )) + } + } + + fn visible_page_name(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_preferences_window_get_visible_page_name( + self.as_ref().to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn pop_subpage(&self) -> bool { + unsafe { + from_glib(ffi::adw_preferences_window_pop_subpage( + self.as_ref().to_glib_none().0, + )) + } + } + + #[allow(deprecated)] + fn present_subpage(&self, subpage: &impl IsA) { + unsafe { + ffi::adw_preferences_window_present_subpage( + self.as_ref().to_glib_none().0, + subpage.as_ref().to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn push_subpage(&self, page: &impl IsA) { + unsafe { + ffi::adw_preferences_window_push_subpage( + self.as_ref().to_glib_none().0, + page.as_ref().to_glib_none().0, + ); + } + } + + fn remove(&self, page: &impl IsA) { + unsafe { + ffi::adw_preferences_window_remove( + self.as_ref().to_glib_none().0, + page.as_ref().to_glib_none().0, + ); + } + } + + #[allow(deprecated)] + fn set_can_navigate_back(&self, can_navigate_back: bool) { + unsafe { + ffi::adw_preferences_window_set_can_navigate_back( + self.as_ref().to_glib_none().0, + can_navigate_back.into_glib(), + ); + } + } + + fn set_search_enabled(&self, search_enabled: bool) { + unsafe { + ffi::adw_preferences_window_set_search_enabled( + self.as_ref().to_glib_none().0, + search_enabled.into_glib(), + ); + } + } + + fn set_visible_page(&self, page: &impl IsA) { + unsafe { + ffi::adw_preferences_window_set_visible_page( + self.as_ref().to_glib_none().0, + page.as_ref().to_glib_none().0, + ); + } + } + + fn set_visible_page_name(&self, name: &str) { + unsafe { + ffi::adw_preferences_window_set_visible_page_name( + self.as_ref().to_glib_none().0, + name.to_glib_none().0, + ); + } + } + + fn connect_can_navigate_back_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_can_navigate_back_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesWindow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::can-navigate-back\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_can_navigate_back_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_search_enabled_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_search_enabled_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesWindow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::search-enabled\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_search_enabled_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_visible_page_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_visible_page_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesWindow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::visible-page\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_visible_page_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_visible_page_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_visible_page_name_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwPreferencesWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(PreferencesWindow::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::visible-page-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_visible_page_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for PreferencesWindow { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("PreferencesWindow") + } +} diff --git a/libadwaita-0.4.4/src/auto/property_animation_target.rs b/libadwaita-0.4.4/src/auto/property_animation_target.rs new file mode 100644 index 0000000..bfa1ee9 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/property_animation_target.rs @@ -0,0 +1,73 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::AnimationTarget; +use glib::{prelude::*, translate::*}; +use std::fmt; + +glib::wrapper! { + #[doc(alias = "AdwPropertyAnimationTarget")] + pub struct PropertyAnimationTarget(Object) @extends AnimationTarget; + + match fn { + type_ => || ffi::adw_property_animation_target_get_type(), + } +} + +impl PropertyAnimationTarget { + #[doc(alias = "adw_property_animation_target_new")] + pub fn new(object: &impl IsA, property_name: &str) -> PropertyAnimationTarget { + assert_initialized_main_thread!(); + unsafe { + AnimationTarget::from_glib_full(ffi::adw_property_animation_target_new( + object.as_ref().to_glib_none().0, + property_name.to_glib_none().0, + )) + .unsafe_cast() + } + } + + #[doc(alias = "adw_property_animation_target_new_for_pspec")] + #[doc(alias = "new_for_pspec")] + pub fn for_pspec( + object: &impl IsA, + pspec: impl AsRef, + ) -> PropertyAnimationTarget { + assert_initialized_main_thread!(); + unsafe { + AnimationTarget::from_glib_full(ffi::adw_property_animation_target_new_for_pspec( + object.as_ref().to_glib_none().0, + pspec.as_ref().to_glib_none().0, + )) + .unsafe_cast() + } + } + + #[doc(alias = "adw_property_animation_target_get_object")] + #[doc(alias = "get_object")] + pub fn object(&self) -> glib::Object { + unsafe { + from_glib_none(ffi::adw_property_animation_target_get_object( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_property_animation_target_get_pspec")] + #[doc(alias = "get_pspec")] + pub fn pspec(&self) -> glib::ParamSpec { + unsafe { + from_glib_none(ffi::adw_property_animation_target_get_pspec( + self.to_glib_none().0, + )) + } + } +} + +impl fmt::Display for PropertyAnimationTarget { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("PropertyAnimationTarget") + } +} diff --git a/libadwaita-0.4.4/src/auto/spin_row.rs b/libadwaita-0.4.4/src/auto/spin_row.rs new file mode 100644 index 0000000..d13efd9 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/spin_row.rs @@ -0,0 +1,864 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{ActionRow, PreferencesRow}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwSpinRow")] + pub struct SpinRow(Object) @extends ActionRow, PreferencesRow, gtk::ListBoxRow, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable, gtk::Editable; + + match fn { + type_ => || ffi::adw_spin_row_get_type(), + } +} + +impl SpinRow { + #[doc(alias = "adw_spin_row_new")] + pub fn new( + adjustment: Option<&impl IsA>, + climb_rate: f64, + digits: u32, + ) -> SpinRow { + assert_initialized_main_thread!(); + unsafe { + gtk::Widget::from_glib_none(ffi::adw_spin_row_new( + adjustment.map(|p| p.as_ref()).to_glib_none().0, + climb_rate, + digits, + )) + .unsafe_cast() + } + } + + #[doc(alias = "adw_spin_row_new_with_range")] + #[doc(alias = "new_with_range")] + pub fn with_range(min: f64, max: f64, step: f64) -> SpinRow { + assert_initialized_main_thread!(); + unsafe { + gtk::Widget::from_glib_none(ffi::adw_spin_row_new_with_range(min, max, step)) + .unsafe_cast() + } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`SpinRow`] objects. + /// + /// This method returns an instance of [`SpinRowBuilder`](crate::builders::SpinRowBuilder) which can be used to create [`SpinRow`] objects. + pub fn builder() -> SpinRowBuilder { + SpinRowBuilder::new() + } + + #[doc(alias = "adw_spin_row_configure")] + pub fn configure( + &self, + adjustment: Option<&impl IsA>, + climb_rate: f64, + digits: u32, + ) { + unsafe { + ffi::adw_spin_row_configure( + self.to_glib_none().0, + adjustment.map(|p| p.as_ref()).to_glib_none().0, + climb_rate, + digits, + ); + } + } + + #[doc(alias = "adw_spin_row_get_adjustment")] + #[doc(alias = "get_adjustment")] + pub fn adjustment(&self) -> gtk::Adjustment { + unsafe { from_glib_none(ffi::adw_spin_row_get_adjustment(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_spin_row_get_climb_rate")] + #[doc(alias = "get_climb_rate")] + pub fn climb_rate(&self) -> f64 { + unsafe { ffi::adw_spin_row_get_climb_rate(self.to_glib_none().0) } + } + + #[doc(alias = "adw_spin_row_get_digits")] + #[doc(alias = "get_digits")] + pub fn digits(&self) -> u32 { + unsafe { ffi::adw_spin_row_get_digits(self.to_glib_none().0) } + } + + #[doc(alias = "adw_spin_row_get_numeric")] + #[doc(alias = "get_numeric")] + pub fn is_numeric(&self) -> bool { + unsafe { from_glib(ffi::adw_spin_row_get_numeric(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_spin_row_get_snap_to_ticks")] + #[doc(alias = "get_snap_to_ticks")] + pub fn snaps_to_ticks(&self) -> bool { + unsafe { from_glib(ffi::adw_spin_row_get_snap_to_ticks(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_spin_row_get_update_policy")] + #[doc(alias = "get_update_policy")] + pub fn update_policy(&self) -> gtk::SpinButtonUpdatePolicy { + unsafe { from_glib(ffi::adw_spin_row_get_update_policy(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_spin_row_get_value")] + #[doc(alias = "get_value")] + pub fn value(&self) -> f64 { + unsafe { ffi::adw_spin_row_get_value(self.to_glib_none().0) } + } + + #[doc(alias = "adw_spin_row_get_wrap")] + #[doc(alias = "get_wrap")] + pub fn wraps(&self) -> bool { + unsafe { from_glib(ffi::adw_spin_row_get_wrap(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_spin_row_set_adjustment")] + pub fn set_adjustment(&self, adjustment: Option<&impl IsA>) { + unsafe { + ffi::adw_spin_row_set_adjustment( + self.to_glib_none().0, + adjustment.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_spin_row_set_climb_rate")] + pub fn set_climb_rate(&self, climb_rate: f64) { + unsafe { + ffi::adw_spin_row_set_climb_rate(self.to_glib_none().0, climb_rate); + } + } + + #[doc(alias = "adw_spin_row_set_digits")] + pub fn set_digits(&self, digits: u32) { + unsafe { + ffi::adw_spin_row_set_digits(self.to_glib_none().0, digits); + } + } + + #[doc(alias = "adw_spin_row_set_numeric")] + pub fn set_numeric(&self, numeric: bool) { + unsafe { + ffi::adw_spin_row_set_numeric(self.to_glib_none().0, numeric.into_glib()); + } + } + + #[doc(alias = "adw_spin_row_set_snap_to_ticks")] + pub fn set_snap_to_ticks(&self, snap_to_ticks: bool) { + unsafe { + ffi::adw_spin_row_set_snap_to_ticks(self.to_glib_none().0, snap_to_ticks.into_glib()); + } + } + + #[doc(alias = "adw_spin_row_set_update_policy")] + pub fn set_update_policy(&self, policy: gtk::SpinButtonUpdatePolicy) { + unsafe { + ffi::adw_spin_row_set_update_policy(self.to_glib_none().0, policy.into_glib()); + } + } + + #[doc(alias = "adw_spin_row_set_value")] + pub fn set_value(&self, value: f64) { + unsafe { + ffi::adw_spin_row_set_value(self.to_glib_none().0, value); + } + } + + #[doc(alias = "adw_spin_row_set_wrap")] + pub fn set_wrap(&self, wrap: bool) { + unsafe { + ffi::adw_spin_row_set_wrap(self.to_glib_none().0, wrap.into_glib()); + } + } + + #[doc(alias = "adw_spin_row_update")] + pub fn update(&self) { + unsafe { + ffi::adw_spin_row_update(self.to_glib_none().0); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "output")] + pub fn connect_output bool + 'static>(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn output_trampoline bool + 'static>( + this: *mut ffi::AdwSpinRow, + f: glib::ffi::gpointer, + ) -> glib::ffi::gboolean { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)).into_glib() + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"output\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + output_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "wrapped")] + pub fn connect_wrapped(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn wrapped_trampoline( + this: *mut ffi::AdwSpinRow, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"wrapped\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + wrapped_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adjustment")] + pub fn connect_adjustment_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_adjustment_trampoline( + this: *mut ffi::AdwSpinRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::adjustment\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_adjustment_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "climb-rate")] + pub fn connect_climb_rate_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_climb_rate_trampoline( + this: *mut ffi::AdwSpinRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::climb-rate\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_climb_rate_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "digits")] + pub fn connect_digits_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_digits_trampoline( + this: *mut ffi::AdwSpinRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::digits\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_digits_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "numeric")] + pub fn connect_numeric_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_numeric_trampoline( + this: *mut ffi::AdwSpinRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::numeric\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_numeric_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "snap-to-ticks")] + pub fn connect_snap_to_ticks_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_snap_to_ticks_trampoline( + this: *mut ffi::AdwSpinRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::snap-to-ticks\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_snap_to_ticks_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "update-policy")] + pub fn connect_update_policy_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_update_policy_trampoline( + this: *mut ffi::AdwSpinRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::update-policy\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_update_policy_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "value")] + pub fn connect_value_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_value_trampoline( + this: *mut ffi::AdwSpinRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::value\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_value_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "wrap")] + pub fn connect_wrap_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_wrap_trampoline( + this: *mut ffi::AdwSpinRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::wrap\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_wrap_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl Default for SpinRow { + fn default() -> Self { + glib::object::Object::new::() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`SpinRow`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct SpinRowBuilder { + builder: glib::object::ObjectBuilder<'static, SpinRow>, +} + +impl SpinRowBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn adjustment(self, adjustment: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("adjustment", adjustment.clone().upcast()), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn climb_rate(self, climb_rate: f64) -> Self { + Self { + builder: self.builder.property("climb-rate", climb_rate), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn digits(self, digits: u32) -> Self { + Self { + builder: self.builder.property("digits", digits), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn numeric(self, numeric: bool) -> Self { + Self { + builder: self.builder.property("numeric", numeric), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn snap_to_ticks(self, snap_to_ticks: bool) -> Self { + Self { + builder: self.builder.property("snap-to-ticks", snap_to_ticks), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn update_policy(self, update_policy: gtk::SpinButtonUpdatePolicy) -> Self { + Self { + builder: self.builder.property("update-policy", update_policy), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn value(self, value: f64) -> Self { + Self { + builder: self.builder.property("value", value), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn wrap(self, wrap: bool) -> Self { + Self { + builder: self.builder.property("wrap", wrap), + } + } + + pub fn activatable_widget(self, activatable_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("activatable-widget", activatable_widget.clone().upcast()), + } + } + + #[cfg_attr(feature = "v1_3", deprecated = "Since 1.3")] + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn subtitle(self, subtitle: impl Into) -> Self { + Self { + builder: self.builder.property("subtitle", subtitle.into()), + } + } + + pub fn subtitle_lines(self, subtitle_lines: i32) -> Self { + Self { + builder: self.builder.property("subtitle-lines", subtitle_lines), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn subtitle_selectable(self, subtitle_selectable: bool) -> Self { + Self { + builder: self + .builder + .property("subtitle-selectable", subtitle_selectable), + } + } + + pub fn title_lines(self, title_lines: i32) -> Self { + Self { + builder: self.builder.property("title-lines", title_lines), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + pub fn title_selectable(self, title_selectable: bool) -> Self { + Self { + builder: self.builder.property("title-selectable", title_selectable), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn use_markup(self, use_markup: bool) -> Self { + Self { + builder: self.builder.property("use-markup", use_markup), + } + } + + pub fn use_underline(self, use_underline: bool) -> Self { + Self { + builder: self.builder.property("use-underline", use_underline), + } + } + + pub fn activatable(self, activatable: bool) -> Self { + Self { + builder: self.builder.property("activatable", activatable), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn selectable(self, selectable: bool) -> Self { + Self { + builder: self.builder.property("selectable", selectable), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn action_name(self, action_name: impl Into) -> Self { + Self { + builder: self.builder.property("action-name", action_name.into()), + } + } + + pub fn action_target(self, action_target: &glib::Variant) -> Self { + Self { + builder: self + .builder + .property("action-target", action_target.clone()), + } + } + + pub fn editable(self, editable: bool) -> Self { + Self { + builder: self.builder.property("editable", editable), + } + } + + pub fn enable_undo(self, enable_undo: bool) -> Self { + Self { + builder: self.builder.property("enable-undo", enable_undo), + } + } + + pub fn max_width_chars(self, max_width_chars: i32) -> Self { + Self { + builder: self.builder.property("max-width-chars", max_width_chars), + } + } + + pub fn text(self, text: impl Into) -> Self { + Self { + builder: self.builder.property("text", text.into()), + } + } + + pub fn width_chars(self, width_chars: i32) -> Self { + Self { + builder: self.builder.property("width-chars", width_chars), + } + } + + pub fn xalign(self, xalign: f32) -> Self { + Self { + builder: self.builder.property("xalign", xalign), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`SpinRow`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> SpinRow { + self.builder.build() + } +} + +impl fmt::Display for SpinRow { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("SpinRow") + } +} diff --git a/libadwaita-0.4.4/src/auto/split_button.rs b/libadwaita-0.4.4/src/auto/split_button.rs new file mode 100644 index 0000000..bbe2948 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/split_button.rs @@ -0,0 +1,757 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwSplitButton")] + pub struct SplitButton(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable; + + match fn { + type_ => || ffi::adw_split_button_get_type(), + } +} + +impl SplitButton { + #[doc(alias = "adw_split_button_new")] + pub fn new() -> SplitButton { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_split_button_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`SplitButton`] objects. + /// + /// This method returns an instance of [`SplitButtonBuilder`](crate::builders::SplitButtonBuilder) which can be used to create [`SplitButton`] objects. + pub fn builder() -> SplitButtonBuilder { + SplitButtonBuilder::new() + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_split_button_get_can_shrink")] + #[doc(alias = "get_can_shrink")] + pub fn can_shrink(&self) -> bool { + unsafe { from_glib(ffi::adw_split_button_get_can_shrink(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_split_button_get_child")] + #[doc(alias = "get_child")] + pub fn child(&self) -> Option { + unsafe { from_glib_none(ffi::adw_split_button_get_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_split_button_get_direction")] + #[doc(alias = "get_direction")] + pub fn direction(&self) -> gtk::ArrowType { + unsafe { from_glib(ffi::adw_split_button_get_direction(self.to_glib_none().0)) } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_split_button_get_dropdown_tooltip")] + #[doc(alias = "get_dropdown_tooltip")] + pub fn dropdown_tooltip(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_split_button_get_dropdown_tooltip( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_split_button_get_icon_name")] + #[doc(alias = "get_icon_name")] + pub fn icon_name(&self) -> Option { + unsafe { from_glib_none(ffi::adw_split_button_get_icon_name(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_split_button_get_label")] + #[doc(alias = "get_label")] + pub fn label(&self) -> Option { + unsafe { from_glib_none(ffi::adw_split_button_get_label(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_split_button_get_menu_model")] + #[doc(alias = "get_menu_model")] + pub fn menu_model(&self) -> Option { + unsafe { from_glib_none(ffi::adw_split_button_get_menu_model(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_split_button_get_popover")] + #[doc(alias = "get_popover")] + pub fn popover(&self) -> Option { + unsafe { from_glib_none(ffi::adw_split_button_get_popover(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_split_button_get_use_underline")] + #[doc(alias = "get_use_underline")] + pub fn uses_underline(&self) -> bool { + unsafe { + from_glib(ffi::adw_split_button_get_use_underline( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_split_button_popdown")] + pub fn popdown(&self) { + unsafe { + ffi::adw_split_button_popdown(self.to_glib_none().0); + } + } + + #[doc(alias = "adw_split_button_popup")] + pub fn popup(&self) { + unsafe { + ffi::adw_split_button_popup(self.to_glib_none().0); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_split_button_set_can_shrink")] + pub fn set_can_shrink(&self, can_shrink: bool) { + unsafe { + ffi::adw_split_button_set_can_shrink(self.to_glib_none().0, can_shrink.into_glib()); + } + } + + #[doc(alias = "adw_split_button_set_child")] + pub fn set_child(&self, child: Option<&impl IsA>) { + unsafe { + ffi::adw_split_button_set_child( + self.to_glib_none().0, + child.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_split_button_set_direction")] + pub fn set_direction(&self, direction: gtk::ArrowType) { + unsafe { + ffi::adw_split_button_set_direction(self.to_glib_none().0, direction.into_glib()); + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_split_button_set_dropdown_tooltip")] + pub fn set_dropdown_tooltip(&self, tooltip: &str) { + unsafe { + ffi::adw_split_button_set_dropdown_tooltip( + self.to_glib_none().0, + tooltip.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_split_button_set_icon_name")] + pub fn set_icon_name(&self, icon_name: &str) { + unsafe { + ffi::adw_split_button_set_icon_name(self.to_glib_none().0, icon_name.to_glib_none().0); + } + } + + #[doc(alias = "adw_split_button_set_label")] + pub fn set_label(&self, label: &str) { + unsafe { + ffi::adw_split_button_set_label(self.to_glib_none().0, label.to_glib_none().0); + } + } + + #[doc(alias = "adw_split_button_set_menu_model")] + pub fn set_menu_model(&self, menu_model: Option<&impl IsA>) { + unsafe { + ffi::adw_split_button_set_menu_model( + self.to_glib_none().0, + menu_model.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_split_button_set_popover")] + pub fn set_popover(&self, popover: Option<&impl IsA>) { + unsafe { + ffi::adw_split_button_set_popover( + self.to_glib_none().0, + popover.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_split_button_set_use_underline")] + pub fn set_use_underline(&self, use_underline: bool) { + unsafe { + ffi::adw_split_button_set_use_underline( + self.to_glib_none().0, + use_underline.into_glib(), + ); + } + } + + #[doc(alias = "activate")] + pub fn connect_activate(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn activate_trampoline( + this: *mut ffi::AdwSplitButton, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"activate\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + activate_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + pub fn emit_activate(&self) { + self.emit_by_name::<()>("activate", &[]); + } + + #[doc(alias = "clicked")] + pub fn connect_clicked(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn clicked_trampoline( + this: *mut ffi::AdwSplitButton, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"clicked\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + clicked_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + pub fn emit_clicked(&self) { + self.emit_by_name::<()>("clicked", &[]); + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "can-shrink")] + pub fn connect_can_shrink_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_can_shrink_trampoline( + this: *mut ffi::AdwSplitButton, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::can-shrink\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_can_shrink_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "child")] + pub fn connect_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_child_trampoline( + this: *mut ffi::AdwSplitButton, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "direction")] + pub fn connect_direction_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_direction_trampoline( + this: *mut ffi::AdwSplitButton, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::direction\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_direction_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "dropdown-tooltip")] + pub fn connect_dropdown_tooltip_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_dropdown_tooltip_trampoline( + this: *mut ffi::AdwSplitButton, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::dropdown-tooltip\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_dropdown_tooltip_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "icon-name")] + pub fn connect_icon_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_icon_name_trampoline( + this: *mut ffi::AdwSplitButton, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::icon-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_icon_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "label")] + pub fn connect_label_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_label_trampoline( + this: *mut ffi::AdwSplitButton, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::label\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_label_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "menu-model")] + pub fn connect_menu_model_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_menu_model_trampoline( + this: *mut ffi::AdwSplitButton, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::menu-model\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_menu_model_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "popover")] + pub fn connect_popover_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_popover_trampoline( + this: *mut ffi::AdwSplitButton, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::popover\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_popover_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "use-underline")] + pub fn connect_use_underline_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_use_underline_trampoline( + this: *mut ffi::AdwSplitButton, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::use-underline\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_use_underline_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for SplitButton { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`SplitButton`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct SplitButtonBuilder { + builder: glib::object::ObjectBuilder<'static, SplitButton>, +} + +impl SplitButtonBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn can_shrink(self, can_shrink: bool) -> Self { + Self { + builder: self.builder.property("can-shrink", can_shrink), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn direction(self, direction: gtk::ArrowType) -> Self { + Self { + builder: self.builder.property("direction", direction), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn dropdown_tooltip(self, dropdown_tooltip: impl Into) -> Self { + Self { + builder: self + .builder + .property("dropdown-tooltip", dropdown_tooltip.into()), + } + } + + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn label(self, label: impl Into) -> Self { + Self { + builder: self.builder.property("label", label.into()), + } + } + + pub fn menu_model(self, menu_model: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("menu-model", menu_model.clone().upcast()), + } + } + + pub fn popover(self, popover: &impl IsA) -> Self { + Self { + builder: self.builder.property("popover", popover.clone().upcast()), + } + } + + pub fn use_underline(self, use_underline: bool) -> Self { + Self { + builder: self.builder.property("use-underline", use_underline), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn action_name(self, action_name: impl Into) -> Self { + Self { + builder: self.builder.property("action-name", action_name.into()), + } + } + + pub fn action_target(self, action_target: &glib::Variant) -> Self { + Self { + builder: self + .builder + .property("action-target", action_target.clone()), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`SplitButton`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> SplitButton { + self.builder.build() + } +} + +impl fmt::Display for SplitButton { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("SplitButton") + } +} diff --git a/libadwaita-0.4.4/src/auto/spring_animation.rs b/libadwaita-0.4.4/src/auto/spring_animation.rs new file mode 100644 index 0000000..4efe583 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/spring_animation.rs @@ -0,0 +1,451 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{Animation, AnimationTarget, SpringParams}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwSpringAnimation")] + pub struct SpringAnimation(Object) @extends Animation; + + match fn { + type_ => || ffi::adw_spring_animation_get_type(), + } +} + +impl SpringAnimation { + #[doc(alias = "adw_spring_animation_new")] + pub fn new( + widget: &impl IsA, + from: f64, + to: f64, + spring_params: SpringParams, + target: impl IsA, + ) -> SpringAnimation { + skip_assert_initialized!(); + unsafe { + Animation::from_glib_none(ffi::adw_spring_animation_new( + widget.as_ref().to_glib_none().0, + from, + to, + spring_params.into_glib_ptr(), + target.upcast().into_glib_ptr(), + )) + .unsafe_cast() + } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`SpringAnimation`] objects. + /// + /// This method returns an instance of [`SpringAnimationBuilder`](crate::builders::SpringAnimationBuilder) which can be used to create [`SpringAnimation`] objects. + pub fn builder() -> SpringAnimationBuilder { + SpringAnimationBuilder::new() + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_spring_animation_calculate_value")] + pub fn calculate_value(&self, time: u32) -> f64 { + unsafe { ffi::adw_spring_animation_calculate_value(self.to_glib_none().0, time) } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_spring_animation_calculate_velocity")] + pub fn calculate_velocity(&self, time: u32) -> f64 { + unsafe { ffi::adw_spring_animation_calculate_velocity(self.to_glib_none().0, time) } + } + + #[doc(alias = "adw_spring_animation_get_clamp")] + #[doc(alias = "get_clamp")] + pub fn is_clamp(&self) -> bool { + unsafe { from_glib(ffi::adw_spring_animation_get_clamp(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_spring_animation_get_epsilon")] + #[doc(alias = "get_epsilon")] + pub fn epsilon(&self) -> f64 { + unsafe { ffi::adw_spring_animation_get_epsilon(self.to_glib_none().0) } + } + + #[doc(alias = "adw_spring_animation_get_estimated_duration")] + #[doc(alias = "get_estimated_duration")] + pub fn estimated_duration(&self) -> u32 { + unsafe { ffi::adw_spring_animation_get_estimated_duration(self.to_glib_none().0) } + } + + #[doc(alias = "adw_spring_animation_get_initial_velocity")] + #[doc(alias = "get_initial_velocity")] + pub fn initial_velocity(&self) -> f64 { + unsafe { ffi::adw_spring_animation_get_initial_velocity(self.to_glib_none().0) } + } + + #[doc(alias = "adw_spring_animation_get_spring_params")] + #[doc(alias = "get_spring_params")] + pub fn spring_params(&self) -> SpringParams { + unsafe { + from_glib_none(ffi::adw_spring_animation_get_spring_params( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_spring_animation_get_value_from")] + #[doc(alias = "get_value_from")] + pub fn value_from(&self) -> f64 { + unsafe { ffi::adw_spring_animation_get_value_from(self.to_glib_none().0) } + } + + #[doc(alias = "adw_spring_animation_get_value_to")] + #[doc(alias = "get_value_to")] + pub fn value_to(&self) -> f64 { + unsafe { ffi::adw_spring_animation_get_value_to(self.to_glib_none().0) } + } + + #[doc(alias = "adw_spring_animation_get_velocity")] + #[doc(alias = "get_velocity")] + pub fn velocity(&self) -> f64 { + unsafe { ffi::adw_spring_animation_get_velocity(self.to_glib_none().0) } + } + + #[doc(alias = "adw_spring_animation_set_clamp")] + pub fn set_clamp(&self, clamp: bool) { + unsafe { + ffi::adw_spring_animation_set_clamp(self.to_glib_none().0, clamp.into_glib()); + } + } + + #[doc(alias = "adw_spring_animation_set_epsilon")] + pub fn set_epsilon(&self, epsilon: f64) { + unsafe { + ffi::adw_spring_animation_set_epsilon(self.to_glib_none().0, epsilon); + } + } + + #[doc(alias = "adw_spring_animation_set_initial_velocity")] + pub fn set_initial_velocity(&self, velocity: f64) { + unsafe { + ffi::adw_spring_animation_set_initial_velocity(self.to_glib_none().0, velocity); + } + } + + #[doc(alias = "adw_spring_animation_set_spring_params")] + pub fn set_spring_params(&self, spring_params: &SpringParams) { + unsafe { + ffi::adw_spring_animation_set_spring_params( + self.to_glib_none().0, + spring_params.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_spring_animation_set_value_from")] + pub fn set_value_from(&self, value: f64) { + unsafe { + ffi::adw_spring_animation_set_value_from(self.to_glib_none().0, value); + } + } + + #[doc(alias = "adw_spring_animation_set_value_to")] + pub fn set_value_to(&self, value: f64) { + unsafe { + ffi::adw_spring_animation_set_value_to(self.to_glib_none().0, value); + } + } + + #[doc(alias = "clamp")] + pub fn connect_clamp_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_clamp_trampoline( + this: *mut ffi::AdwSpringAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::clamp\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_clamp_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "epsilon")] + pub fn connect_epsilon_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_epsilon_trampoline( + this: *mut ffi::AdwSpringAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::epsilon\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_epsilon_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "estimated-duration")] + pub fn connect_estimated_duration_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_estimated_duration_trampoline< + F: Fn(&SpringAnimation) + 'static, + >( + this: *mut ffi::AdwSpringAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::estimated-duration\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_estimated_duration_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "initial-velocity")] + pub fn connect_initial_velocity_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_initial_velocity_trampoline< + F: Fn(&SpringAnimation) + 'static, + >( + this: *mut ffi::AdwSpringAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::initial-velocity\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_initial_velocity_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "spring-params")] + pub fn connect_spring_params_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_spring_params_trampoline( + this: *mut ffi::AdwSpringAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::spring-params\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_spring_params_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "value-from")] + pub fn connect_value_from_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_value_from_trampoline( + this: *mut ffi::AdwSpringAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::value-from\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_value_from_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "value-to")] + pub fn connect_value_to_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_value_to_trampoline( + this: *mut ffi::AdwSpringAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::value-to\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_value_to_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "velocity")] + pub fn connect_velocity_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_velocity_trampoline( + this: *mut ffi::AdwSpringAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::velocity\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_velocity_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for SpringAnimation { + fn default() -> Self { + glib::object::Object::new::() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`SpringAnimation`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct SpringAnimationBuilder { + builder: glib::object::ObjectBuilder<'static, SpringAnimation>, +} + +impl SpringAnimationBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn clamp(self, clamp: bool) -> Self { + Self { + builder: self.builder.property("clamp", clamp), + } + } + + pub fn epsilon(self, epsilon: f64) -> Self { + Self { + builder: self.builder.property("epsilon", epsilon), + } + } + + pub fn initial_velocity(self, initial_velocity: f64) -> Self { + Self { + builder: self.builder.property("initial-velocity", initial_velocity), + } + } + + pub fn spring_params(self, spring_params: &SpringParams) -> Self { + Self { + builder: self + .builder + .property("spring-params", spring_params.clone()), + } + } + + pub fn value_from(self, value_from: f64) -> Self { + Self { + builder: self.builder.property("value-from", value_from), + } + } + + pub fn value_to(self, value_to: f64) -> Self { + Self { + builder: self.builder.property("value-to", value_to), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn follow_enable_animations_setting(self, follow_enable_animations_setting: bool) -> Self { + Self { + builder: self.builder.property( + "follow-enable-animations-setting", + follow_enable_animations_setting, + ), + } + } + + pub fn target(self, target: &impl IsA) -> Self { + Self { + builder: self.builder.property("target", target.clone().upcast()), + } + } + + pub fn widget(self, widget: &impl IsA) -> Self { + Self { + builder: self.builder.property("widget", widget.clone().upcast()), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`SpringAnimation`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> SpringAnimation { + self.builder.build() + } +} + +impl fmt::Display for SpringAnimation { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("SpringAnimation") + } +} diff --git a/libadwaita-0.4.4/src/auto/spring_params.rs b/libadwaita-0.4.4/src/auto/spring_params.rs new file mode 100644 index 0000000..6c3ae0b --- /dev/null +++ b/libadwaita-0.4.4/src/auto/spring_params.rs @@ -0,0 +1,55 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::translate::*; + +glib::wrapper! { + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct SpringParams(Shared); + + match fn { + ref => |ptr| ffi::adw_spring_params_ref(ptr), + unref => |ptr| ffi::adw_spring_params_unref(ptr), + type_ => || ffi::adw_spring_params_get_type(), + } +} + +impl SpringParams { + #[doc(alias = "adw_spring_params_new")] + pub fn new(damping_ratio: f64, mass: f64, stiffness: f64) -> SpringParams { + assert_initialized_main_thread!(); + unsafe { from_glib_full(ffi::adw_spring_params_new(damping_ratio, mass, stiffness)) } + } + + #[doc(alias = "adw_spring_params_new_full")] + pub fn new_full(damping: f64, mass: f64, stiffness: f64) -> SpringParams { + assert_initialized_main_thread!(); + unsafe { from_glib_full(ffi::adw_spring_params_new_full(damping, mass, stiffness)) } + } + + #[doc(alias = "adw_spring_params_get_damping")] + #[doc(alias = "get_damping")] + pub fn damping(&self) -> f64 { + unsafe { ffi::adw_spring_params_get_damping(self.to_glib_none().0) } + } + + #[doc(alias = "adw_spring_params_get_damping_ratio")] + #[doc(alias = "get_damping_ratio")] + pub fn damping_ratio(&self) -> f64 { + unsafe { ffi::adw_spring_params_get_damping_ratio(self.to_glib_none().0) } + } + + #[doc(alias = "adw_spring_params_get_mass")] + #[doc(alias = "get_mass")] + pub fn mass(&self) -> f64 { + unsafe { ffi::adw_spring_params_get_mass(self.to_glib_none().0) } + } + + #[doc(alias = "adw_spring_params_get_stiffness")] + #[doc(alias = "get_stiffness")] + pub fn stiffness(&self) -> f64 { + unsafe { ffi::adw_spring_params_get_stiffness(self.to_glib_none().0) } + } +} diff --git a/libadwaita-0.4.4/src/auto/squeezer.rs b/libadwaita-0.4.4/src/auto/squeezer.rs new file mode 100644 index 0000000..a78573e --- /dev/null +++ b/libadwaita-0.4.4/src/auto/squeezer.rs @@ -0,0 +1,747 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{FoldThresholdPolicy, SqueezerPage, SqueezerTransitionType}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwSqueezer")] + pub struct Squeezer(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable; + + match fn { + type_ => || ffi::adw_squeezer_get_type(), + } +} + +impl Squeezer { + #[doc(alias = "adw_squeezer_new")] + pub fn new() -> Squeezer { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_squeezer_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`Squeezer`] objects. + /// + /// This method returns an instance of [`SqueezerBuilder`](crate::builders::SqueezerBuilder) which can be used to create [`Squeezer`] objects. + pub fn builder() -> SqueezerBuilder { + SqueezerBuilder::new() + } + + #[doc(alias = "adw_squeezer_add")] + pub fn add(&self, child: &impl IsA) -> SqueezerPage { + unsafe { + from_glib_none(ffi::adw_squeezer_add( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_squeezer_get_allow_none")] + #[doc(alias = "get_allow_none")] + pub fn allows_none(&self) -> bool { + unsafe { from_glib(ffi::adw_squeezer_get_allow_none(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_squeezer_get_homogeneous")] + #[doc(alias = "get_homogeneous")] + pub fn is_homogeneous(&self) -> bool { + unsafe { from_glib(ffi::adw_squeezer_get_homogeneous(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_squeezer_get_interpolate_size")] + #[doc(alias = "get_interpolate_size")] + pub fn is_interpolate_size(&self) -> bool { + unsafe { + from_glib(ffi::adw_squeezer_get_interpolate_size( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_squeezer_get_page")] + #[doc(alias = "get_page")] + pub fn page(&self, child: &impl IsA) -> SqueezerPage { + unsafe { + from_glib_none(ffi::adw_squeezer_get_page( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_squeezer_get_pages")] + #[doc(alias = "get_pages")] + pub fn pages(&self) -> gtk::SelectionModel { + unsafe { from_glib_full(ffi::adw_squeezer_get_pages(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_squeezer_get_switch_threshold_policy")] + #[doc(alias = "get_switch_threshold_policy")] + pub fn switch_threshold_policy(&self) -> FoldThresholdPolicy { + unsafe { + from_glib(ffi::adw_squeezer_get_switch_threshold_policy( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_squeezer_get_transition_duration")] + #[doc(alias = "get_transition_duration")] + pub fn transition_duration(&self) -> u32 { + unsafe { ffi::adw_squeezer_get_transition_duration(self.to_glib_none().0) } + } + + #[doc(alias = "adw_squeezer_get_transition_running")] + #[doc(alias = "get_transition_running")] + pub fn is_transition_running(&self) -> bool { + unsafe { + from_glib(ffi::adw_squeezer_get_transition_running( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_squeezer_get_transition_type")] + #[doc(alias = "get_transition_type")] + pub fn transition_type(&self) -> SqueezerTransitionType { + unsafe { from_glib(ffi::adw_squeezer_get_transition_type(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_squeezer_get_visible_child")] + #[doc(alias = "get_visible_child")] + pub fn visible_child(&self) -> Option { + unsafe { from_glib_none(ffi::adw_squeezer_get_visible_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_squeezer_get_xalign")] + #[doc(alias = "get_xalign")] + pub fn xalign(&self) -> f32 { + unsafe { ffi::adw_squeezer_get_xalign(self.to_glib_none().0) } + } + + #[doc(alias = "adw_squeezer_get_yalign")] + #[doc(alias = "get_yalign")] + pub fn yalign(&self) -> f32 { + unsafe { ffi::adw_squeezer_get_yalign(self.to_glib_none().0) } + } + + #[doc(alias = "adw_squeezer_remove")] + pub fn remove(&self, child: &impl IsA) { + unsafe { + ffi::adw_squeezer_remove(self.to_glib_none().0, child.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_squeezer_set_allow_none")] + pub fn set_allow_none(&self, allow_none: bool) { + unsafe { + ffi::adw_squeezer_set_allow_none(self.to_glib_none().0, allow_none.into_glib()); + } + } + + #[doc(alias = "adw_squeezer_set_homogeneous")] + pub fn set_homogeneous(&self, homogeneous: bool) { + unsafe { + ffi::adw_squeezer_set_homogeneous(self.to_glib_none().0, homogeneous.into_glib()); + } + } + + #[doc(alias = "adw_squeezer_set_interpolate_size")] + pub fn set_interpolate_size(&self, interpolate_size: bool) { + unsafe { + ffi::adw_squeezer_set_interpolate_size( + self.to_glib_none().0, + interpolate_size.into_glib(), + ); + } + } + + #[doc(alias = "adw_squeezer_set_switch_threshold_policy")] + pub fn set_switch_threshold_policy(&self, policy: FoldThresholdPolicy) { + unsafe { + ffi::adw_squeezer_set_switch_threshold_policy( + self.to_glib_none().0, + policy.into_glib(), + ); + } + } + + #[doc(alias = "adw_squeezer_set_transition_duration")] + pub fn set_transition_duration(&self, duration: u32) { + unsafe { + ffi::adw_squeezer_set_transition_duration(self.to_glib_none().0, duration); + } + } + + #[doc(alias = "adw_squeezer_set_transition_type")] + pub fn set_transition_type(&self, transition: SqueezerTransitionType) { + unsafe { + ffi::adw_squeezer_set_transition_type(self.to_glib_none().0, transition.into_glib()); + } + } + + #[doc(alias = "adw_squeezer_set_xalign")] + pub fn set_xalign(&self, xalign: f32) { + unsafe { + ffi::adw_squeezer_set_xalign(self.to_glib_none().0, xalign); + } + } + + #[doc(alias = "adw_squeezer_set_yalign")] + pub fn set_yalign(&self, yalign: f32) { + unsafe { + ffi::adw_squeezer_set_yalign(self.to_glib_none().0, yalign); + } + } + + #[doc(alias = "allow-none")] + pub fn connect_allow_none_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_allow_none_trampoline( + this: *mut ffi::AdwSqueezer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::allow-none\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_allow_none_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "homogeneous")] + pub fn connect_homogeneous_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_homogeneous_trampoline( + this: *mut ffi::AdwSqueezer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::homogeneous\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_homogeneous_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "interpolate-size")] + pub fn connect_interpolate_size_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_interpolate_size_trampoline( + this: *mut ffi::AdwSqueezer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::interpolate-size\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_interpolate_size_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "pages")] + pub fn connect_pages_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_pages_trampoline( + this: *mut ffi::AdwSqueezer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::pages\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_pages_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "switch-threshold-policy")] + pub fn connect_switch_threshold_policy_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_switch_threshold_policy_trampoline< + F: Fn(&Squeezer) + 'static, + >( + this: *mut ffi::AdwSqueezer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::switch-threshold-policy\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_switch_threshold_policy_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "transition-duration")] + pub fn connect_transition_duration_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_transition_duration_trampoline( + this: *mut ffi::AdwSqueezer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::transition-duration\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_transition_duration_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "transition-running")] + pub fn connect_transition_running_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_transition_running_trampoline( + this: *mut ffi::AdwSqueezer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::transition-running\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_transition_running_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "transition-type")] + pub fn connect_transition_type_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_transition_type_trampoline( + this: *mut ffi::AdwSqueezer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::transition-type\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_transition_type_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "visible-child")] + pub fn connect_visible_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_visible_child_trampoline( + this: *mut ffi::AdwSqueezer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::visible-child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_visible_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "xalign")] + pub fn connect_xalign_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_xalign_trampoline( + this: *mut ffi::AdwSqueezer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::xalign\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_xalign_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "yalign")] + pub fn connect_yalign_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_yalign_trampoline( + this: *mut ffi::AdwSqueezer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::yalign\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_yalign_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for Squeezer { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`Squeezer`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct SqueezerBuilder { + builder: glib::object::ObjectBuilder<'static, Squeezer>, +} + +impl SqueezerBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn allow_none(self, allow_none: bool) -> Self { + Self { + builder: self.builder.property("allow-none", allow_none), + } + } + + pub fn homogeneous(self, homogeneous: bool) -> Self { + Self { + builder: self.builder.property("homogeneous", homogeneous), + } + } + + pub fn interpolate_size(self, interpolate_size: bool) -> Self { + Self { + builder: self.builder.property("interpolate-size", interpolate_size), + } + } + + pub fn switch_threshold_policy(self, switch_threshold_policy: FoldThresholdPolicy) -> Self { + Self { + builder: self + .builder + .property("switch-threshold-policy", switch_threshold_policy), + } + } + + pub fn transition_duration(self, transition_duration: u32) -> Self { + Self { + builder: self + .builder + .property("transition-duration", transition_duration), + } + } + + pub fn transition_type(self, transition_type: SqueezerTransitionType) -> Self { + Self { + builder: self.builder.property("transition-type", transition_type), + } + } + + pub fn xalign(self, xalign: f32) -> Self { + Self { + builder: self.builder.property("xalign", xalign), + } + } + + pub fn yalign(self, yalign: f32) -> Self { + Self { + builder: self.builder.property("yalign", yalign), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn orientation(self, orientation: gtk::Orientation) -> Self { + Self { + builder: self.builder.property("orientation", orientation), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`Squeezer`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> Squeezer { + self.builder.build() + } +} + +impl fmt::Display for Squeezer { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Squeezer") + } +} diff --git a/libadwaita-0.4.4/src/auto/squeezer_page.rs b/libadwaita-0.4.4/src/auto/squeezer_page.rs new file mode 100644 index 0000000..0fb8b3c --- /dev/null +++ b/libadwaita-0.4.4/src/auto/squeezer_page.rs @@ -0,0 +1,70 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwSqueezerPage")] + pub struct SqueezerPage(Object); + + match fn { + type_ => || ffi::adw_squeezer_page_get_type(), + } +} + +impl SqueezerPage { + #[doc(alias = "adw_squeezer_page_get_child")] + #[doc(alias = "get_child")] + pub fn child(&self) -> gtk::Widget { + unsafe { from_glib_none(ffi::adw_squeezer_page_get_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_squeezer_page_get_enabled")] + #[doc(alias = "get_enabled")] + pub fn is_enabled(&self) -> bool { + unsafe { from_glib(ffi::adw_squeezer_page_get_enabled(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_squeezer_page_set_enabled")] + pub fn set_enabled(&self, enabled: bool) { + unsafe { + ffi::adw_squeezer_page_set_enabled(self.to_glib_none().0, enabled.into_glib()); + } + } + + #[doc(alias = "enabled")] + pub fn connect_enabled_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_enabled_trampoline( + this: *mut ffi::AdwSqueezerPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::enabled\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_enabled_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for SqueezerPage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("SqueezerPage") + } +} diff --git a/libadwaita-0.4.4/src/auto/status_page.rs b/libadwaita-0.4.4/src/auto/status_page.rs new file mode 100644 index 0000000..ecb3c15 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/status_page.rs @@ -0,0 +1,477 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwStatusPage")] + pub struct StatusPage(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_status_page_get_type(), + } +} + +impl StatusPage { + #[doc(alias = "adw_status_page_new")] + pub fn new() -> StatusPage { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_status_page_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`StatusPage`] objects. + /// + /// This method returns an instance of [`StatusPageBuilder`](crate::builders::StatusPageBuilder) which can be used to create [`StatusPage`] objects. + pub fn builder() -> StatusPageBuilder { + StatusPageBuilder::new() + } + + #[doc(alias = "adw_status_page_get_child")] + #[doc(alias = "get_child")] + pub fn child(&self) -> Option { + unsafe { from_glib_none(ffi::adw_status_page_get_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_status_page_get_description")] + #[doc(alias = "get_description")] + pub fn description(&self) -> Option { + unsafe { from_glib_none(ffi::adw_status_page_get_description(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_status_page_get_icon_name")] + #[doc(alias = "get_icon_name")] + pub fn icon_name(&self) -> Option { + unsafe { from_glib_none(ffi::adw_status_page_get_icon_name(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_status_page_get_paintable")] + #[doc(alias = "get_paintable")] + pub fn paintable(&self) -> Option { + unsafe { from_glib_none(ffi::adw_status_page_get_paintable(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_status_page_get_title")] + #[doc(alias = "get_title")] + pub fn title(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_status_page_get_title(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_status_page_set_child")] + pub fn set_child(&self, child: Option<&impl IsA>) { + unsafe { + ffi::adw_status_page_set_child( + self.to_glib_none().0, + child.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_status_page_set_description")] + pub fn set_description(&self, description: Option<&str>) { + unsafe { + ffi::adw_status_page_set_description( + self.to_glib_none().0, + description.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_status_page_set_icon_name")] + pub fn set_icon_name(&self, icon_name: Option<&str>) { + unsafe { + ffi::adw_status_page_set_icon_name(self.to_glib_none().0, icon_name.to_glib_none().0); + } + } + + #[doc(alias = "adw_status_page_set_paintable")] + pub fn set_paintable(&self, paintable: Option<&impl IsA>) { + unsafe { + ffi::adw_status_page_set_paintable( + self.to_glib_none().0, + paintable.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_status_page_set_title")] + pub fn set_title(&self, title: &str) { + unsafe { + ffi::adw_status_page_set_title(self.to_glib_none().0, title.to_glib_none().0); + } + } + + #[doc(alias = "child")] + pub fn connect_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_child_trampoline( + this: *mut ffi::AdwStatusPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "description")] + pub fn connect_description_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_description_trampoline( + this: *mut ffi::AdwStatusPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::description\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_description_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "icon-name")] + pub fn connect_icon_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_icon_name_trampoline( + this: *mut ffi::AdwStatusPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::icon-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_icon_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "paintable")] + pub fn connect_paintable_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_paintable_trampoline( + this: *mut ffi::AdwStatusPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::paintable\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_paintable_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "title")] + pub fn connect_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_trampoline( + this: *mut ffi::AdwStatusPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for StatusPage { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`StatusPage`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct StatusPageBuilder { + builder: glib::object::ObjectBuilder<'static, StatusPage>, +} + +impl StatusPageBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn description(self, description: impl Into) -> Self { + Self { + builder: self.builder.property("description", description.into()), + } + } + + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn paintable(self, paintable: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("paintable", paintable.clone().upcast()), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`StatusPage`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> StatusPage { + self.builder.build() + } +} + +impl fmt::Display for StatusPage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("StatusPage") + } +} diff --git a/libadwaita-0.4.4/src/auto/style_manager.rs b/libadwaita-0.4.4/src/auto/style_manager.rs new file mode 100644 index 0000000..8a92aaf --- /dev/null +++ b/libadwaita-0.4.4/src/auto/style_manager.rs @@ -0,0 +1,197 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::ColorScheme; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwStyleManager")] + pub struct StyleManager(Object); + + match fn { + type_ => || ffi::adw_style_manager_get_type(), + } +} + +impl StyleManager { + #[doc(alias = "adw_style_manager_get_color_scheme")] + #[doc(alias = "get_color_scheme")] + pub fn color_scheme(&self) -> ColorScheme { + unsafe { + from_glib(ffi::adw_style_manager_get_color_scheme( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_style_manager_get_dark")] + #[doc(alias = "get_dark")] + pub fn is_dark(&self) -> bool { + unsafe { from_glib(ffi::adw_style_manager_get_dark(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_style_manager_get_display")] + #[doc(alias = "get_display")] + pub fn display(&self) -> Option { + unsafe { from_glib_none(ffi::adw_style_manager_get_display(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_style_manager_get_high_contrast")] + #[doc(alias = "get_high_contrast")] + pub fn is_high_contrast(&self) -> bool { + unsafe { + from_glib(ffi::adw_style_manager_get_high_contrast( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_style_manager_get_system_supports_color_schemes")] + #[doc(alias = "get_system_supports_color_schemes")] + pub fn system_supports_color_schemes(&self) -> bool { + unsafe { + from_glib(ffi::adw_style_manager_get_system_supports_color_schemes( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_style_manager_set_color_scheme")] + pub fn set_color_scheme(&self, color_scheme: ColorScheme) { + unsafe { + ffi::adw_style_manager_set_color_scheme( + self.to_glib_none().0, + color_scheme.into_glib(), + ); + } + } + + #[doc(alias = "adw_style_manager_get_default")] + #[doc(alias = "get_default")] + #[allow(clippy::should_implement_trait)] + pub fn default() -> StyleManager { + assert_initialized_main_thread!(); + unsafe { from_glib_none(ffi::adw_style_manager_get_default()) } + } + + #[doc(alias = "adw_style_manager_get_for_display")] + #[doc(alias = "get_for_display")] + pub fn for_display(display: &gdk::Display) -> StyleManager { + assert_initialized_main_thread!(); + unsafe { + from_glib_none(ffi::adw_style_manager_get_for_display( + display.to_glib_none().0, + )) + } + } + + #[doc(alias = "color-scheme")] + pub fn connect_color_scheme_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_color_scheme_trampoline( + this: *mut ffi::AdwStyleManager, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::color-scheme\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_color_scheme_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "dark")] + pub fn connect_dark_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_dark_trampoline( + this: *mut ffi::AdwStyleManager, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::dark\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_dark_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "high-contrast")] + pub fn connect_high_contrast_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_high_contrast_trampoline( + this: *mut ffi::AdwStyleManager, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::high-contrast\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_high_contrast_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "system-supports-color-schemes")] + pub fn connect_system_supports_color_schemes_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_system_supports_color_schemes_trampoline< + F: Fn(&StyleManager) + 'static, + >( + this: *mut ffi::AdwStyleManager, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::system-supports-color-schemes\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_system_supports_color_schemes_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for StyleManager { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("StyleManager") + } +} diff --git a/libadwaita-0.4.4/src/auto/swipe_tracker.rs b/libadwaita-0.4.4/src/auto/swipe_tracker.rs new file mode 100644 index 0000000..8c7f38a --- /dev/null +++ b/libadwaita-0.4.4/src/auto/swipe_tracker.rs @@ -0,0 +1,502 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{NavigationDirection, Swipeable}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwSwipeTracker")] + pub struct SwipeTracker(Object) @implements gtk::Orientable; + + match fn { + type_ => || ffi::adw_swipe_tracker_get_type(), + } +} + +impl SwipeTracker { + #[doc(alias = "adw_swipe_tracker_new")] + pub fn new(swipeable: &impl IsA) -> SwipeTracker { + skip_assert_initialized!(); + unsafe { + from_glib_full(ffi::adw_swipe_tracker_new( + swipeable.as_ref().to_glib_none().0, + )) + } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`SwipeTracker`] objects. + /// + /// This method returns an instance of [`SwipeTrackerBuilder`](crate::builders::SwipeTrackerBuilder) which can be used to create [`SwipeTracker`] objects. + pub fn builder() -> SwipeTrackerBuilder { + SwipeTrackerBuilder::new() + } + + #[doc(alias = "adw_swipe_tracker_get_allow_long_swipes")] + #[doc(alias = "get_allow_long_swipes")] + pub fn allows_long_swipes(&self) -> bool { + unsafe { + from_glib(ffi::adw_swipe_tracker_get_allow_long_swipes( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_swipe_tracker_get_allow_mouse_drag")] + #[doc(alias = "get_allow_mouse_drag")] + pub fn allows_mouse_drag(&self) -> bool { + unsafe { + from_glib(ffi::adw_swipe_tracker_get_allow_mouse_drag( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_swipe_tracker_get_enabled")] + #[doc(alias = "get_enabled")] + pub fn is_enabled(&self) -> bool { + unsafe { from_glib(ffi::adw_swipe_tracker_get_enabled(self.to_glib_none().0)) } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_swipe_tracker_get_lower_overshoot")] + #[doc(alias = "get_lower_overshoot")] + pub fn is_lower_overshoot(&self) -> bool { + unsafe { + from_glib(ffi::adw_swipe_tracker_get_lower_overshoot( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_swipe_tracker_get_reversed")] + #[doc(alias = "get_reversed")] + pub fn is_reversed(&self) -> bool { + unsafe { from_glib(ffi::adw_swipe_tracker_get_reversed(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_swipe_tracker_get_swipeable")] + #[doc(alias = "get_swipeable")] + pub fn swipeable(&self) -> Swipeable { + unsafe { from_glib_none(ffi::adw_swipe_tracker_get_swipeable(self.to_glib_none().0)) } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_swipe_tracker_get_upper_overshoot")] + #[doc(alias = "get_upper_overshoot")] + pub fn is_upper_overshoot(&self) -> bool { + unsafe { + from_glib(ffi::adw_swipe_tracker_get_upper_overshoot( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_swipe_tracker_set_allow_long_swipes")] + pub fn set_allow_long_swipes(&self, allow_long_swipes: bool) { + unsafe { + ffi::adw_swipe_tracker_set_allow_long_swipes( + self.to_glib_none().0, + allow_long_swipes.into_glib(), + ); + } + } + + #[doc(alias = "adw_swipe_tracker_set_allow_mouse_drag")] + pub fn set_allow_mouse_drag(&self, allow_mouse_drag: bool) { + unsafe { + ffi::adw_swipe_tracker_set_allow_mouse_drag( + self.to_glib_none().0, + allow_mouse_drag.into_glib(), + ); + } + } + + #[doc(alias = "adw_swipe_tracker_set_enabled")] + pub fn set_enabled(&self, enabled: bool) { + unsafe { + ffi::adw_swipe_tracker_set_enabled(self.to_glib_none().0, enabled.into_glib()); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_swipe_tracker_set_lower_overshoot")] + pub fn set_lower_overshoot(&self, overshoot: bool) { + unsafe { + ffi::adw_swipe_tracker_set_lower_overshoot( + self.to_glib_none().0, + overshoot.into_glib(), + ); + } + } + + #[doc(alias = "adw_swipe_tracker_set_reversed")] + pub fn set_reversed(&self, reversed: bool) { + unsafe { + ffi::adw_swipe_tracker_set_reversed(self.to_glib_none().0, reversed.into_glib()); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_swipe_tracker_set_upper_overshoot")] + pub fn set_upper_overshoot(&self, overshoot: bool) { + unsafe { + ffi::adw_swipe_tracker_set_upper_overshoot( + self.to_glib_none().0, + overshoot.into_glib(), + ); + } + } + + #[doc(alias = "adw_swipe_tracker_shift_position")] + pub fn shift_position(&self, delta: f64) { + unsafe { + ffi::adw_swipe_tracker_shift_position(self.to_glib_none().0, delta); + } + } + + #[doc(alias = "begin-swipe")] + pub fn connect_begin_swipe(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn begin_swipe_trampoline( + this: *mut ffi::AdwSwipeTracker, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"begin-swipe\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + begin_swipe_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "end-swipe")] + pub fn connect_end_swipe(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn end_swipe_trampoline( + this: *mut ffi::AdwSwipeTracker, + velocity: libc::c_double, + to: libc::c_double, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), velocity, to) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"end-swipe\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + end_swipe_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "prepare")] + pub fn connect_prepare( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn prepare_trampoline< + F: Fn(&SwipeTracker, NavigationDirection) + 'static, + >( + this: *mut ffi::AdwSwipeTracker, + direction: ffi::AdwNavigationDirection, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), from_glib(direction)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"prepare\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + prepare_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "update-swipe")] + pub fn connect_update_swipe(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn update_swipe_trampoline( + this: *mut ffi::AdwSwipeTracker, + progress: libc::c_double, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), progress) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"update-swipe\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + update_swipe_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "allow-long-swipes")] + pub fn connect_allow_long_swipes_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_allow_long_swipes_trampoline( + this: *mut ffi::AdwSwipeTracker, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::allow-long-swipes\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_allow_long_swipes_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "allow-mouse-drag")] + pub fn connect_allow_mouse_drag_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_allow_mouse_drag_trampoline( + this: *mut ffi::AdwSwipeTracker, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::allow-mouse-drag\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_allow_mouse_drag_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "enabled")] + pub fn connect_enabled_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_enabled_trampoline( + this: *mut ffi::AdwSwipeTracker, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::enabled\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_enabled_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "lower-overshoot")] + pub fn connect_lower_overshoot_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_lower_overshoot_trampoline( + this: *mut ffi::AdwSwipeTracker, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::lower-overshoot\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_lower_overshoot_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "reversed")] + pub fn connect_reversed_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_reversed_trampoline( + this: *mut ffi::AdwSwipeTracker, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::reversed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_reversed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "upper-overshoot")] + pub fn connect_upper_overshoot_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_upper_overshoot_trampoline( + this: *mut ffi::AdwSwipeTracker, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::upper-overshoot\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_upper_overshoot_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for SwipeTracker { + fn default() -> Self { + glib::object::Object::new::() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`SwipeTracker`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct SwipeTrackerBuilder { + builder: glib::object::ObjectBuilder<'static, SwipeTracker>, +} + +impl SwipeTrackerBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn allow_long_swipes(self, allow_long_swipes: bool) -> Self { + Self { + builder: self + .builder + .property("allow-long-swipes", allow_long_swipes), + } + } + + pub fn allow_mouse_drag(self, allow_mouse_drag: bool) -> Self { + Self { + builder: self.builder.property("allow-mouse-drag", allow_mouse_drag), + } + } + + pub fn enabled(self, enabled: bool) -> Self { + Self { + builder: self.builder.property("enabled", enabled), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn lower_overshoot(self, lower_overshoot: bool) -> Self { + Self { + builder: self.builder.property("lower-overshoot", lower_overshoot), + } + } + + pub fn reversed(self, reversed: bool) -> Self { + Self { + builder: self.builder.property("reversed", reversed), + } + } + + pub fn swipeable(self, swipeable: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("swipeable", swipeable.clone().upcast()), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn upper_overshoot(self, upper_overshoot: bool) -> Self { + Self { + builder: self.builder.property("upper-overshoot", upper_overshoot), + } + } + + pub fn orientation(self, orientation: gtk::Orientation) -> Self { + Self { + builder: self.builder.property("orientation", orientation), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`SwipeTracker`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> SwipeTracker { + self.builder.build() + } +} + +impl fmt::Display for SwipeTracker { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("SwipeTracker") + } +} diff --git a/libadwaita-0.4.4/src/auto/swipeable.rs b/libadwaita-0.4.4/src/auto/swipeable.rs new file mode 100644 index 0000000..9bccfce --- /dev/null +++ b/libadwaita-0.4.4/src/auto/swipeable.rs @@ -0,0 +1,98 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::NavigationDirection; +use glib::{prelude::*, translate::*}; +use std::{fmt, mem}; + +glib::wrapper! { + #[doc(alias = "AdwSwipeable")] + pub struct Swipeable(Interface) @requires gtk::Widget, gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_swipeable_get_type(), + } +} + +impl Swipeable { + pub const NONE: Option<&'static Swipeable> = None; +} + +pub trait SwipeableExt: 'static { + #[doc(alias = "adw_swipeable_get_cancel_progress")] + #[doc(alias = "get_cancel_progress")] + fn cancel_progress(&self) -> f64; + + #[doc(alias = "adw_swipeable_get_distance")] + #[doc(alias = "get_distance")] + fn distance(&self) -> f64; + + #[doc(alias = "adw_swipeable_get_progress")] + #[doc(alias = "get_progress")] + fn progress(&self) -> f64; + + #[doc(alias = "adw_swipeable_get_snap_points")] + #[doc(alias = "get_snap_points")] + fn snap_points(&self) -> Vec; + + #[doc(alias = "adw_swipeable_get_swipe_area")] + #[doc(alias = "get_swipe_area")] + fn swipe_area( + &self, + navigation_direction: NavigationDirection, + is_drag: bool, + ) -> gdk::Rectangle; +} + +impl> SwipeableExt for O { + fn cancel_progress(&self) -> f64 { + unsafe { ffi::adw_swipeable_get_cancel_progress(self.as_ref().to_glib_none().0) } + } + + fn distance(&self) -> f64 { + unsafe { ffi::adw_swipeable_get_distance(self.as_ref().to_glib_none().0) } + } + + fn progress(&self) -> f64 { + unsafe { ffi::adw_swipeable_get_progress(self.as_ref().to_glib_none().0) } + } + + fn snap_points(&self) -> Vec { + unsafe { + let mut n_snap_points = mem::MaybeUninit::uninit(); + let ret = FromGlibContainer::from_glib_full_num( + ffi::adw_swipeable_get_snap_points( + self.as_ref().to_glib_none().0, + n_snap_points.as_mut_ptr(), + ), + n_snap_points.assume_init() as _, + ); + ret + } + } + + fn swipe_area( + &self, + navigation_direction: NavigationDirection, + is_drag: bool, + ) -> gdk::Rectangle { + unsafe { + let mut rect = gdk::Rectangle::uninitialized(); + ffi::adw_swipeable_get_swipe_area( + self.as_ref().to_glib_none().0, + navigation_direction.into_glib(), + is_drag.into_glib(), + rect.to_glib_none_mut().0, + ); + rect + } + } +} + +impl fmt::Display for Swipeable { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Swipeable") + } +} diff --git a/libadwaita-0.4.4/src/auto/switch_row.rs b/libadwaita-0.4.4/src/auto/switch_row.rs new file mode 100644 index 0000000..4051e11 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/switch_row.rs @@ -0,0 +1,408 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{ActionRow, PreferencesRow}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwSwitchRow")] + pub struct SwitchRow(Object) @extends ActionRow, PreferencesRow, gtk::ListBoxRow, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable; + + match fn { + type_ => || ffi::adw_switch_row_get_type(), + } +} + +impl SwitchRow { + #[doc(alias = "adw_switch_row_new")] + pub fn new() -> SwitchRow { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_switch_row_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`SwitchRow`] objects. + /// + /// This method returns an instance of [`SwitchRowBuilder`](crate::builders::SwitchRowBuilder) which can be used to create [`SwitchRow`] objects. + pub fn builder() -> SwitchRowBuilder { + SwitchRowBuilder::new() + } + + #[doc(alias = "adw_switch_row_get_active")] + #[doc(alias = "get_active")] + pub fn is_active(&self) -> bool { + unsafe { from_glib(ffi::adw_switch_row_get_active(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_switch_row_set_active")] + pub fn set_active(&self, is_active: bool) { + unsafe { + ffi::adw_switch_row_set_active(self.to_glib_none().0, is_active.into_glib()); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "active")] + pub fn connect_active_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_active_trampoline( + this: *mut ffi::AdwSwitchRow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::active\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_active_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl Default for SwitchRow { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`SwitchRow`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct SwitchRowBuilder { + builder: glib::object::ObjectBuilder<'static, SwitchRow>, +} + +impl SwitchRowBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn active(self, active: bool) -> Self { + Self { + builder: self.builder.property("active", active), + } + } + + pub fn activatable_widget(self, activatable_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("activatable-widget", activatable_widget.clone().upcast()), + } + } + + #[cfg_attr(feature = "v1_3", deprecated = "Since 1.3")] + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn subtitle(self, subtitle: impl Into) -> Self { + Self { + builder: self.builder.property("subtitle", subtitle.into()), + } + } + + pub fn subtitle_lines(self, subtitle_lines: i32) -> Self { + Self { + builder: self.builder.property("subtitle-lines", subtitle_lines), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn subtitle_selectable(self, subtitle_selectable: bool) -> Self { + Self { + builder: self + .builder + .property("subtitle-selectable", subtitle_selectable), + } + } + + pub fn title_lines(self, title_lines: i32) -> Self { + Self { + builder: self.builder.property("title-lines", title_lines), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "v1_1", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_1")))] + pub fn title_selectable(self, title_selectable: bool) -> Self { + Self { + builder: self.builder.property("title-selectable", title_selectable), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn use_markup(self, use_markup: bool) -> Self { + Self { + builder: self.builder.property("use-markup", use_markup), + } + } + + pub fn use_underline(self, use_underline: bool) -> Self { + Self { + builder: self.builder.property("use-underline", use_underline), + } + } + + pub fn activatable(self, activatable: bool) -> Self { + Self { + builder: self.builder.property("activatable", activatable), + } + } + + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + pub fn selectable(self, selectable: bool) -> Self { + Self { + builder: self.builder.property("selectable", selectable), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn action_name(self, action_name: impl Into) -> Self { + Self { + builder: self.builder.property("action-name", action_name.into()), + } + } + + pub fn action_target(self, action_target: &glib::Variant) -> Self { + Self { + builder: self + .builder + .property("action-target", action_target.clone()), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`SwitchRow`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> SwitchRow { + self.builder.build() + } +} + +impl fmt::Display for SwitchRow { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("SwitchRow") + } +} diff --git a/libadwaita-0.4.4/src/auto/tab_bar.rs b/libadwaita-0.4.4/src/auto/tab_bar.rs new file mode 100644 index 0000000..45a340f --- /dev/null +++ b/libadwaita-0.4.4/src/auto/tab_bar.rs @@ -0,0 +1,733 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +#[cfg(any(feature = "v1_3", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] +use crate::TabPage; +use crate::TabView; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwTabBar")] + pub struct TabBar(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_tab_bar_get_type(), + } +} + +impl TabBar { + #[doc(alias = "adw_tab_bar_new")] + pub fn new() -> TabBar { + assert_initialized_main_thread!(); + unsafe { from_glib_none(ffi::adw_tab_bar_new()) } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`TabBar`] objects. + /// + /// This method returns an instance of [`TabBarBuilder`](crate::builders::TabBarBuilder) which can be used to create [`TabBar`] objects. + pub fn builder() -> TabBarBuilder { + TabBarBuilder::new() + } + + #[doc(alias = "adw_tab_bar_get_autohide")] + #[doc(alias = "get_autohide")] + pub fn is_autohide(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_bar_get_autohide(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_bar_get_end_action_widget")] + #[doc(alias = "get_end_action_widget")] + pub fn end_action_widget(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_tab_bar_get_end_action_widget( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_bar_get_expand_tabs")] + #[doc(alias = "get_expand_tabs")] + pub fn expands_tabs(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_bar_get_expand_tabs(self.to_glib_none().0)) } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_tab_bar_get_extra_drag_preferred_action")] + #[doc(alias = "get_extra_drag_preferred_action")] + pub fn extra_drag_preferred_action(&self) -> gdk::DragAction { + unsafe { + from_glib(ffi::adw_tab_bar_get_extra_drag_preferred_action( + self.to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_tab_bar_get_extra_drag_preload")] + #[doc(alias = "get_extra_drag_preload")] + pub fn is_extra_drag_preload(&self) -> bool { + unsafe { + from_glib(ffi::adw_tab_bar_get_extra_drag_preload( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_bar_get_inverted")] + #[doc(alias = "get_inverted")] + pub fn is_inverted(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_bar_get_inverted(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_bar_get_is_overflowing")] + #[doc(alias = "get_is_overflowing")] + pub fn is_overflowing(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_bar_get_is_overflowing(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_bar_get_start_action_widget")] + #[doc(alias = "get_start_action_widget")] + pub fn start_action_widget(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_tab_bar_get_start_action_widget( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_bar_get_tabs_revealed")] + #[doc(alias = "get_tabs_revealed")] + pub fn is_tabs_revealed(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_bar_get_tabs_revealed(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_bar_get_view")] + #[doc(alias = "get_view")] + pub fn view(&self) -> Option { + unsafe { from_glib_none(ffi::adw_tab_bar_get_view(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_bar_set_autohide")] + pub fn set_autohide(&self, autohide: bool) { + unsafe { + ffi::adw_tab_bar_set_autohide(self.to_glib_none().0, autohide.into_glib()); + } + } + + #[doc(alias = "adw_tab_bar_set_end_action_widget")] + pub fn set_end_action_widget(&self, widget: Option<&impl IsA>) { + unsafe { + ffi::adw_tab_bar_set_end_action_widget( + self.to_glib_none().0, + widget.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_tab_bar_set_expand_tabs")] + pub fn set_expand_tabs(&self, expand_tabs: bool) { + unsafe { + ffi::adw_tab_bar_set_expand_tabs(self.to_glib_none().0, expand_tabs.into_glib()); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_tab_bar_set_extra_drag_preload")] + pub fn set_extra_drag_preload(&self, preload: bool) { + unsafe { + ffi::adw_tab_bar_set_extra_drag_preload(self.to_glib_none().0, preload.into_glib()); + } + } + + #[doc(alias = "adw_tab_bar_set_inverted")] + pub fn set_inverted(&self, inverted: bool) { + unsafe { + ffi::adw_tab_bar_set_inverted(self.to_glib_none().0, inverted.into_glib()); + } + } + + #[doc(alias = "adw_tab_bar_set_start_action_widget")] + pub fn set_start_action_widget(&self, widget: Option<&impl IsA>) { + unsafe { + ffi::adw_tab_bar_set_start_action_widget( + self.to_glib_none().0, + widget.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_tab_bar_set_view")] + pub fn set_view(&self, view: Option<&TabView>) { + unsafe { + ffi::adw_tab_bar_set_view(self.to_glib_none().0, view.to_glib_none().0); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "extra-drag-value")] + pub fn connect_extra_drag_value< + F: Fn(&Self, &TabPage, &glib::Value) -> gdk::DragAction + 'static, + >( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn extra_drag_value_trampoline< + F: Fn(&TabBar, &TabPage, &glib::Value) -> gdk::DragAction + 'static, + >( + this: *mut ffi::AdwTabBar, + page: *mut ffi::AdwTabPage, + value: *mut glib::gobject_ffi::GValue, + f: glib::ffi::gpointer, + ) -> gdk::ffi::GdkDragAction { + let f: &F = &*(f as *const F); + f( + &from_glib_borrow(this), + &from_glib_borrow(page), + &from_glib_borrow(value), + ) + .into_glib() + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"extra-drag-value\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + extra_drag_value_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "autohide")] + pub fn connect_autohide_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_autohide_trampoline( + this: *mut ffi::AdwTabBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::autohide\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_autohide_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "end-action-widget")] + pub fn connect_end_action_widget_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_end_action_widget_trampoline( + this: *mut ffi::AdwTabBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::end-action-widget\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_end_action_widget_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "expand-tabs")] + pub fn connect_expand_tabs_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_expand_tabs_trampoline( + this: *mut ffi::AdwTabBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::expand-tabs\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_expand_tabs_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "extra-drag-preferred-action")] + pub fn connect_extra_drag_preferred_action_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_extra_drag_preferred_action_trampoline< + F: Fn(&TabBar) + 'static, + >( + this: *mut ffi::AdwTabBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::extra-drag-preferred-action\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_extra_drag_preferred_action_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "extra-drag-preload")] + pub fn connect_extra_drag_preload_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_extra_drag_preload_trampoline( + this: *mut ffi::AdwTabBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::extra-drag-preload\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_extra_drag_preload_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "inverted")] + pub fn connect_inverted_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_inverted_trampoline( + this: *mut ffi::AdwTabBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::inverted\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_inverted_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "is-overflowing")] + pub fn connect_is_overflowing_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_is_overflowing_trampoline( + this: *mut ffi::AdwTabBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::is-overflowing\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_is_overflowing_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "start-action-widget")] + pub fn connect_start_action_widget_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_start_action_widget_trampoline( + this: *mut ffi::AdwTabBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::start-action-widget\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_start_action_widget_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "tabs-revealed")] + pub fn connect_tabs_revealed_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_tabs_revealed_trampoline( + this: *mut ffi::AdwTabBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::tabs-revealed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_tabs_revealed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "view")] + pub fn connect_view_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_view_trampoline( + this: *mut ffi::AdwTabBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::view\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_view_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for TabBar { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`TabBar`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct TabBarBuilder { + builder: glib::object::ObjectBuilder<'static, TabBar>, +} + +impl TabBarBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn autohide(self, autohide: bool) -> Self { + Self { + builder: self.builder.property("autohide", autohide), + } + } + + pub fn end_action_widget(self, end_action_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("end-action-widget", end_action_widget.clone().upcast()), + } + } + + pub fn expand_tabs(self, expand_tabs: bool) -> Self { + Self { + builder: self.builder.property("expand-tabs", expand_tabs), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn extra_drag_preload(self, extra_drag_preload: bool) -> Self { + Self { + builder: self + .builder + .property("extra-drag-preload", extra_drag_preload), + } + } + + pub fn inverted(self, inverted: bool) -> Self { + Self { + builder: self.builder.property("inverted", inverted), + } + } + + pub fn start_action_widget(self, start_action_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("start-action-widget", start_action_widget.clone().upcast()), + } + } + + pub fn view(self, view: &TabView) -> Self { + Self { + builder: self.builder.property("view", view.clone()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`TabBar`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> TabBar { + self.builder.build() + } +} + +impl fmt::Display for TabBar { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("TabBar") + } +} diff --git a/libadwaita-0.4.4/src/auto/tab_button.rs b/libadwaita-0.4.4/src/auto/tab_button.rs new file mode 100644 index 0000000..ec73b0b --- /dev/null +++ b/libadwaita-0.4.4/src/auto/tab_button.rs @@ -0,0 +1,379 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::TabView; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwTabButton")] + pub struct TabButton(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable; + + match fn { + type_ => || ffi::adw_tab_button_get_type(), + } +} + +impl TabButton { + #[doc(alias = "adw_tab_button_new")] + pub fn new() -> TabButton { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_tab_button_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`TabButton`] objects. + /// + /// This method returns an instance of [`TabButtonBuilder`](crate::builders::TabButtonBuilder) which can be used to create [`TabButton`] objects. + pub fn builder() -> TabButtonBuilder { + TabButtonBuilder::new() + } + + #[doc(alias = "adw_tab_button_get_view")] + #[doc(alias = "get_view")] + pub fn view(&self) -> Option { + unsafe { from_glib_none(ffi::adw_tab_button_get_view(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_button_set_view")] + pub fn set_view(&self, view: Option<&TabView>) { + unsafe { + ffi::adw_tab_button_set_view(self.to_glib_none().0, view.to_glib_none().0); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "activate")] + pub fn connect_activate(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn activate_trampoline( + this: *mut ffi::AdwTabButton, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"activate\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + activate_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn emit_activate(&self) { + self.emit_by_name::<()>("activate", &[]); + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "clicked")] + pub fn connect_clicked(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn clicked_trampoline( + this: *mut ffi::AdwTabButton, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"clicked\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + clicked_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn emit_clicked(&self) { + self.emit_by_name::<()>("clicked", &[]); + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "view")] + pub fn connect_view_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_view_trampoline( + this: *mut ffi::AdwTabButton, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::view\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_view_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +#[cfg(any(feature = "v1_3", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] +impl Default for TabButton { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`TabButton`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct TabButtonBuilder { + builder: glib::object::ObjectBuilder<'static, TabButton>, +} + +impl TabButtonBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn view(self, view: &TabView) -> Self { + Self { + builder: self.builder.property("view", view.clone()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + pub fn action_name(self, action_name: impl Into) -> Self { + Self { + builder: self.builder.property("action-name", action_name.into()), + } + } + + pub fn action_target(self, action_target: &glib::Variant) -> Self { + Self { + builder: self + .builder + .property("action-target", action_target.clone()), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`TabButton`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> TabButton { + self.builder.build() + } +} + +impl fmt::Display for TabButton { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("TabButton") + } +} diff --git a/libadwaita-0.4.4/src/auto/tab_overview.rs b/libadwaita-0.4.4/src/auto/tab_overview.rs new file mode 100644 index 0000000..681bc37 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/tab_overview.rs @@ -0,0 +1,967 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{TabPage, TabView}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwTabOverview")] + pub struct TabOverview(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_tab_overview_get_type(), + } +} + +impl TabOverview { + #[doc(alias = "adw_tab_overview_new")] + pub fn new() -> TabOverview { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_tab_overview_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`TabOverview`] objects. + /// + /// This method returns an instance of [`TabOverviewBuilder`](crate::builders::TabOverviewBuilder) which can be used to create [`TabOverview`] objects. + pub fn builder() -> TabOverviewBuilder { + TabOverviewBuilder::new() + } + + #[doc(alias = "adw_tab_overview_get_child")] + #[doc(alias = "get_child")] + pub fn child(&self) -> Option { + unsafe { from_glib_none(ffi::adw_tab_overview_get_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_overview_get_enable_new_tab")] + #[doc(alias = "get_enable_new_tab")] + pub fn enables_new_tab(&self) -> bool { + unsafe { + from_glib(ffi::adw_tab_overview_get_enable_new_tab( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_overview_get_enable_search")] + #[doc(alias = "get_enable_search")] + pub fn enables_search(&self) -> bool { + unsafe { + from_glib(ffi::adw_tab_overview_get_enable_search( + self.to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_tab_overview_get_extra_drag_preferred_action")] + #[doc(alias = "get_extra_drag_preferred_action")] + pub fn extra_drag_preferred_action(&self) -> gdk::DragAction { + unsafe { + from_glib(ffi::adw_tab_overview_get_extra_drag_preferred_action( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_overview_get_extra_drag_preload")] + #[doc(alias = "get_extra_drag_preload")] + pub fn is_extra_drag_preload(&self) -> bool { + unsafe { + from_glib(ffi::adw_tab_overview_get_extra_drag_preload( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_overview_get_inverted")] + #[doc(alias = "get_inverted")] + pub fn is_inverted(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_overview_get_inverted(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_overview_get_open")] + #[doc(alias = "get_open")] + pub fn is_open(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_overview_get_open(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_overview_get_search_active")] + #[doc(alias = "get_search_active")] + pub fn is_search_active(&self) -> bool { + unsafe { + from_glib(ffi::adw_tab_overview_get_search_active( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_overview_get_secondary_menu")] + #[doc(alias = "get_secondary_menu")] + pub fn secondary_menu(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_tab_overview_get_secondary_menu( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_overview_get_show_end_title_buttons")] + #[doc(alias = "get_show_end_title_buttons")] + pub fn shows_end_title_buttons(&self) -> bool { + unsafe { + from_glib(ffi::adw_tab_overview_get_show_end_title_buttons( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_overview_get_show_start_title_buttons")] + #[doc(alias = "get_show_start_title_buttons")] + pub fn shows_start_title_buttons(&self) -> bool { + unsafe { + from_glib(ffi::adw_tab_overview_get_show_start_title_buttons( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_overview_get_view")] + #[doc(alias = "get_view")] + pub fn view(&self) -> Option { + unsafe { from_glib_none(ffi::adw_tab_overview_get_view(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_overview_set_child")] + pub fn set_child(&self, child: Option<&impl IsA>) { + unsafe { + ffi::adw_tab_overview_set_child( + self.to_glib_none().0, + child.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_tab_overview_set_enable_new_tab")] + pub fn set_enable_new_tab(&self, enable_new_tab: bool) { + unsafe { + ffi::adw_tab_overview_set_enable_new_tab( + self.to_glib_none().0, + enable_new_tab.into_glib(), + ); + } + } + + #[doc(alias = "adw_tab_overview_set_enable_search")] + pub fn set_enable_search(&self, enable_search: bool) { + unsafe { + ffi::adw_tab_overview_set_enable_search( + self.to_glib_none().0, + enable_search.into_glib(), + ); + } + } + + #[doc(alias = "adw_tab_overview_set_extra_drag_preload")] + pub fn set_extra_drag_preload(&self, preload: bool) { + unsafe { + ffi::adw_tab_overview_set_extra_drag_preload( + self.to_glib_none().0, + preload.into_glib(), + ); + } + } + + #[doc(alias = "adw_tab_overview_set_inverted")] + pub fn set_inverted(&self, inverted: bool) { + unsafe { + ffi::adw_tab_overview_set_inverted(self.to_glib_none().0, inverted.into_glib()); + } + } + + #[doc(alias = "adw_tab_overview_set_open")] + pub fn set_open(&self, open: bool) { + unsafe { + ffi::adw_tab_overview_set_open(self.to_glib_none().0, open.into_glib()); + } + } + + #[doc(alias = "adw_tab_overview_set_secondary_menu")] + pub fn set_secondary_menu(&self, secondary_menu: Option<&impl IsA>) { + unsafe { + ffi::adw_tab_overview_set_secondary_menu( + self.to_glib_none().0, + secondary_menu.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_tab_overview_set_show_end_title_buttons")] + pub fn set_show_end_title_buttons(&self, show_end_title_buttons: bool) { + unsafe { + ffi::adw_tab_overview_set_show_end_title_buttons( + self.to_glib_none().0, + show_end_title_buttons.into_glib(), + ); + } + } + + #[doc(alias = "adw_tab_overview_set_show_start_title_buttons")] + pub fn set_show_start_title_buttons(&self, show_start_title_buttons: bool) { + unsafe { + ffi::adw_tab_overview_set_show_start_title_buttons( + self.to_glib_none().0, + show_start_title_buttons.into_glib(), + ); + } + } + + #[doc(alias = "adw_tab_overview_set_view")] + pub fn set_view(&self, view: Option<&TabView>) { + unsafe { + ffi::adw_tab_overview_set_view(self.to_glib_none().0, view.to_glib_none().0); + } + } + + //#[doc(alias = "adw_tab_overview_setup_extra_drop_target")] + //pub fn setup_extra_drop_target(&self, actions: gdk::DragAction, types: /*Unimplemented*/Option<&CArray TypeId { ns_id: 0, id: 30 }>) { + // unsafe { TODO: call ffi:adw_tab_overview_setup_extra_drop_target() } + //} + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "create-tab")] + pub fn connect_create_tab TabPage + 'static>(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn create_tab_trampoline TabPage + 'static>( + this: *mut ffi::AdwTabOverview, + f: glib::ffi::gpointer, + ) -> *mut ffi::AdwTabPage { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) /*Not checked*/ + .to_glib_none() + .0 + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"create-tab\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + create_tab_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "extra-drag-drop")] + pub fn connect_extra_drag_drop bool + 'static>( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn extra_drag_drop_trampoline< + F: Fn(&TabOverview, &TabPage, &glib::Value) -> bool + 'static, + >( + this: *mut ffi::AdwTabOverview, + page: *mut ffi::AdwTabPage, + value: *mut glib::gobject_ffi::GValue, + f: glib::ffi::gpointer, + ) -> glib::ffi::gboolean { + let f: &F = &*(f as *const F); + f( + &from_glib_borrow(this), + &from_glib_borrow(page), + &from_glib_borrow(value), + ) + .into_glib() + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"extra-drag-drop\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + extra_drag_drop_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "extra-drag-value")] + pub fn connect_extra_drag_value< + F: Fn(&Self, &TabPage, &glib::Value) -> gdk::DragAction + 'static, + >( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn extra_drag_value_trampoline< + F: Fn(&TabOverview, &TabPage, &glib::Value) -> gdk::DragAction + 'static, + >( + this: *mut ffi::AdwTabOverview, + page: *mut ffi::AdwTabPage, + value: *mut glib::gobject_ffi::GValue, + f: glib::ffi::gpointer, + ) -> gdk::ffi::GdkDragAction { + let f: &F = &*(f as *const F); + f( + &from_glib_borrow(this), + &from_glib_borrow(page), + &from_glib_borrow(value), + ) + .into_glib() + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"extra-drag-value\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + extra_drag_value_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "child")] + pub fn connect_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_child_trampoline( + this: *mut ffi::AdwTabOverview, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "enable-new-tab")] + pub fn connect_enable_new_tab_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_enable_new_tab_trampoline( + this: *mut ffi::AdwTabOverview, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::enable-new-tab\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_enable_new_tab_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "enable-search")] + pub fn connect_enable_search_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_enable_search_trampoline( + this: *mut ffi::AdwTabOverview, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::enable-search\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_enable_search_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "extra-drag-preferred-action")] + pub fn connect_extra_drag_preferred_action_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_extra_drag_preferred_action_trampoline< + F: Fn(&TabOverview) + 'static, + >( + this: *mut ffi::AdwTabOverview, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::extra-drag-preferred-action\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_extra_drag_preferred_action_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "extra-drag-preload")] + pub fn connect_extra_drag_preload_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_extra_drag_preload_trampoline( + this: *mut ffi::AdwTabOverview, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::extra-drag-preload\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_extra_drag_preload_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "inverted")] + pub fn connect_inverted_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_inverted_trampoline( + this: *mut ffi::AdwTabOverview, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::inverted\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_inverted_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "open")] + pub fn connect_open_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_open_trampoline( + this: *mut ffi::AdwTabOverview, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::open\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_open_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "search-active")] + pub fn connect_search_active_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_search_active_trampoline( + this: *mut ffi::AdwTabOverview, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::search-active\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_search_active_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "secondary-menu")] + pub fn connect_secondary_menu_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_secondary_menu_trampoline( + this: *mut ffi::AdwTabOverview, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::secondary-menu\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_secondary_menu_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "show-end-title-buttons")] + pub fn connect_show_end_title_buttons_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_show_end_title_buttons_trampoline< + F: Fn(&TabOverview) + 'static, + >( + this: *mut ffi::AdwTabOverview, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::show-end-title-buttons\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_show_end_title_buttons_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "show-start-title-buttons")] + pub fn connect_show_start_title_buttons_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_show_start_title_buttons_trampoline< + F: Fn(&TabOverview) + 'static, + >( + this: *mut ffi::AdwTabOverview, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::show-start-title-buttons\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_show_start_title_buttons_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "view")] + pub fn connect_view_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_view_trampoline( + this: *mut ffi::AdwTabOverview, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::view\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_view_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +#[cfg(any(feature = "v1_3", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] +impl Default for TabOverview { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`TabOverview`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct TabOverviewBuilder { + builder: glib::object::ObjectBuilder<'static, TabOverview>, +} + +impl TabOverviewBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn child(self, child: &impl IsA) -> Self { + Self { + builder: self.builder.property("child", child.clone().upcast()), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn enable_new_tab(self, enable_new_tab: bool) -> Self { + Self { + builder: self.builder.property("enable-new-tab", enable_new_tab), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn enable_search(self, enable_search: bool) -> Self { + Self { + builder: self.builder.property("enable-search", enable_search), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn extra_drag_preload(self, extra_drag_preload: bool) -> Self { + Self { + builder: self + .builder + .property("extra-drag-preload", extra_drag_preload), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn inverted(self, inverted: bool) -> Self { + Self { + builder: self.builder.property("inverted", inverted), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn open(self, open: bool) -> Self { + Self { + builder: self.builder.property("open", open), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn secondary_menu(self, secondary_menu: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("secondary-menu", secondary_menu.clone().upcast()), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn show_end_title_buttons(self, show_end_title_buttons: bool) -> Self { + Self { + builder: self + .builder + .property("show-end-title-buttons", show_end_title_buttons), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn show_start_title_buttons(self, show_start_title_buttons: bool) -> Self { + Self { + builder: self + .builder + .property("show-start-title-buttons", show_start_title_buttons), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn view(self, view: &TabView) -> Self { + Self { + builder: self.builder.property("view", view.clone()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`TabOverview`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> TabOverview { + self.builder.build() + } +} + +impl fmt::Display for TabOverview { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("TabOverview") + } +} diff --git a/libadwaita-0.4.4/src/auto/tab_page.rs b/libadwaita-0.4.4/src/auto/tab_page.rs new file mode 100644 index 0000000..56a8a1c --- /dev/null +++ b/libadwaita-0.4.4/src/auto/tab_page.rs @@ -0,0 +1,599 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwTabPage")] + pub struct TabPage(Object) @implements gtk::Accessible; + + match fn { + type_ => || ffi::adw_tab_page_get_type(), + } +} + +impl TabPage { + #[doc(alias = "adw_tab_page_get_child")] + #[doc(alias = "get_child")] + pub fn child(&self) -> gtk::Widget { + unsafe { from_glib_none(ffi::adw_tab_page_get_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_page_get_icon")] + #[doc(alias = "get_icon")] + pub fn icon(&self) -> Option { + unsafe { from_glib_none(ffi::adw_tab_page_get_icon(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_page_get_indicator_activatable")] + #[doc(alias = "get_indicator_activatable")] + pub fn is_indicator_activatable(&self) -> bool { + unsafe { + from_glib(ffi::adw_tab_page_get_indicator_activatable( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_page_get_indicator_icon")] + #[doc(alias = "get_indicator_icon")] + pub fn indicator_icon(&self) -> Option { + unsafe { from_glib_none(ffi::adw_tab_page_get_indicator_icon(self.to_glib_none().0)) } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_tab_page_get_indicator_tooltip")] + #[doc(alias = "get_indicator_tooltip")] + pub fn indicator_tooltip(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_tab_page_get_indicator_tooltip( + self.to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_tab_page_get_keyword")] + #[doc(alias = "get_keyword")] + pub fn keyword(&self) -> Option { + unsafe { from_glib_none(ffi::adw_tab_page_get_keyword(self.to_glib_none().0)) } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_tab_page_get_live_thumbnail")] + #[doc(alias = "get_live_thumbnail")] + pub fn is_live_thumbnail(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_page_get_live_thumbnail(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_page_get_loading")] + #[doc(alias = "get_loading")] + pub fn is_loading(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_page_get_loading(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_page_get_needs_attention")] + #[doc(alias = "get_needs_attention")] + pub fn needs_attention(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_page_get_needs_attention(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_page_get_parent")] + #[doc(alias = "get_parent")] + #[must_use] + pub fn parent(&self) -> Option { + unsafe { from_glib_none(ffi::adw_tab_page_get_parent(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_page_get_pinned")] + #[doc(alias = "get_pinned")] + pub fn is_pinned(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_page_get_pinned(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_page_get_selected")] + #[doc(alias = "get_selected")] + pub fn is_selected(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_page_get_selected(self.to_glib_none().0)) } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_tab_page_get_thumbnail_xalign")] + #[doc(alias = "get_thumbnail_xalign")] + pub fn thumbnail_xalign(&self) -> f32 { + unsafe { ffi::adw_tab_page_get_thumbnail_xalign(self.to_glib_none().0) } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_tab_page_get_thumbnail_yalign")] + #[doc(alias = "get_thumbnail_yalign")] + pub fn thumbnail_yalign(&self) -> f32 { + unsafe { ffi::adw_tab_page_get_thumbnail_yalign(self.to_glib_none().0) } + } + + #[doc(alias = "adw_tab_page_get_title")] + #[doc(alias = "get_title")] + pub fn title(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_tab_page_get_title(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_page_get_tooltip")] + #[doc(alias = "get_tooltip")] + pub fn tooltip(&self) -> Option { + unsafe { from_glib_none(ffi::adw_tab_page_get_tooltip(self.to_glib_none().0)) } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_tab_page_invalidate_thumbnail")] + pub fn invalidate_thumbnail(&self) { + unsafe { + ffi::adw_tab_page_invalidate_thumbnail(self.to_glib_none().0); + } + } + + #[doc(alias = "adw_tab_page_set_icon")] + pub fn set_icon(&self, icon: Option<&impl IsA>) { + unsafe { + ffi::adw_tab_page_set_icon( + self.to_glib_none().0, + icon.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_tab_page_set_indicator_activatable")] + pub fn set_indicator_activatable(&self, activatable: bool) { + unsafe { + ffi::adw_tab_page_set_indicator_activatable( + self.to_glib_none().0, + activatable.into_glib(), + ); + } + } + + #[doc(alias = "adw_tab_page_set_indicator_icon")] + pub fn set_indicator_icon(&self, indicator_icon: Option<&impl IsA>) { + unsafe { + ffi::adw_tab_page_set_indicator_icon( + self.to_glib_none().0, + indicator_icon.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_tab_page_set_indicator_tooltip")] + pub fn set_indicator_tooltip(&self, tooltip: &str) { + unsafe { + ffi::adw_tab_page_set_indicator_tooltip( + self.to_glib_none().0, + tooltip.to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_tab_page_set_keyword")] + pub fn set_keyword(&self, keyword: &str) { + unsafe { + ffi::adw_tab_page_set_keyword(self.to_glib_none().0, keyword.to_glib_none().0); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_tab_page_set_live_thumbnail")] + pub fn set_live_thumbnail(&self, live_thumbnail: bool) { + unsafe { + ffi::adw_tab_page_set_live_thumbnail(self.to_glib_none().0, live_thumbnail.into_glib()); + } + } + + #[doc(alias = "adw_tab_page_set_loading")] + pub fn set_loading(&self, loading: bool) { + unsafe { + ffi::adw_tab_page_set_loading(self.to_glib_none().0, loading.into_glib()); + } + } + + #[doc(alias = "adw_tab_page_set_needs_attention")] + pub fn set_needs_attention(&self, needs_attention: bool) { + unsafe { + ffi::adw_tab_page_set_needs_attention( + self.to_glib_none().0, + needs_attention.into_glib(), + ); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_tab_page_set_thumbnail_xalign")] + pub fn set_thumbnail_xalign(&self, xalign: f32) { + unsafe { + ffi::adw_tab_page_set_thumbnail_xalign(self.to_glib_none().0, xalign); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_tab_page_set_thumbnail_yalign")] + pub fn set_thumbnail_yalign(&self, yalign: f32) { + unsafe { + ffi::adw_tab_page_set_thumbnail_yalign(self.to_glib_none().0, yalign); + } + } + + #[doc(alias = "adw_tab_page_set_title")] + pub fn set_title(&self, title: &str) { + unsafe { + ffi::adw_tab_page_set_title(self.to_glib_none().0, title.to_glib_none().0); + } + } + + #[doc(alias = "adw_tab_page_set_tooltip")] + pub fn set_tooltip(&self, tooltip: &str) { + unsafe { + ffi::adw_tab_page_set_tooltip(self.to_glib_none().0, tooltip.to_glib_none().0); + } + } + + #[doc(alias = "icon")] + pub fn connect_icon_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_icon_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::icon\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_icon_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "indicator-activatable")] + pub fn connect_indicator_activatable_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_indicator_activatable_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::indicator-activatable\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_indicator_activatable_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "indicator-icon")] + pub fn connect_indicator_icon_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_indicator_icon_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::indicator-icon\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_indicator_icon_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "indicator-tooltip")] + pub fn connect_indicator_tooltip_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_indicator_tooltip_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::indicator-tooltip\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_indicator_tooltip_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "keyword")] + pub fn connect_keyword_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_keyword_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::keyword\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_keyword_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "live-thumbnail")] + pub fn connect_live_thumbnail_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_live_thumbnail_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::live-thumbnail\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_live_thumbnail_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "loading")] + pub fn connect_loading_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_loading_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::loading\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_loading_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "needs-attention")] + pub fn connect_needs_attention_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_needs_attention_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::needs-attention\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_needs_attention_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "pinned")] + pub fn connect_pinned_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_pinned_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::pinned\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_pinned_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "selected")] + pub fn connect_selected_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_selected_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::selected\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_selected_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "thumbnail-xalign")] + pub fn connect_thumbnail_xalign_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_thumbnail_xalign_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::thumbnail-xalign\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_thumbnail_xalign_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "thumbnail-yalign")] + pub fn connect_thumbnail_yalign_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_thumbnail_yalign_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::thumbnail-yalign\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_thumbnail_yalign_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "title")] + pub fn connect_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "tooltip")] + pub fn connect_tooltip_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_tooltip_trampoline( + this: *mut ffi::AdwTabPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::tooltip\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_tooltip_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for TabPage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("TabPage") + } +} diff --git a/libadwaita-0.4.4/src/auto/tab_view.rs b/libadwaita-0.4.4/src/auto/tab_view.rs new file mode 100644 index 0000000..d70a22b --- /dev/null +++ b/libadwaita-0.4.4/src/auto/tab_view.rs @@ -0,0 +1,1009 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::TabPage; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +use crate::TabViewShortcuts; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwTabView")] + pub struct TabView(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_tab_view_get_type(), + } +} + +impl TabView { + #[doc(alias = "adw_tab_view_new")] + pub fn new() -> TabView { + assert_initialized_main_thread!(); + unsafe { from_glib_none(ffi::adw_tab_view_new()) } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`TabView`] objects. + /// + /// This method returns an instance of [`TabViewBuilder`](crate::builders::TabViewBuilder) which can be used to create [`TabView`] objects. + pub fn builder() -> TabViewBuilder { + TabViewBuilder::new() + } + + #[doc(alias = "adw_tab_view_add_page")] + pub fn add_page(&self, child: &impl IsA, parent: Option<&TabPage>) -> TabPage { + unsafe { + from_glib_none(ffi::adw_tab_view_add_page( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + parent.to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_tab_view_add_shortcuts")] + pub fn add_shortcuts(&self, shortcuts: TabViewShortcuts) { + unsafe { + ffi::adw_tab_view_add_shortcuts(self.to_glib_none().0, shortcuts.into_glib()); + } + } + + #[doc(alias = "adw_tab_view_append")] + pub fn append(&self, child: &impl IsA) -> TabPage { + unsafe { + from_glib_none(ffi::adw_tab_view_append( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_view_append_pinned")] + pub fn append_pinned(&self, child: &impl IsA) -> TabPage { + unsafe { + from_glib_none(ffi::adw_tab_view_append_pinned( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_view_close_other_pages")] + pub fn close_other_pages(&self, page: &TabPage) { + unsafe { + ffi::adw_tab_view_close_other_pages(self.to_glib_none().0, page.to_glib_none().0); + } + } + + #[doc(alias = "adw_tab_view_close_page")] + pub fn close_page(&self, page: &TabPage) { + unsafe { + ffi::adw_tab_view_close_page(self.to_glib_none().0, page.to_glib_none().0); + } + } + + #[doc(alias = "adw_tab_view_close_page_finish")] + pub fn close_page_finish(&self, page: &TabPage, confirm: bool) { + unsafe { + ffi::adw_tab_view_close_page_finish( + self.to_glib_none().0, + page.to_glib_none().0, + confirm.into_glib(), + ); + } + } + + #[doc(alias = "adw_tab_view_close_pages_after")] + pub fn close_pages_after(&self, page: &TabPage) { + unsafe { + ffi::adw_tab_view_close_pages_after(self.to_glib_none().0, page.to_glib_none().0); + } + } + + #[doc(alias = "adw_tab_view_close_pages_before")] + pub fn close_pages_before(&self, page: &TabPage) { + unsafe { + ffi::adw_tab_view_close_pages_before(self.to_glib_none().0, page.to_glib_none().0); + } + } + + #[doc(alias = "adw_tab_view_get_default_icon")] + #[doc(alias = "get_default_icon")] + pub fn default_icon(&self) -> gio::Icon { + unsafe { from_glib_none(ffi::adw_tab_view_get_default_icon(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_view_get_is_transferring_page")] + #[doc(alias = "get_is_transferring_page")] + pub fn is_transferring_page(&self) -> bool { + unsafe { + from_glib(ffi::adw_tab_view_get_is_transferring_page( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_view_get_menu_model")] + #[doc(alias = "get_menu_model")] + pub fn menu_model(&self) -> Option { + unsafe { from_glib_none(ffi::adw_tab_view_get_menu_model(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_view_get_n_pages")] + #[doc(alias = "get_n_pages")] + pub fn n_pages(&self) -> i32 { + unsafe { ffi::adw_tab_view_get_n_pages(self.to_glib_none().0) } + } + + #[doc(alias = "adw_tab_view_get_n_pinned_pages")] + #[doc(alias = "get_n_pinned_pages")] + pub fn n_pinned_pages(&self) -> i32 { + unsafe { ffi::adw_tab_view_get_n_pinned_pages(self.to_glib_none().0) } + } + + #[doc(alias = "adw_tab_view_get_page")] + #[doc(alias = "get_page")] + pub fn page(&self, child: &impl IsA) -> TabPage { + unsafe { + from_glib_none(ffi::adw_tab_view_get_page( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_view_get_page_position")] + #[doc(alias = "get_page_position")] + pub fn page_position(&self, page: &TabPage) -> i32 { + unsafe { ffi::adw_tab_view_get_page_position(self.to_glib_none().0, page.to_glib_none().0) } + } + + #[doc(alias = "adw_tab_view_get_pages")] + #[doc(alias = "get_pages")] + pub fn pages(&self) -> gtk::SelectionModel { + unsafe { from_glib_full(ffi::adw_tab_view_get_pages(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_view_get_selected_page")] + #[doc(alias = "get_selected_page")] + pub fn selected_page(&self) -> Option { + unsafe { from_glib_none(ffi::adw_tab_view_get_selected_page(self.to_glib_none().0)) } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_tab_view_get_shortcuts")] + #[doc(alias = "get_shortcuts")] + pub fn shortcuts(&self) -> TabViewShortcuts { + unsafe { from_glib(ffi::adw_tab_view_get_shortcuts(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_view_insert")] + pub fn insert(&self, child: &impl IsA, position: i32) -> TabPage { + unsafe { + from_glib_none(ffi::adw_tab_view_insert( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + position, + )) + } + } + + #[doc(alias = "adw_tab_view_insert_pinned")] + pub fn insert_pinned(&self, child: &impl IsA, position: i32) -> TabPage { + unsafe { + from_glib_none(ffi::adw_tab_view_insert_pinned( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + position, + )) + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_tab_view_invalidate_thumbnails")] + pub fn invalidate_thumbnails(&self) { + unsafe { + ffi::adw_tab_view_invalidate_thumbnails(self.to_glib_none().0); + } + } + + #[doc(alias = "adw_tab_view_prepend")] + pub fn prepend(&self, child: &impl IsA) -> TabPage { + unsafe { + from_glib_none(ffi::adw_tab_view_prepend( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_view_prepend_pinned")] + pub fn prepend_pinned(&self, child: &impl IsA) -> TabPage { + unsafe { + from_glib_none(ffi::adw_tab_view_prepend_pinned( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_tab_view_remove_shortcuts")] + pub fn remove_shortcuts(&self, shortcuts: TabViewShortcuts) { + unsafe { + ffi::adw_tab_view_remove_shortcuts(self.to_glib_none().0, shortcuts.into_glib()); + } + } + + #[doc(alias = "adw_tab_view_reorder_backward")] + pub fn reorder_backward(&self, page: &TabPage) -> bool { + unsafe { + from_glib(ffi::adw_tab_view_reorder_backward( + self.to_glib_none().0, + page.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_view_reorder_first")] + pub fn reorder_first(&self, page: &TabPage) -> bool { + unsafe { + from_glib(ffi::adw_tab_view_reorder_first( + self.to_glib_none().0, + page.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_view_reorder_forward")] + pub fn reorder_forward(&self, page: &TabPage) -> bool { + unsafe { + from_glib(ffi::adw_tab_view_reorder_forward( + self.to_glib_none().0, + page.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_view_reorder_last")] + pub fn reorder_last(&self, page: &TabPage) -> bool { + unsafe { + from_glib(ffi::adw_tab_view_reorder_last( + self.to_glib_none().0, + page.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_view_reorder_page")] + pub fn reorder_page(&self, page: &TabPage, position: i32) -> bool { + unsafe { + from_glib(ffi::adw_tab_view_reorder_page( + self.to_glib_none().0, + page.to_glib_none().0, + position, + )) + } + } + + #[doc(alias = "adw_tab_view_select_next_page")] + pub fn select_next_page(&self) -> bool { + unsafe { from_glib(ffi::adw_tab_view_select_next_page(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_tab_view_select_previous_page")] + pub fn select_previous_page(&self) -> bool { + unsafe { + from_glib(ffi::adw_tab_view_select_previous_page( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_tab_view_set_default_icon")] + pub fn set_default_icon(&self, default_icon: &impl IsA) { + unsafe { + ffi::adw_tab_view_set_default_icon( + self.to_glib_none().0, + default_icon.as_ref().to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_tab_view_set_menu_model")] + pub fn set_menu_model(&self, menu_model: Option<&impl IsA>) { + unsafe { + ffi::adw_tab_view_set_menu_model( + self.to_glib_none().0, + menu_model.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_tab_view_set_page_pinned")] + pub fn set_page_pinned(&self, page: &TabPage, pinned: bool) { + unsafe { + ffi::adw_tab_view_set_page_pinned( + self.to_glib_none().0, + page.to_glib_none().0, + pinned.into_glib(), + ); + } + } + + #[doc(alias = "adw_tab_view_set_selected_page")] + pub fn set_selected_page(&self, selected_page: &TabPage) { + unsafe { + ffi::adw_tab_view_set_selected_page( + self.to_glib_none().0, + selected_page.to_glib_none().0, + ); + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_tab_view_set_shortcuts")] + pub fn set_shortcuts(&self, shortcuts: TabViewShortcuts) { + unsafe { + ffi::adw_tab_view_set_shortcuts(self.to_glib_none().0, shortcuts.into_glib()); + } + } + + #[doc(alias = "adw_tab_view_transfer_page")] + pub fn transfer_page(&self, page: &TabPage, other_view: &TabView, position: i32) { + unsafe { + ffi::adw_tab_view_transfer_page( + self.to_glib_none().0, + page.to_glib_none().0, + other_view.to_glib_none().0, + position, + ); + } + } + + #[doc(alias = "close-page")] + pub fn connect_close_page bool + 'static>( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn close_page_trampoline bool + 'static>( + this: *mut ffi::AdwTabView, + page: *mut ffi::AdwTabPage, + f: glib::ffi::gpointer, + ) -> glib::ffi::gboolean { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), &from_glib_borrow(page)).into_glib() + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"close-page\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + close_page_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "create-window")] + pub fn connect_create_window Option + 'static>( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn create_window_trampoline< + F: Fn(&TabView) -> Option + 'static, + >( + this: *mut ffi::AdwTabView, + f: glib::ffi::gpointer, + ) -> *mut ffi::AdwTabView { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) /*Not checked*/ + .to_glib_none() + .0 + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"create-window\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + create_window_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "indicator-activated")] + pub fn connect_indicator_activated( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn indicator_activated_trampoline( + this: *mut ffi::AdwTabView, + page: *mut ffi::AdwTabPage, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), &from_glib_borrow(page)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"indicator-activated\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + indicator_activated_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "page-attached")] + pub fn connect_page_attached( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn page_attached_trampoline( + this: *mut ffi::AdwTabView, + page: *mut ffi::AdwTabPage, + position: libc::c_int, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), &from_glib_borrow(page), position) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"page-attached\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + page_attached_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "page-detached")] + pub fn connect_page_detached( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn page_detached_trampoline( + this: *mut ffi::AdwTabView, + page: *mut ffi::AdwTabPage, + position: libc::c_int, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), &from_glib_borrow(page), position) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"page-detached\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + page_detached_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "page-reordered")] + pub fn connect_page_reordered( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn page_reordered_trampoline( + this: *mut ffi::AdwTabView, + page: *mut ffi::AdwTabPage, + position: libc::c_int, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), &from_glib_borrow(page), position) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"page-reordered\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + page_reordered_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "setup-menu")] + pub fn connect_setup_menu) + 'static>( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn setup_menu_trampoline) + 'static>( + this: *mut ffi::AdwTabView, + page: *mut ffi::AdwTabPage, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f( + &from_glib_borrow(this), + Option::::from_glib_borrow(page).as_ref().as_ref(), + ) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"setup-menu\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + setup_menu_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "default-icon")] + pub fn connect_default_icon_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_default_icon_trampoline( + this: *mut ffi::AdwTabView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::default-icon\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_default_icon_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "is-transferring-page")] + pub fn connect_is_transferring_page_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_is_transferring_page_trampoline( + this: *mut ffi::AdwTabView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::is-transferring-page\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_is_transferring_page_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "menu-model")] + pub fn connect_menu_model_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_menu_model_trampoline( + this: *mut ffi::AdwTabView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::menu-model\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_menu_model_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "n-pages")] + pub fn connect_n_pages_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_n_pages_trampoline( + this: *mut ffi::AdwTabView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::n-pages\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_n_pages_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "n-pinned-pages")] + pub fn connect_n_pinned_pages_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_n_pinned_pages_trampoline( + this: *mut ffi::AdwTabView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::n-pinned-pages\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_n_pinned_pages_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "pages")] + pub fn connect_pages_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_pages_trampoline( + this: *mut ffi::AdwTabView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::pages\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_pages_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "selected-page")] + pub fn connect_selected_page_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_selected_page_trampoline( + this: *mut ffi::AdwTabView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::selected-page\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_selected_page_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "shortcuts")] + pub fn connect_shortcuts_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_shortcuts_trampoline( + this: *mut ffi::AdwTabView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::shortcuts\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_shortcuts_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for TabView { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`TabView`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct TabViewBuilder { + builder: glib::object::ObjectBuilder<'static, TabView>, +} + +impl TabViewBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn default_icon(self, default_icon: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("default-icon", default_icon.clone().upcast()), + } + } + + pub fn menu_model(self, menu_model: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("menu-model", menu_model.clone().upcast()), + } + } + + pub fn selected_page(self, selected_page: &TabPage) -> Self { + Self { + builder: self + .builder + .property("selected-page", selected_page.clone()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn shortcuts(self, shortcuts: TabViewShortcuts) -> Self { + Self { + builder: self.builder.property("shortcuts", shortcuts), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`TabView`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> TabView { + self.builder.build() + } +} + +impl fmt::Display for TabView { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("TabView") + } +} diff --git a/libadwaita-0.4.4/src/auto/timed_animation.rs b/libadwaita-0.4.4/src/auto/timed_animation.rs new file mode 100644 index 0000000..f3671e7 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/timed_animation.rs @@ -0,0 +1,409 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{Animation, AnimationTarget, Easing}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwTimedAnimation")] + pub struct TimedAnimation(Object) @extends Animation; + + match fn { + type_ => || ffi::adw_timed_animation_get_type(), + } +} + +impl TimedAnimation { + #[doc(alias = "adw_timed_animation_new")] + pub fn new( + widget: &impl IsA, + from: f64, + to: f64, + duration: u32, + target: impl IsA, + ) -> TimedAnimation { + skip_assert_initialized!(); + unsafe { + Animation::from_glib_none(ffi::adw_timed_animation_new( + widget.as_ref().to_glib_none().0, + from, + to, + duration, + target.upcast().into_glib_ptr(), + )) + .unsafe_cast() + } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`TimedAnimation`] objects. + /// + /// This method returns an instance of [`TimedAnimationBuilder`](crate::builders::TimedAnimationBuilder) which can be used to create [`TimedAnimation`] objects. + pub fn builder() -> TimedAnimationBuilder { + TimedAnimationBuilder::new() + } + + #[doc(alias = "adw_timed_animation_get_alternate")] + #[doc(alias = "get_alternate")] + pub fn is_alternate(&self) -> bool { + unsafe { + from_glib(ffi::adw_timed_animation_get_alternate( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_timed_animation_get_duration")] + #[doc(alias = "get_duration")] + pub fn duration(&self) -> u32 { + unsafe { ffi::adw_timed_animation_get_duration(self.to_glib_none().0) } + } + + #[doc(alias = "adw_timed_animation_get_easing")] + #[doc(alias = "get_easing")] + pub fn easing(&self) -> Easing { + unsafe { from_glib(ffi::adw_timed_animation_get_easing(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_timed_animation_get_repeat_count")] + #[doc(alias = "get_repeat_count")] + pub fn repeat_count(&self) -> u32 { + unsafe { ffi::adw_timed_animation_get_repeat_count(self.to_glib_none().0) } + } + + #[doc(alias = "adw_timed_animation_get_reverse")] + #[doc(alias = "get_reverse")] + pub fn is_reverse(&self) -> bool { + unsafe { from_glib(ffi::adw_timed_animation_get_reverse(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_timed_animation_get_value_from")] + #[doc(alias = "get_value_from")] + pub fn value_from(&self) -> f64 { + unsafe { ffi::adw_timed_animation_get_value_from(self.to_glib_none().0) } + } + + #[doc(alias = "adw_timed_animation_get_value_to")] + #[doc(alias = "get_value_to")] + pub fn value_to(&self) -> f64 { + unsafe { ffi::adw_timed_animation_get_value_to(self.to_glib_none().0) } + } + + #[doc(alias = "adw_timed_animation_set_alternate")] + pub fn set_alternate(&self, alternate: bool) { + unsafe { + ffi::adw_timed_animation_set_alternate(self.to_glib_none().0, alternate.into_glib()); + } + } + + #[doc(alias = "adw_timed_animation_set_duration")] + pub fn set_duration(&self, duration: u32) { + unsafe { + ffi::adw_timed_animation_set_duration(self.to_glib_none().0, duration); + } + } + + #[doc(alias = "adw_timed_animation_set_easing")] + pub fn set_easing(&self, easing: Easing) { + unsafe { + ffi::adw_timed_animation_set_easing(self.to_glib_none().0, easing.into_glib()); + } + } + + #[doc(alias = "adw_timed_animation_set_repeat_count")] + pub fn set_repeat_count(&self, repeat_count: u32) { + unsafe { + ffi::adw_timed_animation_set_repeat_count(self.to_glib_none().0, repeat_count); + } + } + + #[doc(alias = "adw_timed_animation_set_reverse")] + pub fn set_reverse(&self, reverse: bool) { + unsafe { + ffi::adw_timed_animation_set_reverse(self.to_glib_none().0, reverse.into_glib()); + } + } + + #[doc(alias = "adw_timed_animation_set_value_from")] + pub fn set_value_from(&self, value: f64) { + unsafe { + ffi::adw_timed_animation_set_value_from(self.to_glib_none().0, value); + } + } + + #[doc(alias = "adw_timed_animation_set_value_to")] + pub fn set_value_to(&self, value: f64) { + unsafe { + ffi::adw_timed_animation_set_value_to(self.to_glib_none().0, value); + } + } + + #[doc(alias = "alternate")] + pub fn connect_alternate_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_alternate_trampoline( + this: *mut ffi::AdwTimedAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::alternate\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_alternate_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "duration")] + pub fn connect_duration_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_duration_trampoline( + this: *mut ffi::AdwTimedAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::duration\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_duration_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "easing")] + pub fn connect_easing_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_easing_trampoline( + this: *mut ffi::AdwTimedAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::easing\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_easing_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "repeat-count")] + pub fn connect_repeat_count_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_repeat_count_trampoline( + this: *mut ffi::AdwTimedAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::repeat-count\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_repeat_count_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "reverse")] + pub fn connect_reverse_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_reverse_trampoline( + this: *mut ffi::AdwTimedAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::reverse\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_reverse_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "value-from")] + pub fn connect_value_from_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_value_from_trampoline( + this: *mut ffi::AdwTimedAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::value-from\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_value_from_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "value-to")] + pub fn connect_value_to_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_value_to_trampoline( + this: *mut ffi::AdwTimedAnimation, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::value-to\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_value_to_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for TimedAnimation { + fn default() -> Self { + glib::object::Object::new::() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`TimedAnimation`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct TimedAnimationBuilder { + builder: glib::object::ObjectBuilder<'static, TimedAnimation>, +} + +impl TimedAnimationBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn alternate(self, alternate: bool) -> Self { + Self { + builder: self.builder.property("alternate", alternate), + } + } + + pub fn duration(self, duration: u32) -> Self { + Self { + builder: self.builder.property("duration", duration), + } + } + + pub fn easing(self, easing: Easing) -> Self { + Self { + builder: self.builder.property("easing", easing), + } + } + + pub fn repeat_count(self, repeat_count: u32) -> Self { + Self { + builder: self.builder.property("repeat-count", repeat_count), + } + } + + pub fn reverse(self, reverse: bool) -> Self { + Self { + builder: self.builder.property("reverse", reverse), + } + } + + pub fn value_from(self, value_from: f64) -> Self { + Self { + builder: self.builder.property("value-from", value_from), + } + } + + pub fn value_to(self, value_to: f64) -> Self { + Self { + builder: self.builder.property("value-to", value_to), + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + pub fn follow_enable_animations_setting(self, follow_enable_animations_setting: bool) -> Self { + Self { + builder: self.builder.property( + "follow-enable-animations-setting", + follow_enable_animations_setting, + ), + } + } + + pub fn target(self, target: &impl IsA) -> Self { + Self { + builder: self.builder.property("target", target.clone().upcast()), + } + } + + pub fn widget(self, widget: &impl IsA) -> Self { + Self { + builder: self.builder.property("widget", widget.clone().upcast()), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`TimedAnimation`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> TimedAnimation { + self.builder.build() + } +} + +impl fmt::Display for TimedAnimation { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("TimedAnimation") + } +} diff --git a/libadwaita-0.4.4/src/auto/toast.rs b/libadwaita-0.4.4/src/auto/toast.rs new file mode 100644 index 0000000..48b6bf5 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/toast.rs @@ -0,0 +1,452 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::ToastPriority; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwToast")] + pub struct Toast(Object); + + match fn { + type_ => || ffi::adw_toast_get_type(), + } +} + +impl Toast { + #[doc(alias = "adw_toast_new")] + pub fn new(title: &str) -> Toast { + assert_initialized_main_thread!(); + unsafe { from_glib_full(ffi::adw_toast_new(title.to_glib_none().0)) } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`Toast`] objects. + /// + /// This method returns an instance of [`ToastBuilder`](crate::builders::ToastBuilder) which can be used to create [`Toast`] objects. + pub fn builder() -> ToastBuilder { + ToastBuilder::new() + } + + #[doc(alias = "adw_toast_dismiss")] + pub fn dismiss(&self) { + unsafe { + ffi::adw_toast_dismiss(self.to_glib_none().0); + } + } + + #[doc(alias = "adw_toast_get_action_name")] + #[doc(alias = "get_action_name")] + pub fn action_name(&self) -> Option { + unsafe { from_glib_none(ffi::adw_toast_get_action_name(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_toast_get_action_target_value")] + #[doc(alias = "get_action_target_value")] + pub fn action_target_value(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_toast_get_action_target_value( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_toast_get_button_label")] + #[doc(alias = "get_button_label")] + pub fn button_label(&self) -> Option { + unsafe { from_glib_none(ffi::adw_toast_get_button_label(self.to_glib_none().0)) } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_toast_get_custom_title")] + #[doc(alias = "get_custom_title")] + pub fn custom_title(&self) -> Option { + unsafe { from_glib_none(ffi::adw_toast_get_custom_title(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_toast_get_priority")] + #[doc(alias = "get_priority")] + pub fn priority(&self) -> ToastPriority { + unsafe { from_glib(ffi::adw_toast_get_priority(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_toast_get_timeout")] + #[doc(alias = "get_timeout")] + pub fn timeout(&self) -> u32 { + unsafe { ffi::adw_toast_get_timeout(self.to_glib_none().0) } + } + + #[doc(alias = "adw_toast_get_title")] + #[doc(alias = "get_title")] + pub fn title(&self) -> Option { + unsafe { from_glib_none(ffi::adw_toast_get_title(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_toast_set_action_name")] + pub fn set_action_name(&self, action_name: Option<&str>) { + unsafe { + ffi::adw_toast_set_action_name(self.to_glib_none().0, action_name.to_glib_none().0); + } + } + + #[doc(alias = "adw_toast_set_action_target_value")] + pub fn set_action_target_value(&self, action_target: Option<&glib::Variant>) { + unsafe { + ffi::adw_toast_set_action_target_value( + self.to_glib_none().0, + action_target.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_toast_set_button_label")] + pub fn set_button_label(&self, button_label: Option<&str>) { + unsafe { + ffi::adw_toast_set_button_label(self.to_glib_none().0, button_label.to_glib_none().0); + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_toast_set_custom_title")] + pub fn set_custom_title(&self, widget: Option<&impl IsA>) { + unsafe { + ffi::adw_toast_set_custom_title( + self.to_glib_none().0, + widget.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_toast_set_detailed_action_name")] + pub fn set_detailed_action_name(&self, detailed_action_name: Option<&str>) { + unsafe { + ffi::adw_toast_set_detailed_action_name( + self.to_glib_none().0, + detailed_action_name.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_toast_set_priority")] + pub fn set_priority(&self, priority: ToastPriority) { + unsafe { + ffi::adw_toast_set_priority(self.to_glib_none().0, priority.into_glib()); + } + } + + #[doc(alias = "adw_toast_set_timeout")] + pub fn set_timeout(&self, timeout: u32) { + unsafe { + ffi::adw_toast_set_timeout(self.to_glib_none().0, timeout); + } + } + + #[doc(alias = "adw_toast_set_title")] + pub fn set_title(&self, title: &str) { + unsafe { + ffi::adw_toast_set_title(self.to_glib_none().0, title.to_glib_none().0); + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "button-clicked")] + pub fn connect_button_clicked(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn button_clicked_trampoline( + this: *mut ffi::AdwToast, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"button-clicked\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + button_clicked_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "dismissed")] + pub fn connect_dismissed(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn dismissed_trampoline( + this: *mut ffi::AdwToast, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"dismissed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + dismissed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "action-name")] + pub fn connect_action_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_action_name_trampoline( + this: *mut ffi::AdwToast, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::action-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_action_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "action-target")] + pub fn connect_action_target_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_action_target_trampoline( + this: *mut ffi::AdwToast, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::action-target\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_action_target_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "button-label")] + pub fn connect_button_label_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_button_label_trampoline( + this: *mut ffi::AdwToast, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::button-label\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_button_label_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "custom-title")] + pub fn connect_custom_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_custom_title_trampoline( + this: *mut ffi::AdwToast, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::custom-title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_custom_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "priority")] + pub fn connect_priority_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_priority_trampoline( + this: *mut ffi::AdwToast, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::priority\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_priority_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "timeout")] + pub fn connect_timeout_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_timeout_trampoline( + this: *mut ffi::AdwToast, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::timeout\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_timeout_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "title")] + pub fn connect_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_trampoline( + this: *mut ffi::AdwToast, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for Toast { + fn default() -> Self { + glib::object::Object::new::() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`Toast`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ToastBuilder { + builder: glib::object::ObjectBuilder<'static, Toast>, +} + +impl ToastBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn action_name(self, action_name: impl Into) -> Self { + Self { + builder: self.builder.property("action-name", action_name.into()), + } + } + + pub fn action_target(self, action_target: &glib::Variant) -> Self { + Self { + builder: self + .builder + .property("action-target", action_target.clone()), + } + } + + pub fn button_label(self, button_label: impl Into) -> Self { + Self { + builder: self.builder.property("button-label", button_label.into()), + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub fn custom_title(self, custom_title: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("custom-title", custom_title.clone().upcast()), + } + } + + pub fn priority(self, priority: ToastPriority) -> Self { + Self { + builder: self.builder.property("priority", priority), + } + } + + pub fn timeout(self, timeout: u32) -> Self { + Self { + builder: self.builder.property("timeout", timeout), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`Toast`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> Toast { + self.builder.build() + } +} + +impl fmt::Display for Toast { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Toast") + } +} diff --git a/libadwaita-0.4.4/src/auto/toast_overlay.rs b/libadwaita-0.4.4/src/auto/toast_overlay.rs new file mode 100644 index 0000000..fc44445 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/toast_overlay.rs @@ -0,0 +1,87 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::Toast; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwToastOverlay")] + pub struct ToastOverlay(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_toast_overlay_get_type(), + } +} + +impl ToastOverlay { + #[doc(alias = "adw_toast_overlay_new")] + pub fn new() -> ToastOverlay { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_toast_overlay_new()).unsafe_cast() } + } + + #[doc(alias = "adw_toast_overlay_add_toast")] + pub fn add_toast(&self, toast: Toast) { + unsafe { + ffi::adw_toast_overlay_add_toast(self.to_glib_none().0, toast.into_glib_ptr()); + } + } + + #[doc(alias = "adw_toast_overlay_get_child")] + #[doc(alias = "get_child")] + pub fn child(&self) -> Option { + unsafe { from_glib_none(ffi::adw_toast_overlay_get_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_toast_overlay_set_child")] + pub fn set_child(&self, child: Option<&impl IsA>) { + unsafe { + ffi::adw_toast_overlay_set_child( + self.to_glib_none().0, + child.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "child")] + pub fn connect_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_child_trampoline( + this: *mut ffi::AdwToastOverlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for ToastOverlay { + fn default() -> Self { + Self::new() + } +} + +impl fmt::Display for ToastOverlay { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ToastOverlay") + } +} diff --git a/libadwaita-0.4.4/src/auto/toolbar_view.rs b/libadwaita-0.4.4/src/auto/toolbar_view.rs new file mode 100644 index 0000000..d2df592 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/toolbar_view.rs @@ -0,0 +1,726 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::ToolbarStyle; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwToolbarView")] + pub struct ToolbarView(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_toolbar_view_get_type(), + } +} + +impl ToolbarView { + #[doc(alias = "adw_toolbar_view_new")] + pub fn new() -> ToolbarView { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_toolbar_view_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`ToolbarView`] objects. + /// + /// This method returns an instance of [`ToolbarViewBuilder`](crate::builders::ToolbarViewBuilder) which can be used to create [`ToolbarView`] objects. + pub fn builder() -> ToolbarViewBuilder { + ToolbarViewBuilder::new() + } + + #[doc(alias = "adw_toolbar_view_add_bottom_bar")] + pub fn add_bottom_bar(&self, widget: &impl IsA) { + unsafe { + ffi::adw_toolbar_view_add_bottom_bar( + self.to_glib_none().0, + widget.as_ref().to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_toolbar_view_add_top_bar")] + pub fn add_top_bar(&self, widget: &impl IsA) { + unsafe { + ffi::adw_toolbar_view_add_top_bar( + self.to_glib_none().0, + widget.as_ref().to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_toolbar_view_get_bottom_bar_height")] + #[doc(alias = "get_bottom_bar_height")] + pub fn bottom_bar_height(&self) -> i32 { + unsafe { ffi::adw_toolbar_view_get_bottom_bar_height(self.to_glib_none().0) } + } + + #[doc(alias = "adw_toolbar_view_get_bottom_bar_style")] + #[doc(alias = "get_bottom_bar_style")] + pub fn bottom_bar_style(&self) -> ToolbarStyle { + unsafe { + from_glib(ffi::adw_toolbar_view_get_bottom_bar_style( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_toolbar_view_get_content")] + #[doc(alias = "get_content")] + pub fn content(&self) -> Option { + unsafe { from_glib_none(ffi::adw_toolbar_view_get_content(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_toolbar_view_get_extend_content_to_bottom_edge")] + #[doc(alias = "get_extend_content_to_bottom_edge")] + pub fn is_extend_content_to_bottom_edge(&self) -> bool { + unsafe { + from_glib(ffi::adw_toolbar_view_get_extend_content_to_bottom_edge( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_toolbar_view_get_extend_content_to_top_edge")] + #[doc(alias = "get_extend_content_to_top_edge")] + pub fn is_extend_content_to_top_edge(&self) -> bool { + unsafe { + from_glib(ffi::adw_toolbar_view_get_extend_content_to_top_edge( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_toolbar_view_get_reveal_bottom_bars")] + #[doc(alias = "get_reveal_bottom_bars")] + pub fn reveals_bottom_bars(&self) -> bool { + unsafe { + from_glib(ffi::adw_toolbar_view_get_reveal_bottom_bars( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_toolbar_view_get_reveal_top_bars")] + #[doc(alias = "get_reveal_top_bars")] + pub fn reveals_top_bars(&self) -> bool { + unsafe { + from_glib(ffi::adw_toolbar_view_get_reveal_top_bars( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_toolbar_view_get_top_bar_height")] + #[doc(alias = "get_top_bar_height")] + pub fn top_bar_height(&self) -> i32 { + unsafe { ffi::adw_toolbar_view_get_top_bar_height(self.to_glib_none().0) } + } + + #[doc(alias = "adw_toolbar_view_get_top_bar_style")] + #[doc(alias = "get_top_bar_style")] + pub fn top_bar_style(&self) -> ToolbarStyle { + unsafe { + from_glib(ffi::adw_toolbar_view_get_top_bar_style( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_toolbar_view_remove")] + pub fn remove(&self, widget: &impl IsA) { + unsafe { + ffi::adw_toolbar_view_remove(self.to_glib_none().0, widget.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_toolbar_view_set_bottom_bar_style")] + pub fn set_bottom_bar_style(&self, style: ToolbarStyle) { + unsafe { + ffi::adw_toolbar_view_set_bottom_bar_style(self.to_glib_none().0, style.into_glib()); + } + } + + #[doc(alias = "adw_toolbar_view_set_content")] + pub fn set_content(&self, content: Option<&impl IsA>) { + unsafe { + ffi::adw_toolbar_view_set_content( + self.to_glib_none().0, + content.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_toolbar_view_set_extend_content_to_bottom_edge")] + pub fn set_extend_content_to_bottom_edge(&self, extend: bool) { + unsafe { + ffi::adw_toolbar_view_set_extend_content_to_bottom_edge( + self.to_glib_none().0, + extend.into_glib(), + ); + } + } + + #[doc(alias = "adw_toolbar_view_set_extend_content_to_top_edge")] + pub fn set_extend_content_to_top_edge(&self, extend: bool) { + unsafe { + ffi::adw_toolbar_view_set_extend_content_to_top_edge( + self.to_glib_none().0, + extend.into_glib(), + ); + } + } + + #[doc(alias = "adw_toolbar_view_set_reveal_bottom_bars")] + pub fn set_reveal_bottom_bars(&self, reveal: bool) { + unsafe { + ffi::adw_toolbar_view_set_reveal_bottom_bars(self.to_glib_none().0, reveal.into_glib()); + } + } + + #[doc(alias = "adw_toolbar_view_set_reveal_top_bars")] + pub fn set_reveal_top_bars(&self, reveal: bool) { + unsafe { + ffi::adw_toolbar_view_set_reveal_top_bars(self.to_glib_none().0, reveal.into_glib()); + } + } + + #[doc(alias = "adw_toolbar_view_set_top_bar_style")] + pub fn set_top_bar_style(&self, style: ToolbarStyle) { + unsafe { + ffi::adw_toolbar_view_set_top_bar_style(self.to_glib_none().0, style.into_glib()); + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "bottom-bar-height")] + pub fn connect_bottom_bar_height_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_bottom_bar_height_trampoline( + this: *mut ffi::AdwToolbarView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::bottom-bar-height\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_bottom_bar_height_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "bottom-bar-style")] + pub fn connect_bottom_bar_style_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_bottom_bar_style_trampoline( + this: *mut ffi::AdwToolbarView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::bottom-bar-style\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_bottom_bar_style_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "content")] + pub fn connect_content_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_content_trampoline( + this: *mut ffi::AdwToolbarView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::content\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_content_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "extend-content-to-bottom-edge")] + pub fn connect_extend_content_to_bottom_edge_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_extend_content_to_bottom_edge_trampoline< + F: Fn(&ToolbarView) + 'static, + >( + this: *mut ffi::AdwToolbarView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::extend-content-to-bottom-edge\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_extend_content_to_bottom_edge_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "extend-content-to-top-edge")] + pub fn connect_extend_content_to_top_edge_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_extend_content_to_top_edge_trampoline< + F: Fn(&ToolbarView) + 'static, + >( + this: *mut ffi::AdwToolbarView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::extend-content-to-top-edge\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_extend_content_to_top_edge_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "reveal-bottom-bars")] + pub fn connect_reveal_bottom_bars_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_reveal_bottom_bars_trampoline( + this: *mut ffi::AdwToolbarView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::reveal-bottom-bars\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_reveal_bottom_bars_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "reveal-top-bars")] + pub fn connect_reveal_top_bars_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_reveal_top_bars_trampoline( + this: *mut ffi::AdwToolbarView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::reveal-top-bars\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_reveal_top_bars_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "top-bar-height")] + pub fn connect_top_bar_height_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_top_bar_height_trampoline( + this: *mut ffi::AdwToolbarView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::top-bar-height\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_top_bar_height_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "top-bar-style")] + pub fn connect_top_bar_style_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_top_bar_style_trampoline( + this: *mut ffi::AdwToolbarView, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::top-bar-style\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_top_bar_style_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +impl Default for ToolbarView { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`ToolbarView`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ToolbarViewBuilder { + builder: glib::object::ObjectBuilder<'static, ToolbarView>, +} + +impl ToolbarViewBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn bottom_bar_style(self, bottom_bar_style: ToolbarStyle) -> Self { + Self { + builder: self.builder.property("bottom-bar-style", bottom_bar_style), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn content(self, content: &impl IsA) -> Self { + Self { + builder: self.builder.property("content", content.clone().upcast()), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn extend_content_to_bottom_edge(self, extend_content_to_bottom_edge: bool) -> Self { + Self { + builder: self.builder.property( + "extend-content-to-bottom-edge", + extend_content_to_bottom_edge, + ), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn extend_content_to_top_edge(self, extend_content_to_top_edge: bool) -> Self { + Self { + builder: self + .builder + .property("extend-content-to-top-edge", extend_content_to_top_edge), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn reveal_bottom_bars(self, reveal_bottom_bars: bool) -> Self { + Self { + builder: self + .builder + .property("reveal-bottom-bars", reveal_bottom_bars), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn reveal_top_bars(self, reveal_top_bars: bool) -> Self { + Self { + builder: self.builder.property("reveal-top-bars", reveal_top_bars), + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub fn top_bar_style(self, top_bar_style: ToolbarStyle) -> Self { + Self { + builder: self.builder.property("top-bar-style", top_bar_style), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`ToolbarView`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> ToolbarView { + self.builder.build() + } +} + +impl fmt::Display for ToolbarView { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ToolbarView") + } +} diff --git a/libadwaita-0.4.4/src/auto/versions.txt b/libadwaita-0.4.4/src/auto/versions.txt new file mode 100644 index 0000000..e4be50d --- /dev/null +++ b/libadwaita-0.4.4/src/auto/versions.txt @@ -0,0 +1,3 @@ +Generated by gir (https://github.com/gtk-rs/gir @ c0ef822cedca) +from +from gir-files (https://github.com/gtk-rs/gir-files.git @ 6d1aaead565c) diff --git a/libadwaita-0.4.4/src/auto/view_stack.rs b/libadwaita-0.4.4/src/auto/view_stack.rs new file mode 100644 index 0000000..d7f8457 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/view_stack.rs @@ -0,0 +1,559 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::ViewStackPage; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwViewStack")] + pub struct ViewStack(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_view_stack_get_type(), + } +} + +impl ViewStack { + #[doc(alias = "adw_view_stack_new")] + pub fn new() -> ViewStack { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_view_stack_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`ViewStack`] objects. + /// + /// This method returns an instance of [`ViewStackBuilder`](crate::builders::ViewStackBuilder) which can be used to create [`ViewStack`] objects. + pub fn builder() -> ViewStackBuilder { + ViewStackBuilder::new() + } + + #[doc(alias = "adw_view_stack_add")] + pub fn add(&self, child: &impl IsA) -> ViewStackPage { + unsafe { + from_glib_none(ffi::adw_view_stack_add( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_stack_add_named")] + pub fn add_named(&self, child: &impl IsA, name: Option<&str>) -> ViewStackPage { + unsafe { + from_glib_none(ffi::adw_view_stack_add_named( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + name.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_stack_add_titled")] + pub fn add_titled( + &self, + child: &impl IsA, + name: Option<&str>, + title: &str, + ) -> ViewStackPage { + unsafe { + from_glib_none(ffi::adw_view_stack_add_titled( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + name.to_glib_none().0, + title.to_glib_none().0, + )) + } + } + + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + #[doc(alias = "adw_view_stack_add_titled_with_icon")] + pub fn add_titled_with_icon( + &self, + child: &impl IsA, + name: Option<&str>, + title: &str, + icon_name: &str, + ) -> ViewStackPage { + unsafe { + from_glib_none(ffi::adw_view_stack_add_titled_with_icon( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + name.to_glib_none().0, + title.to_glib_none().0, + icon_name.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_stack_get_child_by_name")] + #[doc(alias = "get_child_by_name")] + pub fn child_by_name(&self, name: &str) -> Option { + unsafe { + from_glib_none(ffi::adw_view_stack_get_child_by_name( + self.to_glib_none().0, + name.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_stack_get_hhomogeneous")] + #[doc(alias = "get_hhomogeneous")] + pub fn is_hhomogeneous(&self) -> bool { + unsafe { from_glib(ffi::adw_view_stack_get_hhomogeneous(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_view_stack_get_page")] + #[doc(alias = "get_page")] + pub fn page(&self, child: &impl IsA) -> ViewStackPage { + unsafe { + from_glib_none(ffi::adw_view_stack_get_page( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_stack_get_pages")] + #[doc(alias = "get_pages")] + pub fn pages(&self) -> gtk::SelectionModel { + unsafe { from_glib_full(ffi::adw_view_stack_get_pages(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_view_stack_get_vhomogeneous")] + #[doc(alias = "get_vhomogeneous")] + pub fn is_vhomogeneous(&self) -> bool { + unsafe { from_glib(ffi::adw_view_stack_get_vhomogeneous(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_view_stack_get_visible_child")] + #[doc(alias = "get_visible_child")] + pub fn visible_child(&self) -> Option { + unsafe { from_glib_none(ffi::adw_view_stack_get_visible_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_view_stack_get_visible_child_name")] + #[doc(alias = "get_visible_child_name")] + pub fn visible_child_name(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_view_stack_get_visible_child_name( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_stack_remove")] + pub fn remove(&self, child: &impl IsA) { + unsafe { + ffi::adw_view_stack_remove(self.to_glib_none().0, child.as_ref().to_glib_none().0); + } + } + + #[doc(alias = "adw_view_stack_set_hhomogeneous")] + pub fn set_hhomogeneous(&self, hhomogeneous: bool) { + unsafe { + ffi::adw_view_stack_set_hhomogeneous(self.to_glib_none().0, hhomogeneous.into_glib()); + } + } + + #[doc(alias = "adw_view_stack_set_vhomogeneous")] + pub fn set_vhomogeneous(&self, vhomogeneous: bool) { + unsafe { + ffi::adw_view_stack_set_vhomogeneous(self.to_glib_none().0, vhomogeneous.into_glib()); + } + } + + #[doc(alias = "adw_view_stack_set_visible_child")] + pub fn set_visible_child(&self, child: &impl IsA) { + unsafe { + ffi::adw_view_stack_set_visible_child( + self.to_glib_none().0, + child.as_ref().to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_view_stack_set_visible_child_name")] + pub fn set_visible_child_name(&self, name: &str) { + unsafe { + ffi::adw_view_stack_set_visible_child_name( + self.to_glib_none().0, + name.to_glib_none().0, + ); + } + } + + #[doc(alias = "hhomogeneous")] + pub fn connect_hhomogeneous_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_hhomogeneous_trampoline( + this: *mut ffi::AdwViewStack, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::hhomogeneous\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_hhomogeneous_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "pages")] + pub fn connect_pages_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_pages_trampoline( + this: *mut ffi::AdwViewStack, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::pages\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_pages_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "vhomogeneous")] + pub fn connect_vhomogeneous_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_vhomogeneous_trampoline( + this: *mut ffi::AdwViewStack, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::vhomogeneous\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_vhomogeneous_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "visible-child")] + pub fn connect_visible_child_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_visible_child_trampoline( + this: *mut ffi::AdwViewStack, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::visible-child\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_visible_child_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "visible-child-name")] + pub fn connect_visible_child_name_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_visible_child_name_trampoline( + this: *mut ffi::AdwViewStack, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::visible-child-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_visible_child_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for ViewStack { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`ViewStack`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ViewStackBuilder { + builder: glib::object::ObjectBuilder<'static, ViewStack>, +} + +impl ViewStackBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn hhomogeneous(self, hhomogeneous: bool) -> Self { + Self { + builder: self.builder.property("hhomogeneous", hhomogeneous), + } + } + + pub fn vhomogeneous(self, vhomogeneous: bool) -> Self { + Self { + builder: self.builder.property("vhomogeneous", vhomogeneous), + } + } + + pub fn visible_child(self, visible_child: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("visible-child", visible_child.clone().upcast()), + } + } + + pub fn visible_child_name(self, visible_child_name: impl Into) -> Self { + Self { + builder: self + .builder + .property("visible-child-name", visible_child_name.into()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`ViewStack`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> ViewStack { + self.builder.build() + } +} + +impl fmt::Display for ViewStack { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ViewStack") + } +} diff --git a/libadwaita-0.4.4/src/auto/view_stack_page.rs b/libadwaita-0.4.4/src/auto/view_stack_page.rs new file mode 100644 index 0000000..24470e3 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/view_stack_page.rs @@ -0,0 +1,307 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwViewStackPage")] + pub struct ViewStackPage(Object) @implements gtk::Accessible; + + match fn { + type_ => || ffi::adw_view_stack_page_get_type(), + } +} + +impl ViewStackPage { + #[doc(alias = "adw_view_stack_page_get_badge_number")] + #[doc(alias = "get_badge_number")] + pub fn badge_number(&self) -> u32 { + unsafe { ffi::adw_view_stack_page_get_badge_number(self.to_glib_none().0) } + } + + #[doc(alias = "adw_view_stack_page_get_child")] + #[doc(alias = "get_child")] + pub fn child(&self) -> gtk::Widget { + unsafe { from_glib_none(ffi::adw_view_stack_page_get_child(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_view_stack_page_get_icon_name")] + #[doc(alias = "get_icon_name")] + pub fn icon_name(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_view_stack_page_get_icon_name( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_stack_page_get_name")] + #[doc(alias = "get_name")] + pub fn name(&self) -> Option { + unsafe { from_glib_none(ffi::adw_view_stack_page_get_name(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_view_stack_page_get_needs_attention")] + #[doc(alias = "get_needs_attention")] + pub fn needs_attention(&self) -> bool { + unsafe { + from_glib(ffi::adw_view_stack_page_get_needs_attention( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_stack_page_get_title")] + #[doc(alias = "get_title")] + pub fn title(&self) -> Option { + unsafe { from_glib_none(ffi::adw_view_stack_page_get_title(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_view_stack_page_get_use_underline")] + #[doc(alias = "get_use_underline")] + pub fn uses_underline(&self) -> bool { + unsafe { + from_glib(ffi::adw_view_stack_page_get_use_underline( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_stack_page_get_visible")] + #[doc(alias = "get_visible")] + pub fn is_visible(&self) -> bool { + unsafe { from_glib(ffi::adw_view_stack_page_get_visible(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_view_stack_page_set_badge_number")] + pub fn set_badge_number(&self, badge_number: u32) { + unsafe { + ffi::adw_view_stack_page_set_badge_number(self.to_glib_none().0, badge_number); + } + } + + #[doc(alias = "adw_view_stack_page_set_icon_name")] + pub fn set_icon_name(&self, icon_name: Option<&str>) { + unsafe { + ffi::adw_view_stack_page_set_icon_name( + self.to_glib_none().0, + icon_name.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_view_stack_page_set_name")] + pub fn set_name(&self, name: Option<&str>) { + unsafe { + ffi::adw_view_stack_page_set_name(self.to_glib_none().0, name.to_glib_none().0); + } + } + + #[doc(alias = "adw_view_stack_page_set_needs_attention")] + pub fn set_needs_attention(&self, needs_attention: bool) { + unsafe { + ffi::adw_view_stack_page_set_needs_attention( + self.to_glib_none().0, + needs_attention.into_glib(), + ); + } + } + + #[doc(alias = "adw_view_stack_page_set_title")] + pub fn set_title(&self, title: Option<&str>) { + unsafe { + ffi::adw_view_stack_page_set_title(self.to_glib_none().0, title.to_glib_none().0); + } + } + + #[doc(alias = "adw_view_stack_page_set_use_underline")] + pub fn set_use_underline(&self, use_underline: bool) { + unsafe { + ffi::adw_view_stack_page_set_use_underline( + self.to_glib_none().0, + use_underline.into_glib(), + ); + } + } + + #[doc(alias = "adw_view_stack_page_set_visible")] + pub fn set_visible(&self, visible: bool) { + unsafe { + ffi::adw_view_stack_page_set_visible(self.to_glib_none().0, visible.into_glib()); + } + } + + #[doc(alias = "badge-number")] + pub fn connect_badge_number_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_badge_number_trampoline( + this: *mut ffi::AdwViewStackPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::badge-number\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_badge_number_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "icon-name")] + pub fn connect_icon_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_icon_name_trampoline( + this: *mut ffi::AdwViewStackPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::icon-name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_icon_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "name")] + pub fn connect_name_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_name_trampoline( + this: *mut ffi::AdwViewStackPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::name\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_name_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "needs-attention")] + pub fn connect_needs_attention_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_needs_attention_trampoline( + this: *mut ffi::AdwViewStackPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::needs-attention\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_needs_attention_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "title")] + pub fn connect_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_trampoline( + this: *mut ffi::AdwViewStackPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "use-underline")] + pub fn connect_use_underline_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_use_underline_trampoline( + this: *mut ffi::AdwViewStackPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::use-underline\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_use_underline_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "visible")] + pub fn connect_visible_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_visible_trampoline( + this: *mut ffi::AdwViewStackPage, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::visible\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_visible_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for ViewStackPage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ViewStackPage") + } +} diff --git a/libadwaita-0.4.4/src/auto/view_switcher.rs b/libadwaita-0.4.4/src/auto/view_switcher.rs new file mode 100644 index 0000000..b0367b1 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/view_switcher.rs @@ -0,0 +1,341 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::{ViewStack, ViewSwitcherPolicy}; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwViewSwitcher")] + pub struct ViewSwitcher(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_view_switcher_get_type(), + } +} + +impl ViewSwitcher { + #[doc(alias = "adw_view_switcher_new")] + pub fn new() -> ViewSwitcher { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_view_switcher_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`ViewSwitcher`] objects. + /// + /// This method returns an instance of [`ViewSwitcherBuilder`](crate::builders::ViewSwitcherBuilder) which can be used to create [`ViewSwitcher`] objects. + pub fn builder() -> ViewSwitcherBuilder { + ViewSwitcherBuilder::new() + } + + #[doc(alias = "adw_view_switcher_get_policy")] + #[doc(alias = "get_policy")] + pub fn policy(&self) -> ViewSwitcherPolicy { + unsafe { from_glib(ffi::adw_view_switcher_get_policy(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_view_switcher_get_stack")] + #[doc(alias = "get_stack")] + pub fn stack(&self) -> Option { + unsafe { from_glib_none(ffi::adw_view_switcher_get_stack(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_view_switcher_set_policy")] + pub fn set_policy(&self, policy: ViewSwitcherPolicy) { + unsafe { + ffi::adw_view_switcher_set_policy(self.to_glib_none().0, policy.into_glib()); + } + } + + #[doc(alias = "adw_view_switcher_set_stack")] + pub fn set_stack(&self, stack: Option<&ViewStack>) { + unsafe { + ffi::adw_view_switcher_set_stack(self.to_glib_none().0, stack.to_glib_none().0); + } + } + + #[doc(alias = "policy")] + pub fn connect_policy_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_policy_trampoline( + this: *mut ffi::AdwViewSwitcher, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::policy\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_policy_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "stack")] + pub fn connect_stack_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_stack_trampoline( + this: *mut ffi::AdwViewSwitcher, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::stack\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_stack_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for ViewSwitcher { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`ViewSwitcher`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ViewSwitcherBuilder { + builder: glib::object::ObjectBuilder<'static, ViewSwitcher>, +} + +impl ViewSwitcherBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn policy(self, policy: ViewSwitcherPolicy) -> Self { + Self { + builder: self.builder.property("policy", policy), + } + } + + pub fn stack(self, stack: &ViewStack) -> Self { + Self { + builder: self.builder.property("stack", stack.clone()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`ViewSwitcher`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> ViewSwitcher { + self.builder.build() + } +} + +impl fmt::Display for ViewSwitcher { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ViewSwitcher") + } +} diff --git a/libadwaita-0.4.4/src/auto/view_switcher_bar.rs b/libadwaita-0.4.4/src/auto/view_switcher_bar.rs new file mode 100644 index 0000000..7138aa5 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/view_switcher_bar.rs @@ -0,0 +1,341 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::ViewStack; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwViewSwitcherBar")] + pub struct ViewSwitcherBar(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_view_switcher_bar_get_type(), + } +} + +impl ViewSwitcherBar { + #[doc(alias = "adw_view_switcher_bar_new")] + pub fn new() -> ViewSwitcherBar { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_view_switcher_bar_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`ViewSwitcherBar`] objects. + /// + /// This method returns an instance of [`ViewSwitcherBarBuilder`](crate::builders::ViewSwitcherBarBuilder) which can be used to create [`ViewSwitcherBar`] objects. + pub fn builder() -> ViewSwitcherBarBuilder { + ViewSwitcherBarBuilder::new() + } + + #[doc(alias = "adw_view_switcher_bar_get_reveal")] + #[doc(alias = "get_reveal")] + pub fn reveals(&self) -> bool { + unsafe { from_glib(ffi::adw_view_switcher_bar_get_reveal(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_view_switcher_bar_get_stack")] + #[doc(alias = "get_stack")] + pub fn stack(&self) -> Option { + unsafe { from_glib_none(ffi::adw_view_switcher_bar_get_stack(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_view_switcher_bar_set_reveal")] + pub fn set_reveal(&self, reveal: bool) { + unsafe { + ffi::adw_view_switcher_bar_set_reveal(self.to_glib_none().0, reveal.into_glib()); + } + } + + #[doc(alias = "adw_view_switcher_bar_set_stack")] + pub fn set_stack(&self, stack: Option<&ViewStack>) { + unsafe { + ffi::adw_view_switcher_bar_set_stack(self.to_glib_none().0, stack.to_glib_none().0); + } + } + + #[doc(alias = "reveal")] + pub fn connect_reveal_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_reveal_trampoline( + this: *mut ffi::AdwViewSwitcherBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::reveal\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_reveal_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "stack")] + pub fn connect_stack_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_stack_trampoline( + this: *mut ffi::AdwViewSwitcherBar, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::stack\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_stack_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for ViewSwitcherBar { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`ViewSwitcherBar`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ViewSwitcherBarBuilder { + builder: glib::object::ObjectBuilder<'static, ViewSwitcherBar>, +} + +impl ViewSwitcherBarBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn reveal(self, reveal: bool) -> Self { + Self { + builder: self.builder.property("reveal", reveal), + } + } + + pub fn stack(self, stack: &ViewStack) -> Self { + Self { + builder: self.builder.property("stack", stack.clone()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`ViewSwitcherBar`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> ViewSwitcherBar { + self.builder.build() + } +} + +impl fmt::Display for ViewSwitcherBar { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ViewSwitcherBar") + } +} diff --git a/libadwaita-0.4.4/src/auto/view_switcher_title.rs b/libadwaita-0.4.4/src/auto/view_switcher_title.rs new file mode 100644 index 0000000..3e79dd8 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/view_switcher_title.rs @@ -0,0 +1,489 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use crate::ViewStack; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwViewSwitcherTitle")] + pub struct ViewSwitcherTitle(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_view_switcher_title_get_type(), + } +} + +impl ViewSwitcherTitle { + #[doc(alias = "adw_view_switcher_title_new")] + pub fn new() -> ViewSwitcherTitle { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_view_switcher_title_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`ViewSwitcherTitle`] objects. + /// + /// This method returns an instance of [`ViewSwitcherTitleBuilder`](crate::builders::ViewSwitcherTitleBuilder) which can be used to create [`ViewSwitcherTitle`] objects. + pub fn builder() -> ViewSwitcherTitleBuilder { + ViewSwitcherTitleBuilder::new() + } + + #[doc(alias = "adw_view_switcher_title_get_stack")] + #[doc(alias = "get_stack")] + pub fn stack(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_view_switcher_title_get_stack( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_switcher_title_get_subtitle")] + #[doc(alias = "get_subtitle")] + pub fn subtitle(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_view_switcher_title_get_subtitle( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_switcher_title_get_title")] + #[doc(alias = "get_title")] + pub fn title(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::adw_view_switcher_title_get_title( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_switcher_title_get_title_visible")] + #[doc(alias = "get_title_visible")] + pub fn is_title_visible(&self) -> bool { + unsafe { + from_glib(ffi::adw_view_switcher_title_get_title_visible( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_switcher_title_get_view_switcher_enabled")] + #[doc(alias = "get_view_switcher_enabled")] + pub fn is_view_switcher_enabled(&self) -> bool { + unsafe { + from_glib(ffi::adw_view_switcher_title_get_view_switcher_enabled( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_view_switcher_title_set_stack")] + pub fn set_stack(&self, stack: Option<&ViewStack>) { + unsafe { + ffi::adw_view_switcher_title_set_stack(self.to_glib_none().0, stack.to_glib_none().0); + } + } + + #[doc(alias = "adw_view_switcher_title_set_subtitle")] + pub fn set_subtitle(&self, subtitle: &str) { + unsafe { + ffi::adw_view_switcher_title_set_subtitle( + self.to_glib_none().0, + subtitle.to_glib_none().0, + ); + } + } + + #[doc(alias = "adw_view_switcher_title_set_title")] + pub fn set_title(&self, title: &str) { + unsafe { + ffi::adw_view_switcher_title_set_title(self.to_glib_none().0, title.to_glib_none().0); + } + } + + #[doc(alias = "adw_view_switcher_title_set_view_switcher_enabled")] + pub fn set_view_switcher_enabled(&self, enabled: bool) { + unsafe { + ffi::adw_view_switcher_title_set_view_switcher_enabled( + self.to_glib_none().0, + enabled.into_glib(), + ); + } + } + + #[doc(alias = "stack")] + pub fn connect_stack_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_stack_trampoline( + this: *mut ffi::AdwViewSwitcherTitle, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::stack\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_stack_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "subtitle")] + pub fn connect_subtitle_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_subtitle_trampoline( + this: *mut ffi::AdwViewSwitcherTitle, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::subtitle\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_subtitle_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "title")] + pub fn connect_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_trampoline( + this: *mut ffi::AdwViewSwitcherTitle, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "title-visible")] + pub fn connect_title_visible_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_visible_trampoline< + F: Fn(&ViewSwitcherTitle) + 'static, + >( + this: *mut ffi::AdwViewSwitcherTitle, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title-visible\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_visible_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "view-switcher-enabled")] + pub fn connect_view_switcher_enabled_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_view_switcher_enabled_trampoline< + F: Fn(&ViewSwitcherTitle) + 'static, + >( + this: *mut ffi::AdwViewSwitcherTitle, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::view-switcher-enabled\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_view_switcher_enabled_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for ViewSwitcherTitle { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`ViewSwitcherTitle`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct ViewSwitcherTitleBuilder { + builder: glib::object::ObjectBuilder<'static, ViewSwitcherTitle>, +} + +impl ViewSwitcherTitleBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn stack(self, stack: &ViewStack) -> Self { + Self { + builder: self.builder.property("stack", stack.clone()), + } + } + + pub fn subtitle(self, subtitle: impl Into) -> Self { + Self { + builder: self.builder.property("subtitle", subtitle.into()), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + pub fn view_switcher_enabled(self, view_switcher_enabled: bool) -> Self { + Self { + builder: self + .builder + .property("view-switcher-enabled", view_switcher_enabled), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`ViewSwitcherTitle`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> ViewSwitcherTitle { + self.builder.build() + } +} + +impl fmt::Display for ViewSwitcherTitle { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("ViewSwitcherTitle") + } +} diff --git a/libadwaita-0.4.4/src/auto/window.rs b/libadwaita-0.4.4/src/auto/window.rs new file mode 100644 index 0000000..19b14cd --- /dev/null +++ b/libadwaita-0.4.4/src/auto/window.rs @@ -0,0 +1,530 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +use crate::Breakpoint; +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwWindow")] + pub struct Window(Object) @extends gtk::Window, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager; + + match fn { + type_ => || ffi::adw_window_get_type(), + } +} + +impl Window { + pub const NONE: Option<&'static Window> = None; + + #[doc(alias = "adw_window_new")] + pub fn new() -> Window { + assert_initialized_main_thread!(); + unsafe { gtk::Widget::from_glib_none(ffi::adw_window_new()).unsafe_cast() } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`Window`] objects. + /// + /// This method returns an instance of [`WindowBuilder`](crate::builders::WindowBuilder) which can be used to create [`Window`] objects. + pub fn builder() -> WindowBuilder { + WindowBuilder::new() + } +} + +impl Default for Window { + fn default() -> Self { + Self::new() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`Window`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct WindowBuilder { + builder: glib::object::ObjectBuilder<'static, Window>, +} + +impl WindowBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn content(self, content: &impl IsA) -> Self { + Self { + builder: self.builder.property("content", content.clone().upcast()), + } + } + + pub fn application(self, application: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("application", application.clone().upcast()), + } + } + + pub fn decorated(self, decorated: bool) -> Self { + Self { + builder: self.builder.property("decorated", decorated), + } + } + + pub fn default_height(self, default_height: i32) -> Self { + Self { + builder: self.builder.property("default-height", default_height), + } + } + + pub fn default_widget(self, default_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("default-widget", default_widget.clone().upcast()), + } + } + + pub fn default_width(self, default_width: i32) -> Self { + Self { + builder: self.builder.property("default-width", default_width), + } + } + + pub fn deletable(self, deletable: bool) -> Self { + Self { + builder: self.builder.property("deletable", deletable), + } + } + + pub fn destroy_with_parent(self, destroy_with_parent: bool) -> Self { + Self { + builder: self + .builder + .property("destroy-with-parent", destroy_with_parent), + } + } + + pub fn display(self, display: &gdk::Display) -> Self { + Self { + builder: self.builder.property("display", display.clone()), + } + } + + pub fn focus_visible(self, focus_visible: bool) -> Self { + Self { + builder: self.builder.property("focus-visible", focus_visible), + } + } + + pub fn focus_widget(self, focus_widget: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("focus-widget", focus_widget.clone().upcast()), + } + } + + pub fn fullscreened(self, fullscreened: bool) -> Self { + Self { + builder: self.builder.property("fullscreened", fullscreened), + } + } + + #[cfg(any(feature = "gtk_v4_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "gtk_v4_2")))] + pub fn handle_menubar_accel(self, handle_menubar_accel: bool) -> Self { + Self { + builder: self + .builder + .property("handle-menubar-accel", handle_menubar_accel), + } + } + + pub fn hide_on_close(self, hide_on_close: bool) -> Self { + Self { + builder: self.builder.property("hide-on-close", hide_on_close), + } + } + + pub fn icon_name(self, icon_name: impl Into) -> Self { + Self { + builder: self.builder.property("icon-name", icon_name.into()), + } + } + + pub fn maximized(self, maximized: bool) -> Self { + Self { + builder: self.builder.property("maximized", maximized), + } + } + + pub fn mnemonics_visible(self, mnemonics_visible: bool) -> Self { + Self { + builder: self + .builder + .property("mnemonics-visible", mnemonics_visible), + } + } + + pub fn modal(self, modal: bool) -> Self { + Self { + builder: self.builder.property("modal", modal), + } + } + + pub fn resizable(self, resizable: bool) -> Self { + Self { + builder: self.builder.property("resizable", resizable), + } + } + + pub fn startup_id(self, startup_id: impl Into) -> Self { + Self { + builder: self.builder.property("startup-id", startup_id.into()), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + #[cfg(any(feature = "gtk_v4_6", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "gtk_v4_6")))] + pub fn titlebar(self, titlebar: &impl IsA) -> Self { + Self { + builder: self.builder.property("titlebar", titlebar.clone().upcast()), + } + } + + pub fn transient_for(self, transient_for: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("transient-for", transient_for.clone().upcast()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`Window`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> Window { + self.builder.build() + } +} + +pub trait AdwWindowExt: 'static { + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_window_add_breakpoint")] + fn add_breakpoint(&self, breakpoint: Breakpoint); + + #[doc(alias = "adw_window_get_content")] + #[doc(alias = "get_content")] + fn content(&self) -> Option; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "adw_window_get_current_breakpoint")] + #[doc(alias = "get_current_breakpoint")] + fn current_breakpoint(&self) -> Option; + + #[doc(alias = "adw_window_set_content")] + fn set_content(&self, content: Option<&impl IsA>); + + #[doc(alias = "content")] + fn connect_content_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + #[doc(alias = "current-breakpoint")] + fn connect_current_breakpoint_notify(&self, f: F) -> SignalHandlerId; +} + +impl> AdwWindowExt for O { + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn add_breakpoint(&self, breakpoint: Breakpoint) { + unsafe { + ffi::adw_window_add_breakpoint( + self.as_ref().to_glib_none().0, + breakpoint.into_glib_ptr(), + ); + } + } + + fn content(&self) -> Option { + unsafe { from_glib_none(ffi::adw_window_get_content(self.as_ref().to_glib_none().0)) } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn current_breakpoint(&self) -> Option { + unsafe { + from_glib_none(ffi::adw_window_get_current_breakpoint( + self.as_ref().to_glib_none().0, + )) + } + } + + fn set_content(&self, content: Option<&impl IsA>) { + unsafe { + ffi::adw_window_set_content( + self.as_ref().to_glib_none().0, + content.map(|p| p.as_ref()).to_glib_none().0, + ); + } + } + + fn connect_content_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_content_trampoline, F: Fn(&P) + 'static>( + this: *mut ffi::AdwWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(Window::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::content\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_content_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + fn connect_current_breakpoint_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_current_breakpoint_trampoline< + P: IsA, + F: Fn(&P) + 'static, + >( + this: *mut ffi::AdwWindow, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(Window::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::current-breakpoint\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_current_breakpoint_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl fmt::Display for Window { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Window") + } +} diff --git a/libadwaita-0.4.4/src/auto/window_title.rs b/libadwaita-0.4.4/src/auto/window_title.rs new file mode 100644 index 0000000..80fdb25 --- /dev/null +++ b/libadwaita-0.4.4/src/auto/window_title.rs @@ -0,0 +1,346 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from +// from gir-files (https://github.com/gtk-rs/gir-files.git) +// DO NOT EDIT + +use glib::{ + prelude::*, + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use std::{boxed::Box as Box_, fmt, mem::transmute}; + +glib::wrapper! { + #[doc(alias = "AdwWindowTitle")] + pub struct WindowTitle(Object) @extends gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; + + match fn { + type_ => || ffi::adw_window_title_get_type(), + } +} + +impl WindowTitle { + #[doc(alias = "adw_window_title_new")] + pub fn new(title: &str, subtitle: &str) -> WindowTitle { + assert_initialized_main_thread!(); + unsafe { + gtk::Widget::from_glib_none(ffi::adw_window_title_new( + title.to_glib_none().0, + subtitle.to_glib_none().0, + )) + .unsafe_cast() + } + } + + // rustdoc-stripper-ignore-next + /// Creates a new builder-pattern struct instance to construct [`WindowTitle`] objects. + /// + /// This method returns an instance of [`WindowTitleBuilder`](crate::builders::WindowTitleBuilder) which can be used to create [`WindowTitle`] objects. + pub fn builder() -> WindowTitleBuilder { + WindowTitleBuilder::new() + } + + #[doc(alias = "adw_window_title_get_subtitle")] + #[doc(alias = "get_subtitle")] + pub fn subtitle(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_window_title_get_subtitle(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_window_title_get_title")] + #[doc(alias = "get_title")] + pub fn title(&self) -> glib::GString { + unsafe { from_glib_none(ffi::adw_window_title_get_title(self.to_glib_none().0)) } + } + + #[doc(alias = "adw_window_title_set_subtitle")] + pub fn set_subtitle(&self, subtitle: &str) { + unsafe { + ffi::adw_window_title_set_subtitle(self.to_glib_none().0, subtitle.to_glib_none().0); + } + } + + #[doc(alias = "adw_window_title_set_title")] + pub fn set_title(&self, title: &str) { + unsafe { + ffi::adw_window_title_set_title(self.to_glib_none().0, title.to_glib_none().0); + } + } + + #[doc(alias = "subtitle")] + pub fn connect_subtitle_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_subtitle_trampoline( + this: *mut ffi::AdwWindowTitle, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::subtitle\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_subtitle_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "title")] + pub fn connect_title_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_title_trampoline( + this: *mut ffi::AdwWindowTitle, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::title\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_title_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +impl Default for WindowTitle { + fn default() -> Self { + glib::object::Object::new::() + } +} + +// rustdoc-stripper-ignore-next +/// A [builder-pattern] type to construct [`WindowTitle`] objects. +/// +/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html +#[must_use = "The builder must be built to be used"] +pub struct WindowTitleBuilder { + builder: glib::object::ObjectBuilder<'static, WindowTitle>, +} + +impl WindowTitleBuilder { + fn new() -> Self { + Self { + builder: glib::object::Object::builder(), + } + } + + pub fn subtitle(self, subtitle: impl Into) -> Self { + Self { + builder: self.builder.property("subtitle", subtitle.into()), + } + } + + pub fn title(self, title: impl Into) -> Self { + Self { + builder: self.builder.property("title", title.into()), + } + } + + pub fn can_focus(self, can_focus: bool) -> Self { + Self { + builder: self.builder.property("can-focus", can_focus), + } + } + + pub fn can_target(self, can_target: bool) -> Self { + Self { + builder: self.builder.property("can-target", can_target), + } + } + + pub fn css_classes(self, css_classes: impl Into) -> Self { + Self { + builder: self.builder.property("css-classes", css_classes.into()), + } + } + + pub fn css_name(self, css_name: impl Into) -> Self { + Self { + builder: self.builder.property("css-name", css_name.into()), + } + } + + pub fn cursor(self, cursor: &gdk::Cursor) -> Self { + Self { + builder: self.builder.property("cursor", cursor.clone()), + } + } + + pub fn focus_on_click(self, focus_on_click: bool) -> Self { + Self { + builder: self.builder.property("focus-on-click", focus_on_click), + } + } + + pub fn focusable(self, focusable: bool) -> Self { + Self { + builder: self.builder.property("focusable", focusable), + } + } + + pub fn halign(self, halign: gtk::Align) -> Self { + Self { + builder: self.builder.property("halign", halign), + } + } + + pub fn has_tooltip(self, has_tooltip: bool) -> Self { + Self { + builder: self.builder.property("has-tooltip", has_tooltip), + } + } + + pub fn height_request(self, height_request: i32) -> Self { + Self { + builder: self.builder.property("height-request", height_request), + } + } + + pub fn hexpand(self, hexpand: bool) -> Self { + Self { + builder: self.builder.property("hexpand", hexpand), + } + } + + pub fn hexpand_set(self, hexpand_set: bool) -> Self { + Self { + builder: self.builder.property("hexpand-set", hexpand_set), + } + } + + pub fn layout_manager(self, layout_manager: &impl IsA) -> Self { + Self { + builder: self + .builder + .property("layout-manager", layout_manager.clone().upcast()), + } + } + + pub fn margin_bottom(self, margin_bottom: i32) -> Self { + Self { + builder: self.builder.property("margin-bottom", margin_bottom), + } + } + + pub fn margin_end(self, margin_end: i32) -> Self { + Self { + builder: self.builder.property("margin-end", margin_end), + } + } + + pub fn margin_start(self, margin_start: i32) -> Self { + Self { + builder: self.builder.property("margin-start", margin_start), + } + } + + pub fn margin_top(self, margin_top: i32) -> Self { + Self { + builder: self.builder.property("margin-top", margin_top), + } + } + + pub fn name(self, name: impl Into) -> Self { + Self { + builder: self.builder.property("name", name.into()), + } + } + + pub fn opacity(self, opacity: f64) -> Self { + Self { + builder: self.builder.property("opacity", opacity), + } + } + + pub fn overflow(self, overflow: gtk::Overflow) -> Self { + Self { + builder: self.builder.property("overflow", overflow), + } + } + + pub fn receives_default(self, receives_default: bool) -> Self { + Self { + builder: self.builder.property("receives-default", receives_default), + } + } + + pub fn sensitive(self, sensitive: bool) -> Self { + Self { + builder: self.builder.property("sensitive", sensitive), + } + } + + pub fn tooltip_markup(self, tooltip_markup: impl Into) -> Self { + Self { + builder: self + .builder + .property("tooltip-markup", tooltip_markup.into()), + } + } + + pub fn tooltip_text(self, tooltip_text: impl Into) -> Self { + Self { + builder: self.builder.property("tooltip-text", tooltip_text.into()), + } + } + + pub fn valign(self, valign: gtk::Align) -> Self { + Self { + builder: self.builder.property("valign", valign), + } + } + + pub fn vexpand(self, vexpand: bool) -> Self { + Self { + builder: self.builder.property("vexpand", vexpand), + } + } + + pub fn vexpand_set(self, vexpand_set: bool) -> Self { + Self { + builder: self.builder.property("vexpand-set", vexpand_set), + } + } + + pub fn visible(self, visible: bool) -> Self { + Self { + builder: self.builder.property("visible", visible), + } + } + + pub fn width_request(self, width_request: i32) -> Self { + Self { + builder: self.builder.property("width-request", width_request), + } + } + + pub fn accessible_role(self, accessible_role: gtk::AccessibleRole) -> Self { + Self { + builder: self.builder.property("accessible-role", accessible_role), + } + } + + // rustdoc-stripper-ignore-next + /// Build the [`WindowTitle`]. + #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"] + pub fn build(self) -> WindowTitle { + self.builder.build() + } +} + +impl fmt::Display for WindowTitle { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("WindowTitle") + } +} diff --git a/libadwaita-0.4.4/src/breakpoint.rs b/libadwaita-0.4.4/src/breakpoint.rs new file mode 100644 index 0000000..9de459e --- /dev/null +++ b/libadwaita-0.4.4/src/breakpoint.rs @@ -0,0 +1,35 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::Breakpoint; +use glib::translate::*; +use glib::Cast; + +impl Breakpoint { + #[doc(alias = "adw_breakpoint_add_settersv")] + #[doc(alias = "add_settersv")] + pub fn add_setters( + &self, + additions: &[(&impl glib::IsA, &str, impl glib::ToValue)], + ) { + let n_setters = additions.len() as _; + let objects = additions + .iter() + .map(|(o, _n, _v)| (*o).clone().upcast::()) + .collect::>(); + let names = additions.iter().map(|(_o, n, _v)| *n).collect::>(); + let values = additions + .iter() + .map(|(_o, _n, v)| v.to_value()) + .collect::>(); + + unsafe { + ffi::adw_breakpoint_add_settersv( + self.to_glib_none().0, + n_setters, + objects.as_slice().to_glib_none().0, + names.as_slice().to_glib_none().0, + values.as_slice().to_glib_none().0, + ); + } + } +} diff --git a/libadwaita-0.4.4/src/builders.rs b/libadwaita-0.4.4/src/builders.rs new file mode 100644 index 0000000..53a233a --- /dev/null +++ b/libadwaita-0.4.4/src/builders.rs @@ -0,0 +1,3 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +pub use crate::auto::builders::*; diff --git a/libadwaita-0.4.4/src/carousel.rs b/libadwaita-0.4.4/src/carousel.rs new file mode 100644 index 0000000..75e9c44 --- /dev/null +++ b/libadwaita-0.4.4/src/carousel.rs @@ -0,0 +1,13 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::Carousel; +use glib::translate::*; + +impl Carousel { + #[doc(alias = "adw_carousel_get_nth_page")] + #[doc(alias = "get_nth_page")] + pub fn nth_page(&self, n: u32) -> gtk::Widget { + assert!(n < self.n_pages()); + unsafe { from_glib_none(ffi::adw_carousel_get_nth_page(self.to_glib_none().0, n)) } + } +} diff --git a/libadwaita-0.4.4/src/functions.rs b/libadwaita-0.4.4/src/functions.rs new file mode 100644 index 0000000..0bf929a --- /dev/null +++ b/libadwaita-0.4.4/src/functions.rs @@ -0,0 +1,11 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +#[doc(alias = "adw_init")] +pub fn init() -> Result<(), glib::BoolError> { + skip_assert_initialized!(); + gtk::init()?; + unsafe { + ffi::adw_init(); + } + Ok(()) +} diff --git a/libadwaita-0.4.4/src/lib.rs b/libadwaita-0.4.4/src/lib.rs new file mode 100644 index 0000000..00e5132 --- /dev/null +++ b/libadwaita-0.4.4/src/lib.rs @@ -0,0 +1,138 @@ +#![cfg_attr(feature = "dox", feature(doc_cfg))] +#![allow(clippy::needless_doctest_main)] +#![doc( + html_logo_url = "https://gitlab.gnome.org/GNOME/libadwaita/-/raw/main/doc/libadwaita.svg", + html_favicon_url = "https://gitlab.gnome.org/GNOME/libadwaita/-/raw/main/demo/data/org.gnome.Adwaita1.Demo-symbolic.svg" +)] +//! # Rust Adwaita bindings +//! +//! This library contains safe Rust bindings for [Adwaita](https://gitlab.gnome.org/GNOME/libadwaita), a library that offers +//! building blocks for modern GNOME applications. +//! +//! See also +//! +//! - [GTK 4 Rust bindings documentation](mod@gtk) +//! - [Libadwaita documentation](https://gnome.pages.gitlab.gnome.org/libadwaita/) +//! - [gtk-rs project overview](https://gtk-rs.org/) +//! +//! # Example +//! +//! Adwaita needs to be initialized before use. +//! This can be done by either: +//! - using [`adw::Application`](struct@Application) instead of [`gtk::Application`](struct@gtk::Application), or by +//! - calling [`fn@init`] on [`startup`](fn@gio::prelude::ApplicationExt::connect_startup). +//! +//! The [`libadwaita`](mod@crate) crate is usually renamed to `adw`. You can +//! do this globally in your `Cargo.toml` file: +//! +//! ```toml +//! [dependencies.adw] +//! package = "libadwaita" +//! version = "0.x.y" +//! ``` +//! +//! ```no_run +//! # use libadwaita as adw; +//! use adw::prelude::*; +//! +//! use adw::{ActionRow, Application, ApplicationWindow, HeaderBar}; +//! use gtk::{Box, ListBox, Orientation, SelectionMode}; +//! +//! fn main() { +//! let application = Application::builder() +//! .application_id("com.example.FirstAdwaitaApp") +//! .build(); +//! +//! application.connect_activate(|app| { +//! // ActionRows are only available in Adwaita +//! let row = ActionRow::builder() +//! .activatable(true) +//! .title("Click me") +//! .build(); +//! row.connect_activated(|_| { +//! eprintln!("Clicked!"); +//! }); +//! +//! let list = ListBox::builder() +//! .margin_top(32) +//! .margin_end(32) +//! .margin_bottom(32) +//! .margin_start(32) +//! .selection_mode(SelectionMode::None) +//! // makes the list look nicer +//! .css_classes(vec![String::from("boxed-list")]) +//! .build(); +//! list.append(&row); +//! +//! // Combine the content in a box +//! let content = Box::new(Orientation::Vertical, 0); +//! // Adwaitas' ApplicationWindow does not include a HeaderBar +//! content.append(&HeaderBar::new()); +//! content.append(&list); +//! +//! let window = ApplicationWindow::builder() +//! .application(app) +//! .title("First App") +//! .default_width(350) +//! // add content to window +//! .content(&content) +//! .build(); +//! window.show(); +//! }); +//! +//! application.run(); +//! } +//! ``` + +// Re-export the -sys bindings +pub use ffi; +pub use gdk; +pub use gio; +pub use glib; +pub use gtk; + +/// Asserts that this is the main thread and `gtk::init` has been called. +macro_rules! assert_initialized_main_thread { + () => { + if !::gtk::is_initialized_main_thread() { + if ::gtk::is_initialized() { + panic!("libadwaita may only be used from the main thread."); + } else { + panic!("Gtk has to be initialized before using libadwaita."); + } + } + }; +} + +macro_rules! skip_assert_initialized { + () => {}; +} + +#[allow(unused_imports)] +#[allow(clippy::let_and_return)] +#[allow(clippy::type_complexity)] +mod auto; + +mod application; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +mod breakpoint; +mod carousel; +mod functions; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +mod message_dialog; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +mod spin_row; +mod tab_bar; +mod tab_view; +mod toast; + +pub use auto::functions::*; +pub use auto::*; +pub use functions::*; + +pub mod builders; +pub mod prelude; +pub mod subclass; diff --git a/libadwaita-0.4.4/src/message_dialog.rs b/libadwaita-0.4.4/src/message_dialog.rs new file mode 100644 index 0000000..df58775 --- /dev/null +++ b/libadwaita-0.4.4/src/message_dialog.rs @@ -0,0 +1,113 @@ +use glib::object::IsA; +use glib::translate::*; + +use crate::prelude::*; +use crate::MessageDialog; + +#[cfg(any(feature = "v1_3", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] +use std::boxed::Box as Box_; +#[cfg(any(feature = "v1_3", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] +use std::pin::Pin; + +pub trait MessageDialogExtManual: 'static { + #[doc(alias = "adw_message_dialog_get_response_label")] + #[doc(alias = "get_response_label")] + fn response_label(&self, response: &str) -> glib::GString; + + #[doc(alias = "adw_message_dialog_add_responses")] + fn add_responses(&self, ids_and_labels: &[(&str, &str)]); + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + #[doc(alias = "adw_message_dialog_choose")] + fn choose( + self, + cancellable: Option<&impl IsA>, + callback: P, + ); + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn choose_future(self) -> Pin + 'static>>; +} + +impl> MessageDialogExtManual for O { + #[doc(alias = "adw_message_dialog_get_response_label")] + #[doc(alias = "get_response_label")] + fn response_label(&self, response: &str) -> glib::GString { + assert!(self.as_ref().has_response(response)); + + unsafe { + from_glib_none(ffi::adw_message_dialog_get_response_label( + self.as_ref().to_glib_none().0, + response.to_glib_none().0, + )) + } + } + + #[doc(alias = "adw_message_dialog_add_responses")] + fn add_responses(&self, ids_and_labels: &[(&str, &str)]) { + ids_and_labels.iter().for_each(|(id, label)| { + self.add_response(id, label); + }); + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn choose( + self, + cancellable: Option<&impl IsA>, + callback: P, + ) { + let main_context = glib::MainContext::ref_thread_default(); + let is_main_context_owner = main_context.is_owner(); + let has_acquired_main_context = (!is_main_context_owner) + .then(|| main_context.acquire().ok()) + .flatten(); + assert!( + is_main_context_owner || has_acquired_main_context.is_some(), + "Async operations only allowed if the thread is owning the MainContext" + ); + + let user_data: Box_> = + Box_::new(glib::thread_guard::ThreadGuard::new(callback)); + unsafe extern "C" fn choose_trampoline( + _source_object: *mut glib::gobject_ffi::GObject, + res: *mut gio::ffi::GAsyncResult, + user_data: glib::ffi::gpointer, + ) { + let result = from_glib_none(ffi::adw_message_dialog_choose_finish( + _source_object as *mut _, + res, + )); + let callback: Box_> = + Box_::from_raw(user_data as *mut _); + let callback: P = callback.into_inner(); + callback(result); + } + let callback = choose_trampoline::

; + unsafe { + ffi::adw_message_dialog_choose( + self.upcast().into_glib_ptr(), + cancellable.map(|p| p.as_ref()).to_glib_none().0, + Some(callback), + Box_::into_raw(user_data) as *mut _, + ); + } + } + + #[cfg(any(feature = "v1_3", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_3")))] + fn choose_future(self) -> Pin + 'static>> { + Box_::pin(gio::GioFuture::new( + &self, + move |obj: &O, cancellable, send| { + obj.clone().choose(Some(cancellable), move |res| { + send.resolve(res); + }); + }, + )) + } +} diff --git a/libadwaita-0.4.4/src/prelude.rs b/libadwaita-0.4.4/src/prelude.rs new file mode 100644 index 0000000..d5dac57 --- /dev/null +++ b/libadwaita-0.4.4/src/prelude.rs @@ -0,0 +1,8 @@ +#[doc(hidden)] +pub use gtk::prelude::*; + +pub use crate::auto::traits::*; + +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +pub use crate::message_dialog::MessageDialogExtManual; diff --git a/libadwaita-0.4.4/src/spin_row.rs b/libadwaita-0.4.4/src/spin_row.rs new file mode 100644 index 0000000..3dd1063 --- /dev/null +++ b/libadwaita-0.4.4/src/spin_row.rs @@ -0,0 +1,42 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::SpinRow; +use glib::{ + signal::{connect_raw, SignalHandlerId}, + translate::*, +}; +use gtk::{glib, prelude::*}; +use libc::{c_double, c_int}; +use std::{boxed::Box as Box_, mem::transmute}; + +impl SpinRow { + pub fn connect_input(&self, f: F) -> SignalHandlerId + where + F: Fn(&Self) -> Option> + 'static, + { + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"input\0".as_ptr() as *mut _, + Some(transmute(input_trampoline:: as usize)), + Box_::into_raw(f), + ) + } + } +} + +unsafe extern "C" fn input_trampoline Option> + 'static>( + this: *mut ffi::AdwSpinRow, + new_value: *mut c_double, + f: &F, +) -> c_int { + match f(SpinRow::from_glib_borrow(this).unsafe_cast_ref()) { + Some(Ok(v)) => { + *new_value = v; + glib::ffi::GTRUE + } + Some(Err(_)) => gtk::ffi::GTK_INPUT_ERROR, + None => glib::ffi::GFALSE, + } +} diff --git a/libadwaita-0.4.4/src/subclass/action_row.rs b/libadwaita-0.4.4/src/subclass/action_row.rs new file mode 100644 index 0000000..4bdea3a --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/action_row.rs @@ -0,0 +1,44 @@ +use glib::subclass::prelude::*; +use glib::translate::*; +use glib::Cast; + +use crate::subclass::prelude::PreferencesRowImpl; +use crate::ActionRow; + +pub trait ActionRowImpl: PreferencesRowImpl { + fn activate(&self) { + ActionRowImplExt::parent_activate(self) + } +} + +pub trait ActionRowImplExt: ObjectSubclass { + fn parent_activate(&self); +} + +impl ActionRowImplExt for T { + fn parent_activate(&self) { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::AdwActionRowClass; + if let Some(f) = (*parent_class).activate { + f(self.obj().unsafe_cast_ref::().to_glib_none().0) + } + } + } +} + +unsafe impl IsSubclassable for ActionRow { + fn class_init(class: &mut glib::Class) { + Self::parent_class_init::(class); + + let klass = class.as_mut(); + klass.activate = Some(row_activate::); + } +} + +unsafe extern "C" fn row_activate(ptr: *mut ffi::AdwActionRow) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + + ActionRowImpl::activate(imp) +} diff --git a/libadwaita-0.4.4/src/subclass/application.rs b/libadwaita-0.4.4/src/subclass/application.rs new file mode 100644 index 0000000..3beb727 --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/application.rs @@ -0,0 +1,7 @@ +use crate::Application; + +use gtk::subclass::prelude::*; + +pub trait AdwApplicationImpl: GtkApplicationImpl {} + +unsafe impl IsSubclassable for Application {} diff --git a/libadwaita-0.4.4/src/subclass/application_window.rs b/libadwaita-0.4.4/src/subclass/application_window.rs new file mode 100644 index 0000000..776f473 --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/application_window.rs @@ -0,0 +1,6 @@ +use crate::ApplicationWindow; +use gtk::subclass::prelude::*; + +pub trait AdwApplicationWindowImpl: ApplicationWindowImpl {} + +unsafe impl IsSubclassable for ApplicationWindow {} diff --git a/libadwaita-0.4.4/src/subclass/bin.rs b/libadwaita-0.4.4/src/subclass/bin.rs new file mode 100644 index 0000000..207e6c0 --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/bin.rs @@ -0,0 +1,7 @@ +use crate::Bin; +use glib::subclass::prelude::*; +use gtk::subclass::prelude::WidgetImpl; + +pub trait BinImpl: WidgetImpl {} + +unsafe impl IsSubclassable for Bin {} diff --git a/libadwaita-0.4.4/src/subclass/breakpoint_bin.rs b/libadwaita-0.4.4/src/subclass/breakpoint_bin.rs new file mode 100644 index 0000000..60d091a --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/breakpoint_bin.rs @@ -0,0 +1,7 @@ +use crate::BreakpointBin; +use glib::subclass::prelude::*; +use gtk::subclass::prelude::WidgetImpl; + +pub trait BreakpointBinImpl: WidgetImpl {} + +unsafe impl IsSubclassable for BreakpointBin {} diff --git a/libadwaita-0.4.4/src/subclass/combo_row.rs b/libadwaita-0.4.4/src/subclass/combo_row.rs new file mode 100644 index 0000000..93845ef --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/combo_row.rs @@ -0,0 +1,7 @@ +use super::action_row::ActionRowImpl; +use crate::ComboRow; +use glib::subclass::prelude::*; + +pub trait ComboRowImpl: ActionRowImpl {} + +unsafe impl IsSubclassable for ComboRow {} diff --git a/libadwaita-0.4.4/src/subclass/entry_row.rs b/libadwaita-0.4.4/src/subclass/entry_row.rs new file mode 100644 index 0000000..58bf970 --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/entry_row.rs @@ -0,0 +1,8 @@ +use glib::subclass::prelude::*; + +use crate::subclass::prelude::PreferencesRowImpl; +use crate::EntryRow; + +pub trait EntryRowImpl: PreferencesRowImpl {} + +unsafe impl IsSubclassable for EntryRow {} diff --git a/libadwaita-0.4.4/src/subclass/expander_row.rs b/libadwaita-0.4.4/src/subclass/expander_row.rs new file mode 100644 index 0000000..c7a377b --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/expander_row.rs @@ -0,0 +1,7 @@ +use super::preferences_row::PreferencesRowImpl; +use crate::ExpanderRow; +use glib::subclass::prelude::*; + +pub trait ExpanderRowImpl: PreferencesRowImpl {} + +unsafe impl IsSubclassable for ExpanderRow {} diff --git a/libadwaita-0.4.4/src/subclass/message_dialog.rs b/libadwaita-0.4.4/src/subclass/message_dialog.rs new file mode 100644 index 0000000..15bfb20 --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/message_dialog.rs @@ -0,0 +1,53 @@ +use crate::MessageDialog; +use glib::translate::*; +use glib::Cast; +use gtk::subclass::prelude::*; + +pub trait MessageDialogImpl: gtk::subclass::prelude::WindowImpl { + fn response(&self, response: &str) { + self.parent_response(response) + } +} + +pub trait MessageDialogImplExt: ObjectSubclass { + fn parent_response(&self, response: &str); +} + +impl MessageDialogImplExt for T { + fn parent_response(&self, response: &str) { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::AdwMessageDialogClass; + if let Some(f) = (*parent_class).response { + f( + self.obj() + .unsafe_cast_ref::() + .to_glib_none() + .0, + response.to_glib_none().0, + ) + } + } + } +} + +unsafe impl IsSubclassable for MessageDialog { + fn class_init(class: &mut glib::Class) { + Self::parent_class_init::(class); + + let klass = class.as_mut(); + klass.response = Some(message_dialog_response::); + } +} + +unsafe extern "C" fn message_dialog_response( + ptr: *mut ffi::AdwMessageDialog, + response: *const libc::c_char, +) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + + let response: Borrowed = from_glib_borrow(response); + + imp.response(response.as_ref()) +} diff --git a/libadwaita-0.4.4/src/subclass/mod.rs b/libadwaita-0.4.4/src/subclass/mod.rs new file mode 100644 index 0000000..8047c8f --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/mod.rs @@ -0,0 +1,54 @@ +pub mod action_row; +pub mod application; +pub mod application_window; +pub mod bin; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub mod breakpoint_bin; +pub mod combo_row; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +pub mod entry_row; +pub mod expander_row; +#[cfg(any(feature = "v1_2", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] +mod message_dialog; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub mod navigation_page; +pub mod preferences_group; +pub mod preferences_page; +pub mod preferences_row; +pub mod preferences_window; +#[cfg(any(feature = "v1_4", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] +pub mod spin_row; +pub mod swipeable; +pub mod window; + +pub mod prelude { + pub use super::action_row::ActionRowImpl; + pub use super::application::AdwApplicationImpl; + pub use super::application_window::AdwApplicationWindowImpl; + pub use super::bin::BinImpl; + #[cfg(any(feature = "v1_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_4")))] + pub use super::breakpoint_bin::BreakpointBinImpl; + pub use super::combo_row::ComboRowImpl; + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub use super::entry_row::EntryRowImpl; + pub use super::expander_row::ExpanderRowImpl; + #[cfg(any(feature = "v1_2", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_2")))] + pub use super::message_dialog::{MessageDialogImpl, MessageDialogImplExt}; + pub use super::preferences_group::PreferencesGroupImpl; + pub use super::preferences_page::PreferencesPageImpl; + pub use super::preferences_row::PreferencesRowImpl; + pub use super::preferences_window::PreferencesWindowImpl; + pub use super::swipeable::SwipeableImpl; + pub use super::window::AdwWindowImpl; + pub use gio::subclass::prelude::*; + pub use glib::subclass::prelude::*; + pub use gtk::subclass::prelude::*; +} diff --git a/libadwaita-0.4.4/src/subclass/navigation_page.rs b/libadwaita-0.4.4/src/subclass/navigation_page.rs new file mode 100644 index 0000000..cdb10ab --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/navigation_page.rs @@ -0,0 +1,136 @@ +use crate::NavigationPage; +use glib::subclass::prelude::*; +use glib::translate::*; +use glib::Cast; +use gtk::subclass::prelude::WidgetImpl; + +pub trait NavigationPageImpl: WidgetImpl { + fn hidden(&self) { + self.parent_hidden() + } + + fn hiding(&self) { + self.parent_hiding(); + } + + fn showing(&self) { + self.parent_showing(); + } + + fn shown(&self) { + self.parent_shown(); + } +} + +pub trait NavigationPageImplExt: ObjectSubclass { + fn parent_hidden(&self); + fn parent_hiding(&self); + fn parent_showing(&self); + fn parent_shown(&self); +} + +impl NavigationPageImplExt for T { + fn parent_hidden(&self) { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::AdwNavigationPageClass; + if let Some(f) = (*parent_class).hidden { + f(self + .obj() + .unsafe_cast_ref::() + .to_glib_none() + .0); + } + } + } + + fn parent_hiding(&self) { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::AdwNavigationPageClass; + if let Some(f) = (*parent_class).hiding { + f(self + .obj() + .unsafe_cast_ref::() + .to_glib_none() + .0); + } + } + } + + fn parent_showing(&self) { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::AdwNavigationPageClass; + if let Some(f) = (*parent_class).showing { + f(self + .obj() + .unsafe_cast_ref::() + .to_glib_none() + .0); + } + } + } + + fn parent_shown(&self) { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::AdwNavigationPageClass; + if let Some(f) = (*parent_class).shown { + f(self + .obj() + .unsafe_cast_ref::() + .to_glib_none() + .0); + } + } + } +} + +unsafe impl IsSubclassable for NavigationPage { + fn class_init(class: &mut glib::Class) { + Self::parent_class_init::(class); + + let klass = class.as_mut(); + klass.hidden = Some(navigation_page_hidden::); + klass.hiding = Some(navigation_page_hiding::); + klass.showing = Some(navigation_page_showing::); + klass.shown = Some(navigation_page_shown::); + } +} + +unsafe extern "C" fn navigation_page_hidden( + ptr: *mut ffi::AdwNavigationPage, +) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + + imp.hidden(); +} + +unsafe extern "C" fn navigation_page_hiding( + ptr: *mut ffi::AdwNavigationPage, +) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + + imp.hiding(); +} + +unsafe extern "C" fn navigation_page_showing( + ptr: *mut ffi::AdwNavigationPage, +) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + + imp.showing(); +} + +unsafe extern "C" fn navigation_page_shown( + ptr: *mut ffi::AdwNavigationPage, +) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + + imp.shown(); +} diff --git a/libadwaita-0.4.4/src/subclass/preferences_group.rs b/libadwaita-0.4.4/src/subclass/preferences_group.rs new file mode 100644 index 0000000..28732da --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/preferences_group.rs @@ -0,0 +1,7 @@ +use crate::PreferencesGroup; +use glib::subclass::prelude::*; +use gtk::subclass::widget::WidgetImpl; + +pub trait PreferencesGroupImpl: WidgetImpl {} + +unsafe impl IsSubclassable for PreferencesGroup {} diff --git a/libadwaita-0.4.4/src/subclass/preferences_page.rs b/libadwaita-0.4.4/src/subclass/preferences_page.rs new file mode 100644 index 0000000..8d07cb8 --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/preferences_page.rs @@ -0,0 +1,7 @@ +use crate::PreferencesPage; +use glib::subclass::prelude::*; +use gtk::subclass::widget::WidgetImpl; + +pub trait PreferencesPageImpl: WidgetImpl {} + +unsafe impl IsSubclassable for PreferencesPage {} diff --git a/libadwaita-0.4.4/src/subclass/preferences_row.rs b/libadwaita-0.4.4/src/subclass/preferences_row.rs new file mode 100644 index 0000000..c65c35d --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/preferences_row.rs @@ -0,0 +1,7 @@ +use crate::PreferencesRow; +use glib::subclass::prelude::*; +use gtk::subclass::list_box_row::ListBoxRowImpl; + +pub trait PreferencesRowImpl: ListBoxRowImpl {} + +unsafe impl IsSubclassable for PreferencesRow {} diff --git a/libadwaita-0.4.4/src/subclass/preferences_window.rs b/libadwaita-0.4.4/src/subclass/preferences_window.rs new file mode 100644 index 0000000..7027e33 --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/preferences_window.rs @@ -0,0 +1,7 @@ +use super::window::AdwWindowImpl; +use crate::PreferencesWindow; +use glib::subclass::prelude::*; + +pub trait PreferencesWindowImpl: AdwWindowImpl {} + +unsafe impl IsSubclassable for PreferencesWindow {} diff --git a/libadwaita-0.4.4/src/subclass/spin_row.rs b/libadwaita-0.4.4/src/subclass/spin_row.rs new file mode 100644 index 0000000..ea0e187 --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/spin_row.rs @@ -0,0 +1,8 @@ +use glib::subclass::prelude::*; + +use crate::subclass::prelude::ActionRowImpl; +use crate::SpinRow; + +pub trait SpinRowImpl: ActionRowImpl {} + +unsafe impl IsSubclassable for SpinRow {} diff --git a/libadwaita-0.4.4/src/subclass/swipeable.rs b/libadwaita-0.4.4/src/subclass/swipeable.rs new file mode 100644 index 0000000..c8a6357 --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/swipeable.rs @@ -0,0 +1,200 @@ +use crate::{NavigationDirection, Swipeable}; +use glib::translate::*; +use glib::Cast; +use gtk::subclass::prelude::*; + +pub trait SwipeableImpl: WidgetImpl { + fn cancel_progress(&self) -> f64 { + self.parent_cancel_progress() + } + + fn distance(&self) -> f64 { + self.parent_distance() + } + + fn progress(&self) -> f64 { + self.parent_progress() + } + + fn snap_points(&self) -> Vec { + self.parent_snap_points() + } + + fn swipe_area( + &self, + navigation_direction: NavigationDirection, + is_drag: bool, + ) -> gdk::Rectangle { + self.parent_swipe_area(navigation_direction, is_drag) + } +} + +pub trait SwipeableImplExt: ObjectSubclass { + fn parent_cancel_progress(&self) -> f64; + fn parent_distance(&self) -> f64; + fn parent_progress(&self) -> f64; + fn parent_snap_points(&self) -> Vec; + fn parent_swipe_area( + &self, + navigation_direction: NavigationDirection, + is_drag: bool, + ) -> gdk::Rectangle; +} + +impl SwipeableImplExt for T { + fn parent_cancel_progress(&self) -> f64 { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().parent_interface::() + as *const ffi::AdwSwipeableInterface; + + let func = (*parent_iface) + .get_cancel_progress + .expect("no parent \"get_cancel_progress\" implementation"); + + func(self.obj().unsafe_cast_ref::().to_glib_none().0) + } + } + + fn parent_distance(&self) -> f64 { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().parent_interface::() + as *const ffi::AdwSwipeableInterface; + + let func = (*parent_iface) + .get_distance + .expect("no parent \"get_distance\" implementation"); + + func(self.obj().unsafe_cast_ref::().to_glib_none().0) + } + } + + fn parent_progress(&self) -> f64 { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().parent_interface::() + as *const ffi::AdwSwipeableInterface; + + let func = (*parent_iface) + .get_progress + .expect("no parent \"get_progress\" implementation"); + + func(self.obj().unsafe_cast_ref::().to_glib_none().0) + } + } + + fn parent_snap_points(&self) -> Vec { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().parent_interface::() + as *const ffi::AdwSwipeableInterface; + + let func = (*parent_iface) + .get_snap_points + .expect("no parent \"get_snap_points\" implementation"); + + let mut n_points = std::mem::MaybeUninit::uninit(); + + let points = func( + self.obj().unsafe_cast_ref::().to_glib_none().0, + n_points.as_mut_ptr(), + ); + + let size = n_points.assume_init() as usize; + Vec::from_raw_parts(points, size, size) + } + } + + fn parent_swipe_area( + &self, + navigation_direction: NavigationDirection, + is_drag: bool, + ) -> gdk::Rectangle { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().parent_interface::() + as *const ffi::AdwSwipeableInterface; + + let func = (*parent_iface) + .get_swipe_area + .expect("no parent \"get_swipe_area\" implementation"); + + let mut rect = gdk::Rectangle::uninitialized(); + func( + self.obj().unsafe_cast_ref::().to_glib_none().0, + navigation_direction.into_glib(), + is_drag.into_glib(), + rect.to_glib_none_mut().0, + ); + + rect + } + } +} + +unsafe impl IsImplementable for Swipeable { + fn interface_init(iface: &mut glib::Interface) { + let iface = iface.as_mut(); + + iface.get_cancel_progress = Some(swipeable_get_cancel_progress::); + iface.get_distance = Some(swipeable_get_distance::); + iface.get_progress = Some(swipeable_get_progress::); + iface.get_snap_points = Some(swipeable_get_snap_points::); + iface.get_swipe_area = Some(swipeable_get_swipe_area::); + } +} + +unsafe extern "C" fn swipeable_get_cancel_progress( + swipeable: *mut ffi::AdwSwipeable, +) -> f64 { + let instance = &*(swipeable as *mut T::Instance); + let imp = instance.imp(); + + imp.cancel_progress() +} + +unsafe extern "C" fn swipeable_get_distance( + swipeable: *mut ffi::AdwSwipeable, +) -> f64 { + let instance = &*(swipeable as *mut T::Instance); + let imp = instance.imp(); + + imp.distance() +} + +unsafe extern "C" fn swipeable_get_progress( + swipeable: *mut ffi::AdwSwipeable, +) -> f64 { + let instance = &*(swipeable as *mut T::Instance); + let imp = instance.imp(); + + imp.progress() +} + +unsafe extern "C" fn swipeable_get_snap_points( + swipeable: *mut ffi::AdwSwipeable, + n_pointsptr: *mut libc::c_int, +) -> *mut f64 { + let instance = &*(swipeable as *mut T::Instance); + let imp = instance.imp(); + + let points = imp.snap_points(); + + n_pointsptr.write(points.len() as libc::c_int); + ToGlibContainerFromSlice::to_glib_full_from_slice(points.as_slice()) +} + +unsafe extern "C" fn swipeable_get_swipe_area( + swipeable: *mut ffi::AdwSwipeable, + navigation_direction: ffi::AdwNavigationDirection, + is_drag: i32, + area: *mut gdk::ffi::GdkRectangle, +) { + let instance = &*(swipeable as *mut T::Instance); + let imp = instance.imp(); + + let swipe_area = imp.swipe_area(from_glib(navigation_direction), from_glib(is_drag)); + + *area = *swipe_area.to_glib_full(); +} diff --git a/libadwaita-0.4.4/src/subclass/window.rs b/libadwaita-0.4.4/src/subclass/window.rs new file mode 100644 index 0000000..a811e7f --- /dev/null +++ b/libadwaita-0.4.4/src/subclass/window.rs @@ -0,0 +1,6 @@ +use crate::Window; +use gtk::subclass::prelude::*; + +pub trait AdwWindowImpl: WindowImpl {} + +unsafe impl IsSubclassable for Window {} diff --git a/libadwaita-0.4.4/src/tab_bar.rs b/libadwaita-0.4.4/src/tab_bar.rs new file mode 100644 index 0000000..7ed54ce --- /dev/null +++ b/libadwaita-0.4.4/src/tab_bar.rs @@ -0,0 +1,57 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::{TabBar, TabPage}; +use glib::object::ObjectType as ObjectType_; +use glib::signal::connect_raw; +use glib::signal::SignalHandlerId; +use glib::translate::*; +use std::boxed::Box as Box_; +use std::mem::transmute; + +impl TabBar { + #[doc(alias = "adw_tab_bar_setup_extra_drop_target")] + pub fn setup_extra_drop_target(&self, actions: gdk::DragAction, types: &[glib::Type]) { + unsafe { + ffi::adw_tab_bar_setup_extra_drop_target( + self.to_glib_none().0, + actions.into_glib(), + types.to_glib_none().0, + types.len() as usize, + ) + } + } + + #[doc(alias = "extra-drag-drop")] + pub fn connect_extra_drag_drop bool + 'static>( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn extra_drag_drop_trampoline< + F: Fn(&TabBar, &TabPage, &glib::Value) -> bool + 'static, + >( + this: *mut ffi::AdwTabBar, + page: *mut ffi::AdwTabPage, + value: *mut glib::gobject_ffi::GValue, + f: glib::ffi::gpointer, + ) -> glib::ffi::gboolean { + let f: &F = &*(f as *const F); + f( + &from_glib_borrow(this), + &from_glib_borrow(page), + &*(value as *const glib::Value), + ) + .into_glib() + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"extra-drag-drop\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + extra_drag_drop_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} diff --git a/libadwaita-0.4.4/src/tab_view.rs b/libadwaita-0.4.4/src/tab_view.rs new file mode 100644 index 0000000..9a2e045 --- /dev/null +++ b/libadwaita-0.4.4/src/tab_view.rs @@ -0,0 +1,18 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::{TabPage, TabView}; +use glib::translate::*; + +impl TabView { + #[doc(alias = "adw_tab_view_get_nth_page")] + #[doc(alias = "get_nth_page")] + pub fn nth_page(&self, position: i32) -> TabPage { + assert!(position < self.n_pages()); + unsafe { + from_glib_none(ffi::adw_tab_view_get_nth_page( + self.to_glib_none().0, + position, + )) + } + } +} diff --git a/libadwaita-0.4.4/src/toast.rs b/libadwaita-0.4.4/src/toast.rs new file mode 100644 index 0000000..bee0e3b --- /dev/null +++ b/libadwaita-0.4.4/src/toast.rs @@ -0,0 +1,18 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::Toast; +use glib::translate::*; +use glib::ToVariant; + +impl Toast { + #[doc(alias = "adw_toast_set_action_target")] + #[doc(alias = "adw_toast_set_action_target_value")] + pub fn set_action_target(&self, target: Option<&impl ToVariant>) { + unsafe { + ffi::adw_toast_set_action_target_value( + self.to_glib_none().0, + target.map(|v| v.to_variant()).to_glib_none().0, + ); + } + } +} diff --git a/src/components/alg_page.rs b/src/components/alg_page.rs index aeb950d..ad38c91 100644 --- a/src/components/alg_page.rs +++ b/src/components/alg_page.rs @@ -1,5 +1,6 @@ use crate::utils::{get_alg_info_from_gitlab, ini_to_table}; use crate::CONFIG; +use libadwaita as adw; use adw::prelude::*; use gtk::glib::clone; use gtk::glib::PropertyGet; diff --git a/src/components/app.rs b/src/components/app.rs index d189126..798c607 100644 --- a/src/components/app.rs +++ b/src/components/app.rs @@ -1,6 +1,7 @@ use crate::components::alert::{Alert, AlertMsg, AlertResponse, AlertSettings}; use crate::components::alg_page::AlgPage; use crate::components::new_project::NewPageModel; +use libadwaita as adw; use adw::prelude::*; use gtk::prelude::*; use gtk::Widget; diff --git a/src/config.rs b/src/config.rs index 372a868..ac2849b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -151,7 +151,7 @@ impl RadarConfig { } pub fn to_preferences_entrys(config: Rc>) -> Vec { - use adw::prelude::*; + use libadwaita::prelude::*; let mut group = Vec::new(); let mut settings = Self::to_settings(config); for setting in settings.iter_mut() {