ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   AddOn Search/Requests (https://www.esoui.com/forums/forumdisplay.php?f=165)
-   -   Grid (https://www.esoui.com/forums/showthread.php?t=2139)

Dingodan 08/17/14 07:44 AM

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

skyraker 08/23/14 10:34 AM

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!

sirinsidiator 08/23/14 12:04 PM

I know you want to learn about textures, but I imagine you could also use LineControl elements to achieve this. ;)

merlight 08/23/14 12:09 PM

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.

skyraker 08/23/14 01:20 PM

Quote:

Originally Posted by sirinsidiator (Post 11782)
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.

Quote:

Originally Posted by merlight (Post 11783)
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.

skyraker 08/28/14 09:11 AM

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?

skyraker 08/28/14 09:34 AM

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.

merlight 08/28/14 10:47 AM

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).

Garkin 08/28/14 11:07 AM

Quote:

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

skyraker 08/29/14 02:09 PM

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.

Dingodan 08/29/14 03:13 PM

You guys are awsome.

i can't wait to use this when it is finished.

skyraker 08/29/14 03:48 PM

Yeah, almost done with a early version.

Still incorporating settings and saved variables. Then will probably have to work out bugs.

merlight 08/29/14 04:31 PM

Quote:

Originally Posted by skyraker (Post 11899)
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.

skyraker 08/29/14 05:34 PM

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.

skyraker 08/29/14 06:11 PM

AlignGrid

merlight 09/01/14 09:11 PM

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?

skyraker 09/02/14 04:26 PM

Quote:

Originally Posted by merlight (Post 11929)
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.

merlight 09/02/14 05:04 PM

Quote:

Originally Posted by skyraker (Post 11945)
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 :D

Quote:

Originally Posted by skyraker (Post 11945)
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.

merlight 09/02/14 05:16 PM

For the record, here's some info about pixel rounding from http://forums.elderscrollsonline.com...tes-change-log

Quote:

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.



All times are GMT -6. The time now is 10:58 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2014 - 2022 MMOUI