app.go raw
1 package gui
2
3 import (
4 "fmt"
5 "io/ioutil"
6 "os"
7 "os/exec"
8 "path/filepath"
9
10 uberatomic "go.uber.org/atomic"
11 "golang.org/x/exp/shiny/materialdesign/icons"
12
13 l "github.com/p9c/p9/pkg/gel/gio/layout"
14 "github.com/p9c/p9/pkg/gel/gio/text"
15
16 "github.com/p9c/p9/pkg/gel"
17 "github.com/p9c/p9/cmd/gui/cfg"
18 "github.com/p9c/p9/pkg/p9icons"
19 )
20
21 func (wg *WalletGUI) GetAppWidget() (a *gel.App) {
22 a = wg.App(wg.Window.Width, uberatomic.NewString("home"), Break1).
23 SetMainDirection(l.W).
24 SetLogo(&p9icons.ParallelCoin).
25 SetAppTitleText("Parallelcoin Wallet")
26 wg.MainApp = a
27 wg.config = cfg.New(wg.Window, wg.quit)
28 wg.configs = wg.config.Config()
29 a.Pages(
30 map[string]l.Widget{
31 "home": wg.Page(
32 "home", gel.Widgets{
33 // p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
34 gel.WidgetSize{Widget: wg.OverviewPage()},
35 },
36 ),
37 "send": wg.Page(
38 "send", gel.Widgets{
39 // p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
40 gel.WidgetSize{Widget: wg.SendPage.Fn},
41 },
42 ),
43 "receive": wg.Page(
44 "receive", gel.Widgets{
45 // p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
46 gel.WidgetSize{Widget: wg.ReceivePage.Fn},
47 },
48 ),
49 "history": wg.Page(
50 "history", gel.Widgets{
51 // p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
52 gel.WidgetSize{Widget: wg.HistoryPage()},
53 },
54 ),
55 "settings": wg.Page(
56 "settings", gel.Widgets{
57 // p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
58 gel.WidgetSize{
59 Widget: func(gtx l.Context) l.Dimensions {
60 return wg.configs.Widget(wg.config)(gtx)
61 },
62 },
63 },
64 ),
65 "console": wg.Page(
66 "console", gel.Widgets{
67 // p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
68 gel.WidgetSize{Widget: wg.console.Fn},
69 },
70 ),
71 "help": wg.Page(
72 "help", gel.Widgets{
73 gel.WidgetSize{Widget: wg.HelpPage()},
74 },
75 ),
76 "log": wg.Page(
77 "log", gel.Widgets{
78 gel.WidgetSize{Widget: a.Placeholder("log")},
79 },
80 ),
81 "quit": wg.Page(
82 "quit", gel.Widgets{
83 gel.WidgetSize{
84 Widget: func(gtx l.Context) l.Dimensions {
85 return wg.VFlex().
86 SpaceEvenly().
87 AlignMiddle().
88 Rigid(
89 wg.H4("are you sure?").Color(wg.MainApp.BodyColorGet()).Alignment(text.Middle).Fn,
90 ).
91 Rigid(
92 wg.Flex().
93 // SpaceEvenly().
94 Flexed(0.5, gel.EmptyMaxWidth()).
95 Rigid(
96 wg.Button(
97 wg.clickables["quit"].SetClick(
98 func() {
99 // interrupt.Request()
100 wg.gracefulShutdown()
101 // close(wg.quit)
102 },
103 ),
104 ).Color("Light").TextScale(5).Text(
105 "yes!!!",
106 ).Fn,
107 ).
108 Flexed(0.5, gel.EmptyMaxWidth()).
109 Fn,
110 ).
111 Fn(gtx)
112 },
113 },
114 },
115 ),
116 // "goroutines": wg.Page(
117 // "log", p9.Widgets{
118 // // p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
119 //
120 // p9.WidgetSize{
121 // Widget: func(gtx l.Context) l.Dimensions {
122 // le := func(gtx l.Context, index int) l.Dimensions {
123 // return wg.State.goroutines[index](gtx)
124 // }
125 // return func(gtx l.Context) l.Dimensions {
126 // return wg.ButtonInset(
127 // 0.25,
128 // wg.Fill(
129 // "DocBg",
130 // wg.lists["recent"].
131 // Vertical().
132 // // Background("DocBg").Color("DocText").Active("Primary").
133 // Length(len(wg.State.goroutines)).
134 // ListElement(le).
135 // Fn,
136 // ).Fn,
137 // ).
138 // Fn(gtx)
139 // }(gtx)
140 // // wg.NodeRunCommandChan <- "stop"
141 // // consume.Kill(wg.Worker)
142 // // consume.Kill(wg.cx.StateCfg.Miner)
143 // // close(wg.cx.NodeKill)
144 // // close(wg.cx.KillAll)
145 // // time.Sleep(time.Second*3)
146 // // interrupt.Request()
147 // // os.Exit(0)
148 // // return l.Dimensions{}
149 // },
150 // },
151 // },
152 // ),
153 "mining": wg.Page(
154 "mining", gel.Widgets{
155 gel.WidgetSize{
156 Widget: a.Placeholder("mining"),
157 },
158 },
159 ),
160 "explorer": wg.Page(
161 "explorer", gel.Widgets{
162 gel.WidgetSize{
163 Widget: a.Placeholder("explorer"),
164 },
165 },
166 ),
167 },
168 )
169 a.SideBar(
170 []l.Widget{
171 // wg.SideBarButton(" ", " ", 11),
172 wg.SideBarButton("home", "home", 0),
173 wg.SideBarButton("send", "send", 1),
174 wg.SideBarButton("receive", "receive", 2),
175 wg.SideBarButton("history", "history", 3),
176 // wg.SideBarButton("explorer", "explorer", 6),
177 // wg.SideBarButton("mining", "mining", 7),
178 wg.SideBarButton("console", "console", 9),
179 wg.SideBarButton("settings", "settings", 5),
180 // wg.SideBarButton("log", "log", 10),
181 wg.SideBarButton("help", "help", 8),
182 // wg.SideBarButton(" ", " ", 11),
183 // wg.SideBarButton("quit", "quit", 11),
184 },
185 )
186 a.ButtonBar(
187 []l.Widget{
188
189 // gel.EmptyMaxWidth(),
190 // wg.PageTopBarButton(
191 // "goroutines", 0, &icons.ActionBugReport, func(name string) {
192 // wg.App.ActivePage(name)
193 // }, a, "",
194 // ),
195 wg.PageTopBarButton(
196 "help", 1, &icons.ActionHelp, func(name string) {
197 wg.MainApp.ActivePage(name)
198 }, a, "",
199 ),
200 wg.PageTopBarButton(
201 "home", 4, &icons.ActionLockOpen, func(name string) {
202 wg.unlockPassword.Wipe()
203 wg.unlockPassword.Focus()
204 wg.WalletWatcher.Q()
205 // if wg.WalletClient != nil {
206 // wg.WalletClient.Disconnect()
207 // wg.WalletClient = nil
208 // }
209 // wg.wallet.Stop()
210 // wg.node.Stop()
211 wg.State.SetActivePage("home")
212 wg.unlockPage.ActivePage("home")
213 wg.stateLoaded.Store(false)
214 wg.ready.Store(false)
215 }, a, "green",
216 ),
217 // wg.Flex().Rigid(wg.Inset(0.5, gel.EmptySpace(0, 0)).Fn).Fn,
218 // wg.PageTopBarButton(
219 // "quit", 3, &icons.ActionExitToApp, func(name string) {
220 // wg.MainApp.ActivePage(name)
221 // }, a, "",
222 // ),
223 },
224 )
225 a.StatusBar(
226 []l.Widget{
227 // func(gtx l.Context) l.Dimensions { return wg.RunStatusPanel(gtx) },
228 // wg.Inset(0.5, gel.EmptySpace(0, 0)).Fn,
229 // wg.Inset(0.5, gel.EmptySpace(0, 0)).Fn,
230 wg.RunStatusPanel,
231 },
232 []l.Widget{
233 // gel.EmptyMaxWidth(),
234 wg.StatusBarButton(
235 "console", 3, &p9icons.Terminal, func(name string) {
236 wg.MainApp.ActivePage(name)
237 }, a,
238 ),
239 wg.StatusBarButton(
240 "log", 4, &icons.ActionList, func(name string) {
241 D.Ln("click on button", name)
242 if wg.MainApp.MenuOpen {
243 wg.MainApp.MenuOpen = false
244 }
245 wg.MainApp.ActivePage(name)
246 }, a,
247 ),
248 wg.StatusBarButton(
249 "settings", 5, &icons.ActionSettings, func(name string) {
250 D.Ln("click on button", name)
251 if wg.MainApp.MenuOpen {
252 wg.MainApp.MenuOpen = false
253 }
254 wg.MainApp.ActivePage(name)
255 }, a,
256 ),
257 // wg.Inset(0.5, gel.EmptySpace(0, 0)).Fn,
258 },
259 )
260 // a.PushOverlay(wg.toasts.DrawToasts())
261 // a.PushOverlay(wg.dialog.DrawDialog())
262 return
263 }
264
265 func (wg *WalletGUI) Page(title string, widget gel.Widgets) func(gtx l.Context) l.Dimensions {
266 return func(gtx l.Context) l.Dimensions {
267 return wg.VFlex().
268 // SpaceEvenly().
269 Rigid(
270 wg.Responsive(
271 wg.Size.Load(), gel.Widgets{
272 // p9.WidgetSize{
273 // Widget: a.ButtonInset(0.25, a.H5(title).Color(wg.App.BodyColorGet()).Fn).Fn,
274 // },
275 gel.WidgetSize{
276 // Size: 800,
277 Widget: gel.EmptySpace(0, 0),
278 // a.ButtonInset(0.25, a.Caption(title).Color(wg.BodyColorGet()).Fn).Fn,
279 },
280 },
281 ).Fn,
282 ).
283 Flexed(
284 1,
285 wg.Inset(
286 0.25,
287 wg.Responsive(wg.Size.Load(), widget).Fn,
288 ).Fn,
289 ).Fn(gtx)
290 }
291 }
292
293 func (wg *WalletGUI) SideBarButton(title, page string, index int) func(gtx l.Context) l.Dimensions {
294 return func(gtx l.Context) l.Dimensions {
295 var scale float32
296 scale = gel.Scales["H6"]
297 var color string
298 background := "Transparent"
299 color = "DocText"
300 var ins float32 = 0.5
301 // var hl = false
302 if wg.MainApp.ActivePageGet() == page || wg.MainApp.PreRendering {
303 background = "PanelBg"
304 scale = gel.Scales["H6"]
305 color = "DocText"
306 // ins = 0.5
307 // hl = true
308 }
309 if title == " " {
310 scale = gel.Scales["H6"] / 2
311 }
312 max := int(wg.MainApp.SideBarSize.V)
313 if max > 0 {
314 gtx.Constraints.Max.X = max
315 gtx.Constraints.Min.X = max
316 }
317 // D.Ln("sideMAXXXXXX!!", max)
318 return wg.Direction().E().Embed(
319 wg.ButtonLayout(wg.sidebarButtons[index]).
320 CornerRadius(scale).Corners(0).
321 Background(background).
322 Embed(
323 wg.Inset(
324 ins,
325 func(gtx l.Context) l.Dimensions {
326 return wg.H5(title).
327 Color(color).
328 Alignment(text.End).
329 Fn(gtx)
330 },
331 ).Fn,
332 ).
333 SetClick(
334 func() {
335 if wg.MainApp.MenuOpen {
336 wg.MainApp.MenuOpen = false
337 }
338 wg.MainApp.ActivePage(page)
339 },
340 ).
341 Fn,
342 ).
343 Fn(gtx)
344 }
345 }
346
347 func (wg *WalletGUI) PageTopBarButton(
348 name string, index int, ico *[]byte, onClick func(string), app *gel.App,
349 highlightColor string,
350 ) func(gtx l.Context) l.Dimensions {
351 return func(gtx l.Context) l.Dimensions {
352 background := "Transparent"
353 // background := app.TitleBarBackgroundGet()
354 color := app.MenuColorGet()
355
356 if app.ActivePageGet() == name {
357 color = "PanelText"
358 // background = "scrim"
359 background = "PanelBg"
360 }
361 // if name == "home" {
362 // background = "scrim"
363 // }
364 if highlightColor != "" {
365 color = highlightColor
366 }
367 ic := wg.Icon().
368 Scale(gel.Scales["H5"]).
369 Color(color).
370 Src(ico).
371 Fn
372 return wg.Flex().Rigid(
373 // wg.ButtonInset(0.25,
374 wg.ButtonLayout(wg.buttonBarButtons[index]).
375 CornerRadius(0).
376 Embed(
377 wg.Inset(
378 0.375,
379 ic,
380 ).Fn,
381 ).
382 Background(background).
383 SetClick(func() { onClick(name) }).
384 Fn,
385 // ).Fn,
386 ).Fn(gtx)
387 }
388 }
389
390 func (wg *WalletGUI) StatusBarButton(
391 name string,
392 index int,
393 ico *[]byte,
394 onClick func(string),
395 app *gel.App,
396 ) func(gtx l.Context) l.Dimensions {
397 return func(gtx l.Context) l.Dimensions {
398 background := app.StatusBarBackgroundGet()
399 color := app.StatusBarColorGet()
400 if app.ActivePageGet() == name {
401 // background, color = color, background
402 background = "PanelBg"
403 // color = "Danger"
404 }
405 ic := wg.Icon().
406 Scale(gel.Scales["H5"]).
407 Color(color).
408 Src(ico).
409 Fn
410 return wg.Flex().
411 Rigid(
412 wg.ButtonLayout(wg.statusBarButtons[index]).
413 CornerRadius(0).
414 Embed(
415 wg.Inset(0.25, ic).Fn,
416 ).
417 Background(background).
418 SetClick(func() { onClick(name) }).
419 Fn,
420 ).Fn(gtx)
421 }
422 }
423
424 func (wg *WalletGUI) SetNodeRunState(b bool) {
425 go func() {
426 D.Ln("node run state is now", b)
427 if b {
428 wg.node.Start()
429 } else {
430 wg.node.Stop()
431 }
432 }()
433 }
434
435 func (wg *WalletGUI) SetWalletRunState(b bool) {
436 go func() {
437 D.Ln("node run state is now", b)
438 if b {
439 wg.wallet.Start()
440 } else {
441 wg.wallet.Stop()
442 }
443 }()
444 }
445
446 func (wg *WalletGUI) RunStatusPanel(gtx l.Context) l.Dimensions {
447 return func(gtx l.Context) l.Dimensions {
448 t, f := &p9icons.Link, &p9icons.LinkOff
449 var runningIcon *[]byte
450 if wg.node.Running() {
451 runningIcon = t
452 } else {
453 runningIcon = f
454 }
455 miningIcon := &p9icons.Mine
456 if !wg.miner.Running() {
457 miningIcon = &p9icons.NoMine
458 }
459 controllerIcon := &icons.NotificationSyncDisabled
460 if wg.cx.Config.Controller.True() {
461 controllerIcon = &icons.NotificationSync
462 }
463 discoverColor :=
464 "DocText"
465 discoverIcon :=
466 &icons.DeviceWiFiTethering
467 if wg.cx.Config.Discovery.False() {
468 discoverIcon =
469 &icons.CommunicationPortableWiFiOff
470 discoverColor =
471 "scrim"
472 }
473 clr := "scrim"
474 if wg.cx.Config.Controller.True() {
475 clr = "DocText"
476 }
477 clr2 := "DocText"
478 if wg.cx.Config.GenThreads.V() == 0 {
479 clr2 = "scrim"
480 }
481 // background := wg.App.StatusBarBackgroundGet()
482 color := wg.MainApp.StatusBarColorGet()
483 ic := wg.Icon().
484 Scale(gel.Scales["H5"]).
485 Color(color).
486 Src(&icons.NavigationRefresh).
487 Fn
488 return wg.Flex().AlignMiddle().
489 Rigid(
490 wg.ButtonLayout(wg.statusBarButtons[0]).
491 CornerRadius(0).
492 Embed(
493 wg.Inset(
494 0.25,
495 wg.Icon().
496 Scale(gel.Scales["H5"]).
497 Color("DocText").
498 Src(runningIcon).
499 Fn,
500 ).Fn,
501 ).
502 Background(wg.MainApp.StatusBarBackgroundGet()).
503 SetClick(
504 func() {
505 go func() {
506 D.Ln("clicked node run control button", wg.node.Running())
507 // wg.toggleNode()
508 wg.unlockPassword.Wipe()
509 wg.unlockPassword.Focus()
510 if wg.node.Running() {
511 if wg.wallet.Running() {
512 wg.WalletWatcher.Q()
513 }
514 wg.node.Stop()
515 wg.ready.Store(false)
516 wg.stateLoaded.Store(false)
517 wg.State.SetActivePage("home")
518 } else {
519 wg.node.Start()
520 // wg.ready.Store(true)
521 // wg.stateLoaded.Store(true)
522 }
523 }()
524 },
525 ).
526 Fn,
527 ).
528 Rigid(
529 wg.Inset(
530 0.33,
531 wg.Body1(fmt.Sprintf("%d", wg.State.bestBlockHeight.Load())).
532 Font("go regular").TextScale(gel.Scales["Caption"]).
533 Color("DocText").
534 Fn,
535 ).Fn,
536 ).
537 Rigid(
538 wg.ButtonLayout(wg.statusBarButtons[6]).
539 CornerRadius(0).
540 Embed(
541 wg.Inset(
542 0.25,
543 wg.Icon().
544 Scale(gel.Scales["H5"]).
545 Color(discoverColor).
546 Src(discoverIcon).
547 Fn,
548 ).Fn,
549 ).
550 Background(wg.MainApp.StatusBarBackgroundGet()).
551 SetClick(
552 func() {
553 go func() {
554 wg.cx.Config.Discovery.Flip()
555 _ = wg.cx.Config.WriteToFile(wg.cx.Config.ConfigFile.V())
556 I.Ln("discover enabled:",
557 wg.cx.Config.Discovery.True())
558 }()
559 },
560 ).
561 Fn,
562 ).
563 Rigid(
564 wg.Inset(
565 0.33,
566 wg.Caption(fmt.Sprintf("%d LAN %d", len(wg.otherNodes), wg.peerCount.Load())).
567 Font("go regular").
568 Color("DocText").
569 Fn,
570 ).Fn,
571 ).
572 Rigid(
573 wg.ButtonLayout(wg.statusBarButtons[7]).
574 CornerRadius(0).
575 Embed(
576 wg.
577 Inset(
578 0.25, wg.
579 Icon().
580 Scale(gel.Scales["H5"]).
581 Color(clr).
582 Src(controllerIcon).Fn,
583 ).Fn,
584 ).
585 Background(wg.MainApp.StatusBarBackgroundGet()).
586 SetClick(
587 func() {
588 if wg.ChainClient != nil && !wg.ChainClient.Disconnected() {
589 wg.cx.Config.Controller.Flip()
590 I.Ln("controller running:",
591 wg.cx.Config.Controller.True())
592 var e error
593 if e = wg.ChainClient.SetGenerate(
594 wg.cx.Config.Controller.True(),
595 wg.cx.Config.GenThreads.V(),
596 ); !E.Chk(e) {
597 }
598 }
599 // // wg.toggleMiner()
600 // go func() {
601 // if wg.miner.Running() {
602 // *wg.cx.Config.Generate = false
603 // wg.miner.Stop()
604 // } else {
605 // wg.miner.Start()
606 // *wg.cx.Config.Generate = true
607 // }
608 // save.Save(wg.cx.Config)
609 // }()
610 },
611 ).
612 Fn,
613 ).
614 Rigid(
615 wg.ButtonLayout(wg.statusBarButtons[1]).
616 CornerRadius(0).
617 Embed(
618 wg.Inset(
619 0.25, wg.
620 Icon().
621 Scale(gel.Scales["H5"]).
622 Color(clr2).
623 Src(miningIcon).Fn,
624 ).Fn,
625 ).
626 Background(wg.MainApp.StatusBarBackgroundGet()).
627 SetClick(
628 func() {
629 // wg.toggleMiner()
630 go func() {
631 if wg.cx.Config.GenThreads.V() != 0 {
632 if wg.miner.Running() {
633 wg.cx.Config.Generate.F()
634 wg.miner.Stop()
635 } else {
636 wg.miner.Start()
637 wg.cx.Config.Generate.T()
638 }
639 _ = wg.cx.Config.WriteToFile(wg.cx.Config.ConfigFile.V())
640 }
641 }()
642 },
643 ).
644 Fn,
645 ).
646 Rigid(
647 func(gtx l.Context) l.Dimensions {
648 return wg.incdecs["generatethreads"].
649 // Color("DocText").
650 // Background(wg.MainApp.StatusBarBackgroundGet()).
651 Fn(gtx)
652 },
653 ).
654 Rigid(
655 func(gtx l.Context) l.Dimensions {
656 if !wg.wallet.Running() {
657 return l.Dimensions{}
658 }
659
660 return wg.Flex().
661 Rigid(
662 wg.ButtonLayout(wg.statusBarButtons[2]).
663 CornerRadius(0).
664 Embed(
665 wg.Inset(0.25, ic).Fn,
666 ).
667 Background(wg.MainApp.StatusBarBackgroundGet()).
668 SetClick(
669 func() {
670 D.Ln("clicked reset wallet button")
671 go func() {
672 var e error
673 wasRunning := wg.wallet.Running()
674 D.Ln("was running", wasRunning)
675 if wasRunning {
676 wg.wallet.Stop()
677 }
678 args := []string{
679 os.Args[0],
680 "DD"+
681 wg.cx.Config.DataDir.V(),
682 "pipelog",
683 "walletpass"+
684 wg.cx.Config.WalletPass.V(),
685 "wallet",
686 "drophistory",
687 }
688 runner := exec.Command(args[0], args[1:]...)
689 runner.Stderr = os.Stderr
690 runner.Stdout = os.Stderr
691 if e = wg.writeWalletCookie(); E.Chk(e) {
692 }
693 if e = runner.Run(); E.Chk(e) {
694 }
695 if wasRunning {
696 wg.wallet.Start()
697 }
698 }()
699 },
700 ).
701 Fn,
702 ).Fn(gtx)
703 },
704 ).
705 Fn(gtx)
706 }(gtx)
707 }
708
709 func (wg *WalletGUI) writeWalletCookie() (e error) {
710 // for security with apps launching the wallet, the public password can be set with a file that is deleted after
711 walletPassPath := filepath.Join(wg.cx.Config.DataDir.V(), wg.cx.ActiveNet.Name, "wp.txt")
712 D.Ln("runner", walletPassPath)
713 b := wg.cx.Config.WalletPass.Bytes()
714 if e = ioutil.WriteFile(walletPassPath, b, 0700); E.Chk(e) {
715 }
716 D.Ln("created password cookie")
717 return
718 }
719
720 //
721 // func (wg *WalletGUI) toggleNode() {
722 // if wg.node.Running() {
723 // wg.node.Stop()
724 // *wg.cx.Config.NodeOff = true
725 // } else {
726 // wg.node.Start()
727 // *wg.cx.Config.NodeOff = false
728 // }
729 // save.Save(wg.cx.Config)
730 // }
731 //
732 // func (wg *WalletGUI) startNode() {
733 // if !wg.node.Running() {
734 // wg.node.Start()
735 // }
736 // D.Ln("startNode")
737 // }
738 //
739 // func (wg *WalletGUI) stopNode() {
740 // if wg.wallet.Running() {
741 // wg.stopWallet()
742 // wg.unlockPassword.Wipe()
743 // // wg.walletLocked.Store(true)
744 // }
745 // if wg.node.Running() {
746 // wg.node.Stop()
747 // }
748 // D.Ln("stopNode")
749 // }
750 //
751 // func (wg *WalletGUI) toggleMiner() {
752 // if wg.miner.Running() {
753 // wg.miner.Stop()
754 // *wg.cx.Config.Generate = false
755 // }
756 // if !wg.miner.Running() && *wg.cx.Config.GenThreads > 0 {
757 // wg.miner.Start()
758 // *wg.cx.Config.Generate = true
759 // }
760 // save.Save(wg.cx.Config)
761 // }
762 //
763 // func (wg *WalletGUI) startMiner() {
764 // if *wg.cx.Config.GenThreads == 0 && wg.miner.Running() {
765 // wg.stopMiner()
766 // D.Ln("was zero threads")
767 // } else {
768 // wg.miner.Start()
769 // D.Ln("startMiner")
770 // }
771 // }
772 //
773 // func (wg *WalletGUI) stopMiner() {
774 // if wg.miner.Running() {
775 // wg.miner.Stop()
776 // }
777 // D.Ln("stopMiner")
778 // }
779 //
780 // func (wg *WalletGUI) toggleWallet() {
781 // if wg.wallet.Running() {
782 // wg.stopWallet()
783 // *wg.cx.Config.WalletOff = true
784 // } else {
785 // wg.startWallet()
786 // *wg.cx.Config.WalletOff = false
787 // }
788 // save.Save(wg.cx.Config)
789 // }
790 //
791 // func (wg *WalletGUI) startWallet() {
792 // if !wg.node.Running() {
793 // wg.startNode()
794 // }
795 // if !wg.wallet.Running() {
796 // wg.wallet.Start()
797 // wg.unlockPassword.Wipe()
798 // // wg.walletLocked.Store(false)
799 // }
800 // D.Ln("startWallet")
801 // }
802 //
803 // func (wg *WalletGUI) stopWallet() {
804 // if wg.wallet.Running() {
805 // wg.wallet.Stop()
806 // // wg.unlockPassword.Wipe()
807 // // wg.walletLocked.Store(true)
808 // }
809 // wg.unlockPassword.Wipe()
810 // D.Ln("stopWallet")
811 // }
812