Added an experience tab to the region floater
parent
88d0281121
commit
d74119ec2b
|
|
@ -403,6 +403,7 @@ set(viewer_SOURCE_FILES
|
|||
llpanelclassified.cpp
|
||||
llpanelcontents.cpp
|
||||
llpaneleditwearable.cpp
|
||||
llpanelexperiencelisteditor.cpp
|
||||
llpanelexperiences.cpp
|
||||
llpanelface.cpp
|
||||
llpanelgenerictip.cpp
|
||||
|
|
@ -989,6 +990,7 @@ set(viewer_HEADER_FILES
|
|||
llpanelclassified.h
|
||||
llpanelcontents.h
|
||||
llpaneleditwearable.h
|
||||
llpanelexperiencelisteditor.h
|
||||
llpanelexperiences.h
|
||||
llpanelface.h
|
||||
llpanelgenerictip.h
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@
|
|||
#include "llavatarnamecache.h"
|
||||
#include "llfloaterexperienceprofile.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "lldraghandle.h"
|
||||
|
||||
#define BTN_FIND "find"
|
||||
#define BTN_OK "ok_btn"
|
||||
|
|
@ -80,7 +82,7 @@ public:
|
|||
}
|
||||
}
|
||||
};
|
||||
LLFloaterExperiencePicker* LLFloaterExperiencePicker::show( select_callback_t callback, const LLUUID& key, BOOL allow_multiple, BOOL closeOnSelect )
|
||||
LLFloaterExperiencePicker* LLFloaterExperiencePicker::show( select_callback_t callback, const LLUUID& key, BOOL allow_multiple, BOOL closeOnSelect, LLView * frustumOrigin )
|
||||
{
|
||||
LLFloaterExperiencePicker* floater =
|
||||
LLFloaterReg::showTypedInstance<LLFloaterExperiencePicker>("experience_search", key);
|
||||
|
|
@ -93,14 +95,91 @@ LLFloaterExperiencePicker* LLFloaterExperiencePicker::show( select_callback_t ca
|
|||
floater->mSelectionCallback = callback;
|
||||
floater->mCloseOnSelect = closeOnSelect;
|
||||
floater->setAllowMultiple(allow_multiple);
|
||||
|
||||
if(frustumOrigin)
|
||||
{
|
||||
floater->mFrustumOrigin = frustumOrigin->getHandle();
|
||||
}
|
||||
|
||||
return floater;
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterExperiencePicker::drawFrustum()
|
||||
{
|
||||
if(mFrustumOrigin.get())
|
||||
{
|
||||
LLView * frustumOrigin = mFrustumOrigin.get();
|
||||
LLRect origin_rect;
|
||||
frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, this);
|
||||
// draw context cone connecting color picker with color swatch in parent floater
|
||||
LLRect local_rect = getLocalRect();
|
||||
if (hasFocus() && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f)
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
LLGLEnable(GL_CULL_FACE);
|
||||
gGL.begin(LLRender::QUADS);
|
||||
{
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
|
||||
if (gFocusMgr.childHasMouseCapture(getDragHandle()))
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterExperiencePicker::draw()
|
||||
{
|
||||
drawFrustum();
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
LLFloaterExperiencePicker::LLFloaterExperiencePicker( const LLSD& key )
|
||||
:LLFloater(key)
|
||||
,mContextConeOpacity (0.f)
|
||||
,mContextConeInAlpha(0.f)
|
||||
,mContextConeOutAlpha(0.f)
|
||||
,mContextConeFadeTime(0.f)
|
||||
{
|
||||
setDefaultFilters();
|
||||
|
||||
mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
|
||||
mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
|
||||
mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
|
||||
}
|
||||
|
||||
LLFloaterExperiencePicker::~LLFloaterExperiencePicker()
|
||||
|
|
@ -219,7 +298,8 @@ void LLFloaterExperiencePicker::find()
|
|||
|
||||
bool LLFloaterExperiencePicker::isSelectButtonEnabled()
|
||||
{
|
||||
return getChild<LLScrollListCtrl>(LIST_RESULTS)->getFirstSelectedIndex() >=0;
|
||||
LLScrollListCtrl* list=getChild<LLScrollListCtrl>(LIST_RESULTS);
|
||||
return list->getFirstSelectedIndex() >=0;
|
||||
}
|
||||
|
||||
void LLFloaterExperiencePicker::getSelectedExperienceIds( const LLScrollListCtrl* results, uuid_vec_t &experience_ids )
|
||||
|
|
@ -306,17 +386,15 @@ void LLFloaterExperiencePicker::filterContent()
|
|||
|
||||
search_results->deleteAllItems();
|
||||
|
||||
int maturity = getChild<LLComboBox>(TEXT_MATURITY)->getSelectedValue().asInteger();
|
||||
LLSD item;
|
||||
LLSD::array_const_iterator it = experiences.beginArray();
|
||||
for ( ; it != experiences.endArray(); ++it)
|
||||
{
|
||||
const LLSD& experience = *it;
|
||||
|
||||
if(experience[LLExperienceCache::MATURITY].asInteger() > maturity)
|
||||
if(isExperienceHidden(experience))
|
||||
continue;
|
||||
|
||||
|
||||
item["id"]=experience[LLExperienceCache::EXPERIENCE_ID];
|
||||
LLSD& columns = item["columns"];
|
||||
columns[0]["column"] = "maturity";
|
||||
|
|
@ -335,11 +413,7 @@ void LLFloaterExperiencePicker::filterContent()
|
|||
{
|
||||
LLStringUtil::format_map_t map;
|
||||
map["[TEXT]"] = childGetText(TEXT_EDIT);
|
||||
LLSD item;
|
||||
item["id"] = LLUUID::null;
|
||||
item["columns"][1]["column"] = "name";
|
||||
item["columns"][1]["value"] = columnSpace+getString("not_found", map);
|
||||
search_results->addElement(item);
|
||||
getChild<LLScrollListCtrl>(LIST_RESULTS)->setCommentText(getString("not_found", map));
|
||||
search_results->setEnabled(false);
|
||||
getChildView(BTN_OK)->setEnabled(false);
|
||||
getChildView(BTN_PROFILE)->setEnabled(false);
|
||||
|
|
@ -364,6 +438,41 @@ void LLFloaterExperiencePicker::onMaturity()
|
|||
filterContent();
|
||||
}
|
||||
|
||||
bool LLFloaterExperiencePicker::isExperienceHidden( const LLSD& experience) const
|
||||
{
|
||||
bool hide=false;
|
||||
filter_list::const_iterator it = mFilters.begin();
|
||||
for(/**/;it != mFilters.end(); ++it)
|
||||
{
|
||||
if((*it)(experience)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return hide;
|
||||
}
|
||||
|
||||
bool LLFloaterExperiencePicker::FilterOverRating( const LLSD& experience )
|
||||
{
|
||||
int maturity = getChild<LLComboBox>(TEXT_MATURITY)->getSelectedValue().asInteger();
|
||||
return experience[LLExperienceCache::MATURITY].asInteger() > maturity;
|
||||
}
|
||||
|
||||
bool LLFloaterExperiencePicker::FilterWithProperty( const LLSD& experience, S32 prop )
|
||||
{
|
||||
return (experience[LLExperienceCache::PROPERTIES].asInteger() & prop) != 0;
|
||||
}
|
||||
|
||||
void LLFloaterExperiencePicker::setDefaultFilters()
|
||||
{
|
||||
mFilters.clear();
|
||||
addFilter(boost::bind(&LLFloaterExperiencePicker::FilterOverRating, this, _1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -40,15 +40,26 @@ public:
|
|||
|
||||
// The callback function will be called with an avatar name and UUID.
|
||||
typedef boost::function<void (const uuid_vec_t&)> select_callback_t;
|
||||
// filter function for experiences, return true if the experience should be hidden.
|
||||
typedef boost::function<bool (const LLSD&)> filter_function;
|
||||
typedef std::vector<filter_function> filter_list;
|
||||
|
||||
static LLFloaterExperiencePicker* show( select_callback_t callback, const LLUUID& key, BOOL allow_multiple, BOOL closeOnSelect );
|
||||
static LLFloaterExperiencePicker* show( select_callback_t callback, const LLUUID& key, BOOL allow_multiple, BOOL closeOnSelect, LLView * frustumOrigin);
|
||||
|
||||
LLFloaterExperiencePicker(const LLSD& key);
|
||||
virtual ~LLFloaterExperiencePicker();
|
||||
|
||||
BOOL postBuild();
|
||||
|
||||
void addFilter(filter_function func){mFilters.push_back(func);}
|
||||
template <class IT>
|
||||
void addFilters(IT begin, IT end){mFilters.insert(mFilters.end(), begin, end);}
|
||||
void setDefaultFilters();
|
||||
|
||||
static bool FilterWithProperty(const LLSD& experience, S32 prop);
|
||||
bool FilterOverRating(const LLSD& experience);
|
||||
|
||||
virtual void draw();
|
||||
private:
|
||||
void editKeystroke(LLLineEditor* caller, void* user_data);
|
||||
|
||||
|
|
@ -68,13 +79,23 @@ private:
|
|||
void processResponse( const LLUUID& query_id, const LLSD& content );
|
||||
|
||||
void filterContent();
|
||||
bool isExperienceHidden(const LLSD& experience) const ;
|
||||
std::string getMaturityString(int maturity);
|
||||
|
||||
|
||||
select_callback_t mSelectionCallback;
|
||||
bool mCloseOnSelect;
|
||||
filter_list mFilters;
|
||||
LLUUID mQueryID;
|
||||
LLSD mResponse;
|
||||
bool mCloseOnSelect;
|
||||
|
||||
|
||||
void drawFrustum();
|
||||
LLHandle <LLView> mFrustumOrigin;
|
||||
F32 mContextConeOpacity;
|
||||
F32 mContextConeInAlpha;
|
||||
F32 mContextConeOutAlpha;
|
||||
F32 mContextConeFadeTime;
|
||||
};
|
||||
|
||||
#endif // LL_LLFLOATEREXPERIENCEPICKER_H
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@
|
|||
#include "lltrans.h"
|
||||
#include "llagentui.h"
|
||||
#include "llmeshrepository.h"
|
||||
#include "llpanelexperiencelisteditor.h"
|
||||
#include <boost/function.hpp>
|
||||
#include "llfloaterexperiencepicker.h"
|
||||
#include "llexperiencecache.h"
|
||||
|
||||
const S32 TERRAIN_TEXTURE_COUNT = 4;
|
||||
const S32 CORNER_COUNT = 4;
|
||||
|
|
@ -214,6 +218,14 @@ BOOL LLFloaterRegionInfo::postBuild()
|
|||
panel->buildFromFile("panel_region_debug.xml");
|
||||
mTab->addTabPanel(panel);
|
||||
|
||||
if(!gAgent.getRegion()->getCapability("RegionExperiences").empty())
|
||||
{
|
||||
panel = new LLPanelRegionExperiences;
|
||||
mInfoPanels.push_back(panel);
|
||||
panel->buildFromFile("panel_region_experiences.xml");
|
||||
mTab->addTabPanel(panel);
|
||||
}
|
||||
|
||||
gMessageSystem->setHandlerFunc(
|
||||
"EstateOwnerMessage",
|
||||
&processEstateOwnerRequest);
|
||||
|
|
@ -3463,3 +3475,153 @@ void LLPanelEnvironmentInfo::onRegionSettingsApplied(bool ok)
|
|||
LLEnvManagerNew::instance().requestRegionSettings();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLPanelRegionExperiences::postBuild()
|
||||
{
|
||||
mAllowed = setupList("panel_allowed");
|
||||
mTrusted = setupList("panel_trusted");
|
||||
mBlocked = setupList("panel_blocked");
|
||||
return LLPanelRegionInfo::postBuild();
|
||||
}
|
||||
|
||||
LLPanelExperienceListEditor* LLPanelRegionExperiences::setupList( const char* control_name )
|
||||
{
|
||||
LLPanelExperienceListEditor* child = findChild<LLPanelExperienceListEditor>(control_name);
|
||||
child->getChild<LLTextBox>("text_name")->setText(getString(control_name));
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
boost::signals2::connection LLPanelRegionExperiences::processResponse( LLPanelExperienceListEditor* panel, boost::signals2::connection& conn, const LLSD& content )
|
||||
{
|
||||
if(conn.connected())
|
||||
{
|
||||
conn.disconnect();
|
||||
}
|
||||
panel->setExperienceIds(content);
|
||||
|
||||
return panel->setChangedCallback(boost::bind(&LLPanelRegionExperiences::listChanged, this));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLPanelRegionExperiences::processResponse( const LLSD& content )
|
||||
{
|
||||
mAllowedConnection=processResponse(mAllowed, mAllowedConnection, content["allowed"]);
|
||||
mBlockedConnection=processResponse(mBlocked, mBlockedConnection, content["blocked"]);
|
||||
mTrustedConnection=processResponse(mTrusted, mTrustedConnection, content["trusted"]);
|
||||
disableButton("apply_btn");
|
||||
}
|
||||
|
||||
|
||||
class LLRegionExperienceResponder : public LLHTTPClient::Responder
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void (const LLSD&)> callback_t;
|
||||
|
||||
callback_t mCallback;
|
||||
|
||||
LLRegionExperienceResponder(callback_t callback) : mCallback(callback) { }
|
||||
|
||||
void completed(U32 status, const std::string& reason, const LLSD& content)
|
||||
{
|
||||
if (isGoodStatus(status))
|
||||
{
|
||||
mCallback(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "experience responder failed [status:" << status << "]: " << content << llendl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void LLPanelRegionExperiences::infoCallback(LLHandle<LLPanelRegionExperiences> handle, const LLSD& content)
|
||||
{
|
||||
|
||||
if(handle.isDead())
|
||||
return;
|
||||
|
||||
LLPanelRegionExperiences* floater = handle.get();
|
||||
if (floater)
|
||||
{
|
||||
floater->processResponse(content);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLPanelRegionExperiences::FilterExisting(const LLSD& experience)
|
||||
{
|
||||
LLUUID id = experience[LLExperienceCache::EXPERIENCE_ID].asUUID();
|
||||
return mAllowed->getExperienceIds().find(id) != mAllowed->getExperienceIds().end() ||
|
||||
mBlocked->getExperienceIds().find(id) != mBlocked->getExperienceIds().end() ||
|
||||
mTrusted->getExperienceIds().find(id) != mTrusted->getExperienceIds().end() ;
|
||||
}
|
||||
|
||||
|
||||
bool LLPanelRegionExperiences::refreshFromRegion(LLViewerRegion* region)
|
||||
{
|
||||
BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
|
||||
|
||||
mAllowed->loading();
|
||||
mAllowed->setReadonly(!allow_modify);
|
||||
mAllowed->addFilter(boost::bind(LLFloaterExperiencePicker::FilterWithProperty, _1, LLExperienceCache::PROPERTY_GRID));
|
||||
mAllowed->addFilter(boost::bind(&LLPanelRegionExperiences::FilterExisting, this, _1));
|
||||
|
||||
mBlocked->loading();
|
||||
mBlocked->setReadonly(!allow_modify);
|
||||
mBlocked->addFilter(boost::bind(LLFloaterExperiencePicker::FilterWithProperty, _1, LLExperienceCache::PROPERTY_PRIVILEGED));
|
||||
mBlocked->addFilter(boost::bind(&LLPanelRegionExperiences::FilterExisting, this, _1));
|
||||
|
||||
mTrusted->loading();
|
||||
mTrusted->setReadonly(!allow_modify);
|
||||
mTrusted->addFilter(boost::bind(&LLPanelRegionExperiences::FilterExisting, this, _1));
|
||||
|
||||
std::string url = region->getCapability("RegionExperiences");
|
||||
if (!url.empty())
|
||||
{
|
||||
LLHTTPClient::get(url, new LLRegionExperienceResponder(boost::bind(&LLPanelRegionExperiences::infoCallback,
|
||||
getDerivedHandle<LLPanelRegionExperiences>(), _1)));
|
||||
}
|
||||
return LLPanelRegionInfo::refreshFromRegion(region);
|
||||
}
|
||||
|
||||
LLSD LLPanelRegionExperiences::addIds(LLPanelExperienceListEditor* panel)
|
||||
{
|
||||
LLSD ids;
|
||||
const uuid_list_t& id_list = panel->getExperienceIds();
|
||||
for(uuid_list_t::const_iterator it = id_list.begin(); it != id_list.end(); ++it)
|
||||
{
|
||||
ids.append(*it);
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLPanelRegionExperiences::sendUpdate()
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
std::string url = region->getCapability("RegionExperiences");
|
||||
if (!url.empty())
|
||||
{
|
||||
LLSD content;
|
||||
|
||||
content["allowed"]=addIds(mAllowed);
|
||||
content["blocked"]=addIds(mBlocked);
|
||||
content["trusted"]=addIds(mTrusted);
|
||||
|
||||
LLHTTPClient::post(url, content, new LLRegionExperienceResponder(boost::bind(&LLPanelRegionExperiences::infoCallback,
|
||||
getDerivedHandle<LLPanelRegionExperiences>(), _1)));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelRegionExperiences::listChanged()
|
||||
{
|
||||
onChangeAnything();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ class LLPanelRegionDebugInfo;
|
|||
class LLPanelRegionTerrainInfo;
|
||||
class LLPanelEstateInfo;
|
||||
class LLPanelEstateCovenant;
|
||||
class LLPanelExperienceListEditor;
|
||||
|
||||
class LLEventTimer;
|
||||
class LLEnvironmentSettings;
|
||||
|
|
@ -450,4 +451,34 @@ private:
|
|||
LLComboBox* mDayCyclePresetCombo;
|
||||
};
|
||||
|
||||
class LLPanelRegionExperiences : public LLPanelRegionInfo
|
||||
{
|
||||
LOG_CLASS(LLPanelEnvironmentInfo);
|
||||
|
||||
public:
|
||||
LLPanelRegionExperiences(){}
|
||||
/*virtual*/ BOOL postBuild();
|
||||
virtual BOOL sendUpdate();
|
||||
|
||||
static void infoCallback(LLHandle<LLPanelRegionExperiences> handle, const LLSD& content);
|
||||
|
||||
void listChanged();
|
||||
bool refreshFromRegion(LLViewerRegion* region);
|
||||
private:
|
||||
void processResponse( const LLSD& content );
|
||||
boost::signals2::connection processResponse( LLPanelExperienceListEditor* panel, boost::signals2::connection& connection, const LLSD& content);
|
||||
void refreshRegionExperiences();
|
||||
|
||||
LLPanelExperienceListEditor* setupList(const char* control_name);
|
||||
static LLSD addIds( LLPanelExperienceListEditor* panel );
|
||||
bool FilterExisting(const LLSD& experience );
|
||||
|
||||
LLPanelExperienceListEditor* mTrusted;
|
||||
boost::signals2::connection mTrustedConnection;
|
||||
LLPanelExperienceListEditor* mAllowed;
|
||||
boost::signals2::connection mAllowedConnection;
|
||||
LLPanelExperienceListEditor* mBlocked;
|
||||
boost::signals2::connection mBlockedConnection;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,213 @@
|
|||
/**
|
||||
* @file llpanelexperiencelisteditor.cpp
|
||||
* @brief Editor for building a list of experiences
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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 "llpanelexperiencelisteditor.h"
|
||||
|
||||
#include "llbutton.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llfloaterexperiencepicker.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llhandle.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llagent.h"
|
||||
|
||||
|
||||
static LLRegisterPanelClassWrapper<LLPanelExperienceListEditor> t_panel_experience_list_editor("panel_experience_list_editor");
|
||||
|
||||
|
||||
LLPanelExperienceListEditor::LLPanelExperienceListEditor()
|
||||
:mItems(NULL)
|
||||
,mProfile(NULL)
|
||||
,mRemove(NULL)
|
||||
,mChangedCallback(NULL)
|
||||
,mReadonly(false)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLPanelExperienceListEditor::postBuild()
|
||||
{
|
||||
mItems = getChild<LLScrollListCtrl>("experience_list");
|
||||
mAdd = getChild<LLButton>("btn_add");
|
||||
mRemove = getChild<LLButton>("btn_remove");
|
||||
mProfile = getChild<LLButton>("btn_profile");
|
||||
|
||||
childSetAction("btn_add", boost::bind(&LLPanelExperienceListEditor::onAdd, this));
|
||||
childSetAction("btn_remove", boost::bind(&LLPanelExperienceListEditor::onRemove, this));
|
||||
childSetAction("btn_profile", boost::bind(&LLPanelExperienceListEditor::onProfile, this));
|
||||
|
||||
mItems->setCommitCallback(boost::bind(&LLPanelExperienceListEditor::checkButtonsEnabled, this));
|
||||
|
||||
checkButtonsEnabled();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const uuid_list_t& LLPanelExperienceListEditor::getExperienceIds() const
|
||||
{
|
||||
return mExperienceIds;
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::addExperienceIds( const uuid_vec_t& experience_ids )
|
||||
{
|
||||
mExperienceIds.insert(experience_ids.begin(), experience_ids.end());
|
||||
onItems();
|
||||
}
|
||||
|
||||
|
||||
void LLPanelExperienceListEditor::setExperienceIds( const LLSD& experience_ids )
|
||||
{
|
||||
mExperienceIds.clear();
|
||||
mExperienceIds.insert(experience_ids.beginArray(), experience_ids.endArray());
|
||||
onItems();
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::addExperience( const LLUUID& id )
|
||||
{
|
||||
mExperienceIds.insert(id);
|
||||
onItems();
|
||||
}
|
||||
void LLPanelExperienceListEditor::onAdd()
|
||||
{
|
||||
if(!mPicker.isDead())
|
||||
{
|
||||
mPicker.get()->setFrontmost(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
mKey.generateNewID();
|
||||
|
||||
LLFloaterExperiencePicker* picker=LLFloaterExperiencePicker::show(boost::bind(&LLPanelExperienceListEditor::addExperienceIds, this, _1), mKey, FALSE, TRUE, mAdd);
|
||||
picker->addFilters(mFilters.begin(), mFilters.end());
|
||||
|
||||
mPicker = picker->getDerivedHandle<LLFloaterExperiencePicker>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLPanelExperienceListEditor::onRemove()
|
||||
{
|
||||
std::vector<LLScrollListItem*> items= mItems->getAllSelected();
|
||||
std::vector<LLScrollListItem*>::iterator it = items.begin();
|
||||
for(/**/; it != items.end(); ++it)
|
||||
{
|
||||
if((*it) != NULL)
|
||||
{
|
||||
mExperienceIds.erase((*it)->getValue());
|
||||
}
|
||||
}
|
||||
onItems();
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::onProfile()
|
||||
{
|
||||
LLScrollListItem* item = mItems->getFirstSelected();
|
||||
if(item)
|
||||
{
|
||||
LLFloaterReg::showInstance("experience_profile", item->getUUID(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::checkButtonsEnabled()
|
||||
{
|
||||
mAdd->setEnabled(!mReadonly);
|
||||
int selected = mItems->getNumSelected();
|
||||
mRemove->setEnabled(!mReadonly && selected>0);
|
||||
mProfile->setEnabled(selected==1);
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::onItems()
|
||||
{
|
||||
mItems->deleteAllItems();
|
||||
|
||||
LLSD item;
|
||||
uuid_list_t::iterator it = mExperienceIds.begin();
|
||||
for(/**/; it != mExperienceIds.end(); ++it)
|
||||
{
|
||||
const LLUUID& experience = *it;
|
||||
item["id"]=experience;
|
||||
LLSD& columns = item["columns"];
|
||||
columns[0]["column"] = "experience_name";
|
||||
columns[0]["value"] = getString("loading");
|
||||
mItems->addElement(item);
|
||||
|
||||
LLExperienceCache::get(experience, boost::bind(&LLPanelExperienceListEditor::experienceDetailsCallback,
|
||||
getDerivedHandle<LLPanelExperienceListEditor>(), _1));
|
||||
}
|
||||
|
||||
|
||||
if(mItems->getItemCount() == 0)
|
||||
{
|
||||
mItems->setCommentText(getString("no_results"));
|
||||
}
|
||||
|
||||
|
||||
checkButtonsEnabled();
|
||||
if(mChangedCallback)
|
||||
{
|
||||
(*mChangedCallback)();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::experienceDetailsCallback( LLHandle<LLPanelExperienceListEditor> panel, const LLSD& experience )
|
||||
{
|
||||
if(!panel.isDead())
|
||||
{
|
||||
panel.get()->onExperienceDetails(experience);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::onExperienceDetails( const LLSD& experience )
|
||||
{
|
||||
LLScrollListItem* item = mItems->getItem(experience[LLExperienceCache::EXPERIENCE_ID]);
|
||||
if(!item)
|
||||
return;
|
||||
|
||||
item->getColumn(0)->setValue(experience[LLExperienceCache::NAME]);
|
||||
}
|
||||
|
||||
LLPanelExperienceListEditor::~LLPanelExperienceListEditor()
|
||||
{
|
||||
if(!mPicker.isDead())
|
||||
{
|
||||
mPicker.get()->closeFloater();
|
||||
}
|
||||
delete mChangedCallback;
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::loading()
|
||||
{
|
||||
mItems->clear();
|
||||
mItems->setCommentText( getString("loading"));
|
||||
}
|
||||
|
||||
void LLPanelExperienceListEditor::setReadonly( bool val )
|
||||
{
|
||||
mReadonly = val;
|
||||
setCtrlsEnabled(!mReadonly);
|
||||
checkButtonsEnabled();
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* @file llpanelexperiencelisteditor.cpp
|
||||
* @brief Editor for building a list of experiences
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPANELEXPERIENCELISTEDITOR_H
|
||||
#define LL_LLPANELEXPERIENCELISTEDITOR_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "lluuid.h"
|
||||
#include <set>
|
||||
|
||||
class LLScrollListCtrl;
|
||||
class LLButton;
|
||||
class LLFloaterExperiencePicker;
|
||||
|
||||
class LLPanelExperienceListEditor : public LLPanel
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::signals2::signal<void () > list_changed_signal_t;
|
||||
// filter function for experiences, return true if the experience should be hidden.
|
||||
typedef boost::function<bool (const LLSD&)> filter_function;
|
||||
typedef std::vector<filter_function> filter_list;
|
||||
typedef LLHandle<LLFloaterExperiencePicker> PickerHandle;
|
||||
LLPanelExperienceListEditor();
|
||||
~LLPanelExperienceListEditor();
|
||||
BOOL postBuild();
|
||||
|
||||
void loading();
|
||||
|
||||
const uuid_list_t& getExperienceIds()const;
|
||||
void setExperienceIds(const LLSD& experience_ids);
|
||||
void addExperienceIds(const uuid_vec_t& experience_ids);
|
||||
|
||||
void addExperience(const LLUUID& id);
|
||||
|
||||
boost::signals2::connection setChangedCallback(list_changed_signal_t::slot_type cb )
|
||||
{
|
||||
if (!mChangedCallback) mChangedCallback = new list_changed_signal_t();
|
||||
return mChangedCallback->connect(cb);
|
||||
}
|
||||
|
||||
bool getReadonly() const { return mReadonly; }
|
||||
void setReadonly(bool val);
|
||||
|
||||
|
||||
void addFilter(filter_function func){mFilters.push_back(func);}
|
||||
private:
|
||||
|
||||
void onItems();
|
||||
void onRemove();
|
||||
void onAdd();
|
||||
void onProfile();
|
||||
|
||||
void checkButtonsEnabled();
|
||||
static void experienceDetailsCallback( LLHandle<LLPanelExperienceListEditor> panel, const LLSD& experience );
|
||||
void onExperienceDetails( const LLSD& experience );
|
||||
void processResponse( const LLSD& content );
|
||||
uuid_list_t mExperienceIds;
|
||||
|
||||
|
||||
LLScrollListCtrl* mItems;
|
||||
filter_list mFilters;
|
||||
LLButton* mAdd;
|
||||
LLButton* mRemove;
|
||||
LLButton* mProfile;
|
||||
PickerHandle mPicker;
|
||||
list_changed_signal_t* mChangedCallback;
|
||||
LLUUID mKey;
|
||||
bool mReadonly;
|
||||
|
||||
};
|
||||
|
||||
#endif //LL_LLPANELEXPERIENCELISTEDITOR_H
|
||||
|
|
@ -1609,6 +1609,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
|
|||
capabilityNames.append("UpdateExperience");
|
||||
capabilityNames.append("IsExperienceAdmin");
|
||||
capabilityNames.append("IsExperienceContributor");
|
||||
capabilityNames.append("RegionExperiences");
|
||||
capabilityNames.append("GetMesh");
|
||||
capabilityNames.append("GetMetadata");
|
||||
capabilityNames.append("GetObjectCost");
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@
|
|||
right="-1"
|
||||
height="239"
|
||||
top_pad="4"
|
||||
follows="all"
|
||||
follows="all"
|
||||
column_padding="5"
|
||||
can_resize="true"
|
||||
name="search_results">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="0"
|
||||
width="300"
|
||||
height="100"
|
||||
min_height="100"
|
||||
follows="all"
|
||||
border="true"
|
||||
name="experince_list_editor">
|
||||
<panel.string
|
||||
name="loading">
|
||||
loading...
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="no_results">
|
||||
(empty)
|
||||
</panel.string>
|
||||
<text
|
||||
layout="topleft"
|
||||
name="text_name"
|
||||
left="3"
|
||||
right="-1"
|
||||
height="12"
|
||||
follows="left|top|right">
|
||||
Experience List
|
||||
</text>
|
||||
<scroll_list
|
||||
draw_heading="false"
|
||||
left="3"
|
||||
width="225"
|
||||
height="77"
|
||||
follows="all"
|
||||
can_resize="false"
|
||||
name="experience_list">
|
||||
<columns
|
||||
width="225"
|
||||
user_resize="false"
|
||||
name="experience_name"
|
||||
label="Name"/>
|
||||
</scroll_list>
|
||||
<button
|
||||
layout="topleft"
|
||||
follows="top|right"
|
||||
top_pad="-77"
|
||||
left_pad="3"
|
||||
width="65"
|
||||
name="btn_add"
|
||||
label="Add..."/>
|
||||
<button
|
||||
layout="topleft"
|
||||
follows="top|right"
|
||||
width="64"
|
||||
name="btn_remove"
|
||||
label="Remove"/>
|
||||
<button
|
||||
layout="topleft"
|
||||
follows="top|right"
|
||||
width="64"
|
||||
name="btn_profile"
|
||||
label="Profile..."/>
|
||||
</panel>
|
||||
|
|
@ -2,14 +2,78 @@
|
|||
<panel
|
||||
border="true"
|
||||
follows="top|left"
|
||||
height="510"
|
||||
height="320"
|
||||
help_topic="panel_region_experience_tab"
|
||||
label="Experience"
|
||||
label="Experiences"
|
||||
name="Experiences"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="Experience"
|
||||
top="320"
|
||||
width="530">
|
||||
|
||||
width="480">
|
||||
<panel.string
|
||||
name="panel_allowed">
|
||||
Allowed Experiences
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="panel_blocked">
|
||||
Blocked Experiences
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="panel_trusted">
|
||||
Trusted Experiences
|
||||
</panel.string>
|
||||
|
||||
<layout_stack
|
||||
left="5"
|
||||
layout="topleft"
|
||||
follows="all"
|
||||
top="100"
|
||||
right="-5"
|
||||
height="140"
|
||||
min_height="140"
|
||||
orientation="vertical">
|
||||
<layout_panel
|
||||
height="100"
|
||||
min_height="100"
|
||||
width="530">
|
||||
<panel follows="all"
|
||||
width="530"
|
||||
name="panel_trusted"
|
||||
class="panel_experience_list_editor"
|
||||
filename="panel_experience_list_editor.xml" />
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
height="100"
|
||||
min_height="100"
|
||||
width="530">
|
||||
<panel
|
||||
label="SOME LABEL"
|
||||
width="530"
|
||||
name="panel_allowed"
|
||||
class="panel_experience_list_editor"
|
||||
filename="panel_experience_list_editor.xml"/>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
height="100"
|
||||
min_height="100"
|
||||
width="530">
|
||||
<panel
|
||||
width="530"
|
||||
name="panel_blocked"
|
||||
class="panel_experience_list_editor"
|
||||
filename="panel_experience_list_editor.xml"/>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
height="30"
|
||||
min_height="30"
|
||||
max_height="30"
|
||||
width="530">
|
||||
<button
|
||||
layout="topleft"
|
||||
width="85"
|
||||
left="3"
|
||||
label="Apply"
|
||||
name="apply_btn"/>
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
</panel>
|
||||
|
|
|
|||
Loading…
Reference in New Issue