Child gadgets enumeration

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Justin
Addict
Addict
Posts: 948
Joined: Sat Apr 26, 2003 2:49 pm

Child gadgets enumeration

Post by Justin »

Since some gadgets supports childs a system to enumerate them would be very useful to create some layout engine.
FirstChildGadget()
NextChildGadget()
I know PB uses this internally and there is some kind of hack to use it but a native solution would be great.
No API.
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Child gadgets enumeration

Post by BorisTheOld »

Justin wrote:Since some gadgets supports childs a system to enumerate them would be very useful to create some layout engine.....No API.
You can do it yourself by using arrays to track the child gadgets that are assigned to each parent gadget.

We use classes to represent each gadget type. The following example shows how we include auto sizing for a Panel gadget and a Panel Item (a panel tab). The code makes extensive use of macros that I haven't included. However it can be treated as psuedo-code, so it's quite easy to follow.

Code: Select all

;===============================================
;
;  class methods    :  clsPanel.pbi
;
;  class reference  :  6016  :  Panel Class
;
;  date generated   :  2013-06-24 20:43
;
;===============================================
;
BeginClass(Panel)
;
;===============================================
;
;  Properties
;
BeginClassData(Panel)
;
;  primary  properties
;
  FieldPointer(prpVirtualTable)                                                ; 16393 : pointer to the class virtual table
  Field(exiClassReferenceNumber, typInt32)                                     ; 16447 : the entity number for the class (module, program, package, etc)
  Field(exoParent, objGeneric)                                                 ; 16086 : reference to an object`s parent
  Field(exiChildEntryNumber, typInt32)                                         ; 16484 : entry number of the object in the parent child array (1 based)
;
;  private dvsam control blocks
;
;
;  private file records
;
;
;  private file objects
;
;
;  private properties
;
  FieldDynamicArray(proChild, objGeneric)                                      ; 16448 : reference to a child object
  Field(priChildCount, typInt32)                                               ; 16451 : number of child objects attached to a parent object
;
;  external properties:  read/write
;
  Field(exlPanelMarginFlag, typBoolean)                                        ; 16495 : true = panel margins have been determined
  Field(exiPanelWidthMargin, typInt32)                                         ; 16496 : width margin for a tabbed panel
  Field(exiPanelHeightMargin, typInt32)                                        ; 16497 : height margin for a tabbed panel
  Field(exiPanelItemPadding, typInt32)                                         ; 16658 : padding to be applied to all the panel`s panelitems (pixels)
;
;  external properties:  read only
;
  Field(exiGadgetNumber, typInt32)                                             ; 16402 : assigned by pb using #pb_any
  Field(exiActualLeft, typInt32)                                               ; 16417 : actual left position of the gui object (pixels)
  Field(exiActualTop, typInt32)                                                ; 16418 : actual top position of the gui object (pixels)
  Field(exiActualWidth, typInt32)                                              ; 16419 : actual width of the gui object (pixels)
  Field(exiActualHeight, typInt32)                                             ; 16420 : actual height of the gui object (pixels)
;
;  external properties:  write only
;
  Field(exiMarginTop, typInt32)                                                ; 16128 : top margin outside the gadget (pixels)
  Field(exiMarginBottom, typInt32)                                             ; 16129 : bottom margin outside the gadget (pixels)
  Field(exiMarginLeft, typInt32)                                               ; 16130 : left margin outside the gadget (pixels)
  Field(exiMarginRight, typInt32)                                              ; 16131 : right margin outside the gadget (pixels)
  Field(exlResizeAllowed, typBoolean)                                          ; 16405 : true = gui object can be resized
  Field(exlShrinkAllowed, typBoolean)                                          ; 16406 : true = gui object can shrink below the base size
  Field(exiHorizontalAlignmentMode, typInt32)                                  ; 16408 : fill, start, end, centre
  Field(exlHorizontalAlignment, typBoolean)                                    ; 16409 : true = horizontal gui object alignment is allowed
  Field(exiVerticalAlignmentMode, typInt32)                                    ; 16410 : fill, start, end, centre
  Field(exlVerticalAlignment, typBoolean)                                      ; 16411 : true = vertical gui object alignment is allowed
  Field(exiBaseLeft, typInt32)                                                 ; 16413 : nominal left position of the gui object (pixels)
  Field(exiBaseTop, typInt32)                                                  ; 16414 : nominal top position of the gui object (pixels)
  Field(exiBaseWidth, typInt32)                                                ; 16415 : nominal width of the gui object (pixels)
  Field(exiBaseHeight, typInt32)                                               ; 16416 : nominal height of the gui object (pixels)
;
EndClassData
;
;===============================================
;
;  Private Declares
;
DeclarePrivateSubroutine(Panel, Constructor)   (ByVal(Me, strPanel))
DeclarePrivateSubroutine(Panel, Destructor)    (ByVal(Me, strPanel))
DeclarePrivateSubroutine(Panel, ApplyExternalResizeRules)      (ByVal(Me, strPanel))
;
;===============================================
;
;  Primary Methods
;
;-----------------------------------------------
;
ExternalFunction(Panel, Create, typObject) ()
;
;  Create                              create a class instance
;
  Local(Me, strPanel)

  Me = AllocateMemory(SizeOf(strPanel))
  If IsObject(Me)
    InitializeStructure(Me, strPanel)
    Me\prpVirtualTable = LabelPtr(Panel, VirtualTable)
    ClassCall(Panel, Constructor) (Me)
  EndIf
  ProcedureReturn Me
