ResizeGadgets: Auto-resize or auto-move your gadgets.

Share your advanced PureBasic knowledge/code with the community.
User avatar
emerkel
New User
New User
Posts: 3
Joined: Tue Nov 02, 2004 12:40 am
Location: Edmond OK

Very nice!

Post by emerkel »

Thanks very much. Resize code is the most boring and tedious code there is to write, I appreciate your hard work :)
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

akj wrote:rsts:
When you said "The resizing looks wierd" were you referring to the output of my test program?
If you were, please be aware the test program was only intended to show some of the available gadget resizing possibilities, and it was not meant to be a cosmetic display.
On the other hand, if it was a program you wrote yourself that was giving the wierd resizing, please post a copy of the program and if possible a screen shot (but I do not know how one does this in a forum) and I will investigate.

chen:
I do not know of a cross-platform solution.
In Windows, one way to implement a window size limitation, but avoiding flicker is to invoke a callback function just before the event loop with a statement like this:

Code: Select all

SetWindowCallback(@MinSize())
The callback routine itself could be:

Code: Select all

Procedure MinSize(hWnd, Msg, wParam, lParam)
Define *r.rect ; Will map to lParam
Select Msg
Case #WM_SIZING
  *r=lParam
  With *r
    If \right-\left<=200: \right=\left+200: EndIf
    If \bottom-\top<=200: \bottom=\top+200: EndIf
  EndWith
  ProcedureReturn 0
EndSelect 
ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure
Of course, this callback routine could be merged with the NoFlick() routine posted by einander earlier in this topic.

P.S. I have just noticed that in the above code I have written "Define *r.rect" whereas I meant to write "Protected *r.rect". Could someone please explain to me the difference between Define and Protected when they occur in a procedure? I do not really understand the scope of a variable declared with Define.
it is better to use the GETMINMAXINFO message because it's easier and really block the resizing.

Code: Select all

Procedure.l MinMaxCB(WindowID.l,message.l,wParam.l,lParam.l,result.l) 
  
  If message = #WM_GETMINMAXINFO
    
      If WindowID(myWindow) = WindowID
        
        *pMinMax.MINMAXINFO = lParam
        *pMinMax\ptMinTrackSize\x = 640
        *pMinMax\ptMinTrackSize\y = 480
        *pMinMax\ptMaxTrackSize\x = 800
        *pMinMax\ptMaxTrackSize\y = 600
        
        ProcedureReturn #Null
        
      EndIf
    
  EndIf
  
  ProcedureReturn result
  
EndProcedure 
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
chen
Enthusiast
Enthusiast
Posts: 338
Joined: Fri Dec 23, 2005 2:20 pm
Location: Quebec, Canada
Contact:

Re: PB 4.0 version added

Post by chen »

USCode wrote:New version for PB 4.0 added to original posting.
How I can using your code proportionally resize these objects ( cross-platform):
I left the lock flags as 1's to catch the effect:

Code: Select all

Enumeration
  #Window_0
  #exit
  #Gadget1
  #Gadget2
EndEnumeration

Global Event.l, event_gadget.l, event_window.l
Global panel0.l, str1.l, str2.l

XIncludeFile "RS_ResizeGadgets.pbi"

