Procházet zdrojové kódy

gui builder dev...

leonsal před 8 roky
rodič
revize
8ee2c69555
5 změnil soubory, kde provedl 255 přidání a 67 odebrání
  1. 39 0
      core/node.go
  2. 1 0
      gui/align.go
  3. 105 66
      gui/builder.go
  4. 1 0
      gui/builder_layout.go
  5. 109 1
      gui/builder_panel.go

+ 39 - 0
core/node.go

@@ -5,6 +5,8 @@
 package core
 
 import (
+	"strings"
+
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/math32"
 )
@@ -93,6 +95,43 @@ func (n *Node) LoaderID() string {
 	return n.loaderID
 }
 
+// FindPath finds a node with the specified path starting with this node and
+// searching in all its children recursively.
+// A path is the sequence of the names from the first node to the desired node
+// separated by the forward slash.
+func (n *Node) FindPath(path string) INode {
+
+	// Internal recursive function to find node
+	var finder func(inode INode, path string) INode
+	finder = func(inode INode, path string) INode {
+		// Get first component of the path
+		parts := strings.Split(path, "/")
+		if len(parts) == 0 {
+			return nil
+		}
+		first := parts[0]
+		// Checks current node
+		node := inode.GetNode()
+		if node.name != first {
+			return nil
+		}
+		// If the path has finished this is the desired node
+		rest := strings.Join(parts[1:], "/")
+		if rest == "" {
+			return inode
+		}
+		// Otherwise search in this node children
+		for _, ichild := range node.children {
+			found := finder(ichild, rest)
+			if found != nil {
+				return found
+			}
+		}
+		return nil
+	}
+	return finder(n, path)
+}
+
 // FindLoaderID looks in the specified node and all its children
 // for a node with the specifid loaderID and if found returns it.
 // Returns nil if not found

+ 1 - 0
gui/align.go

@@ -1,6 +1,7 @@
 // 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
 
 // Align specifies the alignment of an object inside another

+ 105 - 66
gui/builder.go

