1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: MIT
3
4import { Theme } from "../theme.slint";
5import { MenuButton } from "menu_button.slint";
6import { MenuBackground } from "../components/menu_background.slint";
7
8export component Menu {
9 in-out property <bool> menu-button-visible;
10 in property <length> start-y;
11 in property <length> end-y;
12 in property <bool> stays-open;
13 in property <length> menu-width <=> i-menu-container.width;
14 in property <length> menu-height <=> i-menu-container.height;
15 out property <bool> open;
16
17 callback opend();
18 callback closed();
19
20 public function hide-button() {
21 menu-button-visible = false;
22 }
23
24 public function open-menu() {
25 open = true;
26 }
27
28 public function hide() {
29 menu-button-visible = false;
30 open = false;
31 closed();
32 }
33
34 private property <int> container-visibility;
35
36 states [
37 open when root.open : {
38 container-visibility: 1.0;
39 i-menu-container.y: end-y;
40
41 in {
42 animate i-menu-container.y { duration: Theme.durations.medium; }
43 }
44 out {
45 animate container-visibility, i-menu-container.y { duration: Theme.durations.medium; }
46 }
47 }
48 ]
49
50 if (open) : Rectangle {
51 background: Theme.palette.pure-black;
52 opacity: 0.5;
53
54 TouchArea {
55 clicked => {
56 hide();
57 }
58 }
59 }
60
61 i-menu-container := Rectangle {
62 x: (parent.width - self.width) / 2;
63 y: parent.height - start-y;
64 width: root.width / 3;
65 height: root.height - 75px;
66
67 i-container := MenuBackground {
68 visible: container-visibility == 1.0;
69
70 // avoid click-through
71 TouchArea {}
72
73 @children
74 }
75
76 if(menu-button-visible || container-visibility == 1.0 || stays-open) : HorizontalLayout {
77 y: -i-menu-button.height / 2;
78 alignment: center;
79
80 VerticalLayout {
81 alignment: start;
82
83 i-menu-button := MenuButton {
84 clicked => {
85 if(open) {
86 hide();
87 } else {
88 open-menu();
89 }
90 }
91 }
92 }
93 }
94 }
95}
96
97export component MobileMenu {
98 out property <bool> open;
99 in property <length> end-y;
100 in property <length> menu-x;
101 out property <length> menu-width: 200px;
102
103 if (root.open) : Rectangle {
104 background: Theme.palette.pure-black;
105 opacity: 0.5;
106
107 TouchArea {
108 clicked => {
109 hide();
110 }
111 }
112 }
113
114 public function open-menu() {
115 root.open = true;
116 }
117
118 public function hide() {
119 root.open = false;
120 }
121
122 Rectangle {
123 clip: true;
124 menu := Rectangle {
125 x: root.menu-x;
126 y: -self.height;
127 width: root.menu-width;
128 height: root.height / 2;
129 visible: visibility > 0.0;
130
131 private property <float> visibility;
132
133 MenuBackground {
134 // avoid click-through
135 TouchArea {}
136
137 @children
138 }
139
140 states [
141 open when root.open : {
142 menu.y: end-y;
143 visibility: 1.0;
144
145 out {
146 animate visibility { duration: Theme.durations.medium; }
147 }
148 }
149 ]
150
151 animate y { duration: Theme.durations.fast; }
152 }
153
154 }
155}
156