Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
PageModel.cs
4using Waher.Content;
5
7{
11 public class PageModel
12 {
13 private readonly XmppFormViewModel model;
14 private readonly DataForm form;
15 private readonly Layout.Page page;
16
17 public PageModel(XmppFormViewModel Model, Layout.Page Page)
18 {
19 this.model = Model;
20 this.page = Page;
21 this.form = this.page.Form;
22 }
23
24 public string Label => this.page.Label;
25
26 public bool HasLabel => !string.IsNullOrEmpty(this.page.Label);
27
28 public View Content => this.BuildContent(this.page.Elements);
29
30 private VerticalStackLayout BuildContent(Layout.LayoutElement[] Elements)
31 {
32 VerticalStackLayout Result = new VerticalStackLayout();
33
34 foreach (Layout.LayoutElement Element in Elements)
35 {
36 if (this.BuildContent(Element) is View view)
37 Result.Children.Add(view);
38 }
39
40 return Result;
41 }
42
43 private object? BuildContent(Layout.LayoutElement Element)
44 {
45 if (Element is Layout.FieldReference FieldRef)
46 {
47 Field Field = FieldRef.Form[FieldRef.Var];
48 if (Field is null)
49 return null;
50
51 if (Field is BooleanField)
52 {
53 HorizontalStackLayout Layout = [];
54
55 CheckBox CheckBox = new()
56 {
57 IsChecked = CommonTypes.TryParse(Field.ValueString, out bool b) && b,
58 IsEnabled = !Field.ReadOnly,
59 StyleId = Field.Var,
60 VerticalOptions = LayoutOptions.Center,
61 BackgroundColor = BackgroundColor(Field)
62 };
63
64 CheckBox.CheckedChanged += this.CheckBox_CheckedChanged;
65
66 Layout.Children.Add(CheckBox);
67 Layout.Children.Add(new Label()
68 {
69 Text = Field.Label,
70 Style = AppStyles.KeyLabel,
71 LineBreakMode = LineBreakMode.WordWrap,
72 VerticalOptions = LayoutOptions.Center
73 });
74
75 return Layout;
76 }
77 else if (Field is FixedField FixedField)
78 {
79 return new Label()
80 {
82 Style = AppStyles.InfoLabel,
83 LineBreakMode = LineBreakMode.WordWrap
84 };
85 }
87 {
88 VerticalStackLayout Layout = [];
89
90 Layout.Children.Add(new Label()
91 {
92 Text = Field.Label,
93 Style = AppStyles.KeyLabel,
94 LineBreakMode = LineBreakMode.WordWrap
95 });
96
97 Entry Entry = new()
98 {
99 Text = Field.ValueString,
100 IsEnabled = !Field.ReadOnly,
101 StyleId = Field.Var,
102 BackgroundColor = BackgroundColor(Field),
103 IsPassword = Field is TextPrivateField
104 };
105
106 Entry.TextChanged += this.Entry_TextChanged;
107
108 Layout.Children.Add(Entry);
109
110 return Layout;
111 }
112 else if (Field is TextMultiField || Field is JidMultiField)
113 {
114 VerticalStackLayout Layout = [];
115
116 Layout.Children.Add(new Label()
117 {
118 Text = Field.Label,
119 Style = AppStyles.KeyLabel,
120 LineBreakMode = LineBreakMode.WordWrap
121 });
122
123 Editor Editor = new()
124 {
125 Text = Field.ValueString,
126 IsEnabled = !Field.ReadOnly,
127 StyleId = Field.Var,
128 BackgroundColor = BackgroundColor(Field)
129 };
130
131 Editor.TextChanged += this.Editor_TextChanged;
132
133 Layout.Children.Add(Editor);
134
135 return Layout;
136 }
138 {
139 VerticalStackLayout Layout = [];
140
141 Layout.Children.Add(new Label()
142 {
143 Text = Field.Label,
144 Style = AppStyles.KeyLabel,
145 LineBreakMode = LineBreakMode.WordWrap
146 });
147
148 Picker Picker = new()
149 {
150 Title = Field.Description,
151 IsEnabled = !Field.ReadOnly,
152 StyleId = Field.Var,
153 BackgroundColor = BackgroundColor(Field)
154 };
155
156 if (Field?.Options is not null)
157 {
158 foreach (KeyValuePair<string, string> Option in Field.Options)
159 Picker.Items.Add(Option.Key);
160 }
161
162 Picker.SelectedItem = Field?.ValueString;
163 Picker.SelectedIndexChanged += this.Picker_SelectedIndexChanged;
164
165 Layout.Children.Add(Picker);
166
167 return Layout;
168 }
169 else if (Field is ListMultiField)
170 {
171 VerticalStackLayout Layout = [];
172
173 Layout.Children.Add(new Label()
174 {
175 Text = Field.Label,
176 Style = AppStyles.KeyLabel,
177 LineBreakMode = LineBreakMode.WordWrap
178 });
179
180 if (Field.Options is not null)
181 {
182 Dictionary<string, bool> Selected = [];
183
184 if (Field.ValueStrings is not null)
185 {
186 foreach (string s in Field.ValueStrings)
187 Selected[s] = true;
188 }
189
190 foreach (KeyValuePair<string, string> Option in Field.Options)
191 {
192 HorizontalStackLayout Layout2 = [];
193
194 CheckBox CheckBox = new()
195 {
196 IsChecked = Selected.ContainsKey(Option.Value),
197 IsEnabled = !Field.ReadOnly,
198 StyleId = Field.Var + " | " + Option.Value,
199 VerticalOptions = LayoutOptions.Center,
200 BackgroundColor = BackgroundColor(Field)
201 };
202
203 CheckBox.CheckedChanged += this.MultiCheckBox_CheckedChanged;
204
205 Layout2.Children.Add(CheckBox);
206 Layout2.Children.Add(new Label()
207 {
208 Text = Option.Key,
209 Style = AppStyles.KeyLabel,
210 LineBreakMode = LineBreakMode.WordWrap,
211 VerticalOptions = LayoutOptions.Center
212 });
213
214 Layout.Children.Add(Layout2);
215 }
216 }
217
218 return Layout;
219 }
220 else if (Field is MediaField MediaField)
221 {
223
224 if (string.IsNullOrEmpty(Media.ContentType) || Media.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
225 {
226 VerticalStackLayout Layout = [];
227
228 Layout.Children.Add(new Label()
229 {
230 Text = Field.Label,
231 Style = AppStyles.KeyLabel,
232 LineBreakMode = LineBreakMode.WordWrap
233 });
234
235 ImageSource? Source;
236
237 if (Media.Binary is not null)
238 Source = ImageSource.FromStream(() => new MemoryStream(Media.Binary));
239 else if (!string.IsNullOrEmpty(Media.URL) && Uri.TryCreate(Media.URL, UriKind.Absolute, out Uri? ParsedUrl))
240 Source = ImageSource.FromUri(ParsedUrl);
241 else
242 Source = null;
243
244 if (Source is not null)
245 {
246 Image Image = new()
247 {
248 Source = Source,
249 HorizontalOptions = LayoutOptions.Center,
250 VerticalOptions = LayoutOptions.Start
251 };
252
253 Layout.Children.Add(Image);
254 }
255
256 return Layout;
257 }
258 else
259 return null; // TODO: audio, video
260 }
261 else
262 return null;
263 }
264 else if (Element is Layout.Section Section)
265 {
266 VerticalStackLayout Layout = [];
267
268 if (!string.IsNullOrEmpty(Section.Label))
269 {
270 Layout.Children.Add(new Label()
271 {
272 Text = Section.Label,
274 LineBreakMode = LineBreakMode.WordWrap
275 });
276 }
277
278 foreach (Layout.LayoutElement Element2 in Section.Elements)
279 {
280 object? Content = this.BuildContent(Element2);
281
282 if (Content is View View)
283 Layout.Children.Add(View);
284 }
285
286 Frame Frame = new()
287 {
288 BorderColor = AppColors.PrimaryForeground,
289 Padding = new Thickness(10),
290 CornerRadius = 5,
291 Content = Layout
292 };
293
294 return Frame;
295 }
296 else if (Element is Layout.TextElement Text)
297 {
298 return new Label()
299 {
300 Text = Text.Text,
301 Style = AppStyles.InfoLabel,
302 LineBreakMode = LineBreakMode.WordWrap
303 };
304 }
305 else
306 return null;
307 }
308
309 private static Color? BackgroundColor(Field F)
310 {
311 if (F.HasError)
313 else if (F.NotSame)
315 else
316 return null;
317 }
318
319 private void CheckBox_CheckedChanged(object? sender, CheckedChangedEventArgs e)
320 {
321 if (sender is not CheckBox CheckBox)
322 return;
323
324 string Var = CheckBox.StyleId;
325 Field Field = this.form[Var];
326 if (Field is null)
327 return;
328
330
331 CheckBox.BackgroundColor = BackgroundColor(Field);
332
333 this.model.ValidateForm();
334 }
335
336 private void Entry_TextChanged(object? sender, TextChangedEventArgs e)
337 {
338 if (sender is not Entry Entry)
339 return;
340
341 string Var = Entry.StyleId;
342 Field Field = this.form[Var];
343 if (Field is null)
344 return;
345
346 Field.SetValue(e.NewTextValue);
347
348 Entry.BackgroundColor = BackgroundColor(Field);
349
350 this.model.ValidateForm();
351 }
352
353 private void Editor_TextChanged(object? sender, TextChangedEventArgs e)
354 {
355 if (sender is not Editor Editor)
356 return;
357
358 string Var = Editor.StyleId;
359 Field Field = this.form[Var];
360 if (Field is null)
361 return;
362
363 Field.SetValue(e.NewTextValue);
364
365 Editor.BackgroundColor = BackgroundColor(Field);
366
367 this.model.ValidateForm();
368 }
369
370 private void Picker_SelectedIndexChanged(object? sender, EventArgs e)
371 {
372 if (sender is not Picker Picker)
373 return;
374
375 string Var = Picker.StyleId;
376 Field Field = this.form[Var];
377 if (Field is null)
378 return;
379
380 string s = Picker.SelectedItem?.ToString() ?? string.Empty;
381
382 if (Field.Options is not null)
383 {
384 foreach (KeyValuePair<string, string> P in Field.Options)
385 {
386 if (s == P.Key)
387 {
388 s = P.Value;
389 break;
390 }
391 }
392 }
393
394 Field.SetValue(s);
395
396 Picker.BackgroundColor = BackgroundColor(Field);
397
398 this.model.ValidateForm();
399 }
400
401 private void MultiCheckBox_CheckedChanged(object? sender, CheckedChangedEventArgs e)
402 {
403 if (sender is not CheckBox CheckBox)
404 return;
405
406 string Var = CheckBox.StyleId;
407 int i = Var.IndexOf(" | ", StringComparison.InvariantCultureIgnoreCase);
408 if (i < 0)
409 return;
410
411 string Value = Var[(i + 3)..];
412 Var = Var[..i];
413
414 Field Field = this.form[Var];
415 if (Field is null)
416 return;
417
418 List<string> Values = [];
419 if (Field.ValueStrings is not null)
420 Values.AddRange(Field.ValueStrings);
421
422 if (e.Value)
423 {
424 i = Values.IndexOf(Value);
425 if (i < 0)
426 Values.Add(Value);
427 }
428 else
429 Values.Remove(Value);
430
431 Field.SetValue([.. Values]);
432
433 CheckBox.BackgroundColor = BackgroundColor(Field);
434
435 this.model.ValidateForm();
436 }
437
438 }
439}
Static class that gives access to app-specific themed colors
Definition: AppColors.cs:7
static Color DisabledFilledButtonBackground
DisabledFilledButton background color.
Definition: AppColors.cs:302
static Color PrimaryForeground
Primary foreground color.
Definition: AppColors.cs:62
static Color ErrorBackground
Error Background Color.
Definition: AppColors.cs:462
Static class that gives access to app-specific styles
Definition: AppStyles.cs:11
static Style SectionTitleLabel
Style of section title labels
Definition: AppStyles.cs:160
static Style InfoLabel
Style of information labels
Definition: AppStyles.cs:220
static Style KeyLabel
Style of key labels
Definition: AppStyles.cs:172
The view model to bind to for when displaying the calculator.
Helps with parsing of commong data types.
Definition: CommonTypes.cs:13
static string Encode(bool x)
Encodes a Boolean for use in XML and other formats.
Definition: CommonTypes.cs:594
static bool TryParse(string s, out double Value)
Tries to decode a string encoded double.
Definition: CommonTypes.cs:46
Implements support for data forms. Data Forms are defined in the following XEPs:
Definition: DataForm.cs:42
Base class for form fields
Definition: Field.cs:16
async Task< object > SetValue(string Value)
Sets the value of the field.
Definition: Field.cs:228
DataForm Form
Data Form containing the field.
Definition: Field.cs:73
string Var
Variable name
Definition: Field.cs:81
bool ReadOnly
Flags the field as being read-only.
Definition: Field.cs:145
string ValueString
Value as a single string. If field contains multiple values, they will be concatenated into a single ...
Definition: Field.cs:101
string Description
Description
Definition: Field.cs:111
string[] ValueStrings
Values for the field (string representations).
Definition: Field.cs:96
KeyValuePair< string, string >[] Options
Options, as (Key=M2H Label, Value=M2M Value) pairs.
Definition: Field.cs:106
Media Media
Media content to display in the field.
Definition: MediaField.cs:68
Class managing a page in a data form layout.
Definition: Page.cs:11
Class managing a section within a page in a data form layout.
Definition: Section.cs:13
LayoutElement[] Elements
Embedded layout elements.
Definition: Section.cs:118
Class containing information about media content in a data form.
Definition: Media.cs:18
string URL
Any web-based URL for the media.
Definition: Media.cs:137
string ContentType
Content-Type of data, if available.
Definition: Media.cs:128
byte[] Binary
Binary content, if available in the form.
Definition: Media.cs:119
Definition: App.xaml.cs:4