mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-29 01:18:11 +08:00
Use builder pattern for widgets (#941)
* Use builder pattern for widgets * Arguments to new function
This commit is contained in:
committed by
Keavon Chambers
parent
e5fcf5f2da
commit
04059f55b9
@@ -447,29 +447,16 @@ impl WidgetHolder {
|
||||
Self { widget_id: generate_uuid(), widget }
|
||||
}
|
||||
pub fn unrelated_separator() -> Self {
|
||||
WidgetHolder::new(Widget::Separator(Separator {
|
||||
separator_type: SeparatorType::Unrelated,
|
||||
direction: SeparatorDirection::Horizontal,
|
||||
}))
|
||||
Separator::new(SeparatorDirection::Horizontal, SeparatorType::Unrelated).widget_holder()
|
||||
}
|
||||
pub fn related_separator() -> Self {
|
||||
WidgetHolder::new(Widget::Separator(Separator {
|
||||
separator_type: SeparatorType::Related,
|
||||
direction: SeparatorDirection::Horizontal,
|
||||
}))
|
||||
Separator::new(SeparatorDirection::Horizontal, SeparatorType::Related).widget_holder()
|
||||
}
|
||||
pub fn text_widget(text: impl Into<String>) -> Self {
|
||||
WidgetHolder::new(Widget::TextLabel(TextLabel {
|
||||
value: text.into(),
|
||||
..Default::default()
|
||||
}))
|
||||
TextLabel::new(text).widget_holder()
|
||||
}
|
||||
pub fn bold_text(text: impl Into<String>) -> Self {
|
||||
WidgetHolder::new(Widget::TextLabel(TextLabel {
|
||||
value: text.into(),
|
||||
bold: true,
|
||||
..Default::default()
|
||||
}))
|
||||
TextLabel::new(text).bold(true).widget_holder()
|
||||
}
|
||||
/// Diffing updates self (where self is old) based on new, updating the list of modifications as it does so.
|
||||
pub fn diff(&mut self, new: Self, widget_path: &mut [usize], widget_diffs: &mut Vec<WidgetDiff>) {
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
pub mod layout_widget;
|
||||
pub mod misc;
|
||||
pub mod widgets;
|
||||
|
||||
pub mod widget_prelude {
|
||||
pub use super::layout_widget::{LayoutGroup, Widget, WidgetHolder, WidgetLayout};
|
||||
pub use super::widgets::assist_widgets::*;
|
||||
pub use super::widgets::button_widgets::*;
|
||||
pub use super::widgets::input_widgets::*;
|
||||
pub use super::widgets::label_widgets::*;
|
||||
pub use super::widgets::menu_widgets::*;
|
||||
}
|
||||
|
||||
@@ -2,13 +2,16 @@ use crate::messages::layout::utility_types::layout_widget::WidgetCallback;
|
||||
use crate::messages::{input_mapper::utility_types::misc::ActionKeys, portfolio::document::node_graph::FrontendGraphDataType};
|
||||
|
||||
use derivative::*;
|
||||
use graphite_proc_macros::WidgetBuilder;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Derivative, Serialize, Deserialize)]
|
||||
#[derive(Clone, Default, Derivative, Serialize, Deserialize, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq)]
|
||||
pub struct IconButton {
|
||||
#[widget_builder(constructor)]
|
||||
pub icon: String,
|
||||
|
||||
#[widget_builder(constructor)]
|
||||
pub size: u32, // TODO: Convert to an `IconSize` enum
|
||||
|
||||
pub disabled: bool,
|
||||
@@ -26,7 +29,7 @@ pub struct IconButton {
|
||||
pub on_update: WidgetCallback<IconButton>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq, Default)]
|
||||
pub struct PopoverButton {
|
||||
pub icon: Option<String>,
|
||||
@@ -34,9 +37,11 @@ pub struct PopoverButton {
|
||||
pub disabled: bool,
|
||||
|
||||
// Placeholder popover content heading
|
||||
#[widget_builder(constructor)]
|
||||
pub header: String,
|
||||
|
||||
// Placeholder popover content paragraph
|
||||
#[widget_builder(constructor)]
|
||||
pub text: String,
|
||||
|
||||
pub tooltip: String,
|
||||
@@ -45,7 +50,7 @@ pub struct PopoverButton {
|
||||
pub tooltip_shortcut: Option<ActionKeys>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Default)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Default, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq)]
|
||||
#[serde(rename_all(serialize = "camelCase", deserialize = "camelCase"))]
|
||||
pub struct ParameterExposeButton {
|
||||
@@ -65,10 +70,11 @@ pub struct ParameterExposeButton {
|
||||
pub on_update: WidgetCallback<ParameterExposeButton>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Default)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Default, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq)]
|
||||
#[serde(rename_all(serialize = "camelCase", deserialize = "camelCase"))]
|
||||
pub struct TextButton {
|
||||
#[widget_builder(constructor)]
|
||||
pub label: String,
|
||||
|
||||
pub icon: Option<String>,
|
||||
@@ -91,10 +97,11 @@ pub struct TextButton {
|
||||
pub on_update: WidgetCallback<TextButton>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Default)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Default, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq)]
|
||||
#[serde(rename_all(serialize = "camelCase", deserialize = "camelCase"))]
|
||||
pub struct BreadcrumbTrailButtons {
|
||||
#[widget_builder(constructor)]
|
||||
pub labels: Vec<String>,
|
||||
|
||||
pub disabled: bool,
|
||||
|
||||
@@ -2,13 +2,15 @@ use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
||||
use crate::messages::layout::utility_types::layout_widget::WidgetCallback;
|
||||
|
||||
use document_legacy::{color::Color, layers::layer_info::LayerDataTypeDiscriminant, LayerId};
|
||||
use graphite_proc_macros::WidgetBuilder;
|
||||
|
||||
use derivative::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Derivative, Serialize, Deserialize)]
|
||||
#[derive(Clone, Derivative, Serialize, Deserialize, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq)]
|
||||
pub struct CheckboxInput {
|
||||
#[widget_builder(constructor)]
|
||||
pub checked: bool,
|
||||
|
||||
pub disabled: bool,
|
||||
@@ -39,9 +41,10 @@ impl Default for CheckboxInput {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Derivative, Serialize, Deserialize)]
|
||||
#[derive(Clone, Derivative, Serialize, Deserialize, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq, Default)]
|
||||
pub struct ColorInput {
|
||||
#[widget_builder(constructor)]
|
||||
pub value: Option<Color>,
|
||||
|
||||
// TODO: Add allow_none
|
||||
@@ -62,9 +65,10 @@ pub struct ColorInput {
|
||||
pub on_update: WidgetCallback<ColorInput>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq, Default)]
|
||||
pub struct DropdownInput {
|
||||
#[widget_builder(constructor)]
|
||||
pub entries: DropdownInputEntries,
|
||||
|
||||
// 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)
|
||||
@@ -90,11 +94,13 @@ pub struct DropdownInput {
|
||||
|
||||
pub type DropdownInputEntries = Vec<Vec<DropdownEntryData>>;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Default)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Default, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq)]
|
||||
#[widget_builder(not_widget_holder)]
|
||||
pub struct DropdownEntryData {
|
||||
pub value: String,
|
||||
|
||||
#[widget_builder(constructor)]
|
||||
pub label: String,
|
||||
|
||||
pub icon: String,
|
||||
@@ -114,13 +120,15 @@ pub struct DropdownEntryData {
|
||||
pub on_update: WidgetCallback<()>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, WidgetBuilder)]
|
||||
#[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")]
|
||||
@@ -142,7 +150,7 @@ pub struct FontInput {
|
||||
/// This widget allows for the flexible use of the layout system.
|
||||
/// In a custom layout, one can define a widget that is just used to trigger code on the backend.
|
||||
/// This is used in MenuLayout to pipe the triggering of messages from the frontend to backend.
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Default)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Default, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq)]
|
||||
pub struct InvisibleStandinInput {
|
||||
#[serde(skip)]
|
||||
@@ -150,15 +158,18 @@ pub struct InvisibleStandinInput {
|
||||
pub on_update: WidgetCallback<()>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq, Default)]
|
||||
pub struct LayerReferenceInput {
|
||||
#[widget_builder(constructor)]
|
||||
pub value: Option<Vec<LayerId>>,
|
||||
|
||||
#[serde(rename = "layerName")]
|
||||
#[widget_builder(constructor)]
|
||||
pub layer_name: Option<String>,
|
||||
|
||||
#[serde(rename = "layerType")]
|
||||
#[widget_builder(constructor)]
|
||||
pub layer_type: Option<LayerDataTypeDiscriminant>,
|
||||
|
||||
pub disabled: bool,
|
||||
@@ -178,7 +189,7 @@ pub struct LayerReferenceInput {
|
||||
pub on_update: WidgetCallback<LayerReferenceInput>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq, Default)]
|
||||
pub struct NumberInput {
|
||||
// Label
|
||||
@@ -193,10 +204,13 @@ pub struct NumberInput {
|
||||
pub disabled: bool,
|
||||
|
||||
// Value
|
||||
#[widget_builder(constructor)]
|
||||
pub value: Option<f64>,
|
||||
|
||||
#[widget_builder(skip)]
|
||||
pub min: Option<f64>,
|
||||
|
||||
#[widget_builder(skip)]
|
||||
pub max: Option<f64>,
|
||||
|
||||
#[serde(rename = "isInteger")]
|
||||
@@ -247,9 +261,6 @@ pub struct NumberInput {
|
||||
}
|
||||
|
||||
impl NumberInput {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
pub fn int(mut self) -> Self {
|
||||
self.is_integer = true;
|
||||
self
|
||||
@@ -265,20 +276,8 @@ impl NumberInput {
|
||||
self.mode = NumberInputMode::Range;
|
||||
self
|
||||
}
|
||||
pub fn unit(mut self, val: impl Into<String>) -> Self {
|
||||
self.unit = val.into();
|
||||
self
|
||||
}
|
||||
pub fn dp(mut self, decimal_places: u32) -> Self {
|
||||
self.display_decimal_places = decimal_places;
|
||||
self
|
||||
}
|
||||
pub fn percentage(self) -> Self {
|
||||
self.min(0.).max(100.).unit("%").dp(2)
|
||||
}
|
||||
pub fn disabled(mut self, disabled: bool) -> Self {
|
||||
self.disabled = disabled;
|
||||
self
|
||||
self.min(0.).max(100.).unit("%").display_decimal_places(2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,13 +296,15 @@ pub enum NumberInputMode {
|
||||
Range,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Derivative, Serialize, Deserialize)]
|
||||
#[derive(Clone, Default, Derivative, Serialize, Deserialize, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq)]
|
||||
pub struct OptionalInput {
|
||||
#[widget_builder(constructor)]
|
||||
pub checked: bool,
|
||||
|
||||
pub disabled: bool,
|
||||
|
||||
#[widget_builder(constructor)]
|
||||
pub icon: String,
|
||||
|
||||
pub tooltip: String,
|
||||
@@ -317,9 +318,10 @@ pub struct OptionalInput {
|
||||
pub on_update: WidgetCallback<OptionalInput>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Derivative, Serialize, Deserialize)]
|
||||
#[derive(Clone, Default, Derivative, Serialize, Deserialize, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq)]
|
||||
pub struct RadioInput {
|
||||
#[widget_builder(constructor)]
|
||||
pub entries: Vec<RadioEntryData>,
|
||||
|
||||
pub disabled: bool,
|
||||
@@ -329,11 +331,13 @@ pub struct RadioInput {
|
||||
pub selected_index: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Derivative, Serialize, Deserialize)]
|
||||
#[derive(Clone, Default, Derivative, Serialize, Deserialize, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq)]
|
||||
#[widget_builder(not_widget_holder)]
|
||||
pub struct RadioEntryData {
|
||||
pub value: String,
|
||||
|
||||
#[widget_builder(constructor)]
|
||||
pub label: String,
|
||||
|
||||
pub icon: String,
|
||||
@@ -349,17 +353,20 @@ pub struct RadioEntryData {
|
||||
pub on_update: WidgetCallback<()>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq, Default)]
|
||||
pub struct SwatchPairInput {
|
||||
#[widget_builder(constructor)]
|
||||
pub primary: Color,
|
||||
|
||||
#[widget_builder(constructor)]
|
||||
pub secondary: Color,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq, Default)]
|
||||
pub struct TextAreaInput {
|
||||
#[widget_builder(constructor)]
|
||||
pub value: String,
|
||||
|
||||
pub label: Option<String>,
|
||||
@@ -374,9 +381,10 @@ pub struct TextAreaInput {
|
||||
pub on_update: WidgetCallback<TextAreaInput>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, WidgetBuilder)]
|
||||
#[derivative(Debug, PartialEq, Default)]
|
||||
pub struct TextInput {
|
||||
#[widget_builder(constructor)]
|
||||
pub value: String,
|
||||
|
||||
pub label: Option<String>,
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
use derivative::*;
|
||||
use graphite_proc_macros::WidgetBuilder;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Debug, Default, PartialEq, Eq)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Debug, Default, PartialEq, Eq, WidgetBuilder)]
|
||||
pub struct IconLabel {
|
||||
#[widget_builder(constructor)]
|
||||
pub icon: String,
|
||||
|
||||
pub disabled: bool,
|
||||
@@ -10,29 +12,33 @@ pub struct IconLabel {
|
||||
pub tooltip: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, WidgetBuilder)]
|
||||
pub struct Separator {
|
||||
#[widget_builder(constructor)]
|
||||
pub direction: SeparatorDirection,
|
||||
|
||||
#[serde(rename = "type")]
|
||||
#[widget_builder(constructor)]
|
||||
pub separator_type: SeparatorType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum SeparatorDirection {
|
||||
#[default]
|
||||
Horizontal,
|
||||
Vertical,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum SeparatorType {
|
||||
Related,
|
||||
#[default]
|
||||
Unrelated,
|
||||
Section,
|
||||
List,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Debug, PartialEq, Eq, Default)]
|
||||
#[derive(Clone, Serialize, Deserialize, Derivative, Debug, PartialEq, Eq, Default, WidgetBuilder)]
|
||||
pub struct TextLabel {
|
||||
pub disabled: bool,
|
||||
|
||||
@@ -51,6 +57,7 @@ pub struct TextLabel {
|
||||
pub tooltip: String,
|
||||
|
||||
// Body
|
||||
#[widget_builder(constructor)]
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user