#![feature(prelude_import)]#![allow(dead_code, unused_variables)]#[prelude_import]use std::prelude::rust_2021::*;#[macro_use]extern crate std;use color::black;use components::button;use element::Element;use frame::frame;use gpui::{ geometry::{rect::RectF, vector::vec2f}, platform::WindowOptions,};use log::LevelFilter;use simplelog::SimpleLogger;use themes::{rose_pine, ThemeColors};use view::view;mod adapter { use crate::element::{LayoutContext, PaintContext}; use gpui::{geometry::rect::RectF, LayoutEngine}; use util::ResultExt; use crate::element::AnyElement; pub struct Adapter<V>(pub(crate) AnyElement<V>); impl<V: 'static> gpui::Element<V> for Adapter<V> { type LayoutState = Option<LayoutEngine>; type PaintState = (); fn layout( &mut self, constraint: gpui::SizeConstraint, view: &mut V, cx: &mut LayoutContext<V>, ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) { cx.push_layout_engine(LayoutEngine::new()); let node = self.0.layout(view, cx).log_err(); if let Some(node) = node { let layout_engine = cx.layout_engine().unwrap(); layout_engine.compute_layout(node, constraint.max).log_err(); } let layout_engine = cx.pop_layout_engine(); if true { if !layout_engine.is_some() { ::core::panicking::panic("assertion failed: layout_engine.is_some()") } } (constraint.max, layout_engine) } fn paint( &mut self, scene: &mut gpui::SceneBuilder, bounds: RectF, visible_bounds: RectF, layout_engine: &mut Option<LayoutEngine>, view: &mut V, legacy_cx: &mut gpui::PaintContext<V>, ) -> Self::PaintState { legacy_cx.push_layout_engine(layout_engine.take().unwrap()); let mut cx = PaintContext::new(legacy_cx, scene); self.0.paint(view, &mut cx).log_err(); *layout_engine = legacy_cx.pop_layout_engine(); if true { if !layout_engine.is_some() { ::core::panicking::panic("assertion failed: layout_engine.is_some()") } } } fn rect_for_text_range( &self, range_utf16: std::ops::Range<usize>, bounds: RectF, visible_bounds: RectF, layout: &Self::LayoutState, paint: &Self::PaintState, view: &V, cx: &gpui::ViewContext<V>, ) -> Option<RectF> { ::core::panicking::panic("not yet implemented") } fn debug( &self, bounds: RectF, layout: &Self::LayoutState, paint: &Self::PaintState, view: &V, cx: &gpui::ViewContext<V>, ) -> gpui::serde_json::Value { ::core::panicking::panic("not yet implemented") } }}mod color { #![allow(dead_code)] use std::{num::ParseIntError, ops::Range}; use smallvec::SmallVec; pub fn rgb<C: From<Rgba>>(hex: u32) -> C { let r = ((hex >> 16) & 0xFF) as f32 / 255.0; let g = ((hex >> 8) & 0xFF) as f32 / 255.0; let b = (hex & 0xFF) as f32 / 255.0; Rgba { r, g, b, a: 1.0 }.into() } pub struct Rgba { pub r: f32, pub g: f32, pub b: f32, pub a: f32, } #[automatically_derived] impl ::core::clone::Clone for Rgba { #[inline] fn clone(&self) -> Rgba { let _: ::core::clone::AssertParamIsClone<f32>; *self } } #[automatically_derived] impl ::core::marker::Copy for Rgba {} #[automatically_derived] impl ::core::default::Default for Rgba { #[inline] fn default() -> Rgba { Rgba { r: ::core::default::Default::default(), g: ::core::default::Default::default(), b: ::core::default::Default::default(), a: ::core::default::Default::default(), } } } #[automatically_derived] impl ::core::fmt::Debug for Rgba { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { ::core::fmt::Formatter::debug_struct_field4_finish( f, "Rgba", "r", &self.r, "g", &self.g, "b", &self.b, "a", &&self.a, ) } } 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<gpui::color::Color> for Rgba { fn from(value: gpui::color::Color) -> Self { Self { r: value.0.r as f32 / 255.0, g: value.0.g as f32 / 255.0, b: value.0.b as f32 / 255.0, a: value.0.a as f32 / 255.0, } } } impl From<Hsla> for Rgba { fn from(color: Hsla) -> Self { let h = color.h; let s = color.s; let l = color.l; let c = (1.0 - (2.0 * l - 1.0).abs()) * s; let x = c * (1.0 - ((h * 6.0) % 2.0 - 1.0).abs()); let m = l - c / 2.0; let cm = c + m; let xm = x + m; let (r, g, b) = match (h * 6.0).floor() as i32 { 0 | 6 => (cm, xm, m), 1 => (xm, cm, m), 2 => (m, cm, xm), 3 => (m, xm, cm), 4 => (xm, m, cm), _ => (cm, m, xm), }; Rgba { r, g, b, a: color.a } } } 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 { fn into(self) -> gpui::color::Color { gpui::color::rgba(self.r, self.g, self.b, self.a) } } pub struct Hsla { pub h: f32, pub s: f32, pub l: f32, pub a: f32, } #[automatically_derived] impl ::core::default::Default for Hsla { #[inline] fn default() -> Hsla { Hsla { h: ::core::default::Default::default(), s: ::core::default::Default::default(), l: ::core::default::Default::default(), a: ::core::default::Default::default(), } } } #[automatically_derived] impl ::core::marker::Copy for Hsla {} #[automatically_derived] impl ::core::clone::Clone for Hsla { #[inline] fn clone(&self) -> Hsla { let _: ::core::clone::AssertParamIsClone<f32>; *self } } #[automatically_derived] impl ::core::fmt::Debug for Hsla { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { ::core::fmt::Formatter::debug_struct_field4_finish( f, "Hsla", "h", &self.h, "s", &self.s, "l", &self.l, "a", &&self.a, ) } } #[automatically_derived] impl ::core::marker::StructuralPartialEq for Hsla {} #[automatically_derived] impl ::core::cmp::PartialEq for Hsla { #[inline] fn eq(&self, other: &Hsla) -> bool { self.h == other.h && self.s == other.s && self.l == other.l && self.a == other.a } } pub fn hsla(h: f32, s: f32, l: f32, a: f32) -> Hsla { Hsla { h: h.clamp(0., 1.), s: s.clamp(0., 1.), l: l.clamp(0., 1.), a: a.clamp(0., 1.), } } pub fn black() -> Hsla { Hsla { h: 0., s: 0., l: 0., a: 1. } } impl From<Rgba> for Hsla { fn from(color: Rgba) -> Self { let r = color.r; let g = color.g; let b = color.b; let max = r.max(g.max(b)); let min = r.min(g.min(b)); let delta = max - min; let l = (max + min) / 2.0; let s = if l == 0.0 || l == 1.0 { 0.0 } else if l < 0.5 { delta / (2.0 * l) } else { delta / (2.0 - 2.0 * l) }; let h = if delta == 0.0 { 0.0 } else if max == r { ((g - b) / delta).rem_euclid(6.0) / 6.0 } else if max == g { ((b - r) / delta + 2.0) / 6.0 } else { ((r - g) / delta + 4.0) / 6.0 }; Hsla { h, s, l, a: color.a } } } 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 /// value of 1.0. pub fn saturate(mut self, amount: f32) -> Self { self.s += amount; self.s = self.s.clamp(0.0, 1.0); self } /// Decreases the saturation of the color by a certain amount, with a min /// value of 0.0. pub fn desaturate(mut self, amount: f32) -> Self { self.s -= amount; self.s = self.s.max(0.0); if self.s < 0.0 { self.s = 0.0; } self } /// Brightens the color by increasing the lightness by a certain amount, /// with a max value of 1.0. pub fn brighten(mut self, amount: f32) -> Self { self.l += amount; self.l = self.l.clamp(0.0, 1.0); self } /// Darkens the color by decreasing the lightness by a certain amount, /// with a max value of 0.0. pub fn darken(mut self, amount: f32) -> Self { self.l -= amount; self.l = self.l.clamp(0.0, 1.0); self } } impl From<gpui::color::Color> for Hsla { fn from(value: gpui::color::Color) -> Self { Rgba::from(value).into() } } impl Into<gpui::color::Color> for Hsla { fn into(self) -> gpui::color::Color { Rgba::from(self).into() } } pub struct ColorScale { colors: SmallVec<[Hsla; 2]>, positions: SmallVec<[f32; 2]>, } pub fn scale<I, C>(colors: I) -> ColorScale where I: IntoIterator<Item = C>, C: Into<Hsla>, { let mut scale = ColorScale { colors: colors.into_iter().map(Into::into).collect(), positions: SmallVec::new(), }; let num_colors: f32 = scale.colors.len() as f32 - 1.0; scale .positions = (0..scale.colors.len()) .map(|i| i as f32 / num_colors) .collect(); scale } impl ColorScale { fn at(&self, t: f32) -> Hsla { if true { if !(0.0 <= t && t <= 1.0) { { ::core::panicking::panic_fmt( format_args!( "t value {0} is out of range. Expected value in range 0.0 to 1.0", t, ), ); } } } let position = match self .positions .binary_search_by(|a| a.partial_cmp(&t).unwrap()) { Ok(index) | Err(index) => index, }; let lower_bound = position.saturating_sub(1); let upper_bound = position.min(self.colors.len() - 1); let lower_color = &self.colors[lower_bound]; let upper_color = &self.colors[upper_bound]; match upper_bound.checked_sub(lower_bound) { Some(0) | None => *lower_color, Some(_) => { let interval_t = (t - self.positions[lower_bound]) / (self.positions[upper_bound] - self.positions[lower_bound]); let h = lower_color.h + interval_t * (upper_color.h - lower_color.h); let s = lower_color.s + interval_t * (upper_color.s - lower_color.s); let l = lower_color.l + interval_t * (upper_color.l - lower_color.l); let a = lower_color.a + interval_t * (upper_color.a - lower_color.a); Hsla { h, s, l, a } } } } }}mod components { use crate::{ element::{Element, ElementMetadata}, frame, text::ArcCow, themes::rose_pine, }; use gpui::{platform::MouseButton, ViewContext}; use playground_macros::Element; use std::{marker::PhantomData, rc::Rc}; struct ButtonHandlers<V, D> { click: Option<Rc<dyn Fn(&mut V, &D, &mut ViewContext<V>)>>, } impl<V, D> Default for ButtonHandlers<V, D> { fn default() -> Self { Self { click: None } } } #[element_crate = "crate"] pub struct Button<V: 'static, D: 'static> { metadata: ElementMetadata<V>, handlers: ButtonHandlers<V, D>, label: Option<ArcCow<'static, str>>, icon: Option<ArcCow<'static, str>>, data: Rc<D>, view_type: PhantomData<V>, } impl<V: 'static, D: 'static> crate::element::Element<V> for Button<V, D> { type Layout = crate::element::AnyElement<V>; fn declared_style(&mut self) -> &mut crate::style::OptionalStyle { &mut self.metadata.style } fn handlers_mut(&mut self) -> &mut Vec<crate::element::EventHandler<V>> { &mut self.metadata.handlers } fn layout( &mut self, view: &mut V, cx: &mut crate::element::LayoutContext<V>, ) -> anyhow::Result<(taffy::tree::NodeId, Self::Layout)> { let mut element = self.render(view, cx).into_any(); let node_id = element.layout(view, cx)?; Ok((node_id, element)) } fn paint<'a>( &mut self, layout: crate::element::Layout<'a, Self::Layout>, view: &mut V, cx: &mut crate::element::PaintContext<V>, ) -> anyhow::Result<()> { layout.from_element.paint(view, cx)?; Ok(()) } } impl<V: 'static, D: 'static> crate::element::IntoElement<V> for Button<V, D> { type Element = Self; fn into_element(self) -> Self { self } } impl<V: 'static> Button<V, ()> { fn new() -> Self { Self { metadata: Default::default(), handlers: ButtonHandlers::default(), label: None, icon: None, data: Rc::new(()), view_type: PhantomData, } } pub fn data<D: 'static>(self, data: D) -> Button<V, D> { Button { metadata: Default::default(), handlers: ButtonHandlers::default(), label: self.label, icon: self.icon, data: Rc::new(data), view_type: PhantomData, } } } impl<V: 'static, D: 'static> Button<V, D> { pub fn label(mut self, label: impl Into<ArcCow<'static, str>>) -> Self { self.label = Some(label.into()); self } pub fn icon(mut self, icon: impl Into<ArcCow<'static, str>>) -> Self { self.icon = Some(icon.into()); self }Lines 1–500 of 5670. Load more
#![feature(prelude_import)] #![allow(dead_code, unused_variables)] #[prelude_import] use std::prelude::rust_2021::*; #[macro_use] extern crate std; use color::black; use components::button; use element::Element; use frame::frame; use gpui::{ geometry::{rect::RectF, vector::vec2f}, platform::WindowOptions, }; use log::LevelFilter; use simplelog::SimpleLogger; use themes::{rose_pine, ThemeColors}; use view::view; mod adapter { use crate::element::{LayoutContext, PaintContext}; use gpui::{geometry::rect::RectF, LayoutEngine}; use util::ResultExt; use crate::element::AnyElement; pub struct Adapter<V>(pub(crate) AnyElement<V>); impl<V: 'static> gpui::Element<V> for Adapter<V> { type LayoutState = Option<LayoutEngine>; type PaintState = (); fn layout( &mut self, constraint: gpui::SizeConstraint, view: &mut V, cx: &mut LayoutContext<V>, ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) { cx.push_layout_engine(LayoutEngine::new()); let node = self.0.layout(view, cx).log_err(); if let Some(node) = node { let layout_engine = cx.layout_engine().unwrap(); layout_engine.compute_layout(node, constraint.max).log_err(); } let layout_engine = cx.pop_layout_engine(); if true { if !layout_engine.is_some() { ::core::panicking::panic("assertion failed: layout_engine.is_some()") } } (constraint.max, layout_engine) } fn paint( &mut self, scene: &mut gpui::SceneBuilder, bounds: RectF, visible_bounds: RectF, layout_engine: &mut Option<LayoutEngine>, view: &mut V, legacy_cx: &mut gpui::PaintContext<V>, ) -> Self::PaintState { legacy_cx.push_layout_engine(layout_engine.take().unwrap()); let mut cx = PaintContext::new(legacy_cx, scene); self.0.paint(view, &mut cx).log_err(); *layout_engine = legacy_cx.pop_layout_engine(); if true { if !layout_engine.is_some() { ::core::panicking::panic("assertion failed: layout_engine.is_some()") } } } fn rect_for_text_range( &self, range_utf16: std::ops::Range<usize>, bounds: RectF, visible_bounds: RectF, layout: &Self::LayoutState, paint: &Self::PaintState, view: &V, cx: &gpui::ViewContext<V>, ) -> Option<RectF> { ::core::panicking::panic("not yet implemented") } fn debug( &self, bounds: RectF, layout: &Self::LayoutState, paint: &Self::PaintState, view: &V, cx: &gpui::ViewContext<V>, ) -> gpui::serde_json::Value { ::core::panicking::panic("not yet implemented") } } } mod color { #![allow(dead_code)] use std::{num::ParseIntError, ops::Range}; use smallvec::SmallVec; pub fn rgb<C: From<Rgba>>(hex: u32) -> C { let r = ((hex >> 16) & 0xFF) as f32 / 255.0; let g = ((hex >> 8) & 0xFF) as f32 / 255.0; let b = (hex & 0xFF) as f32 / 255.0; Rgba { r, g, b, a: 1.0 }.into() } pub struct Rgba { pub r: f32, pub g: f32, pub b: f32, pub a: f32, } #[automatically_derived] impl ::core::clone::Clone for Rgba { #[inline] fn clone(&self) -> Rgba { let _: ::core::clone::AssertParamIsClone<f32>; *self } } #[automatically_derived] impl ::core::marker::Copy for Rgba {} #[automatically_derived] impl ::core::default::Default for Rgba { #[inline] fn default() -> Rgba { Rgba { r: ::core::default::Default::default(), g: ::core::default::Default::default(), b: ::core::default::Default::default(), a: ::core::default::Default::default(), } } } #[automatically_derived] impl ::core::fmt::Debug for Rgba { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { ::core::fmt::Formatter::debug_struct_field4_finish( f, "Rgba", "r", &self.r, "g", &self.g, "b", &self.b, "a", &&self.a, ) } } 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<gpui::color::Color> for Rgba { fn from(value: gpui::color::Color) -> Self { Self { r: value.0.r as f32 / 255.0, g: value.0.g as f32 / 255.0, b: value.0.b as f32 / 255.0, a: value.0.a as f32 / 255.0, } } } impl From<Hsla> for Rgba { fn from(color: Hsla) -> Self { let h = color.h; let s = color.s; let l = color.l; let c = (1.0 - (2.0 * l - 1.0).abs()) * s; let x = c * (1.0 - ((h * 6.0) % 2.0 - 1.0).abs()); let m = l - c / 2.0; let cm = c + m; let xm = x + m; let (r, g, b) = match (h * 6.0).floor() as i32 { 0 | 6 => (cm, xm, m), 1 => (xm, cm, m), 2 => (m, cm, xm), 3 => (m, xm, cm), 4 => (xm, m, cm), _ => (cm, m, xm), }; Rgba { r, g, b, a: color.a } } } 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 { fn into(self) -> gpui::color::Color { gpui::color::rgba(self.r, self.g, self.b, self.a) } } pub struct Hsla { pub h: f32, pub s: f32, pub l: f32, pub a: f32, } #[automatically_derived] impl ::core::default::Default for Hsla { #[inline] fn default() -> Hsla { Hsla { h: ::core::default::Default::default(), s: ::core::default::Default::default(), l: ::core::default::Default::default(), a: ::core::default::Default::default(), } } } #[automatically_derived] impl ::core::marker::Copy for Hsla {} #[automatically_derived] impl ::core::clone::Clone for Hsla { #[inline] fn clone(&self) -> Hsla { let _: ::core::clone::AssertParamIsClone<f32>; *self } } #[automatically_derived] impl ::core::fmt::Debug for Hsla { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { ::core::fmt::Formatter::debug_struct_field4_finish( f, "Hsla", "h", &self.h, "s", &self.s, "l", &self.l, "a", &&self.a, ) } } #[automatically_derived] impl ::core::marker::StructuralPartialEq for Hsla {} #[automatically_derived] impl ::core::cmp::PartialEq for Hsla { #[inline] fn eq(&self, other: &Hsla) -> bool { self.h == other.h && self.s == other.s && self.l == other.l && self.a == other.a } } pub fn hsla(h: f32, s: f32, l: f32, a: f32) -> Hsla { Hsla { h: h.clamp(0., 1.), s: s.clamp(0., 1.), l: l.clamp(0., 1.), a: a.clamp(0., 1.), } } pub fn black() -> Hsla { Hsla { h: 0., s: 0., l: 0., a: 1. } } impl From<Rgba> for Hsla { fn from(color: Rgba) -> Self { let r = color.r; let g = color.g; let b = color.b; let max = r.max(g.max(b)); let min = r.min(g.min(b)); let delta = max - min; let l = (max + min) / 2.0; let s = if l == 0.0 || l == 1.0 { 0.0 } else if l < 0.5 { delta / (2.0 * l) } else { delta / (2.0 - 2.0 * l) }; let h = if delta == 0.0 { 0.0 } else if max == r { ((g - b) / delta).rem_euclid(6.0) / 6.0 } else if max == g { ((b - r) / delta + 2.0) / 6.0 } else { ((r - g) / delta + 4.0) / 6.0 }; Hsla { h, s, l, a: color.a } } } 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 /// value of 1.0. pub fn saturate(mut self, amount: f32) -> Self { self.s += amount; self.s = self.s.clamp(0.0, 1.0); self } /// Decreases the saturation of the color by a certain amount, with a min /// value of 0.0. pub fn desaturate(mut self, amount: f32) -> Self { self.s -= amount; self.s = self.s.max(0.0); if self.s < 0.0 { self.s = 0.0; } self } /// Brightens the color by increasing the lightness by a certain amount, /// with a max value of 1.0. pub fn brighten(mut self, amount: f32) -> Self { self.l += amount; self.l = self.l.clamp(0.0, 1.0); self } /// Darkens the color by decreasing the lightness by a certain amount, /// with a max value of 0.0. pub fn darken(mut self, amount: f32) -> Self { self.l -= amount; self.l = self.l.clamp(0.0, 1.0); self } } impl From<gpui::color::Color> for Hsla { fn from(value: gpui::color::Color) -> Self { Rgba::from(value).into() } } impl Into<gpui::color::Color> for Hsla { fn into(self) -> gpui::color::Color { Rgba::from(self).into() } } pub struct ColorScale { colors: SmallVec<[Hsla; 2]>, positions: SmallVec<[f32; 2]>, } pub fn scale<I, C>(colors: I) -> ColorScale where I: IntoIterator<Item = C>, C: Into<Hsla>, { let mut scale = ColorScale { colors: colors.into_iter().map(Into::into).collect(), positions: SmallVec::new(), }; let num_colors: f32 = scale.colors.len() as f32 - 1.0; scale .positions = (0..scale.colors.len()) .map(|i| i as f32 / num_colors) .collect(); scale } impl ColorScale { fn at(&self, t: f32) -> Hsla { if true { if !(0.0 <= t && t <= 1.0) { { ::core::panicking::panic_fmt( format_args!( "t value {0} is out of range. Expected value in range 0.0 to 1.0", t, ), ); } } } let position = match self .positions .binary_search_by(|a| a.partial_cmp(&t).unwrap()) { Ok(index) | Err(index) => index, }; let lower_bound = position.saturating_sub(1); let upper_bound = position.min(self.colors.len() - 1); let lower_color = &self.colors[lower_bound]; let upper_color = &self.colors[upper_bound]; match upper_bound.checked_sub(lower_bound) { Some(0) | None => *lower_color, Some(_) => { let interval_t = (t - self.positions[lower_bound]) / (self.positions[upper_bound] - self.positions[lower_bound]); let h = lower_color.h + interval_t * (upper_color.h - lower_color.h); let s = lower_color.s + interval_t * (upper_color.s - lower_color.s); let l = lower_color.l + interval_t * (upper_color.l - lower_color.l); let a = lower_color.a + interval_t * (upper_color.a - lower_color.a); Hsla { h, s, l, a } } } } } } mod components { use crate::{ element::{Element, ElementMetadata}, frame, text::ArcCow, themes::rose_pine, }; use gpui::{platform::MouseButton, ViewContext}; use playground_macros::Element; use std::{marker::PhantomData, rc::Rc}; struct ButtonHandlers<V, D> { click: Option<Rc<dyn Fn(&mut V, &D, &mut ViewContext<V>)>>, } impl<V, D> Default for ButtonHandlers<V, D> { fn default() -> Self { Self { click: None } } } #[element_crate = "crate"] pub struct Button<V: 'static, D: 'static> { metadata: ElementMetadata<V>, handlers: ButtonHandlers<V, D>, label: Option<ArcCow<'static, str>>, icon: Option<ArcCow<'static, str>>, data: Rc<D>, view_type: PhantomData<V>, } impl<V: 'static, D: 'static> crate::element::Element<V> for Button<V, D> { type Layout = crate::element::AnyElement<V>; fn declared_style(&mut self) -> &mut crate::style::OptionalStyle { &mut self.metadata.style } fn handlers_mut(&mut self) -> &mut Vec<crate::element::EventHandler<V>> { &mut self.metadata.handlers } fn layout( &mut self, view: &mut V, cx: &mut crate::element::LayoutContext<V>, ) -> anyhow::Result<(taffy::tree::NodeId, Self::Layout)> { let mut element = self.render(view, cx).into_any(); let node_id = element.layout(view, cx)?; Ok((node_id, element)) } fn paint<'a>( &mut self, layout: crate::element::Layout<'a, Self::Layout>, view: &mut V, cx: &mut crate::element::PaintContext<V>, ) -> anyhow::Result<()> { layout.from_element.paint(view, cx)?; Ok(()) } } impl<V: 'static, D: 'static> crate::element::IntoElement<V> for Button<V, D> { type Element = Self; fn into_element(self) -> Self { self } } impl<V: 'static> Button<V, ()> { fn new() -> Self { Self { metadata: Default::default(), handlers: ButtonHandlers::default(), label: None, icon: None, data: Rc::new(()), view_type: PhantomData, } } pub fn data<D: 'static>(self, data: D) -> Button<V, D> { Button { metadata: Default::default(), handlers: ButtonHandlers::default(), label: self.label, icon: self.icon, data: Rc::new(data), view_type: PhantomData, } } } impl<V: 'static, D: 'static> Button<V, D> { pub fn label(mut self, label: impl Into<ArcCow<'static, str>>) -> Self { self.label = Some(label.into()); self } pub fn icon(mut self, icon: impl Into<ArcCow<'static, str>>) -> Self { self.icon = Some(icon.into()); self }