Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/desktop-gpui/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions apps/desktop-gpui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ cap-enc-ffmpeg = { path = "../../crates/enc-ffmpeg" }
cap-timestamp = { path = "../../crates/timestamp" }
cap-utils = { path = "../../crates/utils" }
cap-project = { path = "../../crates/project" }
# The cursor style picker draws the same SVG assets the renderer composites.
# gpui's `svg()` keeps only a glyph's alpha, so the two-tone cursor art has to
# be rasterised instead: `resvg` at the pin cap-rendering already builds, into
# a `RenderImage` (`src/editor_sidebar/cursor.rs`).
cap-cursor-info = { path = "../../crates/cursor-info" }
resvg = "0.45"
# The editor stack. `cap-rendering` is not a new subtree -- cap-recording
# already depends on it, so wgpu 25 and its vendored wgpu-hal have been built
# by this workspace since the recording unit; naming it here only makes the
Expand Down
1 change: 1 addition & 0 deletions apps/desktop-gpui/assets/icons/app-window.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/desktop-gpui/assets/icons/ban.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/desktop-gpui/assets/icons/globe.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/desktop-gpui/assets/icons/mouse-pointer-click.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions apps/desktop-gpui/src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ const FONTS: &[(&str, &[u8])] = assets!("fonts":
/// illustration would come out as a filled silhouette.
const ICONS: &[(&str, &[u8])] = assets!("icons":
"app-window-mac.svg",
"app-window.svg",
"ban.svg",
"globe.svg",
"area.svg",
"arrows.svg",
"audio-on.svg",
Expand Down Expand Up @@ -168,6 +171,7 @@ const ICONS: &[(&str, &[u8])] = assets!("icons":
"maximize.svg",
"moon.svg",
"mouse-pointer-2.svg",
"mouse-pointer-click.svg",
"move.svg",
"move-right.svg",
"palette.svg",
Expand Down Expand Up @@ -315,6 +319,7 @@ mod tests {
include_str!("mode_select_window.rs"),
include_str!("teleprompter_window.rs"),
include_str!("editor_window.rs"),
include_str!("editor_window/frame.rs"),
// The timeline's nine track glyphs and its scene-mode icons are named
// in the strip's own module, not in the window that hosts it.
include_str!("editor_timeline.rs"),
Expand All @@ -324,6 +329,9 @@ mod tests {
// The five later tabs, the colour-grade section and the eight segment
// panels each name their own glyphs.
include_str!("editor_tabs.rs"),
// The cursor tab's style picker and ripple section live one directory
// down, and the ripple field names its own glyph.
include_str!("editor_sidebar/cursor.rs"),
include_str!("editor_color.rs"),
include_str!("editor_panels.rs"),
// The crop dialog's ratio / Full / Reset glyphs and the chevron
Expand Down
34 changes: 33 additions & 1 deletion apps/desktop-gpui/src/editor_sidebar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
//! re-encode (`src-tauri/src/recording.rs:181-208, 437-472`).

use std::{
collections::HashMap,
collections::{BTreeMap, HashMap},
path::{Path, PathBuf},
sync::Arc,
time::Instant,
Expand Down Expand Up @@ -63,6 +63,7 @@ use crate::{
};

mod animated_gradient;
mod cursor;

// ---------------------------------------------------------------------------
// The catalogue: every constant the background section reads
Expand Down Expand Up @@ -725,6 +726,9 @@ pub enum ColorTarget {
GradientTo,
AnimatedGradientStop(usize),
BorderColor,
/// The click ripple's ring colour, the one `[u8; 3]` target outside the
/// background tab.
CursorRipple,
CaptionColor,
CaptionBackground,
CaptionHighlight,
Expand All @@ -744,6 +748,7 @@ impl ColorTarget {
| Self::GradientTo
| Self::AnimatedGradientStop(_)
| Self::BorderColor
| Self::CursorRipple
)
}
}
Expand Down Expand Up @@ -797,6 +802,16 @@ pub struct SidebarState {
/// `KCollapsible open={!project.cursor.raw}` physics panel.
pub camera_shadow_open: CollapsibleState,
pub cursor_physics_open: CollapsibleState,
/// The click-ripple settings, revealed by their own toggle.
pub cursor_ripple_open: CollapsibleState,
/// The style picker's rasterised cursor art, keyed by shape and the device
/// pixel box it was drawn for. A `BTreeMap` because `CursorShape` is `Ord`
/// but not `Hash`.
cursor_previews:
std::cell::RefCell<BTreeMap<(cap_cursor_info::CursorShape, u32, u32), Arc<RenderImage>>>,
/// The device scale those were rasterised at, sampled once a frame from
/// `render` -- the only place in the sidebar's chain with a `&Window`.
cursor_scale: f32,
/// The 3D panel's three `Camera3DSection`s and the zoom panel's helper.
pub panel_sections: std::cell::RefCell<HashMap<PanelSection, std::rc::Rc<CollapsibleState>>>,

Expand Down Expand Up @@ -873,6 +888,9 @@ impl SidebarState {
grade_previews: std::cell::RefCell::new(HashMap::new()),
camera_shadow_open: CollapsibleState::new(false),
cursor_physics_open: CollapsibleState::new(!config.cursor.raw),
cursor_ripple_open: CollapsibleState::new(config.cursor.ripple.enabled),
cursor_previews: std::cell::RefCell::new(BTreeMap::new()),
cursor_scale: 2.,
panel_sections: std::cell::RefCell::new(HashMap::new()),
noise: std::cell::RefCell::new(None),
menu: None,
Expand Down Expand Up @@ -1628,6 +1646,7 @@ impl EditorWindow {
.as_ref()
.map_or(UI_BORDER_FALLBACK.color, |border| border.color),
),
ColorTarget::CursorRipple => Some(self.project.cursor.ripple.color),
_ => self.hex_string_for(target).and_then(|hex| {
hex_to_rgb(&hex).map(|rgba| [rgba[0] as u16, rgba[1] as u16, rgba[2] as u16])
}),
Expand Down Expand Up @@ -1664,6 +1683,17 @@ impl EditorWindow {
if target.is_hex_string() {
return self.set_hex_color(target, color, window, cx);
}
// The one `[u8; 3]` target that does not live under `background`, so
// it takes the general fan-out rather than `edit_background`.
if target == ColorTarget::CursorRipple {
return self.edit_project("cursor-ripple-color", window, cx, move |project| {
if project.cursor.ripple.color == color {
return false;
}
project.cursor.ripple.color = color;
true
});
}
self.edit_background(
"color",
|project| {
Expand Down Expand Up @@ -3864,6 +3894,8 @@ pub(crate) fn format_slider_value(value: f32, unit: &str) -> String {
"int" => format!("{}", value.round() as i32),
"x100%" => format!("{}%", (value * 100.).round() as i32),
"pct" => format!("{:.1}%", value * 100.),
// The ripple duration's `${v.toFixed(2)}s`.
"secs" => format!("{value:.2}s"),
unit => format!("{value:.1}{unit}"),
}
}
Expand Down
Loading
Loading