Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 5 additions & 3 deletions editor/src/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const SIDE_EFFECT_FREE_MESSAGES: &[MessageDiscriminant] = &[
NodeGraphMessageDiscriminant::RunDocumentGraph,
))),
MessageDiscriminant::Portfolio(PortfolioMessageDiscriminant::SubmitActiveGraphRender),
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::TriggerFontLoad),
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::TriggerFontDataLoad),
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::UpdateUIScale),
];
/// Since we don't need to update the frontend multiple times per frame,
Expand All @@ -69,6 +69,7 @@ const FRONTEND_UPDATE_MESSAGES: &[MessageDiscriminant] = &[
const DEBUG_MESSAGE_BLOCK_LIST: &[MessageDiscriminant] = &[
MessageDiscriminant::Broadcast(BroadcastMessageDiscriminant::TriggerEvent(EventMessageDiscriminant::AnimationFrame)),
MessageDiscriminant::Animation(AnimationMessageDiscriminant::IncrementFrameCounter),
MessageDiscriminant::Portfolio(PortfolioMessageDiscriminant::AutoSaveAllDocuments),
];
// TODO: Find a way to combine these with the list above. We use strings for now since these are the standard variant names used by multiple messages. But having these also type-checked would be best.
const DEBUG_MESSAGE_ENDING_BLOCK_LIST: &[&str] = &["PointerMove", "PointerOutsideViewport", "Overlays", "Draw", "CurrentTime", "Time"];
Expand Down Expand Up @@ -179,7 +180,7 @@ impl Dispatcher {
}
Message::Frontend(message) => {
// Handle these messages immediately by returning early
if let FrontendMessage::TriggerFontLoad { .. } = message {
if let FrontendMessage::TriggerFontDataLoad { .. } | FrontendMessage::TriggerFontCatalogLoad = message {
self.responses.push(message);
self.cleanup_queues(false);

Expand Down Expand Up @@ -359,8 +360,9 @@ impl Dispatcher {
fn log_message(&self, message: &Message, queues: &[VecDeque<Message>], message_logging_verbosity: MessageLoggingVerbosity) {
let discriminant = MessageDiscriminant::from(message);
let is_blocked = DEBUG_MESSAGE_BLOCK_LIST.contains(&discriminant) || DEBUG_MESSAGE_ENDING_BLOCK_LIST.iter().any(|blocked_name| discriminant.local_name().ends_with(blocked_name));
let is_empty_batched = if let Message::Batched { messages } = message { messages.is_empty() } else { false };

if !is_blocked {
if !is_blocked && !is_empty_batched {
match message_logging_verbosity {
MessageLoggingVerbosity::Off => {}
MessageLoggingVerbosity::Names => {
Expand Down
11 changes: 9 additions & 2 deletions editor/src/messages/frontend/frontend_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,19 @@ pub enum FrontendMessage {
#[serde(rename = "fontSize")]
font_size: f64,
color: Color,
url: String,
#[serde(rename = "fontData")]
font_data: Vec<u8>,
transform: [f64; 6],
#[serde(rename = "maxWidth")]
max_width: Option<f64>,
#[serde(rename = "maxHeight")]
max_height: Option<f64>,
align: TextAlign,
},
DisplayEditableTextboxUpdateFontData {
#[serde(rename = "fontData")]
font_data: Vec<u8>,
},
DisplayEditableTextboxTransform {
transform: [f64; 6],
},
Expand Down Expand Up @@ -92,8 +97,10 @@ pub enum FrontendMessage {
name: String,
filename: String,
},
TriggerFontLoad {
TriggerFontCatalogLoad,
TriggerFontDataLoad {
font: Font,
url: String,
},
TriggerImport,
TriggerPersistenceRemoveDocument {
Expand Down
40 changes: 0 additions & 40 deletions editor/src/messages/layout/layout_message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*;
use graphene_std::raster::color::Color;
use graphene_std::text::Font;
use graphene_std::vector::style::{FillChoice, GradientStops};
use serde_json::Value;
use std::collections::HashMap;
Expand Down Expand Up @@ -48,7 +47,6 @@ impl MessageHandler<LayoutMessage, LayoutMessageContext<'_>> for LayoutMessageHa
}
LayoutMessage::WidgetValueUpdate { layout_target, widget_id, value } => {
self.handle_widget_callback(layout_target, widget_id, value, WidgetValueAction::Update, responses);
responses.add(LayoutMessage::ResendActiveWidget { layout_target, widget_id });
}
}
}
Expand Down Expand Up @@ -264,44 +262,6 @@ impl LayoutMessageHandler {

responses.add(callback_message);
}
Widget::FontInput(font_input) => {
let callback_message = match action {
WidgetValueAction::Commit => (font_input.on_commit.callback)(&()),
WidgetValueAction::Update => {
let Some(update_value) = value.as_object() else {
error!("FontInput update was not of type: object");
return;
};
let Some(font_family_value) = update_value.get("fontFamily") else {
error!("FontInput update does not have a fontFamily");
return;
};
let Some(font_style_value) = update_value.get("fontStyle") else {
error!("FontInput update does not have a fontStyle");
return;
};

let Some(font_family) = font_family_value.as_str() else {
error!("FontInput update fontFamily was not of type: string");
return;
};
let Some(font_style) = font_style_value.as_str() else {
error!("FontInput update fontStyle was not of type: string");
return;
};

font_input.font_family = font_family.into();
font_input.font_style = font_style.into();

responses.add(PortfolioMessage::LoadFont {
font: Font::new(font_family.into(), font_style.into()),
});
(font_input.on_update.callback)(font_input)
}
};

responses.add(callback_message);
}
Widget::IconButton(icon_button) => {
let callback_message = match action {
WidgetValueAction::Commit => (icon_button.on_commit.callback)(&()),
Expand Down
82 changes: 38 additions & 44 deletions editor/src/messages/layout/utility_types/layout_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,43 +353,7 @@ impl From<Vec<WidgetInstance>> for LayoutGroup {
}

impl LayoutGroup {
/// Applies a tooltip label to all widgets in this row or column without a tooltip.
pub fn with_tooltip_label(self, label: impl Into<String>) -> Self {
let (is_col, mut widgets) = match self {
LayoutGroup::Column { widgets } => (true, widgets),
LayoutGroup::Row { widgets } => (false, widgets),
_ => unimplemented!(),
};
let label = label.into();
for widget in &mut widgets {
let val = match &mut widget.widget {
Widget::CheckboxInput(x) => &mut x.tooltip_label,
Widget::ColorInput(x) => &mut x.tooltip_label,
Widget::CurveInput(x) => &mut x.tooltip_label,
Widget::DropdownInput(x) => &mut x.tooltip_label,
Widget::FontInput(x) => &mut x.tooltip_label,
Widget::IconButton(x) => &mut x.tooltip_label,
Widget::IconLabel(x) => &mut x.tooltip_label,
Widget::ImageButton(x) => &mut x.tooltip_label,
Widget::ImageLabel(x) => &mut x.tooltip_label,
Widget::NumberInput(x) => &mut x.tooltip_label,
Widget::ParameterExposeButton(x) => &mut x.tooltip_label,
Widget::PopoverButton(x) => &mut x.tooltip_label,
Widget::TextAreaInput(x) => &mut x.tooltip_label,
Widget::TextButton(x) => &mut x.tooltip_label,
Widget::TextInput(x) => &mut x.tooltip_label,
Widget::TextLabel(x) => &mut x.tooltip_label,
Widget::BreadcrumbTrailButtons(x) => &mut x.tooltip_label,
Widget::ReferencePointInput(_) | Widget::RadioInput(_) | Widget::Separator(_) | Widget::ShortcutLabel(_) | Widget::WorkingColorsInput(_) | Widget::NodeCatalog(_) => continue,
};
if val.is_empty() {
val.clone_from(&label);
}
}
if is_col { Self::Column { widgets } } else { Self::Row { widgets } }
}

/// Applies a tooltip description to all widgets in this row or column without a tooltip.
/// Applies a tooltip description to all widgets without a tooltip in this row or column.
pub fn with_tooltip_description(self, description: impl Into<String>) -> Self {
let (is_col, mut widgets) = match self {
LayoutGroup::Column { widgets } => (true, widgets),
Expand All @@ -403,20 +367,24 @@ impl LayoutGroup {
Widget::ColorInput(x) => &mut x.tooltip_description,
Widget::CurveInput(x) => &mut x.tooltip_description,
Widget::DropdownInput(x) => &mut x.tooltip_description,
Widget::FontInput(x) => &mut x.tooltip_description,
Widget::IconButton(x) => &mut x.tooltip_description,
Widget::IconLabel(x) => &mut x.tooltip_description,
Widget::ImageButton(x) => &mut x.tooltip_description,
Widget::ImageLabel(x) => &mut x.tooltip_description,
Widget::NumberInput(x) => &mut x.tooltip_description,
Widget::ParameterExposeButton(x) => &mut x.tooltip_description,
Widget::PopoverButton(x) => &mut x.tooltip_description,
Widget::TextAreaInput(x) => &mut x.tooltip_description,
Widget::TextButton(x) => &mut x.tooltip_description,
Widget::TextInput(x) => &mut x.tooltip_description,
Widget::TextLabel(x) => &mut x.tooltip_description,
Widget::BreadcrumbTrailButtons(x) => &mut x.tooltip_description,
Widget::ReferencePointInput(_) | Widget::RadioInput(_) | Widget::Separator(_) | Widget::ShortcutLabel(_) | Widget::WorkingColorsInput(_) | Widget::NodeCatalog(_) => continue,
Widget::ReferencePointInput(_)
| Widget::RadioInput(_)
| Widget::Separator(_)
| Widget::ShortcutLabel(_)
| Widget::WorkingColorsInput(_)
| Widget::NodeCatalog(_)
| Widget::ParameterExposeButton(_) => continue,
};
if val.is_empty() {
val.clone_from(&description);
Expand Down Expand Up @@ -727,7 +695,6 @@ pub enum Widget {
ColorInput(ColorInput),
CurveInput(CurveInput),
DropdownInput(DropdownInput),
FontInput(FontInput),
IconButton(IconButton),
IconLabel(IconLabel),
ImageButton(ImageButton),
Expand Down Expand Up @@ -782,7 +749,6 @@ impl DiffUpdate {
Widget::CheckboxInput(widget) => widget.tooltip_shortcut.as_mut(),
Widget::ColorInput(widget) => widget.tooltip_shortcut.as_mut(),
Widget::DropdownInput(widget) => widget.tooltip_shortcut.as_mut(),
Widget::FontInput(widget) => widget.tooltip_shortcut.as_mut(),
Widget::IconButton(widget) => widget.tooltip_shortcut.as_mut(),
Widget::NumberInput(widget) => widget.tooltip_shortcut.as_mut(),
Widget::ParameterExposeButton(widget) => widget.tooltip_shortcut.as_mut(),
Expand Down Expand Up @@ -838,10 +804,38 @@ impl DiffUpdate {
(recursive_wrapper.0)(entry_sections, &recursive_wrapper)
};

// Hash the menu list entry sections for caching purposes
let hash_menu_list_entry_sections = |entry_sections: &MenuListEntrySections| {
struct RecursiveHasher<'a> {
hasher: DefaultHasher,
hash_fn: &'a dyn Fn(&mut RecursiveHasher, &MenuListEntrySections),
}
let mut recursive_hasher = RecursiveHasher {
hasher: DefaultHasher::new(),
hash_fn: &|recursive_hasher, entry_sections| {
for (index, entries) in entry_sections.iter().enumerate() {
index.hash(&mut recursive_hasher.hasher);
for entry in entries {
entry.hash(&mut recursive_hasher.hasher);
(recursive_hasher.hash_fn)(recursive_hasher, &entry.children);
}
}
},
};
(recursive_hasher.hash_fn)(&mut recursive_hasher, entry_sections);
recursive_hasher.hasher.finish()
};

// Apply shortcut conversions to all widgets that have menu lists
let convert_menu_lists = |widget_instance: &mut WidgetInstance| match &mut widget_instance.widget {
Widget::DropdownInput(dropdown_input) => apply_action_shortcut_to_menu_lists(&mut dropdown_input.entries),
Widget::TextButton(text_button) => apply_action_shortcut_to_menu_lists(&mut text_button.menu_list_children),
Widget::DropdownInput(dropdown_input) => {
apply_action_shortcut_to_menu_lists(&mut dropdown_input.entries);
dropdown_input.entries_hash = hash_menu_list_entry_sections(&dropdown_input.entries);
}
Widget::TextButton(text_button) => {
apply_action_shortcut_to_menu_lists(&mut text_button.menu_list_children);
text_button.menu_list_children_hash = hash_menu_list_entry_sections(&text_button.menu_list_children);
}
_ => {}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ pub struct TextButton {
#[serde(rename = "menuListChildren")]
pub menu_list_children: MenuListEntrySections,

#[serde(rename = "menuListChildrenHash")]
#[widget_builder(skip)]
pub menu_list_children_hash: u64,

// Callbacks
#[serde(skip)]
#[derivative(Debug = "ignore", PartialEq = "ignore")]
Expand Down
51 changes: 18 additions & 33 deletions editor/src/messages/layout/utility_types/widgets/input_widgets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ pub struct DropdownInput {
#[widget_builder(constructor)]
pub entries: MenuListEntrySections,

#[serde(rename = "entriesHash")]
#[widget_builder(skip)]
pub entries_hash: u64,

// This uses `u32` instead of `usize` since it will be serialized as a normal JS number (replace this with `usize` after switching to a Rust-based GUI)
#[serde(rename = "selectedIndex")]
pub selected_index: Option<u32>,
Expand All @@ -94,6 +98,9 @@ pub struct DropdownInput {

pub narrow: bool,

#[serde(rename = "virtualScrolling")]
pub virtual_scrolling: bool,

#[serde(rename = "tooltipLabel")]
pub tooltip_label: String,

Expand Down Expand Up @@ -142,6 +149,10 @@ pub struct MenuListEntry {

pub children: MenuListEntrySections,

#[serde(rename = "childrenHash")]
#[widget_builder(skip)]
pub children_hash: u64,

// Callbacks
#[serde(skip)]
#[derivative(Debug = "ignore", PartialEq = "ignore")]
Expand All @@ -152,39 +163,13 @@ pub struct MenuListEntry {
pub on_commit: WidgetCallback<()>,
}

#[derive(Clone, serde::Serialize, serde::Deserialize, Derivative, WidgetBuilder, specta::Type)]
#[derivative(Debug, PartialEq, Default)]
pub struct FontInput {
#[serde(rename = "fontFamily")]
#[widget_builder(constructor)]
pub font_family: String,

#[serde(rename = "fontStyle")]
#[widget_builder(constructor)]
pub font_style: String,

#[serde(rename = "isStyle")]
pub is_style_picker: bool,

pub disabled: bool,

#[serde(rename = "tooltipLabel")]
pub tooltip_label: String,

#[serde(rename = "tooltipDescription")]
pub tooltip_description: String,

#[serde(rename = "tooltipShortcut")]
pub tooltip_shortcut: Option<ActionShortcut>,

// Callbacks
#[serde(skip)]
#[derivative(Debug = "ignore", PartialEq = "ignore")]
pub on_update: WidgetCallback<FontInput>,

#[serde(skip)]
#[derivative(Debug = "ignore", PartialEq = "ignore")]
pub on_commit: WidgetCallback<()>,
impl std::hash::Hash for MenuListEntry {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.value.hash(state);
self.label.hash(state);
self.icon.hash(state);
self.disabled.hash(state);
}
}

#[derive(Clone, serde::Serialize, serde::Deserialize, Derivative, WidgetBuilder, specta::Type)]
Expand Down
Loading