func NewProjectOpener(theme gxui.Theme, projPane gxui.Control) *ProjectOpener { return &ProjectOpener{ statusKeeper: statusKeeper{theme: theme}, name: theme.CreateTextBox(), projPane: projPane, } }
func (l *DropDownList) Init(outer DropDownListOuter, theme gxui.Theme) { l.outer = outer l.Container.Init(outer, theme) l.BackgroundBorderPainter.Init(outer) l.Focusable.Init(outer) l.theme = theme l.list = theme.CreateList() l.list.OnSelectionChanged(func(item gxui.AdapterItem) { l.outer.RemoveAll() adapter := l.list.Adapter() if item != nil && adapter != nil { l.selected = l.AddChild(adapter.Create(l.theme, adapter.ItemIndex(item))) } else { l.selected = nil } l.Relayout() }) l.list.OnItemClicked(func(gxui.MouseEvent, gxui.AdapterItem) { l.HideList() }) l.list.OnKeyPress(func(ev gxui.KeyboardEvent) { switch ev.Key { case gxui.KeyEnter, gxui.KeyEscape: l.HideList() } }) l.list.OnLostFocus(l.HideList) l.OnDetach(l.HideList) l.SetMouseEventTarget(true) // Interface compliance test _ = gxui.DropDownList(l) }
func (t *TextBox) Init(outer TextBoxOuter, driver gxui.Driver, theme gxui.Theme, font gxui.Font) { t.List.Init(outer, theme) t.Focusable.Init(outer) t.outer = outer t.driver = driver t.font = font t.onRedrawLines = gxui.CreateEvent(func() {}) t.controller = gxui.CreateTextBoxController() t.adapter = &TextBoxAdapter{TextBox: t} t.desiredWidth = 100 t.SetScrollBarEnabled(false) // Defaults to single line t.OnGainedFocus(func() { t.onRedrawLines.Fire() }) t.OnLostFocus(func() { t.onRedrawLines.Fire() }) t.horizScroll = theme.CreateScrollBar() t.horizScrollChild = t.AddChild(t.horizScroll) t.horizScroll.SetOrientation(gxui.Horizontal) t.horizScroll.OnScroll(func(from, to int) { t.SetHorizOffset(from) }) t.controller.OnTextChanged(func([]gxui.TextBoxEdit) { t.onRedrawLines.Fire() t.List.DataChanged(false) }) t.controller.OnSelectionChanged(func() { t.onRedrawLines.Fire() }) t.List.SetAdapter(t.adapter) // Interface compliance test _ = gxui.TextBox(t) }
func (a *customAdapter) Create(theme gxui.Theme, index int) gxui.Control { phase := float32(index) / 1000 c := gxui.Color{ R: 0.5 + 0.5*math.Sinf(math.TwoPi*(phase+0.000)), G: 0.5 + 0.5*math.Sinf(math.TwoPi*(phase+0.333)), B: 0.5 + 0.5*math.Sinf(math.TwoPi*(phase+0.666)), A: 1.0, } i := theme.CreateImage() i.SetBackgroundBrush(gxui.CreateBrush(c)) i.SetMargin(math.Spacing{L: 3, T: 3, R: 3, B: 3}) i.OnMouseEnter(func(ev gxui.MouseEvent) { i.SetBorderPen(gxui.CreatePen(2, gxui.Gray80)) }) i.OnMouseExit(func(ev gxui.MouseEvent) { i.SetBorderPen(gxui.TransparentPen) }) i.OnMouseDown(func(ev gxui.MouseEvent) { i.SetBackgroundBrush(gxui.CreateBrush(c.MulRGB(0.7))) }) i.OnMouseUp(func(ev gxui.MouseEvent) { i.SetBackgroundBrush(gxui.CreateBrush(c)) }) return i }
func (defaultTreeControlCreator) Create(theme gxui.Theme, control gxui.Control, node *TreeToListNode) gxui.Control { ll := theme.CreateLinearLayout() ll.SetDirection(gxui.LeftToRight) btn := theme.CreateButton() btn.SetBackgroundBrush(gxui.TransparentBrush) btn.SetBorderPen(gxui.CreatePen(1, gxui.Gray30)) btn.SetMargin(math.Spacing{L: 2, R: 2, T: 1, B: 1}) btn.OnClick(func(ev gxui.MouseEvent) { if ev.Button == gxui.MouseButtonLeft { node.ToggleExpanded() } }) update := func() { btn.SetVisible(!node.IsLeaf()) if node.IsExpanded() { btn.SetText("-") } else { btn.SetText("+") } } update() gxui.WhileAttached(btn, node.OnChange, update) ll.AddChild(btn) ll.AddChild(control) ll.SetPadding(math.Spacing{L: 16 * node.Depth()}) return ll }
// Color picker uses the customAdapter for driving a list func colorPicker(theme gxui.Theme) gxui.Control { layout := theme.CreateLinearLayout() layout.SetDirection(gxui.TopToBottom) label0 := theme.CreateLabel() label0.SetText("Color palette:") layout.AddChild(label0) adapter := &customAdapter{} list := theme.CreateList() list.SetAdapter(adapter) list.SetOrientation(gxui.Horizontal) layout.AddChild(list) label1 := theme.CreateLabel() label1.SetMargin(math.Spacing{T: 30}) label1.SetText("Selected color:") layout.AddChild(label1) selected := theme.CreateImage() selected.SetExplicitSize(math.Size{W: 32, H: 32}) layout.AddChild(selected) list.OnSelectionChanged(func(item gxui.AdapterItem) { if item != nil { control := list.ItemControl(item) selected.SetBackgroundBrush(control.(gxui.Image).BackgroundBrush()) } }) return layout }
func createIconButton(driver gxui.Driver, theme gxui.Theme, iconPath string) gxui.Button { button := theme.CreateButton() button.SetType(gxui.PushButton) fileBytes, err := assets.Asset(iconPath) if err != nil { log.Printf("Error: Failed to read asset %s: %s", iconPath, err) return button } f := bytes.NewBuffer(fileBytes) src, _, err := image.Decode(f) if err != nil { log.Printf("Error: Failed to decode image %s: %s", iconPath, err) return button } src = resize.Resize(24, 24, src, resize.Bilinear) rgba := image.NewRGBA(src.Bounds()) draw.Draw(rgba, src.Bounds(), src, image.ZP, draw.Src) texture := driver.CreateTexture(rgba, 1) icon := theme.CreateImage() icon.SetTexture(texture) button.AddChild(icon) return button }
func (d *DrawPaint) Init(outer DrawPaintOuter, theme gxui.Theme) { d.outer = outer d.driver = theme.Driver() if debugVerifyDetachOnGC { runtime.SetFinalizer(d.outer, verifyDetach) } }
// Create implements gxui.TreeNode. func (d directory) Create(theme gxui.Theme) gxui.Control { _, name := filepath.Split(d.path) if name == "" { name = d.path } l := theme.CreateLabel() l.SetText(name) l.SetColor(directoryColor) return l }
func newCompletionLabel(theme gxui.Theme, color gxui.Color) *completionLabel { l := &completionLabel{} l.Init(l, theme, theme.DefaultMonospaceFont(), color) l.SetMargin(math.Spacing{ T: 3, R: 3, }) l.SetHorizontalAlignment(gxui.AlignCenter) l.padding = completionPadding return l }
func NewProjectsPane(driver gxui.Driver, theme gxui.Theme, projFrame gxui.Control) *Projects { pane := &Projects{ theme: theme, projectFrame: projFrame, button: createIconButton(driver, theme, "projects.png"), projects: theme.CreateList(), projectsAdapter: gxui.CreateDefaultAdapter(), } pane.projectsAdapter.SetItems(settings.Projects()) pane.projects.SetAdapter(pane.projectsAdapter) return pane }
func (a *filesAdapter) Create(theme gxui.Theme, index int) gxui.Control { path := a.files[index] _, name := filepath.Split(path) label := theme.CreateLabel() label.SetText(name) if fi, err := os.Stat(path); err == nil && fi.IsDir() { label.SetColor(directoryColor) } else { label.SetColor(fileColor) } return label }
// Create a PanelHolder with a 3 panels func panelHolder(name string, theme gxui.Theme) gxui.PanelHolder { label := func(text string) gxui.Label { label := theme.CreateLabel() label.SetText(text) return label } holder := theme.CreatePanelHolder() holder.AddPanel(label(name+" 0 content"), name+" 0 panel") holder.AddPanel(label(name+" 1 content"), name+" 1 panel") holder.AddPanel(label(name+" 2 content"), name+" 2 panel") return holder }
func (e *editor) CreateLine(theme gxui.Theme, index int) (mixins.TextBoxLine, gxui.Control) { lineNumber := theme.CreateLabel() lineNumber.SetText(fmt.Sprintf("%4d", index+1)) line := &mixins.CodeEditorLine{} line.Init(line, theme, &e.CodeEditor, index) layout := theme.CreateLinearLayout() layout.SetDirection(gxui.LeftToRight) layout.AddChild(lineNumber) layout.AddChild(line) return line, layout }
// mixins.TextBox overrides func (e *CodeEditor) CreateLine(theme gxui.Theme, index int) (TextBoxLine, gxui.Control) { lineNumber := theme.CreateLabel() lineNumber.SetText(fmt.Sprintf("%.4d", index+1)) // Displayed lines start at 1 line := &CodeEditorLine{} line.Init(line, theme, e, index) layout := theme.CreateLinearLayout() layout.SetDirection(gxui.LeftToRight) layout.AddChild(lineNumber) layout.AddChild(line) return line, layout }
func (p *PanelHolder) Init(outer PanelHolderOuter, theme gxui.Theme) { p.Container.Init(outer, theme) p.outer = outer p.theme = theme p.tabLayout = theme.CreateLinearLayout() p.tabLayout.SetDirection(gxui.LeftToRight) p.Container.AddChild(p.tabLayout) p.SetMargin(math.Spacing{L: 1, T: 2, R: 1, B: 1}) p.SetMouseEventTarget(true) // For drag-drop targets // Interface compliance test _ = gxui.PanelHolder(p) }
func newCommandBox(driver gxui.Driver, theme gxui.Theme, controller Controller) *commandBox { box := &commandBox{ driver: driver, controller: controller, } box.label = theme.CreateLabel() box.label.SetColor(cmdColor) box.LinearLayout.Init(box, theme) box.SetDirection(gxui.LeftToRight) box.AddChild(box.label) box.Clear() return box }
func (n *genericNode) Init(outer mixins.LinearLayoutOuter, driver gxui.Driver, theme gxui.Theme, name string, color gxui.Color) { n.LinearLayout.Init(outer, theme) n.driver = driver n.theme = theme n.SetDirection(gxui.TopToBottom) n.button = newTreeButton(driver, theme.(*basic.Theme), name) n.button.Label().SetColor(color) n.LinearLayout.AddChild(n.button) n.children = theme.CreateLinearLayout() n.children.SetDirection(gxui.TopToBottom) n.children.SetMargin(math.Spacing{L: 10}) }
func NewGotoLine(theme gxui.Theme) *GotoLine { input := theme.CreateTextBox() input.OnTextChanged(func([]gxui.TextBoxEdit) { runes := []rune(input.Text()) for index := 0; index < len(runes); index++ { if !unicode.IsDigit(runes[index]) { runes = append(runes[:index], runes[index+1:]...) index-- } } text := string(runes) if text != input.Text() { input.SetText(text) } }) return &GotoLine{ statusKeeper: statusKeeper{theme: theme}, lineNumInput: input, } }
func (l *List) Init(outer ListOuter, theme gxui.Theme) { l.outer = outer l.Container.Init(outer, theme) l.BackgroundBorderPainter.Init(outer) l.Focusable.Init(outer) l.theme = theme l.scrollBar = theme.CreateScrollBar() l.scrollBarChild = l.AddChild(l.scrollBar) l.scrollBarEnabled = true l.scrollBar.OnScroll(func(from, to int) { l.SetScrollOffset(from) }) l.SetOrientation(gxui.Vertical) l.SetBackgroundBrush(gxui.TransparentBrush) l.SetMouseEventTarget(true) l.details = make(map[gxui.AdapterItem]itemDetails) // Interface compliance test _ = gxui.List(l) }
func (l *ScrollLayout) Init(outer ScrollLayoutOuter, theme gxui.Theme) { l.Container.Init(outer, theme) l.BackgroundBorderPainter.Init(outer) l.outer = outer l.theme = theme l.canScrollX = true l.canScrollY = true scrollBarX := theme.CreateScrollBar() scrollBarX.SetOrientation(gxui.Horizontal) scrollBarX.OnScroll(func(from, to int) { l.SetScrollOffset(math.Point{X: from, Y: l.scrollOffset.Y}) }) scrollBarY := theme.CreateScrollBar() scrollBarY.SetOrientation(gxui.Vertical) scrollBarY.OnScroll(func(from, to int) { l.SetScrollOffset(math.Point{X: l.scrollOffset.X, Y: from}) }) l.scrollBarX = l.AddChild(scrollBarX) l.scrollBarY = l.AddChild(scrollBarY) l.SetMouseEventTarget(true) // Interface compliance test _ = gxui.ScrollLayout(l) }
func (treeControlCreator) Create(theme gxui.Theme, control gxui.Control, node *mixins.TreeToListNode) gxui.Control { img := theme.CreateImage() imgSize := math.Size{W: 10, H: 10} ll := theme.CreateLinearLayout() ll.SetDirection(gxui.LeftToRight) btn := theme.CreateButton() btn.SetBackgroundBrush(gxui.TransparentBrush) btn.SetBorderPen(gxui.CreatePen(1, gxui.Gray30)) btn.SetMargin(math.Spacing{L: 1, R: 1, T: 1, B: 1}) btn.OnClick(func(ev gxui.MouseEvent) { if ev.Button == gxui.MouseButtonLeft { node.ToggleExpanded() } }) btn.AddChild(img) update := func() { expanded := node.IsExpanded() canvas := theme.Driver().CreateCanvas(imgSize) btn.SetVisible(!node.IsLeaf()) switch { case !btn.IsMouseDown(gxui.MouseButtonLeft) && expanded: canvas.DrawPolygon(expandedPoly, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray70)) case !btn.IsMouseDown(gxui.MouseButtonLeft) && !expanded: canvas.DrawPolygon(collapsedPoly, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray70)) case expanded: canvas.DrawPolygon(expandedPoly, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray30)) case !expanded: canvas.DrawPolygon(collapsedPoly, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray30)) } canvas.Complete() img.SetCanvas(canvas) } btn.OnMouseDown(func(gxui.MouseEvent) { update() }) btn.OnMouseUp(func(gxui.MouseEvent) { update() }) update() gxui.WhileAttached(btn, node.OnChange, update) ll.AddChild(btn) ll.AddChild(control) ll.SetPadding(math.Spacing{L: 16 * node.Depth()}) return ll }
// Create implements gxui.TreeNode. func (n *node) Create(theme gxui.Theme) gxui.Control { layout := theme.CreateLinearLayout() layout.SetDirection(gxui.LeftToRight) label := theme.CreateLabel() label.SetText(n.name) textbox := theme.CreateTextBox() textbox.SetText(n.name) textbox.SetPadding(math.ZeroSpacing) textbox.SetMargin(math.ZeroSpacing) addButton := theme.CreateButton() addButton.SetText("+") addButton.OnClick(func(gxui.MouseEvent) { n.add("<new>") }) edit := func() { layout.RemoveAll() layout.AddChild(textbox) layout.AddChild(addButton) gxui.SetFocus(textbox) } commit := func() { n.name = textbox.Text() label.SetText(n.name) layout.RemoveAll() layout.AddChild(label) layout.AddChild(addButton) } // When the user clicks the label, replace it with an editable text-box label.OnClick(func(gxui.MouseEvent) { edit() }) // When the text-box loses focus, replace it with a label again. textbox.OnLostFocus(commit) layout.AddChild(label) layout.AddChild(addButton) return layout }
// Number picker uses the gxui.DefaultAdapter for driving a list func numberPicker(theme gxui.Theme, overlay gxui.BubbleOverlay) gxui.Control { items := []string{ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty", } adapter := gxui.CreateDefaultAdapter() adapter.SetItems(items) layout := theme.CreateLinearLayout() layout.SetDirection(gxui.TopToBottom) label0 := theme.CreateLabel() label0.SetText("Numbers:") layout.AddChild(label0) dropList := theme.CreateDropDownList() dropList.SetAdapter(adapter) dropList.SetBubbleOverlay(overlay) layout.AddChild(dropList) list := theme.CreateList() list.SetAdapter(adapter) list.SetOrientation(gxui.Vertical) layout.AddChild(list) label1 := theme.CreateLabel() label1.SetMargin(math.Spacing{T: 30}) label1.SetText("Selected number:") layout.AddChild(label1) selected := theme.CreateLabel() layout.AddChild(selected) dropList.OnSelectionChanged(func(item gxui.AdapterItem) { if list.Selected() != item { list.Select(item) } }) list.OnSelectionChanged(func(item gxui.AdapterItem) { if dropList.Selected() != item { dropList.Select(item) } selected.SetText(fmt.Sprintf("%s - %d", item, adapter.ItemIndex(item))) }) return layout }
func (a *fsAdapter) create(theme gxui.Theme, path string) gxui.Label { label := theme.CreateLabel() label.SetText(filepath.Base(path)) return label }
func (a *fsAdapter) Size(theme gxui.Theme) math.Size { return math.Size{ W: 20 * theme.DefaultMonospaceFont().GlyphMaxSize().W, H: theme.DefaultMonospaceFont().GlyphMaxSize().H, } }
// Override directory.Create so that the full root is shown, unaltered. func (a directoryAdapter) Create(theme gxui.Theme, index int) gxui.Control { l := theme.CreateLabel() l.SetText(a.subdirs[index]) l.SetColor(directoryColor) return l }
func (l *Layoutable) Init(outer LayoutableOuter, theme gxui.Theme) { l.outer = outer l.driver = theme.Driver() }