Thread Tools Display Modes
08/17/14, 07:44 AM   #1
Dingodan
 
Dingodan's Avatar
Join Date: Apr 2014
Posts: 50
Grid

It would be great if someone could make an addon with keybind for toggle to show an grid all over the screen to align addon ui's.
Like this
  Reply With Quote
08/23/14, 10:34 AM   #2
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
I'm going to try to do something like this as a way to learn a little bit about textures and photo editing. I would assume it would encompass things like:
  1. Getting current screen size
  2. dividing screen by grid block size
  3. dynamically creating required number of blocks
  4. displaying grid as lowest possible layer
  5. possibly allowing block size modification

As I said, the hard part for me will be actually getting a texture made right and put into the addon correctly. Most of the rest I shouldn't have as much problem on.

It's a project at least!
  Reply With Quote
08/23/14, 12:04 PM   #3
sirinsidiator
 
sirinsidiator's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 1,567
I know you want to learn about textures, but I imagine you could also use LineControl elements to achieve this.
  Reply With Quote
08/23/14, 12:09 PM   #4
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Texture is actually the easy part, since you don't need any. Just make a texture control template:
xml Code:
  1. <Texture name="GridLine" color="aa000000" layer="BACKGROUND" virtual="true">
  2.    <Dimensions x="1" y="1" />
  3. </Texture>
... and create as many as needed using ZO_ControlPool, and change width or height.
  Reply With Quote
08/23/14, 01:20 PM   #5
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
Originally Posted by sirinsidiator View Post
I know you want to learn about textures, but I imagine you could also use LineControl elements to achieve this.
I thought about that too, but it still wants a texture for the line.

Originally Posted by merlight View Post
Texture is actually the easy part, since you don't need any. Just make a texture control template:
xml Code:
  1. <Texture name="GridLine" color="aa000000" layer="BACKGROUND" virtual="true">
  2.    <Dimensions x="1" y="1" />
  3. </Texture>
... and create as many as needed using ZO_ControlPool, and change width or height.
I'll take a look at that too. As I said, I'm using this as sort of a learning exercise in texture creations and implementation, so creating a simple box wasn't something too time consuming to learn.
  Reply With Quote
08/28/14, 09:11 AM   #6
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
Gah. I understand the concept of ControlPool, but I cannot seem to wrap my head around implementation. I see it called in different addons different ways and that gets confusing. I think what is getting me is what parameters it takes. Two examples from two addons:

Lua Code:
  1. ZO_ControlPool.New(self, "XRGACompassPin", ZO_CompassContainer, XRGA.AddonInfo.Prefix.."Pin")
Lua Code:
  1. self.container = GetControl(scrollContainer, "ScrollChild")
  2.     self.checkboxPool = ZO_ControlPool:New("ZO_Options_Checkbox", self.container, "Checkbox")

So obviously self is the object the pool will be in. The first string object is the control (so in my case "GridLine"). The third parameter seems to be some container reference, though I cannot understand how that would apply to mine. The last parameter is the prefix for the ID of each object.

I guess that means I'm stuck on what container object I should use. Any thoughts?
  Reply With Quote
08/28/14, 09:34 AM   #7
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
To follow on with seeing if I understand ControlPool:

So once I have to Pool I essentially want to maintain a table of created objects that are in use and a table of objects that have been released.

I use AcquireObject() to get/create a new control, place it in the table I created, modify it to what want and display it.

When the grid is 'disabled', I release all the objects back to the pool for the next use.
  Reply With Quote
08/28/14, 10:47 AM   #8
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Lua Code:
  1. pool = ZO_ControlPool:New(templateName, parentControl, namePrefix)
  2. pool:SetCustomFactoryBehavior(
  3.     function (control)
  4.         -- custom init called for each new control created (not for each Acquire!)
  5.     end)
  6. pool:SetCustomResetBehavior(
  7.     function (control)
  8.         -- custom cleanup called for each Release
  9.     end)
  10.  
  11. control, key = pool:AcquireObject()
  12. pool:ReleaseObject(key)
  13.  
  14. pool:ReleaseAllObjects()

templateName ... is the name of a virtual control in XML
parentControl ... optional parent to all controls created by the pool; if it's nil, GuiRoot will be their parent
namePrefix ... optional "prefix" to created controls' names

For example, if parentControl:GetName() == "GridContainer" and namePrefix == "Line", created child controls will be named "GridContainerLine1", "GridContainerLine2", etc. If namePrefix == nil, templateName will be used instead (which makes ugly long names, so I rather use prefix ).

You don't have to maintain a table of active objects unless you want to release them selectively. In this case I think you could just hide the parent control, and only rebuild the grid (ReleaseAllObjects and re-create) when settings change (screen resolution, grid spacing).

