Layout

Basic layout with GTK+-based applications uses a familiar vertical and horizontal box model. Go-GTK (as a straightforward binding to this API) exposes this same functionality. We lay out the GoMail main window using a vertical box to position the menu and toolbar above the main content. Our main content is then a horizontally split pane created with gtk.NewHPaned() (where H refers to the horizontal layout, not the bar orientation, which is vertical). Before looking at the details, here's the basic layout code for the main window. The toolbar and menu creation code is omitted for brevity but can be found in the example code repository:

package main

import "github.com/mattn/go-gtk/gtk"

const padding = 3

func main() {
gtk.Init(nil)
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
window.SetTitle("GoMail")
window.Connect("destroy", func() {
gtk.MainQuit()
})

list := gtk.NewTreeView()
list.AppendColumn(gtk.NewTreeViewColumnWithAttributes("Inbox", gtk.NewCellRendererText(), "text", 0))
meta := gtk.NewHBox(false, padding)

labels := gtk.NewVBox(true, padding)
labels.Add(gtk.NewLabel("To"))
labels.Add(gtk.NewLabel("From"))
labels.Add(gtk.NewLabel("Date"))
values := gtk.NewVBox(true, padding)
values.Add(gtk.NewLabel("email"))
values.Add(gtk.NewLabel("email"))
values.Add(gtk.NewLabel("date"))
meta.Add(labels)
meta.Add(values)

content := gtk.NewTextView()
content.GetBuffer().SetText("email content")
content.SetEditable(false)

detail := gtk.NewVBox(false, padding)
detail.PackStart(gtk.NewLabel("subject"), false, true, 0)
detail.PackStart(meta, false, true, 0)
detail.Add(content)

split := gtk.NewHPaned()
split.Add1(list)
split.Add2(detail)

vbox := gtk.NewVBox(false, padding)
vbox.PackStart(buildMenu(), false, true, 0)
vbox.PackStart(buildToolbar(), false, true, 0)
vbox.Add(split)

window.Add(vbox)
window.SetBorderWidth(padding)
window.Resize(600, 400)
window.ShowAll()
gtk.Main()
}

There are two things of note in this code. First is the padding constant defined at the top of the file. The box model doesn't define a standard spacing and so we pass this constant each time the layout requires some visual padding. The second important lesson is the difference between the Add(IWidget) and PackStart(IWidget, bool, bool, uint) methods on the boxes. The Add method simply appends the widget to the container (gtk.Box inherits from gtk.Container) and it'll cause the child to expand to fill the space available. For a menu bar and toolbar, we don't desire a vertical expansion so we use the PackStart method, which allows more control over behavior. The first Boolean parameter controls expansion; by passing false, we instruct the container that the widget shouldn't take up any free space.

The second Boolean controls fill and states whether or not the widget should fill any space available after any space calculations have been performed, so passing true specifies that our toolbar should be full width. In gtk.VBox, the expand parameter refers to vertical stretch and the fill applies to horizontal. 

We also need to add some content to the list view, which requires the creation of a model to represent the content we will present. As the content will be a single column with no parent/child relationship, we can use gtk.ListStore, rather than the more complex gtk.TreeStore. The way that content is set into a model is by using an iterator and applying values to each row of data. For the purpose of this layout, we add email1 and email2 to the 0th (first) column of the view:

   model := gtk.NewListStore(gtk.TYPE_STRING)
list.SetModel(model)

var iter gtk.TreeIter
model.Append(&iter)
model.SetValue(&iter, 0, "email1")
model.Append(&iter)
model.SetValue(&iter, 0, "email2")

The toolbar API is simple to use and, by utilizing the stock icons included in GTK+, provides standard icons for many common actions. As some of our buttons are non-standard (Reply and Reply All), we set the toolbar style to show icons and labels; later, we can add some custom icons. Each item can have its action set using the OnClicked() function or by connecting the clicked signal:

   toolbar := gtk.NewToolbar()
toolbar.SetStyle(gtk.TOOLBAR_BOTH)
item := gtk.NewToolButtonFromStock(gtk.STOCK_NEW)
item.OnClicked(showCompose)
toolbar.Add(item)

The rest of the icons can be added similarly. The menu code is slightly more complicated; each drop-down menu (whether a sub-menu or a main menu) needs to be created with gtk.NewMenu(), and its items added as shown. Each top-level menu then needs to have a new menu item created (for example, gtk.NewMenuItemWithLabel()) and the menu connected using SetSubmenu(). The constructed menu can then be appended to the menu bar:

menubar := gtk.NewMenuBar()
fileMenu := gtk.NewMenuItemWithLabel("File")

menu := gtk.NewMenu()
item := gtk.NewMenuItemWithLabel("New")
item.Connect("activate", showCompose)
menu.Append(item)

fileMenu.SetSubmenu(menu)
menubar.Append(fileMenu)

With all of this code in place (and a few more items in the toolbar and menu), we have a basic application layout that should look familiar. As you can see, we are already benefiting from the additional features of a larger widget toolkit with standard icons and more complete styling and layouts:

The basic layout of GoMail using Go-GTK before we make any style adjustments

The layout, particularly of the email details panel, can be improved using label.SetAlignment(0, 0) to set a left alignment, and the content of a label can be made bold by using the markup capability of the pango library; just call label.SetMarkup(fmt.Sprintf("<b>%s</b>", label.GetText())). The preceding code was focused on the basic layout, so these tweaks have been left out. The additional details are included in the example code repository and the completed interface can be seen in the later section about themes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.218.221