diff --git a/example/go.mod b/example/go.mod index 14ead805..66637946 100644 --- a/example/go.mod +++ b/example/go.mod @@ -3,7 +3,7 @@ module gioui.org/example go 1.13 require ( - gioui.org v0.0.0-20200402190513-da01fbdea784 + gioui.org v0.0.0-20200416175719-b1aed3eae023 github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72 github.com/google/go-github/v24 v24.0.1 diff --git a/example/go.sum b/example/go.sum index 669115b1..856e93d3 100644 --- a/example/go.sum +++ b/example/go.sum @@ -1,7 +1,7 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -gioui.org v0.0.0-20200402190513-da01fbdea784 h1:gH0+2HCtuzxAdK6sd0BeCxZLAkCbhptF607odwS5QY0= -gioui.org v0.0.0-20200402190513-da01fbdea784/go.mod h1:AHI9rFr6AEEHCb8EPVtb/p5M+NMJRKH58IOp8O3Je04= +gioui.org v0.0.0-20200416175719-b1aed3eae023 h1:I7I2412lWuAC2kQPk9TLONjCv/8dWfOBJEjFOJhwF3g= +gioui.org v0.0.0-20200416175719-b1aed3eae023/go.mod h1:AHI9rFr6AEEHCb8EPVtb/p5M+NMJRKH58IOp8O3Je04= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 h1:SCYMcCJ89LjRGwEa0tRluNRiMjZHalQZrVrvTbPh+qw= github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= diff --git a/example/tabs/tabs.go b/example/tabs/tabs.go new file mode 100644 index 00000000..cd29020f --- /dev/null +++ b/example/tabs/tabs.go @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: Unlicense OR MIT + +package main + +import ( + "fmt" + "image" + "image/color" + "log" + + "gioui.org/app" + "gioui.org/f32" + "gioui.org/io/system" + "gioui.org/layout" + "gioui.org/op/paint" + "gioui.org/unit" + "gioui.org/widget" + "gioui.org/widget/material" + + "gioui.org/font/gofont" +) + +func main() { + go func() { + w := app.NewWindow() + if err := loop(w); err != nil { + log.Fatal(err) + } + }() + app.Main() +} + +func loop(w *app.Window) error { + gofont.Register() + th := material.NewTheme() + gtx := layout.NewContext(w.Queue()) + for { + e := <-w.Events() + switch e := e.(type) { + case system.DestroyEvent: + return e.Err + case system.FrameEvent: + gtx.Reset(e.Config, e.Size) + drawTabs(gtx, th) + e.Frame(gtx.Ops) + } + } +} + +var tabs Tabs + +type Tabs struct { + list layout.List + tabs []Tab + selected int +} + +type Tab struct { + btn widget.Button + Title string +} + +func init() { + for i := 1; i <= 100; i++ { + tabs.tabs = append(tabs.tabs, + Tab{Title: fmt.Sprintf("Tab %d", i)}, + ) + } +} + +func drawTabs(gtx *layout.Context, th *material.Theme) { + layout.Flex{Axis: layout.Vertical}.Layout(gtx, + layout.Rigid(func() { + tabs.list.Layout(gtx, len(tabs.tabs), func(tabIdx int) { + t := &tabs.tabs[tabIdx] + if t.btn.Clicked(gtx) { + tabs.selected = tabIdx + } + var tabWidth int + layout.Stack{Alignment: layout.S}.Layout(gtx, + layout.Stacked(func() { + tabBtn := th.Button(t.Title) + tabBtn.Background = color.RGBA{} // No background. + tabBtn.CornerRadius = unit.Value{} // No corners. + tabBtn.Color = color.RGBA{A: 0xff} // Black text. + tabBtn.TextSize = unit.Sp(20) + tabBtn.Layout(gtx, &t.btn) + tabWidth = gtx.Dimensions.Size.X + }), + layout.Stacked(func() { + if tabs.selected != tabIdx { + return + } + paint.ColorOp{Color: th.Color.Primary}.Add(gtx.Ops) + tabHeight := gtx.Px(unit.Dp(4)) + paint.PaintOp{Rect: f32.Rectangle{ + Max: f32.Point{ + X: float32(tabWidth), + Y: float32(tabHeight), + }, + }}.Add(gtx.Ops) + gtx.Dimensions = layout.Dimensions{ + Size: image.Point{X: tabWidth, Y: tabHeight}, + } + }), + ) + }) + }), + layout.Flexed(1, func() { + layout.Center.Layout(gtx, func() { + th.H1(fmt.Sprintf("Tab content #%d", tabs.selected)).Layout(gtx) + }) + }), + ) +}