Last edited by merlight : 08/28/14 at 10:52 AM. Reason: added custom reset comment
  Reply With Quote
08/28/14, 11:07 AM   #9
Garkin
 
Garkin's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 832
Originally Posted by skyraker
To follow on with seeing if I understand ControlPool:

So once I have to Pool I essentially want to maintain a table of created objects that are in use and a table of objects that have been released.

I use AcquireObject() to get/create a new control, place it in the table I created, modify it to what want and display it.

When the grid is 'disabled', I release all the objects back to the pool for the next use.
Yes, it is exactly as you say. AcquireObject() returns first free object or if there is not free object, it will create a new one using the factory function in case of object pool - ZO_ObjectPool:New(factoryFunction, resetFunction) or from the template in case of control pool - ZO_ControlPool:New(templateName, parent, prefix).

As I did't want to use XML (you have to use XML to define control template), I have used just object pool instead of control pool in my Bloody Screen addon (v0.1). Here is how it works:
Warning: Spoiler


In your case you will have to do the same as me - create top level window of the same size as GuiRoot, set draw layer to overlay as you want to display grid on the top of other windows and then create lines.

top level window:
Lua Code:
  1. TLW = WINDOW_MANAGER:CreateTopLevelWindow()
  2. TLW:SetAnchorFill(GuiRoot)
  3. TLW:SetDrawLayer(DL_OVERLAY)
  4. TLW:SetMouseEnabled(false)

simple object pool for lines:
Lua Code:
  1. local function FactoryFunction(pool)
  2.    local line = WINDOW_MANAGER:CreateControl(nil, TLW, CT_TEXTURE)
  3.    line:SetColor(0,0,0,1) --black
  4.    return line
  5. end
  6.  
  7. local function ResetFunction(object)
  8.    object:SetHidden(true)
  9. end
  10.  
  11. local objectPool = ZO_ObjectPool:New(FactoryFunction, ResetFunction)
  12. --if you omit reset function, object pool will use default ZO_ObjectPool_DefaultResetControl function which works exactly the same as my ResetFunction - it will just hide released object.

And then create lots of lines:
Lua Code:
  1. local GRID_SIZE = 50
  2. local LINE_THICKNESS = 3
  3. local SCREEN_WIDTH, SCREEN_HEIGHT = GuiRoot:GetDimensions()
  4.  
  5. --horizontal lines
  6. for i = 1, zo_floor(SCREEN_WIDTH / GRID_SIZE) do
  7.    local line = objectPool:AcquireObject()
  8.    line:SetDimensions(SCREEN_WIDTH, LINE_THICKNESS)
  9.    line:SetAnchor(TOPLEFT, TLW, TOPLEFT, GRID_SIZE * i, 0)
  10.    line:SetHidden(false)
  11. end
  12.  
  13. --vertical lines
  14. for i = 1, zo_floor(SCREEN_HEIGHT / GRID_SIZE) do
  15.    local line = objectPool:AcquireObject()
  16.    line:SetDimensions(LINE_THICKNESS, SCREEN_HEIGHT)
  17.    line:SetAnchor(TOPLEFT, TLW, TOPLEFT, 0, GRID_SIZE * i)
  18.    line:SetHidden(false)
  19. end

Last edited by Garkin : 08/28/14 at 11:15 AM.
  Reply With Quote
08/29/14, 02:09 PM   #10
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
Thanks Garkin. You really made that easy to understand.

Though I found something odd in my first implementation. With a line thickness of 2+, everything looks like nice, even squares (except on the bottom and right which is expected with screen dimensions).

Thickness 2

With one thickness, you can tell that it doesn't seem to make nice squares. I looked and made sure that the line data is correct.

Thickness 1

Sorry about using links. I'm not very proficient at uploading images to these posts.

Last edited by skyraker : 08/29/14 at 02:12 PM.
  Reply With Quote
08/29/14, 03:13 PM   #11
Dingodan
 
Dingodan's Avatar
Join Date: Apr 2014
Posts: 50
You guys are awsome.

i can't wait to use this when it is finished.
  Reply With Quote
08/29/14, 03:48 PM   #12
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
Yeah, almost done with a early version.

Still incorporating settings and saved variables. Then will probably have to work out bugs.
  Reply With Quote
08/29/14, 04:31 PM   #13
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Originally Posted by skyraker View Post
Thanks Garkin. You really made that easy to understand.

Though I found something odd in my first implementation. With a line thickness of 2+, everything looks like nice, even squares (except on the bottom and right which is expected with screen dimensions).

Thickness 2

With one thickness, you can tell that it doesn't seem to make nice squares. I looked and made sure that the line data is correct.

Thickness 1

