// Setup the TextView, put it in a ScrolledWindow, and add both to box. func setupTextView(box *gtk.Box) *gtk.TextView { sw, _ := gtk.ScrolledWindowNew(nil, nil) tv, _ := gtk.TextViewNew() sw.Add(tv) box.PackStart(sw, true, true, 0) return tv }
func (ui *Ui) initDevicesList() *gtk.ScrolledWindow { scroller, _ := gtk.ScrolledWindowNew(nil, nil) scroller.SetSizeRequest(sidebarWidth, -1) list, _ := gtk.ListBoxNew() scroller.Add(list) ui.devicesList = list list.Connect("row-selected", func(box *gtk.ListBox, row *gtk.ListBoxRow) { index := row.GetIndex() for deviceId, r := range ui.devicesRows { if index == r.GetIndex() { ui.selectDevice(ui.devices[deviceId]) return } } }) return scroller }
func createRecvCoins() *gtk.Widget { store, err := gtk.ListStoreNew(glib.TYPE_STRING, glib.TYPE_STRING) if err != nil { log.Fatal(err) } RecvCoins.Store = store tv, err := gtk.TreeViewNewWithModel(store) if err != nil { log.Fatal(err) } RecvCoins.Treeview = tv renderer, err := gtk.CellRendererTextNew() if err != nil { log.Fatal(err) } renderer.Set("editable", true) renderer.Set("editable-set", true) renderer.Connect("edited", func(_ *glib.Object, path, text string) { iter, err := store.GetIterFromString(path) if err == nil { store.Set(iter, []int{0}, []interface{}{text}) } }) col, err := gtk.TreeViewColumnNewWithAttribute("Label", renderer, "text", 0) if err != nil { log.Fatal(err) } col.SetExpand(true) tv.AppendColumn(col) cr, err := gtk.CellRendererTextNew() if err != nil { log.Fatal(err) } col, err = gtk.TreeViewColumnNewWithAttribute("Address", cr, "text", 1) if err != nil { log.Fatal(err) } col.SetMinWidth(350) tv.AppendColumn(col) newAddr, err := gtk.ButtonNewWithLabel("New Address") if err != nil { log.Fatal(err) } newAddr.SetSizeRequest(150, -1) newAddr.Connect("clicked", func() { go func() { triggers.newAddr <- 1 reply := <-triggerReplies.newAddr if err, ok := reply.(error); ok { glib.IdleAdd(func() { mDialog := errorDialog("New address generation failed", err.Error()) mDialog.Run() mDialog.Destroy() }) } else if addr, ok := reply.(string); ok { glib.IdleAdd(func() { iter := RecvCoins.Store.Append() RecvCoins.Store.Set(iter, []int{0, 1}, []interface{}{"", addr}) }) } }() }) newAddr.SetSensitive(false) RecvCoins.NewAddrBtn = newAddr buttons, err := gtk.GridNew() if err != nil { log.Fatal(err) } buttons.Add(newAddr) cpyAddr, err := gtk.ButtonNewWithLabel("Copy Address") if err != nil { log.Fatal(err) } cpyAddr.SetSizeRequest(150, -1) cpyAddr.Connect("clicked", func() { sel, err := tv.GetSelection() if err != nil { log.Fatal(err) } var iter gtk.TreeIter if sel.GetSelected(nil, &iter) { val, err := store.GetValue(&iter, 1) if err != nil { log.Fatal(err) } display, err := gdk.DisplayGetDefault() if err != nil { log.Fatal(err) } clipboard, err := gtk.ClipboardGetForDisplay( display, gdk.SELECTION_CLIPBOARD) if err != nil { log.Fatal(err) } primary, err := gtk.ClipboardGetForDisplay( display, gdk.SELECTION_PRIMARY) if err != nil { log.Fatal(err) } s, _ := val.GetString() clipboard.SetText(s) primary.SetText(s) } }) buttons.Add(cpyAddr) sw, err := gtk.ScrolledWindowNew(nil, nil) if err != nil { log.Fatal(err) } sw.Add(tv) sw.SetPolicy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) sw.SetHExpand(true) sw.SetVExpand(true) grid, err := gtk.GridNew() if err != nil { log.Fatal(err) } grid.SetOrientation(gtk.ORIENTATION_VERTICAL) grid.Add(sw) grid.Add(buttons) return &grid.Container.Widget }
func windowWidget() *gtk.Widget { grid, err := gtk.GridNew() if err != nil { log.Fatal("Unable to create grid:", err) } grid.SetOrientation(gtk.ORIENTATION_VERTICAL) // Just as a demonstration, we create and destroy a Label without ever // adding it to a container. In native GTK, this would result in a // memory leak, since gtk_widget_destroy() will not deallocate any // memory when passed a GtkWidget with a floating reference. // // gotk3 handles this situation by always sinking floating references // of any struct type embedding a glib.InitiallyUnowned, and by setting // a finalizer to unreference the object when Go has lost scope of the // variable. Due to this design, widgets may be allocated freely // without worrying about handling memory incorrectly. // // The following code is not entirely useful (except to demonstrate // this point), but it is also not "incorrect" as the C equivalent // would be. unused, err := gtk.LabelNew("This label is never used") if err != nil { // Calling Destroy() is also unnecessary in this case. The // memory will still be freed with or without calling it. unused.Destroy() } sw, err := gtk.ScrolledWindowNew(nil, nil) if err != nil { log.Fatal("Unable to create scrolled window:", err) } grid.Attach(sw, 0, 0, 2, 1) sw.SetHExpand(true) sw.SetVExpand(true) labelsGrid, err := gtk.GridNew() if err != nil { log.Fatal("Unable to create grid:", err) } labelsGrid.SetOrientation(gtk.ORIENTATION_VERTICAL) sw.Add(labelsGrid) labelsGrid.SetHExpand(true) insertBtn, err := gtk.ButtonNewWithLabel("Add a label") if err != nil { log.Fatal("Unable to create button:", err) } removeBtn, err := gtk.ButtonNewWithLabel("Remove a label") if err != nil { log.Fatal("Unable to create button:", err) } nLabels := 1 insertBtn.Connect("clicked", func() { var s string if nLabels == 1 { s = fmt.Sprintf("Inserted %d label.", nLabels) } else { s = fmt.Sprintf("Inserted %d labels.", nLabels) } label, err := gtk.LabelNew(s) if err != nil { log.Print("Unable to create label:", err) return } labelList.PushBack(label) labelsGrid.Add(label) label.SetHExpand(true) labelsGrid.ShowAll() nLabels++ }) removeBtn.Connect("clicked", func() { e := labelList.Front() if e == nil { log.Print("Nothing to remove") return } lab, ok := labelList.Remove(e).(*gtk.Label) if !ok { log.Print("Element to remove is not a *gtk.Label") return } // (*Widget).Destroy() breaks this label's reference with all // other objects (in this case, the Grid container it was added // to). lab.Destroy() // At this point, only Go retains a reference to the GtkLabel. // When the lab variable goes out of scope when this function // returns, at the next garbage collector run, a finalizer will // be run to perform the final unreference and free the widget. }) grid.Attach(insertBtn, 0, 1, 1, 1) grid.Attach(removeBtn, 1, 1, 1, 1) return &grid.Container.Widget }
func createAddrBook() *gtk.Widget { grid, err := gtk.GridNew() if err != nil { log.Fatal(err) } grid.SetOrientation(gtk.ORIENTATION_VERTICAL) store, err := gtk.ListStoreNew(glib.TYPE_STRING, glib.TYPE_STRING) if err != nil { log.Fatal(err) } tv, err := gtk.TreeViewNew() if err != nil { log.Fatal(err) } tv.SetModel(store) addrBookWidgets.store = store addrBookWidgets.treeview = tv sw, err := gtk.ScrolledWindowNew(nil, nil) if err != nil { log.Fatal(err) } sw.Add(tv) sw.SetPolicy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) sw.SetHExpand(true) sw.SetVExpand(true) grid.Add(sw) renderer, err := gtk.CellRendererTextNew() if err != nil { log.Fatal(err) } renderer.Set("editable", true) renderer.Set("editable-set", true) renderer.Connect("edited", func(_ *glib.Object, path, text string) { iter, err := store.GetIterFromString(path) if err == nil { store.Set(iter, []int{0}, []interface{}{text}) } }) col, err := gtk.TreeViewColumnNewWithAttribute("Label", renderer, "text", 0) if err != nil { log.Fatal(err) } col.SetExpand(true) tv.AppendColumn(col) renderer, err = gtk.CellRendererTextNew() if err != nil { log.Fatal(err) } renderer.Set("editable", true) renderer.Set("editable-set", true) renderer.Connect("edited", func(_ *glib.Object, path, text string) { iter, err := store.GetIterFromString(path) if err == nil { // TODO(jrick): verify this is a valid address store.Set(iter, []int{1}, []interface{}{text}) } }) col, err = gtk.TreeViewColumnNewWithAttribute("Address", renderer, "text", 1) if err != nil { log.Fatal(err) } col.SetMinWidth(350) tv.AppendColumn(col) // put in an example address iter := store.Append() store.Set(iter, []int{0, 1}, []interface{}{"editable label", "01234567890"}) buttons, err := gtk.GridNew() if err != nil { log.Fatal(err) } newAddr, err := gtk.ButtonNewWithLabel("New Address") if err != nil { log.Fatal(err) } newAddr.SetSizeRequest(150, -1) newAddr.Connect("clicked", func() { iter := store.Append() store.Set(iter, []int{0, 1}, []interface{}{"", "new address"}) }) buttons.Add(newAddr) cpyAddr, err := gtk.ButtonNewWithLabel("Copy Address") if err != nil { log.Fatal(err) } cpyAddr.SetSizeRequest(150, -1) cpyAddr.Connect("clicked", func() { sel, err := tv.GetSelection() if err != nil { log.Fatal(err) } var iter gtk.TreeIter if sel.GetSelected(nil, &iter) { val, err := store.GetValue(&iter, 1) if err != nil { log.Fatal(err) } display, err := gdk.DisplayGetDefault() if err != nil { log.Fatal(err) } clipboard, err := gtk.ClipboardGetForDisplay( display, gdk.SELECTION_CLIPBOARD) if err != nil { log.Fatal(err) } primary, err := gtk.ClipboardGetForDisplay( display, gdk.SELECTION_PRIMARY) if err != nil { log.Fatal(err) } s, _ := val.GetString() clipboard.SetText(s) primary.SetText(s) } }) buttons.Add(cpyAddr) grid.Add(buttons) return &grid.Container.Widget }
func createTransactions() *gtk.Widget { sw, err := gtk.ScrolledWindowNew(nil, nil) if err != nil { log.Fatal(err) } store, err := gtk.ListStoreNew(glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_STRING) if err != nil { log.Fatal(err) } tv, err := gtk.TreeViewNew() if err != nil { log.Fatal(err) } tv.SetModel(store) tv.SetHExpand(true) tv.SetVExpand(true) txWidgets.store = store txWidgets.treeview = tv sw.Add(tv) cr, err := gtk.CellRendererTextNew() if err != nil { log.Fatal(err) } col, err := gtk.TreeViewColumnNewWithAttribute("Date", cr, "text", 0) if err != nil { log.Fatal(err) } tv.AppendColumn(col) cr, err = gtk.CellRendererTextNew() if err != nil { log.Fatal(err) } col, err = gtk.TreeViewColumnNewWithAttribute("Type", cr, "text", 1) if err != nil { log.Fatal(err) } tv.AppendColumn(col) cr, err = gtk.CellRendererTextNew() if err != nil { log.Fatal(err) } col, err = gtk.TreeViewColumnNewWithAttribute("Address", cr, "text", 2) if err != nil { log.Fatal(err) } col.SetExpand(true) tv.AppendColumn(col) cr, err = gtk.CellRendererTextNew() if err != nil { log.Fatal(err) } col, err = gtk.TreeViewColumnNewWithAttribute("Amount", cr, "text", 3) if err != nil { log.Fatal(err) } tv.AppendColumn(col) return &sw.Bin.Container.Widget }
func createSendCoins() *gtk.Widget { grid, err := gtk.GridNew() if err != nil { log.Fatal(err) } grid.SetOrientation(gtk.ORIENTATION_VERTICAL) sw, err := gtk.ScrolledWindowNew(nil, nil) if err != nil { log.Fatal(err) } sw.SetPolicy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) sw.SetHExpand(true) sw.SetVExpand(true) grid.Add(sw) entriesGrid, err := gtk.GridNew() if err != nil { log.Fatal(err) } SendCoins.EntryGrid = entriesGrid entriesGrid.SetOrientation(gtk.ORIENTATION_VERTICAL) sw.Add(entriesGrid) insertSendEntries(entriesGrid) bot, err := gtk.GridNew() if err != nil { log.Fatal(err) } btn, err := gtk.ButtonNewWithLabel("Add Recipient") if err != nil { log.Fatal(err) } btn.SetSizeRequest(150, -1) btn.Connect("clicked", func() { insertSendEntries(entriesGrid) }) bot.Add(btn) l, err := gtk.LabelNew("Balance: ") if err != nil { log.Fatal(err) } bot.Add(l) SendCoins.Balance = l submitBtn, err := gtk.ButtonNewWithLabel("Send") if err != nil { log.Fatal(err) } submitBtn.SetSizeRequest(150, -1) submitBtn.SetHAlign(gtk.ALIGN_END) submitBtn.SetHExpand(true) submitBtn.SetSensitive(false) submitBtn.Connect("clicked", func() { sendTo := make(map[string]float64) for e := recipients.Front(); e != nil; e = e.Next() { r := e.Value.(*recipient) // Get and validate address addr, err := r.payTo.GetText() if err != nil { d := errorDialog("Error getting payment address", err.Error()) d.Run() d.Destroy() return } _, net, err := btcutil.DecodeAddress(addr) if err != nil { d := errorDialog("Invalid payment address", fmt.Sprintf("'%v' is not a valid payment address", addr)) d.Run() d.Destroy() return } switch net { case btcwire.MainNet: if !cfg.MainNet { d := errorDialog("Invalid payment address", fmt.Sprintf("'%v' is a mainnet address", addr)) d.Run() d.Destroy() return } case btcwire.TestNet3: if cfg.MainNet { d := errorDialog("Invalid payment address", fmt.Sprintf("'%v' is a testnet address", addr)) d.Run() d.Destroy() return } } // Get amount and units and convert to float64 amt := r.amount.GetValue() // Combo box isn't used right now. /* switch r.combo.GetActive() { case 0: // BTC // nothing case 1: // mBTC amt /= 1000 case 2: // uBTC amt /= 1000000 } */ sendTo[addr] = amt } go txSenderAndReplyListener(sendTo) }) SendCoins.SendBtn = submitBtn bot.Add(submitBtn) grid.Add(bot) return &grid.Container.Widget }