Procházet zdrojové kódy

gui builder dev...

leonsal před 8 roky
rodič
revize
c5815c8847
2 změnil soubory, kde provedl 305 přidání a 57 odebrání
  1. 106 57
      gui/builder.go
  2. 199 0
      gui/builder_layout.go

+ 106 - 57
gui/builder.go

@@ -24,7 +24,13 @@ type Builder struct {
 	imgpath  string                     // base path for image panels files
 	imgpath  string                     // base path for image panels files
 	builders map[string]BuilderFunc     // map of builder functions by type
 	builders map[string]BuilderFunc     // map of builder functions by type
 	attribs  map[string]AttribCheckFunc // map of attribute name with check functions
 	attribs  map[string]AttribCheckFunc // map of attribute name with check functions
-	layouts  map[string]LayoutFunc      // map of layout type to layout func
+	layouts  map[string]IBuilderLayout  // map of layout type to layout builder
+}
+
+// IBuilderLayout is the interface for all layout builders
+type IBuilderLayout interface {
+	BuildLayout(b *Builder, am map[string]interface{}) (ILayout, error)
+	BuildParams(b *Builder, am map[string]interface{}) (interface{}, error)
 }
 }
 
 
 // BuilderFunc is type for functions which build a gui object from an attribute map
 // BuilderFunc is type for functions which build a gui object from an attribute map
