flickerstreak@122
|
1 --[[
|
flickerstreak@122
|
2 ReAction Button base class
|
flickerstreak@122
|
3 --]]
|
flickerstreak@122
|
4
|
flickerstreak@122
|
5 -- local imports
|
flickerstreak@122
|
6 local ReAction = ReAction
|
flickerstreak@122
|
7 local L = ReAction.L
|
flickerstreak@122
|
8 local _G = _G
|
flickerstreak@122
|
9 local CreateFrame = CreateFrame
|
flickerstreak@122
|
10 local GetBindingKey = GetBindingKey
|
flickerstreak@122
|
11 local format = string.format
|
flickerstreak@122
|
12
|
flickerstreak@122
|
13 ReAction:UpdateRevision("$Revision: 154 $")
|
flickerstreak@122
|
14
|
flickerstreak@122
|
15 -- libraries
|
flickerstreak@122
|
16 local KB = LibStub("LibKeyBound-1.0")
|
flickerstreak@122
|
17 local LBF = LibStub("LibButtonFacade",true) -- optional
|
flickerstreak@122
|
18
|
flickerstreak@122
|
19 -- private
|
flickerstreak@122
|
20 local trash = CreateFrame("Frame")
|
flickerstreak@122
|
21 local frameList = { }
|
flickerstreak@122
|
22 local idPools = { }
|
flickerstreak@122
|
23
|
flickerstreak@122
|
24 local function kb_onEnter( frame )
|
flickerstreak@122
|
25 KB:Set(frame)
|
flickerstreak@122
|
26 end
|
flickerstreak@122
|
27
|
flickerstreak@122
|
28 -- Button class
|
flickerstreak@122
|
29 local Button = { }
|
flickerstreak@122
|
30
|
flickerstreak@122
|
31 ReAction.Button = Button -- export to ReAction
|
flickerstreak@122
|
32
|
flickerstreak@128
|
33 function Button:New( name, barConfig, bar, idx, inherits, buttonType )
|
flickerstreak@122
|
34 buttonType = buttonType or "CheckButton"
|
flickerstreak@122
|
35
|
flickerstreak@122
|
36 -- create new self
|
flickerstreak@122
|
37 self = setmetatable(
|
flickerstreak@122
|
38 {
|
flickerstreak@122
|
39 bar = bar,
|
flickerstreak@122
|
40 idx = idx,
|
flickerstreak@128
|
41 barConfig = barConfig,
|
flickerstreak@128
|
42 config = barConfig.buttons[idx],
|
flickerstreak@122
|
43 name = name,
|
flickerstreak@122
|
44 },
|
flickerstreak@122
|
45 { __index = self } )
|
flickerstreak@122
|
46
|
flickerstreak@122
|
47 -- have to recycle frames with the same name: CreateFrame() doesn't overwrite
|
flickerstreak@122
|
48 -- existing globals. Can't set to nil in the global because it's then tainted.
|
flickerstreak@122
|
49 -- Caller is responsible for ensuring global uniqueness of names.
|
flickerstreak@122
|
50 local f = name and frameList[name]
|
flickerstreak@122
|
51 if f then
|
flickerstreak@122
|
52 f:SetParent(bar:GetFrame())
|
flickerstreak@122
|
53 else
|
flickerstreak@122
|
54 f = CreateFrame(buttonType, name, bar:GetFrame(), inherits)
|
flickerstreak@122
|
55 if name then
|
flickerstreak@122
|
56 frameList[name] = f
|
flickerstreak@122
|
57 end
|
flickerstreak@122
|
58 end
|
flickerstreak@122
|
59
|
flickerstreak@122
|
60 self.frame = f
|
flickerstreak@122
|
61
|
flickerstreak@122
|
62 if config then
|
flickerstreak@122
|
63 config.name = name
|
flickerstreak@122
|
64 end
|
flickerstreak@122
|
65
|
flickerstreak@122
|
66 -- install LibKeyBound handlers onto frame
|
flickerstreak@122
|
67 function f:GetActionName()
|
flickerstreak@122
|
68 return format("%s:%s", bar:GetName(), idx)
|
flickerstreak@122
|
69 end
|
flickerstreak@122
|
70
|
flickerstreak@122
|
71 local clickBinding = format("CLICK %s:LeftButton", name)
|
flickerstreak@122
|
72 function f:GetHotkey()
|
flickerstreak@122
|
73 return KB:ToShortKey(GetBindingKey(clickBinding))
|
flickerstreak@122
|
74 end
|
flickerstreak@122
|
75
|
flickerstreak@122
|
76 return self
|
flickerstreak@122
|
77 end
|
flickerstreak@122
|
78
|
flickerstreak@122
|
79 function Button:Destroy()
|
flickerstreak@126
|
80 local f = self:GetFrame()
|
flickerstreak@126
|
81 if f then
|
flickerstreak@126
|
82 f:Hide()
|
flickerstreak@126
|
83 f:SetParent(trash)
|
flickerstreak@126
|
84 f:ClearAllPoints()
|
flickerstreak@126
|
85 end
|
flickerstreak@122
|
86 end
|
flickerstreak@122
|
87
|
flickerstreak@128
|
88 function Button:GetBar()
|
flickerstreak@128
|
89 return self.bar
|
flickerstreak@128
|
90 end
|
flickerstreak@128
|
91
|
flickerstreak@122
|
92 function Button:GetFrame()
|
flickerstreak@122
|
93 return self.frame
|
flickerstreak@122
|
94 end
|
flickerstreak@122
|
95
|
flickerstreak@122
|
96 function Button:GetName()
|
flickerstreak@122
|
97 return self.name
|
flickerstreak@122
|
98 end
|
flickerstreak@122
|
99
|
flickerstreak@122
|
100 function Button:GetConfig()
|
flickerstreak@122
|
101 return self.config
|
flickerstreak@122
|
102 end
|
flickerstreak@122
|
103
|
flickerstreak@128
|
104 function Button:GetBarConfig()
|
flickerstreak@128
|
105 -- this is the per-bar Button config structure,
|
flickerstreak@128
|
106 -- not the config structure of the bar itself
|
flickerstreak@128
|
107 return self.barConfig
|
flickerstreak@128
|
108 end
|
flickerstreak@128
|
109
|
flickerstreak@122
|
110 function Button:GetActionID()
|
flickerstreak@122
|
111 -- derived classes should override this
|
flickerstreak@122
|
112 return nil
|
flickerstreak@122
|
113 end
|
flickerstreak@122
|
114
|
flickerstreak@122
|
115 function Button:SetActionIDPool( poolID, maxID )
|
flickerstreak@122
|
116 self.actionPoolID = poolID
|
flickerstreak@122
|
117 self.actionMaxID = maxID
|
flickerstreak@122
|
118 end
|
flickerstreak@122
|
119
|
flickerstreak@122
|
120 function Button:AcquireActionID( id, hint, unique )
|
flickerstreak@122
|
121 local poolID = self.actionPoolID
|
flickerstreak@122
|
122 local maxID = self.actionMaxID
|
flickerstreak@122
|
123 if not poolID or not maxID then
|
flickerstreak@122
|
124 error("AcquireActionID: must setup pool first with SetActionIDPool")
|
flickerstreak@122
|
125 end
|
flickerstreak@123
|
126 local pool = idPools[poolID]
|
flickerstreak@122
|
127 if not pool then
|
flickerstreak@122
|
128 pool = { nWraps = 0, useCount = { } }
|
flickerstreak@122
|
129 for i = 1, maxID do
|
flickerstreak@122
|
130 pool.useCount[i] = 0
|
flickerstreak@122
|
131 end
|
flickerstreak@123
|
132 idPools[poolID] = pool
|
flickerstreak@122
|
133 end
|
flickerstreak@122
|
134 local useCount = pool.useCount
|
flickerstreak@122
|
135 if id == nil then
|
flickerstreak@122
|
136 repeat
|
flickerstreak@126
|
137 local nWraps = pool.nWraps or 0
|
flickerstreak@126
|
138 if hint and (useCount[hint] == nil or useCount[hint] == nWraps) then
|
flickerstreak@122
|
139 id = hint
|
flickerstreak@122
|
140 else
|
flickerstreak@122
|
141 local start = hint or 1
|
flickerstreak@122
|
142 for i = start, maxID do
|
flickerstreak@122
|
143 if useCount[i] == nil or useCount[i] == nWraps then
|
flickerstreak@122
|
144 id = i
|
flickerstreak@122
|
145 break
|
flickerstreak@122
|
146 end
|
flickerstreak@122
|
147 end
|
flickerstreak@122
|
148 if not id then
|
flickerstreak@122
|
149 for i = 1, start do
|
flickerstreak@122
|
150 if useCount[i] == nil or useCount[i] == nWraps then
|
flickerstreak@122
|
151 id = i
|
flickerstreak@122
|
152 break
|
flickerstreak@122
|
153 end
|
flickerstreak@122
|
154 end
|
flickerstreak@122
|
155 end
|
flickerstreak@122
|
156 end
|
flickerstreak@122
|
157 if id == nil then
|
flickerstreak@122
|
158 if unique then
|
flickerstreak@122
|
159 return nil
|
flickerstreak@122
|
160 end
|
flickerstreak@122
|
161 pool.nWraps = nWraps + 1
|
flickerstreak@122
|
162 end
|
flickerstreak@126
|
163 until id ~= nil
|
flickerstreak@122
|
164 end
|
flickerstreak@122
|
165 useCount[id] = (useCount[id] or 0) + 1
|
flickerstreak@122
|
166 return id
|
flickerstreak@122
|
167 end
|
flickerstreak@122
|
168
|
flickerstreak@122
|
169 function Button:ReleaseActionID( id )
|
flickerstreak@122
|
170 local poolID = self.actionPoolID
|
flickerstreak@122
|
171 if not poolID then
|
flickerstreak@122
|
172 error("ReleaseActionID: must setup pool first with SetActionIDPool")
|
flickerstreak@122
|
173 end
|
flickerstreak@123
|
174 local pool = idPools[poolID]
|
flickerstreak@122
|
175 if pool and id and pool.useCount[id] then
|
flickerstreak@122
|
176 pool.useCount[id] = pool.useCount[id] - 1
|
flickerstreak@122
|
177 pool.nWraps = min(pool.useCount[id], pool.nWraps)
|
flickerstreak@122
|
178 end
|
flickerstreak@122
|
179 end
|
flickerstreak@122
|
180
|
flickerstreak@122
|
181 function Button:Refresh()
|
flickerstreak@122
|
182 self.bar:PlaceButton( self, self.frame:GetWidth(), self.frame:GetHeight() )
|
flickerstreak@122
|
183 end
|
flickerstreak@122
|
184
|
flickerstreak@122
|
185 function Button:SetKeybindMode( mode )
|
flickerstreak@122
|
186 local f = self.frame
|
flickerstreak@122
|
187 if mode then
|
flickerstreak@122
|
188 self.oldOnEnter = f:GetScript("OnEnter")
|
flickerstreak@122
|
189 f:SetScript("OnEnter", kb_onEnter)
|
flickerstreak@124
|
190 elseif self.oldOnEnter then
|
flickerstreak@122
|
191 f:SetScript("OnEnter", self.oldOnEnter)
|
flickerstreak@122
|
192 self.oldOnEnter = nil
|
flickerstreak@122
|
193 end
|
flickerstreak@128
|
194 self:ShowGridTemp(mode)
|
flickerstreak@122
|
195 self:UpdateKeybindModeDisplay( mode )
|
flickerstreak@122
|
196 end
|
flickerstreak@122
|
197
|
flickerstreak@122
|
198 function Button:UpdateKeybindModeDisplay( mode )
|
flickerstreak@122
|
199 self.border = self.border or _G[format("%sBorder",tostring(self:GetName()))]
|
flickerstreak@122
|
200 if self.border then
|
flickerstreak@122
|
201 if mode then
|
flickerstreak@122
|
202 self.border:SetVertexColor(KB:GetColorKeyBoundMode())
|
flickerstreak@122
|
203 self.border:Show()
|
flickerstreak@122
|
204 else
|
flickerstreak@122
|
205 self.border:Hide()
|
flickerstreak@122
|
206 end
|
flickerstreak@122
|
207 end
|
flickerstreak@122
|
208 end
|
flickerstreak@122
|
209
|
flickerstreak@122
|
210 function Button:UpdateHotkey( hotkey )
|
flickerstreak@122
|
211 hotkey = hotkey or self.hotkey
|
flickerstreak@122
|
212 if not hotkey then
|
flickerstreak@122
|
213 hotkey = _G[format("%sHotKey", tostring(self:GetName()))]
|
flickerstreak@122
|
214 self.hotkey = hotkey
|
flickerstreak@122
|
215 end
|
flickerstreak@122
|
216 if hotkey then
|
flickerstreak@122
|
217 local txt = self.frame:GetHotkey()
|
flickerstreak@122
|
218 hotkey:SetText( txt )
|
flickerstreak@122
|
219 if txt == nil or txt == "" then
|
flickerstreak@122
|
220 hotkey:Hide()
|
flickerstreak@122
|
221 else
|
flickerstreak@122
|
222 hotkey:Show()
|
flickerstreak@122
|
223 end
|
flickerstreak@122
|
224 end
|
flickerstreak@122
|
225 end
|
flickerstreak@122
|
226
|
flickerstreak@122
|
227 function Button:GetActionIDLabel( create )
|
flickerstreak@122
|
228 local f = self.frame
|
flickerstreak@122
|
229 if not f.actionIDLabel and create then
|
flickerstreak@122
|
230 local label = f:CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
|
flickerstreak@122
|
231 label:SetAllPoints()
|
flickerstreak@122
|
232 label:SetJustifyH("CENTER")
|
flickerstreak@122
|
233 label:SetShadowColor(0,0,0,1)
|
flickerstreak@122
|
234 label:SetShadowOffset(2,-2)
|
flickerstreak@122
|
235 f.actionIDLabel = label -- store the label with the frame for recycling
|
flickerstreak@122
|
236 end
|
flickerstreak@122
|
237 return f.actionIDLabel
|
flickerstreak@122
|
238 end
|
flickerstreak@122
|
239
|
flickerstreak@122
|
240 function Button:UpdateActionIDLabel( show )
|
flickerstreak@122
|
241 local label = self:GetActionIDLabel( show )
|
flickerstreak@122
|
242 if label then
|
flickerstreak@122
|
243 if show then
|
flickerstreak@122
|
244 local id = self:GetActionID()
|
flickerstreak@122
|
245 if id then
|
flickerstreak@122
|
246 label:SetText(tostring(id))
|
flickerstreak@122
|
247 label:Show()
|
flickerstreak@122
|
248 return
|
flickerstreak@122
|
249 end
|
flickerstreak@122
|
250 end
|
flickerstreak@122
|
251 label:Hide()
|
flickerstreak@122
|
252 end
|
flickerstreak@122
|
253 end
|
flickerstreak@122
|
254
|
flickerstreak@122
|
255 function Button:SetNormalVertexColor( r, g, b, a )
|
flickerstreak@122
|
256 if LBF then
|
flickerstreak@122
|
257 LBF:SetNormalVertexColor(self.frame, r, g, b, a)
|
flickerstreak@122
|
258 else
|
flickerstreak@122
|
259 self.frame:GetNormalTexture():SetVertexColor(r,g,b,a)
|
flickerstreak@122
|
260 end
|
flickerstreak@122
|
261 end
|
flickerstreak@122
|
262
|
flickerstreak@122
|
263 function Button:GetNormalVertexColor()
|
flickerstreak@122
|
264 if LBF then
|
flickerstreak@122
|
265 return LBF:GetNormalVertexColor(self.frame)
|
flickerstreak@122
|
266 else
|
flickerstreak@122
|
267 return self.frame:GetNormalTexture():GetVertexColor()
|
flickerstreak@122
|
268 end
|
flickerstreak@122
|
269 end
|
flickerstreak@122
|
270
|
flickerstreak@122
|
271 function Button:UpdateShowGrid()
|
flickerstreak@122
|
272 -- does nothing by default
|
flickerstreak@122
|
273 end
|
flickerstreak@128
|
274
|
flickerstreak@128
|
275 function Button:ShowGridTemp(show)
|
flickerstreak@128
|
276 -- does nothing by default
|
flickerstreak@128
|
277 end
|
flickerstreak@128
|
278
|
flickerstreak@128
|
279 function Button:ShowGrid(show)
|
flickerstreak@128
|
280 -- does nothing by default
|
flickerstreak@128
|
281 end
|