Mercurial > wow > reaction
comparison modules/Action.lua @ 116:fb48811a8736
Convert to standard keybindings
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Fri, 23 Jan 2009 23:44:55 +0000 |
parents | 77bb68eb402b |
children | fb6c3a642ae3 |
comparison
equal
deleted
inserted
replaced
115:af0172ed7037 | 116:fb48811a8736 |
---|---|
15 local CreateFrame = CreateFrame | 15 local CreateFrame = CreateFrame |
16 local format = string.format | 16 local format = string.format |
17 local wipe = wipe | 17 local wipe = wipe |
18 | 18 |
19 ReAction:UpdateRevision("$Revision$") | 19 ReAction:UpdateRevision("$Revision$") |
20 | |
21 local weak = { __mode="k" } | |
20 | 22 |
21 -- libraries | 23 -- libraries |
22 local KB = LibStub("LibKeyBound-1.0") | 24 local KB = LibStub("LibKeyBound-1.0") |
23 local LBF -- initialized later | 25 local LBF -- initialized later |
24 | 26 |
265 }, | 267 }, |
266 }, | 268 }, |
267 }, | 269 }, |
268 } | 270 } |
269 | 271 |
270 local weak = { __mode="k" } | |
271 local meta = { __index = Handle } | 272 local meta = { __index = Handle } |
272 | 273 |
273 function Handle:New( bar, config ) | 274 function Handle:New( bar, config ) |
274 local self = setmetatable( | 275 local self = setmetatable( |
275 { | 276 { |
363 ]]) | 364 ]]) |
364 end | 365 end |
365 | 366 |
366 function Handle:SetKeybindMode(mode) | 367 function Handle:SetKeybindMode(mode) |
367 for _, b in pairs(self.btns) do | 368 for _, b in pairs(self.btns) do |
368 if mode then | 369 b:SetKeybindMode(mode) |
369 -- set the border for all buttons to the keybind-enable color | |
370 b.border:SetVertexColor(KB:GetColorKeyBoundMode()) | |
371 b.border:Show() | |
372 elseif IsEquippedAction(b:GetActionID()) then | |
373 b.border:SetVertexColor(0, 1.0, 0, 0.35) -- from ActionButton.lua | |
374 else | |
375 b.border:Hide() | |
376 end | |
377 end | 370 end |
378 end | 371 end |
379 | 372 |
380 function Handle:GetLastButton() | 373 function Handle:GetLastButton() |
381 return self.btns[#self.btns] | 374 return self.btns[#self.btns] |
761 end | 754 end |
762 end | 755 end |
763 end | 756 end |
764 | 757 |
765 ------ Button class ------ | 758 ------ Button class ------ |
766 | 759 local frameRecycler = { } |
760 local trash = CreateFrame("Frame") | |
761 local OnUpdate, KBAttach, GetHotkey | |
767 do | 762 do |
768 local frameRecycler = { } | 763 local ATTACK_BUTTON_FLASH_TIME = ATTACK_BUTTON_FLASH_TIME |
769 local trash = CreateFrame("Frame") | 764 local IsActionInRange = IsActionInRange |
770 local OnUpdate, KBAttach, GetActionName, GetHotkey, SetKey, FreeKey, ClearBindings, GetBindings | 765 |
771 do | 766 function OnUpdate(frame, elapsed) |
772 local ATTACK_BUTTON_FLASH_TIME = ATTACK_BUTTON_FLASH_TIME | 767 -- note: This function taints frame.flashtime and frame.rangeTimer. Both of these |
773 local IsActionInRange = IsActionInRange | 768 -- are only read by ActionButton_OnUpdate (which this function replaces). In |
774 | 769 -- all other places they're just written, so it doesn't taint any secure code. |
775 local buttonLookup = setmetatable({},{__mode="kv"}) | 770 if frame.flashing == 1 then |
776 | 771 frame.flashtime = frame.flashtime - elapsed |
777 function OnUpdate(frame, elapsed) | 772 if frame.flashtime <= 0 then |
778 -- note: This function taints frame.flashtime and frame.rangeTimer. Both of these | 773 local overtime = -frame.flashtime |
779 -- are only read by ActionButton_OnUpdate (which this function replaces). In | 774 if overtime >= ATTACK_BUTTON_FLASH_TIME then |
780 -- all other places they're just written, so it doesn't taint any secure code. | 775 overtime = 0 |
781 if frame.flashing == 1 then | |
782 frame.flashtime = frame.flashtime - elapsed | |
783 if frame.flashtime <= 0 then | |
784 local overtime = -frame.flashtime | |
785 if overtime >= ATTACK_BUTTON_FLASH_TIME then | |
786 overtime = 0 | |
787 end | |
788 frame.flashtime = ATTACK_BUTTON_FLASH_TIME - overtime | |
789 | |
790 local flashTexture = frame.flash | |
791 if flashTexture:IsShown() then | |
792 flashTexture:Hide() | |
793 else | |
794 flashTexture:Show() | |
795 end | |
796 end | 776 end |
797 end | 777 frame.flashtime = ATTACK_BUTTON_FLASH_TIME - overtime |
798 | 778 |
799 if frame.rangeTimer then | 779 local flashTexture = frame.flash |
800 frame.rangeTimer = frame.rangeTimer - elapsed; | 780 if flashTexture:IsShown() then |
801 | 781 flashTexture:Hide() |
802 if frame.rangeTimer <= 0 then | 782 else |
803 if IsActionInRange(frame.action) == 0 then | 783 flashTexture:Show() |
804 frame.icon:SetVertexColor(1.0,0.1,0.1) | |
805 else | |
806 ActionButton_UpdateUsable(frame) | |
807 end | |
808 frame.rangeTimer = 0.1 | |
809 end | 784 end |
810 end | 785 end |
811 end | 786 end |
812 | 787 |
813 -- Use KeyBound-1.0 for binding, but use Override bindings instead of | 788 if frame.rangeTimer then |
814 -- regular bindings to support multiple profile use. This is a little | 789 frame.rangeTimer = frame.rangeTimer - elapsed; |
815 -- weird with the KeyBound dialog box (which has per-char selector as well | 790 |
816 -- as an OK/Cancel box) but it's the least amount of effort to implement. | 791 if frame.rangeTimer <= 0 then |
817 function GetActionName(f) | 792 if IsActionInRange(frame.action) == 0 then |
818 local b = buttonLookup[f] | 793 frame.icon:SetVertexColor(1.0,0.1,0.1) |
819 if b then | 794 else |
820 return format("%s:%s", b.bar:GetName(), b.idx) | 795 ActionButton_UpdateUsable(frame) |
821 end | |
822 end | |
823 | |
824 function GetHotkey(f) | |
825 local b = buttonLookup[f] | |
826 if b then | |
827 return KB:ToShortKey(b:GetConfig().hotkey) | |
828 end | |
829 end | |
830 | |
831 function SetKey(f, key) | |
832 local b = buttonLookup[f] | |
833 if b then | |
834 local c = b:GetConfig() | |
835 if c.hotkey then | |
836 SetOverrideBinding(f, false, c.hotkey, nil) | |
837 end | 796 end |
838 if key then | 797 frame.rangeTimer = 0.1 |
839 SetOverrideBindingClick(f, false, key, f:GetName(), nil) | 798 end |
840 end | 799 end |
841 c.hotkey = key | 800 end |
842 b:DisplayHotkey(GetHotkey(f)) | 801 |
843 end | 802 local function GetActionName(f) |
844 end | 803 local b = f and f._reactionButton |
845 | 804 if b then |
846 function FreeKey(f, key) | 805 return format("%s:%s", b.bar:GetName(), b.idx) |
847 local b = buttonLookup[f] | 806 end |
848 if b then | 807 end |
849 local c = b:GetConfig() | 808 |
850 if c.hotkey == key then | 809 function GetHotkey(f) |
851 local action = f:GetActionName() | 810 return KB:ToShortKey(GetBindingKey(format("CLICK %s:LeftButton",f:GetName()))) |
852 SetOverrideBinding(f, false, c.hotkey, nil) | 811 end |
853 c.hotkey = nil | 812 |
854 b:DisplayHotkey(nil) | 813 local function kb_onEnter( self ) |
855 return action | 814 if ReAction:GetKeybindMode() then |
856 end | 815 KB:Set(self) |
857 end | 816 end |
858 return ReAction:FreeOverrideHotkey(key) | 817 end |
859 end | 818 |
860 | 819 function KBAttach( button ) |
861 function ClearBindings(f) | 820 if not button.kbHooked then |
862 SetKey(f, nil) | 821 button.kbHooked = true |
863 end | |
864 | |
865 function GetBindings(f) | |
866 local b = buttonLookup[f] | |
867 if b then | |
868 return b:GetConfig().hotkey | |
869 end | |
870 end | |
871 | |
872 function KBAttach( button ) | |
873 local f = button:GetFrame() | 822 local f = button:GetFrame() |
823 f:HookScript("OnEnter", kb_onEnter) | |
874 f.GetActionName = GetActionName | 824 f.GetActionName = GetActionName |
875 f.GetHotkey = GetHotkey | 825 f.GetHotkey = GetHotkey |
876 f.SetKey = SetKey | 826 end |
877 f.FreeKey = FreeKey | 827 end |
878 f.ClearBindings = ClearBindings | 828 |
879 f.GetBindings = GetBindings | 829 -- This is a bit hokey : install a bare hook on ActionButton_UpdateHotkey because |
880 buttonLookup[f] = button | 830 -- even though it's secure it's never called in a way that can cause taint. This is |
881 f:SetKey(button:GetConfig().hotkey) | 831 -- for performance reasons to avoid having to hook frame:OnEvent securely. |
882 ReAction:RegisterKeybindFrame(f) | 832 local UpdateHotkey_old = ActionButton_UpdateHotkeys |
883 if ReAction:GetKeybindMode() then | 833 ActionButton_UpdateHotkeys = function( frame, ... ) |
884 button.border:SetVertexColor(KB:GetColorKeyBoundMode()) | 834 local b = frame._reactionButton |
885 button.border:Show() | 835 if b then |
886 end | 836 b.hotkey:SetText( GetHotkey(frame) ) |
887 end | |
888 end | |
889 | |
890 local meta = {__index = Button} | |
891 | |
892 function Button:New( handle, idx, config, barConfig ) | |
893 local bar = handle.bar | |
894 | |
895 -- create new self | |
896 self = setmetatable( | |
897 { | |
898 bar = bar, | |
899 idx = idx, | |
900 config = config, | |
901 barConfig = barConfig, | |
902 }, meta ) | |
903 | |
904 local name = config.name or ("ReAction_%s_%s_%d"):format(bar:GetName(),moduleID,idx) | |
905 self.name = name | |
906 config.name = name | |
907 local lastButton = handle:GetLastButton() | |
908 config.actionID = IDAlloc:Acquire(config.actionID, lastButton and lastButton.config.actionID) -- gets a free one if none configured | |
909 self.nPages = 1 | |
910 | |
911 -- have to recycle frames with the same name: CreateFrame() doesn't overwrite | |
912 -- existing globals. Can't set to nil in the global because it's then tainted. | |
913 local parent = bar:GetFrame() | |
914 local f = frameRecycler[name] | |
915 if f then | |
916 f:SetParent(parent) | |
917 else | 837 else |
918 f = CreateFrame("CheckButton", name, parent, "ActionBarButtonTemplate") | 838 return UpdateHotkey_old(frame, ...) |
919 -- ditch the old hotkey text because it's tied in ActionButton_Update() to the | 839 end |
920 -- standard binding. We use override bindings. | 840 end |
921 local hotkey = _G[name.."HotKey"] | 841 end |
922 hotkey:SetParent(trash) | 842 |
923 hotkey = f:CreateFontString(nil, "ARTWORK", "NumberFontNormalSmallGray") | 843 local meta = {__index = Button} |
924 hotkey:SetWidth(36) | 844 |
925 hotkey:SetHeight(18) | 845 function Button:New( handle, idx, config, barConfig ) |
926 hotkey:SetJustifyH("RIGHT") | 846 local bar = handle.bar |
927 hotkey:SetJustifyV("TOP") | 847 |
928 hotkey:SetPoint("TOPLEFT",f,"TOPLEFT",-2,-2) | 848 -- create new self |
929 f.hotkey = hotkey | 849 self = setmetatable( |
930 f.icon = _G[name.."Icon"] | 850 { |
931 f.flash = _G[name.."Flash"] | 851 bar = bar, |
932 f:SetScript("OnUpdate",OnUpdate) | 852 idx = idx, |
933 end | 853 config = config, |
934 | 854 barConfig = barConfig, |
935 self.hotkey = f.hotkey | 855 }, meta ) |
936 self.border = _G[name.."Border"] | 856 |
937 | 857 local name = config.name or ("ReAction_%s_%s_%d"):format(bar:GetName(),moduleID,idx) |
938 f:SetAttribute("action", config.actionID) | 858 self.name = name |
939 f:SetAttribute("default-action", config.actionID) | 859 config.name = name |
940 -- install mind control actions for all buttons just for simplicity | 860 local lastButton = handle:GetLastButton() |
941 if self.idx <= 12 then | 861 config.actionID = IDAlloc:Acquire(config.actionID, lastButton and lastButton.config.actionID) -- gets a free one if none configured |
942 f:SetAttribute("mindcontrol-action", 120 + self.idx) | 862 self.nPages = 1 |
943 end | 863 |
944 | 864 -- have to recycle frames with the same name: CreateFrame() doesn't overwrite |
945 -- set a _childupdate handler, called within the header's context | 865 -- existing globals. Can't set to nil in the global because it's then tainted. |
946 f:SetAttribute("_childupdate", | 866 local parent = bar:GetFrame() |
947 -- function _childupdate(self, snippetid, message) | 867 local f = frameRecycler[name] |
948 [[ | 868 if f then |
949 local action = "default-action" | 869 f:SetParent(parent) |
950 if doMindControl and GetBonusBarOffset() == 5 then | 870 else |
951 action = "mindcontrol-action" | 871 f = CreateFrame("CheckButton", name, parent, "ActionBarButtonTemplate") |
952 elseif page and state and page[state] then | 872 -- ditch the old hotkey text because it's tied in ActionButton_Update() to the |
953 action = "action-"..page[state] | 873 -- standard binding. |
954 end | 874 local hotkey = _G[name.."HotKey"] |
955 local value = self:GetAttribute(action) | 875 hotkey:SetParent(trash) |
956 if value then | 876 hotkey = f:CreateFontString(nil, "ARTWORK", "NumberFontNormalSmallGray") |
957 self:SetAttribute("action",value) | 877 hotkey:SetWidth(36) |
958 end | 878 hotkey:SetHeight(18) |
959 ]]) | 879 hotkey:SetJustifyH("RIGHT") |
960 | 880 hotkey:SetJustifyV("TOP") |
961 -- install drag wrappers to lock buttons | 881 hotkey:SetPoint("TOPLEFT",f,"TOPLEFT",-2,-2) |
962 bar:GetFrame():WrapScript(f, "OnDragStart", | 882 f.hotkey = hotkey |
963 -- OnDragStart(self, button, kind, value, ...) | 883 f.icon = _G[name.."Icon"] |
964 [[ | 884 f.flash = _G[name.."Flash"] |
965 if lockButtons and (PlayerInCombat() or not lockButtonsCombat) and not IsModifiedClick("PICKUPACTION") then | 885 f:SetScript("OnUpdate",OnUpdate) |
966 return "clear" | 886 end |
967 end | 887 |
968 ]]) | 888 f._reactionButton = self |
969 | 889 |
970 self.frame = f | 890 self.hotkey = f.hotkey |
971 | 891 self.border = _G[name.."Border"] |
972 | 892 |
973 -- initialize the hide state | 893 f:SetAttribute("action", config.actionID) |
974 f:SetAttribute("showgrid",0) | 894 f:SetAttribute("default-action", config.actionID) |
975 self:ShowGrid(not barConfig.hideEmpty) | 895 -- install mind control actions for all buttons just for simplicity |
976 if ReAction:GetConfigMode() then | 896 if self.idx <= 12 then |
977 self:ShowGrid(true) | 897 f:SetAttribute("mindcontrol-action", 120 + self.idx) |
978 end | 898 end |
979 | 899 |
980 -- show the ID label if applicable | 900 -- set a _childupdate handler, called within the header's context |
981 self:ShowActionIDLabel(ReAction:GetConfigMode()) | 901 f:SetAttribute("_childupdate", |
982 | 902 -- function _childupdate(self, snippetid, message) |
983 -- attach the keybinder | 903 [[ |
984 KBAttach(self) | 904 local action = "default-action" |
985 | 905 if doMindControl and GetBonusBarOffset() == 5 then |
986 -- attach to skinner | 906 action = "mindcontrol-action" |
987 bar:SkinButton(self, | 907 elseif page and state and page[state] then |
988 { | 908 action = "action-"..page[state] |
989 HotKey = self.hotkey, | 909 end |
990 } | 910 local value = self:GetAttribute(action) |
991 ) | 911 if value then |
992 | 912 self:SetAttribute("action",value) |
993 self:Refresh() | 913 end |
994 return self | 914 ]]) |
995 end | 915 |
996 | 916 -- install drag wrappers to lock buttons |
997 function Button:Destroy() | 917 bar:GetFrame():WrapScript(f, "OnDragStart", |
918 -- OnDragStart(self, button, kind, value, ...) | |
919 [[ | |
920 if lockButtons and (PlayerInCombat() or not lockButtonsCombat) and not IsModifiedClick("PICKUPACTION") then | |
921 return "clear" | |
922 end | |
923 ]]) | |
924 | |
925 self.frame = f | |
926 | |
927 -- initialize the hide state | |
928 f:SetAttribute("showgrid",0) | |
929 self:ShowGrid(not barConfig.hideEmpty) | |
930 if ReAction:GetConfigMode() then | |
931 self:ShowGrid(true) | |
932 end | |
933 | |
934 -- set the hotkey text | |
935 self.hotkey:SetText( GetHotkey(self.frame) ) | |
936 | |
937 -- show the ID label if applicable | |
938 self:ShowActionIDLabel(ReAction:GetConfigMode()) | |
939 | |
940 -- attach to skinner | |
941 bar:SkinButton(self, | |
942 { | |
943 HotKey = self.hotkey, | |
944 } | |
945 ) | |
946 | |
947 self:Refresh() | |
948 return self | |
949 end | |
950 | |
951 function Button:Destroy() | |
952 local f = self.frame | |
953 f:UnregisterAllEvents() | |
954 f:Hide() | |
955 f:SetParent(UIParent) | |
956 f:ClearAllPoints() | |
957 if self.name then | |
958 frameRecycler[self.name] = f | |
959 end | |
960 if self.config.actionID then | |
961 IDAlloc:Release(self.config.actionID) | |
962 end | |
963 if self.config.pageactions then | |
964 for _, id in ipairs(self.config.pageactions) do | |
965 IDAlloc:Release(id) | |
966 end | |
967 end | |
968 f._reactionButton = nil | |
969 self.frame = nil | |
970 self.config = nil | |
971 self.bar = nil | |
972 end | |
973 | |
974 function Button:Refresh() | |
975 local f = self.frame | |
976 self.bar:PlaceButton(self, 36, 36) | |
977 self:RefreshPages() | |
978 end | |
979 | |
980 function Button:GetFrame() | |
981 return self.frame | |
982 end | |
983 | |
984 function Button:GetName() | |
985 return self.name | |
986 end | |
987 | |
988 function Button:GetConfig() | |
989 return self.config | |
990 end | |
991 | |
992 function Button:GetActionID(page) | |
993 if page == nil then | |
994 -- get the effective ID | |
995 return self.frame.action -- kept up-to-date by Blizzard's ActionButton_CalculateAction() | |
996 else | |
997 if page == 1 then | |
998 return self.config.actionID | |
999 else | |
1000 return self.config.pageactions and self.config.pageactions[page] or self.config.actionID | |
1001 end | |
1002 end | |
1003 end | |
1004 | |
1005 function Button:SetActionID( id, page ) | |
1006 id = tonumber(id) | |
1007 page = tonumber(page) | |
1008 if id == nil or id < 1 or id > 120 then | |
1009 error("Button:SetActionID - invalid action ID") | |
1010 end | |
1011 if page and page ~= 1 then | |
1012 if not self.config.pageactions then | |
1013 self.config.pageactions = { } | |
1014 end | |
1015 if self.config.pageactions[page] then | |
1016 IDAlloc:Release(self.config.pageactions[page]) | |
1017 end | |
1018 self.config.pageactions[page] = id | |
1019 IDAlloc:Acquire(self.config.pageactions[page]) | |
1020 self.frame:SetAttribute(("action-page%d"):format(page),id) | |
1021 else | |
1022 IDAlloc:Release(self.config.actionID) | |
1023 self.config.actionID = id | |
1024 IDAlloc:Acquire(self.config.actionID) | |
1025 self.frame:SetAttribute("action",id) | |
1026 if self.config.pageactions then | |
1027 self.config.pageactions[1] = id | |
1028 self.frame:SetAttribute("action-page1",id) | |
1029 end | |
1030 end | |
1031 end | |
1032 | |
1033 function Button:RefreshPages( force ) | |
1034 local nPages = self.barConfig.nPages | |
1035 if nPages and (nPages ~= self.nPages or force) then | |
1036 local f = self:GetFrame() | |
1037 local c = self.config.pageactions | |
1038 if nPages > 1 and not c then | |
1039 c = { } | |
1040 self.config.pageactions = c | |
1041 end | |
1042 for i = 1, nPages do | |
1043 if i > 1 then | |
1044 c[i] = IDAlloc:Acquire(c[i], self.config.actionID + (i-1)*self.bar:GetNumButtons()) | |
1045 else | |
1046 c[i] = self.config.actionID -- page 1 is the same as the base actionID | |
1047 end | |
1048 f:SetAttribute(("action-page%d"):format(i),c[i]) | |
1049 end | |
1050 for i = nPages+1, #c do | |
1051 IDAlloc:Release(c[i]) | |
1052 c[i] = nil | |
1053 f:SetAttribute(("action-page%d"):format(i),nil) | |
1054 end | |
1055 self.nPages = nPages | |
1056 end | |
1057 end | |
1058 | |
1059 function Button:ShowGrid( show ) | |
1060 if not InCombatLockdown() then | |
998 local f = self.frame | 1061 local f = self.frame |
999 f:UnregisterAllEvents() | 1062 local count = f:GetAttribute("showgrid") |
1000 f:Hide() | 1063 if show then |
1001 f:SetParent(UIParent) | 1064 count = count + 1 |
1002 f:ClearAllPoints() | |
1003 if self.name then | |
1004 frameRecycler[self.name] = f | |
1005 end | |
1006 if self.config.actionID then | |
1007 IDAlloc:Release(self.config.actionID) | |
1008 end | |
1009 if self.config.pageactions then | |
1010 for _, id in ipairs(self.config.pageactions) do | |
1011 IDAlloc:Release(id) | |
1012 end | |
1013 end | |
1014 self.frame = nil | |
1015 self.config = nil | |
1016 self.bar = nil | |
1017 end | |
1018 | |
1019 function Button:Refresh() | |
1020 local f = self.frame | |
1021 self.bar:PlaceButton(self, 36, 36) | |
1022 self:RefreshPages() | |
1023 end | |
1024 | |
1025 function Button:GetFrame() | |
1026 return self.frame | |
1027 end | |
1028 | |
1029 function Button:GetName() | |
1030 return self.name | |
1031 end | |
1032 | |
1033 function Button:GetConfig() | |
1034 return self.config | |
1035 end | |
1036 | |
1037 function Button:GetActionID(page) | |
1038 if page == nil then | |
1039 -- get the effective ID | |
1040 return self.frame.action -- kept up-to-date by Blizzard's ActionButton_CalculateAction() | |
1041 else | 1065 else |
1042 if page == 1 then | 1066 count = count - 1 |
1043 return self.config.actionID | 1067 end |
1068 if count < 0 then | |
1069 count = 0 | |
1070 end | |
1071 f:SetAttribute("showgrid",count) | |
1072 | |
1073 if count >= 1 and not f:GetAttribute("statehidden") then | |
1074 if LBF then | |
1075 LBF:SetNormalVertexColor(self.frame, 1.0, 1.0, 1.0, 0.5) | |
1044 else | 1076 else |
1045 return self.config.pageactions and self.config.pageactions[page] or self.config.actionID | 1077 self.frame:GetNormalTexture():SetVertexColor(1.0, 1.0, 1.0, 0.5); |
1046 end | 1078 end |
1047 end | 1079 f:Show() |
1048 end | 1080 elseif count < 1 and not HasAction(self:GetActionID()) then |
1049 | 1081 f:Hide() |
1050 function Button:SetActionID( id, page ) | 1082 end |
1051 id = tonumber(id) | 1083 end |
1052 page = tonumber(page) | 1084 end |
1053 if id == nil or id < 1 or id > 120 then | 1085 |
1054 error("Button:SetActionID - invalid action ID") | 1086 function Button:ShowActionIDLabel( show ) |
1055 end | 1087 local f = self:GetFrame() |
1056 if page and page ~= 1 then | 1088 if show then |
1057 if not self.config.pageactions then | 1089 local id = self:GetActionID() |
1058 self.config.pageactions = { } | 1090 if not f.actionIDLabel then |
1059 end | 1091 local label = f:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") |
1060 if self.config.pageactions[page] then | 1092 label:SetAllPoints() |
1061 IDAlloc:Release(self.config.pageactions[page]) | 1093 label:SetJustifyH("CENTER") |
1062 end | 1094 label:SetShadowColor(0,0,0,1) |
1063 self.config.pageactions[page] = id | 1095 label:SetShadowOffset(2,-2) |
1064 IDAlloc:Acquire(self.config.pageactions[page]) | 1096 f.actionIDLabel = label -- store the label with the frame for recycling |
1065 self.frame:SetAttribute(("action-page%d"):format(page),id) | 1097 |
1066 else | 1098 f:HookScript("OnAttributeChanged", |
1067 IDAlloc:Release(self.config.actionID) | 1099 function(frame, attr, value) |
1068 self.config.actionID = id | 1100 if label:IsVisible() and attr:match("action") then |
1069 IDAlloc:Acquire(self.config.actionID) | 1101 label:SetText(tostring(frame.action)) |
1070 self.frame:SetAttribute("action",id) | 1102 end |
1071 if self.config.pageactions then | 1103 end) |
1072 self.config.pageactions[1] = id | 1104 end |
1073 self.frame:SetAttribute("action-page1",id) | 1105 f.actionIDLabel:SetText(tostring(id)) |
1074 end | 1106 f.actionIDLabel:Show() |
1075 end | 1107 elseif f.actionIDLabel then |
1076 end | 1108 f.actionIDLabel:Hide() |
1077 | 1109 end |
1078 function Button:RefreshPages( force ) | 1110 end |
1079 local nPages = self.barConfig.nPages | 1111 |
1080 if nPages and (nPages ~= self.nPages or force) then | 1112 function Button:SetKeybindMode( mode ) |
1081 local f = self:GetFrame() | 1113 if mode then |
1082 local c = self.config.pageactions | 1114 KBAttach( self ) |
1083 if nPages > 1 and not c then | 1115 -- set the border for all buttons to the keybind-enable color |
1084 c = { } | 1116 self.border:SetVertexColor(KB:GetColorKeyBoundMode()) |
1085 self.config.pageactions = c | 1117 self.border:Show() |
1086 end | 1118 elseif IsEquippedAction(self:GetActionID()) then |
1087 for i = 1, nPages do | 1119 self.border:SetVertexColor(0, 1.0, 0, 0.35) -- from ActionButton.lua |
1088 if i > 1 then | 1120 else |
1089 c[i] = IDAlloc:Acquire(c[i], self.config.actionID + (i-1)*self.bar:GetNumButtons()) | 1121 self.border:Hide() |
1090 else | 1122 end |
1091 c[i] = self.config.actionID -- page 1 is the same as the base actionID | 1123 end |
1092 end | |
1093 f:SetAttribute(("action-page%d"):format(i),c[i]) | |
1094 end | |
1095 for i = nPages+1, #c do | |
1096 IDAlloc:Release(c[i]) | |
1097 c[i] = nil | |
1098 f:SetAttribute(("action-page%d"):format(i),nil) | |
1099 end | |
1100 self.nPages = nPages | |
1101 end | |
1102 end | |
1103 | |
1104 function Button:ShowGrid( show ) | |
1105 if not InCombatLockdown() then | |
1106 local f = self.frame | |
1107 local count = f:GetAttribute("showgrid") | |
1108 if show then | |
1109 count = count + 1 | |
1110 else | |
1111 count = count - 1 | |
1112 end | |
1113 if count < 0 then | |
1114 count = 0 | |
1115 end | |
1116 f:SetAttribute("showgrid",count) | |
1117 | |
1118 if count >= 1 and not f:GetAttribute("statehidden") then | |
1119 if LBF then | |
1120 LBF:SetNormalVertexColor(self.frame, 1.0, 1.0, 1.0, 0.5) | |
1121 else | |
1122 self.frame:GetNormalTexture():SetVertexColor(1.0, 1.0, 1.0, 0.5); | |
1123 end | |
1124 f:Show() | |
1125 elseif count < 1 and not HasAction(self:GetActionID()) then | |
1126 f:Hide() | |
1127 end | |
1128 end | |
1129 end | |
1130 | |
1131 function Button:ShowActionIDLabel( show ) | |
1132 local f = self:GetFrame() | |
1133 if show then | |
1134 local id = self:GetActionID() | |
1135 if not f.actionIDLabel then | |
1136 local label = f:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") | |
1137 label:SetAllPoints() | |
1138 label:SetJustifyH("CENTER") | |
1139 label:SetShadowColor(0,0,0,1) | |
1140 label:SetShadowOffset(2,-2) | |
1141 f.actionIDLabel = label -- store the label with the frame for recycling | |
1142 | |
1143 f:HookScript("OnAttributeChanged", | |
1144 function(frame, attr, value) | |
1145 if label:IsVisible() and attr:match("action") then | |
1146 label:SetText(tostring(frame.action)) | |
1147 end | |
1148 end) | |
1149 end | |
1150 f.actionIDLabel:SetText(tostring(id)) | |
1151 f.actionIDLabel:Show() | |
1152 elseif f.actionIDLabel then | |
1153 f.actionIDLabel:Hide() | |
1154 end | |
1155 end | |
1156 | |
1157 function Button:DisplayHotkey( key ) | |
1158 self.hotkey:SetText(key or "") | |
1159 end | |
1160 end |