Add swatch
This commit is contained in:
parent
0b7e5392f4
commit
ae1e62c1f2
62
labelswatch.go
Normal file
62
labelswatch.go
Normal file
@ -0,0 +1,62 @@
|
||||
package objects
|
||||
|
||||
import "image/color"
|
||||
import "git.tebibyte.media/tomo/tomo"
|
||||
import "git.tebibyte.media/tomo/tomo/input"
|
||||
import "git.tebibyte.media/tomo/tomo/event"
|
||||
import "git.tebibyte.media/tomo/objects/layouts"
|
||||
|
||||
// LabelSwatch is a swatch with a label.
|
||||
type LabelSwatch struct {
|
||||
tomo.ContainerBox
|
||||
swatch *Swatch
|
||||
label *Label
|
||||
}
|
||||
|
||||
// NewLabelSwatch creates a new labeled swatch with the specified color and
|
||||
// label text.
|
||||
func NewLabelSwatch (value color.Color, text string) *LabelSwatch {
|
||||
box := &LabelSwatch {
|
||||
ContainerBox: tomo.NewContainerBox(),
|
||||
swatch: NewSwatch(value),
|
||||
label: NewLabel(text),
|
||||
}
|
||||
box.SetRole(tomo.R("objects", "LabelSwatch", ""))
|
||||
box.label.SetAlign(tomo.AlignStart, tomo.AlignMiddle)
|
||||
box.Add(box.swatch)
|
||||
box.Add(box.label)
|
||||
box.SetLayout(layouts.NewGrid([]bool { false, true }, []bool { false }))
|
||||
|
||||
box.OnMouseUp(box.handleMouseUp)
|
||||
box.label.OnMouseUp(box.handleMouseUp)
|
||||
return box
|
||||
}
|
||||
|
||||
// SetValue sets the color of the swatch.
|
||||
func (this *LabelSwatch) SetValue (value color.Color) {
|
||||
this.swatch.SetValue(value)
|
||||
}
|
||||
|
||||
// Value returns the color of the swatch.
|
||||
func (this *LabelSwatch) Value () color.Color {
|
||||
return this.swatch.Value()
|
||||
}
|
||||
|
||||
// RGBA satisfies the color.Color interface
|
||||
func (this *LabelSwatch) RGBA () (r, g, b, a uint32) {
|
||||
return this.swatch.RGBA()
|
||||
}
|
||||
|
||||
// OnValueChange specifies a function to be called when the swatch's color
|
||||
// changes.
|
||||
func (this *LabelSwatch) OnValueChange (callback func ()) event.Cookie {
|
||||
return this.swatch.OnValueChange(callback)
|
||||
}
|
||||
|
||||
func (this *LabelSwatch) handleMouseUp (button input.Button) {
|
||||
if button != input.ButtonLeft { return }
|
||||
if this.MousePosition().In(this.Bounds()) {
|
||||
this.swatch.SetFocused(true)
|
||||
this.swatch.Choose()
|
||||
}
|
||||
}
|
143
swatch.go
Normal file
143
swatch.go
Normal file
@ -0,0 +1,143 @@
|
||||
package objects
|
||||
|
||||
import "log"
|
||||
import "image"
|
||||
import "image/color"
|
||||
import "git.tebibyte.media/tomo/tomo"
|
||||
import "git.tebibyte.media/tomo/tomo/input"
|
||||
import "git.tebibyte.media/tomo/tomo/event"
|
||||
import "git.tebibyte.media/tomo/tomo/canvas"
|
||||
import "git.tebibyte.media/tomo/objects/layouts"
|
||||
|
||||
// Swatch displays a color, allowing the user to edit it by clicking on it.
|
||||
type Swatch struct {
|
||||
tomo.CanvasBox
|
||||
value color.Color
|
||||
editing bool
|
||||
on struct {
|
||||
valueChange event.FuncBroadcaster
|
||||
}
|
||||
}
|
||||
|
||||
// NewSwatch creates a new swatch with the given color.
|
||||
func NewSwatch (value color.Color) *Swatch {
|
||||
swatch := &Swatch {
|
||||
CanvasBox: tomo.NewCanvasBox(),
|
||||
}
|
||||
swatch.SetRole(tomo.R("objects", "Swatch", ""))
|
||||
swatch.SetDrawer(swatch)
|
||||
swatch.SetValue(value)
|
||||
|
||||
swatch.OnMouseUp(swatch.handleMouseUp)
|
||||
swatch.OnKeyUp(swatch.handleKeyUp)
|
||||
swatch.SetFocusable(true)
|
||||
return swatch
|
||||
}
|
||||
|
||||
// SetValue sets the color of the swatch.
|
||||
func (this *Swatch) SetValue (value color.Color) {
|
||||
this.value = value
|
||||
if value == nil { value = color.Transparent }
|
||||
this.Invalidate()
|
||||
}
|
||||
|
||||
// Value returns the color of the swatch.
|
||||
func (this *Swatch) Value () color.Color {
|
||||
return this.value
|
||||
}
|
||||
|
||||
// RGBA satisfies the color.Color interface
|
||||
func (this *Swatch) RGBA () (r, g, b, a uint32) {
|
||||
return this.value.RGBA()
|
||||
}
|
||||
|
||||
// OnValueChange specifies a function to be called when the swatch's color
|
||||
// changes.
|
||||
func (this *Swatch) OnValueChange (callback func ()) event.Cookie {
|
||||
return this.on.valueChange.Connect(callback)
|
||||
}
|
||||
|
||||
// Choose creates a modal that allows the user to edit the color of the swatch.
|
||||
func (this *Swatch) Choose () {
|
||||
if this.editing { return }
|
||||
|
||||
var err error
|
||||
var window tomo.Window
|
||||
if parent := this.Window(); parent != nil {
|
||||
window, err = parent.NewModal(image.Rectangle { })
|
||||
} else {
|
||||
window, err = tomo.NewWindow(image.Rectangle { })
|
||||
}
|
||||
if err != nil {
|
||||
log.Println("objects: could not create swatch modal:", err)
|
||||
return
|
||||
}
|
||||
window.SetTitle("Select Color")
|
||||
|
||||
colorPicker := NewColorPicker(this.Value())
|
||||
colorPicker.OnValueChange(func () {
|
||||
this.userSetValue(colorPicker.Value())
|
||||
})
|
||||
|
||||
colorMemory := this.value
|
||||
cancelButton := NewButton("Cancel")
|
||||
cancelButton.SetIcon(tomo.IconDialogCancel)
|
||||
cancelButton.OnClick(func () {
|
||||
this.userSetValue(colorMemory)
|
||||
window.Close()
|
||||
})
|
||||
okButton := NewButton("OK")
|
||||
okButton.SetFocused(true)
|
||||
okButton.SetIcon(tomo.IconDialogOkay)
|
||||
okButton.OnClick(func () {
|
||||
window.Close()
|
||||
})
|
||||
|
||||
controlRow := NewInnerContainer (
|
||||
layouts.ContractHorizontal,
|
||||
cancelButton,
|
||||
okButton)
|
||||
controlRow.SetAlign(tomo.AlignEnd, tomo.AlignMiddle)
|
||||
window.SetRoot(NewOuterContainer (
|
||||
layouts.Column { true, false },
|
||||
colorPicker,
|
||||
controlRow))
|
||||
window.OnClose(func () {
|
||||
this.editing = false
|
||||
})
|
||||
this.editing = true
|
||||
window.SetVisible(true)
|
||||
}
|
||||
|
||||
func (this *Swatch) Draw (can canvas.Canvas) {
|
||||
pen := can.Pen()
|
||||
|
||||
// transparency slash
|
||||
pen.Stroke(color.RGBA { R: 255, A: 255 })
|
||||
pen.StrokeWeight(1)
|
||||
pen.Path(this.Bounds().Min, this.Bounds().Max)
|
||||
|
||||
// color
|
||||
if this.value != nil {
|
||||
pen.StrokeWeight(0)
|
||||
pen.Fill(this.value)
|
||||
pen.Rectangle(this.Bounds())
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Swatch) userSetValue (value color.Color) {
|
||||
this.SetValue(value)
|
||||
this.on.valueChange.Broadcast()
|
||||
}
|
||||
|
||||
func (this *Swatch) handleKeyUp (key input.Key, numberPad bool) {
|
||||
if key != input.KeyEnter && key != input.Key(' ') { return }
|
||||
this.Choose()
|
||||
}
|
||||
|
||||
func (this *Swatch) handleMouseUp (button input.Button) {
|
||||
if button != input.ButtonLeft { return }
|
||||
if this.MousePosition().In(this.Bounds()) {
|
||||
this.Choose()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user