From dcb457be7a14181b56101fbaea5f7d4a716203e0 Mon Sep 17 00:00:00 2001 From: Sylvester Stephenson Date: Tue, 26 Sep 2023 21:40:17 +0200 Subject: [PATCH 1/5] Added a basic example of how to use webview with VTray to create a desktop app with a custom notification tray icon with menus. --- examples/app-with-systray/assets/icon.ico | Bin 0 -> 67646 bytes examples/app-with-systray/index.html | 8 +++ examples/app-with-systray/main.v | 63 ++++++++++++++++++++++ examples/app-with-systray/v.mod | 7 +++ 4 files changed, 78 insertions(+) create mode 100644 examples/app-with-systray/assets/icon.ico create mode 100644 examples/app-with-systray/index.html create mode 100644 examples/app-with-systray/main.v create mode 100644 examples/app-with-systray/v.mod diff --git a/examples/app-with-systray/assets/icon.ico b/examples/app-with-systray/assets/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..06bede17d811b694e94ddc42ff4e6dbca823c03d GIT binary patch literal 67646 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 GSNZ?&eCW{t literal 0 HcmV?d00001 diff --git a/examples/app-with-systray/index.html b/examples/app-with-systray/index.html new file mode 100644 index 0000000..2914cc1 --- /dev/null +++ b/examples/app-with-systray/index.html @@ -0,0 +1,8 @@ + + + Desktop App with notification tray + + +

Basic App with VTray!

+ + diff --git a/examples/app-with-systray/main.v b/examples/app-with-systray/main.v new file mode 100644 index 0000000..299f014 --- /dev/null +++ b/examples/app-with-systray/main.v @@ -0,0 +1,63 @@ +module main + +import webview +import ouri028.vtray + +enum MenuItems { + edit = 1 + quit = 2 +} + +struct Tray { +pub mut: + tray vtray.VTrayApp +} + +fn create_tray() { + mut systray := Tray{ + tray: vtray.VTrayApp{ + identifier: 'VTray!' + tooltip: 'VTray Demo!' + icon: '${@VMODROOT}/assets/icon.ico' + items: [ + &vtray.VTrayMenuItem{ + id: int(MenuItems.edit) + text: 'Edit' + }, + &vtray.VTrayMenuItem{ + id: int(MenuItems.quit) + text: 'Quit' + }, + ] + } + } + systray.tray.on_click = systray.on_click + systray.tray.vtray_init() + systray.tray.run() + systray.tray.destroy() +} + +// on_click -> This is the tray event listener +// which will give you an id that you can use to handle +// your tray logic. +fn (systray &Tray) on_click(menu_id int) { + match menu_id { + int(MenuItems.edit) { + println('EDIT!') + } + int(MenuItems.quit) { + systray.tray.destroy() + } + else {} + } +} + +fn main() { + w := webview.create(debug: true) + w.set_title('VTray Example!') + w.set_size(600, 400, .@none) + w.navigate('file://${@VMODROOT}/index.html') + spawn create_tray() + w.run() + w.destroy() +} diff --git a/examples/app-with-systray/v.mod b/examples/app-with-systray/v.mod new file mode 100644 index 0000000..2f47fee --- /dev/null +++ b/examples/app-with-systray/v.mod @@ -0,0 +1,7 @@ +Module { + name: 'VTray-Test' + description: '' + version: '0.0.1' + license: 'MIT' + dependencies: ['ouri028.vtray'] +} From 791f7b5dee916ce747155f048644f488d7be8599 Mon Sep 17 00:00:00 2001 From: Sylvester Stephenson <49057553+Ouri028@users.noreply.github.com> Date: Sun, 1 Oct 2023 14:20:27 -0700 Subject: [PATCH 2/5] Update main.v --- examples/app-with-systray/main.v | 68 ++++++++++++++------------------ 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/examples/app-with-systray/main.v b/examples/app-with-systray/main.v index 299f014..f7c56c0 100644 --- a/examples/app-with-systray/main.v +++ b/examples/app-with-systray/main.v @@ -9,55 +9,45 @@ enum MenuItems { } struct Tray { -pub mut: + pub mut: tray vtray.VTrayApp } -fn create_tray() { - mut systray := Tray{ - tray: vtray.VTrayApp{ - identifier: 'VTray!' - tooltip: 'VTray Demo!' - icon: '${@VMODROOT}/assets/icon.ico' - items: [ - &vtray.VTrayMenuItem{ - id: int(MenuItems.edit) - text: 'Edit' - }, - &vtray.VTrayMenuItem{ - id: int(MenuItems.quit) - text: 'Quit' - }, - ] - } +fn main() { + mut systray := &vtray.VTrayApp{ + identifier: 'VTray!' + tooltip: 'VTray Demo!' + icon: '${@VMODROOT}/assets/icon.png' + items: [ + &vtray.VTrayMenuItem{ + id: int(MenuItems.edit) + text: 'Edit' + }, + &vtray.VTrayMenuItem{ + id: int(MenuItems.quit) + text: 'Quit' + }, + ] } - systray.tray.on_click = systray.on_click - systray.tray.vtray_init() - systray.tray.run() - systray.tray.destroy() -} - -// on_click -> This is the tray event listener -// which will give you an id that you can use to handle -// your tray logic. -fn (systray &Tray) on_click(menu_id int) { - match menu_id { - int(MenuItems.edit) { - println('EDIT!') + on_click := fn [systray] (menu_id int) { + match menu_id { + int(MenuItems.edit) { + println('EDIT!') + } + int(MenuItems.quit) { + systray.destroy() + } + else {} } - int(MenuItems.quit) { - systray.tray.destroy() - } - else {} } -} - -fn main() { + systray.on_click = on_click + systray.vtray_init() w := webview.create(debug: true) w.set_title('VTray Example!') w.set_size(600, 400, .@none) w.navigate('file://${@VMODROOT}/index.html') - spawn create_tray() + spawn systray.run() w.run() w.destroy() + systray.destroy() } From d63c7e94b88dc7587e30d6b99b1f2a11d72426bc Mon Sep 17 00:00:00 2001 From: Sylvester Stephenson <49057553+Ouri028@users.noreply.github.com> Date: Sun, 1 Oct 2023 14:21:21 -0700 Subject: [PATCH 3/5] Update main.v --- examples/app-with-systray/main.v | 5 ----- 1 file changed, 5 deletions(-) diff --git a/examples/app-with-systray/main.v b/examples/app-with-systray/main.v index f7c56c0..865b920 100644 --- a/examples/app-with-systray/main.v +++ b/examples/app-with-systray/main.v @@ -8,11 +8,6 @@ enum MenuItems { quit = 2 } -struct Tray { - pub mut: - tray vtray.VTrayApp -} - fn main() { mut systray := &vtray.VTrayApp{ identifier: 'VTray!' From a1686e8ee1532776c0cce2a05df9f59e8dfa02bf Mon Sep 17 00:00:00 2001 From: Sylvester Stephenson Date: Tue, 3 Oct 2023 20:28:42 +0200 Subject: [PATCH 4/5] Added icon.png for MacOS. Also updated example to switch between icons depending on OS. --- examples/app-with-systray/assets/icon.png | Bin 0 -> 690 bytes examples/app-with-systray/main.v | 7 ++++++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 examples/app-with-systray/assets/icon.png diff --git a/examples/app-with-systray/assets/icon.png b/examples/app-with-systray/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..46233bc549ba26a11f13d680e9f5ad15af3c39ff GIT binary patch literal 690 zcmV;j0!{siP)Px%Y)M2xR7gu>WS|jXq>;G{L)>8Z%5{$!8JU>AzI%56)APHR-#@!~?$PNjv#|x2 zyrxA8zqqt9udt*pC!et5|NsB~?p@F<2UCj@6iVhnS$cs*Q;`k2v1dW!jXiT3ki}F? zUF$T=JsOe4t{z;Md;jv$DOe3=U|?Vl=s5BRS;OByzkY14apFW4^UUb@#>~QsBDQ5p zF)ITD16(ggMQc zbGJ(9+kvd{!Ksb2F0AWL2Z?Fh1x;4ev(7=5Ke>6P*XxJ3wj+ySO>O}lNB$!#`v33m z-;GuFEFdxOtnS~8OiW-l3~ZTFjA0H|gYB|r921h$u|(Fqv&&DG@yCz9PD#zrkj3A> ze0bvM>PaYSLGoA)=8=%oaw%AL71@C2R}XFY{p$KpDOH1TWbp&bx^=$1dx4@Br@%Aik>};S^ z1p&`*pI?4<=Moe(Fge_11uw5iK=t<5$OixZ{F;IB<2^*AEvOe``0@os4Pk>B7#RFo z_WfXDVPi)&{MW;y3{1={4FCTA`MGU+IR~;F!Q=*0py86#py85KkF4R_gA)vFEQ|~{ zPw#5JeR5|VSq3vOFmMEP9Qlr{`Oo){3=D5?Fl?Dp49e0!$TgV3t9Hw4Hf{kCWCOn3 z*!gzPf@TykbPEU;^q@4Y;gHk})A*l}f$_o7mDAony1oaOYw@OIe42=nBj{pc48f)b Y08lK|7g~P<0ssI207*qoM6N<$f`-pb{r~^~ literal 0 HcmV?d00001 diff --git a/examples/app-with-systray/main.v b/examples/app-with-systray/main.v index 865b920..e38dcb1 100644 --- a/examples/app-with-systray/main.v +++ b/examples/app-with-systray/main.v @@ -9,10 +9,15 @@ enum MenuItems { } fn main() { + icon := if macos { + '${@VMODROOT}/assets/icon.png' + } else { + '${@VMODROOT}/assets/icon.ico' + } mut systray := &vtray.VTrayApp{ identifier: 'VTray!' tooltip: 'VTray Demo!' - icon: '${@VMODROOT}/assets/icon.png' + icon: icon items: [ &vtray.VTrayMenuItem{ id: int(MenuItems.edit) From e75aa19b565a010ab7b7bbbd2fdcd89e536c75ef Mon Sep 17 00:00:00 2001 From: Sylvester Stephenson Date: Tue, 3 Oct 2023 20:31:26 +0200 Subject: [PATCH 5/5] Fixed conditional statement. --- examples/app-with-systray/main.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/app-with-systray/main.v b/examples/app-with-systray/main.v index e38dcb1..edc3adf 100644 --- a/examples/app-with-systray/main.v +++ b/examples/app-with-systray/main.v @@ -9,9 +9,9 @@ enum MenuItems { } fn main() { - icon := if macos { + icon := $if macos { '${@VMODROOT}/assets/icon.png' - } else { + } $else { '${@VMODROOT}/assets/icon.ico' } mut systray := &vtray.VTrayApp{