kas_core/event/config_cx.rs
1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License in the LICENSE-APACHE file or at:
4// https://www.apache.org/licenses/LICENSE-2.0
5
6//! Configuration context
7
8use crate::event::EventState;
9use crate::geom::Rect;
10use crate::layout::AlignPair;
11use crate::text::format::FormattableText;
12use crate::theme::{Feature, SizeCx, Text, ThemeSize};
13use crate::{Id, Node};
14use std::any::TypeId;
15use std::fmt::Debug;
16use std::ops::{Deref, DerefMut};
17
18#[allow(unused)] use crate::event::{Event, EventCx};
19#[allow(unused)] use crate::{Action, Events, Layout};
20
21/// Widget configuration and update context
22///
23/// This type supports easy access to [`EventState`] (via [`Deref`],
24/// [`DerefMut`] and [`Self::ev_state`]) as well as [`SizeCx`]
25/// ([`Self::size_cx`]).
26#[must_use]
27pub struct ConfigCx<'a> {
28 sh: &'a dyn ThemeSize,
29 pub(crate) ev: &'a mut EventState,
30}
31
32impl<'a> ConfigCx<'a> {
33 /// Construct
34 #[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
35 #[cfg_attr(docsrs, doc(cfg(internal_doc)))]
36 pub fn new(sh: &'a dyn ThemeSize, ev: &'a mut EventState) -> Self {
37 ConfigCx { sh, ev }
38 }
39
40 /// Access a [`SizeCx`]
41 #[inline]
42 pub fn size_cx(&self) -> SizeCx<'a> {
43 SizeCx::new(self.sh)
44 }
45
46 /// Access [`EventState`]
47 #[inline]
48 pub fn ev_state(&mut self) -> &mut EventState {
49 self.ev
50 }
51
52 /// Configure a widget
53 ///
54 /// All widgets must be configured after construction (see
55 /// [widget lifecycle](Layout#widget-lifecycle)).
56 /// This method performs complete configuration of the widget by calling
57 /// [`Events::configure`], [`Events::update`], [`Events::configure_recurse`].
58 ///
59 /// Pass the `id` to assign to the widget. This is usually constructed with
60 /// [`Events::make_child_id`].
61 #[inline]
62 pub fn configure(&mut self, mut widget: Node<'_>, id: Id) {
63 if id.is_valid() {
64 widget._configure(self, id);
65 }
66 }
67
68 /// Update a widget
69 ///
70 /// All widgets must be updated after input data changes.
71 /// This method recursively updates the widget by calling
72 /// [`Events::update`] and [`Events::update_recurse`].
73 #[inline]
74 pub fn update(&mut self, mut widget: Node<'_>) {
75 widget._update(self);
76 }
77
78 /// Align a feature's rect
79 ///
80 /// In case the input `rect` is larger than desired on either axis, it is
81 /// reduced in size and offset within the original `rect` as is preferred.
82 #[inline]
83 pub fn align_feature(&self, feature: Feature, rect: Rect, align: AlignPair) -> Rect {
84 self.sh.align_feature(feature, rect, align)
85 }
86
87 /// Configure a text object
88 ///
89 /// This selects a font given the [`TextClass`][crate::theme::TextClass],
90 /// [theme configuration][crate::config::ThemeConfig] and
91 /// the loaded [fonts][crate::text::fonts].
92 #[inline]
93 pub fn text_configure<T: FormattableText>(&self, text: &mut Text<T>) {
94 let class = text.class();
95 self.sh.text_configure(text, class);
96 }
97
98 /// Set a target for messages of a specific type when sent to `Id::default()`
99 ///
100 /// Messages of this type sent to `Id::default()` from any window will be
101 /// sent to `id`.
102 pub fn set_send_target_for<M: Debug + 'static>(&mut self, id: Id) {
103 let type_id = TypeId::of::<M>();
104 self.pending_send_targets.push((type_id, id));
105 }
106}
107
108impl<'a> Deref for ConfigCx<'a> {
109 type Target = EventState;
110 fn deref(&self) -> &EventState {
111 self.ev
112 }
113}
114impl<'a> DerefMut for ConfigCx<'a> {
115 fn deref_mut(&mut self) -> &mut EventState {
116 self.ev
117 }
118}