mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-19 02:48:12 +08:00
Add new icons to all menu bar entries
This commit is contained in:
@@ -211,10 +211,18 @@ impl Dispatcher {
|
||||
let ipp = &self.message_handlers.input_preprocessor_message_handler;
|
||||
let preferences = &self.message_handlers.preferences_message_handler;
|
||||
let current_tool = &self.message_handlers.tool_message_handler.tool_state.tool_data.active_tool_type;
|
||||
let message_logging_verbosity = self.message_handlers.debug_message_handler.message_logging_verbosity;
|
||||
|
||||
self.message_handlers
|
||||
.portfolio_message_handler
|
||||
.process_message(message, &mut queue, PortfolioMessageData { ipp, preferences, current_tool });
|
||||
self.message_handlers.portfolio_message_handler.process_message(
|
||||
message,
|
||||
&mut queue,
|
||||
PortfolioMessageData {
|
||||
ipp,
|
||||
preferences,
|
||||
current_tool,
|
||||
message_logging_verbosity,
|
||||
},
|
||||
);
|
||||
}
|
||||
Message::Preferences(message) => {
|
||||
self.message_handlers.preferences_message_handler.process_message(message, &mut queue, ());
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum MessageLoggingVerbosity {
|
||||
#[default]
|
||||
Off,
|
||||
|
||||
@@ -30,25 +30,25 @@ impl LayoutHolder for DemoArtworkDialog {
|
||||
let mut rows_of_images_with_buttons: Vec<_> = ARTWORK
|
||||
.chunks(3)
|
||||
.flat_map(|chunk| {
|
||||
let images = chunk.iter().map(|(_, thumbnail, _)| ImageLabel::new(*thumbnail).width(Some("256px".into())).widget_holder()).collect();
|
||||
fn make_dialog(name: &str, filename: &str) -> Message {
|
||||
DialogMessage::CloseDialogAndThen {
|
||||
followups: vec![FrontendMessage::TriggerFetchAndOpenDocument {
|
||||
name: name.to_string(),
|
||||
filename: filename.to_string(),
|
||||
}
|
||||
.into()],
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
let images = chunk
|
||||
.iter()
|
||||
.map(|(name, thumbnail, filename)| ImageButton::new(*thumbnail).width(Some("256px".into())).on_update(|_| make_dialog(name, filename)).widget_holder())
|
||||
.collect();
|
||||
|
||||
let buttons = chunk
|
||||
.iter()
|
||||
.map(|(name, _, filename)| {
|
||||
TextButton::new(*name)
|
||||
.min_width(256)
|
||||
.on_update(|_| {
|
||||
DialogMessage::CloseDialogAndThen {
|
||||
followups: vec![FrontendMessage::TriggerFetchAndOpenDocument {
|
||||
name: name.to_string(),
|
||||
filename: filename.to_string(),
|
||||
}
|
||||
.into()],
|
||||
}
|
||||
.into()
|
||||
})
|
||||
.widget_holder()
|
||||
})
|
||||
.map(|(name, _, filename)| TextButton::new(*name).min_width(256).flush(true).on_update(|_| make_dialog(name, filename)).widget_holder())
|
||||
.collect();
|
||||
|
||||
vec![LayoutGroup::Row { widgets: images }, LayoutGroup::Row { widgets: buttons }, LayoutGroup::Row { widgets: vec![] }]
|
||||
|
||||
@@ -201,10 +201,18 @@ impl LayoutMessageHandler {
|
||||
WidgetValueAction::Commit => (icon_button.on_commit.callback)(&()),
|
||||
WidgetValueAction::Update => (icon_button.on_update.callback)(icon_button),
|
||||
};
|
||||
|
||||
responses.add(callback_message);
|
||||
}
|
||||
Widget::ImageButton(image_label) => {
|
||||
let callback_message = match action {
|
||||
WidgetValueAction::Commit => (image_label.on_commit.callback)(&()),
|
||||
WidgetValueAction::Update => (image_label.on_update.callback)(&()),
|
||||
};
|
||||
|
||||
responses.add(callback_message);
|
||||
}
|
||||
Widget::IconLabel(_) => {}
|
||||
Widget::ImageLabel(_) => {}
|
||||
Widget::InvisibleStandinInput(invisible) => {
|
||||
let callback_message = match action {
|
||||
WidgetValueAction::Commit => (invisible.on_commit.callback)(&()),
|
||||
|
||||
@@ -333,7 +333,7 @@ impl LayoutGroup {
|
||||
Widget::FontInput(x) => &mut x.tooltip,
|
||||
Widget::IconButton(x) => &mut x.tooltip,
|
||||
Widget::IconLabel(x) => &mut x.tooltip,
|
||||
Widget::ImageLabel(x) => &mut x.tooltip,
|
||||
Widget::ImageButton(x) => &mut x.tooltip,
|
||||
Widget::NumberInput(x) => &mut x.tooltip,
|
||||
Widget::ParameterExposeButton(x) => &mut x.tooltip,
|
||||
Widget::PopoverButton(x) => &mut x.tooltip,
|
||||
@@ -504,7 +504,7 @@ pub enum Widget {
|
||||
FontInput(FontInput),
|
||||
IconButton(IconButton),
|
||||
IconLabel(IconLabel),
|
||||
ImageLabel(ImageLabel),
|
||||
ImageButton(ImageButton),
|
||||
InvisibleStandinInput(InvisibleStandinInput),
|
||||
NodeCatalog(NodeCatalog),
|
||||
NumberInput(NumberInput),
|
||||
@@ -579,8 +579,8 @@ impl DiffUpdate {
|
||||
Widget::ParameterExposeButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
|
||||
Widget::PopoverButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
|
||||
Widget::TextButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
|
||||
Widget::ImageButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
|
||||
Widget::IconLabel(_)
|
||||
| Widget::ImageLabel(_)
|
||||
| Widget::CurveInput(_)
|
||||
| Widget::InvisibleStandinInput(_)
|
||||
| Widget::NodeCatalog(_)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||
use crate::messages::portfolio::document::node_graph::utility_types::FrontendGraphDataType;
|
||||
use crate::messages::tool::tool_messages::tool_prelude::WidgetCallback;
|
||||
|
||||
use graphene_std::vector::style::FillChoice;
|
||||
use graphite_proc_macros::WidgetBuilder;
|
||||
@@ -120,6 +121,31 @@ pub struct TextButton {
|
||||
pub on_commit: WidgetCallback<()>,
|
||||
}
|
||||
|
||||
#[derive(Clone, serde::Serialize, serde::Deserialize, Derivative, Default, WidgetBuilder, specta::Type)]
|
||||
#[derivative(Debug, PartialEq)]
|
||||
pub struct ImageButton {
|
||||
#[widget_builder(constructor)]
|
||||
pub image: String,
|
||||
|
||||
pub width: Option<String>,
|
||||
|
||||
pub height: Option<String>,
|
||||
|
||||
pub tooltip: String,
|
||||
|
||||
#[serde(skip)]
|
||||
pub tooltip_shortcut: Option<ActionKeys>,
|
||||
|
||||
// Callbacks
|
||||
#[serde(skip)]
|
||||
#[derivative(Debug = "ignore", PartialEq = "ignore")]
|
||||
pub on_update: WidgetCallback<()>,
|
||||
|
||||
#[serde(skip)]
|
||||
#[derivative(Debug = "ignore", PartialEq = "ignore")]
|
||||
pub on_commit: WidgetCallback<()>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Derivative, serde::Serialize, serde::Deserialize, WidgetBuilder, specta::Type)]
|
||||
#[derivative(Debug, PartialEq, Default)]
|
||||
pub struct ColorButton {
|
||||
|
||||
@@ -11,18 +11,6 @@ pub struct IconLabel {
|
||||
pub tooltip: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, serde::Serialize, serde::Deserialize, Derivative, Debug, Default, PartialEq, Eq, WidgetBuilder, specta::Type)]
|
||||
pub struct ImageLabel {
|
||||
#[widget_builder(constructor)]
|
||||
pub image: String,
|
||||
|
||||
pub width: Option<String>,
|
||||
|
||||
pub height: Option<String>,
|
||||
|
||||
pub tooltip: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, WidgetBuilder, specta::Type)]
|
||||
pub struct Separator {
|
||||
pub direction: SeparatorDirection,
|
||||
@@ -55,6 +43,9 @@ pub struct TextLabel {
|
||||
|
||||
pub italic: bool,
|
||||
|
||||
#[serde(rename = "centerAlign")]
|
||||
pub center_align: bool,
|
||||
|
||||
#[serde(rename = "tableAlign")]
|
||||
pub table_align: bool,
|
||||
|
||||
|
||||
@@ -37,10 +37,9 @@ pub enum DocumentMessage {
|
||||
axis: AlignAxis,
|
||||
aggregate: AlignAggregate,
|
||||
},
|
||||
ClearArtboards,
|
||||
RemoveArtboards,
|
||||
ClearLayersPanel,
|
||||
CreateEmptyFolder,
|
||||
DebugPrintDocument,
|
||||
DeleteNode {
|
||||
node_id: NodeId,
|
||||
},
|
||||
|
||||
@@ -272,8 +272,8 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
||||
});
|
||||
}
|
||||
}
|
||||
DocumentMessage::ClearArtboards => {
|
||||
responses.add(GraphOperationMessage::ClearArtboards);
|
||||
DocumentMessage::RemoveArtboards => {
|
||||
responses.add(GraphOperationMessage::RemoveArtboards);
|
||||
}
|
||||
DocumentMessage::ClearLayersPanel => {
|
||||
// Send an empty layer list
|
||||
@@ -305,9 +305,6 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
||||
});
|
||||
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![id] });
|
||||
}
|
||||
DocumentMessage::DebugPrintDocument => {
|
||||
info!("{:?}", self.network_interface);
|
||||
}
|
||||
DocumentMessage::DeleteNode { node_id } => {
|
||||
responses.add(DocumentMessage::StartTransaction);
|
||||
|
||||
@@ -1337,7 +1334,6 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
||||
fn actions(&self) -> ActionList {
|
||||
let mut common = actions!(DocumentMessageDiscriminant;
|
||||
CreateEmptyFolder,
|
||||
DebugPrintDocument,
|
||||
DeselectAllLayers,
|
||||
GraphViewOverlayToggle,
|
||||
Noop,
|
||||
|
||||
@@ -103,7 +103,7 @@ pub enum GraphOperationMessage {
|
||||
location: IVec2,
|
||||
dimensions: IVec2,
|
||||
},
|
||||
ClearArtboards,
|
||||
RemoveArtboards,
|
||||
NewSvg {
|
||||
id: NodeId,
|
||||
svg: String,
|
||||
|
||||
@@ -202,7 +202,7 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageData<'_>> for Gr
|
||||
modify_inputs.resize_artboard(location, dimensions);
|
||||
}
|
||||
}
|
||||
GraphOperationMessage::ClearArtboards => {
|
||||
GraphOperationMessage::RemoveArtboards => {
|
||||
if network_interface.all_artboards().is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::messages::debug::utility_types::MessageLoggingVerbosity;
|
||||
use crate::messages::input_mapper::utility_types::macros::action_keys;
|
||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
|
||||
@@ -10,6 +11,8 @@ pub struct MenuBarMessageData {
|
||||
pub node_graph_open: bool,
|
||||
pub has_selected_nodes: bool,
|
||||
pub has_selected_layers: bool,
|
||||
pub has_selection_history: (bool, bool),
|
||||
pub message_logging_verbosity: MessageLoggingVerbosity,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
@@ -19,6 +22,8 @@ pub struct MenuBarMessageHandler {
|
||||
node_graph_open: bool,
|
||||
has_selected_nodes: bool,
|
||||
has_selected_layers: bool,
|
||||
has_selection_history: (bool, bool),
|
||||
message_logging_verbosity: MessageLoggingVerbosity,
|
||||
}
|
||||
|
||||
impl MessageHandler<MenuBarMessage, MenuBarMessageData> for MenuBarMessageHandler {
|
||||
@@ -29,12 +34,16 @@ impl MessageHandler<MenuBarMessage, MenuBarMessageData> for MenuBarMessageHandle
|
||||
node_graph_open,
|
||||
has_selected_nodes,
|
||||
has_selected_layers,
|
||||
has_selection_history,
|
||||
message_logging_verbosity,
|
||||
} = data;
|
||||
self.has_active_document = has_active_document;
|
||||
self.rulers_visible = rulers_visible;
|
||||
self.node_graph_open = node_graph_open;
|
||||
self.has_selected_nodes = has_selected_nodes;
|
||||
self.has_selected_layers = has_selected_layers;
|
||||
self.has_selection_history = has_selection_history;
|
||||
self.message_logging_verbosity = message_logging_verbosity;
|
||||
|
||||
match message {
|
||||
MenuBarMessage::SendLayout => self.send_layout(responses, LayoutTarget::MenuBar),
|
||||
@@ -52,6 +61,10 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
let node_graph_open = self.node_graph_open;
|
||||
let has_selected_nodes = self.has_selected_nodes;
|
||||
let has_selected_layers = self.has_selected_layers;
|
||||
let has_selection_history = self.has_selection_history;
|
||||
let message_logging_verbosity_off = self.message_logging_verbosity == MessageLoggingVerbosity::Off;
|
||||
let message_logging_verbosity_names = self.message_logging_verbosity == MessageLoggingVerbosity::Names;
|
||||
let message_logging_verbosity_contents = self.message_logging_verbosity == MessageLoggingVerbosity::Contents;
|
||||
|
||||
let menu_bar_entries = vec![
|
||||
MenuBarEntry {
|
||||
@@ -89,6 +102,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Close".into(),
|
||||
icon: Some("Close".into()),
|
||||
shortcut: action_keys!(PortfolioMessageDiscriminant::CloseActiveDocumentWithConfirmation),
|
||||
action: MenuBarEntry::create_action(|_| PortfolioMessage::CloseActiveDocumentWithConfirmation.into()),
|
||||
disabled: no_active_document,
|
||||
@@ -96,6 +110,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Close All".into(),
|
||||
icon: Some("CloseAll".into()),
|
||||
shortcut: action_keys!(PortfolioMessageDiscriminant::CloseAllDocumentsWithConfirmation),
|
||||
action: MenuBarEntry::create_action(|_| PortfolioMessage::CloseAllDocumentsWithConfirmation.into()),
|
||||
disabled: no_active_document,
|
||||
@@ -104,6 +119,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
],
|
||||
vec![MenuBarEntry {
|
||||
label: "Save".into(),
|
||||
icon: Some("Save".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SaveDocument),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SaveDocument.into()),
|
||||
disabled: no_active_document,
|
||||
@@ -112,12 +128,14 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Import…".into(),
|
||||
icon: Some("FileImport".into()),
|
||||
shortcut: action_keys!(PortfolioMessageDiscriminant::Import),
|
||||
action: MenuBarEntry::create_action(|_| PortfolioMessage::Import.into()),
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Export…".into(),
|
||||
icon: Some("FileExport".into()),
|
||||
shortcut: action_keys!(DialogMessageDiscriminant::RequestExportDialog),
|
||||
action: MenuBarEntry::create_action(|_| DialogMessage::RequestExportDialog.into()),
|
||||
disabled: no_active_document,
|
||||
@@ -140,6 +158,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Undo".into(),
|
||||
icon: Some("HistoryUndo".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::Undo),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::Undo.into()),
|
||||
disabled: no_active_document,
|
||||
@@ -147,6 +166,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Redo".into(),
|
||||
icon: Some("HistoryRedo".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::Redo),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::Redo.into()),
|
||||
disabled: no_active_document,
|
||||
@@ -179,51 +199,28 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
],
|
||||
vec![MenuBarEntry {
|
||||
label: "Remove Artboards".into(),
|
||||
icon: Some("Artboard".into()),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::RemoveArtboards.into()),
|
||||
disabled: no_active_document,
|
||||
..MenuBarEntry::default()
|
||||
}],
|
||||
]),
|
||||
),
|
||||
MenuBarEntry::new_root(
|
||||
"Layer".into(),
|
||||
no_active_document,
|
||||
MenuBarEntryChildren(vec![
|
||||
vec![MenuBarEntry {
|
||||
label: "New".into(),
|
||||
icon: Some("NewLayer".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::CreateEmptyFolder),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::CreateEmptyFolder.into()),
|
||||
disabled: no_active_document,
|
||||
..MenuBarEntry::default()
|
||||
}],
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Select All".into(),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectAllLayers),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectAllLayers.into()),
|
||||
label: "New Layer".into(),
|
||||
icon: Some("NewLayer".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::CreateEmptyFolder),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::CreateEmptyFolder.into()),
|
||||
disabled: no_active_document,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Deselect All".into(),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::DeselectAllLayers),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::DeselectAllLayers.into()),
|
||||
disabled: no_active_document || !has_selected_nodes,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
],
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Previous Selection".into(),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectionStepBack),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectionStepBack.into()),
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Next Selection".into(),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectionStepForward),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectionStepForward.into()),
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
],
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Group Selected".into(),
|
||||
icon: Some("Folder".into()),
|
||||
@@ -246,9 +243,44 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
],
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Select All".into(),
|
||||
icon: Some("SelectAll".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectAllLayers),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectAllLayers.into()),
|
||||
disabled: no_active_document,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Deselect All".into(),
|
||||
icon: Some("DeselectAll".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::DeselectAllLayers),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::DeselectAllLayers.into()),
|
||||
disabled: no_active_document || !has_selected_nodes,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Previous Selection".into(),
|
||||
icon: Some("HistoryUndo".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectionStepBack),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectionStepBack.into()),
|
||||
disabled: !has_selection_history.0,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Next Selection".into(),
|
||||
icon: Some("HistoryRedo".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectionStepForward),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectionStepForward.into()),
|
||||
disabled: !has_selection_history.1,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
],
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Grab Selected".into(),
|
||||
icon: Some("TransformationGrab".into()),
|
||||
shortcut: action_keys!(TransformLayerMessageDiscriminant::BeginGrab),
|
||||
action: MenuBarEntry::create_action(|_| TransformLayerMessage::BeginGrab.into()),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
@@ -256,6 +288,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Rotate Selected".into(),
|
||||
icon: Some("TransformationRotate".into()),
|
||||
shortcut: action_keys!(TransformLayerMessageDiscriminant::BeginRotate),
|
||||
action: MenuBarEntry::create_action(|_| TransformLayerMessage::BeginRotate.into()),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
@@ -263,6 +296,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Scale Selected".into(),
|
||||
icon: Some("TransformationScale".into()),
|
||||
shortcut: action_keys!(TransformLayerMessageDiscriminant::BeginScale),
|
||||
action: MenuBarEntry::create_action(|_| TransformLayerMessage::BeginScale.into()),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
@@ -271,52 +305,57 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
],
|
||||
vec![MenuBarEntry {
|
||||
label: "Order".into(),
|
||||
icon: Some("StackHollow".into()),
|
||||
action: MenuBarEntry::no_action(),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
children: MenuBarEntryChildren(vec![vec![
|
||||
MenuBarEntry {
|
||||
label: "Raise To Front".into(),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectedLayersRaiseToFront),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectedLayersRaiseToFront.into()),
|
||||
children: MenuBarEntryChildren(vec![
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Raise To Front".into(),
|
||||
icon: Some("Stack".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectedLayersRaiseToFront),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectedLayersRaiseToFront.into()),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Raise".into(),
|
||||
icon: Some("StackRaise".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectedLayersRaise),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectedLayersRaise.into()),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Lower".into(),
|
||||
icon: Some("StackLower".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectedLayersLower),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectedLayersLower.into()),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Lower to Back".into(),
|
||||
icon: Some("StackBottom".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectedLayersLowerToBack),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectedLayersLowerToBack.into()),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
],
|
||||
vec![MenuBarEntry {
|
||||
label: "Reverse".into(),
|
||||
icon: Some("StackReverse".into()),
|
||||
// shortcut: action_keys!(DocumentMessageDiscriminant::SelectedLayersReverse),
|
||||
action: MenuBarEntry::create_action(|_| DialogMessage::RequestComingSoonDialog { issue: Some(2271) }.into()),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Raise".into(),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectedLayersRaise),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectedLayersRaise.into()),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Lower".into(),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectedLayersLower),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectedLayersLower.into()),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Lower to Back".into(),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::SelectedLayersLowerToBack),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::SelectedLayersLowerToBack.into()),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
]]),
|
||||
}],
|
||||
]),
|
||||
..MenuBarEntry::default()
|
||||
}],
|
||||
]),
|
||||
),
|
||||
MenuBarEntry::new_root(
|
||||
"Document".into(),
|
||||
no_active_document,
|
||||
MenuBarEntryChildren(vec![vec![MenuBarEntry {
|
||||
label: "Clear Artboards".into(),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::ClearArtboards.into()),
|
||||
disabled: no_active_document,
|
||||
..MenuBarEntry::default()
|
||||
}]]),
|
||||
),
|
||||
MenuBarEntry::new_root(
|
||||
"View".into(),
|
||||
no_active_document,
|
||||
@@ -324,6 +363,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Tilt".into(),
|
||||
icon: Some("Tilt".into()),
|
||||
shortcut: action_keys!(NavigationMessageDiscriminant::BeginCanvasTilt),
|
||||
action: MenuBarEntry::create_action(|_| NavigationMessage::BeginCanvasTilt { was_dispatched_from_menu: true }.into()),
|
||||
disabled: no_active_document || node_graph_open,
|
||||
@@ -331,6 +371,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Reset Tilt".into(),
|
||||
icon: Some("TiltReset".into()),
|
||||
shortcut: action_keys!(NavigationMessageDiscriminant::CanvasTiltSet),
|
||||
action: MenuBarEntry::create_action(|_| NavigationMessage::CanvasTiltSet { angle_radians: 0.into() }.into()),
|
||||
disabled: no_active_document || node_graph_open,
|
||||
@@ -354,10 +395,9 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
disabled: no_active_document,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
],
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Zoom to Fit Selection".into(),
|
||||
icon: Some("FrameSelected".into()),
|
||||
shortcut: action_keys!(NavigationMessageDiscriminant::FitViewportToSelection),
|
||||
action: MenuBarEntry::create_action(|_| NavigationMessage::FitViewportToSelection.into()),
|
||||
disabled: no_active_document || !has_selected_layers,
|
||||
@@ -365,6 +405,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Zoom to Fit All".into(),
|
||||
icon: Some("FrameAll".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::ZoomCanvasToFitAll),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::ZoomCanvasToFitAll.into()),
|
||||
disabled: no_active_document,
|
||||
@@ -372,6 +413,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Zoom to 100%".into(),
|
||||
icon: Some("Zoom1x".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::ZoomCanvasTo100Percent),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::ZoomCanvasTo100Percent.into()),
|
||||
disabled: no_active_document,
|
||||
@@ -379,6 +421,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Zoom to 200%".into(),
|
||||
icon: Some("Zoom2x".into()),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::ZoomCanvasTo200Percent),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::ZoomCanvasTo200Percent.into()),
|
||||
disabled: no_active_document,
|
||||
@@ -407,6 +450,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
}],
|
||||
vec![MenuBarEntry {
|
||||
label: "User Manual".into(),
|
||||
icon: Some("UserManual".into()),
|
||||
action: MenuBarEntry::create_action(|_| {
|
||||
FrontendMessage::TriggerVisitLink {
|
||||
url: "https://graphite.rs/learn/".into(),
|
||||
@@ -418,6 +462,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Report a Bug".into(),
|
||||
icon: Some("Bug".into()),
|
||||
action: MenuBarEntry::create_action(|_| {
|
||||
FrontendMessage::TriggerVisitLink {
|
||||
url: "https://github.com/GraphiteEditor/Graphite/issues/new".into(),
|
||||
@@ -428,6 +473,7 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Visit on GitHub".into(),
|
||||
icon: Some("Website".into()),
|
||||
action: MenuBarEntry::create_action(|_| {
|
||||
FrontendMessage::TriggerVisitLink {
|
||||
url: "https://github.com/GraphiteEditor/Graphite".into(),
|
||||
@@ -437,50 +483,49 @@ impl LayoutHolder for MenuBarMessageHandler {
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
],
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Debug: Print Messages".into(),
|
||||
action: MenuBarEntry::no_action(),
|
||||
children: MenuBarEntryChildren(vec![vec![
|
||||
vec![MenuBarEntry {
|
||||
label: "Developer Debug".into(),
|
||||
icon: Some("Code".into()),
|
||||
action: MenuBarEntry::no_action(),
|
||||
children: MenuBarEntryChildren(vec![
|
||||
vec![MenuBarEntry {
|
||||
label: "Print Trace Logs".into(),
|
||||
icon: Some(if log::max_level() == log::LevelFilter::Trace { "CheckboxChecked" } else { "CheckboxUnchecked" }.into()),
|
||||
action: MenuBarEntry::create_action(|_| DebugMessage::ToggleTraceLogs.into()),
|
||||
..MenuBarEntry::default()
|
||||
}],
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Off".into(),
|
||||
// icon: Some("Checkmark".into()), // TODO: Find a way to set this icon on the active mode
|
||||
label: "Print Messages: Off".into(),
|
||||
icon: message_logging_verbosity_off.then_some("SmallDot".into()),
|
||||
shortcut: action_keys!(DebugMessageDiscriminant::MessageOff),
|
||||
action: MenuBarEntry::create_action(|_| DebugMessage::MessageOff.into()),
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Only Names".into(),
|
||||
label: "Print Messages: Only Names".into(),
|
||||
icon: message_logging_verbosity_names.then_some("SmallDot".into()),
|
||||
shortcut: action_keys!(DebugMessageDiscriminant::MessageNames),
|
||||
action: MenuBarEntry::create_action(|_| DebugMessage::MessageNames.into()),
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Full Contents".into(),
|
||||
label: "Print Messages: Full Contents".into(),
|
||||
icon: message_logging_verbosity_contents.then_some("SmallDot".into()),
|
||||
shortcut: action_keys!(DebugMessageDiscriminant::MessageContents),
|
||||
action: MenuBarEntry::create_action(|_| DebugMessage::MessageContents.into()),
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
]]),
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Debug: Print Trace Logs".into(),
|
||||
icon: Some(if log::max_level() == log::LevelFilter::Trace { "CheckboxChecked" } else { "CheckboxUnchecked" }.into()),
|
||||
action: MenuBarEntry::create_action(|_| DebugMessage::ToggleTraceLogs.into()),
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Debug: Print Document".into(),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::DebugPrintDocument.into()),
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Debug: Panic (DANGER)".into(),
|
||||
action: MenuBarEntry::create_action(|_| panic!()),
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
],
|
||||
],
|
||||
vec![MenuBarEntry {
|
||||
label: "Trigger a Crash".into(),
|
||||
icon: Some("Warning".into()),
|
||||
action: MenuBarEntry::create_action(|_| panic!()),
|
||||
..MenuBarEntry::default()
|
||||
}],
|
||||
]),
|
||||
..MenuBarEntry::default()
|
||||
}],
|
||||
]),
|
||||
),
|
||||
];
|
||||
|
||||
@@ -3,6 +3,7 @@ use super::document::utility_types::network_interface::{self, InputConnector, Ou
|
||||
use super::utility_types::{PanelType, PersistentData};
|
||||
use crate::application::generate_uuid;
|
||||
use crate::consts::DEFAULT_DOCUMENT_NAME;
|
||||
use crate::messages::debug::utility_types::MessageLoggingVerbosity;
|
||||
use crate::messages::dialog::simple_dialogs;
|
||||
use crate::messages::frontend::utility_types::FrontendDocumentDetails;
|
||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||
@@ -28,6 +29,7 @@ pub struct PortfolioMessageData<'a> {
|
||||
pub ipp: &'a InputPreprocessorMessageHandler,
|
||||
pub preferences: &'a PreferencesMessageHandler,
|
||||
pub current_tool: &'a ToolType,
|
||||
pub message_logging_verbosity: MessageLoggingVerbosity,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@@ -45,7 +47,12 @@ pub struct PortfolioMessageHandler {
|
||||
|
||||
impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMessageHandler {
|
||||
fn process_message(&mut self, message: PortfolioMessage, responses: &mut VecDeque<Message>, data: PortfolioMessageData) {
|
||||
let PortfolioMessageData { ipp, preferences, current_tool } = data;
|
||||
let PortfolioMessageData {
|
||||
ipp,
|
||||
preferences,
|
||||
current_tool,
|
||||
message_logging_verbosity,
|
||||
} = data;
|
||||
|
||||
match message {
|
||||
// Sub-messages
|
||||
@@ -55,6 +62,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
|
||||
let mut node_graph_open = false;
|
||||
let mut has_selected_nodes = false;
|
||||
let mut has_selected_layers = false;
|
||||
let mut has_selection_history = (false, false);
|
||||
|
||||
if let Some(document) = self.active_document_id.and_then(|document_id| self.documents.get_mut(&document_id)) {
|
||||
has_active_document = true;
|
||||
@@ -63,6 +71,14 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
|
||||
let selected_nodes = document.network_interface.selected_nodes(&[]).unwrap();
|
||||
has_selected_nodes = selected_nodes.selected_nodes().next().is_some();
|
||||
has_selected_layers = selected_nodes.selected_visible_layers(&document.network_interface).next().is_some();
|
||||
has_selection_history = document
|
||||
.network_interface
|
||||
.network_metadata(&[])
|
||||
.map(|metadata| {
|
||||
let metadata = &metadata.persistent_metadata;
|
||||
(!metadata.selection_undo_history.is_empty(), !metadata.selection_redo_history.is_empty())
|
||||
})
|
||||
.unwrap_or((false, false));
|
||||
}
|
||||
self.menu_bar_message_handler.process_message(
|
||||
message,
|
||||
@@ -73,6 +89,8 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
|
||||
node_graph_open,
|
||||
has_selected_nodes,
|
||||
has_selected_layers,
|
||||
has_selection_history,
|
||||
message_logging_verbosity,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user