summaryrefslogtreecommitdiff
path: root/indra/newview/llpanelpicks.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llpanelpicks.cpp')
-rw-r--r--indra/newview/llpanelpicks.cpp488
1 files changed, 488 insertions, 0 deletions
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
new file mode 100644
index 0000000000..c34038c672
--- /dev/null
+++ b/indra/newview/llpanelpicks.cpp
@@ -0,0 +1,488 @@
+/**
+ * @file llpanelpicks.cpp
+ * @brief LLPanelPicks and related class implementations
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagent.h"
+#include "llavatarconstants.h"
+#include "lltexturectrl.h"
+#include "llviewergenericmessage.h" // send_generic_message
+#include "llmenugl.h"
+#include "llviewermenu.h"
+#include "llregistry.h"
+
+#include "llpanelpicks.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llpanelavatar.h"
+#include "llpanelprofile.h"
+#include "llpanelpick.h"
+#include "llscrollcontainer.h"
+#include "lllistctrl.h"
+
+static const std::string XML_BTN_NEW = "new_btn";
+static const std::string XML_BTN_DELETE = "trash_btn";
+static const std::string XML_BTN_INFO = "info_btn";
+static const std::string XML_BTN_TELEPORT = "teleport_btn";
+static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn";
+
+static const std::string PICK_ID("pick_id");
+static const std::string PICK_CREATOR_ID("pick_creator_id");
+static const std::string PICK_NAME("pick_name");
+
+
+static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");
+
+//-----------------------------------------------------------------------------
+// LLPanelPicks
+//-----------------------------------------------------------------------------
+LLPanelPicks::LLPanelPicks()
+: LLPanelProfileTab(),
+ mPopupMenu(NULL),
+ mProfilePanel(NULL),
+ mPickPanel(NULL),
+ mPicksList(NULL)
+{
+}
+
+LLPanelPicks::~LLPanelPicks()
+{
+ if(getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
+ }
+}
+
+void* LLPanelPicks::create(void* data /* = NULL */)
+{
+ return new LLPanelPicks();
+}
+
+void LLPanelPicks::updateData()
+{
+ LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(getAvatarId(),APT_PICKS);
+}
+
+void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
+{
+ if(APT_PICKS == type)
+ {
+ LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
+ if(avatar_picks && getAvatarId() == avatar_picks->target_id)
+ {
+ std::string name, second_name;
+ gCacheName->getName(getAvatarId(),name,second_name);
+ childSetTextArg("pick_title", "[NAME]",name);
+
+ mPicksList->clear();
+
+ LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
+ for(; avatar_picks->picks_list.end() != it; ++it)
+ {
+ LLUUID pick_id = it->first;
+ std::string pick_name = it->second;
+
+ LLPickItem* picture = LLPickItem::create();
+ picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
+ picture->setPickName(pick_name);
+ picture->setPickId(pick_id);
+ picture->setCreatorId(getAvatarId());
+
+ LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);
+ picture->update();
+
+ LLSD pick_value = LLSD();
+ pick_value.insert(PICK_ID, pick_id);
+ pick_value.insert(PICK_NAME, pick_name);
+ pick_value.insert(PICK_CREATOR_ID, getAvatarId());
+
+ mPicksList->addItem(picture, pick_value);
+
+ picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickItem, this, _1));
+ picture->setRightMouseDownCallback(boost::bind(&LLPanelPicks::onRightMouseDownItem, this, _1, _2, _3, _4));
+ picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
+ picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
+ }
+
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
+ updateButtons();
+ }
+ }
+}
+
+LLPickItem* LLPanelPicks::getSelectedPickItem()
+{
+ LLPanel* selected_item = mPicksList->getSelectedItem();
+ if (!selected_item) return NULL;
+
+ return dynamic_cast<LLPickItem*>(selected_item);
+}
+
+BOOL LLPanelPicks::postBuild()
+{
+ mPicksList = getChild<LLListCtrl>("picks_list");
+
+ childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));
+
+ childSetAction("teleport_btn", boost::bind(&LLPanelPicks::onClickTeleport, this));
+ childSetAction("show_on_map_btn", boost::bind(&LLPanelPicks::onClickMap, this));
+
+ childSetAction("info_btn", boost::bind(&LLPanelPicks::onClickInfo, this));
+ childSetAction("new_btn", boost::bind(&LLPanelPicks::onClickNew, this));
+
+ CommitCallbackRegistry::ScopedRegistrar registar;
+ registar.add("Pick.Info", boost::bind(&LLPanelPicks::onClickInfo, this));
+ registar.add("Pick.Edit", boost::bind(&LLPanelPicks::onClickMenuEdit, this));
+ registar.add("Pick.Teleport", boost::bind(&LLPanelPicks::onClickTeleport, this));
+ registar.add("Pick.Map", boost::bind(&LLPanelPicks::onClickMap, this));
+ registar.add("Pick.Delete", boost::bind(&LLPanelPicks::onClickDelete, this));
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+
+ return TRUE;
+}
+
+void LLPanelPicks::onOpen(const LLSD& key)
+{
+ const LLUUID id(key.asUUID());
+ BOOL self = (gAgent.getID() == id);
+
+ // only agent can edit her picks
+ childSetEnabled("edit_panel", self);
+ childSetVisible("edit_panel", self);
+
+ // Disable buttons when viewing profile for first time
+ if(getAvatarId() != id)
+ {
+ clear();
+
+ childSetEnabled(XML_BTN_INFO,FALSE);
+ childSetEnabled(XML_BTN_TELEPORT,FALSE);
+ childSetEnabled(XML_BTN_SHOW_ON_MAP,FALSE);
+ }
+
+ // and see a special title - set as invisible by default in xml file
+ if (self)
+ {
+ childSetVisible("pick_title", !self);
+ childSetVisible("pick_title_agent", self);
+
+ mPopupMenu->setItemVisible("pick_delete", TRUE);
+ mPopupMenu->setItemVisible("pick_edit", TRUE);
+ mPopupMenu->setItemVisible("pick_separator", TRUE);
+ }
+
+ LLPanelProfileTab::onOpen(key);
+}
+
+//static
+void LLPanelPicks::onClickDelete()
+{
+ LLSD pick_value = mPicksList->getSelectedValue();
+ if (pick_value.isUndefined()) return;
+
+ LLSD args;
+ args["PICK"] = pick_value[PICK_NAME];
+ LLNotifications::instance().add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDelete, this, _1, _2));
+}
+
+bool LLPanelPicks::callbackDelete(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+
+ LLSD pick_value = mPicksList->getSelectedValue();
+
+ if (0 == option)
+ {
+ LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]);
+ mPicksList->removeItemByValue(pick_value);
+ }
+ updateButtons();
+ return false;
+}
+
+bool LLPanelPicks::callbackTeleport( const LLSD& notification, const LLSD& response )
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+
+ if (0 == option)
+ {
+ onClickTeleport();
+ }
+ return false;
+}
+
+//static
+void LLPanelPicks::onClickTeleport()
+{
+ LLPickItem* pick_item = getSelectedPickItem();
+ if (!pick_item) return;
+ LLPanelPick::teleport(pick_item->getPosGlobal());
+}
+
+//static
+void LLPanelPicks::onClickMap()
+{
+ LLPickItem* pick_item = getSelectedPickItem();
+ if (!pick_item) return;
+ LLPanelPick::showOnMap(pick_item->getPosGlobal());
+}
+
+
+void LLPanelPicks::onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
+{
+ if (mPopupMenu)
+ {
+ mPopupMenu->buildDrawLabels();
+ mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
+ ((LLContextMenu*)mPopupMenu)->show(x, y);
+ LLMenuGL::showPopup(item, mPopupMenu, x, y);
+ }
+}
+
+void LLPanelPicks::onDoubleClickItem(LLUICtrl* item)
+{
+ LLSD pick_value = mPicksList->getSelectedValue();
+ if (pick_value.isUndefined()) return;
+
+ LLSD args;
+ args["PICK"] = pick_value[PICK_NAME];
+ LLNotifications::instance().add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
+}
+
+void LLPanelPicks::updateButtons()
+{
+ int picks_num = mPicksList->size();
+ bool has_selected = mPicksList->numSelected();
+
+ childSetEnabled(XML_BTN_INFO, has_selected);
+
+ if (getAvatarId() == gAgentID)
+ {
+ childSetEnabled(XML_BTN_NEW, picks_num < MAX_AVATAR_PICKS);
+ childSetEnabled(XML_BTN_DELETE, has_selected);
+ }
+
+ childSetEnabled(XML_BTN_INFO, has_selected);
+ childSetEnabled(XML_BTN_TELEPORT, has_selected);
+ childSetEnabled(XML_BTN_SHOW_ON_MAP, has_selected);
+}
+
+void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)
+{
+ mProfilePanel = profile_panel;
+}
+
+
+void LLPanelPicks::buildPickPanel()
+{
+ if (mPickPanel == NULL)
+ {
+ mPickPanel = new LLPanelPick();
+ mPickPanel->setExitCallback(boost::bind(&LLPanelPicks::onClickBack, this));
+ }
+}
+
+void LLPanelPicks::onClickNew()
+{
+ buildPickPanel();
+ mPickPanel->setEditMode(TRUE);
+ mPickPanel->createNewPick();
+ getProfilePanel()->togglePanel(mPickPanel);
+}
+
+void LLPanelPicks::onClickInfo()
+{
+ LLSD selected_value = mPicksList->getSelectedValue();
+ if (selected_value.isUndefined()) return;
+
+ buildPickPanel();
+ mPickPanel->reset();
+ mPickPanel->init(selected_value[PICK_CREATOR_ID], selected_value[PICK_ID]);
+ getProfilePanel()->togglePanel(mPickPanel);
+}
+
+void LLPanelPicks::onClickBack()
+{
+ getProfilePanel()->togglePanel(mPickPanel);
+}
+
+void LLPanelPicks::onClickMenuEdit()
+{
+ //*TODO, refactor - most of that is similar to onClickInfo
+ LLSD selected_value = mPicksList->getSelectedValue();
+ if (selected_value.isUndefined()) return;
+
+ buildPickPanel();
+ mPickPanel->reset();
+ mPickPanel->init(selected_value[PICK_CREATOR_ID], selected_value[PICK_ID]);
+ mPickPanel->setEditMode(TRUE);
+ getProfilePanel()->togglePanel(mPickPanel);
+}
+
+inline LLPanelProfile* LLPanelPicks::getProfilePanel()
+{
+ llassert_always(NULL != mProfilePanel);
+ return mProfilePanel;
+}
+
+//-----------------------------------------------------------------------------
+// LLPanelPicks
+//-----------------------------------------------------------------------------
+LLPickItem::LLPickItem()
+: LLPanel()
+, mPickID(LLUUID::null)
+, mCreatorID(LLUUID::null)
+, mParcelID(LLUUID::null)
+, mSnapshotID(LLUUID::null)
+, mNeedData(true)
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this,"panel_pick_list_item.xml");
+}
+
+LLPickItem::~LLPickItem()
+{
+ if (mCreatorID.notNull())
+ {
+ LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
+ }
+
+}
+
+LLPickItem* LLPickItem::create()
+{
+ return new LLPickItem();
+}
+
+void LLPickItem::init(LLPickData* pick_data)
+{
+ setPickDesc(pick_data->desc);
+ setSnapshotId(pick_data->snapshot_id);
+ mPosGlobal = pick_data->pos_global;
+ mLocation = pick_data->location_text;
+
+ LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture");
+ picture->setImageAssetID(pick_data->snapshot_id);
+}
+
+void LLPickItem::setPickName(const std::string& name)
+{
+ mPickName = name;
+ childSetValue("picture_name",name);
+
+}
+
+const std::string& LLPickItem::getPickName()
+{
+ return mPickName;
+}
+
+const LLUUID& LLPickItem::getCreatorId()
+{
+ return mCreatorID;
+}
+
+const LLUUID& LLPickItem::getSnapshotId()
+{
+ return mSnapshotID;
+}
+
+void LLPickItem::setPickDesc(const std::string& descr)
+{
+ childSetValue("picture_descr",descr);
+}
+
+void LLPickItem::setPickId(const LLUUID& id)
+{
+ mPickID = id;
+}
+
+const LLUUID& LLPickItem::getPickId()
+{
+ return mPickID;
+}
+
+const LLVector3d& LLPickItem::getPosGlobal()
+{
+ return mPosGlobal;
+}
+
+const std::string& LLPickItem::getLocation()
+{
+ return mLocation;
+}
+
+const std::string LLPickItem::getDescription()
+{
+ return childGetValue("picture_descr").asString();
+}
+
+void LLPickItem::update()
+{
+ mNeedData = true;
+ LLAvatarPropertiesProcessor::instance().sendDataRequest(mCreatorID, APT_PICK_INFO, &mPickID);
+ mNeedData = false;
+}
+
+void LLPickItem::processProperties(void *data, EAvatarProcessorType type)
+{
+ if (APT_PICK_INFO != type) return;
+ if (!data) return;
+
+ LLPickData* pick_data = static_cast<LLPickData *>(data);
+ if (!pick_data) return;
+ if (mPickID != pick_data->pick_id) return;
+
+ init(pick_data);
+ LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
+}
+
+void LLPanelPicks::onClose()
+{
+ // Toggle off Pick Info panel if it is visible.
+ if(mPickPanel && mPickPanel->getVisible())
+ {
+ getProfilePanel()->togglePanel(mPickPanel);
+ }
+}
+
+BOOL LLPickItem::postBuild()
+{
+ setMouseEnterCallback(boost::bind(&LLPanelPick::childSetVisible, this, "hovered_icon", true));
+ setMouseLeaveCallback(boost::bind(&LLPanelPick::childSetVisible, this, "hovered_icon", false));
+ return TRUE;
+}
+
+void LLPickItem::setValue(const LLSD& value)
+{
+ if (!value.isMap()) return;;
+ if (!value.has("selected")) return;
+ childSetVisible("selected_icon", value["selected"]);
+}