From eb4a12232219955d6adaae7a63e35686bc6615a4 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Tue, 15 Sep 2026 20:12:31 -0700 Subject: [PATCH] Rename the SpectrumInput widget to SliderInput (#4541) Rename the 'SpectrumInput' widget to 'SliderInput' --- .../color_picker/color_picker_message.rs | 6 +- .../color_picker_message_handler.rs | 36 +++--- .../messages/layout/layout_message_handler.rs | 32 ++--- .../layout/utility_types/layout_widget.rs | 6 +- .../utility_types/widgets/input_widgets.rs | 22 ++-- .../document/node_graph/node_properties.rs | 122 +++++++++--------- .../floating-menus/ColorPicker.svelte | 2 +- .../src/components/widgets/WidgetSpan.svelte | 6 +- ...pectrumInput.svelte => SliderInput.svelte} | 22 ++-- 9 files changed, 127 insertions(+), 127 deletions(-) rename frontend/src/components/widgets/inputs/{SpectrumInput.svelte => SliderInput.svelte} (97%) diff --git a/editor/src/messages/color_picker/color_picker_message.rs b/editor/src/messages/color_picker/color_picker_message.rs index 0a969d581b..072a2876fc 100644 --- a/editor/src/messages/color_picker/color_picker_message.rs +++ b/editor/src/messages/color_picker/color_picker_message.rs @@ -1,4 +1,4 @@ -use crate::messages::layout::utility_types::widgets::input_widgets::{SpectrumInputUpdate, VisualColorPickersInputUpdate}; +use crate::messages::layout::utility_types::widgets::input_widgets::{SliderInputUpdate, VisualColorPickersInputUpdate}; use crate::messages::prelude::*; use graphene_std::vector::style::{FillChoice, GradientHueDirection, GradientInterpolation, GradientSpace, GradientSpread}; @@ -45,8 +45,8 @@ pub enum ColorPickerMessage { /// Swap the current "new" color with the captured "old" color. SwapNewWithOld, - /// `SpectrumInput` change: marker move/insert/delete, midpoint move/reset, or active marker selection changed. - GradientUpdate { update: SpectrumInputUpdate }, + /// `SliderInput` change: marker move/insert/delete, midpoint move/reset, or active marker selection changed. + GradientUpdate { update: SliderInputUpdate }, /// Gradient spread choice from the gradient "Ends" selection. SetGradientSpread { gradient_spread: GradientSpread }, /// Gradient cyclic choice: whether the stops wrap as a cycle, from the "Cyclic" checkbox. diff --git a/editor/src/messages/color_picker/color_picker_message_handler.rs b/editor/src/messages/color_picker/color_picker_message_handler.rs index 208fa10e9a..9ce33e5144 100644 --- a/editor/src/messages/color_picker/color_picker_message_handler.rs +++ b/editor/src/messages/color_picker/color_picker_message_handler.rs @@ -1,6 +1,6 @@ use crate::messages::color_picker::color_picker_message::{HsvChannel, RgbChannel}; use crate::messages::layout::utility_types::widget_prelude::*; -use crate::messages::layout::utility_types::widgets::input_widgets::{ColorPresetsInputUpdate, SpectrumInputUpdate, SpectrumMarker, VisualColorPickersInputUpdate}; +use crate::messages::layout::utility_types::widgets::input_widgets::{ColorPresetsInputUpdate, SliderInputUpdate, SliderMarker, VisualColorPickersInputUpdate}; use crate::messages::prelude::*; use graphene_std::Color; use graphene_std::color::SRGBA8; @@ -377,10 +377,10 @@ impl ColorPickerMessageHandler { }); } - /// Apply an incoming `SpectrumInput` intent to the gradient state and broadcast the result. - fn apply_gradient_update(&mut self, update: SpectrumInputUpdate, responses: &mut VecDeque) { + /// Apply an incoming `SliderInput` intent to the gradient state and broadcast the result. + fn apply_gradient_update(&mut self, update: SliderInputUpdate, responses: &mut VecDeque) { // Active marker selection is the one update that doesn't mutate the gradient - if let SpectrumInputUpdate::ActiveMarker { + if let SliderInputUpdate::ActiveMarker { active_marker_index, active_marker_is_midpoint, } = update @@ -401,19 +401,19 @@ impl ColorPickerMessageHandler { let Some(mut gradient) = self.gradient.clone() else { return }; match update { - SpectrumInputUpdate::MoveMarker { index, position } => { + SliderInputUpdate::MoveMarker { index, position } => { let new_index = gradient.move_stop(index as usize, position, self.gradient_cyclic); if Some(index) == self.active_marker_index { self.active_marker_index = Some(new_index as u32); } } - SpectrumInputUpdate::MoveMidpoint { index, position } => { + SliderInputUpdate::MoveMidpoint { index, position } => { if (index as usize) >= gradient.len() { return; } gradient.set_midpoint(index as usize, position.clamp(MIN_MIDPOINT, MAX_MIDPOINT)); } - SpectrumInputUpdate::InsertMarker { position } => { + SliderInputUpdate::InsertMarker { position } => { let new_index = gradient.insert_stop(position, self.gradient_settings()); self.active_marker_index = Some(new_index as u32); self.active_marker_is_midpoint = false; @@ -422,7 +422,7 @@ impl ColorPickerMessageHandler { self.snapshot_old(); } } - SpectrumInputUpdate::InsertDuplicate { index, position } => { + SliderInputUpdate::InsertDuplicate { index, position } => { let source = index as usize; let Some(insert_index) = gradient.duplicate_stop(source, position, self.gradient_cyclic) else { return; @@ -432,7 +432,7 @@ impl ColorPickerMessageHandler { self.active_marker_index = Some(dragged_index as u32); self.active_marker_is_midpoint = false; } - SpectrumInputUpdate::RemoveDuplicate { index } => { + SliderInputUpdate::RemoveDuplicate { index } => { let anchor = index as usize; if anchor >= gradient.len() || gradient.len() <= 2 { return; @@ -449,7 +449,7 @@ impl ColorPickerMessageHandler { self.active_marker_index = Some(active - 1); } } - SpectrumInputUpdate::DeleteMarker { index } => { + SliderInputUpdate::DeleteMarker { index } => { // Enforce minimum stop count. The gradient editor needs at least 2 stops to remain meaningful. if gradient.len() <= 2 || (index as usize) >= gradient.len() { return; @@ -463,10 +463,10 @@ impl ColorPickerMessageHandler { self.snapshot_old(); } } - SpectrumInputUpdate::ResetMidpoint { index } => { + SliderInputUpdate::ResetMidpoint { index } => { gradient.reset_midpoint(index as usize); } - SpectrumInputUpdate::ResetMarker { index } => { + SliderInputUpdate::ResetMarker { index } => { let i = index as usize; let count = gradient.len(); if i >= count { @@ -483,7 +483,7 @@ impl ColorPickerMessageHandler { self.active_marker_index = Some(new_index as u32); } } - SpectrumInputUpdate::ActiveMarker { .. } => unreachable!("handled above"), + SliderInputUpdate::ActiveMarker { .. } => unreachable!("handled above"), } responses.add(FrontendMessage::ColorPickerColorChanged { @@ -514,10 +514,10 @@ impl ColorPickerMessageHandler { if let Some(gradient) = &self.gradient { // For gradient editing, the markers' handle colors mirror their gradient stop colors let markers = (0..gradient.len()) - .filter_map(|i| Some(SpectrumMarker::new(gradient.position(i, self.gradient_cyclic), gradient.midpoint(i), gradient.color(i)?))) + .filter_map(|i| Some(SliderMarker::new(gradient.position(i, self.gradient_cyclic), gradient.midpoint(i), gradient.color(i)?))) .collect(); let mut row_widgets = vec![ - SpectrumInput::new(GradientStops::from(gradient)) + SliderInput::new(GradientStops::from(gradient)) .track_space(self.gradient_space) .track_cyclic(self.gradient_cyclic) .track_hue_direction(self.gradient_hue_direction) @@ -531,7 +531,7 @@ impl ColorPickerMessageHandler { .allow_reorder(true) .allow_select(true) .disabled(self.disabled) - .on_update(|update: &SpectrumInputUpdate| ColorPickerMessage::GradientUpdate { update: update.clone() }.into()) + .on_update(|update: &SliderInputUpdate| ColorPickerMessage::GradientUpdate { update: update.clone() }.into()) .widget_instance(), ]; @@ -556,12 +556,12 @@ impl ColorPickerMessageHandler { return Message::NoOp; }; let update = if is_midpoint { - SpectrumInputUpdate::MoveMidpoint { + SliderInputUpdate::MoveMidpoint { index: captured_index, position: new_value / 100., } } else { - SpectrumInputUpdate::MoveMarker { + SliderInputUpdate::MoveMarker { index: captured_index, position: new_value / 100., } diff --git a/editor/src/messages/layout/layout_message_handler.rs b/editor/src/messages/layout/layout_message_handler.rs index 46d19c402c..8e0746b650 100644 --- a/editor/src/messages/layout/layout_message_handler.rs +++ b/editor/src/messages/layout/layout_message_handler.rs @@ -255,20 +255,20 @@ impl LayoutMessageHandler { responses.add(callback_message); } - Widget::SpectrumInput(spectrum_input) => { + Widget::SliderInput(slider_input) => { let callback_message = match action { - WidgetValueAction::Commit => (spectrum_input.on_commit.callback)(&()), + WidgetValueAction::Commit => (slider_input.on_commit.callback)(&()), WidgetValueAction::Update => { - let Ok(update) = serde_json::from_value::(value) else { - warn!("SpectrumInput update was not able to be parsed as SpectrumInputUpdate"); + let Ok(update) = serde_json::from_value::(value) else { + warn!("SliderInput update was not able to be parsed as SliderInputUpdate"); return; }; // Don't mutate the stored widget here: leaving its old values lets the layout diff detect a change // when the new layout is rebuilt with the updated state. Otherwise the frontend's stored layout // keeps stale values for `activeMarkerIndex`, etc., and any other widget's diff (e.g. the position - // NumberInput) will trigger Svelte to re-spread those stale props onto SpectrumInput, clobbering + // NumberInput) will trigger Svelte to re-spread those stale props onto SliderInput, clobbering // its local `activeMarkerIndex` and making subsequent drags target the wrong stop. - (spectrum_input.on_update.callback)(&update) + (slider_input.on_update.callback)(&update) } }; @@ -565,20 +565,20 @@ fn populate_computed_display_fields(layout: &mut Layout) { }) .collect(); } - Widget::SpectrumInput(spectrum_input) => { + Widget::SliderInput(slider_input) => { // The track strip spans exactly 0 to 1, which no spread affects, so the widget carries no spread of its own let settings = graphene_std::vector::style::GradientSettings { spread: Default::default(), - cyclic: spectrum_input.track_cyclic, - space: spectrum_input.track_space, - hue_direction: spectrum_input.track_hue_direction, - interpolation: spectrum_input.track_interpolation, + cyclic: slider_input.track_cyclic, + space: slider_input.track_space, + hue_direction: slider_input.track_hue_direction, + interpolation: slider_input.track_interpolation, }; - let track_gradient = graphene_std::vector::style::Gradient::from(&spectrum_input.track); - spectrum_input.track_samples = track_gradient + let track_gradient = graphene_std::vector::style::Gradient::from(&slider_input.track); + slider_input.track_samples = track_gradient .interpolated_samples_or_black(settings) .into_iter() - .map(|(position, color, _)| SpectrumSample::new(position, color)) + .map(|(position, color, _)| SliderSample::new(position, color)) .collect(); // The end caps sample the track's boundary colors, which a cyclic wrap makes the wrapped interval's boundary-crossing color rather than the outermost stops' let track_evaluator = track_gradient.evaluator(settings); @@ -586,8 +586,8 @@ fn populate_computed_display_fields(layout: &mut Layout) { let color = track_evaluator.evaluate(t); SRGBA8::from(color).to_css_hex() }; - spectrum_input.track_start_css = cap(0.); - spectrum_input.track_end_css = cap(1.); + slider_input.track_start_css = cap(0.); + slider_input.track_end_css = cap(1.); } Widget::ColorComparisonInput(comparison) => { let contrasting = |color: Option| color.map_or(SRGBA8::BLACK, |color| color.contrasting_text_color()).to_css_hex(); diff --git a/editor/src/messages/layout/utility_types/layout_widget.rs b/editor/src/messages/layout/utility_types/layout_widget.rs index e53ab5ca88..114b6a55f8 100644 --- a/editor/src/messages/layout/utility_types/layout_widget.rs +++ b/editor/src/messages/layout/utility_types/layout_widget.rs @@ -470,7 +470,7 @@ impl LayoutGroup { | Widget::ParameterExposeButton(_) | Widget::ColorComparisonInput(_) | Widget::ColorPresetsInput(_) - | Widget::SpectrumInput(_) + | Widget::SliderInput(_) | Widget::TransferCurveInput(_) | Widget::VisualColorPickersInput(_) => continue, }; @@ -823,7 +823,7 @@ pub enum Widget { PopoverButton(PopoverButton), RadioInput(RadioInput), Separator(Separator), - SpectrumInput(SpectrumInput), + SliderInput(SliderInput), TextAreaInput(TextAreaInput), TextButton(TextButton), TextInput(TextInput), @@ -888,7 +888,7 @@ impl DiffUpdate { | Widget::WorkingColorsInput(_) | Widget::ColorComparisonInput(_) | Widget::ColorPresetsInput(_) - | Widget::SpectrumInput(_) + | Widget::SliderInput(_) | Widget::TransferCurveInput(_) | Widget::VisualColorPickersInput(_) => None, }; diff --git a/editor/src/messages/layout/utility_types/widgets/input_widgets.rs b/editor/src/messages/layout/utility_types/widgets/input_widgets.rs index 28d81bb866..55879b7fd6 100644 --- a/editor/src/messages/layout/utility_types/widgets/input_widgets.rs +++ b/editor/src/messages/layout/utility_types/widgets/input_widgets.rs @@ -624,7 +624,7 @@ pub enum TransferCurveInputUpdate { #[cfg_attr(feature = "wasm", derive(tsify::Tsify))] #[derive(Clone, Derivative, serde::Serialize, serde::Deserialize, WidgetBuilder)] #[derivative(Debug, PartialEq, Default)] -pub struct SpectrumInput { +pub struct SliderInput { // Content /// The colored gradient drawn behind the markers (display-only, caller-owned). #[widget_builder(constructor)] @@ -644,7 +644,7 @@ pub struct SpectrumInput { /// Straight-alpha samples the frontend draws as the stops of an SVG gradient filling the track strip. Auto-populated from `track` at layout-send time. #[serde(rename = "trackSamples")] #[widget_builder(skip)] - pub track_samples: Vec, + pub track_samples: Vec, /// Hex string for the track strip's leftmost solid-color end-cap. Auto-populated by evaluating `track` at position 0. #[serde(rename = "trackStartCSS")] #[widget_builder(skip)] @@ -654,7 +654,7 @@ pub struct SpectrumInput { #[widget_builder(skip)] pub track_end_css: String, /// The handles the user can drag along the track. Their handle colors are caller-owned (e.g., for a gradient editor they follow the stop colors, for a "Shadows/Midpoints/Highlights" widget they're hardcoded). - pub markers: Vec, + pub markers: Vec, #[serde(rename = "activeMarkerIndex")] pub active_marker_index: Option, #[serde(rename = "activeMarkerIsMidpoint")] @@ -689,7 +689,7 @@ pub struct SpectrumInput { // Callbacks #[serde(skip)] #[derivative(Debug = "ignore", PartialEq = "ignore")] - pub on_update: WidgetCallback, + pub on_update: WidgetCallback, #[serde(skip)] #[derivative(Debug = "ignore", PartialEq = "ignore")] pub on_commit: WidgetCallback<()>, @@ -697,12 +697,12 @@ pub struct SpectrumInput { #[cfg_attr(feature = "wasm", derive(tsify::Tsify))] #[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct SpectrumMarker { +pub struct SliderMarker { /// Position along the track, normally 0..1. A shifted or stretched non-cyclic ramp can push it outside, where it is not drawn. position: f64, /// Midpoint (0..1) of the interval to the next marker, used only with `show_midpoints`. The last marker's midpoint spans the wrap of a cyclic track, or is otherwise ignored. midpoint: f64, - /// CSS color string for the marker handle's fill. Set via `SpectrumMarker::new` from a linear [`Color`], + /// CSS color string for the marker handle's fill. Set via `SliderMarker::new` from a linear [`Color`], /// discarding any transparency so the handle always shows the RGB that steers the interpolation. #[serde(rename = "handleColorCSS")] handle_color_css: String, @@ -717,7 +717,7 @@ pub struct SpectrumMarker { between_neighbors: bool, } -impl SpectrumMarker { +impl SliderMarker { pub fn new(position: f64, midpoint: f64, handle_color: Color) -> Self { let handle_color_css = format!("#{}", SRGBA8::from(handle_color).to_rgb_hex()); Self { @@ -748,8 +748,8 @@ impl SpectrumMarker { #[cfg_attr(feature = "wasm", derive(tsify::Tsify))] #[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct SpectrumSample { - /// Position (0..1) of the sample along the spectrum track, drawn as the SVG stop's `offset`. +pub struct SliderSample { + /// Position (0..1) of the sample along the slider track, drawn as the SVG stop's `offset`. position: f64, /// `#rrggbb` hex of the sample's color, drawn as the SVG stop's `stop-color`. color: String, @@ -757,7 +757,7 @@ pub struct SpectrumSample { alpha: f32, } -impl SpectrumSample { +impl SliderSample { pub fn new(position: f64, color: Color) -> Self { Self { position, @@ -769,7 +769,7 @@ impl SpectrumSample { #[cfg_attr(feature = "wasm", derive(tsify::Tsify))] #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)] -pub enum SpectrumInputUpdate { +pub enum SliderInputUpdate { MoveMarker { index: u32, position: f64, diff --git a/editor/src/messages/portfolio/document/node_graph/node_properties.rs b/editor/src/messages/portfolio/document/node_graph/node_properties.rs index 8adc52eb2b..0b8f4ce79c 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_properties.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_properties.rs @@ -1346,12 +1346,12 @@ pub fn query_assign_colors_randomize(node_id: NodeId, context: &NodePropertiesCo }) } -/// 2-stop black-to-white gradient track for spectrum sliders that map a value to a grayscale axis. +/// 2-stop black-to-white gradient track for sliders that map a value to a grayscale axis. fn bw_track() -> Gradient { Gradient::from(vec![Color::BLACK, Color::WHITE]) } -/// 3-stop black-to-color-to-white gradient track for spectrum sliders that map a value to a hue's full luminance range. +/// 3-stop black-to-color-to-white gradient track for sliders that map a value to a hue's full luminance range. fn color_track(color: Color) -> Gradient { Gradient::from(vec![Color::BLACK, color, Color::WHITE]) } @@ -1369,7 +1369,7 @@ pub(crate) fn brightness_contrast_properties(node_id: NodeId, context: &mut Node let brightness_min = if use_classic_value { -100. } else { -150. }; let brightness_max = if use_classic_value { 100. } else { 150. }; - let brightness = spectrum_slider_row( + let brightness = gradient_slider_row( node_id, context, BrightnessInput, @@ -1385,7 +1385,7 @@ pub(crate) fn brightness_contrast_properties(node_id: NodeId, context: &mut Node let zero_position = -contrast_min / (100. - contrast_min); let mut contrast_track = Gradient::from(vec![Color::MIDDLE_GRAY, Color::BLACK, Color::MIDDLE_GRAY]); contrast_track.set_positions(&[0., zero_position, 1.]); - let contrast = spectrum_slider_row( + let contrast = gradient_slider_row( node_id, context, ContrastInput, @@ -1402,7 +1402,7 @@ pub(crate) fn brightness_contrast_properties(node_id: NodeId, context: &mut Node let mut layout = vec![brightness, contrast, LayoutGroup::row(use_classic)]; if use_classic_value { let number_input = NumberInput::default().mode_increment().min(0.).max(255.); - layout.push(spectrum_slider_row(node_id, context, ClassicPivotInput, bw_track(), Color::WHITE, 0., 255., 127., number_input)); + layout.push(gradient_slider_row(node_id, context, ClassicPivotInput, bw_track(), Color::WHITE, 0., 255., 127., number_input)); } layout @@ -1481,22 +1481,22 @@ pub(crate) fn levels_properties(node_id: NodeId, context: &mut NodePropertiesCon }; let input_range_params = [ - SpectrumSectionParam::new(shadows, Color::BLACK, 0., MarkerScale::Percent), - SpectrumSectionParam::new(midtones, Color::MIDDLE_GRAY, 1., MarkerScale::Gamma).between_neighbors(), - SpectrumSectionParam::new(highlights, Color::WHITE, 100., MarkerScale::Percent), + SliderSectionParam::new(shadows, Color::BLACK, 0., MarkerScale::Percent), + SliderSectionParam::new(midtones, Color::MIDDLE_GRAY, 1., MarkerScale::Gamma).between_neighbors(), + SliderSectionParam::new(highlights, Color::WHITE, 100., MarkerScale::Percent), ]; let output_range_params = [ - SpectrumSectionParam::new(output_minimums, Color::BLACK, 0., MarkerScale::Percent), - SpectrumSectionParam::new(output_maximums, Color::WHITE, 100., MarkerScale::Percent), + SliderSectionParam::new(output_minimums, Color::BLACK, 0., MarkerScale::Percent), + SliderSectionParam::new(output_maximums, Color::WHITE, 100., MarkerScale::Percent), ]; let mut layout = vec![channel]; - build_shared_spectrum_section(node_id, context, &bw_track(), &input_range_params, &mut layout); - build_shared_spectrum_section(node_id, context, &bw_track(), &output_range_params, &mut layout); + build_shared_slider_section(node_id, context, &bw_track(), &input_range_params, &mut layout); + build_shared_slider_section(node_id, context, &bw_track(), &output_range_params, &mut layout); layout } -/// How a shared spectrum marker's value maps onto its track. +/// How a shared slider marker's value maps onto its track. #[derive(Clone, Copy)] enum MarkerScale { /// A 0..100 percentage, placed linearly. @@ -1545,8 +1545,8 @@ impl MarkerScale { } } -/// One parameter of a shared spectrum section and how its marker sits on the track. -struct SpectrumSectionParam { +/// One parameter of a shared slider section and how its marker sits on the track. +struct SliderSectionParam { parameter: ParameterRef, handle_color: Color, /// The value a double-click resets to. @@ -1560,7 +1560,7 @@ struct SpectrumSectionParam { between_neighbors: bool, } -impl SpectrumSectionParam { +impl SliderSectionParam { fn new(parameter: impl Into, handle_color: Color, default_value: f64, scale: MarkerScale) -> Self { Self { parameter: parameter.into(), @@ -1589,10 +1589,10 @@ impl SpectrumSectionParam { } } -/// Append a section of related parameters as rows: a shared spectrum over `track` (with one marker per non-exposed parameter) sits on the first non-exposed row +/// Append a section of related parameters as rows: a shared slider over `track` (with one marker per non-exposed parameter) sits on the first non-exposed row /// alongside its 60px number input, and the remaining non-exposed rows show only their 60px number input. Exposed parameters render as the standard exposed-row display. /// Marker positions are clamped to non-decreasing display order so they never visually cross even if the underlying values do. -fn build_shared_spectrum_section(node_id: NodeId, context: &mut NodePropertiesContext, track: &Gradient, params: &[SpectrumSectionParam], layout: &mut Vec) { +fn build_shared_slider_section(node_id: NodeId, context: &mut NodePropertiesContext, track: &Gradient, params: &[SliderSectionParam], layout: &mut Vec) { // Snapshot exposure and values before the mutable-borrow loop let exposure_and_value: Vec<(bool, f64)> = match get_document_node(node_id, context) { Ok(document_node) => params @@ -1608,7 +1608,7 @@ fn build_shared_spectrum_section(node_id: NodeId, context: &mut NodePropertiesCo }) .collect(), Err(err) => { - log::error!("Could not get document node in build_shared_spectrum_section: {err}"); + log::error!("Could not get document node in build_shared_slider_section: {err}"); return; } }; @@ -1655,12 +1655,12 @@ fn build_shared_spectrum_section(node_id: NodeId, context: &mut NodePropertiesCo } } - let spectrum_markers: Vec = marker_positions + let slider_markers: Vec = marker_positions .iter() .zip(&marker_colors_and_links) .zip(&marker_between) .map(|((&position, &(handle_color, paired, dashed)), &between)| { - let mut marker = SpectrumMarker::new(position, 0.5, handle_color); + let mut marker = SliderMarker::new(position, 0.5, handle_color); if paired { marker = marker.pair_with_next(); } @@ -1674,11 +1674,11 @@ fn build_shared_spectrum_section(node_id: NodeId, context: &mut NodePropertiesCo }) .collect(); - // Build the shared spectrum widget (placed on the first non-exposed row) - let spectrum_widget = (!spectrum_markers.is_empty()).then(|| { - SpectrumInput::new(GradientStops::from(track)) + // Build the shared slider widget (placed on the first non-exposed row) + let slider_widget = (!slider_markers.is_empty()).then(|| { + SliderInput::new(GradientStops::from(track)) .track_space(GradientSpace::RgbGamma) - .markers(spectrum_markers) + .markers(slider_markers) .show_midpoints(false) .allow_insert(false) .allow_delete(false) @@ -1691,9 +1691,9 @@ fn build_shared_spectrum_section(node_id: NodeId, context: &mut NodePropertiesCo let marker_scales = marker_scales.clone(); let marker_positions = marker_positions.clone(); let marker_between = marker_between.clone(); - move |update: &SpectrumInputUpdate| { + move |update: &SliderInputUpdate| { let i = match update { - SpectrumInputUpdate::MoveMarker { index, .. } | SpectrumInputUpdate::ResetMarker { index } => *index as usize, + SliderInputUpdate::MoveMarker { index, .. } | SliderInputUpdate::ResetMarker { index } => *index as usize, _ => return Message::NoOp, }; let (Some(&input_index), Some(&scale), Some(&between), Some(&default_position)) = @@ -1709,17 +1709,17 @@ fn build_shared_spectrum_section(node_id: NodeId, context: &mut NodePropertiesCo let right = (i + 1..marker_positions.len()).find(|&j| bounding(j)).map_or(1., |j| marker_positions[j]); let scale_position = match update { - SpectrumInputUpdate::MoveMarker { position, .. } if between => { + SliderInputUpdate::MoveMarker { position, .. } if between => { let span = right - left; if span <= f64::EPSILON { return Message::NoOp; } ((position - left) / span).clamp(0., 1.) } - SpectrumInputUpdate::MoveMarker { position, .. } => *position, + SliderInputUpdate::MoveMarker { position, .. } => *position, // A default that would cross a neighbor falls back to the midpoint between them - SpectrumInputUpdate::ResetMarker { .. } if between || cyclic || (left..=right).contains(&default_position) => default_position, - SpectrumInputUpdate::ResetMarker { .. } => (left + right) / 2., + SliderInputUpdate::ResetMarker { .. } if between || cyclic || (left..=right).contains(&default_position) => default_position, + SliderInputUpdate::ResetMarker { .. } => (left + right) / 2., _ => return Message::NoOp, }; NodeGraphMessage::SetInputValue { @@ -1733,9 +1733,9 @@ fn build_shared_spectrum_section(node_id: NodeId, context: &mut NodePropertiesCo .on_commit(commit_value) .widget_instance() }); - let spectrum_owner = marker_input_indices.first().copied(); + let slider_owner = marker_input_indices.first().copied(); - // One row per parameter: first non-exposed carries the shared spectrum, others get just a number input + // One row per parameter: first non-exposed carries the shared slider, others get just a number input for (i, param) in params.iter().enumerate() { let (exposed, current) = exposure_and_value[i]; let input_index = param.parameter.input_index; @@ -1748,10 +1748,10 @@ fn build_shared_spectrum_section(node_id: NodeId, context: &mut NodePropertiesCo let mut row = start_widgets(&ParameterWidgetsInfo::at_index(node_id, input_index, true, context)); row.push(Separator::new(SeparatorStyle::Unrelated).widget_instance()); - if Some(input_index) == spectrum_owner - && let Some(spectrum) = &spectrum_widget + if Some(input_index) == slider_owner + && let Some(slider) = &slider_widget { - row.push(spectrum.clone()); + row.push(slider.clone()); row.push(Separator::new(SeparatorStyle::Unrelated).widget_instance()); } @@ -1898,7 +1898,7 @@ pub(crate) fn hue_saturation_properties(node_id: NodeId, context: &mut NodePrope let mut layout = vec![enum_choice::().for_socket(range_info).disabled(colorize_value).property_row()]; layout.extend([ - spectrum_slider_row( + gradient_slider_row( node_id, context, hue, @@ -1909,7 +1909,7 @@ pub(crate) fn hue_saturation_properties(node_id: NodeId, context: &mut NodePrope hue_default, NumberInput::default().mode_increment().unit("°").min(hue_min).max(hue_max), ), - spectrum_slider_row( + gradient_slider_row( node_id, context, saturation, @@ -1920,7 +1920,7 @@ pub(crate) fn hue_saturation_properties(node_id: NodeId, context: &mut NodePrope saturation_default, NumberInput::default().mode_increment().unit("%").min(saturation_min).max(100.), ), - spectrum_slider_row( + gradient_slider_row( node_id, context, lightness, @@ -1937,12 +1937,12 @@ pub(crate) fn hue_saturation_properties(node_id: NodeId, context: &mut NodePrope if !colorize_value && let (Some(values), Some(defaults)) = (range_values, range_defaults) { let [falloff_start, range_start, range_end, falloff_end] = values; let params = [ - SpectrumSectionParam::new(falloff_start, Color::WHITE, defaults[0], MarkerScale::Degrees).pair_with_next(), - SpectrumSectionParam::new(range_start, Color::WHITE, defaults[1], MarkerScale::Degrees).dash_to_next(), - SpectrumSectionParam::new(range_end, Color::WHITE, defaults[2], MarkerScale::Degrees).pair_with_next(), - SpectrumSectionParam::new(falloff_end, Color::WHITE, defaults[3], MarkerScale::Degrees), + SliderSectionParam::new(falloff_start, Color::WHITE, defaults[0], MarkerScale::Degrees).pair_with_next(), + SliderSectionParam::new(range_start, Color::WHITE, defaults[1], MarkerScale::Degrees).dash_to_next(), + SliderSectionParam::new(range_end, Color::WHITE, defaults[2], MarkerScale::Degrees).pair_with_next(), + SliderSectionParam::new(falloff_end, Color::WHITE, defaults[3], MarkerScale::Degrees), ]; - build_shared_spectrum_section(node_id, context, &hue_track, ¶ms, &mut layout); + build_shared_slider_section(node_id, context, &hue_track, ¶ms, &mut layout); } let colorize = bool_widget(ParameterWidgetsInfo::new(node_id, ColorizeInput, true, context), CheckboxInput::default()); @@ -1951,7 +1951,7 @@ pub(crate) fn hue_saturation_properties(node_id: NodeId, context: &mut NodePrope layout } -/// A single-marker `SpectrumInput` over `track` driving the number at `input_index`: the marker sits at `position`, double-click +/// A single-marker `SliderInput` over `track` driving the number at `input_index`: the marker sits at `position`, double-click /// returns it to `default_position`, and each move sets the input to `value_at` the new position. fn value_slider( node_id: NodeId, @@ -1961,18 +1961,18 @@ fn value_slider( position: f64, default_position: Option, value_at: impl Fn(f64) -> TaggedValue + 'static + Send + Sync, -) -> SpectrumInput { - SpectrumInput::new(track) +) -> SliderInput { + SliderInput::new(track) .track_space(GradientSpace::RgbGamma) - .markers(vec![SpectrumMarker::new(position, 0.5, handle_color)]) + .markers(vec![SliderMarker::new(position, 0.5, handle_color)]) .show_midpoints(false) .allow_insert(false) .allow_delete(false) .allow_reorder(false) - .on_update(move |update: &SpectrumInputUpdate| { + .on_update(move |update: &SliderInputUpdate| { let new_position = match update { - SpectrumInputUpdate::MoveMarker { index: 0, position } => Some(*position), - SpectrumInputUpdate::ResetMarker { index: 0 } => default_position, + SliderInputUpdate::MoveMarker { index: 0, position } => Some(*position), + SliderInputUpdate::ResetMarker { index: 0 } => default_position, _ => None, }; let Some(new_position) = new_position else { return Message::NoOp }; @@ -2048,8 +2048,8 @@ pub(crate) fn range_slider_widget(parameter_widgets_info: ParameterWidgetsInfo, ) } -/// Build a row with a single-marker `SpectrumInput` and a 60px `NumberInput`. The marker maps `value_min..value_max` to position 0..1, and double-click resets to `default_value`. -fn spectrum_slider_row( +/// Build a row with a single-marker `SliderInput` over `track` and a 60px `NumberInput`. The marker maps `value_min..value_max` to position 0..1, and double-click resets to `default_value`. +fn gradient_slider_row( node_id: NodeId, context: &mut NodePropertiesContext, parameter: impl Into, @@ -2069,7 +2069,7 @@ fn spectrum_slider_row( .and_then(|input| input.as_non_exposed_value()) .and_then(|tagged| if let TaggedValue::F32(value) = tagged { Some(*value as f64) } else { None }); - // Only add the spectrum and number widgets when the input is not exposed + // Only add the slider and number widgets when the input is not exposed if let Some(current) = current { let slider = SliderRange { min: value_min, @@ -2116,12 +2116,12 @@ pub(crate) fn threshold_properties(node_id: NodeId, context: &mut NodeProperties use graphene_std::raster::threshold::*; let params = [ - SpectrumSectionParam::new(MinLuminanceInput, Color::WHITE, 50., MarkerScale::Percent).dash_to_next(), - SpectrumSectionParam::new(MaxLuminanceInput, Color::WHITE, 100., MarkerScale::Percent), + SliderSectionParam::new(MinLuminanceInput, Color::WHITE, 50., MarkerScale::Percent).dash_to_next(), + SliderSectionParam::new(MaxLuminanceInput, Color::WHITE, 100., MarkerScale::Percent), ]; let mut layout = Vec::with_capacity(2); - build_shared_spectrum_section(node_id, context, &bw_track(), ¶ms, &mut layout); + build_shared_slider_section(node_id, context, &bw_track(), ¶ms, &mut layout); layout } @@ -2179,7 +2179,7 @@ pub(crate) fn color_balance_properties(node_id: NodeId, context: &mut NodeProper let mut layout = vec![tone]; for (parameter, track) in parameters.into_iter().zip(tracks) { - layout.push(spectrum_slider_row(node_id, context, parameter, track, Color::WHITE, -100., 100., 0., number_input.clone())); + layout.push(gradient_slider_row(node_id, context, parameter, track, Color::WHITE, -100., 100., 0., number_input.clone())); } layout.push(LayoutGroup::row(preserve_luminosity)); @@ -2204,7 +2204,7 @@ pub(crate) fn black_and_white_properties(node_id: NodeId, context: &mut NodeProp (MagentasInput.into(), Color::MAGENTA, 80.), ]; for (parameter, color, default) in params { - layout.push(spectrum_slider_row( + layout.push(gradient_slider_row( node_id, context, parameter.clone(), @@ -2268,7 +2268,7 @@ pub(crate) fn channel_mixer_properties(node_id: NodeId, context: &mut NodeProper layout.push(output_channel); } for (i, (parameter, &default)) in parameters.into_iter().zip(defaults.iter()).enumerate() { - layout.push(spectrum_slider_row( + layout.push(gradient_slider_row( node_id, context, parameter, @@ -2329,7 +2329,7 @@ pub(crate) fn selective_color_properties(node_id: NodeId, context: &mut NodeProp let mut layout = vec![colors]; for (i, parameter) in parameters.into_iter().enumerate() { - layout.push(spectrum_slider_row(node_id, context, parameter, tracks[i].clone(), Color::WHITE, -100., 100., 0., number_input.clone())); + layout.push(gradient_slider_row(node_id, context, parameter, tracks[i].clone(), Color::WHITE, -100., 100., 0., number_input.clone())); } layout.push(mode); diff --git a/frontend/src/components/floating-menus/ColorPicker.svelte b/frontend/src/components/floating-menus/ColorPicker.svelte index aec680c23f..0b9b7a3776 100644 --- a/frontend/src/components/floating-menus/ColorPicker.svelte +++ b/frontend/src/components/floating-menus/ColorPicker.svelte @@ -83,7 +83,7 @@ .pickers-and-gradient .widget-span { --row-height: 24px; - &:has(.spectrum-input) { + &:has(.slider-input) { margin-top: 16px; .number-input { diff --git a/frontend/src/components/widgets/WidgetSpan.svelte b/frontend/src/components/widgets/WidgetSpan.svelte index 4bdb35d930..6e2385640f 100644 --- a/frontend/src/components/widgets/WidgetSpan.svelte +++ b/frontend/src/components/widgets/WidgetSpan.svelte @@ -15,7 +15,7 @@ import NumberInput from "/src/components/widgets/inputs/NumberInput.svelte"; import RadioInput from "/src/components/widgets/inputs/RadioInput.svelte"; import ReferencePointInput from "/src/components/widgets/inputs/ReferencePointInput.svelte"; - import SpectrumInput from "/src/components/widgets/inputs/SpectrumInput.svelte"; + import SliderInput from "/src/components/widgets/inputs/SliderInput.svelte"; import TextAreaInput from "/src/components/widgets/inputs/TextAreaInput.svelte"; import TextInput from "/src/components/widgets/inputs/TextInput.svelte"; import TransferCurveInput from "/src/components/widgets/inputs/TransferCurveInput.svelte"; @@ -243,8 +243,8 @@ }, }), }, - SpectrumInput: { - component: SpectrumInput, + SliderInput: { + component: SliderInput, getProps: (props, index) => ({ ...props, $$events: { diff --git a/frontend/src/components/widgets/inputs/SpectrumInput.svelte b/frontend/src/components/widgets/inputs/SliderInput.svelte similarity index 97% rename from frontend/src/components/widgets/inputs/SpectrumInput.svelte rename to frontend/src/components/widgets/inputs/SliderInput.svelte index e884405ea5..6bf052a079 100644 --- a/frontend/src/components/widgets/inputs/SpectrumInput.svelte +++ b/frontend/src/components/widgets/inputs/SliderInput.svelte @@ -3,22 +3,22 @@ import { preventEscapeClosingParentFloatingMenu } from "/src/components/layout/FloatingMenu.svelte"; import LayoutCol from "/src/components/layout/LayoutCol.svelte"; import LayoutRow from "/src/components/layout/LayoutRow.svelte"; - import type { GradientInterpolation, SpectrumInputUpdate, SpectrumMarker, SpectrumSample } from "/wrapper/pkg/graphite_wasm_wrapper"; + import type { GradientInterpolation, SliderInputUpdate, SliderMarker, SliderSample } from "/wrapper/pkg/graphite_wasm_wrapper"; const BUTTON_LEFT = 0; const BUTTON_RIGHT = 2; - const dispatch = createEventDispatcher<{ update: SpectrumInputUpdate; dragging: boolean }>(); + const dispatch = createEventDispatcher<{ update: SliderInputUpdate; dragging: boolean }>(); // Document-unique `id` for this instance's SVG gradient, referenced by its `url(#...)` - const gradientId = `spectrum-input-gradient-${String(Math.random()).substring(2)}`; + const gradientId = `slider-input-gradient-${String(Math.random()).substring(2)}`; - export let trackSamples: SpectrumSample[]; + export let trackSamples: SliderSample[]; export let trackStartCSS: string; export let trackEndCSS: string; export let trackCyclic = false; export let trackInterpolation: GradientInterpolation = "Linear"; - export let markers: SpectrumMarker[]; + export let markers: SliderMarker[]; export let activeMarkerIndex: number | undefined = 0; export let activeMarkerIsMidpoint = false; export let showMidpoints = true; @@ -92,7 +92,7 @@ return WHOLE_PATHS; } - function emit(intent: SpectrumInputUpdate) { + function emit(intent: SliderInputUpdate) { dispatch("update", intent); } @@ -151,7 +151,7 @@ } // A marker paired with its successor draws as one marker split down the middle while the two coincide (the successor drawing nothing) and as a half once apart - function markerShape(markers: SpectrumMarker[], index: number): MarkerShape { + function markerShape(markers: SliderMarker[], index: number): MarkerShape { const marker = markers[index]; const previous = markers[index - 1]; const next = markers[index + 1]; @@ -161,7 +161,7 @@ } // The spans from each marker passing `linked` to its successor, which on a wrapping track may cross the track's ends in two pieces - function markerSpans(markers: SpectrumMarker[], allowWrap: boolean, linked: (marker: SpectrumMarker) => boolean): { index: number; left: number; width: number }[] { + function markerSpans(markers: SliderMarker[], allowWrap: boolean, linked: (marker: SliderMarker) => boolean): { index: number; left: number; width: number }[] { const spans: { index: number; left: number; width: number }[] = []; markers.forEach((marker, index) => { @@ -616,7 +616,7 @@ // Map midpoint pairs to absolute track positions for rendering the diamond markers. // A rendered diamond's index is the index of the interval's left marker, which for the cyclic wrapped interval's diamond is the last marker. - function diamondPositions(markers: SpectrumMarker[], showMidpoints: boolean, trackCyclic: boolean, trackInterpolation: GradientInterpolation): number[] { + function diamondPositions(markers: SliderMarker[], showMidpoints: boolean, trackCyclic: boolean, trackInterpolation: GradientInterpolation): number[] { // A stepped ramp jumps at its stops, so no midpoint has anything to bias if (!showMidpoints || trackInterpolation === "Stepped" || markers.length < 2) return []; const positions = markers.slice(0, -1).map((marker, i) => marker.position + marker.midpoint * (markers[i + 1].position - marker.position)); @@ -645,7 +645,7 @@