// Creates the tab for the specified song. Calls updateLabels and updateCover // with the create argument to true. Defines two grids : igrid and ogrid // igrid contains all the labels // ogrid groups the area containing the image handler and the igrid func (s *song) createTab() { s.generateLabels(true) s.generateCover(true) // Inside Grid igrid := ui.NewGrid() igrid.Add(s.title, nil, ui.South, false, ui.LeftTop, false, ui.LeftTop, 1, 1) igrid.Add(s.album, nil, ui.South, false, ui.LeftTop, false, ui.LeftTop, 1, 1) igrid.Add(s.artist, nil, ui.South, false, ui.LeftTop, false, ui.LeftTop, 1, 1) igrid.Add(s.year, nil, ui.South, false, ui.LeftTop, false, ui.LeftTop, 1, 1) // Outside Grid ogrid := ui.NewGrid() ogrid.Add(ui.NewArea(100, 100, &areaHandler{s.cover}), nil, ui.South, false, ui.LeftTop, true, ui.LeftTop, 1, 1) ogrid.Add(igrid, nil, ui.East, false, ui.LeftTop, true, ui.LeftTop, 1, 1) s.stack = ui.NewVerticalStack(ogrid) }
func gui() { //Define endpoint apiEndpointLabel := ui.NewLabel("API Endpoint:") apiEndpointTextField := ui.NewTextField() if len(os.Getenv("CARINA_API_ENDPOINT")) > 0 { apiEndpointTextField.SetText(os.Getenv("CARINA_API_ENDPOINT")) } else { apiEndpointTextField.SetText(libcarina.BetaEndpoint) } //Define credentials area usernameLabel := ui.NewLabel("Username:"******"CARINA_USERNAME")) > 0 { usernameTextField.SetText(os.Getenv("CARINA_USERNAME")) } apiKeyLabel := ui.NewLabel("API Key:") apiKeyTextField := ui.NewPasswordField() if len(os.Getenv("CARINA_APIKEY")) > 0 { apiKeyTextField.SetText(os.Getenv("CARINA_APIKEY")) } connectBtn := ui.NewButton("Connect") // layout the login controls on a grid loginGrid := ui.NewGrid() loginGrid.Add(apiEndpointLabel, nil, ui.East, true, ui.LeftTop, false, ui.Center, 1, 1) loginGrid.Add(apiEndpointTextField, apiEndpointLabel, ui.South, true, ui.Fill, false, ui.Center, 1, 1) loginGrid.Add(usernameLabel, apiEndpointLabel, ui.East, true, ui.LeftTop, false, ui.Center, 1, 1) loginGrid.Add(usernameTextField, usernameLabel, ui.South, true, ui.Fill, false, ui.Center, 1, 1) loginGrid.Add(apiKeyLabel, usernameLabel, ui.East, true, ui.LeftTop, false, ui.Center, 1, 1) loginGrid.Add(apiKeyTextField, apiKeyLabel, ui.South, true, ui.Fill, false, ui.Center, 1, 1) loginGrid.Add(connectBtn, nil, ui.East, true, ui.LeftTop, false, ui.Center, 1, 1) loginGrid.SetPadded(true) //div grp1 divGrp1 := ui.NewGroup("", ui.Space()) divGrp1.SetMargined(true) // Define the table that lists all running clusters var c libcarina.Cluster clusterListTable := ui.NewTable(reflect.TypeOf(c)) // Create control buttons newBtn := ui.NewButton("New") growBtn := ui.NewButton("Grow") rebuildBtn := ui.NewButton("Rebuild") credentialsBtn := ui.NewButton("Credentials") deleteBtn := ui.NewButton("Delete") buttonStack := ui.NewVerticalStack(newBtn, growBtn, rebuildBtn, credentialsBtn, deleteBtn) //div grp2 divGrp2 := ui.NewGroup("", ui.Space()) divGrp2.SetMargined(true) //Show containers on the cluster containerListLabel := ui.NewLabel("Containers") var cont dockerclient.Container containerListTable := ui.NewTable(reflect.TypeOf(cont)) mainGrid := ui.NewGrid() mainGrid.Add(loginGrid, nil, ui.East, true, ui.Fill, false, ui.Center, 12, 1) mainGrid.Add(divGrp1, loginGrid, ui.South, true, ui.Fill, false, ui.Center, 12, 1) mainGrid.Add(clusterListTable, divGrp1, ui.South, true, ui.Fill, false, ui.Center, 9, 1) mainGrid.Add(buttonStack, clusterListTable, ui.East, true, ui.Fill, false, ui.Center, 3, 1) mainGrid.Add(divGrp2, clusterListTable, ui.South, true, ui.Fill, false, ui.Center, 12, 1) mainGrid.Add(containerListLabel, divGrp2, ui.South, true, ui.Fill, false, ui.Center, 12, 1) mainGrid.Add(containerListTable, containerListLabel, ui.South, true, ui.Fill, false, ui.Center, 12, 1) mainGrid.SetPadded(true) connectBtn.OnClicked(func() { connect(apiEndpointTextField.Text(), usernameTextField.Text(), apiKeyTextField.Text()) go monitorClusterList(clusterListTable) }) clusterListTable.OnSelected(func() { c, found := getSelectedCluster(clusterListTable) if found { if c.Status == "active" { containers := getContainers(c.ClusterName) containerListTable.Lock() d := containerListTable.Data().(*[]dockerclient.Container) *d = containers containerListTable.Unlock() txt := fmt.Sprintf("%d containers running on %s cluster", len(containers), c.ClusterName) containerListLabel.SetText(txt) } } }) newBtn.OnClicked(func() { if loggedInFlag { newCluster() } }) deleteBtn.OnClicked(func() { c, found := getSelectedCluster(clusterListTable) if found { carinaClient.Delete(c.ClusterName) fmt.Println("Deleting", c.ClusterName) } }) rebuildBtn.OnClicked(func() { c, found := getSelectedCluster(clusterListTable) if found { fmt.Println("Rebuiding", c.ClusterName) carinaClient.Rebuild(c.ClusterName) } }) credentialsBtn.OnClicked(func() { c, found := getSelectedCluster(clusterListTable) if found { fmt.Println("Getting credentials for", c.ClusterName) carinaClient.GetCredentials(c.ClusterName) } }) growBtn.OnClicked(func() { c, found := getSelectedCluster(clusterListTable) if found { fmt.Println("Growing", c.ClusterName) } }) //Main stack of the interfaces w = ui.NewWindow("Carina by Rackspace GUI Client ("+VERSION+")", 620, 300, mainGrid) w.SetMargined(true) w.OnClosing(func() bool { ui.Stop() return true }) w.Show() }
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() }