comparison classes/ReAction_ActionType.lua @ 7:f920db5fc6b1

version 0.3
author Flick <flickerstreak@gmail.com>
date Tue, 20 Mar 2007 21:25:29 +0000
parents
children c05fd3e18b4f
comparison
equal deleted inserted replaced
6:2da5089ab7ff 7:f920db5fc6b1
1 -- The ReAction.ActionType mixin defines 'regular' action button functionality
2 -- and is an implementation of the ReAction.IActionType interface.
3 --
4 -- The Mixin assumes that it is being mixed in with a ReAction-derived class
5 -- which implements the ReAction.IDisplay and ReAction.ActionType.IDisplay interfaces.
6 --
7 -- This mixin using the following configuration properties:
8 --
9 -- self.config = {
10 -- selfcast = nil / "alt" / "ctrl" / "shift" / "auto" / "none". nil (default) = use Interface Options menu setting.
11 -- }
12 --
13
14 local AceOO = AceLibrary("AceOO-2.0")
15
16 ReAction.ActionType = AceOO.Mixin {
17 -- ReAction.IActionType interface
18 "SetID",
19 "GetID",
20 "SetupAction",
21 "UpdateAction",
22 "PickupAction",
23 "PlaceAction",
24 "IsActionEmpty",
25 "UpdateTooltip",
26
27 -- event handlers
28 "ACTIONBAR_SLOT_CHANGED",
29 "PLAYER_ENTERING_WORLD",
30 "ACTIONBAR_SHOWGRID",
31 "ACTIONBAR_HIDEGRID",
32 "ACTIONBAR_UPDATE_STATE",
33 "ACTIONBAR_UPDATE_USABLE",
34 "UNIT_INVENTORY_CHANGED",
35 "CRAFT_SHOW",
36 "PLAYER_ENTER_COMBAT",
37 "PLAYER_LEAVE_COMBAT",
38 "START_AUTOREPEAT_SPELL",
39 "STOP_AUTOREPEAT_SPELL",
40 "OnAttributeChanged",
41
42 -- internal functions
43 "UpdateSelfcast",
44 "UpdateIcon",
45 "UpdateInUse",
46 "UpdateCount",
47 "UpdateMacroText",
48 "UpdateUsable",
49 "UpdateCooldown",
50 "UpdateActionEvents",
51 }
52
53 local RAAT = ReAction.ActionType
54
55
56 -- Required display elements
57 RAAT.IDisplay = AceOO.Interface {
58 DisplayUsable = "function", -- DisplayUsable(bool, notEnoughMana, outOfRange), change display to indicate action usable/unusable
59 DisplayEquipped = "function", -- DisplayEquipped(bool)
60 DisplayAutoRepeat = "function", -- DisplayAutoRepeat(bool)
61 DisplayInUse = "function", -- DisplayInUse(bool)
62 DisplayIcon = "function", -- DisplayIcon(texture), nil means empty slot
63 DisplayName = "function", -- DisplayName(text), macro names
64 DisplayCount = "function", -- DisplayCount(number), stack count
65 DisplayCooldown = "function", -- DisplayCooldown(start,duration,enable)
66 }
67
68
69 ---------------------------------------
70 -- ReAction.IActionType interface implementation
71 ---------------------------------------
72 function RAAT:SetID( id, page )
73 local f = self:GetActionFrame()
74 id = tonumber(id) -- force data integrity
75 page = tonumber(page)
76 local button = page and ("-page"..page) or "*"
77 if id then
78 f:SetAttribute("*action"..button, id)
79 if page and page > 1 and self.config.selfcast == "right-click" then
80 -- disable right-click auto-cast
81 self.config.selfcast = nil
82 end
83 elseif page then
84 f:SetAttribute("*action"..button, ATTRIBUTE_NOOP)
85 end
86 self:UpdateSelfcast()
87 end
88
89 function RAAT:GetID(page)
90 local f = self:GetActionFrame()
91 page = tonumber(page)
92 local button = page and ("page"..page) or SecureStateChild_GetEffectiveButton(f)
93 return SecureButton_GetModifiedAttribute(f, "action", button)
94 end
95
96 function RAAT:SetupAction()
97 local f = self:GetActionFrame()
98 f:SetAttribute("useparent*", true)
99 f:SetAttribute("type", "action")
100
101 self:RegisterEvent("PLAYER_ENTERING_WORLD")
102 self:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
103 self:RegisterEvent("ACTIONBAR_SHOWGRID")
104 self:RegisterEvent("ACTIONBAR_HIDEGRID")
105
106 self:UpdateSelfcast()
107
108 f:SetScript("OnAttributeChanged", function(frame,name,value) self:OnAttributeChanged(name,value) end)
109 end
110
111 function RAAT:UpdateAction()
112 self:UpdateIcon()
113 self:UpdateCount()
114 self:UpdateMacroText()
115 self:UpdateUsable()
116 self:UpdateCooldown()
117 self:UpdateActionEvents()
118 end
119
120 function RAAT:PickupAction()
121 PickupAction(self:GetID())
122 self:UpdateAction()
123 end
124
125 function RAAT:PlaceAction()
126 if not InCombatLockdown() then
127 -- PlaceAction() is protected. However the user can still drop a new action
128 -- onto a button while in combat by dragging then clicking, because
129 -- UseAction() appears to swap the cursor action for the current action if
130 -- an action is on the cursor.
131 PlaceAction(self:GetID())
132 end
133 self:UpdateActionEvents()
134 self:UpdateIcon()
135 end
136
137 function RAAT:IsActionEmpty()
138 local slot = self:GetID()
139 return not(slot and HasAction(slot))
140 end
141
142 function RAAT:UpdateTooltip()
143 local action = self:GetID()
144 if action and GameTooltip:IsOwned(self:GetActionFrame()) then
145 GameTooltip:SetAction(action)
146 end
147 end
148
149
150
151
152
153
154
155 -----------------------------
156 -- Event Handling
157 -----------------------------
158 function RAAT:ACTIONBAR_SLOT_CHANGED(slot)
159 if slot == 0 or slot == self:GetID() then
160 self:UpdateAction()
161 end
162 end
163
164 function RAAT:PLAYER_ENTERING_WORLD()
165 self:UpdateAction()
166 end
167
168 function RAAT:ACTIONBAR_SHOWGRID()
169 self:TempShow(true)
170 end
171
172 function RAAT:ACTIONBAR_HIDEGRID()
173 self:TempShow(false)
174 end
175
176 function RAAT:ACTIONBAR_UPDATE_STATE()
177 self:UpdateInUse()
178 end
179
180 function RAAT:ACTIONBAR_UPDATE_USABLE()
181 self:UpdateUsable()
182 self:UpdateCooldown()
183 end
184
185 function RAAT:UNIT_INVENTORY_CHANGED(unit)
186 if unit == "player" then
187 self:UpdateIcon()
188 self:UpdateCount()
189 end
190 end
191
192 function RAAT:CRAFT_SHOW()
193 self:UpdateInUse()
194 end
195
196 function RAAT:PLAYER_ENTER_COMBAT()
197 if IsAttackAction(self:GetID()) then
198 self:DisplayAutoRepeat(true)
199 self:UpdateInUse()
200 end
201 end
202
203 function RAAT:PLAYER_LEAVE_COMBAT()
204 if IsAttackAction(self:GetID()) then
205 self:DisplayAutoRepeat(false)
206 self:UpdateInUse()
207 end
208 end
209
210 function RAAT:START_AUTOREPEAT_SPELL()
211 if IsAutoRepeatAction(self:GetID()) then
212 self:DisplayAutoRepeat(true)
213 end
214 end
215
216 function RAAT:STOP_AUTOREPEAT_SPELL()
217 if not IsAttackAction(self:GetID()) then
218 self:DisplayAutoRepeat(false)
219 self:UpdateInUse()
220 end
221 end
222
223 function RAAT:OnAttributeChanged(name, value)
224 if self.config then
225 self:UpdateAction()
226 self:UpdateDisplay()
227 end
228 end
229
230
231
232
233 ---------------------------------
234 -- Internal methods
235 ---------------------------------
236 function RAAT:UpdateSelfcast()
237 if not InCombatLockdown() then
238 local c = self.config and self.config.selfcast
239 local f = self:GetActionFrame()
240
241 f:SetAttribute("alt-unit*",nil)
242 f:SetAttribute("ctrl-unit*",nil)
243 f:SetAttribute("shift-unit*",nil)
244 f:SetAttribute("*unit2",nil)
245 if c == nil then
246 f:SetAttribute("unit",nil)
247 f:SetAttribute("checkselfcast", true)
248 else
249 f:SetAttribute("checkselfcast",ATTRIBUTE_NOOP)
250 f:SetAttribute("unit","none") -- "none" gives you the glowing cast hand if no target selected, or casts on target if target selected
251 if c == "none" then
252 -- nothing to do
253 elseif c == "alt" or c == "ctrl" or c == "shift" then
254 f:SetAttribute(c.."-unit*","player")
255 elseif c == "right-click" then
256 if f:GetAttribute("*action-page2") then
257 -- right-click modifier not supported with multipage
258 self.config.selfcast = nil
259 f:SetAttribute("unit",nil)
260 f:SetAttribute("checkselfcast",true)
261 else
262 f:SetAttribute("*unit2","player")
263 end
264 end
265 end
266 end
267 end
268
269 function RAAT:UpdateIcon()
270 local action = self:GetID()
271 local texture = action and GetActionTexture(action)
272
273 self:DisplayIcon(action and texture)
274 self:DisplayEquipped(action and IsEquippedAction(action))
275 self:UpdateInUse()
276 self:UpdateUsable()
277 self:UpdateCooldown()
278 end
279
280 function RAAT:UpdateInUse()
281 local action = self:GetID()
282 if action and (IsCurrentAction(action) or IsAutoRepeatAction(action)) then
283 self:DisplayInUse(true)
284 else
285 self:DisplayInUse(false)
286 end
287 end
288
289 function RAAT:UpdateCount()
290 local action = self:GetID()
291 if action and (IsConsumableAction(action) or IsStackableAction(action)) then
292 self:DisplayCount(GetActionCount(action)) -- will display a 0 if none remaining
293 else
294 self:DisplayCount(nil) -- will display nothing
295 end
296 end
297
298 function RAAT:UpdateMacroText()
299 local action = self:GetID()
300 self:DisplayName(action and GetActionText(action))
301 end
302
303 function RAAT:UpdateUsable()
304 local action = self:GetID()
305 if action and HasAction(action) then
306 local isUsable, notEnoughMana = IsUsableAction(action)
307 local outOfRange = IsActionInRange(action) == 0
308 self:DisplayUsable(isUsable and not outOfRange, notEnoughMana, outOfRange)
309 else
310 self:DisplayUsable(false, false, false)
311 end
312 end
313
314 function RAAT:UpdateCooldown()
315 local action = self:GetID()
316 if action then
317 self:DisplayCooldown(GetActionCooldown(action))
318 end
319 end
320
321 function RAAT:UpdateActionEvents()
322 local action = self:GetID()
323 if action and HasAction(action) then
324 if not self.actionEventsRegistered then
325 self:RegisterEvent("ACTIONBAR_UPDATE_STATE")
326 self:RegisterEvent("ACTIONBAR_UPDATE_USABLE")
327 self:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN", "ACTIONBAR_UPDATE_USABLE")
328 self:RegisterEvent("UPDATE_INVENTORY_ALERTS", "ACTIONBAR_UPDATE_USABLE")
329 self:RegisterEvent("PLAYER_AURAS_CHANGED", "ACTIONBAR_UPDATE_USABLE")
330 self:RegisterEvent("PLAYER_TARGET_CHANGED", "ACTIONBAR_UPDATE_USABLE")
331 self:RegisterEvent("UNIT_INVENTORY_CHANGED")
332 self:RegisterEvent("CRAFT_SHOW")
333 self:RegisterEvent("CRAFT_CLOSE", "CRAFT_SHOW")
334 self:RegisterEvent("TRADE_SKILL_SHOW", "CRAFT_SHOW")
335 self:RegisterEvent("TRADE_SKILL_CLOSE", "CRAFT_SHOW")
336 self:RegisterEvent("PLAYER_ENTER_COMBAT")
337 self:RegisterEvent("PLAYER_LEAVE_COMBAT")
338 self:RegisterEvent("START_AUTOREPEAT_SPELL")
339 self:RegisterEvent("STOP_AUTOREPEAT_SPELL")
340 self.actionEventsRegistered = true
341 end
342 elseif self.actionEventsRegistered then
343 self:UnregisterEvent("ACTIONBAR_UPDATE_STATE")
344 self:UnregisterEvent("ACTIONBAR_UPDATE_USABLE")
345 self:UnregisterEvent("ACTIONBAR_UPDATE_COOLDOWN")
346 self:UnregisterEvent("UPDATE_INVENTORY_ALERTS")
347 self:UnregisterEvent("PLAYER_AURAS_CHANGED")
348 self:UnregisterEvent("PLAYER_TARGET_CHANGED")
349 self:UnregisterEvent("UNIT_INVENTORY_CHANGED")
350 self:UnregisterEvent("CRAFT_SHOW")
351 self:UnregisterEvent("CRAFT_CLOSE")
352 self:UnregisterEvent("TRADE_SKILL_SHOW")
353 self:UnregisterEvent("TRADE_SKILL_CLOSE")
354 self:UnregisterEvent("PLAYER_ENTER_COMBAT")
355 self:UnregisterEvent("PLAYER_LEAVE_COMBAT")
356 self:UnregisterEvent("START_AUTOREPEAT_SPELL")
357 self:UnregisterEvent("STOP_AUTOREPEAT_SPELL")
358 self.actionEventsRegistered = false
359 end
360 end
361