My quest to perfect sizing handles continues. I'm getting in such a mess with it.
The cursor test isn't accurate, especially when the shape is rotated. What do I need to adjust the mouse or handle position by based on the rotation?
How can I tell what to do with the sizing handle when the shape is rotated? For example, right now the code thinks it's always going to need to adjust the height, even when the handle is on the right. I'd really rather avoid doing something like this:
Code: Select all
If a => 0 And a < 24
*b\handle\which = #HANDLE_N
*b\handle\which = #HANDLE_NE
*b\handle\which = #HANDLE_E
*b\handle\which = #HANDLE_SE
*b\handle\which = #HANDLE_S
*b\handle\which = #HANDLE_SW
*b\handle\which = #HANDLE_W
*b\handle\which = #HANDLE_NW
ElseIf a => 24 And a < 48
*b\handle\which = #HANDLE_NE
*b\handle\which = #HANDLE_E
; ...and so on...
ElseIf a => 48 And a < 72
ElseIf a => 72 And a < 96
ElseIf a => 96 And a < 120
ElseIf a => 120 And a < 144
ElseIf a => 144 And a < 168
ElseIf a => 168 And a < 192
ElseIf a => 192 And a < 216
ElseIf a => 216 And a < 240
ElseIf a => 240 And a < 264
ElseIf a => 264 And a < 288
ElseIf a => 288 And a < 312
ElseIf a => 312 And a < 336
ElseIf a => 336 And a < 360
EndIf
Code: Select all
EnableExplicit
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Structure Point : x.i : y.i : EndStructure
CompilerEndIf
Procedure rotatePoint(*point.Point, *rotationCenterPoint.Point, degrees.F, *_return.Point)
Define radians.f = Radian(degrees)
Define pointX.f = *point\x - *rotationCenterPoint\x
Define pointY.f = *point\y - *rotationCenterPoint\y
Define newPointX.f = pointX * Cos(radians) - pointY * Sin(radians)
Define newPointY.f = pointX * Sin(radians) + pointY * Cos(radians)
*_return\x = newPointX + *rotationCenterPoint\x
*_return\y = newPointY + *rotationCenterPoint\y
EndProcedure
Structure Box
x.i : y.i
w.i : h.i
handleCur.Point
handleOrig.Point
angle.f
EndStructure
Global currentPoint.Point, lastPoint.Point, resize
Declare UpdateBoxHandle()
Global *b.Box = AllocateStructure(Box)
With *b
\x = 200 : \y = 150
\w = 100 : \h = 125
\handleCur\x = \x + (\w / 2)
\handleCur\y = \y
CopyStructure(@\handleCur, @\handleOrig, Point)
\angle = 45
EndWith
UpdateBoxHandle()
Procedure UpdateBoxHandle()
Protected handle.Point, center.Point, newPos.Point
handle\x = *b\x + (*b\w / 2)
handle\y = *b\y - 4
center\x = *b\x + *b\w / 2
center\y = *b\y + *b\h / 2
rotatePoint(@handle, @center, *b\angle, *b\handleCur)
*b\handleCur\x - 4
*b\handleCur\y - 4
EndProcedure
Procedure DrawCanvas()
Protected txt$
txt$ = ~"Left/right to rotate\n\n0 to reset\n\nEscape to end\n\n\nAngle: " + Str(*b\angle) + Chr(176)
If StartVectorDrawing(CanvasVectorOutput(0))
VectorSourceColor(RGBA(0, 0, 0, 255))
FillVectorOutput()
VectorSourceColor(RGBA(255, 255, 255, 255))
MovePathCursor(20, 20)
DrawVectorParagraph(txt$, 200, 200)
RotateCoordinates(*b\x + *b\w / 2, *b\y + *b\h / 2, *b\angle)
AddPathBox(*b\x, *b\y, *b\w, *b\h)
VectorSourceColor(RGBA(0, 0, 255, 255))
StrokePath(1)
StopVectorDrawing()
EndIf
If StartDrawing(CanvasOutput(0))
Box(*b\handleCur\x, *b\handleCur\y, 8, 8, RGB(255, 255, 255))
Box(*b\handleOrig\x, *b\handleOrig\y, 8, 8, RGB(255, 165, 0))
DrawingMode(#PB_2DDrawing_Transparent)
StopDrawing()
EndIf
EndProcedure
Procedure OnCanvasEvents()
Protected offset.Point, newY, newH, mousePos.Point, center.Point
Select EventType()
Case #PB_EventType_MouseMove
currentPoint\x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
currentPoint\y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
If resize & GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
offset\y = currentPoint\y - lastPoint\y
*b\y + offset\y
*b\h - offset\y
UpdateBoxHandle()
DrawCanvas()
Else
center\x = *b\x + *b\w / 2
center\y = *b\y + *b\h / 2
rotatePoint(@currentPoint, @center, -*b\angle, @mousePos)
If mousePos\x => *b\handleOrig\x And mousePos\x < *b\handleOrig\x + 8 And
mousePos\y => *b\handleOrig\y And mousePos\y < *b\handleOrig\y + 8
resize = 1
SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
Else
SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_Default)
EndIf
EndIf
lastPoint\x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
lastPoint\y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
Case #PB_EventType_LeftButtonUp
resize = 0
SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_Default)
Case #PB_EventType_KeyDown
Select GetGadgetAttribute(0, #PB_Canvas_Key)
Case #PB_Shortcut_Left
*b\angle - 5
If *b\angle < 0
*b\angle = 359
EndIf
If *b\angle > 359
*b\angle = 0
EndIf
UpdateBoxHandle()
DrawCanvas()
Case #PB_Shortcut_Right
*b\angle + 5
If *b\angle < 0
*b\angle = 359
EndIf
If *b\angle > 359
*b\angle = 0
EndIf
UpdateBoxHandle()
DrawCanvas()
Case #PB_Shortcut_0
*b\angle = 0
UpdateBoxHandle()
DrawCanvas()
Case #PB_Shortcut_Escape : End
DrawCanvas()
EndSelect
EndSelect
EndProcedure
If OpenWindow(0, 0, 0, 640, 480, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 640, 480, #PB_Canvas_Keyboard)
BindGadgetEvent(0, @OnCanvasEvents(), #PB_All)
DrawCanvas()
SetActiveGadget(0)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf