slint_interpreter/
value_model.rs1use crate::api::Value;
5use core::cell::Cell;
6use i_slint_core::model::{Model, ModelNotify, ModelRc, ModelTracker};
7
8pub struct ValueModel {
9 value: Value,
10}
11
12impl ValueModel {
13 pub fn new(value: Value) -> Self {
14 Self { value }
15 }
16}
17
18impl ModelTracker for ValueModel {
19 fn attach_peer(&self, peer: i_slint_core::model::ModelPeer) {
20 if let Value::Model(ref model_ptr) = self.value {
21 model_ptr.model_tracker().attach_peer(peer)
22 }
23 }
24
25 fn track_row_count_changes(&self) {
26 if let Value::Model(ref model_ptr) = self.value {
27 model_ptr.model_tracker().track_row_count_changes()
28 }
29 }
30
31 fn track_row_data_changes(&self, row: usize) {
32 if let Value::Model(ref model_ptr) = self.value {
33 model_ptr.model_tracker().track_row_data_changes(row)
34 }
35 }
36}
37
38impl Model for ValueModel {
39 type Data = Value;
40
41 fn row_count(&self) -> usize {
42 match &self.value {
43 Value::Bool(b) => {
44 if *b {
45 1
46 } else {
47 0
48 }
49 }
50 Value::Number(x) => x.max(Default::default()) as usize,
51 Value::Void => 0,
52 Value::Model(model_ptr) => model_ptr.row_count(),
53 x => panic!("Invalid model {x:?}"),
54 }
55 }
56
57 fn row_data(&self, row: usize) -> Option<Self::Data> {
58 if row >= self.row_count() {
59 None
60 } else {
61 Some(match &self.value {
62 Value::Bool(_) => Value::Void,
63 Value::Number(_) => Value::Number(row as _),
64 Value::Model(model_ptr) => model_ptr.row_data(row)?,
65 x => panic!("Invalid model {x:?}"),
66 })
67 }
68 }
69
70 fn model_tracker(&self) -> &dyn ModelTracker {
71 self
72 }
73
74 fn set_row_data(&self, row: usize, data: Self::Data) {
75 match &self.value {
76 Value::Model(model_ptr) => model_ptr.set_row_data(row, data),
77 _ => eprintln!("Trying to change the value of a read-only integer model."),
78 }
79 }
80
81 fn as_any(&self) -> &dyn core::any::Any {
82 self
83 }
84}
85
86#[derive(Default)]
88pub(crate) struct BoolModel {
89 value: Cell<bool>,
90 notify: ModelNotify,
91}
92
93impl Model for BoolModel {
94 type Data = Value;
95 fn row_count(&self) -> usize {
96 if self.value.get() {
97 1
98 } else {
99 0
100 }
101 }
102 fn row_data(&self, row: usize) -> Option<Self::Data> {
103 (row == 0 && self.value.get()).then_some(Value::Void)
104 }
105 fn model_tracker(&self) -> &dyn ModelTracker {
106 &self.notify
107 }
108}
109
110impl BoolModel {
111 pub fn set_value(&self, val: bool) {
112 let old = self.value.replace(val);
113 if old != val {
114 self.notify.reset();
115 }
116 }
117}
118
119pub struct ValueMapModel<T>(pub ModelRc<T>);
121
122impl<T: TryFrom<Value> + Into<Value> + 'static> Model for ValueMapModel<T> {
123 type Data = Value;
124
125 fn row_count(&self) -> usize {
126 self.0.row_count()
127 }
128
129 fn row_data(&self, row: usize) -> Option<Self::Data> {
130 self.0.row_data(row).map(|x| x.into())
131 }
132
133 fn model_tracker(&self) -> &dyn ModelTracker {
134 self.0.model_tracker()
135 }
136
137 fn as_any(&self) -> &dyn core::any::Any {
138 self
139 }
140
141 fn set_row_data(&self, row: usize, data: Self::Data) {
142 if let Ok(data) = data.try_into() {
143 self.0.set_row_data(row, data)
144 }
145 }
146}