mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Implement closing the current, and all, documents from the menu bar (#265)
Closes #261 Additional cleanup and refactoring with the way the backend relays the list of open documents to the frontend and prompts for confirmation.
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
use crate::{consts::ROTATE_SNAP_INTERVAL, frontend::layer_panel::*, EditorError};
|
||||
use document_core::{document::Document as InteralDocument, layers::Layer, LayerId};
|
||||
use document_core::{document::Document as InternalDocument, layers::Layer, LayerId};
|
||||
use glam::{DAffine2, DVec2};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Document {
|
||||
pub document: InteralDocument,
|
||||
pub document: InternalDocument,
|
||||
pub name: String,
|
||||
pub layer_data: HashMap<Vec<LayerId>, LayerData>,
|
||||
}
|
||||
@@ -14,7 +14,7 @@ pub struct Document {
|
||||
impl Default for Document {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
document: InteralDocument::default(),
|
||||
document: InternalDocument::default(),
|
||||
name: String::from("Untitled Document"),
|
||||
layer_data: vec![(vec![], LayerData::new(true))].into_iter().collect(),
|
||||
}
|
||||
@@ -24,7 +24,7 @@ impl Default for Document {
|
||||
impl Document {
|
||||
pub fn with_name(name: String) -> Self {
|
||||
Self {
|
||||
document: InteralDocument::default(),
|
||||
document: InternalDocument::default(),
|
||||
name,
|
||||
layer_data: vec![(vec![], LayerData::new(true))].into_iter().collect(),
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ pub enum DocumentMessage {
|
||||
ToggleLayerExpansion(Vec<LayerId>),
|
||||
SelectDocument(usize),
|
||||
CloseDocument(usize),
|
||||
CloseActiveDocument,
|
||||
CloseActiveDocumentWithConfirmation,
|
||||
CloseAllDocumentsWithConfirmation,
|
||||
CloseAllDocuments,
|
||||
NewDocument,
|
||||
NextDocument,
|
||||
PrevDocument,
|
||||
@@ -187,14 +189,27 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
||||
responses.push_back(FrontendMessage::SetActiveDocument { document_index: self.active_document }.into());
|
||||
responses.push_back(RenderDocument.into());
|
||||
}
|
||||
CloseActiveDocument => {
|
||||
responses.push_back(FrontendMessage::PromptCloseConfirmationModal.into());
|
||||
CloseActiveDocumentWithConfirmation => {
|
||||
responses.push_back(FrontendMessage::PromptConfirmationToCloseDocument { document_index: self.active_document }.into());
|
||||
}
|
||||
CloseAllDocumentsWithConfirmation => {
|
||||
responses.push_back(FrontendMessage::PromptConfirmationToCloseAllDocuments.into());
|
||||
}
|
||||
CloseAllDocuments => {
|
||||
// Empty the list of internal document data
|
||||
self.documents.clear();
|
||||
|
||||
// Create a new blank document
|
||||
responses.push_back(DocumentMessage::NewDocument.into());
|
||||
}
|
||||
CloseDocument(id) => {
|
||||
assert!(id < self.documents.len(), "Tried to select a document that was not initialized");
|
||||
// Remove doc from the backend store. Use 'id' as FE tabs and BE documents will be in sync.
|
||||
// Remove doc from the backend store; use `id` as client tabs and backend documents will be in sync
|
||||
self.documents.remove(id);
|
||||
responses.push_back(FrontendMessage::CloseDocument { document_index: id }.into());
|
||||
|
||||
// Send the new list of document tab names
|
||||
let open_documents = self.documents.iter().map(|doc| doc.name.clone()).collect();
|
||||
responses.push_back(FrontendMessage::UpdateOpenDocumentsList { open_documents }.into());
|
||||
|
||||
// Last tab was closed, so create a new blank tab
|
||||
if self.documents.is_empty() {
|
||||
@@ -254,12 +269,10 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
||||
self.active_document = self.documents.len();
|
||||
let new_document = Document::with_name(name);
|
||||
self.documents.push(new_document);
|
||||
responses.push_back(
|
||||
FrontendMessage::NewDocument {
|
||||
document_name: self.active_document().name.clone(),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
// Send the new list of document tab names
|
||||
let open_documents = self.documents.iter().map(|doc| doc.name.clone()).collect();
|
||||
responses.push_back(FrontendMessage::UpdateOpenDocumentsList { open_documents }.into());
|
||||
|
||||
responses.push_back(
|
||||
FrontendMessage::ExpandFolder {
|
||||
@@ -280,7 +293,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
||||
}
|
||||
ExportDocument => responses.push_back(
|
||||
FrontendMessage::ExportDocument {
|
||||
//TODO: Add canvas size instead of using 1080p per default
|
||||
//TODO: Add canvas size instead of using 1920x1080 by default
|
||||
document: format!(
|
||||
r#"<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 1080">{}{}</svg>"#,
|
||||
"\n",
|
||||
@@ -513,14 +526,45 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
||||
}
|
||||
}
|
||||
fn actions(&self) -> ActionList {
|
||||
let mut common = actions!(DocumentMessageDiscriminant; Undo, SelectAllLayers, DeselectAllLayers, RenderDocument, ExportDocument, NewDocument, CloseActiveDocument, NextDocument, PrevDocument, MouseMove, TranslateCanvasEnd, TranslateCanvasBegin, PasteLayers, RotateCanvasBegin, ZoomCanvasBegin, SetCanvasZoom, MultiplyCanvasZoom, SetRotation, WheelCanvasZoom, WheelCanvasTranslate);
|
||||
let mut common = actions!(DocumentMessageDiscriminant;
|
||||
Undo,
|
||||
SelectAllLayers,
|
||||
DeselectAllLayers,
|
||||
RenderDocument,
|
||||
ExportDocument,
|
||||
NewDocument,
|
||||
CloseActiveDocumentWithConfirmation,
|
||||
CloseAllDocumentsWithConfirmation,
|
||||
CloseAllDocuments,
|
||||
NextDocument,
|
||||
PrevDocument,
|
||||
MouseMove,
|
||||
TranslateCanvasEnd,
|
||||
TranslateCanvasBegin,
|
||||
PasteLayers,
|
||||
RotateCanvasBegin,
|
||||
ZoomCanvasBegin,
|
||||
SetCanvasZoom,
|
||||
MultiplyCanvasZoom,
|
||||
SetRotation,
|
||||
WheelCanvasZoom,
|
||||
WheelCanvasTranslate,
|
||||
);
|
||||
|
||||
if self.active_document().layer_data.values().any(|data| data.selected) {
|
||||
let select = actions!(DocumentMessageDiscriminant; DeleteSelectedLayers, DuplicateSelectedLayers, CopySelectedLayers, NudgeSelectedLayers );
|
||||
let select = actions!(DocumentMessageDiscriminant;
|
||||
DeleteSelectedLayers,
|
||||
DuplicateSelectedLayers,
|
||||
CopySelectedLayers,
|
||||
NudgeSelectedLayers,
|
||||
);
|
||||
common.extend(select);
|
||||
}
|
||||
if self.rotating {
|
||||
let snapping = actions!(DocumentMessageDiscriminant; EnableSnapping, DisableSnapping);
|
||||
let snapping = actions!(DocumentMessageDiscriminant;
|
||||
EnableSnapping,
|
||||
DisableSnapping,
|
||||
);
|
||||
common.extend(snapping);
|
||||
}
|
||||
common
|
||||
|
||||
@@ -12,14 +12,14 @@ pub enum FrontendMessage {
|
||||
ExpandFolder { path: Vec<LayerId>, children: Vec<LayerPanelEntry> },
|
||||
SetActiveTool { tool_name: String },
|
||||
SetActiveDocument { document_index: usize },
|
||||
CloseDocument { document_index: usize },
|
||||
NewDocument { document_name: String },
|
||||
UpdateOpenDocumentsList { open_documents: Vec<String> },
|
||||
PromptConfirmationToCloseDocument { document_index: usize },
|
||||
PromptConfirmationToCloseAllDocuments,
|
||||
UpdateCanvas { document: String },
|
||||
ExportDocument { document: String },
|
||||
EnableTextInput,
|
||||
DisableTextInput,
|
||||
UpdateWorkingColors { primary: Color, secondary: Color },
|
||||
PromptCloseConfirmationModal,
|
||||
SetCanvasZoom { new_zoom: f64 },
|
||||
SetRotation { new_radians: f64 },
|
||||
}
|
||||
@@ -44,7 +44,6 @@ impl MessageHandler<FrontendMessage, ()> for FrontendMessageHandler {
|
||||
CollapseFolder,
|
||||
ExpandFolder,
|
||||
SetActiveTool,
|
||||
NewDocument,
|
||||
UpdateCanvas,
|
||||
EnableTextInput,
|
||||
DisableTextInput,
|
||||
|
||||
@@ -204,9 +204,11 @@ impl Default for Mapping {
|
||||
entry! {action=DocumentMessage::WheelCanvasZoom, message=InputMapperMessage::MouseScroll, modifiers=[KeyControl]},
|
||||
entry! {action=DocumentMessage::WheelCanvasTranslate{use_y_as_x: true}, message=InputMapperMessage::MouseScroll, modifiers=[KeyShift]},
|
||||
entry! {action=DocumentMessage::WheelCanvasTranslate{use_y_as_x: false}, message=InputMapperMessage::MouseScroll},
|
||||
entry! {action=DocumentMessage::NewDocument, key_down=KeyN, modifiers=[KeyShift]},
|
||||
entry! {action=DocumentMessage::NextDocument, key_down=KeyTab, modifiers=[KeyShift]},
|
||||
entry! {action=DocumentMessage::CloseActiveDocument, key_down=KeyW, modifiers=[KeyShift]},
|
||||
entry! {action=DocumentMessage::NewDocument, key_down=KeyN, modifiers=[KeyControl]},
|
||||
entry! {action=DocumentMessage::NextDocument, key_down=KeyTab, modifiers=[KeyControl]},
|
||||
entry! {action=DocumentMessage::PrevDocument, key_down=KeyTab, modifiers=[KeyControl, KeyShift]},
|
||||
entry! {action=DocumentMessage::CloseAllDocumentsWithConfirmation, key_down=KeyW, modifiers=[KeyControl, KeyAlt]}, // TODO: Fix this, it's matching the one below
|
||||
entry! {action=DocumentMessage::CloseActiveDocumentWithConfirmation, key_down=KeyW, modifiers=[KeyControl]},
|
||||
entry! {action=DocumentMessage::DuplicateSelectedLayers, key_down=KeyD, modifiers=[KeyControl]},
|
||||
entry! {action=DocumentMessage::CopySelectedLayers, key_down=KeyC, modifiers=[KeyControl]},
|
||||
entry! {action=DocumentMessage::NudgeSelectedLayers(-SHIFT_NUDGE_AMOUNT, -SHIFT_NUDGE_AMOUNT), key_down=KeyArrowUp, modifiers=[KeyShift, KeyArrowLeft]},
|
||||
|
||||
Reference in New Issue
Block a user