Quantcast Overlapping NineSlice textures with ButtonFrameTemplate - WoWInterface
 
Thread Tools Display Modes
03-28-20, 10:05 AM   #1
LudiusMaximus
A Chromatic Dragonspawn
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 176
Overlapping NineSlice textures with ButtonFrameTemplate

I am using ButtonFrameTemplate for a frame.
But as my frame has a low height I get overlapping NineSlice textures resulting in the frame shaddows adding up.



Lua Code:
  1. local myFrame = CreateFrame("Frame", "myFrame", UIparent, "ButtonFrameTemplate")
  2. myFrame:SetPoint("TOPLEFT")
  3. ButtonFrameTemplate_HidePortrait(myFrame)
  4. myFrame:SetFrameStrata("HIGH")
  5. myFrame:SetWidth(430)
  6. myFrame:SetHeight(220)
  7.  
  8. myFrame.NineSlice.LeftEdge:Hide()
  9. myFrame.NineSlice.RightEdge:Hide()

As you can see, I already removed NineSlice.LeftEdge and NineSlice.RightEdge but is it possible to crop the NineSlice corner textures somehow?

Or is there another solution like using the templates differently?
__________________
~ Be the change you want to see in the world... of warcraft interface! ~
  Reply With Quote
03-28-20, 02:26 PM   #2
Vrul
An Onyxian Warder
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 352
I would resize the bottom corners and not hide the edges:
Code:
local myFrame = CreateFrame("Frame", "myFrame", UIparent, "ButtonFrameTemplate")
myFrame:SetPoint("TOPLEFT")
ButtonFrameTemplate_HidePortrait(myFrame)
myFrame:SetFrameStrata("HIGH")
myFrame:SetWidth(430)
myFrame:SetHeight(220)
 
local function ResizeCorner(parent, cornerName, newX, newY)
	local corner = parent[cornerName]
	local oldX, oldY = corner:GetSize()
	local L, R, T, B = 0, newX / oldX, 0, newY / oldY
	if cornerName:match("Right") then
		L, R = 1 - R, 1
	end
	if cornerName:match("Bottom") then
		T, B = 1 - B, 1
	end
	corner:SetSize(newX, newY)
	corner:SetTexCoord(L, R, T, B)
end

ResizeCorner(myFrame.NineSlice, "BottomLeftCorner", 36, 36)
ResizeCorner(myFrame.NineSlice, "BottomRightCorner", 36, 36)
  Reply With Quote
03-28-20, 05:05 PM   #3
LudiusMaximus
A Chromatic Dragonspawn
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 176
Thanks so much (again)! :-)
So it comes down to SetTexCoord() once more.


Can I ask a general question regarding this?

If I have a texture file
e.g. Interface/FrameGeneral/UIFrameMetal:



How would I go about to find the correct SetTexCoord() arguments for, say, the texture with the two topright buttom slots?

In this particular case I know that there is the Atlas name UI-Frame-Metal-CornerTopRightDouble, which I found out using Texture Atlas Viewer.

But for any texture in general, how do you find out your desired SetTexCoord() arguments?
Is there a tool for this as well?
__________________
~ Be the change you want to see in the world... of warcraft interface! ~
  Reply With Quote
03-28-20, 05:16 PM   #4
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,214
For the most part, find the Blizzard XML file the frame/texture is defined in and check for its TexCoords tag.
Code:
<TexCoords left="0" right="0.675" top="0" bottom="0.675"/>
Exporting the Blizzard UI
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
03-28-20, 05:39 PM   #5
LudiusMaximus
A Chromatic Dragonspawn
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 176
Originally Posted by Fizzlemizz View Post
For the most part, find the Blizzard XML file the frame/texture is defined in and check for its TexCoords tag.
Ah, thanks! I see that this is used quite a lot.

But when I try to find the textures and coordinates used by ButtonFrameTemplate, I seem to run into a dead end...

In BlizzardInterfaceCode\Interface\SharedXML\SharedUIPanelTemplates.xml I find the definition of ButtonFrameTemplate. But when I trace back the inheritances I end up here without any mention of Interface/FrameGeneral/UIFrameMetal or any of its Atlas equivalents:

Code:
  <Frame name="NineSlicePanelTemplate" mixin="NineSlicePanelMixin" frameLevel="500" setAllPoints="true" virtual="true">
    <Scripts>
      <OnLoad method="OnLoad"/>
    </Scripts>
  </Frame>
