Skip to content

Commit 90c91db

Browse files
committed
Disable the Brush tool by default and add it to preferences under experimental
1 parent 68a9bbc commit 90c91db

File tree

7 files changed

+114
-58
lines changed

7 files changed

+114
-58
lines changed

editor/src/messages/dialog/preferences_dialog/preferences_dialog_message_handler.rs

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ impl PreferencesDialogMessageHandler {
8989
.tooltip_label("Zoom with Scroll")
9090
.tooltip_description(zoom_with_scroll_description)
9191
.for_checkbox(checkbox_id)
92-
.table_align(true)
9392
.widget_instance(),
9493
];
9594

@@ -102,7 +101,10 @@ impl PreferencesDialogMessageHandler {
102101
let selection_label = vec![
103102
Separator::new(SeparatorType::Unrelated).widget_instance(),
104103
Separator::new(SeparatorType::Unrelated).widget_instance(),
105-
TextLabel::new("Selection").widget_instance(),
104+
TextLabel::new("Selection")
105+
.tooltip_label("Selection")
106+
.tooltip_description("Choose how targets are selected within dragged rectangular and lasso areas.")
107+
.widget_instance(),
106108
];
107109

108110
let selection_mode = RadioInput::new(vec![
@@ -151,7 +153,7 @@ impl PreferencesDialogMessageHandler {
151153

152154
let experimental_header = vec![TextLabel::new("Experimental").italic(true).widget_instance()];
153155

154-
let node_graph_section_description = "Appearance of the wires running between node connections in the graph.";
156+
let node_graph_section_description = "Configure the appearance of the wires running between node connections in the graph.";
155157
let node_graph_wires_label = vec![
156158
Separator::new(SeparatorType::Unrelated).widget_instance(),
157159
Separator::new(SeparatorType::Unrelated).widget_instance(),
@@ -181,13 +183,18 @@ impl PreferencesDialogMessageHandler {
181183
];
182184

183185
let checkbox_id = CheckboxId::new();
184-
let vello_description = "Use the experimental Vello renderer. (Your browser must support WebGPU).";
186+
let vello_description = "Use the experimental Vello renderer instead of SVG-based rendering.".to_string();
187+
#[cfg(target_family = "wasm")]
188+
let mut vello_description = vello_description;
189+
#[cfg(target_family = "wasm")]
190+
vello_description.push_str("\n\n(Your browser must support WebGPU.)");
191+
185192
let use_vello = vec![
186193
Separator::new(SeparatorType::Unrelated).widget_instance(),
187194
Separator::new(SeparatorType::Unrelated).widget_instance(),
188195
CheckboxInput::new(preferences.use_vello && preferences.supports_wgpu())
189196
.tooltip_label("Vello Renderer")
190-
.tooltip_description(vello_description)
197+
.tooltip_description(vello_description.clone())
191198
.disabled(!preferences.supports_wgpu())
192199
.on_update(|checkbox_input: &CheckboxInput| PreferencesMessage::UseVello { use_vello: checkbox_input.checked }.into())
193200
.for_label(checkbox_id)
@@ -197,14 +204,14 @@ impl PreferencesDialogMessageHandler {
197204
.tooltip_description(vello_description)
198205
.disabled(!preferences.supports_wgpu())
199206
.for_checkbox(checkbox_id)
200-
.table_align(true)
201207
.widget_instance(),
202208
];
203209

204210
let checkbox_id = CheckboxId::new();
205211
let vector_mesh_description = "
206-
Allow tools to produce vector meshes, where more than two segments can connect to an anchor point.\n\
207-
Currently this does not properly handle stroke joins and fills.
212+
Allow the Pen tool to produce branching geometry, where more than two segments may be connected to one anchor point.\n\
213+
\n\
214+
Currently, vector meshes do not properly render strokes (branching joins) and fills (multiple regions).
208215
"
209216
.trim();
210217
let vector_meshes = vec![
@@ -220,23 +227,58 @@ impl PreferencesDialogMessageHandler {
220227
.tooltip_label("Vector Meshes")
221228
.tooltip_description(vector_mesh_description)
222229
.for_checkbox(checkbox_id)
223-
.table_align(true)
230+
.widget_instance(),
231+
];
232+
233+
let checkbox_id = CheckboxId::new();
234+
let brush_tool_description = "
235+
Enable the Brush tool to support basic raster-based layer painting.\n\
236+
\n\
237+
This legacy tool has performance and quality limitations and is slated for replacement in future versions of Graphite that will focus on raster graphics editing.
238+
"
239+
.trim();
240+
let brush_tool = vec![
241+
Separator::new(SeparatorType::Unrelated).widget_instance(),
242+
Separator::new(SeparatorType::Unrelated).widget_instance(),
243+
CheckboxInput::new(preferences.brush_tool)
244+
.tooltip_label("Brush Tool")
245+
.tooltip_description(brush_tool_description)
246+
.on_update(|checkbox_input: &CheckboxInput| PreferencesMessage::BrushTool { enabled: checkbox_input.checked }.into())
247+
.for_label(checkbox_id)
248+
.widget_instance(),
249+
TextLabel::new("Brush Tool")
250+
.tooltip_label("Brush Tool")
251+
.tooltip_description(brush_tool_description)
252+
.for_checkbox(checkbox_id)
224253
.widget_instance(),
225254
];
226255

227256
Layout(vec![
257+
// NAVIGATION
228258
LayoutGroup::Row { widgets: navigation_header },
259+
// Navigation: Zoom Rate
229260
LayoutGroup::Row { widgets: zoom_rate_label },
230261
LayoutGroup::Row { widgets: zoom_rate },
262+
// Navigation: Zoom with Scroll
231263
LayoutGroup::Row { widgets: zoom_with_scroll },
264+
//
265+
// EDITING
232266
LayoutGroup::Row { widgets: editing_header },
267+
// Editing: Selection
233268
LayoutGroup::Row { widgets: selection_label },
234269
LayoutGroup::Row { widgets: selection_mode },
270+
//
271+
// EXPERIMENTAL
235272
LayoutGroup::Row { widgets: experimental_header },
273+
// Experimental: Node Graph Wires
236274
LayoutGroup::Row { widgets: node_graph_wires_label },
237275
LayoutGroup::Row { widgets: graph_wire_style },
276+
// Experimental: Vello Renderer
238277
LayoutGroup::Row { widgets: use_vello },
278+
// Experimental: Vector Meshes
239279
LayoutGroup::Row { widgets: vector_meshes },
280+
// Experimental: Brush Tool
281+
LayoutGroup::Row { widgets: brush_tool },
240282
])
241283
}
242284

editor/src/messages/preferences/preferences_message.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub enum PreferencesMessage {
1313
UseVello { use_vello: bool },
1414
SelectionMode { selection_mode: SelectionMode },
1515
VectorMeshes { enabled: bool },
16+
BrushTool { enabled: bool },
1617
ModifyLayout { zoom_with_scroll: bool },
1718
GraphWireStyle { style: GraphWireStyle },
1819
ViewportZoomWheelRate { rate: f64 },

editor/src/messages/preferences/preferences_message_handler.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub struct PreferencesMessageHandler {
1111
pub zoom_with_scroll: bool,
1212
pub use_vello: bool,
1313
pub vector_meshes: bool,
14+
pub brush_tool: bool,
1415
pub graph_wire_style: GraphWireStyle,
1516
pub viewport_zoom_wheel_rate: f64,
1617
}
@@ -38,6 +39,7 @@ impl Default for PreferencesMessageHandler {
3839
zoom_with_scroll: matches!(MappingVariant::default(), MappingVariant::ZoomWithScroll),
3940
use_vello: EditorPreferences::default().use_vello,
4041
vector_meshes: false,
42+
brush_tool: false,
4143
graph_wire_style: GraphWireStyle::default(),
4244
viewport_zoom_wheel_rate: VIEWPORT_ZOOM_WHEEL_RATE,
4345
}
@@ -76,6 +78,10 @@ impl MessageHandler<PreferencesMessage, ()> for PreferencesMessageHandler {
7678
PreferencesMessage::VectorMeshes { enabled } => {
7779
self.vector_meshes = enabled;
7880
}
81+
PreferencesMessage::BrushTool { enabled } => {
82+
self.brush_tool = enabled;
83+
responses.add(ToolMessage::RefreshToolShelf);
84+
}
7985
PreferencesMessage::ModifyLayout { zoom_with_scroll } => {
8086
self.zoom_with_scroll = zoom_with_scroll;
8187

editor/src/messages/tool/tool_message.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub enum ToolMessage {
7979
PreUndo,
8080
Redo,
8181
RefreshToolOptions,
82+
RefreshToolShelf,
8283
ResetColors,
8384
SelectWorkingColor {
8485
color: Color,

editor/src/messages/tool/tool_message_handler.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ impl MessageHandler<ToolMessage, ToolMessageContext<'_>> for ToolMessageHandler
101101
let tool_type = tool_type.get_tool();
102102

103103
responses.add(ToolMessage::RefreshToolOptions);
104-
tool_data.send_layout(responses, LayoutTarget::ToolShelf);
104+
responses.add(ToolMessage::RefreshToolShelf);
105105

106106
// Do nothing if switching to the same tool
107107
if self.tool_is_active && tool_type == old_tool {
@@ -176,7 +176,7 @@ impl MessageHandler<ToolMessage, ToolMessageContext<'_>> for ToolMessageHandler
176176
responses.add(ToolMessage::RefreshToolOptions);
177177

178178
// Notify the frontend about the new active tool to be displayed
179-
tool_data.send_layout(responses, LayoutTarget::ToolShelf);
179+
responses.add(ToolMessage::RefreshToolShelf);
180180
}
181181
ToolMessage::DeactivateTools => {
182182
let tool_data = &mut self.tool_state.tool_data;
@@ -220,7 +220,7 @@ impl MessageHandler<ToolMessage, ToolMessageContext<'_>> for ToolMessageHandler
220220
tool_data.tools.get(active_tool).unwrap().send_layout(responses, LayoutTarget::ToolOptions);
221221

222222
// Notify the frontend about the initial active tool
223-
tool_data.send_layout(responses, LayoutTarget::ToolShelf);
223+
tool_data.send_layout(responses, LayoutTarget::ToolShelf, preferences.brush_tool);
224224

225225
// Notify the frontend about the initial working colors
226226
document_data.update_working_colors(responses);
@@ -259,6 +259,10 @@ impl MessageHandler<ToolMessage, ToolMessageContext<'_>> for ToolMessageHandler
259259
let tool_data = &mut self.tool_state.tool_data;
260260
tool_data.tools.get(&tool_data.active_tool_type).unwrap().send_layout(responses, LayoutTarget::ToolOptions);
261261
}
262+
ToolMessage::RefreshToolShelf => {
263+
let tool_data = &mut self.tool_state.tool_data;
264+
tool_data.send_layout(responses, LayoutTarget::ToolShelf, preferences.brush_tool);
265+
}
262266
ToolMessage::ResetColors => {
263267
let document_data = &mut self.tool_state.document_tool_data;
264268

editor/src/messages/tool/utility_types.rs

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -231,31 +231,42 @@ impl ToolData {
231231
}
232232
}
233233

234-
impl LayoutHolder for ToolData {
235-
fn layout(&self) -> Layout {
234+
impl ToolData {
235+
pub fn send_layout(&self, responses: &mut VecDeque<Message>, layout_target: LayoutTarget, brush_tool: bool) {
236+
responses.add(LayoutMessage::SendLayout {
237+
layout: self.layout(brush_tool),
238+
layout_target,
239+
});
240+
}
241+
242+
fn layout(&self, brush_tool: bool) -> Layout {
236243
let active_tool = self.active_shape_type.unwrap_or(self.active_tool_type);
237244

238245
let tool_groups_layout = list_tools_in_groups()
239246
.iter()
240247
.map(|tool_group|
241248
tool_group
242249
.iter()
243-
.map(|tool_availability| {
244-
match tool_availability {
245-
ToolAvailability::Available(tool) =>
250+
.filter_map(|tool_availability| {
251+
if !brush_tool && let ToolRole::Normal(tool) = tool_availability && tool.tool_type() == ToolType::Brush {
252+
return None;
253+
}
254+
255+
Some(match tool_availability {
256+
ToolRole::Normal(tool) =>
246257
ToolEntry::new(tool.tool_type(), tool.icon_name())
247258
.tooltip_label(tool.tooltip_label())
248259
.tooltip_shortcut(action_shortcut!(tool_type_to_activate_tool_message(tool.tool_type()))),
249-
ToolAvailability::AvailableAsShape(shape) =>
260+
ToolRole::Shape(shape) =>
250261
ToolEntry::new(shape.tool_type(), shape.icon_name())
251262
.tooltip_label(shape.tooltip_label())
252263
.tooltip_description(shape.tooltip_description())
253264
.tooltip_shortcut(action_shortcut!(tool_type_to_activate_tool_message(shape.tool_type()))),
254-
// ToolAvailability::ComingSoon(tool) => tool.clone(),
255-
}
265+
})
256266
})
257267
.collect::<Vec<_>>()
258268
)
269+
.filter(|group| !group.is_empty())
259270
.flat_map(|group| {
260271
let separator = std::iter::once(Separator::new(SeparatorType::Section).direction(SeparatorDirection::Vertical).widget_instance());
261272
let buttons = group.into_iter().map(|ToolEntry { tooltip_label, tooltip_description, tooltip_shortcut, tool_type, icon_name }| {
@@ -319,9 +330,8 @@ impl Default for ToolFsmState {
319330
.into_iter()
320331
.flatten()
321332
.filter_map(|tool| match tool {
322-
ToolAvailability::Available(tool) => Some((tool.tool_type(), tool)),
323-
ToolAvailability::AvailableAsShape(_) => None,
324-
// ToolAvailability::ComingSoon(_) => None,
333+
ToolRole::Normal(tool) => Some((tool.tool_type(), tool)),
334+
ToolRole::Shape(_) => None,
325335
})
326336
.collect(),
327337
},
@@ -369,7 +379,6 @@ pub enum ToolType {
369379
Patch,
370380
Detail,
371381
Relight,
372-
Frame,
373382
}
374383

375384
impl ToolType {
@@ -385,58 +394,57 @@ impl ToolType {
385394
}
386395
}
387396

388-
enum ToolAvailability {
389-
Available(Box<Tool>),
390-
AvailableAsShape(ShapeType),
391-
// ComingSoon(ToolEntry),
397+
enum ToolRole {
398+
Normal(Box<Tool>),
399+
Shape(ShapeType),
392400
}
393401

394402
/// List of all the tools in their conventional ordering and grouping.
395-
fn list_tools_in_groups() -> Vec<Vec<ToolAvailability>> {
403+
fn list_tools_in_groups() -> Vec<Vec<ToolRole>> {
396404
vec![
397405
vec![
398406
// General tool group
399-
ToolAvailability::Available(Box::<select_tool::SelectTool>::default()),
400-
ToolAvailability::Available(Box::<artboard_tool::ArtboardTool>::default()),
401-
ToolAvailability::Available(Box::<navigate_tool::NavigateTool>::default()),
402-
ToolAvailability::Available(Box::<eyedropper_tool::EyedropperTool>::default()),
403-
ToolAvailability::Available(Box::<fill_tool::FillTool>::default()),
404-
ToolAvailability::Available(Box::<gradient_tool::GradientTool>::default()),
407+
ToolRole::Normal(Box::<select_tool::SelectTool>::default()),
408+
ToolRole::Normal(Box::<artboard_tool::ArtboardTool>::default()),
409+
ToolRole::Normal(Box::<navigate_tool::NavigateTool>::default()),
410+
ToolRole::Normal(Box::<eyedropper_tool::EyedropperTool>::default()),
411+
ToolRole::Normal(Box::<fill_tool::FillTool>::default()),
412+
ToolRole::Normal(Box::<gradient_tool::GradientTool>::default()),
405413
],
406414
vec![
407415
// Vector tool group
408-
ToolAvailability::Available(Box::<path_tool::PathTool>::default()),
409-
ToolAvailability::Available(Box::<pen_tool::PenTool>::default()),
410-
ToolAvailability::Available(Box::<freehand_tool::FreehandTool>::default()),
411-
ToolAvailability::Available(Box::<spline_tool::SplineTool>::default()),
412-
ToolAvailability::AvailableAsShape(ShapeType::Line),
413-
ToolAvailability::AvailableAsShape(ShapeType::Rectangle),
414-
ToolAvailability::AvailableAsShape(ShapeType::Ellipse),
415-
ToolAvailability::Available(Box::<shape_tool::ShapeTool>::default()),
416-
ToolAvailability::Available(Box::<text_tool::TextTool>::default()),
416+
ToolRole::Normal(Box::<path_tool::PathTool>::default()),
417+
ToolRole::Normal(Box::<pen_tool::PenTool>::default()),
418+
ToolRole::Normal(Box::<freehand_tool::FreehandTool>::default()),
419+
ToolRole::Normal(Box::<spline_tool::SplineTool>::default()),
420+
ToolRole::Shape(ShapeType::Line),
421+
ToolRole::Shape(ShapeType::Rectangle),
422+
ToolRole::Shape(ShapeType::Ellipse),
423+
ToolRole::Normal(Box::<shape_tool::ShapeTool>::default()),
424+
ToolRole::Normal(Box::<text_tool::TextTool>::default()),
417425
],
418426
vec![
419427
// Raster tool group
420-
ToolAvailability::Available(Box::<brush_tool::BrushTool>::default()),
421-
// ToolAvailability::ComingSoon(
428+
ToolRole::Normal(Box::<brush_tool::BrushTool>::default()),
429+
// ToolRole::Normal(
422430
// ToolEntry::new(ToolType::Heal, "RasterHealTool")
423431
// .tooltip_label("Heal Tool")
424432
// .tooltip_shortcut(action_shortcut_manual!(Key::KeyJ)),
425433
// ),
426-
// ToolAvailability::ComingSoon(
434+
// ToolRole::Normal(
427435
// ToolEntry::new(ToolType::Clone, "RasterCloneTool")
428436
// .tooltip_label("Clone Tool")
429437
// .tooltip_shortcut(action_shortcut_manual!(Key::KeyC)),
430438
// ),
431-
// ToolAvailability::ComingSoon(ToolEntry::new(ToolType::Patch, "RasterPatchTool")
439+
// ToolRole::Normal(ToolEntry::new(ToolType::Patch, "RasterPatchTool")
432440
// .tooltip_label("Patch Tool"),
433441
// ),
434-
// ToolAvailability::ComingSoon(
442+
// ToolRole::Normal(
435443
// ToolEntry::new(ToolType::Detail, "RasterDetailTool")
436444
// .tooltip_label("Detail Tool")
437445
// .tooltip_shortcut(action_shortcut_manual!(Key::KeyD)),
438446
// ),
439-
// ToolAvailability::ComingSoon(
447+
// ToolRole::Normal(
440448
// ToolEntry::new(ToolType::Relight, "RasterRelightTool")
441449
// .tooltip_label("Relight Tool")
442450
// .tooltip_shortcut(action_shortcut_manual!(Key::KeyO)),

frontend/src/components/panels/Document.svelte

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -304,14 +304,8 @@
304304
if (cursor === "custom-rotate") {
305305
const svg = `
306306
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="20" height="20">
307-
<path transform="translate(2 2)" fill="black" stroke="black" stroke-width="2px" d="
308-
M8,15.2C4,15.2,0.8,12,0.8,8C0.8,4,4,0.8,8,0.8c2,0,3.9,0.8,5.3,2.3l-1,1C11.2,2.9,9.6,2.2,8,2.2C4.8,2.2,2.2,4.8,2.2,8s2.6,5.8,5.8,5.8s5.8-2.6,5.8-5.8h1.4C15.2,12,12,15.2,8,15.2z
309-
" />
310-
<polygon transform="translate(2 2)" fill="black" stroke="black" stroke-width="2px" points="12.6,0 15.5,5 9.7,5" />
311-
<path transform="translate(2 2)" fill="white" d="
312-
M8,15.2C4,15.2,0.8,12,0.8,8C0.8,4,4,0.8,8,0.8c2,0,3.9,0.8,5.3,2.3l-1,1C11.2,2.9,9.6,2.2,8,2.2C4.8,2.2,2.2,4.8,2.2,8s2.6,5.8,5.8,5.8s5.8-2.6,5.8-5.8h1.4C15.2,12,12,15.2,8,15.2z
313-
" />
314-
<polygon transform="translate(2 2)" fill="white" points="12.6,0 15.5,5 9.7,5" />
307+
<path fill="none" stroke="black" stroke-width="2" d="M10,15.8c-3.2,0-5.8-2.6-5.8-5.8S6.8,4.2,10,4.2c0.999,0,1.999,0.273,2.877,0.771L11.7,7h5.8l-2.9-5l-1.013,1.746C12.5,3.125,11.271,2.8,10,2.8C6,2.8,2.8,6,2.8,10S6,17.2,10,17.2s7.2-3.2,7.2-7.2h-1.4C15.8,13.2,13.2,15.8,10,15.8z" />
308+
<path fill="white" d="M10,15.8c-3.2,0-5.8-2.6-5.8-5.8S6.8,4.2,10,4.2c0.999,0,1.999,0.273,2.877,0.771L11.7,7h5.8l-2.9-5l-1.013,1.746C12.5,3.125,11.271,2.8,10,2.8C6,2.8,2.8,6,2.8,10S6,17.2,10,17.2s7.2-3.2,7.2-7.2h-1.4C15.8,13.2,13.2,15.8,10,15.8z" />
315309
</svg>
316310
`
317311
.split("\n")

0 commit comments

Comments
 (0)