WIP Themes Support
This commit is contained in:
parent
4206330398
commit
e675ead0ed
45
button.go
45
button.go
|
@ -5,13 +5,14 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.kirsle.net/go/render"
|
"git.kirsle.net/go/render"
|
||||||
"git.kirsle.net/go/ui/theme"
|
"git.kirsle.net/go/ui/style"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Button is a clickable button.
|
// Button is a clickable button.
|
||||||
type Button struct {
|
type Button struct {
|
||||||
BaseWidget
|
BaseWidget
|
||||||
child Widget
|
child Widget
|
||||||
|
style *style.Button
|
||||||
|
|
||||||
// Private options.
|
// Private options.
|
||||||
hovering bool
|
hovering bool
|
||||||
|
@ -22,27 +23,28 @@ type Button struct {
|
||||||
func NewButton(name string, child Widget) *Button {
|
func NewButton(name string, child Widget) *Button {
|
||||||
w := &Button{
|
w := &Button{
|
||||||
child: child,
|
child: child,
|
||||||
|
style: &style.DefaultButton,
|
||||||
}
|
}
|
||||||
w.IDFunc(func() string {
|
w.IDFunc(func() string {
|
||||||
return fmt.Sprintf("Button<%s>", name)
|
return fmt.Sprintf("Button<%s>", name)
|
||||||
})
|
})
|
||||||
|
|
||||||
w.Configure(Config{
|
w.SetStyle(Theme.Button)
|
||||||
BorderSize: 2,
|
|
||||||
BorderStyle: BorderRaised,
|
|
||||||
OutlineSize: 1,
|
|
||||||
OutlineColor: theme.ButtonOutlineColor,
|
|
||||||
Background: theme.ButtonBackgroundColor,
|
|
||||||
})
|
|
||||||
|
|
||||||
w.Handle(MouseOver, func(e EventData) error {
|
w.Handle(MouseOver, func(e EventData) error {
|
||||||
w.hovering = true
|
w.hovering = true
|
||||||
w.SetBackground(theme.ButtonHoverColor)
|
w.SetBackground(w.style.HoverBackground)
|
||||||
|
if label, ok := w.child.(*Label); ok {
|
||||||
|
label.Font.Color = w.style.HoverForeground
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
w.Handle(MouseOut, func(e EventData) error {
|
w.Handle(MouseOut, func(e EventData) error {
|
||||||
w.hovering = false
|
w.hovering = false
|
||||||
w.SetBackground(theme.ButtonBackgroundColor)
|
w.SetBackground(w.style.Background)
|
||||||
|
if label, ok := w.child.(*Label); ok {
|
||||||
|
label.Font.Color = w.style.Foreground
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -53,13 +55,34 @@ func NewButton(name string, child Widget) *Button {
|
||||||
})
|
})
|
||||||
w.Handle(MouseUp, func(e EventData) error {
|
w.Handle(MouseUp, func(e EventData) error {
|
||||||
w.clicked = false
|
w.clicked = false
|
||||||
w.SetBorderStyle(BorderRaised)
|
w.SetBorderStyle(BorderStyle(w.style.BorderStyle))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetStyle sets the button style.
|
||||||
|
func (w *Button) SetStyle(v *style.Button) {
|
||||||
|
if v == nil {
|
||||||
|
v = &style.DefaultButton
|
||||||
|
}
|
||||||
|
|
||||||
|
w.style = v
|
||||||
|
w.Configure(Config{
|
||||||
|
BorderSize: w.style.BorderSize,
|
||||||
|
BorderStyle: BorderStyle(w.style.BorderStyle),
|
||||||
|
OutlineSize: w.style.OutlineSize,
|
||||||
|
OutlineColor: w.style.OutlineColor,
|
||||||
|
Background: w.style.Background,
|
||||||
|
})
|
||||||
|
|
||||||
|
// If the child is a Label, apply the foreground color.
|
||||||
|
if label, ok := w.child.(*Label); ok {
|
||||||
|
label.Font.Color = w.style.Foreground
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Children returns the button's child widget.
|
// Children returns the button's child widget.
|
||||||
func (w *Button) Children() []Widget {
|
func (w *Button) Children() []Widget {
|
||||||
return []Widget{w.child}
|
return []Widget{w.child}
|
||||||
|
|
11
eg/themes/Makefile
Normal file
11
eg/themes/Makefile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
.PHONY: run
|
||||||
|
run:
|
||||||
|
go run main.go
|
||||||
|
|
||||||
|
.PHONY: wasm
|
||||||
|
wasm:
|
||||||
|
GOOS=js GOARCH=wasm go build -v -o windows.wasm main_wasm.go
|
||||||
|
|
||||||
|
.PHONY: wasm-serve
|
||||||
|
wasm-serve: wasm
|
||||||
|
../wasm-common/serve.sh
|
107
eg/themes/main.go
Normal file
107
eg/themes/main.go
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.kirsle.net/go/render"
|
||||||
|
"git.kirsle.net/go/render/event"
|
||||||
|
"git.kirsle.net/go/render/sdl"
|
||||||
|
"git.kirsle.net/go/ui"
|
||||||
|
"git.kirsle.net/go/ui/theme"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Program globals.
|
||||||
|
var (
|
||||||
|
// Size of the MainWindow.
|
||||||
|
Width = 1024
|
||||||
|
Height = 768
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
sdl.DefaultFontFilename = "../DejaVuSans.ttf"
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mw, err := ui.NewMainWindow("Theme Demo", Width, Height)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Menu bar.
|
||||||
|
menu := ui.NewMenuBar("Main Menu")
|
||||||
|
file := menu.AddMenu("Select Theme")
|
||||||
|
file.AddItem("Default", func() {
|
||||||
|
addWindow(mw, theme.Default)
|
||||||
|
})
|
||||||
|
file.AddItem("DefaultFlat", func() {
|
||||||
|
addWindow(mw, theme.DefaultFlat)
|
||||||
|
})
|
||||||
|
file.AddItem("DefaultDark", func() {
|
||||||
|
addWindow(mw, theme.DefaultDark)
|
||||||
|
})
|
||||||
|
|
||||||
|
menu.Supervise(mw.Supervisor())
|
||||||
|
menu.Compute(mw.Engine)
|
||||||
|
mw.Pack(menu, menu.PackTop())
|
||||||
|
|
||||||
|
mw.SetBackground(render.White)
|
||||||
|
|
||||||
|
mw.OnLoop(func(e *event.State) {
|
||||||
|
if e.Escape {
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
mw.MainLoop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a new child window.
|
||||||
|
func addWindow(mw *ui.MainWindow, theme theme.Theme) {
|
||||||
|
ui.Theme = theme
|
||||||
|
|
||||||
|
win1 := ui.NewWindow(theme.Name)
|
||||||
|
win1.SetButtons(ui.CloseButton)
|
||||||
|
win1.Configure(ui.Config{
|
||||||
|
Width: 320,
|
||||||
|
Height: 240,
|
||||||
|
})
|
||||||
|
win1.Compute(mw.Engine)
|
||||||
|
win1.Supervise(mw.Supervisor())
|
||||||
|
|
||||||
|
// Draw a label.
|
||||||
|
label := ui.NewLabel(ui.Label{
|
||||||
|
Text: theme.Name,
|
||||||
|
})
|
||||||
|
win1.Place(label, ui.Place{
|
||||||
|
Top: 10,
|
||||||
|
Left: 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add a button with tooltip.
|
||||||
|
btn2 := ui.NewButton(theme.Name+":Button2", ui.NewLabel(ui.Label{
|
||||||
|
Text: "Button",
|
||||||
|
}))
|
||||||
|
btn2.Handle(ui.Click, func(ed ui.EventData) error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
mw.Add(btn2)
|
||||||
|
win1.Place(btn2, ui.Place{
|
||||||
|
Top: 10,
|
||||||
|
Right: 10,
|
||||||
|
})
|
||||||
|
ui.NewTooltip(btn2, ui.Tooltip{
|
||||||
|
Text: "Hello world!",
|
||||||
|
Edge: ui.Bottom,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add a checkbox.
|
||||||
|
var b bool
|
||||||
|
cb := ui.NewCheckbox("Checkbox", &b, ui.NewLabel(ui.Label{
|
||||||
|
Text: "Check me!",
|
||||||
|
}))
|
||||||
|
mw.Add(cb)
|
||||||
|
win1.Place(cb, ui.Place{
|
||||||
|
Top: 30,
|
||||||
|
Left: 10,
|
||||||
|
})
|
||||||
|
}
|
169
eg/themes/main_wasm.go
Normal file
169
eg/themes/main_wasm.go
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
// +build js,wasm
|
||||||
|
|
||||||
|
// WebAssembly version of the window manager demo.
|
||||||
|
// To build: make wasm
|
||||||
|
// To test: make wasm-serve
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.kirsle.net/go/render"
|
||||||
|
"git.kirsle.net/go/render/canvas"
|
||||||
|
"git.kirsle.net/go/ui"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Program globals.
|
||||||
|
var (
|
||||||
|
ThrottleFPS = 1000 / 60
|
||||||
|
|
||||||
|
// Size of the MainWindow.
|
||||||
|
Width = 1024
|
||||||
|
Height = 768
|
||||||
|
|
||||||
|
// Cascade offset for creating multiple windows.
|
||||||
|
Cascade = render.NewPoint(10, 32)
|
||||||
|
CascadeStep = render.NewPoint(24, 24)
|
||||||
|
CascadeLoops = 1
|
||||||
|
|
||||||
|
// Colors for each window created.
|
||||||
|
WindowColors = []render.Color{
|
||||||
|
render.Blue,
|
||||||
|
render.Red,
|
||||||
|
render.DarkYellow,
|
||||||
|
render.DarkGreen,
|
||||||
|
render.DarkCyan,
|
||||||
|
render.DarkBlue,
|
||||||
|
render.DarkRed,
|
||||||
|
}
|
||||||
|
WindowID int
|
||||||
|
OpenWindows int
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mw, err := canvas.New("canvas")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind DOM event handlers.
|
||||||
|
mw.AddEventListeners()
|
||||||
|
|
||||||
|
supervisor := ui.NewSupervisor()
|
||||||
|
|
||||||
|
frame := ui.NewFrame("Main Frame")
|
||||||
|
frame.Resize(render.NewRect(mw.WindowSize()))
|
||||||
|
frame.Compute(mw)
|
||||||
|
|
||||||
|
_, height := mw.WindowSize()
|
||||||
|
lbl := ui.NewLabel(ui.Label{
|
||||||
|
Text: "Window Manager Demo",
|
||||||
|
Font: render.Text{
|
||||||
|
FontFilename: "DejaVuSans.ttf",
|
||||||
|
Size: 32,
|
||||||
|
Color: render.SkyBlue,
|
||||||
|
Shadow: render.SkyBlue.Darken(60),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
lbl.Compute(mw)
|
||||||
|
lbl.MoveTo(render.NewPoint(
|
||||||
|
20,
|
||||||
|
height-lbl.Size().H-20,
|
||||||
|
))
|
||||||
|
|
||||||
|
// Menu bar.
|
||||||
|
menu := ui.NewMenuBar("Main Menu")
|
||||||
|
file := menu.AddMenu("Options")
|
||||||
|
file.AddItem("New window", func() {
|
||||||
|
addWindow(mw, frame, supervisor)
|
||||||
|
})
|
||||||
|
file.AddItem("Close all windows", func() {
|
||||||
|
OpenWindows -= supervisor.CloseAllWindows()
|
||||||
|
})
|
||||||
|
|
||||||
|
menu.Supervise(supervisor)
|
||||||
|
menu.Compute(mw)
|
||||||
|
frame.Pack(menu, menu.PackTop())
|
||||||
|
|
||||||
|
// Add some windows to play with.
|
||||||
|
addWindow(mw, frame, supervisor)
|
||||||
|
addWindow(mw, frame, supervisor)
|
||||||
|
|
||||||
|
for {
|
||||||
|
mw.Clear(render.RGBA(255, 255, 200, 255))
|
||||||
|
start := time.Now()
|
||||||
|
ev, err := mw.Poll()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
frame.Present(mw, frame.Point())
|
||||||
|
lbl.Present(mw, lbl.Point())
|
||||||
|
supervisor.Loop(ev)
|
||||||
|
supervisor.Present(mw)
|
||||||
|
|
||||||
|
var delay uint32
|
||||||
|
elapsed := time.Now().Sub(start)
|
||||||
|
tmp := elapsed / time.Millisecond
|
||||||
|
if ThrottleFPS-int(tmp) > 0 {
|
||||||
|
delay = uint32(ThrottleFPS - int(tmp))
|
||||||
|
}
|
||||||
|
mw.Delay(delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a new child window.
|
||||||
|
func addWindow(engine render.Engine, parent *ui.Frame, sup *ui.Supervisor) {
|
||||||
|
var (
|
||||||
|
color = WindowColors[WindowID%len(WindowColors)]
|
||||||
|
title = fmt.Sprintf("Window %d", WindowID+1)
|
||||||
|
)
|
||||||
|
WindowID++
|
||||||
|
|
||||||
|
win1 := ui.NewWindow(title)
|
||||||
|
win1.SetButtons(ui.CloseButton)
|
||||||
|
win1.ActiveTitleBackground = color
|
||||||
|
win1.InactiveTitleBackground = color.Darken(60)
|
||||||
|
win1.InactiveTitleForeground = render.Grey
|
||||||
|
win1.Configure(ui.Config{
|
||||||
|
Width: 320,
|
||||||
|
Height: 240,
|
||||||
|
})
|
||||||
|
win1.Compute(engine)
|
||||||
|
win1.Supervise(sup)
|
||||||
|
|
||||||
|
// Re-open a window when the last one is closed.
|
||||||
|
OpenWindows++
|
||||||
|
win1.Handle(ui.CloseWindow, func(ed ui.EventData) error {
|
||||||
|
OpenWindows--
|
||||||
|
if OpenWindows <= 0 {
|
||||||
|
addWindow(engine, parent, sup)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// Default placement via cascade.
|
||||||
|
win1.MoveTo(Cascade)
|
||||||
|
Cascade.Add(CascadeStep)
|
||||||
|
if Cascade.Y > Height-240-64 {
|
||||||
|
CascadeLoops++
|
||||||
|
Cascade.Y = 24
|
||||||
|
Cascade.X = 24 * CascadeLoops
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a window duplicator button.
|
||||||
|
btn2 := ui.NewButton(title+":Button2", ui.NewLabel(ui.Label{
|
||||||
|
Text: "New Window",
|
||||||
|
}))
|
||||||
|
btn2.Handle(ui.Click, func(ed ui.EventData) error {
|
||||||
|
addWindow(engine, parent, sup)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
sup.Add(btn2)
|
||||||
|
win1.Place(btn2, ui.Place{
|
||||||
|
Top: 10,
|
||||||
|
Right: 10,
|
||||||
|
})
|
||||||
|
}
|
14
label.go
14
label.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.kirsle.net/go/render"
|
"git.kirsle.net/go/render"
|
||||||
|
"git.kirsle.net/go/ui/style"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultFont is the default font settings used for a Label.
|
// DefaultFont is the default font settings used for a Label.
|
||||||
|
@ -23,6 +24,7 @@ type Label struct {
|
||||||
IntVariable *int
|
IntVariable *int
|
||||||
Font render.Text
|
Font render.Text
|
||||||
|
|
||||||
|
style *style.Label
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
lineHeight int
|
lineHeight int
|
||||||
|
@ -36,6 +38,7 @@ func NewLabel(c Label) *Label {
|
||||||
IntVariable: c.IntVariable,
|
IntVariable: c.IntVariable,
|
||||||
Font: DefaultFont,
|
Font: DefaultFont,
|
||||||
}
|
}
|
||||||
|
w.SetStyle(Theme.Label)
|
||||||
if !c.Font.IsZero() {
|
if !c.Font.IsZero() {
|
||||||
w.Font = c.Font
|
w.Font = c.Font
|
||||||
}
|
}
|
||||||
|
@ -45,6 +48,17 @@ func NewLabel(c Label) *Label {
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetStyle sets the label's default style.
|
||||||
|
func (w *Label) SetStyle(v *style.Label) {
|
||||||
|
if v == nil {
|
||||||
|
v = &style.DefaultLabel
|
||||||
|
}
|
||||||
|
|
||||||
|
w.style = v
|
||||||
|
w.SetBackground(w.style.Background)
|
||||||
|
w.Font.Color = w.style.Foreground
|
||||||
|
}
|
||||||
|
|
||||||
// text returns the label's displayed text, coming from the TextVariable if
|
// text returns the label's displayed text, coming from the TextVariable if
|
||||||
// available or else the Text attribute instead.
|
// available or else the Text attribute instead.
|
||||||
func (w *Label) text() render.Text {
|
func (w *Label) text() render.Text {
|
||||||
|
|
71
style/button.go
Normal file
71
style/button.go
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
// Package style provides style definitions for UI components.
|
||||||
|
package style
|
||||||
|
|
||||||
|
import "git.kirsle.net/go/render"
|
||||||
|
|
||||||
|
// Default styles for widgets without a theme.
|
||||||
|
var (
|
||||||
|
DefaultWindow = Window{
|
||||||
|
ActiveTitleBackground: render.Blue,
|
||||||
|
ActiveTitleForeground: render.White,
|
||||||
|
InactiveTitleBackground: render.DarkGrey,
|
||||||
|
InactiveTitleForeground: render.Grey,
|
||||||
|
ActiveBackground: render.Grey,
|
||||||
|
InactiveBackground: render.Grey,
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultLabel = Label{
|
||||||
|
Background: render.Invisible,
|
||||||
|
Foreground: render.Black,
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultButton = Button{
|
||||||
|
Background: render.RGBA(200, 200, 200, 255),
|
||||||
|
Foreground: render.Black,
|
||||||
|
OutlineColor: render.Black,
|
||||||
|
OutlineSize: 1,
|
||||||
|
HoverBackground: render.RGBA(200, 255, 255, 255),
|
||||||
|
HoverForeground: render.Black,
|
||||||
|
BorderStyle: BorderRaised,
|
||||||
|
BorderSize: 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultTooltip = Tooltip{
|
||||||
|
Background: render.RGBA(0, 0, 0, 230),
|
||||||
|
Foreground: render.White,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Window style configuration.
|
||||||
|
type Window struct {
|
||||||
|
ActiveTitleBackground render.Color
|
||||||
|
ActiveTitleForeground render.Color
|
||||||
|
ActiveBackground render.Color
|
||||||
|
InactiveTitleBackground render.Color
|
||||||
|
InactiveTitleForeground render.Color
|
||||||
|
InactiveBackground render.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
// Label style configuration.
|
||||||
|
type Label struct {
|
||||||
|
Background render.Color
|
||||||
|
Foreground render.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button style configuration.
|
||||||
|
type Button struct {
|
||||||
|
Background render.Color
|
||||||
|
Foreground render.Color // Labels only
|
||||||
|
OutlineColor render.Color
|
||||||
|
OutlineSize int
|
||||||
|
HoverBackground render.Color
|
||||||
|
HoverForeground render.Color
|
||||||
|
BorderStyle BorderStyle
|
||||||
|
BorderSize int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tooltip style configuration.
|
||||||
|
type Tooltip struct {
|
||||||
|
Background render.Color
|
||||||
|
Foreground render.Color
|
||||||
|
}
|
13
style/style.go
Normal file
13
style/style.go
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Package style provides style definitions for UI components.
|
||||||
|
package style
|
||||||
|
|
||||||
|
// BorderStyle options for widget.SetBorderStyle()
|
||||||
|
type BorderStyle string
|
||||||
|
|
||||||
|
// Styles for a widget border.
|
||||||
|
const (
|
||||||
|
BorderNone BorderStyle = ""
|
||||||
|
BorderSolid BorderStyle = "solid"
|
||||||
|
BorderRaised = "raised"
|
||||||
|
BorderSunken = "sunken"
|
||||||
|
)
|
6
theme.go
Normal file
6
theme.go
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
package ui
|
||||||
|
|
||||||
|
import "git.kirsle.net/go/ui/theme"
|
||||||
|
|
||||||
|
// Theme sets the default theme used when creating new widgets.
|
||||||
|
var Theme = theme.Default
|
|
@ -1,6 +1,9 @@
|
||||||
package theme
|
package theme
|
||||||
|
|
||||||
import "git.kirsle.net/go/render"
|
import (
|
||||||
|
"git.kirsle.net/go/render"
|
||||||
|
"git.kirsle.net/go/ui/style"
|
||||||
|
)
|
||||||
|
|
||||||
// Color schemes.
|
// Color schemes.
|
||||||
var (
|
var (
|
||||||
|
@ -10,3 +13,64 @@ var (
|
||||||
|
|
||||||
BorderColorOffset = 40
|
BorderColorOffset = 40
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Theme is a collection of styles for various built-in widgets.
|
||||||
|
type Theme struct {
|
||||||
|
Name string
|
||||||
|
Window *style.Window
|
||||||
|
Label *style.Label
|
||||||
|
Button *style.Button
|
||||||
|
Tooltip *style.Tooltip
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default theme.
|
||||||
|
var Default = Theme{
|
||||||
|
Name: "Default",
|
||||||
|
Label: &style.DefaultLabel,
|
||||||
|
Button: &style.DefaultButton,
|
||||||
|
Tooltip: &style.DefaultTooltip,
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultFlat is a flat version of the default theme.
|
||||||
|
var DefaultFlat = Theme{
|
||||||
|
Name: "DefaultFlat",
|
||||||
|
Button: &style.Button{
|
||||||
|
Background: style.DefaultButton.Background,
|
||||||
|
Foreground: style.DefaultButton.Foreground,
|
||||||
|
OutlineColor: style.DefaultButton.OutlineColor,
|
||||||
|
OutlineSize: 1,
|
||||||
|
HoverBackground: style.DefaultButton.HoverBackground,
|
||||||
|
HoverForeground: style.DefaultButton.HoverForeground,
|
||||||
|
BorderStyle: style.BorderSolid,
|
||||||
|
BorderSize: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultDark is a dark version of the default theme.
|
||||||
|
var DefaultDark = Theme{
|
||||||
|
Name: "DefaultDark",
|
||||||
|
Label: &style.Label{
|
||||||
|
Foreground: render.Grey,
|
||||||
|
},
|
||||||
|
Window: &style.Window{
|
||||||
|
ActiveTitleBackground: render.Red,
|
||||||
|
ActiveTitleForeground: render.White,
|
||||||
|
InactiveTitleBackground: render.DarkGrey,
|
||||||
|
InactiveTitleForeground: render.Grey,
|
||||||
|
ActiveBackground: render.Black,
|
||||||
|
InactiveBackground: render.Black,
|
||||||
|
},
|
||||||
|
Button: &style.Button{
|
||||||
|
Background: render.Black,
|
||||||
|
Foreground: render.Grey,
|
||||||
|
OutlineColor: render.DarkGrey,
|
||||||
|
OutlineSize: 1,
|
||||||
|
HoverBackground: render.Grey,
|
||||||
|
BorderStyle: style.BorderRaised,
|
||||||
|
BorderSize: 2,
|
||||||
|
},
|
||||||
|
Tooltip: &style.Tooltip{
|
||||||
|
Background: render.RGBA(60, 60, 60, 230),
|
||||||
|
Foreground: render.Cyan,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
15
tooltip.go
15
tooltip.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.kirsle.net/go/render"
|
"git.kirsle.net/go/render"
|
||||||
|
"git.kirsle.net/go/ui/style"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -20,6 +21,7 @@ type Tooltip struct {
|
||||||
TextVariable *string // String pointer instead of text.
|
TextVariable *string // String pointer instead of text.
|
||||||
Edge Edge // side to display tooltip on
|
Edge Edge // side to display tooltip on
|
||||||
|
|
||||||
|
style *style.Tooltip
|
||||||
target Widget
|
target Widget
|
||||||
lineHeight int
|
lineHeight int
|
||||||
font render.Text
|
font render.Text
|
||||||
|
@ -74,9 +76,22 @@ func NewTooltip(target Widget, tt Tooltip) *Tooltip {
|
||||||
return fmt.Sprintf(`Tooltip<"%s">`, w.Value())
|
return fmt.Sprintf(`Tooltip<"%s">`, w.Value())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
w.SetStyle(Theme.Tooltip)
|
||||||
|
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetStyle sets the tooltip's default style.
|
||||||
|
func (w *Tooltip) SetStyle(v *style.Tooltip) {
|
||||||
|
if v == nil {
|
||||||
|
v = &style.DefaultTooltip
|
||||||
|
}
|
||||||
|
|
||||||
|
w.style = v
|
||||||
|
w.SetBackground(w.style.Background)
|
||||||
|
w.font.Color = w.style.Foreground
|
||||||
|
}
|
||||||
|
|
||||||
// Value returns the current text displayed in the tooltop, whether from the
|
// Value returns the current text displayed in the tooltop, whether from the
|
||||||
// configured Text or the TextVariable pointer.
|
// configured Text or the TextVariable pointer.
|
||||||
func (w *Tooltip) Value() string {
|
func (w *Tooltip) Value() string {
|
||||||
|
|
39
window.go
39
window.go
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.kirsle.net/go/render"
|
"git.kirsle.net/go/render"
|
||||||
|
"git.kirsle.net/go/ui/style"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Window is a frame with a title bar.
|
// Window is a frame with a title bar.
|
||||||
|
@ -19,6 +20,7 @@ type Window struct {
|
||||||
InactiveTitleForeground render.Color
|
InactiveTitleForeground render.Color
|
||||||
|
|
||||||
// Private widgets.
|
// Private widgets.
|
||||||
|
style *style.Window
|
||||||
body *Frame
|
body *Frame
|
||||||
titleBar *Frame
|
titleBar *Frame
|
||||||
titleLabel *Label
|
titleLabel *Label
|
||||||
|
@ -58,12 +60,6 @@ func NewWindow(title string) *Window {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
w.body.Configure(Config{
|
|
||||||
Background: render.Grey,
|
|
||||||
BorderSize: 2,
|
|
||||||
BorderStyle: BorderRaised,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Title bar widget.
|
// Title bar widget.
|
||||||
titleBar, titleLabel := w.setupTitleBar()
|
titleBar, titleLabel := w.setupTitleBar()
|
||||||
w.body.Pack(titleBar, Pack{
|
w.body.Pack(titleBar, Pack{
|
||||||
|
@ -87,9 +83,32 @@ func NewWindow(title string) *Window {
|
||||||
// Set up parent/child relationships
|
// Set up parent/child relationships
|
||||||
w.body.SetParent(w)
|
w.body.SetParent(w)
|
||||||
|
|
||||||
|
w.SetStyle(Theme.Window)
|
||||||
|
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetStyle sets the window style.
|
||||||
|
func (w *Window) SetStyle(v *style.Window) {
|
||||||
|
if v == nil {
|
||||||
|
v = &style.DefaultWindow
|
||||||
|
}
|
||||||
|
|
||||||
|
w.style = v
|
||||||
|
w.body.Configure(Config{
|
||||||
|
Background: w.style.ActiveBackground,
|
||||||
|
BorderSize: 2,
|
||||||
|
BorderStyle: BorderRaised,
|
||||||
|
})
|
||||||
|
if w.focused {
|
||||||
|
w.titleBar.SetBackground(w.style.ActiveTitleBackground)
|
||||||
|
w.titleLabel.Font.Color = w.style.ActiveTitleForeground
|
||||||
|
} else {
|
||||||
|
w.titleBar.SetBackground(w.style.InactiveTitleBackground)
|
||||||
|
w.titleLabel.Font.Color = w.style.InactiveTitleForeground
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// setupTitlebar creates the title bar frame of the window.
|
// setupTitlebar creates the title bar frame of the window.
|
||||||
func (w *Window) setupTitleBar() (*Frame, *Label) {
|
func (w *Window) setupTitleBar() (*Frame, *Label) {
|
||||||
frame := NewFrame("Titlebar for Window: " + w.Title)
|
frame := NewFrame("Titlebar for Window: " + w.Title)
|
||||||
|
@ -260,12 +279,12 @@ func (w *Window) SetFocus(v bool) {
|
||||||
|
|
||||||
// Update the title bar colors.
|
// Update the title bar colors.
|
||||||
var (
|
var (
|
||||||
bg = w.ActiveTitleBackground
|
bg = w.style.ActiveTitleBackground
|
||||||
fg = w.ActiveTitleForeground
|
fg = w.style.ActiveTitleForeground
|
||||||
)
|
)
|
||||||
if !w.focused {
|
if !w.focused {
|
||||||
bg = w.InactiveTitleBackground
|
bg = w.style.InactiveTitleBackground
|
||||||
fg = w.InactiveTitleForeground
|
fg = w.style.InactiveTitleForeground
|
||||||
}
|
}
|
||||||
w.titleBar.SetBackground(bg)
|
w.titleBar.SetBackground(bg)
|
||||||
w.titleLabel.Font.Color = fg
|
w.titleLabel.Font.Color = fg
|
||||||
|
|
Loading…
Reference in New Issue
Block a user