Пример #1
0
// 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
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
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
}