This PR cleans up some color & elevation misc. ### Don't allow deriving Color from Hsla The point of the [ui::Color] enum is to encourage consistent color usage, and the the Color::Custom case is really only meant for cases where we have no other choice. `impl From<Hsla> for Color` encourages blindly passing colors into `Color::Custom` – with this in place we might as well remove the entire `Color` enum. The usages that were updated due to this removal were for colors that already exist in the Color enum, making it even more clear that it didn't make sense to have this. ### `ElevationIndex` -> `Elevation` This name would make more sense if we had an `Elevation` in the first place. The new name is more clear. #### `Button::elevation` As part of this change I also updated button's `layer` method to `elevation`, since it takes an elevation. This method still has the following issue: You want to use `Button::elevation` when it's default colors are invisible on the layer you are rendering the button on. However, current this method uses the elevation's `bg` color, rather than it's `on_elevation_bg`. Ideally when you use `Button::elevation` you want to pass the elevation you are _on_, not choosing one that will show up the elevation you are on. This change will be in a separate PR, as it likely will have widespread visual impact across the app. Release Notes: - N/A
131 lines
5.4 KiB
Rust
131 lines
5.4 KiB
Rust
use std::fmt::{self, Display, Formatter};
|
||
|
||
use gpui::{hsla, point, px, App, BoxShadow, Hsla};
|
||
use smallvec::{smallvec, SmallVec};
|
||
use theme::{ActiveTheme, Appearance};
|
||
|
||
/// Today, elevation is primarily used to add shadows to elements, and set the correct background for elements like buttons.
|
||
///
|
||
/// Elevation can be thought of as the physical closeness of an element to the
|
||
/// user. Elements with lower elevations are physically further away on the
|
||
/// z-axis and appear to be underneath elements with higher elevations.
|
||
///
|
||
/// In the future, a more complete approach to elevation may be added.
|
||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||
pub enum Elevation {
|
||
/// On the layer of the app background. This is under panels, panes, and
|
||
/// other surfaces.
|
||
Background,
|
||
/// The primary surface – Contains panels, panes, containers, etc.
|
||
Surface,
|
||
/// The same elevation as the primary surface, but used for the editable areas, like buffers
|
||
EditorSurface,
|
||
/// A surface that is elevated above the primary surface. but below washes, models, and dragged elements.
|
||
ElevatedSurface,
|
||
/// A surface above the [Elevation::ElevatedSurface] that is used for dialogs, alerts, modals, etc.
|
||
ModalSurface,
|
||
}
|
||
|
||
impl Display for Elevation {
|
||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||
match self {
|
||
Elevation::Background => write!(f, "Background"),
|
||
Elevation::Surface => write!(f, "Surface"),
|
||
Elevation::EditorSurface => write!(f, "Editor Surface"),
|
||
Elevation::ElevatedSurface => write!(f, "Elevated Surface"),
|
||
Elevation::ModalSurface => write!(f, "Modal Surface"),
|
||
}
|
||
}
|
||
}
|
||
|
||
impl Elevation {
|
||
/// Returns an appropriate shadow for the given elevation index.
|
||
pub fn shadow(self, cx: &App) -> SmallVec<[BoxShadow; 2]> {
|
||
let is_light = cx.theme().appearance() == Appearance::Light;
|
||
|
||
match self {
|
||
Elevation::Surface => smallvec![],
|
||
Elevation::EditorSurface => smallvec![],
|
||
|
||
Elevation::ElevatedSurface => smallvec![
|
||
BoxShadow {
|
||
color: hsla(0., 0., 0., 0.12),
|
||
offset: point(px(0.), px(2.)),
|
||
blur_radius: px(3.),
|
||
spread_radius: px(0.),
|
||
},
|
||
BoxShadow {
|
||
color: hsla(0., 0., 0., if is_light { 0.03 } else { 0.06 }),
|
||
offset: point(px(1.), px(1.)),
|
||
blur_radius: px(0.),
|
||
spread_radius: px(0.),
|
||
}
|
||
],
|
||
|
||
Elevation::ModalSurface => smallvec![
|
||
BoxShadow {
|
||
color: hsla(0., 0., 0., if is_light { 0.06 } else { 0.12 }),
|
||
offset: point(px(0.), px(2.)),
|
||
blur_radius: px(3.),
|
||
spread_radius: px(0.),
|
||
},
|
||
BoxShadow {
|
||
color: hsla(0., 0., 0., if is_light { 0.06 } else { 0.08 }),
|
||
offset: point(px(0.), px(3.)),
|
||
blur_radius: px(6.),
|
||
spread_radius: px(0.),
|
||
},
|
||
BoxShadow {
|
||
color: hsla(0., 0., 0., 0.04),
|
||
offset: point(px(0.), px(6.)),
|
||
blur_radius: px(12.),
|
||
spread_radius: px(0.),
|
||
},
|
||
BoxShadow {
|
||
color: hsla(0., 0., 0., if is_light { 0.04 } else { 0.12 }),
|
||
offset: point(px(1.), px(1.)),
|
||
blur_radius: px(0.),
|
||
spread_radius: px(0.),
|
||
},
|
||
],
|
||
|
||
_ => smallvec![],
|
||
}
|
||
}
|
||
|
||
/// Returns the background color for the given elevation index.
|
||
pub fn bg(&self, cx: &mut App) -> Hsla {
|
||
match self {
|
||
Elevation::Background => cx.theme().colors().background,
|
||
Elevation::Surface => cx.theme().colors().surface_background,
|
||
Elevation::EditorSurface => cx.theme().colors().editor_background,
|
||
Elevation::ElevatedSurface => cx.theme().colors().elevated_surface_background,
|
||
Elevation::ModalSurface => cx.theme().colors().elevated_surface_background,
|
||
}
|
||
}
|
||
|
||
/// Returns a color that is appropriate a filled element on this elevation
|
||
pub fn on_elevation_bg(&self, cx: &App) -> Hsla {
|
||
match self {
|
||
Elevation::Background => cx.theme().colors().surface_background,
|
||
Elevation::Surface => cx.theme().colors().background,
|
||
Elevation::EditorSurface => cx.theme().colors().surface_background,
|
||
Elevation::ElevatedSurface => cx.theme().colors().background,
|
||
Elevation::ModalSurface => cx.theme().colors().background,
|
||
}
|
||
}
|
||
|
||
/// Attempts to return a darker background color than the current elevation index's background.
|
||
///
|
||
/// If the current background color is already dark, it will return a lighter color instead.
|
||
pub fn darker_bg(&self, cx: &App) -> Hsla {
|
||
match self {
|
||
Elevation::Background => cx.theme().colors().surface_background,
|
||
Elevation::Surface => cx.theme().colors().editor_background,
|
||
Elevation::EditorSurface => cx.theme().colors().surface_background,
|
||
Elevation::ElevatedSurface => cx.theme().colors().editor_background,
|
||
Elevation::ModalSurface => cx.theme().colors().editor_background,
|
||
}
|
||
}
|
||
}
|