Thread Tools Display Modes
06-05-09, 09:50 PM   #1
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Dropdown issues

I've been trying to figure out why this is happening for the past week and haven't come up with anything.


The dropdown options appear to be residual data from a dropdown in Loot Filter. However, this isn't loot filter specific as it'll fill in any data from dropdowns accessed prior to selecting a frame. I'm quite puzzled.

Code:
http://pastey.net/115482
  Reply With Quote
06-06-09, 06:02 AM   #2
xConStruct
A Chromatic Dragonspawn
 
xConStruct's Avatar
AddOn Author - Click to view addons
Join Date: May 2008
Posts: 199
You're calling UIDropDownMenu_Initialize(dm, CFM_StrataDropInit) before CFM_StrataDropInit is defined as a function - so in that moment where _Initialize is executed, CFM_StrataDropInit is nil.

Just define CFM_StrataDropInit (and the others ) before you call the Initialize.
__________________
« Website | GitHub »

Oh hai!
  Reply With Quote
06-06-09, 07:19 AM   #3
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Originally Posted by Cargor View Post
You're calling UIDropDownMenu_Initialize(dm, CFM_StrataDropInit) before CFM_StrataDropInit is defined as a function - so in that moment where _Initialize is executed, CFM_StrataDropInit is nil.

Just define CFM_StrataDropInit (and the others ) before you call the Initialize.
Ok, maybe it's just because I just woke up, so I may be misunderstanding. Moved the CFM_XDropInit functions before the button create function and still have the same issue.

EDIT: I should've mentioned that the dropframes themselves work just fine. The issue shown is when a user clicks on a frame in the left list and it's not selecting the values to set the dropdowns to. (CFM_SelectFrame())

Last edited by Sythalin : 06-06-09 at 07:25 AM.
  Reply With Quote
06-06-09, 07:33 AM   #4
Samsan
An Aku'mai Servant
 
Samsan's Avatar
Join Date: May 2009
Posts: 33
Curious

Would it be possible to clear data on show so that the dropdowns only show selected frame data onclick?

Just a thought...
__________________
To give is to receive so the more that you give the more that you receive.
  Reply With Quote
06-06-09, 08:16 AM   #5
xConStruct
A Chromatic Dragonspawn
 
xConStruct's Avatar
AddOn Author - Click to view addons
Join Date: May 2008
Posts: 199
Yeah, just looked at your complete code of the addon and noticed that your dropdown-creation was done in a function, so it doesn't matter where the other functions are defined. From the pastey it looked like it's directly executed on load

Is the data of activeProfile[frame].point every time available and not nil? Maybe this is a stupid question, but you don't have any default "SelectedValue" to which the if-block can fall back if none of the options ("CENTER" / "BOTTOMLEFT", ...) is set. And maybe this causes the frame to fall back to some completely different text.

By the way, as far as I know you can set the dropdown-entry-values directly to "BOTTOMLEFT" (and so on) instead of just numbers. This should simplify your code a lot.
__________________
« Website | GitHub »

Oh hai!
  Reply With Quote
06-06-09, 07:29 PM   #6
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Originally Posted by Cargor View Post
Yeah, just looked at your complete code of the addon and noticed that your dropdown-creation was done in a function, so it doesn't matter where the other functions are defined. From the pastey it looked like it's directly executed on load
Yeah, sorry. Should've clarified that.

Is the data of activeProfile[frame].point every time available and not nil?
Yes, activeProfile data is always readily available for a frame.

