Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e26fb6c
Add text tool
0HyperCube Jan 22, 2022
ef874f8
Merge branch 'master' into add-text-tool
0HyperCube Jan 23, 2022
009e3ac
Double click with the select tool to edit text
0HyperCube Jan 24, 2022
d0cb6e4
Merge branch 'master' into add-text-tool
0HyperCube Jan 24, 2022
bfacd20
Fix (I think?) transitioning to select tool
0HyperCube Jan 24, 2022
a461640
Commit and abort text editing
0HyperCube Jan 24, 2022
03cb944
Transition to a contenteditable div and autosize
0HyperCube Jan 26, 2022
9c3e1d1
Fix right click blocking
0HyperCube Jan 26, 2022
4f8814f
Cleanup hints
0HyperCube Jan 26, 2022
59c1bfc
Ctrl + enter leaves text edit mode
0HyperCube Jan 26, 2022
e329c49
Render indervidual bounding boxes for text
0HyperCube Jan 26, 2022
92d0b1b
Re-format space indents
0HyperCube Jan 26, 2022
53a5bfb
Reflect font size in the textarea
0HyperCube Jan 26, 2022
a9cfadb
Fix change tool behaviour
0HyperCube Jan 27, 2022
c08152e
Remove starting text
0HyperCube Jan 27, 2022
f1f62d6
Populate the cache (caused doc load bug)
0HyperCube Jan 27, 2022
830ab9f
Remove console log
0HyperCube Jan 27, 2022
1fc881c
Chrome display the flashing text entry cursor
0HyperCube Jan 27, 2022
780759a
Update overlay on input
0HyperCube Jan 27, 2022
2297e36
Cleanup input.ts
0HyperCube Jan 27, 2022
4aae9c8
Fix bounding boxes
0HyperCube Jan 29, 2022
9a26a7b
Merge branch 'master' into add-text-tool
Keavon Jan 29, 2022
39adb86
Apply review feedback
0HyperCube Jan 30, 2022
36c07f5
Merge branch 'master' into add-text-tool
0HyperCube Jan 30, 2022
e2351d2
Remove manual test
0HyperCube Jan 30, 2022
140aae5
Remove svg from gitignore
0HyperCube Jan 30, 2022
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
60 changes: 60 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions editor/src/document/document_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ pub enum DocumentMessage {
SetSnapping {
snap: bool,
},
SetTexboxEditability {
path: Vec<LayerId>,
editable: bool,
},
SetViewMode {
view_mode: ViewMode,
},
Expand Down
55 changes: 39 additions & 16 deletions editor/src/document/document_message_handler.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::clipboards::Clipboard;
use super::layer_panel::{layer_panel_entry, LayerMetadata, LayerPanelEntry, RawBuffer};
use super::layer_panel::{layer_panel_entry, LayerDataTypeDiscriminant, LayerMetadata, LayerPanelEntry, RawBuffer};
use super::utility_types::{AlignAggregate, AlignAxis, DocumentSave, FlipAxis, VectorManipulatorSegment, VectorManipulatorShape};
use super::vectorize_layer_metadata;
use super::{ArtboardMessageHandler, MovementMessageHandler, OverlaysMessageHandler, TransformLayerMessageHandler};
Expand Down Expand Up @@ -146,11 +146,11 @@ impl DocumentMessageHandler {
_ => return None,
};

let shape = match &layer.ok()?.data {
LayerDataType::Shape(shape) => Some(shape),
LayerDataType::Folder(_) => None,
let (path, closed) = match &layer.ok()?.data {
LayerDataType::Shape(shape) => Some((shape.path.clone(), shape.closed)),
LayerDataType::Text(text) => Some((text.to_bez_path_nonmut(), true)),
_ => None,
}?;
let path = shape.path.clone();

let segments = path
.segments()
Expand All @@ -170,7 +170,7 @@ impl DocumentMessageHandler {
path,
segments,
transform: viewport_transform,
closed: shape.closed,
closed,
})
});

Expand Down Expand Up @@ -204,6 +204,16 @@ impl DocumentMessageHandler {
})
}

pub fn selected_visible_text_layers(&self) -> impl Iterator<Item = &[LayerId]> {
self.selected_layers().filter(|path| match self.graphene_document.layer(path) {
Ok(layer) => {
let discriminant: LayerDataTypeDiscriminant = (&layer.data).into();
layer.visible && discriminant == LayerDataTypeDiscriminant::Text
}
Err(_) => false,
})
}

