Thread Tools Display Modes
02-10-14, 06:24 PM   #1
Haleth
This Space For Rent
 
Haleth's Avatar
Featured
Join Date: Sep 2008
Posts: 1,173
SetScrollChild help

Hi!

I'm trying to figure out a bug where frame parent/child ordering doesn't work properly on scroll frames. I've determined that either I'm missing something, or the SetScrollChild() function is bugged.

Take the following sample code:

Code:
local scrollFrame = CreateFrame("ScrollFrame", "TestScrollFrame", UIParent)
scrollFrame:SetSize(100, 100)
scrollFrame:SetPoint("CENTER")
scrollFrame:SetBackdrop({
	bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
})
scrollFrame:SetBackdropColor(0, 0, 0, .5)

local scrollChild = CreateFrame("Frame", "TestScrollFrameContents", scrollFrame)
scrollChild:SetSize(100, 100)
scrollChild:SetPoint("TOP", scrollFrame, "TOP")

scrollFrame:SetScrollChild(scrollChild)

local check = CreateFrame("CheckButton", "TestCheckButton", scrollChild, "InterfaceOptionsCheckButtonTemplate")
check:SetPoint("CENTER")
check:SetNormalTexture("")

local bd = CreateFrame("Frame", nil, check)
bd:SetPoint("TOPLEFT", 4, -4)
bd:SetPoint("BOTTOMRIGHT", -4, 4)
bd:SetFrameLevel(check:GetFrameLevel()-1)
bd:SetBackdrop({
	bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
})
bd:SetBackdropColor(0, 0, 0)
This creates a semi-transparent ScrollFrame with an equally sized frame as its child. In the centre of the child is a check button with a solid black background. I know I could just use SetBackdrop on the check button, but I need to use frames as a backdrop for a specific reason in my addon.

The problem here is that for some reason, the check button's background frame appears on top of the check button, despite the fact that its frame level is lower. So, the checked texture will appear behind the black background.

However, if I comment out this line:

Code:
scrollFrame:SetScrollChild(scrollChild)
The background will appear behind the check button, even though scrollChild already had scrollFrame as its parent during creation.

What is the problem here?

The only other thing I've managed to find on this problem is this: http://blue.cardplace.com/newcache/f...4311215435.htm and the issue is unresolved there too.

Last edited by Haleth : 02-10-14 at 06:28 PM.
  Reply With Quote
02-10-14, 06:51 PM   #2
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Make the checkbutton a child of "bd" and forget about frame levels.

Right now you're creating a backdrop on top of the frame you want it to be behind.
  Reply With Quote
02-10-14, 07:36 PM   #3
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
I can remember that I had the same problem 2 years ago with http://www.wowinterface.com/download...doManager.html

My intention with the scrollframe was to clip all game elements if they leave the map. I've tried everything with framelevel and framestrata, but the scollframe ignores them all.
The childs have a frame level and it's even set with SetFrameLevel and you could get it with GetFrameLevel... but the frames in the scrollframe are simply not re-arranged. Never.

I ended up with pre building all needed elements in the order the should be stacked up (in your case backdrop frame first then checkbutton frame).

btw: without
Lua Code:
  1. scrollFrame:SetScrollChild(scrollChild)
the child frames are not clipped (try set the anchor 'outside' the scrollframes borders) which makes the scrollframe somewhat useless. -.-

Last edited by Duugu : 02-10-14 at 07:56 PM.
  Reply With Quote
02-11-14, 05:28 AM   #4
Haleth
This Space For Rent
 
Haleth's Avatar
Featured
Join Date: Sep 2008
Posts: 1,173
semlar: I could use that workaround, but the problem is I'm often working with the default Blizzard frames and reparenting checkboxes often have all kinds of consequences. It's something I'd rather avoid.

The thing is, this is supposed to work, but for some reason SetScrollChild seems to mess with frame order, like Duugu said.
  Reply With Quote
