Skip to content

Commit

Permalink
add box shadow
Browse files Browse the repository at this point in the history
  • Loading branch information
dzhou121 committed Aug 18, 2023
1 parent 2c51ee3 commit 246ba21
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 26 deletions.
13 changes: 10 additions & 3 deletions examples/counter/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ fn app_view() -> impl View {
stack(|| {
(
label(|| "Increment".to_string())
.style(|| Style::BASE.border(1.0).border_radius(10.0).padding_px(10.0))
.style(|| {
Style::BASE
.border_radius(10.0)
.padding_px(10.0)
.background(Color::WHITE)
.box_shadow_blur(5.0)
})
.on_click({
move |_| {
set_counter.update(|value| *value += 1);
Expand All @@ -39,7 +45,8 @@ fn app_view() -> impl View {
})
.style(|| {
Style::BASE
.border(1.0)
.box_shadow_blur(5.0)
.background(Color::WHITE)
.border_radius(10.0)
.padding_px(10.0)
.margin_left_px(10.0)
Expand All @@ -57,7 +64,7 @@ fn app_view() -> impl View {
.disabled(move || counter.get() == 0)
.style(|| {
Style::BASE
.border(1.0)
.box_shadow_blur(5.0)
.border_radius(10.0)
.padding_px(10.0)
.margin_left_px(10.0)
Expand Down
2 changes: 1 addition & 1 deletion renderer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub trait Renderer {
/// Fill a [`Shape`], using the [non-zero fill rule].
///
/// [non-zero fill rule]: https://en.wikipedia.org/wiki/Nonzero-rule
fn fill<'b>(&mut self, path: &impl Shape, brush: impl Into<BrushRef<'b>>);
fn fill<'b>(&mut self, path: &impl Shape, brush: impl Into<BrushRef<'b>>, blur_radius: f64);

/// Draw a [`TextLayout`].
///
Expand Down
13 changes: 12 additions & 1 deletion src/app_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::{any::Any, collections::HashMap};

use crate::action::exec_after;
use crate::animate::AnimValue;
use crate::context::MoveListener;
use crate::id::WindowId;
use crate::view::{view_debug_tree, view_tab_navigation};
use crate::window::WINDOWS;
Expand Down Expand Up @@ -162,6 +163,10 @@ pub enum UpdateMessage {
id: Id,
action: Box<ResizeCallback>,
},
MoveListener {
id: Id,
action: Box<dyn Fn(Point)>,
},
CleanupListener {
id: Id,
action: Box<dyn Fn()>,
Expand Down Expand Up @@ -546,11 +551,17 @@ impl<V: View> AppHandle<V> {
UpdateMessage::ResizeListener { id, action } => {
let state = cx.app_state.view_state(id);
state.resize_listener = Some(ResizeListener {
window_origin: Point::ZERO,
rect: Rect::ZERO,
callback: action,
});
}
UpdateMessage::MoveListener { id, action } => {
let state = cx.app_state.view_state(id);
state.move_listener = Some(MoveListener {
window_origin: Point::ZERO,
callback: action,
});
}
UpdateMessage::CleanupListener { id, action } => {
let state = cx.app_state.view_state(id);
state.cleanup_listener = Some(action);
Expand Down
18 changes: 16 additions & 2 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,20 @@ impl ViewContextStore {
}

pub type EventCallback = dyn Fn(&Event) -> bool;
pub type ResizeCallback = dyn Fn(Point, Rect);
pub type ResizeCallback = dyn Fn(Rect);
pub type MenuCallback = dyn Fn() -> Menu;

pub(crate) struct ResizeListener {
pub(crate) window_origin: Point,
pub(crate) rect: Rect,
pub(crate) callback: Box<ResizeCallback>,
}

/// The listener when the view is got moved to a different position in the window
pub(crate) struct MoveListener {
pub(crate) window_origin: Point,
pub(crate) callback: Box<dyn Fn(Point)>,
}

pub struct ViewState {
pub(crate) node: Node,
pub(crate) children_nodes: Vec<Node>,
Expand All @@ -95,6 +100,7 @@ pub struct ViewState {
pub(crate) context_menu: Option<Box<MenuCallback>>,
pub(crate) popout_menu: Option<Box<MenuCallback>>,
pub(crate) resize_listener: Option<ResizeListener>,
pub(crate) move_listener: Option<MoveListener>,
pub(crate) cleanup_listener: Option<Box<dyn Fn()>>,
pub(crate) last_pointer_down: Option<PointerEvent>,
}
Expand Down Expand Up @@ -123,6 +129,7 @@ impl ViewState {
context_menu: None,
popout_menu: None,
resize_listener: None,
move_listener: None,
cleanup_listener: None,
last_pointer_down: None,
}
Expand Down Expand Up @@ -841,6 +848,13 @@ impl<'a> LayoutCx<'a> {
.get_mut(&id)
.and_then(|s| s.resize_listener.as_mut())
}

pub(crate) fn get_move_listener(&mut self, id: Id) -> Option<&mut MoveListener> {
self.app_state
.view_states
.get_mut(&id)
.and_then(|s| s.move_listener.as_mut())
}
}

pub struct PaintCx<'a> {
Expand Down
6 changes: 6 additions & 0 deletions src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

use std::{any::Any, cell::RefCell, collections::HashMap, num::NonZeroU64};

use glazier::kurbo::Point;

use crate::{
animate::Animation,
app_handle::{StyleSelector, UpdateMessage, DEFERRED_UPDATE_MESSAGES, UPDATE_MESSAGES},
Expand Down Expand Up @@ -199,6 +201,10 @@ impl Id {
self.add_update_message(UpdateMessage::ResizeListener { id: *self, action });
}

pub fn update_move_listener(&self, action: Box<dyn Fn(Point)>) {
self.add_update_message(UpdateMessage::MoveListener { id: *self, action });
}

pub fn update_cleanup_listener(&self, action: Box<dyn Fn()>) {
self.add_update_message(UpdateMessage::CleanupListener { id: *self, action });
}
Expand Down
3 changes: 2 additions & 1 deletion src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ impl floem_renderer::Renderer for Renderer {
&mut self,
path: &impl glazier::kurbo::Shape,
brush: impl Into<peniko::BrushRef<'b>>,
blur_radius: f64,
) {
match self {
Renderer::Vger(v) => {
v.fill(path, brush);
v.fill(path, brush, blur_radius);
}
}
}
Expand Down
47 changes: 47 additions & 0 deletions src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ pub enum CursorStyle {
Text,
}

#[derive(Debug, Clone, Copy)]
pub struct BoxShadow {
pub blur_radius: f64,
pub color: Color,
}

/// The value for a [`Style`] property
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StyleValue<T> {
Expand Down Expand Up @@ -86,6 +92,14 @@ impl<T> StyleValue<T> {
Self::Base => f(),
}
}

pub fn as_mut(&mut self) -> Option<&mut T> {
match self {
Self::Val(x) => Some(x),
Self::Unset => None,
Self::Base => None,
}
}
}

impl<T> Default for StyleValue<T> {
Expand Down Expand Up @@ -250,6 +264,7 @@ define_styles!(
cursor nocb: Option<CursorStyle> = None,
color nocb: Option<Color> = None,
background nocb: Option<Color> = None,
box_shadow nocb: Option<BoxShadow> = None,
font_size nocb: Option<f32> = None,
font_family nocb: Option<String> = None,
font_weight nocb: Option<Weight> = None,
Expand Down Expand Up @@ -565,6 +580,38 @@ impl Style {
self
}

pub fn box_shadow_blur(mut self, blur_radius: f64) -> Self {
if let Some(box_shadow) = self.box_shadow.as_mut() {
if let Some(box_shadow) = box_shadow.as_mut() {
box_shadow.blur_radius = blur_radius;
return self;
}
}

self.box_shadow = Some(BoxShadow {
blur_radius,
color: Color::BLACK,
})
.into();
self
}

pub fn box_shadow_color(mut self, color: Color) -> Self {
if let Some(box_shadow) = self.box_shadow.as_mut() {
if let Some(box_shadow) = box_shadow.as_mut() {
box_shadow.color = color;
return self;
}
}

self.box_shadow = Some(BoxShadow {
blur_radius: 0.0,
color,
})
.into();
self
}

pub fn font_size(mut self, size: impl Into<StyleValue<f32>>) -> Self {
self.font_size = size.into().map(Some);
self
Expand Down
45 changes: 34 additions & 11 deletions src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,10 +286,16 @@ pub trait View {

if let Some(resize) = cx.get_resize_listener(self.id()) {
let new_rect = size.to_rect().with_origin(origin);
if new_rect != resize.rect || window_origin != resize.window_origin {
if new_rect != resize.rect {
resize.rect = new_rect;
resize.window_origin = window_origin;
(*resize.callback)(window_origin, new_rect);
(*resize.callback)(new_rect);
}
}

if let Some(listener) = cx.get_move_listener(self.id()) {
if window_origin != listener.window_origin {
listener.window_origin = window_origin;
(*listener.callback)(window_origin);
}
}

Expand Down Expand Up @@ -734,11 +740,6 @@ pub trait View {
}

fn paint_bg(cx: &mut PaintCx, style: &ComputedStyle, size: Size) {
let bg = match style.background {
Some(color) => color,
None => return,
};

let radius = style.border_radius;
if radius > 0.0 {
let rect = size.to_rect();
Expand All @@ -747,13 +748,35 @@ fn paint_bg(cx: &mut PaintCx, style: &ComputedStyle, size: Size) {
if width > 0.0 && height > 0.0 && radius as f64 > width.max(height) / 2.0 {
let radius = width.max(height) / 2.0;
let circle = Circle::new(rect.center(), radius);
cx.fill(&circle, bg);
let bg = match style.background {
Some(color) => color,
None => return,
};
cx.fill(&circle, bg, 0.0);
} else {
let rect = rect.to_rounded_rect(radius as f64);
cx.fill(&rect, bg);
if let Some(shadow) = style.box_shadow.as_ref() {
if shadow.blur_radius > 0.0 {
cx.fill(&rect, shadow.color, shadow.blur_radius);
}
}
let bg = match style.background {
Some(color) => color,
None => return,
};
cx.fill(&rect, bg, 0.0);
}
} else {
cx.fill(&size.to_rect(), bg);
if let Some(shadow) = style.box_shadow.as_ref() {
if shadow.blur_radius > 0.0 {
cx.fill(&size.to_rect(), shadow.color, shadow.blur_radius);
}
}
let bg = match style.background {
Some(color) => color,
None => return,
};
cx.fill(&size.to_rect(), bg, 0.0);
}
}

Expand Down
8 changes: 7 additions & 1 deletion src/views/decorator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,18 @@ pub trait Decorators: View + Sized {
self
}

fn on_resize(self, action: impl Fn(Point, Rect) + 'static) -> Self {
fn on_resize(self, action: impl Fn(Rect) + 'static) -> Self {
let id = self.id();
id.update_resize_listener(Box::new(action));
self
}

fn on_move(self, action: impl Fn(Point) + 'static) -> Self {
let id = self.id();
id.update_move_listener(Box::new(action));
self
}

fn on_cleanup(self, action: impl Fn() + 'static) -> Self {
let id = self.id();
id.update_cleanup_listener(Box::new(action));
Expand Down
Loading

0 comments on commit 246ba21

Please sign in to comment.