Procedure Open_Window_0()
  If OpenWindow(#Window_0, 5, 5, 500, 520, "PureBasic 4.0 -> Gadgets", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar|#PB_Window_ScreenCentered )

    If CreateGadgetList(WindowID(#Window_0)) ; - Gadget List
      ; ---- Start Gadgets code ---- 
      panel0 = PanelGadget(#PB_Any, 50, 30, 400, 400)
        AddGadgetItem(panel0, 1,"Tab 1")
        ; Tab 1 Objects here, X,Y, Widht, Height relative to Panel Gadget
        str1 = StringGadget(#PB_Any, 40, 30, 300, 130, "")
        str2 = StringGadget(#PB_Any, 40, 175, 300, 155, "")
        AddGadgetItem(panel0, 2,"Tab 2")
        ; Tab 2 Objects here, X,Y, Widht, Height relative to Panel Gadget
        AddGadgetItem(panel0, 3,"Tab 3")
        ; Tab 3 Objects here, X,Y, Widht, Height relative to Panel Gadget
      CloseGadgetList()
      ; ---- End Gadgets code ----
    EndIf
    
  Else
    MessageRequester("Gadgets Creation Failure!","Gadgets Not Created!!!")
  EndIf
  
EndProcedure

Procedure registerObgets()
  RS_Register(#Window_0,panel0,1,1,1,1)
  RS_Register(#Window_0,str1,1,1,1,1)
  RS_Register(#Window_0,str2,1,1,1,1)
EndProcedure

Open_Window_0() ; Execute the GUI
registerObgets()

Repeat
  focus.l = -1       ; To Detect what gadget has the focus and be able to take additional actions
  
  Event = WaitWindowEvent()
  event_window = EventWindow() 
  event_gadget = EventGadget() 
  
  Select event_window
    Case #Window_0
      ;Events in the main window
      Select Event
          ; --- Window Events
        Case #PB_Event_CloseWindow
          focus = #exit
        Case #PB_Event_SizeWindow
          RS_Resize(Event, event_window)
          
          ; ---Gadget Events
        Case #PB_Event_Gadget
          Select event_gadget
            Case #Gadget1
              Debug "Your code"
            Case #Gadget2
              Debug "Your code"
            Default
          EndSelect
          
        Default
      EndSelect
    Default
      
  EndSelect
  
Until focus = #exit
eddiepb
New User
New User
Posts: 1
Joined: Mon Oct 30, 2006 4:28 pm

Post by eddiepb »

USCode,

Just wanted to let you know that I think your code is great. I will be looking at incorporating it into a project I am working on.

Thanks for sharing.

Eddie
infratec
Always Here
Always Here
Posts: 7587
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: ResizeGadgets: Auto-resize or auto-move your gadgets.

Post by infratec »

Hi,

I updated your cool stuff for PB 4.60 and made some minor changes.
Save it as RS_ResizeGadgets.pbi

Code: Select all

;
; RS_ResizeGadgets.pbi
; Automatically Resize PureBasic Gadgets
; Author: USCode
; January 07, 2012 - cosmetics, additional tests and some speed improvements
; 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

EnableExplicit

Structure RS_gadget_struct
  Window.i
  Gadget.i
  Left.i
  Top.i
  Right.i
  Bottom.i
  Lock_left.i
  Lock_top.i
  Lock_right.i
  Lock_bottom.i
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, GadgetID, Left (boolean), Top (boolean), Right (boolean), Bottom (boolean).
Procedure RS_Register(RS_window.i, RS_gadget.i, RS_left.i, RS_top.i, RS_right.i, RS_bottom.i)
  
  Protected.i WWidth, WHeight, GX, GY
  
  If IsGadget(RS_gadget)
    If 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
        
        WWidth  = WindowWidth(RS_window)
        WHeight = WindowHeight(RS_window)
        
        GX = GadgetX(RS_gadget)
        GY = GadgetY(RS_gadget)
        
        If RS_left   = #False : \Left   = WWidth  - GX : EndIf
        If RS_top    = #False : \Top    = WHeight - GY : EndIf
        If RS_right  = #True  : \Right  = WWidth  - (GX + GadgetWidth(RS_gadget))  : EndIf
        If RS_bottom = #True  : \Bottom = WHeight - (GY + GadgetHeight(RS_gadget)) : EndIf
        
      EndWith
    EndIf
  EndIf
  
EndProcedure


; RS_Unregister - Unregister gadget from resizing
Procedure RS_Unregister(RS_window.i, RS_gadget.i)
  
  With RS_Gadgets()
    ForEach RS_Gadgets()
      If \Window = RS_window And (\Gadget = RS_gadget Or \Gadget = -1)
        DeleteElement(RS_Gadgets())
        If \Gadget <> -1 : Break : EndIf
      EndIf
    Next
  EndWith
  
EndProcedure


; RS_Resize - Resize all registered gadgets for the resizing window.
; Parameters: Event ID, Event Window ID
Procedure RS_Resize(RS_Event.i, RS_window.i)
  
  Protected.i RS_x, RS_y, RS_w, RS_h, WWidth, WHeight
  
  If RS_Event = #PB_Event_SizeWindow And ListSize(RS_Gadgets()) > 0
    
    With RS_Gadgets()
      ForEach RS_Gadgets()
        If \Window = RS_window
          
          WWidth  = WindowWidth(RS_window)
          WHeight = WindowHeight(RS_window)
          
          If IsGadget(\Gadget)
            RS_x = GadgetX(\Gadget)
            RS_y = GadgetY(\Gadget)
            RS_w = #PB_Ignore
            RS_h = #PB_Ignore
            
            If \Lock_left   = #False : RS_x = WWidth  - \Left : EndIf
            If \Lock_top    = #False : RS_y = WHeight - \Top  : EndIf       
            If \Lock_right  = #True  : RS_w = WWidth  - RS_x - \Right  : EndIf
            If \Lock_bottom = #True  : RS_h = WHeight - RS_y - \Bottom : EndIf       
            
            ResizeGadget(\Gadget, RS_x, RS_y, RS_w, RS_h)
          EndIf
          
        EndIf
      Next
    EndWith
    
  EndIf
  
EndProcedure
And the example:

Code: Select all

;
; RS_ResizeGadgets test
;

; (1) RESIZE INCLUDE
XIncludeFile "RS_ResizeGadgets.pbi"

;- Window Constants
;
Enumeration
  #Window_0
EndEnumeration

;- Gadget Constants
;
Enumeration
  #Button_0
  #Button_1
  #Button_2
  #Button_3
  #Listview_0
EndEnumeration


If OpenWindow(#Window_0, 358, 178, 300, 300, "Resize Test",  #PB_Window_SizeGadget | #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
  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)
  
  ; (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)
  
  Exit = #False
  Repeat
    
    Event = WaitWindowEvent()
    
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #Button_0 : Debug "GadgetID: #Button_0"
          Case #Button_1 : Debug "GadgetID: #Button_1"
          Case #Button_2 : Debug "GadgetID: #Button_2"
          Case #Button_3 : Debug "GadgetID: #Button_3"
          Case #Listview_0 : Debug "GadgetID: #Listview_0"
        EndSelect
      Case #PB_Event_SizeWindow : RS_Resize(Event, EventWindow())
      Case #PB_Event_CloseWindow : Exit = #True
    EndSelect
    
  Until Exit
  
EndIf
Bernd
Last edited by infratec on Sun Jan 08, 2012 10:49 pm, edited 2 times in total.
USCode
Addict
Addict
Posts: 923
Joined: Wed Mar 24, 2004 11:04 pm
Location: Seattle

Re: ResizeGadgets: Auto-resize or auto-move your gadgets.

Post by USCode »

Hi Bernd,
If you have the time, would you mind highlighting in bold the changes you made so I can evaluate them and get them into the code given on my original posting?
Thanks Bernd!
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: ResizeGadgets: Auto-resize or auto-move your gadgets.

Post by Danilo »

USCode wrote:Hi Bernd,
If you have the time, would you mind highlighting in bold the changes you made so I can evaluate them and get them into the code given on my original posting?
Thanks Bernd!
Diff for your operating system could help. On Windows WinDiff.exe is included in the MS Platform SDK.
You use it like this: "WinDiff.exe file1.pb file2.pb" and voila, you see all changes. ;)
USCode
Addict
Addict
Posts: 923
Joined: Wed Mar 24, 2004 11:04 pm
Location: Seattle

Re: ResizeGadgets: Auto-resize or auto-move your gadgets.

Post by USCode »

Danilo wrote:Diff for your operating system could help. On Windows WinDiff.exe is included in the MS Platform SDK.
You use it like this: "WinDiff.exe file1.pb file2.pb" and voila, you see all changes. ;)
Plus there's the new Compare Files feature built into PB 4.60!

Bernd, I just looked at my RS_ResizeGadgets source code and noticed I had updated the code for PB 4.5 back in Sept 2010.
Also, I had added the ability to unregister all the gadgets for a Window in one call automatically.
I've posted that updated code in my original post. Thanks for bringing this to my attention!
Last edited by USCode on Sun Jan 08, 2012 7:40 am, edited 1 time in total.
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: ResizeGadgets: Auto-resize or auto-move your gadgets.

Post by skywalk »

I think the Notepad++ Compare plug-in is very handy.
You can edit 2 files side-by-side and re-compare on the fly seeing your changes highlight instantly.
http://sourceforge.net/projects/npp-compare/
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
infratec
Always Here
Always Here
Posts: 7587
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: ResizeGadgets: Auto-resize or auto-move your gadgets.

Post by infratec »

Hi USCode,

I added your stuff from 2010 in my version above.
There are only few differences, since you now also use foreach :cry:

I added some more checks (If IsGadget()),
I use Break to stop the loop if the gadget is found,
I use only integers,
I use protected variables.

That's all.

And again, it is a super clean and easy solution. (didn't saw it before)
(The best solutions are often simple ones)

Bernd
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: ResizeGadgets: Auto-resize or auto-move your gadgets.

Post by skywalk »

Code: Select all

; RS_Resize - Resize all registered gadgets for the resizing window.
; Parameters: Event ID, Event Window ID
Procedure RS_Resize(RS_Event.i, RS_window.i)
  
  ;FROM:
  ;Protected.i RS_size, RS_x, RS_y, RS_w, RS_h, WWidth, WHeight
  ;TO:   RS_size variable not used.
  Protected.i RS_x, RS_y, RS_w, RS_h, WWidth, WHeight
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
infratec
Always Here
Always Here
Posts: 7587
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: ResizeGadgets: Auto-resize or auto-move your gadgets.

Post by infratec »

Thanks :!:

Fixed.
User avatar
Thorsten1867
Addict
Addict
Posts: 1372
Joined: Wed Aug 24, 2005 4:02 pm
Location: Germany

Re: ResizeGadgets: Auto-resize or auto-move your gadgets.

Post by Thorsten1867 »

I have changed and extended the code of USCode for PureBasic V5.2x:
ResizeWindowModule.pbi
Translated with http://www.DeepL.com/Translator

Download of PureBasic - Modules
Download of PureBasic - Programs

[Windows 11 x64] [PB V5.7x]
User avatar
Michael Vogel
Addict
Addict
Posts: 2797
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: ResizeGadgets: Auto-resize or auto-move your gadgets.

Post by Michael Vogel »

infratec wrote:

Code: Select all

;
; RS_ResizeGadgets.pbi
; Automatically Resize PureBasic Gadgets
; Author: USCode
; January 07, 2012 - cosmetics, additional tests and some speed improvements
; 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

EnableExplicit

Structure RS_gadget_struct
  Window.i
  Gadget.i
  Left.i
  Top.i
  Right.i
  Bottom.i
  Lock_left.i
  Lock_top.i
  Lock_right.i
  Lock_bottom.i
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, GadgetID, Left (boolean), Top (boolean), Right (boolean), Bottom (boolean).
Procedure RS_Register(RS_window.i, RS_gadget.i, RS_left.i, RS_top.i, RS_right.i, RS_bottom.i)
  
  Protected.i WWidth, WHeight, GX, GY
  
  If IsGadget(RS_gadget)
    If 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
        
        WWidth  = WindowWidth(RS_window)
        WHeight = WindowHeight(RS_window)
        
        GX = GadgetX(RS_gadget)
        GY = GadgetY(RS_gadget)
        
        If RS_left   = #False : \Left   = WWidth  - GX : EndIf
        If RS_top    = #False : \Top    = WHeight - GY : EndIf
        If RS_right  = #True  : \Right  = WWidth  - (GX + GadgetWidth(RS_gadget))  : EndIf
        If RS_bottom = #True  : \Bottom = WHeight - (GY + GadgetHeight(RS_gadget)) : EndIf
        
      EndWith
    EndIf
  EndIf
  
EndProcedure


; RS_Unregister - Unregister gadget from resizing
Procedure RS_Unregister(RS_window.i, RS_gadget.i)
  
  With RS_Gadgets()
    ForEach RS_Gadgets()
      If \Window = RS_window And (\Gadget = RS_gadget Or \Gadget = -1)
        DeleteElement(RS_Gadgets())
        If \Gadget <> -1 : Break : EndIf
      EndIf
    Next
  EndWith
  
EndProcedure


; RS_Resize - Resize all registered gadgets for the resizing window.
; Parameters: Event ID, Event Window ID
Procedure RS_Resize(RS_Event.i, RS_window.i)
  
  Protected.i RS_x, RS_y, RS_w, RS_h, WWidth, WHeight
  
  If RS_Event = #PB_Event_SizeWindow And ListSize(RS_Gadgets()) > 0
    
    With RS_Gadgets()
      ForEach RS_Gadgets()
        If \Window = RS_window
          
          WWidth  = WindowWidth(RS_window)
          WHeight = WindowHeight(RS_window)
          
          If IsGadget(\Gadget)
            RS_x = GadgetX(\Gadget)
            RS_y = GadgetY(\Gadget)
            RS_w = #PB_Ignore
            RS_h = #PB_Ignore
            
            If \Lock_left   = #False : RS_x = WWidth  - \Left : EndIf
            If \Lock_top    = #False : RS_y = WHeight - \Top  : EndIf       
            If \Lock_right  = #True  : RS_w = WWidth  - RS_x - \Right  : EndIf
            If \Lock_bottom = #True  : RS_h = WHeight - RS_y - \Bottom : EndIf       
            
            ResizeGadget(\Gadget, RS_x, RS_y, RS_w, RS_h)
          EndIf
          
        EndIf
      Next
    EndWith
    
  EndIf
  
EndProcedure

When using comboboxes, the text could get selected when resizing - any idea how to supress this effect?

Code: Select all

Enumeration
	#Button_0
	#Button_1
	#Button_2
	#Button_3
	#Listview_0
EndEnumeration


If OpenWindow(#Window_0, 358, 178, 300, 300, "Resize Test",  #PB_Window_SizeGadget | #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
	ComboBoxGadget(#Button_0, 5, 5, 50, 25, #PB_ComboBox_Editable)
	ComboBoxGadget(#Button_1, 245, 5, 50, 25,#PB_ComboBox_Editable)
	ComboBoxGadget(#Button_2, 5, 270, 50, 25,#PB_ComboBox_Editable)
	ComboBoxGadget(#Button_3, 245, 270, 50, 25,#PB_ComboBox_Editable)
	ListViewGadget(#Listview_0, 55, 30, 190, 240)

	For i=#Button_0 To #Button_3
		AddGadgetItem(i,0,"Hi")
		SetGadgetText(i,"Hi")
	Next i

	RS_Register(#Window_0, #Button_0, 1,1,1,1)
	RS_Register(#Window_0, #Button_1, 1,1,1,1)
	RS_Register(#Window_0, #Button_2, 1,0,1,1)
	RS_Register(#Window_0, #Button_3, 1,0,1,1)
	RS_Register(#Window_0, #Listview_0, #True, #True, #True, #True)


	Repeat

		Event = WaitWindowEvent()

		Select Event
		Case #PB_Event_Gadget
			Select EventGadget()
			Case #Button_0 : Debug "GadgetID: #Button_0"
			Case #Button_1 : Debug "GadgetID: #Button_1"
			Case #Button_2 : Debug "GadgetID: #Button_2"
			Case #Button_3 : Debug "GadgetID: #Button_3"
			Case #Listview_0 : Debug "GadgetID: #Listview_0"
			EndSelect
		Case #PB_Event_SizeWindow : RS_Resize(Event, EventWindow())
		Case #PB_Event_CloseWindow : Exit = #True
		EndSelect

	Until Exit

EndIf
mestnyi
Addict
Addict
Posts: 1098
Joined: Mon Nov 25, 2013 6:41 am

Re: ResizeGadgets: Auto-resize or auto-move your gadgets.

Post by mestnyi »

When using comboboxes, the text could get selected when resizing
Clarify that it does not understand what you mean by that? :)
Post Reply