EndFunction
;
;-----------------------------------------------
;
ExternalFunction(Panel, Destroy, typObject) (ByVal(Me, strPanel))
;
;  Destroy                             destroy a class instance
;
  If IsObject(Me)
    ClassCall(Panel, Destructor) (Me)
    ClearStructure(Me, strPanel)
    FreeMemory(Me)
  EndIf
  ProcedureReturn Nothing
EndFunction
;
;-----------------------------------------------
;
;  exiClassReferenceNumber             16447 : the entity number for the class (module, program, package, etc)
;
ExternalGet(Panel, exiClassReferenceNumber, typInt32)  (ByVal(Me, strPanel))
  ProcedureReturn Me\exiClassReferenceNumber
EndGet
;
;-----------------------------------------------
;
;  exoParent                           16086 : reference to an object`s parent
;
ExternalSet(Panel, exoParent)          (ByVal(Me, strPanel), ByVal(bvoParent, typObject))
  Me\exoParent = bvoParent
EndSet
;
;-----------------------------------------------
;
;  exiChildEntryNumber                 16484 : entry number of the object in the parent child array (1 based)
;
ExternalGet(Panel, exiChildEntryNumber, typInt32)      (ByVal(Me, strPanel))
  ProcedureReturn Me\exiChildEntryNumber
EndGet
;
ExternalSet(Panel, exiChildEntryNumber)        (ByVal(Me, strPanel), ByVal(bviChildEntryNumber, typInt32))
  Me\exiChildEntryNumber = bviChildEntryNumber
EndSet
;
;===============================================
;
;  External Methods
;
;-----------------------------------------------
;
ExternalSubroutine(Panel, Events)      (ByVal(Me, strPanel))
;
;  Events                              process gadget events
;
;
;
;  not used -- placeholder only
;
EndSubroutine
;
;-----------------------------------------------
;
ExternalSubroutine(Panel, Resize)      (ByVal(Me, strPanel))
;
;  Resize                              process a window resize event
;
;
  Local(iLoop, typInt32)                                                       ; 15051 : generic loop counter

  If IsTrue(Me\exlResizeAllowed)

    ClassCall(Panel, ApplyExternalResizeRules) (Me)                            ; calculate new size

    ResizeGadget(Me\exiGadgetNumber, Me\exiActualLeft, Me\exiActualTop, Me\exiActualWidth, Me\exiActualHeight)

    For iLoop = 1 To Me\priChildCount                                          ; resize all child objects
      ObjectCall(Me\proChild(iLoop), Resize) ()
    Next

  EndIf

EndSubroutine
;
;-----------------------------------------------
;
ExternalSubroutine(Panel, Build)       (ByVal(Me, strPanel))
;
;  Build                               build this object
;
;

  AttachMeToParent

  Me\exiActualLeft   = Me\exiBaseLeft                                          ; set the initial dimensions
  Me\exiActualTop    = Me\exiBaseTop
  Me\exiActualWidth  = Me\exiBaseWidth
  Me\exiActualHeight = Me\exiBaseHeight

  ClassCall(Panel, ApplyExternalResizeRules) (Me)                              ; calculate the initial size

  Me\exiGadgetNumber = PanelGadget(#PB_Any, Me\exiActualLeft, Me\exiActualTop, Me\exiActualWidth, Me\exiActualHeight)

  CloseGadgetList()                                                            ; defer attachment of panel items until later

  SetGadgetData(Me\exiGadgetNumber, Me)                                        ; link this object to its gadget

EndSubroutine
;
;-----------------------------------------------
;
ExternalSubroutine(Panel, AttachChild) (ByVal(Me, strPanel), ByRef(broChild, objGeneric))
;
;  AttachChild                         attach a child object
;
;  broChild                            16448 : reference to a child object
;

  Me\priChildCount = Me\priChildCount + 1                                      ; increment the child count
  ReDim Me\proChild(Me\priChildCount)                                          ; add an entry to the child array
  Me\proChild(Me\priChildCount) = Ref(broChild)                                ; store the child object reference
  Set(Ref(broChild), exiChildEntryNumber, Me\priChildCount)                    ; update the child`s entry number

EndSubroutine
;
;-----------------------------------------------
;
ExternalSubroutine(Panel, DetachChild) (ByVal(Me, strPanel), ByRef(broChild, objGeneric))
;
;  DetachChild                         detach a child object
;
;  broChild                            16448 : reference to a child object
;
  Local(iLoop, typInt32)                                                       ; 15051 : generic loop counter
  Local(iChildEntryNumber, typInt32)                                           ; 16484 : entry number of the object in the parent child array (1 based)

  iChildEntryNumber = Get(Ref(broChild), exiChildEntryNumber)                  ; extract the child entry number

  If (iChildEntryNumber > 0) And (iChildEntryNumber <= Me\priChildCount)

    Me\priChildCount  = Me\priChildCount - 1                                   ; decrement the child count

    For iLoop = iChildEntryNumber To Me\priChildCount                          ; adjust the array entries
      Me\proChild(iLoop) = Me\proChild(iLoop + 1)                              ; shift left into the vacated spot
      Set(Me\proChild(iLoop), exiChildEntryNumber, iLoop)                      ; adjust the child`s entry number
      SetGadgetItemData(Me\exiGadgetNumber, iLoop - 1, Me\proChild(iLoop))     ; link the child object to its gadget item
    Next

    ReDim Me\proChild(Me\priChildCount)                                        ; trim the last entry off the array

  EndIf

  Set(Ref(broChild), exoParent, Nothing)                                       ; detach the child from this parent object
  Set(Ref(broChild), exiChildEntryNumber, 0)                                   ; clear the child`s entry number

