Page 1 of 1

AutoResizer - automatically resize child gadgets

Posted: Sat Jan 07, 2012 6:40 pm
by breeze4me
AutoResizer is very similar to nxResize(by srod) and PureRESIZE(by gnozal).
It is used for resizing or anchoring the child gadgets of a window.
It doesn't use subclassing methods, so it may be easy to be adapted to the other platforms.(but for Windows only just now)


The usage is simple.
OpenWindow(#Window, ......)
SmartWindowRefresh(#Window, ......) ;optional
WindowBounds(#Window, ......) ;optional
......
XXXXXGadget(#Gadget, ......)
AutoResizer_SetAnchors(#Gadget, x, x, x, x [, w [, h]]) ;x: -1/0/1 w,h: 0/1
......
(see the details in the source code)


in the event loop
Event = WaitWindowEvent()
......
If Event = #PB_Event_SizeWindow
AutoResizer_ResizeGadgets(EventWindow())
EndIf
......
or simply use
AutoResizer_SetWinCallback(#Window) ;Windows only.



AutoResizer.pbi

Code: Select all

EnableExplicit
;-------------------------------------------------------------------------------------------
; AutoResizer
;
; Version : 1.0
; Author  : breeze4me (PureBasic English forum)
; OS      : Windows, Linux
; License : Free to use. No warranty at all.

;- structures, variables, helper functions
Structure AutoResizerGadget
  GadgetNum.i
  ParentGadget.i
  Lv.i
  LockWH.i
  Width.i
  Height.i
  LeftType.l
  StructureUnion
    LeftL.l
    LeftF.f
  EndStructureUnion
  TopType.l
  StructureUnion
    TopL.l
    TopF.f
  EndStructureUnion
  RightType.l
  StructureUnion
    RightL.l
    RightF.f
  EndStructureUnion
  BottomType.l
  StructureUnion
    BottomL.l
    BottomF.f
  EndStructureUnion
EndStructure

Structure AutoResizerWindow
  Sorted.i
  List Gadget.AutoResizerGadget()
EndStructure

Global NewMap _AutoResizer_Window.AutoResizerWindow()

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Windows
    Structure ParentGadget
      Found.i
      GadgetNum.i
    EndStructure
    
    Procedure AutoResizer_PropEnumProcEx(hwnd, *lpszString, hData, *dwData.ParentGadget)
      Protected Prop$, res = #True
      If (*lpszString >> 16)  ;if not an atom
        Prop$ = PeekS(*lpszString)
        If Prop$ = "PB_ID"   ;gadget
          *dwData\Found = 1
          *dwData\GadgetNum = hData
          res = #False
        ElseIf Prop$ = "PB_WindowID"  ;window
          *dwData\Found = 1
          *dwData\GadgetNum = -1
          res = #False
        EndIf
      EndIf
      ProcedureReturn res
    EndProcedure
    
    ;Return value: 
    ; the parent gadget number.
    ; -1 : the parent is a window. or an error is occurred.
    Procedure AutoResizer_GetParentGadget(Gadget)
      Protected hWnd, i, ParentGadget.ParentGadget\GadgetNum = -1
      hWnd = GetParent_(GadgetID(Gadget))
      For i = 0 To 1
        EnumPropsEx_(hWnd, @AutoResizer_PropEnumProcEx(), @ParentGadget)
        If ParentGadget\Found : Break : EndIf
        hWnd = GetParent_(hWnd)
      Next
      ProcedureReturn ParentGadget\GadgetNum
    EndProcedure
    
    ;Return value: the PB window number of the parent window
    Procedure AutoResizer_GetParentWnd(Gadget, *Lv.Integer)
      Protected Lv, Wnd, hWnd = GadgetID(Gadget)
      Repeat
        Lv + 1
        hWnd = GetParent_(hWnd)
        Wnd = GetProp_(hWnd, "PB_WindowID")
      Until Wnd <> 0
      If *Lv
        *Lv\i = Lv
      EndIf
      ProcedureReturn (Wnd - 1)
    EndProcedure
    
  CompilerCase #PB_OS_Linux
    ImportC ""
      g_object_get_data(*object, key.p-utf8)
    EndImport
    
    ;Return value: 
    ; the parent gadget number.
    ; -1 : the parent is a window. or an error is occurred.
    Procedure AutoResizer_GetParentGadget(Gadget)
      Protected ParentGadget = -1, GadgetID = GadgetID(Gadget)
      Protected WndID = gtk_widget_get_toplevel_(GadgetID)
      Repeat
        GadgetID = gtk_widget_get_parent_(GadgetID)
        If GadgetID  ;if exist a parent gadget
          ParentGadget = g_object_get_data(GadgetID, "pb_id")
          If ParentGadget
            ParentGadget - 1
            Break
          Else  ;it's a container widget.
            Continue
          EndIf
        Else
          Break
        EndIf
      ForEver
      If GadgetID = 0 Or GadgetID = WndID
        ParentGadget = -1
      EndIf
      ProcedureReturn ParentGadget
    EndProcedure
    
    ;Return value: the PB window number of the parent window
    Procedure AutoResizer_GetParentWnd(Gadget, *Lv.Integer)
      Protected Lv, ParentWnd, GadgetID = GadgetID(Gadget)
      Protected WndID = gtk_widget_get_toplevel_(GadgetID)
      Repeat
        Lv + 1
        GadgetID = gtk_widget_get_parent_(GadgetID)
        If WndID = GadgetID
          ParentWnd = g_object_get_data(GadgetID, "pb_id")
          Break
        EndIf
      ForEver 
      If *Lv
        *Lv\i = Lv
      EndIf
      ProcedureReturn ParentWnd
    EndProcedure
CompilerEndSelect

;- main functions
Procedure AutoResizer_RemoveAnchors(Gadget)
  Protected Wnd
  If IsGadget(Gadget)
    Wnd = AutoResizer_GetParentWnd(Gadget, 0)
    If Wnd <> -1   ;if a parent window exist
      ForEach _AutoResizer_Window(Str(Wnd))\Gadget()  ;find and remove the data
        If _AutoResizer_Window()\Gadget()\GadgetNum = Gadget
          DeleteElement(_AutoResizer_Window()\Gadget())
          Break
        EndIf
      Next
    EndIf
  EndIf
EndProcedure

;Left, Top, Right, Bottom: set left/top/right/bottom anchor
;  0: no anchor.
;  1: fixed anchor.
; -1: proportional anchor.(variable anchor)
;LockWidth, LockHeight: 
; if Left = -1 and Right = -1 and LockWidth = 1, then the width is locked.
; if Top = -1 and Bottom = -1 and LockHeight = 1, then the height is locked.
; the other combinations are ignored.
Procedure AutoResizer_SetAnchors(Gadget, Left, Top, Right, Bottom, LockWidth=0, LockHeight=0)
  Protected Wnd, Lv, Exist, pw, ph, l, r, t, b
  If Left < -1 Or Left > 1 : ProcedureReturn 0 : EndIf
  If Top < -1 Or Top > 1 : ProcedureReturn 0 : EndIf
  If Right < -1 Or Right > 1 : ProcedureReturn 0 : EndIf
  If Bottom < -1 Or Bottom > 1 : ProcedureReturn 0 : EndIf
  If Not (LockWidth = 0 Or LockWidth = 1) : ProcedureReturn 0 : EndIf
  If Not (LockHeight = 0 Or LockHeight = 1) : ProcedureReturn 0 : EndIf
  If IsGadget(Gadget)
    Wnd = AutoResizer_GetParentWnd(Gadget, @Lv)
    If Wnd <> -1   ;if a parent window exist
      ForEach _AutoResizer_Window(Str(Wnd))\Gadget()  ;find previous gadget data
        If _AutoResizer_Window()\Gadget()\GadgetNum = Gadget
          Exist = 1
          Break
        EndIf
      Next
      If Not Exist
        If AddElement(_AutoResizer_Window()\Gadget())
          Exist = 1
        EndIf
      EndIf
      If Exist
        _AutoResizer_Window()\Sorted = 0
        With _AutoResizer_Window()\Gadget()
          \GadgetNum = Gadget
          \Lv = Lv
          \ParentGadget = AutoResizer_GetParentGadget(Gadget)
          If \ParentGadget <> -1
            Select GadgetType(\ParentGadget)
              Case #PB_GadgetType_Panel
                pw = GetGadgetAttribute(\ParentGadget, #PB_Panel_ItemWidth)
                ph = GetGadgetAttribute(\ParentGadget, #PB_Panel_ItemHeight)
              Case #PB_GadgetType_ScrollArea
                pw = GetGadgetAttribute(\ParentGadget, #PB_ScrollArea_InnerWidth)
                ph = GetGadgetAttribute(\ParentGadget, #PB_ScrollArea_InnerHeight)
              Default
                pw = GadgetWidth(\ParentGadget)
                ph = GadgetHeight(\ParentGadget)
            EndSelect
          Else  ;the parent is a window or an error is occurred.
            pw = WindowWidth(Wnd)
            ph = WindowHeight(Wnd)
          EndIf
          
          \Width = GadgetWidth(Gadget)
          \Height = GadgetHeight(Gadget)
          l = GadgetX(Gadget)
          r = pw - l - \Width
          t = GadgetY(Gadget)
          b = ph - t - \Height
          
          \LockWH = (LockWidth << 16) | LockHeight
          If LockWidth And (Left = -1 And Right = -1)
            pw - \Width
          EndIf
          If LockHeight And (Top = -1 And Bottom = -1)
            ph - \Height
          EndIf
          
          \LeftType = Left
          If Left < 0 : \LeftF = l / pw
          Else : \LeftL = l
          EndIf
          \TopType = Top
          If Top < 0 : \TopF = t / ph
          Else : \TopL = t
          EndIf
          \RightType = Right
          If Right < 0 : \RightF = r / pw
          Else : \RightL = r
          EndIf
          \BottomType = Bottom
          If Bottom < 0 : \BottomF = b / ph
          Else : \BottomL = b
          EndIf
        EndWith
        ProcedureReturn 1
      EndIf
    EndIf
  EndIf
  ProcedureReturn 0
EndProcedure

Procedure AutoResizer_ResizeGadgets(Window)
  Protected hWnd, pw, ph, w, h, x, y, r, b
  If IsWindow(Window) And FindMapElement(_AutoResizer_Window(), Str(Window))
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      hWnd = WindowID(Window)
      ;LockWindowUpdate_(hWnd)
    CompilerEndIf
    If Not _AutoResizer_Window()\Sorted
      _AutoResizer_Window()\Sorted = 1
      SortStructuredList(_AutoResizer_Window()\Gadget(), #PB_Sort_Ascending, OffsetOf(AutoResizerGadget\Lv), #PB_Sort_Integer)
    EndIf
    ForEach _AutoResizer_Window()\Gadget()
      With _AutoResizer_Window()\Gadget()
        If IsGadget(\GadgetNum)
          If \ParentGadget <> -1
            Select GadgetType(\ParentGadget)
              Case #PB_GadgetType_Panel
                pw = GetGadgetAttribute(\ParentGadget, #PB_Panel_ItemWidth)
                ph = GetGadgetAttribute(\ParentGadget, #PB_Panel_ItemHeight)
              Case #PB_GadgetType_ScrollArea
                pw = GetGadgetAttribute(\ParentGadget, #PB_ScrollArea_InnerWidth)
                ph = GetGadgetAttribute(\ParentGadget, #PB_ScrollArea_InnerHeight)
              Case #PB_GadgetType_Splitter
                Continue
              Default
                pw = GadgetWidth(\ParentGadget)
                ph = GadgetHeight(\ParentGadget)
            EndSelect
          Else  ;the parent is a window or an error is occurred.
            pw = WindowWidth(Window)
            ph = WindowHeight(Window)
          EndIf
          
          w = 0 : h = 0 ;: x = 0 : y = 0 : r = 0 : b = 0
          
          If \LockWH & $FFFF0000 And (\LeftType = -1 And \RightType = -1)
            pw - \Width : w = #PB_Ignore
          EndIf
          If \LockWH & $FFFF And (\TopType = -1 And \BottomType = -1)
            ph - \Height : h = #PB_Ignore
          EndIf
          
          If \LeftType < 0 : x = pw * \LeftF
          Else : x = \LeftL
          EndIf
          If \RightType < 0 : r = pw * \RightF
          Else : r = \RightL
          EndIf
          If \LeftType * \RightType
            If w <> #PB_Ignore : w = pw - r - x : EndIf
          Else
            If \RightType = 0
              w = #PB_Ignore
            Else
              x = pw - r - \Width
              w = #PB_Ignore
            EndIf
          EndIf
          
          If \TopType < 0 : y = ph * \TopF
          Else : y = \TopL
          EndIf
          If \BottomType < 0 : b = ph * \BottomF
          Else : b = \BottomL
          EndIf
          If \TopType * \BottomType
            If h <> #PB_Ignore : h = ph - b - y : EndIf
          Else
            If \BottomType = 0
              h = #PB_Ignore
            Else
              y = ph - b - \Height
              h = #PB_Ignore
            EndIf
          EndIf
          
          ResizeGadget(\GadgetNum, x, y, w, h)
          CompilerIf #PB_Compiler_OS = #PB_OS_Windows
            UpdateWindow_(hWnd)  ;for solving some drawing issues (e.g. slow PC and Windows XP with the classic theme mode)
          CompilerEndIf
        EndIf
      EndWith
    Next
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      ;LockWindowUpdate_(0)
      ;RedrawWindow_(hWnd, 0, 0, #RDW_ERASE | #RDW_INVALIDATE | #RDW_ERASENOW | #RDW_UPDATENOW | #RDW_ALLCHILDREN)  ;for solving some drawing issues
      RedrawWindow_(hWnd, 0, 0, #RDW_INVALIDATE | #RDW_UPDATENOW | #RDW_ALLCHILDREN)  ;less flicker without SmartWindowRefresh (Windows 7)
    CompilerEndIf
  EndIf
EndProcedure

#AutoResizer_OldWndProc = "AutoResizer_OldWndProc"

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  
  Procedure AutoResizer_WinCallback(hWnd, Msg, wParam, lParam)
    Protected Window, OldWndProc = GetProp_(hWnd, #AutoResizer_OldWndProc)
    Select Msg
      Case #WM_SIZE
        Window = GetProp_(hWnd, "PB_WindowID") - 1
        If IsWindow(Window)
          AutoResizer_ResizeGadgets(Window)
        EndIf
      Case #WM_NCDESTROY
        RemoveProp_(hWnd, #AutoResizer_OldWndProc)
    EndSelect
    ProcedureReturn CallWindowProc_(OldWndProc, hWnd, Msg, wParam, lParam)
  EndProcedure
  
  Procedure AutoResizer_SetWinCallback(Window)
    Protected hWnd
    If IsWindow(Window)
      hWnd = WindowID(Window)
      ProcedureReturn SetProp_(hWnd, #AutoResizer_OldWndProc, SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, @AutoResizer_WinCallback()))
    EndIf
    ProcedureReturn 0
  EndProcedure
  
CompilerEndIf

DisableExplicit
;-------------------------------------------------------------------------------------------
[/size]

Example

Code: Select all

;- Example

XIncludeFile "AutoResizer.pbi"

#WindowWidth  = 390
#WindowHeight = 350
If OpenWindow(0, 50, 50, #WindowWidth, #WindowHeight, "Example 1", #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
  SmartWindowRefresh(0, 1)
  WindowBounds(0, #WindowWidth, #WindowHeight, #PB_Ignore, #PB_Ignore)
  
  Top = 10
  GadgetHeight = 24
  
  gadget = Frame3DGadget(#PB_Any, 10, Top, 370, 290, "Player...") : Top+20
  AutoResizer_SetAnchors(gadget, 1, 1, 1, 1)
  
  StringGadget(0,  20, Top, 200, GadgetHeight, "")
  AutoResizer_SetAnchors(0, 1, 1, 1, 0)
  
  ButtonGadget(1, 225, Top,  70, GadgetHeight, "Play")
  AutoResizer_SetAnchors(1, 0, 1, 1, 0)
  
  ButtonGadget(2, 300, Top,  70, GadgetHeight, "Stop")  : Top+35
  DisableGadget(2,1)
  AutoResizer_SetAnchors(2, 0, 1, 1, 0)
  
  PanelGadget(3, 20, Top, #WindowWidth-40, #WindowHeight-Top-60)
    AddGadgetItem(3, 0, "MP3 PlayList")
      ListViewGadget(4, 6, 10, 230, 148)
      For k=0 To 30
        AddGadgetItem(4, -1, "Music Song "+Str(k))
      Next
      AutoResizer_SetAnchors(4, 1, 1, 1, 1)
      
      ButtonGadget(5, 250, 10, 80, GadgetHeight, "Add")
      ButtonGadget(6, 250, 38, 80, GadgetHeight, "Remove")
      ButtonGadget(7, 250, 66, 80, GadgetHeight, "Select")
      SpinGadget(18, 250, 100, 80, GadgetHeight, 0, 100)
      
      AutoResizer_SetAnchors(5, 0, 1, 1, 0)
      AutoResizer_SetAnchors(6, 0, 1, 1, 0)
      AutoResizer_SetAnchors(7, 0, 1, 1, 0)
      AutoResizer_SetAnchors(18, 0, 1, 1, 0)
      
      TrackBarGadget(17, 10, 168, 310, 25, 0, 100)
      AutoResizer_SetAnchors(17, 1, 0, 1, 1)
    
    AddGadgetItem(3, 1, "Options")
      Top = 10
      CheckBoxGadget(10, 10, Top, 250, GadgetHeight, "Enable low-pass filter") : Top+30
      CheckBoxGadget(11, 10, Top, 250, GadgetHeight, "Enable visual plug-in")  : Top+30
      
      ComboBoxGadget(12, 10, Top, 250, 21) : Top+30
      AddGadgetItem(12, -1, "FireWorks")
      AddGadgetItem(12, -1, "OpenGL spectrum")
      AddGadgetItem(12, -1, "Bump bass")
      SetGadgetState(12,0)
      DisableGadget(12,1)
      AutoResizer_SetAnchors(12, 1, 1, 1, 0)
      
      OptionGadget(13, 10, Top, 80, GadgetHeight, "640*480") : Top+20
      OptionGadget(14, 10, Top, 80, GadgetHeight, "800*600") : Top+20
      OptionGadget(15, 10, Top, 80, GadgetHeight, "1024*768")
      SetGadgetState(13, 1)
      
      ButtonGadget(16, 150, Top, 80, GadgetHeight, "Info")
      AutoResizer_SetAnchors(16, 0, 1, 1, 0)
  CloseGadgetList()
  AutoResizer_SetAnchors(3, 1, 1, 1, 1)
  
  TextGadget(9, 10, #WindowHeight-30, 250, 24, "PureBasic - Gadget demonstration")
  AutoResizer_SetAnchors(9, 1, 0, 0, 1)
  
  ButtonGadget(8, #WindowWidth-100, #WindowHeight-36, 80, 24, "Quit")
  AutoResizer_SetAnchors(8, 0, 0, 1, 1)
  
  
  
  Enumeration 20
    #txt1
    #txt2
    #txt3
    #txt4
    #btn1
    #btn2
    #btn3
    #spl
  EndEnumeration
  #W = 600
  #H = 400
  OpenWindow(1, 100, 100, #W, #H, "Example 2", #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  SmartWindowRefresh(1, 1)
  WindowBounds(1, #W, #H, #PB_Ignore, #PB_Ignore)
  
  TextGadget(#txt1, 40, 0, #W-60, 20, "", #PB_Text_Border)
  AutoResizer_SetAnchors(#txt1, -1, 1, -1, 0, 1)
  
  ButtonGadget(#btn1, 10, 20, #W/2-10, 17, "button 0")
  AutoResizer_SetAnchors(#btn1, 1, 1, -1, -1)
  
  ButtonGadget(#btn2, 0, 40, #W/2, 20, "button 1")
  AutoResizer_SetAnchors(#btn2, 1, -1, -1, -1)
  
  ButtonGadget(#btn3, 0, 60, #W/2, 20, "button 2")
  AutoResizer_SetAnchors(#btn3, 1, -1, -1, -1)
  
  For i = 1 To 12
    gadget = ButtonGadget(#PB_Any, 0, 70 + i * #H/20, #W/2, #H/20, "button " + Str(i+2))
    AutoResizer_SetAnchors(gadget, 1, -1, -1, -1)
  Next
  
  gadget = ButtonGadget(#PB_Any, 0, 70 + i * #H/20 + 20, #W/2, #H/8, "button " + Str(i+2))
  AutoResizer_SetAnchors(gadget, 1, -1, -1, 1)
  
  TextGadget(#txt2, #W/2, 20, #W/2, #H/2, "Text 2", #PB_Text_Border)
  AutoResizer_SetAnchors(#txt2, -1, 1, 1, -1)
  
  TextGadget(#txt3, 0, 0, 0, 0, "Text 3", #PB_Text_Border)
  TextGadget(#txt4, 0, 0, 0, 0, "Text 4", #PB_Text_Border)
  SplitterGadget(#spl, #W/2, (#H-20)/2 + 35, #W/2, #H/2-25, #txt3, #txt4, #PB_Splitter_Vertical | #PB_Splitter_Separator)
  AutoResizer_SetAnchors(#spl, -1, -1, 1, 1)
  
  
  
  Enumeration #PB_Compiler_EnumerationValue
    #cnt
    #w2txt1
    #w2txt2
    #w2txt3
    #w2txt4
    #w2txt5
  EndEnumeration
  OpenWindow(2, 200, 200, #W, #H, "Example 3", #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  SmartWindowRefresh(2, 1)
  
  ContainerGadget(#cnt, 0, 0, #W, #H, #PB_Container_Flat)
    TextGadget(#w2txt1, (#W-80)/2, 20, 80, 20, "Text 1", #PB_Text_Border)
    AutoResizer_SetAnchors(#w2txt1, -1, 1, -1, 0, 1)
    
    TextGadget(#w2txt2, (#W-80)/2, (#H-20)/2, 80, 20, "variable H", #PB_Text_Border)
    ;AutoResizer_SetAnchors(#w2txt2, -1, -1, -1, -1, 1, 1)
    AutoResizer_SetAnchors(#w2txt2, -1, -1, -1, -1, 1)  ;variable height.
    
    TextGadget(#w2txt3, (#W-80)/2, #H-40, 80, 20, "variable W", #PB_Text_Border)
    ;AutoResizer_SetAnchors(#w2txt3, -1, 0, -1, 1, 1)
    AutoResizer_SetAnchors(#w2txt3, -1, 0, -1, 1)      ;variable width.
    
    TextGadget(#w2txt4, 40, (#H-20)/2, 80, 20, "Text 4", #PB_Text_Border)
    AutoResizer_SetAnchors(#w2txt4, 1, -1, 0, -1, 0, 1)
    
    TextGadget(#w2txt5, #W-80-40, (#H-20)/2, 80, 20, "Text 5", #PB_Text_Border)
    AutoResizer_SetAnchors(#w2txt5, 0, -1, 1, -1, 0, 1)
  CloseGadgetList()
  AutoResizer_SetAnchors(#cnt, 1, 1, 1, 1)
  
  
  
  Enumeration #PB_Compiler_EnumerationValue
    #scrarea
    #w3btn1
    #w3btn2
    #w3btn3
    #w3txt1
  EndEnumeration
  OpenWindow(3, 0, 0, 350, 200, "Example 4", #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
  SmartWindowRefresh(3, 1)
  
  ScrollAreaGadget(#scrarea, 10, 10, 330, 180, 370, 170)
    ButtonGadget(#w3btn1, 10, 10, 230, 30,"Button 1")
    AutoResizer_SetAnchors(#w3btn1, 0, 0, 1, 0)
    
    ButtonGadget(#w3btn2, 30, 50, 230, 30,"Button 2")
    AutoResizer_SetAnchors(#w3btn2, 0, 0, 1, 0)
    
    ButtonGadget(#w3btn3, 50, 90, 230, 30,"Button 3")
    AutoResizer_SetAnchors(#w3btn3, 0, 0, 1, 0)
    
    TextGadget(#w3txt1, 70, 130, 250, 30, "This is the content of a ScrollAreaGadget!", #PB_Text_Right)
    AutoResizer_SetAnchors(#w3txt1, 0, 0, 1, 1)
  CloseGadgetList()
  AutoResizer_SetAnchors(#scrarea, 1, 1, 1, 1)
  SetGadgetAttribute(#scrarea, #PB_ScrollArea_X , 300)
  
  
  
  Enumeration #PB_Compiler_EnumerationValue
    #img
  EndEnumeration
  If LoadImage(0, #PB_Compiler_Home + "Examples\Sources\Data\PureBasicLogo.bmp")
    iw = ImageWidth(0)
    ih = ImageHeight(0)
    
    OpenWindow(4, 0, 0, iw + 14, ih + 14, "Example 5", #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
    SmartWindowRefresh(4, 1)
    WindowBounds(4, iw + 14, ih + 14, #PB_Ignore, #PB_Ignore)
    
    ImageGadget(#img, 5, 5, iw+4, ih+4, ImageID(0), #PB_Image_Border)
    AutoResizer_SetAnchors(#img, 1, 1, 1, 1)
  EndIf
  
  
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    AutoResizer_SetWinCallback(0)
    AutoResizer_SetWinCallback(2)
  CompilerEndIf
  
  Repeat
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_SizeWindow
      EventWnd = EventWindow()
      Select EventWnd
        Case 3
          CompilerIf #PB_Compiler_OS = #PB_OS_Windows
            LockWindowUpdate_(GadgetID(#scrarea))  ;for solving some drawing issue of the scrollarea gadget.
          CompilerEndIf
          SetGadgetAttribute(#scrarea, #PB_ScrollArea_InnerWidth, WindowWidth(3) + 20)
          SetGadgetAttribute(#scrarea, #PB_ScrollArea_InnerHeight, WindowHeight(3) - 30)
          CompilerIf #PB_Compiler_OS = #PB_OS_Windows
            LockWindowUpdate_(0)
            UpdateWindow_(GadgetID(#scrarea))  ;for solving some drawing issue of the scrollarea gadget.
          CompilerEndIf
          
          AutoResizer_ResizeGadgets(EventWnd)
          
        Case 4
          AutoResizer_ResizeGadgets(EventWnd)
          
          ;resize image
          CopyImage(0, 1)
          ResizeImage(1, GadgetWidth(#img) - 4, GadgetHeight(#img) - 4)
          SetGadgetState(#img, ImageID(1))
          CompilerIf #PB_Compiler_OS = #PB_OS_Windows
            RedrawWindow_(WindowID(4), 0, 0, #RDW_ERASE | #RDW_INVALIDATE | #RDW_UPDATENOW | #RDW_ALLCHILDREN) ;for solving the window drawing issue
          CompilerEndIf
          
        Case 1
          AutoResizer_ResizeGadgets(EventWnd)
          SetGadgetText(#txt1, "init width: " + Str(#W-60) + " current width: " + Str(GadgetWidth(#txt1)) + " L/R:" + StrF(GadgetX(#txt1) / (WindowWidth(1) - GadgetWidth(#txt1) - GadgetX(#txt1)), 2))
          
        CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
          Default
            AutoResizer_ResizeGadgets(EventWnd)
        CompilerEndIf
      EndSelect
    EndIf
    
  Until Event = #PB_Event_CloseWindow
EndIf
[/size]

Re: AutoResizer - automatically resize child gadgets

Posted: Sat Jan 07, 2012 7:19 pm
by infratec
Hi,

great work :!:
Hope I can test it with Linux next time.

Bernd

Btw.:

Code: Select all

If Not (Left = 0 Or Left = -1 Or left = 1)
is the same as

Code: Select all

If Left < -1 Or Left > 1
If I'm not wrong. :wink:

Re: AutoResizer - automatically resize child gadgets

Posted: Sat Jan 07, 2012 7:44 pm
by skywalk
Really nice and clean code :D

Re: AutoResizer - automatically resize child gadgets

Posted: Sat Jan 07, 2012 8:48 pm
by USCode
breeze4me wrote:AutoResizer is very similar to nxResize(by srod) and PureRESIZE(by gnozal).
It is used for resizing or anchoring the child gadgets of a window.
It doesn't use subclassing methods, so it may be easy to be adapted to the other platforms.(but for Windows only just now)
FYI - I released something similar way back in April 2004: http://www.purebasic.fr/english/viewtop ... ize#p52312
I also released the source code AND it's cross-platform.

Re: AutoResizer - automatically resize child gadgets

Posted: Sun Jan 08, 2012 12:58 am
by skywalk
USCode wrote:FYI - I released something similar way back in April 2004: viewtopic.php?f=12&t=10218&p=52312&hilit=resize#p52312
I also released the source code AND it's cross-platform.
Doh! Even simpler and with no callbacks. :oops:
Thanks for both versions.
Would be cool if this was a native feature. 8)

Re: AutoResizer - automatically resize child gadgets

Posted: Sun Jan 08, 2012 3:07 am
by breeze4me
infratec wrote:Hope I can test it with Linux next time.
I have no Linux programming knowledges, so it is difficult for me to add the functionality. :oops:
The non-crossplatform parts are AutoResizer_GetParentGadget and AutoResizer_GetParentWnd functions, it returns the parent gadget(or window) number.
Maybe Linux has similar functions to GetParent_() API. That can be a start point, I think.
Or it is possible that the other functions is modified to accept an additional "ParentGadget" parameter.

infratec wrote:Btw.:

Code: Select all

If Not (Left = 0 Or Left = -1 Or left = 1)
is the same as

Code: Select all

If Left < -1 Or Left > 1
If I'm not wrong. :wink:
Thanks! I edited the code.

Re: AutoResizer - automatically resize child gadgets

Posted: Sun Jan 08, 2012 3:20 am
by breeze4me
skywalk wrote:Really nice and clean code :D
Thank you. :D
skywalk wrote:Would be cool if this was a native feature. 8)
+1 :!:



USCode wrote:FYI - I released something similar way back in April 2004: viewtopic.php?f=12&t=10218&p=52312&hilit=resize#p52312
I also released the source code AND it's cross-platform.
Ah! It seems to be basically the same way.
The difference is that my code can set proportional anchors, so it needs non-crossplatform parts.

Re: AutoResizer - automatically resize child gadgets

Posted: Mon Jan 09, 2012 2:01 pm
by Kwai chang caine
Works great
Thanks for sharing 8)

Re: AutoResizer - automatically resize child gadgets

Posted: Mon Jan 09, 2012 9:05 pm
by breeze4me
Linux code added. (tested on Ubuntu v11.10)

The window "Example 1" doesn't work correctly, because of PB GadgetX/Y function bug. (PB 4.61 Beta 1 x86 Linux)(viewtopic.php?f=23&t=48349)