@@ -3,31 +3,68 @@ import { installConf, invokeCommand } from "@/utils";
33import { appWindow } from " @tauri-apps/api/window" ;
44import { onMounted , ref } from " vue" ;
55import { event } from " @tauri-apps/api" ;
6+ import { useI18n } from " vue-i18n" ;
7+
8+ interface MenuItem {
9+ icon? : string ,
10+ label: string
11+ action: () => void
12+ }
613
714const { isSetupMode } = defineProps ({
815 isSetupMode: {
916 type: Boolean ,
1017 default: true ,
1118 },
1219});
20+ const { t } = useI18n ();
1321
1422const exitDisabled = ref (false );
1523const labels = ref <Record <string , string >>({});
1624const appTitle = ref (' ' );
1725
26+ // Drop-dowm menu controls
27+ const showMenu = ref (false );
28+ const menuItems: MenuItem [] = [
29+ {
30+ icon: ' /icons/settings.svg' ,
31+ label: t (' settings' ),
32+ action : () => showPanel (' settings' ),
33+ },
34+ {
35+ icon: ' /icons/help.svg' ,
36+ label: t (' help' ),
37+ action : () => showPanel (' help' ),
38+ },
39+ {
40+ icon: ' /icons/info.svg' ,
41+ label: t (' about' ),
42+ action : () => showPanel (' about' ),
43+ },
44+ {
45+ icon: ' /icons/exit.svg' ,
46+ label: t (' exit' ),
47+ action : () => close (),
48+ }
49+ ]
50+
1851function minimize() { appWindow .minimize (); }
1952function maximize() { appWindow .toggleMaximize () }
2053function close() {
2154 invokeCommand (' close_window' );
2255}
2356
57+ function showPanel(name : string ) {
58+ console .log (" showing: " , name );
59+ }
60+
2461onMounted (() => {
2562 invokeCommand (' get_build_cfg_locale_str' , { key: ' logo_text' }).then ((res ) => {
2663 if (typeof res === ' string' ) {
2764 labels .value .logoText = res
2865 }
2966 });
30-
67+
3168 event .listen (' toggle-exit-blocker' , (event ) => {
3269 if (typeof event .payload === ' boolean' ) {
3370 exitDisabled .value = event .payload ;
@@ -50,12 +87,28 @@ onMounted(() => {
5087
5188 <div data-tauri-drag-region class =" titlebar-buttons" id =" titlebar-buttons" >
5289 <!-- FIXME: we need an English translation for GUI before enabling this -->
53- <div class =" titlebar-button" >
90+ <div class =" titlebar-button" @click = " showMenu = !showMenu " >
5491 <svg xmlns =" http://www.w3.org/2000/svg" width =" 18" viewBox =" 0 0 18 24" >
55- <path d =" M2 8C2 7.44772 2.44772 7 3 7H21C21.5523 7 22 7.44772 22 8C22 8.55228 21.5523 9 21 9H3C2.44772 9 2 8.55228 2 8Z" ></path >
56- <path d =" M2 12C2 11.4477 2.44772 11 3 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H3C2.44772 13 2 12.5523 2 12Z" ></path >
57- <path d =" M3 15C2.44772 15 2 15.4477 2 16C2 16.5523 2.44772 17 3 17H15C15.5523 17 16 16.5523 16 16C16 15.4477 15.5523 15 15 15H3Z" ></path >
92+ <path
93+ d =" M2 8C2 7.44772 2.44772 7 3 7H21C21.5523 7 22 7.44772 22 8C22 8.55228 21.5523 9 21 9H3C2.44772 9 2 8.55228 2 8Z" >
94+ </path >
95+ <path
96+ d =" M2 12C2 11.4477 2.44772 11 3 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H3C2.44772 13 2 12.5523 2 12Z" >
97+ </path >
98+ <path
99+ d =" M3 15C2.44772 15 2 15.4477 2 16C2 16.5523 2.44772 17 3 17H15C15.5523 17 16 16.5523 16 16C16 15.4477 15.5523 15 15 15H3Z" >
100+ </path >
58101 </svg >
102+ <div class =" menu-wrapper" >
103+ <transition name =" dropdown" >
104+ <ul v-if =" showMenu" class =" dropdown-menu" >
105+ <li v-for =" (item, index) in menuItems" :key =" index" class =" menu-item" @click =" item.action" >
106+ <img :src =" item.icon" class =" icon" />
107+ <span class =" label" >{{ item.label }}</span >
108+ </li >
109+ </ul >
110+ </transition >
111+ </div >
59112 </div >
60113
61114 <div class =" titlebar-button" id =" titlebar-minimize" @click =" minimize" >
@@ -66,7 +119,8 @@ onMounted(() => {
66119
67120 <div class =" titlebar-button" id =" titlebar-maximize" @click =" maximize" >
68121 <svg xmlns =" http://www.w3.org/2000/svg" width =" 18" viewBox =" 0 0 16 16" >
69- <path d =" M4.5 3A1.5 1.5 0 0 0 3 4.5v7A1.5 1.5 0 0 0 4.5 13h7a1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 11.5 3zM5 4.5h6a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5" />
122+ <path
123+ d =" M4.5 3A1.5 1.5 0 0 0 3 4.5v7A1.5 1.5 0 0 0 4.5 13h7a1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 11.5 3zM5 4.5h6a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5" />
70124 </svg >
71125 </div >
72126
@@ -124,7 +178,7 @@ onMounted(() => {
124178 border-radius : 3px ;
125179 margin-inline : 3px ;
126180 padding : 0 ;
127- fill :rgb (155 , 155 , 155 );
181+ fill : rgb (155 , 155 , 155 );
128182}
129183
130184.titlebar-button :hover {
@@ -142,36 +196,62 @@ onMounted(() => {
142196 font-size : 2.3vh ;
143197}
144198
145- .sub-menu {
146- position : absolute ;
147- background-color : rgba (2 , 2 , 10 , 0.8 );
148- transform : translateY (70% );
149- border-radius : 3px ;
199+ .menu-wrapper {
200+ position : relative ;
201+ margin-top : 5vh ;
150202}
151203
152- .sub-menu ul {
153- margin : 0 ;
204+ .dropdown-menu {
205+ position : absolute ;
206+ right : 0 ;
154207 padding : 0 ;
208+ border-radius : 20px ;
209+ background : rgba (255 , 255 , 255 , .5 );
210+ border : 2px solid transparent ;
211+ box-shadow : 0 0 0 2px rgba (255 , 255 , 255 , .6 ), 0 16px 32px rgba (0 , 0 , 0 , .12 );
212+ backdrop-filter : url (#frosted );
213+ -webkit-backdrop-filter : blur (20px );
214+ overflow : hidden ;
215+ list-style : none ;
216+ transform-origin : top center ;
155217}
156218
157- .sub-menu ul li {
158- list-style : none ;
219+ .menu-item {
159220 display : flex ;
160- padding : 1rem ;
161- color : white ;
162- font-size : 14px ;
163- text-decoration : none ;
221+ align-items : center ;
222+ padding : 2vh 4vw ;
223+ cursor : pointer ;
224+ transition : all 0.2s ease ;
225+ gap : 2vw ;
226+ }
227+
228+ .menu-item :hover {
229+ --uno : ' bg-light-primary' ;
230+ }
231+
232+ .icon {
233+ position : absolute ;
234+ left : 15% ;
235+ width : 1.5rem ;
236+ height : 1.5rem ;
164237}
165238
166- .sub-menu ul li :hover {
167- background-color : #526ecc ;
239+ .label {
240+ margin-left : 30% ;
241+ font-weight : 500 ;
242+ font-size : clamp (0.5rem , 2.6vh , 1.5rem );
243+ --uno : ' text-regular' ;
168244}
169245
170- .fade-leave-active {
171- transition : all .5s ease-out ;
246+ /* Animation classes */
247+ .dropdown-enter-active ,
248+ .dropdown-leave-active {
249+ transition : all 0.4s cubic-bezier (0.165 , 0.84 , 0.44 , 1 );
172250}
173251
174- .fade-leave-to {
252+ .dropdown-enter-from ,
253+ .dropdown-leave-to {
175254 opacity : 0 ;
255+ transform : scaleY (0.8 ) translateY (-10px );
176256}
177257 </style >
0 commit comments