EndSubroutine
;
;===============================================
;
;  Property Methods
;
;-----------------------------------------------
;
;  external properties:  read/write
;
;--------
;
ExternalGet(Panel, exlPanelMarginFlag, typBoolean)     (ByVal(Me, strPanel))
  ProcedureReturn Me\exlPanelMarginFlag
EndGet
;
ExternalSet(Panel, exlPanelMarginFlag) (ByVal(Me, strPanel), ByVal(bvlPanelMarginFlag, typBoolean))
  Me\exlPanelMarginFlag = bvlPanelMarginFlag
EndSet
;
;--------
;
ExternalGet(Panel, exiPanelWidthMargin, typInt32)      (ByVal(Me, strPanel))
  ProcedureReturn Me\exiPanelWidthMargin
EndGet
;
ExternalSet(Panel, exiPanelWidthMargin)        (ByVal(Me, strPanel), ByVal(bviPanelWidthMargin, typInt32))
  Me\exiPanelWidthMargin = bviPanelWidthMargin
EndSet
;
;--------
;
ExternalGet(Panel, exiPanelHeightMargin, typInt32)     (ByVal(Me, strPanel))
  ProcedureReturn Me\exiPanelHeightMargin
EndGet
;
ExternalSet(Panel, exiPanelHeightMargin)       (ByVal(Me, strPanel), ByVal(bviPanelHeightMargin, typInt32))
  Me\exiPanelHeightMargin = bviPanelHeightMargin
EndSet
;
;--------
;
ExternalGet(Panel, exiPanelItemPadding, typInt32)      (ByVal(Me, strPanel))
  ProcedureReturn Me\exiPanelItemPadding
EndGet
;
ExternalSet(Panel, exiPanelItemPadding)        (ByVal(Me, strPanel), ByVal(bviPanelItemPadding, typInt32))
  Me\exiPanelItemPadding = bviPanelItemPadding
EndSet
;
;-----------------------------------------------
;
;  external properties:  read only
;
;--------
;
ExternalGet(Panel, exiGadgetNumber, typInt32)  (ByVal(Me, strPanel))
  ProcedureReturn Me\exiGadgetNumber
EndGet
;
;--------
;
ExternalGet(Panel, exiActualLeft, typInt32)    (ByVal(Me, strPanel))
  ProcedureReturn Me\exiActualLeft
EndGet
;
;--------
;
ExternalGet(Panel, exiActualTop, typInt32)     (ByVal(Me, strPanel))
  ProcedureReturn Me\exiActualTop
EndGet
;
;--------
;
ExternalGet(Panel, exiActualWidth, typInt32)   (ByVal(Me, strPanel))
  ProcedureReturn Me\exiActualWidth
EndGet
;
;--------
;
ExternalGet(Panel, exiActualHeight, typInt32)  (ByVal(Me, strPanel))
  ProcedureReturn Me\exiActualHeight
EndGet
;
;-----------------------------------------------
;
;  external properties:  write only
;
;--------
;
ExternalSet(Panel, exiMarginTop)       (ByVal(Me, strPanel), ByVal(bviMarginTop, typInt32))
  Me\exiMarginTop = bviMarginTop
EndSet
;
;--------
;
ExternalSet(Panel, exiMarginBottom)    (ByVal(Me, strPanel), ByVal(bviMarginBottom, typInt32))
  Me\exiMarginBottom = bviMarginBottom
EndSet
;
;--------
;
ExternalSet(Panel, exiMarginLeft)      (ByVal(Me, strPanel), ByVal(bviMarginLeft, typInt32))
  Me\exiMarginLeft = bviMarginLeft
EndSet
;
;--------
;
ExternalSet(Panel, exiMarginRight)     (ByVal(Me, strPanel), ByVal(bviMarginRight, typInt32))
  Me\exiMarginRight = bviMarginRight
EndSet
;
;--------
;
ExternalSet(Panel, exlResizeAllowed)   (ByVal(Me, strPanel), ByVal(bvlResizeAllowed, typBoolean))
  Me\exlResizeAllowed = bvlResizeAllowed
EndSet
;
;--------
;
ExternalSet(Panel, exlShrinkAllowed)   (ByVal(Me, strPanel), ByVal(bvlShrinkAllowed, typBoolean))
  Me\exlShrinkAllowed = bvlShrinkAllowed
EndSet
;
;--------
;
ExternalSet(Panel, exiHorizontalAlignmentMode) (ByVal(Me, strPanel), ByVal(bviHorizontalAlignmentMode, typInt32))
  Me\exiHorizontalAlignmentMode = bviHorizontalAlignmentMode
