Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Lock tool style #1119

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/rnote-engine/src/pens/penholder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ impl PenHolder {
self.pen_mode_state = pen_mode_state;
}

/// mutable pen mode state
pub fn pen_mode_state_mut(&mut self) -> &mut PenModeState {
&mut self.pen_mode_state
}

pub fn backlog_policy(&self) -> BacklogPolicy {
self.backlog_policy
}
Expand Down
47 changes: 47 additions & 0 deletions crates/rnote-engine/src/pens/penmode.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::CloneConfig;
use std::cell::RefCell;

// Imports
use super::PenStyle;
Expand Down Expand Up @@ -28,6 +29,12 @@ pub struct PenModeState {
#[serde(rename = "penmode_eraser_style")]
penmode_eraser_style: PenStyle,

//lock styles
#[serde(rename = "lock_pen")]
penmode_pen_lock: bool,
#[serde(rename = "lock_eraser")]
penmode_eraser_lock: bool,

#[serde(skip)]
penmode_pen_style_override: Option<PenStyle>,
#[serde(skip)]
Expand All @@ -41,6 +48,9 @@ impl Default for PenModeState {
penmode_pen_style: PenStyle::Brush,
penmode_eraser_style: PenStyle::Eraser,

penmode_pen_lock: false,
penmode_eraser_lock: true,

penmode_pen_style_override: None,
penmode_eraser_style_override: None,
}
Expand All @@ -53,12 +63,35 @@ impl CloneConfig for PenModeState {
pen_mode: self.pen_mode,
penmode_pen_style: self.penmode_pen_style,
penmode_eraser_style: self.penmode_eraser_style,
penmode_pen_lock: self.penmode_pen_lock.clone(),
penmode_eraser_lock: self.penmode_eraser_lock.clone(),
..Default::default()
}
}
}

