summaryrefslogtreecommitdiff
path: root/indra/llui/llfloaterreglistener.cpp
blob: 082d7c1573dcaf418087156611587928b7bcd7ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
 * @file   llfloaterreglistener.cpp
 * @author Nat Goodspeed
 * @date   2009-08-12
 * @brief  Implementation for llfloaterreglistener.
 * 
 * $LicenseInfo:firstyear=2009&license=viewergpl$
 * Copyright (c) 2009, Linden Research, Inc.
 * $/LicenseInfo$
 */

// Precompiled header
#include "linden_common.h"
// associated header
#include "llfloaterreglistener.h"
// STL headers
// std headers
// external library headers
// other Linden headers
#include "llfloaterreg.h"
#include "llfloater.h"
#include "llbutton.h"

LLFloaterRegListener::LLFloaterRegListener():
    LLEventAPI("LLFloaterReg",
               "LLFloaterReg listener to (e.g.) show/hide LLFloater instances")
{
    add("getBuildMap",
        "Return on [\"reply\"] data about all registered LLFloaterReg floater names",
        &LLFloaterRegListener::getBuildMap,
        LLSD().with("reply", LLSD()));
    LLSD requiredName;
    requiredName["name"] = LLSD();
    add("showInstance",
        "Ask to display the floater specified in [\"name\"]",
        &LLFloaterRegListener::showInstance,
        requiredName);
    add("hideInstance",
        "Ask to hide the floater specified in [\"name\"]",
        &LLFloaterRegListener::hideInstance,
        requiredName);
    add("toggleInstance",
        "Ask to toggle the state of the floater specified in [\"name\"]",
        &LLFloaterRegListener::toggleInstance,
        requiredName);
    LLSD requiredNameButton;
    requiredNameButton["name"] = LLSD();
    requiredNameButton["button"] = LLSD();
    add("clickButton",
        "Simulate clicking the named [\"button\"] in the visible floater named in [\"name\"]",
        &LLFloaterRegListener::clickButton,
        requiredNameButton);
}

void LLFloaterRegListener::getBuildMap(const LLSD& event) const
{
    // Honor the "reqid" convention by echoing event["reqid"] in our reply packet.
    LLReqID reqID(event);
    LLSD reply(reqID.makeResponse());
    // Build an LLSD map that mirrors sBuildMap. Since we have no good way to
    // represent a C++ callable in LLSD, the only part of BuildData we can
    // store is the filename. For each LLSD map entry, it would be more
    // extensible to store a nested LLSD map containing a single key "file" --
    // but we don't bother, simply storing the string filename instead.
    for (LLFloaterReg::build_map_t::const_iterator mi(LLFloaterReg::sBuildMap.begin()),
                                                   mend(LLFloaterReg::sBuildMap.end());
         mi != mend; ++mi)
    {
        reply[mi->first] = mi->second.mFile;
    }
    // Send the reply to the LLEventPump named in event["reply"].
    LLEventPumps::instance().obtain(event["reply"]).post(reply);
}

void LLFloaterRegListener::showInstance(const LLSD& event) const
{
    LLFloaterReg::showInstance(event["name"], event["key"], event["focus"]);
}

void LLFloaterRegListener::hideInstance(const LLSD& event) const
{
    LLFloaterReg::hideInstance(event["name"], event["key"]);
}

void LLFloaterRegListener::toggleInstance(const LLSD& event) const
{
    LLFloaterReg::toggleInstance(event["name"], event["key"]);
}

void LLFloaterRegListener::clickButton(const LLSD& event) const
{
    // If the caller requests a reply, build the reply.
    LLReqID reqID(event);
    LLSD reply(reqID.makeResponse());

    LLFloater* floater = LLFloaterReg::findInstance(event["name"], event["key"]);
    if (! LLFloater::isShown(floater))
    {
        reply["type"]  = "LLFloater";
        reply["name"]  = event["name"];
        reply["key"]   = event["key"];
        reply["error"] = floater? "!isShown()" : "NULL";
    }
    else
    {
        // Here 'floater' points to an LLFloater instance with the specified
        // name and key which isShown().
        LLButton* button = floater->findChild<LLButton>(event["button"]);
        if (! LLButton::isAvailable(button))
        {
            reply["type"]  = "LLButton";
            reply["name"]  = event["button"];
            reply["error"] = button? "!isAvailable()" : "NULL";
        }
        else
        {
            // Here 'button' points to an isAvailable() LLButton child of
            // 'floater' with the specified button name. Pretend to click it.
            button->onCommit();
            // Leave reply["error"] isUndefined(): no error, i.e. success.
        }
    }

    // Send a reply only if caller asked for a reply.
    LLSD replyPump(event["reply"]);
    if (replyPump.isString())       // isUndefined() if absent
    {
        LLEventPumps::instance().obtain(replyPump).post(reply);
    }
}