Files
SingularityViewer/indra/newview/lldroptarget.cpp

267 lines
7.3 KiB
C++

/**
* @file lldroptarget.cpp
* @Class LLDropTarget
*
* This handy class is a simple way to drop something on another
* view. It handles drop events, always setting itself to the size of
* its parent.
*
* Altered to support a callback so it can return the item
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Pulled into its own file for more widespread use
* Rewritten by Liru Færs to act as its own ui element and use a control
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (c) 2004-2009, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "lldroptarget.h"
#include <boost/signals2/shared_connection_block.hpp>
#include "llbutton.h"
#include "llinventorymodel.h"
#include "llstartup.h"
#include "lltextbox.h"
#include "lltooldraganddrop.h"
#include "lltrans.h"
#include "llviewborder.h"
static LLRegisterWidget<LLDropTarget> r("drop_target");
std::string currently_set_to(const LLInventoryItem* item)
{
if (!item) return LLTrans::getString("CurrentlyNotSet");
LLStringUtil::format_map_t args;
args["[ITEM]"] = item->getName();
return LLTrans::getString("CurrentlySetTo", args);
}
LLDropTarget::LLDropTarget(const LLDropTarget::Params& p)
: LLView(p)
, mReset(NULL)
{
setToolTip(std::string(p.tool_tip));
mText = new LLTextBox("drop_text", LLRect(), p.label);
addChild(mText);
setControlName(p.control_name, NULL);
mText->setFollows(FOLLOWS_NONE);
mText->setMouseOpaque(false);
mText->setHAlign(LLFontGL::HCENTER);
mText->setVPad(1);
mBorder = new LLViewBorder("drop_border", LLRect(), LLViewBorder::BEVEL_IN);
addChild(mBorder);
mBorder->setMouseOpaque(false);
if (!p.border_visible) mBorder->setBorderWidth(0);
if (p.show_reset)
{
addChild(mReset = new LLButton("reset", LLRect(), "icn_clear_lineeditor.tga", "icn_clear_lineeditor.tga", "", boost::bind(&LLDropTarget::setValue, this, _2)));
}
// Now set the rects of the children
p.fill_parent ? fillParent(getParent()) : setChildRects(p.rect);
}
LLDropTarget::~LLDropTarget()
{
}
// static
LLView* LLDropTarget::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory* factory)
{
LLDropTarget* target = new LLDropTarget;
target->initFromXML(node, parent);
return target;
}
// virtual
void LLDropTarget::initFromXML(LLXMLNodePtr node, LLView* parent)
{
LLView::initFromXML(node, parent);
const LLRect& rect = getRect();
if (node->hasAttribute("show_reset"))
{
bool show;
node->getAttribute_bool("show_reset", show);
if (!show)
{
delete mReset;
mReset = NULL;
}
}
setChildRects(LLRect(0, rect.getHeight(), rect.getWidth(), 0));
if (node->hasAttribute("name")) // Views can't have names, but drop targets can
{
std::string name;
node->getAttributeString("name", name);
setName(name);
}
if (node->hasAttribute("label"))
{
std::string label;
node->getAttributeString("label", label);
mText->setText(label);
}
if (node->hasAttribute("fill_parent"))
{
bool fill;
node->getAttribute_bool("fill_parent", fill);
if (fill) fillParent(parent);
}
if (node->hasAttribute("border_visible"))
{
bool border_visible;
node->getAttribute_bool("border_visible", border_visible);
if (!border_visible) mBorder->setBorderWidth(0);
}
}
// virtual
void LLDropTarget::setControlName(const std::string& control_name, LLView* context)
{
if (control_name.empty()) // The "empty set"
{
mControl = NULL;
mConnection.disconnect();
return; // This DropTarget never changes text, it isn't tied to a control
}
bool none(true);
std::string text;
if (LLStartUp::getStartupState() != STATE_STARTED) // Too early for PerAccount
{
text = LLTrans::getString("NotLoggedIn");
}
else
{
mControl = gSavedPerAccountSettings.getControl(control_name);
if (!mControl)
{
LL_ERRS() << "Could not find control \"" << control_name << "\" in gSavedPerAccountSettings" << LL_ENDL;
return; // Though this should never happen.
}
const LLUUID id(mControl->getValue().asString());
none = id.isNull();
if (none)
text = LLTrans::getString("CurrentlyNotSet");
else if (LLViewerInventoryItem* item = gInventory.getItem(id))
text = currently_set_to(item);
else
text = LLTrans::getString("CurrentlySetToAnItemNotOnThisAccount");
}
if (mControl)
mConnection = mControl->getSignal()->connect(boost::bind(&LLView::setValue, this, _2));
else
mConnection.disconnect();
mText->setText(text);
if (mReset) mReset->setVisible(!none);
}
void LLDropTarget::setChildRects(LLRect rect)
{
mBorder->setRect(rect);
if (mReset)
{
// Reset button takes rightmost part of the text area.
S32 height(rect.getHeight());
rect.mRight -= height;
mText->setRect(rect);
rect.mLeft = rect.mRight;
rect.mRight += height;
mReset->setRect(rect);
}
else
{
mText->setRect(rect);
}
}
void LLDropTarget::fillParent(const LLView* parent)
{
if (!parent) return; // No parent to fill
const std::string& tool_tip = getToolTip();
if (!tool_tip.empty()) // Don't tool_tip the entire parent
{
mText->setToolTip(tool_tip);
setToolTip(LLStringExplicit(""));
}
// The following block enlarges the target, but maintains the desired size for the text and border
setChildRects(getRect()); // Children maintain the old rectangle
const LLRect& parent_rect = parent->getRect();
setRect(LLRect(0, parent_rect.getHeight(), parent_rect.getWidth(), 0));
}
void LLDropTarget::setControlValue(const std::string& val)
{
if (mControl)
{
boost::signals2::shared_connection_block block(mConnection);
mControl->setValue(val);
}
}
void LLDropTarget::setItem(const LLInventoryItem* item)
{
if (mReset) mReset->setVisible(!!item);
mText->setText(currently_set_to(item));
setControlValue(item ? item->getUUID().asString() : "");
}
void LLDropTarget::setValue(const LLSD& value)
{
const LLUUID& id(value.asUUID());
setItem(id.isNull() ? NULL : gInventory.getItem(id));
}
void LLDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
{
LL_INFOS() << "LLDropTarget::doDrop()" << LL_ENDL;
}
BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg)
{
if (mID.notNull())
return getParent() ? LLToolDragAndDrop::handleGiveDragAndDrop(mID, LLUUID::null, drop, cargo_type, cargo_data, accept) : false;
if (LLViewerInventoryItem* inv_item = static_cast<LLViewerInventoryItem*>(cargo_data))
{
*accept = ACCEPT_YES_COPY_SINGLE;
if (drop) setItem(inv_item);
}
return true;
}