Beispiel #1
0
func NewProjectOpener(theme gxui.Theme, projPane gxui.Control) *ProjectOpener {
	return &ProjectOpener{
		statusKeeper: statusKeeper{theme: theme},
		name:         theme.CreateTextBox(),
		projPane:     projPane,
	}
}
Beispiel #2
0
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)
}
Beispiel #3
0
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)
}
Beispiel #4
0
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
}
Beispiel #5
0
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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
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
}
Beispiel #8
0
func (d *DrawPaint) Init(outer DrawPaintOuter, theme gxui.Theme) {
	d.outer = outer
	d.driver = theme.Driver()

	if debugVerifyDetachOnGC {
		runtime.SetFinalizer(d.outer, verifyDetach)
	}
}
Beispiel #9
0
// 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
}
Beispiel #10
0
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
}
Beispiel #11
0
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
}
Beispiel #12
0
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
}
Beispiel #13
0
// 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
}
Beispiel #14
0
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
}
Beispiel #15
0
// 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
}
Beispiel #16
0
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)
}
Beispiel #17
0
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
}
Beispiel #18
0
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})
}
Beispiel #19
0
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,
	}
}
Beispiel #20
0
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)
}
Beispiel #21
0
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)
}
Beispiel #22
0
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
}
Beispiel #23
0
// 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
}
Beispiel #24
0
// 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
}
Beispiel #25
0
func (a *fsAdapter) create(theme gxui.Theme, path string) gxui.Label {
	label := theme.CreateLabel()
	label.SetText(filepath.Base(path))
	return label
}
Beispiel #26
0
func (a *fsAdapter) Size(theme gxui.Theme) math.Size {
	return math.Size{
		W: 20 * theme.DefaultMonospaceFont().GlyphMaxSize().W,
		H: theme.DefaultMonospaceFont().GlyphMaxSize().H,
	}
}
Beispiel #27
0
// 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
}
Beispiel #28
0
func (l *Layoutable) Init(outer LayoutableOuter, theme gxui.Theme) {
	l.outer = outer
	l.driver = theme.Driver()
}