[style] Fade out windows on close
This commit is contained in:
parent
29bb7c9f9d
commit
e2217ff63a
7 changed files with 86 additions and 27 deletions
|
@ -158,6 +158,34 @@ impl Area {
|
|||
add_contents(&mut content_ui);
|
||||
prepared.end(ctx, content_ui)
|
||||
}
|
||||
|
||||
pub fn show_open_close_animation(&self, ctx: &CtxRef, frame: &Frame, is_open: bool) {
|
||||
// must be called first so animation managers know the latest state
|
||||
let visibility_factor = ctx.animate_bool(self.id.with("close_animation"), is_open);
|
||||
|
||||
if is_open {
|
||||
// we actually only show close animations.
|
||||
// when opening a window we show it right away.
|
||||
return;
|
||||
}
|
||||
if visibility_factor <= 0.0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let layer_id = LayerId::new(self.order, self.id);
|
||||
let area_rect = ctx.memory().areas.get(self.id).map(|area| area.rect());
|
||||
if let Some(area_rect) = area_rect {
|
||||
let clip_rect = ctx.available_rect();
|
||||
let painter = Painter::new(ctx.clone(), layer_id, clip_rect);
|
||||
|
||||
// shrinkage: looks kinda a bad on its own
|
||||
// let area_rect =
|
||||
// Rect::from_center_size(area_rect.center(), visibility_factor * area_rect.size());
|
||||
|
||||
let frame = frame.multiply_with_opacity(visibility_factor);
|
||||
painter.add(frame.paint(area_rect));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Prepared {
|
||||
|
|
|
@ -90,6 +90,13 @@ impl Frame {
|
|||
self.stroke = stroke;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn multiply_with_opacity(mut self, opacity: f32) -> Self {
|
||||
self.fill = self.fill.linear_multiply(opacity);
|
||||
self.stroke.color = self.stroke.color.linear_multiply(opacity);
|
||||
self.shadow.color = self.shadow.color.linear_multiply(opacity);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Prepared {
|
||||
|
@ -122,6 +129,31 @@ impl Frame {
|
|||
prepared.end(ui);
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn paint(&self, outer_rect: Rect) -> Shape {
|
||||
let Self {
|
||||
margin: _,
|
||||
corner_radius,
|
||||
shadow,
|
||||
fill,
|
||||
stroke,
|
||||
} = *self;
|
||||
|
||||
let frame_shape = Shape::Rect {
|
||||
rect: outer_rect,
|
||||
corner_radius,
|
||||
fill,
|
||||
stroke,
|
||||
};
|
||||
|
||||
if shadow == Default::default() {
|
||||
frame_shape
|
||||
} else {
|
||||
let shadow = shadow.tessellate(outer_rect, corner_radius);
|
||||
let shadow = Shape::Triangles(shadow);
|
||||
Shape::Vec(vec![shadow, frame_shape])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Prepared {
|
||||
|
@ -141,26 +173,9 @@ impl Prepared {
|
|||
..
|
||||
} = self;
|
||||
|
||||
let frame_shape = Shape::Rect {
|
||||
rect: outer_rect,
|
||||
corner_radius: frame.corner_radius,
|
||||
fill: frame.fill,
|
||||
stroke: frame.stroke,
|
||||
};
|
||||
|
||||
if frame.shadow == Default::default() {
|
||||
ui.painter().set(where_to_put_background, frame_shape);
|
||||
} else {
|
||||
let shadow = frame.shadow.tessellate(outer_rect, frame.corner_radius);
|
||||
let shadow = Shape::Triangles(shadow);
|
||||
ui.painter().set(
|
||||
where_to_put_background,
|
||||
Shape::Vec(vec![shadow, frame_shape]),
|
||||
)
|
||||
};
|
||||
|
||||
let shape = frame.paint(outer_rect);
|
||||
ui.painter().set(where_to_put_background, shape);
|
||||
ui.advance_cursor_after_rect(outer_rect);
|
||||
|
||||
outer_rect
|
||||
}
|
||||
}
|
||||
|
|
|
@ -224,7 +224,12 @@ impl<'open> Window<'open> {
|
|||
with_title_bar,
|
||||
} = self;
|
||||
|
||||
if matches!(open, Some(false)) && !ctx.memory().everything_is_visible() {
|
||||
let frame = frame.unwrap_or_else(|| Frame::window(&ctx.style()));
|
||||
|
||||
let is_open = !matches!(open, Some(false)) || ctx.memory().everything_is_visible();
|
||||
area.show_open_close_animation(ctx, &frame, is_open);
|
||||
|
||||
if !is_open {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -244,8 +249,6 @@ impl<'open> Window<'open> {
|
|||
let resize = resize.resizable(false); // We move it manually
|
||||
let mut resize = resize.id(resize_id);
|
||||
|
||||
let frame = frame.unwrap_or_else(|| Frame::window(&ctx.style()));
|
||||
|
||||
let mut area = area.begin(ctx);
|
||||
|
||||
let title_content_spacing = 2.0 * ctx.style().spacing.item_spacing.y;
|
||||
|
|
|
@ -22,7 +22,7 @@ impl Default for WidgetGallery {
|
|||
radio: Enum::First,
|
||||
scalar: 42.0,
|
||||
string: "Hello World!".to_owned(),
|
||||
color: (egui::Rgba::from(egui::Color32::LIGHT_BLUE) * 0.5).into(),
|
||||
color: egui::Color32::LIGHT_BLUE.linear_multiply(0.5),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,6 +129,14 @@ impl Color32 {
|
|||
pub fn to_tuple(&self) -> (u8, u8, u8, u8) {
|
||||
(self.r(), self.g(), self.b(), self.a())
|
||||
}
|
||||
|
||||
/// Multiply with 0.5 to make color half as opaque.
|
||||
pub fn linear_multiply(self, factor: f32) -> Color32 {
|
||||
debug_assert!(0.0 <= factor && factor <= 1.0);
|
||||
// As an unfortunate side-effect of using premultiplied alpha
|
||||
// we need a somewhat expensive conversion to linear space and back.
|
||||
Rgba::from(self).multiply(factor).into()
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
use super::*;
|
||||
|
||||
/// A rectangular shadow with a soft penumbra.
|
||||
/// The color and fuzziness of a fuzzy shape.
|
||||
/// Can be used for a rectangular shadow with a soft penumbra.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct Shadow {
|
||||
// The shadow extends this much outside the rect.
|
||||
/// The shadow extends this much outside the rect.
|
||||
/// The size of the fuzzy penumbra.
|
||||
pub extrusion: f32,
|
||||
|
||||
/// Color of the opaque center of the shadow.
|
||||
pub color: Color32,
|
||||
}
|
||||
|
||||
|
|
|
@ -420,8 +420,9 @@ fn stroke_path(
|
|||
|
||||
fn mul_color(color: Color32, factor: f32) -> Color32 {
|
||||
debug_assert!(0.0 <= factor && factor <= 1.0);
|
||||
// sRGBA correct fading requires conversion to linear space and back again because of premultiplied alpha
|
||||
Rgba::from(color).multiply(factor).into()
|
||||
// As an unfortunate side-effect of using premultiplied alpha
|
||||
// we need a somewhat expensive conversion to linear space and back.
|
||||
color.linear_multiply(factor)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue