Display Scale module

Share your advanced PureBasic knowledge/code with the community.
User avatar
idle
Always Here
Always Here
Posts: 6095
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Display Scale module

Post by idle »

Helper module for DPI aware windows

note I will eventually make a seamless inline C patch so your code won't need any changes at all apart from a usemodule but for now you either need to use the functions as declared or prefix them with the module name.

Assumes you use callbacks to size your gadgets and the like see test code

compile as console so debug output is shown in case pb debugger goes off screen when you change scale
should open up a window 800*600 with 4 buttons 60*30 in the corners all coordinates should be reported as
native display resolutions.

Code: Select all

DeclareModule DSX 
  ;Display Scale Module aims to take care of display scale automatically 
  ;By idle 2/4/23
  ;licence MIT 
  ;Functions can be called as theyre declared or by the prototypes but you need to prefix them with module name DSX::
  ;or it will call the PB functions  
    
  Declare _OpenWindow(window,x,y,InnerWidth,InnerHeight,Title$,flags=0,ParentID=0)
  Declare _OpenWindowedScreen(windowid,x,y,width,height,autostretch=#True,rightoffset=0,bottomoffset=0,flipmode=#PB_Screen_WaitSynchronization )
  Declare _ResizeWindow(window,x,y,Width,Height)
  Declare _WindowBounds(window,MinimumWidth,MinimumHeight,MaximumWidth,MaximumHeight)
  Declare _WindowWidth(window,mode=#PB_Window_InnerCoordinate)
  Declare _WindowHeight(Window,Mode=#PB_Window_InnerCoordinate) 
  Declare _WindowMouseX(Window)
  Declare _WindowMouseY(Window)
  Declare _WindowX(Window)
  Declare _WindowY(Window)
  Declare _ResizeGadget(gadget,x,y,w,h) 
  Declare _GadgetWidth(gadget) 
  Declare _GadgetHeight(gadget) 
  Declare _GadgetX(gadget) 
  Declare _GadgetY(gadget)  
  
  Prototype pOpenWindow(window,x,y,InnerWidth,InnerHeight,Title$,flags=0,ParentID=0)
  Global OpenWindow.pOpenWindow = @_OpenWindow() 
  Prototype pOpenWindowedScreen(windowid,x,y,width,height,autostretch=#True,rightoffset=0,bottomoffset=0,flipmode=#PB_Screen_WaitSynchronization )
  Global OpenWindowedScreen.pOpenWindowedScreen = @_OpenWindowedScreen() 
  Prototype pResizeWindow(window,x,y,Width,Height)
  Global ResizeWindow.pResizeWindow = @_ResizeWindow() 
  Prototype pWindowBounds(window,MinimumWidth,MinimumHeight,MaximumWidth,MaximumHeight) 
  Global WindowBounds.pWindowBounds = @_WindowBounds() 
  Prototype pWindowWidth(window,mode=#PB_Window_InnerCoordinate) 
  Global WindowWidth.pWindowWidth = @_WindowWidth() 
  Prototype pWindowHeight(Window,Mode=#PB_Window_InnerCoordinate) 
  Global WindowHeight.pWindowHeight = @_WindowHeight() 
  Prototype pWindowMouseX(Window)
  Global WindowMouseX.pWindowMouseX = @_WindowMouseX()
  Prototype pWindowMouseY(Window)
  Global WindowMouseY.pWindowMouseY = @_WindowMouseY() 
  Prototype pWindowX(Window)
  Global WindowX.pWindowX = @_WindowX() 
  Prototype pWindowY(Window) 
  Global WindowY.pWindowY = @_WindowY()
  Prototype pResizeGadget(gadget,x,y,w,h) 
  Global ResizeGadget.pResizeGadget  = @_ResizeGadget() 
  Prototype pGadgetWidth(gadget) 
  Global GadgetWidth.pGadgetWidth = @_GadgetWidth()
  Prototype pGadgetHeight(gadget) 
  Global GadgetHeight.pGadgetHeight = @_GadgetHeight()
  Prototype pGadgetX(gadget) 
  Global GadgetX.pGadgetX = @_GadgetX() 
  Prototype pGadgetY(gadget) 
  Global GadgetY.pGadgetY = @_GadgetY() 
  
EndDeclareModule   

Module DSX 
  
  Global gsx.d,gsy.d,gsxI.d,gsyI.d 
  gsx = DesktopResolutionX()
  gsy = DesktopResolutionY()
  gsxI = 1.0 / gsx 
  gsyI = 1.0 / gsy 
  ExamineDesktops() 
  
  Procedure _OpenWindow(window,x,y,InnerWidth,InnerHeight,Title$,flags=0,ParentID=0)
    OpenWindow(window,x*gsxI,y*gsyI,InnerWidth*gsxI,InnerHeight*gsyI,Title$,flags,ParentID)
  EndProcedure   
  Procedure _OpenWindowedScreen(windowid,x,y,width,height,autostretch=#True,rightoffset=0,bottomoffset=0,flipmode=#PB_Screen_WaitSynchronization)
    OpenWindowedScreen(windowid,x*gsxi,y*gsyi,width*gsxi,height*gsyi,autostretch,rightoffset,bottomoffset,flipmode)
  EndProcedure   
  Procedure _ResizeWindow(window,x,y,Width,Height)
    ProcedureReturn ResizeWindow(window,x*gsxI,y*gsyI,Width*gsxI,Height*gsyI)
  EndProcedure    
  Procedure _WindowBounds(window,MinimumWidth,MinimumHeight,MaximumWidth,MaximumHeight)
    ProcedureReturn WindowBounds(window,MinimumWidth*gsxi,MinimumHeight*gsyi,MaximumWidth*gsxi,MaximumHeight*gsyi)
  EndProcedure   
  Procedure _WindowWidth(window,mode=#PB_Window_InnerCoordinate)
    ProcedureReturn WindowWidth(window,mode)*gsx 
  EndProcedure  
  Procedure _WindowHeight(Window,Mode=#PB_Window_InnerCoordinate) 
    ProcedureReturn WindowHeight(Window,Mode)*gsx 
  EndProcedure  
  Procedure _WindowMouseX(Window)
    ProcedureReturn WindowMouseX(Window)
  EndProcedure
  Procedure _WindowMouseY(Window)
    ProcedureReturn WindowMouseY(Window) 
  EndProcedure 
  Procedure _WindowX(Window)
    ProcedureReturn (WindowX(Window)*gsx)
  EndProcedure 
  Procedure _WindowY(Window)
    ProcedureReturn(WindowY(Window)*gsy)
  EndProcedure 
  Procedure _ResizeGadget(gadget,x,y,w,h) 
    ProcedureReturn ResizeGadget(gadget,x*gsxI,y*gsyI,w*gsxI,h*gsyI) 
  EndProcedure   
  Procedure _GadgetWidth(gadget) 
    ProcedureReturn GadgetWidth(gadget)*gsx 
  EndProcedure 
  Procedure _GadgetHeight(gadget) 
    ProcedureReturn GadgetHeight(gadget)*gsy 
  EndProcedure   
  Procedure _GadgetX(gadget) 
    ProcedureReturn GadgetX(gadget)*gsx 
  EndProcedure  
  Procedure _GadgetY(gadget) 
    ProcedureReturn GadgetY(gadget)*gsy 
  EndProcedure   
  
EndModule 

CompilerIf #PB_Compiler_IsMainFile  
 
UseModule DSX

Procedure OnMove() 
  PrintN("window sx " + Str(DSX::WindowX(EventWindow())) + " sy " + Str(DSX::WindowY(EventWindow())))  
EndProcedure 

Procedure OnSize() 
  Protected win 
  win = EventWindow() 
  PrintN("window swidth " + Str(DSX::WindowWidth(win)) + " sheight "  + Str(DSX::WindowHeight(win))) 
  DSX::ResizeGadget(1,5,5,60,30) 
  DSX::ResizeGadget(2,DSX::WindowWidth(win)-65,5,60,30) 
  DSX::ResizeGadget(3,DSX::WindowWidth(win)-65,DSX::WindowHeight(win)-35,60,30) 
  DSX::ResizeGadget(4,5,DSX::WindowHeight(win)-35,60,30) 
EndProcedure   

Procedure OnLeftClick() 
  Protected win 
  
  win = EventWindow() 
  Static pos 
  PrintN("mouse sx " +  Str(DSX::WindowMouseX(win)) + " sy " + Str(DSX::WindowMouseY(win))) ;mouse coords are scaled 
  Select pos  
    Case 0 
      DSX::ResizeWindow(win,0,0,DSX::WindowWidth(win),DSX::WindowHeight(win)) 
    Case 1 
      DSX::ResizeWindow(win, DesktopWidth(0)-DSX::WindowWidth(win),0,DSX::WindowWidth(win),DSX::WindowHeight(win))  
    Case 2 
      DSX::ResizeWindow(win,DesktopWidth(0)-DSX::WindowWidth(win),DesktopHeight(0)-DSX::WindowHeight(win),DSX::WindowWidth(win),DSX::WindowHeight(win)) 
    Case 3 
      DSX::ResizeWindow(win,0,DesktopHeight(0)-DSX::WindowHeight(win),DSX::WindowWidth(win),DSX::WindowHeight(win))    
  EndSelect 
  pos + 1 
  pos % 4 
  
EndProcedure 

Procedure OnButtonclick() 
  gad = EventGadget() 
  PrintN("button " + GetGadgetText(gad) + " width " + DSX::GadgetWidth(gad) + " height " + DSX::GadgetHeight(gad)) 
  PrintN("button " + GetGadgetText(gad) + " x " + DSX::GadgetX(gad) + " y " + DSX::GadgetY(gad)) 
EndProcedure   

OpenConsole()
PrintN( "SX = " + StrD(gsx) + " SY = " + StrD(gsy))

flags = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_SizeGadget

DSX::OpenWindow(0,0,0,800,600,"scale test", Flags)
DSX::WindowBounds(0,135,70,#PB_Ignore,#PB_Ignore) 

BindEvent(#PB_Event_MoveWindow,@OnMove()) 
BindEvent(#PB_Event_SizeWindow,@OnSize()) 
BindEvent(#PB_Event_LeftClick,@OnLeftClick())

ButtonGadget(1,0,0,60,30,"But1") 
BindGadgetEvent(1, @OnButtonclick())
ButtonGadget(2,0,0,60,30,"But2") 
BindGadgetEvent(2, @OnButtonclick())
ButtonGadget(3,0,0,60,30,"But3")
BindGadgetEvent(3, @OnButtonclick())
ButtonGadget(4,0,0,60,30,"But4") 
BindGadgetEvent(4, @OnButtonclick())

OnSize() 

InitSprite() 
InitMouse()
InitKeyboard() 

Global gEvent,px,py,vx.f=1.5,vy.f=1.5 

If OpenWindowedScreen(WindowID(0),0,0,DesktopWidth(0),DesktopHeight(0))
  CreateSprite(0, 20, 20)
  If StartDrawing(SpriteOutput(0))
    Box(0, 0, 20, 20, RGB(255, 0, 155))
    Box(5, 5, 10, 10, RGB(155, 0, 255))
    StopDrawing()
  EndIf
  ReleaseMouse(#True) 
  
  Repeat  
    Repeat 
      gEvent = WindowEvent() 
      Select gEvent 
        Case #PB_Event_CloseWindow
          End 
      EndSelect
    Until gEvent = 0
    
    ExamineKeyboard() 
        
    If PX < 0 : vx = -vx : px = 0 : ElseIf px > DSX::WindowWidth(0)-20 : px = DSX::WindowWidth(0)-20 : vx = -vx : EndIf 
    If PY < 0 : vy = -vy : py = 0 : ElseIf py > DSX::WindowHeight(0)-20 : py = DSX::WindowHeight(0)-20 : vy = -vy : EndIf 
    px + vx 
    py + vy 
    ClearScreen($F0f0f0) 
    DisplaySprite(0,px,py) 
    FlipBuffers() 
    
  Until KeyboardPushed(#PB_Key_Escape)  
  
EndIf  
   
    
CompilerEndIf 

User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5526
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Display Scale module

Post by Kwai chang caine »

Great works :shock:
I don't know all possibility, but apparently that works here, with resize and move the window :wink:
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
Post Reply