Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
AaronErhardt committed Mar 13, 2024
1 parent ae4245a commit 7b65e68
Show file tree
Hide file tree
Showing 28 changed files with 893 additions and 871 deletions.
2 changes: 1 addition & 1 deletion book/next/basic_concepts/components.html
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ <h1 id="components"><a class="header" href="#components">Components</a></h1>
<h2 id="the-component-trait"><a class="header" href="#the-component-trait">The <code>Component</code> trait</a></h2>
<p>The <code>Component</code> trait is the base of every component inside Relm4, it defines how a component should behave, communicate and produce widgets.</p>
<h2 id="the-simplecomponent-trait"><a class="header" href="#the-simplecomponent-trait">The <code>SimpleComponent</code> trait</a></h2>
<p>The <code>SimpleComponent</code> trait is a convenience trait that implements the <code>Component</code> trait, but removes some advanced features that are not relevant for most use-cases. </p>
<p>The <code>SimpleComponent</code> trait is a convenience trait that implements the <code>Component</code> trait, but removes some advanced features that are not relevant for most use-cases.</p>
<p>For each implementation of <code>SimpleComponent</code>, Relm4 will automatically implement <code>Component</code> as well. Thus, it can also be used instead of <code>Component</code>. This mechanism is called <a href="https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods">blanket implementation</a> and is used for traits like <code>From</code> in the standard library as well.</p>

