Compare commits

..

No commits in common. "bfd6ae49df9a64e675d99fe8040dcaedef57b9bc" and "b9514a08ff0e0120003f646627d24d1cc52914ad" have entirely different histories.

2 changed files with 48 additions and 177 deletions

View File

@ -16,12 +16,6 @@ import (
"golang.org/x/image/font/gofont/goregular" "golang.org/x/image/font/gofont/goregular"
) )
func NewButton(face text.Face, t string, c color.RGBA) giowrap.Clickable {
lbl := giowrap.NewLabel(t, giowrap.LabelFace(face), giowrap.LabelAlignment(text.Center))
bg := giowrap.NewBackground(giowrap.BgColor(c), giowrap.BgRadius(ui.Dp(4)))
return giowrap.AsClickable(bg(lbl))
}
func main() { func main() {
go func() { go func() {
w := app.NewWindow(nil) w := app.NewWindow(nil)
@ -31,21 +25,24 @@ func main() {
} }
ctx := giowrap.NewContext(w) ctx := giowrap.NewContext(w)
t := time.NewTicker(time.Second/30) t := time.NewTicker(time.Second/30)
e1 := giowrap.NewEditor("text 1",giowrap.EditorFace(ctx.Faces.For(regular, ui.Sp(24)))) e1 := giowrap.NewEditor(ctx.Faces.For(regular, ui.Sp(24)), true)
e1.SetText("text 1")
e1.Focus() e1.Focus()
e2 := giowrap.NewEditor("text 2",giowrap.EditorFace(ctx.Faces.For(regular, ui.Sp(24)))) e2 := giowrap.NewEditor(ctx.Faces.For(regular, ui.Sp(24)), true)
e2.SetText("text 2")
f1 := giowrap.NewFlex(giowrap.FlexAxis(layout.Vertical)) f := giowrap.NewFlex(layout.Vertical, layout.Start, layout.Start)
OuterInset := giowrap.NewInset(giowrap.InsetSize(ui.Dp(10))) OuterInset := giowrap.NewInset(ui.Dp(10),ui.Dp(10),ui.Dp(10),ui.Dp(10))
InnerInset := giowrap.NewInset(giowrap.InsetSize(ui.Dp(10))) InnerInset := giowrap.NewInset(ui.Dp(10),ui.Dp(10),ui.Dp(10),ui.Dp(10))
f2 := giowrap.NewFlex(giowrap.FlexAxis(layout.Horizontal)) lbl := giowrap.NewLabel(
ctx.Faces.For(regular, ui.Sp(24)),
btn1 := NewButton(ctx.Faces.For(regular, ui.Sp(24)), "push",
"push1", color.RGBA{A: 0xff, R: 0x3c, G: 0x98, B: 0xc6}) text.Center,
btn2 := NewButton(ctx.Faces.For(regular, ui.Sp(24)), )
"push2", color.RGBA{A: 0xff, R: 0x3c, G: 0x98, B: 0xc6}) bg := giowrap.NewBackground(color.RGBA{A: 0xff, R: 0x3c, G: 0x98, B: 0xc6}, ui.Dp(4))
btn := giowrap.Clickable(bg(lbl))
for { for {
select { select {
@ -58,22 +55,15 @@ func main() {
case app.DrawEvent: case app.DrawEvent:
ctx = ctx.Reset(e) ctx = ctx.Reset(e)
ctx = OuterInset( ctx = OuterInset(
f1( f(
e1, e1,
giowrap.Flexible(5), giowrap.Flexible(5),
InnerInset(e2), InnerInset(e2),
giowrap.Flexible(10), giowrap.Flexible(10),
f2( btn,
InnerInset(btn1),
giowrap.Flexible(1),
InnerInset(btn2),
),
)).Layout(ctx) )).Layout(ctx)
ctx.Draw() ctx.Draw()
if btn1.Clicked(ctx) { if btn.Clicked(ctx) {
log.Print("Clicked: " + e1.Text() )
}
if btn2.Clicked(ctx) {
log.Print("Clicked: " + e2.Text() ) log.Print("Clicked: " + e2.Text() )
} }
} }

181
main.go
View File

@ -2,8 +2,7 @@ package giowrap
import ( import (
"image/color" "image/color"
//"log" "log"
"sync"
"gioui.org/ui" "gioui.org/ui"
"gioui.org/ui/app" "gioui.org/ui/app"
@ -18,24 +17,6 @@ import (
"gioui.org/ui/pointer" "gioui.org/ui/pointer"
) )
type Extra struct {
cur, max int
sync.Mutex
data []interface{}
}
var extra Extra
func (e *Extra) New() int {
e.Lock()
if e.data == nil { e.data = make([]interface{},0) }
ret := e.max
e.max = e.max + 1
e.data = append(e.data,nil)
e.Unlock()
return ret
}
type Context struct { type Context struct {
Faces measure.Faces Faces measure.Faces
@ -45,15 +26,16 @@ type Context struct {
ops *ui.Ops ops *ui.Ops
cs layout.Constraints cs layout.Constraints
dims layout.Dimens dims layout.Dimens
extra map[string]interface{}
} }
func NewContext(w *app.Window) Context { func NewContext(w *app.Window) Context {
ret := Context{ return Context{
w: w, w: w,
ops: new(ui.Ops), ops: new(ui.Ops),
q: w.Queue(), q: w.Queue(),
extra: make(map[string]interface{}),
} }
return ret
} }
func (ctx Context) Reset(e app.DrawEvent) Context { func (ctx Context) Reset(e app.DrawEvent) Context {
@ -80,26 +62,12 @@ type Label struct {
l *text.Label l *text.Label
} }
type LabelOpts struct { func NewLabel(face text.Face, t string, alignment text.Alignment) *Label {
face text.Face
alignment text.Alignment
}
type LabelOption func(*LabelOpts)
func LabelFace(x text.Face) LabelOption {
return func(o *LabelOpts) { o.face = x }
}
func LabelAlignment(x text.Alignment) LabelOption {
return func(o *LabelOpts) { o.alignment = x }
}
func NewLabel(t string, lops ...LabelOption) *Label {
ret := &Label{} ret := &Label{}
opts := &LabelOpts{}
for _,o := range lops { o(opts) }
ret.l = &text.Label{ ret.l = &text.Label{
Face: opts.face, Face: face,
Text: t, Text: t,
Alignment: opts.alignment, Alignment: alignment,
} }
return ret return ret
} }
@ -113,24 +81,9 @@ type Editor struct {
e *text.Editor e *text.Editor
} }
type EditorOpts struct { func NewEditor(face text.Face, singleline bool) *Editor {
face text.Face
singleline bool
}
type EditorOption func(*EditorOpts)
func EditorFace(x text.Face) EditorOption {
return func(o *EditorOpts) { o.face = x }
}
func EditorSingleline() EditorOption {
return func(o *EditorOpts) { o.singleline = true }
}
func NewEditor(t string, eops ...EditorOption) *Editor {
ret := &Editor{} ret := &Editor{}
opts := &EditorOpts{} ret.e = &text.Editor{ Face: face, SingleLine: singleline }
for _,o := range eops { o(opts) }
ret.e = &text.Editor{ Face: opts.face, SingleLine: opts.singleline }
ret.SetText(t)
return ret return ret
} }
@ -157,57 +110,33 @@ func (fw fWidget) Layout(ctx Context) Context {
type Flex WidgetCombinator type Flex WidgetCombinator
// This "Widget" does nothing except set the Flexible field of a FlexOpts // This "Widget" does nothing except set the Flexible key of ctx.extra.
// struct within the Extra data structure
func Flexible(v float32) Widget { func Flexible(v float32) Widget {
return NewfWidget(func(ctx Context) Context { return NewfWidget(func(ctx Context) Context {
extra.data[extra.cur].(*FlexOpts).flexible = v ctx.extra["Flexible"] = v
return ctx return ctx
}) })
} }
type FlexOpts struct {
axis layout.Axis
mainAxisAlignment layout.MainAxisAlignment
crossAxisAlignment layout.CrossAxisAlignment
flexible float32
}
type FlexOption func(*FlexOpts)
func FlexAxis(x layout.Axis) FlexOption {
return func(o *FlexOpts) { o.axis = x }
}
func MainAxisAlignment(x layout.MainAxisAlignment) FlexOption {
return func(o *FlexOpts) { o.mainAxisAlignment = x }
}
func CrossAxisAlignment(x layout.CrossAxisAlignment) FlexOption {
return func(o *FlexOpts) { o.crossAxisAlignment = x }
}
// NewFlex returns a WidgetCombinator that wraps the layout.Flex element. // NewFlex returns a WidgetCombinator that wraps the layout.Flex element.
func NewFlex(fos ...FlexOption) Flex { func NewFlex(axis layout.Axis, mainAxisAlignment layout.MainAxisAlignment, crossAxisAlignment layout.CrossAxisAlignment) Flex {
opts := &FlexOpts{}
for _,o := range fos { o(opts) }
f := layout.Flex{ f := layout.Flex{
Axis: opts.axis, Axis: axis,
MainAxisAlignment: opts.mainAxisAlignment, MainAxisAlignment: mainAxisAlignment,
CrossAxisAlignment: opts.crossAxisAlignment, CrossAxisAlignment: crossAxisAlignment,
} }
index := extra.New()
extra.data[index] = opts
return func(ws ...Widget) Widget { return func(ws ...Widget) Widget {
return NewfWidget(func(ctx Context) Context { return NewfWidget(func(ctx Context) Context {
// ensure child widgets write options to the right place
extra.cur = index
opts := extra.data[index].(*FlexOpts)
f.Init(ctx.ops, ctx.cs) f.Init(ctx.ops, ctx.cs)
fcs := make([]layout.FlexChild,len(ws)) fcs := make([]layout.FlexChild,len(ws))
for i, w := range ws { for i, w := range ws {
if v := opts.flexible; v != 0 { if v,ok := ctx.extra["Flexible"]; ok {
ctx.cs = f.Flexible(v) switch v := v.(type) {
case float32:
ctx.cs = f.Flexible(v)
default:
log.Fatal("Type error")
}
} else { } else {
ctx.cs = f.Rigid() ctx.cs = f.Rigid()
} }
@ -215,43 +144,15 @@ func NewFlex(fos ...FlexOption) Flex {
fcs[i] = f.End(ctx.dims) fcs[i] = f.End(ctx.dims)
} }
ctx.dims = f.Layout(fcs...) ctx.dims = f.Layout(fcs...)
delete(ctx.extra, "Flexible")
return ctx return ctx
}) })
} }
} }
type InsetOpts struct {
top, right, bottom, left ui.Value
}
type InsetOption func(*InsetOpts)
func InsetTop(x ui.Value) InsetOption {
return func(o *InsetOpts) { o.top = x }
}
func InsetRight(x ui.Value) InsetOption {
return func(o *InsetOpts) { o.right = x }
}
func InsetBottom(x ui.Value) InsetOption {
return func(o *InsetOpts) { o.bottom = x }
}
func InsetLeft(x ui.Value) InsetOption {
return func(o *InsetOpts) { o.left = x }
}
func InsetSize(x ui.Value) InsetOption {
return func(o *InsetOpts) {
o.top = x
o.right = x
o.bottom = x
o.left = x
}
}
//NewInset returns a WidgetCombinator that wraps the layout.Inset element. //NewInset returns a WidgetCombinator that wraps the layout.Inset element.
func NewInset(insos ...InsetOption) WidgetCombinator { func NewInset(top, right, bottom, left ui.Value) WidgetCombinator {
opts := &InsetOpts{} ins := layout.Inset{ Top: top, Right: right, Bottom: bottom, Left: left }
for _,o := range insos { o(opts) }
ins := layout.Inset{ Top: opts.top, Right: opts.right, Bottom: opts.bottom, Left: opts.left }
return func(ws ...Widget) Widget { return func(ws ...Widget) Widget {
return NewfWidget(func(ctx Context) Context { return NewfWidget(func(ctx Context) Context {
ctx.cs = ins.Begin(ctx.c, ctx.ops, ctx.cs) ctx.cs = ins.Begin(ctx.c, ctx.ops, ctx.cs)
@ -289,27 +190,12 @@ func Enclose(e Enclosure, ws ...Widget) Widget {
}) })
} }
type BackgroundOpts struct { func NewBackground(color color.RGBA, radius ui.Value) WidgetCombinator {
c color.RGBA
radius ui.Value
}
type BackgroundOption func(*BackgroundOpts)
func BgColor(c color.RGBA) BackgroundOption {
return func(o *BackgroundOpts) { o.c = c }
}
func BgRadius(x ui.Value) BackgroundOption {
return func(o *BackgroundOpts) { o.radius = x }
}
func NewBackground(bos ...BackgroundOption) WidgetCombinator {
opts := &BackgroundOpts{}
for _,o := range bos { o(opts) }
bg := &Background{ bg := &Background{
Color: opts.c, Color: color,
Radius: opts.radius, Radius: radius,
Inset: layout.UniformInset(opts.radius), Inset: layout.UniformInset(radius), // FIXME: need to be able to
} } // do math ops on Values
return func(ws ...Widget) Widget { return func(ws ...Widget) Widget {
return Enclose(bg, ws...) return Enclose(bg, ws...)
} }
@ -358,11 +244,6 @@ func rrect(ops *ui.Ops, width, height, se, sw, nw, ne float32) {
b.End() b.End()
} }
type Clickable interface {
Widget
Clicked(Context) bool
}
//cWidget is a clickable Widget that provides the Clicked() method. //cWidget is a clickable Widget that provides the Clicked() method.
type cWidget struct { type cWidget struct {
w Widget w Widget
@ -386,6 +267,6 @@ func (w cWidget) Clicked(ctx Context) bool {
} }
//Clickable converts any Widget into a clickable Widget. //Clickable converts any Widget into a clickable Widget.
func AsClickable(w Widget) cWidget { func Clickable(w Widget) cWidget {
return cWidget{ w: w, click: new(gesture.Click) } return cWidget{ w: w, click: new(gesture.Click) }
} }