Page 1 of 1

[CrossPlatform] Resizable borderless window

Posted: Tue Sep 27, 2016 9:19 am
by Peyman
i try to create a resizable borderless window for all platform with canvas, I wrote left, right, top and bottom borders resizing algorithm so now what about corners ? some body can help me for this ?

thx

Code: Select all

Enumeration
  #UP_FRAME
  #BOTOM_FRAME
  #LEFT_FRAME
  #RIGHT_FRAME
  #CAPTION_FRAME
EndEnumeration

#BORDER_SIZE = 10
#BORDER_COLOR = 15707194
#CAPTION_COLOR = #Black
#CAPTION_SIZE = 30
#BACKGROUND_COLOR = #White
#MINIMUM_WIDTH = 200
#MINIMUM_HEIGHT = 100
#CORNERS_SIZE = 8

Procedure DrawCanvas()
  
  ; Resize Borders
  ResizeGadget(#UP_FRAME, #PB_Ignore, #PB_Ignore, WindowWidth(0), #PB_Ignore)
  ResizeGadget(#RIGHT_FRAME, WindowWidth(0) - #BORDER_SIZE, #PB_Ignore, WindowWidth(0), WindowHeight(0) - #BORDER_SIZE * 2)
  ResizeGadget(#BOTOM_FRAME, #PB_Ignore, WindowHeight(0) - #BORDER_SIZE, WindowWidth(0), #PB_Ignore)
  ResizeGadget(#LEFT_FRAME, #PB_Ignore, #PB_Ignore, #PB_Ignore, WindowHeight(0) - #BORDER_SIZE * 2)
  
  ; Resize Caption
  ResizeGadget(#CAPTION_FRAME, #PB_Ignore, #PB_Ignore, WindowWidth(0) - #BORDER_SIZE * 2, #PB_Ignore)
  
  
  StartDrawing(CanvasOutput(#UP_FRAME))
    Box(0, 0, GadgetWidth(#UP_FRAME), GadgetHeight(#UP_FRAME), #BORDER_COLOR)
  StopDrawing()
  
  StartDrawing(CanvasOutput(#RIGHT_FRAME))
    Box(0, 0, GadgetWidth(#RIGHT_FRAME), GadgetHeight(#RIGHT_FRAME), #BORDER_COLOR)
  StopDrawing()
    
  StartDrawing(CanvasOutput(#BOTOM_FRAME))
    Box(0, 0, GadgetWidth(#BOTOM_FRAME), GadgetHeight(#BOTOM_FRAME), #BORDER_COLOR)
  StopDrawing()
  
  StartDrawing(CanvasOutput(#LEFT_FRAME))
    Box(0, 0, GadgetWidth(#LEFT_FRAME), GadgetHeight(#LEFT_FRAME), #BORDER_COLOR)
  StopDrawing()
    
  StartDrawing(CanvasOutput(#CAPTION_FRAME))
    Box(0, 0, GadgetWidth(#CAPTION_FRAME), GadgetHeight(#CAPTION_FRAME), #CAPTION_COLOR)
  StopDrawing()
  
EndProcedure


Procedure CanvasCallback()
  Protected event.i, gadget.i
  Protected rect.RECT, flag.b = #False
  Protected.i new_x = #PB_Ignore, new_y = #PB_Ignore, new_w = #PB_Ignore, new_h = #PB_Ignore
  Protected tmp.i, canvas_x.i, canvas_y.i
  Static.i desktop_x, desktop_y
  
  event = EventType()
  gadget = EventGadget()
  
  Select EventType()
    Case #PB_EventType_MouseEnter
      Select gadget
        Case #UP_FRAME
          canvas_x = GetGadgetAttribute(gadget, #PB_Canvas_MouseX)
          If canvas_x <= #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          ElseIf canvas_x >= GadgetWidth(gadget) - #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          Else
            SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
          EndIf
          
        Case #BOTOM_FRAME
          canvas_x = GetGadgetAttribute(gadget, #PB_Canvas_MouseX)
          If canvas_x <= #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          ElseIf canvas_x >= GadgetWidth(gadget) - #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          Else
            SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
          EndIf
          
        Case #LEFT_FRAME
          canvas_y = GetGadgetAttribute(gadget, #PB_Canvas_MouseY)
          If canvas_y <= #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          ElseIf canvas_y >= GadgetHeight(gadget) - #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          Else
            SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftRight)
          EndIf
          
        Case #RIGHT_FRAME
          canvas_y = GetGadgetAttribute(gadget, #PB_Canvas_MouseY)
          If canvas_y <= #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          ElseIf canvas_y >= GadgetHeight(gadget) - #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          Else
            SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftRight)
          EndIf
          
      EndSelect
      
    ;Case #PB_EventType_MouseLeave
      ;SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Default)
      
    Case #PB_EventType_LeftButtonDown
      If gadget = #CAPTION_FRAME
        desktop_x = DesktopMouseX()
        desktop_y = DesktopMouseY()
      EndIf
    
    Case #PB_EventType_MouseMove
      If GetGadgetAttribute(gadget, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
        
        rect\left = WindowX(0)
        rect\top = WindowY(0)
        rect\right = rect\left + WindowWidth(0)
        rect\bottom = rect\top + WindowHeight(0)
        
        Select gadget
          Case #RIGHT_FRAME
            If rect\right - rect\left > #MINIMUM_WIDTH Or (DesktopMouseX() > rect\right And rect\right - rect\left <= #MINIMUM_WIDTH)
              new_w =  DesktopMouseX() - rect\left
              flag = #True
            EndIf
            
          Case #BOTOM_FRAME
            If rect\bottom - rect\top > #MINIMUM_HEIGHT Or (DesktopMouseY() > rect\bottom And rect\bottom - rect\top <= #MINIMUM_HEIGHT)
              new_h = DesktopMouseY() - rect\top
              flag = #True
            EndIf
            
          Case #UP_FRAME
            tmp = DesktopMouseY() - rect\top
            new_y = DesktopMouseY()
            
            If tmp >= 0
              new_h = rect\bottom - rect\top - tmp
            Else
              new_h = rect\bottom - rect\top + Abs(tmp)
            EndIf
            
            If new_h > #MINIMUM_HEIGHT
              flag = #True
            EndIf
            
          Case #LEFT_FRAME
            tmp = DesktopMouseX() - rect\left
            new_x = DesktopMouseX()
            
            If tmp >= 0
              new_w = rect\right - rect\left - tmp
            Else
              new_w = rect\right - rect\left + Abs(tmp)
            EndIf
            
            If new_w > #MINIMUM_WIDTH
              flag = #True
            EndIf
            
          Case #CAPTION_FRAME
            ResizeWindow(0, rect\left + DesktopMouseX() - desktop_x, rect\top + DesktopMouseY() - desktop_y, #PB_Ignore, #PB_Ignore)
            desktop_x = DesktopMouseX()
            desktop_y = DesktopMouseY()
        EndSelect
        
        If flag
          ResizeWindow(0, new_x, new_y, new_w, new_h)
          DrawCanvas()
        EndIf
        
      ElseIf GetGadgetAttribute(gadget, #PB_Canvas_Buttons) = #Null
        
      Select gadget
        Case #UP_FRAME
          canvas_x = GetGadgetAttribute(gadget, #PB_Canvas_MouseX)
          If canvas_x <= #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          ElseIf canvas_x >= GadgetWidth(gadget) - #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          Else
            SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
          EndIf
          
        Case #BOTOM_FRAME
          canvas_x = GetGadgetAttribute(gadget, #PB_Canvas_MouseX)
          If canvas_x <= #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          ElseIf canvas_x >= GadgetWidth(gadget) - #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          Else
            SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
          EndIf
          
        Case #LEFT_FRAME
          canvas_y = GetGadgetAttribute(gadget, #PB_Canvas_MouseY)
          If canvas_y <= #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          ElseIf canvas_y >= GadgetHeight(gadget) - #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          Else
            SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftRight)
          EndIf
          
        Case #RIGHT_FRAME
          canvas_y = GetGadgetAttribute(gadget, #PB_Canvas_MouseY)
          If canvas_y <= #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          ElseIf canvas_y >= GadgetHeight(gadget) - #CORNERS_SIZE
            CompilerIf #PB_Compiler_OS = #PB_OS_Windows
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
            CompilerElse
              SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
            CompilerEndIf
          Else
            SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftRight)
          EndIf
        EndSelect
      EndIf
  EndSelect
  
EndProcedure
  
If OpenWindow(0, 0, 0, 320, 240, "Test", #PB_Window_ScreenCentered | #PB_Window_BorderLess)
  
  SetWindowColor(0, #BACKGROUND_COLOR)
  ButtonGadget(100, 20, 50, 50, 20, "Exit")
  ButtonGadget(200, 80, 50, 50, 20, "Min")
  
  ; Borders
  CanvasGadget(#UP_FRAME, 0, 0, WindowWidth(0), #BORDER_SIZE)
  CanvasGadget(#RIGHT_FRAME, WindowWidth(0) - #BORDER_SIZE, #BORDER_SIZE, #BORDER_SIZE, WindowHeight(0) - #BORDER_SIZE * 2)
  CanvasGadget(#BOTOM_FRAME, 0, WindowHeight(0) - #BORDER_SIZE, WindowWidth(0), #BORDER_SIZE)
  CanvasGadget(#LEFT_FRAME, 0, #BORDER_SIZE, #BORDER_SIZE, WindowHeight(0) - #BORDER_SIZE * 2)
  
  ; Caption
  CanvasGadget(#CAPTION_FRAME, #BORDER_SIZE, #BORDER_SIZE, WindowWidth(0) - #BORDER_SIZE * 2, #CAPTION_SIZE)
  
  DrawCanvas()
  
  BindGadgetEvent(#UP_FRAME, @CanvasCallback())
  BindGadgetEvent(#RIGHT_FRAME, @CanvasCallback())
  BindGadgetEvent(#BOTOM_FRAME, @CanvasCallback())
  BindGadgetEvent(#LEFT_FRAME, @CanvasCallback())
  BindGadgetEvent(#CAPTION_FRAME, @CanvasCallback())
  
  Repeat
    event = WaitWindowEvent()
    If event = #PB_Event_Gadget
      Select EventGadget()
        Case 100
          Break
          
        Case 200
          SetWindowState(0, #PB_Window_Minimize)
          
      EndSelect
    EndIf
  Until event = #PB_Event_CloseWindow
  
EndIf

Re: [CrossPlatform] Resizable borderless window

Posted: Tue Sep 27, 2016 9:28 am
by HanPBF

Re: [CrossPlatform] Resizable borderless window

Posted: Tue Sep 27, 2016 2:10 pm
by Demivec
Peyman wrote: try to create a resizable borderless window for all platform with canvas, I wrote left, right, top and bottom borders resizing algorithm so now what about corners ? some body can help me for this ?

Code: Select all

Enumeration
  #UP_FRAME
  #BOTOM_FRAME
  #LEFT_FRAME
  #RIGHT_FRAME
  #CAPTION_FRAME
EndEnumeration

EnumerationBinary
  #TOP_BORDER
  #BOTOM_BORDER
  #LEFT_BORDER
  #RIGHT_BORDER
EndEnumeration

#BORDER_SIZE = 10
#BORDER_COLOR = 15707194
#CAPTION_COLOR = #Black
#CAPTION_SIZE = 30
#BACKGROUND_COLOR = #White
#MINIMUM_WIDTH = 200
#MINIMUM_HEIGHT = 100
#CORNERS_SIZE = 8

Procedure DrawCanvas()
  ; Redraw Caption
  StartDrawing(CanvasOutput(#CAPTION_FRAME))
  Box(0, 0, OutputWidth(), OutputHeight(), #CAPTION_COLOR)
  StopDrawing()
  
  ; Redraw Borders
  StartDrawing(CanvasOutput(#UP_FRAME))
  Box(0, 0, OutputWidth(), OutputHeight(), #BORDER_COLOR)
  StopDrawing()
  
  StartDrawing(CanvasOutput(#LEFT_FRAME))
  Box(0, 0, OutputWidth(), OutputHeight(), #BORDER_COLOR)
  StopDrawing()
  
  StartDrawing(CanvasOutput(#RIGHT_FRAME))
  Box(0, 0, OutputWidth(), OutputHeight(), #BORDER_COLOR)
  StopDrawing()
  
  StartDrawing(CanvasOutput(#BOTOM_FRAME))
  Box(0, 0, OutputWidth(), OutputHeight(), #BORDER_COLOR)
  StopDrawing()
  
EndProcedure

Procedure updateWindowSize(new_x, new_y, new_w, new_h)
  Protected w, h, hasChanged = #False
  
  If new_w = #PB_Ignore
    w = WindowWidth(0)
  Else
    w = new_w
    hasChanged = #True
  EndIf
  
  If new_h = #PB_Ignore
    h = WindowHeight(0)
  Else
    h = new_h
    hasChanged = #True
  EndIf
  
  
  If hasChanged
    ; Resize Caption
    ResizeGadget(#CAPTION_FRAME, #PB_Ignore, #PB_Ignore, w - #BORDER_SIZE * 2, #PB_Ignore) 
    
    ; Resize Borders
    ResizeGadget(#UP_FRAME, #PB_Ignore, #PB_Ignore, w, #PB_Ignore)
    ResizeGadget(#LEFT_FRAME, #PB_Ignore, #PB_Ignore, #PB_Ignore, h - #BORDER_SIZE * 2)
    ResizeGadget(#RIGHT_FRAME, w - #BORDER_SIZE, #PB_Ignore, w, h - #BORDER_SIZE * 2)
    ResizeGadget(#BOTOM_FRAME, #PB_Ignore, h - #BORDER_SIZE, w, #PB_Ignore)
    DrawCanvas()
  EndIf
  
  ResizeWindow(0, new_x, new_y, new_w, new_h)
EndProcedure


Procedure setCanvasCursor(gadget, canvas_x, canvas_y)
  
  Protected resizeBorder = 0
  
  Select gadget
    Case #UP_FRAME
      canvas_x = GetGadgetAttribute(gadget, #PB_Canvas_MouseX)
      If canvas_x <= #CORNERS_SIZE
        resizeBorder = #TOP_BORDER + #LEFT_BORDER
      ElseIf canvas_x >= GadgetWidth(gadget) - #CORNERS_SIZE
        resizeBorder = #TOP_BORDER + #RIGHT_BORDER
      Else
        resizeBorder = #TOP_BORDER
      EndIf
    Case #BOTOM_FRAME
      canvas_x = GetGadgetAttribute(gadget, #PB_Canvas_MouseX)
      If canvas_x <= #CORNERS_SIZE
        resizeBorder = #BOTOM_BORDER + #LEFT_BORDER
      ElseIf canvas_x >= GadgetWidth(gadget) - #CORNERS_SIZE
        resizeBorder = #BOTOM_BORDER + #RIGHT_BORDER
      Else
        resizeBorder = #BOTOM_BORDER
      EndIf
    Case #LEFT_FRAME
      canvas_y = GetGadgetAttribute(gadget, #PB_Canvas_MouseY)
      If canvas_y <= #CORNERS_SIZE
        resizeBorder = #TOP_BORDER + #LEFT_BORDER
      ElseIf canvas_y >= GadgetHeight(gadget) - #CORNERS_SIZE
        resizeBorder = #BOTOM_BORDER + #LEFT_BORDER
      Else
        resizeBorder = #LEFT_BORDER
      EndIf
    Case #RIGHT_FRAME
      canvas_y = GetGadgetAttribute(gadget, #PB_Canvas_MouseY)
      If canvas_y <= #CORNERS_SIZE
        resizeBorder = #TOP_BORDER + #RIGHT_BORDER
      ElseIf canvas_y >= GadgetHeight(gadget) - #CORNERS_SIZE
        resizeBorder = #BOTOM_BORDER + #RIGHT_BORDER
      Else
        resizeBorder = #RIGHT_BORDER
      EndIf
      
  EndSelect
  
  Select resizeBorder
    Case (#TOP_BORDER + #LEFT_BORDER), (#BOTOM_BORDER + #RIGHT_BORDER)
      CompilerIf #PB_Compiler_OS = #PB_OS_Windows
        SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
      CompilerElse
        SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
      CompilerEndIf
    Case (#TOP_BORDER + #RIGHT_BORDER), (#BOTOM_BORDER + #LEFT_BORDER)
      CompilerIf #PB_Compiler_OS = #PB_OS_Windows
        SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
      CompilerElse 
        SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
      CompilerEndIf
    Case #LEFT_BORDER, #RIGHT_BORDER
      SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftRight)
    Case  #TOP_BORDER, #BOTOM_BORDER
      SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
  EndSelect
  
  ProcedureReturn resizeBorder
EndProcedure

Procedure CanvasCallback()
  Protected event.i, gadget.i
  Protected rect.RECT, resizeWindow.b = #False
  Protected.i new_x = #PB_Ignore, new_y = #PB_Ignore, new_w = #PB_Ignore, new_h = #PB_Ignore
  Protected tmp.i, canvas_x.i, canvas_y.i
  Static.i desktop_x, desktop_y
  Static.i resizeBorder = 0
  
  event = EventType()
  gadget = EventGadget()
  
  Select event
    Case #PB_EventType_MouseEnter
      resizeBorder = setCanvasCursor(gadget, canvas_x, canvas_y)
      
      ;Case #PB_EventType_MouseLeave
      ;SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Default)
      
    Case #PB_EventType_LeftButtonDown
      If gadget = #CAPTION_FRAME
        desktop_x = DesktopMouseX()
        desktop_y = DesktopMouseY()
      EndIf
      
    Case #PB_EventType_MouseMove
      If GetGadgetAttribute(gadget, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
        
        rect\left = WindowX(0)
        rect\top = WindowY(0)
        rect\right = rect\left + WindowWidth(0)
        rect\bottom = rect\top + WindowHeight(0)
        
        Select gadget
          Case #RIGHT_FRAME, #BOTOM_FRAME, #UP_FRAME, #LEFT_FRAME
            If resizeBorder & #RIGHT_BORDER
              If rect\right - rect\left > #MINIMUM_WIDTH Or (DesktopMouseX() > rect\right And rect\right - rect\left <= #MINIMUM_WIDTH)
                new_w =  DesktopMouseX() - rect\left
                resizeWindow = #True
              EndIf
            EndIf
            
            If resizeBorder & #BOTOM_BORDER
              If rect\bottom - rect\top > #MINIMUM_HEIGHT Or (DesktopMouseY() > rect\bottom And rect\bottom - rect\top <= #MINIMUM_HEIGHT)
                new_h = DesktopMouseY() - rect\top
                resizeWindow = #True
              EndIf
            EndIf
            
            If resizeBorder & #TOP_BORDER
              tmp = DesktopMouseY() - rect\top
              new_y = DesktopMouseY()
              
              If tmp >= 0
                new_h = rect\bottom - rect\top - tmp
              Else
                new_h = rect\bottom - rect\top + Abs(tmp)
              EndIf
              
              If new_h > #MINIMUM_HEIGHT
                resizeWindow = #True
              EndIf
            EndIf
            
            If resizeBorder & #LEFT_BORDER
              tmp = DesktopMouseX() - rect\left
              new_x = DesktopMouseX()
              
              If tmp >= 0
                new_w = rect\right - rect\left - tmp
              Else
                new_w = rect\right - rect\left + Abs(tmp)
              EndIf
              
              If new_w > #MINIMUM_WIDTH
                resizeWindow = #True
              EndIf
            EndIf
            
          Case #CAPTION_FRAME
            ResizeWindow(0, rect\left + DesktopMouseX() - desktop_x, rect\top + DesktopMouseY() - desktop_y, #PB_Ignore, #PB_Ignore)
            desktop_x = DesktopMouseX()
            desktop_y = DesktopMouseY()
        EndSelect
        
        If resizeWindow
          updateWindowSize(new_x, new_y, new_w, new_h)
        EndIf
        
      ElseIf GetGadgetAttribute(gadget, #PB_Canvas_Buttons) = #Null
        resizeBorder = setCanvasCursor(gadget, canvas_x, canvas_y)
      EndIf
  EndSelect
  
EndProcedure

If OpenWindow(0, 0, 0, 320, 240, "Test", #PB_Window_ScreenCentered | #PB_Window_BorderLess)
  
  SetWindowColor(0, #BACKGROUND_COLOR)
  ButtonGadget(100, 20, 50, 50, 20, "Exit")
  ButtonGadget(200, 80, 50, 50, 20, "Min")
  
  ; Borders
  CanvasGadget(#UP_FRAME, 0, 0, WindowWidth(0), #BORDER_SIZE)
  CanvasGadget(#RIGHT_FRAME, WindowWidth(0) - #BORDER_SIZE, #BORDER_SIZE, #BORDER_SIZE, WindowHeight(0) - #BORDER_SIZE * 2)
  CanvasGadget(#BOTOM_FRAME, 0, WindowHeight(0) - #BORDER_SIZE, WindowWidth(0), #BORDER_SIZE)
  CanvasGadget(#LEFT_FRAME, 0, #BORDER_SIZE, #BORDER_SIZE, WindowHeight(0) - #BORDER_SIZE * 2)
  
  ; Caption
  CanvasGadget(#CAPTION_FRAME, #BORDER_SIZE, #BORDER_SIZE, WindowWidth(0) - #BORDER_SIZE * 2, #CAPTION_SIZE)
  
  DrawCanvas()
  
  BindGadgetEvent(#UP_FRAME, @CanvasCallback())
  BindGadgetEvent(#RIGHT_FRAME, @CanvasCallback())
  BindGadgetEvent(#BOTOM_FRAME, @CanvasCallback())
  BindGadgetEvent(#LEFT_FRAME, @CanvasCallback())
  BindGadgetEvent(#CAPTION_FRAME, @CanvasCallback())
  
  Repeat
    event = WaitWindowEvent()
    If event = #PB_Event_Gadget
      Select EventGadget()
        Case 100
          Break
          
        Case 200
          SetWindowState(0, #PB_Window_Minimize)
          
      EndSelect
    EndIf
  Until event = #PB_Event_CloseWindow
  
EndIf

Re: [CrossPlatform] Resizable borderless window

Posted: Tue Sep 27, 2016 3:25 pm
by Peyman
wow Demivec thx so much, really nice idea

i made some small change for minimum width and height of window, maybe its good if u have time to create a module or something and post it in tricks 'n' tips section

Code: Select all

Enumeration 5000
  #UP_FRAME
  #BOTOM_FRAME
  #LEFT_FRAME
  #RIGHT_FRAME
  #CAPTION_FRAME
EndEnumeration

EnumerationBinary
 #TOP_BORDER
 #BOTOM_BORDER
 #LEFT_BORDER
 #RIGHT_BORDER
EndEnumeration



#BORDER_SIZE = 10
#BORDER_COLOR = 15707194
#CAPTION_COLOR = #Black
#CAPTION_SIZE = 30
#BACKGROUND_COLOR = #White
#MINIMUM_WIDTH = 200
#MINIMUM_HEIGHT = 100
#CORNERS_SIZE = 8

Procedure DrawCanvas()
  ; Redraw Caption
  StartDrawing(CanvasOutput(#CAPTION_FRAME))
    Box(0, 0, OutputWidth(), OutputHeight(), #CAPTION_COLOR)
  StopDrawing()
  
  ; Redraw Borders
  StartDrawing(CanvasOutput(#UP_FRAME))
    Box(0, 0, OutputWidth(), OutputHeight(), #BORDER_COLOR)
  StopDrawing()
  
  StartDrawing(CanvasOutput(#LEFT_FRAME))
    Box(0, 0, OutputWidth(), OutputHeight(), #BORDER_COLOR)
  StopDrawing()
     
  StartDrawing(CanvasOutput(#RIGHT_FRAME))
    Box(0, 0, OutputWidth(), OutputHeight(), #BORDER_COLOR)
  StopDrawing()
  
  StartDrawing(CanvasOutput(#BOTOM_FRAME))
    Box(0, 0, OutputWidth(), OutputHeight(), #BORDER_COLOR)
  StopDrawing()
  
EndProcedure

Procedure updateWindowSize(new_x, new_y, new_w, new_h)
  Protected w, h, hasChanged = #False
  
  If new_w = #PB_Ignore
    w = WindowWidth(0)
  Else
    w = new_w
    hasChanged = #True
  EndIf
  
  If new_h = #PB_Ignore
    h = WindowHeight(0)
  Else
    h = new_h
    hasChanged = #True
  EndIf
    
  If hasChanged
    ; Resize Caption
    ResizeGadget(#CAPTION_FRAME, #PB_Ignore, #PB_Ignore, w - #BORDER_SIZE * 2, #PB_Ignore) 
    
    ; Resize Borders
    ResizeGadget(#UP_FRAME, #PB_Ignore, #PB_Ignore, w, #PB_Ignore)
    ResizeGadget(#LEFT_FRAME, #PB_Ignore, #PB_Ignore, #PB_Ignore, h - #BORDER_SIZE * 2)
    ResizeGadget(#RIGHT_FRAME, w - #BORDER_SIZE, #PB_Ignore, w, h - #BORDER_SIZE * 2)
    ResizeGadget(#BOTOM_FRAME, #PB_Ignore, h - #BORDER_SIZE, w, #PB_Ignore)
    DrawCanvas()
  EndIf
  
  ResizeWindow(0, new_x, new_y, new_w, new_h)
EndProcedure


Procedure setCanvasCursor(gadget)
  Protected resizeBorder = 0
  
  Select gadget
    Case #UP_FRAME
      canvas_x = GetGadgetAttribute(gadget, #PB_Canvas_MouseX)
      If canvas_x <= #CORNERS_SIZE
        CompilerIf #PB_Compiler_OS = #PB_OS_Windows
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
        CompilerElse
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
        CompilerEndIf
        resizeBorder = #TOP_BORDER + #LEFT_BORDER
      ElseIf canvas_x >= GadgetWidth(gadget) - #CORNERS_SIZE
        CompilerIf #PB_Compiler_OS = #PB_OS_Windows
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
        CompilerElse 
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
        CompilerEndIf
        resizeBorder = #TOP_BORDER + #RIGHT_BORDER
      Else
        SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
        resizeBorder = #TOP_BORDER
      EndIf
      
    Case #BOTOM_FRAME
      canvas_x = GetGadgetAttribute(gadget, #PB_Canvas_MouseX)
      If canvas_x <= #CORNERS_SIZE
        CompilerIf #PB_Compiler_OS = #PB_OS_Windows
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
        CompilerElse
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
        CompilerEndIf
        resizeBorder = #BOTOM_BORDER + #LEFT_BORDER
      ElseIf canvas_x >= GadgetWidth(gadget) - #CORNERS_SIZE
        CompilerIf #PB_Compiler_OS = #PB_OS_Windows
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
        CompilerElse
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
        CompilerEndIf
        resizeBorder = #BOTOM_BORDER + #RIGHT_BORDER
      Else
        SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
        resizeBorder = #BOTOM_BORDER
      EndIf
      
    Case #LEFT_FRAME
      canvas_y = GetGadgetAttribute(gadget, #PB_Canvas_MouseY)
      If canvas_y <= #CORNERS_SIZE
        CompilerIf #PB_Compiler_OS = #PB_OS_Windows
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
        CompilerElse
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
        CompilerEndIf
        resizeBorder = #TOP_BORDER + #LEFT_BORDER
      ElseIf canvas_y >= GadgetHeight(gadget) - #CORNERS_SIZE
        CompilerIf #PB_Compiler_OS = #PB_OS_Windows
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
        CompilerElse
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
        CompilerEndIf
        resizeBorder = #BOTOM_BORDER + #LEFT_BORDER
      Else
        SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftRight)
        resizeBorder = #LEFT_BORDER
      EndIf
      
    Case #RIGHT_FRAME
      canvas_y = GetGadgetAttribute(gadget, #PB_Canvas_MouseY)
      If canvas_y <= #CORNERS_SIZE
        CompilerIf #PB_Compiler_OS = #PB_OS_Windows
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
        CompilerElse
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
        CompilerEndIf
        resizeBorder = #TOP_BORDER + #RIGHT_BORDER
      ElseIf canvas_y >= GadgetHeight(gadget) - #CORNERS_SIZE
        CompilerIf #PB_Compiler_OS = #PB_OS_Windows
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
        CompilerElse
          SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
        CompilerEndIf
        resizeBorder = #BOTOM_BORDER + #RIGHT_BORDER
      Else
        SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftRight)
        resizeBorder = #RIGHT_BORDER
      EndIf
      
  EndSelect
  
  ProcedureReturn resizeBorder
EndProcedure

Procedure CanvasCallback()
  Protected event.i, gadget.i
  Protected rect.RECT, resizeWindow.b = #False
  Protected.i new_x = #PB_Ignore, new_y = #PB_Ignore, new_w = #PB_Ignore, new_h = #PB_Ignore
  Protected tmp.i
  Static.i desktop_x, desktop_y
  Static.i resizeBorder = 0
  
  event = EventType()
  gadget = EventGadget()
  
  Select event
    Case #PB_EventType_MouseEnter
      resizeBorder = setCanvasCursor(gadget)
      
      ;Case #PB_EventType_MouseLeave
      ;SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Default)
      
    Case #PB_EventType_LeftButtonDown
      If gadget = #CAPTION_FRAME
        desktop_x = DesktopMouseX()
        desktop_y = DesktopMouseY()
      EndIf
      
    Case #PB_EventType_MouseMove
      If GetGadgetAttribute(gadget, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
        
        rect\left = WindowX(0)
        rect\top = WindowY(0)
        rect\right = rect\left + WindowWidth(0)
        rect\bottom = rect\top + WindowHeight(0)
        
        Select gadget
          Case #RIGHT_FRAME, #BOTOM_FRAME, #UP_FRAME, #LEFT_FRAME
            If resizeBorder & #RIGHT_BORDER
              If rect\right - rect\left > #MINIMUM_WIDTH Or (DesktopMouseX() > rect\right And rect\right - rect\left <= #MINIMUM_WIDTH)
                new_w =  DesktopMouseX() - rect\left
                resizeWindow = #True
              EndIf
            EndIf
            
            If resizeBorder & #BOTOM_BORDER
              If rect\bottom - rect\top > #MINIMUM_HEIGHT Or (DesktopMouseY() > rect\bottom And rect\bottom - rect\top <= #MINIMUM_HEIGHT)
                new_h = DesktopMouseY() - rect\top
                resizeWindow = #True
              EndIf
            EndIf
            
            If resizeBorder & #TOP_BORDER
              tmp = DesktopMouseY() - rect\top
              
              If tmp >= 0
                new_h = rect\bottom - rect\top - tmp
              Else
                new_h = rect\bottom - rect\top + Abs(tmp)
              EndIf
              
              If new_h > #MINIMUM_HEIGHT
                new_y = DesktopMouseY()
                resizeWindow = #True
              Else
                new_h = #PB_Ignore
              EndIf
            EndIf
            
            If resizeBorder & #LEFT_BORDER
              tmp = DesktopMouseX() - rect\left
              
              If tmp >= 0
                new_w = rect\right - rect\left - tmp
              Else
                new_w = rect\right - rect\left + Abs(tmp)
              EndIf
              
              If new_w > #MINIMUM_WIDTH
                resizeWindow = #True
                new_x = DesktopMouseX()
              Else
                new_w = #PB_Ignore
              EndIf
            EndIf
            
          Case #CAPTION_FRAME
            ResizeWindow(0, rect\left + DesktopMouseX() - desktop_x, rect\top + DesktopMouseY() - desktop_y, #PB_Ignore, #PB_Ignore)
            desktop_x = DesktopMouseX()
            desktop_y = DesktopMouseY()
        EndSelect
        
        If resizeWindow
          updateWindowSize(new_x, new_y, new_w, new_h)
        EndIf
        
      ElseIf GetGadgetAttribute(gadget, #PB_Canvas_Buttons) = #Null
        resizeBorder = setCanvasCursor(gadget)
      EndIf
  EndSelect
  
EndProcedure

If OpenWindow(0, 0, 0, 320, 240, "Test", #PB_Window_ScreenCentered | #PB_Window_BorderLess)
  
  SetWindowColor(0, #BACKGROUND_COLOR)
  ButtonGadget(100, 20, 50, 50, 20, "Exit")
  ButtonGadget(200, 80, 50, 50, 20, "Min")
  
  ; Borders
  CanvasGadget(#UP_FRAME, 0, 0, WindowWidth(0), #BORDER_SIZE)
  CanvasGadget(#RIGHT_FRAME, WindowWidth(0) - #BORDER_SIZE, #BORDER_SIZE, #BORDER_SIZE, WindowHeight(0) - #BORDER_SIZE * 2)
  CanvasGadget(#BOTOM_FRAME, 0, WindowHeight(0) - #BORDER_SIZE, WindowWidth(0), #BORDER_SIZE)
  CanvasGadget(#LEFT_FRAME, 0, #BORDER_SIZE, #BORDER_SIZE, WindowHeight(0) - #BORDER_SIZE * 2)
  
  ; Caption
  CanvasGadget(#CAPTION_FRAME, #BORDER_SIZE, #BORDER_SIZE, WindowWidth(0) - #BORDER_SIZE * 2, #CAPTION_SIZE)
  
  DrawCanvas()
  
  BindGadgetEvent(#UP_FRAME, @CanvasCallback())
  BindGadgetEvent(#RIGHT_FRAME, @CanvasCallback())
  BindGadgetEvent(#BOTOM_FRAME, @CanvasCallback())
  BindGadgetEvent(#LEFT_FRAME, @CanvasCallback())
  BindGadgetEvent(#CAPTION_FRAME, @CanvasCallback())
  
  Repeat
    event = WaitWindowEvent()
    If event = #PB_Event_Gadget
      Select EventGadget()
        Case 100
          Break
          
        Case 200
          SetWindowState(0, #PB_Window_Minimize)
          
      EndSelect
    EndIf
  Until event = #PB_Event_CloseWindow
  
EndIf

Re: [CrossPlatform] Resizable borderless window

Posted: Wed Sep 28, 2016 12:08 am
by Demivec
Peyman wrote:i made some small change for minimum width and height of window, maybe its good if u have time to create a module or something and post it in tricks 'n' tips section
I had looked at problems related to the previous solution and hadn't come with a working solution. It's good to see you fixed it.

Just as a matter of clean code, I had updated the previous code to simplify it before your last post.


Now for a few other questions. What do you want the module called? What about some additional features such as a Maximum Height/Width, more than one window or custom drawing of the borders or caption?

Re: [CrossPlatform] Resizable borderless window

Posted: Mon Oct 03, 2016 12:37 pm
by Peyman
Demivec wrote:
Peyman wrote:i made some small change for minimum width and height of window, maybe its good if u have time to create a module or something and post it in tricks 'n' tips section
I had looked at problems related to the previous solution and hadn't come with a working solution. It's good to see you fixed it.

Just as a matter of clean code, I had updated the previous code to simplify it before your last post.


Now for a few other questions. What do you want the module called? What about some additional features such as a Maximum Height/Width, more than one window or custom drawing of the borders or caption?
sry I was absent for a short time, a module that can help some body in CrossPlatform resizable borderless window.
Maximum Height/Width ? why not ? WindowBounds() function dont work in this way so its a good future
more than one window ? absolutely, this is what module do here
caption ? i dont think so, because its the responsibility of end programmer to control the moving of its program's window, i use caption because i try to create a Windows 10 theme for my program that look likes same in all OSs, and for my next mission work on a custom ScrollBarGadget and ScrollAreaGadget :wink:

Re: [CrossPlatform] Resizable borderless window

Posted: Tue Feb 07, 2017 11:25 pm
by eddy
Here is a version with canvas container.
I works but there's a flickering when canvas is resizing (Windows)

Code: Select all

; coded in PB5.60+
Enumeration 5000
   #WINDOW_FRAMES
   #BUTTON_CLOSE
   #BUTTON_MINIMIZE
EndEnumeration

EnumerationBinary
   #TOP_FRAME
   #BOTOM_FRAME
   #LEFT_FRAME
   #RIGHT_FRAME
   #CAPTION_FRAME
EndEnumeration

#CORNERS_SIZE=8
#BORDER_SIZE=10
#BORDER_COLOR=15707194
#CAPTION_SIZE=30
#CAPTION_COLOR=#Black
#BACKGROUND_COLOR=#White


Procedure DrawCanvas()
   StartDrawing(CanvasOutput(#WINDOW_FRAMES))   
   ; Redraw Borders
   Box(0, 0, OutputWidth(), OutputHeight(), #BORDER_COLOR)
   ; Redraw Background
   Box(#BORDER_SIZE, #BORDER_SIZE, OutputWidth()-2*#BORDER_SIZE, OutputHeight()-2*#BORDER_SIZE, #BACKGROUND_COLOR)
   ; Redraw Caption
   Box(#BORDER_SIZE, #BORDER_SIZE, OutputWidth()-2*#BORDER_SIZE, #CAPTION_SIZE, #CAPTION_COLOR)   
   StopDrawing()
EndProcedure

Procedure HitAnyFrames(gadget)
   Protected hitFrames=0
   Protected mouseX=GetGadgetAttribute(gadget, #PB_Canvas_MouseX)
   Protected mouseY=GetGadgetAttribute(gadget, #PB_Canvas_MouseY)
   ; Detect frames
   If (mouseX<=#CORNERS_SIZE)
      hitFrames | #LEFT_FRAME
   EndIf
   If (mouseY<=#CORNERS_SIZE)
      hitFrames | #TOP_FRAME
   EndIf
   If (mouseX>=GadgetWidth(gadget) - #CORNERS_SIZE)
      hitFrames | #RIGHT_FRAME
   EndIf
   If (mouseY>=GadgetHeight(gadget) - #CORNERS_SIZE)
      hitFrames | #BOTOM_FRAME
   EndIf
   If (mouseY>#BORDER_SIZE And mouseY<=#BORDER_SIZE + #CAPTION_SIZE) And (mouseX>#BORDER_SIZE And mouseX<GadgetWidth(gadget) - #BORDER_SIZE)
      hitFrames=#CAPTION_FRAME
   EndIf
   ; Change cursor
   Select hitFrames
      Case 0, #CAPTION_FRAME
         SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Default)
      Case #TOP_FRAME, #BOTOM_FRAME
         SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
      Case #LEFT_FRAME, #RIGHT_FRAME
         SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftRight)
         CompilerIf #PB_Compiler_OS=#PB_OS_Windows
         Case #LEFT_FRAME | #TOP_FRAME, #RIGHT_FRAME | #BOTOM_FRAME
            SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
         Case #LEFT_FRAME | #BOTOM_FRAME, #RIGHT_FRAME | #TOP_FRAME
            SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
         CompilerElse
         Default
            SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
         CompilerEndIf
   EndSelect
   
   ProcedureReturn hitFrames
EndProcedure

Procedure CanvasCallback()
   Static hitFrames=0, dragWindowX, dragWindowY, rect.RECT   
   Protected event=EventType()
   Protected gadget=EventGadget()
   Protected win=EventWindow()
   
   Select event
      Case #PB_EventType_MouseEnter
         hitFrames=HitAnyFrames(gadget)
         
      Case #PB_EventType_LeftButtonUp
         If hitFrames
            hitFrames=0            
         EndIf
      Case #PB_EventType_LeftButtonDown
         hitFrames=HitAnyFrames(gadget)
         If hitFrames
            dragWindowX=WindowMouseX(win)
            dragWindowY=WindowMouseY(win)
            rect\left=WindowX(win)
            rect\top=WindowY(win)
            rect\right=rect\left + WindowWidth(win)
            rect\bottom=rect\top + WindowHeight(win)
         EndIf         
      Case #PB_EventType_MouseMove
         If GetGadgetAttribute(gadget, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
            If hitFrames=#CAPTION_FRAME
               ResizeWindow(win, DesktopMouseX() - dragWindowX, DesktopMouseY() - dragWindowY, #PB_Ignore, #PB_Ignore)
            Else
               Protected x=#PB_Ignore, y=#PB_Ignore, w=#PB_Ignore, h=#PB_Ignore
               If hitFrames & #LEFT_FRAME
                  rect\left=DesktopMouseX() - dragWindowX : w=rect\right-rect\left
                  x=rect\left
               EndIf
               If hitFrames & #RIGHT_FRAME
                  w=(rect\right - rect\left) + (DesktopMouseX() - dragWindowX-rect\left)                  
               EndIf
               If hitFrames & #TOP_FRAME
                  rect\top=DesktopMouseY() - dragWindowY : h=rect\bottom-rect\top
                  y=rect\top
               EndIf
               If hitFrames & #BOTOM_FRAME
                  h=(rect\bottom-rect\top) + (DesktopMouseY() - dragWindowY-rect\top)
               EndIf
               ResizeWindow(win, x, y, w, h)
               ResizeGadget(gadget, #PB_Ignore, #PB_Ignore, w, h)
               DrawCanvas()
            EndIf
         Else
            hitFrames=HitAnyFrames(gadget)
         EndIf
   EndSelect
   
EndProcedure

If OpenWindow(0, 0, 0, 320, 240, "Test", #PB_Window_ScreenCentered | #PB_Window_BorderLess)
   SetWindowColor(0, #BACKGROUND_COLOR)
   WindowBounds(0, 200, 100, #PB_Ignore, #PB_Ignore)
   SmartWindowRefresh(0, 1)
   CanvasGadget(#WINDOW_FRAMES, 0, 0, WindowWidth(0), WindowHeight(0), #PB_Canvas_Container)
   ButtonGadget(#BUTTON_CLOSE, #BORDER_SIZE + 5, #BORDER_SIZE + 5, 50, 20, "Exit")
   ButtonGadget(#BUTTON_MINIMIZE, #BORDER_SIZE + 70, #BORDER_SIZE + 5, 50, 20, "Min")
   CloseGadgetList()
   
   DrawCanvas()
   
   BindGadgetEvent(#WINDOW_FRAMES, @CanvasCallback())
   
   Repeat
      event=WaitWindowEvent()
      If event=#PB_Event_Gadget
         Select EventGadget()
            Case #BUTTON_CLOSE
               Break
            Case #BUTTON_MINIMIZE
               SetWindowState(0, #PB_Window_Minimize)
         EndSelect
      EndIf
   Until event=#PB_Event_CloseWindow
   
EndIf