EndSet
;
;--------
;
ExternalSet(Panel, exlHorizontalAlignment)     (ByVal(Me, strPanel), ByVal(bvlHorizontalAlignment, typBoolean))
  Me\exlHorizontalAlignment = bvlHorizontalAlignment
EndSet
;
;--------
;
ExternalSet(Panel, exiVerticalAlignmentMode)   (ByVal(Me, strPanel), ByVal(bviVerticalAlignmentMode, typInt32))
  Me\exiVerticalAlignmentMode = bviVerticalAlignmentMode
EndSet
;
;--------
;
ExternalSet(Panel, exlVerticalAlignment)       (ByVal(Me, strPanel), ByVal(bvlVerticalAlignment, typBoolean))
  Me\exlVerticalAlignment = bvlVerticalAlignment
EndSet
;
;--------
;
ExternalSet(Panel, exiBaseLeft)        (ByVal(Me, strPanel), ByVal(bviBaseLeft, typInt32))
  Me\exiBaseLeft = bviBaseLeft
EndSet
;
;--------
;
ExternalSet(Panel, exiBaseTop)         (ByVal(Me, strPanel), ByVal(bviBaseTop, typInt32))
  Me\exiBaseTop = bviBaseTop
EndSet
;
;--------
;
ExternalSet(Panel, exiBaseWidth)       (ByVal(Me, strPanel), ByVal(bviBaseWidth, typInt32))
  Me\exiBaseWidth = bviBaseWidth
EndSet
;
;--------
;
ExternalSet(Panel, exiBaseHeight)      (ByVal(Me, strPanel), ByVal(bviBaseHeight, typInt32))
  Me\exiBaseHeight = bviBaseHeight
EndSet
;
;===============================================
;
;  Private Methods
;
;-----------------------------------------------
;
PrivateSubroutine(Panel, Constructor)  (ByVal(Me, strPanel))
;
;  Constructor                         class constructor
;
;
;
;  auto generated code
;
  Me\exiClassReferenceNumber = 6016                                            ; Panel Class

;
;  manual code
;

  Me\exiPanelItemPadding = 10

EndSubroutine
;
;-----------------------------------------------
;
PrivateSubroutine(Panel, Destructor)   (ByVal(Me, strPanel))
;
;  Destructor                          class destructor
;
;
;
;  manual code
;

  DestroyMyGadget
  DetachMeFromParent
  DetachMyChildren(Panel)

;
;  auto generated code
;

EndSubroutine
;
;-----------------------------------------------
;
PrivateSubroutine(Panel, ApplyExternalResizeRules)     (ByVal(Me, strPanel))
;
;  ApplyExternalResizeRules            apply the external resize rules
;
;
  Local(oGenericContainer, objContainer)                                       ; 16077 : generic reference to a container object
  Local(iParentWidth, typInt32)                                                ; 16458 : parent container width (pixels)
  Local(iParentHeight, typInt32)                                               ; 16459 : parent container height (pixels)
  Local(iParentPadding, typInt32)                                              ; 16460 : parent container padding (pixels)
;
;  Note:
;
;  1)  If no horizontal alignment, then Me\exiActualLeft and Me\exiActualWidth remain unchanged
;
;  2)  If no vertical alignment, then Me\exiActualTop and Me\exiActualHeight remain unchanged
;

  oGenericContainer = Me\exoParent                                             ; reference the parent container

  iParentWidth   = Get(oGenericContainer, exiActualWidth)
  iParentHeight  = Get(oGenericContainer, exiActualHeight)
  iParentPadding = Get(oGenericContainer, exiPadding)

  If IsTrue(Me\exlHorizontalAlignment)
    Select Me\exiHorizontalAlignmentMode
      Case #iGUI_ALIGN_FILL
        Me\exiActualLeft  = iParentPadding + Me\exiMarginLeft
        Me\exiActualWidth = iParentWidth - iParentPadding - Me\exiMarginLeft - Me\exiMarginRight - iParentPadding
      Case #iGUI_ALIGN_START
        Me\exiActualLeft  = iParentPadding + Me\exiMarginLeft
      Case #iGUI_ALIGN_END
        Me\exiActualLeft  = iParentWidth - iParentPadding - Me\exiMarginRight - Me\exiActualWidth
      Case #iGUI_ALIGN_CENTRE
        Me\exiActualLeft  = (iParentWidth - Me\exiActualWidth) / 2
    EndSelect
  EndIf

  If IsTrue(Me\exlVerticalAlignment)
    Select Me\exiVerticalAlignmentMode
      Case #iGUI_ALIGN_FILL
        Me\exiActualTop  = iParentPadding + Me\exiMarginTop
        Me\exiActualHeight = iParentHeight - iParentPadding - Me\exiMarginTop - Me\exiMarginBottom - iParentPadding
      Case #iGUI_ALIGN_START
        Me\exiActualTop  = iParentPadding + Me\exiMarginTop
      Case #iGUI_ALIGN_END
        Me\exiActualTop  = iParentHeight - iParentPadding - Me\exiMarginBottom - Me\exiActualHeight
      Case #iGUI_ALIGN_CENTRE
        Me\exiActualTop  = (iParentHeight - Me\exiActualHeight) / 2
    EndSelect
  EndIf

