mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-03 20:28:12 +08:00
Make checkboxes not use interior mutability (#2976)
* Make checkboxes not use interior mutability * Use copy instead of cloning * Fix --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -5,8 +5,6 @@ use graphene_std::Color;
|
||||
use graphene_std::raster::curve::Curve;
|
||||
use graphene_std::transform::ReferencePoint;
|
||||
use graphite_proc_macros::WidgetBuilder;
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone, Derivative, serde::Serialize, serde::Deserialize, WidgetBuilder, specta::Type)]
|
||||
#[derivative(Debug, PartialEq)]
|
||||
@@ -20,7 +18,7 @@ pub struct CheckboxInput {
|
||||
|
||||
pub tooltip: String,
|
||||
|
||||
#[serde(rename = "forLabel", skip_serializing_if = "checkbox_id_is_empty")]
|
||||
#[serde(rename = "forLabel")]
|
||||
pub for_label: CheckboxId,
|
||||
|
||||
#[serde(skip)]
|
||||
@@ -44,19 +42,24 @@ impl Default for CheckboxInput {
|
||||
icon: "Checkmark".into(),
|
||||
tooltip: Default::default(),
|
||||
tooltip_shortcut: Default::default(),
|
||||
for_label: CheckboxId::default(),
|
||||
for_label: CheckboxId::new(),
|
||||
on_update: Default::default(),
|
||||
on_commit: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Debug, Eq, PartialEq)]
|
||||
pub struct CheckboxId(Arc<OnceCell<u64>>);
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct CheckboxId(u64);
|
||||
|
||||
impl CheckboxId {
|
||||
pub fn fill(&mut self) {
|
||||
let _ = self.0.set(graphene_std::uuid::generate_uuid());
|
||||
pub fn new() -> Self {
|
||||
Self(graphene_std::uuid::generate_uuid())
|
||||
}
|
||||
}
|
||||
impl Default for CheckboxId {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
impl specta::Type for CheckboxId {
|
||||
@@ -65,31 +68,6 @@ impl specta::Type for CheckboxId {
|
||||
specta::datatype::DataType::Primitive(specta::datatype::PrimitiveType::u64)
|
||||
}
|
||||
}
|
||||
impl serde::Serialize for CheckboxId {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
self.0.get().copied().serialize(serializer)
|
||||
}
|
||||
}
|
||||
impl<'a> serde::Deserialize<'a> for CheckboxId {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'a>,
|
||||
{
|
||||
let optional_id: Option<u64> = Option::deserialize(deserializer)?;
|
||||
// TODO: This is potentially weird because after deserialization the two labels will be decoupled if the value not existent
|
||||
let id = optional_id.unwrap_or(0);
|
||||
let checkbox_id = CheckboxId(OnceCell::new().into());
|
||||
checkbox_id.0.set(id).map_err(serde::de::Error::custom)?;
|
||||
Ok(checkbox_id)
|
||||
}
|
||||
}
|
||||
|
||||
fn checkbox_id_is_empty(id: &CheckboxId) -> bool {
|
||||
id.0.get().is_none()
|
||||
}
|
||||
|
||||
#[derive(Clone, serde::Serialize, serde::Deserialize, Derivative, WidgetBuilder, specta::Type)]
|
||||
#[derivative(Debug, PartialEq, Default)]
|
||||
|
||||
@@ -57,21 +57,12 @@ pub struct TextLabel {
|
||||
|
||||
pub tooltip: String,
|
||||
|
||||
#[serde(rename = "checkboxId")]
|
||||
#[widget_builder(skip)]
|
||||
pub checkbox_id: CheckboxId,
|
||||
#[serde(rename = "forCheckbox")]
|
||||
pub for_checkbox: CheckboxId,
|
||||
|
||||
// Body
|
||||
#[widget_builder(constructor)]
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl TextLabel {
|
||||
pub fn for_checkbox(mut self, id: &mut CheckboxId) -> Self {
|
||||
id.fill();
|
||||
self.checkbox_id = id.clone();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add UserInputLabel
|
||||
|
||||
Reference in New Issue
Block a user