By the way, as far as I know you can set the dropdown-entry-values directly to "BOTTOMLEFT" (and so on) instead of just numbers. This should simplify your code a lot.
To make sure I understand, I could simply replace
Code:
local point = activeProfile[frame].point
	if  point == "CENTER" then
		UIDropDownMenu_SetSelectedValue(CFM_ToBox, 0)
	elseif point == "TOP" then
		UIDropDownMenu_SetSelectedValue(CFM_ToBox, 1)
	elseif point == "TOPRIGHT" then
		UIDropDownMenu_SetSelectedValue(CFM_ToBox, 2)
	elseif point == "RIGHT" then
		UIDropDownMenu_SetSelectedValue(CFM_ToBox, 3)
	elseif point == "BOTTOMRIGHT" then
		UIDropDownMenu_SetSelectedValue(CFM_ToBox, 4)
	elseif point == "BOTTOM" then
		UIDropDownMenu_SetSelectedValue(CFM_ToBox, 5)
	elseif point == "BOTTOMLEFT" then
		UIDropDownMenu_SetSelectedValue(CFM_ToBox, 6)
	elseif point == "LEFT" then
		UIDropDownMenu_SetSelectedValue(CFM_ToBox, 7)
	elseif point == "TOPLEFT" then
		UIDropDownMenu_SetSelectedValue(CFM_ToBox, 8)
	end
with
Code:
local point = activeProfile[frame].point
	UIDropDownMenu_SetSelectedValue(CFM_ToBox, point)
?

Would it be possible to clear data on show so that the dropdowns only show selected frame data onclick?
I shouldn't have to clear any data as the function is directly referencing my dropdowns and it's data only. At least, that's the way I understand it....

Gonna stick some debug print()'s in there and track the data assignments. Post back with results.
  Reply With Quote
06-06-09, 07:41 PM   #7
Foxlit
A Warpwood Thunder Caller
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 91
The actual cause: UIDropDownMenu_SetSelectedValue has preconditions that you're not meeting -- namely, it may only be called to set the value of the last dropdown interacted with by the user.

UIDropDownMenu doesn't store information about what your dropdown contains except as part of the visible list frames that appear when you interact with the dropdown. Those list frames are reused for every dropdown in the game: so the moment someone opens another dropdown, information about your dropdown vanishes from those frames. When you call _SetSelectedValue, it iterates over the information stored in those frames to attempt to determine what it should actually display. In some cases, it finds matching values from someone else's dropdown, and you get their text instead.

Solution: use UIDropDownMenu_SetText(dropdown, "text") -- you can either call it after your _SetSelectedValue (thus masking the incorrect value problem), or use it in conjunction with passing info.checked to _AddButton (thus removing the need to call _SetSelectedValue, ever).
__________________
... and you do get used to it, after a while.
  Reply With Quote
06-06-09, 07:47 PM   #8
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Ok, stuck a print() after calling the local vars and they call them correctly. It's just not assigning them. Odd thing while testing:

Test 1
1) open CFM
2) click a frame

print() outputs: all correct
dropdown point: correct
dropdown rpoint: correct
dropdown strata: incorrect

Test 2
1) open Loot Filter
2) click "Type"
3) click to show and hide the dropdown menu
4) click "Close"
5) open CFM
6) click frame

print() outputs: all correct
dropdown point: incorrect
dropdown rpoint: incorrect
dropdown strata: incorrect

7) click other frames

print() outputs: still correct
all dropdowns: change incorrectly to LF values
  Reply With Quote
06-06-09, 07:54 PM   #9
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Originally Posted by Foxlit View Post
Solution: use UIDropDownMenu_SetText(dropdown, "text") -- you can either call it after your _SetSelectedValue (thus masking the incorrect value problem)
Nice, this works.

BUT...

or use it in conjunction with passing info.checked to _AddButton (thus removing the need to call _SetSelectedValue, ever).
As I'm using all this to learn, I'm curious on how to do this. First time I'm working with drop frames so I'd love to see how this works.

Last edited by Sythalin : 06-06-09 at 07:55 PM. Reason: GRAMMER FAIL
  Reply With Quote
08-18-09, 11:48 AM   #10
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Code:
-- Dropdown Art Chooser
	dm = CreateFrame("FRAME", "CART_ArtDrop", parent, "UIDropDownMenuTemplate")
		dm:SetPoint("TOP")
		dm:SetScale(.75)
		UIDropDownMenu_SetWidth(dm,200)
		UIDropDownMenu_Initialize(dm, CART_ArtDropInit)

