Skip to content

Commit

Permalink
Merge branch 'master' into add-mirror-node
Browse files Browse the repository at this point in the history
  • Loading branch information
skoriop committed Mar 1, 2024
2 parents e9f65fd + 70dce1c commit 9b9a7c6
Show file tree
Hide file tree
Showing 33 changed files with 307 additions and 165 deletions.
3 changes: 3 additions & 0 deletions editor/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ pub const VIEWPORT_ROTATE_SNAP_INTERVAL: f64 = 15.;

pub const VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR: f64 = 0.95;

pub const DRAG_BEYOND_VIEWPORT_MAX_OVEREXTENSION_PIXELS: f64 = 50.;
pub const DRAG_BEYOND_VIEWPORT_SPEED_FACTOR: f64 = 0.5;

// Snapping point
pub const SNAP_POINT_TOLERANCE: f64 = 5.;

Expand Down
2 changes: 1 addition & 1 deletion editor/src/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ mod test {

let responses = editor.handle_message(PortfolioMessage::OpenDocumentFile {
document_name: document_name.into(),
document_serialized_content: document_serialized_content.into(),
document_serialized_content,
});

for response in responses {
Expand Down
1 change: 1 addition & 0 deletions editor/src/messages/broadcast/broadcast_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize, Hash)]
#[impl_message(Message, BroadcastMessage, TriggerEvent)]
pub enum BroadcastEvent {
AnimationFrame,
CanvasTransformed,
ToolAbort,
SelectionChanged,
Expand Down
37 changes: 17 additions & 20 deletions editor/src/messages/input_mapper/default_mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
use crate::messages::prelude::*;
use crate::messages::tool::tool_messages::brush_tool::BrushToolMessageOptionsUpdate;
use crate::messages::tool::tool_messages::select_tool::SelectToolPointerKeys;

use glam::DVec2;

Expand Down Expand Up @@ -68,10 +69,10 @@ pub fn default_mapping() -> Mapping {
entry!(KeyDown(Minus); action_dispatch=TransformLayerMessage::TypeNegate),
entry!(KeyDown(Comma); action_dispatch=TransformLayerMessage::TypeDecimalPoint),
entry!(KeyDown(Period); action_dispatch=TransformLayerMessage::TypeDecimalPoint),
entry!(PointerMove; refresh_keys=[Shift, Control], action_dispatch=TransformLayerMessage::PointerMove { slow_key: Shift, snap_key: Control }),
entry!(PointerMove; refresh_keys=[Control, Shift], action_dispatch=TransformLayerMessage::PointerMove { slow_key: Shift, snap_key: Control }),
//
// SelectToolMessage
entry!(PointerMove; refresh_keys=[Control, Shift, Alt], action_dispatch=SelectToolMessage::PointerMove { axis_align: Shift, snap_angle: Control, center: Alt, duplicate: Alt }),
entry!(PointerMove; refresh_keys=[Control, Alt, Shift], action_dispatch=SelectToolMessage::PointerMove(SelectToolPointerKeys { axis_align: Shift, snap_angle: Control, center: Alt, duplicate: Alt })),
entry!(KeyDown(Lmb); action_dispatch=SelectToolMessage::DragStart { add_to_selection: Shift, select_deepest: Accel }),
entry!(KeyUp(Lmb); action_dispatch=SelectToolMessage::DragStop { remove_from_selection: Shift }),
entry!(KeyDown(Enter); action_dispatch=SelectToolMessage::Enter),
Expand Down Expand Up @@ -174,7 +175,7 @@ pub fn default_mapping() -> Mapping {
entry!(KeyUp(Lmb); action_dispatch=LineToolMessage::DragStop),
entry!(KeyDown(Rmb); action_dispatch=LineToolMessage::Abort),
entry!(KeyDown(Escape); action_dispatch=LineToolMessage::Abort),
entry!(PointerMove; refresh_keys=[Alt, Control, Shift], action_dispatch=LineToolMessage::PointerMove { center: Alt, lock_angle: Control, snap_angle: Shift }),
entry!(PointerMove; refresh_keys=[Control, Alt, Shift], action_dispatch=LineToolMessage::PointerMove { center: Alt, lock_angle: Control, snap_angle: Shift }),
//
// PathToolMessage
entry!(KeyDown(Delete); modifiers=[Accel], action_dispatch=PathToolMessage::DeleteAndBreakPath),
Expand Down Expand Up @@ -222,7 +223,7 @@ pub fn default_mapping() -> Mapping {
entry!(KeyDown(ArrowDown); modifiers=[Shift, ArrowRight], action_dispatch=PathToolMessage::NudgeSelectedPoints { delta_x: BIG_NUDGE_AMOUNT, delta_y: BIG_NUDGE_AMOUNT }),
//
// PenToolMessage
entry!(PointerMove; refresh_keys=[Shift, Control], action_dispatch=PenToolMessage::PointerMove { snap_angle: Shift, break_handle: Alt, lock_angle: Control}),
entry!(PointerMove; refresh_keys=[Control, Shift], action_dispatch=PenToolMessage::PointerMove { snap_angle: Shift, break_handle: Alt, lock_angle: Control}),
entry!(KeyDown(Lmb); action_dispatch=PenToolMessage::DragStart),
entry!(KeyUp(Lmb); action_dispatch=PenToolMessage::DragStop),
entry!(KeyDown(Rmb); action_dispatch=PenToolMessage::Confirm),
Expand Down Expand Up @@ -268,7 +269,7 @@ pub fn default_mapping() -> Mapping {
entry!(KeyDown(KeyE); action_dispatch=ToolMessage::ActivateToolEllipse),
entry!(KeyDown(KeyY); action_dispatch=ToolMessage::ActivateToolPolygon),
entry!(KeyDown(KeyB); action_dispatch=ToolMessage::ActivateToolBrush),
entry!(KeyDown(KeyX); modifiers=[Shift, Accel], action_dispatch=ToolMessage::ResetColors),
entry!(KeyDown(KeyX); modifiers=[Accel, Shift], action_dispatch=ToolMessage::ResetColors),
entry!(KeyDown(KeyX); modifiers=[Shift], action_dispatch=ToolMessage::SwapColors),
entry!(KeyDown(KeyC); modifiers=[Alt], action_dispatch=ToolMessage::SelectRandomPrimaryColor),
//
Expand Down Expand Up @@ -325,6 +326,16 @@ pub fn default_mapping() -> Mapping {
entry!(KeyDown(KeyG); action_dispatch=TransformLayerMessage::BeginGrab),
entry!(KeyDown(KeyR); action_dispatch=TransformLayerMessage::BeginRotate),
entry!(KeyDown(KeyS); action_dispatch=TransformLayerMessage::BeginScale),
entry!(KeyDown(Digit0); action_dispatch=TransformLayerMessage::TypeDigit { digit: 0 }),
entry!(KeyDown(Digit1); action_dispatch=TransformLayerMessage::TypeDigit { digit: 1 }),
entry!(KeyDown(Digit2); action_dispatch=TransformLayerMessage::TypeDigit { digit: 2 }),
entry!(KeyDown(Digit3); action_dispatch=TransformLayerMessage::TypeDigit { digit: 3 }),
entry!(KeyDown(Digit4); action_dispatch=TransformLayerMessage::TypeDigit { digit: 4 }),
entry!(KeyDown(Digit5); action_dispatch=TransformLayerMessage::TypeDigit { digit: 5 }),
entry!(KeyDown(Digit6); action_dispatch=TransformLayerMessage::TypeDigit { digit: 6 }),
entry!(KeyDown(Digit7); action_dispatch=TransformLayerMessage::TypeDigit { digit: 7 }),
entry!(KeyDown(Digit8); action_dispatch=TransformLayerMessage::TypeDigit { digit: 8 }),
entry!(KeyDown(Digit9); action_dispatch=TransformLayerMessage::TypeDigit { digit: 9 }),
//
// NavigationMessage
entry!(KeyDown(Mmb); modifiers=[Alt], action_dispatch=NavigationMessage::RotateCanvasBegin { was_dispatched_from_menu: false }),
Expand Down Expand Up @@ -374,19 +385,6 @@ pub fn default_mapping() -> Mapping {
];
let (mut key_up, mut key_down, mut key_up_no_repeat, mut key_down_no_repeat, mut double_click, mut wheel_scroll, mut pointer_move) = mappings;

// TODO: Hardcode these 10 lines into 10 lines of declarations, or make this use a macro to do all 10 in one line
const NUMBER_KEYS: [Key; 10] = [Digit0, Digit1, Digit2, Digit3, Digit4, Digit5, Digit6, Digit7, Digit8, Digit9];
for (i, key) in NUMBER_KEYS.iter().enumerate() {
key_down[*key as usize].0.insert(
0,
MappingEntry {
action: TransformLayerMessage::TypeDigit { digit: i as u8 }.into(),
input: InputMapperMessage::KeyDown(*key),
modifiers: modifiers!(),
},
);
}

let sort = |list: &mut KeyMappingEntries| list.0.sort_by(|u, v| v.modifiers.ones().cmp(&u.modifiers.ones()));
for list in [&mut key_up, &mut key_down, &mut key_up_no_repeat, &mut key_down_no_repeat] {
for sublist in list {
Expand All @@ -410,9 +408,8 @@ pub fn default_mapping() -> Mapping {
}
}

/// Defaults except that scrolling without modifiers is bound to zooming instead of vertical panning
/// Default mappings except that scrolling without modifier keys held down is bound to zooming instead of vertical panning
pub fn zoom_with_scroll() -> Mapping {
// TODO(multisn8): for other keymaps this patterns might be useful
use InputMapperMessage::*;

let mut mapping = default_mapping();
Expand Down
27 changes: 20 additions & 7 deletions editor/src/messages/input_mapper/input_mapper_message_handler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::utility_types::input_keyboard::KeysGroup;
use super::utility_types::misc::Mapping;
use crate::messages::input_mapper::utility_types::input_keyboard::{self, Key};
use crate::messages::portfolio::utility_types::KeyboardPlatformLayout;
use crate::messages::prelude::*;

use std::fmt::Write;
Expand Down Expand Up @@ -59,10 +60,17 @@ impl InputMapperMessageHandler {
// Filter for the desired message
let found_actions = all_mapping_entries.filter(|entry| entry.action.to_discriminant() == *action_to_find);

let keyboard_layout = || GLOBAL_PLATFORM.get().copied().unwrap_or_default().as_keyboard_platform_layout();
let platform_accel_key = match keyboard_layout() {
KeyboardPlatformLayout::Standard => Key::Control,
KeyboardPlatformLayout::Mac => Key::Command,
};

// Find the key combinations for all keymaps matching the desired action
assert!(std::mem::size_of::<usize>() >= std::mem::size_of::<Key>());
found_actions
.map(|entry| {
// Get the modifier keys for the entry (and convert them to Key)
let mut keys = entry
.modifiers
.iter()
Expand All @@ -76,6 +84,7 @@ impl InputMapperMessageHandler {
})
.collect::<Vec<_>>();

// Append the key button for the entry
match entry.input {
InputMapperMessage::KeyDown(key) => keys.push(key),
InputMapperMessage::KeyUp(key) => keys.push(key),
Expand All @@ -84,16 +93,20 @@ impl InputMapperMessageHandler {
_ => (),
}

keys.sort_by(|a, b| {
keys.sort_by(|&a, &b| {
// Order according to platform guidelines mentioned at https://ux.stackexchange.com/questions/58185/normative-ordering-for-modifier-key-combinations
const ORDER: [Key; 4] = [Key::Control, Key::Alt, Key::Shift, Key::Command];

match (ORDER.contains(a), ORDER.contains(b)) {
(true, true) => ORDER.iter().position(|key| key == a).unwrap().cmp(&ORDER.iter().position(|key| key == b).unwrap()),
(true, false) => std::cmp::Ordering::Less,
(false, true) => std::cmp::Ordering::Greater,
(false, false) => std::cmp::Ordering::Equal,
}
// Treat the `Accel` virtual key as the platform's accel key for sorting comparison purposes
let a = if a == Key::Accel { platform_accel_key } else { a };
let b = if b == Key::Accel { platform_accel_key } else { b };

// Find where the keys are in the order, or put them at the end if they're not found
let a = ORDER.iter().position(|&key| key == a).unwrap_or(ORDER.len());
let b = ORDER.iter().position(|&key| key == b).unwrap_or(ORDER.len());

// Compare the positions of both keys
a.cmp(&b)
});

KeysGroup(keys)
Expand Down
8 changes: 5 additions & 3 deletions editor/src/messages/layout/layout_message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,15 @@ impl<F: Fn(&MessageDiscriminant) -> Vec<KeysGroup>> MessageHandler<LayoutMessage
// Resend that diff
self.send_diff(vec![diff], layout_target, responses, &action_input_mapping);
}
SendLayout { layout, layout_target } => self.diff_and_send_layout_to_frontend(layout_target, layout, responses, &action_input_mapping),
SendLayout { layout, layout_target } => {
self.diff_and_send_layout_to_frontend(layout_target, layout, responses, &action_input_mapping);
}
WidgetValueCommit { layout_target, widget_id, value } => {
self.handle_widget_callback(layout_target, widget_id, value, WidgetValueAction::Commit, responses);
}
WidgetValueUpdate { layout_target, widget_id, value } => {
self.handle_widget_callback(layout_target, widget_id, value, WidgetValueAction::Update, responses);
responses.add(ResendActiveWidget { layout_target, widget_id: widget_id });
responses.add(ResendActiveWidget { layout_target, widget_id });
}
}
}
Expand Down Expand Up @@ -345,7 +347,7 @@ impl LayoutMessageHandler {
/// Send a diff to the frontend based on the layout target.
#[remain::check]
fn send_diff(&self, mut diff: Vec<WidgetDiff>, layout_target: LayoutTarget, responses: &mut VecDeque<Message>, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>) {
diff.iter_mut().for_each(|diff| diff.new_value.apply_shortcut(action_input_mapping));
diff.iter_mut().for_each(|diff| diff.new_value.apply_keyboard_shortcut(action_input_mapping));

trace!("{layout_target:?} diff {diff:#?}");

Expand Down
4 changes: 2 additions & 2 deletions editor/src/messages/layout/utility_types/layout_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,8 +528,8 @@ pub enum DiffUpdate {
}

impl DiffUpdate {
/// Append the shortcut to the tooltip where applicable
pub fn apply_shortcut(&mut self, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>) {
/// Append the keyboard shortcut to the tooltip where applicable
pub fn apply_keyboard_shortcut(&mut self, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>) {
// Function used multiple times later in this code block to convert `ActionKeys::Action` to `ActionKeys::Keys` and append its shortcut to the tooltip
let apply_shortcut_to_tooltip = |tooltip_shortcut: &mut ActionKeys, tooltip: &mut String| {
let shortcut_text = tooltip_shortcut.to_keys(action_input_mapping);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ pub struct PopoverButton {

#[derive(Clone, Serialize, Deserialize, Derivative, Default, WidgetBuilder, specta::Type)]
#[derivative(Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct ParameterExposeButton {
pub exposed: bool,

Expand All @@ -91,7 +90,6 @@ pub struct ParameterExposeButton {

#[derive(Clone, Serialize, Deserialize, Derivative, Default, WidgetBuilder, specta::Type)]
#[derivative(Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct TextButton {
#[widget_builder(constructor)]
pub label: String,
Expand Down Expand Up @@ -160,7 +158,6 @@ pub struct ColorButton {

#[derive(Clone, Serialize, Deserialize, Derivative, Default, WidgetBuilder, specta::Type)]
#[derivative(Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct BreadcrumbTrailButtons {
#[widget_builder(constructor)]
pub labels: Vec<String>,
Expand Down
36 changes: 24 additions & 12 deletions editor/src/messages/portfolio/document/document_message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl Default for DocumentMessageHandler {
node_graph_handler: Default::default(),
navigation_handler: NavigationMessageHandler::default(),
overlays_message_handler: OverlaysMessageHandler::default(),
properties_panel_message_handler: PropertiesPanelMessageHandler::default(),
properties_panel_message_handler: PropertiesPanelMessageHandler,
// ============================================
// Fields that are saved in the document format
// ============================================
Expand Down Expand Up @@ -468,12 +468,25 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
responses.add(OverlaysMessage::Draw);
}
GroupSelectedLayers => {
// TODO: Add code that changes the insert index of the new folder based on the selected layer
let parent = self
.metadata()
.deepest_common_ancestor(self.selected_nodes.selected_layers(self.metadata()), true)
.unwrap_or(LayerNodeIdentifier::ROOT);

let calculated_insert_index = parent.children(self.metadata()).enumerate().find_map(|(index, direct_child)| {
if self.selected_nodes.selected_layers(self.metadata()).any(|selected| selected == direct_child) {
return Some(index as isize);
}

for descendant in direct_child.decendants(self.metadata()) {
if self.selected_nodes.selected_layers(self.metadata()).any(|selected| selected == descendant) {
return Some(index as isize);
}
}

None
});

let folder_id = NodeId(generate_uuid());

responses.add(PortfolioMessage::Copy { clipboard: Clipboard::Internal });
Expand All @@ -483,14 +496,13 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
id: folder_id,
nodes: HashMap::new(),
parent,
insert_index: -1,
insert_index: calculated_insert_index.unwrap_or(-1),
});
responses.add(PortfolioMessage::PasteIntoFolder {
clipboard: Clipboard::Internal,
parent: LayerNodeIdentifier::new_unchecked(folder_id),
insert_index: -1,
});

responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![folder_id] });
}
ImaginateGenerate => responses.add(PortfolioMessage::SubmitGraphRender { document_id }),
Expand Down Expand Up @@ -695,7 +707,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
let metadata = self.metadata();
let all_layers_except_artboards = metadata.all_layers().filter(move |&layer| !metadata.is_artboard(layer));
let nodes = all_layers_except_artboards.map(|layer| layer.to_node()).collect();
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: nodes });
responses.add(NodeGraphMessage::SelectedNodesSet { nodes });
}
SelectedLayersLower => {
responses.add(DocumentMessage::SelectedLayersReorder { relative_index_offset: 1 });
Expand Down Expand Up @@ -874,7 +886,7 @@ impl DocumentMessageHandler {
self.metadata
.root()
.decendants(&self.metadata)
.filter(|&layer| self.selected_nodes.layer_visible(layer, &self.network(), &self.metadata()))
.filter(|&layer| self.selected_nodes.layer_visible(layer, self.network(), self.metadata()))
.filter(|&layer| !is_artboard(layer, network))
.filter_map(|layer| self.metadata.click_target(layer).map(|targets| (layer, targets)))
.filter(move |(layer, target)| target.iter().any(move |target| target.intersect_rectangle(document_quad, self.metadata.transform_to_document(*layer))))
Expand All @@ -887,7 +899,7 @@ impl DocumentMessageHandler {
self.metadata
.root()
.decendants(&self.metadata)
.filter(|&layer| self.selected_nodes.layer_visible(layer, &self.network(), &self.metadata()))
.filter(|&layer| self.selected_nodes.layer_visible(layer, self.network(), self.metadata()))
.filter_map(|layer| self.metadata.click_target(layer).map(|targets| (layer, targets)))
.filter(move |(layer, target)| target.iter().any(|target: &ClickTarget| target.intersect_point(point, self.metadata.transform_to_document(*layer))))
.map(|(layer, _)| layer)
Expand All @@ -901,7 +913,7 @@ impl DocumentMessageHandler {
/// Get the combined bounding box of the click targets of the selected visible layers in viewport space
pub fn selected_visible_layers_bounding_box_viewport(&self) -> Option<[DVec2; 2]> {
self.selected_nodes
.selected_visible_layers(&self.network(), &self.metadata())
.selected_visible_layers(self.network(), self.metadata())
.filter_map(|layer| self.metadata.bounding_box_viewport(layer))
.reduce(graphene_core::renderer::Quad::combine_bounds)
}
Expand Down Expand Up @@ -940,7 +952,7 @@ impl DocumentMessageHandler {
}

/// Returns the bounding boxes for all visible layers.
pub fn bounding_boxes<'a>(&'a self) -> impl Iterator<Item = [DVec2; 2]> + 'a {
pub fn bounding_boxes(&self) -> impl Iterator<Item = [DVec2; 2]> + '_ {
// TODO: Remove this function entirely?
// self.visible_layers().filter_map(|path| self.document_legacy.viewport_bounding_box(path, font_cache).ok()?)
std::iter::empty()
Expand Down Expand Up @@ -1373,7 +1385,7 @@ impl DocumentMessageHandler {
}
}

(opacity_identical.then(|| first_opacity), blend_mode_identical.then(|| first_blend_mode))
(opacity_identical.then_some(first_opacity), blend_mode_identical.then_some(first_blend_mode))
})
.unwrap_or((None, None));

Expand All @@ -1394,12 +1406,12 @@ impl DocumentMessageHandler {
let layers_panel_options_bar = WidgetLayout::new(vec![LayoutGroup::Row {
widgets: vec![
DropdownInput::new(blend_mode_menu_entries)
.selected_index(blend_mode.map(|blend_mode| blend_mode.index_in_list_svg_subset()).flatten().map(|index| index as u32))
.selected_index(blend_mode.and_then(|blend_mode| blend_mode.index_in_list_svg_subset()).map(|index| index as u32))
.disabled(disabled)
.draw_icon(false)
.widget_holder(),
Separator::new(SeparatorType::Related).widget_holder(),
NumberInput::new(opacity.map(|opacity| opacity as f64))
NumberInput::new(opacity)
.label("Opacity")
.unit("%")
.display_decimal_places(2)
Expand Down

0 comments on commit 9b9a7c6

Please sign in to comment.