-
Posted by Vardelm on Tue, 17 Aug 2010 13:29:43
I've started work on my first major addon, and it's a totem bar. My 1st big challenge is finding a way to code button "flyouts", similar to the standard totem bar, but doing so on mouseover. There are a few totem bar addons that do this already, such as TotemTimers. I've looked through the code there, but haven't been able to find out how the flyouts work there.
As things stand, I have 4 buttons for the 4 element groups. Using OnEnter, I show another frame (called "ListFrame") that sits over the original button, plus stretches above it some ways. There are then currently 3 additional buttons (ListButton1, etc.) that sit on top of the ListFrame, which are for the individual totems that can be assigned to that group. The ListFrame covers the entire area of the initial element button plus the 3 ListButtons for that group. The ListFrame has an OnLeave script to hide the ListFrame.
Unfortunately, what happens is that as soon as my cursor leaves the original element button, the flyout disappears. I think that's because the mouse can only be "in" 1 frame at a time, correct? Thus, when it moves onto one of the ListButtons, it's no longer considered to be in the ListFrame.
Question is, how can I get the flyout to stay visible while my mouse is on either the original element button or the associated flyout (consisting of the ListFrame & ListButtons)? I think all I need is a pointer in the general direction, and I can (hopefully) figure out the exact code myself.
Thanks!
Code to follow....
EDIT: Found a workable, if clunky, solution. See below.
-
Posted by Vardelm on Tue, 17 Aug 2010 13:31:54
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ http://wowprogramming.com/FrameXML/UI.xsd"> <!--============================================================--> <!-- TotemToter Button Template --> <!--============================================================--> <Button name="TotemToterButtonTemplate" inherits="SecureActionButtonTemplate" virtual="true"> <Size> <AbsDimension x="37" y="37"/> </Size> <Layers> <Layer level="BORDER"> <Texture name="$parentIconTexture" parentKey="icon"/> </Layer> <Layer level="OVERLAY"> <Texture name="$parentGlow" parentKey="glow" alphaMode="ADD" file="Interface\Buttons\UI-ActionButton-Border"> <Size x="70" y="70"/> <Anchors> <Anchor point="CENTER"/> </Anchors> <Color r="1.0" g="1.0" b="1.0" a="0.6"/> </Texture> </Layer> </Layers> <NormalTexture name="$parentNormalTexture" file="Interface\Buttons\UI-EmptySlot"> <Size> <AbsDimension x="64" y="64"/> </Size> <Anchors> <Anchor point="CENTER"> <Offset> <AbsDimension x="0" y="-1"/> </Offset> </Anchor> </Anchors> </NormalTexture> <PushedTexture file="Interface\Buttons\UI-Quickslot-Depress"/> <HighlightTexture file="Interface\Buttons\ButtonHilight-Square" alphaMode="ADD"/> </Button> <!--============================================================--> <!-- TotemToter Main Button Template --> <!--============================================================--> <Button name="TotemToterMainButtonTemplate" inherits="TotemToterButtonTemplate" virtual="true"> <Size> <AbsDimension x="37" y="37"/> </Size> <Scripts> <OnEnter> TotemToter_ShowListFrame(self) </OnEnter> </Scripts> </Button> <!--============================================================--> <!-- TotemToter List Frame Template --> <!--============================================================--> <Frame name="TotemToterListFrameTemplate" parentKey="ListFrame" enableMouse="true" virtual="true" hidden="true"> <Size> <AbsDimension x="37" y="165"/> </Size> <Layers> <Layer level="BACKGROUND"> <Texture setAllPoints="true"> <Color r="0.0" g="0.8" b="0.0" a="0.5"/> </Texture> </Layer> </Layers> <Scripts> <OnLeave> TotemToter_HideListFrame(self) </OnLeave> </Scripts> </Frame> <!--============================================================--> <!-- TotemToter List Button Template --> <!--============================================================--> <Button name="TotemToterListButtonTemplate" inherits="TotemToterButtonTemplate" virtual="true"> <Size> <AbsDimension x="37" y="37"/> </Size> <Scripts> </Scripts> </Button> <!--============================================================--> <!-- TotemToter Frames --> <!--============================================================--> <Frame name="TotemToter" parent="UIParent"> <Size x="100" y="100"/> <Anchors> <Anchor point="CENTER" /> </Anchors> <Layers> <Layer level="BACKGROUND" setAllPoints="true"> <Texture setAllPoints="true"> <Color r="0.0" g="0.0" b="0.8" a="0.5"/> </Texture> </Layer> </Layers> <Scripts> <OnLoad> TotemToter_CreateButtons() </OnLoad> </Scripts> </Frame> </Ui>
-
Posted by Vardelm on Tue, 17 Aug 2010 13:32:28
function TotemToter_CreateButtons() local newFrame local lastFrame newFrame = TotemToter_CreateMainButton("Call") newFrame:SetPoint("CENTER", TotemToter, "CENTER") lastFrame = newFrame newFrame = TotemToter_CreateMainButton("Fire") newFrame:SetPoint("TOPLEFT", lastFrame, "TOPRIGHT", 4, 0) lastFrame = newFrame newFrame = TotemToter_CreateMainButton("Earth") newFrame:SetPoint("TOPLEFT", lastFrame, "TOPRIGHT", 4, 0) lastFrame = newFrame newFrame = TotemToter_CreateMainButton("Water") newFrame:SetPoint("TOPLEFT", lastFrame, "TOPRIGHT", 4, 0) lastFrame = newFrame newFrame = TotemToter_CreateMainButton("Air") newFrame:SetPoint("TOPLEFT", lastFrame, "TOPRIGHT", 4, 0) end function TotemToter_CreateMainButton(element) local newFrame = CreateFrame("Button", "TotemToter" .. element .. "MainButton", self, "TotemToterMainButtonTemplate") newFrame:SetParent("TotemToter") TotemToter_CreateListFrame(newFrame) return newFrame end function TotemToter_CreateListFrame(parentFrame) local newFrame = CreateFrame("Frame", parentFrame:GetName() .. "ListFrame", self, "TotemToterListFrameTemplate") newFrame:SetParent(parentFrame) newFrame:SetPoint("BOTTOM", parentFrame, "BOTTOM") for index = 1, 3 do TotemToter_CreateListButton(newFrame, index) end return newFrame end function TotemToter_CreateListButton(parentFrame, index) local newFrame = CreateFrame("Button", parentFrame:GetName() .. "ListButton" .. index, self, "TotemToterListButtonTemplate") newFrame:SetParent(parentFrame) if index == 1 then newFrame:SetPoint("BOTTOM", parentFrame, "BOTTOM", 0, 44) else relativeFrame = parentFrame:GetName() .. "ListButton" .. (index-1) newFrame:SetPoint("BOTTOM", relativeFrame, "TOP", 0, 4) end return newFrame end function TotemToter_ShowListFrame(frame) frame = _G[frame:GetName() .. "ListFrame"] frame:Show() end function TotemToter_HideListFrame(frame) frame:Hide() end
-
Posted by Vardelm on Tue, 17 Aug 2010 19:36:54
I found a solution, although it may be on the clunky side. I just assigned the show & hide scripts to the main element button, the list frame, & the list button. So, it checks for OnEnter & OnLeave for all of these. I then modified the show & hide functions to account for the different frames using the function, as show below.
My question at this point, although this works, is there a more elegant solution that isn't too difficult to explain?
function TotemToter_ShowListFrame(frame) local childFrame = _G[frame:GetName() .. "ListFrame"] local parentFrame = frame:GetParent() local parentFrameName = parentFrame:GetName() if childFrame then childFrame:Show() elseif strfind(parentFrameName, "ListFrame") then parentFrame:Show() else frame:Show() end end function TotemToter_HideListFrame(frame) local childFrame = _G[frame:GetName() .. "ListFrame"] local parentFrame = frame:GetParent() local parentFrameName = parentFrame:GetName() if childFrame then childFrame:Hide() elseif strfind(parentFrameName, "ListFrame") then parentFrame:Hide() else frame:Hide() end end
-
Posted by jnwhiteh on Thu, 19 Aug 2010 11:15:35
It doesn't seem like that would be a problem.. if it works then that's good enough. Elegance and optimization can always happen at a later time!
-
Posted by Vardelm on Fri, 20 Aug 2010 14:11:04
It doesn't seem like that would be a problem.. if it works then that's good enough. Elegance and optimization can always happen at a later time!
Good enough for me then! :)