func initGUI() { /* ff := ui.ListFontFamilies() for i := 0; i < ff.NumFamilies(); i++ { log.Printf("%3d. Font family '%s'\n", i + 1, ff.Family(i)) } */ window := ui.NewWindow("Привет мир!", 800, 480, false) window.SetMargined(true) progress := ui.NewProgressBar() labelTime := ui.NewLabel("") labelInfo := ui.NewLabel("Info") labelInfoButtonHandler := func(b *ui.Button) { labelInfo.SetText("Click button " + b.Text()) } hbox := ui.NewHorizontalBox() hbox.SetPadded(true) hbox.Append(func() *ui.Box { box := ui.NewVerticalBox() box.SetPadded(true) box.Append(func() *ui.Button { button := ui.NewButton("Button 1") button.OnClicked(labelInfoButtonHandler) return button }(), false) box.Append(func() *ui.Button { button := ui.NewButton("Button 2") button.OnClicked(labelInfoButtonHandler) return button }(), false) box.Append(func() *ui.Button { button := ui.NewButton("Button 3") button.OnClicked(labelInfoButtonHandler) return button }(), false) box.Append(ui.NewHorizontalSeparator(), false) label := ui.NewLabel("It's all") box.Append(label, true) box.Append(func() *ui.Button { button := ui.NewButton("Exit") button.OnClicked(func(*ui.Button) { ui.Quit() }) return button }(), false) return box }(), false) areaHandler := NewHistogramAreaHandler(20) area := ui.NewArea(areaHandler) hbox.Append(func() *ui.Box { box := ui.NewVerticalBox() box.SetPadded(true) box.Append(labelInfo, false) box.Append(labelTime, false) tab := ui.NewTab() tab.Append("Histogram demo", area) tab.Append("Controls demo", func() *ui.Box { box := ui.NewVerticalBox() box.SetPadded(true) box.Append(ui.NewEntry(), false) box.Append(ui.NewCheckbox("Check it"), false) box.Append(func() *ui.RadioButtons { radio := ui.NewRadioButtons() radio.Append("Radio button 1") radio.Append("Radio button 2") radio.Append("Radio button 3") return radio }(), false) box.Append(func() *ui.Group { combo := ui.NewCombobox() combo.Append("First") combo.Append("Second") combo.Append("Third") combo.Append("Fourth") combo.OnSelected(func(cb *ui.Combobox) { ui.MsgBoxError(window, "OnSelected", "Line #"+strconv.Itoa(cb.Selected()+1)) }) group := ui.NewGroup("Can't get text, only index") group.SetChild(combo) return group }(), false) box.Append(ui.NewSlider(0, 100), false) box.Append(ui.NewSpinbox(0, 10), false) box.Append(ui.NewDatePicker(), false) box.Append(ui.NewDateTimePicker(), false) return box }()) tab.Append("Tab 3", ui.NewLabel("At tab 3")) box.Append(tab, true) box.Append(progress, false) return box }(), true) window.SetChild(hbox) window.OnClosing(func(*ui.Window) bool { log.Println("Window close") ui.Quit() return true }) window.Show() progressCounter := 0 progressTicker := time.NewTicker(time.Millisecond * 50) go func() { for _ = range progressTicker.C { // Что бы записать значение в виджет используем потокобезопасный вызов ui.QueueMain(func() { progress.SetValue(progressCounter) }) progressCounter++ if progressCounter > 100 { progressCounter = 0 } } }() timeTicker := time.NewTicker(time.Millisecond * 10) go func() { for t := range timeTicker.C { // Что бы записать значение в виджет используем потокобезопасный вызов ui.QueueMain(func() { labelTime.SetText(t.Format(time.StampMilli)) }) } }() hystogrammTicker := time.NewTicker(time.Millisecond * 500) go func() { for _ = range hystogrammTicker.C { // Что бы записать значение в виджет используем потокобезопасный вызов ui.QueueMain(func() { areaHandler.Push(rand.Intn(100)) area.QueueRedrawAll() }) } }() log.Println("InitGUI done") }
// showMessageBoxForNotification shows a generic dialog with the supplied title and bodyText func showMessageBoxForNotification(title string, bodyText string, window *ui.Window) { ui.MsgBoxError(window, title, bodyText) }
// showMessageBoxForErrors shows an error dialog where its body consists of errors converted to strings func showMessageBoxForErrors(title string, errors []error, window *ui.Window) { ui.MsgBoxError(window, title, convertErrorStringListToString(errors)) }
func myMain() { var cmd *exec.Cmd var timer *time.Timer var timerChan <-chan time.Time var w *ui.Window status := ui.NewLabel("") stop := func() { if cmd != nil { // stop the command if it's running err := cmd.Process.Kill() if err != nil { ui.MsgBoxError(w, fmt.Sprintf("Error killing process: %v", err), "You may need to kill it manually.") } err = cmd.Process.Release() if err != nil { ui.MsgBoxError(w, fmt.Sprintf("Error releasing process: %v", err), "") } cmd = nil } if timer != nil { // stop the timer if we started it timer.Stop() timer = nil timerChan = nil } status.SetText("") } w = ui.NewWindow("wakeup", 400, 100) ui.AppQuit = w.Closing // treat application close as main window close cmdbox := ui.NewLineEdit(defCmdLine) timebox := ui.NewLineEdit(defTime) bStart := ui.NewButton("Start") bStop := ui.NewButton("Stop") // a Stack to keep both buttons at the same size btnbox := ui.NewHorizontalStack(bStart, bStop) btnbox.SetStretchy(0) btnbox.SetStretchy(1) // and a Stack around that Stack to keep them at a reasonable size, with space to their right btnbox = ui.NewHorizontalStack(btnbox, status) // the main layout grid := ui.NewGrid(2, ui.NewLabel("Command"), cmdbox, ui.NewLabel("Time"), timebox, ui.Space(), ui.Space(), // the Space on the right will consume the window blank space ui.Space(), btnbox) grid.SetStretchy(2, 1) // make the Space noted above consume grid.SetFilling(0, 1) // make the two textboxes grow horizontally grid.SetFilling(1, 1) w.Open(grid) mainloop: for { select { case <-w.Closing: break mainloop case <-bStart.Clicked: stop() // only one alarm at a time alarmTime, err := time.Parse(timeFmt, timebox.Text()) if err != nil { ui.MsgBoxError(w, fmt.Sprintf("Error parsing time %q: %v", timebox.Text(), err), fmt.Sprintf("Make sure your time is in the form %q (without quotes).", timeFmt)) continue } now := time.Now() later := bestTime(now, alarmTime) timer = time.NewTimer(later.Sub(now)) timerChan = timer.C status.SetText("Started") case <-timerChan: cmd = exec.Command("/bin/sh", "-c", "exec "+cmdbox.Text()) // keep stdin /dev/null in case user wants to run multiple alarms on one instance (TODO should I allow this program to act as a pipe?) // keep stdout /dev/null to avoid stty mucking cmd.Stderr = os.Stderr err := cmd.Start() status.SetText("Firing") if err != nil { ui.MsgBoxError(w, fmt.Sprintf("Error running program: %v", err), "") cmd = nil status.SetText("") } timer = nil timerChan = nil case <-bStop.Clicked: stop() } } // clean up stop() }