Keep a correct ratio for my app window

Just starting out? Need help? Post your questions and find answers here.
wawavoun
User
User
Posts: 38
Joined: Fri Oct 18, 2019 4:49 pm

Keep a correct ratio for my app window

Post by wawavoun »

Hello,

I use a canvas into a window for 2ddrawing operations...

The canvas is resized if the window is resized by the operator. No problem.

Now what is the best way to manage things in order to keep the correct ratio H/W of the window and in turn of the canvas ?

The maths are not the problem.
Into the main loop window event call Mainwindow_Event(Event) located into a the pbf file which in turn call ResizeGadgetsMainWindow() which do some resize of gadgets inside...
I dont want to modify the pbf file because it is autogenerated by the form designer so where and how can I force for example the with of the windows to keep the aspect ratio.

I have try this but then the inside gadgets resizing wont works (like if event was erased)...

Code: Select all

Repeat
;  
  Event = WaitWindowEvent()
  ;
  Select EventWindow()
  ;    
    Case MainWindow
      ;   
      If Event = #PB_Event_SizeWindow
        ResizeWindow(MainWindow, #PB_Ignore, #PB_Ignore, WindowHeight(MainWindow) * 0.75, #PB_Ignore)
      EndIf  
      MainWindow_Events(Event) ; Le nom de la procédure est toujours le nom de la fenêtre suivi de '_Events'
  ;    
  EndSelect
  ;
Until Event = #PB_Event_CloseWindow Or ExitProg = #True; Ferme toutes les fenêtres en quittant l'une d'elle
Thanks.
Philippe
User avatar
jacdelad
Addict
Addict
Posts: 2027
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Keep a correct ratio for my app window

Post by jacdelad »

Here's a code I wrote some time ago (with much help of RADHAD and idle!!!):

Code: Select all

Structure _AR
  Window.i
  Ratio.f
  dx.l
  dy.l
EndStructure
Global NewMap AspectRatioMap._AR()
Procedure AspectRatioCallBack(hwnd,msg,wparam,lparam);
  Protected *rc.rect,w,h  
  Select msg 
    Case #WM_SIZING  
      If FindMapElement(AspectRatioMap(),Str(hwnd))
        *rc = lparam 
        w = *rc\right - *rc\left - AspectRatioMap(Str(hwnd))\dx
        h = *rc\bottom - *rc\top - AspectRatioMap(Str(hwnd))\dy
        Select wparam 
          Case 1;Left
            *rc\bottom = *rc\top + w/AspectRatioMap(Str(hwnd))\Ratio + AspectRatioMap(Str(hwnd))\dy
          Case 2;Right
            *rc\bottom = *rc\top + w/AspectRatioMap(Str(hwnd))\Ratio + AspectRatioMap(Str(hwnd))\dy
          Case 3;Top
            *rc\right = *rc\left + h*AspectRatioMap(Str(hwnd))\Ratio + AspectRatioMap(Str(hwnd))\dx
          Case 6;Bottom
            *rc\right = *rc\left + h*AspectRatioMap(Str(hwnd))\Ratio + AspectRatioMap(Str(hwnd))\dx
          Case 4;Top Left
            If w/AspectRatioMap(Str(hwnd))\Ratio<h
              *rc\top = *rc\bottom - w/AspectRatioMap(Str(hwnd))\Ratio - AspectRatioMap(Str(hwnd))\dy
            Else
              *rc\left = *rc\right - h*AspectRatioMap(Str(hwnd))\Ratio - AspectRatioMap(Str(hwnd))\dx
            EndIf
          Case 7;Bottom Left 
            If w/AspectRatioMap(Str(hwnd))\Ratio<h
              *rc\bottom = *rc\top + w/AspectRatioMap(Str(hwnd))\Ratio + AspectRatioMap(Str(hwnd))\dy
            Else
              *rc\left = *rc\right - h*AspectRatioMap(Str(hwnd))\Ratio - AspectRatioMap(Str(hwnd))\dx
            EndIf
          Case 5;Top Right
            If w/AspectRatioMap(Str(hwnd))\Ratio<h
              *rc\top = *rc\bottom - w/AspectRatioMap(Str(hwnd))\Ratio - AspectRatioMap(Str(hwnd))\dy
            Else
              *rc\right = *rc\left + h*AspectRatioMap(Str(hwnd))\Ratio + AspectRatioMap(Str(hwnd))\dx
            EndIf
          Case 8;Bottom Right  
            If w/AspectRatioMap(Str(hwnd))\Ratio<h
              *rc\bottom = *rc\top + w/AspectRatioMap(Str(hwnd))\Ratio + AspectRatioMap(Str(hwnd))\dy
            Else
              *rc\right = *rc\left + h*AspectRatioMap(Str(hwnd))\Ratio + AspectRatioMap(Str(hwnd))\dx
            EndIf
        EndSelect
      EndIf
  EndSelect 
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure SetWindowAspectRatio(Window,Enable=#True)
  Protected rect.rect,WindowID=WindowID(Window)
  If Enable
    GetWindowRect_(WindowID(Window),rect)
    AspectRatioMap(Str(WindowID))\Window=Window
    AspectRatioMap(Str(WindowID))\Ratio=WindowWidth(Window,#PB_Window_InnerCoordinate)/WindowHeight(Window,#PB_Window_InnerCoordinate)
    AspectRatioMap(Str(WindowID))\dy=rect\bottom-rect\top-WindowHeight(Window,#PB_Window_InnerCoordinate)
    AspectRatioMap(Str(WindowID))\dx=rect\right-rect\left-WindowWidth(Window,#PB_Window_InnerCoordinate)
    SetWindowCallback(@AspectRatioCallBack(),Window)
  Else
    If FindMapElement(AspectRatioMap(),Str(WindowID))
      SetWindowCallback(0,AspectRatioMap(Str(WindowID))\Window)
      DeleteMapElement(AspectRatioMap(),Str(WindowID))
    EndIf
  EndIf
EndProcedure
Procedure WindowBoundsEx(Window,minx,miny,maxx,maxy)
  Protected WindowID=WindowID(Window)
  If FindMapElement(AspectRatioMap(),Str(WindowID))
    If minx<>#PB_Ignore Or miny<>#PB_Ignore
      If minx<>#PB_Ignore And miny<>#PB_Ignore
        If miny*AspectRatioMap(Str(WindowID))\Ratio>minx:minx=miny*AspectRatioMap(Str(WindowID))\Ratio:EndIf
        If minx/AspectRatioMap(Str(WindowID))\Ratio>miny:miny=minx/AspectRatioMap(Str(WindowID))\Ratio:EndIf
      ElseIf minx=#PB_Ignore
        minx=miny/AspectRatioMap(Str(WindowID))\Ratio
      ElseIf miny=#PB_Ignore
        miny=minx*AspectRatioMap(Str(WindowID))\Ratio
      EndIf
    EndIf
    If maxx<>#PB_Ignore Or maxy<>#PB_Ignore
      If maxx<>#PB_Ignore And maxy<>#PB_Ignore
        If maxy*AspectRatioMap(Str(WindowID))\Ratio<maxx:maxx=maxy*AspectRatioMap(Str(WindowID))\Ratio:EndIf
        If maxx/AspectRatioMap(Str(WindowID))\Ratio<maxy:maxy=maxx/AspectRatioMap(Str(WindowID))\Ratio:EndIf
      ElseIf maxx=#PB_Ignore
        maxx=maxy/AspectRatioMap(Str(WindowID))\Ratio
      ElseIf maxy=#PB_Ignore
        maxy=maxx*AspectRatioMap(Str(WindowID))\Ratio
      EndIf
    EndIf
  EndIf
  WindowBounds(Window,minx,miny,maxx,maxy)
EndProcedure
Macro WindowBounds(window,minx,miny,maxx,maxy)
  WindowBoundsEx(window,minx,miny,maxx,maxy)
EndMacro

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit 
  OpenWindow(0,0,0,250,250,"Test",#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_SizeGadget)
  SetWindowAspectRatio(0,1)
  WindowBounds(0,#PB_Ignore,200,1200,900)
  Repeat
  Until WaitWindowEvent()=#PB_Event_CloseWindow
CompilerEndIf
http://forums.purebasic.com/english/vie ... c9#p598883

After resizing your window you just have to adapt your canvas to the new window size and redraw your content.
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
wawavoun
User
User
Posts: 38
Joined: Fri Oct 18, 2019 4:49 pm

Re: Keep a correct ratio for my app window

Post by wawavoun »

Thanks,

Its a huge piece of code for something looking simple (but sometime looking simple doesn't mean simple).

So I modify my question : what is the simplest way to do that (I dont care about flicker etc...) ?

Regards.
Philippe
User avatar
jacdelad
Addict
Addict
Posts: 2027
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Keep a correct ratio for my app window

Post by jacdelad »

I think this is the simplest way. You call one function to set the aspect ratio and the rest is done "by itself". A few lines of code shouldn't worry you.
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4984
Joined: Sun Apr 12, 2009 6:27 am

Re: Keep a correct ratio for my app window

Post by RASHAD »

Hi wawavoun
It's a complicated task
jacdelad did it in a very professional way
The simplest way is to use The Mouse Wheel

Code: Select all

If OpenWindow(0, 0, 0, 600, 400, "Canvas container example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  CanvasGadget(0, 10, 10, 580, 360, #PB_Canvas_Container)
  ButtonGadget(1, 10, 10, 80, 30, "Clean up")
  CloseGadgetList()
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case  #PB_Event_Gadget
        Select EventGadget() 
          Case 0
            Select EventType()
              Case #PB_EventType_MouseWheel
                Value.f = GetGadgetAttribute(0,#PB_Canvas_WheelDelta )
                If value > 0                  
                  ResizeWindow(0,#PB_Ignore,#PB_Ignore,WindowWidth(0)*1.05,WindowHeight(0)*1.05)
                Else
                  ResizeWindow(0,#PB_Ignore,#PB_Ignore,WindowWidth(0)/1.05,WindowHeight(0)/1.05)
                EndIf                  
                HideWindow(0,0,#PB_Window_ScreenCentered)                  
                ResizeGadget(0,10,10,WindowWidth(0)-20,WindowHeight(0)-40)
            EndSelect
        EndSelect
    EndSelect    
  Until Quit = 1
EndIf

Egypt my love
Post Reply