Is this a non-"for the most part" case, then?
__________________
~ Be the change you want to see in the world... of warcraft interface! ~
  Reply With Quote
03-28-20, 05:38 PM   #6
Vrul
An Onyxian Warder
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 352
Or you would open it in an image editor and count pixels to calculate the coords as they are in percentages of the image's dimensions.
  Reply With Quote
03-28-20, 06:26 PM   #7
Vrul
An Onyxian Warder
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 352
For your example you would use:
Code:
myFrame.NineSlice.TopRightCorner:SetTexture("Interface\\FrameGeneral\\UIFrameMetal")
myFrame.NineSlice.TopRightCorner:SetTexCoord(0/512, 133/512, 269/512, 401/512)
I found the coords to be (0/512, 133/512, 282/512, 401/512) based on pixels but they seem to use a bit of extra white space at the top so I just kept tweaking the third argument (which is the top) until I arrived at a good fit.

Note that I left all arguments in the form pixelPos/dimensionSize to make it easier to understand (I hope).
  Reply With Quote
03-28-20, 06:29 PM   #8
LudiusMaximus
A Chromatic Dragonspawn
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 176
Originally Posted by Vrul View Post
I found the coords to be (0/512, 133/512, 282/512, 401/512) based on pixels
Thanks for your reply! So it is a lot of tweaking after all, unless you find the Atlas name or the TexCoords anywhere. I learned a lot today! Thanks again! :-D
__________________
~ Be the change you want to see in the world... of warcraft interface! ~
  Reply With Quote
03-28-20, 07:42 PM   #9
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,214
Maybe something like Discord Art (or probably KgPanels) where you can create a texture with the artwork and click some buttons and/or enter coords so you don't have to do continous /reload. Possibly quicker for getting started at least.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
03-31-20, 03:51 AM   #10
LudiusMaximus
A Chromatic Dragonspawn
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 176
May I ask a related follow-up question?

I would like to place a button divider texture in my frame:

Code:
local myFrame = CreateFrame("Frame", "cosFix_SetFactorFrame", UIparent, "ButtonFrameTemplate")
myFrame:SetPoint("TOPLEFT")
ButtonFrameTemplate_HidePortrait(myFrame)
myFrame:SetFrameStrata("HIGH")
myFrame:SetWidth(430)
myFrame:SetHeight(220)

myFrame.exportButton = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
myFrame.exportButton:SetPoint("TOPRIGHT", -20, 0)
myFrame.exportButton:SetText("Export")
myFrame.exportButton:SetWidth(70)

myFrame.exportButton.btnDivLeft = f.NineSlice:CreateTexture("cosFix_btnDivLeft", "BORDER")
myFrame.exportButton.btnDivLeft:SetPoint("RIGHT", f.exportButton, "LEFT", -10, 0)
myFrame.exportButton.btnDivLeft:SetAtlas("UI-Frame-BtnDivLeft", true)
It should look like this:



But what I get is:



(The -10 offset is there on purpose for testing.)
But how can I get on top of the NineSlice border texture??
__________________
~ Be the change you want to see in the world... of warcraft interface! ~
  Reply With Quote
03-31-20, 06:59 AM   #11
Vrul
An Onyxian Warder
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 352
The region method SetDrawLayer is what you want to use.
  Reply With Quote
03-31-20, 07:27 AM   #12
LudiusMaximus
A Chromatic Dragonspawn
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 176
Originally Posted by Vrul View Post
The region method SetDrawLayer is what you want to use.
Hm thanks, but could you please be a little more specific?

Which is the LayeredRegion I should call SetDrawLayer() for?

The only texture I could think of was myFrame.NineSlice.TopRightCorner.

So I tried
Code:
myFrame.NineSlice.TopRightCorner:SetDrawLayer("BORDER")
but how do I continue from here?
__________________
~ Be the change you want to see in the world... of warcraft interface! ~
  Reply With Quote
03-31-20, 08:20 AM   #13
LudiusMaximus
A Chromatic Dragonspawn
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 176
Originally Posted by Vrul View Post
The region method SetDrawLayer is what you want to use.
Sorry, but I have absolutely no idea what I am supposed to do with SetDrawLayer!

