kas_core/core/
data.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//! Widget data types
7
8use super::Id;
9#[allow(unused)] use super::Widget;
10use crate::geom::Rect;
11
12#[cfg(feature = "winit")] pub use winit::window::Icon;
13
14/// An icon used for the window titlebar, taskbar, etc.
15#[cfg(not(feature = "winit"))]
16#[derive(Clone)]
17pub struct Icon;
18#[cfg(not(feature = "winit"))]
19impl Icon {
20    /// Creates an `Icon` from 32bpp RGBA data.
21    ///
22    /// The length of `rgba` must be divisible by 4, and `width * height` must equal
23    /// `rgba.len() / 4`. Otherwise, this will return a `BadIcon` error.
24    pub fn from_rgba(
25        rgba: Vec<u8>,
26        width: u32,
27        height: u32,
28    ) -> Result<Self, impl std::error::Error> {
29        let _ = (rgba, width, height);
30        Result::<Self, std::convert::Infallible>::Ok(Icon)
31    }
32}
33
34/// Common widget data
35///
36/// This type may be used for a [`Widget`]'s `core: widget_core!()` field.
37#[derive(Default, Debug)]
38pub struct CoreData {
39    pub rect: Rect,
40    pub id: Id,
41    #[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
42    #[cfg_attr(docsrs, doc(cfg(internal_doc)))]
43    #[cfg(debug_assertions)]
44    pub status: WidgetStatus,
45}
46
47/// Note: the clone has default-initialised identifier.
48/// Configuration and layout solving is required as for any other widget.
49impl Clone for CoreData {
50    fn clone(&self) -> Self {
51        CoreData {
52            rect: self.rect,
53            ..CoreData::default()
54        }
55    }
56}
57
58/// Widget state tracker
59///
60/// This struct is used to track status of widget operations and panic in case
61/// of inappropriate call order (such cases are memory safe but may cause
62/// incorrect widget behaviour).
63///
64/// It is not used in release builds.
65#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
66#[cfg_attr(docsrs, doc(cfg(internal_doc)))]
67#[cfg(debug_assertions)]
68#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
69pub enum WidgetStatus {
70    #[default]
71    New,
72    Configured,
73    SizeRulesX,
74    SizeRulesY,
75    SetRect,
76}
77
78#[cfg(debug_assertions)]
79impl WidgetStatus {
80    fn require(&self, id: &Id, expected: Self) {
81        if *self < expected {
82            panic!("WidgetStatus of {id}: require {expected:?}, found {self:?}");
83        }
84    }
85
86    /// Configure
87    pub fn configure(&mut self, _id: &Id) {
88        // re-configure does not require repeating other actions
89        *self = (*self).max(WidgetStatus::Configured);
90    }
91
92    /// Update
93    pub fn update(&self, id: &Id) {
94        self.require(id, WidgetStatus::Configured);
95
96        // Update-after-configure is already guaranteed (see impls module).
97        // NOTE: Update-after-data-change should be required but is hard to
98        // detect; we could store a data hash but draw does not receive data.
99        // As such we don't bother recording this operation.
100    }
101
102    /// Size rules
103    pub fn size_rules(&mut self, id: &Id, axis: crate::layout::AxisInfo) {
104        // NOTE: Possibly this is too strict and we should not require
105        // re-running size_rules(vert) or set_rect afterwards?
106        if axis.is_horizontal() {
107            self.require(id, WidgetStatus::Configured);
108            *self = WidgetStatus::SizeRulesX;
109        } else {
110            self.require(id, WidgetStatus::SizeRulesX);
111            *self = WidgetStatus::SizeRulesY;
112        }
113    }
114
115    /// Set rect
116    pub fn set_rect(&mut self, id: &Id) {
117        self.require(id, WidgetStatus::SizeRulesY);
118        *self = WidgetStatus::SetRect;
119    }
120
121    pub fn require_rect(&self, id: &Id) {
122        self.require(id, WidgetStatus::SetRect);
123    }
124}