func (ui *GTKUI) createWidget(v interface{}) gtk.WidgetLike { switch v := v.(type) { case VBox: vbox := gtk.Box(gtk.GTK_ORIENTATION_VERTICAL, v.spacing) for _, child := range v.children { widget := ui.newWidget(child) if child.PackEnd() { vbox.PackEnd(widget, child.Expand(), child.Fill(), child.Padding()) } else { vbox.PackStart(widget, child.Expand(), child.Fill(), child.Padding()) } } return vbox case HBox: hbox := gtk.Box(gtk.GTK_ORIENTATION_HORIZONTAL, v.spacing) for _, child := range v.children { widget := ui.newWidget(child) hbox.PackStart(widget, child.Expand(), child.Fill(), child.Padding()) } return hbox case EventBox: box := gtk.EventBox() if v.child != nil { widget := ui.newWidget(v.child) box.Add(widget) } configureWidget(&box.GtkWidget, v.widgetBase) if len(v.name) > 0 { box.Connect("button-press-event", func(e interface{}) { ui.clicked(v.name) }) } return box case Label: label := gtk.Label(v.text) if len(v.markup) > 0 { label.SetMarkup(v.markup) } label.SetAlignment(v.xAlign, v.yAlign) configureWidget(&label.GtkWidget, v.widgetBase) if v.wrap != 0 { label.SetSizeRequest(v.wrap, -1) label.SetLineWrap(true) } label.SetSelectable(v.selectable) return label case Entry: entry := gtk.Entry() entry.SetText(v.text) if v.width > 0 { entry.SetWidthChars(v.width) } if name := v.name; len(name) > 0 { ui.entries[name] = entry entry.Connect("destroy", func() { delete(ui.entries, name) }) entry.Connect("activate", func() { ui.clicked(v.name) }) if v.updateOnChange { entry.Connect("changed", func() { ui.updatedEntry(v.name) }) } } if v.password { entry.SetVisibility(false) } configureWidget(&entry.GtkWidget, v.widgetBase) return entry case Button: var button *gtk.GtkButton if len(v.text) > 0 { button = gtk.ButtonWithLabel(v.text) } else { button = gtk.Button() if len(v.markup) > 0 { label := gtk.Label("") label.SetMarkup(v.markup) button.Add(label) } } if v.image != indicatorNone { image := gtk.ImageFromPixbuf(v.image.Image()) button.Add(image) } button.Clicked(func() { ui.clicked(v.name) }) configureWidget(&button.GtkWidget, v.widgetBase) return button case Spinner: spinner := gtk.Spinner() spinner.Start() return spinner case Paned: paned := gtk.Paned(gtk.GTK_ORIENTATION_HORIZONTAL) left := ui.newWidget(v.left) right := ui.newWidget(v.right) paned.Add1(left) paned.Add2(right) return paned case Scrolled: scrolled := gtk.ScrolledWindow(nil, nil) horizonalPolicy := gtk.GtkPolicyType(gtk.GTK_POLICY_NEVER) if v.horizontal { horizonalPolicy = gtk.GTK_POLICY_AUTOMATIC } scrolled.SetPolicy(horizonalPolicy, gtk.GTK_POLICY_AUTOMATIC) child := ui.newWidget(v.child) if v.viewport { scrolled.AddWithViewPort(child) } else { scrolled.Add(child) } return scrolled case TextView: view := gtk.TextView() view.SetBorderWidth(1) view.SetEditable(v.editable) if len(v.text) > 0 { buffer := gtk.TextBuffer(gtk.TextTagTable()) buffer.SetText(v.text) view.SetBuffer(buffer) } if v.wrap { view.SetWrapMode(gtk.GTK_WRAP_WORD_CHAR) } if v.updateOnChange && len(v.name) > 0 { view.GetBuffer().Connect("changed", func() { ui.updated(v.name) }) } if v.spellCheck { if _, err := gtkspell.New(view, ""); err != nil { panic(err) } } if name := v.name; len(name) > 0 { ui.textViews[name] = view view.Connect("destroy", func() { delete(ui.textViews, name) }) } configureWidget(&view.GtkWidget, v.widgetBase) return view case Combo: combo := gtk.ComboBoxText() selectedIndex := -1 for i, l := range v.labels { combo.AppendText(l) if len(v.preSelected) > 0 && l == v.preSelected { selectedIndex = i } } if selectedIndex >= 0 { combo.SetActive(selectedIndex) } if name := v.name; len(name) > 0 { ui.combos[name] = combo combo.Connect("destroy", func() { delete(ui.combos, name) }) combo.Connect("changed", func() { ui.clicked(v.name) }) } configureWidget(&combo.GtkWidget, v.widgetBase) return combo case Image: image := gtk.ImageFromPixbuf(v.image.Image()) image.SetAlignment(v.xAlign, v.yAlign) configureWidget(&image.GtkWidget, v.widgetBase) return image case Frame: frame := gtk.Frame("") configureWidget(&frame.GtkWidget, v.widgetBase) if v.child != nil { widget := ui.newWidget(v.child) frame.Add(widget) } return frame case Progress: pro := gtk.ProgressBar() configureWidget(&pro.GtkWidget, v.widgetBase) return pro case Grid: grid := gtk.Grid() configureWidget(&grid.GtkWidget, v.widgetBase) for y, row := range v.rows { x := 0 for _, elem := range row { if elem.widget != nil { grid.Attach(ui.newWidget(elem.widget), x, y, elem.width, elem.height) } x += elem.width } } if v.rowSpacing > 0 { grid.SetRowSpacing(v.rowSpacing) } if v.colSpacing > 0 { grid.SetColSpacing(v.colSpacing) } if v.rowHomogeneous { grid.SetRowHomogeneous(true) } if v.colHomogeneous { grid.SetColumnHomogeneous(true) } return grid case RadioGroup: hbox := gtk.Box(gtk.GTK_ORIENTATION_HORIZONTAL, 2) var last *gtk.GtkRadioButton for i, labelText := range v.labels { last = gtk.RadioButtonWithLabelFromWidget(last, labelText) i := i last.Connect("toggled", func() { ui.radioGroups[v.name] = i ui.clicked(v.name) }) last.Connect("destroy", func() { delete(ui.radioGroups, v.name) }) hbox.PackStart(last, false, true, 2) } return hbox case Calendar: cal := gtk.Calendar() configureWidget(&cal.GtkWidget, v.widgetBase) if len(v.name) > 0 { ui.calendars[v.name] = cal cal.Connect("destroy", func() { delete(ui.calendars, v.name) }) } return cal case SpinButton: spin := gtk.SpinButtonWithRange(v.min, v.max, v.step) configureWidget(&spin.GtkWidget, v.widgetBase) if len(v.name) > 0 { ui.spinButtons[v.name] = spin spin.Connect("destroy", func() { delete(ui.spinButtons, v.name) }) } return spin case CheckButton: check := gtk.CheckButtonWithLabel(v.text) configureWidget(&check.GtkWidget, v.widgetBase) check.SetActive(v.checked) if len(v.name) > 0 { check.Connect("toggled", func() { ui.clicked(v.name) }) check.Connect("destroy", func() { delete(ui.checks, v.name) }) ui.checks[v.name] = check } return check default: panic("unknown widget: " + fmt.Sprintf("%#v", v)) } panic("forgot to return") }
func (ui *GTKUI) createWidget(v interface{}) gtk.WidgetLike { switch v := v.(type) { case VBox: vbox := gtk.VBox(v.homogeneous, v.spacing) for _, child := range v.children { widget := ui.newWidget(child) if child.PackEnd() { vbox.PackEnd(widget, child.Expand(), child.Fill(), child.Padding()) } else { vbox.PackStart(widget, child.Expand(), child.Fill(), child.Padding()) } } return vbox case HBox: hbox := gtk.HBox(v.homogeneous, v.spacing) for _, child := range v.children { widget := ui.newWidget(child) hbox.PackStart(widget, child.Expand(), child.Fill(), child.Padding()) } return hbox case EventBox: box := gtk.EventBox() if v.child != nil { widget := ui.newWidget(v.child) box.Add(widget) } configureWidget(&box.GtkWidget, v.widgetBase) if len(v.name) > 0 { box.Connect("button-press-event", func(e interface{}) { ui.clicked(v.name) }) } return box case Label: label := gtk.Label(v.text) label.SetAlignment(v.xAlign, v.yAlign) configureWidget(&label.GtkWidget, v.widgetBase) if v.wrap != 0 { label.SetSizeRequest(v.wrap, -1) label.SetLineWrap(true) } label.SetSelectable(v.selectable) return label case Entry: entry := gtk.Entry() entry.SetText(v.text) if v.width > 0 { entry.SetWidthChars(v.width) } if name := v.name; len(name) > 0 { ui.entries[name] = entry entry.Connect("destroy", func() { delete(ui.entries, name) }) entry.Connect("activate", func() { ui.clicked(v.name) }) } if v.password { entry.SetVisibility(false) } configureWidget(&entry.GtkWidget, v.widgetBase) return entry case Button: button := gtk.ButtonWithLabel(v.text) button.Clicked(func() { ui.clicked(v.name) }) configureWidget(&button.GtkWidget, v.widgetBase) return button case Spinner: spinner := gtk.Spinner() spinner.Start() return spinner case Paned: paned := gtk.HPaned() left := ui.newWidget(v.left) right := ui.newWidget(v.right) paned.Add1(left) paned.Add2(right) return paned case Scrolled: scrolled := gtk.ScrolledWindow(nil, nil) horizonalPolicy := gtk.GtkPolicyType(gtk.GTK_POLICY_NEVER) if v.horizontal { horizonalPolicy = gtk.GTK_POLICY_AUTOMATIC } scrolled.SetPolicy(horizonalPolicy, gtk.GTK_POLICY_AUTOMATIC) child := ui.newWidget(v.child) if v.viewport { scrolled.AddWithViewPort(child) } else { scrolled.Add(child) } return scrolled case TextView: view := gtk.TextView() view.SetBorderWidth(1) view.SetEditable(v.editable) if len(v.text) > 0 { buffer := gtk.TextBuffer(gtk.TextTagTable()) buffer.SetText(v.text) view.SetBuffer(buffer) } if v.wrap { view.SetWrapMode(gtk.GTK_WRAP_WORD_CHAR) } if v.updateOnChange && len(v.name) > 0 { view.GetBuffer().Connect("changed", func() { ui.updated(v.name) }) } if v.spellCheck { if _, err := gtkspell.New(view, ""); err != nil { panic(err) } } if name := v.name; len(name) > 0 { ui.textViews[name] = view view.Connect("destroy", func() { delete(ui.textViews, name) }) } configureWidget(&view.GtkWidget, v.widgetBase) return view case Combo: combo := gtk.ComboBoxNewText() selectedIndex := -1 for i, l := range v.labels { combo.AppendText(l) if len(v.preSelected) > 0 && l == v.preSelected { selectedIndex = i } } if selectedIndex >= 0 { combo.SetActive(selectedIndex) } if name := v.name; len(name) > 0 { ui.combos[name] = combo combo.Connect("destroy", func() { delete(ui.combos, name) }) combo.Connect("changed", func() { ui.clicked(v.name) }) } configureWidget(&combo.GtkWidget, v.widgetBase) return combo case Image: image := gtk.ImageFromPixbuf(v.image.Image()) image.SetAlignment(v.xAlign, v.yAlign) configureWidget(&image.GtkWidget, v.widgetBase) return image default: panic("unknown widget: " + fmt.Sprintf("%#v", v)) } panic("forgot to return") }