EndSubroutine
;
;===============================================
;
;  Virtual Table
;
BeginVirtualTable(Panel)
;
;  primary  methods
;
  VirtualFunc(Panel, Destroy)
  VirtualGetx(Panel, exiClassReferenceNumber)
  VirtualSetx(Panel, exoParent)
  VirtualGetx(Panel, exiChildEntryNumber)
  VirtualSetx(Panel, exiChildEntryNumber)
;
;  external methods
;
  VirtualSubr(Panel, Events)
  VirtualSubr(Panel, Resize)
  VirtualSubr(Panel, Build)
  VirtualSubr(Panel, AttachChild)
  VirtualSubr(Panel, DetachChild)
;
;  external properties:  read/write
;
  VirtualGetx(Panel, exlPanelMarginFlag)
  VirtualSetx(Panel, exlPanelMarginFlag)
  VirtualGetx(Panel, exiPanelWidthMargin)
  VirtualSetx(Panel, exiPanelWidthMargin)
  VirtualGetx(Panel, exiPanelHeightMargin)
  VirtualSetx(Panel, exiPanelHeightMargin)
  VirtualGetx(Panel, exiPanelItemPadding)
  VirtualSetx(Panel, exiPanelItemPadding)
;
;  external properties:  read only
;
  VirtualGetx(Panel, exiGadgetNumber)
  VirtualGetx(Panel, exiActualLeft)
  VirtualGetx(Panel, exiActualTop)
  VirtualGetx(Panel, exiActualWidth)
  VirtualGetx(Panel, exiActualHeight)
;
;  external properties:  write only
;
  VirtualSetx(Panel, exiMarginTop)
  VirtualSetx(Panel, exiMarginBottom)
  VirtualSetx(Panel, exiMarginLeft)
  VirtualSetx(Panel, exiMarginRight)
  VirtualSetx(Panel, exlResizeAllowed)
  VirtualSetx(Panel, exlShrinkAllowed)
  VirtualSetx(Panel, exiHorizontalAlignmentMode)
  VirtualSetx(Panel, exlHorizontalAlignment)
  VirtualSetx(Panel, exiVerticalAlignmentMode)
  VirtualSetx(Panel, exlVerticalAlignment)
  VirtualSetx(Panel, exiBaseLeft)
  VirtualSetx(Panel, exiBaseTop)
  VirtualSetx(Panel, exiBaseWidth)
  VirtualSetx(Panel, exiBaseHeight)
;
EndVirtualTable
;
;===============================================
;
EndClass
;
;===============================================
;  end of  :  clsPanel.bi
;===============================================

Code: Select all

;===============================================
;
;  class methods    :  clsPanelItem.pbi
;
;  class reference  :  6046  :  PanelItem Class
;
;  date generated   :  2013-06-24 10:37
;
;===============================================
;
BeginClass(PanelItem)
;
;===============================================
;
;  Properties
;
BeginClassData(PanelItem)
;
;  primary  properties
;
  FieldPointer(prpVirtualTable)                                                ; 16393 : pointer to the class virtual table
  Field(exiClassReferenceNumber, typInt32)                                     ; 16447 : the entity number for the class (module, program, package, etc)
  Field(exoParent, objGeneric)                                                 ; 16086 : reference to an object`s parent
  Field(exiChildEntryNumber, typInt32)                                         ; 16484 : entry number of the object in the parent child array (1 based)
;
;  private dvsam control blocks
;
;
;  private file records
;
;
;  private file objects
;
;
;  private properties
;
  Field(priGadgetNumber, typInt32)                                             ; 16402 : assigned by pb using #pb_any
  FieldDynamicArray(proChild, objGeneric)                                      ; 16448 : reference to a child object
  Field(priChildCount, typInt32)                                               ; 16451 : number of child objects attached to a parent object
;
;  external properties:  read/write
;
;
;  external properties:  read only
;
  Field(exiActualLeft, typInt32)                                               ; 16417 : actual left position of the gui object (pixels)
  Field(exiActualTop, typInt32)                                                ; 16418 : actual top position of the gui object (pixels)
  Field(exiActualWidth, typInt32)                                              ; 16419 : actual width of the gui object (pixels)
  Field(exiActualHeight, typInt32)                                             ; 16420 : actual height of the gui object (pixels)
  Field(exiPanelItemPadding, typInt32)                                         ; 16658 : padding to be applied to all the panel`s panelitems (pixels)
;
;  external properties:  write only
;
  FieldCallBack(expCBDesign)                                                   ; 16080 : callback ptr:  design an object
  Field(exlResizeAllowed, typBoolean)                                          ; 16405 : true = gui object can be resized
  Field(exlShrinkAllowed, typBoolean)                                          ; 16406 : true = gui object can shrink below the base size
  Field(exsTabText, typString)                                                 ; 16489 : panel tab text
