Add support for clicking checkboxes via their labels (#2667)

This commit is contained in:
Keavon Chambers
2025-05-24 04:46:15 -07:00
committed by GitHub
parent 80f38d91c0
commit c4678336e5
13 changed files with 320 additions and 163 deletions
@@ -5,6 +5,8 @@ use graphene_core::Color;
use graphene_core::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)]
@@ -18,6 +20,9 @@ pub struct CheckboxInput {
pub tooltip: String,
#[serde(rename = "forLabel", skip_serializing_if = "checkbox_id_is_empty")]
pub for_label: CheckboxId,
#[serde(skip)]
pub tooltip_shortcut: Option<ActionKeys>,
@@ -39,12 +44,51 @@ impl Default for CheckboxInput {
icon: "Checkmark".into(),
tooltip: Default::default(),
tooltip_shortcut: Default::default(),
for_label: CheckboxId::default(),
on_update: Default::default(),
on_commit: Default::default(),
}
}
}
#[derive(Clone, Default, Debug, Eq, PartialEq)]
pub struct CheckboxId(Arc<OnceCell<u64>>);
impl CheckboxId {
pub fn fill(&mut self) {
let _ = self.0.set(graphene_core::uuid::generate_uuid());
}
}
impl specta::Type for CheckboxId {
fn inline(_type_map: &mut specta::TypeCollection, _generics: specta::Generics) -> specta::datatype::DataType {
// TODO: This might not be right, but it works for now. We just need the type `bigint | undefined`.
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 id = u64::deserialize(deserializer)?;
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)]
pub struct DropdownInput {
@@ -1,3 +1,4 @@
use super::input_widgets::CheckboxId;
use derivative::*;
use graphite_proc_macros::WidgetBuilder;
@@ -56,9 +57,21 @@ pub struct TextLabel {
pub tooltip: String,
#[serde(rename = "checkboxId")]
#[widget_builder(skip)]
pub checkbox_id: 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