I committed an alpha version of a multi-column tooltip library I'm working on. I've always been a command-line (MUD, etc) coder, so GUI-programming is almost alien in concept to me and therefore I am struggling with frame anchoring.
What I have so far almost works: No text is displayed (but the frame is), so I'm having problems testing and refining it. At the moment, it supports frame-recycling, ClearLines(), AddLine(), AddColumn(), etc.
Any input would be appreciated - I'm tired of using GameTooltip with it's two-column limitation.
Ok, this project has taken off rather quickly with Adirelle, Tristanian, and Kaelten on board now. In the three days since my first post with the original code, the API has completely changed and is in fact still in flux - but it is a working prototype if anyone wants to check it out.
i am really new to this whole lua coding game. So sorry if this question is a little dumb. But i am confused on what this dose. I understand it adds tooltips but is it a lip for a addon someone is coding so they can make custom tooltips ?
i am really new to this whole lua coding game. So sorry if this question is a little dumb. But i am confused on what this dose. I understand it adds tooltips but is it a lip for a addon someone is coding so they can make custom tooltips ?
WoW's default tooltip - GameTooltip - has support for a maximum of two columns. This is a library for an addon to use in order to overcome this deficiency and possibly do a bit more, without doing too much else.
If someone hasn't done so before I get home from work, I'm going to take a look at CreateLine() because it doesn't appear to see the font parameter properly for whatever reason. Using AddHeader() with nothing more than a text label raised an error. I ended up adding a default font object in CreateCell() to compensate for now, because I really need to go to bed. I think the default should be set anyway, but I set it to GameTooltipText when it should really be self.regularFont
The library is still rather small (around 300 lines). For now, as Kaelten said, we are just thinking about adding colspans. Custom cells could be added too. That would allow to display money frames or textures. Neither should be hard nor heavy to implement, though we have to find a smart API to do it.
Now I'm also concerned with small display tweaks, like tooltip border size and internal cell margin. They are constant values ATM. Should we allow to change them ? Where ?
ATM the number of columns and their alignment are set when the tooltip is acquired and cannot be changed afterward. Though this is not very flexible, it allows to keep the code small. I'd like to keep this design but adding optional parameters would become tricky. Any thought on this ?
Acquire now enforces the tooltip name to be a string. I do not see any good reason to do this. Anything that can be used as a table key should work (and the parameter should be renamed "instanceKey" or something like that).
And finally, I would like to tweak the default settings so the tooltip really looks like a GameTooltip by default. Has anyone an idea of the default backdrop, alpha, padding and margin settings to use ?
ATM the number of columns and their alignment are set when the tooltip is acquired and cannot be changed afterward. Though this is not very flexible, it allows to keep the code small. I'd like to keep this design but adding optional parameters would become tricky. Any thought on this ?
In the initial iteration of the library I'd like to keep the "static" definition of columns and alignments as well, unless someone has a viable suggestion of how this can be modified with minimal overhead.
Acquire now enforces the tooltip name to be a string. I do not see any good reason to do this. Anything that can be used as a table key should work (and the parameter should be renamed "instanceKey" or something like that).
In all honesty, the name must either be a frame (in almost every case the parent frame - frame to anchor the tooltip to) or a string referring to that. We choose one and with stick with it, imo. You have to think about Acquire in conjunction with IsAcquired. You will have to use the exact same type of argument, if you want something reliable returned and since IsAcquired is gonna be used by displays a lot, it makes no sense having them to "guess" how to call the method.
Btw I'm also thinking of returning the tooltip frame in IsAcquired if true. Everyone ok with this ? Thoughts ?
And finally, I would like to tweak the default settings so the tooltip really looks like a GameTooltip by default. Has anyone an idea of the default backdrop, alpha, padding and margin settings to use ?
I was gonna look at this today when I come back from work but yes, some tweaking is in order.
In all honesty, the name must either be a frame (in almost every case the parent frame - frame to anchor the tooltip to) or a string referring to that. We choose one and with stick with it, imo. You have to think about Acquire in conjunction with IsAcquired.
IIRC, we didn't agree on actively restricting "name" to strings, though it would make sense with the current argument name (and that why I would like to rename it, e.g. "handle", "id" or "key" ?). Actually this "name" is only used as an index to the internal activeTooltips table. Anything but nil can be used as table index, including tables and frames. Leaving this choice open allows creative uses. By example, an addon could use itself as a key to be sure to acquire an unique tooltip instance. Obviously IsAcquired should accept the same kind of parameters.
You will have to use the exact same type of argument, if you want something reliable returned and since IsAcquired is gonna be used by displays a lot, it makes no sense having them to "guess" how to call the method.
Even if you have your own specific purpose in mind, please remember that LibTooltip is a general-purpose library. We shouldn't take design decision based only on a specific use case.
Btw I'm also thinking of returning the tooltip frame in IsAcquired if true. Everyone ok with this ? Thoughts ?
IsXXX method must return a boolean. If we wanted a method to return the tooltip, it should be named GetXXX, e.g. GetTooltip. So I'd rather add a new method for this.
IIRC, we didn't agree on actively restricting "name" to strings, though it would make sense with the current argument name (and that why I would like to rename it, e.g. "handle", "id" or "key" ?). Actually this "name" is only used as an index to the internal activeTooltips table. Anything but nil can be used as table index, including tables and frames. Leaving this choice open allows creative uses. By example, an addon could use itself as a key to be sure to acquire an unique tooltip instance. Obviously IsAcquired should accept the same kind of parameters.
On principle I agree that leaving the choice open is "the right thing to do". In practice however, this can cause complications with IsAcquired, unless you intend this to be a method that will be used internally by the addon that constructs the tooltip. My point is, at the very least provide some recommendations.
Even if you have your own specific purpose in mind, please remember that LibTooltip is a general-purpose library. We shouldn't take design decision based only on a specific use case.
It is my point exactly that because it is meant to be general-purpose, it would be to the best interest of everyone to support certain common sense elements. I can only picture (and correct me if I'm wrong) 2 types of addons that will want to use the lib. Addons that need (to create/populate) a multi-column tooltip and possibly displays to manipulate aspects of the tip, where applicable. How many other choices are there ?
IsXXX method must return a boolean. If we wanted a method to return the tooltip, it should be named GetXXX, e.g. GetTooltip. So I'd rather add a new method for this.
I can only picture (and correct me if I'm wrong) 2 types of addons that will want to use the lib. Addons that need (to create/populate) a multi-column tooltip and possibly displays to manipulate aspects of the tip, where applicable. How many other choices are there ?
About the displays, there are three possibilities :
.OnTooltipShow: the display addon provides the tooltip to the LDB datasource and has full control over it. It this case, the LDB datasource should not interact with the tooltip beside filling it with content.
.tooltip: the LDB datasource provide a frame to be used as a tooltip. The display is only responsible for anchoring it and showing/hiding it.
.OnEnter+.OnLeave : in this case the LDB datasource does whatever it wants. It may create a GameTooltip, a LibTooltip tooltip, or even a SimpleHTML frame. The display has not control over what is created (or not) and should not assume it could retrieve it or modify it.
Using IsAcquired/GetTooltip to try to interact with the tooltip in the third case is just an hack. It will be broken by any LDB datasource that does something like this :
local tip
function datasource:OnEnter(frame)
tip = tip or CreateFrame('SimpleHTML', UIParent)
tip:SetText("<html><body>Bla</body></html>")
tip:SetPoint("TOP", frame, "TOP", 0, 0)
tip:Show()
end
function datasource:OnLeave(frame)
tip:Hide()
end
As I already said, this is an "issue" with the LDB data specifications. And there is no way to reliably fix this in LibTooltip. Even if we restricted the tooltip name to a string, anyone could write a Broker_DeathCounter LDB datasource that created a tooltip named "MyOwnFooBaredTooltip".
OnTooltipShow: the display addon provides the tooltip to the LDB datasource and has full control over it. It this case, the LDB datasource should not interact with the tooltip beside filling it with content.
This is not applicable in our case, since the display cannot "assume" that a plugin would be using Libtooltip API inside an OnTooltipShow, so that it can use :Acquire and provide the tooltip frame returned to the OnTooltipShow func. A display simply cannot know that (with the current implementation that is).
tooltip: the LDB datasource provide a frame to be used as a tooltip. The display is only responsible for anchoring it and showing/hiding it.
This may be a possibility, although I always pictured it as an option for non-dynamic stuff. Good call though.
OnEnter+.OnLeave : in this case the LDB datasource does whatever it wants. It may create a GameTooltip, a LibTooltip tooltip, or even a SimpleHTML frame. The display has not control over what is created (or not) and should not assume it could retrieve it or modify it.
Using IsAcquired/GetTooltip to try to interact with the tooltip in the third case is just an hack. It will be broken by any LDB datasource that does something like this :
local tip
function datasource:OnEnter(frame)
tip = tip or CreateFrame('SimpleHTML', UIParent)
tip:SetText("<html><body>Bla</body></html>")
tip:SetPoint("TOP", frame, "TOP", 0, 0)
tip:Show()
end
function datasource:OnLeave(frame)
tip:Hide()
end
It wouldn't break if the display was calling its setters after OnEnter in our case and was only setting very basic stuff. That's not the point anyway, since a display can simply use our iterate method and go through the list of active tooltips, get the relativeto frame, match it with its own and thus locate the active tip. Is that less of a "hack" ? I do agree though, that you have a point about detection not actually being reliable via IsAcquired.
It wouldn't break if the display was calling its setters after OnEnter in our case and was only setting very basic stuff. That's not the point anyway, since a display can simply use our iterate method and go through the list of active tooltips, get the relativeto frame, match it with its own and thus locate the active tip. Is that less of a "hack" ?
It is totally a hack. It is a workaround to a "hole" in the LDB API. It assumes the LDB OnEnter callback creates a LibTooltip and anchors said tooltip to the displaying frame.
The real solution would be that the LDB specifications enforced the OnEnter callback to return the frame used as a tooltip, if any was created.
That would allow this kind of code from the display POV :
Aye it does assume that, although it shouldn't break if a libtooltip isn't present. I'm not saying its pretty or that I like it, but at least provides some sort of limited interaction. Anyway, we've derailed enough, more to point. What did you have in mind for the GetTooltip method ?
Aye it does assume that, although it shouldn't break if a libtooltip isn't present. I'm not saying its pretty or that I like it, but at least provides some sort of limited interaction. Anyway, we've derailed enough, more to point. What did you have in mind for the GetTooltip method ?
Simply :
function lib:GetTooltip(name) return activeTooltips[name] end
What I have so far almost works: No text is displayed (but the frame is), so I'm having problems testing and refining it. At the moment, it supports frame-recycling, ClearLines(), AddLine(), AddColumn(), etc.
Any input would be appreciated - I'm tired of using GameTooltip with it's two-column limitation.
http://www.wowace.com/projects/libtooltip/
So do I. We're managing so far.
WoW's default tooltip - GameTooltip - has support for a maximum of two columns. This is a library for an addon to use in order to overcome this deficiency and possibly do a bit more, without doing too much else.
It's designed for an addon to use as its tooltip rather than the default GameTooltip.
Now I'm also concerned with small display tweaks, like tooltip border size and internal cell margin. They are constant values ATM. Should we allow to change them ? Where ?
ATM the number of columns and their alignment are set when the tooltip is acquired and cannot be changed afterward. Though this is not very flexible, it allows to keep the code small. I'd like to keep this design but adding optional parameters would become tricky. Any thought on this ?
Acquire now enforces the tooltip name to be a string. I do not see any good reason to do this. Anything that can be used as a table key should work (and the parameter should be renamed "instanceKey" or something like that).
And finally, I would like to tweak the default settings so the tooltip really looks like a GameTooltip by default. Has anyone an idea of the default backdrop, alpha, padding and margin settings to use ?
In the initial iteration of the library I'd like to keep the "static" definition of columns and alignments as well, unless someone has a viable suggestion of how this can be modified with minimal overhead.
In all honesty, the name must either be a frame (in almost every case the parent frame - frame to anchor the tooltip to) or a string referring to that. We choose one and with stick with it, imo. You have to think about Acquire in conjunction with IsAcquired. You will have to use the exact same type of argument, if you want something reliable returned and since IsAcquired is gonna be used by displays a lot, it makes no sense having them to "guess" how to call the method.
Btw I'm also thinking of returning the tooltip frame in IsAcquired if true. Everyone ok with this ? Thoughts ?
I was gonna look at this today when I come back from work but yes, some tweaking is in order.
IIRC, we didn't agree on actively restricting "name" to strings, though it would make sense with the current argument name (and that why I would like to rename it, e.g. "handle", "id" or "key" ?). Actually this "name" is only used as an index to the internal activeTooltips table. Anything but nil can be used as table index, including tables and frames. Leaving this choice open allows creative uses. By example, an addon could use itself as a key to be sure to acquire an unique tooltip instance. Obviously IsAcquired should accept the same kind of parameters.
Even if you have your own specific purpose in mind, please remember that LibTooltip is a general-purpose library. We shouldn't take design decision based only on a specific use case.
IsXXX method must return a boolean. If we wanted a method to return the tooltip, it should be named GetXXX, e.g. GetTooltip. So I'd rather add a new method for this.
On principle I agree that leaving the choice open is "the right thing to do". In practice however, this can cause complications with IsAcquired, unless you intend this to be a method that will be used internally by the addon that constructs the tooltip. My point is, at the very least provide some recommendations.
It is my point exactly that because it is meant to be general-purpose, it would be to the best interest of everyone to support certain common sense elements. I can only picture (and correct me if I'm wrong) 2 types of addons that will want to use the lib. Addons that need (to create/populate) a multi-column tooltip and possibly displays to manipulate aspects of the tip, where applicable. How many other choices are there ?
Agreed.
About the displays, there are three possibilities :
Using IsAcquired/GetTooltip to try to interact with the tooltip in the third case is just an hack. It will be broken by any LDB datasource that does something like this :
As I already said, this is an "issue" with the LDB data specifications. And there is no way to reliably fix this in LibTooltip. Even if we restricted the tooltip name to a string, anyone could write a Broker_DeathCounter LDB datasource that created a tooltip named "MyOwnFooBaredTooltip".
This is not applicable in our case, since the display cannot "assume" that a plugin would be using Libtooltip API inside an OnTooltipShow, so that it can use :Acquire and provide the tooltip frame returned to the OnTooltipShow func. A display simply cannot know that (with the current implementation that is).
This may be a possibility, although I always pictured it as an option for non-dynamic stuff. Good call though.
It wouldn't break if the display was calling its setters after OnEnter in our case and was only setting very basic stuff. That's not the point anyway, since a display can simply use our iterate method and go through the list of active tooltips, get the relativeto frame, match it with its own and thus locate the active tip. Is that less of a "hack" ? I do agree though, that you have a point about detection not actually being reliable via IsAcquired.
It is totally a hack. It is a workaround to a "hole" in the LDB API. It assumes the LDB OnEnter callback creates a LibTooltip and anchors said tooltip to the displaying frame.
The real solution would be that the LDB specifications enforced the OnEnter callback to return the frame used as a tooltip, if any was created.
That would allow this kind of code from the display POV :
<script src="http://gist.github.com/18057.js"></script>
But this is not the case...
Simply :