</main>
Expand Down
2 changes: 1 addition & 1 deletion book/next/basic_concepts/messages.html
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ <h1 class="menu-title">GUI development with Relm4</h1>
<main>
<h1 id="messages"><a class="header" href="#messages">Messages</a></h1>
<p>To help the computer understand what we want to tell it, we first translate user interactions into messages.</p>
<p>In Relm4, a message can be any data type, but most often, an <code>enum</code> is used. </p>
<p>In Relm4, a message can be any data type, but most often, an <code>enum</code> is used.</p>
<pre><code class="language-rust no_run noplayground">enum AppInput {
Increment,
Decrement,
Expand Down
2 changes: 1 addition & 1 deletion book/next/basic_concepts/model.html
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ <h1 class="menu-title">GUI development with Relm4</h1>
<main>
<h1 id="model"><a class="header" href="#model">Model</a></h1>
<p>Like a person, a computer needs a brain to be functional. It needs to process our messages and remember the results.</p>
<p>Relm4 uses the term model as a data type that represents the application state, the memory of your application. </p>
<p>Relm4 uses the term model as a data type that represents the application state, the memory of your application.</p>
<p>For example, to store a counter value, we can store a <code>u8</code> in our model:</p>
<pre><code class="language-rust no_run noplayground">struct AppModel {
counter: u8,
Expand Down
122 changes: 61 additions & 61 deletions book/next/child_components.html
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ <h2 id="the-alert-component"><a class="header" href="#the-alert-component">The a
<p>When initializing the model, we conditionally set up some widgets based on the settings passed by the caller. We set <code>is_active</code> to <code>false</code> since the dialog is not currently displayed.</p>
<pre><code class="language-rust ignore"> fn init(
settings: AlertSettings,
root: &amp;Self::Root,
root: Self::Root,
sender: ComponentSender&lt;Self&gt;,
) -&gt; ComponentParts&lt;Self&gt; {
let model = Alert {
Expand All @@ -284,16 +284,16 @@ <h2 id="the-alert-component"><a class="header" href="#the-alert-component">The a
let accept_widget = widgets
.dialog
.widget_for_response(gtk::ResponseType::Accept)
.expect(&quot;No button for accept response set&quot;);
accept_widget.add_css_class(&quot;destructive-action&quot;);
.expect("No button for accept response set");
accept_widget.add_css_class("destructive-action");
}

ComponentParts { model, widgets }
}</code></pre>
<p>Lastly, the view. Note that the component connects to the <a href="https://docs.gtk.org/gtk4/signal.Dialog.response.html"><code>response</code>
signal</a> of the underlying dialog and sends an <em>input</em> to itself when a response is received.</p>
<pre><code class="language-rust ignore"> view! {
#[name = &quot;dialog&quot;]
#[name = "dialog"]
gtk::MessageDialog {
set_message_type: gtk::MessageType::Question,
#[watch]
Expand Down Expand Up @@ -337,7 +337,7 @@ <h2 id="usage"><a class="header" href="#usage">Usage</a></h2>

view! {
main_window = gtk::ApplicationWindow {
set_title: Some(&quot;Simple app&quot;),
set_title: Some("Simple app"),
set_default_width: 300,
set_default_height: 100,

Expand All @@ -352,24 +352,24 @@ <h2 id="usage"><a class="header" href="#usage">Usage</a></h2>
set_spacing: 5,

append = &amp;gtk::Button {
set_label: &quot;Increment&quot;,
set_label: "Increment",
connect_clicked[sender] =&gt; move |_| {
sender.input(AppMsg::Increment);
},
},
append = &amp;gtk::Button {
set_label: &quot;Decrement&quot;,
set_label: "Decrement",
connect_clicked[sender] =&gt; move |_| {
sender.input(AppMsg::Decrement);
},
},
append = &amp;gtk::Label {
set_margin_all: 5,
#[watch]
set_label: &amp;format!(&quot;Counter: {}&quot;, model.counter),
set_label: &amp;format!("Counter: {}", model.counter),
},
append = &amp;gtk::Button {
set_label: &quot;Close&quot;,
set_label: "Close",
connect_clicked[sender] =&gt; move |_| {
sender.input(AppMsg::CloseRequest);
},
Expand Down Expand Up @@ -399,7 +399,7 @@ <h2 id="usage"><a class="header" href="#usage">Usage</a></h2>
}
}
AppMsg::Save =&gt; {
println!(&quot;* Open save dialog here *&quot;);
println!("* Open save dialog here *");
}
AppMsg::Close =&gt; {
relm4::main_application().quit();
Expand All @@ -408,30 +408,30 @@ <h2 id="usage"><a class="header" href="#usage">Usage</a></h2>
}
}

fn init(_: (), root: &amp;Self::Root, sender: ComponentSender&lt;Self&gt;) -&gt; ComponentParts&lt;Self&gt; {
fn init(_: (), root: Self::Root, sender: ComponentSender&lt;Self&gt;) -&gt; ComponentParts&lt;Self&gt; {
let model = App {
counter: 0,
alert_toggle: false,
dialog: Alert::builder()
.transient_for(root)
.transient_for(&amp;root)
.launch(AlertSettings {
text: String::from(&quot;Do you want to quit without saving? (First alert)&quot;),
secondary_text: Some(String::from(&quot;Your counter hasn't reached 42 yet&quot;)),
confirm_label: String::from(&quot;Close without saving&quot;),
cancel_label: String::from(&quot;Cancel&quot;),
option_label: Some(String::from(&quot;Save&quot;)),
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)
.transient_for(&amp;root)
.launch(AlertSettings {
text: String::from(&quot;Do you want to quit without saving? (Second alert)&quot;),
secondary_text: Some(String::from(&quot;Your counter hasn't reached 42 yet&quot;)),
confirm_label: String::from(&quot;Close without saving&quot;),
cancel_label: String::from(&quot;Cancel&quot;),
option_label: Some(String::from(&quot;Save&quot;)),
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,
})
Expand All @@ -453,7 +453,7 @@ <h2 id="usage"><a class="header" href="#usage">Usage</a></h2>
}

fn main() {
let app = RelmApp::new(&quot;relm4.example.alert&quot;);
let app = RelmApp::new("relm4.example.alert");
app.run::&lt;App&gt;(());
}</code></pre>
<p>This is mostly stuff that we've already done in previous chapters, but there are a few additional things to know about interacting with child components.</p>
Expand All @@ -465,30 +465,30 @@ <h2 id="usage"><a class="header" href="#usage">Usage</a></h2>
second_dialog: Controller&lt;Alert&gt;,
}</code></pre>
<p>We initialize them with the builder pattern in the <code>init</code> method.</p>
<pre><code class="language-rust ignore"> fn init(_: (), root: &amp;Self::Root, sender: ComponentSender&lt;Self&gt;) -&gt; ComponentParts&lt;Self&gt; {
<pre><code class="language-rust ignore"> fn init(_: (), root: Self::Root, sender: ComponentSender&lt;Self&gt;) -&gt; ComponentParts&lt;Self&gt; {
let model = App {
counter: 0,
alert_toggle: false,
dialog: Alert::builder()
.transient_for(root)
.transient_for(&amp;root)
.launch(AlertSettings {
text: String::from(&quot;Do you want to quit without saving? (First alert)&quot;),
secondary_text: Some(String::from(&quot;Your counter hasn't reached 42 yet&quot;)),
confirm_label: String::from(&quot;Close without saving&quot;),
cancel_label: String::from(&quot;Cancel&quot;),
option_label: Some(String::from(&quot;Save&quot;)),
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)
.transient_for(&amp;root)
.launch(AlertSettings {
text: String::from(&quot;Do you want to quit without saving? (Second alert)&quot;),
secondary_text: Some(String::from(&quot;Your counter hasn't reached 42 yet&quot;)),
confirm_label: String::from(&quot;Close without saving&quot;),
cancel_label: String::from(&quot;Cancel&quot;),
option_label: Some(String::from(&quot;Save&quot;)),
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,
})
Expand Down Expand Up @@ -578,7 +578,7 @@ <h2 id="the-complete-code"><a class="header" href="#the-complete-code">The compl
type Output = AlertResponse;

view! {
#[name = &quot;dialog&quot;]
#[name = "dialog"]
gtk::MessageDialog {
set_message_type: gtk::MessageType::Question,
#[watch]
Expand All @@ -598,7 +598,7 @@ <h2 id="the-complete-code"><a class="header" href="#the-complete-code">The compl

fn init(
settings: AlertSettings,
root: &amp;Self::Root,
root: Self::Root,
sender: ComponentSender&lt;Self&gt;,
) -&gt; ComponentParts&lt;Self&gt; {
let model = Alert {
Expand All @@ -618,8 +618,8 @@ <h2 id="the-complete-code"><a class="header" href="#the-complete-code">The compl
let accept_widget = widgets
.dialog
.widget_for_response(gtk::ResponseType::Accept)
.expect(&quot;No button for accept response set&quot;);
accept_widget.add_css_class(&quot;destructive-action&quot;);
.expect("No button for accept response set");
accept_widget.add_css_class("destructive-action");
}

ComponentParts { model, widgets }
Expand Down Expand Up @@ -669,7 +669,7 @@ <h2 id="the-complete-code"><a class="header" href="#the-complete-code">The compl

view! {
main_window = gtk::ApplicationWindow {
set_title: Some(&quot;Simple app&quot;),
set_title: Some("Simple app"),
set_default_width: 300,
set_default_height: 100,

Expand All @@ -684,24 +684,24 @@ <h2 id="the-complete-code"><a class="header" href="#the-complete-code">The compl
set_spacing: 5,

append = &amp;gtk::Button {
set_label: &quot;Increment&quot;,
set_label: "Increment",
connect_clicked[sender] =&gt; move |_| {
sender.input(AppMsg::Increment);
},
},
append = &amp;gtk::Button {
set_label: &quot;Decrement&quot;,
set_label: "Decrement",
connect_clicked[sender] =&gt; move |_| {
sender.input(AppMsg::Decrement);
},
},
append = &amp;gtk::Label {
set_margin_all: 5,
#[watch]
set_label: &amp;format!(&quot;Counter: {}&quot;, model.counter),
set_label: &amp;format!("Counter: {}", model.counter),
},
append = &amp;gtk::Button {
set_label: &quot;Close&quot;,
set_label: "Close",
connect_clicked[sender] =&gt; move |_| {
sender.input(AppMsg::CloseRequest);
},
Expand Down Expand Up @@ -731,7 +731,7 @@ <h2 id="the-complete-code"><a class="header" href="#the-complete-code">The compl
}
}
AppMsg::Save =&gt; {
println!(&quot;* Open save dialog here *&quot;);
println!("* Open save dialog here *");
}
AppMsg::Close =&gt; {
relm4::main_application().quit();
Expand All @@ -740,30 +740,30 @@ <h2 id="the-complete-code"><a class="header" href="#the-complete-code">The compl
}
}

fn init(_: (), root: &amp;Self::Root, sender: ComponentSender&lt;Self&gt;) -&gt; ComponentParts&lt;Self&gt; {
fn init(_: (), root: Self::Root, sender: ComponentSender&lt;Self&gt;) -&gt; ComponentParts&lt;Self&gt; {
let model = App {
counter: 0,
alert_toggle: false,
dialog: Alert::builder()
.transient_for(root)
.transient_for(&amp;root)
.launch(AlertSettings {
text: String::from(&quot;Do you want to quit without saving? (First alert)&quot;),
secondary_text: Some(String::from(&quot;Your counter hasn't reached 42 yet&quot;)),
confirm_label: String::from(&quot;Close without saving&quot;),
cancel_label: String::from(&quot;Cancel&quot;),
option_label: Some(String::from(&quot;Save&quot;)),
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)
.transient_for(&amp;root)
.launch(AlertSettings {
text: String::from(&quot;Do you want to quit without saving? (Second alert)&quot;),
secondary_text: Some(String::from(&quot;Your counter hasn't reached 42 yet&quot;)),
confirm_label: String::from(&quot;Close without saving&quot;),
cancel_label: String::from(&quot;Cancel&quot;),
option_label: Some(String::from(&quot;Save&quot;)),
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,
})
Expand All @@ -785,7 +785,7 @@ <h2 id="the-complete-code"><a class="header" href="#the-complete-code">The compl
}

fn main() {
let app = RelmApp::new(&quot;relm4.example.alert&quot;);
let app = RelmApp::new("relm4.example.alert");
app.run::&lt;App&gt;(());
}</code></pre>

Expand Down
Loading

0 comments on commit 7b65e68

Please sign in to comment.