What if we base themes on Rose Pine
This commit is contained in:
parent
82c903de14
commit
3b1e5e966a
10 changed files with 368 additions and 131 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -5301,11 +5301,14 @@ dependencies = [
|
||||||
name = "playground_ui"
|
name = "playground_ui"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"collections",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"gpui",
|
"gpui",
|
||||||
"log",
|
"log",
|
||||||
"optional_struct",
|
"optional_struct",
|
||||||
|
"serde",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
"util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -9,11 +9,14 @@ path = "src/playground_ui.rs"
|
||||||
crate-type = ["dylib"]
|
crate-type = ["dylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
derive_more = "0.99.17"
|
collections = { path = "../../../collections" }
|
||||||
|
util = { path = "../../../util" }
|
||||||
gpui = { path = "../.." }
|
gpui = { path = "../.." }
|
||||||
|
derive_more = "0.99.17"
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
optional_struct = "0.3.1"
|
optional_struct = "0.3.1"
|
||||||
smallvec.workspace = true
|
smallvec.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gpui = { path = "../..", features = ["test-support"] }
|
gpui = { path = "../..", features = ["test-support"] }
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::{num::ParseIntError, ops::Range};
|
||||||
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
pub fn rgb(hex: u32) -> Rgba {
|
pub fn rgb<C: From<Rgba>>(hex: u32) -> C {
|
||||||
let r = ((hex >> 16) & 0xFF) as f32 / 255.0;
|
let r = ((hex >> 16) & 0xFF) as f32 / 255.0;
|
||||||
let g = ((hex >> 8) & 0xFF) as f32 / 255.0;
|
let g = ((hex >> 8) & 0xFF) as f32 / 255.0;
|
||||||
let b = (hex & 0xFF) as f32 / 255.0;
|
let b = (hex & 0xFF) as f32 / 255.0;
|
||||||
Rgba { r, g, b, a: 1.0 }
|
Rgba { r, g, b, a: 1.0 }.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default, Debug)]
|
#[derive(Clone, Copy, Default, Debug)]
|
||||||
|
@ -17,6 +19,22 @@ pub struct Rgba {
|
||||||
pub a: f32,
|
pub a: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Lerp {
|
||||||
|
fn lerp(&self, level: f32) -> Hsla;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Lerp for Range<Hsla> {
|
||||||
|
fn lerp(&self, level: f32) -> Hsla {
|
||||||
|
let level = level.clamp(0., 1.);
|
||||||
|
Hsla {
|
||||||
|
h: self.start.h + (level * (self.end.h - self.start.h)),
|
||||||
|
s: self.start.s + (level * (self.end.s - self.start.s)),
|
||||||
|
l: self.start.l + (level * (self.end.l - self.start.l)),
|
||||||
|
a: self.start.a + (level * (self.end.a - self.start.a)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Hsla> for Rgba {
|
impl From<Hsla> for Rgba {
|
||||||
fn from(color: Hsla) -> Self {
|
fn from(color: Hsla) -> Self {
|
||||||
let h = color.h;
|
let h = color.h;
|
||||||
|
@ -47,18 +65,39 @@ impl From<Hsla> for Rgba {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&'_ str> for Rgba {
|
||||||
|
type Error = ParseIntError;
|
||||||
|
|
||||||
|
fn try_from(value: &'_ str) -> Result<Self, Self::Error> {
|
||||||
|
let r = u8::from_str_radix(&value[1..3], 16)? as f32 / 255.0;
|
||||||
|
let g = u8::from_str_radix(&value[3..5], 16)? as f32 / 255.0;
|
||||||
|
let b = u8::from_str_radix(&value[5..7], 16)? as f32 / 255.0;
|
||||||
|
let a = if value.len() > 7 {
|
||||||
|
u8::from_str_radix(&value[7..9], 16)? as f32 / 255.0
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Rgba { r, g, b, a })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Into<gpui::color::Color> for Rgba {
|
impl Into<gpui::color::Color> for Rgba {
|
||||||
fn into(self) -> gpui::color::Color {
|
fn into(self) -> gpui::color::Color {
|
||||||
gpui::color::rgba(self.r, self.g, self.b, self.a)
|
gpui::color::rgba(self.r, self.g, self.b, self.a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct Hsla {
|
pub struct Hsla {
|
||||||
h: f32,
|
pub h: f32,
|
||||||
s: f32,
|
pub s: f32,
|
||||||
l: f32,
|
pub l: f32,
|
||||||
a: f32,
|
pub a: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hsla(h: f32, s: f32, l: f32, a: f32) -> Hsla {
|
||||||
|
Hsla { h, s, l, a }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Rgba> for Hsla {
|
impl From<Rgba> for Hsla {
|
||||||
|
@ -100,6 +139,13 @@ impl From<Rgba> for Hsla {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hsla {
|
impl Hsla {
|
||||||
|
/// Scales the saturation and lightness by the given values, clamping at 1.0.
|
||||||
|
pub fn scale_sl(mut self, s: f32, l: f32) -> Self {
|
||||||
|
self.s = (self.s * s).clamp(0., 1.);
|
||||||
|
self.l = (self.l * l).clamp(0., 1.);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Increases the saturation of the color by a certain amount, with a max
|
/// Increases the saturation of the color by a certain amount, with a max
|
||||||
/// value of 1.0.
|
/// value of 1.0.
|
||||||
pub fn saturate(mut self, amount: f32) -> Self {
|
pub fn saturate(mut self, amount: f32) -> Self {
|
||||||
|
|
|
@ -28,6 +28,7 @@ pub struct Frame<V: View> {
|
||||||
style: FrameStyle,
|
style: FrameStyle,
|
||||||
children: Vec<AnyElement<V>>,
|
children: Vec<AnyElement<V>>,
|
||||||
id: Option<Cow<'static, str>>,
|
id: Option<Cow<'static, str>>,
|
||||||
|
before_paint: Option<Box<dyn FnMut(RectF, &mut FrameLayout, &mut PaintContext<V>)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn column<V: View>() -> Frame<V> {
|
pub fn column<V: View>() -> Frame<V> {
|
||||||
|
@ -60,6 +61,7 @@ impl<V: View> Default for Frame<V> {
|
||||||
style: Default::default(),
|
style: Default::default(),
|
||||||
children: Default::default(),
|
children: Default::default(),
|
||||||
id: None,
|
id: None,
|
||||||
|
before_paint: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +81,6 @@ impl<V: View> Element<V> for Frame<V> {
|
||||||
} else {
|
} else {
|
||||||
todo!()
|
todo!()
|
||||||
};
|
};
|
||||||
|
|
||||||
(layout.size.max(constraint.min), layout)
|
(layout.size.max(constraint.min), layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,22 +93,21 @@ impl<V: View> Element<V> for Frame<V> {
|
||||||
view: &mut V,
|
view: &mut V,
|
||||||
cx: &mut PaintContext<V>,
|
cx: &mut PaintContext<V>,
|
||||||
) -> Self::PaintState {
|
) -> Self::PaintState {
|
||||||
dbg!(self.id_string());
|
if let Some(before_paint) = &mut self.before_paint {
|
||||||
dbg!(bounds.origin(), bounds.size());
|
before_paint(bounds, layout, cx);
|
||||||
|
}
|
||||||
|
|
||||||
let bounds_center = dbg!(bounds.size()) / 2.;
|
let bounds_center = bounds.size() / 2.;
|
||||||
let bounds_target = bounds_center + (bounds_center * self.style.align.0);
|
let bounds_target = bounds_center + (bounds_center * self.style.align.0);
|
||||||
let layout_center = dbg!(layout.size) / 2.;
|
let layout_center = layout.size / 2.;
|
||||||
let layout_target = layout_center + layout_center * self.style.align.0;
|
let layout_target = layout_center + layout_center * self.style.align.0;
|
||||||
let delta = bounds_target - layout_target;
|
let delta = bounds_target - layout_target;
|
||||||
|
|
||||||
let aligned_bounds = RectF::new(bounds.origin() + delta, layout.size);
|
let aligned_bounds = RectF::new(bounds.origin() + delta, layout.size);
|
||||||
dbg!(aligned_bounds.origin(), aligned_bounds.size());
|
|
||||||
let margined_bounds = RectF::from_points(
|
let margined_bounds = RectF::from_points(
|
||||||
aligned_bounds.origin() + vec2f(layout.margins.left, layout.margins.top),
|
aligned_bounds.origin() + vec2f(layout.margins.left, layout.margins.top),
|
||||||
aligned_bounds.lower_right() - vec2f(layout.margins.right, layout.margins.bottom),
|
aligned_bounds.lower_right() - vec2f(layout.margins.right, layout.margins.bottom),
|
||||||
);
|
);
|
||||||
dbg!(margined_bounds.origin(), margined_bounds.size());
|
|
||||||
|
|
||||||
// Paint drop shadow
|
// Paint drop shadow
|
||||||
for shadow in &self.style.shadows {
|
for shadow in &self.style.shadows {
|
||||||
|
@ -238,6 +238,11 @@ impl<V: View> Frame<V> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn size(self, size: impl Into<Size<Length>>) -> Self {
|
||||||
|
let size = size.into();
|
||||||
|
self.width(size.width).height(size.height)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn width(mut self, width: impl Into<Length>) -> Self {
|
pub fn width(mut self, width: impl Into<Length>) -> Self {
|
||||||
self.style.size.width = width.into();
|
self.style.size.width = width.into();
|
||||||
self
|
self
|
||||||
|
@ -508,8 +513,15 @@ impl<V: View> Frame<V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg!(self.id_string());
|
layout
|
||||||
dbg!(layout)
|
}
|
||||||
|
|
||||||
|
fn before_paint<H>(mut self, handler: H) -> Self
|
||||||
|
where
|
||||||
|
H: 'static + FnMut(RectF, &mut FrameLayout, &mut PaintContext<V>),
|
||||||
|
{
|
||||||
|
self.before_paint = Some(Box::new(handler));
|
||||||
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +611,7 @@ struct TextStyle {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Add, Default, Clone)]
|
#[derive(Add, Default, Clone)]
|
||||||
struct Size<T> {
|
pub struct Size<T> {
|
||||||
width: T,
|
width: T,
|
||||||
height: T,
|
height: T,
|
||||||
}
|
}
|
||||||
|
@ -1478,12 +1490,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view<F, E>(mut function: F) -> ViewFn
|
pub fn view<F, E>(mut render: F) -> ViewFn
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(&mut ViewContext<ViewFn>) -> E,
|
F: 'static + FnMut(&mut ViewContext<ViewFn>) -> E,
|
||||||
E: Element<ViewFn>,
|
E: Element<ViewFn>,
|
||||||
{
|
{
|
||||||
ViewFn(Box::new(move |cx| (function)(cx).into_any()))
|
ViewFn(Box::new(move |cx| (render)(cx).into_any()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ViewFn(Box<dyn FnMut(&mut ViewContext<ViewFn>) -> AnyElement<ViewFn>>);
|
pub struct ViewFn(Box<dyn FnMut(&mut ViewContext<ViewFn>) -> AnyElement<ViewFn>>);
|
||||||
|
@ -1508,8 +1520,8 @@ mod tests {
|
||||||
use gpui::TestAppContext;
|
use gpui::TestAppContext;
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_layout(cx: &mut TestAppContext) {
|
fn test_frame_layout(cx: &mut TestAppContext) {
|
||||||
let window = cx.add_window(|_| {
|
cx.add_window(|_| {
|
||||||
view(|_| {
|
view(|_| {
|
||||||
let theme = rose_pine::dawn();
|
let theme = rose_pine::dawn();
|
||||||
column()
|
column()
|
||||||
|
@ -1520,32 +1532,25 @@ mod tests {
|
||||||
row()
|
row()
|
||||||
.width(auto())
|
.width(auto())
|
||||||
.height(rems(10.))
|
.height(rems(10.))
|
||||||
.fill(theme.foam)
|
|
||||||
.justify(1.)
|
.justify(1.)
|
||||||
.child(row().width(rems(10.)).height(auto()).fill(theme.gold)),
|
.child(
|
||||||
|
row()
|
||||||
|
.width(rems(10.))
|
||||||
|
.height(auto())
|
||||||
|
.fill(theme.surface(1.)),
|
||||||
|
)
|
||||||
|
.before_paint(|bounds, layout, cx| {
|
||||||
|
assert_eq!(bounds.origin(), vec2f(0., 0.));
|
||||||
|
assert_eq!(layout.size.x(), cx.window_size().x());
|
||||||
|
assert_eq!(layout.size.y(), rems(10.).to_pixels(cx.rem_pixels()));
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.child(row())
|
.child(row())
|
||||||
});
|
.before_paint(|bounds, layout, cx| {
|
||||||
});
|
assert_eq!(layout.size, cx.window_size());
|
||||||
|
})
|
||||||
window.update(cx, |cx| {
|
})
|
||||||
let root = cx.root_element();
|
})
|
||||||
dbg!(root.debug(cx).unwrap());
|
.remove(cx);
|
||||||
});
|
|
||||||
|
|
||||||
// tree.layout(
|
|
||||||
// SizeConstraint::strict(vec2f(100., 100.)),
|
|
||||||
// &mut (),
|
|
||||||
// LayoutContext::test(),
|
|
||||||
// );
|
|
||||||
|
|
||||||
// LayoutContext::new(
|
|
||||||
// cx,
|
|
||||||
// new_parents,
|
|
||||||
// views_to_notify_if_ancestors_change,
|
|
||||||
// refreshing,
|
|
||||||
// )
|
|
||||||
|
|
||||||
// tree.layout(SizeConstraint::strict(vec2f(100., 100.)), &mut (), cx)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use frame::{length::auto, *};
|
use frame::{length::auto, *};
|
||||||
use gpui::{AnyElement, Element, LayoutContext, View, ViewContext};
|
use gpui::{AnyElement, Element, LayoutContext, View, ViewContext};
|
||||||
use std::{borrow::Cow, cell::RefCell, marker::PhantomData, rc::Rc};
|
use std::{borrow::Cow, cell::RefCell, marker::PhantomData, rc::Rc};
|
||||||
|
use themes::ThemeColors;
|
||||||
use tokens::{margin::m4, text::lg};
|
use tokens::{margin::m4, text::lg};
|
||||||
|
|
||||||
mod color;
|
mod color;
|
||||||
|
@ -21,6 +22,25 @@ impl<V: View> Playground<V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn workspace<V: View>(theme: &ThemeColors) -> impl Element<V> {
|
||||||
|
column()
|
||||||
|
.child(title_bar(theme))
|
||||||
|
.child(stage(theme))
|
||||||
|
.child(status_bar(theme))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn title_bar<V: View>(theme: &ThemeColors) -> impl Element<V> {
|
||||||
|
row().fill(theme.surface(1.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stage<V: View>(theme: &ThemeColors) -> impl Element<V> {
|
||||||
|
row().fill(theme.surface(0.9))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn status_bar<V: View>(theme: &ThemeColors) -> impl Element<V> {
|
||||||
|
row().fill(theme.surface(0.1))
|
||||||
|
}
|
||||||
|
|
||||||
pub trait DialogDelegate<V: View>: 'static {}
|
pub trait DialogDelegate<V: View>: 'static {}
|
||||||
|
|
||||||
impl<V: View> DialogDelegate<V> for () {}
|
impl<V: View> DialogDelegate<V> for () {}
|
||||||
|
@ -113,6 +133,36 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl<V, D, F> Button<V, D, F>
|
||||||
|
// where
|
||||||
|
// V: View,
|
||||||
|
// F: ClickHandler<V, D>,
|
||||||
|
// {
|
||||||
|
// fn render(&mut self, _: &mut V, _: &mut LayoutContext<V>) -> impl Element<V> {
|
||||||
|
// // TODO! Handle click etc
|
||||||
|
// row()
|
||||||
|
// .fill(theme.colors.primary(5))
|
||||||
|
// .child(text(self.label.clone()).text_color(theme.colors.on_primary()))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// struct Tab<V> {
|
||||||
|
// active: bool,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// impl<V> Tab<V>
|
||||||
|
// where
|
||||||
|
// V: View,
|
||||||
|
// {
|
||||||
|
// fn tab(&mut self, _: &mut V, _: &mut LayoutContext<V>) -> impl Element<V> {
|
||||||
|
// let theme = todo!();
|
||||||
|
// // TODO! Handle click etc
|
||||||
|
// row()
|
||||||
|
// .fill(theme.colors.neutral(6))
|
||||||
|
// .child(text(self.label.clone()).text_color(theme.colors.on_neutral()))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
impl<V: View> Button<V, (), ()> {
|
impl<V: View> Button<V, (), ()> {
|
||||||
fn data<D>(self, data: D) -> Button<V, D, ()>
|
fn data<D>(self, data: D) -> Button<V, D, ()>
|
||||||
where
|
where
|
||||||
|
|
|
@ -1 +1,92 @@
|
||||||
|
use crate::color::{Hsla, Lerp};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::{ops::Range, sync::Arc};
|
||||||
|
|
||||||
pub mod rose_pine;
|
pub mod rose_pine;
|
||||||
|
|
||||||
|
pub struct ThemeColors {
|
||||||
|
pub base: Range<Hsla>,
|
||||||
|
pub surface: Range<Hsla>,
|
||||||
|
pub overlay: Range<Hsla>,
|
||||||
|
pub muted: Range<Hsla>,
|
||||||
|
pub subtle: Range<Hsla>,
|
||||||
|
pub text: Range<Hsla>,
|
||||||
|
pub highlight_low: Range<Hsla>,
|
||||||
|
pub highlight_med: Range<Hsla>,
|
||||||
|
pub highlight_high: Range<Hsla>,
|
||||||
|
pub success: Range<Hsla>,
|
||||||
|
pub warning: Range<Hsla>,
|
||||||
|
pub error: Range<Hsla>,
|
||||||
|
pub inserted: Range<Hsla>,
|
||||||
|
pub deleted: Range<Hsla>,
|
||||||
|
pub modified: Range<Hsla>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ThemeColors {
|
||||||
|
pub fn base(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn surface(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn overlay(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn muted(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn subtle(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn text(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn highlight_low(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn highlight_med(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn highlight_high(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn success(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn warning(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn error(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn inserted(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn deleted(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
pub fn modified(&self, level: f32) -> Hsla {
|
||||||
|
self.deleted.lerp(level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct Entity {
|
||||||
|
class: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
kind: String,
|
||||||
|
id: Arc<str>,
|
||||||
|
name: String,
|
||||||
|
value: String,
|
||||||
|
description: String,
|
||||||
|
category_id: String,
|
||||||
|
last_updated_by: String,
|
||||||
|
last_updated: String,
|
||||||
|
tags: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct Category {
|
||||||
|
id: String,
|
||||||
|
label: String,
|
||||||
|
}
|
||||||
|
|
|
@ -1,86 +1,133 @@
|
||||||
use crate::color::{rgb, Rgba};
|
use std::ops::Range;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
use crate::{
|
||||||
pub struct ThemeColors {
|
color::{hsla, rgb, Hsla},
|
||||||
pub base: Rgba,
|
ThemeColors,
|
||||||
pub surface: Rgba,
|
};
|
||||||
pub overlay: Rgba,
|
|
||||||
pub muted: Rgba,
|
|
||||||
pub subtle: Rgba,
|
|
||||||
pub text: Rgba,
|
|
||||||
pub love: Rgba,
|
|
||||||
pub gold: Rgba,
|
|
||||||
pub rose: Rgba,
|
|
||||||
pub pine: Rgba,
|
|
||||||
pub foam: Rgba,
|
|
||||||
pub iris: Rgba,
|
|
||||||
pub highlight_low: Rgba,
|
|
||||||
pub highlight_med: Rgba,
|
|
||||||
pub highlight_high: Rgba,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RosePineThemes {
|
pub struct RosePineThemes {
|
||||||
pub default: ThemeColors,
|
pub default: RosePinePalette,
|
||||||
pub dawn: ThemeColors,
|
pub dawn: RosePinePalette,
|
||||||
pub moon: ThemeColors,
|
pub moon: RosePinePalette,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct RosePinePalette {
|
||||||
|
pub base: Hsla,
|
||||||
|
pub surface: Hsla,
|
||||||
|
pub overlay: Hsla,
|
||||||
|
pub muted: Hsla,
|
||||||
|
pub subtle: Hsla,
|
||||||
|
pub text: Hsla,
|
||||||
|
pub love: Hsla,
|
||||||
|
pub gold: Hsla,
|
||||||
|
pub rose: Hsla,
|
||||||
|
pub pine: Hsla,
|
||||||
|
pub foam: Hsla,
|
||||||
|
pub iris: Hsla,
|
||||||
|
pub highlight_low: Hsla,
|
||||||
|
pub highlight_med: Hsla,
|
||||||
|
pub highlight_high: Hsla,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RosePinePalette {
|
||||||
|
pub fn default() -> RosePinePalette {
|
||||||
|
RosePinePalette {
|
||||||
|
base: rgb(0x191724),
|
||||||
|
surface: rgb(0x1f1d2e),
|
||||||
|
overlay: rgb(0x26233a),
|
||||||
|
muted: rgb(0x6e6a86),
|
||||||
|
subtle: rgb(0x908caa),
|
||||||
|
text: rgb(0xe0def4),
|
||||||
|
love: rgb(0xeb6f92),
|
||||||
|
gold: rgb(0xf6c177),
|
||||||
|
rose: rgb(0xebbcba),
|
||||||
|
pine: rgb(0x31748f),
|
||||||
|
foam: rgb(0x9ccfd8),
|
||||||
|
iris: rgb(0xc4a7e7),
|
||||||
|
highlight_low: rgb(0x21202e),
|
||||||
|
highlight_med: rgb(0x403d52),
|
||||||
|
highlight_high: rgb(0x524f67),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn moon() -> RosePinePalette {
|
||||||
|
RosePinePalette {
|
||||||
|
base: rgb(0x232136),
|
||||||
|
surface: rgb(0x2a273f),
|
||||||
|
overlay: rgb(0x393552),
|
||||||
|
muted: rgb(0x6e6a86),
|
||||||
|
subtle: rgb(0x908caa),
|
||||||
|
text: rgb(0xe0def4),
|
||||||
|
love: rgb(0xeb6f92),
|
||||||
|
gold: rgb(0xf6c177),
|
||||||
|
rose: rgb(0xea9a97),
|
||||||
|
pine: rgb(0x3e8fb0),
|
||||||
|
foam: rgb(0x9ccfd8),
|
||||||
|
iris: rgb(0xc4a7e7),
|
||||||
|
highlight_low: rgb(0x2a283e),
|
||||||
|
highlight_med: rgb(0x44415a),
|
||||||
|
highlight_high: rgb(0x56526e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dawn() -> RosePinePalette {
|
||||||
|
RosePinePalette {
|
||||||
|
base: rgb(0xfaf4ed),
|
||||||
|
surface: rgb(0xfffaf3),
|
||||||
|
overlay: rgb(0xf2e9e1),
|
||||||
|
muted: rgb(0x9893a5),
|
||||||
|
subtle: rgb(0x797593),
|
||||||
|
text: rgb(0x575279),
|
||||||
|
love: rgb(0xb4637a),
|
||||||
|
gold: rgb(0xea9d34),
|
||||||
|
rose: rgb(0xd7827e),
|
||||||
|
pine: rgb(0x286983),
|
||||||
|
foam: rgb(0x56949f),
|
||||||
|
iris: rgb(0x907aa9),
|
||||||
|
highlight_low: rgb(0xf4ede8),
|
||||||
|
highlight_med: rgb(0xdfdad9),
|
||||||
|
highlight_high: rgb(0xcecacd),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default() -> ThemeColors {
|
pub fn default() -> ThemeColors {
|
||||||
ThemeColors {
|
theme_colors(&RosePinePalette::default())
|
||||||
base: rgb(0x191724),
|
|
||||||
surface: rgb(0x1f1d2e),
|
|
||||||
overlay: rgb(0x26233a),
|
|
||||||
muted: rgb(0x6e6a86),
|
|
||||||
subtle: rgb(0x908caa),
|
|
||||||
text: rgb(0xe0def4),
|
|
||||||
love: rgb(0xeb6f92),
|
|
||||||
gold: rgb(0xf6c177),
|
|
||||||
rose: rgb(0xebbcba),
|
|
||||||
pine: rgb(0x31748f),
|
|
||||||
foam: rgb(0x9ccfd8),
|
|
||||||
iris: rgb(0xc4a7e7),
|
|
||||||
highlight_low: rgb(0x21202e),
|
|
||||||
highlight_med: rgb(0x403d52),
|
|
||||||
highlight_high: rgb(0x524f67),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn moon() -> ThemeColors {
|
pub fn moon() -> ThemeColors {
|
||||||
ThemeColors {
|
theme_colors(&RosePinePalette::moon())
|
||||||
base: rgb(0x232136),
|
|
||||||
surface: rgb(0x2a273f),
|
|
||||||
overlay: rgb(0x393552),
|
|
||||||
muted: rgb(0x6e6a86),
|
|
||||||
subtle: rgb(0x908caa),
|
|
||||||
text: rgb(0xe0def4),
|
|
||||||
love: rgb(0xeb6f92),
|
|
||||||
gold: rgb(0xf6c177),
|
|
||||||
rose: rgb(0xea9a97),
|
|
||||||
pine: rgb(0x3e8fb0),
|
|
||||||
foam: rgb(0x9ccfd8),
|
|
||||||
iris: rgb(0xc4a7e7),
|
|
||||||
highlight_low: rgb(0x2a283e),
|
|
||||||
highlight_med: rgb(0x44415a),
|
|
||||||
highlight_high: rgb(0x56526e),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dawn() -> ThemeColors {
|
pub fn dawn() -> ThemeColors {
|
||||||
|
theme_colors(&RosePinePalette::dawn())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn theme_colors(p: &RosePinePalette) -> ThemeColors {
|
||||||
ThemeColors {
|
ThemeColors {
|
||||||
base: rgb(0xfaf4ed),
|
base: scale_sl(p.base, (0.8, 0.8), (1.2, 1.2)),
|
||||||
surface: rgb(0xfffaf3),
|
surface: scale_sl(p.surface, (0.8, 0.8), (1.2, 1.2)),
|
||||||
overlay: rgb(0xf2e9e1),
|
overlay: scale_sl(p.overlay, (0.8, 0.8), (1.2, 1.2)),
|
||||||
muted: rgb(0x9893a5),
|
muted: scale_sl(p.muted, (0.8, 0.8), (1.2, 1.2)),
|
||||||
subtle: rgb(0x797593),
|
subtle: scale_sl(p.subtle, (0.8, 0.8), (1.2, 1.2)),
|
||||||
text: rgb(0x575279),
|
text: scale_sl(p.text, (0.8, 0.8), (1.2, 1.2)),
|
||||||
love: rgb(0xb4637a),
|
highlight_low: scale_sl(p.highlight_low, (0.8, 0.8), (1.2, 1.2)),
|
||||||
gold: rgb(0xea9d34),
|
highlight_med: scale_sl(p.highlight_med, (0.8, 0.8), (1.2, 1.2)),
|
||||||
rose: rgb(0xd7827e),
|
highlight_high: scale_sl(p.highlight_high, (0.8, 0.8), (1.2, 1.2)),
|
||||||
pine: rgb(0x286983),
|
success: scale_sl(p.foam, (0.8, 0.8), (1.2, 1.2)),
|
||||||
foam: rgb(0x56949f),
|
warning: scale_sl(p.gold, (0.8, 0.8), (1.2, 1.2)),
|
||||||
iris: rgb(0x907aa9),
|
error: scale_sl(p.love, (0.8, 0.8), (1.2, 1.2)),
|
||||||
highlight_low: rgb(0xf4ede8),
|
inserted: scale_sl(p.foam, (0.8, 0.8), (1.2, 1.2)),
|
||||||
highlight_med: rgb(0xdfdad9),
|
deleted: scale_sl(p.love, (0.8, 0.8), (1.2, 1.2)),
|
||||||
highlight_high: rgb(0xcecacd),
|
modified: scale_sl(p.rose, (0.8, 0.8), (1.2, 1.2)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Produces a range by multiplying the saturation and lightness of the base color by the given
|
||||||
|
/// start and end factors.
|
||||||
|
fn scale_sl(base: Hsla, (start_s, start_l): (f32, f32), (end_s, end_l): (f32, f32)) -> Range<Hsla> {
|
||||||
|
let start = hsla(base.h, base.s * start_s, base.l * start_l, base.a);
|
||||||
|
let end = hsla(base.h, base.s * end_s, base.l * end_l, base.a);
|
||||||
|
Range { start, end }
|
||||||
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ pub use test_app_context::{ContextHandle, TestAppContext};
|
||||||
use window_input_handler::WindowInputHandler;
|
use window_input_handler::WindowInputHandler;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
elements::{AnyElement, AnyRootElement, Empty, RootElement},
|
elements::{AnyElement, AnyRootElement, RootElement},
|
||||||
executor::{self, Task},
|
executor::{self, Task},
|
||||||
fonts::TextStyle,
|
fonts::TextStyle,
|
||||||
json,
|
json,
|
||||||
|
@ -55,7 +55,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
util::post_inc,
|
util::post_inc,
|
||||||
window::{Window, WindowContext},
|
window::{Window, WindowContext},
|
||||||
AssetCache, AssetSource, ClipboardItem, Element, FontCache, MouseRegionId,
|
AssetCache, AssetSource, ClipboardItem, FontCache, MouseRegionId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::ref_counts::RefCounts;
|
use self::ref_counts::RefCounts;
|
||||||
|
@ -129,16 +129,6 @@ pub trait View: Entity + Sized {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for () {
|
|
||||||
type Event = ();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl View for () {
|
|
||||||
fn render(&mut self, _: &mut ViewContext<'_, '_, Self>) -> AnyElement<Self> {
|
|
||||||
Empty::new().into_any()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait BorrowAppContext {
|
pub trait BorrowAppContext {
|
||||||
fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T;
|
fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T;
|
||||||
fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, f: F) -> T;
|
fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, f: F) -> T;
|
||||||
|
@ -2155,7 +2145,7 @@ struct ViewMetadata {
|
||||||
keymap_context: KeymapContext,
|
keymap_context: KeymapContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone, Debug)]
|
||||||
pub struct WindowInvalidation {
|
pub struct WindowInvalidation {
|
||||||
pub updated: HashSet<usize>,
|
pub updated: HashSet<usize>,
|
||||||
pub removed: Vec<usize>,
|
pub removed: Vec<usize>,
|
||||||
|
|
|
@ -940,7 +940,9 @@ impl<'a> WindowContext<'a> {
|
||||||
pub fn layout(&mut self, refreshing: bool) -> Result<HashMap<usize, usize>> {
|
pub fn layout(&mut self, refreshing: bool) -> Result<HashMap<usize, usize>> {
|
||||||
let window_size = self.window.platform_window.content_size();
|
let window_size = self.window.platform_window.content_size();
|
||||||
let root_view_id = self.window.root_view().id();
|
let root_view_id = self.window.root_view().id();
|
||||||
|
|
||||||
let mut rendered_root = self.window.rendered_views.remove(&root_view_id).unwrap();
|
let mut rendered_root = self.window.rendered_views.remove(&root_view_id).unwrap();
|
||||||
|
|
||||||
let mut new_parents = HashMap::default();
|
let mut new_parents = HashMap::default();
|
||||||
let mut views_to_notify_if_ancestors_change = HashMap::default();
|
let mut views_to_notify_if_ancestors_change = HashMap::default();
|
||||||
rendered_root.layout(
|
rendered_root.layout(
|
||||||
|
|
|
@ -92,7 +92,7 @@ postage.workspace = true
|
||||||
rand.workspace = true
|
rand.workspace = true
|
||||||
regex.workspace = true
|
regex.workspace = true
|
||||||
rsa = "0.4"
|
rsa = "0.4"
|
||||||
rust-embed = { version = "6.3", features = ["include-exclude"] }
|
rust-embed = { version = "6.8.1" }
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_derive.workspace = true
|
serde_derive.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue