Styles are now reactive

This commit is contained in:
Jonathan Johnson 2023-11-09 10:42:56 -08:00
parent 897880de25
commit 1714948174
No known key found for this signature in database
GPG key ID: A66D6A34D6620579
15 changed files with 168 additions and 119 deletions

View file

@ -11,15 +11,15 @@ fn main() -> gooey::Result<()> {
Canvas::new(move |context| {
angle += Angle::degrees(1);
let center = Point::from(context.graphics.size()).into_signed() / 2;
context.graphics.draw_text(
let center = Point::from(context.gfx.size()).into_signed() / 2;
context.gfx.draw_text(
Text::new("Canvas exposes the full power of Kludgine", Color::WHITE)
.origin(TextOrigin::Center),
center - Point::new(Px(0), Px(100)),
None,
None,
);
context.graphics.draw_shape(
context.gfx.draw_shape(
&Shape::filled_rect(
Rect::new(Point::new(Px(-50), Px(-50)), Size::new(Px(100), Px(100))),
Color::RED,

View file

@ -16,8 +16,8 @@ fn main() -> gooey::Result {
Stack::columns(
Label::new(chat_log.clone()).vertical_scroll().expand().and(
Canvas::new(|context| {
let entire_canvas = Rect::from(context.graphics.size());
context.graphics.draw_shape(
let entire_canvas = Rect::from(context.gfx.size());
context.gfx.draw_shape(
&Shape::filled_rect(entire_canvas, Color::RED),
Point::default(),
None,

View file

@ -401,7 +401,7 @@ pub struct GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass> {
/// The graphics context clipped and offset to the area of the widget being
/// rendered. Drawing at 0,0 will draw at the top-left pixel of the laid-out
/// widget region.
pub graphics: Exclusive<'context, Graphics<'clip, 'gfx, 'pass>>,
pub gfx: Exclusive<'context, Graphics<'clip, 'gfx, 'pass>>,
}
impl<'context, 'window, 'clip, 'gfx, 'pass> GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass> {
@ -409,7 +409,7 @@ impl<'context, 'window, 'clip, 'gfx, 'pass> GraphicsContext<'context, 'window, '
pub fn borrowed(&mut self) -> GraphicsContext<'_, 'window, 'clip, 'gfx, 'pass> {
GraphicsContext {
widget: self.widget.borrowed(),
graphics: Exclusive::Borrowed(&mut self.graphics),
gfx: Exclusive::Borrowed(&mut self.gfx),
}
}
@ -428,12 +428,12 @@ impl<'context, 'window, 'clip, 'gfx, 'pass> GraphicsContext<'context, 'window, '
widget.manage(self).map(|widget| {
let widget = self.widget.for_other(&widget);
let layout = widget.last_layout().map_or_else(
|| Rect::from(self.graphics.clip_rect().size).into_signed(),
|rect| rect - self.graphics.region().origin,
|| Rect::from(self.gfx.clip_rect().size).into_signed(),
|rect| rect - self.gfx.region().origin,
);
GraphicsContext {
widget,
graphics: Exclusive::Owned(self.graphics.clipped_to(layout)),
gfx: Exclusive::Owned(self.gfx.clipped_to(layout)),
}
})
}
@ -442,7 +442,7 @@ impl<'context, 'window, 'clip, 'gfx, 'pass> GraphicsContext<'context, 'window, '
pub fn clipped_to(&mut self, clip: Rect<Px>) -> GraphicsContext<'_, 'window, '_, 'gfx, 'pass> {
GraphicsContext {
widget: self.widget.borrowed(),
graphics: Exclusive::Owned(self.graphics.clipped_to(clip)),
gfx: Exclusive::Owned(self.gfx.clipped_to(clip)),
}
}
@ -456,13 +456,13 @@ impl<'context, 'window, 'clip, 'gfx, 'pass> GraphicsContext<'context, 'window, '
return;
}
let visible_rect = Rect::from(self.graphics.region().size - (Px(1), Px(1)));
let visible_rect = Rect::from(self.gfx.region().size - (Px(1), Px(1)));
let focus_ring = Shape::stroked_rect(
visible_rect,
styles.get_or_default(&HighlightColor),
styles.get(&HighlightColor, self),
StrokeOptions::default(),
);
self.graphics
self.gfx
.draw_shape(&focus_ring, Point::default(), None, None);
}
@ -519,7 +519,9 @@ impl<'context, 'window, 'clip, 'gfx, 'pass> DerefMut
/// A context to a function that is rendering a widget.
pub struct LayoutContext<'context, 'window, 'clip, 'gfx, 'pass> {
graphics: GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>,
/// The graphics context that this layout operation is being performed
/// within.
pub graphics: GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>,
persist_layout: bool,
}
@ -647,7 +649,7 @@ impl<'window> AsEventContext<'window> for EventContext<'_, 'window> {
impl<'window> AsEventContext<'window> for GraphicsContext<'_, 'window, '_, '_, '_> {
fn as_event_context(&mut self) -> EventContext<'_, 'window> {
EventContext::new(self.widget.borrowed(), &mut self.graphics)
EventContext::new(self.widget.borrowed(), &mut self.gfx)
}
}
@ -886,7 +888,7 @@ impl<'context, 'window> WidgetContext<'context, 'window> {
) -> Component::ComponentType {
self.current_node
.tree
.query_style(&self.current_node, query)
.query_style(&self.current_node, query, self)
}
pub(crate) fn handle(&self) -> WindowHandle {

View file

@ -6,16 +6,17 @@ use std::ops::Add;
use std::sync::Arc;
use crate::animation::{EasingFunction, ZeroToOne};
use crate::context::WidgetContext;
use crate::names::Name;
use crate::styles::components::{FocusableWidgets, VisualOrder};
use crate::utils::Lazy;
use crate::value::{IntoValue, Value};
use crate::value::{Dynamic, IntoValue, Value};
pub mod components;
/// A collection of style components organized by their name.
#[derive(Clone, Debug, Default)]
pub struct Styles(Arc<HashMap<Group, HashMap<Name, Component>>>);
pub struct Styles(Arc<HashMap<Group, HashMap<Name, Value<Component>>>>);
impl Styles {
/// Returns an empty collection.
@ -32,15 +33,15 @@ impl Styles {
}
/// Inserts a [`Component`] with a given name.
pub fn insert_named(&mut self, name: ComponentName, component: impl Into<Component>) {
pub fn insert_named(&mut self, name: ComponentName, component: impl IntoComponentValue) {
Arc::make_mut(&mut self.0)
.entry(name.group)
.or_default()
.insert(name.name, component.into());
.insert(name.name, component.into_component_value());
}
/// Inserts a [`Component`] using then name provided.
pub fn insert(&mut self, name: &impl NamedComponent, component: impl Into<Component>) {
pub fn insert(&mut self, name: &impl NamedComponent, component: impl IntoComponentValue) {
let name = name.name().into_owned();
self.insert_named(name, component);
}
@ -54,7 +55,7 @@ impl Styles {
/// Returns the associated component for the given name, if found.
#[must_use]
pub fn get<Named>(&self, component: &Named) -> Option<&Component>
pub fn get_named<Named>(&self, component: &Named) -> Option<&Value<Component>>
where
Named: NamedComponent + ?Sized,
{
@ -67,7 +68,11 @@ impl Styles {
/// Returns the component associated with the given name, or if not found,
/// returns the default value provided by the definition.
#[must_use]
pub fn get_or_default<Named>(&self, component: &Named) -> Named::ComponentType
pub fn get<Named>(
&self,
component: &Named,
context: &WidgetContext<'_, '_>,
) -> Named::ComponentType
where
Named: ComponentDefinition + ?Sized,
{
@ -76,12 +81,44 @@ impl Styles {
.get(&name.group)
.and_then(|group| group.get(&name.name))
.and_then(|component| {
<Named::ComponentType>::try_from_component(component.clone()).ok()
component.redraw_when_changed(context);
<Named::ComponentType>::try_from_component(component.get()).ok()
})
.unwrap_or_else(|| component.default_value())
}
}
/// A value that can be converted into a `Value<Component>`.
pub trait IntoComponentValue {
/// Returns `self` stored in a component value.
fn into_component_value(self) -> Value<Component>;
}
impl<T> IntoComponentValue for T
where
T: Into<Component>,
{
fn into_component_value(self) -> Value<Component> {
Value::Constant(self.into())
}
}
impl IntoComponentValue for Value<Component> {
fn into_component_value(self) -> Value<Component> {
self
}
}
impl<T> IntoComponentValue for Dynamic<T>
where
T: Clone,
Component: From<T>,
{
fn into_component_value(self) -> Value<Component> {
Value::Dynamic(self.map_each_into())
}
}
impl FromIterator<(ComponentName, Component)> for Styles {
fn from_iter<T: IntoIterator<Item = (ComponentName, Component)>>(iter: T) -> Self {
let iter = iter.into_iter();
@ -95,7 +132,7 @@ impl FromIterator<(ComponentName, Component)> for Styles {
impl IntoIterator for Styles {
type IntoIter = StylesIntoIter;
type Item = (ComponentName, Component);
type Item = (ComponentName, Value<Component>);
fn into_iter(self) -> Self::IntoIter {
StylesIntoIter {
@ -109,12 +146,12 @@ impl IntoIterator for Styles {
/// An iterator over the owned contents of a [`Styles`] instance.
pub struct StylesIntoIter {
main: hash_map::IntoIter<Group, HashMap<Name, Component>>,
names: Option<(Group, hash_map::IntoIter<Name, Component>)>,
main: hash_map::IntoIter<Group, HashMap<Name, Value<Component>>>,
names: Option<(Group, hash_map::IntoIter<Name, Value<Component>>)>,
}
impl Iterator for StylesIntoIter {
type Item = (ComponentName, Component);
type Item = (ComponentName, Value<Component>);
fn next(&mut self) -> Option<Self::Item> {
loop {

View file

@ -5,6 +5,7 @@ use std::sync::{Arc, Mutex, PoisonError};
use kludgine::figures::units::Px;
use kludgine::figures::{Point, Rect};
use crate::context::WidgetContext;
use crate::styles::components::VisualOrder;
use crate::styles::{ComponentDefaultvalue, ComponentDefinition, ComponentType, Styles};
use crate::widget::{ManagedWidget, WidgetId, WidgetInstance};
@ -296,11 +297,12 @@ impl Tree {
&self,
perspective: &ManagedWidget,
component: &Component,
context: &WidgetContext<'_, '_>,
) -> Component::ComponentType {
self.data
.lock()
.map_or_else(PoisonError::into_inner, |g| g)
.query_style(perspective.id(), component)
.query_style(perspective.id(), component, context)
}
}
@ -396,8 +398,8 @@ impl TreeData {
let node = &self.nodes[&perspective];
if let Some(styles) = &node.styles {
query.retain(|name| {
if let Some(component) = styles.get(dbg!(name)) {
resolved.insert(name, dbg!(component.clone()));
if let Some(component) = styles.get_named(name) {
resolved.insert(name, component.clone());
false
} else {
true
@ -414,17 +416,18 @@ impl TreeData {
&self,
mut perspective: WidgetId,
query: &Component,
context: &WidgetContext<'_, '_>,
) -> Component::ComponentType {
let name = query.name();
loop {
let node = &self.nodes[&perspective];
if let Some(styles) = &node.styles {
if let Some(component) = styles.get(&name) {
let Ok(value) =
<Component::ComponentType>::try_from_component(component.clone())
if let Some(component) = styles.get_named(&name) {
let Ok(value) = <Component::ComponentType>::try_from_component(component.get())
else {
break;
};
component.redraw_when_changed(context);
return value;
}
}

View file

@ -90,8 +90,8 @@ impl Align {
context: &mut LayoutContext<'_, '_, '_, '_, '_>,
) -> Layout {
let margin = self.edges.get();
let vertical = FrameInfo::new(context.graphics.scale(), margin.top, margin.bottom);
let horizontal = FrameInfo::new(context.graphics.scale(), margin.left, margin.right);
let vertical = FrameInfo::new(context.gfx.scale(), margin.top, margin.bottom);
let horizontal = FrameInfo::new(context.gfx.scale(), margin.left, margin.right);
let content_available = Size::new(
horizontal.child_constraint(available_space.width),

View file

@ -88,15 +88,15 @@ impl Button {
&Easing,
]);
let background_color = if !self.enabled.get() {
styles.get_or_default(&ButtonDisabledBackground)
styles.get(&ButtonDisabledBackground, context)
} else if context.active() {
styles.get_or_default(&ButtonActiveBackground)
styles.get(&ButtonActiveBackground, context)
} else if context.hovered() {
styles.get_or_default(&ButtonHoverBackground)
styles.get(&ButtonHoverBackground, context)
} else if context.is_default() {
styles.get_or_default(&PrimaryColor)
styles.get(&PrimaryColor, context)
} else {
styles.get_or_default(&ButtonBackground)
styles.get(&ButtonBackground, context)
};
match (immediate, &self.background_color) {
@ -104,7 +104,7 @@ impl Button {
self.background_color_animation = dynamic
.transition_to(background_color)
.over(Duration::from_millis(150))
.with_easing(styles.get_or_default(&Easing))
.with_easing(styles.get(&Easing, context))
.spawn();
}
(true, Some(dynamic)) => {
@ -139,7 +139,7 @@ impl Widget for Button {
self.currently_enabled = enabled;
}
let size = context.graphics.region().size;
let size = context.gfx.region().size;
let center = Point::from(size) / 2;
self.label.redraw_when_changed(context);
self.enabled.redraw_when_changed(context);
@ -157,7 +157,7 @@ impl Widget for Button {
let background = self.current_background_color(context);
let background = Shape::filled_rect(visible_rect, background);
context
.graphics
.gfx
.draw_shape(&background, Point::default(), None, None);
if context.focused() {
@ -165,8 +165,9 @@ impl Widget for Button {
}
self.label.map(|label| {
context.graphics.draw_text(
Text::new(label, styles.get_or_default(&TextColor))
let text_color = styles.get(&TextColor, context);
context.gfx.draw_text(
Text::new(label, text_color)
.origin(kludgine::text::TextOrigin::Center)
.wrap_at(size.width),
center,
@ -246,12 +247,12 @@ impl Widget for Button {
) -> Size<UPx> {
let padding = context
.query_style(&IntrinsicPadding)
.into_px(context.graphics.scale())
.into_px(context.gfx.scale())
.into_unsigned();
let width = available_space.width.max().try_into().unwrap_or(Px::MAX);
self.label.map(|label| {
let measured = context
.graphics
.gfx
.measure_text::<Px>(Text::from(label).wrap_at(width));
let mut size = measured.size.into_unsigned();

View file

@ -82,10 +82,10 @@ impl WrapperWidget for Expand {
Size::<UPx>::new(
available_space
.width
.fit_measured(size.width, context.graphics.scale()),
.fit_measured(size.width, context.gfx.scale()),
available_space
.height
.fit_measured(size.height, context.graphics.scale()),
.fit_measured(size.height, context.gfx.scale()),
)
.into_signed()
.into()

View file

@ -62,7 +62,12 @@ impl Input {
self
}
fn editor_mut(&mut self, kludgine: &mut Kludgine, styles: &Styles) -> &mut Editor {
fn editor_mut(
&mut self,
kludgine: &mut Kludgine,
styles: &Styles,
context: &WidgetContext<'_, '_>,
) -> &mut Editor {
match (&self.editor, self.text.generation()) {
(Some(editor), generation) if editor.generation == generation => {}
(_, generation) => {
@ -70,11 +75,8 @@ impl Input {
let mut buffer = Buffer::new(
kludgine.font_system(),
Metrics::new(
styles.get_or_default(&TextSize).into_px(scale).into_float(),
styles
.get_or_default(&LineHeight)
.into_px(scale)
.into_float(),
styles.get(&TextSize, context).into_px(scale).into_float(),
styles.get(&LineHeight, context).into_px(scale).into_float(),
),
);
self.text.map(|text| {
@ -132,13 +134,14 @@ impl Widget for Input {
) -> EventHandling {
context.focus();
let styles = context.query_styles(&[&TextColor]);
self.editor_mut(context.kludgine, &styles).action(
context.kludgine.font_system(),
Action::Click {
x: location.x.0,
y: location.y.0,
},
);
self.editor_mut(context.kludgine, &styles, &context.widget)
.action(
context.kludgine.font_system(),
Action::Click {
x: location.x.0,
y: location.y.0,
},
);
context.set_needs_redraw();
HANDLED
}
@ -151,13 +154,14 @@ impl Widget for Input {
context: &mut EventContext<'_, '_>,
) {
let styles = context.query_styles(&[&TextColor]);
self.editor_mut(context.kludgine, &styles).action(
context.kludgine.font_system(),
Action::Drag {
x: location.x.0,
y: location.y.0,
},
);
self.editor_mut(context.kludgine, &styles, &context.widget)
.action(
context.kludgine.font_system(),
Action::Drag {
x: location.x.0,
y: location.y.0,
},
);
self.cursor_state.force_on();
context.set_needs_redraw();
}
@ -166,19 +170,19 @@ impl Widget for Input {
fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_, '_>) {
self.cursor_state.update(context.elapsed());
let cursor_state = self.cursor_state;
let size = context.graphics.size();
let size = context.gfx.size();
let styles = context.query_styles(&[&TextColor, &HighlightColor]);
let highlight = styles.get_or_default(&HighlightColor);
let editor = self.editor_mut(&mut context.graphics, &styles);
let highlight = styles.get(&HighlightColor, context);
let editor = self.editor_mut(&mut context.gfx, &styles, &context.widget);
let cursor = editor.cursor();
let selection = editor.select_opt();
let buffer = editor.buffer_mut();
buffer.set_size(
context.graphics.font_system(),
context.gfx.font_system(),
size.width.into_float(),
size.height.into_float(),
);
buffer.shape_until_scroll(context.graphics.font_system());
buffer.shape_until_scroll(context.gfx.font_system());
if context.focused() {
context.draw_focus_ring_using(&styles);
@ -196,7 +200,7 @@ impl Widget for Input {
if start_position.y == end_position.y {
// Single line selection
let width = end_position.x - start_position.x + end_width;
context.graphics.draw_shape(
context.gfx.draw_shape(
&Shape::filled_rect(
Rect::new(start_position, Size::new(width, line_height)),
highlight,
@ -208,7 +212,7 @@ impl Widget for Input {
} else {
// Draw from start to end of line,
let width = size.width.into_signed() - start_position.x;
context.graphics.draw_shape(
context.gfx.draw_shape(
&Shape::filled_rect(
Rect::new(start_position, Size::new(width, line_height)),
highlight,
@ -221,7 +225,7 @@ impl Widget for Input {
let bottom_of_first_line = start_position.y + line_height;
let distance_between = end_position.y - bottom_of_first_line;
if distance_between > 0 {
context.graphics.draw_shape(
context.gfx.draw_shape(
&Shape::filled_rect(
Rect::new(
Point::new(Px(0), bottom_of_first_line),
@ -235,7 +239,7 @@ impl Widget for Input {
);
}
// Draw from 0 to end + width
context.graphics.draw_shape(
context.gfx.draw_shape(
&Shape::filled_rect(
Rect::new(
Point::new(Px(0), end_position.y),
@ -251,7 +255,7 @@ impl Widget for Input {
}
(Ok((start_position, _)), Err(_)) => {
let width = size.width.into_signed() - start_position.x;
context.graphics.draw_shape(
context.gfx.draw_shape(
&Shape::filled_rect(
Rect::new(start_position, Size::new(width, line_height)),
highlight,
@ -265,7 +269,7 @@ impl Widget for Input {
if end_position.y > 0 {
todo!("fill above start");
}
context.graphics.draw_shape(
context.gfx.draw_shape(
&Shape::filled_rect(
Rect::new(
Point::new(Px(0), end_position.y),
@ -288,7 +292,7 @@ impl Widget for Input {
} else if let Ok((location, _)) = cursor_glyph(buffer, &cursor) {
let window_focused = context.window().focused().get();
if window_focused && cursor_state.visible {
context.graphics.draw_shape(
context.gfx.draw_shape(
&Shape::filled_rect(
Rect::new(
location,
@ -309,9 +313,10 @@ impl Widget for Input {
}
}
context.graphics.draw_text_buffer(
let text_color = styles.get(&TextColor, context);
context.gfx.draw_text_buffer(
buffer,
styles.get_or_default(&TextColor),
text_color,
TextOrigin::TopLeft,
Point::<Px>::default(),
None,
@ -325,15 +330,15 @@ impl Widget for Input {
context: &mut LayoutContext<'_, '_, '_, '_, '_>,
) -> Size<UPx> {
let styles = context.query_styles(&[&TextColor]);
let editor = self.editor_mut(&mut context.graphics, &styles);
let editor = self.editor_mut(&mut context.graphics.gfx, &styles, &context.graphics.widget);
let buffer = editor.buffer_mut();
buffer.set_size(
context.graphics.font_system(),
context.gfx.font_system(),
available_space.width.max().into_float(),
available_space.height.max().into_float(),
);
context
.graphics
.gfx
.measure_text_buffer::<Px>(buffer, Color::WHITE)
.size
.into_unsigned()
@ -351,7 +356,7 @@ impl Widget for Input {
}
let styles = context.query_styles(&[&TextColor]);
let editor = self.editor_mut(context.kludgine, &styles);
let editor = self.editor_mut(context.kludgine, &styles, &context.widget);
// println!(
// "Keyboard input: {:?}. {:?}, {:?}",
@ -434,11 +439,15 @@ impl Widget for Input {
match ime {
Ime::Enabled | Ime::Disabled => {}
Ime::Preedit(text, cursor) => {
println!("TODO: preview IME input {text}, cursor: {cursor:?}");
tracing::warn!("TODO: preview IME input {text}, cursor: {cursor:?}");
}
Ime::Commit(text) => {
self.editor_mut(context.kludgine, &Self::styles(&context.widget))
.insert_string(&text, None);
self.editor_mut(
context.kludgine,
&Self::styles(&context.widget),
&context.widget,
)
.insert_string(&text, None);
context.set_needs_redraw();
}
}

View file

@ -30,18 +30,19 @@ impl Widget for Label {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {
self.text.redraw_when_changed(context);
let size = context.graphics.region().size;
let size = context.gfx.region().size;
let center = Point::from(size) / 2;
let styles = context.query_styles(&[&TextColor]);
if let Some(measured) = &self.prepared_text {
context
.graphics
.gfx
.draw_measured_text(measured, TextOrigin::Center, center, None, None);
} else {
let text_color = styles.get(&TextColor, context);
self.text.map(|contents| {
context.graphics.draw_text(
Text::new(contents, styles.get_or_default(&TextColor))
context.gfx.draw_text(
Text::new(contents, text_color)
.wrap_at(size.width)
.origin(TextOrigin::Center),
center,
@ -59,12 +60,12 @@ impl Widget for Label {
) -> Size<UPx> {
let padding = context
.query_style(&IntrinsicPadding)
.into_px(context.graphics.scale())
.into_px(context.gfx.scale())
.into_unsigned();
let width = available_space.width.max().try_into().unwrap_or(Px::MAX);
self.text.map(|contents| {
let measured = context
.graphics
.gfx
.measure_text(Text::from(contents).wrap_at(width));
let mut size = measured.size.try_cast().unwrap_or_default();
size += padding * 2;

View file

@ -69,17 +69,13 @@ impl WrapperWidget for Resize {
let child = self.child.mounted(&mut context.as_event_context());
let size = if let (Some(width), Some(height)) = (self.width, self.height) {
Size::new(
width.into_px(context.graphics.scale()).into_unsigned(),
height.into_px(context.graphics.scale()).into_unsigned(),
width.into_px(context.gfx.scale()).into_unsigned(),
height.into_px(context.gfx.scale()).into_unsigned(),
)
} else {
let available_space = Size::new(
override_constraint(available_space.width, self.width, context.graphics.scale()),
override_constraint(
available_space.height,
self.height,
context.graphics.scale(),
),
override_constraint(available_space.width, self.width, context.gfx.scale()),
override_constraint(available_space.height, self.height, context.gfx.scale()),
);
context.for_other(&child).layout(available_space)
};

View file

@ -94,13 +94,13 @@ impl Scroll {
.scrollbar_opacity
.transition_to(ZeroToOne::ONE)
.over(Duration::from_millis(300))
.with_easing(styles.get_or_default(&EasingIn))
.with_easing(styles.get(&EasingIn, context))
.and_then(Duration::from_secs(1))
.and_then(
self.scrollbar_opacity
.transition_to(ZeroToOne::ZERO)
.over(Duration::from_millis(300))
.with_easing(styles.get_or_default(&EasingOut)),
.with_easing(styles.get(&EasingOut, context)),
)
.spawn();
}
@ -126,7 +126,7 @@ impl Widget for Scroll {
fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_, '_>) {
context.redraw_when_changed(&self.scrollbar_opacity);
let Some(visible_rect) = context.graphics.visible_rect() else {
let Some(visible_rect) = context.gfx.visible_rect() else {
return;
};
let visible_bottom_right = visible_rect.into_signed().extent();
@ -135,7 +135,7 @@ impl Widget for Scroll {
context.for_other(&managed).redraw();
if self.horizontal_bar.amount_hidden > 0 {
context.graphics.draw_shape(
context.gfx.draw_shape(
&Shape::filled_rect(
Rect::new(
Point::new(
@ -153,7 +153,7 @@ impl Widget for Scroll {
}
if self.vertical_bar.amount_hidden > 0 {
context.graphics.draw_shape(
context.gfx.draw_shape(
&Shape::filled_rect(
Rect::new(
Point::new(
@ -178,11 +178,11 @@ impl Widget for Scroll {
) -> Size<UPx> {
let styles = context.query_styles(&[&ScrollBarThickness, &LineHeight]);
self.bar_width = styles
.get_or_default(&ScrollBarThickness)
.into_px(context.graphics.scale());
.get(&ScrollBarThickness, context)
.into_px(context.gfx.scale());
self.line_height = styles
.get_or_default(&LineHeight)
.into_px(context.graphics.scale());
.get(&LineHeight, context)
.into_px(context.gfx.scale());
let (mut scroll, current_max_scroll) = self.constrain_scroll();

View file

@ -145,7 +145,7 @@ impl Widget for Stack {
let content_size = self.layout.update(
available_space,
context.graphics.scale(),
context.gfx.scale(),
|child_index, constraints, persist| {
let mut context = context.for_other(&self.synced_children[child_index]);
if !persist {

View file

@ -67,7 +67,7 @@ where
let focus = self.focus.get();
// TODO this needs to be updated to support being placed in side of a scroll view.
self.layers.map(|layers| {
tilemap::draw(layers, focus, self.zoom, context.graphics.inner_graphics());
tilemap::draw(layers, focus, self.zoom, context.gfx.inner_graphics());
});
context.draw_focus_ring();

View file

@ -352,10 +352,10 @@ where
let mut window = RunningWindow::new(window, &self.focused, &self.occluded);
let mut context = GraphicsContext {
widget: WidgetContext::new(self.root.clone(), &self.redraw_status, &mut window),
graphics: Exclusive::Owned(Graphics::new(graphics)),
gfx: Exclusive::Owned(Graphics::new(graphics)),
};
let mut layout_context = LayoutContext::new(&mut context);
let window_size = layout_context.graphics.size();
let window_size = layout_context.gfx.size();
let actual_size = layout_context.layout(Size::new(
ConstraintLimit::ClippedAfter(window_size.width),
ConstraintLimit::ClippedAfter(window_size.height),