Use builder pattern for widgets (#941)

* Use builder pattern for widgets

* Arguments to new function
This commit is contained in:
0HyperCube
2023-01-08 14:34:24 +00:00
committed by Keavon Chambers
parent e5fcf5f2da
commit 04059f55b9
8 changed files with 412 additions and 304 deletions
@@ -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,
}