func (defaultTreeControlCreator) Create(theme gxui.Theme, control gxui.Control, node *TreeToListNode) gxui.Control { ll := theme.CreateLinearLayout() ll.SetDirection(gxui.LeftToRight) btn := theme.CreateButton() btn.SetBackgroundBrush(gxui.TransparentBrush) btn.SetBorderPen(gxui.CreatePen(1, gxui.Gray30)) btn.SetMargin(math.Spacing{L: 2, R: 2, T: 1, B: 1}) btn.OnClick(func(ev gxui.MouseEvent) { if ev.Button == gxui.MouseButtonLeft { node.ToggleExpanded() } }) update := func() { btn.SetVisible(!node.IsLeaf()) if node.IsExpanded() { btn.SetText("-") } else { btn.SetText("+") } } update() gxui.WhileAttached(btn, node.OnChange, update) ll.AddChild(btn) ll.AddChild(control) ll.SetPadding(math.Spacing{L: 16 * node.Depth()}) return ll }
//画行走路线 func drawWalkPath(window gxui.Window, theme gxui.Theme, driver gxui.Driver, x1, y1, x2, y2 int64) { ps, isWalk := nm.FindPath(nmastar, x1, y1, x2, y2) if !isWalk { return } canvas := driver.CreateCanvas(math.Size{W: int(nmj.Width), H: int(nmj.Heigth)}) var polys []gxui.PolygonVertex for i := 0; i < len(ps); i++ { polys = append(polys, gxui.PolygonVertex{ Position: math.Point{ int(ps[i].X), int(ps[i].Y), }}) } canvas.DrawLines(polys, gxui.CreatePen(2, gxui.Green)) canvas.Complete() image := theme.CreateImage() image.SetCanvas(canvas) window.AddChild(image) }
func (a *customAdapter) Create(theme gxui.Theme, index int) gxui.Control { phase := float32(index) / 1000 c := gxui.Color{ R: 0.5 + 0.5*math.Sinf(math.TwoPi*(phase+0.000)), G: 0.5 + 0.5*math.Sinf(math.TwoPi*(phase+0.333)), B: 0.5 + 0.5*math.Sinf(math.TwoPi*(phase+0.666)), A: 1.0, } i := theme.CreateImage() i.SetBackgroundBrush(gxui.CreateBrush(c)) i.SetMargin(math.Spacing{L: 3, T: 3, R: 3, B: 3}) i.OnMouseEnter(func(ev gxui.MouseEvent) { i.SetBorderPen(gxui.CreatePen(2, gxui.Gray80)) }) i.OnMouseExit(func(ev gxui.MouseEvent) { i.SetBorderPen(gxui.TransparentPen) }) i.OnMouseDown(func(ev gxui.MouseEvent) { i.SetBackgroundBrush(gxui.CreateBrush(c.MulRGB(0.7))) }) i.OnMouseUp(func(ev gxui.MouseEvent) { i.SetBackgroundBrush(gxui.CreateBrush(c)) }) return i }
func CreateStyle(fontColor, brushColor, penColor gxui.Color, penWidth float32) Style { return Style{ FontColor: fontColor, Pen: gxui.CreatePen(penWidth, penColor), Brush: gxui.CreateBrush(brushColor), } }
func buildMoon(theme gxui.Theme, center math.Point, radius float32) gxui.Image { c := 40 p := make(gxui.Polygon, c*2) for i := 0; i < c; i++ { frac := float32(i) / float32(c) α := math.Lerpf(math.Pi*1.2, math.Pi*-0.2, frac) p[i] = gxui.PolygonVertex{ Position: math.Point{ X: center.X + int(radius*math.Sinf(α)), Y: center.Y + int(radius*math.Cosf(α)), }, RoundedRadius: 0, } } for i := 0; i < c; i++ { frac := float32(i) / float32(c) α := math.Lerpf(math.Pi*-0.2, math.Pi*1.2, frac) r := math.Lerpf(radius, radius*0.5, math.Sinf(frac*math.Pi)) p[i+c] = gxui.PolygonVertex{ Position: math.Point{ X: center.X + int(r*math.Sinf(α)), Y: center.Y + int(r*math.Cosf(α)), }, RoundedRadius: 0, } } image := theme.CreateImage() image.SetPolygon(p, gxui.CreatePen(3, gxui.Gray80), gxui.CreateBrush(gxui.Gray40)) return image }
func CreateProgressBar(theme *Theme) gxui.ProgressBar { b := &ProgressBar{} b.Init(b, theme) b.theme = theme b.chevronWidth = 10 b.OnAttach(func() { driver := theme.Driver() b.ticker = time.NewTicker(time.Millisecond * 50) go func() { for _ = range b.ticker.C { if !driver.Call(b.animationTick) { return } } }() }) b.OnDetach(func() { if b.chevrons != nil { b.chevrons.Release() b.chevrons = nil b.ticker.Stop() b.ticker = nil } }) b.SetBackgroundBrush(gxui.CreateBrush(gxui.Gray10)) b.SetBorderPen(gxui.CreatePen(1, gxui.Gray40)) return b }
func drawMoon(canvas gxui.Canvas, center math.Point, radius float32) { c := 40 p := make(gxui.Polygon, c*2) for i := 0; i < c; i++ { frac := float32(i) / float32(c) α := math.Lerpf(math.Pi*1.2, math.Pi*-0.2, frac) p[i] = gxui.PolygonVertex{ Position: math.Point{ X: center.X + int(radius*math.Sinf(α)), Y: center.Y + int(radius*math.Cosf(α)), }, RoundedRadius: 0, } } for i := 0; i < c; i++ { frac := float32(i) / float32(c) α := math.Lerpf(math.Pi*-0.2, math.Pi*1.2, frac) r := math.Lerpf(radius, radius*0.5, math.Sinf(frac*math.Pi)) p[i+c] = gxui.PolygonVertex{ Position: math.Point{ X: center.X + int(r*math.Sinf(α)), Y: center.Y + int(r*math.Cosf(α)), }, RoundedRadius: 0, } } canvas.DrawPolygon(p, gxui.CreatePen(3, gxui.Gray80), gxui.CreateBrush(gxui.Gray40)) }
func route(driver gxui.Driver, src_id, dest_id int32, src, dest Point3) (canvas gxui.Canvas) { defer func() { canvas.Complete() }() canvas = driver.CreateCanvas(math.Size{W: 800, H: 600}) t0 := time.Now() // Phase 1. Use Dijkstra to find shortest path on Triangles path := dijkstra.Run(src_id) // Phase 2. construct path indices // Check if this path include src & dest path_triangle := [][3]int32{triangles[dest_id]} prev_id := dest_id for { cur_id, ok := path[prev_id] if !ok { return canvas } path_triangle = append([][3]int32{triangles[cur_id]}, path_triangle...) if cur_id == src_id { break } prev_id = cur_id } // Phase 3. use Navmesh to construct line start, end := &Point3{X: src.X, Y: src.Y}, &Point3{X: dest.X, Y: dest.Y} nm := NavMesh{} trilist := TriangleList{vertices, path_triangle} r, _ := nm.Route(trilist, start, end) log.Println("navmesh time:", time.Now().Sub(t0)) var poly []gxui.PolygonVertex poly = append(poly, gxui.PolygonVertex{ Position: math.Point{ int(SCALE_FACTOR * start.X), int(SCALE_FACTOR * start.Y), }}) for k := range r.Line { poly = append(poly, gxui.PolygonVertex{ Position: math.Point{ int(SCALE_FACTOR * r.Line[k].X), int(SCALE_FACTOR * r.Line[k].Y), }}) } poly = append(poly, gxui.PolygonVertex{ Position: math.Point{ int(SCALE_FACTOR * end.X), int(SCALE_FACTOR * end.Y), }}) canvas.DrawLines(poly, gxui.CreatePen(2, gxui.Green)) return }
func (t *CodeEditorLine) PaintBorders(c gxui.Canvas, info CodeEditorLinePaintInfo) { start, _ := info.LineSpan.Span() offsets := info.GlyphOffsets for _, l := range t.ce.layers { if l != nil && l.BorderColor() != nil { color := *l.BorderColor() interval.Visit(l.Spans(), info.LineSpan, func(vs, ve uint64, _ int) { s, e := vs-start, ve-start r := math.CreateRect(offsets[s].X, 0, offsets[e-1].X+info.GlyphWidth, info.LineHeight) c.DrawRoundedRect(r, 3, 3, 3, 3, gxui.CreatePen(0.5, color), gxui.TransparentBrush) }) } } }
func appMain(driver gxui.Driver) { theme := flags.CreateTheme(driver) width := int(nmj.Width) height := int(nmj.Heigth) window := theme.CreateWindow(width, height, "navmesh") canvas := driver.CreateCanvas(math.Size{W: width, H: height}) ps := nmj.Points // mouse isStart := true x1, y1, x2, y2 := int64(0), int64(0), int64(0), int64(0) window.OnMouseDown(func(me gxui.MouseEvent) { if nm.IsWalkOfPoint(navmesh.Point{X: int64(me.Point.X), Y: int64(me.Point.Y)}) { if isStart { x1 = int64(me.Point.X) y1 = int64(me.Point.Y) } else { x2 = int64(me.Point.X) y2 = int64(me.Point.Y) } if !isStart { drawWalkPath(window, theme, driver, x1, y1, x2, y2) } isStart = !isStart } }) // draw mesh for i := 0; i < len(ps); i++ { polys := make([]gxui.PolygonVertex, 0, len(ps[i])) for j := 0; j < len(ps[i]); j++ { polys = append(polys, gxui.PolygonVertex{ Position: math.Point{ int(ps[i][j].X), int(ps[i][j].Y), }}) } // canvas.DrawPolygon(polys, gxui.CreatePen(2, gxui.Gray80), gxui.CreateBrush(gxui.Gray40)) canvas.DrawPolygon(polys, gxui.CreatePen(2, gxui.Red), gxui.CreateBrush(gxui.Yellow)) } canvas.Complete() image := theme.CreateImage() image.SetCanvas(canvas) window.AddChild(image) window.OnClose(driver.Terminate) }
func drawStar(canvas gxui.Canvas, center math.Point, radius, rotation float32, points int) { p := make(gxui.Polygon, points*2) for i := 0; i < points*2; i++ { frac := float32(i) / float32(points*2) α := frac*math.TwoPi + rotation r := []float32{radius, radius / 2}[i&1] p[i] = gxui.PolygonVertex{ Position: math.Point{ X: center.X + int(r*math.Cosf(α)), Y: center.Y + int(r*math.Sinf(α)), }, RoundedRadius: []float32{0, 50}[i&1], } } canvas.DrawPolygon(p, gxui.CreatePen(3, gxui.Red), gxui.CreateBrush(gxui.Yellow)) }
func (treeControlCreator) Create(theme gxui.Theme, control gxui.Control, node *mixins.TreeToListNode) gxui.Control { img := theme.CreateImage() imgSize := math.Size{W: 10, H: 10} ll := theme.CreateLinearLayout() ll.SetDirection(gxui.LeftToRight) btn := theme.CreateButton() btn.SetBackgroundBrush(gxui.TransparentBrush) btn.SetBorderPen(gxui.CreatePen(1, gxui.Gray30)) btn.SetMargin(math.Spacing{L: 1, R: 1, T: 1, B: 1}) btn.OnClick(func(ev gxui.MouseEvent) { if ev.Button == gxui.MouseButtonLeft { node.ToggleExpanded() } }) btn.AddChild(img) update := func() { expanded := node.IsExpanded() canvas := theme.Driver().CreateCanvas(imgSize) btn.SetVisible(!node.IsLeaf()) switch { case !btn.IsMouseDown(gxui.MouseButtonLeft) && expanded: canvas.DrawPolygon(expandedPoly, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray70)) case !btn.IsMouseDown(gxui.MouseButtonLeft) && !expanded: canvas.DrawPolygon(collapsedPoly, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray70)) case expanded: canvas.DrawPolygon(expandedPoly, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray30)) case !expanded: canvas.DrawPolygon(collapsedPoly, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray30)) } canvas.Complete() img.SetCanvas(canvas) } btn.OnMouseDown(func(gxui.MouseEvent) { update() }) btn.OnMouseUp(func(gxui.MouseEvent) { update() }) update() gxui.WhileAttached(btn, node.OnChange, update) ll.AddChild(btn) ll.AddChild(control) ll.SetPadding(math.Spacing{L: 16 * node.Depth()}) return ll }
func buildStar(theme gxui.Theme, center math.Point, radius, rotation float32, points int) gxui.Image { p := make(gxui.Polygon, points*2) for i := 0; i < points*2; i++ { frac := float32(i) / float32(points*2) α := frac*math.TwoPi + rotation r := []float32{radius, radius / 2}[i&1] p[i] = gxui.PolygonVertex{ Position: math.Point{ X: center.X + int(r*math.Cosf(α)), Y: center.Y + int(r*math.Sinf(α)), }, RoundedRadius: []float32{0, 50}[i&1], } } image := theme.CreateImage() image.SetPolygon(p, gxui.CreatePen(3, gxui.Red), gxui.CreateBrush(gxui.Yellow)) return image }
func drawTimeAxis(canvas gxui.Canvas) { p := gxui.Polygon{ gxui.PolygonVertex{ Position: math.Point{ X: 0, Y: 400, }, RoundedRadius: 0, }, gxui.PolygonVertex{ Position: math.Point{ X: 400, Y: 400, }, RoundedRadius: 0, }, } canvas.DrawLines(p, gxui.CreatePen(1.0, gxui.White)) }
func (t *Tree) CreateExpandButton(theme gxui.Theme, node *mixins.TreeInternalNode) gxui.Button { img := theme.CreateImage() imgSize := math.Size{W: 10, H: 10} btn := theme.CreateButton() btn.SetBackgroundBrush(gxui.TransparentBrush) btn.SetBorderPen(gxui.CreatePen(1, gxui.Gray30)) btn.SetMargin(math.Spacing{L: 1, R: 1, T: 1, B: 1}) btn.OnClick(func(ev gxui.MouseEvent) { if ev.Button == gxui.MouseButtonLeft { if node.IsExpanded() { node.Collapse() } else { node.Expand() } } }) btn.AddChild(img) updateStyle := func() { canvas := theme.Driver().CreateCanvas(imgSize) switch { case !btn.IsMouseDown(gxui.MouseButtonLeft) && node.IsExpanded(): canvas.DrawPolygon(expandedPoly, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray70)) case !btn.IsMouseDown(gxui.MouseButtonLeft) && !node.IsExpanded(): canvas.DrawPolygon(collapsedPoly, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray70)) case node.IsExpanded(): canvas.DrawPolygon(expandedPoly, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray30)) case !node.IsExpanded(): canvas.DrawPolygon(collapsedPoly, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray30)) } canvas.Complete() img.SetCanvas(canvas) } btn.OnMouseDown(func(gxui.MouseEvent) { updateStyle() }) btn.OnMouseUp(func(gxui.MouseEvent) { updateStyle() }) node.OnExpandedChanged(func(e bool) { updateStyle() }) updateStyle() return btn }
func (f Field) drawHorizontalLines(canvas gxui.Canvas) { for y := f.cellHeight; y < f.height; y += f.cellHeight { p := make(gxui.Polygon, 2) p[0] = gxui.PolygonVertex{ Position: math.Point{ X: 0, Y: y, }, RoundedRadius: 0, } p[1] = gxui.PolygonVertex{ Position: math.Point{ X: f.width, Y: y, }, RoundedRadius: 0, } canvas.DrawLines(p, gxui.CreatePen(1, gxui.Gray80)) } }
func (f Field) drawVerticalLines(canvas gxui.Canvas) { for x := f.cellWidth; x < f.width; x += f.cellWidth { p := make(gxui.Polygon, 2) p[0] = gxui.PolygonVertex{ Position: math.Point{ X: x, Y: 0, }, RoundedRadius: 0, } p[1] = gxui.PolygonVertex{ Position: math.Point{ X: x, Y: f.height, }, RoundedRadius: 0, } canvas.DrawLines(p, gxui.CreatePen(1, gxui.Gray80)) } }
func (s Snake) Draw(canvas gxui.Canvas) { bendCount := len(s.bends) p := make(gxui.Polygon, 2+bendCount) p[0] = gxui.PolygonVertex{ Position: s.head, RoundedRadius: 0, } for i, bend := range s.bends { p[i+1] = gxui.PolygonVertex{ Position: bend.point, RoundedRadius: 0, } } p[bendCount+1] = gxui.PolygonVertex{ Position: s.tail, RoundedRadius: 0, } canvas.DrawLines(p, gxui.CreatePen(float32(s.width), gxui.Green70)) }
func (t *Tree) PaintUnexpandedSelection(c gxui.Canvas, r math.Rect) { c.DrawRoundedRect(r, 2.0, 2.0, 2.0, 2.0, gxui.CreatePen(1, gxui.Gray50), gxui.TransparentBrush) }
func (t *DefaultTextBoxLine) PaintCaret(c gxui.Canvas, top, bottom math.Point) { r := math.Rect{Min: top, Max: bottom}.ExpandI(t.caretWidth / 2) c.DrawRoundedRect(r, 1, 1, 1, 1, gxui.CreatePen(0.5, gxui.Gray70), gxui.WhiteBrush) }
func appMain(driver gxui.Driver) { theme := flags.CreateTheme(driver) window := theme.CreateWindow(800, 600, "navmesh") canvas := driver.CreateCanvas(math.Size{W: 800, H: 600}) // mouse isStart := true var src_id, dest_id int32 // source & dest triangle id var src, dest Point3 window.OnMouseDown(func(me gxui.MouseEvent) { pt := Point3{X: float32(me.Point.X) / SCALE_FACTOR, Y: float32(me.Point.Y) / SCALE_FACTOR} id := getTriangleId(pt) if isStart { src_id = id src = pt } else { dest_id = id dest = pt } if !isStart { if src_id != -1 && dest_id != -1 { canvas := route(driver, src_id, dest_id, src, dest) image := theme.CreateImage() image.SetCanvas(canvas) window.AddChild(image) } } isStart = !isStart }) // draw mesh for k := 0; k < len(triangles); k++ { poly := []gxui.PolygonVertex{ gxui.PolygonVertex{ Position: math.Point{ int(SCALE_FACTOR * vertices[triangles[k][0]].X), int(SCALE_FACTOR * vertices[triangles[k][0]].Y), }}, gxui.PolygonVertex{ Position: math.Point{ int(SCALE_FACTOR * vertices[triangles[k][1]].X), int(SCALE_FACTOR * vertices[triangles[k][1]].Y), }}, gxui.PolygonVertex{ Position: math.Point{ int(SCALE_FACTOR * vertices[triangles[k][2]].X), int(SCALE_FACTOR * vertices[triangles[k][2]].Y), }}, } canvas.DrawPolygon(poly, gxui.CreatePen(3, gxui.Gray80), gxui.CreateBrush(gxui.Gray40)) //canvas.DrawPolygon(poly, gxui.CreatePen(2, gxui.Red), gxui.CreateBrush(gxui.Yellow)) } canvas.Complete() image := theme.CreateImage() image.SetCanvas(canvas) window.AddChild(image) window.OnClose(driver.Terminate) }