Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Region dragging with mouse example, e.g. for Splash Window with no title bar
!Examle how to drag window by Region using Mouse. Might use for a Splash with no Caption.
!Best choice is probably the LAST one BrahnMove1Accept() ... so scroll to the bottom
PROGRAM
MAP
CarlMove PROCEDURE() !I have used this on many machines and know it works
CarlMoveSimpler PROCEDURE() !From https://gist.github.com/fushnisoft/4f9da267e165033e007a
BrahnMoveOriginal PROCEDURE() !Code from Brahn's GIST that
BrahnMoveGetPoz PROCEDURE() !Use GetPosition not Prop:Xpos Prop:Ypos
BrahnMove1Accept PROCEDURE() !No Nested Accept and use GetPosition not Prop:Xpos Prop:Ypos
!^^^^^^ Best Choice ^^^^^^^^^ !Has least code and works fine on MM
END
CODE
START(BrahnMoveOriginal)
START(BrahnMoveGetPoz)
START(BrahnMove1Accept)
START(CarlMoveSimpler)
START(CarlMove)
!======================================================================================
!This code tries to only move the window if it has changed by 3 DLUs from the Prev X/Y.
!I may have done that for a more complet window.
CarlMove PROCEDURE()
AboutWindow WINDOW,AT(,,270,120),CENTER,FONT('Segoe UI',10),COLOR(COLOR:White)
STRING('Carl Move Original'),AT(54,20),FONT(,24,,FONT:bold)
STRING('Drag Me'),AT(103,50),FONT(,16,,FONT:regular)
BUTTON('Halt'),AT(222,0,,9),USE(?Halt),SKIP,FLAT
BUTTON('X'),AT(258,0,11,9),USE(?Xclose),SKIP,STD(STD:Close)
REGION,AT(1,1),USE(?MoveRegion),IMM
END !^^^^^ Region MUST be LAST so it does not interfer with other controls
RgIsMoving BOOL
RgMsOrigX LONG
RgMsOrigY LONG
RgWinOrigX LONG
RgWinOrigY LONG
RgMsPrevX LONG
RgMsPrevY LONG
MX LONG
MY LONG
MinMv EQUATE(3) !Had 3 which had jitter with small moves, but maybe I did it for a complex window
CODE
OPEN(AboutWindow)
?MoveRegion{PROP:Full}=1 !FULL on Window makes it hard to design
!Only set ^^^^^^PROP:Full= 1 ---> If Region is Last or you have NO Button,Check,Entry Controls After the Region. This is an ABOUT window with 1 Buttons
??MoveRegion{PROP:Curosr}=CURSOR:Hand !Make Region Obvious by changing mouse when over it
ACCEPT
CASE ACCEPTED()
OF ?Halt ; LOOP T#=1 TO 9 ; POST(EVENT:CloseWindow,,T#) ; END ; BREAK
END
CASE FIELD()
OF ?MoveRegion
CASE EVENT()
OF EVENT:MouseDown
RgIsMoving = 1
RgMsOrigX = MOUSEX() ; RgMsPrevX = RgMsOrigX
RgMsOrigY = MOUSEY() ; RgMsPrevY = RgMsOrigY
GETPOSITION(0,RgWinOrigX,RgWinOrigY)
OF EVENT:MouseUP
RgIsMoving=0
OF EVENT:MouseMove
IF RgIsMoving THEN
MX=MOUSEX()
MY=MOUSEY()
IF ABS(MX-RgMsPrevX)>MinMv OR ABS(MY-RgMsPrevY)>MinMv THEN !move a little less
RgWinOrigX=RgWinOrigX+(MX-RgMsOrigX)
RgWinOrigY=RgWinOrigY+(MY-RgMsOrigY)
SETPOSITION(0,RgWinOrigX, RgWinOrigY)
RgMsPrevX=mouseX() !must store Prev After moving window because that changes the relative mouse value
RgMsPrevY=mouseY()
END
END !If Is Move
END !Case Event
END
END
!======================================================================================
!Moves window with every EVENT:MouseMove like Brahn. Seems fine ... with this
CarlMoveSimpler PROCEDURE()
AboutWindow WINDOW,AT(,,270,120),CENTER,FONT('Segoe UI',10),COLOR(COLOR:White)
STRING('Carl Move Simpler'),AT(45,20),FONT(,24,,FONT:bold)
STRING('Drag Me'),AT(103,50),FONT(,16,,FONT:regular)
BUTTON('X'),AT(258,0,11,9),USE(?Xclose),SKIP,STD(STD:Close)
REGION,AT(1,1),USE(?MoveRegion),IMM
END !^^^^^ Region MUST be LAST so it does not interfer with other controls
RgIsMoving BOOL
RgMsOrigX LONG
RgMsOrigY LONG
RgWinOrigX LONG
RgWinOrigY LONG
!RgMsPrevX LONG !
!RgMsPrevY LONG
MX LONG
MY LONG
MinMv EQUATE(3) !3 has some jitter with small moves, but maybe I did it for a complex window
CODE
OPEN(AboutWindow)
GETPOSITION(0,x#,y#,w#,h#) ; SETPOSITION(0,x#-w#-4,y#+h#) !so not on top of Carl Window
?MoveRegion{PROP:Full}=1 !FULL on Window makes it hard to design so do it at runtime
!Only set ^^^^^^PROP:Full= 1 ---> If Region is last, or you have NO Button,Check,Entry after the Region
ACCEPT
CASE FIELD()
OF ?MoveRegion
CASE EVENT()
OF EVENT:MouseDown
RgIsMoving = 1
RgMsOrigX = MOUSEX() !; RgMsPrevX = RgMsOrigX
RgMsOrigY = MOUSEY() !; RgMsPrevY = RgMsOrigY
GETPOSITION(0,RgWinOrigX,RgWinOrigY)
OF EVENT:MouseUP
RgIsMoving=0
OF EVENT:MouseMove
IF RgIsMoving THEN
MX=MOUSEX()
MY=MOUSEY()
!IF ABS(MX-RgMsPrevX)>MinMv OR ABS(MY-RgMsPrevY)>MinMv THEN !move a little less
RgWinOrigX=RgWinOrigX+(MX-RgMsOrigX)
RgWinOrigY=RgWinOrigY+(MY-RgMsOrigY)
SETPOSITION(0,RgWinOrigX, RgWinOrigY)
! RgMsPrevX=mouseX() !must store Prev After moving window because that changes the relative mouse value
! RgMsPrevY=mouseY()
!END
END !If Is Move
END !Case Event
END
END
!==================================================================================
BrahnMoveOriginal PROCEDURE() !https://gist.github.com/fushnisoft/4f9da267e165033e007a
AboutWindow WINDOW,AT(,,270,120),FONT('Segoe UI',10),COLOR(COLOR:White),CENTER
STRING('Brahn Move About Window'),AT(14,20),FONT(,24,,FONT:bold)
STRING('Drag Me'),AT(103,77),FONT(,16,,FONT:regular)
BUTTON('X'),AT(258,0,11,9),USE(?Xclose),SKIP,STD(STD:Close)
REGION,AT(1,1),FULL,USE(?MoveRegion),IMM
END !^^^^^ Region MUST be LAST so it does not interfer with other controls
origX LONG
origY LONG
CODE
OPEN(AboutWindow)
GETPOSITION(0,x#,y#,w#,h#) ; SETPOSITION(0,x#+w#+4,y#-h#) !so not on top of Carl Window
ACCEPT
CASE FIELD()
OF ?MoveRegion
CASE EVENT()
OF Event:MouseDown
origX = MOUSEX()
origY = MOUSEY()
ACCEPT
CASE EVENT()
OF Event:MouseUp
BREAK
OF Event:MouseMove
0{Prop:Xpos} = 0{Prop:Xpos} + (MOUSEX() - origX)
0{Prop:Ypos} = 0{Prop:Ypos} + (MOUSEY() - origY)
!== Better ==> SETPOSITION(0,0{Prop:Xpos} + (MOUSEX() - OrigX), 0{Prop:Ypos} + (MOUSEY() - OrigY))
END
END
END
END
END
!==================================================================================
BrahnMoveGetPoz PROCEDURE() !USe GetPosition not Prop:Xpos Prop:Ypos
AboutWindow WINDOW,AT(,,270,120),FONT('Segoe UI',10),COLOR(COLOR:White),CENTER
STRING('Brahn GetPosition Window'),AT(18,20),FONT(,24,,FONT:bold)
STRING('Drag Me'),AT(103,77),FONT(,16,,FONT:regular)
BUTTON('X'),AT(258,0,11,9),USE(?Xclose),SKIP,STD(STD:Close)
REGION,AT(1,1),FULL,USE(?MoveRegion),IMM
END !^^^^^ Region MUST be LAST so it does not interfer with other controls
origX LONG
origY LONG
NowX LONG
NowY LONG
CODE
OPEN(AboutWindow)
GETPOSITION(0,x#,y#,w#,h#) ; SETPOSITION(0,x#+w#+4,y#+h#) !so not on top of Carl Window
ACCEPT
CASE FIELD()
OF ?MoveRegion
CASE EVENT()
OF Event:MouseDown
origX = MOUSEX()
origY = MOUSEY()
ACCEPT
CASE EVENT()
OF Event:MouseUp
BREAK
OF Event:MouseMove
! 0{Prop:Xpos} = 0{Prop:Xpos} + (MOUSEX() - origX)
! 0{Prop:Ypos} = 0{Prop:Ypos} + (MOUSEY() - origY)
GETPOSITION(0,NowX, NowY)
SETPOSITION(0,NowX + (MOUSEX() - OrigX), NowY + (MOUSEY() - OrigY))
END
END
END
END
END
!==================================================================================
! IMO this is the BEST code because it is very small. Note it has some Debug/Trace you can remove.
!==================================================================================
BrahnMove1Accept PROCEDURE() !No Nested Accept and use GetPosition not Prop:Xpos Prop:Ypos
UsePixels BYTE
AboutWindow WINDOW,AT(,,270,120),CENTER,FONT('Segoe UI',10),COLOR(0E1FFFFH),IMM
STRING('Brahn - 1 Accept - Best!'),AT(34,20),FONT(,24,,FONT:bold)
STRING('Click n Drag Me'),AT(9,77),USE(?DragMe),FONT(,16,,FONT:regular)
STRING('Mouse'),AT(97,97),USE(?MouseXY),FONT(,12,,FONT:regular)
BUTTON('X'),AT(258,0,11,9),USE(?Xclose),SKIP,STD(STD:Close)
CHECK('Use Pixels'),AT(9,104),USE(UsePixels),TIP('Try Prop:Pixels to see if smoother moving?<13,10>Ocde in Event:Move ')
REGION,AT(1,1),FULL,USE(?MoveRegion),IMM
END !^^^^^ Region MUST be LAST so it does not interfer with other controls
MsDownX LONG,AUTO
MsDownY LONG,AUTO
WndX LONG,AUTO
WndY LONG,AUTO
MouseIsDown BOOL !Event:MouseDown occured in Region so Move Window
MsMoveCnt LONG !Just curious how many Event:MouseMove occur Trace/Debug
EvtMovedCnt LONG !Just curious how many Event:MouseMove occur Trace/Debug
CODE
OPEN(AboutWindow)
GETPOSITION(0,x#,y#,w#,h#) ; SETPOSITION(0,x#-w#+4,y#-h#) !so not on top of Carl Window
! GOTO NoDebugVersion:
ACCEPT
CASE FIELD()
OF ?MoveRegion
CASE EVENT()
OF Event:MouseDown
0{PROP:Pixels}=UsePixels !TEST? Mark G suggested. Seems smoother but not enough that I would do it.
MsDownX = MOUSEX()
MsDownY = MOUSEY()
MouseIsDown = 1
?DragMe{PROP:Text}='Mouse Down Drag' ; MsMoveCnt=0 ; EvtMovedCnt = 0 ! Trace/Debug
OF Event:MouseUp
MouseIsDown=0
0{PROP:Pixels}='' !TEST?
!You may wish to POST(EVENT:Moved) if you have code that needs this event, seems unlikely
?DragMe{PROP:Text}='Mouse Up (' & MsMoveCnt &' Mouse Moves, ' & EvtMovedCnt &' Move Events)' ! Trace/Debug
OF Event:MouseMove !Event fires for REGION with IMM on any Mouse Over
IF MouseIsDown THEN !Only move window if got Mouse Down previously
GETPOSITION(0,WndX, WndY)
SETPOSITION(0,WndX + (MOUSEX() - MsDownX), WndY + (MOUSEY() - MsDownY))
MsMoveCnt+=1 ! Trace/Debug
END
!Show MouseMove in Region with IMM. Region gets the event for any Mouse OVER the region with IMM, hence the need to trap MouseIsDown=1
?MouseXY{PROP:Text}='Event:MouseMove ' & MOUSEX() &','& MOUSEY() ! Trace/Debug
OF EVENT:Moved ; EvtMovedCnt += 1 !SETPOSITION() does NOT post this ! Trace/Debug
END !Case Event
END !Case Field
END
RETURN
NoDebugVersion: !==================== No Debug Version ====================
HIDE(?UsePixels)
ACCEPT
CASE FIELD()
OF ?MoveRegion
CASE EVENT()
OF Event:MouseDown
MsDownX = MOUSEX()
MsDownY = MOUSEY()
MouseIsDown = 1
OF Event:MouseUp
MouseIsDown=0
OF Event:MouseMove !Event fires for REGION with IMM on any Mouse Over
IF MouseIsDown THEN !Only move window if got Mouse Down previously
GETPOSITION(0,WndX, WndY)
SETPOSITION(0,WndX + (MOUSEX() - MsDownX), WndY + (MOUSEY() - MsDownY))
END
END !Case Event
END !Case Field
END
RETURN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment