WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   "global EnableMouse is nil" (https://www.wowinterface.com/forums/showthread.php?t=38231)

Sythalin 01-07-11 04:58 PM

"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?

lilsparky 01-07-11 05:21 PM

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

Akkorian 01-07-11 05:26 PM

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


Sythalin 01-07-11 10:35 PM

Quote:

Originally Posted by Akkorian (Post 225978)
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.

Akkorian 01-07-11 11:17 PM

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. :confused:

Vrul 01-07-11 11:20 PM

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


Sythalin 01-08-11 02:05 PM

Quote:

Originally Posted by Akkorian (Post 226007)
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. :confused:

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


All times are GMT -6. The time now is 11:35 PM.

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