Sorry about using links. I'm not very proficient at uploading images to these posts.
I don't know, try postimg.org, those you posted are shrinked; looks like some lines are missing, but I can't tell whether it's caused by the resize or by the game

Textures have methods IsPixelRoundingEnabled(), SetPixelRoundingEnabled(bool). Not sure what's the default, try setting the opposite

Also, there's GetUIGlobalScale(). In Map control they use it to compute mapPixels = mapUnits * GetUIGlobalScale().
So I'd try hline:SetHeight(1 / GetUIGlobalScale()) and see how it looks.
  Reply With Quote
08/29/14, 05:34 PM   #14
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
I was wondering if it was the UI Scale, but with the other thicknesses working right it would seem odd that a thickness of 1 would be the only issue. I may give it a try later.

It isn't missing lines in the second image, that is the problem. It just seems to be displaying every so many lines off, despite having the correct anchor point value.
  Reply With Quote
08/29/14, 06:11 PM   #15
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
AlignGrid
  Reply With Quote
09/01/14, 09:11 PM   #16
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Tried it, at first I didn't see any issues with line width. Normally I'm playing in windowed fullscreen in native resolution (1920x1080), so GetUIGlobalScale() was 1. When I switched to windowed, GetUIGlobalScale() changed to 0.6something and the grid looked really bad.

I also rewrote grid creation so that line width and grid size settings are in pixels. That is, I divided them by UI scale. But even so, some lines appeared thicker probably due to accumulation of rounding errors. Finally I disabled pixel rounding and it looks ok now.

Here's my modified code: https://gist.github.com/merlight/25e02368a1e6187f989c
In addition to the pixel changes described above, there are some more:
- I'm anchoring lines to TOP/LEFT (center), so the red lines have zero offsets and thus they're in the true center
- only every 10th line has full opacity from settings; in-between lines have 40% or 70% opacity (this doesn't work with changing the setting on the fly)
- I wanted to force the red lines to be drawn last, so they're not overlapped by the black ones; but I doubt showing them last will ensure that; perhaps we should SetDrawLevel?
  Reply With Quote
09/02/14, 04:26 PM   #17
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
Originally Posted by merlight View Post
Tried it, at first I didn't see any issues with line width. Normally I'm playing in windowed fullscreen in native resolution (1920x1080), so GetUIGlobalScale() was 1. When I switched to windowed, GetUIGlobalScale() changed to 0.6something and the grid looked really bad.

I also rewrote grid creation so that line width and grid size settings are in pixels. That is, I divided them by UI scale. But even so, some lines appeared thicker probably due to accumulation of rounding errors. Finally I disabled pixel rounding and it looks ok now.

Here's my modified code: https://gist.github.com/merlight/25e02368a1e6187f989c
In addition to the pixel changes described above, there are some more:
- I'm anchoring lines to TOP/LEFT (center), so the red lines have zero offsets and thus they're in the true center
- only every 10th line has full opacity from settings; in-between lines have 40% or 70% opacity (this doesn't work with changing the setting on the fly)
- I wanted to force the red lines to be drawn last, so they're not overlapped by the black ones; but I doubt showing them last will ensure that; perhaps we should SetDrawLevel?
Nice changes. My next update will incorporate your changes, as well as update settings to take advantage of this. For now, the 'fix' for changing transparency I decided to use was to simply adjust the TLW transparency.

Setting the two red lines as being last to be drawn made sure they were over all others. At least on my screen they are.
  Reply With Quote
09/02/14, 05:04 PM   #18
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Originally Posted by skyraker View Post
Nice changes. My next update will incorporate your changes, as well as update settings to take advantage of this. For now, the 'fix' for changing transparency I decided to use was to simply adjust the TLW transparency.
I was too tired to see such simple solution when I wrote that lol

Originally Posted by skyraker View Post
Setting the two red lines as being last to be drawn made sure they were over all others. At least on my screen they are.
I modified the gist a bit more, finally anchoring all lines to screen center (another too-late-to-be-obvious casee ) and I set draw levels just to be sure. Maybe I'll ask ZOS for some more interesting blending modes next.
  Reply With Quote
09/02/14, 05:16 PM   #19
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
For the record, here's some info about pixel rounding from http://forums.elderscrollsonline.com...tes-change-log

Originally Posted by ZOS_JessicaFolsom
Controls that render textures have all had SetPixelRoundingEnabled and IsPixelRoundingEnabled added. Pixel rounding determines how screen-space positioning works for controls. If enabled, the positions of the control's final screen rect are rounded to the next pixel value before being rendered (rather than letting the shader determine which pixels the control covers). This helps reduce jitter for animated controls, sometimes at the cost a legibility/blurriness.
  Reply With Quote

ESOUI » AddOns » AddOn Search/Requests » Grid

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off