impl PenModeState {
pub fn get_lock(&self) -> bool {
match self.pen_mode {
PenMode::Pen => self.penmode_pen_lock,
PenMode::Eraser => self.penmode_eraser_lock,
}
}

pub fn unlock_pen(&mut self, pen_mode: PenMode) {
match pen_mode {
PenMode::Pen => self.penmode_pen_lock = false,
PenMode::Eraser => self.penmode_eraser_lock = false,
}
}

pub fn set_lock(&mut self, pen_mode: PenMode, state: bool) {
match pen_mode {
PenMode::Pen => self.penmode_pen_lock = state,
PenMode::Eraser => self.penmode_eraser_lock = state,
}
}

pub fn current_style_w_override(&self) -> PenStyle {
match self.pen_mode {
PenMode::Pen => self
Expand All @@ -82,6 +115,20 @@ impl PenModeState {
}
}

pub fn get_style(&self, penmode: PenMode) -> PenStyle {
match penmode {
PenMode::Pen => self.penmode_pen_style,
PenMode::Eraser => self.penmode_eraser_style,
}
}

pub fn set_style_single_mode(&mut self, mode: PenMode, style: PenStyle) {
match mode {
PenMode::Pen => self.penmode_pen_style = style,
PenMode::Eraser => self.penmode_eraser_style = style,
}
}

pub fn set_style(&mut self, style: PenStyle) {
match self.pen_mode {
PenMode::Pen => self.penmode_pen_style = style,
Expand Down
8 changes: 8 additions & 0 deletions crates/rnote-ui/data/app.gschema.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -169,5 +169,13 @@
<default>''</default>
<summary>the engine configuration</summary>
</key>
<key name="lock-pen" type="b">
<default>false</default>
<summary>lock the pen tool</summary>
</key>
<key name="lock-eraser" type="b">
<default>true</default>
<summary>lock the eraser tool</summary>
</key>
</schema>
</schemalist>
1 change: 1 addition & 0 deletions crates/rnote-ui/data/resources.gresource.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<file compressed="true" preprocess="xml-stripblanks">ui/overlays.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/penpicker.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/penshortcutrow.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/penmoderow.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/settingspanel.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/shortcuts.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/sidebar.ui</file>
Expand Down
11 changes: 11 additions & 0 deletions crates/rnote-ui/data/ui/penmoderow.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="RnPenModeRow" parent="AdwComboRow">
<child type="suffix">
<object class="GtkSwitch" id="mode">
<property name="halign">end</property>
<property name="valign">center</property>
</object>
</child>
</template>
</interface>
2 changes: 1 addition & 1 deletion crates/rnote-ui/data/ui/penpicker.ui
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</object>
</property>
<child>
<object class="GtkBox">
<object class="GtkBox" id="toolbox">
<property name="spacing">6</property>
<property name="width-request">350</property>
<property name="homogeneous">true</property>
Expand Down
35 changes: 34 additions & 1 deletion crates/rnote-ui/data/ui/settingspanel.ui
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,39 @@ on a drawing pad</property>
</child>
</object>
</child>
<!-- Lock settings for the pen/eraser-->
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Pen/Eraser mode</property>
<child>
<object class="RnPenModeRow" id="lock_pen_mode">
<property name="title" translatable="yes">Tool for the pen action</property>
<property name="subtitle" translatable="yes">Set/lock the action for the pen</property>
<!-- need to add an image for the pen -->
<child type="prefix">
<object class="GtkImage">
<property name="icon_name">drawing-pad-button-4-symbolic</property>
<property name="icon-size">large</property>
</object>
</child>
</object>
</child>
<child>
<object class="RnPenModeRow" id="lock_eraser_mode">
<!-- need to add the id -->
<property name="title" translatable="yes">Tool for the eraser action</property>
<property name="subtitle" translatable="yes">Set/lock the action for the pen</property>
<!-- need to add an image for the eraser -->
<child type="prefix">
<object class="GtkImage">
<property name="icon_name">drawing-pad-button-4-symbolic</property>
<property name="icon-size">large</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
Expand Down Expand Up @@ -552,4 +585,4 @@ on a drawing pad</property>
<property name="value">120</property>
</object>
</template>
</interface>
</interface>
25 changes: 21 additions & 4 deletions crates/rnote-ui/src/appwindow/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,13 +334,30 @@ impl RnAppWindow {
// don't change the style if the current style with override is already the same
// (e.g. when switched to from the pen button, not by clicking the pen page)
if pen_style != canvas.engine_ref().penholder.current_pen_style_w_override() {
let lock_out = canvas.engine_ref().penholder.pen_mode_state().get_lock();
let active_pen = canvas.engine_ref().penholder.pen_mode_state().pen_mode();
if lock_out {
// display a popup that can unlock the pen tool
appwindow.overlays().dispatch_toast_w_button_singleton(
&gettext("Tool Locked"),
&gettext("Unlock"), //padlock symbol ?
clone!(@weak canvas, @weak appwindow => move |_reload_toast | {
canvas.engine_mut().penholder.pen_mode_state_mut().unlock_pen(active_pen);
appwindow.sidebar().settings_panel().set_lock_state(active_pen,false);
appwindow.sidebar().settings_panel().refresh_ui(&appwindow.active_tab_wrapper());
}
)
, 2,
&mut None);
// refresh the ui
appwindow.refresh_ui_from_engine(&appwindow.active_tab_wrapper());
} else {
let mut widget_flags = canvas.engine_mut().change_pen_style(pen_style);
widget_flags |= canvas.engine_mut().change_pen_style_override(None);
appwindow.handle_widget_flags(widget_flags, &canvas);
}

action.set_state(&pen_style_str.to_variant());
}),
action.set_state(&pen_style_str.to_variant());
}
}}),
);