;
EndClassData
;
;===============================================
;
;  Private Declares
;
DeclarePrivateSubroutine(PanelItem, Constructor)       (ByVal(Me, strPanelItem))
DeclarePrivateSubroutine(PanelItem, Destructor)        (ByVal(Me, strPanelItem))
DeclarePrivateSubroutine(PanelItem, UpdatePanelItemSize)       (ByVal(Me, strPanelItem))
;
;===============================================
;
;  Primary Methods
;
;-----------------------------------------------
;
ExternalFunction(PanelItem, Create, typObject) ()
;
;  Create                              create a class instance
;
  Local(Me, strPanelItem)

  Me = AllocateMemory(SizeOf(strPanelItem))
  If IsObject(Me)
    InitializeStructure(Me, strPanelItem)
    Me\prpVirtualTable = LabelPtr(PanelItem, VirtualTable)
    ClassCall(PanelItem, Constructor) (Me)
  EndIf
  ProcedureReturn Me
EndFunction
;
;-----------------------------------------------
;
ExternalFunction(PanelItem, Destroy, typObject) (ByVal(Me, strPanelItem))
;
;  Destroy                             destroy a class instance
;
  If IsObject(Me)
    ClassCall(PanelItem, Destructor) (Me)
    ClearStructure(Me, strPanelItem)
    FreeMemory(Me)
  EndIf
  ProcedureReturn Nothing
EndFunction
;
;-----------------------------------------------
;
;  exiClassReferenceNumber             16447 : the entity number for the class (module, program, package, etc)
;
ExternalGet(PanelItem, exiClassReferenceNumber, typInt32)      (ByVal(Me, strPanelItem))
  ProcedureReturn Me\exiClassReferenceNumber
EndGet
;
;-----------------------------------------------
;
;  exoParent                           16086 : reference to an object`s parent
;
ExternalSet(PanelItem, exoParent)      (ByVal(Me, strPanelItem), ByVal(bvoParent, typObject))
  Me\exoParent = bvoParent
EndSet
;
;-----------------------------------------------
;
;  exiChildEntryNumber                 16484 : entry number of the object in the parent child array (1 based)
;
ExternalGet(PanelItem, exiChildEntryNumber, typInt32)  (ByVal(Me, strPanelItem))
  ProcedureReturn Me\exiChildEntryNumber
EndGet
;
ExternalSet(PanelItem, exiChildEntryNumber)    (ByVal(Me, strPanelItem), ByVal(bviChildEntryNumber, typInt32))
  Me\exiChildEntryNumber = bviChildEntryNumber
EndSet
;
;===============================================
;
;  External Methods
;
;-----------------------------------------------
;
ExternalSubroutine(PanelItem, Events)  (ByVal(Me, strPanelItem))
;
;  Events                              process gadget events
;
;
;
;  not used -- placeholder only
;
EndSubroutine
;
;-----------------------------------------------
;
ExternalSubroutine(PanelItem, Resize)  (ByVal(Me, strPanelItem))
;
;  Resize                              process a window resize event
;
;
  Local(iLoop, typInt32)                                                       ; 15051 : generic loop counter

  If IsTrue(Me\exlResizeAllowed)

    ClassCall(PanelItem, UpdatePanelItemSize) (Me)                             ; update the actual values based on the panel size

    For iLoop = 1 To Me\priChildCount                                          ; resize all child objects
      ObjectCall(Me\proChild(iLoop), Resize) ()
    Next

  EndIf

EndSubroutine
;
;-----------------------------------------------
;
ExternalSubroutine(PanelItem, Build)   (ByVal(Me, strPanelItem))
;
;  Build                               build this object
;
;
  Local(oGenericPanel, objPanel)                                               ; 16384 : generic reference to a tab panel object
  Local(iItemIndex, typInt32)                                                  ; 16478 : gadget item index (zero based)

  AttachMeToParent

  iItemIndex = Me\exiChildEntryNumber - 1                                      ; calculate the panel item index
  oGenericPanel = Me\exoParent                                                 ; point to the parent panel object
  Me\priGadgetNumber = Get(oGenericPanel, exiGadgetNumber)                     ; get the panel gadget number
  Me\exiPanelItemPadding = Get(oGenericPanel, exiPanelItemPadding)             ; used when sizing a program container

  OpenGadgetList(Me\priGadgetNumber)                                           ; open the panel gadget list

    AddGadgetItem(Me\priGadgetNumber, iItemIndex, Me\exsTabText, 0, 0)         ; attach this panel item
    SetGadgetItemData(Me\priGadgetNumber, iItemIndex, Me)                      ; link this object to its gadget item
    ClassCall(PanelItem, UpdatePanelItemSize) (Me)                             ; update the actual size values
    CallBack(Me\expCBDesign)                                                   ; design the panel item

  CloseGadgetList()                                                            ; close the panel gadget list

  SetGadgetState(Me\priGadgetNumber, iItemIndex)                               ; make this the active panel item

EndSubroutine
;
;-----------------------------------------------
;
ExternalSubroutine(PanelItem, AttachChild)     (ByVal(Me, strPanelItem), ByRef(broChild, objGeneric))
;
;  AttachChild                         attach a child object
;
;  broChild                            16448 : reference to a child object
;

  Me\priChildCount = Me\priChildCount + 1                                      ; increment the child count
  ReDim Me\proChild(Me\priChildCount)                                          ; add an entry to the child array
  Me\proChild(Me\priChildCount) = Ref(broChild)                                ; store the child object reference
  Set(Ref(broChild), exiChildEntryNumber, Me\priChildCount)                    ; update the child`s entry number

