|
|
@@ -36,76 +36,6 @@ 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)
|
|
|
|
|
|
-// BuilderFunc is type for functions which builds a layout object from an attribute map
|
|
|
-type LayoutFunc func(*Builder, map[string]interface{}) (ILayout, error)
|
|
|
-
|
|
|
-//// descLayout contains all layout attributes
|
|
|
-//type descLayout struct {
|
|
|
-// Type string // Type of the layout: HBox, VBox, Grid, Dock, others...
|
|
|
-// Cols int // Number of columns for Grid layout
|
|
|
-// Spacing float32 // Spacing in pixels for HBox and VBox
|
|
|
-// AlignH string // HBox group alignment type
|
|
|
-// AlignV string // VBox group alignment type
|
|
|
-// MinHeight bool // HBox, VBox minimum height flag
|
|
|
-// MinWidth bool // HBox, VBox minimum width flag
|
|
|
-// ExpandH bool // Grid
|
|
|
-// ExpandV bool // Grid
|
|
|
-//}
|
|
|
-//
|
|
|
-//// descLayoutParam describes all layout parameters types
|
|
|
-//type descLayoutParams struct {
|
|
|
-// Expand *float32 // HBox, VBox expand factor
|
|
|
-// ColSpan int // Grid layout colspan
|
|
|
-// AlignH string // horizontal alignment
|
|
|
-// AlignV string // vertical alignment
|
|
|
-// Edge string // Dock layout edge: top,right,bottom,left,center
|
|
|
-//}
|
|
|
-
|
|
|
-//// descPanel describes all panel attributes
|
|
|
-//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
|
|
|
-// Width *float32 // Optional width (default = 0)
|
|
|
-// Height *float32 // Optional height (default = 0)
|
|
|
-// AspectWidth *float32 // Optional aspectwidth (default = nil)
|
|
|
-// AspectHeight *float32 // Optional aspectwidth (default = nil)
|
|
|
-// Margins string // Optional margins as 1 or 4 float values
|
|
|
-// Borders string // Optional borders as 1 or 4 float values
|
|
|
-// 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 // All:
|
|
|
-// Visible *bool // All:
|
|
|
-// Renderable *bool // All:
|
|
|
-// Imagefile string // For Panel, Button
|
|
|
-// Layout *descLayout // Optional pointer to layout
|
|
|
-// LayoutParams *descLayoutParams // Optional layout parameters
|
|
|
-// Text string // Label, Button
|
|
|
-// Icons string // Label
|
|
|
-// BgColor string // Label
|
|
|
-// FontColor string // Label
|
|
|
-// FontSize *float32 // Label
|
|
|
-// FontDPI *float32 // Label
|
|
|
-// LineSpacing *float32 // Label
|
|
|
-// PlaceHolder string // Edit
|
|
|
-// MaxLength *uint // Edit
|
|
|
-// Icon string // Button
|
|
|
-// Group string // RadioButton
|
|
|
-// Checked bool // CheckBox, RadioButton
|
|
|
-// ImageLabel *descPanel // DropDown
|
|
|
-// Items []*descPanel // Menu, MenuBar
|
|
|
-// Shortcut string // Menu
|
|
|
-// Value *float32 // Slider
|
|
|
-// ScaleFactor *float32 // Slider
|
|
|
-// Title string // Window
|
|
|
-// Resizable string // Window resizable borders
|
|
|
-// P0 *descPanel // Splitter panel 0
|
|
|
-// P1 *descPanel // Splitter panel 1
|
|
|
-// Split *float32 // Splitter split value
|
|
|
-// parent *descPanel // used internally
|
|
|
-//}
|
|
|
-
|
|
|
// Panel and layout types
|
|
|
const (
|
|
|
TypePanel = "panel"
|
|
|
@@ -479,7 +409,6 @@ func (b *Builder) Build(name string) (IPanel, error) {
|
|
|
|
|
|
// Only one object
|
|
|
if name == "" {
|
|
|
- log.Error("TYPE:---------->%T", b.am)
|
|
|
return b.build(b.am, nil)
|
|
|
}
|
|
|
// Map of gui objects
|
|
|
@@ -1569,748 +1498,6 @@ func AttribCheckBool(b *Builder, am map[string]interface{}, fname string) error
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-/***
|
|
|
-
|
|
|
-
|
|
|
-// buildImageLabel builds a gui object of type: ImageLabel
|
|
|
-func (b *Builder) buildImageLabel(pd *descPanel) (IPanel, error) {
|
|
|
-
|
|
|
- // Builds image label and set common attributes
|
|
|
- imglabel := NewImageLabel(pd.Text)
|
|
|
- err := b.setAttribs(pd, imglabel, asPANEL)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- // Sets optional icon(s)
|
|
|
- icons, err := b.parseIconNames("icons", pd.Icons)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- if icons != "" {
|
|
|
- imglabel.SetIcon(icons)
|
|
|
- }
|
|
|
-
|
|
|
- // Sets optional image from file
|
|
|
- // If path is not absolute join with user supplied image base path
|
|
|
- if pd.Imagefile != "" {
|
|
|
- path := pd.Imagefile
|
|
|
- if !filepath.IsAbs(path) {
|
|
|
- path = filepath.Join(b.imgpath, path)
|
|
|
- }
|
|
|
- err := imglabel.SetImageFromFile(path)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return imglabel, nil
|
|
|
-}
|
|
|
-
|
|
|
-// buildButton builds a gui object of type: Button
|
|
|
-func (b *Builder) buildButton(pd *descPanel) (IPanel, error) {
|
|
|
-
|
|
|
- // Builds button and set commont attributes
|
|
|
- button := NewButton(pd.Text)
|
|
|
- err := b.setAttribs(pd, button, asBUTTON)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- // Sets optional icon
|
|
|
- if pd.Icon != "" {
|
|
|
- cp, err := b.parseIconName("icon", pd.Icon)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- button.SetIcon(cp)
|
|
|
- }
|
|
|
-
|
|
|
- // Sets optional image from file
|
|
|
- // If path is not absolute join with user supplied image base path
|
|
|
- if pd.Imagefile != "" {
|
|
|
- path := pd.Imagefile
|
|
|
- if !filepath.IsAbs(path) {
|
|
|
- path = filepath.Join(b.imgpath, path)
|
|
|
- }
|
|
|
- err := button.SetImage(path)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return button, nil
|
|
|
-}
|
|
|
-
|
|
|
-// buildCheckBox builds a gui object of type: CheckBox
|
|
|
-func (b *Builder) buildCheckBox(pd *descPanel) (IPanel, error) {
|
|
|
-
|
|
|
- // Builds check box and set commont attributes
|
|
|
- cb := NewCheckBox(pd.Text)
|
|
|
- err := b.setAttribs(pd, cb, asWIDGET)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- cb.SetValue(pd.Checked)
|
|
|
- return cb, nil
|
|
|
-}
|
|
|
-
|
|
|
-// buildRadioButton builds a gui object of type: RadioButton
|
|
|
-func (b *Builder) buildRadioButton(pd *descPanel) (IPanel, error) {
|
|
|
-
|
|
|
- // Builds check box and set commont attributes
|
|
|
- rb := NewRadioButton(pd.Text)
|
|
|
- err := b.setAttribs(pd, rb, asWIDGET)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- // Sets optional radio button group
|
|
|
- if pd.Group != "" {
|
|
|
- rb.SetGroup(pd.Group)
|
|
|
- }
|
|
|
- rb.SetValue(pd.Checked)
|
|
|
- return rb, nil
|
|
|
-}
|
|
|
-
|
|
|
-// buildEdit builds a gui object of type: "Edit"
|
|
|
-func (b *Builder) buildEdit(dp *descPanel) (IPanel, error) {
|
|
|
-
|
|
|
- // Builds button and set attributes
|
|
|
- width, _ := b.size(dp)
|
|
|
- edit := NewEdit(int(width), dp.PlaceHolder)
|
|
|
- err := b.setAttribs(dp, edit, asWIDGET)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- edit.SetText(dp.Text)
|
|
|
- return edit, nil
|
|
|
-}
|
|
|
-
|
|
|
-// buildVList builds a gui object of type: VList
|
|
|
-func (b *Builder) buildVList(dp *descPanel) (IPanel, error) {
|
|
|
-
|
|
|
- // Builds list and set commont attributes
|
|
|
- width, height := b.size(dp)
|
|
|
- list := NewVList(width, height)
|
|
|
- err := b.setAttribs(dp, list, asWIDGET)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- // Builds list children
|
|
|
- for i := 0; i < len(dp.Items); i++ {
|
|
|
- item := dp.Items[i]
|
|
|
- b.objpath.push(item.Name)
|
|
|
- child, err := b.build(item, list)
|
|
|
- b.objpath.pop()
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- list.Add(child)
|
|
|
- }
|
|
|
- return list, nil
|
|
|
-}
|
|
|
-
|
|
|
-// buildHList builds a gui object of type: VList
|
|
|
-func (b *Builder) buildHList(dp *descPanel) (IPanel, error) {
|
|
|
-
|
|
|
- // Builds list and set commont attributes
|
|
|
- width, height := b.size(dp)
|
|
|
- list := NewHList(width, height)
|
|
|
- err := b.setAttribs(dp, list, asWIDGET)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- // Builds list children
|
|
|
- for i := 0; i < len(dp.Items); i++ {
|
|
|
- item := dp.Items[i]
|
|
|
- b.objpath.push(item.Name)
|
|
|
- child, err := b.build(item, list)
|
|
|
- b.objpath.pop()
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- list.Add(child)
|
|
|
- }
|
|
|
- return list, nil
|
|
|
-}
|
|
|
-
|
|
|
-// buildDropDown builds a gui object of type: DropDown
|
|
|
-func (b *Builder) buildDropDown(pd *descPanel) (IPanel, error) {
|
|
|
-
|
|
|
- // If image label attribute defined use it, otherwise
|
|
|
- // uses default value.
|
|
|
- var imglabel *ImageLabel
|
|
|
- if pd.ImageLabel != nil {
|
|
|
- pd.ImageLabel.Type = descTypeImageLabel
|
|
|
- ipan, err := b.build(pd.ImageLabel, nil)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- imglabel = ipan.(*ImageLabel)
|
|
|
- } else {
|
|
|
- imglabel = NewImageLabel("")
|
|
|
- }
|
|
|
-
|
|
|
- // Builds drop down and set common attributes
|
|
|
- width, _ := b.size(pd)
|
|
|
- dd := NewDropDown(width, imglabel)
|
|
|
- err := b.setAttribs(pd, dd, asWIDGET)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- // Builds drop down children
|
|
|
- for i := 0; i < len(pd.Items); i++ {
|
|
|
- item := pd.Items[i]
|
|
|
- item.Type = descTypeImageLabel
|
|
|
- b.objpath.push(item.Name)
|
|
|
- child, err := b.build(item, dd)
|
|
|
- b.objpath.pop()
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- dd.Add(child.(*ImageLabel))
|
|
|
- }
|
|
|
- return dd, nil
|
|
|
-}
|
|
|
-
|
|
|
-// buildSlider builds a gui object of type: HSlider or VSlider
|
|
|
-func (b *Builder) buildSlider(pd *descPanel, horiz bool) (IPanel, error) {
|
|
|
-
|
|
|
- // Builds slider and sets its position
|
|
|
- width, height := b.size(pd)
|
|
|
- var slider *Slider
|
|
|
- if horiz {
|
|
|
- slider = NewHSlider(width, height)
|
|
|
- } else {
|
|
|
- slider = NewVSlider(width, height)
|
|
|
- }
|
|
|
- err := b.setAttribs(pd, slider, asWIDGET)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- // Sets optional text
|
|
|
- if pd.Text != "" {
|
|
|
- slider.SetText(pd.Text)
|
|
|
- }
|
|
|
- // Sets optional scale factor
|
|
|
- if pd.ScaleFactor != nil {
|
|
|
- slider.SetScaleFactor(*pd.ScaleFactor)
|
|
|
- }
|
|
|
- // Sets optional value
|
|
|
- if pd.Value != nil {
|
|
|
- slider.SetValue(*pd.Value)
|
|
|
- }
|
|
|
- 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
|
|
|
- width, height := b.size(pd)
|
|
|
- var splitter *Splitter
|
|
|
- if horiz {
|
|
|
- splitter = NewHSplitter(width, height)
|
|
|
- } else {
|
|
|
- splitter = NewVSplitter(width, height)
|
|
|
- }
|
|
|
- err := b.setAttribs(pd, splitter, asWIDGET)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- // Optional split value
|
|
|
- if pd.Split != nil {
|
|
|
- splitter.SetSplit(*pd.Split)
|
|
|
- }
|
|
|
-
|
|
|
- // Splitter panel 0 attributes and items
|
|
|
- if pd.P0 != nil {
|
|
|
- err := b.setAttribs(pd.P0, &splitter.P0, asPANEL)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- err = b.addPanelItems(pd.P0, &splitter.P0)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Splitter panel 1 attributes and items
|
|
|
- if pd.P1 != nil {
|
|
|
- err := b.setAttribs(pd.P1, &splitter.P1, asPANEL)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- err = b.addPanelItems(pd.P1, &splitter.P1)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return splitter, nil
|
|
|
-}
|
|
|
-
|
|
|
-// buildTree builds a gui object of type: Tree
|
|
|
-func (b *Builder) buildTree(dp *descPanel) (IPanel, error) {
|
|
|
-
|
|
|
- // Builds tree and sets its common attributes
|
|
|
- width, height := b.size(dp)
|
|
|
- tree := NewTree(width, height)
|
|
|
- err := b.setAttribs(dp, tree, asWIDGET)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- // Internal function to build tree nodes recursively
|
|
|
- var buildItems func(dp *descPanel, pnode *TreeNode) error
|
|
|
- buildItems = func(dp *descPanel, pnode *TreeNode) error {
|
|
|
- for i := 0; i < len(dp.Items); i++ {
|
|
|
- item := dp.Items[i]
|
|
|
- // Item is a tree node
|
|
|
- if item.Type == "" || item.Type == descTypeTreeNode {
|
|
|
- var node *TreeNode
|
|
|
- if pnode == nil {
|
|
|
- node = tree.AddNode(item.Text)
|
|
|
- } else {
|
|
|
- node = pnode.AddNode(item.Text)
|
|
|
- }
|
|
|
- err := buildItems(item, node)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- continue
|
|
|
- }
|
|
|
- // Other controls
|
|
|
- ipan, err := b.build(item, nil)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- if pnode == nil {
|
|
|
- tree.Add(ipan)
|
|
|
- } else {
|
|
|
- pnode.Add(ipan)
|
|
|
- }
|
|
|
- }
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- // Build nodes
|
|
|
- err = buildItems(dp, nil)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- return tree, nil
|
|
|
-}
|
|
|
-
|
|
|
-// buildMenu builds a gui object of type: Menu or MenuBar from the
|
|
|
-// specified panel descriptor.
|
|
|
-func (b *Builder) buildMenu(pd *descPanel, child, bar bool) (IPanel, error) {
|
|
|
-
|
|
|
- // Builds menu bar or menu
|
|
|
- var menu *Menu
|
|
|
- if bar {
|
|
|
- menu = NewMenuBar()
|
|
|
- } else {
|
|
|
- menu = NewMenu()
|
|
|
- }
|
|
|
- // Only sets attribs for top level menus
|
|
|
- if !child {
|
|
|
- err := b.setAttribs(pd, menu, asWIDGET)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Builds and adds menu items
|
|
|
- for i := 0; i < len(pd.Items); i++ {
|
|
|
- item := pd.Items[i]
|
|
|
- // Item is another menu
|
|
|
- if item.Type == descTypeMenu {
|
|
|
- subm, err := b.buildMenu(item, true, false)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- menu.AddMenu(item.Text, subm.(*Menu))
|
|
|
- continue
|
|
|
- }
|
|
|
- // Item is a separator
|
|
|
- if item.Type == "Separator" {
|
|
|
- menu.AddSeparator()
|
|
|
- continue
|
|
|
- }
|
|
|
- // Item must be a menu option
|
|
|
- mi := menu.AddOption(item.Text)
|
|
|
- // Set item optional icon(s)
|
|
|
- icons, err := b.parseIconNames("icon", item.Icon)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- if icons != "" {
|
|
|
- mi.SetIcon(string(icons))
|
|
|
- }
|
|
|
- // Sets optional menu item shortcut
|
|
|
- err = b.setMenuShortcut(mi, "shortcut", item.Shortcut)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- }
|
|
|
- return menu, nil
|
|
|
-}
|
|
|
-
|
|
|
-// buildWindow builds a gui object of type: Window from the
|
|
|
-// specified panel descriptor.
|
|
|
-func (b *Builder) buildWindow(dp *descPanel) (IPanel, error) {
|
|
|
-
|
|
|
- // Builds window and sets its common attributes
|
|
|
- width, height := b.size(dp)
|
|
|
- win := NewWindow(width, height)
|
|
|
- err := b.setAttribs(dp, win, asWIDGET)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- // Title attribute
|
|
|
- win.SetTitle(dp.Title)
|
|
|
-
|
|
|
- // Parse resizable borders
|
|
|
- if dp.Resizable != "" {
|
|
|
- parts := strings.Fields(dp.Resizable)
|
|
|
- var res Resizable
|
|
|
- for _, name := range parts {
|
|
|
- v, ok := mapResizable[name]
|
|
|
- if !ok {
|
|
|
- return nil, b.err("resizable", "Invalid resizable name:"+name)
|
|
|
- }
|
|
|
- res |= v
|
|
|
- }
|
|
|
- win.SetResizable(res)
|
|
|
- }
|
|
|
-
|
|
|
- // Builds window client panel children recursively
|
|
|
- for i := 0; i < len(dp.Items); i++ {
|
|
|
- item := dp.Items[i]
|
|
|
- b.objpath.push(item.Name)
|
|
|
- child, err := b.build(item, win)
|
|
|
- b.objpath.pop()
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- win.Add(child)
|
|
|
- }
|
|
|
- return win, nil
|
|
|
-}
|
|
|
-
|
|
|
-// addPanelItems adds the items in the panel descriptor to the specified panel
|
|
|
-func (b *Builder) addPanelItems(dp *descPanel, ipan IPanel) error {
|
|
|
-
|
|
|
- pan := ipan.GetPanel()
|
|
|
- for i := 0; i < len(dp.Items); i++ {
|
|
|
- item := dp.Items[i]
|
|
|
- b.objpath.push(item.Name)
|
|
|
- child, err := b.build(item, pan)
|
|
|
- b.objpath.pop()
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- pan.Add(child)
|
|
|
- }
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-// setAttribs sets common attributes from the description to the specified panel
|
|
|
-// The attributes which are set can be specified by the specified bitmask.
|
|
|
-func (b *Builder) setAttribs(pd *descPanel, ipan IPanel, attr uint) error {
|
|
|
-
|
|
|
- panel := ipan.GetPanel()
|
|
|
- // Set optional position
|
|
|
- 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])
|
|
|
- }
|
|
|
-
|
|
|
- // Set optional size
|
|
|
- if attr&aSIZE != 0 {
|
|
|
- if pd.Width != nil {
|
|
|
- panel.SetWidth(*pd.Width)
|
|
|
- }
|
|
|
- if pd.Height != nil {
|
|
|
- panel.SetHeight(*pd.Height)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Set optional margin sizes
|
|
|
- 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
|
|
|
- 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
|
|
|
- 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
|
|
|
- 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
|
|
|
- if attr&aCOLOR != 0 {
|
|
|
- c, err := b.parseColor(fieldColor, pd.Color)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- if c != nil {
|
|
|
- panel.SetColor4(c)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if attr&aNAME != 0 && pd.Name != "" {
|
|
|
- panel.SetName(pd.Name)
|
|
|
- }
|
|
|
- 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)
|
|
|
- }
|
|
|
-
|
|
|
- err := b.setLayoutParams(pd, ipan)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- return b.setLayout(pd, ipan)
|
|
|
-}
|
|
|
-
|
|
|
-// setLayoutParams sets the optional layout params attribute for specified the panel
|
|
|
-func (b *Builder) setLayoutParams(dp *descPanel, ipan IPanel) error {
|
|
|
-
|
|
|
- // If layout params not declared, nothing to do
|
|
|
- if dp.LayoutParams == nil {
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- // Get the parent layout
|
|
|
- if dp.parent == nil {
|
|
|
- return b.err("layoutparams", "No parent defined")
|
|
|
- }
|
|
|
- playout := dp.parent.Layout
|
|
|
- if playout == nil {
|
|
|
- return b.err("layoutparams", "Parent does not have layout")
|
|
|
- }
|
|
|
- panel := ipan.GetPanel()
|
|
|
- dlp := dp.LayoutParams
|
|
|
-
|
|
|
- // HBoxLayout parameters
|
|
|
- if playout.Type == descTypeHBoxLayout {
|
|
|
- // Creates layout parameter
|
|
|
- params := HBoxLayoutParams{Expand: 0, AlignV: AlignTop}
|
|
|
- // Sets optional expand parameter
|
|
|
- if dlp.Expand != nil {
|
|
|
- params.Expand = *dlp.Expand
|
|
|
- }
|
|
|
- // Sets optional align parameter
|
|
|
- if dlp.AlignV != "" {
|
|
|
- align, ok := mapAlignName[dlp.AlignV]
|
|
|
- if !ok {
|
|
|
- return b.err("align", "Invalid align name:"+dlp.AlignV)
|
|
|
- }
|
|
|
- params.AlignV = align
|
|
|
- }
|
|
|
- panel.SetLayoutParams(¶ms)
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- // VBoxLayout parameters
|
|
|
- if playout.Type == descTypeVBoxLayout {
|
|
|
- // Creates layout parameter
|
|
|
- params := VBoxLayoutParams{Expand: 0, AlignH: AlignLeft}
|
|
|
- // Sets optional expand parameter
|
|
|
- if dlp.Expand != nil {
|
|
|
- params.Expand = *dlp.Expand
|
|
|
- }
|
|
|
- // Sets optional align parameter
|
|
|
- if dlp.AlignH != "" {
|
|
|
- align, ok := mapAlignName[dlp.AlignH]
|
|
|
- if !ok {
|
|
|
- return b.err("align", "Invalid align name:"+dlp.AlignH)
|
|
|
- }
|
|
|
- params.AlignH = align
|
|
|
- }
|
|
|
- panel.SetLayoutParams(¶ms)
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- // GridLayout parameters
|
|
|
- if playout.Type == descTypeGridLayout {
|
|
|
- // Creates layout parameter
|
|
|
- params := GridLayoutParams{
|
|
|
- ColSpan: 0,
|
|
|
- AlignH: AlignNone,
|
|
|
- AlignV: AlignNone,
|
|
|
- }
|
|
|
- params.ColSpan = dlp.ColSpan
|
|
|
- // Sets optional alignh parameter
|
|
|
- if dlp.AlignH != "" {
|
|
|
- align, ok := mapAlignName[dlp.AlignH]
|
|
|
- if !ok {
|
|
|
- return b.err("alignh", "Invalid align name:"+dlp.AlignH)
|
|
|
- }
|
|
|
- params.AlignH = align
|
|
|
- }
|
|
|
- // Sets optional alignv parameter
|
|
|
- if dlp.AlignV != "" {
|
|
|
- align, ok := mapAlignName[dlp.AlignV]
|
|
|
- if !ok {
|
|
|
- return b.err("alignv", "Invalid align name:"+dlp.AlignV)
|
|
|
- }
|
|
|
- params.AlignV = align
|
|
|
- }
|
|
|
- panel.SetLayoutParams(¶ms)
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- // DockLayout parameters
|
|
|
- if playout.Type == descTypeDockLayout {
|
|
|
- if dlp.Edge != "" {
|
|
|
- edge, ok := mapEdgeName[dlp.Edge]
|
|
|
- if !ok {
|
|
|
- return b.err("edge", "Invalid edge name:"+dlp.Edge)
|
|
|
- }
|
|
|
- params := DockLayoutParams{Edge: edge}
|
|
|
- panel.SetLayoutParams(¶ms)
|
|
|
- return nil
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return b.err("layoutparams", "Invalid parent layout:"+playout.Type)
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-// setLayout sets the optional panel layout and layout parameters
|
|
|
-func (b *Builder) setLayout(dp *descPanel, ipan IPanel) error {
|
|
|
-
|
|
|
- // If layout types not declared, nothing to do
|
|
|
- if dp.Layout == nil {
|
|
|
- return nil
|
|
|
- }
|
|
|
- dl := dp.Layout
|
|
|
-
|
|
|
- // HBox layout
|
|
|
- if dl.Type == descTypeHBoxLayout {
|
|
|
- hbl := NewHBoxLayout()
|
|
|
- hbl.SetSpacing(dl.Spacing)
|
|
|
- if dl.AlignH != "" {
|
|
|
- align, ok := mapAlignName[dl.AlignH]
|
|
|
- if !ok {
|
|
|
- return b.err("align", "Invalid align name:"+dl.AlignV)
|
|
|
- }
|
|
|
- hbl.SetAlignH(align)
|
|
|
- }
|
|
|
- hbl.SetMinHeight(dl.MinHeight)
|
|
|
- hbl.SetMinWidth(dl.MinWidth)
|
|
|
- ipan.SetLayout(hbl)
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- // VBox layout
|
|
|
- if dl.Type == descTypeVBoxLayout {
|
|
|
- vbl := NewVBoxLayout()
|
|
|
- vbl.SetSpacing(dl.Spacing)
|
|
|
- if dl.AlignV != "" {
|
|
|
- align, ok := mapAlignName[dl.AlignV]
|
|
|
- if !ok {
|
|
|
- return b.err("align", "Invalid align name:"+dl.AlignV)
|
|
|
- }
|
|
|
- vbl.SetAlignV(align)
|
|
|
- }
|
|
|
- vbl.SetMinHeight(dl.MinHeight)
|
|
|
- vbl.SetMinWidth(dl.MinWidth)
|
|
|
- ipan.SetLayout(vbl)
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- // Grid layout
|
|
|
- if dl.Type == descTypeGridLayout {
|
|
|
- // Number of columns
|
|
|
- if dl.Cols == 0 {
|
|
|
- return b.err("cols", "Invalid number of columns:"+dl.AlignH)
|
|
|
- }
|
|
|
- grl := NewGridLayout(dl.Cols)
|
|
|
- // Global horizontal alignment
|
|
|
- if dl.AlignH != "" {
|
|
|
- alignh, ok := mapAlignName[dl.AlignH]
|
|
|
- if !ok {
|
|
|
- return b.err("alignh", "Invalid horizontal align:"+dl.AlignH)
|
|
|
- }
|
|
|
- grl.SetAlignH(alignh)
|
|
|
- }
|
|
|
- // Global vertical alignment
|
|
|
- if dl.AlignV != "" {
|
|
|
- alignv, ok := mapAlignName[dl.AlignV]
|
|
|
- if !ok {
|
|
|
- return b.err("alignv", "Invalid vertical align:"+dl.AlignH)
|
|
|
- }
|
|
|
- grl.SetAlignV(alignv)
|
|
|
- }
|
|
|
- // Expansion flags
|
|
|
- grl.SetExpandH(dl.ExpandH)
|
|
|
- grl.SetExpandV(dl.ExpandV)
|
|
|
- ipan.SetLayout(grl)
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- // Dock layout
|
|
|
- if dl.Type == descTypeDockLayout {
|
|
|
- dockl := NewDockLayout()
|
|
|
- ipan.SetLayout(dockl)
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- return b.err("layout", "Invalid layout type:"+dl.Type)
|
|
|
-}
|
|
|
-****/
|
|
|
-
|
|
|
// setAttribs sets common attributes from the description to the specified panel
|
|
|
// The attributes which are set can be specified by the specified bitmask.
|
|
|
func (b *Builder) setAttribs(am map[string]interface{}, ipan IPanel, attr uint) error {
|
|
|
@@ -2384,37 +1571,6 @@ func (b *Builder) setAttribs(am map[string]interface{}, ipan IPanel, attr uint)
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
-//func (b *Builder) setMenuShortcut(mi *MenuItem, fname, field string) error {
|
|
|
-//
|
|
|
-// field = strings.Trim(field, " ")
|
|
|
-// if field == "" {
|
|
|
-// return nil
|
|
|
-// }
|
|
|
-// parts := strings.Split(field, "+")
|
|
|
-// var mods window.ModifierKey
|
|
|
-// for i := 0; i < len(parts)-1; i++ {
|
|
|
-// switch parts[i] {
|
|
|
-// case "Shift":
|
|
|
-// mods |= window.ModShift
|
|
|
-// case "Ctrl":
|
|
|
-// mods |= window.ModControl
|
|
|
-// case "Alt":
|
|
|
-// mods |= window.ModAlt
|
|
|
-// default:
|
|
|
-// return b.err(am, fname, "Invalid shortcut:"+field)
|
|
|
-// }
|
|
|
-// }
|
|
|
-// // The last part must be a key
|
|
|
-// key := parts[len(parts)-1]
|
|
|
-// for kcode, kname := range mapKeyText {
|
|
|
-// if kname == key {
|
|
|
-// mi.SetShortcut(mods, kcode)
|
|
|
-// return nil
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return b.err(fname, "Invalid shortcut:"+field)
|
|
|
-//}
|
|
|
-
|
|
|
// parseFloats parses a string with a list of floats with the specified size
|
|
|
// and returns a slice. The specified size is 0 any number of floats is allowed.
|
|
|
// The individual values can be separated by spaces or commas
|