-- Art Dropdown Initialize
function CART_ArtDropInit()
	level = level or 0
	local val = 0
	local info = UIDropDownMenu_CreateInfo()
	for k,_ in pairs(CART_ActiveProfile) do
		info.text = k
		info.value = val
		info.func = function() CART_ArtDropClick() end
		info.owner = this:GetParent()
		info.checked = nil
		info.icon = nil
		UIDropDownMenu_AddButton(info, level)
		val = val +1
	end
end

-- Art Dropdown Click
function CART_ArtDropClick()
	UIDropDownMenu_SetSelectedValue(this.owner, this.value)
	CART_ArtInfo(this.text)	
end
Ends with error when it's show:
Code:
Error occured in: Global
Count: 1
Message: ..\FrameXML\UIDropDownMenu.lua line 224:
   attempt to index local 'listFrame' (a nil value)
Debug:
   [C]: ?
   ..\FrameXML\UIDropDownMenu.lua:224: UIDropDownMenu_AddButton()
   CART\CART.lua:205: initFunction()
   ..\FrameXML\UIDropDownMenu.lua:69: UIDropDownMenu_Initialize()
   CART\CART.lua:190: CART_CreateConfig()
   [string "CART_CreateConfig()"]:1: in main chunk
   [C]: RunScript()
   ..\FrameXML\ChatFrame.lua:1879: value()
   ..\FrameXML\ChatFrame.lua:3526: ChatEdit_ParseText()
   ..\FrameXML\ChatFrame.lua:3176: ChatEdit_SendText()
   ..\FrameXML\ChatFrame.lua:3200: ChatEdit_OnEnterPressed()
   [string "*:OnEnterPressed"]:1:
      [string "*:OnEnterPressed"]:1
I've followed the path and can't find a problem.
  Reply With Quote
08-18-09, 01:12 PM   #11
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Its kind of hard to help when you are referencing variables that aren't shown where they are set (i.e. level = level or 0). Also, defaulting level to 0 is bad since Blizzard's own code defaults it to 1 and any value less than 1 will not be created (see UIDropDownMenu_CreateFrames).

You also are doing some very bad coding habits such as excessive use of global variables, using the global "this" instead of using the passed "self", and creating multiple functions when you don't need to. You could clean up the code provided just by rearranging it's order:

Code:
-- Art Dropdown Click
local function CART_ArtDropClick(self)
	UIDropDownMenu_SetSelectedValue(self.owner, self.value)
	CART_ArtInfo(self.text)	
end

-- Art Dropdown Initialize
local function CART_ArtDropInit(self)
	level = level or 1
	local val = 0
	local info = UIDropDownMenu_CreateInfo()
	info.func = CART_ArtDropClick
	info.owner = self:GetParent()
	for k in pairs(CART_ActiveProfile) do
		info.text = k
		info.value = val
		UIDropDownMenu_AddButton(info, level)
		val = val + 1
	end
end

-- Dropdown Art Chooser (assuming this a subset of a function code block based on indentation)
	dm = CreateFrame('FRAME', "CART_ArtDrop", parent, 'UIDropDownMenuTemplate')
	dm:SetPoint('TOP')
	dm:SetScale(0.75)
	UIDropDownMenu_SetWidth(dm, 200)
	UIDropDownMenu_Initialize(dm, CART_ArtDropInit)
  Reply With Quote
08-18-09, 01:17 PM   #12
Tristanian
Andúril
Premium Member
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 279
The offending line in the Blizzard code :

local listFrameName = listFrame:GetName();

where listFrame = _G["DropDownList"..level];

You are passing a level of 0. There is no DropDownList0 frame, they start from 1 and onwards.

Edit : And generally agreed with Vrul. If you are only using a single level menu, there is no compelling reason to not just pass a straightforward 1, rather than define a global (unless you localize it elsewhere, which again isn't really needed unless you are doing something more complicated). While 'this' still works, it's a horrible way to propagate it, on every occasion, when you can simply pass the actual frame.
__________________

Last edited by Tristanian : 08-18-09 at 01:22 PM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Dropdown issues


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