EndSubroutine
;
;-----------------------------------------------
;
ExternalSubroutine(PanelItem, DetachChild)     (ByVal(Me, strPanelItem), ByRef(broChild, objGeneric))
;
;  DetachChild                         detach a child object
;
;  broChild                            16448 : reference to a child object
;
  Local(iLoop, typInt32)                                                       ; 15051 : generic loop counter
  Local(iChildEntryNumber, typInt32)                                           ; 16484 : entry number of the object in the parent child array (1 based)

  iChildEntryNumber = Get(Ref(broChild), exiChildEntryNumber)                  ; extract the child entry number

  If (iChildEntryNumber > 0) And (iChildEntryNumber <= Me\priChildCount)

    Me\priChildCount  = Me\priChildCount - 1                                   ; decrement the child count

    For iLoop = iChildEntryNumber To Me\priChildCount                          ; adjust the array entries
      Me\proChild(iLoop) = Me\proChild(iLoop + 1)                              ; shift left into the vacated spot
      Set(Me\proChild(iLoop), exiChildEntryNumber, iLoop)                      ; adjust the child`s entry number
    Next

    ReDim Me\proChild(Me\priChildCount)                                        ; trim the last entry off the array

  EndIf

  Set(Ref(broChild), exoParent, Nothing)                                       ; detach the child from this parent object
  Set(Ref(broChild), exiChildEntryNumber, 0)                                   ; clear the child`s entry number

EndSubroutine
;
;-----------------------------------------------
;
ExternalSubroutine(PanelItem, Show)    (ByVal(Me, strPanelItem))
;
;  Show                                show the program task panel
;
;
  Local(iItemIndex, typInt32)                                                  ; 16478 : gadget item index (zero based)

  iItemIndex = Me\exiChildEntryNumber - 1                                      ; calculate the panel item index

  SetGadgetState(Me\priGadgetNumber, iItemIndex)                               ; make this the active panel item

EndSubroutine
;
;===============================================
;
;  Property Methods
;
;-----------------------------------------------
;
;  external properties:  read/write
;
;-----------------------------------------------
;
;  external properties:  read only
;
;--------
;
ExternalGet(PanelItem, exiActualLeft, typInt32)        (ByVal(Me, strPanelItem))
  ProcedureReturn Me\exiActualLeft
EndGet
;
;--------
;
ExternalGet(PanelItem, exiActualTop, typInt32) (ByVal(Me, strPanelItem))
  ProcedureReturn Me\exiActualTop
EndGet
;
;--------
;
ExternalGet(PanelItem, exiActualWidth, typInt32)       (ByVal(Me, strPanelItem))
  ProcedureReturn Me\exiActualWidth
EndGet
;
;--------
;
ExternalGet(PanelItem, exiActualHeight, typInt32)      (ByVal(Me, strPanelItem))
  ProcedureReturn Me\exiActualHeight
EndGet
;
;--------
;
ExternalGet(PanelItem, exiPanelItemPadding, typInt32)  (ByVal(Me, strPanelItem))
  ProcedureReturn Me\exiPanelItemPadding
EndGet
;
;-----------------------------------------------
;
;  external properties:  write only
;
;--------
;
ExternalSet(PanelItem, expCBDesign)    (ByVal(Me, strPanelItem), ByVal(bviIndex, typInt32), ByVal(bvpCBDesign, typPointer))
  Me\expCBDesign(bviIndex) = bvpCBDesign
EndSet
;
;--------
;
ExternalSet(PanelItem, exlResizeAllowed)       (ByVal(Me, strPanelItem), ByVal(bvlResizeAllowed, typBoolean))
  Me\exlResizeAllowed = bvlResizeAllowed
EndSet
;
;--------
;
ExternalSet(PanelItem, exlShrinkAllowed)       (ByVal(Me, strPanelItem), ByVal(bvlShrinkAllowed, typBoolean))
  Me\exlShrinkAllowed = bvlShrinkAllowed
EndSet
;
;--------
;
ExternalSet(PanelItem, exsTabText)     (ByVal(Me, strPanelItem), ByVal(bvsTabText, typString))
  Me\exsTabText = bvsTabText
EndSet
;
;===============================================
;
;  Private Methods
;
;-----------------------------------------------
;
PrivateSubroutine(PanelItem, Constructor)      (ByVal(Me, strPanelItem))
;
;  Constructor                         class constructor
;
;
;
;  auto generated code
;
  Me\exiClassReferenceNumber = 6046                                            ; PanelItem Class

;
;  manual code
;

  Me\exlResizeAllowed = True                                                   ; default

EndSubroutine
;
;-----------------------------------------------
;
PrivateSubroutine(PanelItem, Destructor)       (ByVal(Me, strPanelItem))
;
;  Destructor                          class destructor
;
;
;
;  manual code
;

  DestroyMyGadgetItem
  DetachMeFromParent
  DetachMyChildren(PanelItem)

;
;  auto generated code
;

