Skip to content

Instantly share code, notes, and snippets.

@Kvaz1r
Created April 22, 2017 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kvaz1r/0d119fa65673ae4329319cc5d0e7c99b to your computer and use it in GitHub Desktop.
Save Kvaz1r/0d119fa65673ae4329319cc5d0e7c99b to your computer and use it in GitHub Desktop.
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"github.com/nelsam/gxui"
"github.com/nelsam/gxui/drivers/gl"
"github.com/nelsam/gxui/math"
"github.com/nelsam/gxui/mixins"
"github.com/nelsam/gxui/mixins/parts"
"github.com/nelsam/gxui/themes/basic"
"github.com/nelsam/gxui/themes/dark"
)
type Boundser interface {
Bounds() math.Rect
}
type menuBar struct {
mixins.LinearLayout
parent *gxui.Container
theme *basic.Theme
menus map[string]*menu
}
func NewMenuBar(Parent *gxui.Container, theme *basic.Theme) *menuBar {
m := &menuBar{
theme: theme,
parent: Parent,
menus: make(map[string]*menu),
}
m.Init(m, theme)
m.SetDirection(gxui.LeftToRight)
m.SetBorderPen(theme.ButtonDefaultStyle.Pen)
return m
}
func (m *menuBar) Add(menuName, Name string, parent *gxui.Container) {
menu, ok := m.menus[menuName]
if !ok {
menu = NewMenu(m.parent, m.theme)
m.menus[menuName] = menu
button := newMenuButton(m.parent, m.theme, menuName)
child := m.AddChild(button)
button.SetMenu(child, menu)
}
menu.Add(Name)
}
func (m *menuBar) Paint(canvas gxui.Canvas) {
rect := m.Size().Rect()
m.BackgroundBorderPainter.PaintBackground(canvas, rect)
m.PaintChildren.Paint(canvas)
painterRect := math.Rect{
Min: math.Point{
X: rect.Min.X,
Y: rect.Max.Y - 1,
},
Max: rect.Max,
}
m.BackgroundBorderPainter.PaintBorder(canvas, painterRect)
}
func (m *menuBar) DesiredSize(min, max math.Size) math.Size {
size := m.LinearLayout.DesiredSize(min, max)
size.W = max.W
return size
}
type menu struct {
parts.Focusable
mixins.LinearLayout
parent *gxui.Container
theme *basic.Theme
}
func NewMenu(parent *gxui.Container, theme *basic.Theme) *menu {
m := &menu{
parent: parent,
theme: theme,
}
m.Focusable.Init(m)
m.LinearLayout.Init(m, theme)
m.SetBackgroundBrush(theme.ButtonDefaultStyle.Brush)
m.SetBorderPen(theme.ButtonDefaultStyle.Pen)
return m
}
func (m *menu) Add(name string) {
item := newMenuItem(m.theme, name)
m.AddChild(item)
}
type menuItem struct {
mixins.Button
theme *basic.Theme
}
func newMenuItem(theme *basic.Theme, name string) *menuItem {
b := &menuItem{
theme: theme,
}
b.Init(b, theme)
b.SetText(name)
b.SetPadding(math.Spacing{L: 1, R: 1, B: 1, T: 1})
b.SetMargin(math.Spacing{L: 2, R: 2})
b.OnMouseEnter(func(gxui.MouseEvent) { b.Redraw() })
b.OnMouseExit(func(gxui.MouseEvent) { b.Redraw() })
b.OnMouseDown(func(gxui.MouseEvent) { b.Redraw() })
b.OnMouseUp(func(gxui.MouseEvent) { b.Redraw() })
b.OnGainedFocus(b.Redraw)
b.OnLostFocus(b.Redraw)
return b
}
func (b *menuItem) Style() basic.Style {
if b.IsMouseDown(gxui.MouseButtonLeft) && b.IsMouseOver() {
return b.theme.ButtonPressedStyle
}
if b.IsMouseOver() {
return b.theme.ButtonOverStyle
}
return b.theme.ButtonDefaultStyle
}
func (b *menuItem) Paint(canvas gxui.Canvas) {
style := b.Style()
if l := b.Label(); l != nil {
l.SetColor(style.FontColor)
}
rect := b.Size().Rect()
b.BackgroundBorderPainter.PaintBackground(canvas, rect)
b.PaintChildren.Paint(canvas)
}
type menuButton struct {
mixins.Button
menuParent *gxui.Container
theme *basic.Theme
}
func newMenuButton(menuParent *gxui.Container, theme *basic.Theme, name string) *menuButton {
b := &menuButton{
menuParent: menuParent,
theme: theme,
}
b.Init(b, theme)
b.SetText(name)
b.SetPadding(math.Spacing{L: 1, R: 1, B: 1, T: 1})
b.SetMargin(math.Spacing{L: 3})
b.SetBackgroundBrush(b.theme.ButtonDefaultStyle.Brush)
b.SetBorderPen(b.theme.ButtonDefaultStyle.Pen)
b.OnMouseEnter(func(gxui.MouseEvent) { b.Redraw() })
b.OnMouseExit(func(gxui.MouseEvent) { b.Redraw() })
b.OnMouseDown(func(gxui.MouseEvent) { b.Redraw() })
b.OnMouseUp(func(gxui.MouseEvent) { b.Redraw() })
b.OnGainedFocus(b.Redraw)
b.OnLostFocus(b.Redraw)
return b
}
func (b *menuButton) SetMenu(boundser Boundser, menu *menu) {
// b.OnClick(func(gxui.MouseEvent) {
// if b.menuParent.Children().IndexOf(menu) >= 0 {
// b.menuParent.RemoveChild(menu)
// return
// }
// bounds := boundser.Bounds()
// child := b.menuParent.AddChild(menu)
// offset := math.Point{
// X: bounds.Min.X,
// Y: bounds.Max.Y,
// }
// child.Offset = offset
// gxui.SetFocus(menu)
// })
// menu.OnLostFocus(func() {
// if b.menuParent.Children().IndexOf(menu) >= 0 {
// b.menuParent.RemoveChild(menu)
// }
// })
}
func (b *menuButton) Style() basic.Style {
if b.IsMouseDown(gxui.MouseButtonLeft) && b.IsMouseOver() {
return b.theme.ButtonPressedStyle
}
if b.IsMouseOver() {
return b.theme.ButtonOverStyle
}
return b.theme.ButtonDefaultStyle
}
func (b *menuButton) Paint(canvas gxui.Canvas) {
style := b.Style()
if l := b.Label(); l != nil {
l.SetColor(style.FontColor)
}
rect := b.Size().Rect()
poly := gxui.Polygon{
{Position: math.Point{
X: rect.Min.X,
Y: rect.Max.Y,
}},
{Position: math.Point{
X: rect.Min.X,
Y: rect.Min.Y,
}},
{Position: math.Point{
X: rect.Max.X,
Y: rect.Min.Y,
}},
{Position: math.Point{
X: rect.Max.X,
Y: rect.Max.Y,
}},
}
canvas.DrawPolygon(poly, gxui.TransparentPen, style.Brush)
b.PaintChildren.Paint(canvas)
canvas.DrawLines(poly, style.Pen)
}
func appMain(driver gxui.Driver) {
theme := dark.CreateTheme(driver).(*basic.Theme)
menuLayout := theme.CreateLinearLayout()
mainLayout := theme.CreateLinearLayout()
mainLayout.SetVerticalAlignment(gxui.AlignBottom)
menubar := NewMenuBar(menuLayout, theme)
menubar.Add("Test1", "Item1", menuLayout)
menuLayout.AddChild(menubar)
mainLayout.AddChild(menuLayout)
window := theme.CreateWindow(400, 200, "Test")
window.AddChild(mainLayout)
window.OnClose(driver.Terminate)
window.SetBackgroundBrush(gxui.Brush{gxui.Gray30})
}
func main() {
gl.StartDriver(appMain)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment