Add a pivot widget to selected layer(s) to control the origin(s) (#772)

* Add pivot

* Add dragging pivot

* Cleanup

* Remove tabs

* Fix multiplication order

* Restyle pivot

* Add move cursor icon

* Update pivot size

* Code review tweaks

* Fix alt with non-centred pivot

* Comment for add one

* Pivot sets layer panel origin

* Tweek alt centre thing

* Fix division by zero case

* Add pivot dots to properties

* FIx some typos

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
0HyperCube
2022-08-30 22:36:33 +01:00
committed by Keavon Chambers
co-authored by Keavon Chambers
parent 0f6f3be6e7
commit 1e109dc552
13 changed files with 360 additions and 37 deletions
@@ -1,4 +1,5 @@
use super::utility_types::TransformOp;
use crate::messages::layout::utility_types::widgets::assist_widgets::PivotPosition;
use crate::messages::portfolio::document::utility_types::misc::TargetDocument;
use crate::messages::prelude::*;
@@ -25,5 +26,6 @@ pub enum PropertiesPanelMessage {
ModifyTransform { value: f64, transform_op: TransformOp },
ResendActiveProperties,
SetActiveLayers { paths: Vec<Vec<LayerId>>, document: TargetDocument },
SetPivot { new_position: PivotPosition },
UpdateSelectedDocumentProperties,
}
@@ -101,6 +101,13 @@ impl<'a> MessageHandler<PropertiesPanelMessage, PropertiesPanelMessageHandlerDat
let (path, _) = self.active_selection.clone().expect("Received update for properties panel with no active layer");
responses.push_back(Operation::SetTextContent { path, new_text }.into())
}
SetPivot { new_position } => {
let (layer_path, _) = self.active_selection.clone().expect("Received update for properties panel with no active layer");
let position: Option<glam::DVec2> = new_position.into();
let pivot = position.unwrap().into();
responses.push_back(Operation::SetPivot { layer_path, pivot }.into());
}
CheckSelectedWasUpdated { path } => {
if self.matches_selected(&path) {
responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into())
@@ -1,6 +1,7 @@
use super::utility_types::TransformOp;
use crate::messages::layout::utility_types::layout_widget::{Layout, LayoutGroup, Widget, WidgetCallback, WidgetHolder, WidgetLayout};
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widgets::assist_widgets::PivotAssist;
use crate::messages::layout::utility_types::widgets::button_widgets::PopoverButton;
use crate::messages::layout::utility_types::widgets::input_widgets::{ColorInput, FontInput, NumberInput, RadioEntryData, RadioInput, TextAreaInput, TextInput};
use crate::messages::layout::utility_types::widgets::label_widgets::{IconLabel, IconStyle, Separator, SeparatorDirection, SeparatorType, TextLabel};
@@ -80,6 +81,7 @@ pub fn register_artboard_layer_properties(layer: &Layer, responses: &mut VecDequ
} else {
panic!("Artboard must have a solid fill")
};
let pivot = layer.transform.transform_vector2(layer.layerspace_pivot(font_cache));
vec![LayoutGroup::Section {
name: "Artboard".into(),
@@ -95,12 +97,12 @@ pub fn register_artboard_layer_properties(layer: &Layer, responses: &mut VecDequ
direction: SeparatorDirection::Horizontal,
})),
WidgetHolder::new(Widget::NumberInput(NumberInput {
value: Some(layer.transform.x()),
value: Some(layer.transform.x() + pivot.x),
label: "X".into(),
unit: " px".into(),
on_update: WidgetCallback::new(|number_input: &NumberInput| {
on_update: WidgetCallback::new(move |number_input: &NumberInput| {
PropertiesPanelMessage::ModifyTransform {
value: number_input.value.unwrap(),
value: number_input.value.unwrap() - pivot.x,
transform_op: TransformOp::X,
}
.into()
@@ -112,12 +114,12 @@ pub fn register_artboard_layer_properties(layer: &Layer, responses: &mut VecDequ
direction: SeparatorDirection::Horizontal,
})),
WidgetHolder::new(Widget::NumberInput(NumberInput {
value: Some(layer.transform.y()),
value: Some(layer.transform.y() + pivot.y),
label: "Y".into(),
unit: " px".into(),
on_update: WidgetCallback::new(|number_input: &NumberInput| {
on_update: WidgetCallback::new(move |number_input: &NumberInput| {
PropertiesPanelMessage::ModifyTransform {
value: number_input.value.unwrap(),
value: number_input.value.unwrap() - pivot.y,
transform_op: TransformOp::Y,
}
.into()
@@ -308,6 +310,7 @@ pub fn register_artwork_layer_properties(layer: &Layer, responses: &mut VecDeque
}
fn node_section_transform(layer: &Layer, font_cache: &FontCache) -> LayoutGroup {
let pivot = layer.transform.transform_vector2(layer.layerspace_pivot(font_cache));
LayoutGroup::Section {
name: "Transform".into(),
layout: vec![
@@ -317,17 +320,25 @@ fn node_section_transform(layer: &Layer, font_cache: &FontCache) -> LayoutGroup
value: "Location".into(),
..TextLabel::default()
})),
WidgetHolder::new(Widget::Separator(Separator {
separator_type: SeparatorType::Related,
direction: SeparatorDirection::Horizontal,
})),
WidgetHolder::new(Widget::PivotAssist(PivotAssist {
position: layer.pivot.into(),
on_update: WidgetCallback::new(|pivot_assist: &PivotAssist| PropertiesPanelMessage::SetPivot { new_position: pivot_assist.position }.into()),
})),
WidgetHolder::new(Widget::Separator(Separator {
separator_type: SeparatorType::Unrelated,
direction: SeparatorDirection::Horizontal,
})),
WidgetHolder::new(Widget::NumberInput(NumberInput {
value: Some(layer.transform.x()),
value: Some(layer.transform.x() + pivot.x),
label: "X".into(),
unit: " px".into(),
on_update: WidgetCallback::new(|number_input: &NumberInput| {
on_update: WidgetCallback::new(move |number_input: &NumberInput| {
PropertiesPanelMessage::ModifyTransform {
value: number_input.value.unwrap(),
value: number_input.value.unwrap() - pivot.x,
transform_op: TransformOp::X,
}
.into()
@@ -339,12 +350,12 @@ fn node_section_transform(layer: &Layer, font_cache: &FontCache) -> LayoutGroup
direction: SeparatorDirection::Horizontal,
})),
WidgetHolder::new(Widget::NumberInput(NumberInput {
value: Some(layer.transform.y()),
value: Some(layer.transform.y() + pivot.y),
label: "Y".into(),
unit: " px".into(),
on_update: WidgetCallback::new(|number_input: &NumberInput| {
on_update: WidgetCallback::new(move |number_input: &NumberInput| {
PropertiesPanelMessage::ModifyTransform {
value: number_input.value.unwrap(),
value: number_input.value.unwrap() - pivot.y,
transform_op: TransformOp::Y,
}
.into()