02-11-14, 05:47 AM   #5
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
Frame stacking can be a huge pain in the but.

I have not worked with frame stacking inside of a scrollchild yet. Textures have a drawlayer making stacking pretty easy.

If you need frame stacking try to parent your new layer to the layer below. That works for most of the parts.

If that is not an option try to get the framelevel of your current frames and when creating a new frame set it to a higher framelevel.
Lua Code:
  1. local parent = CreateFrame("Frame", nil, UIParent)
  2. local child = CreateFrame("Frame", nil, parent)
  3.  
  4. local child2 = CreateFrame("Frame", nil, parent)
  5. child2:SetFrameLevel(math.max(child:GetFrameLevel())+1)

But if what Duugu wrote is still in place you are screwed.

Btw...not sure why you are not doing what semlar wrote. There is no reparenting. Upon button init you set the parent to the bg.
Lua Code:
  1. local bd = CreateFrame("Frame", nil, scrollChild)
  2. local check = CreateFrame("CheckButton", "TestCheckButton", bd, "InterfaceOptionsCheckButtonTemplate")

Whenever I had stacking issues the parenting technique worked perfectly for me.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)

Last edited by zork : 02-11-14 at 05:53 AM.
  Reply With Quote
02-11-14, 07:04 AM   #6
Choonstertwo
A Chromatic Dragonspawn
 
Choonstertwo's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 194
Originally Posted by zork View Post
Lua Code:
  1. local parent = CreateFrame("Frame", nil, UIParent)
  2. local child = CreateFrame("Frame", nil, parent)
  3.  
  4. local child2 = CreateFrame("Frame", nil, parent)
  5. child2:SetFrameLevel(math.max(child:GetFrameLevel())+1)
I'm just curious, what's the purpose of math.max here? Won't :GetFrameLevel() always return a single number?
  Reply With Quote
02-11-14, 10:15 AM   #7
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Originally Posted by Haleth View Post
I'm often working with the default Blizzard frames and reparenting checkboxes often have all kinds of consequences.
In that case, for each layer you want inside your scrollframe create a frame (eg. one for background, artwork and overlay) and parent your other frames to the level you want them to appear.

If you can't do that, creating the backdrop frame and parenting it to the scrollchild before putting the checkbox in there should make it appear underneath.
  Reply With Quote
02-11-14, 10:21 AM   #8
Haleth
This Space For Rent
 
Haleth's Avatar
Featured
Join Date: Sep 2008
Posts: 1,173
Originally Posted by zork View Post
Btw...not sure why you are not doing what semlar wrote. There is no reparenting. Upon button init you set the parent to the bg.
That would work in the example, but not when I'm modifying the Blizzard UI (which is what I'm doing most of the time - the example was just to narrow down the issue).

Originally Posted by semlar View Post
In that case, for each layer you want inside your scrollframe create a frame (eg. one for background, artwork and overlay) and parent your other frames to the level you want them to appear.

If you can't do that, creating the backdrop frame and parenting it to the scrollchild before putting the checkbox in there should make it appear underneath.
Parenting it to the scrollChild is a trick that works, yep
  Reply With Quote
02-12-14, 07:30 AM   #9
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
Originally Posted by Choonstertwo View Post
I'm just curious, what's the purpose of math.max here? Won't :GetFrameLevel() always return a single number?
That is if you want to overlay more that one frame. In this case it is only one.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
  Reply With Quote
02-12-14, 09:12 AM   #10
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
Originally Posted by zork View Post
That is if you want to overlay more that one frame. In this case it is only one.
Hm.

math.max()
Returns the maximum value among its arguments.


GetFrameLevel returns a single number. That seems to be useless.
  Reply With Quote
02-12-14, 10:11 AM   #11
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
Lua Code:
  1. child:SetFrameLevel(math.max(child1:GetFrameLevel(),child2:GetFrameLevel(),childN:GetFrameLevel())+1)
Only needed when comparing against a set of frames.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » SetScrollChild help


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