func (self *Window) Draw(ctx vg.Context) { now := time.Now() _, _, w, h := self.Bounds() fbw, fbh := self.FramebufferSize() // Calculate pixel ration for hi-dpi devices. bg := color.Gray13 gl.ClearColor(gl.Float(bg.R), gl.Float(bg.G), gl.Float(bg.B), gl.Float(bg.A)) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT) //Do OpenGL stuff // Iterate over scene, rendering what can be rendered if self.renderer != nil { self.renderer.Render() } // 2D Display // r := float64(fbw) / float64(w) gl.Viewport(0, 0, gl.Sizei(fbw), gl.Sizei(fbh)) if self.child != nil { ctx.BeginFrame(int(w), int(h), 1.0) self.child.SetBounds(0.0, 0.0, float64(w), float64(h)) self.child.Draw(ctx) ctx.EndFrame() } if debug { fmt.Println(time.Since(now)) } }
// tokenSize retrieves the metrics from the internal cache, sizes. // It is expensive to calculate the token sizes each frame and the // sizes do not change often to justify the cost. Testing revealed // this approach yields a slower rate of growth. // // TODO: maybe choose to disable cpu scaling for better performance // > echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor // or // > sudo update-rc.d ondemand disable func (self *Text) tokenBounds(i int, ctx *vg.Context) *ui.Rectangle { bounds := self.bounds[i] if bounds == nil { x, y, w, h := ctx.TextBounds(self.tokens[i], 0, 0) bounds = &ui.Rectangle{ui.Position{x, y}, ui.Size{w, h}} self.bounds[i] = bounds } return bounds }
func (self *LineChart) Draw(x, y, w, h float64, ctx vg.Context) { ui.DrawDefaultElement(x, y, w, h, Palette[CHART_BACKGROUND], ctx) // th := self.Title.draw(x, y, w, h, ctx) ctx.BeginPath() ctx.Fill() self.drawSeries(x, y, w, h, ctx) ctx.ResetScissor() }
// draw draws the title and returns the height. func (self *Title) draw(x, y, w, h float64, ctx vg.Context) float64 { th := 0.0 name := self.Model.Title() if len(name) > 0 { th = self.FontSize + 16 // ctx.BeginPath() // ctx.StrokeColor(color.RGBA{0, 50, 100, 25}) // ctx.StrokeWidth(1) // ctx.LineCap(vg.ROUND) // ctx.LineJoin(vg.ROUND) // ctx.MoveTo(x, y+th) // ctx.LineTo(x+1.5, y+th) // ctx.LineTo(x+w+1.5, y+th) // ctx.Stroke() ctx.FillColor(color.RGBA{255, 251, 251, 255}) ctx.TextAlign(vg.ALIGN_LEFT | vg.ALIGN_MIDDLE) ctx.SetFontSize(self.FontSize + 3) ctx.FindFont(vg.FONT_DEFAULT) ctx.WrappedText(x+10, y+self.FontSize, w, name) } return th }
func DrawDefaultElement(x, y, w, h float64, bg color.Color, ctx vg.Context) { // Shadow ctx.BeginPath() ctx.StrokeColor(color.RGBA{100, 100, 100, 100}) ctx.RoundedRect(x, y, w, h, 30) ctx.StrokeWidth(1) ctx.Stroke() ctx.FillPaint(ctx.BoxGradient(x, y, w, h, h*.5, h, bg, bg)) ctx.Fill() }
func (self *LineChart) drawSeries(x, y, w, h float64, ctx vg.Context) { // Boundries baseline := y + h _, max, count := self.Model.Limits() horIncr := w / (count - 1) vratio := (h - 1) / max for _, s := range self.Model.Series() { c1 := CloneColor(s.Color) c1.A = 150 ctx.StrokeColor(c1) ctx.StrokeWidth(s.StrokeWidth) ctx.BeginPath() for i, f := range s.Data { if i == 0 { ctx.MoveTo(x+float64(i)*horIncr, baseline-(f*vratio)) } else { ctx.LineTo(x+float64(i)*horIncr, baseline-(f*vratio)) } } ctx.Stroke() if self.Fill { ctx.BeginPath() // ctx.MoveTo(x, baseline) c2 := CloneColor(s.Color) c2.A = 200 ctx.FillColor(c2) for i, f := range s.Data { if i == 0 { ctx.MoveTo(x+float64(i)*horIncr, baseline-(f*vratio)) } ctx.LineTo(x+float64(i)*horIncr, baseline-(f*vratio)) if i == len(s.Data)-1 { ctx.LineTo(x+float64(i)*horIncr, baseline) ctx.LineTo(x, baseline) ctx.MoveTo(x, baseline-(s.Data[0]*vratio)) break } } ctx.Fill() } } }
func (self *Element) Draw(ctx vg.Context) { x, y, w, h := self.Bounds() x, y = self.Clamp(x, y) // draw background c := CloneColor(self.ActiveBackground) bg := ctx.BoxGradient(x, y, w, h, h, h, c, c) ctx.BeginPath() ctx.RoundedRect(x, y, w, h, self.CornerRadius) ctx.FillPaint(bg) ctx.Fill() ctx.StrokeWidth(self.BorderWidth) ctx.StrokeColor(c.Lighten(-0.5)) ctx.Stroke() if self.DrawCB != nil { self.DrawCB(ctx) } }
func (self *Text) Draw(ctx vg.Context) { x, y, w, h := self.Bounds() self.lastContext = &ctx ctx.Scissor(x, y, w, h) ctx.BeginPath() ctx.RoundedRect(x, y, w, h, self.CornerRadius) ctx.FillColor(self.Background) ctx.Fill() ctx.FillColor(self.Foreground) self.forEachDrawnToken(x, y, w, h, func(i int, x, y, lineHeight float64, bounds *ui.Rectangle, ctx *vg.Context) { ctx.Text(x, y, self.tokens[i]) }, ) // for i := 0; i < len(self.selections); i++ { // s := self.selections[i] // } ctx.ResetScissor() }
func (self *Text) spaceWidth(ctx *vg.Context) float64 { xmin, _, xmax, _ := ctx.TextBounds(".", 0, 0) return xmax - xmin }