SpaceTags
Rather than posting in lots of different places I figured I'd make one blog post here and then spam the various boards with links. The background for this post is that I keep feeling that the configuration of various unitframe and hud addons (as well as some other UI components) leave me wanting when it comes to spatial positioning of the elements. I want to be able to hook my UI elements to parts of the screen and/or to one another. If I move one of the parent objects I want the other objects to move with it. If I change my resolution I want everything to update smoothly (not be left offscreen for example).
When trying to write up some suggestions for mHud and ag_uf I realized that there might be a way to add a library that would provide positioning for multiple addons (and allow them to attach to one another. I therefore present my proposal for SpaceTags.
The premise is that there each object can attach to another object in a number of ways. The top object in the hierarchy is "window", but that should probably be "viewport" instead (assuming the latter automatically adjusts for things like fubar/titanpanel etc). When attaching an object to another, you specify the parent, the connection point and the margins (offsets from the connection point).

UI.main is the reference object and the green (and red) boxes are the positions around it defined by a combination of vertical and horizontal tags plus vertical and horizontal margins. The center tags (hcenter and vcenter) are defaults and do not need to be specified. The default margins are 0.
Thus, to attach UI.child to UI.main we would have the following:
ui.child{ui.main, above, alignright, vmargin=10, hmargin=10}
When the parent object is "window", the corner positions are all (obviously) the same and you have to use negative v and h margins to get the position inside of the window.
Apart from these I also propose two more position tags:
hmirror, vmirror
These would allow you to mirror the placement of objects around the middle of the window (viewport). While I'm not sure vmirror would ever be used, hmirror is handy for positioning HUD objects as well as some UIs that have player and target unit-frames mirrored.
I'll finish up with an example of using these tags to position the following UI:
HUD left to right: tgthealth, playerhealt, playermana, tgtmana
uf.player{window, top, alignleft, vmargin=-10, hmargin=-10}
uf.pet{uf.player, below, alignright, vmargin=2}
uf.target{uf.player, right, hmargin=30}
uf.tot{uf.target, right, hmargin=30}
uf.partygroup{uf.player, leftalign, below, vmargin=50}
uf.party{self, below, vmargin=10}
uf.partytarget{uf.party, right, hmargin=20}
hud.playerhealth{window, hmargin=-200}
hud.playermana{hud.playerhealth, hmirror}
hud.targethealth{hud.playerhealth, left, hmargin=-30}
hud.targetmana{hud.targethealth, hmirror}
One further component is added in the example above to handle repeating groups of frames such as party and party targets. In the first case (party), the whole block is attached to the player frame and each party member is spaced using the "self" tag. For PartyTargets each target is attached, not to one another, but to the parent party member. Thus if you changed the spacing between party members the party targets would follow.
Another thing to note is that the hud.targethealth has a hmargin of -30. This is because, presumably, the object for the hud.targethealth would be a rectangle and we need to overlap the objects to get the arcs closer to one another.
I would propose that a system such as this one would be useful for many different UI objects and being able to share them isn't a bad thing. I can see attaching my cooldown timers to the right of my HUD etc.
One final note, the tags as written above could obviously be manipulated by a UI fairly easily... no need to force users to write the tags themselves. Also, an obvious parent/attachment point is "none" if you want to position the object in some random way.
Comments are welcome!

1 comment:
Hello.
To me what you are writing about sounds a lot like <Region>:SetPoint().
There are AddOns that make it possible to define a list of regions (frames) and place them relatively. An example (though currently quite oudated, but still in working fashion I think) would be Visor2 with Visor2GUI.
Post a Comment