logiguard fork v2: patched GPUI on verified 8c74db0 tree
Rebuilt from the exact zed-industries/zed @ 8c74db00c4053d6c0a9037863d7bd048658da4ca tree (previous orphan was based on a stale/wrong fetch). Same 3-file patch: - serial.rs: add SerialKind::KeyboardEnter - client.rs: store wl_keyboard.enter serial; add latest_serial_of() - window.rs: activate() uses keyboard-enter serial (Mutter focus gate) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use gpui::{Animation, AnimationElement, AnimationExt, Transformation, percentage};
|
||||
|
||||
use crate::{prelude::*, traits::transformable::Transformable};
|
||||
|
||||
/// An extension trait for adding common animations to animatable components.
|
||||
pub trait CommonAnimationExt: AnimationExt {
|
||||
/// Render this component as rotating over the given duration.
|
||||
///
|
||||
/// NOTE: This method uses the location of the caller to generate an ID for this state.
|
||||
/// If this is not sufficient to identify your state (e.g. you're rendering a list item),
|
||||
/// you can provide a custom ElementID using the `use_keyed_rotate_animation` method.
|
||||
#[track_caller]
|
||||
fn with_rotate_animation(self, duration: u64) -> AnimationElement<Self>
|
||||
where
|
||||
Self: Transformable + Sized,
|
||||
{
|
||||
self.with_keyed_rotate_animation(
|
||||
ElementId::CodeLocation(*std::panic::Location::caller()),
|
||||
duration,
|
||||
)
|
||||
}
|
||||
|
||||
/// Render this component as rotating with the given element ID over the given duration.
|
||||
fn with_keyed_rotate_animation(
|
||||
self,
|
||||
id: impl Into<ElementId>,
|
||||
duration: u64,
|
||||
) -> AnimationElement<Self>
|
||||
where
|
||||
Self: Transformable + Sized,
|
||||
{
|
||||
self.with_animation(
|
||||
id,
|
||||
Animation::new(Duration::from_secs(duration)).repeat(),
|
||||
|component, delta| component.transform(Transformation::rotate(percentage(delta))),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AnimationExt> CommonAnimationExt for T {}
|
||||
@@ -0,0 +1,9 @@
|
||||
use gpui::{App, ClickEvent, CursorStyle, Window};
|
||||
|
||||
/// A trait for elements that can be clicked. Enables the use of the `on_click` method.
|
||||
pub trait Clickable {
|
||||
/// Sets the click handler that will fire whenever the element is clicked.
|
||||
fn on_click(self, handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static) -> Self;
|
||||
/// Sets the cursor style when hovering over the element.
|
||||
fn cursor_style(self, cursor_style: CursorStyle) -> Self;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/// A trait for elements that can be disabled. Generally used to implement disabling an element's interactivity and changing its appearance to reflect that it is disabled.
|
||||
pub trait Disableable {
|
||||
/// Sets whether the element is disabled.
|
||||
fn disabled(self, disabled: bool) -> Self;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
use gpui::DefiniteLength;
|
||||
|
||||
/// A trait for elements that can have a fixed with. Enables the use of the `width` and `full_width` methods.
|
||||
pub trait FixedWidth {
|
||||
/// Sets the width of the element.
|
||||
fn width(self, width: impl Into<DefiniteLength>) -> Self;
|
||||
|
||||
/// Sets the element's width to the full width of its container.
|
||||
fn full_width(self) -> Self;
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
use gpui::{App, Styled, hsla};
|
||||
|
||||
use crate::ElevationIndex;
|
||||
use crate::prelude::*;
|
||||
|
||||
fn elevated<E: Styled>(this: E, cx: &App, index: ElevationIndex) -> E {
|
||||
this.bg(cx.theme().colors().elevated_surface_background)
|
||||
.rounded_lg()
|
||||
.border_1()
|
||||
.border_color(cx.theme().colors().border_variant)
|
||||
.shadow(index.shadow(cx))
|
||||
}
|
||||
|
||||
fn elevated_borderless<E: Styled>(this: E, cx: &mut App, index: ElevationIndex) -> E {
|
||||
this.bg(cx.theme().colors().elevated_surface_background)
|
||||
.rounded_lg()
|
||||
.shadow(index.shadow(cx))
|
||||
}
|
||||
|
||||
/// Extends [`gpui::Styled`] with Zed-specific styling methods.
|
||||
// gate on rust-analyzer so rust-analyzer never needs to expand this macro, it takes up to 10 seconds to expand due to inefficiencies in rust-analyzers proc-macro srv
|
||||
#[cfg_attr(
|
||||
all(debug_assertions, not(rust_analyzer)),
|
||||
gpui_macros::derive_inspector_reflection
|
||||
)]
|
||||
pub trait StyledExt: Styled + Sized {
|
||||
/// Horizontally stacks elements.
|
||||
///
|
||||
/// Sets `flex()`, `flex_row()`, `items_center()`
|
||||
fn h_flex(self) -> Self {
|
||||
self.flex().flex_row().items_center()
|
||||
}
|
||||
|
||||
/// Vertically stacks elements.
|
||||
///
|
||||
/// Sets `flex()`, `flex_col()`
|
||||
fn v_flex(self) -> Self {
|
||||
self.flex().flex_col()
|
||||
}
|
||||
|
||||
/// The [`Surface`](ElevationIndex::Surface) elevation level, located above the app background, is the standard level for all elements
|
||||
///
|
||||
/// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
|
||||
///
|
||||
/// Example Elements: Title Bar, Panel, Tab Bar, Editor
|
||||
fn elevation_1(self, cx: &App) -> Self {
|
||||
elevated(self, cx, ElevationIndex::Surface)
|
||||
}
|
||||
|
||||
/// See [`elevation_1`](Self::elevation_1).
|
||||
///
|
||||
/// Renders a borderless version [`elevation_1`](Self::elevation_1).
|
||||
fn elevation_1_borderless(self, cx: &mut App) -> Self {
|
||||
elevated_borderless(self, cx, ElevationIndex::Surface)
|
||||
}
|
||||
|
||||
/// Non-Modal Elevated Surfaces appear above the [`Surface`](ElevationIndex::Surface) layer and is used for things that should appear above most UI elements like an editor or panel, but not elements like popovers, context menus, modals, etc.
|
||||
///
|
||||
/// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
|
||||
///
|
||||
/// Examples: Notifications, Palettes, Detached/Floating Windows, Detached/Floating Panels
|
||||
fn elevation_2(self, cx: &App) -> Self {
|
||||
elevated(self, cx, ElevationIndex::ElevatedSurface)
|
||||
}
|
||||
|
||||
/// See [`elevation_2`](Self::elevation_2).
|
||||
///
|
||||
/// Renders a borderless version [`elevation_2`](Self::elevation_2).
|
||||
fn elevation_2_borderless(self, cx: &mut App) -> Self {
|
||||
elevated_borderless(self, cx, ElevationIndex::ElevatedSurface)
|
||||
}
|
||||
|
||||
/// Modal Surfaces are used for elements that should appear above all other UI elements and are located above the wash layer. This is the maximum elevation at which UI elements can be rendered in their default state.
|
||||
///
|
||||
/// Elements rendered at this layer should have an enforced behavior: Any interaction outside of the modal will either dismiss the modal or prompt an action (Save your progress, etc) then dismiss the modal.
|
||||
///
|
||||
/// If the element does not have this behavior, it should be rendered at the [`Elevated Surface`](ElevationIndex::ElevatedSurface) layer.
|
||||
///
|
||||
/// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
|
||||
///
|
||||
/// Examples: Settings Modal, Channel Management, Wizards/Setup UI, Dialogs
|
||||
fn elevation_3(self, cx: &App) -> Self {
|
||||
elevated(self, cx, ElevationIndex::ModalSurface)
|
||||
}
|
||||
|
||||
/// See [`elevation_3`](Self::elevation_3).
|
||||
///
|
||||
/// Renders a borderless version [`elevation_3`](Self::elevation_3).
|
||||
fn elevation_3_borderless(self, cx: &mut App) -> Self {
|
||||
elevated_borderless(self, cx, ElevationIndex::ModalSurface)
|
||||
}
|
||||
|
||||
/// The theme's primary border color.
|
||||
fn border_primary(self, cx: &mut App) -> Self {
|
||||
self.border_color(cx.theme().colors().border)
|
||||
}
|
||||
|
||||
/// The theme's secondary or muted border color.
|
||||
fn border_muted(self, cx: &mut App) -> Self {
|
||||
self.border_color(cx.theme().colors().border_variant)
|
||||
}
|
||||
|
||||
/// Sets the background color to red for debugging when building UI.
|
||||
fn debug_bg_red(self) -> Self {
|
||||
self.bg(hsla(0. / 360., 1., 0.5, 1.))
|
||||
}
|
||||
|
||||
/// Sets the background color to green for debugging when building UI.
|
||||
fn debug_bg_green(self) -> Self {
|
||||
self.bg(hsla(120. / 360., 1., 0.5, 1.))
|
||||
}
|
||||
|
||||
/// Sets the background color to blue for debugging when building UI.
|
||||
fn debug_bg_blue(self) -> Self {
|
||||
self.bg(hsla(240. / 360., 1., 0.5, 1.))
|
||||
}
|
||||
|
||||
/// Sets the background color to yellow for debugging when building UI.
|
||||
fn debug_bg_yellow(self) -> Self {
|
||||
self.bg(hsla(60. / 360., 1., 0.5, 1.))
|
||||
}
|
||||
|
||||
/// Sets the background color to cyan for debugging when building UI.
|
||||
fn debug_bg_cyan(self) -> Self {
|
||||
self.bg(hsla(160. / 360., 1., 0.5, 1.))
|
||||
}
|
||||
|
||||
/// Sets the background color to magenta for debugging when building UI.
|
||||
fn debug_bg_magenta(self) -> Self {
|
||||
self.bg(hsla(300. / 360., 1., 0.5, 1.))
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Styled> StyledExt for E {}
|
||||
@@ -0,0 +1,69 @@
|
||||
/// A trait for elements that can be toggled.
|
||||
///
|
||||
/// Implement this for elements that are visually distinct
|
||||
/// when in two opposing states, like checkboxes or switches.
|
||||
pub trait Toggleable {
|
||||
/// Sets whether the element is selected.
|
||||
fn toggle_state(self, selected: bool) -> Self;
|
||||
}
|
||||
|
||||
/// Represents the selection status of an element.
|
||||
#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
|
||||
pub enum ToggleState {
|
||||
/// The element is not selected.
|
||||
#[default]
|
||||
Unselected,
|
||||
/// The selection state of the element is indeterminate.
|
||||
Indeterminate,
|
||||
/// The element is selected.
|
||||
Selected,
|
||||
}
|
||||
|
||||
impl ToggleState {
|
||||
/// Returns the inverse of the current selection status.
|
||||
///
|
||||
/// Indeterminate states become selected if inverted.
|
||||
pub fn inverse(&self) -> Self {
|
||||
match self {
|
||||
Self::Unselected | Self::Indeterminate => Self::Selected,
|
||||
Self::Selected => Self::Unselected,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a `ToggleState` from the given `any_checked` and `all_checked` flags.
|
||||
pub fn from_any_and_all(any_checked: bool, all_checked: bool) -> Self {
|
||||
match (any_checked, all_checked) {
|
||||
(true, true) => Self::Selected,
|
||||
(false, false) => Self::Unselected,
|
||||
_ => Self::Indeterminate,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether this toggle state is selected
|
||||
pub fn selected(&self) -> bool {
|
||||
match self {
|
||||
ToggleState::Indeterminate | ToggleState::Unselected => false,
|
||||
ToggleState::Selected => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bool> for ToggleState {
|
||||
fn from(selected: bool) -> Self {
|
||||
if selected {
|
||||
Self::Selected
|
||||
} else {
|
||||
Self::Unselected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<bool>> for ToggleState {
|
||||
fn from(selected: Option<bool>) -> Self {
|
||||
match selected {
|
||||
Some(true) => Self::Selected,
|
||||
Some(false) => Self::Unselected,
|
||||
None => Self::Indeterminate,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
use gpui::Transformation;
|
||||
|
||||
/// A trait for components that can be transformed.
|
||||
pub trait Transformable {
|
||||
/// Sets the transformation for the element.
|
||||
fn transform(self, transformation: Transformation) -> Self;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
use gpui::{InteractiveElement, SharedString, Styled};
|
||||
|
||||
/// A trait for elements that can be made visible on hover by
|
||||
/// tracking a specific group.
|
||||
pub trait VisibleOnHover {
|
||||
/// Sets the element to only be visible when the specified group is hovered.
|
||||
///
|
||||
/// Pass `""` as the `group_name` to use the global group.
|
||||
fn visible_on_hover(self, group_name: impl Into<SharedString>) -> Self;
|
||||
}
|
||||
|
||||
impl<E: InteractiveElement + Styled> VisibleOnHover for E {
|
||||
fn visible_on_hover(self, group_name: impl Into<SharedString>) -> Self {
|
||||
self.invisible()
|
||||
.group_hover(group_name, |style| style.visible())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user