[Modul] "CWMove" - Fenster mit Canvas per Maus bewegen

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

[Modul] "CWMove" - Fenster mit Canvas per Maus bewegen

Beitrag von Bisonte »

Hallo Leute.

Ich hatte vor kurzem das Problem, dass ich ein Fenster ohne Rahmen (mit Flag : #PB_Window_Borderless)
mit der Maus beweglich machen sollte.
Unter Windows hab ich damit kein Problem. Das ganze sollte allerdings auch auf Linux laufen...
Langes stöbern in unserem Community Pool brachte dann eine klitzekleine Routine von danilo ans Tageslicht.
Der Code ist so kurz und schmerzlos mit PB Bordmitteln gewesen, daß ich den in ein MiniModul transferiert habe.

Funktioniert mit Windows, Linux (getestet: Mint 16-18), und MacOS (getestet : El Capitan).
Ein Demo ist beigefügt und muss nicht aus dem Codeschnipsel enfernt werden ;)

Code: Alles auswählen

;: Module   : CanvasWindowMover (CWMove)
;: TargetOS : Windows/Linux/MacOS
;: 
;: Original by         : danilo
;: converted to module : Bisonte
;: 
;: This Module shows the excellent solution from Danilo
;: to move a borderless window by leftbutton down and 
;: moving the mouse. In a crossplatform way !!!
;: The original post from Danilo is in this thread :
;: http://www.purebasic.fr/english/viewtopic.php?p=429066
;: 
;: RegisterCWMove(Gadget) : Create your canvasgadget and register it. So the window
;:                          the canvas is placed on, can be moved with it.
;: FreeCWMove(Gadget)     : If you want to free your gadget you have to free the 
;:                          movement - registration first to avoid conflicts with 
;:                          gadgetcreations after that. 
;: 
DeclareModule CWMove
  
  EnableExplicit
  
  Declare.i RegisterWMove(Gadget)
  Declare.i FreeWMove(Gadget)
  
EndDeclareModule
Module CWMove
    
  Structure s_movement
    MouseDown.i
    OffSetx.i
    OffSety.i
  EndStructure
  
  Global NewMap CM.s_movement()
  
  ;: Private
  Procedure CanvasWindowMovement()

    Protected Key.s = Str(GadgetID(EventGadget()))
    
    If FindMapElement(CM(), Key)
      
      With CM(Key)
        
        Select EventType()
          Case #PB_EventType_LeftButtonDown
            \MouseDown = #True
            \OffsetX = GetGadgetAttribute(EventGadget(), #PB_Canvas_MouseX)
            \OffsetY = GetGadgetAttribute(EventGadget(), #PB_Canvas_MouseY)
            
          Case #PB_EventType_LeftButtonUp
            \MouseDown = #False
            
          Case #PB_EventType_MouseMove
            If \MouseDown And GetGadgetAttribute(EventGadget(), #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
              ResizeWindow(EventWindow(), DesktopMouseX() - \OffsetX, DesktopMouseY() - \OffsetY, #PB_Ignore, #PB_Ignore) 
            EndIf          
            
        EndSelect
        
      EndWith
      
    EndIf
    
  EndProcedure
  
  ;: Public
  Procedure.i RegisterWMove(Gadget)
    
    Protected Key.s, Result = #False
    
    If IsGadget(Gadget)
      
      Key = Str(GadgetID(Gadget))
      
      If GadgetType(Gadget) = #PB_GadgetType_Canvas
        CM(Key)\MouseDown = #False
        CM(Key)\OffSetx = 0
        CM(Key)\OffSety = 0
        BindGadgetEvent(Gadget, @CanvasWindowMovement())
        Result = #True
      EndIf
    EndIf
    
    ProcedureReturn Result
    
  EndProcedure
  Procedure.i FreeWMove(Gadget)
    If IsGadget(Gadget)
      If FindMapElement(CM(), Str(GadgetID(Gadget)))
        UnbindGadgetEvent(Gadget, @CanvasWindowMovement())
        DeleteMapElement(CM(), Str(GadgetID(Gadget)))
      EndIf
    EndIf
  EndProcedure
  
EndModule
;: Example
CompilerIf #PB_Compiler_IsMainFile
  
  EnableExplicit
  
  UseModule CWMove
  
  Define Window, Canvas, Event, Quit
  
  Window = OpenWindow(#PB_Any, 0, 0, 300, 300, "Test", #PB_Window_ScreenCentered|#PB_Window_BorderLess)
  SetWindowColor(Window, RGB(0, 0, 0))
  
  Canvas = CanvasGadget(#PB_Any, 1, 1, WindowWidth(Window) - 2, 40)
    
  If StartDrawing(CanvasOutput(Canvas))
    Box(0, 0, OutputWidth(), OutputHeight(), RGB(128, 128, 128))
    DrawText(5, 5, "Move window with mouse in here", RGB(0, 0, 0), RGB(128, 128, 128))
    StopDrawing()
  EndIf
  
  CWMove::RegisterWMove(Canvas)
  
  AddKeyboardShortcut(Window, #PB_Shortcut_Escape, 59999)
  
  Repeat
    
    Event = WaitWindowEvent()
    
    Select Event
        
      Case #PB_Event_CloseWindow
        Break

      Case #PB_Event_Menu
        
        Select EventMenu()
   
          Case 59999
            Break
            
        EndSelect
        
    EndSelect
    
  ForEver
  
  CWMove::FreeWMove(Canvas)
  FreeGadget(Canvas)
  
  
CompilerEndIf
Suchtags : canvas gadget mouse maus bewegung movement window crossplatform
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​