OnlineLibrary
412 строк · 13.2 Кб
1package gui
2
3import (
4"fmt"
5"time"
6
7"OnlineLibrary/internal/config"
8"OnlineLibrary/internal/gui/msg"
9"github.com/leonelquinteros/gotext"
10"gitverse.ru/kvark128/walk"
11. "gitverse.ru/kvark128/walk/declarative"
12)
13
14type Form interface {
15form() walk.Form
16}
17
18type MainWnd struct {
19mainWindow *walk.MainWindow
20msgChan chan msg.Message
21menuBar *MenuBar
22mainListBox *MainListBox
23statusBar *StatusBar
24}
25
26func NewMainWindow() (*MainWnd, error) {
27wnd := &MainWnd{
28msgChan: make(chan msg.Message, config.MessageBufferSize),
29menuBar: new(MenuBar),
30mainListBox: new(MainListBox),
31statusBar: new(StatusBar),
32}
33
34wnd.menuBar.libraryLogon = walk.NewMutableCondition()
35MustRegisterCondition("libraryLogon", wnd.menuBar.libraryLogon)
36wnd.menuBar.bookMenuEnabled = walk.NewMutableCondition()
37MustRegisterCondition("bookMenuEnabled", wnd.menuBar.bookMenuEnabled)
38
39wndLayout := MainWindow{
40Title: config.ProgramName,
41Layout: VBox{},
42AssignTo: &wnd.mainWindow,
43
44MenuItems: []MenuItem{
45Menu{
46Text: gotext.Get("&Library"),
47Items: []MenuItem{
48Menu{
49Text: gotext.Get("Accounts"),
50AssignTo: &wnd.menuBar.libraryMenu,
51Items: []MenuItem{
52Action{
53Text: gotext.Get("New account"),
54Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyN},
55OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.LIBRARY_ADD} },
56},
57},
58},
59Action{
60Text: gotext.Get("Bookshelf"),
61Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyE},
62Enabled: Bind("libraryLogon"),
63OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.OPEN_BOOKSHELF} },
64},
65Action{
66Text: gotext.Get("New books"),
67Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyK},
68Enabled: Bind("libraryLogon"),
69OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.OPEN_NEWBOOKS} },
70},
71Action{
72Text: gotext.Get("Find..."),
73Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyF},
74Enabled: Bind("libraryLogon"),
75OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.SEARCH_BOOK} },
76},
77Action{
78Text: gotext.Get("Main menu"),
79Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyM},
80Enabled: Bind("libraryLogon"),
81OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.MAIN_MENU} },
82},
83Action{
84Text: gotext.Get("Previous menu"),
85Shortcut: Shortcut{Modifiers: 0, Key: walk.KeyBack},
86Enabled: Bind("libraryLogon"),
87OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.MENU_BACK} },
88},
89Action{
90Text: gotext.Get("Local books"),
91Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyL},
92OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.SET_PROVIDER, Data: config.LocalStorageID} },
93},
94Action{
95Text: gotext.Get("Library information"),
96Enabled: Bind("libraryLogon"),
97OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.LIBRARY_INFO} },
98},
99Action{
100Text: gotext.Get("Delete account"),
101Enabled: Bind("libraryLogon"),
102OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.LIBRARY_REMOVE} },
103},
104Action{
105Text: gotext.Get("Exit"),
106Shortcut: Shortcut{Modifiers: walk.ModAlt, Key: walk.KeyF4},
107OnTriggered: func() { wnd.mainWindow.Close() },
108},
109},
110},
111
112Menu{
113Text: gotext.Get("&Book"),
114AssignTo: &wnd.menuBar.bookMenu,
115Enabled: Bind("bookMenuEnabled"),
116Items: []MenuItem{
117Action{
118Text: gotext.Get("Add book to bookshelf"),
119Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyA},
120Enabled: Bind("libraryLogon"),
121OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.ISSUE_BOOK} },
122},
123Action{
124Text: gotext.Get("Download book"),
125Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyD},
126Enabled: Bind("libraryLogon"),
127OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.DOWNLOAD_BOOK} },
128},
129Action{
130Text: gotext.Get("Remove book from bookshelf"),
131Shortcut: Shortcut{Modifiers: walk.ModShift, Key: walk.KeyDelete},
132Enabled: Bind("libraryLogon"),
133OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.REMOVE_BOOK} },
134},
135Action{
136Text: gotext.Get("Book information"),
137Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyI},
138OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.BOOK_DESCRIPTION} },
139},
140},
141},
142
143Menu{
144Text: gotext.Get("&Playback"),
145Items: []MenuItem{
146Menu{
147Text: gotext.Get("Bookmarks"),
148AssignTo: &wnd.menuBar.bookmarkMenu,
149Items: []MenuItem{
150Action{
151Text: gotext.Get("New bookmark"),
152Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyB},
153OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.BOOKMARK_SET} },
154},
155},
156},
157Action{
158Text: gotext.Get("Play / Pause"),
159Shortcut: Shortcut{Key: walk.KeySpace},
160OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_PLAY_PAUSE} },
161},
162Action{
163Text: gotext.Get("Stop"),
164Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeySpace},
165OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_STOP} },
166},
167
168Menu{
169Text: gotext.Get("Book navigation"),
170Items: []MenuItem{
171Action{
172Text: gotext.Get("Beginning of the book"),
173Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyBack},
174OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_GOTO_FRAGMENT, Data: 0} },
175},
176Action{
177Text: gotext.Get("Go to fragment..."),
178Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyG},
179OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_GOTO_FRAGMENT} },
180},
181Action{
182Text: gotext.Get("Next fragment"),
183Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyNext},
184OnTriggered: func() { wnd.msgChan <- next_fragment },
185},
186Action{
187Text: gotext.Get("Previous fragment"),
188Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyPrior},
189OnTriggered: func() { wnd.msgChan <- previous_fragment },
190},
191},
192},
193
194Menu{
195Text: gotext.Get("Fragment navigation"),
196Items: []MenuItem{
197Action{
198Text: gotext.Get("Beginning of the fragment"),
199Shortcut: Shortcut{Modifiers: walk.ModShift, Key: walk.KeyBack},
200OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_GOTO_POSITION, Data: time.Duration(0)} },
201},
202Action{
203Text: gotext.Get("Go to position..."),
204Shortcut: Shortcut{Modifiers: walk.ModShift, Key: walk.KeyG},
205OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_GOTO_POSITION} },
206},
207Action{
208Text: gotext.Get("5 sec. forward"),
209Shortcut: Shortcut{Modifiers: 0, Key: walk.KeyRight},
210OnTriggered: func() { wnd.msgChan <- rewind_5sec_forward },
211},
212Action{
213Text: gotext.Get("5 sec. backward"),
214Shortcut: Shortcut{Modifiers: 0, Key: walk.KeyLeft},
215OnTriggered: func() { wnd.msgChan <- rewind_5sec_back },
216},
217Action{
218Text: gotext.Get("30 sec. forward"),
219Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyRight},
220OnTriggered: func() { wnd.msgChan <- rewind_30sec_forward },
221},
222Action{
223Text: gotext.Get("30 sec. backward"),
224Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyLeft},
225OnTriggered: func() { wnd.msgChan <- rewind_30sec_back },
226},
227Action{
228Text: gotext.Get("1 min. forward"),
229Shortcut: Shortcut{Modifiers: walk.ModShift, Key: walk.KeyRight},
230OnTriggered: func() { wnd.msgChan <- rewind_1min_forward },
231},
232Action{
233Text: gotext.Get("1 min. backward"),
234Shortcut: Shortcut{Modifiers: walk.ModShift, Key: walk.KeyLeft},
235OnTriggered: func() { wnd.msgChan <- rewind_1min_back },
236},
237Action{
238Text: gotext.Get("5 min. forward"),
239Shortcut: Shortcut{Modifiers: walk.ModControl | walk.ModShift, Key: walk.KeyRight},
240OnTriggered: func() { wnd.msgChan <- rewind_5min_forward },
241},
242Action{
243Text: gotext.Get("5 min. backward"),
244Shortcut: Shortcut{Modifiers: walk.ModControl | walk.ModShift, Key: walk.KeyLeft},
245OnTriggered: func() { wnd.msgChan <- rewind_5min_back },
246},
247},
248},
249
250Menu{
251Text: gotext.Get("Volume"),
252Items: []MenuItem{
253Action{
254Text: gotext.Get("Increase volume"),
255Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyUp},
256OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_VOLUME_UP} },
257},
258Action{
259Text: gotext.Get("Decrease volume"),
260Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyDown},
261OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_VOLUME_DOWN} },
262},
263Action{
264Text: gotext.Get("Reset volume"),
265Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyR},
266OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_VOLUME_RESET} },
267},
268},
269},
270
271Menu{
272Text: gotext.Get("Speed"),
273Items: []MenuItem{
274Action{
275Text: gotext.Get("Increase speed"),
276Shortcut: Shortcut{Modifiers: walk.ModShift, Key: walk.KeyUp},
277OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_SPEED_UP} },
278},
279Action{
280Text: gotext.Get("Decrease speed"),
281Shortcut: Shortcut{Modifiers: walk.ModShift, Key: walk.KeyDown},
282OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_SPEED_DOWN} },
283},
284Action{
285Text: gotext.Get("Reset speed"),
286Shortcut: Shortcut{Modifiers: walk.ModShift, Key: walk.KeyR},
287OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_SPEED_RESET} },
288},
289},
290},
291},
292},
293Menu{
294Text: gotext.Get("&Settings"),
295Items: []MenuItem{
296Menu{
297Text: gotext.Get("Audio output device"),
298AssignTo: &wnd.menuBar.outputDeviceMenu,
299},
300Menu{
301Text: gotext.Get("Language"),
302AssignTo: &wnd.menuBar.languageMenu,
303},
304Action{
305Text: gotext.Get("Pause timer"),
306AssignTo: &wnd.menuBar.pauseTimerItem,
307Shortcut: Shortcut{Modifiers: walk.ModControl, Key: walk.KeyP},
308OnTriggered: func() { wnd.msgChan <- msg.Message{Code: msg.PLAYER_SET_TIMER} },
309},
310Menu{
311Text: gotext.Get("Logging level"),
312AssignTo: &wnd.menuBar.logLevelMenu,
313},
314},
315},
316Menu{
317Text: gotext.Get("&Help"),
318Items: []MenuItem{
319Action{
320Text: gotext.Get("About"),
321OnTriggered: func() {
322msg := gotext.Get("%v version %v\nWorking directory: %v\nAuthor: %v", config.ProgramName, config.ProgramVersion, config.UserData(), config.CopyrightInfo)
323walk.MsgBox(wnd.mainWindow, gotext.Get("About"), msg, walk.MsgBoxOK|walk.MsgBoxIconInformation)
324},
325},
326},
327},
328},
329
330Children: []Widget{
331TextLabel{
332AssignTo: &wnd.mainListBox.label,
333},
334ListBox{
335AssignTo: &wnd.mainListBox.ListBox,
336OnItemActivated: func() {
337wnd.msgChan <- msg.Message{Code: msg.ACTIVATE_MENU}
338},
339},
340},
341
342StatusBarItems: []StatusBarItem{
343StatusBarItem{
344AssignTo: &wnd.statusBar.elapseTime,
345Text: "00:00:00",
346},
347StatusBarItem{
348Text: "/",
349},
350StatusBarItem{
351AssignTo: &wnd.statusBar.totalTime,
352Text: "00:00:00",
353},
354StatusBarItem{
355AssignTo: &wnd.statusBar.fragments,
356},
357StatusBarItem{
358AssignTo: &wnd.statusBar.bookPercent,
359},
360},
361}
362
363if err := wndLayout.Create(); err != nil {
364return nil, err
365}
366
367wnd.menuBar.wnd = wnd.mainWindow
368wnd.menuBar.msgCH = wnd.msgChan
369wnd.mainListBox.msgCH = wnd.msgChan
370wnd.statusBar.StatusBar = wnd.mainWindow.StatusBar()
371
372if err := walk.InitWrapperWindow(wnd.mainListBox); err != nil {
373return nil, err
374}
375return wnd, nil
376}
377
378func (mw *MainWnd) MsgChan() chan msg.Message {
379return mw.msgChan
380}
381
382func (mw *MainWnd) form() walk.Form {
383return mw.mainWindow
384}
385
386func (mw *MainWnd) Run() {
387mw.msgChan <- msg.Message{Code: msg.SET_PROVIDER}
388mw.mainWindow.Run()
389close(mw.msgChan)
390}
391
392func (mw *MainWnd) MenuBar() *MenuBar {
393return mw.menuBar
394}
395
396func (mw *MainWnd) MainListBox() *MainListBox {
397return mw.mainListBox
398}
399
400func (mw *MainWnd) StatusBar() *StatusBar {
401return mw.statusBar
402}
403
404func (mw *MainWnd) SetTitle(title string) {
405mw.mainWindow.Synchronize(func() {
406var windowTitle = config.ProgramName
407if title != "" {
408windowTitle = fmt.Sprintf("%v \u2014 %v", title, windowTitle)
409}
410mw.mainWindow.SetTitle(windowTitle)
411})
412}
413