G-spot - rule based window / gadget / 2D element resizing
Posted: Sun Mar 21, 2010 11:57 pm
(Edit: I think this belongs in 'announcements'...)
This is a work in progress. It's a set of routines to add more intelligent resizing to GUI's. After creating multiple objects, you can add rules that will move and / or resize them, depending on size and position of other GUI elements.
The code is a bit long, but I was trying to figure out a most universal system, which could also be used for other purposes, such as 2D CAD applications, and mixtures of and interactions between gadgets and windows.
In application it would look like this:
The third line above would make sure button 2 would always be located directly below button 1.
The impact on your existing code and gadgets would be close to nill. All it would take is add rules for those gadgets you want to control, and add a call to gs_apply() in your event handler when a window is resized or moved.
The code detects if gadgets or windows exist. You can build an extensive ruleset for hundreds of gadgets, and the ruleset stays applicable, even when some parts of your program (ie. the windows and the gadgets they contain) are inactive ie. not open (yet). I did not want to walk through a linked list or array so I (ab)used
a hash table, but I may change that in the future for speed purposes.
Some rules in an example:
Full code in the next post.
This is a work in progress. It's a set of routines to add more intelligent resizing to GUI's. After creating multiple objects, you can add rules that will move and / or resize them, depending on size and position of other GUI elements.
The code is a bit long, but I was trying to figure out a most universal system, which could also be used for other purposes, such as 2D CAD applications, and mixtures of and interactions between gadgets and windows.
In application it would look like this:
Code: Select all
ButtonGadget(#g_button1,190,190,20,20,"1")
ButtonGadget(#g_button2,360,360,40,40,"2")
gs_addrule(#gs_gadget,#g_button2,#gs_below,#gs_gadget,#g_button1,0,0)
The impact on your existing code and gadgets would be close to nill. All it would take is add rules for those gadgets you want to control, and add a call to gs_apply() in your event handler when a window is resized or moved.
The code detects if gadgets or windows exist. You can build an extensive ruleset for hundreds of gadgets, and the ruleset stays applicable, even when some parts of your program (ie. the windows and the gadgets they contain) are inactive ie. not open (yet). I did not want to walk through a linked list or array so I (ab)used

Some rules in an example:
Code: Select all
gs_init()
;
Enumeration
#w_main_nr
#w_slave_nr
#g_button1
#g_button2
#g_button3
EndEnumeration
;
Global event.i
;
OpenWindow(#w_main_nr,10,10,400,400,"gspot",#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_SizeGadget)
OpenWindow(#w_slave_nr,10,10,220,220,"slave",#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_SizeGadget)
;
UseGadgetList(WindowID(#w_main_nr))
ButtonGadget(#g_button1,190,190,20,20,"1")
ButtonGadget(#g_button2,360,360,40,40,"2")
gs_addrule(#gs_gadget,#g_button2,#gs_below,#gs_gadget,#g_button1,10,20)
gs_addrule(#gs_gadget,#g_button2,#gs_rightof,#gs_gadget,#g_button1,10,20)
gs_addrule(#gs_gadget,#g_button2,#gs_spandown,#gs_window,#w_main_nr,10,20)
gs_addrule(#gs_gadget,#g_button2,#gs_spanright,#gs_window,#w_main_nr,10,20)
gs_addrule(#gs_window,#w_slave_nr,#gs_aligntop,#gs_window,#w_main_nr)
gs_addrule(#gs_window,#w_slave_nr,#gs_rightof,#gs_window,#w_main_nr,10)
gs_addrule(#gs_window,#w_slave_nr,#gs_setsize,#gs_window,#w_main_nr)
;
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_SizeWindow, #PB_Event_MoveWindow
ResizeGadget(#g_button1,WindowWidth(#w_main_nr)/2,WindowHeight(#w_main_nr)/2,#PB_Ignore,#PB_Ignore)
gs_apply()
EndSelect
Until event = #PB_Event_CloseWindow
;
gs_end()