Skip to content

Commit c94c354

Browse files
committed
Add multi containers
1 parent fa5290f commit c94c354

9 files changed

Lines changed: 817 additions & 291 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ documentation = "https://docs.rs/relm/"
66
license = "MIT"
77
name = "relm"
88
repository = "https://github.com/antoyo/relm"
9-
version = "0.9.0"
9+
version = "0.9.1"
1010

1111
[badges]
1212
travis-ci = { repository = "antoyo/relm" }
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
/*
2+
* Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
* this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to
7+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
* the Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
#![feature(proc_macro)]
23+
24+
extern crate gtk;
25+
#[macro_use]
26+
extern crate relm;
27+
extern crate relm_attributes;
28+
#[macro_use]
29+
extern crate relm_derive;
30+
31+
use gtk::{
32+
ButtonExt,
33+
Inhibit,
34+
OrientableExt,
35+
WidgetExt,
36+
};
37+
use gtk::Orientation::{Horizontal, Vertical};
38+
use relm::Widget;
39+
use relm_attributes::widget;
40+
41+
use self::Msg::*;
42+
43+
#[widget]
44+
impl Widget for CenterButton {
45+
fn model() -> () {
46+
}
47+
48+
fn update(&mut self, _msg: (), _model: &mut ()) {
49+
}
50+
51+
view! {
52+
#[data="center"]
53+
gtk::Button {
54+
label: "-",
55+
},
56+
}
57+
}
58+
59+
#[widget]
60+
impl Widget for Button {
61+
fn model() -> () {
62+
}
63+
64+
fn update(&mut self, _msg: (), _model: &mut ()) {
65+
}
66+
67+
view! {
68+
#[data="right"]
69+
gtk::Button {
70+
label: "+",
71+
},
72+
}
73+
}
74+
75+
#[widget]
76+
impl Widget for VBox {
77+
fn model() -> () {
78+
()
79+
}
80+
81+
fn update(&mut self, _event: Msg, _model: &mut ()) {
82+
}
83+
84+
view! {
85+
gtk::Box {
86+
orientation: Horizontal,
87+
// Specify where the widgets will be added in this container by default.
88+
#[container]
89+
gtk::Box {
90+
orientation: Vertical,
91+
},
92+
// Specify where the widgets will be added in this container when the child's data is
93+
// "center".
94+
#[container="center"]
95+
gtk::Box {
96+
orientation: Vertical,
97+
},
98+
#[container="right"]
99+
gtk::Box {
100+
orientation: Vertical,
101+
}
102+
}
103+
}
104+
}
105+
106+
#[derive(Clone)]
107+
pub struct Model {
108+
counter: i32,
109+
}
110+
111+
#[derive(Msg)]
112+
pub enum Msg {
113+
Decrement,
114+
Increment,
115+
Quit,
116+
}
117+
118+
#[widget]
119+
impl Widget for Win {
120+
fn model() -> Model {
121+
Model {
122+
counter: 0,
123+
}
124+
}
125+
126+
fn update(&mut self, event: Msg, model: &mut Model) {
127+
match event {
128+
Decrement => model.counter -= 1,
129+
Increment => model.counter += 1,
130+
Quit => gtk::main_quit(),
131+
}
132+
}
133+
134+
view! {
135+
gtk::Window {
136+
VBox {
137+
gtk::Button {
138+
clicked => Increment,
139+
label: "+",
140+
},
141+
gtk::Label {
142+
text: &model.counter.to_string(),
143+
},
144+
Button {
145+
},
146+
CenterButton {
147+
},
148+
gtk::Button {
149+
clicked => Decrement,
150+
label: "-",
151+
},
152+
},
153+
delete_event(_, _) => (Quit, Inhibit(false)),
154+
}
155+
}
156+
}
157+
158+
fn main() {
159+
Win::run(()).unwrap();
160+
}

examples/multi-container.rs

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
/*
2+
* Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
* this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to
7+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
* the Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
#![feature(proc_macro)]
23+
24+
extern crate gtk;
25+
#[macro_use]
26+
extern crate relm;
27+
extern crate relm_attributes;
28+
#[macro_use]
29+
extern crate relm_derive;
30+
31+
use gtk::{
32+
ContainerExt,
33+
Inhibit,
34+
Label,
35+
WidgetExt,
36+
Window,
37+
};
38+
use gtk::Orientation::{Horizontal, Vertical};
39+
use gtk::WindowType::Toplevel;
40+
use relm::{Component, Container, ContainerWidget, RelmContainer, RemoteRelm, Widget};
41+
42+
use self::Msg::*;
43+
44+
#[derive(Clone)]
45+
struct CenterButton {
46+
button: gtk::Button,
47+
}
48+
49+
impl Widget for CenterButton {
50+
type Model = ();
51+
type ModelParam = ();
52+
type Msg = ();
53+
type Root = gtk::Button;
54+
55+
fn data() -> Option<&'static str> {
56+
Some("center")
57+
}
58+
59+
fn model(_: ()) -> () {
60+
}
61+
62+
fn root(&self) -> &Self::Root {
63+
&self.button
64+
}
65+
66+
fn update(&mut self, _msg: (), _model: &mut ()) {
67+
}
68+
69+
fn view(_relm: &RemoteRelm<Self>, _model: &()) -> Self {
70+
let button = gtk::Button::new_with_label("-");
71+
CenterButton {
72+
button: button,
73+
}
74+
}
75+
}
76+
77+
#[derive(Clone)]
78+
struct Button {
79+
button: gtk::Button,
80+
}
81+
82+
impl Widget for Button {
83+
type Model = ();
84+
type ModelParam = ();
85+
type Msg = ();
86+
type Root = gtk::Button;
87+
88+
fn data() -> Option<&'static str> {
89+
Some("right")
90+
}
91+
92+
fn model(_: ()) -> () {
93+
}
94+
95+
fn root(&self) -> &Self::Root {
96+
&self.button
97+
}
98+
99+
fn update(&mut self, _msg: (), _model: &mut ()) {
100+
}
101+
102+
fn view(_relm: &RemoteRelm<Self>, _model: &()) -> Self {
103+
let button = gtk::Button::new_with_label("+");
104+
Button {
105+
button: button,
106+
}
107+
}
108+
}
109+
110+
#[derive(Clone)]
111+
struct SplitBox {
112+
hbox1: gtk::Box,
113+
hbox2: gtk::Box,
114+
hbox3: gtk::Box,
115+
vbox: gtk::Box,
116+
}
117+
118+
impl Container for SplitBox {
119+
type Container = gtk::Box;
120+
121+
fn container(&self) -> &Self::Container {
122+
&self.hbox1
123+
}
124+
125+
fn add_widget<WIDGET: Widget>(&self, widget: &WIDGET) {
126+
if WIDGET::data() == Some("right") {
127+
self.hbox3.add(widget.root());
128+
}
129+
else if WIDGET::data() == Some("center") {
130+
self.hbox2.add(widget.root());
131+
}
132+
else {
133+
self.hbox1.add(widget.root());
134+
}
135+
}
136+
}
137+
138+
impl Widget for SplitBox {
139+
type Model = ();
140+
type ModelParam = ();
141+
type Msg = ();
142+
type Root = gtk::Box;
143+
144+
fn model(_: ()) -> () {
145+
()
146+
}
147+
148+
fn root(&self) -> &Self::Root {
149+
&self.vbox
150+
}
151+
152+
fn update(&mut self, _event: (), _model: &mut ()) {
153+
}
154+
155+
fn view(_relm: &RemoteRelm<Self>, _model: &Self::Model) -> Self {
156+
let vbox = gtk::Box::new(Horizontal, 0);
157+
let hbox1 = gtk::Box::new(Vertical, 0);
158+
vbox.add(&hbox1);
159+
let hbox2 = gtk::Box::new(Vertical, 0);
160+
vbox.add(&hbox2);
161+
let hbox3 = gtk::Box::new(Vertical, 0);
162+
vbox.add(&hbox3);
163+
SplitBox {
164+
hbox1,
165+
hbox2,
166+
hbox3,
167+
vbox,
168+
}
169+
}
170+
}
171+
172+
#[derive(Msg)]
173+
pub enum Msg {
174+
Quit,
175+
}
176+
177+
#[derive(Clone)]
178+
struct Win {
179+
button: Component<Button>,
180+
center_button: Component<CenterButton>,
181+
vbox: Component<SplitBox>,
182+
window: Window,
183+
}
184+
185+
impl Widget for Win {
186+
type Model = ();
187+
type ModelParam = ();
188+
type Msg = Msg;
189+
type Root = Window;
190+
191+
fn model(_: ()) -> () {
192+
}
193+
194+
fn root(&self) -> &Self::Root {
195+
&self.window
196+
}
197+
198+
fn update(&mut self, event: Msg, _model: &mut ()) {
199+
match event {
200+
Quit => gtk::main_quit(),
201+
}
202+
}
203+
204+
fn view(relm: &RemoteRelm<Self>, _model: &()) -> Self {
205+
let window = Window::new(Toplevel);
206+
let vbox = window.add_widget::<SplitBox, _>(&relm, ());
207+
let plus_button = gtk::Button::new_with_label("+");
208+
vbox.add(&plus_button);
209+
let label = Label::new(Some("0"));
210+
vbox.add(&label);
211+
let button = vbox.add_widget::<Button, _>(&relm, ());
212+
let center_button = vbox.add_widget::<CenterButton, _>(&relm, ());
213+
let minus_button = gtk::Button::new_with_label("-");
214+
vbox.add(&minus_button);
215+
connect!(relm, window, connect_delete_event(_, _) (Some(Quit), Inhibit(false)));
216+
window.show_all();
217+
Win {
218+
button: button,
219+
center_button,
220+
vbox: vbox,
221+
window: window,
222+
}
223+
}
224+
}
225+
226+
fn main() {
227+
Win::run(()).unwrap();
228+
}

0 commit comments

Comments
 (0)