example: update gio version

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-10-08 21:38:09 +02:00
parent abb99eca5c
commit 88e58a98b3
5 changed files with 92 additions and 185 deletions
+3 -3
View File
@@ -3,9 +3,9 @@ module gioui.org/example
go 1.13 go 1.13
require ( require (
gioui.org v0.0.0-20191008153031-a76de40e9a40 gioui.org v0.0.0-20191012123625-abb99eca5c54
github.com/google/go-github/v24 v24.0.1 github.com/google/go-github/v24 v24.0.1
golang.org/x/exp v0.0.0-20190627132806-fd42eb6b336f golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9 golang.org/x/image v0.0.0-20190802002840-cff245a6509b
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
) )
+20 -10
View File
@@ -1,7 +1,9 @@
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
gioui.org v0.0.0-20191008153031-a76de40e9a40 h1:IPGGdRcrEaUmMUcs5ZAoQw6wqpLr+fRm0wD7eQT7HEA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
gioui.org v0.0.0-20191008153031-a76de40e9a40/go.mod h1:+CEjc9B//HrBfWsQOVxjCyih7HGIj3Pww1xFHVDZyyk= gioui.org v0.0.0-20191012123625-abb99eca5c54 h1:1LQMwF6UgHRaAbwvoaKWmnv5LwKt2HyXJooDvkNkmRg=
gioui.org v0.0.0-20191012123625-abb99eca5c54/go.mod h1:KqFFi2Dq5gYA3FJ0sDOt8OBXoMsuxMtE8v2f0JExXAY=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
@@ -12,30 +14,38 @@ github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASu
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20190627132806-fd42eb6b336f h1:F3VDpCbV+46wJMDIwbFSefCwLlvK2CoEKVEYHO8p5Os= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190627132806-fd42eb6b336f/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3 h1:n9HxLrNxWWtEb1cA950nuEEj3QnKbtsCJ6KjcgisNUs=
golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9 h1:uc17S921SPw5F2gJo7slQ3aqvr2RwpL7eb3+DZncu3s= golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+2 -2
View File
@@ -125,10 +125,10 @@ func (a *App) run() error {
a.w.Invalidate() a.w.Invalidate()
} }
} }
case app.UpdateEvent: case app.FrameEvent:
gtx.Reset(&e.Config, e.Size) gtx.Reset(&e.Config, e.Size)
a.ui.Layout(gtx) a.ui.Layout(gtx)
a.w.Update(gtx.Ops) e.Frame(gtx.Ops)
} }
} }
} }
+53 -149
View File
@@ -8,10 +8,9 @@ import (
"fmt" "fmt"
"image" "image"
"image/color" "image/color"
"log"
"runtime" "runtime"
"golang.org/x/image/draw"
_ "image/jpeg" _ "image/jpeg"
_ "image/png" _ "image/png"
@@ -26,28 +25,28 @@ import (
"gioui.org/op" "gioui.org/op"
"gioui.org/op/paint" "gioui.org/op/paint"
"gioui.org/text" "gioui.org/text"
"gioui.org/text/shape" "gioui.org/text/opentype"
"gioui.org/unit" "gioui.org/unit"
"gioui.org/widget" "gioui.org/widget"
"golang.org/x/exp/shiny/iconvg" "gioui.org/widget/material"
"github.com/google/go-github/v24/github" "github.com/google/go-github/v24/github"
"golang.org/x/image/font/gofont/gobold" "golang.org/x/image/font/gofont/gobold"
"golang.org/x/image/font/gofont/goitalic" "golang.org/x/image/font/gofont/goitalic"
"golang.org/x/image/font/gofont/gomono" "golang.org/x/image/font/gofont/gomono"
"golang.org/x/image/font/gofont/goregular" "golang.org/x/image/font/gofont/goregular"
"golang.org/x/image/font/sfnt"
"golang.org/x/exp/shiny/materialdesign/icons" "golang.org/x/exp/shiny/materialdesign/icons"
) )
type UI struct { type UI struct {
fab *ActionButton fab *widget.Button
fabIcon *material.Icon
usersList *layout.List usersList *layout.List
users []*user users []*user
userClicks []gesture.Click userClicks []gesture.Click
selectedUser *userPage selectedUser *userPage
edit, edit2 *text.Editor edit, edit2 *widget.Editor
fetchCommits func(u string) fetchCommits func(u string)
// Profiling. // Profiling.
@@ -69,55 +68,20 @@ type user struct {
avatar image.Image avatar image.Image
} }
type icon struct { var shaper *text.Shaper
src []byte
size unit.Value
// Cached values. var theme *material.Theme
img image.Image
imgSize int
}
type ActionButton struct {
Open bool
icons []*icon
sendIco *icon
}
var families struct {
primary text.Family
mono text.Family
}
var theme struct {
text op.MacroOp
tertText op.MacroOp
brand op.MacroOp
white op.MacroOp
}
func colorMaterial(ops *op.Ops, color color.RGBA) op.MacroOp {
var mat op.MacroOp
mat.Record(ops)
paint.ColorOp{Color: color}.Add(ops)
mat.Stop()
return mat
}
func init() { func init() {
families.primary = &shape.Family{ s := new(text.Shaper)
Regular: mustLoadFont(goregular.TTF), s.Register(text.Font{}, opentype.Must(opentype.Parse(goregular.TTF)))
Bold: mustLoadFont(gobold.TTF), s.Register(text.Font{Style: text.Italic}, opentype.Must(opentype.Parse(goitalic.TTF)))
Italic: mustLoadFont(goitalic.TTF), s.Register(text.Font{Weight: text.Bold}, opentype.Must(opentype.Parse(gobold.TTF)))
} s.Register(text.Font{Typeface: "mono"}, opentype.Must(opentype.Parse(gomono.TTF)))
families.mono = &shape.Family{ shaper = s
Regular: mustLoadFont(gomono.TTF), theme = material.NewTheme(s)
} theme.Color.Text = rgb(0x333333)
var ops op.Ops theme.Color.Hint = rgb(0xbbbbbb)
theme.text = colorMaterial(&ops, rgb(0x333333))
theme.tertText = colorMaterial(&ops, rgb(0xbbbbbb))
theme.brand = colorMaterial(&ops, rgb(0x62798c))
theme.white = colorMaterial(&ops, rgb(0xffffff))
} }
func newUI(fetchCommits func(string)) *UI { func newUI(fetchCommits func(string)) *UI {
@@ -127,27 +91,18 @@ func newUI(fetchCommits func(string)) *UI {
u.usersList = &layout.List{ u.usersList = &layout.List{
Axis: layout.Vertical, Axis: layout.Vertical,
} }
u.fab = &ActionButton{ u.fab = new(widget.Button)
sendIco: &icon{src: icons.ContentSend, size: unit.Dp(24)}, u.edit2 = &widget.Editor{
icons: []*icon{},
}
u.edit2 = &text.Editor{
Family: families.primary,
Face: text.Face{
Style: text.Italic,
},
Size: unit.Sp(14),
//Alignment: text.End, //Alignment: text.End,
SingleLine: true, SingleLine: true,
Hint: "Hint", }
HintMaterial: theme.tertText, var err error
Material: theme.text, u.fabIcon, err = material.NewIcon(icons.ContentSend)
if err != nil {
log.Fatal(err)
} }
u.edit2.SetText("Single line editor. Edit me!") u.edit2.SetText("Single line editor. Edit me!")
u.edit = &text.Editor{ u.edit = &widget.Editor{
Family: families.primary,
Size: unit.Sp(16),
Material: theme.text,
//Alignment: text.End, //Alignment: text.End,
//SingleLine: true, //SingleLine: true,
} }
@@ -155,14 +110,6 @@ func newUI(fetchCommits func(string)) *UI {
return u return u
} }
func mustLoadFont(fontData []byte) *sfnt.Font {
fnt, err := sfnt.Parse(fontData)
if err != nil {
panic("failed to load font")
}
return fnt
}
func rgb(c uint32) color.RGBA { func rgb(c uint32) color.RGBA {
return argb((0xff << 24) | c) return argb((0xff << 24) | c)
} }
@@ -188,7 +135,9 @@ func (u *UI) layoutTimings(gtx *layout.Context) {
layout.Align(layout.NE).Layout(gtx, func() { layout.Align(layout.NE).Layout(gtx, func() {
layout.Inset{Top: unit.Dp(16)}.Layout(gtx, func() { layout.Inset{Top: unit.Dp(16)}.Layout(gtx, func() {
txt := fmt.Sprintf("m: %d %s", mallocs, u.profile.Timings) txt := fmt.Sprintf("m: %d %s", mallocs, u.profile.Timings)
text.Label{Material: theme.text, Size: unit.Sp(10), Text: txt}.Layout(gtx, families.mono) lbl := theme.Caption(txt)
lbl.Font.Typeface = "mono"
lbl.Layout(gtx)
}) })
}) })
} }
@@ -232,7 +181,7 @@ func (up *userPage) Layout(gtx *layout.Context) {
func (up *userPage) commit(gtx *layout.Context, index int) { func (up *userPage) commit(gtx *layout.Context, index int) {
u := up.user u := up.user
msg := up.commits[index].GetMessage() msg := up.commits[index].GetMessage()
label := text.Label{Material: theme.text, Size: unit.Sp(12), Text: msg} label := theme.Caption(msg)
in := layout.Inset{Top: unit.Dp(16), Right: unit.Dp(8), Left: unit.Dp(8)} in := layout.Inset{Top: unit.Dp(16), Right: unit.Dp(8), Left: unit.Dp(8)}
in.Layout(gtx, func() { in.Layout(gtx, func() {
f := layout.Flex{Axis: layout.Horizontal} f := layout.Flex{Axis: layout.Horizontal}
@@ -241,13 +190,13 @@ func (up *userPage) commit(gtx *layout.Context, index int) {
cc := clipCircle{} cc := clipCircle{}
cc.Layout(gtx, func() { cc.Layout(gtx, func() {
gtx.Constraints = layout.RigidConstraints(gtx.Constraints.Constrain(image.Point{X: sz, Y: sz})) gtx.Constraints = layout.RigidConstraints(gtx.Constraints.Constrain(image.Point{X: sz, Y: sz}))
widget.Image{Src: u.avatar, Rect: u.avatar.Bounds()}.Layout(gtx) theme.Image(u.avatar).Layout(gtx)
}) })
}) })
c2 := f.Flex(gtx, 1, func() { c2 := f.Flex(gtx, 1, func() {
gtx.Constraints.Width.Min = gtx.Constraints.Width.Max gtx.Constraints.Width.Min = gtx.Constraints.Width.Max
layout.Inset{Left: unit.Dp(8)}.Layout(gtx, func() { layout.Inset{Left: unit.Dp(8)}.Layout(gtx, func() {
label.Layout(gtx, families.primary) label.Layout(gtx)
}) })
}) })
f.Layout(gtx, c1, c2) f.Layout(gtx, c1, c2)
@@ -260,7 +209,9 @@ func (u *UI) layoutUsers(gtx *layout.Context) {
layout.Align(layout.SE).Layout(gtx, func() { layout.Align(layout.SE).Layout(gtx, func() {
in := layout.UniformInset(unit.Dp(16)) in := layout.UniformInset(unit.Dp(16))
in.Layout(gtx, func() { in.Layout(gtx, func() {
u.fab.Layout(gtx) for u.fab.Clicked(gtx) {
}
theme.IconButton(u.fabIcon).Layout(gtx, u.fab)
}) })
}) })
}) })
@@ -274,7 +225,7 @@ func (u *UI) layoutUsers(gtx *layout.Context) {
sz := gtx.Px(unit.Dp(200)) sz := gtx.Px(unit.Dp(200))
cs := gtx.Constraints cs := gtx.Constraints
gtx.Constraints = layout.RigidConstraints(cs.Constrain(image.Point{X: sz, Y: sz})) gtx.Constraints = layout.RigidConstraints(cs.Constrain(image.Point{X: sz, Y: sz}))
u.edit.Layout(gtx) theme.Editor("Hint").Layout(gtx, u.edit)
}) })
}) })
@@ -282,7 +233,10 @@ func (u *UI) layoutUsers(gtx *layout.Context) {
gtx.Constraints.Width.Min = gtx.Constraints.Width.Max gtx.Constraints.Width.Min = gtx.Constraints.Width.Max
in := layout.Inset{Bottom: unit.Dp(16), Left: unit.Dp(16), Right: unit.Dp(16)} in := layout.Inset{Bottom: unit.Dp(16), Left: unit.Dp(16), Right: unit.Dp(16)}
in.Layout(gtx, func() { in.Layout(gtx, func() {
u.edit2.Layout(gtx) e := theme.Editor("Hint")
e.Font.Size = unit.Sp(14)
e.Font.Style = text.Italic
e.Layout(gtx, u.edit2)
}) })
}) })
@@ -290,15 +244,15 @@ func (u *UI) layoutUsers(gtx *layout.Context) {
gtx.Constraints.Width.Min = gtx.Constraints.Width.Max gtx.Constraints.Width.Min = gtx.Constraints.Width.Max
s := layout.Stack{Alignment: layout.Center} s := layout.Stack{Alignment: layout.Center}
c2 := s.Rigid(gtx, func() { c2 := s.Rigid(gtx, func() {
grey := colorMaterial(gtx.Ops, rgb(0x888888))
in := layout.Inset{Top: unit.Dp(16), Right: unit.Dp(8), Bottom: unit.Dp(8), Left: unit.Dp(8)} in := layout.Inset{Top: unit.Dp(16), Right: unit.Dp(8), Bottom: unit.Dp(8), Left: unit.Dp(8)}
in.Layout(gtx, func() { in.Layout(gtx, func() {
lbl := text.Label{Material: grey, Size: unit.Sp(11), Text: "GOPHERS"} lbl := theme.Caption("GOPHERS")
lbl.Layout(gtx, families.primary) lbl.Color = rgb(0x888888)
lbl.Layout(gtx)
}) })
}) })
c1 := s.Expand(gtx, func() { c1 := s.Expand(gtx, func() {
fill{colorMaterial(gtx.Ops, rgb(0xf2f2f2))}.Layout(gtx) fill{rgb(0xf2f2f2)}.Layout(gtx)
}) })
s.Layout(gtx, c1, c2) s.Layout(gtx, c1, c2)
}) })
@@ -312,16 +266,6 @@ func (u *UI) layoutUsers(gtx *layout.Context) {
st.Layout(gtx, c1, c2) st.Layout(gtx, c1, c2)
} }
func (a *ActionButton) Layout(gtx *layout.Context) {
f := layout.Flex{Axis: layout.Vertical, Alignment: layout.End}
f.Layout(gtx, f.Rigid(gtx, func() {
layout.Inset{Top: unit.Dp(4)}.Layout(gtx, func() {
fab(gtx, a.sendIco.image(gtx), theme.brand, gtx.Px(unit.Dp(56)))
pointer.EllipseAreaOp{Rect: image.Rectangle{Max: gtx.Dimensions.Size}}.Add(gtx.Ops)
})
}))
}
func (u *UI) layoutContributors(gtx *layout.Context) { func (u *UI) layoutContributors(gtx *layout.Context) {
l := u.usersList l := u.usersList
if l.Dragging() { if l.Dragging() {
@@ -346,7 +290,7 @@ func (u *UI) user(gtx *layout.Context, index int) {
cc.Layout(gtx, func() { cc.Layout(gtx, func() {
sz := image.Point{X: gtx.Px(unit.Dp(48)), Y: gtx.Px(unit.Dp(48))} sz := image.Point{X: gtx.Px(unit.Dp(48)), Y: gtx.Px(unit.Dp(48))}
gtx.Constraints = layout.RigidConstraints(gtx.Constraints.Constrain(sz)) gtx.Constraints = layout.RigidConstraints(gtx.Constraints.Constrain(sz))
widget.Image{Src: user.avatar, Rect: user.avatar.Bounds()}.Layout(gtx) theme.Image(user.avatar).Layout(gtx)
}) })
}) })
}) })
@@ -355,14 +299,13 @@ func (u *UI) user(gtx *layout.Context, index int) {
c1 := f.Rigid(gtx, func() { c1 := f.Rigid(gtx, func() {
f := baseline() f := baseline()
c1 := f.Rigid(gtx, func() { c1 := f.Rigid(gtx, func() {
text.Label{Material: theme.text, Size: unit.Sp(13), Text: user.name}.Layout(gtx, families.primary) theme.Body1(user.name).Layout(gtx)
}) })
c2 := f.Flex(gtx, 1, func() { c2 := f.Flex(gtx, 1, func() {
gtx.Constraints.Width.Min = gtx.Constraints.Width.Max gtx.Constraints.Width.Min = gtx.Constraints.Width.Max
layout.Align(layout.E).Layout(gtx, func() { layout.Align(layout.E).Layout(gtx, func() {
layout.Inset{Left: unit.Dp(2)}.Layout(gtx, func() { layout.Inset{Left: unit.Dp(2)}.Layout(gtx, func() {
lbl := text.Label{Material: theme.text, Size: unit.Sp(10), Text: "3 hours ago"} theme.Caption("3 hours ago").Layout(gtx)
lbl.Layout(gtx, families.primary)
}) })
}) })
}) })
@@ -371,7 +314,9 @@ func (u *UI) user(gtx *layout.Context, index int) {
c2 := f.Rigid(gtx, func() { c2 := f.Rigid(gtx, func() {
in := layout.Inset{Top: unit.Dp(4)} in := layout.Inset{Top: unit.Dp(4)}
in.Layout(gtx, func() { in.Layout(gtx, func() {
text.Label{Material: theme.tertText, Size: unit.Sp(12), Text: user.company}.Layout(gtx, families.primary) lbl := theme.Caption(user.company)
lbl.Color = rgb(0xbbbbbb)
lbl.Layout(gtx)
}) })
}) })
f.Layout(gtx, c1, c2) f.Layout(gtx, c1, c2)
@@ -386,7 +331,7 @@ func (u *UI) user(gtx *layout.Context, index int) {
} }
type fill struct { type fill struct {
material op.MacroOp col color.RGBA
} }
func (f fill) Layout(gtx *layout.Context) { func (f fill) Layout(gtx *layout.Context) {
@@ -395,7 +340,7 @@ func (f fill) Layout(gtx *layout.Context) {
dr := f32.Rectangle{ dr := f32.Rectangle{
Max: f32.Point{X: float32(d.X), Y: float32(d.Y)}, Max: f32.Point{X: float32(d.X), Y: float32(d.Y)},
} }
f.material.Add(gtx.Ops) paint.ColorOp{Color: f.col}.Add(gtx.Ops)
paint.PaintOp{Rect: dr}.Add(gtx.Ops) paint.PaintOp{Rect: dr}.Add(gtx.Ops)
gtx.Dimensions = layout.Dimensions{Size: d, Baseline: d.Y} gtx.Dimensions = layout.Dimensions{Size: d, Baseline: d.Y}
} }
@@ -434,47 +379,6 @@ func (c *clipCircle) Layout(gtx *layout.Context, w layout.Widget) {
stack.Pop() stack.Pop()
} }
func fab(gtx *layout.Context, ico image.Image, mat op.MacroOp, size int) {
dp := image.Point{X: (size - ico.Bounds().Dx()) / 2, Y: (size - ico.Bounds().Dy()) / 2}
dims := image.Point{X: size, Y: size}
rr := float32(size) * .5
rrect(gtx.Ops, float32(size), float32(size), rr, rr, rr, rr)
mat.Add(gtx.Ops)
paint.PaintOp{Rect: f32.Rectangle{Max: f32.Point{X: float32(size), Y: float32(size)}}}.Add(gtx.Ops)
paint.ImageOp{Src: ico, Rect: ico.Bounds()}.Add(gtx.Ops)
paint.PaintOp{
Rect: toRectF(ico.Bounds().Add(dp)),
}.Add(gtx.Ops)
gtx.Dimensions = layout.Dimensions{Size: dims}
}
func toRectF(r image.Rectangle) f32.Rectangle {
return f32.Rectangle{
Min: f32.Point{X: float32(r.Min.X), Y: float32(r.Min.Y)},
Max: f32.Point{X: float32(r.Max.X), Y: float32(r.Max.Y)},
}
}
func (ic *icon) image(cfg unit.Converter) image.Image {
sz := cfg.Px(ic.size)
if sz == ic.imgSize {
return ic.img
}
m, _ := iconvg.DecodeMetadata(ic.src)
dx, dy := m.ViewBox.AspectRatio()
img := image.NewRGBA(image.Rectangle{Max: image.Point{X: sz, Y: int(float32(sz) * dy / dx)}})
var ico iconvg.Rasterizer
ico.SetDstImage(img, img.Bounds(), draw.Src)
// Use white for icons.
m.Palette[0] = color.RGBA{A: 0xff, R: 0xff, G: 0xff, B: 0xff}
iconvg.Decode(&ico, ic.src, &iconvg.DecodeOptions{
Palette: &m.Palette,
})
ic.img = img
ic.imgSize = sz
return img
}
// https://pomax.github.io/bezierinfo/#circles_cubic. // https://pomax.github.io/bezierinfo/#circles_cubic.
func rrect(ops *op.Ops, width, height, se, sw, nw, ne float32) { func rrect(ops *op.Ops, width, height, se, sw, nw, ne float32) {
w, h := float32(width), float32(height) w, h := float32(width), float32(height)
@@ -489,7 +393,7 @@ func rrect(ops *op.Ops, width, height, se, sw, nw, ne float32) {
b.Cube(f32.Point{X: 0, Y: -nw * c}, f32.Point{X: nw - nw*c, Y: -nw}, f32.Point{X: nw, Y: -nw}) // NW b.Cube(f32.Point{X: 0, Y: -nw * c}, f32.Point{X: nw - nw*c, Y: -nw}, f32.Point{X: nw, Y: -nw}) // NW
b.Line(f32.Point{X: w - ne - nw, Y: 0}) b.Line(f32.Point{X: w - ne - nw, Y: 0})
b.Cube(f32.Point{X: ne * c, Y: 0}, f32.Point{X: ne, Y: ne - ne*c}, f32.Point{X: ne, Y: ne}) // NE b.Cube(f32.Point{X: ne * c, Y: 0}, f32.Point{X: ne, Y: ne - ne*c}, f32.Point{X: ne, Y: ne}) // NE
b.End() b.End().Add(ops)
} }
const longTextSample = `1. I learned from my grandfather, Verus, to use good manners, and to const longTextSample = `1. I learned from my grandfather, Verus, to use good manners, and to
+14 -21
View File
@@ -10,14 +10,11 @@ import (
"gioui.org/app" "gioui.org/app"
"gioui.org/layout" "gioui.org/layout"
"gioui.org/op"
"gioui.org/op/paint"
"gioui.org/text" "gioui.org/text"
"gioui.org/text/shape" "gioui.org/text/opentype"
"gioui.org/unit" "gioui.org/widget/material"
"golang.org/x/image/font/gofont/goregular" "golang.org/x/image/font/gofont/goregular"
"golang.org/x/image/font/sfnt"
) )
func main() { func main() {
@@ -31,15 +28,11 @@ func main() {
} }
func loop(w *app.Window) error { func loop(w *app.Window) error {
regular, err := sfnt.Parse(goregular.TTF) shaper := new(text.Shaper)
if err != nil { shaper.Register(text.Font{}, opentype.Must(
panic("failed to load font") opentype.Parse(goregular.TTF),
} ))
family := &shape.Family{ th := material.NewTheme(shaper)
Regular: regular,
}
maroon := color.RGBA{127, 0, 0, 255}
message := "Hello, Gio"
gtx := &layout.Context{ gtx := &layout.Context{
Queue: w.Queue(), Queue: w.Queue(),
} }
@@ -48,14 +41,14 @@ func loop(w *app.Window) error {
switch e := e.(type) { switch e := e.(type) {
case app.DestroyEvent: case app.DestroyEvent:
return e.Err return e.Err
case app.UpdateEvent: case app.FrameEvent:
gtx.Reset(&e.Config, e.Size) gtx.Reset(&e.Config, e.Size)
var material op.MacroOp l := th.H1("Hello, Gio")
material.Record(gtx.Ops) maroon := color.RGBA{127, 0, 0, 255}
paint.ColorOp{Color: maroon}.Add(gtx.Ops) l.Color = maroon
material.Stop() l.Alignment = text.Middle
text.Label{Material: material, Size: unit.Sp(72), Alignment: text.Middle, Text: message}.Layout(gtx, family) l.Layout(gtx)
w.Update(gtx.Ops) e.Frame(gtx.Ops)
} }
} }
} }