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}