summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llenvironment.cpp10
-rw-r--r--indra/newview/llfloatereditextdaycycle.cpp74
-rw-r--r--indra/newview/llfloatereditextdaycycle.h135
-rw-r--r--indra/newview/llfloaterfixedenvironment.cpp8
-rw-r--r--indra/newview/llfolderviewmodelinventory.h5
-rw-r--r--indra/newview/llinventoryfilter.cpp28
-rw-r--r--indra/newview/llinventoryfilter.h31
-rw-r--r--indra/newview/llinventorypanel.cpp5
-rw-r--r--indra/newview/llinventorypanel.h5
-rw-r--r--indra/newview/llpanelobjectinventory.cpp35
-rw-r--r--indra/newview/llsettingspicker.cpp1761
-rw-r--r--indra/newview/llsettingspicker.h451
-rw-r--r--indra/newview/llsettingsvo.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/floater_settings_picker.xml118
15 files changed, 2558 insertions, 112 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 9b474284ff..571587867c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -539,6 +539,7 @@ set(viewer_SOURCE_FILES
llsecapi.cpp
llsechandler_basic.cpp
llselectmgr.cpp
+ llsettingspicker.cpp
llsettingsvo.cpp
llshareavatarhandler.cpp
llsidepanelappearance.cpp
@@ -1149,6 +1150,7 @@ set(viewer_HEADER_FILES
llsecapi.h
llsechandler_basic.h
llselectmgr.h
+ llsettingspicker.h
llsettingsvo.h
llsidepanelappearance.h
llsidepanelinventory.h
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index 5b184d8c25..ccb5294a2e 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -550,7 +550,7 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe
return;
}
- if (settings->getSettingType() == "daycycle")
+ if (settings->getSettingsType() == "daycycle")
{
LLSettingsDay::Seconds daylength(LLSettingsDay::DEFAULT_DAYLENGTH);
LLSettingsDay::Seconds dayoffset(LLSettingsDay::DEFAULT_DAYOFFSET);
@@ -561,7 +561,7 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe
}
setEnvironment(env, std::static_pointer_cast<LLSettingsDay>(settings), daylength, dayoffset);
}
- else if (settings->getSettingType() == "sky")
+ else if (settings->getSettingsType() == "sky")
{
fixedEnvironment_t fixedenv(std::static_pointer_cast<LLSettingsSky>(settings), LLSettingsWater::ptr_t());
if (environment)
@@ -570,7 +570,7 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe
}
setEnvironment(env, fixedenv);
}
- else if (settings->getSettingType() == "water")
+ else if (settings->getSettingsType() == "water")
{
fixedEnvironment_t fixedenv(LLSettingsSky::ptr_t(), std::static_pointer_cast<LLSettingsWater>(settings));
if (environment)
@@ -1201,7 +1201,7 @@ void LLEnvironment::onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::p
LLSettingsDay::ptr_t pday;
- if (settings->getSettingType() == "daycycle")
+ if (settings->getSettingsType() == "daycycle")
pday = std::static_pointer_cast<LLSettingsDay>(settings);
else
{
@@ -1561,7 +1561,7 @@ LLSettingsDay::ptr_t LLEnvironment::createDayCycleFromLegacyPreset(const std::st
LLSettingsDay::ptr_t LLEnvironment::createDayCycleFromEnvironment(EnvSelection_t env, LLSettingsBase::ptr_t settings)
{
- std::string type(settings->getSettingType());
+ std::string type(settings->getSettingsType());
if (type == "daycycle")
return std::static_pointer_cast<LLSettingsDay>(settings);
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
index 506e03fddc..daee8a798e 100644
--- a/indra/newview/llfloatereditextdaycycle.cpp
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -46,6 +46,8 @@
#include "llinventorymodel.h"
#include "llviewerparcelmgr.h"
+#include "llsettingspicker.h"
+
// newview
#include "llagent.h"
#include "llparcel.h"
@@ -55,6 +57,8 @@
#include "llpaneleditwater.h"
#include "llpaneleditsky.h"
+#include "llui.h"
+
#include "llenvironment.h"
#include "lltrans.h"
@@ -266,18 +270,31 @@ void LLFloaterEditExtDayCycle::onClose(bool app_quitting)
stopPlay();
}
+void LLFloaterEditExtDayCycle::onFocusReceived()
+{
+ updateEditEnvironment();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
+}
+
+void LLFloaterEditExtDayCycle::onFocusLost()
+{
+ stopPlay();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+}
+
+
void LLFloaterEditExtDayCycle::onVisibilityChange(BOOL new_visibility)
{
- if (new_visibility)
- {
- LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mScratchSky, mScratchWater);
- LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT);
- }
- else
- {
- LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
- stopPlay();
- }
+// if (new_visibility)
+// {
+// LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mScratchSky, mScratchWater);
+// LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT);
+// }
+// else
+// {
+// LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+// stopPlay();
+// }
}
void LLFloaterEditExtDayCycle::refresh()
@@ -335,7 +352,7 @@ void LLFloaterEditExtDayCycle::onButtonImport()
void LLFloaterEditExtDayCycle::onButtonLoadFrame()
{
-
+ doOpenInventoryFloater((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLSettingsType::ST_WATER : LLSettingsType::ST_SKY);
}
void LLFloaterEditExtDayCycle::onAddTrack()
@@ -818,6 +835,7 @@ void LLFloaterEditExtDayCycle::onAssetLoaded(LLUUID asset_id, LLSettingsBase::pt
}
mEditDay = std::dynamic_pointer_cast<LLSettingsDay>(settings);
updateEditEnvironment();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT);
syncronizeTabs();
refresh();
}
@@ -848,7 +866,8 @@ void LLFloaterEditExtDayCycle::loadLiveEnvironment(LLEnvironment::EnvSelection_t
void LLFloaterEditExtDayCycle::updateEditEnvironment(void)
{
-
+ if (!mEditDay)
+ return;
S32 skytrack = (mCurrentTrack) ? mCurrentTrack : 1;
mSkyBlender = std::make_shared<LLTrackBlenderLoopingManual>(mScratchSky, mEditDay, skytrack);
mWaterBlender = std::make_shared<LLTrackBlenderLoopingManual>(mScratchWater, mEditDay, LLSettingsDay::TRACK_WATER);
@@ -1104,4 +1123,35 @@ void LLFloaterEditExtDayCycle::onIdlePlay(void* user_data)
}
+void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type)
+{
+// LLUI::sWindow->setCursor(UI_CURSOR_WAIT);
+ LLFloater* floaterp = mInventoryFloater.get();
+
+ // Show the dialog
+ if (!floaterp)
+ {
+ LLFloaterSettingsPicker *picker = new LLFloaterSettingsPicker(
+ this,
+ LLUUID::null, "SELECT SETTINGS");
+ mInventoryFloater = picker->getHandle();
+
+ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data.asUUID()); });
+// texture_floaterp->setTextureSelectedCallback(boost::bind(&LLOutfitGallery::onTextureSelectionChanged, this, _1));
+// texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2));
+// texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1));
+// texture_floaterp->setLocalTextureEnabled(FALSE);
+
+ floaterp = picker;
+ }
+
+ ((LLFloaterSettingsPicker *)floaterp)->setSettingsFilter(type);
+ floaterp->openFloater();
+ floaterp->setFocus(TRUE);
+}
+
+void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID asset_id)
+{
+ LL_WARNS("LAPRAS") << "Got asset ID=" << asset_id << LL_ENDL;
+}
diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h
index ea9f1e1882..0ec5e91b4d 100644
--- a/indra/newview/llfloatereditextdaycycle.h
+++ b/indra/newview/llfloatereditextdaycycle.h
@@ -60,84 +60,85 @@ public:
static const std::string KEY_DAY_LENGTH;
// **RIDER**
- typedef boost::signals2::signal<void(LLSettingsDay::ptr_t)> edit_commit_signal_t;
- typedef boost::signals2::connection connection_t;
+ typedef boost::signals2::signal<void(LLSettingsDay::ptr_t)> edit_commit_signal_t;
+ typedef boost::signals2::connection connection_t;
- LLFloaterEditExtDayCycle(const LLSD &key);
- ~LLFloaterEditExtDayCycle();
+ LLFloaterEditExtDayCycle(const LLSD &key);
+ virtual ~LLFloaterEditExtDayCycle();
- //void openFloater(LLSettingsDay::ptr_t settings, S64Seconds daylength = S64Seconds(0), S64Seconds dayoffset = S64Seconds(0));
+ virtual BOOL postBuild() override;
+ virtual void onOpen(const LLSD& key) override;
+ virtual void onClose(bool app_quitting) override;
+ virtual void onFocusReceived() override;
+ virtual void onFocusLost() override;
+ virtual void onVisibilityChange(BOOL new_visibility) override;
- BOOL postBuild();
- void onOpen(const LLSD& key);
- void onClose(bool app_quitting);
+ connection_t setEditCommitSignal(edit_commit_signal_t::slot_type cb);
- void onVisibilityChange(BOOL new_visibility);
-
- connection_t setEditCommitSignal(edit_commit_signal_t::slot_type cb);
-
- virtual void refresh();
+ virtual void refresh() override;
private:
// flyout response/click
- void onButtonApply(LLUICtrl *ctrl, const LLSD &data);
- void onBtnCancel();
- void onButtonImport();
- void onButtonLoadFrame();
- void onAddTrack();
- void onRemoveTrack();
- void onCommitName(class LLLineEditor* caller, void* user_data);
- void onTrackSelectionCallback(const LLSD& user_data);
- void onPlayActionCallback(const LLSD& user_data);
+ void onButtonApply(LLUICtrl *ctrl, const LLSD &data);
+ void onBtnCancel();
+ void onButtonImport();
+ void onButtonLoadFrame();
+ void onAddTrack();
+ void onRemoveTrack();
+ void onCommitName(class LLLineEditor* caller, void* user_data);
+ void onTrackSelectionCallback(const LLSD& user_data);
+ void onPlayActionCallback(const LLSD& user_data);
// time slider moved
- void onTimeSliderMoved();
+ void onTimeSliderMoved();
// a frame moved or frame selection changed
- void onFrameSliderCallback(const LLSD &);
- void onFrameSliderDoubleClick(S32 x, S32 y, MASK mask);
- void onFrameSliderMouseDown(S32 x, S32 y, MASK mask);
- void onFrameSliderMouseUp(S32 x, S32 y, MASK mask);
-
- void selectTrack(U32 track_index, bool force = false);
- void selectFrame(F32 frame);
- void clearTabs();
- void updateTabs();
- void updateWaterTabs(const LLSettingsWaterPtr_t &p_water);
- void updateSkyTabs(const LLSettingsSkyPtr_t &p_sky);
- void setWaterTabsEnabled(BOOL enable);
- void setSkyTabsEnabled(BOOL enable);
- void updateButtons();
- void updateSlider(); //track to slider
- void updateTimeAndLabel();
- void addSliderFrame(const F32 frame, LLSettingsBase::ptr_t &setting, bool update_ui = true);
- void removeCurrentSliderFrame();
-
- // **RIDER**
- void loadInventoryItem(const LLUUID &inventoryId);
- void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status);
- void loadLiveEnvironment(LLEnvironment::EnvSelection_t env);
-
- void doImportFromDisk();
- void doApplyCreateNewInventory();
- void doApplyUpdateInventory();
- void doApplyEnvironment(const std::string &where);
- void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
- void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
-
- bool canUseInventory() const;
- bool canApplyRegion() const;
- bool canApplyParcel() const;
-
- void updateEditEnvironment();
- void syncronizeTabs();
- void reblendSettings();
-
- void setTabsData(LLTabContainer * tabcontainer, const LLSettingsBase::ptr_t &settings, bool editable);
+ void onFrameSliderCallback(const LLSD &);
+ void onFrameSliderDoubleClick(S32 x, S32 y, MASK mask);
+ void onFrameSliderMouseDown(S32 x, S32 y, MASK mask);
+ void onFrameSliderMouseUp(S32 x, S32 y, MASK mask);
+
+ void selectTrack(U32 track_index, bool force = false);
+ void selectFrame(F32 frame);
+ void clearTabs();
+ void updateTabs();
+ void updateWaterTabs(const LLSettingsWaterPtr_t &p_water);
+ void updateSkyTabs(const LLSettingsSkyPtr_t &p_sky);
+ void setWaterTabsEnabled(BOOL enable);
+ void setSkyTabsEnabled(BOOL enable);
+ void updateButtons();
+ void updateSlider(); //track to slider
+ void updateTimeAndLabel();
+ void addSliderFrame(const F32 frame, LLSettingsBase::ptr_t &setting, bool update_ui = true);
+ void removeCurrentSliderFrame();
+
+ void loadInventoryItem(const LLUUID &inventoryId);
+ void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status);
+ void loadLiveEnvironment(LLEnvironment::EnvSelection_t env);
+
+ void doImportFromDisk();
+ void doApplyCreateNewInventory();
+ void doApplyUpdateInventory();
+ void doApplyEnvironment(const std::string &where);
+ void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+ void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+
+ void doOpenInventoryFloater(LLSettingsType::type_e type);
+ void onPickerCommitSetting(LLUUID asset_id);
+
+ bool canUseInventory() const;
+ bool canApplyRegion() const;
+ bool canApplyParcel() const;
+
+ void updateEditEnvironment();
+ void syncronizeTabs();
+ void reblendSettings();
+
+ void setTabsData(LLTabContainer * tabcontainer, const LLSettingsBase::ptr_t &settings, bool editable);
// play functions
- void startPlay();
- void stopPlay();
- static void onIdlePlay(void *);
+ void startPlay();
+ void stopPlay();
+ static void onIdlePlay(void *);
LLSettingsDay::ptr_t mEditDay; // edited copy
LLSettingsDay::Seconds mDayLength;
@@ -157,6 +158,8 @@ private:
LLInventoryItem * mInventoryItem;
LLFlyoutComboBtnCtrl * mFlyoutControl;
+ LLHandle<LLFloater> mInventoryFloater;
+
LLTrackBlenderLoopingManual::ptr_t mSkyBlender;
LLTrackBlenderLoopingManual::ptr_t mWaterBlender;
LLSettingsSky::ptr_t mScratchSky;
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
index e7b8481caa..0c6127c61f 100644
--- a/indra/newview/llfloaterfixedenvironment.cpp
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -302,16 +302,16 @@ void LLFloaterFixedEnvironment::doApplyEnvironment(const std::string &where)
if (!parcel)
return;
- if (mSettings->getSettingType() == "sky")
+ if (mSettings->getSettingsType() == "sky")
LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsSky>(mSettings), -1, -1);
- else if (mSettings->getSettingType() == "water")
+ else if (mSettings->getSettingsType() == "water")
LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsWater>(mSettings), -1, -1);
}
else if (where == ACTION_APPLY_REGION)
{
- if (mSettings->getSettingType() == "sky")
+ if (mSettings->getSettingsType() == "sky")
LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsSky>(mSettings), -1, -1);
- else if (mSettings->getSettingType() == "water")
+ else if (mSettings->getSettingsType() == "water")
LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsWater>(mSettings), -1, -1);
}
else
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
index dea54cbe57..06a908cccc 100644
--- a/indra/newview/llfolderviewmodelinventory.h
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -49,8 +49,9 @@ public:
virtual bool hasChildren() const = 0;
virtual LLInventoryType::EType getInventoryType() const = 0;
virtual void performAction(LLInventoryModel* model, std::string action) = 0;
- virtual LLWearableType::EType getWearableType() const = 0;
- virtual EInventorySortGroup getSortGroup() const = 0;
+ virtual LLWearableType::EType getWearableType() const = 0;
+ virtual LLSettingsType::type_e getSettingsType() const = 0;
+ virtual EInventorySortGroup getSortGroup() const = 0;
virtual LLInventoryObject* getInventoryObject() const = 0;
virtual void requestSort();
virtual void setPassedFilter(bool filtered, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0);
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index f64c39c3ad..f33df43919 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -53,6 +53,7 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p)
: mFilterObjectTypes(p.object_types),
mFilterCategoryTypes(p.category_types),
mFilterWearableTypes(p.wearable_types),
+ mFilterSettingsTypes(p.settings_types),
mMinDate(p.date_range.min_date),
mMaxDate(p.date_range.max_date),
mHoursAgo(p.hours_ago),
@@ -325,12 +326,26 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent
if (filterTypes & FILTERTYPE_WEARABLE)
{
LLWearableType::EType type = listener->getWearableType();
- if ((0x1LL << type & mFilterOps.mFilterWearableTypes) == 0)
+ if ((object_type == LLInventoryType::IT_WEARABLE) &&
+ (((0x1LL << type) & mFilterOps.mFilterWearableTypes) == 0))
{
return FALSE;
}
}
+ ////////////////////////////////////////////////////////////////////////////////
+ // FILTERTYPE_SETTINGS
+ // Pass if this item is a setting of the appropriate type
+ if (filterTypes & FILTERTYPE_SETTINGS)
+ {
+ LLSettingsType::type_e type = listener->getSettingsType();
+ if ((object_type == LLInventoryType::IT_SETTINGS) &&
+ (((0x1LL << type) & mFilterOps.mFilterSettingsTypes) == 0))
+ {
+ return FALSE;
+ }
+ }
+
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_EMPTYFOLDERS
// Pass if this item is a folder and is not a system folder that should be hidden
@@ -626,6 +641,12 @@ void LLInventoryFilter::setFilterWearableTypes(U64 types)
mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE;
}
+void LLInventoryFilter::setFilterSettingsTypes(U64 types)
+{
+ updateFilterTypes(types, mFilterOps.mFilterSettingsTypes);
+ mFilterOps.mFilterTypes |= FILTERTYPE_SETTINGS;
+}
+
void LLInventoryFilter::setFilterEmptySystemFolders()
{
mFilterOps.mFilterTypes |= FILTERTYPE_EMPTYFOLDERS;
@@ -1241,6 +1262,11 @@ U64 LLInventoryFilter::getFilterWearableTypes() const
return mFilterOps.mFilterWearableTypes;
}
+U64 LLInventoryFilter::getFilterSettingsTypes() const
+{
+ return mFilterOps.mFilterSettingsTypes;
+}
+
bool LLInventoryFilter::hasFilterString() const
{
return mFilterSubString.size() > 0;
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 01754ed023..9fb986f21d 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -47,18 +47,19 @@ public:
enum EFilterType {
FILTERTYPE_NONE = 0,
- FILTERTYPE_OBJECT = 0x1 << 0, // normal default search-by-object-type
- FILTERTYPE_CATEGORY = 0x1 << 1, // search by folder type
- FILTERTYPE_UUID = 0x1 << 2, // find the object with UUID and any links to it
- FILTERTYPE_DATE = 0x1 << 3, // search by date range
- FILTERTYPE_WEARABLE = 0x1 << 4, // search by wearable type
+ FILTERTYPE_OBJECT = 0x1 << 0, // normal default search-by-object-type
+ FILTERTYPE_CATEGORY = 0x1 << 1, // search by folder type
+ FILTERTYPE_UUID = 0x1 << 2, // find the object with UUID and any links to it
+ FILTERTYPE_DATE = 0x1 << 3, // search by date range
+ FILTERTYPE_WEARABLE = 0x1 << 4, // search by wearable type
FILTERTYPE_EMPTYFOLDERS = 0x1 << 5, // pass if folder is not a system folder to be hidden if empty
FILTERTYPE_MARKETPLACE_ACTIVE = 0x1 << 6, // pass if folder is a marketplace active folder
FILTERTYPE_MARKETPLACE_INACTIVE = 0x1 << 7, // pass if folder is a marketplace inactive folder
FILTERTYPE_MARKETPLACE_UNASSOCIATED = 0x1 << 8, // pass if folder is a marketplace non associated (no market ID) folder
FILTERTYPE_MARKETPLACE_LISTING_FOLDER = 0x1 << 9, // pass iff folder is a listing folder
FILTERTYPE_NO_MARKETPLACE_ITEMS = 0x1 << 10, // pass iff folder is not under the marketplace
- FILTERTYPE_WORN = 0x1 << 11, // pass if item is worn
+ FILTERTYPE_WORN = 0x1 << 11, // pass if item is worn
+ FILTERTYPE_SETTINGS = 0x1 << 12, // pass if the item is a settings object
};
enum EFilterDateDirection
@@ -80,7 +81,7 @@ public:
SO_DATE = 0x1, // Sort inventory by date
SO_FOLDERS_BY_NAME = 0x1 << 1, // Force folder sort by name
SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2,// Force system folders to be on top
- SO_FOLDERS_BY_WEIGHT = 0x1 << 3, // Force folder sort by weight, usually, amount of some elements in their descendents
+ SO_FOLDERS_BY_WEIGHT = 0x1 << 3, // Force folder sort by weight, usually, amount of some elements in their descendants
};
enum ESearchType
@@ -118,6 +119,7 @@ public:
Optional<U32> types;
Optional<U64> object_types,
wearable_types,
+ settings_types,
category_types;
Optional<EFilterLink> links;
Optional<LLUUID> uuid;
@@ -131,7 +133,8 @@ public:
: types("filter_types", FILTERTYPE_OBJECT),
object_types("object_types", 0xffffFFFFffffFFFFULL),
wearable_types("wearable_types", 0xffffFFFFffffFFFFULL),
- category_types("category_types", 0xffffFFFFffffFFFFULL),
+ settings_types("settings_types", 0xffffFFFFffffFFFFULL),
+ category_types("category_types", 0xffffFFFFffffFFFFULL),
links("links", FILTERLINK_INCLUDE_LINKS),
uuid("uuid"),
date_range("date_range"),
@@ -145,10 +148,11 @@ public:
FilterOps(const Params& = Params());
U32 mFilterTypes;
- U64 mFilterObjectTypes, // For _OBJECT
- mFilterWearableTypes,
- mFilterLinks,
- mFilterCategoryTypes; // For _CATEGORY
+ U64 mFilterObjectTypes, // For _OBJECT
+ mFilterWearableTypes,
+ mFilterSettingsTypes, // for _SETTINGS
+ mFilterLinks,
+ mFilterCategoryTypes; // For _CATEGORY
LLUUID mFilterUUID; // for UUID
time_t mMinDate,
@@ -186,11 +190,14 @@ public:
U64 getFilterObjectTypes() const;
U64 getFilterCategoryTypes() const;
U64 getFilterWearableTypes() const;
+ U64 getFilterSettingsTypes() const;
+
bool isFilterObjectTypesWith(LLInventoryType::EType t) const;
void setFilterObjectTypes(U64 types);
void setFilterCategoryTypes(U64 types);
void setFilterUUID(const LLUUID &object_id);
void setFilterWearableTypes(U64 types);
+ void setFilterSettingsTypes(U64 types);
void setFilterEmptySystemFolders();
void setFilterWorn();
void setFilterMarketplaceActiveFolders();
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 7e3fa1d334..7ba9f2fc43 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -377,6 +377,11 @@ void LLInventoryPanel::setFilterWearableTypes(U64 types)
getFilter().setFilterWearableTypes(types);
}
+void LLInventoryPanel::setFilterSettingsTypes(U64 filter)
+{
+ getFilter().setFilterSettingsTypes(filter);
+}
+
void LLInventoryPanel::setFilterSubString(const std::string& string)
{
getFilter().setFilterSubString(string);
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 12001f5a2b..79d39c8b82 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -176,8 +176,9 @@ public:
U32 getFilterObjectTypes() const;
void setFilterPermMask(PermissionMask filter_perm_mask);
U32 getFilterPermMask() const;
- void setFilterWearableTypes(U64 filter);
- void setFilterSubString(const std::string& string);
+ void setFilterWearableTypes(U64 filter);
+ void setFilterSettingsTypes(U64 filter);
+ void setFilterSubString(const std::string& string);
const std::string getFilterSubString();
void setSinceLogoff(BOOL sl);
void setHoursAgo(U32 hours);
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index c50f3477ad..f180a63497 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -145,6 +145,7 @@ public:
virtual bool hasChildren() const { return FALSE; }
virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+ virtual LLSettingsType::type_e getSettingsType() const { return LLSettingsType::ST_NONE; }
virtual EInventorySortGroup getSortGroup() const { return SG_ITEM; }
virtual LLInventoryObject* getInventoryObject() const { return findInvObject(); }
@@ -1414,6 +1415,34 @@ void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
///----------------------------------------------------------------------------
+/// Class LLTaskSettingsBridge
+///----------------------------------------------------------------------------
+
+class LLTaskSettingsBridge : public LLTaskInvFVBridge
+{
+public:
+ LLTaskSettingsBridge(LLPanelObjectInventory* panel,
+ const LLUUID& uuid,
+ const std::string& name,
+ U32 flags) :
+ LLTaskInvFVBridge(panel, uuid, name, flags) {}
+
+ virtual LLUIImagePtr getIcon() const;
+ virtual LLSettingsType::type_e getSettingsType() const;
+};
+
+LLUIImagePtr LLTaskSettingsBridge::getIcon() const
+{
+ return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, FALSE);
+}
+
+LLSettingsType::type_e LLTaskSettingsBridge::getSettingsType() const
+{
+ return LLSettingsType::ST_NONE;
+}
+
+
+///----------------------------------------------------------------------------
/// LLTaskInvFVBridge impl
//----------------------------------------------------------------------------
@@ -1499,6 +1528,12 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
object_id,
object_name);
break;
+ case LLAssetType::AT_SETTINGS:
+ new_bridge = new LLTaskSettingsBridge(panel,
+ object_id,
+ object_name,
+ itemflags);
+ break;
default:
LL_INFOS() << "Unhandled inventory type (llassetstorage.h): "
<< (S32)type << LL_ENDL;
diff --git a/indra/newview/llsettingspicker.cpp b/indra/newview/llsettingspicker.cpp
new file mode 100644
index 0000000000..29b08fc3d7
--- /dev/null
+++ b/indra/newview/llsettingspicker.cpp
@@ -0,0 +1,1761 @@
+/**
+* @author Rider Linden
+* @brief LLSettingsPicker class header file including related functions
+*
+* $LicenseInfo:firstyear=2018&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2018, 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 "llsettingspicker.h"
+
+#include "llfiltereditor.h"
+#include "llfolderviewmodel.h"
+#include "llinventory.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llinventoryobserver.h"
+#include "llinventorypanel.h"
+
+#include "llviewercontrol.h"
+#include "llagent.h"
+
+//=========================================================================
+namespace
+{
+ const std::string FLOATER_DEFINITION_XML("floater_settings_picker.xml");
+
+ const std::string FLT_INVENTORY_SEARCH("flt_inventory_search");
+ const std::string PNL_INVENTORY("pnl_inventory");
+ const std::string CHK_SHOWFOLDERS("chk_showfolders");
+ const std::string BTN_SELECT("btn_select");
+ const std::string BTN_CANCEL("btn_cancel");
+
+ const F32 CONTEXT_CONE_IN_ALPHA(0.0f);
+ const F32 CONTEXT_CONE_OUT_ALPHA(1.0f);
+ const F32 CONTEXT_FADE_TIME(0.08f);
+}
+//=========================================================================
+
+LLFloaterSettingsPicker::LLFloaterSettingsPicker(LLView * owner, LLUUID initial_asset_id, const std::string &label, const LLSD &params):
+ LLFloater(params),
+ mOwner(owner),
+ mLabel(label),
+ mActive(true),
+ mContextConeOpacity(0.0f),
+ mSettingAssetID(initial_asset_id)
+{
+ buildFromFile(FLOATER_DEFINITION_XML);
+ setCanMinimize(FALSE);
+}
+
+
+LLFloaterSettingsPicker::~LLFloaterSettingsPicker()
+{
+
+}
+
+//-------------------------------------------------------------------------
+BOOL LLFloaterSettingsPicker::postBuild()
+{
+ if (!LLFloater::postBuild())
+ return FALSE;
+
+ if (!mLabel.empty())
+ {
+ std::string pick = getString("pick title");
+
+ setTitle(pick + mLabel);
+ }
+
+// childSetCommitCallback(CHK_SHOWFOLDERS, onShowFolders, this);
+ getChildView(CHK_SHOWFOLDERS)->setVisible(FALSE);
+
+ mFilterEdit = getChild<LLFilterEditor>(FLT_INVENTORY_SEARCH);
+ mFilterEdit->setCommitCallback([this](LLUICtrl*, const LLSD& param){ onFilterEdit(param.asString()); });
+
+ mInventoryPanel = getChild<LLInventoryPanel>(PNL_INVENTORY);
+ if (mInventoryPanel)
+ {
+ U32 filter_types = 0x0;
+ filter_types |= 0x1 << LLInventoryType::IT_SETTINGS;
+
+ mInventoryPanel->setFilterTypes(filter_types);
+ mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
+
+ mInventoryPanel->setSelectCallback([this](const LLFloaterSettingsPicker::itemlist_t &items, bool useraction){ onSelectionChange(items, useraction); });
+ mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+
+ // Disable auto selecting first filtered item because it takes away
+ // selection from the item set by LLTextureCtrl owning this floater.
+ mInventoryPanel->getRootFolder()->setAutoSelectOverride(TRUE);
+
+ // don't put keyboard focus on selected item, because the selection callback
+ // will assume that this was user input
+ if (!mSettingAssetID.isNull())
+ {
+ mInventoryPanel->setSelection(findItemID(mSettingAssetID, false), TAKE_FOCUS_NO);
+ }
+ }
+
+ mNoCopySettingsSelected = FALSE;
+
+ childSetAction(BTN_CANCEL, [this](LLUICtrl*, const LLSD& param){ onButtonCancel(); });
+ childSetAction(BTN_SELECT, [this](LLUICtrl*, const LLSD& param){ onButtonSelect(); });
+
+ // update permission filter once UI is fully initialized
+ mSavedFolderState.setApply(FALSE);
+
+ return TRUE;
+}
+
+void LLFloaterSettingsPicker::onClose(bool app_quitting)
+{
+ mCloseSignal();
+ if (mOwner)
+ {
+ mOwner->setFocus(TRUE);
+ }
+}
+
+void LLFloaterSettingsPicker::setValue(const LLSD& value)
+{
+ mSettingAssetID = value.asUUID();
+}
+
+LLSD LLFloaterSettingsPicker::getValue() const
+{
+ return LLSD(mSettingAssetID);
+}
+
+void LLFloaterSettingsPicker::setSettingsFilter(LLSettingsType::type_e type)
+{
+ U64 filter = 0xFFFFFFFFFFFFFFFF;
+ if (type != LLSettingsType::ST_NONE)
+ {
+ filter = static_cast<S64>(0x1) << static_cast<S64>(type);
+ }
+
+ mInventoryPanel->setFilterSettingsTypes(filter);
+}
+
+void LLFloaterSettingsPicker::draw()
+{
+ if (mOwner)
+ {
+ // draw cone of context pointing back to texture swatch
+ LLRect owner_rect;
+ mOwner->localRectToOtherView(mOwner->getLocalRect(), &owner_rect, this);
+ LLRect local_rect = getLocalRect();
+ if (gFocusMgr.childHasKeyboardFocus(this) && mOwner->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, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+ gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
+ gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
+ gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * 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, CONTEXT_CONE_OUT_ALPHA * 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, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+ gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
+ gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
+
+ gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * 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, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+ gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
+ gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
+
+
+ gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * 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, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+ gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
+ gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
+ }
+ gGL.end();
+ }
+ }
+
+// if (gFocusMgr.childHasMouseCapture(getDragHandle()))
+// {
+// mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME));
+// }
+// else
+// {
+ mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME));
+// }
+
+ LLFloater::draw();
+}
+
+//=========================================================================
+void LLFloaterSettingsPicker::onFilterEdit(const std::string& search_string)
+{
+ std::string upper_case_search_string = search_string;
+ LLStringUtil::toUpper(upper_case_search_string);
+
+ if (upper_case_search_string.empty())
+ {
+ if (mInventoryPanel->getFilterSubString().empty())
+ {
+ // current filter and new filter empty, do nothing
+ return;
+ }
+
+ mSavedFolderState.setApply(TRUE);
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
+ // add folder with current item to list of previously opened folders
+ LLOpenFoldersWithSelection opener;
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
+ mInventoryPanel->getRootFolder()->scrollToShowSelection();
+
+ }
+ else if (mInventoryPanel->getFilterSubString().empty())
+ {
+ // first letter in search term, save existing folder open state
+ if (!mInventoryPanel->getFilter().isNotDefault())
+ {
+ mSavedFolderState.setApply(FALSE);
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
+ }
+ }
+
+ mInventoryPanel->setFilterSubString(search_string);
+}
+
+void LLFloaterSettingsPicker::onSelectionChange(const LLFloaterSettingsPicker::itemlist_t &items, bool user_action)
+{
+ if (items.size())
+ {
+ LLFolderViewItem* first_item = items.front();
+ LLInventoryItem* itemp = gInventory.getItem(static_cast<LLFolderViewModelItemInventory*>(first_item->getViewModelItem())->getUUID());
+ mNoCopySettingsSelected = false;
+ if (itemp)
+ {
+// if (!mChangeIDSignal.empty())
+// {
+// mChangeIDSignal(itemp);
+// }
+ if (!itemp->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ mNoCopySettingsSelected = true;
+ }
+ setSettingsID(itemp->getAssetUUID(), false);
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+
+ if (user_action)
+ {
+ mChangeIDSignal(mSettingAssetID);
+ }
+ }
+ }
+}
+
+void LLFloaterSettingsPicker::onButtonCancel()
+{
+ closeFloater();
+}
+
+void LLFloaterSettingsPicker::onButtonSelect()
+{
+ if (mCommitSignal)
+ (*mCommitSignal)(this, LLSD(mSettingAssetID));
+ closeFloater();
+}
+
+//=========================================================================
+void LLFloaterSettingsPicker::setActive(bool active)
+{
+ mActive = active;
+}
+
+void LLFloaterSettingsPicker::setSettingsID(const LLUUID &settings_id, bool set_selection)
+{
+ if (mSettingAssetID != settings_id && mActive)
+ {
+ mNoCopySettingsSelected = false;
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+ mSettingAssetID = settings_id;
+ LLUUID item_id = findItemID(mSettingAssetID, FALSE);
+ if (item_id.isNull())
+ {
+ mInventoryPanel->getRootFolder()->clearSelection();
+ }
+ else
+ {
+ LLInventoryItem* itemp = gInventory.getItem(settings_id);
+ if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ mNoCopySettingsSelected = true;
+ }
+ }
+
+ if (set_selection)
+ {
+ mInventoryPanel->setSelection(settings_id, TAKE_FOCUS_NO);
+ }
+ }
+}
+
+LLUUID LLFloaterSettingsPicker::findItemID(const LLUUID& asset_id, bool copyable_only, bool ignore_library)
+{
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLAssetIDMatches asset_id_matches(asset_id);
+
+ gInventory.collectDescendentsIf(LLUUID::null,
+ cats,
+ items,
+ LLInventoryModel::INCLUDE_TRASH,
+ asset_id_matches);
+
+ if (items.size())
+ {
+ // search for copyable version first
+ for (S32 i = 0; i < items.size(); i++)
+ {
+ LLInventoryItem* itemp = items[i];
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowCopyBy(gAgent.getID(), gAgent.getGroupID()))
+ {
+ if(!ignore_library || !gInventory.isObjectDescendentOf(itemp->getUUID(),gInventory.getLibraryRootFolderID()))
+ {
+ return itemp->getUUID();
+ }
+ }
+ }
+ // otherwise just return first instance, unless copyable requested
+ if (copyable_only)
+ {
+ return LLUUID::null;
+ }
+ else
+ {
+ if(!ignore_library || !gInventory.isObjectDescendentOf(items[0]->getUUID(),gInventory.getLibraryRootFolderID()))
+ {
+ return items[0]->getUUID();
+ }
+ }
+ }
+
+ return LLUUID::null;
+}
+
+
+#if 0
+#include "llrender.h"
+#include "llagent.h"
+#include "llviewertexturelist.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llbutton.h"
+#include "lldraghandle.h"
+#include "llfocusmgr.h"
+#include "llfolderviewmodel.h"
+#include "llinventory.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llinventoryobserver.h"
+#include "llinventorypanel.h"
+#include "lllineeditor.h"
+#include "llui.h"
+#include "llviewerinventory.h"
+#include "llpermissions.h"
+#include "llsaleinfo.h"
+#include "llassetstorage.h"
+#include "lltextbox.h"
+#include "llresizehandle.h"
+#include "llscrollcontainer.h"
+#include "lltoolmgr.h"
+#include "lltoolpipette.h"
+#include "llwindow.h"
+
+#include "lltool.h"
+#include "llviewerwindow.h"
+#include "llviewerobject.h"
+#include "llviewercontrol.h"
+#include "llglheaders.h"
+#include "lluictrlfactory.h"
+#include "lltrans.h"
+
+#include "llradiogroup.h"
+#include "llfloaterreg.h"
+#include "lllocalbitmaps.h"
+#include "llerror.h"
+
+static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
+static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
+static const F32 CONTEXT_FADE_TIME = 0.08f;
+
+static const S32 LOCAL_TRACKING_ID_COLUMN = 1;
+
+//static const char CURRENT_IMAGE_NAME[] = "Current Texture";
+//static const char WHITE_IMAGE_NAME[] = "Blank Texture";
+//static const char NO_IMAGE_NAME[] = "None";
+
+LLFloaterTexturePicker::LLFloaterTexturePicker(
+ LLView* owner,
+ LLUUID image_asset_id,
+ LLUUID default_image_asset_id,
+ LLUUID blank_image_asset_id,
+ BOOL tentative,
+ BOOL allow_no_texture,
+ const std::string& label,
+ PermissionMask immediate_filter_perm_mask,
+ PermissionMask dnd_filter_perm_mask,
+ PermissionMask non_immediate_filter_perm_mask,
+ BOOL can_apply_immediately,
+ LLUIImagePtr fallback_image)
+: LLFloater(LLSD()),
+ mOwner( owner ),
+ mImageAssetID( image_asset_id ),
+ mOriginalImageAssetID(image_asset_id),
+ mFallbackImage(fallback_image),
+ mDefaultImageAssetID(default_image_asset_id),
+ mBlankImageAssetID(blank_image_asset_id),
+ mTentative(tentative),
+ mAllowNoTexture(allow_no_texture),
+ mLabel(label),
+ mTentativeLabel(NULL),
+ mResolutionLabel(NULL),
+ mActive( TRUE ),
+ mFilterEdit(NULL),
+ mImmediateFilterPermMask(immediate_filter_perm_mask),
+ mDnDFilterPermMask(dnd_filter_perm_mask),
+ mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
+ mContextConeOpacity(0.f),
+ mSelectedItemPinned( FALSE ),
+ mCanApply(true),
+ mCanPreview(true),
+ mPreviewSettingChanged(false),
+ mOnFloaterCommitCallback(NULL),
+ mOnFloaterCloseCallback(NULL),
+ mSetImageAssetIDCallback(NULL),
+ mOnUpdateImageStatsCallback(NULL)
+{
+ buildFromFile("floater_texture_ctrl.xml");
+ mCanApplyImmediately = can_apply_immediately;
+ setCanMinimize(FALSE);
+}
+
+LLFloaterTexturePicker::~LLFloaterTexturePicker()
+{
+}
+
+void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b)
+{
+ mCanApplyImmediately = b;
+ if (!mCanApplyImmediately)
+ {
+ getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE);
+ }
+ updateFilterPermMask();
+}
+
+void LLFloaterTexturePicker::stopUsingPipette()
+{
+ if (LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance())
+ {
+ LLToolMgr::getInstance()->clearTransientTool();
+ }
+}
+
+void LLFloaterTexturePicker::updateImageStats()
+{
+ if (mTexturep.notNull())
+ {
+ //RN: have we received header data for this image?
+ if (mTexturep->getFullWidth() > 0 && mTexturep->getFullHeight() > 0)
+ {
+ std::string formatted_dims = llformat("%d x %d", mTexturep->getFullWidth(),mTexturep->getFullHeight());
+ mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims);
+ if (mOnUpdateImageStatsCallback)
+ {
+ mOnUpdateImageStatsCallback(mTexturep);
+ }
+ }
+ else
+ {
+ mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("[? x ?]"));
+ }
+ }
+ else
+ {
+ mResolutionLabel->setTextArg("[DIMENSIONS]", std::string(""));
+ }
+}
+
+// virtual
+BOOL LLFloaterTexturePicker::handleDragAndDrop(
+ S32 x, S32 y, MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type, void *cargo_data,
+ EAcceptance *accept,
+ std::string& tooltip_msg)
+{
+ BOOL handled = FALSE;
+
+ bool is_mesh = cargo_type == DAD_MESH;
+
+ if ((cargo_type == DAD_TEXTURE) || is_mesh)
+ {
+ LLInventoryItem *item = (LLInventoryItem *)cargo_data;
+
+ BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
+ BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
+ BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
+ gAgent.getID());
+
+ PermissionMask item_perm_mask = 0;
+ if (copy) item_perm_mask |= PERM_COPY;
+ if (mod) item_perm_mask |= PERM_MODIFY;
+ if (xfer) item_perm_mask |= PERM_TRANSFER;
+
+ //PermissionMask filter_perm_mask = getFilterPermMask(); Commented out due to no-copy texture loss.
+ PermissionMask filter_perm_mask = mDnDFilterPermMask;
+ if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
+ {
+ if (drop)
+ {
+ setImageID( item->getAssetUUID() );
+ commitIfImmediateSet();
+ }
+
+ *accept = ACCEPT_YES_SINGLE;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+
+ handled = TRUE;
+ LL_DEBUGS("UserInput") << "dragAndDrop handled by LLFloaterTexturePicker " << getName() << LL_ENDL;
+
+ return handled;
+}
+
+BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
+{
+ LLFolderView* root_folder = mInventoryPanel->getRootFolder();
+
+ if (root_folder && mFilterEdit)
+ {
+ if (mFilterEdit->hasFocus()
+ && (key == KEY_RETURN || key == KEY_DOWN)
+ && mask == MASK_NONE)
+ {
+ if (!root_folder->getCurSelectedItem())
+ {
+ LLFolderViewItem* itemp = mInventoryPanel->getItemByID(gInventory.getRootFolderID());
+ if (itemp)
+ {
+ root_folder->setSelection(itemp, FALSE, FALSE);
+ }
+ }
+ root_folder->scrollToShowSelection();
+
+ // move focus to inventory proper
+ mInventoryPanel->setFocus(TRUE);
+
+ // treat this as a user selection of the first filtered result
+ commitIfImmediateSet();
+
+ return TRUE;
+ }
+
+ if (mInventoryPanel->hasFocus() && key == KEY_UP)
+ {
+ mFilterEdit->focusFirstItem(TRUE);
+ }
+ }
+
+ return LLFloater::handleKeyHere(key, mask);
+}
+
+void LLFloaterTexturePicker::onClose(bool app_quitting)
+{
+ if (mOwner && mOnFloaterCloseCallback)
+ {
+ mOnFloaterCloseCallback();
+ }
+ stopUsingPipette();
+}
+
+// virtual
+BOOL LLFloaterTexturePicker::postBuild()
+{
+ LLFloater::postBuild();
+
+ if (!mLabel.empty())
+ {
+ std::string pick = getString("pick title");
+
+ setTitle(pick + mLabel);
+ }
+ mTentativeLabel = getChild<LLTextBox>("Multiple");
+
+ mResolutionLabel = getChild<LLTextBox>("unknown");
+
+
+ childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this);
+ childSetAction("None", LLFloaterTexturePicker::onBtnNone,this);
+ childSetAction("Blank", LLFloaterTexturePicker::onBtnBlank,this);
+
+
+ childSetCommitCallback("show_folders_check", onShowFolders, this);
+ getChildView("show_folders_check")->setVisible( FALSE);
+
+ mFilterEdit = getChild<LLFilterEditor>("inventory search editor");
+ mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2));
+
+ mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
+
+ if(mInventoryPanel)
+ {
+ U32 filter_types = 0x0;
+ filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
+ filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
+
+ mInventoryPanel->setFilterTypes(filter_types);
+ //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss.
+ mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
+ mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));
+ mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+
+ // Disable auto selecting first filtered item because it takes away
+ // selection from the item set by LLTextureCtrl owning this floater.
+ mInventoryPanel->getRootFolder()->setAutoSelectOverride(TRUE);
+
+ // Commented out to scroll to currently selected texture. See EXT-5403.
+ // // store this filter as the default one
+ // mInventoryPanel->getRootFolder()->getFilter().markDefault();
+
+ // Commented out to stop opening all folders with textures
+ // mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_TEXTURE);
+
+ // don't put keyboard focus on selected item, because the selection callback
+ // will assume that this was user input
+ if(!mImageAssetID.isNull())
+ {
+ mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
+ }
+ }
+
+ mModeSelector = getChild<LLRadioGroup>("mode_selection");
+ mModeSelector->setCommitCallback(onModeSelect, this);
+ mModeSelector->setSelectedIndex(0, 0);
+
+ childSetAction("l_add_btn", LLFloaterTexturePicker::onBtnAdd, this);
+ childSetAction("l_rem_btn", LLFloaterTexturePicker::onBtnRemove, this);
+ childSetAction("l_upl_btn", LLFloaterTexturePicker::onBtnUpload, this);
+
+ mLocalScrollCtrl = getChild<LLScrollListCtrl>("l_name_list");
+ mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit, this);
+ LLLocalBitmapMgr::feedScrollList(mLocalScrollCtrl);
+
+ mNoCopyTextureSelected = FALSE;
+
+ getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview"));
+ childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
+
+ if (!mCanApplyImmediately)
+ {
+ getChildView("show_folders_check")->setEnabled(FALSE);
+ }
+
+ getChild<LLUICtrl>("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this));
+ childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this);
+ childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this);
+
+ // update permission filter once UI is fully initialized
+ updateFilterPermMask();
+ mSavedFolderState.setApply(FALSE);
+
+ LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1));
+
+ return TRUE;
+}
+
+// virtual
+void LLFloaterTexturePicker::draw()
+{
+ if (mOwner)
+ {
+ // draw cone of context pointing back to texture swatch
+ LLRect owner_rect;
+ mOwner->localRectToOtherView(mOwner->getLocalRect(), &owner_rect, this);
+ LLRect local_rect = getLocalRect();
+ if (gFocusMgr.childHasKeyboardFocus(this) && mOwner->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, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+ gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
+ gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
+ gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * 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, CONTEXT_CONE_OUT_ALPHA * 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, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+ gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
+ gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
+
+ gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * 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, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+ gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
+ gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
+
+
+ gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * 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, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+ gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
+ gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
+ }
+ gGL.end();
+ }
+ }
+
+ if (gFocusMgr.childHasMouseCapture(getDragHandle()))
+ {
+ mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME));
+ }
+ else
+ {
+ mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME));
+ }
+
+ updateImageStats();
+
+ // if we're inactive, gray out "apply immediate" checkbox
+ getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected);
+ getChildView("Select")->setEnabled(mActive && mCanApply);
+ getChildView("Pipette")->setEnabled(mActive);
+ getChild<LLUICtrl>("Pipette")->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
+
+ //BOOL allow_copy = FALSE;
+ if( mOwner )
+ {
+ mTexturep = NULL;
+ if(mImageAssetID.notNull())
+ {
+ mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID);
+ mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ }
+
+ if (mTentativeLabel)
+ {
+ mTentativeLabel->setVisible( FALSE );
+ }
+
+ getChildView("Default")->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative);
+ getChildView("Blank")->setEnabled(mImageAssetID != mBlankImageAssetID || mTentative);
+ getChildView("None")->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative));
+
+ LLFloater::draw();
+
+ if( isMinimized() )
+ {
+ return;
+ }
+
+ // Border
+ LLRect border = getChildView("preview_widget")->getRect();
+ gl_rect_2d( border, LLColor4::black, FALSE );
+
+
+ // Interior
+ LLRect interior = border;
+ interior.stretch( -1 );
+
+ // If the floater is focused, don't apply its alpha to the texture (STORM-677).
+ const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
+ if( mTexturep )
+ {
+ if( mTexturep->getComponents() == 4 )
+ {
+ gl_rect_2d_checkerboard( interior, alpha );
+ }
+
+ gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha );
+
+ // Pump the priority
+ mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
+ }
+ else if (!mFallbackImage.isNull())
+ {
+ mFallbackImage->draw(interior, UI_VERTEX_COLOR % alpha);
+ }
+ else
+ {
+ gl_rect_2d( interior, LLColor4::grey % alpha, TRUE );
+
+ // Draw X
+ gl_draw_x(interior, LLColor4::black );
+ }
+
+ // Draw Tentative Label over the image
+ if( mTentative && !mViewModel->isDirty() )
+ {
+ mTentativeLabel->setVisible( TRUE );
+ drawChild(mTentativeLabel);
+ }
+
+ if (mSelectedItemPinned) return;
+
+ LLFolderView* folder_view = mInventoryPanel->getRootFolder();
+ if (!folder_view) return;
+
+ LLFolderViewFilter& filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter();
+
+ bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter.getCurrentGeneration() &&
+ filter.isNotDefault();
+
+ // After inventory panel filter is applied we have to update
+ // constraint rect for the selected item because of folder view
+ // AutoSelectOverride set to TRUE. We force PinningSelectedItem
+ // flag to FALSE state and setting filter "dirty" to update
+ // scroll container to show selected item (see LLFolderView::doIdle()).
+ if (!is_filter_active && !mSelectedItemPinned)
+ {
+ folder_view->setPinningSelectedItem(mSelectedItemPinned);
+ folder_view->getViewModelItem()->dirtyFilter();
+ mSelectedItemPinned = TRUE;
+ }
+ }
+}
+
+PermissionMask LLFloaterTexturePicker::getFilterPermMask()
+{
+ bool apply_immediate = getChild<LLUICtrl>("apply_immediate_check")->getValue().asBoolean();
+ return apply_immediate ? mImmediateFilterPermMask : mNonImmediateFilterPermMask;
+}
+
+void LLFloaterTexturePicker::commitCancel()
+{
+ if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply)
+ {
+ mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, LLUUID::null);
+ }
+}
+
+// static
+void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
+{
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setCanApply(true, true);
+ if (self->mOwner)
+ {
+ self->setImageID( self->getDefaultImageAssetID() );
+ }
+ self->commitIfImmediateSet();
+}
+
+// static
+void LLFloaterTexturePicker::onBtnBlank(void* userdata)
+{
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setCanApply(true, true);
+ self->setImageID( self->getBlankImageAssetID() );
+ self->commitIfImmediateSet();
+}
+
+
+// static
+void LLFloaterTexturePicker::onBtnNone(void* userdata)
+{
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setImageID( LLUUID::null );
+ self->commitCancel();
+}
+
+/*
+// static
+void LLFloaterTexturePicker::onBtnRevert(void* userdata)
+{
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setImageID( self->mOriginalImageAssetID );
+ // TODO: Change this to tell the owner to cancel. It needs to be
+ // smart enough to restore multi-texture selections.
+ self->mOwner->onFloaterCommit();
+ self->mViewModel->resetDirty();
+}*/
+
+// static
+void LLFloaterTexturePicker::onBtnCancel(void* userdata)
+{
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setImageID( self->mOriginalImageAssetID );
+ if (self->mOnFloaterCommitCallback)
+ {
+ self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, LLUUID::null);
+ }
+ self->mViewModel->resetDirty();
+ self->closeFloater();
+}
+
+// static
+void LLFloaterTexturePicker::onBtnSelect(void* userdata)
+{
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ LLUUID local_id = LLUUID::null;
+ if (self->mOwner)
+ {
+ if (self->mLocalScrollCtrl->getVisible() && !self->mLocalScrollCtrl->getAllSelected().empty())
+ {
+ LLUUID temp_id = self->mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID();
+ local_id = LLLocalBitmapMgr::getWorldID(temp_id);
+ }
+ }
+ if (self->mOnFloaterCommitCallback)
+ {
+ self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_SELECT, local_id);
+ }
+ self->closeFloater();
+}
+
+void LLFloaterTexturePicker::onBtnPipette()
+{
+ BOOL pipette_active = getChild<LLUICtrl>("Pipette")->getValue().asBoolean();
+ pipette_active = !pipette_active;
+ if (pipette_active)
+ {
+ LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance());
+ }
+ else
+ {
+ LLToolMgr::getInstance()->clearTransientTool();
+ }
+}
+
+// static
+void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata)
+{
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ bool mode = (self->mModeSelector->getSelectedIndex() == 0);
+
+ self->getChild<LLButton>("Default")->setVisible(mode);
+ self->getChild<LLButton>("Blank")->setVisible(mode);
+ self->getChild<LLButton>("None")->setVisible(mode);
+ self->getChild<LLButton>("Pipette")->setVisible(mode);
+ self->getChild<LLFilterEditor>("inventory search editor")->setVisible(mode);
+ self->getChild<LLInventoryPanel>("inventory panel")->setVisible(mode);
+
+ /*self->getChild<LLCheckBox>("show_folders_check")->setVisible(mode);
+ no idea under which conditions the above is even shown, needs testing. */
+
+ self->getChild<LLButton>("l_add_btn")->setVisible(!mode);
+ self->getChild<LLButton>("l_rem_btn")->setVisible(!mode);
+ self->getChild<LLButton>("l_upl_btn")->setVisible(!mode);
+ self->getChild<LLScrollListCtrl>("l_name_list")->setVisible(!mode);
+}
+
+// static
+void LLFloaterTexturePicker::onBtnAdd(void* userdata)
+{
+ if (LLLocalBitmapMgr::addUnit() == true)
+ {
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ LLLocalBitmapMgr::feedScrollList(self->mLocalScrollCtrl);
+ }
+}
+
+// static
+void LLFloaterTexturePicker::onBtnRemove(void* userdata)
+{
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected();
+
+ if (!selected_items.empty())
+ {
+ for(std::vector<LLScrollListItem*>::iterator iter = selected_items.begin();
+ iter != selected_items.end(); iter++)
+ {
+ LLScrollListItem* list_item = *iter;
+ if (list_item)
+ {
+ LLUUID tracking_id = list_item->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID();
+ LLLocalBitmapMgr::delUnit(tracking_id);
+ }
+ }
+
+ self->getChild<LLButton>("l_rem_btn")->setEnabled(false);
+ self->getChild<LLButton>("l_upl_btn")->setEnabled(false);
+ LLLocalBitmapMgr::feedScrollList(self->mLocalScrollCtrl);
+ }
+
+}
+
+// static
+void LLFloaterTexturePicker::onBtnUpload(void* userdata)
+{
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected();
+
+ if (selected_items.empty())
+ {
+ return;
+ }
+
+ /* currently only allows uploading one by one, picks the first item from the selection list. (not the vector!)
+ in the future, it might be a good idea to check the vector size and if more than one units is selected - opt for multi-image upload. */
+
+ LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN);
+ std::string filename = LLLocalBitmapMgr::getFilename(tracking_id);
+
+ if (!filename.empty())
+ {
+ LLFloaterReg::showInstance("upload_image", LLSD(filename));
+ }
+
+}
+
+//static
+void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
+{
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected();
+ bool has_selection = !selected_items.empty();
+
+ self->getChild<LLButton>("l_rem_btn")->setEnabled(has_selection);
+ self->getChild<LLButton>("l_upl_btn")->setEnabled(has_selection && (selected_items.size() < 2));
+ /* since multiple-localbitmap upload is not implemented, upl button gets disabled if more than one is selected. */
+
+ if (has_selection)
+ {
+ LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN);
+ LLUUID inworld_id = LLLocalBitmapMgr::getWorldID(tracking_id);
+ if (self->mSetImageAssetIDCallback)
+ {
+ self->mSetImageAssetIDCallback(inworld_id);
+ }
+
+ if (self->childGetValue("apply_immediate_check").asBoolean())
+ {
+ if (self->mOnFloaterCommitCallback)
+ {
+ self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, inworld_id);
+ }
+ }
+ }
+}
+
+// static
+void LLFloaterTexturePicker::onShowFolders(LLUICtrl* ctrl, void *user_data)
+{
+ LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
+ LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
+
+ if (check_box->get())
+ {
+ picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ }
+ else
+ {
+ picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NO_FOLDERS);
+ }
+}
+
+// static
+void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_data)
+{
+ LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
+
+ LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
+ gSavedSettings.setBOOL("TextureLivePreview", check_box->get());
+
+ picker->updateFilterPermMask();
+ picker->commitIfImmediateSet();
+}
+
+void LLFloaterTexturePicker::updateFilterPermMask()
+{
+ //mInventoryPanel->setFilterPermMask( getFilterPermMask() ); Commented out due to no-copy texture loss.
+}
+
+void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply)
+{
+ getChildRef<LLUICtrl>("Select").setEnabled(can_apply);
+ getChildRef<LLUICtrl>("preview_disabled").setVisible(!can_preview);
+ getChildRef<LLUICtrl>("apply_immediate_check").setVisible(can_preview);
+
+ mCanApply = can_apply;
+ mCanPreview = can_preview ? gSavedSettings.getBOOL("TextureLivePreview") : false;
+ mPreviewSettingChanged = true;
+}
+
+void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled)
+{
+ mModeSelector->setIndexEnabled(1,enabled);
+}
+
+void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te )
+{
+ LLUUID inventory_item_id = findItemID(te.getID(), TRUE);
+ if (inventory_item_id.notNull())
+ {
+ LLToolPipette::getInstance()->setResult(TRUE, "");
+ setImageID(te.getID());
+
+ mNoCopyTextureSelected = FALSE;
+ LLInventoryItem* itemp = gInventory.getItem(inventory_item_id);
+
+ if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ // no copy texture
+ mNoCopyTextureSelected = TRUE;
+ }
+
+ commitIfImmediateSet();
+ }
+ else
+ {
+ LLToolPipette::getInstance()->setResult(FALSE, LLTrans::getString("InventoryNoTexture"));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+// LLTextureCtrl
+
+static LLDefaultChildRegistry::Register<LLTextureCtrl> r("texture_picker");
+
+LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
+: LLUICtrl(p),
+ mDragCallback(NULL),
+ mDropCallback(NULL),
+ mOnCancelCallback(NULL),
+ mOnCloseCallback(NULL),
+ mOnSelectCallback(NULL),
+ mBorderColor( p.border_color() ),
+ mAllowNoTexture( FALSE ),
+ mImmediateFilterPermMask( PERM_NONE ),
+ mNonImmediateFilterPermMask( PERM_NONE ),
+ mCanApplyImmediately( FALSE ),
+ mNeedsRawImageData( FALSE ),
+ mValid( TRUE ),
+ mShowLoadingPlaceholder( TRUE ),
+ mImageAssetID(p.image_id),
+ mDefaultImageAssetID(p.default_image_id),
+ mDefaultImageName(p.default_image_name),
+ mFallbackImage(p.fallback_image)
+{
+
+ // Default of defaults is white image for diff tex
+ //
+ LLUUID whiteImage( gSavedSettings.getString( "UIImgWhiteUUID" ) );
+ setBlankImageAssetID( whiteImage );
+
+ setAllowNoTexture(p.allow_no_texture);
+ setCanApplyImmediately(p.can_apply_immediately);
+ mCommitOnSelection = !p.no_commit_on_selection;
+
+ LLTextBox::Params params(p.caption_text);
+ params.name(p.label);
+ params.rect(LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ));
+ params.initial_value(p.label());
+ params.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
+ mCaption = LLUICtrlFactory::create<LLTextBox> (params);
+ addChild( mCaption );
+
+ S32 image_top = getRect().getHeight();
+ S32 image_bottom = BTN_HEIGHT_SMALL;
+ S32 image_middle = (image_top + image_bottom) / 2;
+ S32 line_height = LLFontGL::getFontSansSerifSmall()->getLineHeight();
+
+ LLTextBox::Params tentative_label_p(p.multiselect_text);
+ tentative_label_p.name("Multiple");
+ tentative_label_p.rect(LLRect (0, image_middle + line_height / 2, getRect().getWidth(), image_middle - line_height / 2 ));
+ tentative_label_p.follows.flags(FOLLOWS_ALL);
+ mTentativeLabel = LLUICtrlFactory::create<LLTextBox> (tentative_label_p);
+
+ // It is no longer possible to associate a style with a textbox, so it has to be done in this fashion
+ LLStyle::Params style_params;
+ style_params.color = LLColor4::white;
+
+ mTentativeLabel->setText(LLTrans::getString("multiple_textures"), style_params);
+ mTentativeLabel->setHAlign(LLFontGL::HCENTER);
+ addChild( mTentativeLabel );
+
+ LLRect border_rect = getLocalRect();
+ border_rect.mBottom += BTN_HEIGHT_SMALL;
+ LLViewBorder::Params vbparams(p.border);
+ vbparams.name("border");
+ vbparams.rect(border_rect);
+ mBorder = LLUICtrlFactory::create<LLViewBorder> (vbparams);
+ addChild(mBorder);
+
+ mLoadingPlaceholderString = LLTrans::getString("texture_loading");
+}
+
+LLTextureCtrl::~LLTextureCtrl()
+{
+ closeDependentFloater();
+}
+
+void LLTextureCtrl::setShowLoadingPlaceholder(BOOL showLoadingPlaceholder)
+{
+ mShowLoadingPlaceholder = showLoadingPlaceholder;
+}
+
+void LLTextureCtrl::setCaption(const std::string& caption)
+{
+ mCaption->setText( caption );
+}
+
+void LLTextureCtrl::setCanApplyImmediately(BOOL b)
+{
+ mCanApplyImmediately = b;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if( floaterp )
+ {
+ floaterp->setCanApplyImmediately(b);
+ }
+}
+
+void LLTextureCtrl::setCanApply(bool can_preview, bool can_apply)
+{
+ LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get());
+ if( floaterp )
+ {
+ floaterp->setCanApply(can_preview, can_apply);
+ }
+}
+
+void LLTextureCtrl::setVisible( BOOL visible )
+{
+ if( !visible )
+ {
+ closeDependentFloater();
+ }
+ LLUICtrl::setVisible( visible );
+}
+
+void LLTextureCtrl::setEnabled( BOOL enabled )
+{
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if( enabled )
+ {
+ std::string tooltip;
+ if (floaterp) tooltip = floaterp->getString("choose_picture");
+ setToolTip( tooltip );
+ }
+ else
+ {
+ setToolTip( std::string() );
+ // *TODO: would be better to keep floater open and show
+ // disabled state.
+ closeDependentFloater();
+ }
+
+ if( floaterp )
+ {
+ floaterp->setActive(enabled);
+ }
+
+ mCaption->setEnabled( enabled );
+
+ LLView::setEnabled( enabled );
+}
+
+void LLTextureCtrl::setValid(BOOL valid )
+{
+ mValid = valid;
+ if (!valid)
+ {
+ LLFloaterTexturePicker* pickerp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if (pickerp)
+ {
+ pickerp->setActive(FALSE);
+ }
+ }
+}
+
+
+// virtual
+void LLTextureCtrl::clear()
+{
+ setImageAssetID(LLUUID::null);
+}
+
+void LLTextureCtrl::setLabel(const std::string& label)
+{
+ mLabel = label;
+ mCaption->setText(label);
+}
+
+void LLTextureCtrl::showPicker(BOOL take_focus)
+{
+ // show hourglass cursor when loading inventory window
+ // because inventory construction is slooow
+ getWindow()->setCursor(UI_CURSOR_WAIT);
+ LLFloater* floaterp = mFloaterHandle.get();
+
+ // Show the dialog
+ if( floaterp )
+ {
+ floaterp->openFloater();
+ }
+ else
+ {
+ floaterp = new LLFloaterTexturePicker(
+ this,
+ getImageAssetID(),
+ getDefaultImageAssetID(),
+ getBlankImageAssetID(),
+ getTentative(),
+ getAllowNoTexture(),
+ mLabel,
+ mImmediateFilterPermMask,
+ mDnDFilterPermMask,
+ mNonImmediateFilterPermMask,
+ mCanApplyImmediately,
+ mFallbackImage);
+ mFloaterHandle = floaterp->getHandle();
+
+ LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
+ if (texture_floaterp && mOnTextureSelectedCallback)
+ {
+ texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback);
+ }
+ if (texture_floaterp && mOnCloseCallback)
+ {
+ texture_floaterp->setOnFloaterCloseCallback(boost::bind(&LLTextureCtrl::onFloaterClose, this));
+ }
+ if (texture_floaterp)
+ {
+ texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2));
+ }
+ if (texture_floaterp)
+ {
+ texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1));
+ }
+
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ root_floater->addDependentFloater(floaterp);
+ floaterp->openFloater();
+ }
+
+ if (take_focus)
+ {
+ floaterp->setFocus(TRUE);
+ }
+}
+
+
+void LLTextureCtrl::closeDependentFloater()
+{
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if( floaterp )
+ {
+ floaterp->setOwner(NULL);
+ floaterp->closeFloater();
+ }
+}
+
+// Allow us to download textures quickly when floater is shown
+class LLTextureFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
+{
+public:
+ virtual void done()
+ {
+ // We need to find textures in all folders, so get the main
+ // background download going.
+ LLInventoryModelBackgroundFetch::instance().start();
+ gInventory.removeObserver(this);
+ delete this;
+ }
+};
+
+BOOL LLTextureCtrl::handleHover(S32 x, S32 y, MASK mask)
+{
+ getWindow()->setCursor(mBorder->parentPointInView(x,y) ? UI_CURSOR_HAND : UI_CURSOR_ARROW);
+ return TRUE;
+}
+
+
+BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = LLUICtrl::handleMouseDown( x, y , mask );
+
+ if (!handled && mBorder->parentPointInView(x, y))
+ {
+ showPicker(FALSE);
+ //grab textures first...
+ LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
+ //...then start full inventory fetch.
+ LLInventoryModelBackgroundFetch::instance().start();
+ handled = TRUE;
+ }
+
+ return handled;
+}
+
+void LLTextureCtrl::onFloaterClose()
+{
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+
+ if (floaterp)
+ {
+ if (mOnCloseCallback)
+ {
+ mOnCloseCallback(this,LLSD());
+ }
+ floaterp->setOwner(NULL);
+ }
+
+ mFloaterHandle.markDead();
+}
+
+void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
+{
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+
+ if( floaterp && getEnabled())
+ {
+ if (op == TEXTURE_CANCEL)
+ mViewModel->resetDirty();
+ // If the "no_commit_on_selection" parameter is set
+ // we get dirty only when user presses OK in the picker
+ // (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
+ else if (mCommitOnSelection || op == TEXTURE_SELECT)
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+
+ if(floaterp->isDirty() || id.notNull()) // mModelView->setDirty does not work.
+ {
+ setTentative( FALSE );
+
+ if (id.notNull())
+ {
+ mImageItemID = id;
+ mImageAssetID = id;
+ }
+ else
+ {
+ mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE);
+ LL_DEBUGS() << "mImageItemID: " << mImageItemID << LL_ENDL;
+ mImageAssetID = floaterp->getAssetID();
+ LL_DEBUGS() << "mImageAssetID: " << mImageAssetID << LL_ENDL;
+ }
+
+ if (op == TEXTURE_SELECT && mOnSelectCallback)
+ {
+ mOnSelectCallback( this, LLSD() );
+ }
+ else if (op == TEXTURE_CANCEL && mOnCancelCallback)
+ {
+ mOnCancelCallback( this, LLSD() );
+ }
+ else
+ {
+ // If the "no_commit_on_selection" parameter is set
+ // we commit only when user presses OK in the picker
+ // (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
+ if (mCommitOnSelection || op == TEXTURE_SELECT)
+ onCommit();
+ }
+ }
+ }
+}
+
+void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb)
+{
+ mOnTextureSelectedCallback = cb;
+ LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get());
+ if (floaterp)
+ {
+ floaterp->setTextureSelectedCallback(cb);
+ }
+}
+
+void LLTextureCtrl::setImageAssetName(const std::string& name)
+{
+ LLPointer<LLUIImage> imagep = LLUI::getUIImage(name);
+ if(imagep)
+ {
+ LLViewerFetchedTexture* pTexture = dynamic_cast<LLViewerFetchedTexture*>(imagep->getImage().get());
+ if(pTexture)
+ {
+ LLUUID id = pTexture->getID();
+ setImageAssetID(id);
+ }
+ }
+}
+
+void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
+{
+ if( mImageAssetID != asset_id )
+ {
+ mImageItemID.setNull();
+ mImageAssetID = asset_id;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if( floaterp && getEnabled() )
+ {
+ floaterp->setImageID( asset_id );
+ floaterp->resetDirty();
+ }
+ }
+}
+
+BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
+ EAcceptance *accept,
+ std::string& tooltip_msg)
+{
+ BOOL handled = FALSE;
+
+ // this downcast may be invalid - but if the second test below
+ // returns true, then the cast was valid, and we can perform
+ // the third test without problems.
+ LLInventoryItem* item = (LLInventoryItem*)cargo_data;
+ bool is_mesh = cargo_type == DAD_MESH;
+
+ if (getEnabled() &&
+ ((cargo_type == DAD_TEXTURE) || is_mesh) &&
+ allowDrop(item))
+ {
+ if (drop)
+ {
+ if(doDrop(item))
+ {
+ if (!mCommitOnSelection)
+ mViewModel->setDirty();
+
+ // This removes the 'Multiple' overlay, since
+ // there is now only one texture selected.
+ setTentative( FALSE );
+ onCommit();
+ }
+ }
+
+ *accept = ACCEPT_YES_SINGLE;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+
+ handled = TRUE;
+ LL_DEBUGS("UserInput") << "dragAndDrop handled by LLTextureCtrl " << getName() << LL_ENDL;
+
+ return handled;
+}
+
+void LLTextureCtrl::draw()
+{
+ mBorder->setKeyboardFocusHighlight(hasFocus());
+
+ if (!mValid)
+ {
+ mTexturep = NULL;
+ }
+ else if (!mImageAssetID.isNull())
+ {
+ LLPointer<LLViewerFetchedTexture> texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES,LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+
+ texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ texture->forceToSaveRawImage(0) ;
+
+ mTexturep = texture;
+ }
+ else//mImageAssetID == LLUUID::null
+ {
+ mTexturep = NULL;
+ }
+
+ // Border
+ LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
+ gl_rect_2d( border, mBorderColor.get(), FALSE );
+
+ // Interior
+ LLRect interior = border;
+ interior.stretch( -1 );
+
+ // If we're in a focused floater, don't apply the floater's alpha to the texture (STORM-677).
+ const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
+ if( mTexturep )
+ {
+ if( mTexturep->getComponents() == 4 )
+ {
+ gl_rect_2d_checkerboard( interior, alpha );
+ }
+
+ gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha);
+ mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
+ }
+ else if (!mFallbackImage.isNull())
+ {
+ mFallbackImage->draw(interior, UI_VERTEX_COLOR % alpha);
+ }
+ else
+ {
+ gl_rect_2d( interior, LLColor4::grey % alpha, TRUE );
+
+ // Draw X
+ gl_draw_x( interior, LLColor4::black );
+ }
+
+ mTentativeLabel->setVisible( getTentative() );
+
+ // Show "Loading..." string on the top left corner while this texture is loading.
+ // Using the discard level, do not show the string if the texture is almost but not
+ // fully loaded.
+ if (mTexturep.notNull() &&
+ (!mTexturep->isFullyLoaded()) &&
+ (mShowLoadingPlaceholder == TRUE))
+ {
+ U32 v_offset = 25;
+ LLFontGL* font = LLFontGL::getFontSansSerif();
+
+ // Don't show as loaded if the texture is almost fully loaded (i.e. discard1) unless god
+ if ((mTexturep->getDiscardLevel() > 1) || gAgent.isGodlike())
+ {
+ font->renderUTF8(
+ mLoadingPlaceholderString,
+ 0,
+ llfloor(interior.mLeft+3),
+ llfloor(interior.mTop-v_offset),
+ LLColor4::white,
+ LLFontGL::LEFT,
+ LLFontGL::BASELINE,
+ LLFontGL::DROP_SHADOW);
+ }
+
+ // Optionally show more detailed information.
+ if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+ {
+ LLFontGL* font = LLFontGL::getFontSansSerif();
+ std::string tdesc;
+ // Show what % the texture has loaded (0 to 100%, 100 is highest), and what level of detail (5 to 0, 0 is best).
+
+ v_offset += 12;
+ tdesc = llformat(" PK : %d%%", U32(mTexturep->getDownloadProgress()*100.0));
+ font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset),
+ LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
+
+ v_offset += 12;
+ tdesc = llformat(" LVL: %d", mTexturep->getDiscardLevel());
+ font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset),
+ LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
+
+ v_offset += 12;
+ tdesc = llformat(" ID : %s...", (mImageAssetID.asString().substr(0,7)).c_str());
+ font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset),
+ LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
+ }
+ }
+
+ LLUICtrl::draw();
+}
+
+BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item)
+{
+ BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
+ BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
+ BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
+ gAgent.getID());
+
+ PermissionMask item_perm_mask = 0;
+ if (copy) item_perm_mask |= PERM_COPY;
+ if (mod) item_perm_mask |= PERM_MODIFY;
+ if (xfer) item_perm_mask |= PERM_TRANSFER;
+
+// PermissionMask filter_perm_mask = mCanApplyImmediately ? commented out due to no-copy texture loss.
+// mImmediateFilterPermMask : mNonImmediateFilterPermMask;
+ PermissionMask filter_perm_mask = mImmediateFilterPermMask;
+ if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
+ {
+ if(mDragCallback)
+ {
+ return mDragCallback(this, item);
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+BOOL LLTextureCtrl::doDrop(LLInventoryItem* item)
+{
+ // call the callback if it exists.
+ if(mDropCallback)
+ {
+ // if it returns TRUE, we return TRUE, and therefore the
+ // commit is called above.
+ return mDropCallback(this, item);
+ }
+
+ // no callback installed, so just set the image ids and carry on.
+ setImageAssetID( item->getAssetUUID() );
+ mImageItemID = item->getUUID();
+ return TRUE;
+}
+
+BOOL LLTextureCtrl::handleUnicodeCharHere(llwchar uni_char)
+{
+ if( ' ' == uni_char )
+ {
+ showPicker(TRUE);
+ return TRUE;
+ }
+ return LLUICtrl::handleUnicodeCharHere(uni_char);
+}
+
+void LLTextureCtrl::setValue( const LLSD& value )
+{
+ setImageAssetID(value.asUUID());
+}
+
+LLSD LLTextureCtrl::getValue() const
+{
+ return LLSD(getImageAssetID());
+}
+
+#endif
diff --git a/indra/newview/llsettingspicker.h b/indra/newview/llsettingspicker.h
new file mode 100644
index 0000000000..968bcaa692
--- /dev/null
+++ b/indra/newview/llsettingspicker.h
@@ -0,0 +1,451 @@
+/**
+ * @file llsettingspicker.h
+ * @author Rider Linden
+ * @brief LLSettingsPicker class header file including related functions
+ *
+ * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2018, 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_SETTINGSPICKER_H
+#define LL_SETTINGSPICKER_H
+
+#include "llinventorysettings.h"
+#include "llfloater.h"
+#include "llpermissionsflags.h"
+#include "llfolderview.h"
+
+#include <boost/signals2.hpp>
+
+//=========================================================================
+class LLFilterEditor;
+class LLInventoryPanel;
+
+//=========================================================================
+class LLFloaterSettingsPicker : public LLFloater
+{
+public:
+ typedef std::function<void (LLUUID id)> commit_callback_t;
+ typedef std::function<void()> close_callback_t;
+ typedef std::function<void(const LLUUID& asset_id)> id_changed_callback_t;
+
+ LLFloaterSettingsPicker(LLView * owner, LLUUID setting_asset_id, const std::string &label, const LLSD &params = LLSD());
+
+ virtual ~LLFloaterSettingsPicker() override;
+
+ void setActive(bool active);
+ void setSettingsID(const LLUUID &settings_id, bool set_selection = true);
+
+ virtual BOOL postBuild() override;
+ virtual void onClose(bool app_quitting) override;
+ virtual void draw() override;
+
+ void setSettingsAssetID(LLUUID setting_asset_id);
+ LLUUID getSettingsAssetID() const { return mSettingAssetID; }
+
+ void setDefaultSettingsAssetID(LLUUID id) { mDefaultSettingsAssetID = id; }
+ LLUUID getDefaultSettingsAssetID() const { return mDefaultSettingsAssetID; }
+
+ void setSettingsFilter(LLSettingsType::type_e type);
+ LLSettingsType::type_e getSettingsFilter() const { return mSettingsType; }
+
+ // Takes a UUID, wraps get/setImageAssetID
+ virtual void setValue(const LLSD& value) override;
+ virtual LLSD getValue() const override;
+
+private:
+ typedef std::deque<LLFolderViewItem *> itemlist_t;
+
+ void onFilterEdit(const std::string& search_string);
+ void onSelectionChange(const itemlist_t &items, bool user_action);
+ void onButtonCancel();
+ void onButtonSelect();
+
+ LLUUID findItemID(const LLUUID& asset_id, bool copyable_only, bool ignore_library = false);
+
+ LLView* mOwner;
+ std::string mLabel;
+ LLUUID mSettingAssetID;
+ LLUUID mDefaultSettingsAssetID;
+
+ LLFilterEditor * mFilterEdit;
+ LLInventoryPanel * mInventoryPanel;
+ LLSettingsType::type_e mSettingsType;
+
+ F32 mContextConeOpacity;
+ PermissionMask mImmediateFilterPermMask;
+ PermissionMask mDnDFilterPermMask;
+ PermissionMask mNonImmediateFilterPermMask;
+
+ bool mActive;
+ bool mNoCopySettingsSelected;
+
+ LLSaveFolderState mSavedFolderState;
+
+// boost::signals2::signal<void(LLUUID id)> mCommitSignal;
+ boost::signals2::signal<void()> mCloseSignal;
+ boost::signals2::signal<void(const LLUUID& asset_id)> mChangeIDSignal;
+};
+
+#if 0
+#include "llcoord.h"
+#include "llfiltereditor.h"
+#include "llfolderview.h"
+#include "lllocalbitmaps.h"
+#include "llstring.h"
+#include "lluictrl.h"
+#include "llradiogroup.h"
+#include "lltextbox.h" // for params
+#include "llviewerinventory.h"
+#include "llviewborder.h" // for params
+#include "llviewerobject.h"
+#include "llviewertexture.h"
+#include "llwindow.h"
+
+class LLButton;
+class LLFloaterTexturePicker;
+class LLInventoryItem;
+class LLViewerFetchedTexture;
+
+// used for setting drag & drop callbacks.
+typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback;
+typedef boost::function<void (LLInventoryItem*)> texture_selected_callback;
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// LLTextureCtrl
+
+
+class LLTextureCtrl
+: public LLUICtrl
+{
+public:
+ typedef enum e_texture_pick_op
+ {
+ TEXTURE_CHANGE,
+ TEXTURE_SELECT,
+ TEXTURE_CANCEL
+ } ETexturePickOp;
+
+public:
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLUUID> image_id;
+ Optional<LLUUID> default_image_id;
+ Optional<std::string> default_image_name;
+ Optional<bool> allow_no_texture;
+ Optional<bool> can_apply_immediately;
+ Optional<bool> no_commit_on_selection; // alternative mode: commit occurs and the widget gets dirty
+ // only on DnD or when OK is pressed in the picker
+ Optional<S32> label_width;
+ Optional<LLUIColor> border_color;
+ Optional<LLUIImage*> fallback_image;
+
+ Optional<LLTextBox::Params> multiselect_text,
+ caption_text;
+
+ Optional<LLViewBorder::Params> border;
+
+ Params()
+ : image_id("image"),
+ default_image_id("default_image_id"),
+ default_image_name("default_image_name"),
+ allow_no_texture("allow_no_texture"),
+ can_apply_immediately("can_apply_immediately"),
+ no_commit_on_selection("no_commit_on_selection", false),
+ label_width("label_width", -1),
+ border_color("border_color"),
+ fallback_image("fallback_image"),
+ multiselect_text("multiselect_text"),
+ caption_text("caption_text"),
+ border("border")
+ {}
+ };
+protected:
+ LLTextureCtrl(const Params&);
+ friend class LLUICtrlFactory;
+public:
+ virtual ~LLTextureCtrl();
+
+ // LLView interface
+
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
+ EAcceptance *accept,
+ std::string& tooltip_msg);
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ virtual BOOL handleUnicodeCharHere(llwchar uni_char);
+
+ virtual void draw();
+ virtual void setVisible( BOOL visible );
+ virtual void setEnabled( BOOL enabled );
+
+ void setValid(BOOL valid);
+
+ // LLUICtrl interface
+ virtual void clear();
+
+ // Takes a UUID, wraps get/setImageAssetID
+ virtual void setValue(const LLSD& value);
+ virtual LLSD getValue() const;
+
+ // LLTextureCtrl interface
+ void showPicker(BOOL take_focus);
+ bool isPickerShown() { return !mFloaterHandle.isDead(); }
+ void setLabel(const std::string& label);
+ void setLabelWidth(S32 label_width) {mLabelWidth =label_width;}
+ const std::string& getLabel() const { return mLabel; }
+
+ void setAllowNoTexture( BOOL b ) { mAllowNoTexture = b; }
+ bool getAllowNoTexture() const { return mAllowNoTexture; }
+
+ const LLUUID& getImageItemID() { return mImageItemID; }
+
+ virtual void setImageAssetName(const std::string& name);
+
+ void setImageAssetID(const LLUUID &image_asset_id);
+ const LLUUID& getImageAssetID() const { return mImageAssetID; }
+
+ void setDefaultImageAssetID( const LLUUID& id ) { mDefaultImageAssetID = id; }
+ const LLUUID& getDefaultImageAssetID() const { return mDefaultImageAssetID; }
+
+ const std::string& getDefaultImageName() const { return mDefaultImageName; }
+
+ void setBlankImageAssetID( const LLUUID& id ) { mBlankImageAssetID = id; }
+ const LLUUID& getBlankImageAssetID() const { return mBlankImageAssetID; }
+
+ void setCaption(const std::string& caption);
+ void setCanApplyImmediately(BOOL b);
+
+ void setCanApply(bool can_preview, bool can_apply);
+
+ void setImmediateFilterPermMask(PermissionMask mask)
+ { mImmediateFilterPermMask = mask; }
+ void setDnDFilterPermMask(PermissionMask mask)
+ { mDnDFilterPermMask = mask; }
+ void setNonImmediateFilterPermMask(PermissionMask mask)
+ { mNonImmediateFilterPermMask = mask; }
+ PermissionMask getImmediateFilterPermMask() { return mImmediateFilterPermMask; }
+ PermissionMask getNonImmediateFilterPermMask() { return mNonImmediateFilterPermMask; }
+
+ void closeDependentFloater();
+
+ void onFloaterClose();
+ void onFloaterCommit(ETexturePickOp op, LLUUID id);
+
+ // This call is returned when a drag is detected. Your callback
+ // should return TRUE if the drag is acceptable.
+ void setDragCallback(drag_n_drop_callback cb) { mDragCallback = cb; }
+
+ // This callback is called when the drop happens. Return TRUE if
+ // the drop happened - resulting in an on commit callback, but not
+ // necessariliy any other change.
+ void setDropCallback(drag_n_drop_callback cb) { mDropCallback = cb; }
+
+ void setOnCancelCallback(commit_callback_t cb) { mOnCancelCallback = cb; }
+ void setOnCloseCallback(commit_callback_t cb) { mOnCloseCallback = cb; }
+ void setOnSelectCallback(commit_callback_t cb) { mOnSelectCallback = cb; }
+
+ /*
+ * callback for changing texture selection in inventory list of texture floater
+ */
+ void setOnTextureSelectedCallback(texture_selected_callback cb);
+
+ void setShowLoadingPlaceholder(BOOL showLoadingPlaceholder);
+
+ LLViewerFetchedTexture* getTexture() { return mTexturep; }
+
+private:
+ BOOL allowDrop(LLInventoryItem* item);
+ BOOL doDrop(LLInventoryItem* item);
+
+private:
+ drag_n_drop_callback mDragCallback;
+ drag_n_drop_callback mDropCallback;
+ commit_callback_t mOnCancelCallback;
+ commit_callback_t mOnSelectCallback;
+ commit_callback_t mOnCloseCallback;
+ texture_selected_callback mOnTextureSelectedCallback;
+ LLPointer<LLViewerFetchedTexture> mTexturep;
+ LLUIColor mBorderColor;
+ LLUUID mImageItemID;
+ LLUUID mImageAssetID;
+ LLUUID mDefaultImageAssetID;
+ LLUUID mBlankImageAssetID;
+ LLUIImagePtr mFallbackImage;
+ std::string mDefaultImageName;
+ LLHandle<LLFloater> mFloaterHandle;
+ LLTextBox* mTentativeLabel;
+ LLTextBox* mCaption;
+ std::string mLabel;
+ BOOL mAllowNoTexture; // If true, the user can select "none" as an option
+ PermissionMask mImmediateFilterPermMask;
+ PermissionMask mDnDFilterPermMask;
+ PermissionMask mNonImmediateFilterPermMask;
+ BOOL mCanApplyImmediately;
+ BOOL mCommitOnSelection;
+ BOOL mNeedsRawImageData;
+ LLViewBorder* mBorder;
+ BOOL mValid;
+ BOOL mShowLoadingPlaceholder;
+ std::string mLoadingPlaceholderString;
+ S32 mLabelWidth;
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// LLFloaterTexturePicker
+typedef boost::function<void(LLTextureCtrl::ETexturePickOp op, LLUUID id)> floater_commit_callback;
+typedef boost::function<void()> floater_close_callback;
+typedef boost::function<void(const LLUUID& asset_id)> set_image_asset_id_callback;
+typedef boost::function<void(LLPointer<LLViewerTexture> texture)> set_on_update_image_stats_callback;
+
+class LLFloaterTexturePicker : public LLFloater
+{
+public:
+ LLFloaterTexturePicker(
+ LLView* owner,
+ LLUUID image_asset_id,
+ LLUUID default_image_asset_id,
+ LLUUID blank_image_asset_id,
+ BOOL tentative,
+ BOOL allow_no_texture,
+ const std::string& label,
+ PermissionMask immediate_filter_perm_mask,
+ PermissionMask dnd_filter_perm_mask,
+ PermissionMask non_immediate_filter_perm_mask,
+ BOOL can_apply_immediately,
+ LLUIImagePtr fallback_image_name
+ );
+
+ virtual ~LLFloaterTexturePicker();
+
+ // LLView overrides
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
+ EAcceptance *accept,
+ std::string& tooltip_msg);
+ /*virtual*/ void draw();
+ /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
+
+ // LLFloater overrides
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onClose(bool app_settings);
+
+ // New functions
+ void setImageID(const LLUUID& image_asset_id, bool set_selection = true);
+ void updateImageStats();
+ const LLUUID& getAssetID() { return mImageAssetID; }
+ const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library = FALSE);
+ void setCanApplyImmediately(BOOL b);
+
+ void setActive(BOOL active);
+
+ LLView* getOwner() const { return mOwner; }
+ void setOwner(LLView* owner) { mOwner = owner; }
+ void stopUsingPipette();
+ PermissionMask getFilterPermMask();
+
+ void updateFilterPermMask();
+ void commitIfImmediateSet();
+ void commitCancel();
+
+ void onFilterEdit(const std::string& search_string);
+
+ void setCanApply(bool can_preview, bool can_apply);
+ void setTextureSelectedCallback(const texture_selected_callback& cb) { mTextureSelectedCallback = cb; }
+ void setOnFloaterCloseCallback(const floater_close_callback& cb) { mOnFloaterCloseCallback = cb; }
+ void setOnFloaterCommitCallback(const floater_commit_callback& cb) { mOnFloaterCommitCallback = cb; }
+ void setSetImageAssetIDCallback(const set_image_asset_id_callback& cb) { mSetImageAssetIDCallback = cb; }
+ void setOnUpdateImageStatsCallback(const set_on_update_image_stats_callback& cb) { mOnUpdateImageStatsCallback = cb; }
+ const LLUUID& getDefaultImageAssetID() { return mDefaultImageAssetID; }
+ const LLUUID& getBlankImageAssetID() { return mBlankImageAssetID; }
+
+ static void onBtnSetToDefault(void* userdata);
+ static void onBtnSelect(void* userdata);
+ static void onBtnCancel(void* userdata);
+ void onBtnPipette();
+ //static void onBtnRevert( void* userdata );
+ static void onBtnBlank(void* userdata);
+ static void onBtnNone(void* userdata);
+ static void onBtnClear(void* userdata);
+ void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
+ static void onShowFolders(LLUICtrl* ctrl, void* userdata);
+ static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
+ void onTextureSelect(const LLTextureEntry& te);
+
+ static void onModeSelect(LLUICtrl* ctrl, void *userdata);
+ static void onBtnAdd(void* userdata);
+ static void onBtnRemove(void* userdata);
+ static void onBtnUpload(void* userdata);
+ static void onLocalScrollCommit(LLUICtrl* ctrl, void* userdata);
+
+ void setLocalTextureEnabled(BOOL enabled);
+
+protected:
+ LLPointer<LLViewerTexture> mTexturep;
+ LLView* mOwner;
+
+ LLUUID mImageAssetID; // Currently selected texture
+ LLUIImagePtr mFallbackImage; // What to show if currently selected texture is null.
+ LLUUID mDefaultImageAssetID;
+ LLUUID mBlankImageAssetID;
+ BOOL mTentative;
+ BOOL mAllowNoTexture;
+ LLUUID mSpecialCurrentImageAssetID; // Used when the asset id has no corresponding texture in the user's inventory.
+ LLUUID mOriginalImageAssetID;
+
+ std::string mLabel;
+
+ LLTextBox* mTentativeLabel;
+ LLTextBox* mResolutionLabel;
+
+ std::string mPendingName;
+ BOOL mActive;
+
+ LLFilterEditor* mFilterEdit;
+ LLInventoryPanel* mInventoryPanel;
+ PermissionMask mImmediateFilterPermMask;
+ PermissionMask mDnDFilterPermMask;
+ PermissionMask mNonImmediateFilterPermMask;
+ BOOL mCanApplyImmediately;
+ BOOL mNoCopyTextureSelected;
+ F32 mContextConeOpacity;
+ LLSaveFolderState mSavedFolderState;
+ BOOL mSelectedItemPinned;
+
+ LLRadioGroup* mModeSelector;
+ LLScrollListCtrl* mLocalScrollCtrl;
+
+private:
+ bool mCanApply;
+ bool mCanPreview;
+ bool mPreviewSettingChanged;
+
+ texture_selected_callback mTextureSelectedCallback;
+ floater_close_callback mOnFloaterCloseCallback;
+ floater_commit_callback mOnFloaterCommitCallback;
+ set_image_asset_id_callback mSetImageAssetIDCallback;
+ set_on_update_image_stats_callback mOnUpdateImageStatsCallback;
+};
+
+#endif
+#endif // LL_LLTEXTURECTRL_H
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index b5fb889669..0ec7db2ed7 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -104,7 +104,7 @@ void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings
create_inventory_settings(gAgent.getID(), gAgent.getSessionID(),
parentFolder, tid,
settings->getName(), "new settings collection.",
- settings->getSettingTypeValue(), nextOwnerPerm, cb);
+ settings->getSettingsTypeValue(), nextOwnerPerm, cb);
}
void LLSettingsVOBase::onInventoryItemCreated(const LLUUID &inventoryId, LLSettingsBase::ptr_t settings, inventory_result_fn callback)
diff --git a/indra/newview/skins/default/xui/en/floater_settings_picker.xml b/indra/newview/skins/default/xui/en/floater_settings_picker.xml
index 75bef9f680..2df52ec6d5 100644
--- a/indra/newview/skins/default/xui/en/floater_settings_picker.xml
+++ b/indra/newview/skins/default/xui/en/floater_settings_picker.xml
@@ -1,11 +1,115 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- height="602"
+ legacy_header_height="18"
+ can_minimize="false"
+ can_resize="true"
+ height="330"
layout="topleft"
- name="floater_settings_picker"
- help_topic=""
- save_rect="true"
- title="Settings Selector"
- width="705">
-
+ min_height="330"
+ min_width="225"
+ name="settings picker"
+ help_topic="settings_picker"
+ title="PICK: SETTINGS"
+ width="225">
+
+ <!-- top static -->
+ <floater.string
+ name="choose_picture">
+ Click to choose a picture
+ </floater.string>
+ <floater.string
+ name="pick title">
+ Pick:
+ </floater.string>
+
+ <layout_stack name="test_stack"
+ follows="all"
+ animate="false"
+ top="20"
+ left="6"
+ right="-6"
+ bottom="-10"
+ auto_resize="true"
+ user_resize="true"
+ orientation="vertical">
+ <layout_panel name="temp"
+ border="false"
+ auto_resize="true"
+ user_resize="true"
+ height="29"
+ min_height="29"
+ bg_alpha_color="blue"
+ background_visible="false">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ label="Filter Textures"
+ layout="topleft"
+ left="4"
+ name="flt_inventory_search"
+ top="4"
+ right="-2" />
+ <inventory_panel
+ allow_multi_select="false"
+ bg_visible="true"
+ bg_alpha_color="DkGray2"
+ border="false"
+ follows="left|top|right|bottom"
+ left_delta="0"
+ name="pnl_inventory"
+ top="31"
+ right="-4"
+ bottom="-26"
+ />
+ <check_box
+ follows="left|bottom"
+ height="14"
+ initial_value="false"
+ label="Show folders"
+ layout="topleft"
+ name="chk_showfolders"
+ top="-20"
+ top_pad="0"
+ left_delta="-3"
+ width="200" />
+ </layout_panel>
+ <layout_panel name="temp"
+ border="false"
+ auto_resize="false"
+ user_resize="false"
+ height="29"
+ min_height="29">
+ <!-- bg_alpha_color="red"
+ background_visible="true" -->
+ <button
+ follows="top|left"
+ height="20"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ left="2"
+ top="2"
+ name="btn_select"
+ width="100" />
+ <button
+ follows="top|left"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_delta="110"
+ top_delta="0"
+ name="btn_cancel"
+ width="100" />
+ </layout_panel>
+ </layout_stack>
+
+ <!-- middle: inventory mode -->
+ <!--
+
+
+-->
+ <!-- bottom static -->
+ <!--
+ -->
</floater>