Last active
March 17, 2021 17:14
-
-
Save CarlTBarnes/3bc3f0164071bc0548df2db8b2fd6963 to your computer and use it in GitHub Desktop.
Region dragging with mouse example, e.g. for Splash Window with no title bar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!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