Added an experience tab to the region floater

master
dolphin 2014-02-04 15:54:41 -08:00
parent 88d0281121
commit d74119ec2b
11 changed files with 780 additions and 18 deletions

View File

@ -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

View File

@ -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));
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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");

View File

@ -124,7 +124,7 @@
right="-1"
height="239"
top_pad="4"
follows="all"
follows="all"
column_padding="5"
can_resize="true"
name="search_results">

View File

@ -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>

View File

@ -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>