Window resize event only after mouse release?
- Andre
- PureBasic Team
- Posts: 2071
- Joined: Fri Apr 25, 2003 6:14 pm
- Location: Germany (Saxony, Deutscheinsiedel)
- Contact:
Window resize event only after mouse release?
Using the #PB_Event_SizeWindow event I'm currently getting resize events after every single pixel change in width/height of the window. So an event is triggered already while the user has the mouse cursor still pressed...
This can be useful of course, but as I'm having very complex GUIs / dialogs (containing a lot of gadgets, charts, filled listicons which content need to be recalculated after a size change, etc.) I can't and don't want to react to every window width/height change (for only 1 pixel) while the user is still resizing the window.
So I'm searching for a solution, where the GUI/dialog resize function is only called, when the mouse cursor was released and the user's resizing action is finished.
The only releated thread I found is this one: http://www.purebasic.fr/english/viewtop ... vent+mouse
What was called a bug here, is my wanted behaviour
(probably even a feature-request for a new #PB_Event_SizeWindowFinished or similar... )
Currently I have only the idea of a workaround: save the old window size (before resize was started) and don't react to every pixel change, but to every +/- 10 pixel or more...
Anyone has a code example, which works on Windows and MacOS?
Thank you very much!
This can be useful of course, but as I'm having very complex GUIs / dialogs (containing a lot of gadgets, charts, filled listicons which content need to be recalculated after a size change, etc.) I can't and don't want to react to every window width/height change (for only 1 pixel) while the user is still resizing the window.
So I'm searching for a solution, where the GUI/dialog resize function is only called, when the mouse cursor was released and the user's resizing action is finished.
The only releated thread I found is this one: http://www.purebasic.fr/english/viewtop ... vent+mouse
What was called a bug here, is my wanted behaviour
(probably even a feature-request for a new #PB_Event_SizeWindowFinished or similar... )
Currently I have only the idea of a workaround: save the old window size (before resize was started) and don't react to every pixel change, but to every +/- 10 pixel or more...
Anyone has a code example, which works on Windows and MacOS?
Thank you very much!
Re: Window resize event only after mouse release?
Unless I'm missing something, this seems to do what you want:
Code: Select all
If OpenWindow(0, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
Quit = 1
EndIf
If Event = #PB_Event_SizeWindow
Debug "Window resized"
EndIf
Until Quit = 1
EndIf
End
Re: Window resize event only after mouse release?
Works fine with MacOS, Window 7 and windows 10
Code: Select all
Procedure UpdateWindow()
Debug "Update Window"
EndProcedure
Procedure SizeWindowHandler()
Static dx, dy, old_dx, old_dy
Protected delta_dx, delta_dy
dx = WindowWidth(0)
dy = WindowHeight(0)
delta_dx = old_dx - dx
delta_dy = old_dy - dy
If delta_dx < -5 Or delta_dx > 5 Or delta_dy < -5 Or delta_dy > 5
old_dx = dx
old_dy = dy
UpdateWindow()
EndIf
EndProcedure
If OpenWindow(0, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
Quit = 1
EndIf
If Event = #PB_Event_SizeWindow
UpdateWindow()
Debug "Finished Size Window"
EndIf
Until Quit = 1
EndIf
End
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Window resize event only after mouse release?
Workaround
Code: Select all
Procedure SizeCB()
HideWindow(1,1)
EndProcedure
Procedure MoveCB()
ResizeWindow(0,WindowX(1),WindowY(1), #PB_Ignore, #PB_Ignore)
EndProcedure
OpenWindow(0,0,0,800,600,"",#PB_Window_BorderLess |#PB_Window_SizeGadget|#PB_Window_ScreenCentered &~ #PB_Window_TitleBar)
OpenWindow(1,0,0,800,578,"Main window",#PB_Window_SystemMenu |#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered| #PB_Window_Invisible,WindowID(0))
StickyWindow(0,1)
BindEvent(#PB_Event_MoveWindow ,@MoveCB())
BindEvent(#PB_Event_SizeWindow ,@SizeCB())
HideWindow(1,0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Quit = 1
Case #PB_Event_MaximizeWindow
flag = 1
Case #PB_Event_SizeWindow
If flag = 0
ResizeWindow(1,WindowX(0),WindowY(0), WindowWidth(0),WindowHeight(0)-22)
EndIf
If flag = 1
flag = 0
EndIf
HideWindow(1,0)
EndSelect
Until Quit = 1
Egypt my love
- Andre
- PureBasic Team
- Posts: 2071
- Joined: Fri Apr 25, 2003 6:14 pm
- Location: Germany (Saxony, Deutscheinsiedel)
- Contact:
Re: Window resize event only after mouse release?
Thank you for your suggestions, friends!
@wombats: This "normal behaviour" is what I want to avoid, because in this case every change of the window size will be recognized and my "UpdateSize" procedure need to react already during resizing of the window by the user. My goal is to react (at least for some parts of my GUI, see first post) only when the user has finished the resizing (= released the mouse).
@mk-soft: seems to work fine, at least here on Win10 (need to be tested on MacOS too).
@RASHAD: during resizing the hiding/displaying of the second window leads to a mostly hidden titlebar of the main window during resizing. So this workaround would be visible for the user...
Currenty the solution of mk-soft seems the way to go.
With my question I initially hoped, that there isn't needed any workaround, if there would be some additional OS events on Windows/MacOS (not natively supported by PB), which could be used instead of #PB_Event_SizeWindow and which are only fired if the mouse was released by the user (= resizing finished).
So any more ideas are welcome!
@wombats: This "normal behaviour" is what I want to avoid, because in this case every change of the window size will be recognized and my "UpdateSize" procedure need to react already during resizing of the window by the user. My goal is to react (at least for some parts of my GUI, see first post) only when the user has finished the resizing (= released the mouse).
@mk-soft: seems to work fine, at least here on Win10 (need to be tested on MacOS too).
@RASHAD: during resizing the hiding/displaying of the second window leads to a mostly hidden titlebar of the main window during resizing. So this workaround would be visible for the user...
Currenty the solution of mk-soft seems the way to go.
With my question I initially hoped, that there isn't needed any workaround, if there would be some additional OS events on Windows/MacOS (not natively supported by PB), which could be used instead of #PB_Event_SizeWindow and which are only fired if the mouse was released by the user (= resizing finished).
So any more ideas are welcome!
Re: Window resize event only after mouse release?
Hi Andre,
Someone might post script for OSX, so here is a Windows only option:
Someone might post script for OSX, so here is a Windows only option:
Code: Select all
Global lpPrevWndFunc
Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
Select uMsg
Case #WM_ENTERSIZEMOVE : Debug "Start Resize"
Case #WM_EXITSIZEMOVE : Debug "End Resize"
EndSelect
ProcedureReturn CallWindowProc_(lpPrevWndFunc, hWnd, uMsg, wParam, lParam)
EndProcedure
If OpenWindow(0, 0, 0, 500, 400, "Resize Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
lpPrevWndFunc = SetWindowLongPtr_(WindowID(0), #GWL_WNDPROC, @WindowCallback())
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Re: Window resize event only after mouse release?
For all OS and without API (Update)
Code: Select all
;- Top
#TimerSizeWindow = 999
Enumeration #PB_Event_FirstCustomValue
#PB_Event_SizeWindowFinished
EndEnumeration
Procedure UpdateWindow(window, dx, dy)
Debug "Update (window=" + window + ", dx=" + dx + ", dy=" + dy + ")"
EndProcedure
Procedure SizeWindowHandler()
Static old_dx, old_dy, timer, time_dx, time_dy
Protected window, dx, dy, delta_dx, delta_dy
window = EventWindow()
dx = WindowWidth(window)
dy = WindowHeight(window)
Select Event()
Case #PB_Event_SizeWindow
If Not timer
Debug "Add Timer"
timer = #True
AddWindowTimer(window, #TimerSizeWindow, 200)
EndIf
delta_dx = old_dx - dx
delta_dy = old_dy - dy
If delta_dx < -5 Or delta_dx > 5 Or delta_dy < -5 Or delta_dy > 5
old_dx = dx
old_dy = dy
UpdateWindow(window, dx, dy)
EndIf
Case #PB_Event_Timer
If EventTimer() = #TimerSizeWindow
delta_dx = time_dx - dx
delta_dy = time_dy - dy
time_dx = dx
time_dy = dy
If delta_dx = 0 And delta_dy = 0
UpdateWindow(window, dx, dy)
Debug "Remove Timer"
timer = #False
RemoveWindowTimer(window, #TimerSizeWindow)
PostEvent(#PB_Event_SizeWindowFinished, window, 0)
EndIf
EndIf
EndSelect
EndProcedure
If OpenWindow(1, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())
BindEvent(#PB_Event_Timer, @SizeWindowHandler())
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
Quit = 1
EndIf
If Event = #PB_Event_SizeWindowFinished
Debug "Finished SizeWindow"
EndIf
Until Quit = 1
EndIf
End
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Window resize event only after mouse release?
Oh...maybe I'm misunderstanding what you are trying to achieve, then. On my laptop (Windows 10), the debug message in my code is only sent when the mouse is released. Maybe it's different on OS X and Linux...I don't remember. Regardless, that's why I use BindEvent() in my program, as it allows for live resizing.Andre wrote: @wombats: This "normal behaviour" is what I want to avoid, because in this case every change of the window size will be recognized and my "UpdateSize" procedure need to react already during resizing of the window by the user. My goal is to react (at least for some parts of my GUI, see first post) only when the user has finished the resizing (= released the mouse).
There is this code by Shardik.
- Andre
- PureBasic Team
- Posts: 2071
- Joined: Fri Apr 25, 2003 6:14 pm
- Location: Germany (Saxony, Deutscheinsiedel)
- Contact:
Re: Window resize event only after mouse release?
Thank you, guys!
@wombats: I'm also on Win10 here (beside my MacBook). As I'm getting the resize event also during resizing, I came to this question... Thank you anyway for the link to the code example on german PB forum.
@mk-soft: As I'm prefering a solution without API / native PB commands I tried your latest example (on Win10) and it works very well. Thank you very much!
Here this solution again with some small modifications - now there is a Debug output only when the window resizing is finished.
@wombats: I'm also on Win10 here (beside my MacBook). As I'm getting the resize event also during resizing, I came to this question... Thank you anyway for the link to the code example on german PB forum.
@mk-soft: As I'm prefering a solution without API / native PB commands I tried your latest example (on Win10) and it works very well. Thank you very much!
Here this solution again with some small modifications - now there is a Debug output only when the window resizing is finished.
Code: Select all
; http://www.purebasic.fr/english/viewtopic.php?f=13&t=68481
; by mk-soft, small changes by André
;- Top
#TimerSizeWindow = 999
Enumeration #PB_Event_FirstCustomValue
#PB_Event_SizeWindowFinished
EndEnumeration
Procedure UpdateWindow(window, dx, dy)
Debug "Update (window=" + window + ", dx=" + dx + ", dy=" + dy + ")"
EndProcedure
Procedure SizeWindowHandler()
Static old_dx, old_dy, timer, time_dx, time_dy
Protected window, dx, dy, delta_dx, delta_dy
window = EventWindow()
dx = WindowWidth(window)
dy = WindowHeight(window)
Select Event()
Case #PB_Event_SizeWindow
If Not timer
;Debug "Add Timer"
timer = #True
AddWindowTimer(window, #TimerSizeWindow, 200)
EndIf
delta_dx = old_dx - dx
delta_dy = old_dy - dy
If delta_dx < -5 Or delta_dx > 5 Or delta_dy < -5 Or delta_dy > 5
old_dx = dx
old_dy = dy
;UpdateWindow(window, dx, dy)
EndIf
Case #PB_Event_Timer
If EventTimer() = #TimerSizeWindow
delta_dx = time_dx - dx
delta_dy = time_dy - dy
time_dx = dx
time_dy = dy
If delta_dx = 0 And delta_dy = 0
;UpdateWindow(window, dx, dy)
;Debug "Remove Timer"
timer = #False
RemoveWindowTimer(window, #TimerSizeWindow)
PostEvent(#PB_Event_SizeWindowFinished, window, 0)
EndIf
EndIf
EndSelect
EndProcedure
If OpenWindow(1, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())
BindEvent(#PB_Event_Timer, @SizeWindowHandler())
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
Quit = 1
EndIf
If Event = #PB_Event_SizeWindowFinished
Debug "Finished SizeWindow"
Debug "...new window size: " + WindowWidth(1) + "x" + WindowHeight(1)
EndIf
Until Quit = 1
EndIf
End
- Andre
- PureBasic Team
- Posts: 2071
- Joined: Fri Apr 25, 2003 6:14 pm
- Location: Germany (Saxony, Deutscheinsiedel)
- Contact:
Re: Window resize event only after mouse release?
Just to check, if/how several windows can be handled and own window-specific callback functions work, I extended the example of mk-soft a bit further... here is the result, based on this I will try to include it in my project now
Edit 18th June 2017: bug-fix + now there specific BindEvent() resize functions for the 2 windows
Code: Select all
; http://www.purebasic.fr/english/viewtopic.php?f=13&t=68481
; by mk-soft, small changes by André
;- Top
#TimerSizeWindow = 999
Enumeration #PB_Event_FirstCustomValue
#PB_Event_SizeWindowFinished
EndEnumeration
Procedure UpdateWindow(window, dx, dy)
Debug "Update (window=" + window + ", dx=" + dx + ", dy=" + dy + ")"
EndProcedure
Procedure SizeWindowHandler()
Static old_dx, old_dy, timer, time_dx, time_dy
Protected window, dx, dy, delta_dx, delta_dy
window = EventWindow()
dx = WindowWidth(window)
dy = WindowHeight(window)
Select Event()
Case #PB_Event_SizeWindow
If Not timer
;Debug "Add Timer"
timer = #True
AddWindowTimer(window, #TimerSizeWindow, 200)
EndIf
delta_dx = old_dx - dx
delta_dy = old_dy - dy
If delta_dx < -5 Or delta_dx > 5 Or delta_dy < -5 Or delta_dy > 5
old_dx = dx
old_dy = dy
;UpdateWindow(window, dx, dy)
EndIf
Case #PB_Event_Timer
If EventTimer() = #TimerSizeWindow
delta_dx = time_dx - dx
delta_dy = time_dy - dy
time_dx = dx
time_dy = dy
If delta_dx = 0 And delta_dy = 0
;UpdateWindow(window, dx, dy)
;Debug "Remove Timer"
timer = #False
RemoveWindowTimer(window, #TimerSizeWindow)
PostEvent(#PB_Event_SizeWindowFinished, window, 0)
EndIf
EndIf
EndSelect
EndProcedure
Procedure UpdateSize_1stWindow()
Debug "UpdateSize_1stWindow() function reached.... here further action on this specific window can be going on :-)"
Debug " new pos+size: " + WindowX(1) + "," + WindowY(1) + " with " + WindowWidth(1) + "x" + WindowHeight(1)
EndProcedure
Procedure UpdateSize_2ndWindow()
Debug "UpdateSize_2ndWindow() function reached.... here further action on this specific window can be going on :-)"
Debug " new pos+size: " + WindowX(2) + "," + WindowY(2) + " with " + WindowWidth(2) + "x" + WindowHeight(2)
EndProcedure
If OpenWindow(1, 50, 100, 400, 200, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
OpenWindow(2, 470, 300, 400, 200, "PureBasic 2nd Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())
BindEvent(#PB_Event_Timer, @SizeWindowHandler())
BindEvent(#PB_Event_SizeWindowFinished, @UpdateSize_1stWindow(), 1)
BindEvent(#PB_Event_SizeWindowFinished, @UpdateSize_2ndWindow(), 2)
Repeat
Event = WaitWindowEvent()
EventWindow = EventWindow()
If Event = #PB_Event_CloseWindow
Quit = 1
EndIf
; Note: Following code isn't needed, as it's fully covered by the BindEvent() functions!
;If Event = #PB_Event_SizeWindowFinished
; Debug "Finished SizeWindow of window: " + GetWindowTitle(EventWindow)
; Debug "...new window size: " + WindowWidth(EventWindow) + "x" + WindowHeight(EventWindow)
;EndIf
Until Quit = 1
EndIf
End