@@ -140,8 +146,13 @@ const (
 	AttribBorderColor  = "bordercolor"  // Color4
 	AttribBorderColor  = "bordercolor"  // Color4
 	AttribChecked      = "checked"      // bool
 	AttribChecked      = "checked"      // bool
 	AttribColor        = "color"        // Color4
 	AttribColor        = "color"        // Color4
+	AttribCols         = "cols"         // Int
+	AttribColSpan      = "colspan"      // Int
+	AttribEdge         = "edge"         // int
 	AttribEnabled      = "enabled"      // bool
 	AttribEnabled      = "enabled"      // bool
 	AttribExpand       = "expand"       // float32
 	AttribExpand       = "expand"       // float32
+	AttribExpandh      = "expandh"      // bool
+	AttribExpandv      = "expandv"      // bool
 	AttribFontColor    = "fontcolor"    // Color4
 	AttribFontColor    = "fontcolor"    // Color4
 	AttribFontDPI      = "fontdpi"      // float32
 	AttribFontDPI      = "fontdpi"      // float32
 	AttribFontSize     = "fontsize"     // float32
 	AttribFontSize     = "fontsize"     // float32
@@ -154,6 +165,8 @@ const (
 	AttribLayout       = "layout"       // map[string]interface{}
 	AttribLayout       = "layout"       // map[string]interface{}
 	AttribLayoutParams = "layoutparams" // map[string]interface{}
 	AttribLayoutParams = "layoutparams" // map[string]interface{}
 	AttribLineSpacing  = "linespacing"  // float32
 	AttribLineSpacing  = "linespacing"  // float32
+	AttribMinHeight    = "minheight"    // bool
+	AttribMinWidth     = "minwidth"     // bool
 	AttribMargins      = "margins"      // BorderSizes
 	AttribMargins      = "margins"      // BorderSizes
 	AttribName         = "name"         // string
 	AttribName         = "name"         // string
 	AttribPaddings     = "paddings"     // BorderSizes
 	AttribPaddings     = "paddings"     // BorderSizes
@@ -253,8 +266,11 @@ func NewBuilder() *Builder {
 		TypeTree:        buildTree,
 		TypeTree:        buildTree,
 	}
 	}
 	// Sets map of layout type name to layout function
 	// Sets map of layout type name to layout function
-	b.layouts = map[string]LayoutFunc{
-		TypeHBoxLayout: layoutHBox,
+	b.layouts = map[string]IBuilderLayout{
+		TypeHBoxLayout: &BuilderLayoutHBox{},
+		TypeVBoxLayout: &BuilderLayoutVBox{},
+		TypeGridLayout: &BuilderLayoutGrid{},
+		TypeDockLayout: &BuilderLayoutDock{},
 	}
 	}
 	// Sets map of attribute name to check function
 	// Sets map of attribute name to check function
 	b.attribs = map[string]AttribCheckFunc{
 	b.attribs = map[string]AttribCheckFunc{
@@ -269,8 +285,13 @@ func NewBuilder() *Builder {
 		AttribBorderColor:  AttribCheckColor,
 		AttribBorderColor:  AttribCheckColor,
 		AttribChecked:      AttribCheckBool,
 		AttribChecked:      AttribCheckBool,
 		AttribColor:        AttribCheckColor,
 		AttribColor:        AttribCheckColor,
+		AttribCols:         AttribCheckInt,
+		AttribColSpan:      AttribCheckInt,
+		AttribEdge:         AttribCheckEdge,
 		AttribEnabled:      AttribCheckBool,
 		AttribEnabled:      AttribCheckBool,
 		AttribExpand:       AttribCheckFloat,
 		AttribExpand:       AttribCheckFloat,
+		AttribExpandh:      AttribCheckBool,
+		AttribExpandv:      AttribCheckBool,
 		AttribFontColor:    AttribCheckColor,
 		AttribFontColor:    AttribCheckColor,
 		AttribFontDPI:      AttribCheckFloat,
 		AttribFontDPI:      AttribCheckFloat,
 		AttribFontSize:     AttribCheckFloat,
 		AttribFontSize:     AttribCheckFloat,
@@ -282,6 +303,8 @@ func NewBuilder() *Builder {
 		AttribLayout:       AttribCheckLayout,
 		AttribLayout:       AttribCheckLayout,
 		AttribLayoutParams: AttribCheckMap,
 		AttribLayoutParams: AttribCheckMap,
 		AttribLineSpacing:  AttribCheckFloat,
 		AttribLineSpacing:  AttribCheckFloat,
+		AttribMinHeight:    AttribCheckBool,
+		AttribMinWidth:     AttribCheckBool,
 		AttribName:         AttribCheckString,
 		AttribName:         AttribCheckString,
 		AttribPaddings:     AttribCheckBorderSizes,
 		AttribPaddings:     AttribCheckBorderSizes,
 		AttribPanel0:       AttribCheckMap,
 		AttribPanel0:       AttribCheckMap,
@@ -313,6 +336,19 @@ func (b *Builder) ParseString(desc string) error {
 		return err
 		return err
 	}
 	}
 
 
+	// If all the values of the top level map keys are other maps,
+	// then it is a description of several objects, otherwise it is
+	// a description of a single object.
+	single := false
+	for _, v := range mii {
+		_, ok := v.(map[interface{}]interface{})
+		if !ok {
+			single = true
+			break
+		}
+	}
+	log.Error("single:%v", single)
+
 	// Internal function which converts map[interface{}]interface{} to
 	// Internal function which converts map[interface{}]interface{} to
 	// map[string]interface{} recursively and lower case of all map keys.
 	// map[string]interface{} recursively and lower case of all map keys.
 	// It also sets a field named "parent_", which pointer to the parent map
 	// It also sets a field named "parent_", which pointer to the parent map
@@ -348,8 +384,8 @@ func (b *Builder) ParseString(desc string) error {
 					return nil, err
 					return nil, err
 				}
 				}
 				ms[ks] = vi
 				ms[ks] = vi
-				// If not parent panel, Checks attribute
-				if par != nil {
+				// If has panel has parent or is a single top level panel, checks attributes
+				if par != nil || single {
 					// Get attribute check function
 					// Get attribute check function
 					acf, ok := b.attribs[ks]
 					acf, ok := b.attribs[ks]
 					if !ok {
 					if !ok {
@@ -383,7 +419,7 @@ func (b *Builder) ParseString(desc string) error {
 		return fmt.Errorf("Parsed result is not a map")
 		return fmt.Errorf("Parsed result is not a map")
 	}
 	}
 	b.am = msi
 	b.am = msi
-	b.debugPrint(b.am, 1)
+	//b.debugPrint(b.am, 1)
 	return nil
 	return nil
 }
 }
 
 
@@ -436,8 +472,7 @@ func (b *Builder) Build(name string) (IPanel, error) {
 
 
 	// Only one object
 	// Only one object
 	if name == "" {
 	if name == "" {
-		if b.am[AttribName] != nil {
-		}
+		log.Error("TYPE:---------->%T", b.am)
 		return b.build(b.am, nil)
 		return b.build(b.am, nil)
 	}
 	}
 	// Map of gui objects
 	// Map of gui objects
@@ -1070,6 +1105,7 @@ func buildTree(b *Builder, am map[string]interface{}) (IPanel, error) {
 	return tree, nil
 	return tree, nil
 }
 }
 
 
+// setLayout sets the optional layout of the specified panel
 func (b *Builder) setLayout(am map[string]interface{}, ipan IPanel) error {
 func (b *Builder) setLayout(am map[string]interface{}, ipan IPanel) error {
 
 
 	// Get layout type
 	// Get layout type
@@ -1083,14 +1119,14 @@ func (b *Builder) setLayout(am map[string]interface{}, ipan IPanel) error {
 		return b.err(am, AttribType, "Layout must have a type")
 		return b.err(am, AttribType, "Layout must have a type")
 	}
 	}
 
 
-	// Get layout buider function
-	lfunc := b.layouts[ltype.(string)]
-	if lfunc == nil {
+	// Get layout builder
+	lbuilder := b.layouts[ltype.(string)]
+	if lbuilder == nil {
 		return b.err(am, AttribType, "Invalid layout type")
 		return b.err(am, AttribType, "Invalid layout type")
 	}
 	}
 
 
-	// Builds layout and set to panel
-	layout, err := lfunc(b, lam)
+	// Builds layout builder and set to panel
+	layout, err := lbuilder.BuildLayout(b, lam)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -1100,53 +1136,52 @@ func (b *Builder) setLayout(am map[string]interface{}, ipan IPanel) error {
 
 
 func (b *Builder) setLayoutParams(am map[string]interface{}, ipan IPanel) error {
 func (b *Builder) setLayoutParams(am map[string]interface{}, ipan IPanel) error {
 
 
-	//	// Get layout params attributes
-	//	lpi := am[AttribLayoutParam]
-	//	if lpi == nil {
-	//		return nil
-	//	}
-	//	lp := lpi.(map[string]interface{})
-	//
-	//	// Get layout type from parent
-	//	pi := am[AttribParent_]
-	//	if pi == nil {
-	//		return b.err(am, AttribType, "Panel has no parent")
-	//		return nil
-	//	}
-	//	par := pi.(map[string]interface{})
-	//	lai := par[AttribLayout]
-	//	if lai == nil {
-	//		return nil
-	//	}
-	//	lam := lai.(map[string]interface{})
-	//	ltype := lam[AttribType]
-	//	if ltype == nil {
-	//		return b.err(am, AttribType, "Layout must have a type")
-	//	}
+	// Get layout params attributes
+	lpi := am[AttribLayoutParams]
+	if lpi == nil {
+		return nil
+	}
+	lp := lpi.(map[string]interface{})
 
 
+	// Get layout type from parent
+	pi := am[AttribParent_]
+	if pi == nil {
+		return b.err(am, AttribType, "Panel has no parent")
+	}
+	par := pi.(map[string]interface{})
+	v := par[AttribLayout]
+	if v == nil {
+		return nil
+	}
+	playout := v.(map[string]interface{})
+	pltype := playout[AttribType].(string)
+
+	// Get layout builder and builds layout params
+	lbuilder := b.layouts[pltype]
+	params, err := lbuilder.BuildParams(b, lp)
+	if err != nil {
+		return err
+	}
+	ipan.GetPanel().SetLayoutParams(params)
 	return nil
 	return nil
 }
 }
 
 
-func layoutHBox(b *Builder, am map[string]interface{}) (ILayout, error) {
+func AttribCheckEdge(b *Builder, am map[string]interface{}, fname string) error {
 
 
-	// Creates layout and sets optional spacing
-	l := NewHBoxLayout()
-	var spacing float32
-	if sp := am[AttribSpacing]; sp != nil {
-		spacing = sp.(float32)
+	v := am[fname]
+	if v == nil {
+		return nil
 	}
 	}
-	l.SetSpacing(spacing)
-
-	// Sets optional horizontal alignment
-	if ah := am[AttribAlignh]; ah != nil {
-		l.SetAlignH(ah.(Align))
+	vs, ok := v.(string)
+	if !ok {
+		return b.err(am, fname, "Invalid edge name")
 	}
 	}
-	// Sets optional minheight flag
-	//hbl.SetMinHeight(dl.MinHeight)
-
-	// Sets optional minwidth flag
-	//hbl.SetMinWidth(dl.MinWidth)
-	return l, nil
+	edge, ok := mapEdgeName[vs]
+	if !ok {
+		return b.err(am, fname, "Invalid edge name")
+	}
+	am[fname] = edge
+	return nil
 }
 }
 
 
 func AttribCheckLayout(b *Builder, am map[string]interface{}, fname string) error {
 func AttribCheckLayout(b *Builder, am map[string]interface{}, fname string) error {
@@ -1422,6 +1457,20 @@ func AttribCheckFloat(b *Builder, am map[string]interface{}, fname string) error
 	return nil
 	return nil
 }
 }
 
 
+func AttribCheckInt(b *Builder, am map[string]interface{}, fname string) error {
+
+	v := am[fname]
+	if v == nil {
+		return nil
+	}
+	vint, ok := v.(int)
+	if !ok {
+		return b.err(am, fname, "Not an integer")
+	}
+	am[fname] = vint
+	return nil
+}
+
 func AttribCheckString(b *Builder, am map[string]interface{}, fname string) error {
 func AttribCheckString(b *Builder, am map[string]interface{}, fname string) error {
 
 
 	v := am[fname]
 	v := am[fname]
@@ -2259,10 +2308,10 @@ func (b *Builder) setAttribs(am map[string]interface{}, ipan IPanel, attr uint)
 	if err != nil {
 	if err != nil {
 		return nil
 		return nil
 	}
 	}
-	//		return err
-	//	}
-	//	return b.setLayout(am, ipan)
-	return nil
+
+	// Sets optional layout params
+	err = b.setLayoutParams(am, panel)
+	return err
 }
 }
 
 
 //func (b *Builder) setMenuShortcut(mi *MenuItem, fname, field string) error {
 //func (b *Builder) setMenuShortcut(mi *MenuItem, fname, field string) error {

+ 199 - 0
gui/builder_layout.go

@@ -0,0 +1,199 @@
+// 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
+
+//
+// BuilderLayoutHBox is builder for HBox layout
+//
+type BuilderLayoutHBox struct{}
+
+// BuildLayout builds and returns an HBoxLayout with the specified attributes
+func (bl *BuilderLayoutHBox) BuildLayout(b *Builder, am map[string]interface{}) (ILayout, error) {
+
+	// Creates layout and sets optional spacing
+	l := NewHBoxLayout()
+	var spacing float32
+	if sp := am[AttribSpacing]; sp != nil {
+		spacing = sp.(float32)
+	}
+	l.SetSpacing(spacing)
+
+	// Sets optional horizontal alignment
+	if ah := am[AttribAlignh]; ah != nil {
+		l.SetAlignH(ah.(Align))
+	}
+
+	// Sets optional minheight flag
+	if mh := am[AttribMinHeight]; mh != nil {
+		l.SetMinHeight(mh.(bool))
+	}
+
+	// Sets optional minwidth flag
+	if mw := am[AttribMinWidth]; mw != nil {
+		l.SetMinWidth(mw.(bool))
+	}
+	return l, nil
+}
+
+// BuildParams builds and returns a pointer to HBoxLayoutParams with the specified attributes
+func (bl *BuilderLayoutHBox) BuildParams(b *Builder, am map[string]interface{}) (interface{}, error) {
+
+	// Creates layout parameters with default values
+	params := HBoxLayoutParams{Expand: 0, AlignV: AlignNone}
+
+	// Sets optional expand parameter
+	if expand := am[AttribExpand]; expand != nil {
+		params.Expand = expand.(float32)
+	}
+
+	// Sets optional align parameter
+	if alignv := am[AttribAlignv]; alignv != nil {
+		params.AlignV = alignv.(Align)
+	}
+	return &params, nil
+}
+
+//
+// BuilderLayoutVBox is builder for VBox layout
+//
+type BuilderLayoutVBox struct{}
+
+// BuildLayout builds and returns an VBoxLayout with the specified attributes
+func (bl *BuilderLayoutVBox) BuildLayout(b *Builder, am map[string]interface{}) (ILayout, error) {
+
+	// Creates layout and sets optional spacing
+	l := NewVBoxLayout()
+	var spacing float32
+	if sp := am[AttribSpacing]; sp != nil {
+		spacing = sp.(float32)
+	}
+	l.SetSpacing(spacing)
+
+	// Sets optional vertical alignment
+	if av := am[AttribAlignh]; av != nil {
+		l.SetAlignV(av.(Align))
+	}
+
+	// Sets optional minheight flag
+	if mh := am[AttribMinHeight]; mh != nil {
+		l.SetMinHeight(mh.(bool))
+	}
+
+	// Sets optional minwidth flag
+	if mw := am[AttribMinWidth]; mw != nil {
+		l.SetMinWidth(mw.(bool))
+	}
+	return l, nil
+}
+
+// BuildParams builds and returns a pointer to VBoxLayoutParams with the specified attributes
+func (bl *BuilderLayoutVBox) BuildParams(b *Builder, am map[string]interface{}) (interface{}, error) {
+
+	// Creates layout parameters with default values
+	params := VBoxLayoutParams{Expand: 0, AlignH: AlignNone}
+
+	// Sets optional expand parameter
+	if expand := am[AttribExpand]; expand != nil {
+		params.Expand = expand.(float32)
+	}
+
+	// Sets optional align parameter
+	if alignh := am[AttribAlignh]; alignh != nil {
+		params.AlignH = alignh.(Align)
+	}
+	return &params, nil
+}
+
+//
+// BuilderLayoutGrid is builder for Grid layout
+//
+type BuilderLayoutGrid struct{}
+
+// BuildLayout builds and returns a GridLayout with the specified attributes
+func (bl *BuilderLayoutGrid) BuildLayout(b *Builder, am map[string]interface{}) (ILayout, error) {
+
+	// Get number of columns
+	v := am[AttribCols]
+	if v == nil {
+		return nil, b.err(am, AttribCols, "Number of columns must be supplied")
+	}
+	cols := v.(int)
+	if cols <= 0 {
+		return nil, b.err(am, AttribCols, "Invalid number of columns")
+	}
+
+	// Creates layout
+	l := NewGridLayout(cols)
+
+	// Sets optional horizontal alignment
+	if ah := am[AttribAlignh]; ah != nil {
+		l.SetAlignH(ah.(Align))
+	}
+
+	// Sets optional vertical alignment
+	if av := am[AttribAlignv]; av != nil {
+		l.SetAlignV(av.(Align))
+	}
+
+	// Sets optional horizontal expand flag
+	if eh := am[AttribExpandh]; eh != nil {
+		l.SetExpandH(eh.(bool))
+	}
+
+	// Sets optional vertical expand flag
+	if ev := am[AttribExpandv]; ev != nil {
+		l.SetExpandV(ev.(bool))
+	}
+
+	return l, nil
+}
+
+// BuildParams builds and returns a pointer to GridLayoutParams with the specified attributes
+func (bl *BuilderLayoutGrid) BuildParams(b *Builder, am map[string]interface{}) (interface{}, error) {
+
+	// Creates layout parameters with default values
+	params := GridLayoutParams{
+		ColSpan: 0,
+		AlignH:  AlignNone,
+		AlignV:  AlignNone,
+	}
+
+	// Sets optional colspan
+	if cs := am[AttribColSpan]; cs != nil {
+		params.ColSpan = cs.(int)
+	}
+
+	// Sets optional alignh parameter
+	if align := am[AttribAlignh]; align != nil {
+		params.AlignH = align.(Align)
+	}
+
+	// Sets optional alignv parameter
+	if align := am[AttribAlignv]; align != nil {
+		params.AlignV = align.(Align)
+	}
+	return &params, nil
+}
+
+//
+// BuilderLayoutDock is builder for Dock layout
+//
+type BuilderLayoutDock struct{}
+
+// BuildLayout builds and returns a DockLayout with the specified attributes
+func (bl *BuilderLayoutDock) BuildLayout(b *Builder, am map[string]interface{}) (ILayout, error) {
+
+	return NewDockLayout(), nil
+}
+
+// BuildParams builds and returns a pointer to DockLayoutParams with the specified attributes
+func (bl *BuilderLayoutDock) BuildParams(b *Builder, am map[string]interface{}) (interface{}, error) {
+
+	edge := am[AttribEdge]
+	if edge == nil {
+		return nil, b.err(am, AttribEdge, "Edge name not found")
+	}
+	params := DockLayoutParams{Edge: edge.(int)}
+	return &params, nil
+}