-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcircle-drawer.pb
149 lines (129 loc) · 5.21 KB
/
circle-drawer.pb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
; PUREBASIC: This code results in a 118 KB executable on Win64 (didn't check sizes on MacOS & Linux)
EnableExplicit
Enumeration Gadgets
#MainWin
#SizeWin
#UndoButton
#RedoButton
#Canvas
#Trackbar
#SizeLabel
EndEnumeration
Structure CircleInfo
x.i ; of center point
y.i ; of center point
r.i ; radius
EndStructure
#Default_Radius = 20
Global NewRadius, OldRadius,
NewList CircleList.CircleInfo() ; this list can only grow, as circle deletion is not required
Procedure.b PointBelongsToCircle(x, y)
Protected distance.f
ForEach CircleList()
distance = Sqr(Pow(x - CircleList()\x, 2) + Pow(y - CircleList()\y, 2))
If distance <= CircleList()\r
ProcedureReturn #True
EndIf
Next
ProcedureReturn #False
EndProcedure
Procedure UndobuttonClick()
MessageRequester("Information", "Undo functionality not yet implemented.", #PB_MessageRequester_Info)
EndProcedure
Procedure RedobuttonClick()
MessageRequester("Information", "Redo functionality not yet implemented.", #PB_MessageRequester_Info)
EndProcedure
Procedure ClearSelection() ; iterate over all circles and fill them with 'non-selected' color
ForEach CircleList()
If StartDrawing(CanvasOutput(#Canvas)) ; CanvasOutput() result is valid for only ONE drawing session
FillArea(CircleList()\x, CircleList()\y, -1, #White) ; auto-select new circle as per spec?
StopDrawing()
EndIf
Next
EndProcedure
Procedure SelectCircle(x, y) ; select the current list member circle
If StartDrawing(CanvasOutput(#Canvas))
FillArea(x, y, -1, #Yellow)
StopDrawing()
EndIf
EndProcedure
Procedure CanvasLeftClick()
Protected x = GetGadgetAttribute(#Canvas, #PB_Canvas_MouseX),
y = GetGadgetAttribute(#Canvas, #PB_Canvas_MouseY)
If PointBelongsToCircle(x, y)
SelectCircle(x, y)
Else
ClearSelection(); as we are about to select the new circle below
If StartDrawing(CanvasOutput(#Canvas)) ; CanvasOutput() result is valid for only ONE drawing session
DrawingMode(#PB_2DDrawing_Outlined)
Circle(x, y, #Default_Radius + 10, #Black)
FillArea(x, y, -1, #Red) ; auto-select new circle as per spec?
StopDrawing()
;
AddElement(CircleList())
CircleList()\x = x
CircleList()\y = y
CircleList()\r = #Default_Radius + 10
EndIf
EndIf
EndProcedure
Procedure CloseSizeAdjustmentWindow() ; event procedures cannot have parameters in PureBasic
CloseWindow(#SizeWin)
DisableWindow(#MainWin, #False)
If OldRadius <> NewRadius ; apply NewRadius set by ShowSizeAdjustmentWindow() to current circle
Debug "Need to redraw circle with new radius"
EndIf
EndProcedure
Procedure SliderMoved()
NewRadius = GetGadgetState(#Trackbar)
;Debug NewRadius
EndProcedure
Procedure ShowSizeAdjustmentWindow(x, y, r)
If OpenWindow(#SizeWin, #PB_Ignore, #PB_Ignore, 230, 80, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
StickyWindow(#SizeWin, #True)
DisableWindow(#MainWin, #True)
;
TextGadget(#PB_Any, 20, 10, 200, 20, "Adjust diameter of circle at " + "(" + Str(x) + ", " + Str(y) + ")")
TrackBarGadget(#Trackbar, 20, 40, 200, 20, #Default_Radius, #Default_Radius * 3, #PB_TrackBar_Ticks)
SetGadgetState(#Trackbar, r) ; set trackbar to the current radius value of the selected circle
BindGadgetEvent(#Trackbar, @SliderMoved(), #PB_EventType_LeftClick);#PB_Event_Gadget)
; window needs its own close event - otherwise closing it terminates the application in event loop
BindEvent(#PB_Event_CloseWindow, @CloseSizeAdjustmentWindow(), #SizeWin) ; close via system menu
EndIf
EndProcedure
Procedure CanvasRightClick()
Protected x = GetGadgetAttribute(#Canvas, #PB_Canvas_MouseX),
y = GetGadgetAttribute(#Canvas, #PB_Canvas_MouseY),
cx, cy, cr
If PointBelongsToCircle(x, y)
; circle on which the user just right-clicked
cx = CircleList()\x
cy = CircleList()\y
cr = CircleList()\r
OldRadius = cr
ShowSizeAdjustmentWindow(cx, cy, cr) ; pass in all 3 circle values: x & y for text label; r for initial trackbar position
EndIf
EndProcedure
Procedure ShowMainWindow()
If OpenWindow(#MainWin, #PB_Ignore, #PB_Ignore, 400, 300, "7GUI - Circle Drawer task in Purebasic", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
ButtonGadget(#UndoButton, 135, 5, 60, 25, "Undo")
ButtonGadget(#RedoButton, 205, 5, 60, 25, "Redo")
CanvasGadget(#Canvas, 5, 35, 390, 260, #PB_Canvas_Border)
SetGadgetAttribute(#Canvas, #PB_Canvas_Cursor, #PB_Cursor_Cross)
;
BindGadgetEvent(#UndoButton, @UndobuttonClick())
BindGadgetEvent(#Redobutton, @RedobuttonClick())
BindGadgetEvent(#Canvas, @CanvasLeftClick(), #PB_EventType_LeftClick)
BindGadgetEvent(#Canvas, @CanvasRightClick(), #PB_EventType_RightClick)
EndIf
EndProcedure
ShowMainWindow() ; a window must be open for the eventloop to run
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow
End
; IDE Options = PureBasic 6.02 LTS (Windows - x64)
; CursorPosition = 126
; FirstLine = 77
; Folding = --
; EnableXP
; DPIAware
; Executable = CircleDrawer.exe