Ver código fonte

gui builder dev...

leonsal 8 anos atrás
pai
commit
ac10a2b208
1 arquivos alterados com 145 adições e 91 exclusões
  1. 145 91
      gui/builder.go

+ 145 - 91
gui/builder.go

@@ -20,7 +20,7 @@ import (
 
 // Builder builds GUI objects from a declarative description in YAML format
 type Builder struct {
-	desc    map[string]*panelDesc // parsed descriptions
+	desc    map[string]*descPanel // parsed descriptions
 	imgpath string                // base path for image panels files
 	objpath strStack              // stack of object names being built
 }
@@ -32,7 +32,7 @@ type descLayout struct {
 }
 
 // descPanel describes all panel types
-type panelDesc struct {
+type descPanel struct {
 	Type         string   // Gui object type: Panel, Label, Edit, etc ...
 	Name         string   // Optional name for identification
 	Position     string   // Optional position as: x y | x,y
@@ -45,12 +45,12 @@ type panelDesc struct {
 	BorderColor  string   // Optional border color as name or 3 or 4 float values
 	Paddings     string   // Optional paddings as 1 or 4 float values
 	Color        string   // Optional color as 1 or 4 float values
-	Enabled      bool
-	Visible      bool
-	Renderable   bool
+	Enabled      *bool
+	Visible      *bool
+	Renderable   *bool
 	Imagefile    string       // For Panel, Button
-	Children     []*panelDesc // Panel
-	Layout       descLayout
+	Children     []*descPanel // Panel
+	Layout       *descLayout  // Optional pointer to layout
 	Text         string       // Label, Button
 	Icons        string       // Label
 	BgColor      string       // Label
@@ -62,8 +62,8 @@ type panelDesc struct {
 	MaxLength    *uint        // Edit
 	Icon         string       // Button
 	Group        string       // RadioButton
-	ImageLabel   *panelDesc   // DropDown
-	Items        []*panelDesc // Menu, MenuBar
+	ImageLabel   *descPanel   // DropDown
+	Items        []*descPanel // Menu, MenuBar
 	Shortcut     string       // Menu
 	Value        *float32     // Slider
 	ScaleFactor  *float32     // Slider
@@ -83,6 +83,8 @@ const (
 	descTypeDropDown    = "DropDown"
 	descTypeHSlider     = "HSlider"
 	descTypeVSlider     = "VSlider"
+	descTypeHSplitter   = "HSplitter"
+	descTypeVSplitter   = "VSplitter"
 	descTypeMenuBar     = "MenuBar"
 	descTypeMenu        = "Menu"
 	fieldMargins        = "margins"
@@ -93,6 +95,22 @@ const (
 	fieldBgColor        = "bgcolor"
 )
 
+const (
+	aPOS         = 1 << iota                          // attribute position
+	aSIZE        = 1 << iota                          // attribute size
+	aNAME        = 1 << iota                          // attribute name
+	aMARGINS     = 1 << iota                          // attribute margins widths
+	aBORDERS     = 1 << iota                          // attribute borders widths
+	aBORDERCOLOR = 1 << iota                          // attribute border color
+	aPADDINGS    = 1 << iota                          // attribute paddings widths
+	aCOLOR       = 1 << iota                          // attribute panel bgcolor
+	aENABLED     = 1 << iota                          // attribute enabled for events
+	aRENDER      = 1 << iota                          // attribute renderable
+	aVISIBLE     = 1 << iota                          // attribute visible
+	asPANEL      = 0xFF                               // attribute set for panels
+	asWIDGET     = aPOS | aNAME | aENABLED | aVISIBLE // attribute set for widgets
+)
+
 // NewBuilder creates and returns a pointer to a new gui Builder object
 func NewBuilder() *Builder {
 
@@ -104,24 +122,24 @@ func NewBuilder() *Builder {
 func (b *Builder) ParseString(desc string) error {
 
 	// Try assuming the description contains a single root panel
-	var pd panelDesc
-	err := yaml.Unmarshal([]byte(desc), &pd)
+	var dp descPanel
+	err := yaml.Unmarshal([]byte(desc), &dp)
 	if err != nil {
 		return err
 	}
-	if pd.Type != "" {
-		b.desc = make(map[string]*panelDesc)
-		b.desc[""] = &pd
+	if dp.Type != "" {
+		b.desc = make(map[string]*descPanel)
+		b.desc[""] = &dp
 		return nil
 	}
 
 	// Try assuming the description is a map of panels
-	var pdm map[string]*panelDesc
-	err = yaml.Unmarshal([]byte(desc), &pdm)
+	var dpm map[string]*descPanel
+	err = yaml.Unmarshal([]byte(desc), &dpm)
 	if err != nil {
 		return err
 	}
-	b.desc = pdm
+	b.desc = dpm
 	return nil
 }
 
@@ -188,7 +206,7 @@ func (b *Builder) SetImagepath(path string) {
 // build builds the gui object from the specified description.
 // All its children are also built recursively
 // Returns the built object or an error
-func (b *Builder) build(pd *panelDesc, iparent IPanel) (IPanel, error) {
+func (b *Builder) build(pd *descPanel, iparent IPanel) (IPanel, error) {
 
 	var err error
 	var pan IPanel
@@ -215,10 +233,17 @@ func (b *Builder) build(pd *panelDesc, iparent IPanel) (IPanel, error) {
 		pan, err = b.buildHList(pd)
 	case descTypeDropDown:
 		pan, err = b.buildDropDown(pd)
+
 	case descTypeHSlider:
 		pan, err = b.buildSlider(pd, true)
 	case descTypeVSlider:
 		pan, err = b.buildSlider(pd, false)
+
+	case descTypeHSplitter:
+		pan, err = b.buildSplitter(pd, true)
+	case descTypeVSplitter:
+		pan, err = b.buildSplitter(pd, false)
+
 	case descTypeMenuBar:
 		pan, err = b.buildMenu(pd, false, true)
 	case descTypeMenu:
@@ -236,11 +261,11 @@ func (b *Builder) build(pd *panelDesc, iparent IPanel) (IPanel, error) {
 }
 
 // buildPanel builds a gui object of type: "Panel"
-func (b *Builder) buildPanel(pd *panelDesc) (IPanel, error) {
+func (b *Builder) buildPanel(pd *descPanel) (IPanel, error) {
 
 	// Builds panel and set common attributes
 	pan := NewPanel(pd.Width, pd.Height)
-	err := b.setCommon(pd, pan)
+	err := b.setCommon(pd, pan, asPANEL)
 	if err != nil {
 		return nil, err
 	}
@@ -259,7 +284,7 @@ func (b *Builder) buildPanel(pd *panelDesc) (IPanel, error) {
 }
 
 // buildImagePanel builds a gui object of type: "ImagePanel"
-func (b *Builder) buildImagePanel(pd *panelDesc) (IPanel, error) {
+func (b *Builder) buildImagePanel(pd *descPanel) (IPanel, error) {
 
 	// Imagefile must be supplied
 	if pd.Imagefile == "" {
@@ -277,7 +302,7 @@ func (b *Builder) buildImagePanel(pd *panelDesc) (IPanel, error) {
 	if err != nil {
 		return nil, err
 	}
-	err = b.setCommon(pd, panel)
+	err = b.setCommon(pd, panel, asPANEL)
 	if err != nil {
 		return nil, err
 	}
@@ -304,7 +329,7 @@ func (b *Builder) buildImagePanel(pd *panelDesc) (IPanel, error) {
 }
 
 // buildLabel builds a gui object of type: "Label"
-func (b *Builder) buildLabel(pd *panelDesc) (IPanel, error) {
+func (b *Builder) buildLabel(pd *descPanel) (IPanel, error) {
 
 	// Builds label with icon or text font
 	var label *Label
@@ -318,7 +343,7 @@ func (b *Builder) buildLabel(pd *panelDesc) (IPanel, error) {
 		label = NewLabel(pd.Text)
 	}
 	// Sets common attributes
-	err = b.setCommon(pd, label)
+	err = b.setCommon(pd, label, asPANEL)
 	if err != nil {
 		return nil, err
 	}
@@ -360,11 +385,11 @@ func (b *Builder) buildLabel(pd *panelDesc) (IPanel, error) {
 }
 
 // buildImageLabel builds a gui object of type: ImageLabel
-func (b *Builder) buildImageLabel(pd *panelDesc) (IPanel, error) {
+func (b *Builder) buildImageLabel(pd *descPanel) (IPanel, error) {
 
 	// Builds image label and set common attributes
 	imglabel := NewImageLabel(pd.Text)
-	err := b.setCommon(pd, imglabel)
+	err := b.setCommon(pd, imglabel, asPANEL)
 	if err != nil {
 		return nil, err
 	}
@@ -382,11 +407,11 @@ func (b *Builder) buildImageLabel(pd *panelDesc) (IPanel, error) {
 }
 
 // buildButton builds a gui object of type: Button
-func (b *Builder) buildButton(pd *panelDesc) (IPanel, error) {
+func (b *Builder) buildButton(pd *descPanel) (IPanel, error) {
 
 	// Builds button and set commont attributes
 	button := NewButton(pd.Text)
-	err := b.setCommon(pd, button)
+	err := b.setCommon(pd, button, asWIDGET)
 	if err != nil {
 		return nil, err
 	}
@@ -417,11 +442,11 @@ func (b *Builder) buildButton(pd *panelDesc) (IPanel, error) {
 }
 
 // buildCheckBox builds a gui object of type: CheckBox
-func (b *Builder) buildCheckBox(pd *panelDesc) (IPanel, error) {
+func (b *Builder) buildCheckBox(pd *descPanel) (IPanel, error) {
 
 	// Builds check box and set commont attributes
 	cb := NewCheckBox(pd.Text)
-	err := b.setCommon(pd, cb)
+	err := b.setCommon(pd, cb, asWIDGET)
 	if err != nil {
 		return nil, err
 	}
@@ -430,11 +455,11 @@ func (b *Builder) buildCheckBox(pd *panelDesc) (IPanel, error) {
 }
 
 // buildRadioButton builds a gui object of type: RadioButton
-func (b *Builder) buildRadioButton(pd *panelDesc) (IPanel, error) {
+func (b *Builder) buildRadioButton(pd *descPanel) (IPanel, error) {
 
 	// Builds check box and set commont attributes
 	rb := NewRadioButton(pd.Text)
-	err := b.setCommon(pd, rb)
+	err := b.setCommon(pd, rb, asWIDGET)
 	if err != nil {
 		return nil, err
 	}
@@ -447,11 +472,11 @@ func (b *Builder) buildRadioButton(pd *panelDesc) (IPanel, error) {
 }
 
 // buildEdit builds a gui object of type: "Edit"
-func (b *Builder) buildEdit(pd *panelDesc) (IPanel, error) {
+func (b *Builder) buildEdit(pd *descPanel) (IPanel, error) {
 
 	// Builds button and set commont attributes
 	edit := NewEdit(int(pd.Width), pd.PlaceHolder)
-	err := b.setCommon(pd, edit)
+	err := b.setCommon(pd, edit, asWIDGET)
 	if err != nil {
 		return nil, err
 	}
@@ -460,11 +485,11 @@ func (b *Builder) buildEdit(pd *panelDesc) (IPanel, error) {
 }
 
 // buildVList builds a gui object of type: VList
-func (b *Builder) buildVList(pd *panelDesc) (IPanel, error) {
+func (b *Builder) buildVList(pd *descPanel) (IPanel, error) {
 
 	// Builds list and set commont attributes
 	list := NewVList(pd.Width, pd.Height)
-	err := b.setCommon(pd, list)
+	err := b.setCommon(pd, list, asWIDGET)
 	if err != nil {
 		return nil, err
 	}
@@ -483,11 +508,11 @@ func (b *Builder) buildVList(pd *panelDesc) (IPanel, error) {
 }
 
 // buildHList builds a gui object of type: VList
-func (b *Builder) buildHList(pd *panelDesc) (IPanel, error) {
+func (b *Builder) buildHList(pd *descPanel) (IPanel, error) {
 
 	// Builds list and set commont attributes
 	list := NewHList(pd.Width, pd.Height)
-	err := b.setCommon(pd, list)
+	err := b.setCommon(pd, list, asWIDGET)
 	if err != nil {
 		return nil, err
 	}
@@ -506,7 +531,7 @@ func (b *Builder) buildHList(pd *panelDesc) (IPanel, error) {
 }
 
 // buildDropDown builds a gui object of type: DropDown
-func (b *Builder) buildDropDown(pd *panelDesc) (IPanel, error) {
+func (b *Builder) buildDropDown(pd *descPanel) (IPanel, error) {
 
 	var imglabel *ImageLabel
 	if pd.ImageLabel != nil {
@@ -522,7 +547,7 @@ func (b *Builder) buildDropDown(pd *panelDesc) (IPanel, error) {
 
 	// Builds drop down and set common attributes
 	dd := NewDropDown(pd.Width, imglabel)
-	err := b.setCommon(pd, dd)
+	err := b.setCommon(pd, dd, asWIDGET)
 	if err != nil {
 		return nil, err
 	}
@@ -543,7 +568,7 @@ func (b *Builder) buildDropDown(pd *panelDesc) (IPanel, error) {
 }
 
 // buildSlider builds a gui object of type: HSlider or VSlider
-func (b *Builder) buildSlider(pd *panelDesc, horiz bool) (IPanel, error) {
+func (b *Builder) buildSlider(pd *descPanel, horiz bool) (IPanel, error) {
 
 	// Builds slider and sets its position
 	var slider *Slider
@@ -553,7 +578,7 @@ func (b *Builder) buildSlider(pd *panelDesc, horiz bool) (IPanel, error) {
 	} else {
 		slider = NewVSlider(pd.Width, pd.Height)
 	}
-	err := b.setPosition(pd, slider)
+	err := b.setCommon(pd, slider, asWIDGET)
 	if err != nil {
 		return nil, err
 	}
@@ -573,9 +598,26 @@ func (b *Builder) buildSlider(pd *panelDesc, horiz bool) (IPanel, error) {
 	return slider, nil
 }
 
+// buildSplitter builds a gui object of type: HSplitterr or VSplitter
+func (b *Builder) buildSplitter(pd *descPanel, horiz bool) (IPanel, error) {
+
+	// Builds splitter and sets its common attributes
+	var splitter *Splitter
+	if horiz {
+		splitter = NewHSplitter(pd.Width, pd.Height)
+	} else {
+		splitter = NewVSplitter(pd.Width, pd.Height)
+	}
+	err := b.setCommon(pd, splitter, asWIDGET)
+	if err != nil {
+		return nil, err
+	}
+	return splitter, nil
+}
+
 // buildMenu builds a gui object of type: Menu or MenuBar from the
 // specified panel descriptor.
-func (b *Builder) buildMenu(pd *panelDesc, child, bar bool) (IPanel, error) {
+func (b *Builder) buildMenu(pd *descPanel, child, bar bool) (IPanel, error) {
 
 	// Builds menu bar or menu
 	var menu *Menu
@@ -584,9 +626,9 @@ func (b *Builder) buildMenu(pd *panelDesc, child, bar bool) (IPanel, error) {
 	} else {
 		menu = NewMenu()
 	}
-	// Only sets position for top level menus
+	// Only sets attribs for top level menus
 	if !child {
-		err := b.setPosition(pd, menu)
+		err := b.setCommon(pd, menu, asWIDGET)
 		if err != nil {
 			return nil, err
 		}
@@ -629,73 +671,85 @@ func (b *Builder) buildMenu(pd *panelDesc, child, bar bool) (IPanel, error) {
 }
 
 // setCommon sets the common attributes in the description to the specified panel
-func (b *Builder) setCommon(pd *panelDesc, ipan IPanel) error {
+func (b *Builder) setCommon(pd *descPanel, ipan IPanel, attr uint) error {
 
+	panel := ipan.GetPanel()
 	// Set optional position
-	err := b.setPosition(pd, ipan)
-	if err != nil {
-		return err
+	if attr&aPOS != 0 && pd.Position != "" {
+		va, err := b.parseFloats("position", pd.Position, 2, 2)
+		if va == nil || err != nil {
+			return err
+		}
+		panel.SetPosition(va[0], va[1])
 	}
-	panel := ipan.GetPanel()
 
 	// Set optional margin sizes
-	bs, err := b.parseBorderSizes(fieldMargins, pd.Margins)
-	if err != nil {
-		return err
-	}
-	if bs != nil {
-		panel.SetMarginsFrom(bs)
+	if attr&aMARGINS != 0 {
+		bs, err := b.parseBorderSizes(fieldMargins, pd.Margins)
+		if err != nil {
+			return err
+		}
+		if bs != nil {
+			panel.SetMarginsFrom(bs)
+		}
 	}
 
 	// Set optional border sizes
-	bs, err = b.parseBorderSizes(fieldBorders, pd.Borders)
-	if err != nil {
-		return err
-	}
-	if bs != nil {
-		panel.SetBordersFrom(bs)
+	if attr&aBORDERS != 0 {
+		bs, err := b.parseBorderSizes(fieldBorders, pd.Borders)
+		if err != nil {
+			return err
+		}
+		if bs != nil {
+			panel.SetBordersFrom(bs)
+		}
 	}
 
 	// Set optional border color
-	c, err := b.parseColor(fieldBorderColor, pd.BorderColor)
-	if err != nil {
-		return err
-	}
-	if c != nil {
-		panel.SetBordersColor4(c)
+	if attr&aBORDERCOLOR != 0 {
+		c, err := b.parseColor(fieldBorderColor, pd.BorderColor)
+		if err != nil {
+			return err
+		}
+		if c != nil {
+			panel.SetBordersColor4(c)
+		}
 	}
 
 	// Set optional paddings sizes
-	bs, err = b.parseBorderSizes(fieldPaddings, pd.Paddings)
-	if err != nil {
-		return err
-	}
-	if bs != nil {
-		panel.SetPaddingsFrom(bs)
+	if attr&aPADDINGS != 0 {
+		bs, err := b.parseBorderSizes(fieldPaddings, pd.Paddings)
+		if err != nil {
+			return err
+		}
+		if bs != nil {
+			panel.SetPaddingsFrom(bs)
+		}
 	}
 
 	// Set optional color
-	c, err = b.parseColor(fieldColor, pd.Color)
-	if err != nil {
-		return err
-	}
-	if c != nil {
-		panel.SetColor4(c)
+	if attr&aCOLOR != 0 {
+		c, err := b.parseColor(fieldColor, pd.Color)
+		if err != nil {
+			return err
+		}
+		if c != nil {
+			panel.SetColor4(c)
+		}
 	}
-	return nil
-}
-
-// Sets the panel optional position from the specified panel descriptor
-func (b *Builder) setPosition(pd *panelDesc, ipan IPanel) error {
 
-	if pd.Position == "" {
-		return nil
+	if attr&aNAME != 0 && pd.Name != "" {
+		panel.SetName(pd.Name)
 	}
-	va, err := b.parseFloats("position", pd.Position, 2, 2)
-	if va == nil || err != nil {
-		return err
+	if attr&aVISIBLE != 0 && pd.Visible != nil {
+		panel.SetVisible(*pd.Visible)
+	}
+	if attr&aENABLED != 0 && pd.Enabled != nil {
+		panel.SetEnabled(*pd.Enabled)
+	}
+	if attr&aRENDER != 0 && pd.Renderable != nil {
+		panel.SetRenderable(*pd.Renderable)
 	}
-	ipan.GetPanel().SetPosition(va[0], va[1])
 	return nil
 }