-
Notifications
You must be signed in to change notification settings - Fork 2
/
menu.lua
212 lines (174 loc) · 6.13 KB
/
menu.lua
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
-- Mark H Carolan
--
-- Stroople project
-- © 2010 Mark H Carolan, Gregory S Hooper
module(..., package.seeall)
local strokeWidthRegular = 3
local strokeWidthHilite = 10
local none, emboss, dropShadow = 0, 1, 2
local dropShadowDistance = 6
function createMenu(params)
local menu = display.newGroup()
menu.items = params.items
menu.isToggle = params.isToggle
menu.highlight = { 240, 250, 240, 255 }
menu.mode = none
local yPos = params.y or 0
local xPos = params.x or display.contentWidth/2
local spacing = params.spacing or 40 -- y spacing
local xSpacing = params.xSpacing or 0
local width = params.width or 100
local itemHeight = params.itemHeight or 40
local textHeight = params.textHeight or 32
local insetX = params.insetX or 0
local insetY = params.insetY or 0
function menu:setText(i, t)
self[i][2].text = t
self[i][3].text = t
end
function menu:getText(i)
return self[i][2].text
end
function menu:button(item, width, height, textHeight, insetX, insetY, emboss)
local button = display.newGroup()
if emboss then
self.mode = emboss
self.highlight = { 240, 250, 240, 255 }
if not item.backColor then item.backColor = {32, 32, 32} end
if not item.foreColor then item.foreColor = {0, 0, 0} end
local r = display.newRoundedRect(0, 0, width, height, 5)
r:setFillColor(item.backColor[1], item.backColor[2], item.backColor[3])
r.savedFillColor = item.backColor
r.strokeWidth = strokeWidthRegular
r:setStrokeColor(item.foreColor[1], item.foreColor[2], item.foreColor[3])
r.x = insetX
r.y = insetY
button:insert(r)
-- Fake emboss.
local t0 = display.newText(item.text, 0, 0, "Verdana-Bold", textHeight)
t0.x = -1
t0.y = -1
t0:setTextColor(220,220, 220)
button:insert(t0) -- index 2
local t1 = display.newText(item.text, 1, 1, "Verdana-Bold", textHeight)
t1.x = 0
t1.y = 0
t1:setTextColor(item.foreColor[1], item.foreColor[2], item.foreColor[3])
button:insert(t1) -- index 3
else -- drop shadow version
self.mode = dropShadow
self.highlight = { 240, 250, 240, 32 }
if not item.backColor then item.backColor = {0, 0, 0, 0} end
if not item.foreColor then item.foreColor = {32, 32, 32} end
local r = display.newRoundedRect(0, 0, width, height, 5)
r:setFillColor(item.backColor[1], item.backColor[2], item.backColor[3], 0)
r.savedFillColor = item.backColor
r.strokeWidth = strokeWidthRegular
r:setStrokeColor(item.foreColor[1], item.foreColor[2], item.foreColor[3], 0)
r.x = insetX
r.y = insetY
r.isVisible = false
r.isHitTestable = true
button:insert(r) -- [1]
-- drop shadow.
local t0 = display.newText(item.text, 0, 0, "Verdana-Bold", textHeight)
t0.x = dropShadowDistance
t0.y = dropShadowDistance
t0:setTextColor(0, 0, 0)
button:insert(t0) -- index [2]
local t1 = display.newText(item.text, 1, 1, "Verdana-Bold", textHeight)
t1.x = 0
t1.y = 0
t1:setTextColor(item.foreColor[1], item.foreColor[2], item.foreColor[3])
button:insert(t1) -- index [3]
end
button.listener = item.handler -- store for removal
button.listenerParam = item.handlerParam
if button.listener then button:addEventListener("touch", button) end
function button:inside(event)
if event.x < self. stageBounds.xMin or
event.x > self.stageBounds.xMax or
event.y < self.stageBounds.yMin or
event.y > self.stageBounds.yMax then
return false
else
return true
end
end
function button:touch(event)
if event.phase == "began" then
display.getCurrentStage():setFocus(self)
if self.parent.mode == emboss then
self[1]:setFillColor(self.parent.highlight[1], self.parent.highlight[2], self.parent.highlight[3], self.parent.highlight[4])
elseif self.parent.mode == dropShadow then
self[2].x = self[2].x - dropShadowDistance/2
self[2].y = self[2].y - dropShadowDistance/2
self[3].x = self[3].x + dropShadowDistance/2
self[3].y = self[3].y + dropShadowDistance/2
end
elseif event.phase == "ended" then
if self.parent.mode == emboss then
self[1]:setFillColor(self[1].savedFillColor[1],
self[1].savedFillColor[2], self[1].savedFillColor[3], self[1].savedFillColor[4])
elseif self.parent.mode == dropShadow then
self[2].x = self[3].x + dropShadowDistance/2
self[2].y = self[3].y + dropShadowDistance/2
self[3].x = self[3].x - dropShadowDistance/2
self[3].y = self[3].y - dropShadowDistance/2
end
display.getCurrentStage():setFocus(nil)
if self:inside(event) then
self.listener(event, self.listenerParam)
if self.parent.isToggle then
if self.parent.savedHilite then
self.parent[self.parent.savedHilite][1].strokeWidth = strokeWidthRegular
end
self[1].strokeWidth = strokeWidthHilite
self.parent.savedHilite = self.myIndex
end
end
elseif event.phase == "cancelled" then
if self.parent.mode == emboss then
self[1]:setFillColor(self[1].savedFillColor[1],
self[1].savedFillColor[2], self[1].savedFillColor[3], self[1].savedFillColor[4])
elseif self.parent.mode == dropShadow then
self[2].x = self[3].x + dropShadowDistance/2
self[2].y = self[3].y + dropShadowDistance/2
self[3].x = self[3].x - dropShadowDistance/2
self[3].y = self[3].y - dropShadowDistance/2
end
display.getCurrentStage():setFocus(nil)
end
end
return button
end
function menu:cleanup()
for i = self.numChildren, 1, -1 do
local button = self[i]
if button then
if button.listener then
button:removeEventListener("touch", button.listener)
end
button:removeSelf()
else
db.print("NULL BUTTON!")
end
end
end
for i = 1, #menu.items do
local item = menu:button(menu.items[i], width, itemHeight, textHeight, insetX, insetY)
item.x = xPos
item.y = yPos
yPos = yPos + spacing
xPos = xPos + xSpacing
item.myIndex = i -- for managing toggle lists; so item knows its index
if menu.isToggle then
if item.myIndex == params.defaultItem then
item[1].strokeWidth = strokeWidthHilite
menu.savedHilite = item.myIndex
end
end
menu:insert(item)
end
return menu
end