package control9 import ( "bitbucket.org/mischief/draw9" "fmt" "image" "log" "strings") type TextButton3 struct { *BaseControl font *draw9.Font image, mask *draw9.Image light, bordercolor *draw9.Image textcolor, pressedtextcolor *draw9.Image lastbut draw9.Mouse pressed, lastshow int lines []string border, align int left, middle, right int toggle, gettextflg int} // Control interface functions func (b *TextButton3) Ctl(e string) { log.Printf("%s ctl %s", b.name, e) f := strings.Fields(e) switch f[0] { default: log.Printf("%s: unrecognized message %s", b.name, e) case "align": b.align = ctlatoi(f[1]) b.lastshow = -1 case "border": b.border = ctlatoi(f[1]) b.lastshow = -1 case "bordercolor": b.bordercolor = geti(f[1]) b.lastshow = -1 case "focus": case "font": /* fixme */ b.lastshow = -1 case "format": /* fixme */ case "hide": b.hidden = true case "image": b.image = geti(f[1]) b.lastshow = -1 case "light": b.light = geti(f[1]) b.lastshow = -1 case "mask": b.mask = geti(f[1]) b.lastshow = -1 case "pressedcolor": b.pressedtextcolor = geti(f[1]) b.lastshow = -1 case "rect": if len(f) < 5 { log.Printf("%s: bad rectangle: %s", b.name, e) return } r := image.Rect(ctlatoi(f[1]), ctlatoi(f[2]), ctlatoi(f[3]), ctlatoi(f[4])) if r.Dx() <= 0 || r.Dy() <= 0 { log.Printf("%s: bad rectangle: %s", b.name, e) return } b.rect = r b.lastshow = -1 case "reveal": b.hidden = false b.lastshow = -1 b.show() case "show": b.lastshow = -1 b.show() case "size": if len(f) != 3 && len(f) != 5 { log.Printf("%s: bad rectangle: %s", b.name, e) return } r := image.Rect(ctlatoi(f[1]), ctlatoi(f[2]), 0x7fffffff, 0x7fffffff) if len(f) == 5 { r.Max.X = ctlatoi(f[3]) r.Max.Y = ctlatoi(f[4]) } if r.Min.X <= 0 || r.Min.Y <= 0 || r.Max.X <= 0 || r.Max.Y <= 0 || r.Max.X < r.Min.X || r.Max.Y < r.Min.Y { log.Printf("%s: bad rectangle: %s", b.name, e) return } b.size = r case "text": b.lines = strings.Split(strings.Join(f[1:], ""), "\n") b.lastshow = -1 b.show() case "textcolor": b.textcolor = geti(f[1]) b.lastshow = -1 case "value": arg := ctlatoi(f[1]) if arg != b.pressed { b.pressed ^= 1 b.show() } }}func (b *TextButton3) Mouse(m draw9.Mouse) { log.Printf("%s mouse %s", b.name, m) if b.left == 1 { if m.Mb1() && !b.lastbut.Mb1() { b.pressed ^= 1 b.show() b.lastbut = m } else if !m.Mb1() && b.lastbut.Mb1() { if b.gettextflg == 0 { b.event <- fmt.Sprintf(b.format, b.name, b.pressed, m.Pt().X, m.Pt().Y) } else { b.event <- fmt.Sprintf("%s: value %s", b.name, b.lines[0]) } b.pressed ^= 1 b.show() b.lastbut = m } } if b.middle == 1 { if m.Mb2() && !b.lastbut.Mb2() { b.pressed ^= 2 b.show() b.lastbut = m } else if !m.Mb2() && b.lastbut.Mb2() { if b.gettextflg == 0 { b.event <- fmt.Sprintf(b.format, b.name, b.pressed, m.Pt().X, m.Pt().Y) } else { b.event <- fmt.Sprintf("%s: value %s", b.name, b.lines[0]) } b.pressed ^= 2 b.show() b.lastbut = m } } if b.right == 1 { if m.Mb3() && !b.lastbut.Mb3() { b.pressed ^= 4 b.show() b.lastbut = m } else if !m.Mb3() && b.lastbut.Mb3() { if b.gettextflg == 0 { b.event <- fmt.Sprintf(b.format, b.name, b.pressed, m.Pt().X, m.Pt().Y) } else { b.event <- fmt.Sprintf("%s: value %s", b.name, b.lines[0]) } b.pressed ^= 4 b.show() b.lastbut = m } }} func (b *TextButton3) Key(c rune) {}func (b *TextButton3) Exit() {}func (b *TextButton3) SetSize() {}func (b *TextButton3) Activate() {} // TextButton3-specific // private junk // draw buttonfunc (b *TextButton3) show() { if b.hidden || b.lastshow == b.pressed { return } r := b.rect b.screen.Draw(r, b.image, nil, b.image.R.Min) if b.pressed > 0 || b.toggle > 0 { b.screen.Draw(r, b.light, b.mask, b.mask.R.Min) } if b.border > 0 { b.screen.Border(r, b.border, b.bordercolor, image.ZP) r = r.Inset(b.border) } dx := 0 f := b.font for _, s := range b.lines { w := f.StringWidth(s) if dx < w { dx = w } } dy := len(b.lines) * f.Height clipr := b.rect.Inset(b.border) pt := ctlalignpt(clipr, dx, dy, b.align) im := b.textcolor if b.pressed > 0 { im = b.pressedtextcolor } for i := 0; i < len(b.lines); i++ { r.Min = pt r.Max.X = pt.X + dx r.Max.Y = pt.Y + f.Height q := ctlalignpt(r, f.StringWidth(b.lines[i]), f.Height, b.align%3) b.screen.String(q, im, image.ZP, f, b.lines[i]) pt.Y += f.Height } b.lastshow = b.pressed b.image.Display.Flush()} // ctor // TextButton3 creates a new TextButton3 Control with the given name.func (cs *Controlset) TextButton3(name string) Control { b := &TextButton3{ BaseControl: cs.newctl(name, CtlTextButton3), image: geti("white"), mask: geti("transparent"), light: geti("yellow"), bordercolor: geti("black"), textcolor: geti("black"), pressedtextcolor: geti("black"), font: cs.screen.Display.DefaultFont, border: 2, align: 4, left: 1, middle: 1, right: 1, } b.format = "%s: value %d %d %d" cs.addctl(b) return b}
package control9
import (
"bitbucket.org/mischief/draw9"
"fmt"
"image"
"log"
"strings"
)
type TextButton3 struct {
*BaseControl
font *draw9.Font
image, mask *draw9.Image
light, bordercolor *draw9.Image
textcolor, pressedtextcolor *draw9.Image
lastbut draw9.Mouse
pressed, lastshow int
lines []string
border, align int
left, middle, right int
toggle, gettextflg int
}
// Control interface functions
func (b *TextButton3) Ctl(e string) {
log.Printf("%s ctl %s", b.name, e)
f := strings.Fields(e)
switch f[0] {
default:
log.Printf("%s: unrecognized message %s", b.name, e)
case "align":
b.align = ctlatoi(f[1])
b.lastshow = -1
case "border":
b.border = ctlatoi(f[1])
b.lastshow = -1
case "bordercolor":
b.bordercolor = geti(f[1])
b.lastshow = -1
case "focus":
case "font":
/* fixme */
b.lastshow = -1
case "format":
/* fixme */
case "hide":
b.hidden = true
case "image":
b.image = geti(f[1])
b.lastshow = -1
case "light":
b.light = geti(f[1])
b.lastshow = -1
case "mask":
b.mask = geti(f[1])
b.lastshow = -1
case "pressedcolor":
b.pressedtextcolor = geti(f[1])
b.lastshow = -1
case "rect":
if len(f) < 5 {
log.Printf("%s: bad rectangle: %s", b.name, e)
return
}
r := image.Rect(ctlatoi(f[1]), ctlatoi(f[2]), ctlatoi(f[3]), ctlatoi(f[4]))
if r.Dx() <= 0 || r.Dy() <= 0 {
log.Printf("%s: bad rectangle: %s", b.name, e)
return
}
b.rect = r
b.lastshow = -1
case "reveal":
b.hidden = false
b.lastshow = -1
b.show()
case "show":
b.lastshow = -1
b.show()
case "size":
if len(f) != 3 && len(f) != 5 {
log.Printf("%s: bad rectangle: %s", b.name, e)
return
}
r := image.Rect(ctlatoi(f[1]), ctlatoi(f[2]), 0x7fffffff, 0x7fffffff)
if len(f) == 5 {
r.Max.X = ctlatoi(f[3])
r.Max.Y = ctlatoi(f[4])
}
if r.Min.X <= 0 || r.Min.Y <= 0 || r.Max.X <= 0 || r.Max.Y <= 0 || r.Max.X < r.Min.X || r.Max.Y < r.Min.Y {
log.Printf("%s: bad rectangle: %s", b.name, e)
return
}
b.size = r
case "text":
b.lines = strings.Split(strings.Join(f[1:], ""), "\n")
b.lastshow = -1
b.show()
case "textcolor":
b.textcolor = geti(f[1])
b.lastshow = -1
case "value":
arg := ctlatoi(f[1])
if arg != b.pressed {
b.pressed ^= 1
b.show()
}
}
}
func (b *TextButton3) Mouse(m draw9.Mouse) {
log.Printf("%s mouse %s", b.name, m)
if b.left == 1 {
if m.Mb1() && !b.lastbut.Mb1() {
b.pressed ^= 1
b.show()
b.lastbut = m
} else if !m.Mb1() && b.lastbut.Mb1() {
if b.gettextflg == 0 {
b.event <- fmt.Sprintf(b.format, b.name, b.pressed, m.Pt().X, m.Pt().Y)
} else {
b.event <- fmt.Sprintf("%s: value %s", b.name, b.lines[0])
}
b.pressed ^= 1
b.show()
b.lastbut = m
}
}
if b.middle == 1 {
if m.Mb2() && !b.lastbut.Mb2() {
b.pressed ^= 2
b.show()
b.lastbut = m
} else if !m.Mb2() && b.lastbut.Mb2() {
if b.gettextflg == 0 {
b.event <- fmt.Sprintf(b.format, b.name, b.pressed, m.Pt().X, m.Pt().Y)
} else {
b.event <- fmt.Sprintf("%s: value %s", b.name, b.lines[0])
}
b.pressed ^= 2
b.show()
b.lastbut = m
}
}
if b.right == 1 {
if m.Mb3() && !b.lastbut.Mb3() {
b.pressed ^= 4
b.show()
b.lastbut = m
} else if !m.Mb3() && b.lastbut.Mb3() {
if b.gettextflg == 0 {
b.event <- fmt.Sprintf(b.format, b.name, b.pressed, m.Pt().X, m.Pt().Y)
} else {
b.event <- fmt.Sprintf("%s: value %s", b.name, b.lines[0])
}
b.pressed ^= 4
b.show()
b.lastbut = m
}
}
}
func (b *TextButton3) Key(c rune) {}
func (b *TextButton3) Exit() {}
func (b *TextButton3) SetSize() {}
func (b *TextButton3) Activate() {}
// TextButton3-specific
// private junk
// draw button
func (b *TextButton3) show() {
if b.hidden || b.lastshow == b.pressed {
return
}
r := b.rect
b.screen.Draw(r, b.image, nil, b.image.R.Min)
if b.pressed > 0 || b.toggle > 0 {
b.screen.Draw(r, b.light, b.mask, b.mask.R.Min)
}
if b.border > 0 {
b.screen.Border(r, b.border, b.bordercolor, image.ZP)
r = r.Inset(b.border)
}
dx := 0
f := b.font
for _, s := range b.lines {
w := f.StringWidth(s)
if dx < w {
dx = w
}
}
dy := len(b.lines) * f.Height
clipr := b.rect.Inset(b.border)
pt := ctlalignpt(clipr, dx, dy, b.align)
im := b.textcolor
if b.pressed > 0 {
im = b.pressedtextcolor
}
for i := 0; i < len(b.lines); i++ {
r.Min = pt
r.Max.X = pt.X + dx
r.Max.Y = pt.Y + f.Height
q := ctlalignpt(r, f.StringWidth(b.lines[i]), f.Height, b.align%3)
b.screen.String(q, im, image.ZP, f, b.lines[i])
pt.Y += f.Height
}
b.lastshow = b.pressed
b.image.Display.Flush()
}
// ctor
// TextButton3 creates a new TextButton3 Control with the given name.
func (cs *Controlset) TextButton3(name string) Control {
b := &TextButton3{
BaseControl: cs.newctl(name, CtlTextButton3),
image: geti("white"),
mask: geti("transparent"),
light: geti("yellow"),
bordercolor: geti("black"),
textcolor: geti("black"),
pressedtextcolor: geti("black"),
font: cs.screen.Display.DefaultFont,
border: 2,
align: 4,
left: 1,
middle: 1,
right: 1,
}
b.format = "%s: value %d %d %d"
cs.addctl(b)
return b
}