Thread Tools Display Modes
01-07-11, 04:58 PM   #1
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
"global EnableMouse is nil"

lua Code:
  1. -- disable mouse stuffs
  2.     cb = CreateFrame("CHECKBUTTON", "CFM_ClickButton", CFM_Panel1, "OptionsCheckButtonTemplate")
  3.         cb:SetPoint("LEFT", CFM_ClickText, "RIGHT", 0, 0)
  4.         cb:SetScale(.75)
  5.         cb:SetScript("OnClick", function(self)
  6.             if selName == nil or selName == "" then
  7.                 print("Please select a frame first.")
  8.                 return
  9.             else
  10.                 CFM_ToggleSetting(self, "disableMouse")
  11.             end
  12.             end)
  13.  
  14.  
  15. -- code stuffs
  16. function CFM_ToggleSetting(self, prop)
  17.     local frame = _G[activeProfile[selName].frame]
  18.     local func
  19.     -- determine what function will be needed based on passed property
  20.     if prop == "disableMouse" then func = EnableMouse() end
  21.     if prop == "clamp" then func = SetClampedToScreen() end
  22.     if self:GetChecked() == 1 then
  23.         activeProfile[selName][prop] = true
  24.         frame:func(true)
  25.     else
  26.         activeProfile[selName][prop] = false
  27.         frame:func(false)
  28.     end
  29. end

