# HG changeset patch # User Emmanuel Gil Peyrot # Date 1629999280 -7200 # Node ID d103f7cca0bde8464befd560a6c49d1c886f2cbc # Parent adab131459942a93a7d09d1f4677bf57d65d1a89 Update to GTK 4. diff --git a/Cargo.toml b/Cargo.toml --- a/Cargo.toml +++ b/Cargo.toml @@ -16,11 +16,11 @@ gui = ["cairo-rs", "gdk", "gio", "glib", [dependencies] input-linux = "0.3.0" bitflags = "1.2.1" -cairo-rs = { version = "0.9.1", optional = true } -gdk = { version = "0.13.2", optional = true } -gio = { version = "0.9.1", optional = true } -glib = { version = "0.10.2", optional = true } -gtk = { version = "0.9.2", optional = true } +cairo-rs = { version = "0.14", optional = true } +gdk = { version = "0.14", optional = true } +gio = { version = "0.14", optional = true } +glib = { version = "0.14", optional = true } +gtk = { package = "gtk4", version = "0.2", optional = true } [profile.release] lto = true diff --git a/src/gtk.rs b/src/gtk.rs --- a/src/gtk.rs +++ b/src/gtk.rs @@ -27,26 +27,25 @@ use crate::{ DEFAULT_WIDTH, DEFAULT_HEIGHT, }; -fn build_main_menu(application: >k::Application) { +fn build_main_menu(app: >k::Application) { let quit = gio::SimpleAction::new("quit", None); - application.set_accels_for_action("app.quit", &["q"]); - application.add_action(&quit); - quit.connect_activate(clone!(@weak application => move |_, _| application.quit())); + app.set_accels_for_action("app.quit", &["q"]); + app.add_action(&quit); + quit.connect_activate(clone!(@weak app => move |_, _| app.quit())); let about = gio::SimpleAction::new("about", None); - application.add_action(&about); + app.add_action(&about); about.connect_activate(|_, _| { - let about = gtk::AboutDialog::new(); - about.set_program_name("TabletEmu"); - about.set_logo_icon_name(Some("input-tablet")); - about.set_website(Some("https://hg.linkmauve.fr/tablet-emu")); - about.set_version(Some("0.1")); - about.set_license_type(gtk::License::Agpl30); - about.set_copyright(Some("© 2020 Emmanuel Gil Peyrot ")); - about.run(); - unsafe { - about.destroy(); - } + let about = gtk::AboutDialog::builder() + .program_name("TabletEmu") + .logo_icon_name("input-tablet") + .website("https://hg.linkmauve.fr/tablet-emu") + .version("0.1") + .license_type(gtk::License::Agpl30) + .copyright("© 2020 Emmanuel Gil Peyrot ") + .build(); + //about.run(); + about.destroy(); }); let menu = gio::Menu::new(); @@ -60,11 +59,11 @@ fn build_main_menu(application: >k::Ap help.append(Some("_About"), Some("app.about")); menu.append_submenu(Some("_Help"), &help); } - application.set_menubar(Some(&menu)); + app.set_menubar(Some(&menu)); } -fn build_ui(application: >k::Application) { - build_main_menu(application); +fn build_ui(app: >k::Application) { + build_main_menu(app); let state = match State::new() { Ok(state) => Arc::new(Mutex::new(state)), @@ -84,12 +83,12 @@ fn build_ui(application: >k::Applicati } }; - let window = gtk::ApplicationWindow::new(application); - window.set_title("tablet-emu"); - window.set_position(gtk::WindowPosition::Center); - - let hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0); - let tools_box = gtk::Box::new(gtk::Orientation::Vertical, 0); + let hbox = gtk::Box::builder() + .orientation(gtk::Orientation::Horizontal) + .build(); + let tools_box = gtk::Box::builder() + .orientation(gtk::Orientation::Vertical) + .build(); macro_rules! impl_tool { ($tool:tt) => { @@ -98,7 +97,7 @@ fn build_ui(application: >k::Applicati tool.connect_clicked(move |b| { let state = state_weak.upgrade().unwrap(); let mut state = state.lock().unwrap(); - let tool = match b.get_label().unwrap().as_str() { + let tool = match b.label().unwrap().as_str() { "_Pen" => Key::ButtonToolPen, "_Rubber" => Key::ButtonToolRubber, "_Brush" => Key::ButtonToolBrush, @@ -108,82 +107,80 @@ fn build_ui(application: >k::Applicati }; state.select_tool(tool); }); - tools_box.add(&tool); + tools_box.append(&tool); }; - }; + } impl_tool!("_Pen"); impl_tool!("_Rubber"); impl_tool!("_Brush"); impl_tool!("P_encil"); impl_tool!("_Airbrush"); - let drawing_area = gtk::DrawingArea::new(); - drawing_area.set_size_request(DEFAULT_WIDTH, DEFAULT_HEIGHT); - drawing_area.set_hexpand(true); - drawing_area.set_events( - gdk::EventMask::BUTTON_PRESS_MASK - | gdk::EventMask::BUTTON_RELEASE_MASK - | gdk::EventMask::POINTER_MOTION_MASK, - ); + let drawing_area = gtk::DrawingArea::builder() + .content_width(DEFAULT_WIDTH) + .content_height(DEFAULT_HEIGHT) + .hexpand(true) + .build(); + let gesture_click = gtk::GestureClick::builder() + .build(); + let event_controller = gtk::EventControllerMotion::builder() + .build(); let state_weak = Arc::downgrade(&state); - drawing_area.connect_configure_event(move |_, event| { + drawing_area.connect_resize(move |_, width, height| { let state = state_weak.upgrade().unwrap(); let mut state = state.lock().unwrap(); - state.set_size(event.get_size()); - true + state.set_size(width, height); }); let state_weak = Arc::downgrade(&state); - drawing_area.connect_button_press_event(move |_, event| { - if event.get_button() != 1 { - return Inhibit(false); + gesture_click.connect_pressed(move |_, n_press, x, y| { + if n_press != 1 { + return; } let state = state_weak.upgrade().unwrap(); let mut state = state.lock().unwrap(); - let (x, y) = event.get_position(); state.press(x, y).unwrap(); - Inhibit(false) }); let state_weak = Arc::downgrade(&state); - drawing_area.connect_button_release_event(move |_, event| { - if event.get_button() != 1 { - return Inhibit(false); + gesture_click.connect_released(move |_, n_press, x, y| { + if n_press != 1 { + return; } let state = state_weak.upgrade().unwrap(); let mut state = state.lock().unwrap(); - let (x, y) = event.get_position(); state.release(x, y).unwrap(); - Inhibit(false) }); - drawing_area.connect_motion_notify_event(move |_, event| { + event_controller.connect_motion(move |_, x, y| { let mut state = state.lock().unwrap(); - let (x, y) = event.get_position(); state.motion(x, y).unwrap(); - Inhibit(false) }); - drawing_area.connect_draw(move |_, ctx| { - //println!("drawing {}", drawing_area); + drawing_area.add_controller(&gesture_click); + drawing_area.add_controller(&event_controller); + drawing_area.set_draw_func(move |_, ctx, _, _| { ctx.set_source_rgb(1., 0., 0.); ctx.set_operator(cairo::Operator::Screen); - ctx.paint(); - Inhibit(false) + ctx.paint().unwrap(); }); - hbox.add(&tools_box); - hbox.add(&drawing_area); + hbox.append(&tools_box); + hbox.append(&drawing_area); - window.add(&hbox); + let window = gtk::ApplicationWindow::builder() + .application(app) + .title("tablet-emu") + .default_width(800) + .default_height(480) + .child(&hbox) + .build(); - window.show_all(); + window.show(); } -pub fn main(args: &[String]) { - let application = gtk::Application::new( - Some("fr.linkmauve.TabletEmu"), - gio::ApplicationFlags::empty(), - ) - .expect("Initialisation failed…"); - application.connect_activate(build_ui); - application.run(args); +pub fn main(_args: &[String]) { + let app = gtk::Application::builder() + .application_id("fr.linkmauve.TabletEmu") + .build(); + app.connect_activate(build_ui); + app.run(); } diff --git a/src/server.rs b/src/server.rs --- a/src/server.rs +++ b/src/server.rs @@ -92,7 +92,7 @@ pub fn run_server(address: &str) -> io:: let mut event: Event = Default::default(); let mut last = Some((0., 0.)); - state.set_size((320, 240)); + state.set_size(320, 240); loop { // TODO: Yolo-alignment. let buf: &mut [u8; 16] = unsafe { std::mem::transmute(&mut event) }; diff --git a/src/state.rs b/src/state.rs --- a/src/state.rs +++ b/src/state.rs @@ -46,7 +46,7 @@ impl State { }) } - pub fn set_size(&mut self, (width, height): (u32, u32)) { + pub fn set_size(&mut self, width: i32, height: i32) { self.width = width as f64; self.height = height as f64; }