leonsal il y a 8 ans
Parent
commit
fd6cda4704
3 fichiers modifiés avec 560 ajouts et 277 suppressions
  1. 426 277
      gui/chart.go
  2. 101 0
      gui/clipper.go
  3. 33 0
      gui/panel.go

+ 426 - 277
gui/chart.go

@@ -5,7 +5,6 @@ import (
 	"github.com/g3n/engine/core"
 	"github.com/g3n/engine/geometry"
 	"github.com/g3n/engine/gls"
-	"github.com/g3n/engine/graphic"
 	"github.com/g3n/engine/material"
 	"github.com/g3n/engine/math32"
 	"github.com/g3n/engine/renderer/shader"
@@ -20,15 +19,15 @@ func init() {
 // ChartLine implements a panel which can contain several line charts
 type ChartLine struct {
 	Panel                // Embedded panel
-	grid    *ChartGrid   // Optional chart grid
+	title   *Label       // Optional title
 	baseX   float32      // NDC x coordinate for y axis
 	baseY   float32      // NDC y coordinate for x axis
 	scaleX  *ChartScaleX // X scale objet
 	firstX  float32      // First value for X label
 	stepX   float32      // Step value for X label
 	formatX string       // Format for X labels
-	scaleY  *ChartScaleY // Y scale objet
-	graphs  []*LineGraph // Array of line graphs
+	//scaleY  *ChartScaleY // Y scale objet
+	//graphs []*LineGraph // Array of line graphs
 }
 
 // NewChartLine creates and returns a new line chart panel with
@@ -45,60 +44,123 @@ func NewChartLine(width, height float32) *ChartLine {
 	return cl
 }
 
-// SetGrid sets the line chart grid with the specified number of
-// grid lines and color
-func (cl *ChartLine) SetGrid(xcount, ycount int, color *math32.Color) {
+func (cl *ChartLine) SetTitle(title *Label) {
 
-	if cl.grid != nil {
-		cl.Node.Remove(cl.grid)
-		cl.grid.Dispose()
+	cl.title = title
+	if cl.title != nil {
+		cl.Add(cl.title)
+	} else {
+		cl.Remove(cl.title)
+	}
+
+	if cl.scaleX != nil {
+		cl.scaleX.recalc()
 	}
-	cl.grid = NewChartGrid(&cl.Panel, xcount, ycount, color)
-	cl.Node.Add(cl.grid)
 }
 
 // SetScaleX sets the line chart x scale number of lines and color
 func (cl *ChartLine) SetScaleX(lines int, color *math32.Color) {
 
 	if cl.scaleX != nil {
-		cl.Node.Remove(cl.scaleX)
+		cl.Remove(cl.scaleX)
 		cl.scaleX.Dispose()
 	}
 	cl.scaleX = newChartScaleX(cl, lines, color)
-	cl.Node.Add(cl.scaleX)
+	cl.Add(cl.scaleX)
 }
 
-// SetScaleY sets the line chart y scale number of lines and color
-func (cl *ChartLine) SetScaleY(lines int, color *math32.Color) {
-
-	if cl.scaleY != nil {
-		cl.Node.Remove(cl.scaleY)
-		cl.scaleY.Dispose()
-	}
-	cl.scaleY = newChartScaleY(cl, lines, color)
-	cl.Node.Add(cl.scaleY)
-}
-
-// AddLine adds a line graph to the chart
-func (cl *ChartLine) AddGraph(name, title string, color *math32.Color, data []float32) {
-
-	graph := newLineGraph(&cl.Panel, name, title, color, data)
-	cl.graphs = append(cl.graphs, graph)
-	cl.Node.Add(graph)
+//// SetScaleY sets the line chart y scale number of lines and color
+//func (cl *ChartLine) SetScaleY(lines int, color *math32.Color) {
+//
+//	if cl.scaleY != nil {
+//		cl.Node.Remove(cl.scaleY)
+//		cl.scaleY.Dispose()
+//	}
+//	cl.scaleY = newChartScaleY(cl, lines, color)
+//	cl.Node.Add(cl.scaleY)
+//}
+//
+//// AddLine adds a line graph to the chart
+//func (cl *ChartLine) AddGraph(name, title string, color *math32.Color, data []float32) {
+//
+//	graph := newLineGraph(&cl.Panel, name, title, color, data)
+//	cl.graphs = append(cl.graphs, graph)
+//	cl.Node.Add(graph)
+//}
+
+/*
+ ChartScaleX is a panel with LINE geometry which draws the chart X horizontal scale axis,
+ vertical lines and line labels.
+
+  |     |
+  |     |
+  |     |
+  |     |
+  +-----+------------------
+  L     L
+
+*/
+type ChartScaleX struct {
+	Panel
+	chart *ChartLine // Container chart
 }
 
+//func NewChartScaleX(width, height float32, lines int, color *math32.Color) *ChartScaleX {
 //
+//	sx := new(ChartScaleX)
+//	baseY := float32(-0.9)
 //
+//	// Generates grid lines using Normalized Device Coordinates and
+//	// considering that the parent panel model coordinates are:
+//	// 0,0,0           1,0,0
+//	// +---------------+
+//	// |               |
+//	// |               |
+//	// +---------------+
+//	// 0,-1,0          1,-1,0
+//	positions := math32.NewArrayF32(0, 0)
+//	// Appends scaleX bottom horizontal base line
+//	positions.Append(
+//		0, baseY, 0, color.R, color.G, color.B, // line start vertex and color
+//		1, baseY, 0, color.R, color.G, color.B, // line end vertex and color
+//	)
+//	// Appends scale X vertical lines
+//	step := 1 / (float32(lines) + 1)
+//	for i := 1; i < lines+1; i++ {
+//		nx := float32(i) * step
+//		positions.Append(
+//			nx, 0, 0, color.R, color.G, color.B, // line start vertex and color
+//			nx, baseY, 0, color.R, color.G, color.B, // line end vertex and color
+//		)
+//		//l := NewLabel(fmt.Sprintf(sx.chart.formatX, float32(i)))
+//		//px, py := ndc2pix(&sx.chart.Panel, nx, chart.baseY)
+//		//log.Error("label px:%v py:%v", px, py)
+//		//l.SetPosition(px, py)
+//		//sx.Add(l)
+//	}
 //
-// ChartScaleX
+//	// Creates geometry using one interlaced VBO
+//	geom := geometry.NewGeometry()
+//	geom.AddVBO(gls.NewVBO().
+//		AddAttrib("VertexPosition", 3).
+//		AddAttrib("VertexColor", 3).
+//		SetBuffer(positions),
+//	)
 //
+//	// Creates material
+//	mat := material.NewMaterial()
+//	mat.SetLineWidth(1.0)
+//	mat.SetShader("shaderChart")
 //
+//	sx.Panel.InitializeGraphic(width, height, geom, mat, gls.LINES)
+//	sx.SetBounded(true)
 //
-type ChartScaleX struct {
-	graphic.Graphic                     // It is a Graphic
-	chart           *ChartLine          // Container chart
-	modelMatrixUni  gls.UniformMatrix4f // Model matrix uniform
-}
+//	l2 := NewLabel("LABEL......")
+//	l2.SetPosition(10, 10)
+//	sx.Panel.Add(l2)
+//	log.Error("sx children:%v", sx.Children())
+//	return sx
+//}
 
 func newChartScaleX(chart *ChartLine, lines int, color *math32.Color) *ChartScaleX {
 
@@ -114,7 +176,6 @@ func newChartScaleX(chart *ChartLine, lines int, color *math32.Color) *ChartScal
 	// +---------------+
 	// 0,-1,0          1,-1,0
 	positions := math32.NewArrayF32(0, 0)
-
 	// Appends scaleX bottom horizontal base line
 	positions.Append(
 		0, chart.baseY, 0, color.R, color.G, color.B, // line start vertex and color
@@ -128,10 +189,6 @@ func newChartScaleX(chart *ChartLine, lines int, color *math32.Color) *ChartScal
 			nx, 0, 0, color.R, color.G, color.B, // line start vertex and color
 			nx, chart.baseY, 0, color.R, color.G, color.B, // line end vertex and color
 		)
-		l := NewLabel(fmt.Sprintf(sx.chart.formatX, float32(i)))
-		px, py := ndc2pix(&sx.chart.Panel, nx, chart.baseY)
-		l.SetPosition(px, py)
-		sx.chart.Add(l)
 	}
 
 	// Creates geometry using one interlaced VBO
@@ -147,276 +204,368 @@ func newChartScaleX(chart *ChartLine, lines int, color *math32.Color) *ChartScal
 	mat.SetLineWidth(1.0)
 	mat.SetShader("shaderChart")
 
-	// Initializes the grid graphic
-	sx.Graphic.Init(geom, gls.LINES)
-	sx.AddMaterial(sx, mat, 0, 0)
-	sx.modelMatrixUni.Init("ModelMatrix")
+	// Initializes the panel with this graphic
+	sx.Panel.InitializeGraphic(chart.ContentWidth(), chart.ContentHeight(), geom, mat, gls.LINES)
+
+	// Add labels after the panel is initialized
+	for i := 1; i < lines+1; i++ {
+		nx := float32(i) * step
+		l := NewLabel(fmt.Sprintf(sx.chart.formatX, float32(i)))
+		px, py := ndc2pix(&sx.chart.Panel, nx, chart.baseY)
+		log.Error("label x:%v y:%v", px, py)
+		l.SetPosition(px, py-20)
+		sx.Add(l)
+	}
+	sx.recalc()
 
 	return sx
 }
 
-// Converts panel ndc coordinates to relative pixels inside panel
-func ndc2pix(p *Panel, nx, ny float32) (px, py float32) {
+func (sx *ChartScaleX) recalc() {
 
-	w := p.ContentWidth()
-	h := p.ContentHeight()
-	return w * nx, -h * ny
+	if sx.chart.title != nil {
+		th := sx.chart.title.Height()
+		sx.SetPosition(0, th)
+		sx.SetHeight(sx.chart.ContentHeight() - th)
+	} else {
+		sx.SetPosition(0, 0)
+		sx.SetHeight(sx.chart.ContentHeight())
+	}
 }
 
 // RenderSetup is called by the renderer before drawing this graphic
 // Calculates the model matrix and transfer to OpenGL.
 func (sx *ChartScaleX) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
 
-	// Set this model matrix the same as the chart panel
-	var mm math32.Matrix4
-	sx.chart.SetModelMatrix(gs, &mm)
+	log.Error("ChartScaleX RenderSetup")
 
-	// Sets and transfer the model matrix uniform
-	sx.modelMatrixUni.SetMatrix4(&mm)
-	sx.modelMatrixUni.Transfer(gs)
+	//	// Set this model matrix the same as the chart panel
+	//	var mm math32.Matrix4
+	//	sx.chart.SetModelMatrix(gs, &mm)
+	//
+	//	// Sets and transfer the model matrix uniform
+	//	sx.modelMatrixUni.SetMatrix4(&mm)
+	//	sx.modelMatrixUni.Transfer(gs)
 }
 
+//func newChartScaleX(chart *ChartLine, lines int, color *math32.Color) *ChartScaleX {
 //
+//	sx := new(ChartScaleX)
+//	sx.chart = chart
 //
+//	// Generates grid lines using Normalized Device Coordinates and
+//	// considering that the parent panel model coordinates are:
+//	// 0,0,0           1,0,0
+//	// +---------------+
+//	// |               |
+//	// |               |
+//	// +---------------+
+//	// 0,-1,0          1,-1,0
+//	positions := math32.NewArrayF32(0, 0)
 //
-// ChartScaleY
+//	// Appends scaleX bottom horizontal base line
+//	positions.Append(
+//		0, chart.baseY, 0, color.R, color.G, color.B, // line start vertex and color
+//		1, chart.baseY, 0, color.R, color.G, color.B, // line end vertex and color
+//	)
+//	// Appends scale X vertical lines
+//	step := 1 / (float32(lines) + 1)
+//	for i := 1; i < lines+1; i++ {
+//		nx := float32(i) * step
+//		positions.Append(
+//			nx, 0, 0, color.R, color.G, color.B, // line start vertex and color
+//			nx, chart.baseY, 0, color.R, color.G, color.B, // line end vertex and color
+//		)
+//		l := NewLabel(fmt.Sprintf(sx.chart.formatX, float32(i)))
+//		px, py := ndc2pix(&sx.chart.Panel, nx, chart.baseY)
+//		l.SetPosition(px, py)
+//		sx.chart.Add(l)
+//	}
 //
+//	// Creates geometry using one interlaced VBO
+//	geom := geometry.NewGeometry()
+//	geom.AddVBO(gls.NewVBO().
+//		AddAttrib("VertexPosition", 3).
+//		AddAttrib("VertexColor", 3).
+//		SetBuffer(positions),
+//	)
 //
+//	// Creates material
+//	mat := material.NewMaterial()
+//	mat.SetLineWidth(1.0)
+//	mat.SetShader("shaderChart")
 //
-type ChartScaleY struct {
-	graphic.Graphic                     // It is a Graphic
-	chart           *ChartLine          // Container chart
-	modelMatrixUni  gls.UniformMatrix4f // Model matrix uniform
-}
-
-func newChartScaleY(chart *ChartLine, lines int, color *math32.Color) *ChartScaleY {
-
-	sy := new(ChartScaleY)
-	sy.chart = chart
-
-	// Generates grid lines using Normalized Device Coordinates and
-	// considering that the parent panel model coordinates are:
-	// 0,0,0           1,0,0
-	// +---------------+
-	// |               |
-	// |               |
-	// +---------------+
-	// 0,-1,0          1,-1,0
-	positions := math32.NewArrayF32(0, 0)
-
-	// Appends scaleY left vertical axis line
-	positions.Append(
-		chart.baseX, 0, 0, color.R, color.G, color.B, // line start vertex and color
-		chart.baseX, -1, 0, color.R, color.G, color.B, // line end vertex and color
-	)
-	// Appends scale horizontal lines starting from baseX
-	step := 1 / (float32(lines) + 1)
-	for i := 1; i < lines+1; i++ {
-		ny := -float32(i) * step
-		positions.Append(
-			chart.baseX, ny, 0, color.R, color.G, color.B, // line start vertex and color
-			1, ny, 0, color.R, color.G, color.B, // line end vertex and color
-		)
-		//		l := NewLabel(fmt.Sprintf(sx.chart.formatX, float32(i)))
-		//		px, py := ndc2pix(&sx.chart.Panel, nx, baseY)
-		//		l.SetPosition(px, py)
-		//		sx.chart.Add(l)
-	}
-
-	// Creates geometry using one interlaced VBO
-	geom := geometry.NewGeometry()
-	geom.AddVBO(gls.NewVBO().
-		AddAttrib("VertexPosition", 3).
-		AddAttrib("VertexColor", 3).
-		SetBuffer(positions),
-	)
-
-	// Creates material
-	mat := material.NewMaterial()
-	mat.SetLineWidth(1.0)
-	mat.SetShader("shaderChart")
-
-	// Initializes the grid graphic
-	sy.Graphic.Init(geom, gls.LINES)
-	sy.AddMaterial(sy, mat, 0, 0)
-	sy.modelMatrixUni.Init("ModelMatrix")
-
-	return sy
-}
-
-// RenderSetup is called by the renderer before drawing this graphic
-// Calculates the model matrix and transfer to OpenGL.
-func (sy *ChartScaleY) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
-
-	// Set this model matrix the same as the chart panel
-	var mm math32.Matrix4
-	sy.chart.SetModelMatrix(gs, &mm)
+//	// Initializes the grid graphic
+//	sx.Graphic.Init(geom, gls.LINES)
+//	sx.AddMaterial(sx, mat, 0, 0)
+//	sx.modelMatrixUni.Init("ModelMatrix")
+//
+//	return sx
+//}
+//
+//
+// Converts panel ndc coordinates to relative pixels inside panel
+func ndc2pix(p *Panel, nx, ny float32) (px, py float32) {
 
-	// Sets and transfer the model matrix uniform
-	sy.modelMatrixUni.SetMatrix4(&mm)
-	sy.modelMatrixUni.Transfer(gs)
+	w := p.ContentWidth()
+	h := p.ContentHeight()
+	return w * nx, -h * ny
 }
 
+//// RenderSetup is called by the renderer before drawing this graphic
+//// Calculates the model matrix and transfer to OpenGL.
+//func (sx *ChartScaleX) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
 //
+//	// Set this model matrix the same as the chart panel
+//	var mm math32.Matrix4
+//	sx.chart.SetModelMatrix(gs, &mm)
 //
+//	// Sets and transfer the model matrix uniform
+//	sx.modelMatrixUni.SetMatrix4(&mm)
+//	sx.modelMatrixUni.Transfer(gs)
+//}
 //
-// ChartGrid
+////
+////
+////
+//// ChartScaleY
+////
+////
+////
+//type ChartScaleY struct {
+//	graphic.Graphic                     // It is a Graphic
+//	chart           *ChartLine          // Container chart
+//	modelMatrixUni  gls.UniformMatrix4f // Model matrix uniform
+//}
 //
+//func newChartScaleY(chart *ChartLine, lines int, color *math32.Color) *ChartScaleY {
 //
+//	sy := new(ChartScaleY)
+//	sy.chart = chart
 //
-
-// ChartGrid implements a 2D grid used inside charts
-type ChartGrid struct {
-	graphic.Graphic                     // It is a Graphic
-	chart           *Panel              // Container chart
-	modelMatrixUni  gls.UniformMatrix4f // Model matrix uniform
-}
-
-// NewChartGrid creates and returns a pointer to a chart grid graphic for the
-// specified parent chart and with the specified number of grid lines and color.
-func NewChartGrid(chart *Panel, xcount, ycount int, color *math32.Color) *ChartGrid {
-
-	cg := new(ChartGrid)
-	cg.chart = chart
-
-	// Generates grid lines using Normalized Device Coordinates and
-	// considering that the parent panel model coordinates are:
-	// 0,0,0           1,0,0
-	// +---------------+
-	// |               |
-	// |               |
-	// +---------------+
-	// 0,-1,0          1,-1,0
-	positions := math32.NewArrayF32(0, 0)
-	xstep := 1 / (float32(xcount) + 1)
-	for xi := 1; xi < xcount+1; xi++ {
-		posx := float32(xi) * xstep
-		positions.Append(
-			posx, 0, 0, color.R, color.G, color.B, // line start vertex and color
-			posx, -1, 0, color.R, color.G, color.B, // line end vertex and color
-		)
-	}
-	ystep := 1 / (float32(ycount) + 1)
-	for yi := 1; yi < ycount+1; yi++ {
-		posy := -float32(yi) * ystep
-		positions.Append(
-			0, posy, 0, color.R, color.G, color.B, // line start vertex and color
-			1, posy, 0, color.R, color.G, color.B, // line end vertex and color
-		)
-	}
-
-	// Creates geometry using one interlaced VBO
-	geom := geometry.NewGeometry()
-	geom.AddVBO(
-		gls.NewVBO().
-			AddAttrib("VertexPosition", 3).
-			AddAttrib("VertexColor", 3).
-			SetBuffer(positions),
-	)
-
-	// Creates material
-	mat := material.NewMaterial()
-	mat.SetLineWidth(1.0)
-	mat.SetShader("shaderChart")
-
-	// Initializes the grid graphic
-	cg.Graphic.Init(geom, gls.LINES)
-	cg.AddMaterial(cg, mat, 0, 0)
-	cg.modelMatrixUni.Init("ModelMatrix")
-	return cg
-}
-
-// RenderSetup is called by the renderer before drawing this graphic
-// Calculates the model matrix and transfer to OpenGL.
-func (cg *ChartGrid) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
-
-	// Set this model matrix the same as the chart panel
-	var mm math32.Matrix4
-	cg.chart.SetModelMatrix(gs, &mm)
-
-	// Sets and transfer the model matrix uniform
-	cg.modelMatrixUni.SetMatrix4(&mm)
-	cg.modelMatrixUni.Transfer(gs)
-}
-
+//	// Generates grid lines using Normalized Device Coordinates and
+//	// considering that the parent panel model coordinates are:
+//	// 0,0,0           1,0,0
+//	// +---------------+
+//	// |               |
+//	// |               |
+//	// +---------------+
+//	// 0,-1,0          1,-1,0
+//	positions := math32.NewArrayF32(0, 0)
 //
+//	// Appends scaleY left vertical axis line
+//	positions.Append(
+//		chart.baseX, 0, 0, color.R, color.G, color.B, // line start vertex and color
+//		chart.baseX, -1, 0, color.R, color.G, color.B, // line end vertex and color
+//	)
+//	// Appends scale horizontal lines starting from baseX
+//	step := 1 / (float32(lines) + 1)
+//	for i := 1; i < lines+1; i++ {
+//		ny := -float32(i) * step
+//		positions.Append(
+//			chart.baseX, ny, 0, color.R, color.G, color.B, // line start vertex and color
+//			1, ny, 0, color.R, color.G, color.B, // line end vertex and color
+//		)
+//		//		l := NewLabel(fmt.Sprintf(sx.chart.formatX, float32(i)))
+//		//		px, py := ndc2pix(&sx.chart.Panel, nx, baseY)
+//		//		l.SetPosition(px, py)
+//		//		sx.chart.Add(l)
+//	}
 //
+//	// Creates geometry using one interlaced VBO
+//	geom := geometry.NewGeometry()
+//	geom.AddVBO(gls.NewVBO().
+//		AddAttrib("VertexPosition", 3).
+//		AddAttrib("VertexColor", 3).
+//		SetBuffer(positions),
+//	)
 //
-// LineGraph
+//	// Creates material
+//	mat := material.NewMaterial()
+//	mat.SetLineWidth(1.0)
+//	mat.SetShader("shaderChart")
 //
+//	// Initializes the grid graphic
+//	sy.Graphic.Init(geom, gls.LINES)
+//	sy.AddMaterial(sy, mat, 0, 0)
+//	sy.modelMatrixUni.Init("ModelMatrix")
 //
+//	return sy
+//}
 //
-
-// LineGraph implemens a 2D line graph
-type LineGraph struct {
-	graphic.Graphic                     // It is a Graphic
-	chart           *Panel              // Container chart
-	modelMatrixUni  gls.UniformMatrix4f // Model matrix uniform
-	name            string              // Name id
-	title           string              // Title string
-	color           *math32.Color       // Line color
-	data            []float32           // Data
-}
-
-// newLineGraph creates and returns a pointer to a line graph graphic for the
-// specified parent chart
-func newLineGraph(chart *Panel, name, title string, color *math32.Color, data []float32) *LineGraph {
-
-	lg := new(LineGraph)
-	lg.chart = chart
-	lg.name = name
-	lg.title = title
-	lg.color = color
-	lg.data = data
-
-	// Generates graph lines using Normalized Device Coordinates and
-	// considering that the parent panel model coordinates are:
-	// 0,0,0           1,0,0
-	// +---------------+
-	// |               |
-	// |               |
-	// +---------------+
-	// 0,-1,0          1,-1,0
-	positions := math32.NewArrayF32(0, 0)
-	for i := 0; i < len(data); i++ {
-		px := float32(i) / float32(len(data))
-		py := -1 + data[i]
-		positions.Append(px, py, 0, color.R, color.G, color.B)
-	}
-
-	// Creates geometry using one interlaced VBO
-	geom := geometry.NewGeometry()
-	geom.AddVBO(gls.NewVBO().
-		AddAttrib("VertexPosition", 3).
-		AddAttrib("VertexColor", 3).
-		SetBuffer(positions),
-	)
-
-	// Creates material
-	mat := material.NewMaterial()
-	mat.SetLineWidth(2.5)
-	mat.SetShader("shaderChart")
-
-	// Initializes the graphic
-	lg.Graphic.Init(geom, gls.LINE_STRIP)
-	lg.AddMaterial(lg, mat, 0, 0)
-	lg.modelMatrixUni.Init("ModelMatrix")
-
-	return lg
-}
-
-// RenderSetup is called by the renderer before drawing this graphic
-// Calculates the model matrix and transfer to OpenGL.
-func (lg *LineGraph) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
-
-	// Set this graphic model matrix the same as the container chart panel
-	var mm math32.Matrix4
-	lg.chart.SetModelMatrix(gs, &mm)
-
-	// Sets and transfer the model matrix uniform
-	lg.modelMatrixUni.SetMatrix4(&mm)
-	lg.modelMatrixUni.Transfer(gs)
-}
+//// RenderSetup is called by the renderer before drawing this graphic
+//// Calculates the model matrix and transfer to OpenGL.
+//func (sy *ChartScaleY) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
+//
+//	// Set this model matrix the same as the chart panel
+//	var mm math32.Matrix4
+//	sy.chart.SetModelMatrix(gs, &mm)
+//
+//	// Sets and transfer the model matrix uniform
+//	sy.modelMatrixUni.SetMatrix4(&mm)
+//	sy.modelMatrixUni.Transfer(gs)
+//}
+//
+////
+////
+////
+//// ChartGrid
+////
+////
+////
+//
+//// ChartGrid implements a 2D grid used inside charts
+//type ChartGrid struct {
+//	graphic.Graphic                     // It is a Graphic
+//	chart           *Panel              // Container chart
+//	modelMatrixUni  gls.UniformMatrix4f // Model matrix uniform
+//}
+//
+//// NewChartGrid creates and returns a pointer to a chart grid graphic for the
+//// specified parent chart and with the specified number of grid lines and color.
+//func NewChartGrid(chart *Panel, xcount, ycount int, color *math32.Color) *ChartGrid {
+//
+//	cg := new(ChartGrid)
+//	cg.chart = chart
+//
+//	// Generates grid lines using Normalized Device Coordinates and
+//	// considering that the parent panel model coordinates are:
+//	// 0,0,0           1,0,0
+//	// +---------------+
+//	// |               |
+//	// |               |
+//	// +---------------+
+//	// 0,-1,0          1,-1,0
+//	positions := math32.NewArrayF32(0, 0)
+//	xstep := 1 / (float32(xcount) + 1)
+//	for xi := 1; xi < xcount+1; xi++ {
+//		posx := float32(xi) * xstep
+//		positions.Append(
+//			posx, 0, 0, color.R, color.G, color.B, // line start vertex and color
+//			posx, -1, 0, color.R, color.G, color.B, // line end vertex and color
+//		)
+//	}
+//	ystep := 1 / (float32(ycount) + 1)
+//	for yi := 1; yi < ycount+1; yi++ {
+//		posy := -float32(yi) * ystep
+//		positions.Append(
+//			0, posy, 0, color.R, color.G, color.B, // line start vertex and color
+//			1, posy, 0, color.R, color.G, color.B, // line end vertex and color
+//		)
+//	}
+//
+//	// Creates geometry using one interlaced VBO
+//	geom := geometry.NewGeometry()
+//	geom.AddVBO(
+//		gls.NewVBO().
+//			AddAttrib("VertexPosition", 3).
+//			AddAttrib("VertexColor", 3).
+//			SetBuffer(positions),
+//	)
+//
+//	// Creates material
+//	mat := material.NewMaterial()
+//	mat.SetLineWidth(1.0)
+//	mat.SetShader("shaderChart")
+//
+//	// Initializes the grid graphic
+//	cg.Graphic.Init(geom, gls.LINES)
+//	cg.AddMaterial(cg, mat, 0, 0)
+//	cg.modelMatrixUni.Init("ModelMatrix")
+//	return cg
+//}
+//
+//// RenderSetup is called by the renderer before drawing this graphic
+//// Calculates the model matrix and transfer to OpenGL.
+//func (cg *ChartGrid) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
+//
+//	// Set this model matrix the same as the chart panel
+//	var mm math32.Matrix4
+//	cg.chart.SetModelMatrix(gs, &mm)
+//
+//	// Sets and transfer the model matrix uniform
+//	cg.modelMatrixUni.SetMatrix4(&mm)
+//	cg.modelMatrixUni.Transfer(gs)
+//}
+//
+////
+////
+////
+//// LineGraph
+////
+////
+////
+//
+//// LineGraph implemens a 2D line graph
+//type LineGraph struct {
+//	graphic.Graphic                     // It is a Graphic
+//	chart           *Panel              // Container chart
+//	modelMatrixUni  gls.UniformMatrix4f // Model matrix uniform
+//	name            string              // Name id
+//	title           string              // Title string
+//	color           *math32.Color       // Line color
+//	data            []float32           // Data
+//}
+//
+//// newLineGraph creates and returns a pointer to a line graph graphic for the
+//// specified parent chart
+//func newLineGraph(chart *Panel, name, title string, color *math32.Color, data []float32) *LineGraph {
+//
+//	lg := new(LineGraph)
+//	lg.chart = chart
+//	lg.name = name
+//	lg.title = title
+//	lg.color = color
+//	lg.data = data
+//
+//	// Generates graph lines using Normalized Device Coordinates and
+//	// considering that the parent panel model coordinates are:
+//	// 0,0,0           1,0,0
+//	// +---------------+
+//	// |               |
+//	// |               |
+//	// +---------------+
+//	// 0,-1,0          1,-1,0
+//	positions := math32.NewArrayF32(0, 0)
+//	for i := 0; i < len(data); i++ {
+//		px := float32(i) / float32(len(data))
+//		py := -1 + data[i]
+//		positions.Append(px, py, 0, color.R, color.G, color.B)
+//	}
+//
+//	// Creates geometry using one interlaced VBO
+//	geom := geometry.NewGeometry()
+//	geom.AddVBO(gls.NewVBO().
+//		AddAttrib("VertexPosition", 3).
+//		AddAttrib("VertexColor", 3).
+//		SetBuffer(positions),
+//	)
+//
+//	// Creates material
+//	mat := material.NewMaterial()
+//	mat.SetLineWidth(2.5)
+//	mat.SetShader("shaderChart")
+//
+//	// Initializes the graphic
+//	lg.Graphic.Init(geom, gls.LINE_STRIP)
+//	lg.AddMaterial(lg, mat, 0, 0)
+//	lg.modelMatrixUni.Init("ModelMatrix")
+//
+//	return lg
+//}
+//
+//// RenderSetup is called by the renderer before drawing this graphic
+//// Calculates the model matrix and transfer to OpenGL.
+//func (lg *LineGraph) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
+//
+//	// Set this graphic model matrix the same as the container chart panel
+//	var mm math32.Matrix4
+//	lg.chart.SetModelMatrix(gs, &mm)
+//
+//	// Sets and transfer the model matrix uniform
+//	lg.modelMatrixUni.SetMatrix4(&mm)
+//	lg.modelMatrixUni.Transfer(gs)
+//}
 
 //
 // Vertex Shader template

+ 101 - 0
gui/clipper.go

@@ -0,0 +1,101 @@
+// Copyright 2016 The G3N Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gui
+
+import (
+	"github.com/g3n/engine/core"
+	"github.com/g3n/engine/geometry"
+	"github.com/g3n/engine/gls"
+	"github.com/g3n/engine/graphic"
+	"github.com/g3n/engine/material"
+	"github.com/g3n/engine/math32"
+)
+
+// Clipper is a 2D graphic which optionally clips its children inside its boundary
+type Clipper struct {
+	graphic.Graphic                     // Embedded graphic
+	root            *Root               // pointer to root container
+	width           float32             // external width in pixels
+	height          float32             // external height in pixels
+	mat             *material.Material  // panel material
+	modelMatrixUni  gls.UniformMatrix4f // pointer to model matrix uniform
+	pospix          math32.Vector3      // absolute position in pixels
+	xmin            float32             // minimum absolute x this panel can use
+	xmax            float32             // maximum absolute x this panel can use
+	ymin            float32             // minimum absolute y this panel can use
+	ymax            float32             // maximum absolute y this panel can use
+	bounded         bool                // panel is bounded by its parent
+	enabled         bool                // enable event processing
+	cursorEnter     bool                // mouse enter dispatched
+	layout          ILayout             // current layout for children
+	layoutParams    interface{}         // current layout parameters used by container panel
+}
+
+// NewClipper creates and returns a pointer to a new clipper with the
+// specified dimensions in pixels
+func NewClipper(width, height float32, geom *geometry.Geometry, mat *material.Material, mode uint32) *Clipper {
+
+	c := new(Clipper)
+	c.Initialize(width, height, geom, mat, mode)
+	return c
+}
+
+// Initialize initializes this panel with a different geometry, material and OpenGL primitive
+func (c *Clipper) Initialize(width, height float32, geom *geometry.Geometry, mat *material.Material, mode uint32) {
+
+	c.width = width
+	c.height = height
+
+	// Initialize graphic
+	c.Graphic.Init(geom, mode)
+	c.AddMaterial(c, mat, 0, 0)
+
+	// Creates and adds uniform
+	c.modelMatrixUni.Init("ModelMatrix")
+
+	// Set defaults
+	c.bounded = true
+	c.enabled = true
+	//c.resize(width, height)
+}
+
+// RenderSetup is called by the Engine before drawing the object
+func (c *Clipper) RenderSetup(gl *gls.GLS, rinfo *core.RenderInfo) {
+
+	// Sets model matrix
+	var mm math32.Matrix4
+	c.SetModelMatrix(gl, &mm)
+	c.modelMatrixUni.SetMatrix4(&mm)
+
+	// Transfer model matrix uniform
+	c.modelMatrixUni.Transfer(gl)
+}
+
+// SetModelMatrix calculates and sets the specified matrix with the model matrix for this panel
+func (c *Clipper) SetModelMatrix(gl *gls.GLS, mm *math32.Matrix4) {
+
+	// Get the current viewport width and height
+	_, _, width, height := gl.GetViewport()
+	fwidth := float32(width)
+	fheight := float32(height)
+
+	// Scale the quad for the viewport so it has fixed dimensions in pixels.
+	fw := float32(c.width) / fwidth
+	fh := float32(c.height) / fheight
+	var scale math32.Vector3
+	scale.Set(2*fw, 2*fh, 1)
+
+	// Convert absolute position in pixel coordinates from the top/left to
+	// standard OpenGL clip coordinates of the quad center
+	var posclip math32.Vector3
+	posclip.X = (c.pospix.X - fwidth/2) / (fwidth / 2)
+	posclip.Y = -(c.pospix.Y - fheight/2) / (fheight / 2)
+	posclip.Z = c.Position().Z
+
+	// Calculates the model matrix
+	var quat math32.Quaternion
+	quat.SetIdentity()
+	mm.Compose(&posclip, &quat, &scale)
+}

+ 33 - 0
gui/panel.go

@@ -142,6 +142,34 @@ func (p *Panel) Initialize(width, height float32) {
 	p.resize(width, height)
 }
 
+// InitializeGraphic initializes this panel with a different graphic
+func (p *Panel) InitializeGraphic(width, height float32, geom *geometry.Geometry, mat *material.Material, mode uint32) {
+
+	p.width = width
+	p.height = height
+
+	// Initialize graphic
+	p.Graphic.Init(geom, mode)
+	p.AddMaterial(p, mat, 0, 0)
+
+	// Creates and adds uniform
+	p.modelMatrixUni.Init("ModelMatrix")
+	p.borderColorUni.Init("BorderColor")
+	p.paddingColorUni.Init("PaddingColor")
+	p.contentColorUni.Init("ContentColor")
+	p.boundsUni.Init("Bounds")
+	p.borderUni.Init("Border")
+	p.paddingUni.Init("Padding")
+	p.contentUni.Init("Content")
+
+	// Set defaults
+	p.borderColorUni.Set(0, 0, 0, 1)
+	p.bounded = true
+	p.enabled = true
+
+	p.resize(width, height)
+}
+
 // GetPanel satisfies the IPanel interface and
 // returns pointer to this panel
 func (pan *Panel) GetPanel() *Panel {
@@ -744,6 +772,11 @@ func (p *Panel) RenderSetup(gl *gls.GLS, rinfo *core.RenderInfo) {
 	p.paddingUni.Transfer(gl)
 	p.contentUni.Transfer(gl)
 	p.modelMatrixUni.Transfer(gl)
+	//log.Error("panel:%p boundsUni.:%v", p, p.boundsUni)
+	//log.Error("panel:%p borderUni.:%v", p, p.borderUni)
+	//log.Error("panel:%p paddingUni:%v", p, p.paddingUni)
+	//log.Error("panel:%p contentUni:%v", p, p.contentUni)
+	//log.Error("panel:%p mm        :%v", p, p.modelMatrixUni)
 }
 
 // SetModelMatrix calculates and sets the specified matrix with the model matrix for this panel