Skip to content
Open
Changes from all 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
46 changes: 41 additions & 5 deletions editor/src/messages/tool/tool_messages/brush_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::messages::portfolio::document::node_graph::document_node_definitions:
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
use crate::messages::portfolio::document::utility_types::network_interface::{FlowType, InputConnector, OutputConnector};
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, selection_changed_since_last_sync, solid};
use crate::messages::tool::common_functionality::resize::viewport_zoom;
use graph_craft::document::value::TaggedValue;
use graph_craft::document::{NodeId, NodeInput};
use graphene_std::Color;
Expand All @@ -30,6 +31,7 @@ pub struct BrushOptions {
hardness: f64,
flow: f64,
color: ToolColorOptions,
autoscale: bool,
last_synced_selection: Vec<LayerNodeIdentifier>,
}

Expand All @@ -40,6 +42,7 @@ impl Default for BrushOptions {
hardness: BRUSH_HARDNESS_DEFAULT,
flow: BRUSH_FLOW_DEFAULT,
color: ToolColorOptions::default(),
autoscale: false,
last_synced_selection: Vec::new(),
}
}
Expand All @@ -49,6 +52,10 @@ impl BrushOptions {
fn active_color(&self) -> Color {
self.color.active_color().unwrap_or_default()
}

fn stroke_diameter(&self, document: &DocumentMessageHandler) -> f64 {
if self.autoscale { self.diameter / viewport_zoom(document) } else { self.diameter }
}
}

#[impl_message(Message, ToolMessage, Brush)]
Expand All @@ -75,6 +82,7 @@ pub enum BrushToolMessageOptionsUpdate {
Diameter(f64),
Hardness(f64),
Flow(f64),
Autoscale(bool),
WorkingColorsChanged,
}

Expand All @@ -99,6 +107,7 @@ impl ToolMetadata for BrushTool {

impl LayoutHolder for BrushTool {
fn layout(&self) -> Layout {
let autoscale_description = "Automatically scale the brush with viewport zoom.";
let widgets = vec![
ColorInput::new(FillChoice::<SRGBA8>::from(self.options.color.fill_choice.as_ref().unwrap_or(&FillChoice::None)))
.mixed(self.options.color.fill_choice.is_none())
Expand All @@ -122,6 +131,30 @@ impl LayoutHolder for BrushTool {
.into()
})
.widget_instance(),
PopoverButton::new()
.popover_layout(Layout(vec![LayoutGroup::row({
let checkbox_id = CheckboxId::new();
vec![
CheckboxInput::new(self.options.autoscale)
.tooltip_label("Autoscale")
.tooltip_description(autoscale_description)
.for_label(checkbox_id)
.on_update(|checkbox_input: &CheckboxInput| {
BrushToolMessage::UpdateOptions {
options: BrushToolMessageOptionsUpdate::Autoscale(checkbox_input.checked),
}
.into()
})
.widget_instance(),
TextLabel::new("Autoscale")
.tooltip_label("Autoscale")
.tooltip_description(autoscale_description)
.for_checkbox(checkbox_id)
.widget_instance(),
]
})]))
.tooltip_label("Diameter Options")
.widget_instance(),
Separator::new(SeparatorStyle::Related).widget_instance(),
NumberInput::new(Some(self.options.hardness))
.label("Hardness")
Expand Down Expand Up @@ -191,6 +224,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionMessageContext<'a>> for Brus
responses.add(ToolMessage::SelectWorkingColor { color, primary: true });
}
}
BrushToolMessageOptionsUpdate::Autoscale(autoscale) => self.options.autoscale = autoscale,
Comment thread
timon-schelling marked this conversation as resolved.
BrushToolMessageOptionsUpdate::WorkingColorsChanged => {
self.options.color.fill_choice = Some(solid(context.global_tool_data.primary_color));
}
Expand Down Expand Up @@ -235,7 +269,7 @@ impl BrushTool {
};
let value = |index: usize| node.inputs.get(index).and_then(|input| input.as_value());
if let Some(TaggedValue::F64(diameter)) = value(brush_strokes::DiameterInput::INDEX) {
self.options.diameter = *diameter;
self.options.diameter = if self.options.autoscale { *diameter * viewport_zoom(document) } else { *diameter };
}
if let Some(TaggedValue::F64(hardness)) = value(brush_strokes::HardnessInput::INDEX) {
self.options.hardness = *hardness;
Expand Down Expand Up @@ -352,8 +386,10 @@ impl BrushToolData {
};
let value = |index: usize| node.inputs.get(index).and_then(|input| input.as_value());
matches!(value(brush_strokes::ColorInput::INDEX), Some(TaggedValue::Color(color)) if *color == options.active_color())
&& matches!(value(brush_strokes::DiameterInput::INDEX), Some(TaggedValue::F64(diameter)) if *diameter == options.diameter)
&& matches!(value(brush_strokes::HardnessInput::INDEX), Some(TaggedValue::F64(hardness)) if *hardness == options.hardness)
&& matches!(value(brush_strokes::DiameterInput::INDEX), Some(TaggedValue::F64(diameter)) if {
let target = options.stroke_diameter(document);
(*diameter - target).abs() <= diameter.abs().max(target.abs()) * (f64::EPSILON * 8.)
}) && matches!(value(brush_strokes::HardnessInput::INDEX), Some(TaggedValue::F64(hardness)) if *hardness == options.hardness)
&& matches!(value(brush_strokes::FlowInput::INDEX), Some(TaggedValue::F64(flow)) if *flow == options.flow)
}

Expand Down Expand Up @@ -444,7 +480,7 @@ impl Fsm for BrushToolFsmState {
parent,
insert_index,
color: tool_options.active_color(),
diameter: tool_options.diameter,
diameter: tool_options.stroke_diameter(document),
hardness: tool_options.hardness,
flow: tool_options.flow,
});
Expand All @@ -458,7 +494,7 @@ impl Fsm for BrushToolFsmState {
layer,
strokes_node_id,
color: tool_options.active_color(),
diameter: tool_options.diameter,
diameter: tool_options.stroke_diameter(document),
hardness: tool_options.hardness,
flow: tool_options.flow,
});
Expand Down
Loading