Resize breaking - SMcNeill - 08-01-2022
An example of some code which I'm having issues with, which may be a glitch in QB64, or might be a glitch in poor Steve. I thought I'd post it here to share so others could test it out and see what's wrong with it.
Code: (Select All) 'Set compiler and global progeam options
'All variables and arrays are dynamic by default
'$Dynamic
'Allow the screen to be resized, but handle operations manually.
$Resize:On
'Allow the use of color names for 32-bit screen mode
$Color:32
_Define A-Z As LONG 'default variable type is long
_Title "Test Glitch"
'Types and global variables
Dim Shared As Long ScreenWidth, ScreenHeight, DisplayScreen, WorkScreen, ReDrawScreen
Dim Shared As Long Font(10), FontSize
'Defaut vaues for global variables
ScreenWidth = 1280
ScreenHeight = 720
DisplayScreen = _NewImage(1024, 720, 32)
WorkScreen = _NewImage(1024, 32000, 32)
ReDrawScreen = 0
Font(0) = _LoadFont("courbd.ttf", 6, "monospace")
Font(1) = _LoadFont("courbd.ttf", 8, "monospace")
Font(2) = _LoadFont("courbd.ttf", 10, "monospace")
Font(3) = _LoadFont("courbd.ttf", 12, "monospace")
Font(4) = _LoadFont("courbd.ttf", 14, "monospace")
Font(5) = _LoadFont("courbd.ttf", 16, "monospace")
Font(6) = _LoadFont("courbd.ttf", 18, "monospace")
Font(7) = _LoadFont("courbd.ttf", 22, "monospace")
Font(8) = _LoadFont("courbd.ttf", 28, "monospace")
Font(9) = _LoadFont("courbd.ttf", 36, "monospace")
Font(10) = _LoadFont("courbd.ttf", 48, "monospace")
FontSize = 8 'starting font size
Screen DisplayScreen
_Delay .2
_Dest WorkScreen
_Font Font(FontSize)
clearFlag = _Resize
Do
AutoResize
Cls , 0
Print _Width(DisplayScreen), _Height(DisplayScreen)
_PutImage , WorkScreen, DisplayScreen, (0, 0)-Step(_Width(DisplayScreen), _Height(DisplayScreen))
_Limit 60
_Display
Loop
Sub AutoResize
Static OldFontSize
W = _Width(DisplayScreen): H = _Height(DisplayScreen)
FW = _FontWidth: FH = _FontHeight
If _Resize Then
Do
_Delay .1
Loop Until _Resize = 0 'wait for the user to finish their resize event
RW = _ResizeWidth: RH = _ResizeHeight
If RW < 640 Then RW = 640
If RW > _DesktopWidth Then RW = _DesktopWidth
If RH < 400 Then RH = 400
If RH > _DesktopHeight Then RH = _DesktopHeight
GoTo resize_event
End If
If OldFontSize <> FontSize Then
RW = W: RH = H
GoTo resize_event
End If
Exit Sub
resize_event:
RW = (RW \ FW) * FW
RH = (RH \ FH) * FH
tempscreen = _NewImage(RW, 32000, 32) 'create the newly sized WorkScreen
_Dest tempscreen 'can't freeimage a screen if it's in use?
_FreeImage WorkScreen 'free the old WorkScreen
WorkScreen = tempscreen
_Dest WorkScreen
_Font Font(FontSize)
tempscreen = _NewImage(RW, RH, 32)
Screen tempscreen
_FreeImage DisplayScreen
DisplayScreen = tempscreen
OldFontSize = FontSize
ReDrawScreen = -1
Do
_Delay .1
Loop Until _Resize = 0
End Sub
Now, at the moment, this doesn't do much except print the width and height of the screen for us. Generally, it works as it should, with one exception -- if we drag the size below the minimum bounds set by the program (640x400).
The first time we snap below 640 width, the program does as it should and resizes back up to 640.
If we then grab it and resize it down below 640 width a second time, the screen loses that snap-ability and refuses to resize. Oddest thing however, is that it still reports itself as being 640 wide, even when it's obviously not.
I've no clue where the glitch is in the matrix on this one!
To add to the oddness, you can then drag the width back to the right a few times, and pass that 640 mark, and after a few attempts, the resize routine will start working just peachy fine again -- as long as you don't go below the 640 limit.
So what's the glitch here guys? Is QB64 doing something oddish, or is it just me with a broken head?
RE: Resize breaking - Pete - 08-01-2022
I think I noticed this problem several years ago with a resize project I was working on. The window would never fail but occasionally fail to snap back. I can't recall if I made a work around or just left it alone. Too long ago for me to remember what the project was or what I named it.
Pete
RE: Resize breaking - SMcNeill - 08-01-2022
(08-01-2022, 07:19 PM)Pete Wrote: I think I noticed this problem several years ago with a resize project I was working on. The window would never fail but occasionally fail to snap back. I can't recall if I made a work around or just left it alone. Too long ago for me to remember what the project was or what I named it.
Pete
Aye. Seems like the snap back is what breaks it. It'll resize properly once if you go below 640 width, but then if you try it a second time, it just gives up and says, "Fine! Have it your way, you big meanie!"
RE: Resize breaking - SMcNeill - 08-01-2022
A simpler demo of the resize breaking:
Code: (Select All) Screen _NewImage(1024, 720, 32)
$Resize:On
_Delay .2: clearFlag = _Resize 'Comment this line out and watch as _RESIZE triggers with our initial screen creation event
Do
If _Resize Then
RW = _ResizeWidth: RH = _ResizeHeight
If RW < 640 Then RW = 640
d = _Display
Screen _NewImage(RW, RH, 32)
_FreeImage d
' _Delay .2: clearFlag = _Resize 'if it's needed above, it should be needed hear to clear our manual resize
Print _Width, _Height, RW, RH
End If
_Limit 30
Loop
RE: Resize breaking - TempodiBasic - 08-01-2022
(08-01-2022, 07:01 PM)SMcNeill Wrote: An example of some code which I'm having issues with, which may be a glitch in QB64, or might be a glitch in poor Steve. I thought I'd post it here to share so others could test it out and see what's wrong with it.
Code: (Select All) 'Set compiler and global progeam options
'All variables and arrays are dynamic by default
'$Dynamic
'Allow the screen to be resized, but handle operations manually.
$Resize:On
'Allow the use of color names for 32-bit screen mode
$Color:32
_Define A-Z As LONG 'default variable type is long
_Title "Test Glitch"
'Types and global variables
Dim Shared As Long ScreenWidth, ScreenHeight, DisplayScreen, WorkScreen, ReDrawScreen
Dim Shared As Long Font(10), FontSize
'Defaut vaues for global variables
ScreenWidth = 1280
ScreenHeight = 720
DisplayScreen = _NewImage(1024, 720, 32)
WorkScreen = _NewImage(1024, 32000, 32)
ReDrawScreen = 0
Font(0) = _LoadFont("courbd.ttf", 6, "monospace")
Font(1) = _LoadFont("courbd.ttf", 8, "monospace")
Font(2) = _LoadFont("courbd.ttf", 10, "monospace")
Font(3) = _LoadFont("courbd.ttf", 12, "monospace")
Font(4) = _LoadFont("courbd.ttf", 14, "monospace")
Font(5) = _LoadFont("courbd.ttf", 16, "monospace")
Font(6) = _LoadFont("courbd.ttf", 18, "monospace")
Font(7) = _LoadFont("courbd.ttf", 22, "monospace")
Font(8) = _LoadFont("courbd.ttf", 28, "monospace")
Font(9) = _LoadFont("courbd.ttf", 36, "monospace")
Font(10) = _LoadFont("courbd.ttf", 48, "monospace")
FontSize = 8 'starting font size
Screen DisplayScreen
_Delay .2
_Dest WorkScreen
_Font Font(FontSize)
clearFlag = _Resize
Do
AutoResize
Cls , 0
Print _Width(DisplayScreen), _Height(DisplayScreen)
_PutImage , WorkScreen, DisplayScreen, (0, 0)-Step(_Width(DisplayScreen), _Height(DisplayScreen))
_Limit 60
_Display
Loop
Sub AutoResize
Static OldFontSize
W = _Width(DisplayScreen): H = _Height(DisplayScreen)
FW = _FontWidth: FH = _FontHeight
If _Resize Then
Do
_Delay .1
Loop Until _Resize = 0 'wait for the user to finish their resize event
RW = _ResizeWidth: RH = _ResizeHeight
If RW < 640 Then RW = 640
If RW > _DesktopWidth Then RW = _DesktopWidth
If RH < 400 Then RH = 400
If RH > _DesktopHeight Then RH = _DesktopHeight
GoTo resize_event
End If
If OldFontSize <> FontSize Then
RW = W: RH = H
GoTo resize_event
End If
Exit Sub
resize_event:
RW = (RW \ FW) * FW
RH = (RH \ FH) * FH
tempscreen = _NewImage(RW, 32000, 32) 'create the newly sized WorkScreen
_Dest tempscreen 'can't freeimage a screen if it's in use?
_FreeImage WorkScreen 'free the old WorkScreen
WorkScreen = tempscreen
_Dest WorkScreen
_Font Font(FontSize)
tempscreen = _NewImage(RW, RH, 32)
Screen tempscreen
_FreeImage DisplayScreen
DisplayScreen = tempscreen
OldFontSize = FontSize
ReDrawScreen = -1
Do
_Delay .1
Loop Until _Resize = 0
End Sub
Now, at the moment, this doesn't do much except print the width and height of the screen for us. Generally, it works as it should, with one exception -- if we drag the size below the minimum bounds set by the program (640x400).
The first time we snap below 640 width, the program does as it should and resizes back up to 640.
If we then grab it and resize it down below 640 width a second time, the screen loses that snap-ability and refuses to resize. Oddest thing however, is that it still reports itself as being 640 wide, even when it's obviously not.
I've no clue where the glitch is in the matrix on this one!
To add to the oddness, you can then drag the width back to the right a few times, and pass that 640 mark, and after a few attempts, the resize routine will start working just peachy fine again -- as long as you don't go below the 640 limit.
So what's the glitch here guys? Is QB64 doing something oddish, or is it just me with a broken head?
Hi Steve
you show me another fine Keyword of QB64!
However running your first code (this above) I see that both resizing in horizontal both in vertical the measurement of width and height of window
stands as minimum 640 for width and 400 for height.
but it seems to me the right effect of these lines of code
Code: (Select All) RW = _ResizeWidth: RH = _ResizeHeight
If RW < 640 Then RW = 640
If RW > _DesktopWidth Then RW = _DesktopWidth
If RH < 400 Then RH = 400
If RH > _DesktopHeight Then RH = _DesktopHeight
while I am not able to understand why do you divide and multiply a number with the same value here...
Code: (Select All) resize_event:
RW = (RW \ FW) * FW
RH = (RH \ FH) * FH
for example if FW = 5 then RW = (RW\ 5) * 5...the same thing I can think about FH...
sorry for dummy question...
waiting feedback
RE: Resize breaking - admin - 08-01-2022
@TempodiBasic Good Question! Let me take a moment to explain:
RW = (RW \ FW) * FH
As you say, it appears as if I'm simply dividing and multiplying the same number here -- yet, if you try it, you get back a different value from the original!
WHY?? Is it an artifact from floating point arithmetic? Is it something else? Just WHY the heck would anyone code something silly like the above??
****************
Keep in mind, we have 2 division operators in QB64 -- / and \.
/ is division.
\ is integer division.
So, in this case, what we're saying is basically:
RW = INT (RW / FW) * FW
The purpose here is easy to understand with a few actual numbers at work...
The user resizes the screen to 1608 pixels wide.
The font is 16 pixels wide.
With the above, we recalculate the width to become:
(RW \ FW) * FW
(1608 \ 16) * 16
100 * 16
1600
We just adjusted the width to 1600 pixels instead of 1608 pixels. We now can print 100 characters on a line, without having 8 pixels on the right that we'd either ignore, or only be able to print half a character on afterwards.
TLDR; It's a resize formula to adjust screen width to perfectly match font width.
RE: Resize breaking - SMcNeill - 08-01-2022
Dang admin said what I wanted to say! Pffftftt!
RE: Resize breaking - TempodiBasic - 08-01-2022
(08-01-2022, 07:49 PM)SMcNeill Wrote: A simpler demo of the resize breaking:
Code: (Select All) Screen _NewImage(1024, 720, 32)
$Resize:On
_Delay .2: clearFlag = _Resize 'Comment this line out and watch as _RESIZE triggers with our initial screen creation event
Do
If _Resize Then
RW = _ResizeWidth: RH = _ResizeHeight
If RW < 640 Then RW = 640
d = _Display
Screen _NewImage(RW, RH, 32)
_FreeImage d
' _Delay .2: clearFlag = _Resize 'if it's needed above, it should be needed hear to clear our manual resize
Print _Width, _Height, RW, RH
End If
_Limit 30
Loop
About this demo...
it is clear that the QB64's keyword _RESIZE (function) works like _MOUNSEINPUT activating _ResizeWidth and _ResizeHeight...
so these last functions refresh their values only if a _RESIZE call has been done before them.
....
as the code has been written the user cannot resize the window width under 640 pixels....but the real width is 120 while for height there i s low limit, so if you drag title bar beyond the lower edge of the window, it crashes.
RE: Resize breaking - Kernelpanic - 08-01-2022
Interesting. I can't say anything about what the admin wrote because I don't have the knowledge.
I've looked at the specs when the window is reduced in size and I see the data doesn't update from 640 X 400 onwards. But I couldn't find where this error is.
I only have a guess. Here "Print" gets something wrong transmitted:
Print _Width(DisplayScreen), _Height(DisplayScreen)
Code: (Select All) Do
AutoResize
Cls , 0
Print _Width(DisplayScreen), _Height(DisplayScreen)
_PutImage , WorkScreen, DisplayScreen, (0, 0)-Step(_Width(DisplayScreen), _Height(DisplayScreen))
_Limit 60
_Display
Loop
Sub AutoResize
Static OldFontSize
W = _Width(DisplayScreen): H = _Height(DisplayScreen)
FW = _FontWidth: FH = _FontHeight
'And so on
' . . .
RE: Resize breaking - SMcNeill - 08-01-2022
(08-01-2022, 10:07 PM)TempodiBasic Wrote: (08-01-2022, 07:49 PM)SMcNeill Wrote: A simpler demo of the resize breaking:
Code: (Select All) Screen _NewImage(1024, 720, 32)
$Resize:On
_Delay .2: clearFlag = _Resize 'Comment this line out and watch as _RESIZE triggers with our initial screen creation event
Do
If _Resize Then
RW = _ResizeWidth: RH = _ResizeHeight
If RW < 640 Then RW = 640
d = _Display
Screen _NewImage(RW, RH, 32)
_FreeImage d
' _Delay .2: clearFlag = _Resize 'if it's needed above, it should be needed hear to clear our manual resize
Print _Width, _Height, RW, RH
End If
_Limit 30
Loop
About this demo...
it is clear that the QB64's keyword _RESIZE (function) works like _MOUNSEINPUT activating _ResizeWidth and _ResizeHeight...
so these last functions refresh their values only if a _RESIZE call has been done before them.
....
as the code has been written the user cannot resize the window width under 640 pixels....but the real width is 120 while for height there i s low limit, so if you drag title bar beyond the lower edge of the window, it crashes.
If you want a working demo, try this one: https://staging.qb64phoenix.com/showthread.php?tid=676
The issue here comes from setting a limit to the resize field, though I have no idea why.
|