- RS_ResizeGadgets -
One of the things I really liked about Borland Delphi was the "anchor" feature which allows you to "lock" one side of a widget to that side of a resizable window. So in essence, when the window was resized by either the user or programmatically, you could get your widgets to react accordingly. Your widgets could stay in place, move, stretch, whatever you wanted the behavior to be. I missed having this automatic behavior in PureBasic...
I haven't been able to find any user or PB routines out there which gave me this functionality, so I wrote a couple of simple routines to take care of it for me and I'd like to share them with you here. I'm very new to PureBasic so I'm sure lots of you wizards out there could improve upon this or offer some helpful suggestions. Any feedback is appreciated.
Essentially, all you have to do is 3 simple changes: IncludeFile my RS_ResizeGadgets.pb source file, RS_Register your gadgets specifying which side(s) you want to lock and call RS_Resize in the Event Loop. See the example below for how to use the 2 resize procedures, the required parameters and various combinations of "locking" you can do.
When you run the example, grab the lower right corner of the window and move that corner around, resizing the window in all various directions. You'll see how you can get the gadgets to behave.
Be sure you have also saved the RS_ResizeGadgets.pb source file listed below as well.
RS_ResizeGadgets for PB 4.5+
Code: Select all
;
; RS_ResizeGadgets.pb
; Automatically Resize PureBasic Gadgets
; Author: USCode
;
; September 13, 2010 - Added With/ForEach statements, 'Window' Unregister, longs to integers
; February 19, 2006 - Updated for PureBasic 4.0.
; April 15, 2004 - Original version for 3.9x.
;
; To use:
; - Include this source file.
; - Call RS_Register ONCE for EACH Gadget to be resized, specifying side locks.
; - Call RS_Resize in the event loop, specifying Event ID and Event Window ID.
;
; DECLARATIONS
; Constants
#RS_All = -1
; Structures
Structure RS_gadget_struct
Window.i
Gadget.i
Left.i
Top.i
Right.i
Bottom.i
Lock_left.b
Lock_top.b
Lock_right.b
Lock_bottom.b
EndStructure
Global NewList RS_Gadgets.RS_gadget_struct()
; PROCEDURES
; RS_Register - Register gadget to be resized and how to resize.
; Specify #TRUE for each side of the gadget you want to LOCK, else #FALSE.
; Parameters: WindowID (integer), GadgetID (integer), Left (boolean), Top (boolean), Right (boolean), Bottom (boolean).
Procedure RS_Register(RS_window.i, RS_gadget.i, RS_left.b, RS_top.b, RS_right.b, RS_bottom.b)
AddElement(RS_Gadgets())
With RS_Gadgets()
\Gadget = RS_gadget
\Window = RS_window
\Lock_left = RS_left
\Lock_top = RS_top
\Lock_right = RS_right
\Lock_bottom = RS_bottom
If RS_left = #False
\Left = WindowWidth(RS_window) - GadgetX(RS_gadget)
EndIf
If RS_top = #False
\Top = WindowHeight(RS_window) - GadgetY(RS_gadget)
EndIf
If RS_right = #True
\Right = WindowWidth(RS_window) - (GadgetX(RS_gadget) + GadgetWidth(RS_gadget))
EndIf
If RS_bottom = #True
\Bottom = WindowHeight(RS_window) - (GadgetY(RS_gadget) + GadgetHeight(RS_gadget))
EndIf
EndWith
EndProcedure
; RS_Unregister - Unregister gadget from resizing.
; Parameters: Window ID (integer), Gadget ID (integer).
; Gadget ID = #RS_All to unregister all gadgets for Window ID.
Procedure RS_Unregister(RS_window.i, RS_gadget.i)
ResetList(RS_Gadgets())
ForEach RS_Gadgets()
If RS_Gadgets()\Window = RS_window And (RS_Gadgets()\Gadget = RS_gadget Or RS_gadget = #RS_All)
DeleteElement(RS_Gadgets())
EndIf
Next
EndProcedure
; RS_Resize - Resize all registered gadgets for the resizing window.
; Parameters: Event ID (integer), Event Window ID (integer).
Procedure RS_Resize(RS_Event.i, RS_window.i)
If RS_Event = #PB_Event_SizeWindow And ListSize(RS_Gadgets()) > 0
Define.i RS_gadget, RS_size, RS_x, RS_y, RS_w, RS_h
ForEach RS_Gadgets()
If RS_Gadgets()\Window = RS_window
With RS_Gadgets()
RS_gadget = \Gadget
RS_x = GadgetX(RS_gadget)
RS_y = GadgetY(RS_gadget)
RS_w = #PB_Ignore:RS_h = #PB_Ignore
If \Lock_left = #False
RS_x = (WindowWidth(RS_window) - \Left)
EndIf
If \Lock_top = #False
RS_y = (WindowHeight(RS_window) - \Top)
EndIf
If \Lock_right = #True
RS_w = (WindowWidth(RS_window) - RS_x) - \Right
EndIf
If \Lock_bottom = #True
RS_h = (WindowHeight(RS_window) - RS_y) - \Bottom
EndIf
ResizeGadget(RS_gadget, RS_x, RS_y, RS_w, RS_h)
EndWith
EndIf
Next
EndIf
EndProcedure
; RS_ResizeGadgets.pb
Code: Select all
;
; RS_ResizeGadgets.pb
; Automatically Resize PureBasic Gadgets
; Author: USCode
; February 19, 2006 - Updated for PureBasic 4.0.
; April 15, 2004 - Original version for 3.9x.
;
; To use:
; - Include this source file.
; - Call RS_Register ONCE for EACH Gadget to be resized, specifying side locks.
; - Call RS_Resize in the event loop, specifying Event ID and Event Window ID.
;
;DECLARATIONS
Structure RS_gadget_struct
Window.l
Gadget.l
Left.l
Top.l
Right.l
Bottom.l
Lock_left.b
Lock_top.b
Lock_right.b
Lock_bottom.b
EndStructure
Global NewList RS_Gadgets.RS_gadget_struct()
;PROCEDURES
; RS_Register - Register gadget to be resized and how to resize.
; Specify #TRUE for each side of the gadget you want to LOCK, else #FALSE.
; Parameters: WindowID (long), GadgetID (long), Left (boolean), Top (boolean), Right (boolean), Bottom (boolean).
Procedure RS_Register(RS_window.l, RS_gadget.l, RS_left.b, RS_top.b, RS_right.b, RS_bottom.b)
AddElement(RS_Gadgets())
RS_Gadgets()\Gadget = RS_gadget
RS_Gadgets()\Window = RS_window
RS_Gadgets()\Lock_left = RS_left
RS_Gadgets()\Lock_top = RS_top
RS_Gadgets()\Lock_right = RS_right
RS_Gadgets()\Lock_bottom = RS_bottom
If RS_left = #False
RS_Gadgets()\Left = WindowWidth(RS_window) - GadgetX(RS_gadget)
EndIf
If RS_top = #False
RS_Gadgets()\Top = WindowHeight(RS_window) - GadgetY(RS_gadget)
EndIf
If RS_right = #True
RS_Gadgets()\Right = WindowWidth(RS_window) - (GadgetX(RS_gadget) + GadgetWidth(RS_gadget))
EndIf
If RS_bottom = #True
RS_Gadgets()\Bottom = WindowHeight(RS_window) - (GadgetY(RS_gadget) + GadgetHeight(RS_gadget))
EndIf
EndProcedure
; RS_Unregister - Unregister gadget from resizing
Procedure RS_Unregister(RS_window.l, RS_gadget.l)
ResetList(RS_Gadgets())
While NextElement(RS_Gadgets())
If (RS_Gadgets()\Window = RS_window) And (RS_Gadgets()\Gadget = RS_gadget)
DeleteElement(RS_Gadgets())
EndIf
Wend
EndProcedure
; RS_Resize - Resize all registered gadgets for the resizing window.
; Parameters: Event ID (long), Event Window ID (long).
Procedure RS_Resize(RS_Event.l, RS_window.l)
If RS_Event = #PB_Event_SizeWindow And CountList(RS_Gadgets()) > 0
RS_gadget.l:RS_size.l:RS_x.l:RS_y.l:RS_w.l:RS_h.l
ResetList(RS_Gadgets())
While NextElement(RS_Gadgets())
If RS_Gadgets()\Window = RS_window
RS_gadget = RS_Gadgets()\Gadget
RS_x = GadgetX(RS_gadget)
RS_y = GadgetY(RS_gadget)
RS_w = #PB_Ignore:RS_h = #PB_Ignore
If RS_Gadgets()\Lock_left = #False
RS_x = (WindowWidth(RS_window) - RS_Gadgets()\Left)
EndIf
If RS_Gadgets()\Lock_top = #False
RS_y = (WindowHeight(RS_window) - RS_Gadgets()\Top)
EndIf
If RS_Gadgets()\Lock_right = #True
RS_w = (WindowWidth(RS_window) - RS_x) - RS_Gadgets()\Right
EndIf
If RS_Gadgets()\Lock_bottom = #True
RS_h = (WindowHeight(RS_window) - RS_y) - RS_Gadgets()\Bottom
EndIf
ResizeGadget(RS_gadget, RS_x, RS_y, RS_w, RS_h)
EndIf
Wend
EndIf
EndProcedure
; RS_ResizeGadgets.pb
Code: Select all
;
; RS_ResizeGadgets test
;
;- Window Constants
;
Enumeration
#Window_0
EndEnumeration
;- Gadget Constants
;
Enumeration
#Button_0
#Button_1
#Button_2
#Button_3
#Listview_0
EndEnumeration
Procedure Open_Window_0()
If OpenWindow(#Window_0, 358, 178, 300, 300, "Resize Test", #PB_Window_SizeGadget | #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
If CreateGadgetList(WindowID(#Window_0))
ButtonGadget(#Button_0, 5, 5, 50, 25, "Button0")
ButtonGadget(#Button_1, 245, 5, 50, 25, "Button1")
ButtonGadget(#Button_2, 5, 270, 50, 25, "Button2")
ButtonGadget(#Button_3, 245, 270, 50, 25, "Button3")
ListViewGadget(#Listview_0, 55, 30, 190, 240)
EndIf
EndIf
EndProcedure
Open_Window_0()
; (1) RESIZE INCLUDE
IncludeFile "C:\Backup\Software\PureBasic\RS_ResizeGadgets\RS_ResizeGadgets.pb"
; (2) REGISTER RESIZE GADGETS
; Parameters: Parent WindowID, GadgetID, Lock Left, Lock Top, Lock Right, Lock Bottom)
RS_Register(#Window_0,#Button_0,#True,#True,#False,#False)
RS_Register(#Window_0,#Button_1,#False,#True,#True,#False)
RS_Register(#Window_0,#Button_2,#True,#False,#False,#True)
RS_Register(#Window_0,#Button_3,#False,#False,#True,#True)
RS_Register(#Window_0,#Listview_0,#True,#True,#True,#True)
;
Repeat
Event = WaitWindowEvent()
; (3) RESIZE GADGETS
RS_Resize(Event,EventWindow())
If Event = #PB_Event_Gadget
GadgetID = EventGadget()
If GadgetID = #Button_0
Debug "GadgetID: #Button_0"
ElseIf GadgetID = #Button_1
Debug "GadgetID: #Button_1"
ElseIf GadgetID = #Button_2
Debug "GadgetID: #Button_2"
ElseIf GadgetID = #Button_3
Debug "GadgetID: #Button_3"
ElseIf GadgetID = #Listview_0
Debug "GadgetID: #Listview_0"
EndIf
EndIf
Until Event = #PB_Event_CloseWindow
End
;
Code: Select all
;
; RS_ResizeGadgets test
;
;- Window Constants
;
Enumeration
#Window_0
EndEnumeration
;- Gadget Constants
;
Enumeration
#Button_0
#Button_1
#Button_2
#Button_3
#Listview_0
EndEnumeration
Procedure Open_Window_0()
If OpenWindow(#Window_0, 358, 178, 300, 300, #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered , "Resize Test")
If CreateGadgetList(WindowID())
ButtonGadget(#Button_0, 5, 5, 50, 25, "Button0")
ButtonGadget(#Button_1, 245, 5, 50, 25, "Button1")
ButtonGadget(#Button_2, 5, 270, 50, 25, "Button2")
ButtonGadget(#Button_3, 245, 270, 50, 25, "Button3")
ListViewGadget(#Listview_0, 55, 30, 190, 240)
EndIf
EndIf
EndProcedure
Open_Window_0()
; (1) RESIZE INCLUDE
IncludeFile "RS_ResizeGadgets.pb"
; (2) REGISTER RESIZE GADGETS
; Parameters: Parent WindowID, GadgetID, Lock Left, Lock Top, Lock Right, Lock Bottom)
RS_Register(#Window_0,#Button_0,#TRUE,#TRUE,#FALSE,#FALSE)
RS_Register(#Window_0,#Button_1,#FALSE,#TRUE,#TRUE,#FALSE)
RS_Register(#Window_0,#Button_2,#TRUE,#FALSE,#FALSE,#TRUE)
RS_Register(#Window_0,#Button_3,#FALSE,#FALSE,#TRUE,#TRUE)
RS_Register(#Window_0,#Listview_0,#TRUE,#TRUE,#TRUE,#TRUE)
;
Repeat
Event = WaitWindowEvent()
; (3) RESIZE GADGETS
RS_Resize(Event,EventWindowID())
If Event = #PB_EventGadget
GadgetID = EventGadgetID()
If GadgetID = #Button_0
Debug "GadgetID: #Button_0"
ElseIf GadgetID = #Button_1
Debug "GadgetID: #Button_1"
ElseIf GadgetID = #Button_2
Debug "GadgetID: #Button_2"
ElseIf GadgetID = #Button_3
Debug "GadgetID: #Button_3"
ElseIf GadgetID = #Listview_0
Debug "GadgetID: #Listview_0"
EndIf
EndIf
Until Event = #PB_EventCloseWindow
End
;
RS_ResizeGadgets.pb for PB 3.9x
Code: Select all
;
;
; RS_ResizeGadgets.pb
; Automatically Resize PureBasic Gadgets
; Author: USCode
; Date: April 15, 2004
;
; To use:
; - Include this source file.
; - Call RS_Register ONCE for EACH Gadget to be resized, specifiying side locks.
; - Call RS_Resize in the event loop, specifying EventID and EventWindowID.
;
;DECLARATIONS
Structure RS_gadget_struct
Window.l
Gadget.l
Left.w
Top.w
Right.w
Bottom.w
Lock_left.b
Lock_top.b
Lock_right.b
Lock_bottom.b
EndStructure
NewList RS_Gadgets.RS_gadget_struct()
;PROCEDURES
; RS_Register - Register gadget to be resized and how to resize.
; Specify #TRUE for each side of the gadget you want to LOCK, else #FALSE.
; Parameters: WindowID (long), GadgetID (long), Left (boolean), Top (boolean), Right (boolean), Bottom (boolean).
Procedure RS_Register(RS_window.l, RS_gadget.l, RS_left.b, RS_top.b, RS_right.b, RS_bottom.b)
AddElement(RS_Gadgets())
RS_Gadgets()\Gadget = RS_gadget
RS_Gadgets()\Window = RS_window
RS_Gadgets()\Lock_left = RS_left
RS_Gadgets()\Lock_top = RS_top
RS_Gadgets()\Lock_right = RS_right
RS_Gadgets()\Lock_bottom = RS_bottom
UseWindow(RS_window)
If RS_left = #FALSE
RS_Gadgets()\Left = WindowWidth() - GadgetX(RS_gadget)
EndIf
If RS_top = #FALSE
RS_Gadgets()\Top = WindowHeight() - GadgetY(RS_gadget)
EndIf
If RS_right = #TRUE
RS_Gadgets()\Right = WindowWidth() - (GadgetX(RS_gadget) + GadgetWidth(RS_gadget))
EndIf
If RS_bottom = #TRUE
RS_Gadgets()\Bottom = WindowHeight() - (GadgetY(RS_gadget) + GadgetHeight(RS_gadget))
EndIf
EndProcedure
; RS_Unregister - Contributed by "FloHimself".
Procedure RS_Unregister(RS_window.l, RS_gadget.l)
ResetList(RS_Gadgets())
While NextElement(RS_Gadgets())
If (RS_Gadgets()\Window = RS_window) And (RS_Gadgets()\Gadget = RS_gadget)
DeleteElement(RS_Gadgets())
EndIf
Wend
EndProcedure
; RS_Resize - Resize all registered gadgets for the resizing window.
; Parameters: Event ID (long), Event Window ID (long).
Procedure RS_Resize(RS_Event.l, RS_window.l)
If RS_Event = #PB_Event_SizeWindow And CountList(RS_Gadgets()) > 0
RS_gadget.l:RS_size.w:RS_x.w:RS_y.w:RS_w.l:RS_h.w
ResetList(RS_Gadgets())
While NextElement(RS_Gadgets())
If RS_Gadgets()\Window = RS_window
UseWindow(RS_window)
RS_gadget = RS_Gadgets()\Gadget
RS_x = GadgetX(RS_gadget)
RS_y = GadgetY(RS_gadget)
RS_w = -1:RS_h = -1
If RS_Gadgets()\Lock_left = #FALSE
RS_x = (WindowWidth() - RS_Gadgets()\Left)
EndIf
If RS_Gadgets()\Lock_top = #FALSE
RS_y = (WindowHeight() - RS_Gadgets()\Top)
EndIf
If RS_Gadgets()\Lock_right = #TRUE
RS_w = (WindowWidth() - RS_x) - RS_Gadgets()\Right
EndIf
If RS_Gadgets()\Lock_bottom = #TRUE
RS_h = (WindowHeight() - RS_y) - RS_Gadgets()\Bottom
EndIf
ResizeGadget(RS_gadget, RS_x, RS_y, RS_w, RS_h)
EndIf
Wend
EndIf
EndProcedure
; RS_ResizeGadgets.pb
I've run a test case with 100 gadgets on 1 window and it ran very fast.
Please let me know if you have any questions/suggestions/comments, etc.
Enjoy.
Thanks,
USCode