From acfe569f9c2c8ccb20fe5fddedc19fee57b1bf92 Mon Sep 17 00:00:00 2001 From: Aaron Erhardt Date: Thu, 26 Oct 2023 09:48:36 +0200 Subject: [PATCH 1/3] Update book to latest beta --- .github/workflows/book-next.yml | 7 ++++ Cargo.toml | 4 +- examples/alert.rs | 2 +- examples/components.rs | 2 +- examples/factory.rs | 28 +++++++------- examples/libadwaita/Cargo.toml | 2 +- src/SUMMARY.md | 1 + src/efficient_ui/factory.md | 17 ++------- src/migrations/0_6_to_0_7.md | 65 +++++++++++++++++++++++++++++++++ 9 files changed, 94 insertions(+), 34 deletions(-) create mode 100644 src/migrations/0_6_to_0_7.md diff --git a/.github/workflows/book-next.yml b/.github/workflows/book-next.yml index 5d7092b..790e048 100644 --- a/.github/workflows/book-next.yml +++ b/.github/workflows/book-next.yml @@ -40,6 +40,12 @@ jobs: - run: mdbook build -d book working-directory: ./ + - name: Link Checker + uses: lycheeverse/lychee-action@v1.8.0 + with: + args: book + fail: true + - name: Deploy uses: peaceiris/actions-gh-pages@v3 # Only deploy when ref is next @@ -60,4 +66,5 @@ jobs: - uses: codespell-project/actions-codespell@master with: check_filenames: true + path: src ignore_words_list: crate,statics,relm \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 0744609..fcf56ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ members = [ [dev-dependencies] rand = "0.8.5" -relm4 = "0.6.2" -relm4-components = "0.6.2" +relm4 = "0.7.0-beta.2" +relm4-components = "0.7.0-beta.2" tokio = { version = "1.25", features = ["rt", "macros", "time", "rt-multi-thread", "sync"] } tracker = "0.2.0" diff --git a/examples/alert.rs b/examples/alert.rs index 87f85e7..d9e533e 100644 --- a/examples/alert.rs +++ b/examples/alert.rs @@ -177,7 +177,7 @@ impl SimpleComponent for App { connect_close_request[sender] => move |_| { sender.input(AppMsg::CloseRequest); - gtk::Inhibit(true) + gtk::glib::Propagation::Stop }, gtk::Box { diff --git a/examples/components.rs b/examples/components.rs index 57ad564..8e26e11 100644 --- a/examples/components.rs +++ b/examples/components.rs @@ -191,7 +191,7 @@ impl SimpleComponent for AppModel { }, connect_close_request[sender] => move |_| { sender.input(AppMsg::CloseRequest); - gtk::Inhibit(true) + gtk::glib::Propagation::Stop } } } diff --git a/examples/factory.rs b/examples/factory.rs index 8e0dc79..8c6bec9 100644 --- a/examples/factory.rs +++ b/examples/factory.rs @@ -36,7 +36,6 @@ impl FactoryComponent for Counter { type Output = CounterOutput; type CommandOutput = (); type Widgets = CounterWidgets; - type ParentInput = AppMsg; type ParentWidget = gtk::Box; // ANCHOR_END: factory_impl_start @@ -69,7 +68,7 @@ impl FactoryComponent for Counter { gtk::Button { set_label: "Up", connect_clicked[sender, index] => move |_| { - sender.output(CounterOutput::MoveUp(index.clone())) + sender.output(CounterOutput::MoveUp(index.clone())).unwrap(); } }, @@ -77,7 +76,7 @@ impl FactoryComponent for Counter { gtk::Button { set_label: "Down", connect_clicked[sender, index] => move |_| { - sender.output(CounterOutput::MoveDown(index.clone())) + sender.output(CounterOutput::MoveDown(index.clone())).unwrap(); } }, @@ -85,23 +84,13 @@ impl FactoryComponent for Counter { gtk::Button { set_label: "To Start", connect_clicked[sender, index] => move |_| { - sender.output(CounterOutput::SendFront(index.clone())) + sender.output(CounterOutput::SendFront(index.clone())).unwrap(); } } } } // ANCHOR_END: factory_view - // ANCHOR: output_to_parent - fn forward_to_parent(output: Self::Output) -> Option { - Some(match output { - CounterOutput::SendFront(index) => AppMsg::SendFront(index), - CounterOutput::MoveUp(index) => AppMsg::MoveUp(index), - CounterOutput::MoveDown(index) => AppMsg::MoveDown(index), - }) - } - // ANCHOR_END: output_to_parent - // ANCHOR: factory_init_model fn init_model(value: Self::Init, _index: &DynamicIndex, _sender: FactorySender) -> Self { Self { value } @@ -183,7 +172,16 @@ impl SimpleComponent for App { root: &Self::Root, sender: ComponentSender, ) -> ComponentParts { - let counters = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()); + // ANCHOR: output_to_parent + let counters = FactoryVecDeque::builder() + .launch(gtk::Box::default()) + .forward(sender.input_sender(), |output| match output { + CounterOutput::SendFront(index) => AppMsg::SendFront(index), + CounterOutput::MoveUp(index) => AppMsg::MoveUp(index), + CounterOutput::MoveDown(index) => AppMsg::MoveDown(index), + }); + // ANCHOR_END: output_to_parent + let model = App { created_widgets: counter, counters, diff --git a/examples/libadwaita/Cargo.toml b/examples/libadwaita/Cargo.toml index bca822f..7525e25 100644 --- a/examples/libadwaita/Cargo.toml +++ b/examples/libadwaita/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dev-dependencies] rand = "0.8.4" -relm4 = { version = "0.6.0", features = ["libadwaita"] } +relm4 = { version = "0.7.0-beta.2", features = ["libadwaita"] } [[example]] name = "simple_manual" diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 3750ff4..f6278eb 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -34,3 +34,4 @@ - [0.2 to 0.4](migrations/0_2_to_0_4.md) - [0.4 to 0.5](migrations/0_4_to_0_5.md) - [0.5 to 0.6](migrations/0_5_to_0_6.md) + - [0.6 to 0.7](migrations/0_6_to_0_7.md) diff --git a/src/efficient_ui/factory.md b/src/efficient_ui/factory.md index f45dd20..84916b9 100644 --- a/src/efficient_ui/factory.md +++ b/src/efficient_ui/factory.md @@ -79,7 +79,6 @@ Let's look at the associated types one by one: + **Output**: The output message type. + **CommandOutput**: The command output message type, we don't need it here. + **Widgets**: The name of the struct that stores out widgets, it will be created by the macro. -+ **ParentInput**: The input message type of the parent component. + **ParentWidget**: The container widget used to store the widgets of the factory, for example `gtk::Box`. ### Creating the widget @@ -101,17 +100,6 @@ Also, we just need to implement the `init_model` function because `init_widgets` {{#include ../../examples/factory.rs:factory_init_model }} ``` -### Forwarding messages - -Factories can implement the `forward_to_parent` method to send messages to their parent component. - -If `Some` is returned, a message is forwarded. -If `None` is returned, nothing happens. - -```rust,no_run,noplayground -{{#include ../../examples/factory.rs:output_to_parent }} -``` - ## The main component Now, we have implemented the `FactoryComponent` type for the elements in our factory. @@ -129,10 +117,11 @@ First we define the model and the input message type and then start the trait im ### Initializing the factory We skip the `view` macro for a moment and look at the `init` method. -You see that we are initializing the `FactoryVecDeque` with a container widget. +You see that we are initializing the `FactoryVecDeque` using a builder pattern. +First, we call `FactoryVecDeque::builder()` to create the builder and use `launch()` to set the root widget of the factory. This widget will store all the widgets created by the factory. -We also pass an input sender so the `forward_to_parent` method we defined earlier can send input messages to our main component. +Then, we use the `forward()` method to pass all output messages of our factory (with type `CounterOutput`) to the input of our component (with type `AppMsg`). The last trick we have up our sleeves is to define a local variable `counter_box` that is a reference to the container widget of our factory. We'll use it in the `view` macro in the next section. diff --git a/src/migrations/0_6_to_0_7.md b/src/migrations/0_6_to_0_7.md new file mode 100644 index 0000000..61df45a --- /dev/null +++ b/src/migrations/0_6_to_0_7.md @@ -0,0 +1,65 @@ +# Migration from v0.6 to v0.7 + +## Factory changes + +`ParentInput` and `forward_to_parent()` were removed from `FactoryComponent` and `AsyncFactoryComponent`. +Instead, factories now support basically the same builder pattern as components. + +### Example + +Replace this: + +```rust +#[relm4::factory] +impl FactoryComponent for Counter { + type ParentInput = AppMsg; + + fn forward_to_parent(output: Self::Output) -> Option { + Some(match output { + CounterOutput::SendFront(index) => AppMsg::SendFront(index), + CounterOutput::MoveUp(index) => AppMsg::MoveUp(index), + CounterOutput::MoveDown(index) => AppMsg::MoveDown(index), + }) + } + + // ... +} + +#[relm4::component] +impl SimpleComponent for App { + // ... + + fn init( + counter: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let counters = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()); + // ... + } +} +``` + +With this: + +```rust +#[relm4::component] +impl SimpleComponent for App { + // ... + + fn init( + counter: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let counters = FactoryVecDeque::builder() + .launch(gtk::Box::default()) + .forward(sender.input_sender(), |output| match output { + CounterOutput::SendFront(index) => AppMsg::SendFront(index), + CounterOutput::MoveUp(index) => AppMsg::MoveUp(index), + CounterOutput::MoveDown(index) => AppMsg::MoveDown(index), + }); + // ... + } +} +``` \ No newline at end of file From 749ca7dd4616f8c0bb05fd46f48d7cb7dda60fbe Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Wed, 20 Dec 2023 00:00:19 +0200 Subject: [PATCH 2/3] Minor cleanups --- examples/factory.rs | 4 ++-- examples/simple.rs | 8 ++------ src/component_macro.md | 29 +++++++++++++++-------------- src/efficient_ui/factory.md | 1 - 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/examples/factory.rs b/examples/factory.rs index 8c6bec9..d19b881 100644 --- a/examples/factory.rs +++ b/examples/factory.rs @@ -35,13 +35,13 @@ impl FactoryComponent for Counter { type Input = CounterMsg; type Output = CounterOutput; type CommandOutput = (); - type Widgets = CounterWidgets; type ParentWidget = gtk::Box; // ANCHOR_END: factory_impl_start // ANCHOR: factory_view view! { - root = gtk::Box { + #[root] + gtk::Box { set_orientation: gtk::Orientation::Horizontal, set_spacing: 10, diff --git a/examples/simple.rs b/examples/simple.rs index b407612..4e90bf9 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -35,18 +35,14 @@ impl SimpleComponent for AppModel { gtk::Button { set_label: "Increment", - connect_clicked[sender] => move |_| { - sender.input(AppMsg::Increment); - } + connect_clicked => AppMsg::Increment }, // ANCHOR: widget_assign_fn gtk::Button::with_label("Decrement") { // ANCHOR_END: widget_assign_fn // ANCHOR: connect - connect_clicked[sender] => move |_| { - sender.input(AppMsg::Decrement); - } + connect_clicked => AppMsg::Decrement // ANCHOR_END: connect }, diff --git a/src/component_macro.md b/src/component_macro.md index 3172961..b681784 100644 --- a/src/component_macro.md +++ b/src/component_macro.md @@ -48,7 +48,7 @@ Sometimes we want to use a constructor function to initialize our widgets. For t ### Events -To connect events, we use this syntax: +To connect events, we use this general syntax: ```rust,no_run,noplayground method_name[cloned_var1, cloned_var2, ...] => move |args, ...| { code... } @@ -56,22 +56,23 @@ method_name[cloned_var1, cloned_var2, ...] => move |args, ...| { code... } Again, there's no magic. The macro will simply assign a closure to a method. Because closures often need to capture local variables that don't implement the `Copy` trait, we need to clone these variables. Therefore, we can list the variables we want to clone in the square brackets after the method name. +For simple cases there's even a shorter syntax for just sending one input message that works with most event handlers. +So instead of this: ```rust,no_run,noplayground -{{#include ../examples/simple.rs:connect }} +method_name[sender] => move |_| { sender.input(Msg); }, +``` + +You can simply write this: + +```rust,no_run,noplayground +method_name => Msg, ``` -> There's even a shorter syntax for just sending one input message that works with most event handlers. -> So instead of this: -> -> ```rust,no_run,noplayground -> method_name[sender] => move |_| { sender.input(Msg); }, -> ``` -> -> You can simply write this: -> -> ```rust,no_run,noplayground -> method_name => Msg, -> ``` +This is what we used in this example: + +```rust,no_run,noplayground +{{#include ../examples/simple.rs:connect }} +``` ### UI updates diff --git a/src/efficient_ui/factory.md b/src/efficient_ui/factory.md index 84916b9..9b93698 100644 --- a/src/efficient_ui/factory.md +++ b/src/efficient_ui/factory.md @@ -78,7 +78,6 @@ Let's look at the associated types one by one: + **Input**: The input message type. + **Output**: The output message type. + **CommandOutput**: The command output message type, we don't need it here. -+ **Widgets**: The name of the struct that stores out widgets, it will be created by the macro. + **ParentWidget**: The container widget used to store the widgets of the factory, for example `gtk::Box`. ### Creating the widget From e174eddfc130b6672d35d93373f53c201a29978b Mon Sep 17 00:00:00 2001 From: Aaron Erhardt Date: Wed, 13 Mar 2024 23:04:11 +0100 Subject: [PATCH 3/3] Update book to 0.7 --- Cargo.toml | 4 ++-- examples/alert.rs | 8 ++++---- examples/async.rs | 4 ++-- examples/commands.rs | 4 ++-- examples/components.rs | 8 ++++---- examples/factory.rs | 2 +- examples/libadwaita/simple_manual.rs | 2 +- examples/macro_reference.rs | 2 +- examples/simple.rs | 2 +- examples/simple_manual.rs | 2 +- examples/threads.rs | 2 +- examples/tracker.rs | 9 ++++----- examples/widget_template.rs | 2 +- examples/widget_template_nested_access.rs | 2 +- examples/worker.rs | 2 +- src/efficient_ui/tracker.md | 11 ++++++----- src/introduction.md | 4 ++-- src/migrations/0_6_to_0_7.md | 15 ++++++++++++++- 18 files changed, 49 insertions(+), 36 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fcf56ec..1dcafe5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ members = [ [dev-dependencies] rand = "0.8.5" -relm4 = "0.7.0-beta.2" -relm4-components = "0.7.0-beta.2" +relm4 = "0.7.0" +relm4-components = "0.7.0" tokio = { version = "1.25", features = ["rt", "macros", "time", "rt-multi-thread", "sync"] } tracker = "0.2.0" diff --git a/examples/alert.rs b/examples/alert.rs index d9e533e..65ddeb1 100644 --- a/examples/alert.rs +++ b/examples/alert.rs @@ -93,7 +93,7 @@ impl SimpleComponent for Alert { // ANCHOR: init_model fn init( settings: AlertSettings, - root: &Self::Root, + root: Self::Root, sender: ComponentSender, ) -> ComponentParts { let model = Alert { @@ -245,12 +245,12 @@ impl SimpleComponent for App { } // ANCHOR: app_init - fn init(_: (), root: &Self::Root, sender: ComponentSender) -> ComponentParts { + fn init(_: (), root: Self::Root, sender: ComponentSender) -> ComponentParts { let model = App { counter: 0, alert_toggle: false, dialog: Alert::builder() - .transient_for(root) + .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")), @@ -262,7 +262,7 @@ impl SimpleComponent for App { }) .forward(sender.input_sender(), convert_alert_response), second_dialog: Alert::builder() - .transient_for(root) + .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")), diff --git a/examples/async.rs b/examples/async.rs index b2ed03e..393a881 100644 --- a/examples/async.rs +++ b/examples/async.rs @@ -55,9 +55,9 @@ impl AsyncComponent for App { } // ANCHOR: init_loading_widgets - fn init_loading_widgets(root: &mut Self::Root) -> Option { + fn init_loading_widgets(root: Self::Root) -> Option { view! { - #[local_ref] + #[local] root { set_title: Some("Simple app"), set_default_size: (300, 100), diff --git a/examples/commands.rs b/examples/commands.rs index c9bd985..8d9f0fb 100644 --- a/examples/commands.rs +++ b/examples/commands.rs @@ -50,7 +50,7 @@ impl Component for CommandModel { } // Initialize the UI. - fn init(_: Self::Init, _: &Self::Root, _: ComponentSender) -> ComponentParts { + fn init(_: Self::Init, _: Self::Root, _: ComponentSender) -> ComponentParts { todo!() } @@ -99,7 +99,7 @@ impl Component for SyncCommandModel { } // Initialize the UI. - fn init(_: Self::Init, _: &Self::Root, _: ComponentSender) -> ComponentParts { + fn init(_: Self::Init, _: Self::Root, _: ComponentSender) -> ComponentParts { todo!() } diff --git a/examples/components.rs b/examples/components.rs index 8e26e11..19c7fca 100644 --- a/examples/components.rs +++ b/examples/components.rs @@ -67,7 +67,7 @@ impl SimpleComponent for HeaderModel { fn init( _params: Self::Init, - root: &Self::Root, + root: Self::Root, sender: ComponentSender, ) -> ComponentParts { let model = HeaderModel; @@ -127,7 +127,7 @@ impl SimpleComponent for DialogModel { fn init( params: Self::Init, - root: &Self::Root, + root: Self::Root, sender: ComponentSender, ) -> ComponentParts { let model = DialogModel { hidden: params }; @@ -200,7 +200,7 @@ impl SimpleComponent for AppModel { // ANCHOR: app_init fn init( params: Self::Init, - root: &Self::Root, + root: Self::Root, sender: ComponentSender, ) -> ComponentParts { // ANCHOR: forward @@ -215,7 +215,7 @@ impl SimpleComponent for AppModel { // ANCHOR_END: forward let dialog = DialogModel::builder() - .transient_for(root) + .transient_for(&root) .launch(true) .forward(sender.input_sender(), |msg| match msg { DialogOutput::Close => AppMsg::Close, diff --git a/examples/factory.rs b/examples/factory.rs index d19b881..3b39d62 100644 --- a/examples/factory.rs +++ b/examples/factory.rs @@ -169,7 +169,7 @@ impl SimpleComponent for App { // Initialize the UI. fn init( counter: Self::Init, - root: &Self::Root, + root: Self::Root, sender: ComponentSender, ) -> ComponentParts { // ANCHOR: output_to_parent diff --git a/examples/libadwaita/simple_manual.rs b/examples/libadwaita/simple_manual.rs index 415e88d..33a8cfe 100644 --- a/examples/libadwaita/simple_manual.rs +++ b/examples/libadwaita/simple_manual.rs @@ -40,7 +40,7 @@ impl SimpleComponent for AppModel { fn init( counter: Self::Init, - window: &Self::Root, + window: Self::Root, sender: ComponentSender, ) -> ComponentParts { let model = AppModel { counter }; diff --git a/examples/macro_reference.rs b/examples/macro_reference.rs index 22cbb2e..cf26cfe 100644 --- a/examples/macro_reference.rs +++ b/examples/macro_reference.rs @@ -171,7 +171,7 @@ impl SimpleComponent for AppModel { // Initialize the UI. fn init( init: Self::Init, - renamed_root: &Self::Root, + renamed_root: Self::Root, sender: ComponentSender, ) -> ComponentParts { let counter = AppModel { diff --git a/examples/simple.rs b/examples/simple.rs index 4e90bf9..4b2e727 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -60,7 +60,7 @@ impl SimpleComponent for AppModel { // Initialize the UI. fn init( counter: Self::Init, - root: &Self::Root, + root: Self::Root, sender: ComponentSender, ) -> ComponentParts { let model = AppModel { counter }; diff --git a/examples/simple_manual.rs b/examples/simple_manual.rs index 1634957..931b6bd 100644 --- a/examples/simple_manual.rs +++ b/examples/simple_manual.rs @@ -55,7 +55,7 @@ impl SimpleComponent for AppModel { /// Initialize the UI and model. fn init( counter: Self::Init, - window: &Self::Root, + window: Self::Root, sender: ComponentSender, ) -> relm4::ComponentParts { let model = AppModel { counter }; diff --git a/examples/threads.rs b/examples/threads.rs index fa73e25..7156d18 100644 --- a/examples/threads.rs +++ b/examples/threads.rs @@ -37,7 +37,7 @@ impl SimpleComponent for AppModel { } // Initialize the UI. - fn init(_: Self::Init, _: &Self::Root, _: ComponentSender) -> ComponentParts { + fn init(_: Self::Init, _: Self::Root, _: ComponentSender) -> ComponentParts { todo!() } diff --git a/examples/tracker.rs b/examples/tracker.rs index 8db59b4..5067d3d 100644 --- a/examples/tracker.rs +++ b/examples/tracker.rs @@ -101,7 +101,7 @@ impl SimpleComponent for AppModel { // Initialize the UI. fn init( _params: Self::Init, - root: &Self::Root, + root: Self::Root, sender: ComponentSender, ) -> ComponentParts { // ANCHOR: model_init @@ -113,12 +113,8 @@ impl SimpleComponent for AppModel { }; // ANCHOR_END: model_init - // ANCHOR: post_init - relm4::set_global_css(".identical { background: #00ad5c; }"); - // Insert the macro code generation here let widgets = view_output!(); - // ANCHOR_END: post_init ComponentParts { model, widgets } } @@ -141,8 +137,11 @@ impl SimpleComponent for AppModel { // ANCHOR_END: update } +// ANCHOR: main fn main() { let app = RelmApp::new("relm4.test.simple"); + app.set_global_css(".identical { background: #00ad5c; }"); app.run::(()); } +// ANCHOR_END: main // ANCHOR_END: all diff --git a/examples/widget_template.rs b/examples/widget_template.rs index eb18dd1..db269ec 100644 --- a/examples/widget_template.rs +++ b/examples/widget_template.rs @@ -115,7 +115,7 @@ impl SimpleComponent for AppModel { fn init( counter: Self::Init, - root: &Self::Root, + root: Self::Root, sender: ComponentSender, ) -> ComponentParts { let model = Self { counter }; diff --git a/examples/widget_template_nested_access.rs b/examples/widget_template_nested_access.rs index f9ccdd1..216772c 100644 --- a/examples/widget_template_nested_access.rs +++ b/examples/widget_template_nested_access.rs @@ -135,7 +135,7 @@ impl SimpleComponent for AppModel { fn init( _init_param: Self::Init, - root: &Self::Root, + root: Self::Root, sender: ComponentSender, ) -> ComponentParts { let model = Self { diff --git a/examples/worker.rs b/examples/worker.rs index ba0db04..9ea5159 100644 --- a/examples/worker.rs +++ b/examples/worker.rs @@ -88,7 +88,7 @@ impl SimpleComponent for AppModel { } // ANCHOR: worker_construction - fn init(_: (), root: &Self::Root, sender: ComponentSender) -> ComponentParts { + fn init(_: (), root: Self::Root, sender: ComponentSender) -> ComponentParts { let model = AppModel { counter: 0, worker: AsyncHandler::builder() diff --git a/src/efficient_ui/tracker.md b/src/efficient_ui/tracker.md index 5b904e5..eb546a6 100644 --- a/src/efficient_ui/tracker.md +++ b/src/efficient_ui/tracker.md @@ -118,15 +118,16 @@ Now we reached the interesting part of the code where we can actually make use o {{#include ../../examples/tracker.rs:view }} ``` -The overall UI is pretty simple: A window that contains a box. This box itself has two boxes that display the two icons and the two buttons to update them. +## The main function + +In this example, we need some additional code in `fn main()` to add [custom CSS](https://docs.gtk.org/gtk4/css-properties.html) that sets the background color for elements with class name "identical". +Later, we just need to assign the "identical" class name to a widget to make it match the CSS selector. -We also added some additional code in `init` that runs before the view is constructed. In our case, we want to add [custom CSS](https://docs.gtk.org/gtk4/css-properties.html) that sets the background color for elements with class name "identical". ```rust,no_run,noplayground -{{#include ../../examples/tracker.rs:post_init }} +{{#include ../../examples/tracker.rs:main }} ``` - ### The `#[track]` attribute The `#[track]` attribute is applied to method invocations in our view code. It allows us to add a condition to the update: if the condition is true, the method will be called, otherwise, it will be skipped. The attribute syntax looks like this: @@ -161,7 +162,7 @@ The second `#[track]` attribute works similarly: {{#include ../../examples/tracker.rs:track2 }} ``` -> **Debugging Helper** +> **Using a tracker as debugging helper** > > Since the `#[track]` attribute parses expressions, you can use the following syntax to debug your trackers: > diff --git a/src/introduction.md b/src/introduction.md index 211d69c..71f3c91 100644 --- a/src/introduction.md +++ b/src/introduction.md @@ -38,8 +38,8 @@ I also recommend reading the [gtk4-rs book](https://gtk-rs.org/gtk4-rs/git/book/ Add the packages you need to your `Cargo.toml`: ```toml -relm4 = "0.6.0" -relm4-components = "0.6.0" +relm4 = "0.7.0" +relm4-components = "0.7.0" ``` ## Issues and feedback diff --git a/src/migrations/0_6_to_0_7.md b/src/migrations/0_6_to_0_7.md index 61df45a..b588766 100644 --- a/src/migrations/0_6_to_0_7.md +++ b/src/migrations/0_6_to_0_7.md @@ -1,5 +1,13 @@ # Migration from v0.6 to v0.7 +## Component changes + +Switching between the `Component` and `AsyncComponent` traits has been a bit unpleasant in previous versions due to complex errors generated by the code generated by `async-trait`. +To avoid this, the signatures of `Component` and `AsyncComponent` were unified. + +This means, that `Component::init()` and `SimpleComponent::init()` now take `Self::Root` as owned parameter instead of a reference (`&Self::Root`). +In most places, this just means that you have to remove a `&`. + ## Factory changes `ParentInput` and `forward_to_parent()` were removed from `FactoryComponent` and `AsyncFactoryComponent`. @@ -62,4 +70,9 @@ impl SimpleComponent for App { // ... } } -``` \ No newline at end of file +``` + +## Other changes + ++ `set_global_css` and `set_global_css_from_file` are now methods of `RelmApp` to prevent calling them before initializing GTK ++ The `drawing` module was moved into the new `abstractions` module \ No newline at end of file