mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-20 03:18:06 +08:00
Implement the Text Tool and text layer MVP (#492)
* Add text tool * Double click with the select tool to edit text * Fix (I think?) transitioning to select tool * Commit and abort text editing * Transition to a contenteditable div and autosize * Fix right click blocking * Cleanup hints * Ctrl + enter leaves text edit mode * Render indervidual bounding boxes for text * Re-format space indents * Reflect font size in the textarea * Fix change tool behaviour * Remove starting text * Populate the cache (caused doc load bug) * Remove console log * Chrome display the flashing text entry cursor * Update overlay on input * Cleanup input.ts * Fix bounding boxes * Apply review feedback * Remove manual test * Remove svg from gitignore Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
committed by
Keavon Chambers
parent
0da8dabba9
commit
a66920aa1c
@@ -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};
|
||||
@@ -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()
|
||||
@@ -170,7 +170,7 @@ impl DocumentMessageHandler {
|
||||
path,
|
||||
segments,
|
||||
transform: viewport_transform,
|
||||
closed: shape.closed,
|
||||
closed,
|
||||
})
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
@@ -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);
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user