// Tab actions
Expand Down
12 changes: 12 additions & 0 deletions crates/rnote-ui/src/appwindow/appsettings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ impl RnAppWindow {
.get_no_changes()
.build();

// lock pen tool
app_settings
.bind("lock-pen", self, "lock-pen")
.get_no_changes()
.build();

// lock eraser tool
app_settings
.bind("lock-eraser", self, "lock-eraser")
.get_no_changes()
.build();

// colorpicker palette
let gdk_color_mapping = |var: &glib::Variant, _: glib::Type| {
let color = var.get::<(f64, f64, f64, f64)>()?;
Expand Down
22 changes: 22 additions & 0 deletions crates/rnote-ui/src/appwindow/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub(crate) struct RnAppWindow {
pub(crate) touch_drawing: Cell<bool>,
pub(crate) focus_mode: Cell<bool>,

pub(crate) lock_pen: Cell<bool>,
pub(crate) lock_eraser: Cell<bool>,

#[template_child]
pub(crate) main_header: TemplateChild<RnMainHeader>,
#[template_child]
Expand Down Expand Up @@ -52,6 +55,9 @@ impl Default for RnAppWindow {
touch_drawing: Cell::new(false),
focus_mode: Cell::new(false),

lock_pen: Cell::new(false),
lock_eraser: Cell::new(false),

main_header: TemplateChild::<RnMainHeader>::default(),
split_view: TemplateChild::<adw::OverlaySplitView>::default(),
sidebar: TemplateChild::<RnSidebar>::default(),
Expand Down Expand Up @@ -135,6 +141,12 @@ impl ObjectImpl for RnAppWindow {
glib::ParamSpecBoolean::builder("focus-mode")
.default_value(false)
.build(),
glib::ParamSpecBoolean::builder("lock-pen")
.default_value(false)
.build(),
glib::ParamSpecBoolean::builder("lock-eraser")
.default_value(false)
.build(),
]
});
PROPERTIES.as_ref()
Expand All @@ -149,6 +161,8 @@ impl ObjectImpl for RnAppWindow {
"respect-borders" => self.respect_borders.get().to_value(),
"touch-drawing" => self.touch_drawing.get().to_value(),
"focus-mode" => self.focus_mode.get().to_value(),
"lock-pen" => self.lock_pen.get().to_value(),
"lock-eraser" => self.lock_eraser.get().to_value(),
_ => unimplemented!(),
}
}
Expand Down Expand Up @@ -212,6 +226,14 @@ impl ObjectImpl for RnAppWindow {
self.overlays.colorpicker().set_visible(!focus_mode);
self.overlays.sidebar_box().set_visible(!focus_mode);
}
"lock-pen" => {
let lock_pen: bool = value.get().expect("The value needs to be of type `bool`");
self.lock_pen.replace(lock_pen);
}
"lock-eraser" => {
let lock_eraser: bool = value.get().expect("The value needs to be of type `bool`");
self.lock_eraser.replace(lock_eraser);
}
_ => unimplemented!(),
}
}
Expand Down
10 changes: 10 additions & 0 deletions crates/rnote-ui/src/appwindow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ impl RnAppWindow {
self.property::<bool>("respect-borders")
}

#[allow(unused)]
pub(crate) fn lock_pen(&self) -> bool {
self.property::<bool>("lock-pen")
}

#[allow(unused)]
pub(crate) fn lock_eraser(&self) -> bool {
self.property::<bool>("lock-eraser")
}

pub(crate) fn app(&self) -> RnApp {
self.application().unwrap().downcast::<RnApp>().unwrap()
}
Expand Down
39 changes: 36 additions & 3 deletions crates/rnote-ui/src/penpicker.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
// Imports
use crate::RnAppWindow;
use gtk4::{
glib, glib::clone, prelude::*, subclass::prelude::*, Button, CompositeTemplate, TemplateChild,
ToggleButton, Widget,
gdk, glib, glib::clone, prelude::*, subclass::prelude::*, Box, Button, CompositeTemplate,
EventControllerLegacy, PropagationPhase, TemplateChild, ToggleButton, Widget,
};
use rnote_engine::pens::PenStyle;
use rnote_engine::pens::{PenMode, PenStyle};
use rnote_engine::WidgetFlags;

mod imp {
use super::*;

#[derive(Default, Debug, CompositeTemplate)]
#[template(resource = "/com/github/flxzt/rnote/ui/penpicker.ui")]
pub(crate) struct RnPenPicker {
#[template_child]
pub(crate) toolbox: TemplateChild<Box>,
#[template_child]
pub(crate) brush_toggle: TemplateChild<ToggleButton>,
#[template_child]
Expand Down Expand Up @@ -108,6 +111,36 @@ impl RnPenPicker {
pub(crate) fn init(&self, appwindow: &RnAppWindow) {
let imp = self.imp();

// create an event controller
let pointer_controller = EventControllerLegacy::builder()
.name("pointer_controller_toolbar")
.propagation_phase(PropagationPhase::Bubble)
.build();

pointer_controller.connect_event(clone!(@weak appwindow => @default-return glib::Propagation::Proceed, move |_,event| {
let mut widget_flags = WidgetFlags::default();
let is_stylus = event.device_tool().is_some();
if is_stylus {
let device_tool = event.device_tool().unwrap();
match device_tool.tool_type() {
gdk::DeviceToolType::Pen => {
// switch the canvas to the pen
widget_flags |= appwindow.active_tab_wrapper().canvas().engine_mut().change_pen_mode(PenMode::Pen);
},
gdk::DeviceToolType::Eraser => {
// switch the canvas to the eraser
widget_flags |= appwindow.active_tab_wrapper().canvas().engine_mut().change_pen_mode(PenMode::Eraser);

},
_ => (),
}
}
appwindow.active_tab_wrapper().canvas().emit_handle_widget_flags(widget_flags);
return glib::Propagation::Proceed
}));

imp.toolbox.add_controller(pointer_controller);

imp.brush_toggle
.connect_toggled(clone!(@weak appwindow => move |brush_toggle| {
if brush_toggle.is_active() {
Expand Down
Loading