use std::sync::atomic::{AtomicU32, Ordering};
use gpui::{Styled, px};
use crate::theme::{
Theme,
typography::{TextStyle, Typeset},
};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ControlSize {
Small,
Regular,
}
impl ControlSize {
pub const fn text(self) -> TextStyle {
match self {
ControlSize::Small => TextStyle::Callout,
ControlSize::Regular => TextStyle::Body,
}
}
pub const fn height(self) -> f32 {
match self {
ControlSize::Small => Theme::CONTROL_HEIGHT_SMALL,
ControlSize::Regular => Theme::BUTTON_HEIGHT,
}
}
pub const fn pad_x(self) -> f32 {
match self {
ControlSize::Small => 8.0,
ControlSize::Regular => 12.0,
}
}
pub const fn pad_y(self) -> f32 {
(self.height() - self.text().line_height()) / 2.0
}
pub fn radius(self) -> f32 {
match self {
ControlSize::Small => Theme::control_radius(),
ControlSize::Regular => Theme::button_radius(),
}
}
}
pub trait Sizing: Styled + Sized {
fn control_size(self, size: ControlSize) -> Self {
self.min_h(px(size.height()))
.px(px(size.pad_x()))
.py(px(size.pad_y()))
.rounded(px(size.radius()))
.text_style(size.text())
}
}
impl<E: Styled> Sizing for E {}
static BASE: AtomicU32 = AtomicU32::new(Theme::BASE_RADIUS.to_bits());
pub(crate) fn set_base_radius(radius: f32) {
BASE.store(radius.to_bits(), Ordering::Relaxed);
}
impl Theme {
pub const VIBRANCY_ALPHA: f32 = if cfg!(any(target_os = "macos", target_family = "wasm")) {
0.80
} else {
1.0
};
pub const HEADER_HEIGHT: f32 = 44.0;
pub const TITLEBAR_HEIGHT: f32 = 38.0;
pub const TITLEBAR_TOP_PAD: f32 = 2.0;
pub const TRAFFIC_LIGHT_INSET: f32 = if cfg!(target_os = "macos") { 78.0 } else { 0.0 };
pub const STATUS_STRIP_HEIGHT: f32 = 24.0;
pub const TRANSCRIPT_FADE_BAND: f32 = 24.0;
pub const BUTTON_HEIGHT: f32 = 24.0;
pub const CONTROL_HEIGHT_SMALL: f32 = 20.0;
pub const BASE_RADIUS: f32 = 8.0;
pub fn bubble_radius() -> f32 {
Self::radius(2.0)
}
pub fn surface_radius() -> f32 {
Self::radius(1.5)
}
pub fn panel_radius() -> f32 {
Self::radius(1.25)
}
pub fn button_radius() -> f32 {
Self::radius(1.0)
}
pub fn control_radius() -> f32 {
Self::radius(0.75)
}
fn radius(ratio: f32) -> f32 {
f32::from_bits(BASE.load(Ordering::Relaxed)) * ratio
}
pub const fn inset_radius(outer: f32, inset: f32) -> f32 {
if outer > inset { outer - inset } else { 0.0 }
}
pub const SPACE: f32 = 8.0;
pub const CONTENT_MARGIN: f32 = 20.0;
}