All I could come up with was this work around.

Code:
local oldX, oldY = 12, 24
local shrinkFactor = 0.83
myFrame.exportButton.btnDivLeft = CreateFrame("Frame", nil, f.exportButton)
myFrame.exportButton.btnDivLeft:SetPoint("RIGHT", f.exportButton, "LEFT", 6, 0)
myFrame.exportButton.btnDivLeft:SetSize(oldX*shrinkFactor, oldY*shrinkFactor)
myFrame.exportButton.btnDivLeft:SetFrameStrata("DIALOG")
local texture = myFrame.exportButton.btnDivLeft:CreateTexture()
texture:SetAllPoints()
texture:SetAtlas("UI-Frame-BtnDivLeft")
But I would still be very interested in learning the mysteries of SetDrawLayer()...
__________________
~ Be the change you want to see in the world... of warcraft interface! ~

Last edited by LudiusMaximus : 03-31-20 at 08:23 AM.
  Reply With Quote
03-31-20, 07:44 AM   #14
LudiusMaximus
A Chromatic Dragonspawn
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 176
Actually, I am getting very indeterministic results...

As I am trying to find the right offset and size it is sometimes drawn on top and sometimes drawn below the NineSlice border...

Code:
myFrame.NineSlice.TopRightCorner:SetDrawLayer("BORDER")
myFrame.exportButton.btnDivLeft = myFrame.NineSlice:CreateTexture("cosFix_btnDivLeft", "BORDER")
myFrame.exportButton.btnDivLeft:SetPoint("RIGHT", myFrame.exportButton, "LEFT", 5, 0)
myFrame.exportButton.btnDivLeft:SetAtlas("UI-Frame-BtnDivLeft", true)
local oldX, oldY = myFrame.exportButton.btnDivLeft:GetSize()
local shrinkFactor = 0.854
myFrame.exportButton.btnDivLeft:SetSize(oldX*shrinkFactor, oldY*shrinkFactor)
__________________
~ Be the change you want to see in the world... of warcraft interface! ~
  Reply With Quote
03-31-20, 08:21 AM   #15
Vrul
An Onyxian Warder
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 352
Both regions are sharing a layer so you need to make sure the subLevel of your new texture is greater than the other:
Code:
local layer, subLevel = myFrame.NineSlice.TopRightCorner:GetDrawLayer()
myFrame.exportButton.btnDivLeft = myFrame.NineSlice:CreateTexture("cosFix_btnDivLeft")
myFrame.exportButton.btnDivLeft:SetDrawLayer(layer, subLevel + 1)
myFrame.exportButton.btnDivLeft:SetPoint("RIGHT", myFrame.exportButton, "LEFT", 5, 0)
myFrame.exportButton.btnDivLeft:SetAtlas("UI-Frame-BtnDivLeft", true)
local oldX, oldY = myFrame.exportButton.btnDivLeft:GetSize()
local shrinkFactor = 0.854
myFrame.exportButton.btnDivLeft:SetSize(oldX*shrinkFactor, oldY*shrinkFactor)
Edit: Or you could have used different layers:
Code:
myFrame.NineSlice.TopRightCorner:SetDrawLayer("BORDER")
myFrame.exportButton.btnDivLeft = myFrame.NineSlice:CreateTexture("cosFix_btnDivLeft", "OVERLAY")
myFrame.exportButton.btnDivLeft:SetPoint("RIGHT", myFrame.exportButton, "LEFT", 5, 0)
myFrame.exportButton.btnDivLeft:SetAtlas("UI-Frame-BtnDivLeft", true)
local oldX, oldY = myFrame.exportButton.btnDivLeft:GetSize()
local shrinkFactor = 0.854
myFrame.exportButton.btnDivLeft:SetSize(oldX*shrinkFactor, oldY*shrinkFactor)

Last edited by Vrul : 03-31-20 at 08:26 AM.
  Reply With Quote
03-31-20, 08:27 AM   #16
LudiusMaximus
A Chromatic Dragonspawn
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 176
Ahhhh! Thank you so much!

It turns out the layer of NineSlice.TopRightCorner is "OVERLAY", not "BORDER"!!
This is why I never had a chance!
__________________
~ Be the change you want to see in the world... of warcraft interface! ~
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Overlapping NineSlice textures with ButtonFrameTemplate

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