Code:
Message: Interface\AddOns\CFM\CFM_GUI.lua:1285: attempt to call global 'EnableMouse' (a nil value)
Time: 01/07/11 16:54:17
Count: 1
Stack: Interface\AddOns\CFM\CFM_GUI.lua:1285: in function `CFM_ToggleSetting'
Interface\AddOns\CFM\CFM_GUI.lua:835: in function <Interface\AddOns\CFM\CFM_GUI.lua:830>

Locals: self = CFM_ClickButton {
 0 = <userdata>
}
prop = "disableMouse"
frame = PlayerFrame
As usually, I have an idea of what I'm doing wrong (the proper way to assign the desired function) but have no idea of how to do it. Ideas?
  Reply With Quote
01-07-11, 05:21 PM   #2
lilsparky
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Oct 2007
Posts: 117
those are not functions, they're methods. i would expect, tho i'm not sure, that this would work:

func = "EnableMouse"

...

fame[func](frame, true/false)


assuming that bliz widget methods act like normal methods...


also, if you set X = func() then you're executing the function func and assigning x to the result as opposed to X = func which would assign X to be a "pointer" to the function itself (so X() would be the same as func()). not that this would work in this case...
  Reply With Quote
01-07-11, 05:26 PM   #3
Akkorian
A Flamescale Wyrmkin
 
Akkorian's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2010
Posts: 111
Hi ChaosInc,

Putting parentheses after the function name makes Lua call the function. If you want to assign the function itself to a variable, rather than its return values, you just write the function name. If it’s a method name, rather than a standalone function, then you usually have to write it as a string, in quotes, so you can look it up in the object table later.

This would work:
Code:
-- disable mouse stuffs
cb = CreateFrame( "CHECKBUTTON", "CFM_ClickButton", CFM_Panel1, "OptionsCheckButtonTemplate" )
cb:SetPoint( "LEFT", CFM_ClickText, "RIGHT", 0, 0)
cb:SetScale( 0.75 )
cb:SetScript( "OnClick", function( self )
	if selName == nil or selName == "" then
		return print( "Please select a frame first." )
	else
		CFM_ToggleSetting( self, "disableMouse" )
	end
end )

-- code stuffs
function CFM_ToggleSetting( self, prop )
	local frame = _G[ activeProfile[ selName ].frame ]
	local func
	-- determine what function will be needed based on passed property
	if prop == "disableMouse" then
		func = "EnableMouse"
	end
	if prop == "clamp" then
		func = "SetClampedToScreen"
	end
	if self:GetChecked() == 1 then
		activeProfile[ selName ][ prop ] = true
		frame[ func ]( frame, true )
	else
		activeProfile[ selName ][ prop ] = false
		frame[ func ]( frame, false )
	end
end
But, it might be easier to just use the function name instead of some other string, like this:

Code:
CFM_ToggleSetting( self, "EnableMouse" )

function CFM_ToggleSetting( self, func )
	local frame = _G[ activeProfile ][ selName ].frame
	-- determine what function will be needed based on passed property
	if self:GetChecked() == 1 then
		activeProfile[ selName ][ func ] = true
		frame[ func ]( frame, true )
	else
		activeProfile[ selName ][ func ] = false
		frame[ func ]( frame, false )
	end
end
__________________
“Be humble, for you are made of earth. Be noble, for you are made of stars.”
  Reply With Quote
01-07-11, 10:35 PM   #4
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Originally Posted by Akkorian View Post
Hi ChaosInc,

Putting parentheses after the function name makes Lua call the function. If you want to assign the function itself to a variable, rather than its return values, you just write the function name. If it’s a method name, rather than a standalone function, then you usually have to write it as a string, in quotes, so you can look it up in the object table later.

This would work:
Code:
-- disable mouse stuffs
cb = CreateFrame( "CHECKBUTTON", "CFM_ClickButton", CFM_Panel1, "OptionsCheckButtonTemplate" )
cb:SetPoint( "LEFT", CFM_ClickText, "RIGHT", 0, 0)
cb:SetScale( 0.75 )
cb:SetScript( "OnClick", function( self )
	if selName == nil or selName == "" then
		return print( "Please select a frame first." )
	else
		CFM_ToggleSetting( self, "disableMouse" )
	end
end )

-- code stuffs
function CFM_ToggleSetting( self, prop )
	local frame = _G[ activeProfile[ selName ].frame ]
	local func
	-- determine what function will be needed based on passed property
	if prop == "disableMouse" then
		func = "EnableMouse"
	end
	if prop == "clamp" then
		func = "SetClampedToScreen"
	end
	if self:GetChecked() == 1 then
		activeProfile[ selName ][ prop ] = true
		frame[ func ]( frame, true )
	else
		activeProfile[ selName ][ prop ] = false
		frame[ func ]( frame, false )
	end
end
But, it might be easier to just use the function name instead of some other string, like this:

Code:
CFM_ToggleSetting( self, "EnableMouse" )

function CFM_ToggleSetting( self, func )
	local frame = _G[ activeProfile ][ selName ].frame
	-- determine what function will be needed based on passed property
	if self:GetChecked() == 1 then
		activeProfile[ selName ][ func ] = true
		frame[ func ]( frame, true )
	else
		activeProfile[ selName ][ func ] = false
		frame[ func ]( frame, false )
	end
end
The latter wouldn't work since I intend mutliple buttons to use this function. Otherwise I'd just put it all into the click script like it currently is. I'm trying to reduce the amount of redundant coding that currently exists. I tried to use simply func = EnableMouse and such, but didn't work. I give your example a run and see how it works.
  Reply With Quote
01-07-11, 11:17 PM   #5
Akkorian
A Flamescale Wyrmkin
 
Akkorian's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2010
Posts: 111
You can’t do func = EnableMouse because there isn’t any function named EnableMouse. Frame-type objects do have an EnableMouse method, but it’s only accessible through the object, not as a global function. You have to store it as a string, and do a table lookup to get the method.

I’m also not sure what you meant by not being able to use the second example with multiple buttons. The only difference between it and the first example is that instead of passing along “clamp” and then having extra code to turn “clamp” into “SetClampedToScreen”, you just pass along “SetClampedToScreen” directly. There’s nothing in there that ties it to a specific button or frame.
__________________
“Be humble, for you are made of earth. Be noble, for you are made of stars.”
  Reply With Quote
01-07-11, 11:20 PM   #6
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Using functions:
Code:
function CFM_ToggleSetting(self, prop)
	local setting = activeProfile[selName]
	local frame = _G[setting.frame]
	local value = self:GetChecked() == 1
	local func
	if prop == "disableMouse" then
		func = frame.EnableMouse
	elseif prop == "clamp" then
		func = frame.SetClampedToScreen
	end
	setting[prop] = value
	func(frame, value)
end

Using methods:
Code:
function CFM_ToggleSetting(self, prop)
	local setting = activeProfile[selName]
	local frame = _G[setting.frame]
	local value = self:GetChecked() == 1
	local method
	if prop == "disableMouse" then
		method = "EnableMouse"
	elseif prop == "clamp" then
		method = "SetClampedToScreen"
	end
	setting[prop] = value
	frame[method](frame, value)
end
  Reply With Quote
01-08-11, 02:05 PM   #7
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Originally Posted by Akkorian View Post
I’m also not sure what you meant by not being able to use the second example with multiple buttons. The only difference between it and the first example is that instead of passing along “clamp” and then having extra code to turn “clamp” into “SetClampedToScreen”, you just pass along “SetClampedToScreen” directly. There’s nothing in there that ties it to a specific button or frame.
I misread what you posted. Admittedly, I read it while in a hurry. I see where I was misunderstanding from the numerous examples you guys posted. I'll fix her up tonight when I get home. Thanks.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » "global EnableMouse is nil"

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