Resize breaking
#1
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?  Tongue
Reply
#2
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
If eggs are brain food, Biden takes his scrambled.
Reply
#3
(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!"
Reply
#4
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
Reply
#5
(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?  Tongue

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
Reply
#6
@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. Wink

TLDR; It's a resize formula to adjust screen width to perfectly match font width.
Reply
#7
Dang admin said what I wanted to say! Pffftftt!
Reply
#8
(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.
Reply
#9
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
  ' . . .
Reply
#10
(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.
Reply




Users browsing this thread: 7 Guest(s)