@@ -20,7 +20,7 @@ import (
 
 // Builder builds GUI objects from a declarative description in YAML format
 type Builder struct {
-	am       map[string]interface{}     // parsed map with gui object atttributes
+	am       map[string]interface{}     // parsed attribute map
 	builders map[string]BuilderFunc     // map of builder functions by type
 	attribs  map[string]AttribCheckFunc // map of attribute name with check functions
 	layouts  map[string]IBuilderLayout  // map of layout type to layout builder
@@ -36,6 +36,9 @@ type IBuilderLayout interface {
 // BuilderFunc is type for functions which build a gui object from an attribute map
 type BuilderFunc func(*Builder, map[string]interface{}) (IPanel, error)
 
+// AttribCheckFunc is the type for all attribute check functions
+type AttribCheckFunc func(b *Builder, am map[string]interface{}, fname string) error
+
 // IgnoreSuffix specified the suffix of ignored keys
 const IgnoreSuffix = "_"
 
@@ -62,6 +65,7 @@ const (
 	TypeMenuBar     = "menubar"
 	TypeMenu        = "menu"
 	TypeWindow      = "window"
+	TypeChart       = "chart"
 	TypeHBoxLayout  = "hbox"
 	TypeVBoxLayout  = "vbox"
 	TypeGridLayout  = "grid"
@@ -70,56 +74,67 @@ const (
 
 // Common attribute names
 const (
-	AttribAlignv       = "alignv"       // Align
-	AttribAlignh       = "alignh"       // Align
-	AttribAspectHeight = "aspectheight" // float32
-	AttribAspectWidth  = "aspectwidth"  // float32
-	AttribBgColor      = "bgcolor"      // Color4
-	AttribBorders      = "borders"      // BorderSizes
-	AttribBorderColor  = "bordercolor"  // Color4
-	AttribChecked      = "checked"      // bool
-	AttribColor        = "color"        // Color4
-	AttribCols         = "cols"         // Int
-	AttribColSpan      = "colspan"      // Int
-	AttribEdge         = "edge"         // int
-	AttribEnabled      = "enabled"      // bool
-	AttribExpand       = "expand"       // float32
-	AttribExpandh      = "expandh"      // bool
-	AttribExpandv      = "expandv"      // bool
-	AttribFontColor    = "fontcolor"    // Color4
-	AttribFontDPI      = "fontdpi"      // float32
-	AttribFontSize     = "fontsize"     // float32
-	AttribGroup        = "group"        // string
-	AttribHeight       = "height"       // float32
-	AttribIcon         = "icon"         // string
-	AttribImageFile    = "imagefile"    // string
-	AttribImageLabel   = "imagelabel"   // []map[string]interface{}
-	AttribItems        = "items"        // []map[string]interface{}
-	AttribLayout       = "layout"       // map[string]interface{}
-	AttribLayoutParams = "layoutparams" // map[string]interface{}
-	AttribLineSpacing  = "linespacing"  // float32
-	AttribMinHeight    = "minheight"    // bool
-	AttribMinWidth     = "minwidth"     // bool
-	AttribMargins      = "margins"      // BorderSizes
-	AttribName         = "name"         // string
-	AttribPaddings     = "paddings"     // BorderSizes
-	AttribPanel0       = "panel0"       // map[string]interface{}
-	AttribPanel1       = "panel1"       // map[string]interface{}
-	AttribParent_      = "parent_"      // string (internal attribute)
-	AttribPlaceHolder  = "placeholder"  // string
-	AttribPosition     = "position"     // []float32
-	AttribRender       = "render"       // bool
-	AttribResizable    = "resizable"    // Resizable
-	AttribScaleFactor  = "scalefactor"  // float32
-	AttribShortcut     = "shortcut"     // []int
-	AttribSpacing      = "spacing"      // float32
-	AttribSplit        = "split"        // float32
-	AttribText         = "text"         // string
-	AttribTitle        = "title"        // string
-	AttribType         = "type"         // string
-	AttribWidth        = "width"        // float32
-	AttribValue        = "value"        // float32
-	AttribVisible      = "visible"      // bool
+	AttribAlignv         = "alignv"       // Align
+	AttribAlignh         = "alignh"       // Align
+	AttribAspectHeight   = "aspectheight" // float32
+	AttribAspectWidth    = "aspectwidth"  // float32
+	AttribBgColor        = "bgcolor"      // Color4
+	AttribBorders        = "borders"      // BorderSizes
+	AttribBorderColor    = "bordercolor"  // Color4
+	AttribChecked        = "checked"      // bool
+	AttribColor          = "color"        // Color4
+	AttribCols           = "cols"         // int
+	AttribColSpan        = "colspan"      // int
+	AttribCountStepx     = "countstepx"   // float32
+	AttribEdge           = "edge"         // int
+	AttribEnabled        = "enabled"      // bool
+	AttribExpand         = "expand"       // float32
+	AttribExpandh        = "expandh"      // bool
+	AttribExpandv        = "expandv"      // bool
+	AttribFirstx         = "firstx"       // float32
+	AttribFontColor      = "fontcolor"    // Color4
+	AttribFontDPI        = "fontdpi"      // float32
+	AttribFontSize       = "fontsize"     // float32
+	AttribFormat         = "format"       // string
+	AttribGroup          = "group"        // string
+	AttribHeight         = "height"       // float32
+	AttribIcon           = "icon"         // string
+	AttribImageFile      = "imagefile"    // string
+	AttribImageLabel     = "imagelabel"   // []map[string]interface{}
+	AttribItems          = "items"        // []map[string]interface{}
+	AttribLayout         = "layout"       // map[string]interface{}
+	AttribLayoutParams   = "layoutparams" // map[string]interface{}
+	AttribLineSpacing    = "linespacing"  // float32
+	AttribLines          = "lines"        // int
+	AttribMargin         = "margin"       // float32
+	AttribMargins        = "margins"      // BorderSizes
+	AttribMinHeight      = "minheight"    // bool
+	AttribMinWidth       = "minwidth"     // bool
+	AttribName           = "name"         // string
+	AttribPaddings       = "paddings"     // BorderSizes
+	AttribPanel0         = "panel0"       // map[string]interface{}
+	AttribPanel1         = "panel1"       // map[string]interface{}
+	AttribParentInternal = "parent_"      // string (internal attribute)
+	AttribPlaceHolder    = "placeholder"  // string
+	AttribPosition       = "position"     // []float32
+	AttribRangeAuto      = "rangeauto"    // bool
+	AttribRangeMin       = "rangemin"     // float32
+	AttribRangeMax       = "rangemax"     // float32
+	AttribRender         = "render"       // bool
+	AttribResizable      = "resizable"    // Resizable
+	AttribScaleFactor    = "scalefactor"  // float32
+	AttribScalex         = "scalex"       // map[string]interface{}
+	AttribScaley         = "scaley"       // map[string]interface{}
+	AttribShortcut       = "shortcut"     // []int
+	AttribSpacing        = "spacing"      // float32
+	AttribSplit          = "split"        // float32
+	AttribStepx          = "stepx"        // float32
+	AttribText           = "text"         // string
+	AttribTitle          = "title"        // string
+	AttribType           = "type"         // string
+	AttribWidth          = "width"        // float32
+	AttribValue          = "value"        // float32
+	AttribVisible        = "visible"      // bool
 )
 
 const (
@@ -174,9 +189,6 @@ var mapResizable = map[string]Resizable{
 	"all":    ResizeAll,
 }
 
-// AttribCheckFunc is the type for all attribute check functions
-type AttribCheckFunc func(b *Builder, am map[string]interface{}, fname string) error
-
 // NewBuilder creates and returns a pointer to a new gui Builder object
 func NewBuilder() *Builder {
 
@@ -202,6 +214,7 @@ func NewBuilder() *Builder {
 		TypeVSplitter:   buildSplitter,
 		TypeTree:        buildTree,
 		TypeWindow:      buildWindow,
+		TypeChart:       buildChart,
 	}
 	// Sets map of layout type name to layout function
 	b.layouts = map[string]IBuilderLayout{
@@ -217,6 +230,7 @@ func NewBuilder() *Builder {
 		AttribAspectWidth:  AttribCheckFloat,
 		AttribAspectHeight: AttribCheckFloat,
 		AttribHeight:       AttribCheckFloat,
+		AttribMargin:       AttribCheckFloat,
 		AttribMargins:      AttribCheckBorderSizes,
 		AttribBgColor:      AttribCheckColor,
 		AttribBorders:      AttribCheckBorderSizes,
@@ -225,14 +239,17 @@ func NewBuilder() *Builder {
 		AttribColor:        AttribCheckColor,
 		AttribCols:         AttribCheckInt,
 		AttribColSpan:      AttribCheckInt,
+		AttribCountStepx:   AttribCheckFloat,
 		AttribEdge:         AttribCheckEdge,
 		AttribEnabled:      AttribCheckBool,
 		AttribExpand:       AttribCheckFloat,
 		AttribExpandh:      AttribCheckBool,
 		AttribExpandv:      AttribCheckBool,
+		AttribFirstx:       AttribCheckFloat,
 		AttribFontColor:    AttribCheckColor,
 		AttribFontDPI:      AttribCheckFloat,
 		AttribFontSize:     AttribCheckFloat,
+		AttribFormat:       AttribCheckString,
 		AttribGroup:        AttribCheckString,
 		AttribIcon:         AttribCheckIcons,
 		AttribImageFile:    AttribCheckString,
@@ -241,6 +258,7 @@ func NewBuilder() *Builder {
 		AttribLayout:       AttribCheckLayout,
 		AttribLayoutParams: AttribCheckMap,
 		AttribLineSpacing:  AttribCheckFloat,
+		AttribLines:        AttribCheckInt,
 		AttribMinHeight:    AttribCheckBool,
 		AttribMinWidth:     AttribCheckBool,
 		AttribName:         AttribCheckString,
@@ -249,12 +267,18 @@ func NewBuilder() *Builder {
 		AttribPanel1:       AttribCheckMap,
 		AttribPlaceHolder:  AttribCheckString,
 		AttribPosition:     AttribCheckPosition,
+		AttribRangeAuto:    AttribCheckBool,
+		AttribRangeMin:     AttribCheckFloat,
+		AttribRangeMax:     AttribCheckFloat,
 		AttribRender:       AttribCheckBool,
 		AttribResizable:    AttribCheckResizable,
 		AttribScaleFactor:  AttribCheckFloat,
+		AttribScalex:       AttribCheckMap,
+		AttribScaley:       AttribCheckMap,
 		AttribShortcut:     AttribCheckMenuShortcut,
 		AttribSpacing:      AttribCheckFloat,
 		AttribSplit:        AttribCheckFloat,
+		AttribStepx:        AttribCheckFloat,
 		AttribText:         AttribCheckString,
 		AttribTitle:        AttribCheckString,
 		AttribType:         AttribCheckStringLower,
@@ -343,7 +367,7 @@ func (b *Builder) ParseString(desc string) error {
 				}
 			}
 			if par != nil {
-				ms[AttribParent_] = par
+				ms[AttribParentInternal] = par
 			}
 			return ms, nil
 
@@ -428,17 +452,33 @@ func (b *Builder) Build(name string) (IPanel, error) {
 	return b.build(am.(map[string]interface{}), nil)
 }
 
-// SetImagePath Sets the path for image panels relative image files
+// SetImagepath Sets the path for image panels relative image files
 func (b *Builder) SetImagepath(path string) {
 
 	b.imgpath = path
 }
 
-func (b *Builder) AddBuilder(typename string, bf BuilderFunc) {
+// AddBuilderPanel adds a panel builder function for the specified type name.
+// If the type name already exists it is replaced.
+func (b *Builder) AddBuilderPanel(typename string, bf BuilderFunc) {
 
 	b.builders[typename] = bf
 }
 
+// AddBuilderLayout adds a layout builder object for the specified type name.
+// If the type name already exists it is replaced.
+func (b *Builder) AddBuilderLayout(typename string, bl IBuilderLayout) {
+
+	b.layouts[typename] = bl
+}
+
+// AddAttrib adds an attribute type and its checker/converte
+// If the attribute type name already exists it is replaced.
+func (b *Builder) AddAttrib(typename string, acf AttribCheckFunc) {
+
+	b.attribs[typename] = acf
+}
+
 // build builds the gui object from the specified description.
 // All its children are also built recursively
 // Returns the built object or an error
@@ -483,7 +523,6 @@ func (b *Builder) setAttribs(am map[string]interface{}, ipan IPanel, attr uint)
 	// Set optional panel width
 	if attr&aSIZE != 0 && am[AttribWidth] != nil {
 		panel.SetWidth(am[AttribWidth].(float32))
-		log.Error("set width:%v", am[AttribWidth])
 	}
 
 	// Sets optional panel height
@@ -582,7 +621,7 @@ func (b *Builder) setLayoutParams(am map[string]interface{}, ipan IPanel) error
 	lp := lpi.(map[string]interface{})
 
 	// Get layout type from parent
-	pi := am[AttribParent_]
+	pi := am[AttribParentInternal]
 	if pi == nil {
 		return b.err(am, AttribType, "Panel has no parent")
 	}
@@ -633,7 +672,7 @@ func AttribCheckResizable(b *Builder, am map[string]interface{}, fname string) e
 	return nil
 }
 
-// AttributeCheckEdge checks and converts attribute with name of layout edge
+// AttribCheckEdge checks and converts attribute with name of layout edge
 func AttribCheckEdge(b *Builder, am map[string]interface{}, fname string) error {
 
 	v := am[fname]
@@ -652,7 +691,7 @@ func AttribCheckEdge(b *Builder, am map[string]interface{}, fname string) error
 	return nil
 }
 
-// AttributeCheckLayout checks and converts layout attribute
+// AttribCheckLayout checks and converts layout attribute
 func AttribCheckLayout(b *Builder, am map[string]interface{}, fname string) error {
 
 	v := am[fname]
@@ -674,7 +713,7 @@ func AttribCheckLayout(b *Builder, am map[string]interface{}, fname string) erro
 	return nil
 }
 
-// AttributeCheckAlignt checks and converts layout align* attribute
+// AttribCheckAlign checks and converts layout align* attribute
 func AttribCheckAlign(b *Builder, am map[string]interface{}, fname string) error {
 
 	v := am[fname]
@@ -698,7 +737,7 @@ func AttribCheckAlign(b *Builder, am map[string]interface{}, fname string) error
 	return nil
 }
 
-// AttributeCheckMenuShortcut checks and converts attribute describing menu shortcut key
+// AttribCheckMenuShortcut checks and converts attribute describing menu shortcut key
 func AttribCheckMenuShortcut(b *Builder, am map[string]interface{}, fname string) error {
 
 	v := am[fname]
@@ -745,7 +784,7 @@ func AttribCheckMenuShortcut(b *Builder, am map[string]interface{}, fname string
 	return nil
 }
 
-// AttributeCheckListMap checks and converts attribute to []map[string]interface{}
+// AttribCheckListMap checks and converts attribute to []map[string]interface{}
 func AttribCheckListMap(b *Builder, am map[string]interface{}, fname string) error {
 
 	v := am[fname]
@@ -769,7 +808,7 @@ func AttribCheckListMap(b *Builder, am map[string]interface{}, fname string) err
 	return nil
 }
 
-// AttributeCheckMap checks and converts attribute to map[string]interface{}
+// AttribCheckMap checks and converts attribute to map[string]interface{}
 func AttribCheckMap(b *Builder, am map[string]interface{}, fname string) error {
 
 	v := am[fname]
@@ -1051,7 +1090,7 @@ func (b *Builder) debugPrint(v interface{}, level int) {
 		level += 3
 		fmt.Printf("\n")
 		for mk, mv := range vt {
-			if mk == AttribParent_ {
+			if mk == AttribParentInternal {
 				continue
 			}
 			fmt.Printf("%s%s:", strings.Repeat(" ", level), mk)

+ 1 - 0
gui/builder_layout.go

@@ -1,6 +1,7 @@
 // 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
 
 //

+ 109 - 1
gui/builder_panel.go

@@ -1,6 +1,7 @@
 // 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 (
@@ -369,7 +370,7 @@ func buildMenu(b *Builder, am map[string]interface{}) (IPanel, error) {
 	}
 
 	// Only sets attribs for top level menus
-	if pi := am[AttribParent_]; pi != nil {
+	if pi := am[AttribParentInternal]; pi != nil {
 		par := pi.(map[string]interface{})
 		ptype := ""
 		if ti := par[AttribType]; ti != nil {
@@ -625,3 +626,110 @@ func buildWindow(b *Builder, am map[string]interface{}) (IPanel, error) {
 	}
 	return win, nil
 }
+
+// buildChart builds a gui object of type: Chart
+func buildChart(b *Builder, am map[string]interface{}) (IPanel, error) {
+
+	// Builds window and sets its common attributes
+	chart := NewChart(0, 0)
+	err := b.setAttribs(am, chart, asPANEL)
+	if err != nil {
+		return nil, err
+	}
+
+	// Sets optional title
+	if title := am[AttribTitle]; title != nil {
+		chart.SetTitle(title.(string), 14)
+	}
+
+	// Sets x scale attibutes
+	if v := am[AttribScalex]; v != nil {
+		sx := v.(map[string]interface{})
+		// Sets optional x scale margin
+		if mx := sx[AttribMargin]; mx != nil {
+			chart.SetMarginX(mx.(float32))
+		}
+		// Sets optional x scale format
+		if fx := sx[AttribFormat]; fx != nil {
+			chart.SetFormatX(fx.(string))
+		}
+		// Sets optional x scale font size
+		if fsize := sx[AttribFontSize]; fsize != nil {
+			chart.SetFontSizeX(float64(fsize.(float32)))
+		}
+		// Number of lines
+		lines := 4
+		if v := sx[AttribLines]; v != nil {
+			lines = v.(int)
+		}
+		// Lines color
+		color4 := math32.NewColor4("Black")
+		if v := sx[AttribColor]; v != nil {
+			color4 = v.(*math32.Color4)
+		}
+		color := color4.ToColor()
+		chart.SetScaleX(lines, &color)
+		// Range first
+		firstX := float32(0)
+		if v := sx[AttribFirstx]; v != nil {
+			firstX = v.(float32)
+		}
+		// Range step
+		stepX := float32(1)
+		if v := sx[AttribStepx]; v != nil {
+			stepX = v.(float32)
+		}
+		// Range count step
+		countStepX := float32(1)
+		if v := sx[AttribStepx]; v != nil {
+			countStepX = v.(float32)
+		}
+		chart.SetRangeX(firstX, stepX, countStepX)
+	}
+
+	// Sets y scale attibutes
+	if v := am[AttribScaley]; v != nil {
+		sy := v.(map[string]interface{})
+		// Sets optional y scale margin
+		if my := sy[AttribMargin]; my != nil {
+			chart.SetMarginY(my.(float32))
+		}
+		// Sets optional y scale format
+		if fy := sy[AttribFormat]; fy != nil {
+			chart.SetFormatY(fy.(string))
+		}
+		// Sets optional y scale font size
+		if fsize := sy[AttribFontSize]; fsize != nil {
+			chart.SetFontSizeY(float64(fsize.(float32)))
+		}
+		// Number of lines
+		lines := 4
+		if v := sy[AttribLines]; v != nil {
+			lines = v.(int)
+		}
+		// Lines color
+		color4 := math32.NewColor4("Black")
+		if v := sy[AttribColor]; v != nil {
+			color4 = v.(*math32.Color4)
+		}
+		color := color4.ToColor()
+		chart.SetScaleY(lines, &color)
+		// Range min
+		rmin := float32(-10)
+		if v := sy[AttribRangeMin]; v != nil {
+			rmin = v.(float32)
+		}
+		// Range max
+		rmax := float32(10)
+		if v := sy[AttribRangeMax]; v != nil {
+			rmax = v.(float32)
+		}
+		chart.SetRangeY(rmin, rmax)
+		// Range auto
+		if rauto := sy[AttribRangeAuto]; rauto != nil {
+			chart.SetRangeYauto(v.(bool))
+		}
+	}
+
+	return chart, nil
+}