EndSubroutine
;
;-----------------------------------------------
;
PrivateSubroutine(PanelItem, UpdatePanelItemSize)      (ByVal(Me, strPanelItem))
;
;  UpdatePanelItemSize                 update the panel item size
;
;
  Local(oGenericPanel, objPanel)                                               ; 16384 : generic reference to a tab panel object
  Local(iParentWidth, typInt32)                                                ; 16458 : parent container width (pixels)
  Local(iParentHeight, typInt32)                                               ; 16459 : parent container height (pixels)
  Local(iPanelWidthMargin, typInt32)                                           ; 16496 : width margin for a tabbed panel
  Local(iPanelHeightMargin, typInt32)                                          ; 16497 : height margin for a tabbed panel
;
;  Note:
;
;  The panel items are automatically resized when the panel is resized.
;
;  This procedure refreshes the actual size info for panel items, prior to
;  their child objects being resized.
;

  oGenericPanel = Me\exoParent                                                 ; reference the parent panel

  iParentWidth   = Get(oGenericPanel, exiActualWidth)
  iParentHeight  = Get(oGenericPanel, exiActualHeight)

  If IsTrue(Get(oGenericPanel, exlPanelMarginFlag))

    Me\exiActualLeft   = 0
    Me\exiActualTop    = 0
    Me\exiActualWidth  = iParentWidth  - Get(oGenericPanel, exiPanelWidthMargin)
    Me\exiActualHeight = iParentHeight - Get(oGenericPanel, exiPanelHeightMargin)

  Else

    Me\exiActualLeft   = 0
    Me\exiActualTop    = 0
    Me\exiActualWidth  = GetGadgetAttribute(Me\priGadgetNumber, #PB_Panel_ItemWidth)
    Me\exiActualHeight = GetGadgetAttribute(Me\priGadgetNumber, #PB_Panel_ItemHeight)

    iPanelWidthMargin  = iParentWidth  - Me\exiActualWidth
    iPanelHeightMargin = iParentHeight - Me\exiActualHeight

    Set(oGenericPanel, exiPanelWidthMargin,  iPanelWidthmargin)
    Set(oGenericPanel, exiPanelHeightMargin, iPanelHeightmargin)

    Set(oGenericPanel, exlPanelMarginFlag, True)                               ; panel margins have been calculated

  EndIf

EndSubroutine
;
;===============================================
;
;  Virtual Table
;
BeginVirtualTable(PanelItem)
;
;  primary  methods
;
  VirtualFunc(PanelItem, Destroy)
  VirtualGetx(PanelItem, exiClassReferenceNumber)
  VirtualSetx(PanelItem, exoParent)
  VirtualGetx(PanelItem, exiChildEntryNumber)
  VirtualSetx(PanelItem, exiChildEntryNumber)
;
;  external methods
;
  VirtualSubr(PanelItem, Events)
  VirtualSubr(PanelItem, Resize)
  VirtualSubr(PanelItem, Build)
  VirtualSubr(PanelItem, AttachChild)
  VirtualSubr(PanelItem, DetachChild)
  VirtualSubr(PanelItem, Show)
;
;  external properties:  read/write
;
;
;  external properties:  read only
;
  VirtualGetx(PanelItem, exiActualLeft)
  VirtualGetx(PanelItem, exiActualTop)
  VirtualGetx(PanelItem, exiActualWidth)
  VirtualGetx(PanelItem, exiActualHeight)
  VirtualGetx(PanelItem, exiPanelItemPadding)
;
;  external properties:  write only
;
  VirtualSetx(PanelItem, expCBDesign)
  VirtualSetx(PanelItem, exlResizeAllowed)
  VirtualSetx(PanelItem, exlShrinkAllowed)
  VirtualSetx(PanelItem, exsTabText)
;
EndVirtualTable
;
;===============================================
;
EndClass
;
;===============================================
;  end of  :  clsPanelItem.bi
;===============================================
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
Shield
Addict
Addict
Posts: 1021
Joined: Fri Jan 21, 2011 8:25 am
Location: 'stralia!
Contact:

Re: Child gadgets enumeration

Post by Shield »

Good you bring it up again, I requested that nine months ago. :)
http://www.purebasic.fr/english/viewtop ... =3&t=51553
Image
Blog: Why Does It Suck? (http://whydoesitsuck.com/)
"You can disagree with me as much as you want, but during this talk, by definition, anybody who disagrees is stupid and ugly."
- Linus Torvalds
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: Child gadgets enumeration

Post by Josh »

Justin wrote:FirstChildGadget()
NextChildGadget()
I would prefer a list, which can be run through with ForEach

@BorisTheOld
I think it's not necessary to show more then 1000 lines of your code. Nobody, except you, can do anything with your cryptic code.
sorry for my bad english
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Child gadgets enumeration

Post by BorisTheOld »

Josh wrote:@BorisTheOld
I think it's not necessary to show more then 1000 lines of your code. Nobody, except you, can do anything with your cryptic code.
I don't expect anyone to do anything with my code. All I'm showing is a technique. It's up to you to write your own code -- I'm certainly not going to do it for you.

The feature you want doesn't exist, and probably won't for a long time. The use of arrays to track the structure of one's GUI is something that can be implemented now. As I pointed out, my code should be treated as psuedo-code. Most of it relates to GUI structure for two specific gadgets. It's easy to follow and is presented as a technique that some might find useful.

Layout and auto-sizing is non-trivial and takes a lot of code. It's necessary to cascade down the parent/child tree and take into account sizing rules which may have implications in areas already re-sized.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
Post Reply