I came across this library and would like to play a little bit with it but some things seem weird to me :
1/ the way you seem to use it in your DKP addon is by not embedding it (I guess you have a standalone version), any particular reason ?
2/ I have very specific needs, I'm trying to display reports that have a varying number of lines AND columns, does that mean that I should recreate a new instance each time I want to change the columns ?
You'd have to reset the column information and data information.... It might not be worth it. Try it out though and let me know if you run into problems.
this seemed like the best way to get these to you...
here's my slightly customized version for gyp. there is still a nil causing issues when i resize too much and there's some cosmetic issue with the multi-selection, but it's mostly okay.
Just FYI, I am dangerously close to getting a working lib-st widget wrapper for AceGUI-3. I'll post code once there's stuff mostly working; I keep having to jump between rewriting my own addon, to the lib-st<->AceGUI wrapper, to either of those behind-the-scenes libraries, and then back again. (Thank Nevcairiel for getting me this far!)
I don't know about lib-st, but Nev fixed the AceGUI bugs that were causing my own addon to explode. And that, in turn, let me get back to working on the lib-st widget. :-)
Ain't got anything usable yet. It's somewhat specific to my guild, but I'll probably end up posting it somewhere as a working example of how to abuse the widget code. The fix from Nevcairiel came out of http://forums.wowace.com/showthread.php?t=17114 and you can see the placeholder labels where lib-st is going to go. (Was using "stuff goes here" and some alphabet text in a two-column table.)
Interesting. I'm very interested to see what you come up with. I've been hesitant to dig too deep into this as I've been on a leave from wow, but still popping in to support guildies who use the dkp mod that uses this lib.
I've also been worried that the structure of lib-st does not follow any of the AceGUI conventions... and a rewrite would be hefty. I hope you find the lib useful and easy to work with.
I've also been worried that the structure of lib-st does not follow any of the AceGUI conventions...
I tried, very very briefly, to do the true "wrapper" layer thing... not going to happen, at least not on this iteration. Trying to take the common AceGUI widget API and translate all of it into lib-st calls is just not feasible in many cases, especially with regard to On* events.
Instead, this version takes the viewpoint that the user will need to know how to work with a lib-st object directly. The user can either set up the lib-st object and then create a widget around it, or else can create the widget and then reach inside to control the st. It's a very thin wrapper, just enough functionality that an AceGUI container can treat this widget like any other widget.
I also considered making the lib-st a container instead of a plain widget. That fell apart faster than a cheesecake hitting a lake. Making an st object able to contain other AceGUI widgets would require rewriting large chunks of lib-st, which is beyond the scope of what I wanted to accomplish (to me, the lib-st widget wrapper is a means rather than the ends).
I hope you find the lib useful and easy to work with.
There are two things that sort of bother me a little bit.
(1) I was surprised that there is no "AddRow"-type function. It could simply take a table representing another ("row object" as SetData calls them), insert it into the larger .data table, and go through the same refresh/resort routine as the major SetData does.
This isn't going to be a problem for my addon, since I'm maintaining an external "real" version of the data table. As the data expands every few minutes, I append another row object and then re-call SetData passing in the same table.
(2) There's going to be a lot of garbage collection churn, and that's just with lib-st, not the widget wrapper. There are improvements that could be made but would require nontrivial changes to lib-st, so I'm trying to avoid thinking about that until the larger project is finished. :-) There might be a suggested patch emerging out of this, or maybe not, depending on caffeine and motivation levels!
All told, lib-st beats the hell out of anything I could have done by hand.
(1) I was surprised that there is no "AddRow"-type function. It could simply take a table representing another ("row object" as SetData calls them), insert it into the larger .data table, and go through the same refresh/resort routine as the major SetData does.
This isn't going to be a problem for my addon, since I'm maintaining an external "real" version of the data table. As the data expands every few minutes, I append another row object and then re-call SetData passing in the same table.
yeah, that's something i've struggled with as well -- i don't think libst was designed with a very dynamic data set in mind. i also have a native data set that gets pumped into a st.data table. recently, i've been thinking that instead of filling in the st.data field directly if it would be more appropriate to have the data table be only a single index into my true data and have all the other cell information be function calls to access my data table indirectly.
this would make all my cells look pretty much identical, which makes me wonder if then there should be a system to define cells based on a heirarchy of prototypes -- one global prototype, one prototype per column, one prototype per row. that would mean you could theoretically use only prototypes to define you table data and then simply ask for a number of rows without having to explicitly fill in any data.
internally, those prototypes could simply fill in the celldata fields or they could be dynamic (and therefore you could change the global prototype and have it globally alter the behavior of your entire table for any fields that weren't over-ridden by other definitions)...
but the big item on my wishlist is the ability to group and subgroup rows (with groups being collapsible).
Actually, I lied, there's one area that was causing problems. A proper solution would require modifying acegui+lib-st code, so I just kludged around it for my addon and went on.
There's no good way to have a lib-st object expand to fill vertical space. The parameters are "height of each row" and "number of visible rows", but there's no easy way of saying "display however many rows fit in <Y> amount of pixels" or (ideally) "vertically expand to fit <that> frame".
Coming from the other direction, all of AceGUI's containers revolve around GetHeight() calls... but those don't return useful information until after the UI has finished its redraw cycle. Until then, they return the sizes based on their hardcoded default values (50x50, 100x200, etc), even though :SetPoint has already been dispatched to anchor them to larger sizes. That's mostly a limitation of the Blizzard system, although this is where the kludge comes in. I document it here mostly so that others coming after me will understand why this part of the code is so cringeworthy.
If you've looked at the mockup screenshots I posted, you'll see I'm using a TabGroup container. The lib-st widget is going to be in one (maybe more) of those tabs. In order to get the visible interior height of the tab drawing area, I stuck code in at the bottom of the bit that populates one of the other tabs. It calls tabs.children[1].frame:GetTop() and :GetBottom(), subtracts them, prints the result. I will pause here so that you can finish retching. Those functions return correct values in this case.
It printed 366.something pixels. I said, fine, screw it, and so the "number of displayed rows" argument passed to CreateST is math.floor(366/rowheight). I drank a bottle of vodka to quiet the complaining voice of the conscientious computer scientist deep within me, noticed that the displayed lib-st object fit perfectly in the tabgroup, and got on with the rest of the addon. I'll probably have to disable resizing the addon frame as a whole, but meh.
So yeah, that's the only disconnect. AceGUI containers can't tell you the calculated height until after they've been populated; lib-st objects have to be told their total height ahead of time. My ugly "iterative" hardcoded number lets me make progress but clearly isn't a good general solution.
A related problem is column width, but goals like percentage widths and suchlike have been discussed in this thread already.
(1) I was surprised that there is no "AddRow"-type function. It could simply take a table representing another ("row object" as SetData calls them), insert it into the larger .data table, and go through the same refresh/resort routine as the major SetData does.
This isn't going to be a problem for my addon, since I'm maintaining an external "real" version of the data table. As the data expands every few minutes, I append another row object and then re-call SetData passing in the same table.
(2) There's going to be a lot of garbage collection churn, and that's just with lib-st, not the widget wrapper. There are improvements that could be made but would require nontrivial changes to lib-st, so I'm trying to avoid thinking about that until the larger project is finished. :-) There might be a suggested patch emerging out of this, or maybe not, depending on caffeine and motivation levels!
All told, lib-st beats the hell out of anything I could have done by hand.
you shouldnt need to setdata with the same table. just appending the data to your data table backend... resorting or calling refresh should do the rest.
Where will the garbage churn be around? I've put in some fixes for unneeded table creation, can you point out any other places?
Actually, I lied, there's one area that was causing problems. A proper solution would require modifying acegui+lib-st code, so I just kludged around it for my addon and went on.
There's no good way to have a lib-st object expand to fill vertical space. The parameters are "height of each row" and "number of visible rows", but there's no easy way of saying "display however many rows fit in <Y> amount of pixels" or (ideally) "vertically expand to fit <that> frame".
i grow and shrink my scrolling table in gyp without much difficulty. i just call SetDisplayRows() with the new value. i fire it off when i resize my window, account for borders, then divide by the row size, then call SetDisplayRows... i might call SetDisplayCols as well because it might require calling both (can't remember off the top of my head).
i don't see any reason you couldn't create an intermediary parent than is exactly the size of the table you want, hook the sizechange event, and have the frame resize automatically call a SetDisplayRows function with the proper number of rows. or for that matter, this could even be built into lib-st's main frame perhaps...
you shouldnt need to setdata with the same table. just appending the data to your data table backend... resorting or calling refresh should do the rest.
Good to know, thanks. That's not obvious from the documentation. Perhaps you could include Refresh on the API page, and mention the above on the SetData page?
edit: actually, Refresh doesn't draw anything; SortData draws the table (but seems a misnomer since I'm not sorting by any field ever).
i grow and shrink my scrolling table in gyp without much difficulty. i just call SetDisplayRows() with the new value. i fire it off when i resize my window, account for borders, then divide by the row size, then call SetDisplayRows... i might call SetDisplayCols as well because it might require calling both (can't remember off the top of my head).
(emphasis mine)
That new value isn't available during the initial display. None of the callbacks for resize ever get fired. I know, because I littered AceGUI-3.0.lua and AceGUIWidget-TabGroup.lua with print() statements. Every size-type number came back with the hardcoded placeholder defaults. For TabGroup, that's a height of 100(frame), 70(border), or 50(content), depending on which member frame was being queried out of desperation that time around. All of the pre-hooked, automated, should-just-work callbacks receive those values.
After the UI cycles, all those numbers become useful, but then it's too late. I shrugged, hacked around it, and now I don't care.
i don't see any reason you couldn't create an intermediary parent than is exactly the size of the table you want, hook the sizechange event, and have the frame resize automatically call a SetDisplayRows function with the proper number of rows. or for that matter, this could even be built into lib-st's main frame perhaps...
I never claimed that no solution was possible. I'm sure that could be made to work. Somebody who actually understands the code could probably do lots of things.
That new value isn't available during the initial display. None of the callbacks for resize ever get fired. I know, because I littered AceGUI-3.0.lua and AceGUIWidget-TabGroup.lua with print() statements. Every size-type number came back with the hardcoded placeholder defaults. For TabGroup, that's a height of 100(frame), 70(border), or 50(content), depending on which member frame was being queried out of desperation that time around. All of the pre-hooked, automated, should-just-work callbacks receive those values.
After the UI cycles, all those numbers become useful, but then it's too late. I shrugged, hacked around it, and now I don't care.
I never claimed that no solution was possible. I'm sure that could be made to work. Somebody who actually understands the code could probably do lots of things.
i really don't know anything about ace-gui, but wouldn't it at some point resize he lib-st frame (assuming that you are attaching anchors, which maybe you're not)? and wouldn't that fire a resize event (with GetHeight returning the proper numbers)? or is that part of the blizz design flaw you were talking about?
anyway, the point of my post was to address how i think a simple solution might be found and that perhaps lib-st ought to understand resizing natively by reacting to size-change events on its own. i think that's probably not a ton of code -- maybe 10 lines or something unless i'm missing something (which is entirely possible).
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
You'd have to reset the column information and data information.... It might not be worth it. Try it out though and let me know if you run into problems.
here's my slightly customized version for gyp. there is still a nil causing issues when i resize too much and there's some cosmetic issue with the multi-selection, but it's mostly okay.
I've also been worried that the structure of lib-st does not follow any of the AceGUI conventions... and a rewrite would be hefty. I hope you find the lib useful and easy to work with.
I tried, very very briefly, to do the true "wrapper" layer thing... not going to happen, at least not on this iteration. Trying to take the common AceGUI widget API and translate all of it into lib-st calls is just not feasible in many cases, especially with regard to On* events.
Instead, this version takes the viewpoint that the user will need to know how to work with a lib-st object directly. The user can either set up the lib-st object and then create a widget around it, or else can create the widget and then reach inside to control the st. It's a very thin wrapper, just enough functionality that an AceGUI container can treat this widget like any other widget.
I also considered making the lib-st a container instead of a plain widget. That fell apart faster than a cheesecake hitting a lake. Making an st object able to contain other AceGUI widgets would require rewriting large chunks of lib-st, which is beyond the scope of what I wanted to accomplish (to me, the lib-st widget wrapper is a means rather than the ends).
There are two things that sort of bother me a little bit.
(1) I was surprised that there is no "AddRow"-type function. It could simply take a table representing another ("row object" as SetData calls them), insert it into the larger .data table, and go through the same refresh/resort routine as the major SetData does.
This isn't going to be a problem for my addon, since I'm maintaining an external "real" version of the data table. As the data expands every few minutes, I append another row object and then re-call SetData passing in the same table.
(2) There's going to be a lot of garbage collection churn, and that's just with lib-st, not the widget wrapper. There are improvements that could be made but would require nontrivial changes to lib-st, so I'm trying to avoid thinking about that until the larger project is finished. :-) There might be a suggested patch emerging out of this, or maybe not, depending on caffeine and motivation levels!
All told, lib-st beats the hell out of anything I could have done by hand.
yeah, that's something i've struggled with as well -- i don't think libst was designed with a very dynamic data set in mind. i also have a native data set that gets pumped into a st.data table. recently, i've been thinking that instead of filling in the st.data field directly if it would be more appropriate to have the data table be only a single index into my true data and have all the other cell information be function calls to access my data table indirectly.
this would make all my cells look pretty much identical, which makes me wonder if then there should be a system to define cells based on a heirarchy of prototypes -- one global prototype, one prototype per column, one prototype per row. that would mean you could theoretically use only prototypes to define you table data and then simply ask for a number of rows without having to explicitly fill in any data.
internally, those prototypes could simply fill in the celldata fields or they could be dynamic (and therefore you could change the global prototype and have it globally alter the behavior of your entire table for any fields that weren't over-ridden by other definitions)...
but the big item on my wishlist is the ability to group and subgroup rows (with groups being collapsible).
not to say that libst doesn't do its job well...
There's no good way to have a lib-st object expand to fill vertical space. The parameters are "height of each row" and "number of visible rows", but there's no easy way of saying "display however many rows fit in <Y> amount of pixels" or (ideally) "vertically expand to fit <that> frame".
Coming from the other direction, all of AceGUI's containers revolve around GetHeight() calls... but those don't return useful information until after the UI has finished its redraw cycle. Until then, they return the sizes based on their hardcoded default values (50x50, 100x200, etc), even though :SetPoint has already been dispatched to anchor them to larger sizes. That's mostly a limitation of the Blizzard system, although this is where the kludge comes in. I document it here mostly so that others coming after me will understand why this part of the code is so cringeworthy.
If you've looked at the mockup screenshots I posted, you'll see I'm using a TabGroup container. The lib-st widget is going to be in one (maybe more) of those tabs. In order to get the visible interior height of the tab drawing area, I stuck code in at the bottom of the bit that populates one of the other tabs. It calls tabs.children[1].frame:GetTop() and :GetBottom(), subtracts them, prints the result. I will pause here so that you can finish retching. Those functions return correct values in this case.
It printed 366.something pixels. I said, fine, screw it, and so the "number of displayed rows" argument passed to CreateST is math.floor(366/rowheight). I drank a bottle of vodka to quiet the complaining voice of the conscientious computer scientist deep within me, noticed that the displayed lib-st object fit perfectly in the tabgroup, and got on with the rest of the addon. I'll probably have to disable resizing the addon frame as a whole, but meh.
So yeah, that's the only disconnect. AceGUI containers can't tell you the calculated height until after they've been populated; lib-st objects have to be told their total height ahead of time. My ugly "iterative" hardcoded number lets me make progress but clearly isn't a good general solution.
A related problem is column width, but goals like percentage widths and suchlike have been discussed in this thread already.
you shouldnt need to setdata with the same table. just appending the data to your data table backend... resorting or calling refresh should do the rest.
Where will the garbage churn be around? I've put in some fixes for unneeded table creation, can you point out any other places?
i grow and shrink my scrolling table in gyp without much difficulty. i just call SetDisplayRows() with the new value. i fire it off when i resize my window, account for borders, then divide by the row size, then call SetDisplayRows... i might call SetDisplayCols as well because it might require calling both (can't remember off the top of my head).
i don't see any reason you couldn't create an intermediary parent than is exactly the size of the table you want, hook the sizechange event, and have the frame resize automatically call a SetDisplayRows function with the proper number of rows. or for that matter, this could even be built into lib-st's main frame perhaps...
Good to know, thanks. That's not obvious from the documentation. Perhaps you could include Refresh on the API page, and mention the above on the SetData page?
edit: actually, Refresh doesn't draw anything; SortData draws the table (but seems a misnomer since I'm not sorting by any field ever).
(emphasis mine)
That new value isn't available during the initial display. None of the callbacks for resize ever get fired. I know, because I littered AceGUI-3.0.lua and AceGUIWidget-TabGroup.lua with print() statements. Every size-type number came back with the hardcoded placeholder defaults. For TabGroup, that's a height of 100(frame), 70(border), or 50(content), depending on which member frame was being queried out of desperation that time around. All of the pre-hooked, automated, should-just-work callbacks receive those values.
After the UI cycles, all those numbers become useful, but then it's too late. I shrugged, hacked around it, and now I don't care.
I never claimed that no solution was possible. I'm sure that could be made to work. Somebody who actually understands the code could probably do lots of things.
i really don't know anything about ace-gui, but wouldn't it at some point resize he lib-st frame (assuming that you are attaching anchors, which maybe you're not)? and wouldn't that fire a resize event (with GetHeight returning the proper numbers)? or is that part of the blizz design flaw you were talking about?
anyway, the point of my post was to address how i think a simple solution might be found and that perhaps lib-st ought to understand resizing natively by reacting to size-change events on its own. i think that's probably not a ton of code -- maybe 10 lines or something unless i'm missing something (which is entirely possible).