changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > demo / src/crates/ui/sidebar.slint

changeset 22: ba323d8c0f93
parent: ui/sidebar.slint@e4c9ec452eb6
author: ellis <ellis@rwest.io>
date: Sat, 03 Jun 2023 22:48:46 -0400
permissions: -rw-r--r--
description: refactor1
1 import { StyleMetrics } from "std-widgets.slint";
2 
3 component SideBarItem inherits Rectangle {
4  callback clicked <=> touch.clicked;
5  in-out property<string> text <=> label.text;
6  in property<bool> selected;
7  in property<bool> has-focus;
8 
9  min-height: l.preferred-height;
10 
11  state := Rectangle {
12  opacity: 0;
13  background: StyleMetrics.window-background;
14 
15  animate opacity { duration: 150ms; }
16  }
17 
18  l := HorizontalLayout {
19  y: (parent.height - self.height) / 2;
20  padding: StyleMetrics.layout-padding;
21  spacing: 0px;
22 
23  label := Text {
24  color: StyleMetrics.default-text-color;
25  vertical-alignment: center;
26  }
27  }
28 
29  touch := TouchArea {
30  width: 100%;
31  height: 100%;
32  }
33 
34  states [
35  pressed when touch.pressed : {
36  state.opacity: 0.8;
37  }
38  hover when touch.has-hover : {
39  state.opacity: 0.6;
40  }
41  selected when root.selected : {
42  state.opacity: 1;
43  }
44  focused when root.has-focus : {
45  state.opacity: 0.8;
46  }
47  ]
48 }
49 
50 export component SideBar inherits Rectangle {
51  in property<[string]> model: [];
52  out property<int> current-item: 0;
53  in property<string> title <=> label.text;
54  out property<int> current-focused: fs.has-focus ? fs.focused-tab : -1; // The currently focused tab
55  width: 180px;
56 
57  forward-focus: fs;
58 
59  accessible-role: tab;
60  accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current-item;
61 
62  Rectangle {
63  background: StyleMetrics.window-background.darker(0.2);
64 
65  fs := FocusScope {
66  x:0;
67  width: 0px; // Do not react on clicks
68  property<int> focused-tab: 0;
69 
70  key-pressed(event) => {
71  if (event.text == "\n") {
72  root.current-item = root.current-focused;
73  return accept;
74  }
75  if (event.text == Key.UpArrow) {
76  self.focused-tab = Math.max(self.focused-tab - 1, 0);
77  return accept;
78  }
79  if (event.text == Key.DownArrow) {
80  self.focused-tab = Math.min(self.focused-tab + 1, root.model.length - 1);
81  return accept;
82  }
83  return reject;
84  }
85 
86  key-released(event) => {
87  if (event.text == " ") {
88  root.current-item = root.current-focused;
89  return accept;
90  }
91  return reject;
92  }
93  }
94  }
95 
96  VerticalLayout {
97  padding-top: StyleMetrics.layout-padding;
98  padding-bottom: StyleMetrics.layout-padding;
99  spacing: StyleMetrics.layout-spacing;
100  alignment: start;
101 
102  label := Text {
103  font-size: 16px;
104  horizontal-alignment: center;
105  }
106 
107  navigation := VerticalLayout {
108  alignment: start;
109  vertical-stretch: 0;
110  for item[index] in root.model : SideBarItem {
111  has-focus: index == root.current-focused;
112  text: item;
113  selected: index == root.current-item;
114  clicked => { root.current-item = index; }
115  }
116  }
117 
118  VerticalLayout {
119  bottom := VerticalLayout {
120  padding-left: StyleMetrics.layout-padding;
121  padding-right: StyleMetrics.layout-padding;
122 
123  @children
124  }
125  }
126  }
127 }