pub fn visible_layers(&self) -> impl Iterator<Item = &[LayerId]> {
self.all_layers().filter(|path| match self.graphene_document.layer(path) {
Ok(layer) => layer.visible,
Expand All @@ -216,17 +226,14 @@ impl DocumentMessageHandler {
for (id, layer) in folder.layer_ids.iter().zip(folder.layers()).rev() {
data.push(*id);
space += 1;
match layer.data {
LayerDataType::Shape(_) => (),
LayerDataType::Folder(ref folder) => {
path.push(*id);
if self.layer_metadata(path).expanded {
structure.push(space);
self.serialize_structure(folder, structure, data, path);
space = 0;
}
path.pop();
if let LayerDataType::Folder(ref folder) = layer.data {
path.push(*id);
if self.layer_metadata(path).expanded {
structure.push(space);
self.serialize_structure(folder, structure, data, path);
space = 0;
}
path.pop();
}
}
structure.push(space | 1 << 63);
Expand Down Expand Up @@ -962,6 +969,22 @@ impl MessageHandler<DocumentMessage, &InputPreprocessorMessageHandler> for Docum
SetSnapping { snap } => {
self.snapping_enabled = snap;
}
SetTexboxEditability { path, editable } => {
let text = self.graphene_document.layer(&path).unwrap().as_text().unwrap();
responses.push_back(DocumentOperation::SetTextEditability { path, editable }.into());
if editable {
responses.push_back(
FrontendMessage::DisplayEditableTextbox {
text: text.text.clone(),
line_width: text.line_width,
font_size: text.size,
}
.into(),
);
} else {
responses.push_back(FrontendMessage::DisplayRemoveEditableTextbox.into());
}
}
SetViewMode { view_mode } => {
self.view_mode = view_mode;
responses.push_front(DocumentMessage::DirtyRenderDocument.into());
Expand Down
3 changes: 3 additions & 0 deletions editor/src/document/layer_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,15 @@ pub struct LayerPanelEntry {
pub enum LayerDataTypeDiscriminant {
Folder,
Shape,
Text,
}

impl fmt::Display for LayerDataTypeDiscriminant {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let name = match self {
LayerDataTypeDiscriminant::Folder => "Folder",
LayerDataTypeDiscriminant::Shape => "Shape",
LayerDataTypeDiscriminant::Text => "Text",
};

formatter.write_str(name)
Expand All @@ -117,6 +119,7 @@ impl From<&LayerDataType> for LayerDataTypeDiscriminant {
match data {
Folder(_) => LayerDataTypeDiscriminant::Folder,
Shape(_) => LayerDataTypeDiscriminant::Shape,
Text(_) => LayerDataTypeDiscriminant::Text,
}
}
}
3 changes: 3 additions & 0 deletions editor/src/frontend/frontend_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ pub enum FrontendMessage {
DisplayDialogError { title: String, description: String },
DisplayDialogPanic { panic_info: String, title: String, description: String },
DisplayDocumentLayerTreeStructure { data_buffer: RawBuffer },
DisplayEditableTextbox { text: String, line_width: Option<f64>, font_size: f64 },
DisplayRemoveEditableTextbox,

// Trigger prefix: cause a browser API to do something
TriggerFileDownload { document: String, name: String },
TriggerFileUpload,
TriggerIndexedDbRemoveDocument { document_id: u64 },
TriggerIndexedDbWriteDocument { document: String, details: FrontendDocumentDetails, version: String },
TriggerTextCommit,

// Update prefix: give the frontend a new value or state for it to use
UpdateActiveDocument { document_id: u64 },
Expand Down
1 change: 1 addition & 0 deletions editor/src/frontend/utility_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ pub enum MouseCursorIcon {
ZoomOut,
Grabbing,
Crosshair,
Text,
}
16 changes: 14 additions & 2 deletions editor/src/input/input_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub struct Mapping {
pub key_down: [KeyMappingEntries; NUMBER_OF_KEYS],
pub pointer_move: KeyMappingEntries,
pub mouse_scroll: KeyMappingEntries,
pub double_click: KeyMappingEntries,
}

impl Default for Mapping {
Expand Down Expand Up @@ -44,6 +45,7 @@ impl Default for Mapping {
entry! {action=SelectMessage::MouseMove { snap_angle: KeyShift }, message=InputMapperMessage::PointerMove},
entry! {action=SelectMessage::DragStart { add_to_selection: KeyShift }, key_down=Lmb},
entry! {action=SelectMessage::DragStop, key_up=Lmb},
entry! {action=SelectMessage::EditText, message=InputMapperMessage::DoubleClick},
entry! {action=SelectMessage::Abort, key_down=Rmb},
entry! {action=SelectMessage::Abort, key_down=KeyEscape},
// Navigate
Expand All @@ -59,6 +61,10 @@ impl Default for Mapping {
// Eyedropper
entry! {action=EyedropperMessage::LeftMouseDown, key_down=Lmb},
entry! {action=EyedropperMessage::RightMouseDown, key_down=Rmb},
// Text
entry! {action=TextMessage::Interact, key_up=Lmb},
entry! {action=TextMessage::Abort, key_down=KeyEscape},
entry! {action=TextMessage::CommitText, key_down=KeyEnter, modifiers=[KeyControl]},
// Rectangle
entry! {action=RectangleMessage::DragStart, key_down=Lmb},
entry! {action=RectangleMessage::DragStop, key_up=Lmb},
Expand Down Expand Up @@ -105,6 +111,7 @@ impl Default for Mapping {
entry! {action=ToolMessage::ActivateTool { tool_type: ToolType::Select }, key_down=KeyV},
entry! {action=ToolMessage::ActivateTool { tool_type: ToolType::Navigate }, key_down=KeyZ},
entry! {action=ToolMessage::ActivateTool { tool_type: ToolType::Eyedropper }, key_down=KeyI},
entry! {action=ToolMessage::ActivateTool { tool_type: ToolType::Text }, key_down=KeyT},
entry! {action=ToolMessage::ActivateTool { tool_type: ToolType::Fill }, key_down=KeyF},
entry! {action=ToolMessage::ActivateTool { tool_type: ToolType::Path }, key_down=KeyA},
entry! {action=ToolMessage::ActivateTool { tool_type: ToolType::Pen }, key_down=KeyP},
Expand Down Expand Up @@ -203,7 +210,7 @@ impl Default for Mapping {
entry! {action=GlobalMessage::LogDebug, key_down=Key2},
entry! {action=GlobalMessage::LogTrace, key_down=Key3},
];
let (mut key_up, mut key_down, mut pointer_move, mut mouse_scroll) = mappings;
let (mut key_up, mut key_down, mut pointer_move, mut mouse_scroll, mut double_click) = 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] = [Key0, Key1, Key2, Key3, Key4, Key5, Key6, Key7, Key8, Key9];
Expand All @@ -226,12 +233,14 @@ impl Default for Mapping {
}
sort(&mut pointer_move);
sort(&mut mouse_scroll);
sort(&mut double_click);

Self {
key_up,
key_down,
pointer_move,
mouse_scroll,
double_click,
}
}
}
Expand All @@ -243,6 +252,7 @@ impl Mapping {
let list = match message {
KeyDown(key) => &self.key_down[key as usize],
KeyUp(key) => &self.key_up[key as usize],
DoubleClick => &self.double_click,
MouseScroll => &self.mouse_scroll,
PointerMove => &self.pointer_move,
};
Expand Down Expand Up @@ -331,18 +341,20 @@ mod input_mapper_macros {
let mut key_down = KeyMappingEntries::key_array();
let mut pointer_move: KeyMappingEntries = Default::default();
let mut mouse_scroll: KeyMappingEntries = Default::default();
let mut double_click: KeyMappingEntries = Default::default();
$(
for entry in $entry {
let arr = match entry.trigger {
InputMapperMessage::KeyDown(key) => &mut key_down[key as usize],
InputMapperMessage::KeyUp(key) => &mut key_up[key as usize],
InputMapperMessage::MouseScroll => &mut mouse_scroll,
InputMapperMessage::PointerMove => &mut pointer_move,
InputMapperMessage::DoubleClick => &mut double_click,
};
arr.push(entry.clone());
}
)*
(key_up, key_down, pointer_move, mouse_scroll)
(key_up, key_down, pointer_move, mouse_scroll, double_click)
}};
}

Expand Down
1 change: 1 addition & 0 deletions editor/src/input/input_mapper_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub enum InputMapperMessage {
KeyUp(Key),

// Messages
DoubleClick,
MouseScroll,
PointerMove,
}
1 change: 1 addition & 0 deletions editor/src/input/input_preprocessor_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use serde::{Deserialize, Serialize};
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum InputPreprocessorMessage {
BoundsOfViewports { bounds_of_viewports: Vec<ViewportBounds> },
DoubleClick { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
KeyDown { key: Key, modifier_keys: ModifierKeys },
KeyUp { key: Key, modifier_keys: ModifierKeys },
MouseDown { editor_mouse_state: EditorMouseState, modifier_keys: ModifierKeys },
Expand Down
8 changes: 8 additions & 0 deletions editor/src/input/input_preprocessor_message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ impl MessageHandler<InputPreprocessorMessage, ()> for InputPreprocessorMessageHa
);
}
}
InputPreprocessorMessage::DoubleClick { editor_mouse_state, modifier_keys } => {
self.handle_modifier_keys(modifier_keys, responses);

let mouse_state = editor_mouse_state.to_mouse_state(&self.viewport_bounds);
self.mouse.position = mouse_state.position;

responses.push_back(InputMapperMessage::DoubleClick.into());
}
InputPreprocessorMessage::KeyDown { key, modifier_keys } => {
self.handle_modifier_keys(modifier_keys, responses);
self.keyboard.set(key as usize);
Expand Down
1 change: 1 addition & 0 deletions editor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ pub mod message_prelude {
pub use crate::viewport_tools::tools::rectangle::{RectangleMessage, RectangleMessageDiscriminant};
pub use crate::viewport_tools::tools::select::{SelectMessage, SelectMessageDiscriminant};
pub use crate::viewport_tools::tools::shape::{ShapeMessage, ShapeMessageDiscriminant};
pub use crate::viewport_tools::tools::text::{TextMessage, TextMessageDiscriminant};
pub use graphite_proc_macros::*;

pub use std::collections::VecDeque;
Expand Down
Loading