Move node graph from panel to overlay on viewport
This commit is contained in:
parent
d74e4b2ab3
commit
185106132d
|
|
@ -9,7 +9,7 @@ on:
|
||||||
- master
|
- master
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
INDEX_HTML_HEAD_REPLACEMENT: <script defer data-domain="dev.graphite.rs" data-api="https://graphite.rs/visit/event" src="https://graphite.rs/visit/script.outbound-links.file-downloads.js"></script>
|
INDEX_HTML_HEAD_REPLACEMENT: <script defer data-domain="dev.graphite.rs" data-api="https://graphite.rs/visit/event" src="https://graphite.rs/visit/script.js"></script>
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ jobs:
|
||||||
RUSTC_WRAPPER: /usr/bin/sccache
|
RUSTC_WRAPPER: /usr/bin/sccache
|
||||||
CARGO_INCREMENTAL: 0
|
CARGO_INCREMENTAL: 0
|
||||||
SCCACHE_DIR: /var/lib/github-actions/.cache
|
SCCACHE_DIR: /var/lib/github-actions/.cache
|
||||||
INDEX_HTML_HEAD_REPLACEMENT: <script defer data-domain="editor.graphite.rs" data-api="https://graphite.rs/visit/event" src="https://graphite.rs/visit/script.outbound-links.file-downloads.js"></script>
|
INDEX_HTML_HEAD_REPLACEMENT: <script defer data-domain="editor.graphite.rs" data-api="https://graphite.rs/visit/event" src="https://graphite.rs/visit/script.js"></script>
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: 📥 Clone and checkout repository
|
- name: 📥 Clone and checkout repository
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ on:
|
||||||
- website/**
|
- website/**
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
INDEX_HTML_HEAD_REPLACEMENT: <script defer data-domain="graphite.rs" data-api="/visit/event" src="/visit/script.outbound-links.file-downloads.js"></script>
|
INDEX_HTML_HEAD_REPLACEMENT: <script defer data-domain="graphite.rs" data-api="/visit/event" src="/visit/script.js"></script>
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
|
||||||
|
|
@ -255,7 +255,6 @@ impl Dispatcher {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::application::Editor;
|
use crate::application::Editor;
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
|
||||||
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
|
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::test_utils::EditorTestUtils;
|
use crate::test_utils::EditorTestUtils;
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,9 @@ pub enum FrontendMessage {
|
||||||
#[serde(rename = "isDefault")]
|
#[serde(rename = "isDefault")]
|
||||||
is_default: bool,
|
is_default: bool,
|
||||||
},
|
},
|
||||||
|
TriggerGraphViewOverlay {
|
||||||
|
open: bool,
|
||||||
|
},
|
||||||
TriggerImport,
|
TriggerImport,
|
||||||
TriggerIndexedDbRemoveDocument {
|
TriggerIndexedDbRemoveDocument {
|
||||||
#[serde(rename = "documentId")]
|
#[serde(rename = "documentId")]
|
||||||
|
|
@ -177,6 +180,11 @@ pub enum FrontendMessage {
|
||||||
#[serde(rename = "setColorChoice")]
|
#[serde(rename = "setColorChoice")]
|
||||||
set_color_choice: Option<String>,
|
set_color_choice: Option<String>,
|
||||||
},
|
},
|
||||||
|
UpdateGraphViewOverlayButtonLayout {
|
||||||
|
#[serde(rename = "layoutTarget")]
|
||||||
|
layout_target: LayoutTarget,
|
||||||
|
diff: Vec<WidgetDiff>,
|
||||||
|
},
|
||||||
UpdateImageData {
|
UpdateImageData {
|
||||||
#[serde(rename = "documentId")]
|
#[serde(rename = "documentId")]
|
||||||
document_id: u64,
|
document_id: u64,
|
||||||
|
|
|
||||||
|
|
@ -330,13 +330,17 @@ pub fn default_mapping() -> Mapping {
|
||||||
entry!(KeyDown(Period); action_dispatch=NavigationMessage::FitViewportToSelection),
|
entry!(KeyDown(Period); action_dispatch=NavigationMessage::FitViewportToSelection),
|
||||||
//
|
//
|
||||||
// PortfolioMessage
|
// PortfolioMessage
|
||||||
entry!(KeyDown(KeyO); modifiers=[Accel], action_dispatch=PortfolioMessage::OpenDocument),
|
entry!(KeyUp(Space); action_dispatch=PortfolioMessage::GraphViewOverlayToggle),
|
||||||
entry!(KeyDown(KeyI); modifiers=[Accel], action_dispatch=PortfolioMessage::Import),
|
entry!(KeyDownNoRepeat(Space); action_dispatch=PortfolioMessage::GraphViewOverlayToggleDisabled { disabled: false }),
|
||||||
entry!(KeyDown(Tab); modifiers=[Control], action_dispatch=PortfolioMessage::NextDocument),
|
entry!(KeyDown(Tab); modifiers=[Control], action_dispatch=PortfolioMessage::NextDocument),
|
||||||
entry!(KeyDown(Tab); modifiers=[Control, Shift], action_dispatch=PortfolioMessage::PrevDocument),
|
entry!(KeyDown(Tab); modifiers=[Control, Shift], action_dispatch=PortfolioMessage::PrevDocument),
|
||||||
entry!(KeyDown(KeyW); modifiers=[Accel], action_dispatch=PortfolioMessage::CloseActiveDocumentWithConfirmation),
|
entry!(KeyDown(KeyW); modifiers=[Accel], action_dispatch=PortfolioMessage::CloseActiveDocumentWithConfirmation),
|
||||||
|
entry!(KeyDown(KeyO); modifiers=[Accel], action_dispatch=PortfolioMessage::OpenDocument),
|
||||||
|
entry!(KeyDown(KeyI); modifiers=[Accel], action_dispatch=PortfolioMessage::Import),
|
||||||
entry!(KeyDown(KeyX); modifiers=[Accel], action_dispatch=PortfolioMessage::Cut { clipboard: Clipboard::Device }),
|
entry!(KeyDown(KeyX); modifiers=[Accel], action_dispatch=PortfolioMessage::Cut { clipboard: Clipboard::Device }),
|
||||||
entry!(KeyDown(KeyC); modifiers=[Accel], action_dispatch=PortfolioMessage::Copy { clipboard: Clipboard::Device }),
|
entry!(KeyDown(KeyC); modifiers=[Accel], action_dispatch=PortfolioMessage::Copy { clipboard: Clipboard::Device }),
|
||||||
|
//
|
||||||
|
// FrontendMessage
|
||||||
entry!(KeyDown(KeyV); modifiers=[Accel], action_dispatch=FrontendMessage::TriggerPaste),
|
entry!(KeyDown(KeyV); modifiers=[Accel], action_dispatch=FrontendMessage::TriggerPaste),
|
||||||
//
|
//
|
||||||
// DialogMessage
|
// DialogMessage
|
||||||
|
|
@ -351,7 +355,7 @@ pub fn default_mapping() -> Mapping {
|
||||||
entry!(KeyDown(Digit1); modifiers=[Alt], action_dispatch=DebugMessage::MessageNames),
|
entry!(KeyDown(Digit1); modifiers=[Alt], action_dispatch=DebugMessage::MessageNames),
|
||||||
entry!(KeyDown(Digit2); modifiers=[Alt], action_dispatch=DebugMessage::MessageContents),
|
entry!(KeyDown(Digit2); modifiers=[Alt], action_dispatch=DebugMessage::MessageContents),
|
||||||
];
|
];
|
||||||
let (mut key_up, mut key_down, mut double_click, mut wheel_scroll, mut pointer_move) = mappings;
|
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
|
// 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];
|
const NUMBER_KEYS: [Key; 10] = [Digit0, Digit1, Digit2, Digit3, Digit4, Digit5, Digit6, Digit7, Digit8, Digit9];
|
||||||
|
|
@ -367,7 +371,7 @@ pub fn default_mapping() -> Mapping {
|
||||||
}
|
}
|
||||||
|
|
||||||
let sort = |list: &mut KeyMappingEntries| list.0.sort_by(|u, v| v.modifiers.ones().cmp(&u.modifiers.ones()));
|
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] {
|
for list in [&mut key_up, &mut key_down, &mut key_up_no_repeat, &mut key_down_no_repeat] {
|
||||||
for sublist in list {
|
for sublist in list {
|
||||||
sort(sublist);
|
sort(sublist);
|
||||||
}
|
}
|
||||||
|
|
@ -379,6 +383,8 @@ pub fn default_mapping() -> Mapping {
|
||||||
Mapping {
|
Mapping {
|
||||||
key_up,
|
key_up,
|
||||||
key_down,
|
key_down,
|
||||||
|
key_up_no_repeat,
|
||||||
|
key_down_no_repeat,
|
||||||
double_click,
|
double_click,
|
||||||
wheel_scroll,
|
wheel_scroll,
|
||||||
pointer_move,
|
pointer_move,
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,12 @@ pub enum InputMapperMessage {
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
#[child]
|
#[child]
|
||||||
KeyUp(Key),
|
KeyUp(Key),
|
||||||
|
#[remain::unsorted]
|
||||||
|
#[child]
|
||||||
|
KeyDownNoRepeat(Key),
|
||||||
|
#[remain::unsorted]
|
||||||
|
#[child]
|
||||||
|
KeyUpNoRepeat(Key),
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
DoubleClick,
|
DoubleClick,
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,16 @@ macro_rules! entry {
|
||||||
input: InputMapperMessage::KeyUp(Key::$refresh),
|
input: InputMapperMessage::KeyUp(Key::$refresh),
|
||||||
modifiers: modifiers!(),
|
modifiers: modifiers!(),
|
||||||
},
|
},
|
||||||
|
MappingEntry {
|
||||||
|
action: $action_dispatch.into(),
|
||||||
|
input: InputMapperMessage::KeyDownNoRepeat(Key::$refresh),
|
||||||
|
modifiers: modifiers!(),
|
||||||
|
},
|
||||||
|
MappingEntry {
|
||||||
|
action: $action_dispatch.into(),
|
||||||
|
input: InputMapperMessage::KeyUpNoRepeat(Key::$refresh),
|
||||||
|
modifiers: modifiers!(),
|
||||||
|
},
|
||||||
)*
|
)*
|
||||||
)*
|
)*
|
||||||
]]
|
]]
|
||||||
|
|
@ -65,6 +75,8 @@ macro_rules! mapping {
|
||||||
[$($entry:expr),* $(,)?] => {{
|
[$($entry:expr),* $(,)?] => {{
|
||||||
let mut key_up = KeyMappingEntries::key_array();
|
let mut key_up = KeyMappingEntries::key_array();
|
||||||
let mut key_down = KeyMappingEntries::key_array();
|
let mut key_down = KeyMappingEntries::key_array();
|
||||||
|
let mut key_up_no_repeat = KeyMappingEntries::key_array();
|
||||||
|
let mut key_down_no_repeat = KeyMappingEntries::key_array();
|
||||||
let mut double_click = KeyMappingEntries::new();
|
let mut double_click = KeyMappingEntries::new();
|
||||||
let mut wheel_scroll = KeyMappingEntries::new();
|
let mut wheel_scroll = KeyMappingEntries::new();
|
||||||
let mut pointer_move = KeyMappingEntries::new();
|
let mut pointer_move = KeyMappingEntries::new();
|
||||||
|
|
@ -77,6 +89,8 @@ macro_rules! mapping {
|
||||||
let corresponding_list = match entry.input {
|
let corresponding_list = match entry.input {
|
||||||
InputMapperMessage::KeyDown(key) => &mut key_down[key as usize],
|
InputMapperMessage::KeyDown(key) => &mut key_down[key as usize],
|
||||||
InputMapperMessage::KeyUp(key) => &mut key_up[key as usize],
|
InputMapperMessage::KeyUp(key) => &mut key_up[key as usize],
|
||||||
|
InputMapperMessage::KeyDownNoRepeat(key) => &mut key_down_no_repeat[key as usize],
|
||||||
|
InputMapperMessage::KeyUpNoRepeat(key) => &mut key_up_no_repeat[key as usize],
|
||||||
InputMapperMessage::DoubleClick => &mut double_click,
|
InputMapperMessage::DoubleClick => &mut double_click,
|
||||||
InputMapperMessage::WheelScroll => &mut wheel_scroll,
|
InputMapperMessage::WheelScroll => &mut wheel_scroll,
|
||||||
InputMapperMessage::PointerMove => &mut pointer_move,
|
InputMapperMessage::PointerMove => &mut pointer_move,
|
||||||
|
|
@ -87,7 +101,7 @@ macro_rules! mapping {
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
|
|
||||||
(key_up, key_down, double_click, wheel_scroll, pointer_move)
|
(key_up, key_down, key_up_no_repeat, key_down_no_repeat, double_click, wheel_scroll, pointer_move)
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ use serde::{Deserialize, Serialize};
|
||||||
pub struct Mapping {
|
pub struct Mapping {
|
||||||
pub key_up: [KeyMappingEntries; NUMBER_OF_KEYS],
|
pub key_up: [KeyMappingEntries; NUMBER_OF_KEYS],
|
||||||
pub key_down: [KeyMappingEntries; NUMBER_OF_KEYS],
|
pub key_down: [KeyMappingEntries; NUMBER_OF_KEYS],
|
||||||
|
pub key_up_no_repeat: [KeyMappingEntries; NUMBER_OF_KEYS],
|
||||||
|
pub key_down_no_repeat: [KeyMappingEntries; NUMBER_OF_KEYS],
|
||||||
pub double_click: KeyMappingEntries,
|
pub double_click: KeyMappingEntries,
|
||||||
pub wheel_scroll: KeyMappingEntries,
|
pub wheel_scroll: KeyMappingEntries,
|
||||||
pub pointer_move: KeyMappingEntries,
|
pub pointer_move: KeyMappingEntries,
|
||||||
|
|
@ -40,6 +42,8 @@ impl Mapping {
|
||||||
match message {
|
match message {
|
||||||
InputMapperMessage::KeyDown(key) => &self.key_down[*key as usize],
|
InputMapperMessage::KeyDown(key) => &self.key_down[*key as usize],
|
||||||
InputMapperMessage::KeyUp(key) => &self.key_up[*key as usize],
|
InputMapperMessage::KeyUp(key) => &self.key_up[*key as usize],
|
||||||
|
InputMapperMessage::KeyDownNoRepeat(key) => &self.key_down_no_repeat[*key as usize],
|
||||||
|
InputMapperMessage::KeyUpNoRepeat(key) => &self.key_up_no_repeat[*key as usize],
|
||||||
InputMapperMessage::DoubleClick => &self.double_click,
|
InputMapperMessage::DoubleClick => &self.double_click,
|
||||||
InputMapperMessage::WheelScroll => &self.wheel_scroll,
|
InputMapperMessage::WheelScroll => &self.wheel_scroll,
|
||||||
InputMapperMessage::PointerMove => &self.pointer_move,
|
InputMapperMessage::PointerMove => &self.pointer_move,
|
||||||
|
|
@ -50,6 +54,8 @@ impl Mapping {
|
||||||
match message {
|
match message {
|
||||||
InputMapperMessage::KeyDown(key) => &mut self.key_down[*key as usize],
|
InputMapperMessage::KeyDown(key) => &mut self.key_down[*key as usize],
|
||||||
InputMapperMessage::KeyUp(key) => &mut self.key_up[*key as usize],
|
InputMapperMessage::KeyUp(key) => &mut self.key_up[*key as usize],
|
||||||
|
InputMapperMessage::KeyDownNoRepeat(key) => &mut self.key_down_no_repeat[*key as usize],
|
||||||
|
InputMapperMessage::KeyUpNoRepeat(key) => &mut self.key_up_no_repeat[*key as usize],
|
||||||
InputMapperMessage::DoubleClick => &mut self.double_click,
|
InputMapperMessage::DoubleClick => &mut self.double_click,
|
||||||
InputMapperMessage::WheelScroll => &mut self.wheel_scroll,
|
InputMapperMessage::WheelScroll => &mut self.wheel_scroll,
|
||||||
InputMapperMessage::PointerMove => &mut self.pointer_move,
|
InputMapperMessage::PointerMove => &mut self.pointer_move,
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ use serde::{Deserialize, Serialize};
|
||||||
pub enum InputPreprocessorMessage {
|
pub enum InputPreprocessorMessage {
|
||||||
BoundsOfViewports { bounds_of_viewports: Vec<ViewportBounds> },
|
BoundsOfViewports { bounds_of_viewports: Vec<ViewportBounds> },
|
||||||
DoubleClick { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
DoubleClick { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
||||||
KeyDown { key: Key, modifier_keys: ModifierKeys },
|
KeyDown { key: Key, key_repeat: bool, modifier_keys: ModifierKeys },
|
||||||
KeyUp { key: Key, modifier_keys: ModifierKeys },
|
KeyUp { key: Key, key_repeat: bool, modifier_keys: ModifierKeys },
|
||||||
PointerDown { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
PointerDown { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
||||||
PointerMove { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
PointerMove { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
||||||
PointerUp { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
PointerUp { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,20 @@ impl MessageHandler<InputPreprocessorMessage, KeyboardPlatformLayout> for InputP
|
||||||
|
|
||||||
responses.add(InputMapperMessage::DoubleClick);
|
responses.add(InputMapperMessage::DoubleClick);
|
||||||
}
|
}
|
||||||
InputPreprocessorMessage::KeyDown { key, modifier_keys } => {
|
InputPreprocessorMessage::KeyDown { key, key_repeat, modifier_keys } => {
|
||||||
self.update_states_of_modifier_keys(modifier_keys, keyboard_platform, responses);
|
self.update_states_of_modifier_keys(modifier_keys, keyboard_platform, responses);
|
||||||
self.keyboard.set(key as usize);
|
self.keyboard.set(key as usize);
|
||||||
|
if !key_repeat {
|
||||||
|
responses.add(InputMapperMessage::KeyDownNoRepeat(key));
|
||||||
|
}
|
||||||
responses.add(InputMapperMessage::KeyDown(key));
|
responses.add(InputMapperMessage::KeyDown(key));
|
||||||
}
|
}
|
||||||
InputPreprocessorMessage::KeyUp { key, modifier_keys } => {
|
InputPreprocessorMessage::KeyUp { key, key_repeat, modifier_keys } => {
|
||||||
self.update_states_of_modifier_keys(modifier_keys, keyboard_platform, responses);
|
self.update_states_of_modifier_keys(modifier_keys, keyboard_platform, responses);
|
||||||
self.keyboard.unset(key as usize);
|
self.keyboard.unset(key as usize);
|
||||||
|
if !key_repeat {
|
||||||
|
responses.add(InputMapperMessage::KeyUpNoRepeat(key));
|
||||||
|
}
|
||||||
responses.add(InputMapperMessage::KeyUp(key));
|
responses.add(InputMapperMessage::KeyUp(key));
|
||||||
}
|
}
|
||||||
InputPreprocessorMessage::PointerDown { editor_mouse_state, modifier_keys } => {
|
InputPreprocessorMessage::PointerDown { editor_mouse_state, modifier_keys } => {
|
||||||
|
|
@ -218,8 +224,9 @@ mod test {
|
||||||
input_preprocessor.keyboard.set(Key::Control as usize);
|
input_preprocessor.keyboard.set(Key::Control as usize);
|
||||||
|
|
||||||
let key = Key::KeyA;
|
let key = Key::KeyA;
|
||||||
|
let key_repeat = false;
|
||||||
let modifier_keys = ModifierKeys::empty();
|
let modifier_keys = ModifierKeys::empty();
|
||||||
let message = InputPreprocessorMessage::KeyDown { key, modifier_keys };
|
let message = InputPreprocessorMessage::KeyDown { key, key_repeat, modifier_keys };
|
||||||
|
|
||||||
let mut responses = VecDeque::new();
|
let mut responses = VecDeque::new();
|
||||||
|
|
||||||
|
|
@ -234,8 +241,9 @@ mod test {
|
||||||
let mut input_preprocessor = InputPreprocessorMessageHandler::default();
|
let mut input_preprocessor = InputPreprocessorMessageHandler::default();
|
||||||
|
|
||||||
let key = Key::KeyS;
|
let key = Key::KeyS;
|
||||||
|
let key_repeat = false;
|
||||||
let modifier_keys = ModifierKeys::CONTROL | ModifierKeys::SHIFT;
|
let modifier_keys = ModifierKeys::CONTROL | ModifierKeys::SHIFT;
|
||||||
let message = InputPreprocessorMessage::KeyUp { key, modifier_keys };
|
let message = InputPreprocessorMessage::KeyUp { key, key_repeat, modifier_keys };
|
||||||
|
|
||||||
let mut responses = VecDeque::new();
|
let mut responses = VecDeque::new();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -291,6 +291,7 @@ impl LayoutMessageHandler {
|
||||||
LayoutTarget::DialogDetails => FrontendMessage::UpdateDialogDetails { layout_target, diff },
|
LayoutTarget::DialogDetails => FrontendMessage::UpdateDialogDetails { layout_target, diff },
|
||||||
LayoutTarget::DocumentBar => FrontendMessage::UpdateDocumentBarLayout { layout_target, diff },
|
LayoutTarget::DocumentBar => FrontendMessage::UpdateDocumentBarLayout { layout_target, diff },
|
||||||
LayoutTarget::DocumentMode => FrontendMessage::UpdateDocumentModeLayout { layout_target, diff },
|
LayoutTarget::DocumentMode => FrontendMessage::UpdateDocumentModeLayout { layout_target, diff },
|
||||||
|
LayoutTarget::GraphViewOverlayButton => FrontendMessage::UpdateGraphViewOverlayButtonLayout { layout_target, diff },
|
||||||
LayoutTarget::LayerTreeOptions => FrontendMessage::UpdateLayerTreeOptionsLayout { layout_target, diff },
|
LayoutTarget::LayerTreeOptions => FrontendMessage::UpdateLayerTreeOptionsLayout { layout_target, diff },
|
||||||
LayoutTarget::MenuBar => unreachable!("Menu bar is not diffed"),
|
LayoutTarget::MenuBar => unreachable!("Menu bar is not diffed"),
|
||||||
LayoutTarget::NodeGraphBar => FrontendMessage::UpdateNodeGraphBarLayout { layout_target, diff },
|
LayoutTarget::NodeGraphBar => FrontendMessage::UpdateNodeGraphBarLayout { layout_target, diff },
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,13 @@ pub enum LayoutTarget {
|
||||||
DocumentBar,
|
DocumentBar,
|
||||||
/// Contains the dropdown for design / select / guide mode found on the top left of the canvas.
|
/// Contains the dropdown for design / select / guide mode found on the top left of the canvas.
|
||||||
DocumentMode,
|
DocumentMode,
|
||||||
|
/// The button below the tool shelf and directly above the working colors which lets the user toggle the node graph overlaid on the canvas.
|
||||||
|
GraphViewOverlayButton,
|
||||||
/// Options for opacity seen at the top of the Layers panel.
|
/// Options for opacity seen at the top of the Layers panel.
|
||||||
LayerTreeOptions,
|
LayerTreeOptions,
|
||||||
/// The dropdown menu at the very top of the application: File, Edit, etc.
|
/// The dropdown menu at the very top of the application: File, Edit, etc.
|
||||||
MenuBar,
|
MenuBar,
|
||||||
/// Bar at the top of the node graph containing the location and the 'preview' and 'hide' buttons.
|
/// Bar at the top of the node graph containing the location and the "Preview" and "Hide" buttons.
|
||||||
NodeGraphBar,
|
NodeGraphBar,
|
||||||
/// The bar at the top of the Properties panel containing the layer name and icon.
|
/// The bar at the top of the Properties panel containing the layer name and icon.
|
||||||
PropertiesOptions,
|
PropertiesOptions,
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,9 @@ impl MessageHandler<NavigationMessage, (&Document, Option<[DVec2; 2]>, &InputPre
|
||||||
TranslateCanvasBegin => {
|
TranslateCanvasBegin => {
|
||||||
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Grabbing });
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Grabbing });
|
||||||
responses.add(FrontendMessage::UpdateInputHints { hint_data: HintData(Vec::new()) });
|
responses.add(FrontendMessage::UpdateInputHints { hint_data: HintData(Vec::new()) });
|
||||||
|
// Because the pan key shares the Spacebar with toggling the graph view overlay, now that we've begun panning,
|
||||||
|
// we need to prevent the graph view overlay from toggling when the Spacebar is released.
|
||||||
|
responses.add(PortfolioMessage::GraphViewOverlayToggleDisabled { disabled: true });
|
||||||
|
|
||||||
self.panning = true;
|
self.panning = true;
|
||||||
self.mouse_position = ipp.mouse.position;
|
self.mouse_position = ipp.mouse.position;
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,13 @@ pub enum PortfolioMessage {
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
is_default: bool,
|
is_default: bool,
|
||||||
},
|
},
|
||||||
|
GraphViewOverlay {
|
||||||
|
open: bool,
|
||||||
|
},
|
||||||
|
GraphViewOverlayToggle,
|
||||||
|
GraphViewOverlayToggleDisabled {
|
||||||
|
disabled: bool,
|
||||||
|
},
|
||||||
ImaginateCheckServerStatus,
|
ImaginateCheckServerStatus,
|
||||||
ImaginatePollServerStatus,
|
ImaginatePollServerStatus,
|
||||||
ImaginatePreferences,
|
ImaginatePreferences,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use crate::application::generate_uuid;
|
||||||
use crate::consts::{DEFAULT_DOCUMENT_NAME, GRAPHITE_DOCUMENT_VERSION};
|
use crate::consts::{DEFAULT_DOCUMENT_NAME, GRAPHITE_DOCUMENT_VERSION};
|
||||||
use crate::messages::dialog::simple_dialogs;
|
use crate::messages::dialog::simple_dialogs;
|
||||||
use crate::messages::frontend::utility_types::FrontendDocumentDetails;
|
use crate::messages::frontend::utility_types::FrontendDocumentDetails;
|
||||||
|
use crate::messages::input_mapper::utility_types::macros::action_keys;
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
use crate::messages::portfolio::document::utility_types::clipboards::{Clipboard, CopyBufferEntry, INTERNAL_CLIPBOARD_COUNT};
|
use crate::messages::portfolio::document::utility_types::clipboards::{Clipboard, CopyBufferEntry, INTERNAL_CLIPBOARD_COUNT};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
@ -24,10 +25,12 @@ pub struct PortfolioMessageHandler {
|
||||||
menu_bar_message_handler: MenuBarMessageHandler,
|
menu_bar_message_handler: MenuBarMessageHandler,
|
||||||
documents: HashMap<u64, DocumentMessageHandler>,
|
documents: HashMap<u64, DocumentMessageHandler>,
|
||||||
document_ids: Vec<u64>,
|
document_ids: Vec<u64>,
|
||||||
pub executor: NodeGraphExecutor,
|
|
||||||
active_document_id: Option<u64>,
|
active_document_id: Option<u64>,
|
||||||
|
graph_view_overlay_open: bool,
|
||||||
|
graph_view_overlay_toggle_disabled: bool,
|
||||||
copy_buffer: [Vec<CopyBufferEntry>; INTERNAL_CLIPBOARD_COUNT as usize],
|
copy_buffer: [Vec<CopyBufferEntry>; INTERNAL_CLIPBOARD_COUNT as usize],
|
||||||
pub persistent_data: PersistentData,
|
pub persistent_data: PersistentData,
|
||||||
|
pub executor: NodeGraphExecutor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &PreferencesMessageHandler)> for PortfolioMessageHandler {
|
impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &PreferencesMessageHandler)> for PortfolioMessageHandler {
|
||||||
|
|
@ -220,6 +223,31 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
||||||
self.persistent_data.font_cache.insert(font, preview_url, data, is_default);
|
self.persistent_data.font_cache.insert(font, preview_url, data, is_default);
|
||||||
self.executor.update_font_cache(self.persistent_data.font_cache.clone());
|
self.executor.update_font_cache(self.persistent_data.font_cache.clone());
|
||||||
}
|
}
|
||||||
|
PortfolioMessage::GraphViewOverlay { open } => {
|
||||||
|
self.graph_view_overlay_open = open;
|
||||||
|
|
||||||
|
let layout = WidgetLayout::new(vec![LayoutGroup::Row {
|
||||||
|
widgets: vec![IconButton::new(if open { "GraphViewOpen" } else { "GraphViewClosed" }, 32)
|
||||||
|
.tooltip(if open { "Hide Node Graph" } else { "Show Node Graph" })
|
||||||
|
.tooltip_shortcut(action_keys!(PortfolioMessageDiscriminant::GraphViewOverlayToggle))
|
||||||
|
.on_update(move |_| PortfolioMessage::GraphViewOverlay { open: !open }.into())
|
||||||
|
.widget_holder()],
|
||||||
|
}]);
|
||||||
|
responses.add(LayoutMessage::SendLayout {
|
||||||
|
layout: Layout::WidgetLayout(layout),
|
||||||
|
layout_target: LayoutTarget::GraphViewOverlayButton,
|
||||||
|
});
|
||||||
|
|
||||||
|
responses.add(FrontendMessage::TriggerGraphViewOverlay { open });
|
||||||
|
}
|
||||||
|
PortfolioMessage::GraphViewOverlayToggle => {
|
||||||
|
if !self.graph_view_overlay_toggle_disabled {
|
||||||
|
responses.add(PortfolioMessage::GraphViewOverlay { open: !self.graph_view_overlay_open });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PortfolioMessage::GraphViewOverlayToggleDisabled { disabled } => {
|
||||||
|
self.graph_view_overlay_toggle_disabled = disabled;
|
||||||
|
}
|
||||||
PortfolioMessage::ImaginateCheckServerStatus => {
|
PortfolioMessage::ImaginateCheckServerStatus => {
|
||||||
let server_status = self.persistent_data.imaginate.server_status().clone();
|
let server_status = self.persistent_data.imaginate.server_status().clone();
|
||||||
self.persistent_data.imaginate.poll_server_check();
|
self.persistent_data.imaginate.poll_server_check();
|
||||||
|
|
@ -519,6 +547,8 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
||||||
|
|
||||||
fn actions(&self) -> ActionList {
|
fn actions(&self) -> ActionList {
|
||||||
let mut common = actions!(PortfolioMessageDiscriminant;
|
let mut common = actions!(PortfolioMessageDiscriminant;
|
||||||
|
GraphViewOverlayToggle,
|
||||||
|
GraphViewOverlayToggleDisabled,
|
||||||
CloseActiveDocumentWithConfirmation,
|
CloseActiveDocumentWithConfirmation,
|
||||||
CloseAllDocuments,
|
CloseAllDocuments,
|
||||||
Import,
|
Import,
|
||||||
|
|
@ -618,6 +648,7 @@ impl PortfolioMessageHandler {
|
||||||
responses.add(PortfolioMessage::SelectDocument { document_id });
|
responses.add(PortfolioMessage::SelectDocument { document_id });
|
||||||
responses.add(PortfolioMessage::LoadDocumentResources { document_id });
|
responses.add(PortfolioMessage::LoadDocumentResources { document_id });
|
||||||
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||||
|
responses.add(PortfolioMessage::GraphViewOverlay { open: self.graph_view_overlay_open });
|
||||||
responses.add(ToolMessage::InitTools);
|
responses.add(ToolMessage::InitTools);
|
||||||
responses.add(PropertiesPanelMessage::Init);
|
responses.add(PropertiesPanelMessage::Init);
|
||||||
responses.add(NavigationMessage::TranslateCanvas { delta: (0., 0.).into() });
|
responses.add(NavigationMessage::TranslateCanvas { delta: (0., 0.).into() });
|
||||||
|
|
|
||||||
|
|
@ -194,13 +194,13 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, u64, &InputPreprocess
|
||||||
document_data.primary_color = Color::BLACK;
|
document_data.primary_color = Color::BLACK;
|
||||||
document_data.secondary_color = Color::WHITE;
|
document_data.secondary_color = Color::WHITE;
|
||||||
|
|
||||||
document_data.update_working_colors(responses);
|
document_data.update_working_colors(responses); // TODO: Make this an event
|
||||||
}
|
}
|
||||||
ToolMessage::SelectPrimaryColor { color } => {
|
ToolMessage::SelectPrimaryColor { color } => {
|
||||||
let document_data = &mut self.tool_state.document_tool_data;
|
let document_data = &mut self.tool_state.document_tool_data;
|
||||||
document_data.primary_color = color;
|
document_data.primary_color = color;
|
||||||
|
|
||||||
self.tool_state.document_tool_data.update_working_colors(responses);
|
self.tool_state.document_tool_data.update_working_colors(responses); // TODO: Make this an event
|
||||||
}
|
}
|
||||||
ToolMessage::SelectRandomPrimaryColor => {
|
ToolMessage::SelectRandomPrimaryColor => {
|
||||||
// Select a random primary color (rgba) based on an UUID
|
// Select a random primary color (rgba) based on an UUID
|
||||||
|
|
@ -213,20 +213,20 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, u64, &InputPreprocess
|
||||||
let random_color = Color::from_rgba8_srgb(r, g, b, 255);
|
let random_color = Color::from_rgba8_srgb(r, g, b, 255);
|
||||||
document_data.primary_color = random_color;
|
document_data.primary_color = random_color;
|
||||||
|
|
||||||
document_data.update_working_colors(responses);
|
document_data.update_working_colors(responses); // TODO: Make this an event
|
||||||
}
|
}
|
||||||
ToolMessage::SelectSecondaryColor { color } => {
|
ToolMessage::SelectSecondaryColor { color } => {
|
||||||
let document_data = &mut self.tool_state.document_tool_data;
|
let document_data = &mut self.tool_state.document_tool_data;
|
||||||
document_data.secondary_color = color;
|
document_data.secondary_color = color;
|
||||||
|
|
||||||
document_data.update_working_colors(responses);
|
document_data.update_working_colors(responses); // TODO: Make this an event
|
||||||
}
|
}
|
||||||
ToolMessage::SwapColors => {
|
ToolMessage::SwapColors => {
|
||||||
let document_data = &mut self.tool_state.document_tool_data;
|
let document_data = &mut self.tool_state.document_tool_data;
|
||||||
|
|
||||||
std::mem::swap(&mut document_data.primary_color, &mut document_data.secondary_color);
|
std::mem::swap(&mut document_data.primary_color, &mut document_data.secondary_color);
|
||||||
|
|
||||||
document_data.update_working_colors(responses);
|
document_data.update_working_colors(responses); // TODO: Make this an event
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sub-messages
|
// Sub-messages
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6,9.5l4-2.4c0,0.5,0.5,0.9,1,0.9h3c0.6,0,1-0.4,1-1V3c0-0.6-0.4-1-1-1h-3c-0.6,0-1,0.4-1,1H6c0-0.6-0.4-1-1-1H2C1.4,2,1,2.4,1,3v2c0,0.6,0.4,1,1,1h3c0.6,0,1-0.4,1-1V4h4v1.9L5.8,8.4C5.6,8.2,5.3,8,5,8H2C1.4,8,1,8.4,1,9v2c0,0.6,0.4,1,1,1h3c0.4,0,0.8-0.2,0.9-0.6L10,13v1c0,0.6,0.4,1,1,1h3c0.6,0,1-0.4,1-1v-2c0-0.6-0.4-1-1-1h-3c-0.5,0-1,0.4-1,1l-4-1.6V9.5z M11,3h3v4h-3V3z M5,5H2V3h3V5z M5,11H2V9h3V11z M11,12h3v2h-3V12z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 495 B |
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6,9.5l4-2.4c0,0.5,0.5,0.9,1,0.9h3c0.6,0,1-0.4,1-1V3c0-0.6-0.4-1-1-1h-3c-0.6,0-1,0.4-1,1H6c0-0.6-0.4-1-1-1H2C1.4,2,1,2.4,1,3v2c0,0.6,0.4,1,1,1h3c0.6,0,1-0.4,1-1V4h4v1.9L5.8,8.4C5.6,8.2,5.3,8,5,8H2C1.4,8,1,8.4,1,9v2c0,0.6,0.4,1,1,1h3c0.4,0,0.8-0.2,0.9-0.6L10,13v1c0,0.6,0.4,1,1,1h3c0.6,0,1-0.4,1-1v-2c0-0.6-0.4-1-1-1h-3c-0.5,0-1,0.4-1,1l-4-1.6V9.5z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 431 B |
|
|
@ -20,11 +20,13 @@
|
||||||
UpdateMouseCursor,
|
UpdateMouseCursor,
|
||||||
UpdateDocumentNodeRender,
|
UpdateDocumentNodeRender,
|
||||||
UpdateDocumentTransform,
|
UpdateDocumentTransform,
|
||||||
|
TriggerGraphViewOverlay,
|
||||||
} from "@graphite/wasm-communication/messages";
|
} from "@graphite/wasm-communication/messages";
|
||||||
|
|
||||||
import EyedropperPreview, { ZOOM_WINDOW_DIMENSIONS } from "@graphite/components/floating-menus/EyedropperPreview.svelte";
|
import EyedropperPreview, { ZOOM_WINDOW_DIMENSIONS } from "@graphite/components/floating-menus/EyedropperPreview.svelte";
|
||||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||||
|
import Graph from "@graphite/components/views/Graph.svelte";
|
||||||
import CanvasRuler from "@graphite/components/widgets/metrics/CanvasRuler.svelte";
|
import CanvasRuler from "@graphite/components/widgets/metrics/CanvasRuler.svelte";
|
||||||
import PersistentScrollbar from "@graphite/components/widgets/metrics/PersistentScrollbar.svelte";
|
import PersistentScrollbar from "@graphite/components/widgets/metrics/PersistentScrollbar.svelte";
|
||||||
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
||||||
|
|
@ -38,6 +40,9 @@
|
||||||
const editor = getContext<Editor>("editor");
|
const editor = getContext<Editor>("editor");
|
||||||
const document = getContext<DocumentState>("document");
|
const document = getContext<DocumentState>("document");
|
||||||
|
|
||||||
|
// Graph view overlay
|
||||||
|
let graphViewOverlayOpen = false;
|
||||||
|
|
||||||
// Interactive text editing
|
// Interactive text editing
|
||||||
let textInput: undefined | HTMLDivElement = undefined;
|
let textInput: undefined | HTMLDivElement = undefined;
|
||||||
let showTextInput: boolean;
|
let showTextInput: boolean;
|
||||||
|
|
@ -135,6 +140,7 @@
|
||||||
// Replace the placeholders with the actual canvas elements
|
// Replace the placeholders with the actual canvas elements
|
||||||
placeholders.forEach((placeholder) => {
|
placeholders.forEach((placeholder) => {
|
||||||
const canvasName = placeholder.getAttribute("data-canvas-placeholder");
|
const canvasName = placeholder.getAttribute("data-canvas-placeholder");
|
||||||
|
if (!canvasName) return;
|
||||||
// Get the canvas element from the global storage
|
// Get the canvas element from the global storage
|
||||||
const canvas = (window as any).imageCanvases[canvasName];
|
const canvas = (window as any).imageCanvases[canvasName];
|
||||||
placeholder.replaceWith(canvas);
|
placeholder.replaceWith(canvas);
|
||||||
|
|
@ -332,6 +338,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
// Show or hide the graph view overlay
|
||||||
|
editor.subscriptions.subscribeJsMessage(TriggerGraphViewOverlay, (triggerGraphViewOverlay) => {
|
||||||
|
graphViewOverlayOpen = triggerGraphViewOverlay.open;
|
||||||
|
});
|
||||||
|
|
||||||
// Update rendered SVGs
|
// Update rendered SVGs
|
||||||
editor.subscriptions.subscribeJsMessage(UpdateDocumentArtwork, async (data) => {
|
editor.subscriptions.subscribeJsMessage(UpdateDocumentArtwork, async (data) => {
|
||||||
await tick();
|
await tick();
|
||||||
|
|
@ -425,23 +436,30 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<LayoutCol class="document">
|
<LayoutCol class="document">
|
||||||
<LayoutRow class="options-bar" scrollableX={true}>
|
<LayoutRow class="options-bar" classes={{ "for-graph": graphViewOverlayOpen }} scrollableX={true}>
|
||||||
<WidgetLayout layout={$document.documentModeLayout} />
|
{#if !graphViewOverlayOpen}
|
||||||
<WidgetLayout layout={$document.toolOptionsLayout} />
|
<WidgetLayout layout={$document.documentModeLayout} />
|
||||||
|
<WidgetLayout layout={$document.toolOptionsLayout} />
|
||||||
|
|
||||||
<LayoutRow class="spacer" />
|
<LayoutRow class="spacer" />
|
||||||
|
|
||||||
<WidgetLayout layout={$document.documentBarLayout} />
|
<WidgetLayout layout={$document.documentBarLayout} />
|
||||||
|
{:else}
|
||||||
|
<WidgetLayout layout={$document.nodeGraphBarLayout} />
|
||||||
|
{/if}
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
<LayoutRow class="shelf-and-viewport">
|
<LayoutRow class="shelf-and-viewport">
|
||||||
<LayoutCol class="shelf">
|
<LayoutCol class="shelf">
|
||||||
<LayoutCol class="tools" scrollableY={true}>
|
{#if !graphViewOverlayOpen}
|
||||||
<WidgetLayout layout={$document.toolShelfLayout} />
|
<LayoutCol class="tools" scrollableY={true}>
|
||||||
</LayoutCol>
|
<WidgetLayout layout={$document.toolShelfLayout} />
|
||||||
|
</LayoutCol>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<LayoutCol class="spacer" />
|
<LayoutCol class="spacer" />
|
||||||
|
|
||||||
<LayoutCol class="working-colors">
|
<LayoutCol class="widgets-below-shelf">
|
||||||
|
<WidgetLayout layout={$document.graphViewOverlayButtonLayout} />
|
||||||
<WidgetLayout layout={$document.workingColorsLayout} />
|
<WidgetLayout layout={$document.workingColorsLayout} />
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
|
|
@ -485,6 +503,9 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="graph-view" class:open={graphViewOverlayOpen} style:--fade-artwork="80%">
|
||||||
|
<Graph />
|
||||||
|
</div>
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
<LayoutCol class="bar-area right-scrollbar">
|
<LayoutCol class="bar-area right-scrollbar">
|
||||||
<PersistentScrollbar
|
<PersistentScrollbar
|
||||||
|
|
@ -521,6 +542,12 @@
|
||||||
.spacer {
|
.spacer {
|
||||||
min-width: 40px;
|
min-width: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.for-graph .widget-layout {
|
||||||
|
flex-direction: row;
|
||||||
|
flex-grow: 1;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.shelf-and-viewport {
|
.shelf-and-viewport {
|
||||||
|
|
@ -557,21 +584,30 @@
|
||||||
|
|
||||||
.spacer {
|
.spacer {
|
||||||
flex: 1 0 auto;
|
flex: 1 0 auto;
|
||||||
min-height: 8px;
|
min-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.working-colors {
|
.widgets-below-shelf {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
|
||||||
.widget-row {
|
.widget-layout:first-of-type {
|
||||||
min-height: 0;
|
height: auto;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.swatch-pair {
|
.widget-layout:last-of-type {
|
||||||
margin: 0;
|
height: auto;
|
||||||
}
|
|
||||||
|
|
||||||
.icon-button {
|
.widget-row {
|
||||||
--widget-height: 0;
|
min-height: 0;
|
||||||
|
|
||||||
|
.swatch-pair {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-button {
|
||||||
|
--widget-height: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -580,11 +616,6 @@
|
||||||
.viewport {
|
.viewport {
|
||||||
flex: 1 1 100%;
|
flex: 1 1 100%;
|
||||||
|
|
||||||
.canvas-area {
|
|
||||||
flex: 1 1 100%;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar-area {
|
.bar-area {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
@ -602,51 +633,89 @@
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.canvas {
|
.canvas-area {
|
||||||
background: var(--color-2-mildblack);
|
flex: 1 1 100%;
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
// Allows the SVG to be placed at explicit integer values of width and height to prevent non-pixel-perfect SVG scaling
|
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
svg {
|
.canvas {
|
||||||
position: absolute;
|
background: var(--color-2-mildblack);
|
||||||
// Fallback values if JS hasn't set these to integers yet
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
// Allows dev tools to select the artwork without being blocked by the SVG containers
|
// Allows the SVG to be placed at explicit integer values of width and height to prevent non-pixel-perfect SVG scaling
|
||||||
pointer-events: none;
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
canvas {
|
svg {
|
||||||
|
position: absolute;
|
||||||
|
// Fallback values if JS hasn't set these to integers yet
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
// Allows dev tools to select the artwork without being blocked by the SVG containers
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent inheritance from reaching the child elements
|
||||||
|
> * {
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent inheritance from reaching the child elements
|
.text-input div {
|
||||||
> * {
|
cursor: text;
|
||||||
pointer-events: auto;
|
background: none;
|
||||||
|
border: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: visible;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
display: inline-block;
|
||||||
|
// Workaround to force Chrome to display the flashing text entry cursor when text is empty
|
||||||
|
padding-left: 1px;
|
||||||
|
margin-left: -1px;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border: none;
|
||||||
|
outline: none; // Ok for contenteditable element
|
||||||
|
margin: -1px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-input div {
|
.graph-view {
|
||||||
cursor: text;
|
pointer-events: none;
|
||||||
background: none;
|
transition: opacity 0.1s ease-in-out;
|
||||||
border: none;
|
opacity: 0;
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
overflow: visible;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
display: inline-block;
|
|
||||||
// Workaround to force Chrome to display the flashing text entry cursor when text is empty
|
|
||||||
padding-left: 1px;
|
|
||||||
margin-left: -1px;
|
|
||||||
|
|
||||||
&:focus {
|
&.open {
|
||||||
border: none;
|
cursor: auto;
|
||||||
outline: none; // Ok for contenteditable element
|
pointer-events: auto;
|
||||||
margin: -1px;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: var(--color-2-mildblack);
|
||||||
|
opacity: var(--fade-artwork);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-artwork,
|
||||||
|
.graph {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -2,7 +2,6 @@
|
||||||
import Document from "@graphite/components/panels/Document.svelte";
|
import Document from "@graphite/components/panels/Document.svelte";
|
||||||
import IconButton from "@graphite/components/widgets/buttons/IconButton.svelte";
|
import IconButton from "@graphite/components/widgets/buttons/IconButton.svelte";
|
||||||
import LayerTree from "@graphite/components/panels/LayerTree.svelte";
|
import LayerTree from "@graphite/components/panels/LayerTree.svelte";
|
||||||
import NodeGraph from "@graphite/components/panels/NodeGraph.svelte";
|
|
||||||
import PopoverButton from "@graphite/components/widgets/buttons/PopoverButton.svelte";
|
import PopoverButton from "@graphite/components/widgets/buttons/PopoverButton.svelte";
|
||||||
import Properties from "@graphite/components/panels/Properties.svelte";
|
import Properties from "@graphite/components/panels/Properties.svelte";
|
||||||
import TextButton from "@graphite/components/widgets/buttons/TextButton.svelte";
|
import TextButton from "@graphite/components/widgets/buttons/TextButton.svelte";
|
||||||
|
|
@ -10,7 +9,6 @@
|
||||||
const PANEL_COMPONENTS = {
|
const PANEL_COMPONENTS = {
|
||||||
Document,
|
Document,
|
||||||
LayerTree,
|
LayerTree,
|
||||||
NodeGraph,
|
|
||||||
Properties,
|
Properties,
|
||||||
};
|
};
|
||||||
type PanelTypes = keyof typeof PANEL_COMPONENTS;
|
type PanelTypes = keyof typeof PANEL_COMPONENTS;
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,7 @@
|
||||||
const PANEL_SIZES = {
|
const PANEL_SIZES = {
|
||||||
/**/ root: 100,
|
/**/ root: 100,
|
||||||
/* ├── */ content: 80,
|
/* ├── */ content: 80,
|
||||||
/* │ ├── */ document: 50,
|
/* │ ├── */ document: 100,
|
||||||
/* │ └── */ graph: 50,
|
|
||||||
/* └── */ details: 20,
|
/* └── */ details: 20,
|
||||||
/* ├── */ properties: 45,
|
/* ├── */ properties: 45,
|
||||||
/* └── */ layers: 55,
|
/* └── */ layers: 55,
|
||||||
|
|
@ -111,12 +110,6 @@
|
||||||
bind:this={documentPanel}
|
bind:this={documentPanel}
|
||||||
/>
|
/>
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
{#if $portfolio.documents.length > 0}
|
|
||||||
<LayoutRow class="workspace-grid-resize-gutter" data-gutter-vertical on:pointerdown={resizePanel} />
|
|
||||||
<LayoutRow class="workspace-grid-subdivision" styles={{ "flex-grow": panelSizes["graph"] }} data-subdivision-name="graph">
|
|
||||||
<Panel panelType="NodeGraph" tabLabels={[{ name: "Node Graph" }]} tabActiveIndex={0} />
|
|
||||||
</LayoutRow>
|
|
||||||
{/if}
|
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
<LayoutCol class="workspace-grid-resize-gutter" data-gutter-horizontal on:pointerdown={(e) => resizePanel(e)} />
|
<LayoutCol class="workspace-grid-resize-gutter" data-gutter-horizontal on:pointerdown={(e) => resizePanel(e)} />
|
||||||
<LayoutCol class="workspace-grid-subdivision" styles={{ "flex-grow": panelSizes["details"] }} data-subdivision-name="details">
|
<LayoutCol class="workspace-grid-subdivision" styles={{ "flex-grow": panelSizes["details"] }} data-subdivision-name="details">
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ export function createInputManager(editor: Editor, dialog: DialogState, document
|
||||||
if (await shouldRedirectKeyboardEventToBackend(e)) {
|
if (await shouldRedirectKeyboardEventToBackend(e)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const modifiers = makeKeyboardModifiersBitfield(e);
|
const modifiers = makeKeyboardModifiersBitfield(e);
|
||||||
editor.instance.onKeyDown(key, modifiers);
|
editor.instance.onKeyDown(key, modifiers, e.repeat);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,7 +118,7 @@ export function createInputManager(editor: Editor, dialog: DialogState, document
|
||||||
if (await shouldRedirectKeyboardEventToBackend(e)) {
|
if (await shouldRedirectKeyboardEventToBackend(e)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const modifiers = makeKeyboardModifiersBitfield(e);
|
const modifiers = makeKeyboardModifiersBitfield(e);
|
||||||
editor.instance.onKeyUp(key, modifiers);
|
editor.instance.onKeyUp(key, modifiers, e.repeat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ import {
|
||||||
UpdateToolOptionsLayout,
|
UpdateToolOptionsLayout,
|
||||||
UpdateToolShelfLayout,
|
UpdateToolShelfLayout,
|
||||||
UpdateWorkingColorsLayout,
|
UpdateWorkingColorsLayout,
|
||||||
|
UpdateGraphViewOverlayButtonLayout,
|
||||||
|
UpdateNodeGraphBarLayout,
|
||||||
} from "@graphite/wasm-communication/messages";
|
} from "@graphite/wasm-communication/messages";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||||
|
|
@ -21,7 +23,9 @@ export function createDocumentState(editor: Editor) {
|
||||||
toolOptionsLayout: defaultWidgetLayout(),
|
toolOptionsLayout: defaultWidgetLayout(),
|
||||||
documentBarLayout: defaultWidgetLayout(),
|
documentBarLayout: defaultWidgetLayout(),
|
||||||
toolShelfLayout: defaultWidgetLayout(),
|
toolShelfLayout: defaultWidgetLayout(),
|
||||||
|
graphViewOverlayButtonLayout: defaultWidgetLayout(),
|
||||||
workingColorsLayout: defaultWidgetLayout(),
|
workingColorsLayout: defaultWidgetLayout(),
|
||||||
|
nodeGraphBarLayout: defaultWidgetLayout(),
|
||||||
});
|
});
|
||||||
const { subscribe, update } = state;
|
const { subscribe, update } = state;
|
||||||
|
|
||||||
|
|
@ -62,6 +66,14 @@ export function createDocumentState(editor: Editor) {
|
||||||
return state;
|
return state;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
editor.subscriptions.subscribeJsMessage(UpdateGraphViewOverlayButtonLayout, async (updateGraphViewOverlayButtonLayout) => {
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
update((state) => {
|
||||||
|
patchWidgetLayout(state.graphViewOverlayButtonLayout, updateGraphViewOverlayButtonLayout);
|
||||||
|
return state;
|
||||||
|
});
|
||||||
|
});
|
||||||
editor.subscriptions.subscribeJsMessage(UpdateWorkingColorsLayout, async (updateWorkingColorsLayout) => {
|
editor.subscriptions.subscribeJsMessage(UpdateWorkingColorsLayout, async (updateWorkingColorsLayout) => {
|
||||||
await tick();
|
await tick();
|
||||||
|
|
||||||
|
|
@ -71,6 +83,14 @@ export function createDocumentState(editor: Editor) {
|
||||||
return state;
|
return state;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
editor.subscriptions.subscribeJsMessage(UpdateNodeGraphBarLayout, (updateNodeGraphBarLayout) => {
|
||||||
|
update((state) => {
|
||||||
|
patchWidgetLayout(state.nodeGraphBarLayout, updateNodeGraphBarLayout);
|
||||||
|
return state;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Other
|
||||||
editor.subscriptions.subscribeJsMessage(TriggerRefreshBoundsOfViewports, async () => {
|
editor.subscriptions.subscribeJsMessage(TriggerRefreshBoundsOfViewports, async () => {
|
||||||
// Wait to display the unpopulated document panel (missing: tools, options bar content, scrollbar positioning, and canvas)
|
// Wait to display the unpopulated document panel (missing: tools, options bar content, scrollbar positioning, and canvas)
|
||||||
await tick();
|
await tick();
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,7 @@ import {
|
||||||
type FrontendNodeType,
|
type FrontendNodeType,
|
||||||
UpdateNodeGraph,
|
UpdateNodeGraph,
|
||||||
UpdateNodeTypes,
|
UpdateNodeTypes,
|
||||||
UpdateNodeGraphBarLayout,
|
|
||||||
UpdateZoomWithScroll,
|
UpdateZoomWithScroll,
|
||||||
defaultWidgetLayout,
|
|
||||||
patchWidgetLayout,
|
|
||||||
} from "@graphite/wasm-communication/messages";
|
} from "@graphite/wasm-communication/messages";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||||
|
|
@ -20,7 +17,6 @@ export function createNodeGraphState(editor: Editor) {
|
||||||
nodes: [] as FrontendNode[],
|
nodes: [] as FrontendNode[],
|
||||||
links: [] as FrontendNodeLink[],
|
links: [] as FrontendNodeLink[],
|
||||||
nodeTypes: [] as FrontendNodeType[],
|
nodeTypes: [] as FrontendNodeType[],
|
||||||
nodeGraphBarLayout: defaultWidgetLayout(),
|
|
||||||
zoomWithScroll: false as boolean,
|
zoomWithScroll: false as boolean,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -38,12 +34,6 @@ export function createNodeGraphState(editor: Editor) {
|
||||||
return state;
|
return state;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
editor.subscriptions.subscribeJsMessage(UpdateNodeGraphBarLayout, (updateNodeGraphBarLayout) => {
|
|
||||||
update((state) => {
|
|
||||||
patchWidgetLayout(state.nodeGraphBarLayout, updateNodeGraphBarLayout);
|
|
||||||
return state;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
editor.subscriptions.subscribeJsMessage(UpdateZoomWithScroll, (updateZoomWithScroll) => {
|
editor.subscriptions.subscribeJsMessage(UpdateZoomWithScroll, (updateZoomWithScroll) => {
|
||||||
update((state) => {
|
update((state) => {
|
||||||
state.zoomWithScroll = updateZoomWithScroll.zoomWithScroll;
|
state.zoomWithScroll = updateZoomWithScroll.zoomWithScroll;
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,8 @@ import FlipHorizontal from "@graphite-frontend/assets/icon-16px-solid/flip-horiz
|
||||||
import FlipVertical from "@graphite-frontend/assets/icon-16px-solid/flip-vertical.svg";
|
import FlipVertical from "@graphite-frontend/assets/icon-16px-solid/flip-vertical.svg";
|
||||||
import Folder from "@graphite-frontend/assets/icon-16px-solid/folder.svg";
|
import Folder from "@graphite-frontend/assets/icon-16px-solid/folder.svg";
|
||||||
import GraphiteLogo from "@graphite-frontend/assets/icon-16px-solid/graphite-logo.svg";
|
import GraphiteLogo from "@graphite-frontend/assets/icon-16px-solid/graphite-logo.svg";
|
||||||
|
import GraphViewClosed from "@graphite-frontend/assets/icon-16px-solid/graph-view-closed.svg";
|
||||||
|
import GraphViewOpen from "@graphite-frontend/assets/icon-16px-solid/graph-view-open.svg";
|
||||||
import Layer from "@graphite-frontend/assets/icon-16px-solid/layer.svg";
|
import Layer from "@graphite-frontend/assets/icon-16px-solid/layer.svg";
|
||||||
import NodeArtboard from "@graphite-frontend/assets/icon-16px-solid/node-artboard.svg";
|
import NodeArtboard from "@graphite-frontend/assets/icon-16px-solid/node-artboard.svg";
|
||||||
import NodeBlur from "@graphite-frontend/assets/icon-16px-solid/node-blur.svg";
|
import NodeBlur from "@graphite-frontend/assets/icon-16px-solid/node-blur.svg";
|
||||||
|
|
@ -166,6 +168,8 @@ const SOLID_16PX = {
|
||||||
FlipVertical: { svg: FlipVertical, size: 16 },
|
FlipVertical: { svg: FlipVertical, size: 16 },
|
||||||
Folder: { svg: Folder, size: 16 },
|
Folder: { svg: Folder, size: 16 },
|
||||||
GraphiteLogo: { svg: GraphiteLogo, size: 16 },
|
GraphiteLogo: { svg: GraphiteLogo, size: 16 },
|
||||||
|
GraphViewClosed: { svg: GraphViewClosed, size: 16 },
|
||||||
|
GraphViewOpen: { svg: GraphViewOpen, size: 16 },
|
||||||
Layer: { svg: Layer, size: 16 },
|
Layer: { svg: Layer, size: 16 },
|
||||||
NodeArtboard: { svg: NodeArtboard, size: 16 },
|
NodeArtboard: { svg: NodeArtboard, size: 16 },
|
||||||
NodeBlur: { svg: NodeBlur, size: 16 },
|
NodeBlur: { svg: NodeBlur, size: 16 },
|
||||||
|
|
|
||||||
|
|
@ -725,6 +725,10 @@ export class TriggerFontLoad extends JsMessage {
|
||||||
isDefault!: boolean;
|
isDefault!: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class TriggerGraphViewOverlay extends JsMessage {
|
||||||
|
open!: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export class TriggerVisitLink extends JsMessage {
|
export class TriggerVisitLink extends JsMessage {
|
||||||
url!: string;
|
url!: string;
|
||||||
}
|
}
|
||||||
|
|
@ -1199,7 +1203,7 @@ export function defaultWidgetLayout(): WidgetLayout {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates a widget layout based on a list of updates, returning the new layout
|
// Updates a widget layout based on a list of updates, giving the new layout by mutating the `layout` argument
|
||||||
export function patchWidgetLayout(/* mut */ layout: WidgetLayout, updates: WidgetDiffUpdate): void {
|
export function patchWidgetLayout(/* mut */ layout: WidgetLayout, updates: WidgetDiffUpdate): void {
|
||||||
layout.layoutTarget = updates.layoutTarget;
|
layout.layoutTarget = updates.layoutTarget;
|
||||||
|
|
||||||
|
|
@ -1300,24 +1304,15 @@ function createLayoutGroup(layoutGroup: any): LayoutGroup {
|
||||||
// WIDGET LAYOUTS
|
// WIDGET LAYOUTS
|
||||||
export class UpdateDialogDetails extends WidgetDiffUpdate { }
|
export class UpdateDialogDetails extends WidgetDiffUpdate { }
|
||||||
|
|
||||||
export class UpdateDocumentModeLayout extends WidgetDiffUpdate { }
|
|
||||||
|
|
||||||
export class UpdateToolOptionsLayout extends WidgetDiffUpdate { }
|
|
||||||
|
|
||||||
export class UpdateDocumentBarLayout extends WidgetDiffUpdate { }
|
export class UpdateDocumentBarLayout extends WidgetDiffUpdate { }
|
||||||
|
|
||||||
export class UpdateToolShelfLayout extends WidgetDiffUpdate { }
|
export class UpdateDocumentModeLayout extends WidgetDiffUpdate { }
|
||||||
|
|
||||||
export class UpdateWorkingColorsLayout extends WidgetDiffUpdate { }
|
export class UpdateGraphViewOverlayButtonLayout extends WidgetDiffUpdate { }
|
||||||
|
|
||||||
export class UpdatePropertyPanelOptionsLayout extends WidgetDiffUpdate { }
|
|
||||||
|
|
||||||
export class UpdatePropertyPanelSectionsLayout extends WidgetDiffUpdate { }
|
|
||||||
|
|
||||||
export class UpdateLayerTreeOptionsLayout extends WidgetDiffUpdate { }
|
export class UpdateLayerTreeOptionsLayout extends WidgetDiffUpdate { }
|
||||||
|
|
||||||
export class UpdateNodeGraphBarLayout extends WidgetDiffUpdate { }
|
// Extends JsMessage instead of WidgetDiffUpdate because the menu bar isn't diffed
|
||||||
|
|
||||||
export class UpdateMenuBarLayout extends JsMessage {
|
export class UpdateMenuBarLayout extends JsMessage {
|
||||||
layoutTarget!: unknown;
|
layoutTarget!: unknown;
|
||||||
|
|
||||||
|
|
@ -1327,6 +1322,18 @@ export class UpdateMenuBarLayout extends JsMessage {
|
||||||
layout!: MenuBarEntry[];
|
layout!: MenuBarEntry[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class UpdateNodeGraphBarLayout extends WidgetDiffUpdate { }
|
||||||
|
|
||||||
|
export class UpdatePropertyPanelOptionsLayout extends WidgetDiffUpdate { }
|
||||||
|
|
||||||
|
export class UpdatePropertyPanelSectionsLayout extends WidgetDiffUpdate { }
|
||||||
|
|
||||||
|
export class UpdateToolOptionsLayout extends WidgetDiffUpdate { }
|
||||||
|
|
||||||
|
export class UpdateToolShelfLayout extends WidgetDiffUpdate { }
|
||||||
|
|
||||||
|
export class UpdateWorkingColorsLayout extends WidgetDiffUpdate { }
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function createMenuLayout(menuBarEntry: any[]): MenuBarEntry[] {
|
function createMenuLayout(menuBarEntry: any[]): MenuBarEntry[] {
|
||||||
return menuBarEntry.map((entry) => ({
|
return menuBarEntry.map((entry) => ({
|
||||||
|
|
@ -1364,6 +1371,7 @@ export const messageMakers: Record<string, MessageMaker> = {
|
||||||
TriggerDownloadRaster,
|
TriggerDownloadRaster,
|
||||||
TriggerDownloadTextFile,
|
TriggerDownloadTextFile,
|
||||||
TriggerFontLoad,
|
TriggerFontLoad,
|
||||||
|
TriggerGraphViewOverlay,
|
||||||
TriggerImport,
|
TriggerImport,
|
||||||
TriggerIndexedDbRemoveDocument,
|
TriggerIndexedDbRemoveDocument,
|
||||||
TriggerIndexedDbWriteDocument,
|
TriggerIndexedDbWriteDocument,
|
||||||
|
|
@ -1382,17 +1390,18 @@ export const messageMakers: Record<string, MessageMaker> = {
|
||||||
UpdateActiveDocument,
|
UpdateActiveDocument,
|
||||||
UpdateDialogDetails,
|
UpdateDialogDetails,
|
||||||
UpdateDocumentArtboards,
|
UpdateDocumentArtboards,
|
||||||
UpdateDocumentNodeRender,
|
|
||||||
UpdateDocumentArtwork,
|
UpdateDocumentArtwork,
|
||||||
UpdateDocumentBarLayout,
|
UpdateDocumentBarLayout,
|
||||||
UpdateDocumentLayerDetails,
|
UpdateDocumentLayerDetails,
|
||||||
UpdateDocumentLayerTreeStructureJs: newUpdateDocumentLayerTreeStructure,
|
UpdateDocumentLayerTreeStructureJs: newUpdateDocumentLayerTreeStructure,
|
||||||
UpdateDocumentModeLayout,
|
UpdateDocumentModeLayout,
|
||||||
|
UpdateDocumentNodeRender,
|
||||||
UpdateDocumentOverlays,
|
UpdateDocumentOverlays,
|
||||||
UpdateDocumentRulers,
|
UpdateDocumentRulers,
|
||||||
UpdateDocumentScrollbars,
|
UpdateDocumentScrollbars,
|
||||||
UpdateDocumentTransform,
|
UpdateDocumentTransform,
|
||||||
UpdateEyedropperSamplingState,
|
UpdateEyedropperSamplingState,
|
||||||
|
UpdateGraphViewOverlayButtonLayout,
|
||||||
UpdateImageData,
|
UpdateImageData,
|
||||||
UpdateInputHints,
|
UpdateInputHints,
|
||||||
UpdateLayerTreeOptionsLayout,
|
UpdateLayerTreeOptionsLayout,
|
||||||
|
|
|
||||||
|
|
@ -420,25 +420,25 @@ impl JsEditorHandle {
|
||||||
|
|
||||||
/// A keyboard button depressed within screenspace the bounds of the viewport
|
/// A keyboard button depressed within screenspace the bounds of the viewport
|
||||||
#[wasm_bindgen(js_name = onKeyDown)]
|
#[wasm_bindgen(js_name = onKeyDown)]
|
||||||
pub fn on_key_down(&self, name: String, modifiers: u8) {
|
pub fn on_key_down(&self, name: String, modifiers: u8, key_repeat: bool) {
|
||||||
let key = translate_key(&name);
|
let key = translate_key(&name);
|
||||||
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
||||||
|
|
||||||
trace!("Key down {:?}, name: {}, modifiers: {:?}", key, name, modifiers);
|
trace!("Key down {:?}, name: {}, modifiers: {:?}, key repeat: {}", key, name, modifiers, key_repeat);
|
||||||
|
|
||||||
let message = InputPreprocessorMessage::KeyDown { key, modifier_keys };
|
let message = InputPreprocessorMessage::KeyDown { key, key_repeat, modifier_keys };
|
||||||
self.dispatch(message);
|
self.dispatch(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A keyboard button released
|
/// A keyboard button released
|
||||||
#[wasm_bindgen(js_name = onKeyUp)]
|
#[wasm_bindgen(js_name = onKeyUp)]
|
||||||
pub fn on_key_up(&self, name: String, modifiers: u8) {
|
pub fn on_key_up(&self, name: String, modifiers: u8, key_repeat: bool) {
|
||||||
let key = translate_key(&name);
|
let key = translate_key(&name);
|
||||||
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
||||||
|
|
||||||
trace!("Key up {:?}, name: {}, modifiers: {:?}", key, name, modifier_keys);
|
trace!("Key up {:?}, name: {}, modifiers: {:?}, key repeat: {}", key, name, modifier_keys, key_repeat);
|
||||||
|
|
||||||
let message = InputPreprocessorMessage::KeyUp { key, modifier_keys };
|
let message = InputPreprocessorMessage::KeyUp { key, key_repeat, modifier_keys };
|
||||||
self.dispatch(message);
|
self.dispatch(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue