-
Notifications
You must be signed in to change notification settings - Fork 0
/
system_tray.go
153 lines (131 loc) · 5.17 KB
/
system_tray.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package main
import (
"log/slog"
"net/url"
"os"
"strings"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/driver/desktop"
layoutv1 "fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
ollamaApi "github.com/ollama/ollama/api"
"github.com/bahelit/ctrl_plus_revise/internal/data"
"github.com/bahelit/ctrl_plus_revise/internal/gui/bindings"
"github.com/bahelit/ctrl_plus_revise/internal/gui/chat"
"github.com/bahelit/ctrl_plus_revise/internal/gui/food"
"github.com/bahelit/ctrl_plus_revise/internal/gui/menu"
"github.com/bahelit/ctrl_plus_revise/internal/gui/question"
"github.com/bahelit/ctrl_plus_revise/internal/gui/settings"
"github.com/bahelit/ctrl_plus_revise/internal/gui/shortcuts"
"github.com/bahelit/ctrl_plus_revise/internal/gui/translator"
)
const (
AppTitle = "Ctrl+Revise AI Text Generator"
GreetingsText = "Welcome to Ctrl+Revise!"
TrayMenuTitle = "Ctrl+Revise"
)
// SetupSysTray initializes the system tray for the application
func SetupSysTray(guiApp fyne.App, ollamaClient *ollamaApi.Client) fyne.Window {
if err := bindings.SetBindingVariables(guiApp); err != nil {
slog.Error("Failed to set binding variables", "error", err)
os.Exit(1)
}
sysTray := guiApp.NewWindow(AppTitle)
sysTray.SetTitle(AppTitle)
sysTray.SetMainMenu(menu.MakeMenu(guiApp, ollamaClient, sysTray))
setupTrayMenu(guiApp, ollamaClient, sysTray)
setupTrayWindowContent(guiApp, ollamaClient, sysTray)
sysTray.SetCloseIntercept(func() {
sysTray.Hide()
})
return sysTray
}
// setupTrayMenu sets up the system tray menu
func setupTrayMenu(guiApp fyne.App, ollamaClient *ollamaApi.Client, sysTray fyne.Window) {
if desk, ok := guiApp.(desktop.App); ok {
desk.SetSystemTrayMenu(fyne.NewMenu(TrayMenuTitle,
fyne.NewMenuItem("Ask a Question", func() { question.AskQuestionWindow(guiApp, ollamaClient) }),
fyne.NewMenuItem("Chat with AI", func() { chat.ConversationManager(guiApp, ollamaClient) }),
fyne.NewMenuItem("Meal Planner", func() { food.MealPlanner(guiApp, ollamaClient) }),
fyne.NewMenuItem("Translate Window", func() { translator.TranslateText(guiApp, ollamaClient) }),
fyne.NewMenuItemSeparator(),
fyne.NewMenuItem("Home Screen", func() { sysTray.Show() }),
fyne.NewMenuItemSeparator(),
fyne.NewMenuItem("Settings", func() { settings.ShowSettings(guiApp, ollamaClient) }),
fyne.NewMenuItem("Keyboard Shortcuts", func() { shortcuts.ShowShortcuts(guiApp) }),
fyne.NewMenuItemSeparator(),
fyne.NewMenuItem("About", func() { settings.ShowAbout(guiApp) }),
))
}
}
// setupTrayWindowContent sets up the content of the system tray window
func setupTrayWindowContent(guiApp fyne.App, ollamaClient *ollamaApi.Client, sysTray fyne.Window) {
welcomeText := mainWindowText()
askQuestionsButton := widget.NewButton("Ask a Question", func() {
question.AskQuestionWindow(guiApp, ollamaClient)
})
askQuestionsButton.Importance = widget.HighImportance
chatButton := widget.NewButton("Chat with AI", func() {
chat.ConversationManager(guiApp, ollamaClient)
})
chatButton.Importance = widget.HighImportance
recipeButton := widget.NewButton("Meal Planner", func() {
food.MealPlanner(guiApp, ollamaClient)
})
recipeButton.Importance = widget.HighImportance
translatorButton := widget.NewButton("Translate Text", func() {
translator.TranslateText(guiApp, ollamaClient)
})
translatorButton.Importance = widget.HighImportance
buttons := container.NewVBox(
container.NewPadded(askQuestionsButton),
container.NewPadded(chatButton),
container.NewPadded(recipeButton),
container.NewPadded(translatorButton),
)
footer := footer()
sysTray.SetContent(container.NewBorder(welcomeText, footer, nil, nil, buttons))
}
func footer() *fyne.Container {
footer := container.NewHBox(
layoutv1.NewSpacer(),
widget.NewHyperlink("Ctrl+Revise", parseURL("https://ctrlplusrevise.com")),
widget.NewLabel("-"),
widget.NewHyperlink("Documentation", parseURL("https://ctrlplusrevise.com/docs/tutorials/")),
widget.NewLabel("-"),
widget.NewHyperlink("Sponsor", parseURL("https://www.patreon.com/SalmonsStudios")),
layoutv1.NewSpacer(),
)
return footer
}
func parseURL(urlStr string) *url.URL {
link, err := url.Parse(urlStr)
if err != nil {
fyne.LogError("Could not parse URL", err)
}
return link
}
func loadIcon(guiApp fyne.App) {
guiApp.SetIcon(data.LogoPNG)
}
func mainWindowText() *fyne.Container {
welcomeText := widget.NewLabel(GreetingsText)
welcomeText.Alignment = fyne.TextAlignCenter
welcomeText.TextStyle = fyne.TextStyle{Bold: true}
ctrlReviseKeys := shortcuts.GetCtrlReviseKeys()
var ctrlReviseString string
keyLength := len(ctrlReviseKeys)
for key, value := range ctrlReviseKeys {
ctrlReviseString += strings.ToUpper(value)
if key != keyLength-1 {
ctrlReviseString += " + "
}
}
shortcutText := widget.NewLabel("Pressing \"" + ctrlReviseString + "\" will send the highlighted text to an AI\nthe response is put into the clipboard")
shortcutText.Alignment = fyne.TextAlignCenter
shortcutText.TextStyle = fyne.TextStyle{Bold: true}
closeMeText := widget.NewLabel("This window can be closed, the program will keep running in the taskbar")
closeMeText.Alignment = fyne.TextAlignCenter
return container.NewVBox(welcomeText, closeMeText, shortcutText)
}