We have detected that cookies are not enabled on your browser. Please enable cookies to ensure the proper experience.
Results 1 to 7 of 7
  1. #1
    Join Date
    Jun 2009
    Location
    UK
    Posts
    1,461

    Lightbulb Function Sourcing

    Hi,

    I am wondering if anyone could help me quickly please with a small block I'm experiencing in coding.
    I want to have automatic tooltips appear when someone mouseovers particular controls, which are created on the fly.
    What I have done so far is create the following function:

    Code:
    function Turbine.UI.Control:SetToolTip (MESSAGE)
        if MESSAGE == nil then return end;
       -- Do something here
    end
    Which works as intended when setting the property in the code

    Code:
    SomeControl:SetToolTip("Test");
    When the plugin is executed, the function is called and does whatever is in the code, which is fine. However, to code the function effectively, I need to know which control the call came from. I am struggling to work out a way of doing this. From researching most people suggest debug.getinfo, but this seems to be disabled in lotro. Is there a way of doing something with the metatables maybe? I know I could easily attach a sender into the function parameters, but I would have thought there would be a more straightforward way of tracing where the call was made.

    Code:
    SomeControl:SetToolTip("Test", SomeControl)
    Seems a bit ridiculous to me. Plus I want this to be something I can use easily in future plugins, and set the same as a standard property.

    I don't know if I'm missing something painfully obvious, I have been staring at code all afternoon.

    Thanks
    [CENTER][SIZE=3][B]Galuhad | Narvelan[/B]
    Lore Breakers of Eldar[/SIZE]

    [URL="http://www.lotrointerface.com/list.php?skinnerid=3762"]Plugins[/URL] | [URL="https://www.lotro.com/forums/showthread.php?538975-Accounts-for-New-Players"]New Player Guide[/URL] | [URL="http://www.twitch.tv/galuhad"]Twitch[/URL]
    [/CENTER]

  2. #2
    Join Date
    Mar 2007
    Posts
    1,167
    If you define the function on an instance of a control as:
    Code:
    abc=Tubine.UI.Control()
    abc.SetToolTip=function(sender, msg)
       -- do something with msg here
    end
    
    def=Tubine.UI.Control()
    def.MouseClick=function(sender,args)
        abc.SetToolTip(sender,"some tooltip")
    end
    Then whenever "def" is clicked, it will send itself as the first parameter of the SetToolTip function. If the issue is using a class and knowing which instance of the class is clicked, then try:

    Code:
    MyControl=class(Turbine.UI.Control)
    
    MyControl.SetToolTip=function(sender,msg)
        -- sender will reference the control that fired the SetToolTip event
    end
    
    MyControl.MouseClick=function(sender,args)
        sender:SetToolTip("some tooltip") -- note, this control gets prepended as the sender parameter
    end
    this way when you click an instance of the MyControl, it will fire it's own SetToolTip event, passing itself as the sender. Yeah, using the mouseclick isn't really useful, it's just a quick example to demonstrate how to acquire a reference to an instance of a class and pass that as a parameter
    note that the functions are defined using the "." notation, not the ":" notation

    If you're trying to do something totally different and this didn't help, please let me know..
    Last edited by Garan; Dec 15 2013 at 03:26 PM.

  3. #3
    Join Date
    Jun 2009
    Location
    UK
    Posts
    1,461
    Thanks for the response Garan. I want to avoid having to do any additional code in the main script itself if possible. So when I call :SetToolTip() then that's it, whether the object is a control, textbox, label, image or whatever. All the mouse events, processing, display of the tooltip etc. will be handled by the ToolTip.lua file. So I can easily drop it into future plugins without any recoding. All I need is someway to get the sender from the :SetToolTip() function without having to really put it in, if an object is calling the function then surely there is someway of getting where the function was called from?
    [CENTER][SIZE=3][B]Galuhad | Narvelan[/B]
    Lore Breakers of Eldar[/SIZE]

    [URL="http://www.lotrointerface.com/list.php?skinnerid=3762"]Plugins[/URL] | [URL="https://www.lotro.com/forums/showthread.php?538975-Accounts-for-New-Players"]New Player Guide[/URL] | [URL="http://www.twitch.tv/galuhad"]Twitch[/URL]
    [/CENTER]

  4. #4
    Join Date
    Jun 2009
    Location
    UK
    Posts
    1,461
    Nevermind, I've got there

    phew.

    Thanks for the help Garan.

    edit:

    Now is there a way I can have two different functions used on mouse events? The tooltip code will obviously need mouse events, but I don't want it to conflict with any other mouse events coded elsewhere?
    Last edited by Galuhad; Dec 15 2013 at 06:09 PM.
    [CENTER][SIZE=3][B]Galuhad | Narvelan[/B]
    Lore Breakers of Eldar[/SIZE]

    [URL="http://www.lotrointerface.com/list.php?skinnerid=3762"]Plugins[/URL] | [URL="https://www.lotro.com/forums/showthread.php?538975-Accounts-for-New-Players"]New Player Guide[/URL] | [URL="http://www.twitch.tv/galuhad"]Twitch[/URL]
    [/CENTER]

  5. #5
    Join Date
    Mar 2007
    Posts
    1,167
    Quote Originally Posted by Galuhad View Post
    Now is there a way I can have two different functions used on mouse events? The tooltip code will obviously need mouse events, but I don't want it to conflict with any other mouse events coded elsewhere?
    Consider the code:
    Code:
    Card=class(Turbine.UI.Lotro.Window)
    function Card:Constructor()
        Turbine.UI.Lotro.Window.Constructor(self); -- this is where our class calls the base class constructor
        self:SetSize(200,200)
        self:SetText("Card")
    end
    function Card:MouseEnter(sender,args)
        -- do some stuff on mouse enter
        Turbine.Shell.WriteLine("Card Mouse Enter")
    end
    BigCard=class(Card)
    function BigCard:Constructor()
        Card.Constructor(self); -- this is where our class calls the base class constructor
        self:SetSize(300,300)
        self:SetText("Big Card")
        self:SetPosition(200,0)
    end
    function BigCard:MouseEnter(sender,args)
            -- call the base class MouseEnter
            Card:MouseEnter(sender,args)
            -- now do some other stuff
            Turbine.Shell.WriteLine("Big Card Mouse Enter")
        end
    end
    
    abc=Card()
    abc:SetVisible(true)
    def=BigCard()
    def:SetVisible(true)
    This creates two classes, Card and BigCard which both implement the MouseEnter event handler but BigCard is derived from Card and when it overrides the Card:MouseEnter handler, it explicitly calls the Card:MouseEnter handler to preserve that functionality.

    Another, more Lua style approach is to assign a table to MouseEnter by changing Big Card:
    Code:
    Card=class(Turbine.UI.Lotro.Window)
    function Card:Constructor()
        Turbine.UI.Lotro.Window.Constructor(self); -- this is where our class calls the base class constructor
        self:SetSize(200,200)
        self:SetText("Card")
    end
    function Card:MouseEnter(sender,args)
        -- do some stuff on mouse enter
        Turbine.Shell.WriteLine("Card Mouse Enter")
    end
    BigCard=class(Card)
    function BigCard:Constructor()
        Card.Constructor(self); -- this is where our class calls the base class constructor
        self:SetSize(300,300)
        self:SetText("Big Card")
        self:SetPosition(200,0)
        self.MouseEnter={self.MouseEnter,function(sender,args)
            -- now do some other stuff
            Turbine.Shell.WriteLine("Big Card Mouse Enter sender:"..tostring(sender))
        end}
    end
    
    abc=Card()
    abc:SetVisible(true)
    def=BigCard()
    def:SetVisible(true)
    Of course, both methods require that you preserve the class implementation of MouseEnter if you override it in the instance, for instance in the second case, if you define def.MouseEnter you would have to add the new functionality to the table. That leads to the third approach which is just an extension of how we implement event handlers for instances of Turbine shared objects. If you define and use the AddCallback functionality in your plugins, you can use the AddCallback mechanism to add handlers:

    AddCallback(def,"MouseEnter",f unction(sender,args) -- do some more stuff here end)

    Code:
    function AddCallback(object, event, callback)
        if (object[event] == nil) then
            object[event] = callback;
        else
            if (type(object[event]) == "table") then
                local exists=false;
                local k,v;
                for k,v in ipairs(object[event]) do
                    if v==callback then
                        exists=true;
                        break;
                    end
                end
                if not exists then
                    table.insert(object[event], callback);
                end
            else
                if object[event]~=callback then
                    object[event] = {object[event], callback};
                end
            end
        end
        return callback;
    end
    
    Card=class(Turbine.UI.Lotro.Window)
    function Card:Constructor()
        Turbine.UI.Lotro.Window.Constructor(self); -- this is where our class calls the base class constructor
        self:SetSize(200,200)
        self:SetText("Card")
        local tmpFunction=function (sender,args)
            -- do some stuff on mouse enter
            Turbine.Shell.WriteLine("Card Mouse Enter sender:"..tostring(sender))
        end
        AddCallback(self,"MouseEnter",tmpFunction)
    end
    BigCard=class(Card)
    function BigCard:Constructor()
        Card.Constructor(self); -- this is where our class calls the base class constructor
        self:SetSize(300,300)
        self:SetText("Big Card")
        self:SetPosition(200,0)
    
        AddCallback(self,"MouseEnter",function(sender,args)
        -- now do some other stuff
        Turbine.Shell.WriteLine("Big Card Mouse Enter sender:"..tostring(sender))
        end)
    end
    
    abc=Card()
    abc:SetVisible(true)
    def=BigCard()
    def:SetVisible(true)
    Note that I declared the function as a local, tmpFunction, in Card which makes it a little easier to use indentation but in BigCard I defined the function right in the call to AddCallback. Either method is acceptable. I just happen to like the indentation of the first method a little better personally.
    Last edited by Garan; Dec 16 2013 at 08:52 AM.

  6. #6
    Join Date
    Jun 2009
    Location
    UK
    Posts
    1,461
    I ended up doing basically the same thing. I created a new property for the control to attach the custom MouseEnter event function, which is then called during the standard MouseEnter event used by the ToolTip script. Probably the best way of getting around it. Thanks again for the help.
    [CENTER][SIZE=3][B]Galuhad | Narvelan[/B]
    Lore Breakers of Eldar[/SIZE]

    [URL="http://www.lotrointerface.com/list.php?skinnerid=3762"]Plugins[/URL] | [URL="https://www.lotro.com/forums/showthread.php?538975-Accounts-for-New-Players"]New Player Guide[/URL] | [URL="http://www.twitch.tv/galuhad"]Twitch[/URL]
    [/CENTER]

  7. #7
    Hi Galuhad,

    Its worth taking a look at the AddCallback function Garan showed you. When events fire, if you have a single function mapped to the callback it will fire. If you have a table of functions, then they will all fire in sequence. That's what the AddCallback function does for you.

    I'd use Garan's code as its tested, and handles scenarios when there are no existing callbacks, a single callback or already a table when you add a new one. This essentially plays nice with the event functionality.


    Kamindra
    [charsig=http://lotrosigs.level3.turbine.com/0420800000006abda/01006/signature.png]Kamindra[/charsig]

 

 

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

This form's session has expired. You need to reload the page.

Reload