mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-20 03:18:06 +08:00
Options bar widgets for tools to control tool behavior (#283)
* Add JSON-backed options widget
* Add initial tool settings messaging to backend
* Add shape side selection with JSON deserialization
* Enforce minimum number of n-gon sides
* Make tool settings JSON errors safer
* Make tool settings JSON errors safer
* Refactor ToolOptions to ToolSettings
* Revert "Refactor ToolOptions to ToolSettings"
This reverts commit 651161fd16.
* Refactor all instances of "settings" to "options"
* Fix names and formatting
* Rearrange ToolOptions data to enforce types
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
pub mod tool_message_handler;
|
||||
pub mod tool_settings;
|
||||
pub mod tool_options;
|
||||
pub mod tools;
|
||||
|
||||
use crate::document::Document;
|
||||
@@ -15,8 +15,8 @@ use std::{
|
||||
fmt::{self, Debug},
|
||||
};
|
||||
pub use tool_message_handler::ToolMessageHandler;
|
||||
use tool_settings::ToolSettings;
|
||||
pub use tool_settings::*;
|
||||
use tool_options::ToolOptions;
|
||||
pub use tool_options::*;
|
||||
use tools::*;
|
||||
|
||||
pub mod tool_messages {
|
||||
@@ -37,7 +37,7 @@ pub trait Fsm {
|
||||
pub struct DocumentToolData {
|
||||
pub primary_color: Color,
|
||||
pub secondary_color: Color,
|
||||
tool_settings: HashMap<ToolType, ToolSettings>,
|
||||
pub tool_options: HashMap<ToolType, ToolOptions>,
|
||||
}
|
||||
|
||||
type SubToolMessageHandler = dyn for<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>>;
|
||||
@@ -48,7 +48,7 @@ pub struct ToolData {
|
||||
|
||||
impl fmt::Debug for ToolData {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("ToolData").field("active_tool_type", &self.active_tool_type).field("tool_settings", &"[…]").finish()
|
||||
f.debug_struct("ToolData").field("active_tool_type", &self.active_tool_type).field("tool_options", &"[…]").finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ impl Default for ToolFsmState {
|
||||
document_tool_data: DocumentToolData {
|
||||
primary_color: Color::BLACK,
|
||||
secondary_color: Color::WHITE,
|
||||
tool_settings: default_tool_settings(),
|
||||
tool_options: default_tool_options(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -105,8 +105,8 @@ impl ToolFsmState {
|
||||
}
|
||||
}
|
||||
|
||||
fn default_tool_settings() -> HashMap<ToolType, ToolSettings> {
|
||||
let tool_init = |tool: ToolType| (tool, tool.default_settings());
|
||||
fn default_tool_options() -> HashMap<ToolType, ToolOptions> {
|
||||
let tool_init = |tool: ToolType| (tool, tool.default_options());
|
||||
std::array::IntoIter::new([
|
||||
tool_init(ToolType::Select),
|
||||
tool_init(ToolType::Ellipse),
|
||||
@@ -174,12 +174,12 @@ impl fmt::Display for ToolType {
|
||||
}
|
||||
|
||||
impl ToolType {
|
||||
fn default_settings(&self) -> ToolSettings {
|
||||
fn default_options(&self) -> ToolOptions {
|
||||
match self {
|
||||
ToolType::Select => ToolSettings::Select { append_mode: SelectAppendMode::New },
|
||||
ToolType::Ellipse => ToolSettings::Ellipse,
|
||||
ToolType::Shape => ToolSettings::Shape {
|
||||
shape: Shape::Polygon { vertices: 3 },
|
||||
ToolType::Select => ToolOptions::Select { append_mode: SelectAppendMode::New },
|
||||
ToolType::Ellipse => ToolOptions::Ellipse,
|
||||
ToolType::Shape => ToolOptions::Shape {
|
||||
shape_type: ShapeType::Polygon { vertices: 6 },
|
||||
},
|
||||
_ => todo!(),
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use document_core::color::Color;
|
||||
use crate::input::InputPreprocessor;
|
||||
use crate::{
|
||||
document::Document,
|
||||
tool::{ToolFsmState, ToolType},
|
||||
tool::{tool_options::ToolOptions, ToolFsmState, ToolType},
|
||||
};
|
||||
use std::collections::VecDeque;
|
||||
|
||||
@@ -16,6 +16,7 @@ pub enum ToolMessage {
|
||||
SelectSecondaryColor(Color),
|
||||
SwapColors,
|
||||
ResetColors,
|
||||
SetToolOptions(ToolType, ToolOptions),
|
||||
#[child]
|
||||
Fill(FillMessage),
|
||||
#[child]
|
||||
@@ -89,6 +90,9 @@ impl MessageHandler<ToolMessage, (&Document, &InputPreprocessor)> for ToolMessag
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
SetToolOptions(tool_type, tool_options) => {
|
||||
self.tool_state.document_tool_data.tool_options.insert(tool_type, tool_options);
|
||||
}
|
||||
message => {
|
||||
let tool_type = match message {
|
||||
Fill(_) => ToolType::Fill,
|
||||
@@ -111,7 +115,7 @@ impl MessageHandler<ToolMessage, (&Document, &InputPreprocessor)> for ToolMessag
|
||||
}
|
||||
}
|
||||
fn actions(&self) -> ActionList {
|
||||
let mut list = actions!(ToolMessageDiscriminant; ResetColors, SwapColors, SelectTool);
|
||||
let mut list = actions!(ToolMessageDiscriminant; ResetColors, SwapColors, SelectTool, SetToolOptions);
|
||||
list.extend(self.tool_state.tool_data.active_tool().actions());
|
||||
list
|
||||
}
|
||||
|
||||
22
core/editor/src/tool/tool_options.rs
Normal file
22
core/editor/src/tool/tool_options.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ToolOptions {
|
||||
Select { append_mode: SelectAppendMode },
|
||||
Ellipse,
|
||||
Shape { shape_type: ShapeType },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub enum SelectAppendMode {
|
||||
New,
|
||||
Add,
|
||||
Subtract,
|
||||
Intersect,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ShapeType {
|
||||
Star { vertices: u32 },
|
||||
Polygon { vertices: u32 },
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum ToolSettings {
|
||||
Select { append_mode: SelectAppendMode },
|
||||
Ellipse,
|
||||
Shape { shape: Shape },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum SelectAppendMode {
|
||||
New,
|
||||
Add,
|
||||
Subtract,
|
||||
Intersect,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum Shape {
|
||||
Star { vertices: u32 },
|
||||
Polygon { vertices: u32 },
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::input::{mouse::ViewportPosition, InputPreprocessor};
|
||||
use crate::tool::{DocumentToolData, Fsm, ToolActionHandlerData};
|
||||
use crate::tool::{DocumentToolData, Fsm, ShapeType, ToolActionHandlerData, ToolOptions, ToolType};
|
||||
use crate::{document::Document, message_prelude::*};
|
||||
use document_core::{layers::style, Operation};
|
||||
use glam::{DAffine2, DVec2};
|
||||
@@ -70,7 +70,12 @@ impl Fsm for ShapeToolFsmState {
|
||||
data.drag_start = input.mouse.position;
|
||||
data.drag_current = input.mouse.position;
|
||||
|
||||
data.sides = 6;
|
||||
data.sides = match tool_data.tool_options.get(&ToolType::Shape) {
|
||||
Some(&ToolOptions::Shape {
|
||||
shape_type: ShapeType::Polygon { vertices },
|
||||
}) => vertices as u8,
|
||||
_ => 6,
|
||||
};
|
||||
|
||||
responses.push_back(Operation::MountWorkingFolder { path: vec![] }.into());
|
||||
Dragging
|
||||
|
||||
Reference in New Issue
Block a user