comparison src/gtk.rs @ 15:d103f7cca0bd

Update to GTK 4.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Thu, 26 Aug 2021 19:34:40 +0200
parents adab13145994
children 478cf2a7d577
comparison
equal deleted inserted replaced
14:adab13145994 15:d103f7cca0bd
25 use crate::{ 25 use crate::{
26 state::State, 26 state::State,
27 DEFAULT_WIDTH, DEFAULT_HEIGHT, 27 DEFAULT_WIDTH, DEFAULT_HEIGHT,
28 }; 28 };
29 29
30 fn build_main_menu(application: &gtk::Application) { 30 fn build_main_menu(app: &gtk::Application) {
31 let quit = gio::SimpleAction::new("quit", None); 31 let quit = gio::SimpleAction::new("quit", None);
32 application.set_accels_for_action("app.quit", &["<Control>q"]); 32 app.set_accels_for_action("app.quit", &["<Control>q"]);
33 application.add_action(&quit); 33 app.add_action(&quit);
34 quit.connect_activate(clone!(@weak application => move |_, _| application.quit())); 34 quit.connect_activate(clone!(@weak app => move |_, _| app.quit()));
35 35
36 let about = gio::SimpleAction::new("about", None); 36 let about = gio::SimpleAction::new("about", None);
37 application.add_action(&about); 37 app.add_action(&about);
38 about.connect_activate(|_, _| { 38 about.connect_activate(|_, _| {
39 let about = gtk::AboutDialog::new(); 39 let about = gtk::AboutDialog::builder()
40 about.set_program_name("TabletEmu"); 40 .program_name("TabletEmu")
41 about.set_logo_icon_name(Some("input-tablet")); 41 .logo_icon_name("input-tablet")
42 about.set_website(Some("https://hg.linkmauve.fr/tablet-emu")); 42 .website("https://hg.linkmauve.fr/tablet-emu")
43 about.set_version(Some("0.1")); 43 .version("0.1")
44 about.set_license_type(gtk::License::Agpl30); 44 .license_type(gtk::License::Agpl30)
45 about.set_copyright(Some("© 2020 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>")); 45 .copyright("© 2020 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>")
46 about.run(); 46 .build();
47 unsafe { 47 //about.run();
48 about.destroy(); 48 about.destroy();
49 }
50 }); 49 });
51 50
52 let menu = gio::Menu::new(); 51 let menu = gio::Menu::new();
53 { 52 {
54 let file = gio::Menu::new(); 53 let file = gio::Menu::new();
58 { 57 {
59 let help = gio::Menu::new(); 58 let help = gio::Menu::new();
60 help.append(Some("_About"), Some("app.about")); 59 help.append(Some("_About"), Some("app.about"));
61 menu.append_submenu(Some("_Help"), &help); 60 menu.append_submenu(Some("_Help"), &help);
62 } 61 }
63 application.set_menubar(Some(&menu)); 62 app.set_menubar(Some(&menu));
64 } 63 }
65 64
66 fn build_ui(application: &gtk::Application) { 65 fn build_ui(app: &gtk::Application) {
67 build_main_menu(application); 66 build_main_menu(app);
68 67
69 let state = match State::new() { 68 let state = match State::new() {
70 Ok(state) => Arc::new(Mutex::new(state)), 69 Ok(state) => Arc::new(Mutex::new(state)),
71 Err(err) => { 70 Err(err) => {
72 match err.kind() { 71 match err.kind() {
82 } 81 }
83 std::process::exit(1); 82 std::process::exit(1);
84 } 83 }
85 }; 84 };
86 85
87 let window = gtk::ApplicationWindow::new(application); 86 let hbox = gtk::Box::builder()
88 window.set_title("tablet-emu"); 87 .orientation(gtk::Orientation::Horizontal)
89 window.set_position(gtk::WindowPosition::Center); 88 .build();
90 89 let tools_box = gtk::Box::builder()
91 let hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0); 90 .orientation(gtk::Orientation::Vertical)
92 let tools_box = gtk::Box::new(gtk::Orientation::Vertical, 0); 91 .build();
93 92
94 macro_rules! impl_tool { 93 macro_rules! impl_tool {
95 ($tool:tt) => { 94 ($tool:tt) => {
96 let tool = gtk::Button::with_mnemonic($tool); 95 let tool = gtk::Button::with_mnemonic($tool);
97 let state_weak = Arc::downgrade(&state); 96 let state_weak = Arc::downgrade(&state);
98 tool.connect_clicked(move |b| { 97 tool.connect_clicked(move |b| {
99 let state = state_weak.upgrade().unwrap(); 98 let state = state_weak.upgrade().unwrap();
100 let mut state = state.lock().unwrap(); 99 let mut state = state.lock().unwrap();
101 let tool = match b.get_label().unwrap().as_str() { 100 let tool = match b.label().unwrap().as_str() {
102 "_Pen" => Key::ButtonToolPen, 101 "_Pen" => Key::ButtonToolPen,
103 "_Rubber" => Key::ButtonToolRubber, 102 "_Rubber" => Key::ButtonToolRubber,
104 "_Brush" => Key::ButtonToolBrush, 103 "_Brush" => Key::ButtonToolBrush,
105 "P_encil" => Key::ButtonToolPencil, 104 "P_encil" => Key::ButtonToolPencil,
106 "_Airbrush" => Key::ButtonToolAirbrush, 105 "_Airbrush" => Key::ButtonToolAirbrush,
107 _ => unreachable!(), 106 _ => unreachable!(),
108 }; 107 };
109 state.select_tool(tool); 108 state.select_tool(tool);
110 }); 109 });
111 tools_box.add(&tool); 110 tools_box.append(&tool);
112 }; 111 };
113 }; 112 }
114 impl_tool!("_Pen"); 113 impl_tool!("_Pen");
115 impl_tool!("_Rubber"); 114 impl_tool!("_Rubber");
116 impl_tool!("_Brush"); 115 impl_tool!("_Brush");
117 impl_tool!("P_encil"); 116 impl_tool!("P_encil");
118 impl_tool!("_Airbrush"); 117 impl_tool!("_Airbrush");
119 118
120 let drawing_area = gtk::DrawingArea::new(); 119 let drawing_area = gtk::DrawingArea::builder()
121 drawing_area.set_size_request(DEFAULT_WIDTH, DEFAULT_HEIGHT); 120 .content_width(DEFAULT_WIDTH)
122 drawing_area.set_hexpand(true); 121 .content_height(DEFAULT_HEIGHT)
123 drawing_area.set_events( 122 .hexpand(true)
124 gdk::EventMask::BUTTON_PRESS_MASK 123 .build();
125 | gdk::EventMask::BUTTON_RELEASE_MASK 124 let gesture_click = gtk::GestureClick::builder()
126 | gdk::EventMask::POINTER_MOTION_MASK, 125 .build();
127 ); 126 let event_controller = gtk::EventControllerMotion::builder()
127 .build();
128 let state_weak = Arc::downgrade(&state); 128 let state_weak = Arc::downgrade(&state);
129 drawing_area.connect_configure_event(move |_, event| { 129 drawing_area.connect_resize(move |_, width, height| {
130 let state = state_weak.upgrade().unwrap(); 130 let state = state_weak.upgrade().unwrap();
131 let mut state = state.lock().unwrap(); 131 let mut state = state.lock().unwrap();
132 state.set_size(event.get_size()); 132 state.set_size(width, height);
133 true
134 }); 133 });
135 let state_weak = Arc::downgrade(&state); 134 let state_weak = Arc::downgrade(&state);
136 drawing_area.connect_button_press_event(move |_, event| { 135 gesture_click.connect_pressed(move |_, n_press, x, y| {
137 if event.get_button() != 1 { 136 if n_press != 1 {
138 return Inhibit(false); 137 return;
139 } 138 }
140 139
141 let state = state_weak.upgrade().unwrap(); 140 let state = state_weak.upgrade().unwrap();
142 let mut state = state.lock().unwrap(); 141 let mut state = state.lock().unwrap();
143 let (x, y) = event.get_position();
144 state.press(x, y).unwrap(); 142 state.press(x, y).unwrap();
145 Inhibit(false)
146 }); 143 });
147 let state_weak = Arc::downgrade(&state); 144 let state_weak = Arc::downgrade(&state);
148 drawing_area.connect_button_release_event(move |_, event| { 145 gesture_click.connect_released(move |_, n_press, x, y| {
149 if event.get_button() != 1 { 146 if n_press != 1 {
150 return Inhibit(false); 147 return;
151 } 148 }
152 149
153 let state = state_weak.upgrade().unwrap(); 150 let state = state_weak.upgrade().unwrap();
154 let mut state = state.lock().unwrap(); 151 let mut state = state.lock().unwrap();
155 let (x, y) = event.get_position();
156 state.release(x, y).unwrap(); 152 state.release(x, y).unwrap();
157 Inhibit(false)
158 }); 153 });
159 drawing_area.connect_motion_notify_event(move |_, event| { 154 event_controller.connect_motion(move |_, x, y| {
160 let mut state = state.lock().unwrap(); 155 let mut state = state.lock().unwrap();
161 let (x, y) = event.get_position();
162 state.motion(x, y).unwrap(); 156 state.motion(x, y).unwrap();
163 Inhibit(false)
164 }); 157 });
165 drawing_area.connect_draw(move |_, ctx| { 158 drawing_area.add_controller(&gesture_click);
166 //println!("drawing {}", drawing_area); 159 drawing_area.add_controller(&event_controller);
160 drawing_area.set_draw_func(move |_, ctx, _, _| {
167 ctx.set_source_rgb(1., 0., 0.); 161 ctx.set_source_rgb(1., 0., 0.);
168 ctx.set_operator(cairo::Operator::Screen); 162 ctx.set_operator(cairo::Operator::Screen);
169 ctx.paint(); 163 ctx.paint().unwrap();
170 Inhibit(false)
171 }); 164 });
172 165
173 hbox.add(&tools_box); 166 hbox.append(&tools_box);
174 hbox.add(&drawing_area); 167 hbox.append(&drawing_area);
175 168
176 window.add(&hbox); 169 let window = gtk::ApplicationWindow::builder()
170 .application(app)
171 .title("tablet-emu")
172 .default_width(800)
173 .default_height(480)
174 .child(&hbox)
175 .build();
177 176
178 window.show_all(); 177 window.show();
179 } 178 }
180 179
181 pub fn main(args: &[String]) { 180 pub fn main(_args: &[String]) {
182 let application = gtk::Application::new( 181 let app = gtk::Application::builder()
183 Some("fr.linkmauve.TabletEmu"), 182 .application_id("fr.linkmauve.TabletEmu")
184 gio::ApplicationFlags::empty(), 183 .build();
185 ) 184 app.connect_activate(build_ui);
186 .expect("Initialisation failed…"); 185 app.run();
187 application.connect_activate(build_ui);
188 application.run(args);
189 } 186 }