Richard Linden 2011-07-07 13:34:13 -07:00
commit 88a90aabcb
147 changed files with 6119 additions and 2893 deletions

View File

@ -1206,9 +1206,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>82798d0da3ac3d97c91517a575d9ea1c</string>
<string>a7c80fd8516df3b879b669b2b220067f</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/231093/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20110526.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/232420/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20110608.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -1230,9 +1230,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f0708d18943a05013493f69ab7dc6429</string>
<string>b9cc0333cc274c9cc40256ab7146b4fc</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/231093/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20110526.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/232420/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20110608.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -1570,9 +1570,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>e19576af3c0affc71293d8f0bcce2606</string>
<string>24e735ae005f3ce7a21a09cc02cece17</string>
<key>url</key>
<string> http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/slvoice-3.2.0002.9361-darwin-20110120.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-slvoice/rev/231678/arch/Darwin/installer/slvoice-3.2.0002.10426-darwin-20110601.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -1582,9 +1582,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>53fefed8120d7c6a0eb6778edae6fa32</string>
<string>8a0bc982367d6fdc20a28b391cd40566</string>
<key>url</key>
<string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/slvoice-3.2.0002.9361-linux-20110120.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-slvoice/rev/231678/arch/Linux/installer/slvoice-3.2.0002.10426-linux-20110601.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1594,9 +1594,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>44f84b3b45f7067a104a7c34d50d62f0</string>
<string>1e821cc7d25eabad013b7f3db260dd6b</string>
<key>url</key>
<string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/slvoice-3.2.0002.9361-windows-20110120.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-slvoice/rev/231678/arch/CYGWIN/installer/slvoice-3.2.0002.10426-windows-20110601.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>

View File

@ -103,8 +103,6 @@ Ales Beaumont
Alexandrea Fride
STORM-255
STORM-960
STORM-1327
STORM-1406
Alissa Sabre
VWR-81
VWR-83
@ -161,6 +159,7 @@ Ann Congrejo
Ansariel Hiller
STORM-1101
VWR-25480
VWR-26150
Ardy Lay
STORM-859
VWR-19499
@ -446,20 +445,9 @@ Jonathan Yap
STORM-1236
STORM-1259
STORM-787
VWR-25480
STORM-1334
STORM-1313
STORM-899
STORM-1273
STORM-457
STORM-1452
STORM-1406
STORM-1327
STORM-1396
STORM-1292
STORM-1392
STORM-1302
STORM-1326
Kage Pixel
VWR-11
Ken March
@ -792,7 +780,6 @@ Strife Onizuka
SNOW-691
TankMaster Finesmith
STORM-1100
STORM-1452
Tayra Dagostino
SNOW-517
SNOW-543
@ -925,7 +912,6 @@ WolfPup Lowenhar
STORM-825
STORM-859
STORM-1098
STORM-1393
VWR-20741
VWR-20933
Zai Lynch

View File

@ -93,6 +93,8 @@ LLFolderDictionary::LLFolderDictionary()
addEntry(LLFolderType::FT_MESH, new FolderEntry("mesh", TRUE));
addEntry(LLFolderType::FT_INBOX, new FolderEntry("inbox", TRUE));
addEntry(LLFolderType::FT_OUTBOX, new FolderEntry("outbox", TRUE));
addEntry(LLFolderType::FT_BASIC_ROOT, new FolderEntry("basic_rt", TRUE));
addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE));
};

View File

@ -83,8 +83,11 @@ public:
FT_MESH = 49,
FT_INBOX = 50,
FT_OUTBOX = 51,
FT_COUNT = 51,
FT_BASIC_ROOT = 52,
FT_COUNT,
FT_NONE = -1
};

File diff suppressed because it is too large Load Diff

View File

@ -1,426 +1,425 @@
/**
* @file llpluginclassmedia.h
* @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class.
*
* @cond
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
* @endcond
*/
#ifndef LL_LLPLUGINCLASSMEDIA_H
#define LL_LLPLUGINCLASSMEDIA_H
#include "llgltypes.h"
#include "llpluginprocessparent.h"
#include "llrect.h"
#include "llpluginclassmediaowner.h"
#include <queue>
#include "v4color.h"
class LLPluginClassMedia : public LLPluginProcessParentOwner
{
LOG_CLASS(LLPluginClassMedia);
public:
LLPluginClassMedia(LLPluginClassMediaOwner *owner);
virtual ~LLPluginClassMedia();
// local initialization, called by the media manager when creating a source
virtual bool init(const std::string &launcher_filename,
const std::string &plugin_dir,
const std::string &plugin_filename,
bool debug);
// undoes everything init() didm called by the media manager when destroying a source
virtual void reset();
void idle(void);
// All of these may return 0 or an actual valid value.
// Callers need to check the return for 0, and not use the values in that case.
int getWidth() const { return (mMediaWidth > 0) ? mMediaWidth : 0; };
int getHeight() const { return (mMediaHeight > 0) ? mMediaHeight : 0; };
int getNaturalWidth() const { return mNaturalMediaWidth; };
int getNaturalHeight() const { return mNaturalMediaHeight; };
int getSetWidth() const { return mSetMediaWidth; };
int getSetHeight() const { return mSetMediaHeight; };
int getBitsWidth() const { return (mTextureWidth > 0) ? mTextureWidth : 0; };
int getBitsHeight() const { return (mTextureHeight > 0) ? mTextureHeight : 0; };
int getTextureWidth() const;
int getTextureHeight() const;
int getFullWidth() const { return mFullMediaWidth; };
int getFullHeight() const { return mFullMediaHeight; };
// This may return NULL. Callers need to check for and handle this case.
unsigned char* getBitsData();
// gets the format details of the texture data
// These may return 0 if they haven't been set up yet. The caller needs to detect this case.
int getTextureDepth() const { return mRequestedTextureDepth; };
int getTextureFormatInternal() const { return mRequestedTextureInternalFormat; };
int getTextureFormatPrimary() const { return mRequestedTextureFormat; };
int getTextureFormatType() const { return mRequestedTextureType; };
bool getTextureFormatSwapBytes() const { return mRequestedTextureSwapBytes; };
bool getTextureCoordsOpenGL() const { return mRequestedTextureCoordsOpenGL; };
void setSize(int width, int height);
void setAutoScale(bool auto_scale);
void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; };
void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; };
// Returns true if all of the texture parameters (depth, format, size, and texture size) are set up and consistent.
// This will initially be false, and will also be false for some time after setSize while the resize is processed.
// Note that if this returns true, it is safe to use all the get() functions above without checking for invalid return values
// until you call idle() again.
bool textureValid(void);
bool getDirty(LLRect *dirty_rect = NULL);
void resetDirty(void);
typedef enum
{
MOUSE_EVENT_DOWN,
MOUSE_EVENT_UP,
MOUSE_EVENT_MOVE,
MOUSE_EVENT_DOUBLE_CLICK
}EMouseEventType;
void mouseEvent(EMouseEventType type, int button, int x, int y, MASK modifiers);
typedef enum
{
KEY_EVENT_DOWN,
KEY_EVENT_UP,
KEY_EVENT_REPEAT
}EKeyEventType;
bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data);
void scrollEvent(int x, int y, MASK modifiers);
// Javascript <-> viewer events
void jsExposeObjectEvent( bool expose );
void jsValuesValidEvent( bool valid );
void jsAgentLocationEvent( double x, double y, double z );
void jsAgentGlobalLocationEvent( double x, double y, double z );
void jsAgentOrientationEvent( double angle );
void jsAgentLanguageEvent( const std::string& language );
void jsAgentRegionEvent( const std::string& region_name );
void jsAgentMaturityEvent( const std::string& maturity );
// Text may be unicode (utf8 encoded)
bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data);
void loadURI(const std::string &uri);
// "Loading" means uninitialized or any state prior to fully running (processing commands)
bool isPluginLoading(void) { return mPlugin?mPlugin->isLoading():false; };
// "Running" means the steady state -- i.e. processing messages
bool isPluginRunning(void) { return mPlugin?mPlugin->isRunning():false; };
// "Exited" means any regular or error state after "Running" (plugin may have crashed or exited normally)
bool isPluginExited(void) { return mPlugin?mPlugin->isDone():false; };
std::string getPluginVersion() { return mPlugin?mPlugin->getPluginVersion():std::string(""); };
bool getDisableTimeout() { return mPlugin?mPlugin->getDisableTimeout():false; };
void setDisableTimeout(bool disable) { if(mPlugin) mPlugin->setDisableTimeout(disable); };
// Inherited from LLPluginProcessParentOwner
/* virtual */ void receivePluginMessage(const LLPluginMessage &message);
/* virtual */ void pluginLaunchFailed();
/* virtual */ void pluginDied();
typedef enum
{
PRIORITY_UNLOADED, // media plugin isn't even loaded.
PRIORITY_STOPPED, // media is not playing, shouldn't need to update at all.
PRIORITY_HIDDEN, // media is not being displayed or is out of view, don't need to do graphic updates, but may still update audio, playhead, etc.
PRIORITY_SLIDESHOW, // media is in the far distance, updates very infrequently
PRIORITY_LOW, // media is in the distance, may be rendered at reduced size
PRIORITY_NORMAL, // normal (default) priority
PRIORITY_HIGH // media has user focus and/or is taking up most of the screen
}EPriority;
static const char* priorityToString(EPriority priority);
void setPriority(EPriority priority);
void setLowPrioritySizeLimit(int size);
F64 getCPUUsage();
void sendPickFileResponse(const std::string &file);
void sendAuthResponse(bool ok, const std::string &username, const std::string &password);
// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
std::string getCursorName() const { return mCursorName; };
LLPluginClassMediaOwner::EMediaStatus getStatus() const { return mStatus; }
void cut();
bool canCut() const { return mCanCut; };
void copy();
bool canCopy() const { return mCanCopy; };
void paste();
bool canPaste() const { return mCanPaste; };
// These can be called before init(), and they will be queued and sent before the media init message.
void setUserDataPath(const std::string &user_data_path);
void setLanguageCode(const std::string &language_code);
void setPluginsEnabled(const bool enabled);
void setJavascriptEnabled(const bool enabled);
void setTarget(const std::string &target);
///////////////////////////////////
// media browser class functions
bool pluginSupportsMediaBrowser(void);
void focus(bool focused);
void clear_cache();
void clear_cookies();
void set_cookies(const std::string &cookies);
void enable_cookies(bool enable);
void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0);
void browse_stop();
void browse_reload(bool ignore_cache = false);
void browse_forward();
void browse_back();
void setBrowserUserAgent(const std::string& user_agent);
void proxyWindowOpened(const std::string &target, const std::string &uuid);
void proxyWindowClosed(const std::string &uuid);
void ignore_ssl_cert_errors(bool ignore);
void addCertificateFilePath(const std::string& path);
// This is valid after MEDIA_EVENT_NAVIGATE_BEGIN or MEDIA_EVENT_NAVIGATE_COMPLETE
std::string getNavigateURI() const { return mNavigateURI; };
// These are valid after MEDIA_EVENT_NAVIGATE_COMPLETE
S32 getNavigateResultCode() const { return mNavigateResultCode; };
std::string getNavigateResultString() const { return mNavigateResultString; };
bool getHistoryBackAvailable() const { return mHistoryBackAvailable; };
bool getHistoryForwardAvailable() const { return mHistoryForwardAvailable; };
// This is valid after MEDIA_EVENT_PROGRESS_UPDATED
int getProgressPercent() const { return mProgressPercent; };
// This is valid after MEDIA_EVENT_STATUS_TEXT_CHANGED
std::string getStatusText() const { return mStatusText; };
// This is valid after MEDIA_EVENT_LOCATION_CHANGED
std::string getLocation() const { return mLocation; };
// This is valid after MEDIA_EVENT_CLICK_LINK_HREF or MEDIA_EVENT_CLICK_LINK_NOFOLLOW
std::string getClickURL() const { return mClickURL; };
// This is valid after MEDIA_EVENT_CLICK_LINK_NOFOLLOW
std::string getClickNavType() const { return mClickNavType; };
// This is valid after MEDIA_EVENT_CLICK_LINK_HREF
std::string getClickTarget() const { return mClickTarget; };
// This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE
std::string getClickUUID() const { return mClickUUID; };
// This is valid after MEDIA_EVENT_NAVIGATE_ERROR_PAGE
S32 getStatusCode() const { return mStatusCode; };
// These are valid during MEDIA_EVENT_GEOMETRY_CHANGE
S32 getGeometryX() const { return mGeometryX; };
S32 getGeometryY() const { return mGeometryY; };
S32 getGeometryWidth() const { return mGeometryWidth; };
S32 getGeometryHeight() const { return mGeometryHeight; };
// These are valid during MEDIA_EVENT_AUTH_REQUEST
std::string getAuthURL() const { return mAuthURL; };
std::string getAuthRealm() const { return mAuthRealm; };
// These are valid during MEDIA_EVENT_LINK_HOVERED
std::string getHoverText() const { return mHoverText; };
std::string getHoverLink() const { return mHoverLink; };
std::string getMediaName() const { return mMediaName; };
std::string getMediaDescription() const { return mMediaDescription; };
// Crash the plugin. If you use this outside of a testbed, you will be punished.
void crashPlugin();
// Hang the plugin. If you use this outside of a testbed, you will be punished.
void hangPlugin();
///////////////////////////////////
// media time class functions
bool pluginSupportsMediaTime(void);
void stop();
void start(float rate = 0.0f);
void pause();
void seek(float time);
void setLoop(bool loop);
void setVolume(float volume);
float getVolume();
F64 getCurrentTime(void) const { return mCurrentTime; };
F64 getDuration(void) const { return mDuration; };
F64 getCurrentPlayRate(void) { return mCurrentRate; };
F64 getLoadedDuration(void) const { return mLoadedDuration; };
// Initialize the URL history of the plugin by sending
// "init_history" message
void initializeUrlHistory(const LLSD& url_history);
protected:
LLPluginClassMediaOwner *mOwner;
// Notify this object's owner that an event has occurred.
void mediaEvent(LLPluginClassMediaOwner::EMediaEvent event);
void sendMessage(const LLPluginMessage &message); // Send message internally, either queueing or sending directly.
std::queue<LLPluginMessage> mSendQueue; // Used to queue messages while the plugin initializes.
void setSizeInternal(void);
bool mTextureParamsReceived; // the mRequestedTexture* fields are only valid when this is true
S32 mRequestedTextureDepth;
LLGLenum mRequestedTextureInternalFormat;
LLGLenum mRequestedTextureFormat;
LLGLenum mRequestedTextureType;
bool mRequestedTextureSwapBytes;
bool mRequestedTextureCoordsOpenGL;
std::string mTextureSharedMemoryName;
size_t mTextureSharedMemorySize;
// True to scale requested media up to the full size of the texture (i.e. next power of two)
bool mAutoScaleMedia;
// default media size for the plugin, from the texture_params message.
int mDefaultMediaWidth;
int mDefaultMediaHeight;
// Size that has been requested by the plugin itself
int mNaturalMediaWidth;
int mNaturalMediaHeight;
// Size that has been requested with setSize()
int mSetMediaWidth;
int mSetMediaHeight;
// Full calculated media size (before auto-scale and downsample calculations)
int mFullMediaWidth;
int mFullMediaHeight;
// Actual media size being set (after auto-scale)
int mRequestedMediaWidth;
int mRequestedMediaHeight;
// Texture size calculated from actual media size
int mRequestedTextureWidth;
int mRequestedTextureHeight;
// Size that the plugin has acknowledged
int mTextureWidth;
int mTextureHeight;
int mMediaWidth;
int mMediaHeight;
float mRequestedVolume;
// Priority of this media stream
EPriority mPriority;
int mLowPrioritySizeLimit;
bool mAllowDownsample;
int mPadding;
LLPluginProcessParent *mPlugin;
LLRect mDirtyRect;
std::string translateModifiers(MASK modifiers);
std::string mCursorName;
int mLastMouseX;
int mLastMouseY;
LLPluginClassMediaOwner::EMediaStatus mStatus;
F64 mSleepTime;
bool mCanCut;
bool mCanCopy;
bool mCanPaste;
std::string mMediaName;
std::string mMediaDescription;
LLColor4 mBackgroundColor;
std::string mTarget;
/////////////////////////////////////////
// media_browser class
std::string mNavigateURI;
S32 mNavigateResultCode;
std::string mNavigateResultString;
bool mHistoryBackAvailable;
bool mHistoryForwardAvailable;
std::string mStatusText;
int mProgressPercent;
std::string mLocation;
std::string mClickURL;
std::string mClickNavType;
std::string mClickTarget;
std::string mClickUUID;
S32 mGeometryX;
S32 mGeometryY;
S32 mGeometryWidth;
S32 mGeometryHeight;
S32 mStatusCode;
std::string mAuthURL;
std::string mAuthRealm;
std::string mHoverText;
std::string mHoverLink;
/////////////////////////////////////////
// media_time class
F64 mCurrentTime;
F64 mDuration;
F64 mCurrentRate;
F64 mLoadedDuration;
//--------------------------------------
//debug use only
//
private:
bool mDeleteOK ;
public:
void setDeleteOK(bool flag) { mDeleteOK = flag ;}
//--------------------------------------
};
#endif // LL_LLPLUGINCLASSMEDIA_H
/**
* @file llpluginclassmedia.h
* @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class.
*
* @cond
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
* @endcond
*/
#ifndef LL_LLPLUGINCLASSMEDIA_H
#define LL_LLPLUGINCLASSMEDIA_H
#include "llgltypes.h"
#include "llpluginprocessparent.h"
#include "llrect.h"
#include "llpluginclassmediaowner.h"
#include <queue>
#include "v4color.h"
class LLPluginClassMedia : public LLPluginProcessParentOwner
{
LOG_CLASS(LLPluginClassMedia);
public:
LLPluginClassMedia(LLPluginClassMediaOwner *owner);
virtual ~LLPluginClassMedia();
// local initialization, called by the media manager when creating a source
virtual bool init(const std::string &launcher_filename,
const std::string &plugin_dir,
const std::string &plugin_filename,
bool debug);
// undoes everything init() didm called by the media manager when destroying a source
virtual void reset();
void idle(void);
// All of these may return 0 or an actual valid value.
// Callers need to check the return for 0, and not use the values in that case.
int getWidth() const { return (mMediaWidth > 0) ? mMediaWidth : 0; };
int getHeight() const { return (mMediaHeight > 0) ? mMediaHeight : 0; };
int getNaturalWidth() const { return mNaturalMediaWidth; };
int getNaturalHeight() const { return mNaturalMediaHeight; };
int getSetWidth() const { return mSetMediaWidth; };
int getSetHeight() const { return mSetMediaHeight; };
int getBitsWidth() const { return (mTextureWidth > 0) ? mTextureWidth : 0; };
int getBitsHeight() const { return (mTextureHeight > 0) ? mTextureHeight : 0; };
int getTextureWidth() const;
int getTextureHeight() const;
int getFullWidth() const { return mFullMediaWidth; };
int getFullHeight() const { return mFullMediaHeight; };
// This may return NULL. Callers need to check for and handle this case.
unsigned char* getBitsData();
// gets the format details of the texture data
// These may return 0 if they haven't been set up yet. The caller needs to detect this case.
int getTextureDepth() const { return mRequestedTextureDepth; };
int getTextureFormatInternal() const { return mRequestedTextureInternalFormat; };
int getTextureFormatPrimary() const { return mRequestedTextureFormat; };
int getTextureFormatType() const { return mRequestedTextureType; };
bool getTextureFormatSwapBytes() const { return mRequestedTextureSwapBytes; };
bool getTextureCoordsOpenGL() const { return mRequestedTextureCoordsOpenGL; };
void setSize(int width, int height);
void setAutoScale(bool auto_scale);
void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; };
void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; };
// Returns true if all of the texture parameters (depth, format, size, and texture size) are set up and consistent.
// This will initially be false, and will also be false for some time after setSize while the resize is processed.
// Note that if this returns true, it is safe to use all the get() functions above without checking for invalid return values
// until you call idle() again.
bool textureValid(void);
bool getDirty(LLRect *dirty_rect = NULL);
void resetDirty(void);
typedef enum
{
MOUSE_EVENT_DOWN,
MOUSE_EVENT_UP,
MOUSE_EVENT_MOVE,
MOUSE_EVENT_DOUBLE_CLICK
}EMouseEventType;
void mouseEvent(EMouseEventType type, int button, int x, int y, MASK modifiers);
typedef enum
{
KEY_EVENT_DOWN,
KEY_EVENT_UP,
KEY_EVENT_REPEAT
}EKeyEventType;
bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data);
void scrollEvent(int x, int y, MASK modifiers);
// Javascript <-> viewer events
void jsEnableObject( bool enable );
void jsAgentLocationEvent( double x, double y, double z );
void jsAgentGlobalLocationEvent( double x, double y, double z );
void jsAgentOrientationEvent( double angle );
void jsAgentLanguageEvent( const std::string& language );
void jsAgentRegionEvent( const std::string& region_name );
void jsAgentMaturityEvent( const std::string& maturity );
// Text may be unicode (utf8 encoded)
bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data);
void loadURI(const std::string &uri);
// "Loading" means uninitialized or any state prior to fully running (processing commands)
bool isPluginLoading(void) { return mPlugin?mPlugin->isLoading():false; };
// "Running" means the steady state -- i.e. processing messages
bool isPluginRunning(void) { return mPlugin?mPlugin->isRunning():false; };
// "Exited" means any regular or error state after "Running" (plugin may have crashed or exited normally)
bool isPluginExited(void) { return mPlugin?mPlugin->isDone():false; };
std::string getPluginVersion() { return mPlugin?mPlugin->getPluginVersion():std::string(""); };
bool getDisableTimeout() { return mPlugin?mPlugin->getDisableTimeout():false; };
void setDisableTimeout(bool disable) { if(mPlugin) mPlugin->setDisableTimeout(disable); };
// Inherited from LLPluginProcessParentOwner
/* virtual */ void receivePluginMessage(const LLPluginMessage &message);
/* virtual */ void pluginLaunchFailed();
/* virtual */ void pluginDied();
typedef enum
{
PRIORITY_UNLOADED, // media plugin isn't even loaded.
PRIORITY_STOPPED, // media is not playing, shouldn't need to update at all.
PRIORITY_HIDDEN, // media is not being displayed or is out of view, don't need to do graphic updates, but may still update audio, playhead, etc.
PRIORITY_SLIDESHOW, // media is in the far distance, updates very infrequently
PRIORITY_LOW, // media is in the distance, may be rendered at reduced size
PRIORITY_NORMAL, // normal (default) priority
PRIORITY_HIGH // media has user focus and/or is taking up most of the screen
}EPriority;
static const char* priorityToString(EPriority priority);
void setPriority(EPriority priority);
void setLowPrioritySizeLimit(int size);
F64 getCPUUsage();
void sendPickFileResponse(const std::string &file);
void sendAuthResponse(bool ok, const std::string &username, const std::string &password);
// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
std::string getCursorName() const { return mCursorName; };
LLPluginClassMediaOwner::EMediaStatus getStatus() const { return mStatus; }
void cut();
bool canCut() const { return mCanCut; };
void copy();
bool canCopy() const { return mCanCopy; };
void paste();
bool canPaste() const { return mCanPaste; };
// These can be called before init(), and they will be queued and sent before the media init message.
void setUserDataPath(const std::string &user_data_path);
void setLanguageCode(const std::string &language_code);
void setPluginsEnabled(const bool enabled);
void setJavascriptEnabled(const bool enabled);
void setTarget(const std::string &target);
///////////////////////////////////
// media browser class functions
bool pluginSupportsMediaBrowser(void);
void focus(bool focused);
void clear_cache();
void clear_cookies();
void set_cookies(const std::string &cookies);
void enable_cookies(bool enable);
void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0);
void browse_stop();
void browse_reload(bool ignore_cache = false);
void browse_forward();
void browse_back();
void setBrowserUserAgent(const std::string& user_agent);
void proxyWindowOpened(const std::string &target, const std::string &uuid);
void proxyWindowClosed(const std::string &uuid);
void ignore_ssl_cert_errors(bool ignore);
void addCertificateFilePath(const std::string& path);
// This is valid after MEDIA_EVENT_NAVIGATE_BEGIN or MEDIA_EVENT_NAVIGATE_COMPLETE
std::string getNavigateURI() const { return mNavigateURI; };
// These are valid after MEDIA_EVENT_NAVIGATE_COMPLETE
S32 getNavigateResultCode() const { return mNavigateResultCode; };
std::string getNavigateResultString() const { return mNavigateResultString; };
bool getHistoryBackAvailable() const { return mHistoryBackAvailable; };
bool getHistoryForwardAvailable() const { return mHistoryForwardAvailable; };
// This is valid after MEDIA_EVENT_PROGRESS_UPDATED
int getProgressPercent() const { return mProgressPercent; };
// This is valid after MEDIA_EVENT_STATUS_TEXT_CHANGED
std::string getStatusText() const { return mStatusText; };
// This is valid after MEDIA_EVENT_LOCATION_CHANGED
std::string getLocation() const { return mLocation; };
// This is valid after MEDIA_EVENT_CLICK_LINK_HREF or MEDIA_EVENT_CLICK_LINK_NOFOLLOW
std::string getClickURL() const { return mClickURL; };
// This is valid after MEDIA_EVENT_CLICK_LINK_NOFOLLOW
std::string getClickNavType() const { return mClickNavType; };
// This is valid after MEDIA_EVENT_CLICK_LINK_HREF
std::string getClickTarget() const { return mClickTarget; };
// This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE
std::string getClickUUID() const { return mClickUUID; };
// This is valid after MEDIA_EVENT_NAVIGATE_ERROR_PAGE
S32 getStatusCode() const { return mStatusCode; };
// These are valid during MEDIA_EVENT_GEOMETRY_CHANGE
S32 getGeometryX() const { return mGeometryX; };
S32 getGeometryY() const { return mGeometryY; };
S32 getGeometryWidth() const { return mGeometryWidth; };
S32 getGeometryHeight() const { return mGeometryHeight; };
// These are valid during MEDIA_EVENT_AUTH_REQUEST
std::string getAuthURL() const { return mAuthURL; };
std::string getAuthRealm() const { return mAuthRealm; };
// These are valid during MEDIA_EVENT_LINK_HOVERED
std::string getHoverText() const { return mHoverText; };
std::string getHoverLink() const { return mHoverLink; };
std::string getMediaName() const { return mMediaName; };
std::string getMediaDescription() const { return mMediaDescription; };
// Crash the plugin. If you use this outside of a testbed, you will be punished.
void crashPlugin();
// Hang the plugin. If you use this outside of a testbed, you will be punished.
void hangPlugin();
///////////////////////////////////
// media time class functions
bool pluginSupportsMediaTime(void);
void stop();
void start(float rate = 0.0f);
void pause();
void seek(float time);
void setLoop(bool loop);
void setVolume(float volume);
float getVolume();
F64 getCurrentTime(void) const { return mCurrentTime; };
F64 getDuration(void) const { return mDuration; };
F64 getCurrentPlayRate(void) { return mCurrentRate; };
F64 getLoadedDuration(void) const { return mLoadedDuration; };
// Initialize the URL history of the plugin by sending
// "init_history" message
void initializeUrlHistory(const LLSD& url_history);
protected:
LLPluginClassMediaOwner *mOwner;
// Notify this object's owner that an event has occurred.
void mediaEvent(LLPluginClassMediaOwner::EMediaEvent event);
void sendMessage(const LLPluginMessage &message); // Send message internally, either queueing or sending directly.
std::queue<LLPluginMessage> mSendQueue; // Used to queue messages while the plugin initializes.
void setSizeInternal(void);
bool mTextureParamsReceived; // the mRequestedTexture* fields are only valid when this is true
S32 mRequestedTextureDepth;
LLGLenum mRequestedTextureInternalFormat;
LLGLenum mRequestedTextureFormat;
LLGLenum mRequestedTextureType;
bool mRequestedTextureSwapBytes;
bool mRequestedTextureCoordsOpenGL;
std::string mTextureSharedMemoryName;
size_t mTextureSharedMemorySize;
// True to scale requested media up to the full size of the texture (i.e. next power of two)
bool mAutoScaleMedia;
// default media size for the plugin, from the texture_params message.
int mDefaultMediaWidth;
int mDefaultMediaHeight;
// Size that has been requested by the plugin itself
int mNaturalMediaWidth;
int mNaturalMediaHeight;
// Size that has been requested with setSize()
int mSetMediaWidth;
int mSetMediaHeight;
// Full calculated media size (before auto-scale and downsample calculations)
int mFullMediaWidth;
int mFullMediaHeight;
// Actual media size being set (after auto-scale)
int mRequestedMediaWidth;
int mRequestedMediaHeight;
// Texture size calculated from actual media size
int mRequestedTextureWidth;
int mRequestedTextureHeight;
// Size that the plugin has acknowledged
int mTextureWidth;
int mTextureHeight;
int mMediaWidth;
int mMediaHeight;
float mRequestedVolume;
// Priority of this media stream
EPriority mPriority;
int mLowPrioritySizeLimit;
bool mAllowDownsample;
int mPadding;
LLPluginProcessParent *mPlugin;
LLRect mDirtyRect;
std::string translateModifiers(MASK modifiers);
std::string mCursorName;
int mLastMouseX;
int mLastMouseY;
LLPluginClassMediaOwner::EMediaStatus mStatus;
F64 mSleepTime;
bool mCanCut;
bool mCanCopy;
bool mCanPaste;
std::string mMediaName;
std::string mMediaDescription;
LLColor4 mBackgroundColor;
std::string mTarget;
/////////////////////////////////////////
// media_browser class
std::string mNavigateURI;
S32 mNavigateResultCode;
std::string mNavigateResultString;
bool mHistoryBackAvailable;
bool mHistoryForwardAvailable;
std::string mStatusText;
int mProgressPercent;
std::string mLocation;
std::string mClickURL;
std::string mClickNavType;
std::string mClickTarget;
std::string mClickUUID;
S32 mGeometryX;
S32 mGeometryY;
S32 mGeometryWidth;
S32 mGeometryHeight;
S32 mStatusCode;
std::string mAuthURL;
std::string mAuthRealm;
std::string mHoverText;
std::string mHoverLink;
/////////////////////////////////////////
// media_time class
F64 mCurrentTime;
F64 mDuration;
F64 mCurrentRate;
F64 mLoadedDuration;
//--------------------------------------
//debug use only
//
private:
bool mDeleteOK ;
public:
void setDeleteOK(bool flag) { mDeleteOK = flag ;}
//--------------------------------------
};
#endif // LL_LLPLUGINCLASSMEDIA_H

View File

@ -28,6 +28,8 @@ include_directories(
set(llui_SOURCE_FILES
llaccordionctrl.cpp
llaccordionctrltab.cpp
llbadge.cpp
llbadgeowner.cpp
llbutton.cpp
llcheckboxctrl.cpp
llclipboard.cpp
@ -120,6 +122,8 @@ set(llui_HEADER_FILES
llaccordionctrl.h
llaccordionctrltab.h
llbadge.h
llbadgeowner.h
llbutton.h
llcallbackmap.h
llcheckboxctrl.h
@ -247,11 +251,11 @@ target_link_libraries(llui
)
# Add tests
if (LL_TESTS)
include(LLAddBuildTest)
SET(llui_TEST_SOURCE_FILES
llurlmatch.cpp
llurlentry.cpp
)
LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}")
endif (LL_TESTS)
if(LL_TESTS)
include(LLAddBuildTest)
SET(llui_TEST_SOURCE_FILES
llurlmatch.cpp
llurlentry.cpp
)
LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}")
endif(LL_TESTS)

View File

@ -1022,7 +1022,7 @@ void LLAccordionCtrlTab::updateLayout ( const LLRect& child_rect )
S32 panel_width = child_rect.getWidth();
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
if(mScrollbar->getVisible() != false)
if(mScrollbar && mScrollbar->getVisible() != false)
{
panel_top+=mScrollbar->getDocPos();
panel_width-=scrollbar_size;

274
indra/llui/llbadge.cpp Normal file
View File

@ -0,0 +1,274 @@
/**
* @file llbadge.cpp
* @brief Implementation for badges
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#define LLBADGE_CPP
#include "llbadge.h"
#include "lluictrlfactory.h"
static LLDefaultChildRegistry::Register<LLBadge> r("badge");
// Compiler optimization, generate extern template
template class LLBadge* LLView::getChild<class LLBadge>(const std::string& name, BOOL recurse) const;
LLBadge::Params::Params()
: image("image")
, border_image("border_image")
, border_color("border_color")
, image_color("image_color")
, label("label")
, label_color("label_color")
, location("location", LLRelPos::TOP_LEFT)
, location_percent_hcenter("location_percent_hcenter")
, location_percent_vcenter("location_percent_vcenter")
, padding_horiz("padding_horiz")
, padding_vert("padding_vert")
{
// We set a name here so the name isn't necessary in any xml files that use badges
name = "badge";
}
bool LLBadge::Params::equals(const Params& a) const
{
bool comp = true;
// skip owner in comparison on purpose
comp &= (border_image() == a.border_image());
comp &= (border_color() == a.border_color());
comp &= (image() == a.image());
comp &= (image_color() == a.image_color());
comp &= (label() == a.label());
comp &= (label_color() == a.label_color());
comp &= (location() == a.location());
comp &= (location_percent_hcenter() == a.location_percent_hcenter());
comp &= (location_percent_vcenter() == a.location_percent_vcenter());
comp &= (padding_horiz() == a.padding_horiz());
comp &= (padding_vert() == a.padding_vert());
return comp;
}
LLBadge::LLBadge(const LLBadge::Params& p)
: LLUICtrl(p)
, mOwner(p.owner)
, mBorderImage(p.border_image)
, mBorderColor(p.border_color)
, mGLFont(p.font)
, mImage(p.image)
, mImageColor(p.image_color)
, mLabel(p.label)
, mLabelColor(p.label_color)
, mLocation(p.location)
, mLocationPercentHCenter(0.5f)
, mLocationPercentVCenter(0.5f)
, mPaddingHoriz(p.padding_horiz)
, mPaddingVert(p.padding_vert)
{
if (mImage.isNull())
{
llwarns << "Badge: " << getName() << " with no image!" << llendl;
}
//
// The following logic is to set the mLocationPercentHCenter and mLocationPercentVCenter
// based on the Location enum and our horizontal and vertical location percentages. The
// draw code then uses this on the owner rectangle to compute the screen location for
// the badge.
//
if (!LLRelPos::IsCenter(mLocation))
{
F32 h_center = p.location_percent_hcenter * 0.01f;
F32 v_center = p.location_percent_vcenter * 0.01f;
if (LLRelPos::IsRight(mLocation))
{
mLocationPercentHCenter = 0.5f * (1.0f + h_center);
}
else if (LLRelPos::IsLeft(mLocation))
{
mLocationPercentHCenter = 0.5f * (1.0f - h_center);
}
if (LLRelPos::IsTop(mLocation))
{
mLocationPercentVCenter = 0.5f * (1.0f + v_center);
}
else if (LLRelPos::IsBottom(mLocation))
{
mLocationPercentVCenter = 0.5f * (1.0f - v_center);
}
}
}
LLBadge::~LLBadge()
{
}
void LLBadge::setLabel(const LLStringExplicit& label)
{
mLabel = label;
}
//
// This is a fallback function to render a rectangle for badges without a valid image
//
void renderBadgeBackground(F32 centerX, F32 centerY, F32 width, F32 height, const LLColor4U &color)
{
gGL.pushUIMatrix();
gGL.loadUIIdentity();
gGL.setSceneBlendType(LLRender::BT_REPLACE);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4ubv(color.mV);
gGL.texCoord2i(0, 0);
F32 x = LLFontGL::sCurOrigin.mX + centerX - width * 0.5f;
F32 y = LLFontGL::sCurOrigin.mY + centerY - height * 0.5f;
LLRectf screen_rect(llround(x),
llround(y),
llround(x) + width,
llround(y) + height);
LLVector3 vertices[4];
vertices[0] = LLVector3(screen_rect.mRight, screen_rect.mTop, 1.0f);
vertices[1] = LLVector3(screen_rect.mLeft, screen_rect.mTop, 1.0f);
vertices[2] = LLVector3(screen_rect.mLeft, screen_rect.mBottom, 1.0f);
vertices[3] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 1.0f);
gGL.begin(LLRender::QUADS);
{
gGL.vertexBatchPreTransformed(vertices, 4);
}
gGL.end();
gGL.popUIMatrix();
}
// virtual
void LLBadge::draw()
{
if (!mLabel.empty())
{
LLView* owner_view = mOwner.get();
if (owner_view)
{
//
// Calculate badge position based on owner
//
LLRect owner_rect;
owner_view->localRectToOtherView(owner_view->getLocalRect(), & owner_rect, this);
F32 badge_center_x = owner_rect.mLeft + owner_rect.getWidth() * mLocationPercentHCenter;
F32 badge_center_y = owner_rect.mBottom + owner_rect.getHeight() * mLocationPercentVCenter;
//
// Calculate badge size based on label text
//
LLWString badge_label_wstring = mLabel;
S32 badge_label_begin_offset = 0;
S32 badge_char_length = S32_MAX;
S32 badge_pixel_length = S32_MAX;
F32 *right_position_out = NULL;
BOOL do_not_use_ellipses = false;
F32 badge_width = (2.0f * mPaddingHoriz) +
mGLFont->getWidthF32(badge_label_wstring.c_str(), badge_label_begin_offset, badge_char_length);
F32 badge_height = (2.0f * mPaddingVert) + mGLFont->getLineHeight();
//
// Draw button image, if available.
// Otherwise draw basic rectangular button.
//
F32 alpha = getDrawContext().mAlpha;
if (!mImage.isNull())
{
F32 badge_x = badge_center_x - badge_width * 0.5f;
F32 badge_y = badge_center_y - badge_height * 0.5f;
mImage->drawSolid((S32) badge_x, (S32) badge_y, (S32) badge_width, (S32) badge_height, mImageColor % alpha);
if (!mBorderImage.isNull())
{
mBorderImage->drawSolid((S32) badge_x, (S32) badge_y, (S32) badge_width, (S32) badge_height, mBorderColor % alpha);
}
}
else
{
lldebugs << "No image for badge " << getName() << " on owner " << owner_view->getName() << llendl;
renderBadgeBackground(badge_center_x, badge_center_y,
badge_width, badge_height,
mImageColor % alpha);
}
//
// Draw the label
//
mGLFont->render(badge_label_wstring, badge_label_begin_offset,
badge_center_x, badge_center_y,
mLabelColor % alpha,
LLFontGL::HCENTER, LLFontGL::VCENTER, // centered around the position
LLFontGL::NORMAL, // normal text (not bold, italics, etc.)
LLFontGL::DROP_SHADOW_SOFT,
badge_char_length, badge_pixel_length,
right_position_out, do_not_use_ellipses);
}
}
}
namespace LLInitParam
{
void TypeValues<LLRelPos::Location>::declareValues()
{
declare("bottom", LLRelPos::BOTTOM);
declare("bottom_left", LLRelPos::BOTTOM_LEFT);
declare("bottom_right", LLRelPos::BOTTOM_RIGHT);
declare("center", LLRelPos::CENTER);
declare("left", LLRelPos::LEFT);
declare("right", LLRelPos::RIGHT);
declare("top", LLRelPos::TOP);
declare("top_left", LLRelPos::TOP_LEFT);
declare("top_right", LLRelPos::TOP_RIGHT);
}
}
// eof

159
indra/llui/llbadge.h Normal file
View File

@ -0,0 +1,159 @@
/**
* @file llbadge.h
* @brief Header for badges
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLBADGE_H
#define LL_LLBADGE_H
#include <string>
#include "lluicolor.h"
#include "lluictrl.h"
#include "llstring.h"
#include "lluiimage.h"
#include "llview.h"
//
// Declarations
//
class LLUICtrlFactory;
class LLFontGL;
//
// Relative Position Alignment
//
namespace LLRelPos
{
enum Location
{
CENTER = 0,
LEFT = (1 << 0),
RIGHT = (1 << 1),
TOP = (1 << 2),
BOTTOM = (1 << 3),
BOTTOM_LEFT = (BOTTOM | LEFT),
BOTTOM_RIGHT = (BOTTOM | RIGHT),
TOP_LEFT = (TOP | LEFT),
TOP_RIGHT = (TOP | RIGHT),
};
inline bool IsBottom(Location relPos) { return (relPos & BOTTOM) == BOTTOM; }
inline bool IsCenter(Location relPos) { return (relPos == CENTER); }
inline bool IsLeft(Location relPos) { return (relPos & LEFT) == LEFT; }
inline bool IsRight(Location relPos) { return (relPos & RIGHT) == RIGHT; }
inline bool IsTop(Location relPos) { return (relPos & TOP) == TOP; }
}
// NOTE: This needs to occur before Optional<LLRelPos::Location> declaration for proper compilation.
namespace LLInitParam
{
template<>
struct TypeValues<LLRelPos::Location> : public TypeValuesHelper<LLRelPos::Location>
{
static void declareValues();
};
}
//
// Classes
//
class LLBadge
: public LLUICtrl
{
public:
struct Params
: public LLInitParam::Block<Params, LLUICtrl::Params>
{
Optional< LLHandle<LLView> > owner; // Mandatory in code but not in xml
Optional< LLUIImage* > border_image;
Optional< LLUIColor > border_color;
Optional< LLUIImage* > image;
Optional< LLUIColor > image_color;
Optional< std::string > label;
Optional< LLUIColor > label_color;
Optional< LLRelPos::Location > location;
Optional< U32 > location_percent_hcenter;
Optional< U32 > location_percent_vcenter;
Optional< F32 > padding_horiz;
Optional< F32 > padding_vert;
Params();
bool equals(const Params&) const;
};
protected:
friend class LLUICtrlFactory;
LLBadge(const Params& p);
public:
~LLBadge();
virtual void draw();
const std::string getLabel() const { return wstring_to_utf8str(mLabel); }
void setLabel( const LLStringExplicit& label);
private:
LLPointer< LLUIImage > mBorderImage;
LLUIColor mBorderColor;
const LLFontGL* mGLFont;
LLPointer< LLUIImage > mImage;
LLUIColor mImageColor;
LLUIString mLabel;
LLUIColor mLabelColor;
LLRelPos::Location mLocation;
F32 mLocationPercentHCenter;
F32 mLocationPercentVCenter;
LLHandle< LLView > mOwner;
F32 mPaddingHoriz;
F32 mPaddingVert;
};
// Build time optimization, generate once in .cpp file
#ifndef LLBADGE_CPP
extern template class LLBadge* LLView::getChild<class LLBadge>(const std::string& name, BOOL recurse) const;
#endif
#endif // LL_LLBADGE_H

126
indra/llui/llbadgeowner.cpp Normal file
View File

@ -0,0 +1,126 @@
/**
* @file llbadgeowner.cpp
* @brief Class to manage badges attached to a UI control
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llbadgeowner.h"
#include "llpanel.h"
//
// Classes
//
LLBadgeOwner::LLBadgeOwner(LLHandle< LLView > viewHandle)
: mBadge(NULL)
, mBadgeOwnerView(viewHandle)
{
}
void LLBadgeOwner::initBadgeParams(const LLBadge::Params& p)
{
if (!p.equals(LLUICtrlFactory::getDefaultParams<LLBadge>()))
{
mBadge = createBadge(p);
}
}
void LLBadgeOwner::setBadgeLabel(const LLStringExplicit& label)
{
if (mBadge == NULL)
{
mBadge = createBadge(LLUICtrlFactory::getDefaultParams<LLBadge>());
addBadgeToParentPanel();
}
if (mBadge)
{
mBadge->setLabel(label);
//
// Push the badge to the front so it renders on top
//
LLView * parent = mBadge->getParent();
if (parent)
{
parent->sendChildToFront(mBadge);
}
}
}
void LLBadgeOwner::setBadgeVisibility(bool visible)
{
if (mBadge)
{
mBadge->setVisible(visible);
}
}
void LLBadgeOwner::addBadgeToParentPanel()
{
LLView * owner_view = mBadgeOwnerView.get();
if (mBadge && owner_view)
{
// Badge parent is badge owner by default
LLView * badge_parent = owner_view;
// Find the appropriate parent for the badge
LLView * parent = owner_view->getParent();
while (parent)
{
LLPanel * parent_panel = dynamic_cast<LLPanel *>(parent);
if (parent_panel && parent_panel->acceptsBadge())
{
badge_parent = parent;
break;
}
parent = parent->getParent();
}
if (badge_parent)
{
badge_parent->addChild(mBadge);
}
else
{
llwarns << "Unable to find parent panel for badge " << mBadge->getName() << " on " << owner_view->getName() << llendl;
}
}
}
LLBadge* LLBadgeOwner::createBadge(const LLBadge::Params& p)
{
LLBadge::Params badge_params(p);
badge_params.owner = mBadgeOwnerView;
return LLUICtrlFactory::create<LLBadge>(badge_params);
}

61
indra/llui/llbadgeowner.h Normal file
View File

@ -0,0 +1,61 @@
/**
* @file llbadgeowner.h
* @brief Header for badge owners
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLBADGEOWNER_H
#define LL_LLBADGEOWNER_H
#include "llbadge.h"
#include "llview.h"
//
// Classes
//
class LLBadgeOwner
{
public:
LLBadgeOwner(LLHandle< LLView > viewHandle);
void initBadgeParams(const LLBadge::Params& p);
void addBadgeToParentPanel();
bool badgeHasParent() const { return (mBadge && mBadge->getParent()); }
void setBadgeLabel(const LLStringExplicit& label);
void setBadgeVisibility(bool visible);
private:
LLBadge* createBadge(const LLBadge::Params& p);
private:
LLBadge* mBadge;
LLHandle< LLView > mBadgeOwnerView;
};
#endif // LL_LLBADGEOWNER_H

View File

@ -99,7 +99,9 @@ LLButton::Params::Params()
scale_image("scale_image", true),
hover_glow_amount("hover_glow_amount"),
commit_on_return("commit_on_return", true),
use_draw_context_alpha("use_draw_context_alpha", true)
use_draw_context_alpha("use_draw_context_alpha", true),
badge("badge"),
handle_right_mouse("handle_right_mouse")
{
addSynonym(is_toggle, "toggle");
held_down_delay.seconds = 0.5f;
@ -109,6 +111,7 @@ LLButton::Params::Params()
LLButton::LLButton(const LLButton::Params& p)
: LLUICtrl(p),
LLBadgeOwner(LLView::getHandle()),
mMouseDownFrame(0),
mMouseHeldDownCount(0),
mBorderEnabled( FALSE ),
@ -160,8 +163,8 @@ LLButton::LLButton(const LLButton::Params& p)
mMouseDownSignal(NULL),
mMouseUpSignal(NULL),
mHeldDownSignal(NULL),
mUseDrawContextAlpha(p.use_draw_context_alpha)
mUseDrawContextAlpha(p.use_draw_context_alpha),
mHandleRightMouse(p.handle_right_mouse)
{
static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
@ -244,6 +247,11 @@ LLButton::LLButton(const LLButton::Params& p)
{
setHeldDownCallback(initCommitCallback(p.mouse_held_callback));
}
if (p.badge.isProvided())
{
LLBadgeOwner::initBadgeParams(p.badge());
}
}
LLButton::~LLButton()
@ -327,8 +335,12 @@ boost::signals2::connection LLButton::setHeldDownCallback( button_callback_t cb,
BOOL LLButton::postBuild()
{
autoResize();
return TRUE;
addBadgeToParentPanel();
return LLUICtrl::postBuild();
}
BOOL LLButton::handleUnicodeCharHere(llwchar uni_char)
{
BOOL handled = FALSE;
@ -447,7 +459,7 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
BOOL LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if (!childrenHandleRightMouseDown(x, y, mask))
if (mHandleRightMouse && !childrenHandleRightMouseDown(x, y, mask))
{
// Route future Mouse messages here preemptively. (Release on mouse up.)
gFocusMgr.setMouseCapture( this );
@ -460,37 +472,42 @@ BOOL LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask)
// if (pointInView(x, y))
// {
// }
// send the mouse down signal
LLUICtrl::handleRightMouseDown(x,y,mask);
// *TODO: Return result of LLUICtrl call above? Should defer to base class
// but this might change the mouse handling of existing buttons in a bad way
// if they are not mouse opaque.
}
// send the mouse down signal
LLUICtrl::handleRightMouseDown(x,y,mask);
// *TODO: Return result of LLUICtrl call above? Should defer to base class
// but this might change the mouse handling of existing buttons in a bad way
// if they are not mouse opaque.
return TRUE;
}
BOOL LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask)
{
// We only handle the click if the click both started and ended within us
if( hasMouseCapture() )
if (mHandleRightMouse)
{
// Always release the mouse
gFocusMgr.setMouseCapture( NULL );
// We only handle the click if the click both started and ended within us
if( hasMouseCapture() )
{
// Always release the mouse
gFocusMgr.setMouseCapture( NULL );
// if (pointInView(x, y))
// {
// mRightMouseUpSignal(this, x,y,mask);
// }
// if (pointInView(x, y))
// {
// mRightMouseUpSignal(this, x,y,mask);
// }
}
else
{
childrenHandleRightMouseUp(x, y, mask);
}
// send the mouse up signal
LLUICtrl::handleRightMouseUp(x,y,mask);
// *TODO: Return result of LLUICtrl call above? Should defer to base class
// but this might change the mouse handling of existing buttons in a bad way.
// if they are not mouse opaque.
}
else
{
childrenHandleRightMouseUp(x, y, mask);
}
// send the mouse up signal
LLUICtrl::handleRightMouseUp(x,y,mask);
// *TODO: Return result of LLUICtrl call above? Should defer to base class
// but this might change the mouse handling of existing buttons in a bad way.
// if they are not mouse opaque.
return TRUE;
}

View File

@ -27,6 +27,8 @@
#ifndef LL_LLBUTTON_H
#define LL_LLBUTTON_H
#include "lluuid.h"
#include "llbadgeowner.h"
#include "llcontrol.h"
#include "lluictrl.h"
#include "v4color.h"
@ -52,15 +54,13 @@ S32 round_up(S32 grid, S32 value);
class LLUICtrlFactory;
class LLUIImage;
class LLUUID;
//
// Classes
//
class LLButton
: public LLUICtrl
: public LLUICtrl, public LLBadgeOwner
{
public:
struct Params
@ -125,7 +125,11 @@ public:
Optional<F32> hover_glow_amount;
Optional<TimeIntervalParam> held_down_delay;
Optional<bool> use_draw_context_alpha;
Optional<bool> use_draw_context_alpha;
Optional<LLBadge::Params> badge;
Optional<bool> handle_right_mouse;
Params();
};
@ -249,7 +253,7 @@ public:
void setImageDisabledSelected(LLPointer<LLUIImage> image);
void setImageFlash(LLPointer<LLUIImage> image);
void setImagePressed(LLPointer<LLUIImage> image);
void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
BOOL getCommitOnReturn() const { return mCommitOnReturn; }
@ -357,6 +361,8 @@ private:
bool mForcePressedState;
LLFrameTimer mFlashingTimer;
bool mHandleRightMouse;
};
// Build time optimization, generate once in .cpp file

View File

@ -49,6 +49,8 @@ void LLLayoutStack::OrientationNames::declareValues()
//
LLLayoutPanel::LLLayoutPanel(const Params& p)
: LLPanel(p),
mExpandedMinDimSpecified(false),
mExpandedMinDim(p.min_dim),
mMinDim(p.min_dim),
mMaxDim(p.max_dim),
mAutoResize(p.auto_resize),
@ -58,6 +60,13 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)
mVisibleAmt(1.f), // default to fully visible
mResizeBar(NULL)
{
// Set the expanded min dim if it is provided, otherwise it gets the p.min_dim value
if (p.expanded_min_dim.isProvided())
{
mExpandedMinDimSpecified = true;
mExpandedMinDim = p.expanded_min_dim();
}
// panels initialized as hidden should not start out partially visible
if (!getVisible())
{
@ -78,20 +87,20 @@ LLLayoutPanel::~LLLayoutPanel()
delete mResizeBar;
mResizeBar = NULL;
}
F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation)
{
if (orientation == LLLayoutStack::HORIZONTAL)
{
F32 collapse_amt =
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinDim / (F32)llmax(1, getRect().getWidth()));
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)getRelevantMinDim() / (F32)llmax(1, getRect().getWidth()));
return mVisibleAmt * collapse_amt;
}
else
{
F32 collapse_amt =
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)mMinDim / (F32)llmax(1, getRect().getHeight())));
return mVisibleAmt * collapse_amt;
F32 collapse_amt =
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)getRelevantMinDim() / (F32)llmax(1, getRect().getHeight())));
return mVisibleAmt * collapse_amt;
}
}
@ -182,14 +191,14 @@ BOOL LLLayoutStack::postBuild()
}
bool LLLayoutStack::addChild(LLView* child, S32 tab_group)
{
{
LLLayoutPanel* panelp = dynamic_cast<LLLayoutPanel*>(child);
if (panelp)
{
if (panelp)
{
mPanels.push_back(panelp);
}
}
return LLView::addChild(child, tab_group);
}
}
S32 LLLayoutStack::getDefaultHeight(S32 cur_height)
@ -281,9 +290,9 @@ bool LLLayoutStack::getPanelMinSize(const std::string& panel_name, S32* min_dimp
{
LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name);
if (panel)
if (panel && min_dimp)
{
if (min_dimp) *min_dimp = panel->mMinDim;
*min_dimp = panel->getRelevantMinDim();
}
return NULL != panel;
@ -316,23 +325,23 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
e_panel_list_t::iterator panel_it;
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLPanel* panelp = (*panel_it);
LLLayoutPanel* panelp = (*panel_it);
if (panelp->getVisible())
{
if (mAnimate)
{
if (!mAnimatedThisFrame)
{
(*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(mOpenTimeConstant));
if ((*panel_it)->mVisibleAmt > 0.99f)
panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(mOpenTimeConstant));
if (panelp->mVisibleAmt > 0.99f)
{
(*panel_it)->mVisibleAmt = 1.f;
panelp->mVisibleAmt = 1.f;
}
}
}
else
{
(*panel_it)->mVisibleAmt = 1.f;
panelp->mVisibleAmt = 1.f;
}
}
else // not visible
@ -341,36 +350,36 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
{
if (!mAnimatedThisFrame)
{
(*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
if ((*panel_it)->mVisibleAmt < 0.001f)
panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
if (panelp->mVisibleAmt < 0.001f)
{
(*panel_it)->mVisibleAmt = 0.f;
panelp->mVisibleAmt = 0.f;
}
}
}
else
{
(*panel_it)->mVisibleAmt = 0.f;
panelp->mVisibleAmt = 0.f;
}
}
if ((*panel_it)->mCollapsed)
if (panelp->mCollapsed)
{
(*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
}
else
{
(*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
}
if (mOrientation == HORIZONTAL)
{
// enforce minimize size constraint by default
if (panelp->getRect().getWidth() < (*panel_it)->mMinDim)
if (panelp->getRect().getWidth() < panelp->getRelevantMinDim())
{
panelp->reshape((*panel_it)->mMinDim, panelp->getRect().getHeight());
panelp->reshape(panelp->getRelevantMinDim(), panelp->getRect().getHeight());
}
total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor(mOrientation));
total_width += llround(panelp->getRect().getWidth() * panelp->getCollapseFactor(mOrientation));
// want n-1 panel gaps for n panels
if (panel_it != mPanels.begin())
{
@ -380,11 +389,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
else //VERTICAL
{
// enforce minimize size constraint by default
if (panelp->getRect().getHeight() < (*panel_it)->mMinDim)
if (panelp->getRect().getHeight() < panelp->getRelevantMinDim())
{
panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinDim);
panelp->reshape(panelp->getRect().getWidth(), panelp->getRelevantMinDim());
}
total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor(mOrientation));
total_height += llround(panelp->getRect().getHeight() * panelp->getCollapseFactor(mOrientation));
if (panel_it != mPanels.begin())
{
total_height += mPanelSpacing;
@ -403,34 +412,23 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
continue;
}
S32 relevant_dimension = (mOrientation == HORIZONTAL) ? (*panel_it)->getRect().getWidth() : (*panel_it)->getRect().getHeight();
S32 relevant_min = (*panel_it)->getRelevantMinDim();
// if currently resizing a panel or the panel is flagged as not automatically resizing
// only track total available headroom, but don't use it for automatic resize logic
if ((*panel_it)->mResizeBar->hasMouseCapture()
|| (!(*panel_it)->mAutoResize
&& !force_resize))
{
if (mOrientation == HORIZONTAL)
{
shrink_headroom_total += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim;
}
else //VERTICAL
{
shrink_headroom_total += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim;
}
shrink_headroom_total += relevant_dimension - relevant_min;
}
else
{
num_resizable_panels++;
if (mOrientation == HORIZONTAL)
{
shrink_headroom_available += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim;
shrink_headroom_total += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim;
}
else //VERTICAL
{
shrink_headroom_available += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim;
shrink_headroom_total += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim;
}
shrink_headroom_available += relevant_dimension - relevant_min;
shrink_headroom_total += relevant_dimension - relevant_min;
}
}
@ -452,27 +450,28 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLPanel* panelp = (*panel_it);
LLLayoutPanel* panelp = (*panel_it);
S32 cur_width = panelp->getRect().getWidth();
S32 cur_height = panelp->getRect().getHeight();
S32 new_width = cur_width;
S32 new_height = cur_height;
S32 new_height = cur_height;
S32 relevant_min = panelp->getRelevantMinDim();
if (mOrientation == HORIZONTAL)
{
new_width = llmax((*panel_it)->mMinDim, new_width);
new_width = llmax(relevant_min, new_width);
}
else
{
new_height = llmax((*panel_it)->mMinDim, new_height);
new_height = llmax(relevant_min, new_height);
}
S32 delta_size = 0;
// if panel can automatically resize (not animating, and resize flag set)...
if ((*panel_it)->getCollapseFactor(mOrientation) == 1.f
&& (force_resize || (*panel_it)->mAutoResize)
&& !(*panel_it)->mResizeBar->hasMouseCapture())
if (panelp->getCollapseFactor(mOrientation) == 1.f
&& (force_resize || panelp->mAutoResize)
&& !panelp->mResizeBar->hasMouseCapture())
{
if (mOrientation == HORIZONTAL)
{
@ -481,8 +480,8 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
{
// shrink proportionally to amount over minimum
// so we can do this in one pass
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - (*panel_it)->mMinDim) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_width - (*panel_it)->mMinDim);
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - relevant_min) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_width - relevant_min);
}
else
{
@ -491,7 +490,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
num_resizable_panels--;
}
pixels_to_distribute -= delta_size;
new_width = llmax((*panel_it)->mMinDim, cur_width + delta_size);
new_width = llmax(relevant_min, cur_width + delta_size);
}
else
{
@ -504,8 +503,8 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
{
// shrink proportionally to amount over minimum
// so we can do this in one pass
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - (*panel_it)->mMinDim) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_height - (*panel_it)->mMinDim);
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - relevant_min) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_height - relevant_min);
}
else
{
@ -513,7 +512,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
num_resizable_panels--;
}
pixels_to_distribute -= delta_size;
new_height = llmax((*panel_it)->mMinDim, cur_height + delta_size);
new_height = llmax(relevant_min, cur_height + delta_size);
}
else
{
@ -566,19 +565,20 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
LLLayoutPanel* last_resizeable_panel = NULL;
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLPanel* panelp = (*panel_it);
LLLayoutPanel* panelp = (*panel_it);
S32 relevant_min = panelp->getRelevantMinDim();
if (mOrientation == HORIZONTAL)
{
(*panel_it)->mResizeBar->setResizeLimits(
(*panel_it)->mMinDim,
(*panel_it)->mMinDim + shrink_headroom_total);
relevant_min,
relevant_min + shrink_headroom_total);
}
else //VERTICAL
{
(*panel_it)->mResizeBar->setResizeLimits(
(*panel_it)->mMinDim,
(*panel_it)->mMinDim + shrink_headroom_total);
relevant_min,
relevant_min + shrink_headroom_total);
}
// toggle resize bars based on panel visibility, resizability, etc
@ -658,7 +658,7 @@ void LLLayoutStack::calcMinExtents()
{
if (mOrientation == HORIZONTAL)
{
mMinWidth += (*panel_it)->mMinDim;
mMinWidth += (*panel_it)->getRelevantMinDim();
if (panel_it != mPanels.begin())
{
mMinWidth += mPanelSpacing;
@ -666,7 +666,7 @@ void LLLayoutStack::calcMinExtents()
}
else //VERTICAL
{
mMinHeight += (*panel_it)->mMinDim;
mMinHeight += (*panel_it)->getRelevantMinDim();
if (panel_it != mPanels.begin())
{
mMinHeight += mPanelSpacing;
@ -688,7 +688,7 @@ void LLLayoutStack::createResizeBars()
LLResizeBar::Params resize_params;
resize_params.name("resize");
resize_params.resizing_view(lp);
resize_params.min_size(lp->mMinDim);
resize_params.min_size(lp->getRelevantMinDim());
resize_params.side(side);
resize_params.snapping_enabled(false);
LLResizeBar* resize_bar = LLUICtrlFactory::create<LLResizeBar>(resize_params);

View File

@ -30,10 +30,10 @@
#include "llpanel.h"
class LLPanel;
class LLLayoutPanel;
class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack>
{
public:
@ -149,6 +149,7 @@ private:
F32 mCloseTimeConstant;
}; // end class LLLayoutStack
class LLLayoutPanel : public LLPanel
{
friend class LLLayoutStack;
@ -156,13 +157,15 @@ friend class LLUICtrlFactory;
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
Optional<S32> min_dim,
Optional<S32> expanded_min_dim,
min_dim,
max_dim;
Optional<bool> user_resize,
auto_resize;
Params()
: min_dim("min_dim", 0),
: expanded_min_dim("expanded_min_dim", 0),
min_dim("min_dim", 0),
max_dim("max_dim", 0),
user_resize("user_resize", true),
auto_resize("auto_resize", true)
@ -177,15 +180,36 @@ public:
~LLLayoutPanel();
void initFromParams(const Params& p);
void setMinDim(S32 value) { mMinDim = value; }
S32 getMinDim() const { return mMinDim; }
void setMinDim(S32 value) { mMinDim = value; if (!mExpandedMinDimSpecified) mExpandedMinDim = value; }
S32 getMaxDim() const { return mMaxDim; }
void setMaxDim(S32 value) { mMaxDim = value; }
protected:
LLLayoutPanel(const Params& p) ;
S32 getExpandedMinDim() const { return mExpandedMinDim; }
void setExpandedMinDim(S32 value) { mExpandedMinDim = value; mExpandedMinDimSpecified = true; }
S32 getRelevantMinDim() const
{
S32 min_dim = mMinDim;
if (!mCollapsed)
{
min_dim = mExpandedMinDim;
}
return min_dim;
}
protected:
LLLayoutPanel(const Params& p);
F32 getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation);
bool mExpandedMinDimSpecified;
S32 mExpandedMinDim;
S32 mMinDim;
S32 mMaxDim;
BOOL mAutoResize;

View File

@ -86,6 +86,8 @@ public:
*/
void start();
void reset() { mCurImageIdx = 0; }
private:
LLLoadingIndicator(const Params&);
void initFromParams(const Params&);

View File

@ -87,7 +87,8 @@ LLPanel::Params::Params()
filename("filename"),
class_name("class"),
help_topic("help_topic"),
visible_callback("visible_callback")
visible_callback("visible_callback"),
accepts_badge("accepts_badge")
{
name = "panel";
addSynonym(background_visible, "bg_visible");
@ -113,7 +114,8 @@ LLPanel::LLPanel(const LLPanel::Params& p)
mCommitCallbackRegistrar(false),
mEnableCallbackRegistrar(false),
mXMLFilename(p.filename),
mVisibleSignal(NULL)
mVisibleSignal(NULL),
mAcceptsBadge(p.accepts_badge)
// *NOTE: Be sure to also change LLPanel::initFromParams(). We have too
// many classes derived from LLPanel to retrofit them all to pass in params.
{
@ -485,6 +487,8 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
mBgAlphaImage = p.bg_alpha_image();
mBgOpaqueImageOverlay = p.bg_opaque_image_overlay;
mBgAlphaImageOverlay = p.bg_alpha_image_overlay;
mAcceptsBadge = p.accepts_badge;
}
static LLFastTimer::DeclareTimer FTM_PANEL_SETUP("Panel Setup");

View File

@ -89,6 +89,8 @@ public:
Multiple<LocalizedString> strings;
Optional<CommitCallbackParam> visible_callback;
Optional<bool> accepts_badge;
Params();
};
@ -250,6 +252,8 @@ public:
boost::signals2::connection setVisibleCallback( const commit_signal_t::slot_type& cb );
bool acceptsBadge() const { return mAcceptsBadge; }
protected:
// Override to set not found list
LLButton* getDefaultButton() { return mDefaultBtn; }
@ -264,6 +268,7 @@ protected:
static factory_stack_t sFactoryStack;
private:
bool mAcceptsBadge;
BOOL mBgVisible; // any background at all?
BOOL mBgOpaque; // use opaque color or image
LLUIColor mBgOpaqueColor;

View File

@ -68,6 +68,7 @@ LLUICtrl::ControlVisibility::ControlVisibility()
LLUICtrl::Params::Params()
: tab_stop("tab_stop", true),
chrome("chrome", false),
requests_front("requests_front", false),
label("label"),
initial_value("value"),
init_callback("init_callback"),
@ -96,9 +97,10 @@ const LLUICtrl::Params& LLUICtrl::getDefaultParams()
LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
: LLView(p),
mTentative(FALSE),
mIsChrome(FALSE),
mRequestsFront(p.requests_front),
mTabStop(FALSE),
mTentative(FALSE),
mViewModel(viewmodel),
mControlVariable(NULL),
mEnabledControlVariable(NULL),
@ -123,6 +125,8 @@ void LLUICtrl::initFromParams(const Params& p)
{
LLView::initFromParams(p);
mRequestsFront = p.requests_front;
setIsChrome(p.chrome);
setControlName(p.control_name);
if(p.enabled_controls.isProvided())
@ -403,6 +407,36 @@ LLViewModel* LLUICtrl::getViewModel() const
return mViewModel;
}
//virtual
BOOL LLUICtrl::postBuild()
{
//
// Find all of the children that want to be in front and move them to the front
//
if (getChildCount() > 0)
{
std::vector<LLUICtrl*> childrenToMoveToFront;
for (LLView::child_list_const_iter_t child_it = beginChild(); child_it != endChild(); ++child_it)
{
LLUICtrl* uictrl = dynamic_cast<LLUICtrl*>(*child_it);
if (uictrl && uictrl->mRequestsFront)
{
childrenToMoveToFront.push_back(uictrl);
}
}
for (std::vector<LLUICtrl*>::iterator it = childrenToMoveToFront.begin(); it != childrenToMoveToFront.end(); ++it)
{
sendChildToFront(*it);
}
}
return LLView::postBuild();
}
bool LLUICtrl::setControlValue(const LLSD& value)
{
if (mControlVariable)

View File

@ -94,7 +94,8 @@ public:
{
Optional<std::string> label;
Optional<bool> tab_stop,
chrome;
chrome,
requests_front;
Optional<LLSD> initial_value;
Optional<CommitCallbackParam> init_callback,
@ -143,6 +144,8 @@ protected:
virtual LLViewModel* getViewModel() const;
// We shouldn't ever need to set this directly
//virtual void setViewModel(const LLViewModelPtr&);
virtual BOOL postBuild();
public:
// LLView interface
@ -301,8 +304,9 @@ protected:
private:
BOOL mTabStop;
BOOL mIsChrome;
BOOL mRequestsFront;
BOOL mTabStop;
BOOL mTentative;
LLRootHandle<LLUICtrl> mUICtrlHandle;

View File

@ -1299,15 +1299,7 @@ void LLView::drawChildren()
{
if (!mChildList.empty())
{
static const LLRect* rootRect = NULL;
if (!mParentView)
{
rootRect = &mRect;
}
LLRect screenRect;
LLView* rootp = LLUI::getRootView();
++sDepth;
for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend();) // ++child_iter)
@ -1317,9 +1309,8 @@ void LLView::drawChildren()
if (viewp->getVisible() && viewp->getRect().isValid())
{
// Only draw views that are within the root view
localRectToScreen(viewp->getRect(),&screenRect);
if ( rootRect->overlaps(screenRect) && LLUI::sDirtyRect.overlaps(screenRect))
LLRect screen_rect = viewp->calcScreenRect();
if ( rootp->getLocalRect().overlaps(screen_rect) && LLUI::sDirtyRect.overlaps(screen_rect))
{
LLUI::pushMatrix();
{

View File

@ -95,7 +95,7 @@ namespace LLInitParam
{
const U8* my_addr = reinterpret_cast<const U8*>(this);
const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
mEnclosingBlockOffset = (U16)(my_addr - block_addr);
mEnclosingBlockOffset = 0x7FFFffff & ((U32)(my_addr - block_addr));
}
bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; }

View File

@ -40,7 +40,7 @@ namespace LLInitParam
{
const U8* my_addr = reinterpret_cast<const U8*>(this);
const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
mEnclosingBlockOffset = (U16)(my_addr - block_addr);
mEnclosingBlockOffset = 0x7FFFffff & ((U32)(my_addr - block_addr));
}
//

View File

@ -34,6 +34,8 @@
#include <boost/unordered_map.hpp>
#include <boost/shared_ptr.hpp>
#include "llerror.h"
namespace LLInitParam
{
template<typename T> const T& defaultValue() { static T value; return value; }
@ -302,8 +304,9 @@ namespace LLInitParam
private:
friend class BaseBlock;
U16 mEnclosingBlockOffset;
bool mIsProvided;
U32 mEnclosingBlockOffset:31;
U32 mIsProvided:1;
};
// various callbacks and constraints associated with an individual param

View File

@ -1168,19 +1168,11 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
authResponse(message_in);
}
else
if(message_name == "js_expose_object")
if(message_name == "js_enable_object")
{
#if LLQTWEBKIT_API_VERSION >= 9
bool expose_object = message_in.getValueBoolean( "expose" );
LLQtWebKit::getInstance()->setExposeObject( expose_object );
#endif
}
else
if(message_name == "js_values_valid")
{
#if LLQTWEBKIT_API_VERSION >= 9
bool valid = message_in.getValueBoolean( "valid" );
LLQtWebKit::getInstance()->setValuesValid( valid );
bool enable = message_in.getValueBoolean( "enable" );
LLQtWebKit::getInstance()->setSLObjectEnabled( enable );
#endif
}
else
@ -1191,6 +1183,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
F32 y = message_in.getValueReal("y");
F32 z = message_in.getValueReal("z");
LLQtWebKit::getInstance()->setAgentLocation( x, y, z );
LLQtWebKit::getInstance()->emitLocation();
#endif
}
else
@ -1201,6 +1194,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
F32 y = message_in.getValueReal("y");
F32 z = message_in.getValueReal("z");
LLQtWebKit::getInstance()->setAgentGlobalLocation( x, y, z );
LLQtWebKit::getInstance()->emitLocation();
#endif
}
else
@ -1209,6 +1203,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
#if LLQTWEBKIT_API_VERSION >= 9
F32 angle = message_in.getValueReal("angle");
LLQtWebKit::getInstance()->setAgentOrientation( angle );
LLQtWebKit::getInstance()->emitLocation();
#endif
}
else
@ -1217,14 +1212,25 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
#if LLQTWEBKIT_API_VERSION >= 9
const std::string& region = message_in.getValue("region");
LLQtWebKit::getInstance()->setAgentRegion( region );
LLQtWebKit::getInstance()->emitLocation();
#endif
}
else
if(message_name == "js_agent_maturity")
if(message_name == "js_agent_maturity")
{
#if LLQTWEBKIT_API_VERSION >= 9
const std::string& maturity = message_in.getValue("maturity");
LLQtWebKit::getInstance()->setAgentMaturity( maturity );
LLQtWebKit::getInstance()->emitMaturity();
#endif
}
else
if(message_name == "js_agent_language")
{
#if LLQTWEBKIT_API_VERSION >= 9
const std::string& maturity = message_in.getValue("maturity");
LLQtWebKit::getInstance()->setAgentMaturity( maturity );
const std::string& language = message_in.getValue("language");
LLQtWebKit::getInstance()->setAgentLanguage( language );
LLQtWebKit::getInstance()->emitLanguage();
#endif
}
else
@ -1384,3 +1390,5 @@ int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void
return 0;
}

View File

@ -363,6 +363,9 @@ set(viewer_SOURCE_FILES
llpanellogin.cpp
llpanelloginlistener.cpp
llpanelmaininventory.cpp
llpanelmarketplaceinbox.cpp
llpanelmarketplaceinboxinventory.cpp
llpanelmarketplaceoutbox.cpp
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
@ -913,6 +916,9 @@ set(viewer_HEADER_FILES
llpanellogin.h
llpanelloginlistener.h
llpanelmaininventory.h
llpanelmarketplaceinbox.h
llpanelmarketplaceinboxinventory.h
llpanelmarketplaceoutbox.h
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
@ -1470,7 +1476,7 @@ set(PACKAGE ON CACHE BOOL
"Add a package target that builds an installer package.")
if (WINDOWS)
set_target_properties(${VIEWER_BINARY_NAME}
set_target_properties(${VIEWER_BINARY_NAME}
PROPERTIES
# *TODO -reenable this once we get server usage sorted out
#LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\""

View File

@ -181,7 +181,7 @@
<binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/>
</third_person>
# Basic editing camera control
<!-- Basic editing camera control -->
<edit>
<binding key="A" mask="NONE" command="spin_around_cw"/>
<binding key="D" mask="NONE" command="spin_around_ccw"/>

View File

@ -4179,6 +4179,28 @@
<string>F32</string>
<key>Value</key>
<real>1.0</real>
</map>
<key>InventoryDisplayInbox</key>
<map>
<key>Comment</key>
<string>Override received items inventory inbox display</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>InventoryDisplayOutbox</key>
<map>
<key>Comment</key>
<string>Override merchant inventory outbox display</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>InventoryLinking</key>
<map>
@ -4422,6 +4444,17 @@
<key>Value</key>
<real>2.0</real>
</map>
<key>LastInventoryInboxExpand</key>
<map>
<key>Comment</key>
<string>The last time the received items inbox was expanded.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string />
</map>
<key>LCDDestination</key>
<map>
<key>Comment</key>
@ -6546,7 +6579,28 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>PostFirstLoginIntroURL</key>
<map>
<key>Comment</key>
<string>URL of intro presenatation after first time users first login</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string></string>
</map>
<key>PostFirstLoginIntroViewed</key>
<map>
<key>Comment</key>
<string>Flag indicating if user has seen intro presenatation after first time users first login</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<string>0</string>
</map>
<key>PrecachingDelay</key>
<map>
<key>Comment</key>
@ -7182,7 +7236,7 @@
</array>
</map>
<key>RenderAnisotropic</key>
<key>RenderAnisotropic</key>
<map>
<key>Comment</key>
<string>Render textures using anisotropic filtering</string>
@ -9627,7 +9681,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
<integer>1</integer>
</map>
<key>ShowSnapshotButton</key>
<map>
@ -13346,5 +13400,43 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>WebProfileRect</key>
<map>
<key>Comment</key>
<string>Web profile dimensions</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Rect</string>
<key>Value</key>
<array>
<integer>0</integer>
<integer>650</integer>
<integer>490</integer>
<integer>0</integer>
</array>
</map>
<key>HelpFloaterOpen</key>
<map>
<key>Comment</key>
<string>Show Help Floater on login?</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>ShowHelpOnFirstLogin</key>
<map>
<key>Comment</key>
<string>Show Help Floater on first login</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
</map>
</llsd>

View File

@ -459,5 +459,16 @@
<key>Value</key>
<integer>0</integer>
</map>
</map>
<key>ShowHelpOnFirstLogin</key>
<map>
<key>Comment</key>
<string>Show Help Floater on first login</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
</map>
</llsd>

View File

@ -33,7 +33,6 @@
#include "llagentwearablesfetch.h"
#include "llappearancemgr.h"
#include "llcallbacklist.h"
#include "llfolderview.h"
#include "llgesturemgr.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
@ -45,6 +44,7 @@
#include "llsidepanelappearance.h"
#include "llsidetray.h"
#include "lltexlayer.h"
#include "lltooldraganddrop.h"
#include "llviewerregion.h"
#include "llvoavatarself.h"
#include "llwearable.h"

View File

@ -49,6 +49,7 @@
#include "llfloaterpay.h"
#include "llfloaterwebcontent.h"
#include "llfloaterworldmap.h"
#include "llfolderview.h"
#include "llgiveinventory.h"
#include "llinventorybridge.h"
#include "llinventorymodel.h" // for gInventory.findCategoryUUIDForType
@ -69,6 +70,7 @@
#include "lltrans.h"
#include "llcallingcard.h"
#include "llslurl.h" // IDEVO
#include "llsidepanelinventory.h"
// static
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
@ -312,7 +314,9 @@ static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarNa
std::string url = getProfileURL(username);
// PROFILES: open in webkit window
LLWeb::loadWebURLInternal(url, "", agent_id.asString());
const bool show_chrome = false;
static LLCachedControl<LLRect> profile_rect(gSavedSettings, "WebProfileRect");
LLFloaterWebContent::create(url, "", agent_id.asString(), show_chrome, profile_rect);
}
// static
@ -444,8 +448,6 @@ void LLAvatarActions::share(const LLUUID& id)
namespace action_give_inventory
{
typedef std::set<LLUUID> uuid_set_t;
/**
* Returns a pointer to 'Add More' inventory panel of Edit Outfit SP.
*/
@ -475,18 +477,16 @@ namespace action_give_inventory
/**
* Checks My Inventory visibility.
*/
static bool is_give_inventory_acceptable()
{
LLInventoryPanel* active_panel = get_active_inventory_panel();
if (!active_panel) return false;
// check selection in the panel
const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
if (inventory_selected_uuids.empty()) return false; // nothing selected
bool acceptable = false;
uuid_set_t::const_iterator it = inventory_selected_uuids.begin();
const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end();
std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();
for (; it != it_end; ++it)
{
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
@ -529,12 +529,12 @@ namespace action_give_inventory
}
}
static void build_items_string(const uuid_set_t& inventory_selected_uuids , std::string& items_string)
static void build_items_string(const std::set<LLUUID>& inventory_selected_uuids , std::string& items_string)
{
llassert(inventory_selected_uuids.size() > 0);
const std::string& separator = LLTrans::getString("words_separator");
for (uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); ; )
for (std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); ; )
{
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
if (NULL != inv_cat)
@ -570,10 +570,7 @@ namespace action_give_inventory
return;
}
LLInventoryPanel* active_panel = get_active_inventory_panel();
if (!active_panel) return;
const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
if (inventory_selected_uuids.empty())
{
return;
@ -590,8 +587,8 @@ namespace action_give_inventory
// We souldn't open IM session, just calculate session ID for logging purpose. See EXT-6710
const LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, avatar_uuid);
uuid_set_t::const_iterator it = inventory_selected_uuids.begin();
const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end();
std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();
const std::string& separator = LLTrans::getString("words_separator");
std::string noncopy_item_names;
@ -654,10 +651,7 @@ namespace action_give_inventory
{
llassert(avatar_names.size() == avatar_uuids.size());
LLInventoryPanel* active_panel = get_active_inventory_panel();
if (!active_panel) return;
const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
if (inventory_selected_uuids.empty())
{
return;
@ -678,6 +672,33 @@ namespace action_give_inventory
}
}
//static
std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
{
std::set<LLUUID> inventory_selected_uuids;
LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel();
if (active_panel)
{
inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
}
if (inventory_selected_uuids.empty())
{
LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
LLInventoryPanel * inbox = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox");
if (inbox)
{
inventory_selected_uuids = inbox->getRootFolder()->getSelectionList();
}
}
return inventory_selected_uuids;
}
//static
void LLAvatarActions::shareWithAvatars()
{
@ -705,12 +726,12 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
// check selection in the panel
LLFolderView* root_folder = inv_panel->getRootFolder();
const uuid_set_t inventory_selected_uuids = root_folder->getSelectionList();
const std::set<LLUUID> inventory_selected_uuids = root_folder->getSelectionList();
if (inventory_selected_uuids.empty()) return false; // nothing selected
bool can_share = true;
uuid_set_t::const_iterator it = inventory_selected_uuids.begin();
const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end();
std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();
for (; it != it_end; ++it)
{
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);

View File

@ -36,6 +36,7 @@
class LLInventoryPanel;
/**
* Friend-related actions (add, remove, offer teleport, etc)
*/
@ -196,6 +197,8 @@ public:
*/
static bool canShareSelectedItems(LLInventoryPanel* inv_panel = NULL);
static std::set<LLUUID> getInventorySelectedUUIDs();
private:
static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);
static bool handleRemove(const LLSD& notification, const LLSD& response);

View File

@ -31,6 +31,7 @@
#include "llinventoryfunctions.h"
#include "llinventoryitemslist.h"
#include "llinventorymodel.h"
#include "llviewerinventory.h"
LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, LLInventoryCollectFunctor* collector)

View File

@ -71,9 +71,18 @@ void LLFloaterHelpBrowser::buildURLHistory()
}
}
void LLFloaterHelpBrowser::onOpen(const LLSD& key)
{
gSavedSettings.setBOOL("HelpFloaterOpen", TRUE);
}
//virtual
void LLFloaterHelpBrowser::onClose(bool app_quitting)
{
if (!app_quitting)
{
gSavedSettings.setBOOL("HelpFloaterOpen", FALSE);
}
// really really destroy the help browser when it's closed, it'll be recreated.
destroy(); // really destroy this dialog on closure, it's relatively heavyweight.
}

View File

@ -42,6 +42,7 @@ class LLFloaterHelpBrowser :
/*virtual*/ BOOL postBuild();
/*virtual*/ void onClose(bool app_quitting);
/*virtual*/ void onOpen(const LLSD& key);
// inherited from LLViewerMediaObserver
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);

View File

@ -99,7 +99,7 @@ void LLFloaterWebContent::initializeURLHistory()
}
//static
void LLFloaterWebContent::create( const std::string &url, const std::string& target, const std::string& uuid )
void LLFloaterWebContent::create( const std::string &url, const std::string& target, const std::string& uuid, bool show_chrome, const LLRect& preferred_media_size)
{
lldebugs << "url = " << url << ", target = " << target << ", uuid = " << uuid << llendl;
@ -155,6 +155,20 @@ void LLFloaterWebContent::create( const std::string &url, const std::string& tar
// tell the browser instance to load the specified URL
browser->open_media(url, target);
LLViewerMedia::proxyWindowOpened(target, uuid);
browser->getChild<LLLayoutPanel>("status_bar")->setVisible(show_chrome);
browser->getChild<LLLayoutPanel>("nav_controls")->setVisible(show_chrome);
if (!show_chrome)
{
browser->setResizeLimits(100, 100);
}
if (!preferred_media_size.isEmpty())
{
//ignore x, y for now
browser->geometryChanged(browser->getRect().mLeft, browser->getRect().mBottom, preferred_media_size.getWidth(), preferred_media_size.getHeight());
}
}
}
@ -210,7 +224,7 @@ void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height)
lldebugs << "geometry change: " << geom << llendl;
handleReshape(geom,false);
setShape(geom);
}
void LLFloaterWebContent::open_media(const std::string& web_url, const std::string& target)

View File

@ -46,7 +46,7 @@ public:
void initializeURLHistory();
static void create(const std::string &url, const std::string& target, const std::string& uuid = LLStringUtil::null);
static void create(const std::string &url, const std::string& target, const std::string& uuid = LLStringUtil::null, bool show_chrome = true, const LLRect& preferred_media_size = LLRect() );
static void closeRequest(const std::string &uuid);
static void geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height);

View File

@ -167,13 +167,23 @@ void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
///----------------------------------------------------------------------------
/// Class LLFolderView
///----------------------------------------------------------------------------
LLFolderView::Params::Params()
: task_id("task_id"),
title("title"),
use_label_suffix("use_label_suffix"),
allow_multiselect("allow_multiselect", true),
show_load_status("show_load_status", true),
use_ellipses("use_ellipses", false)
{
}
// Default constructor
LLFolderView::LLFolderView(const Params& p)
: LLFolderViewFolder(p),
mScrollContainer( NULL ),
mPopupMenuHandle(),
mAllowMultiSelect(TRUE),
mAllowMultiSelect(p.allow_multiselect),
mShowFolderHierarchy(FALSE),
mSourceID(p.task_id),
mRenameItem( NULL ),
@ -194,10 +204,14 @@ LLFolderView::LLFolderView(const Params& p)
mDragAndDropThisFrame(FALSE),
mCallbackRegistrar(NULL),
mParentPanel(p.parent_panel),
mUseEllipses(false),
mUseEllipses(p.use_ellipses),
mDraggingOverItem(NULL),
mStatusTextBox(NULL)
{
mRoot = this;
mShowLoadStatus = p.show_load_status();
LLRect rect = p.rect;
LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
setRect( rect );
@ -263,6 +277,7 @@ LLFolderView::LLFolderView(const Params& p)
menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
mPopupMenuHandle = menu->getHandle();
mListener->openItem();
}
// Destroys the object
@ -308,15 +323,10 @@ void LLFolderView::setSortOrder(U32 order)
if (order != mSortOrder)
{
LLFastTimer t(FTM_SORT);
mSortOrder = order;
for (folders_t::iterator iter = mFolders.begin();
iter != mFolders.end();)
{
folders_t::iterator fit = iter++;
(*fit)->sortBy(order);
}
sortBy(order);
arrangeAll();
}
}
@ -342,7 +352,7 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
{
recursiveIncrementNumDescendantsSelected(folder->numSelected());
}
folder->setShowLoadStatus(true);
folder->setShowLoadStatus(mShowLoadStatus);
folder->setOrigin(0, 0);
folder->reshape(getRect().getWidth(), 0);
folder->setVisible(FALSE);
@ -424,11 +434,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
(folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter
}
// Need to call arrange regardless of visibility, since children's visibility
// might need to be changed too (e.g. even though a folder is invisible, its
// children also need to be set invisible for state-tracking purposes, e.g.
// llfolderviewitem::filter).
// if (folderp->getVisible())
if (folderp->getVisible())
{
S32 child_height = 0;
S32 child_width = 0;
@ -764,7 +770,7 @@ void LLFolderView::sanitizeSelection()
}
// Don't allow invisible items (such as root folders) to be selected.
if (item->getHidden())
if (item == getRoot())
{
items_to_remove.push_back(item);
}
@ -787,7 +793,7 @@ void LLFolderView::sanitizeSelection()
parent_folder;
parent_folder = parent_folder->getParentFolder())
{
if (parent_folder->potentiallyVisible() && !parent_folder->getHidden())
if (parent_folder->potentiallyVisible())
{
// give initial selection to first ancestor folder that potentially passes the filter
if (!new_selection)
@ -806,13 +812,7 @@ void LLFolderView::sanitizeSelection()
}
else
{
// nothing selected to start with, so pick "My Inventory" as best guess
new_selection = getItemByID(gInventory.getRootFolderID());
// ... except if it's hidden from the UI.
if (new_selection && new_selection->getHidden())
{
new_selection = NULL;
}
new_selection = NULL;
}
if (new_selection)
@ -931,14 +931,15 @@ void LLFolderView::draw()
if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())
{
mStatusText = LLTrans::getString("Searching");
//font->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
}
else
{
LLStringUtil::format_map_t args;
args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig());
mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage(), args);
//font->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
if (getFilter())
{
LLStringUtil::format_map_t args;
args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig());
mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage(), args);
}
}
mStatusTextBox->setValue(mStatusText);
mStatusTextBox->setVisible( TRUE );
@ -962,7 +963,9 @@ void LLFolderView::draw()
}
LLFolderViewFolder::draw();
// skip over LLFolderViewFolder::draw since we don't want the folder icon, label,
// and arrow for the root folder
LLView::draw();
mDragAndDropThisFrame = FALSE;
}
@ -1642,11 +1645,7 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
LLFolderViewItem* parent_folder = last_selected->getParentFolder();
if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder())
{
// Don't change selectin to hidden folder. See EXT-5328.
if (!parent_folder->getHidden())
{
setSelection(parent_folder, FALSE, TRUE);
}
setSelection(parent_folder, FALSE, TRUE);
}
else
{
@ -1927,8 +1926,11 @@ void LLFolderView::deleteAllChildren()
closeRenamer();
LLView::deleteViewByHandle(mPopupMenuHandle);
mPopupMenuHandle = LLHandle<LLView>();
mRenamer = NULL;
mScrollContainer = NULL;
mRenameItem = NULL;
mRenamer = NULL;
mStatusTextBox = NULL;
clearSelection();
LLView::deleteAllChildren();
}
@ -2031,7 +2033,7 @@ void LLFolderView::removeItemID(const LLUUID& id)
LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
{
if (id.isNull())
if (id == getListener()->getUUID())
{
return this;
}
@ -2048,7 +2050,7 @@ LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id)
{
if (id.isNull())
if (id == getListener()->getUUID())
{
return this;
}
@ -2173,7 +2175,7 @@ void LLFolderView::doIdle()
// filter to determine visiblity before arranging
filterFromRoot();
// automatically show matching items, and select first one
// automatically show matching items, and select first one if we had a selection
// do this every frame until user puts keyboard focus into the inventory window
// signaling the end of the automatic update
// only do this when mNeedsFilter is set, meaning filtered items have
@ -2183,7 +2185,7 @@ void LLFolderView::doIdle()
LLFastTimer t3(FTM_AUTO_SELECT);
// select new item only if a filtered item not currently selected
LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
if ((!selected_itemp || !selected_itemp->getFiltered()) && !mAutoSelectOverride)
if ((selected_itemp && !selected_itemp->getFiltered()) && !mAutoSelectOverride)
{
// select first filtered item
LLSelectFirstFilteredItem filter;
@ -2496,11 +2498,6 @@ BOOL LLFolderView::isFilterModified()
return mFilter->isNotDefault();
}
BOOL LLFolderView::getAllowMultiSelect()
{
return mAllowMultiSelect;
}
void delete_selected_item(void* user_data)
{
if(user_data)

View File

@ -58,22 +58,6 @@ class LLScrollContainer;
class LLUICtrl;
class LLTextBox;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFolderViewFunctor
//
// Simple abstract base class for applying a functor to folders and
// items in a folder view hierarchy. This is suboptimal for algorithms
// that only work folders or only work on items, but I'll worry about
// that later when it's determined to be too slow.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLFolderViewFunctor
{
public:
virtual ~LLFolderViewFunctor() {}
virtual void doFolder(LLFolderViewFolder* folder) = 0;
virtual void doItem(LLFolderViewItem* item) = 0;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFolderView
//
@ -89,7 +73,12 @@ public:
Mandatory<LLPanel*> parent_panel;
Optional<LLUUID> task_id;
Optional<std::string> title;
Optional<bool> use_label_suffix;
Optional<bool> use_label_suffix,
allow_multiselect,
show_load_status,
use_ellipses;
Params();
};
LLFolderView(const Params&);
virtual ~LLFolderView( void );
@ -102,7 +91,6 @@ public:
// and resort the items if necessary.
void setSortOrder(U32 order);
void setFilterPermMask(PermissionMask filter_perm_mask);
void setAllowMultiSelect(BOOL allow) { mAllowMultiSelect = allow; }
typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
@ -117,7 +105,6 @@ public:
//LLInventoryFilter::EFolderShow getShowFolderState();
U32 getSortOrder() const;
BOOL isFilterModified();
BOOL getAllowMultiSelect();
// Close all folders in the view
void closeAllFolders();
@ -238,7 +225,6 @@ public:
void setShowSingleSelection(BOOL show);
BOOL getShowSingleSelection() { return mShowSingleSelection; }
F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
void setUseEllipses(bool use_ellipses) { mUseEllipses = use_ellipses; }
bool getUseEllipses() { return mUseEllipses; }
void addItemID(const LLUUID& id, LLFolderViewItem* itemp);

View File

@ -30,8 +30,10 @@
// viewer includes
#include "llfolderview.h" // Items depend extensively on LLFolderViews
#include "llfoldervieweventlistener.h"
#include "llviewerfoldertype.h"
#include "llinventorybridge.h" // for LLItemBridge in LLInventorySort::operator()
#include "llinventoryfilter.h"
#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llpanel.h"
#include "llviewercontrol.h" // gSavedSettings
@ -130,10 +132,14 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mIconOpen(p.icon_open),
mIconOverlay(p.icon_overlay),
mListener(p.listener),
mHidden(false),
mShowLoadStatus(false)
{
}
BOOL LLFolderViewItem::postBuild()
{
refresh();
return TRUE;
}
// Destroys the object
@ -195,7 +201,7 @@ LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );
// Skip over items that are invisible or are hidden from the UI.
while(itemp && (!itemp->getVisible() || itemp->getHidden()))
while(itemp && !itemp->getVisible())
{
LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );
if (itemp == next_itemp)
@ -351,7 +357,10 @@ void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
BOOL take_keyboard_focus)
{
LLFolderView* root = getRoot();
if (getParentFolder())
{
getParentFolder()->requestArrange();
}
if(set_selection)
{
setSelectionFromRoot(this, TRUE, take_keyboard_focus);
@ -442,23 +451,20 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
S32 LLFolderViewItem::getItemHeight()
{
if (getHidden()) return 0;
return mItemHeight;
}
void LLFolderViewItem::filter( LLInventoryFilter& filter)
{
const BOOL previous_passed_filter = mPassedFilter;
const BOOL passed_filter = mListener && filter.check(this);
const BOOL passed_filter = filter.check(this);
// If our visibility will change as a result of this filter, then
// we need to be rearranged in our parent folder
if (mParentFolder)
{
if (getVisible() != passed_filter)
mParentFolder->requestArrange();
if (passed_filter != previous_passed_filter)
if (getVisible() != passed_filter
|| previous_passed_filter != passed_filter )
mParentFolder->requestArrange();
}
@ -863,11 +869,6 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLFolderViewItem::draw()
{
if (getHidden())
{
return;
}
static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
@ -891,8 +892,8 @@ void LLFolderViewItem::draw()
// Draw open folder arrow
//
const bool up_to_date = mListener && mListener->isUpToDate();
const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) || // we fetched our children and some of them have passed the filter...
(!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) // we fetched our children and some of them have passed the filter...
|| (!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
if (possibly_has_children)
{
LLUIImage* arrow_image = default_params.folder_arrow_image;
@ -1054,8 +1055,11 @@ void LLFolderViewItem::draw()
{
root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();
}
if ((mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) ||
(LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() && root_is_loading && (mShowLoadStatus || mHidden)))
if ((mIsLoading
&& mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
|| (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive()
&& root_is_loading
&& mShowLoadStatus))
{
std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) ";
font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor,
@ -1119,7 +1123,8 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
mLastCalculatedWidth(0),
mCompletedFilterGeneration(-1),
mMostFilteredDescendantGeneration(-1),
mNeedsSort(false)
mNeedsSort(false),
mPassedFolderFilter(FALSE)
{
}
@ -1131,6 +1136,17 @@ LLFolderViewFolder::~LLFolderViewFolder( void )
gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
}
void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation)
{
mPassedFolderFilter = filtered;
mLastFilterGeneration = filter_generation;
}
bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation)
{
return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
}
// addToFolder() returns TRUE if it succeeds. FALSE otherwise
BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
{
@ -1157,8 +1173,6 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
mHasVisibleChildren = hasFilteredDescendants(filter_generation);
LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getFilter()->getShowFolderState();
// calculate height as a single item (without any children), and reshapes rectangle to match
LLFolderViewItem::arrange( width, height, filter_generation );
@ -1190,8 +1204,10 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
}
else
{
folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders?
(folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter
folderp->setVisible( folderp->getListener()
&& (folderp->getFiltered(filter_generation)
|| (folderp->getFilteredFolder(filter_generation)
&& folderp->hasFilteredDescendants(filter_generation)))); // passed filter or has descendants that passed filter
}
if (folderp->getVisible())
@ -1311,7 +1327,9 @@ void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recur
mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
mCompletedFilterGeneration = generation;
// only aggregate up if we are a lower (older) value
if (recurse_up && mParentFolder && generation < mParentFolder->getCompletedFilterGeneration())
if (recurse_up
&& mParentFolder
&& generation < mParentFolder->getCompletedFilterGeneration())
{
mParentFolder->setCompletedFilterGeneration(generation, TRUE);
}
@ -1336,21 +1354,19 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
// filter folder itself
if (getLastFilterGeneration() < filter_generation)
{
if (getLastFilterGeneration() >= must_pass_generation && // folder has been compared to a valid precursor filter
!mPassedFilter) // and did not pass the filter
if (getLastFilterGeneration() >= must_pass_generation // folder has been compared to a valid precursor filter
&& !mPassedFilter) // and did not pass the filter
{
// go ahead and flag this folder as done
mLastFilterGeneration = filter_generation;
}
else
else // filter self only on first pass through
{
// filter self only on first pass through
// filter against folder rules
filterFolder(filter);
// and then item rules
LLFolderViewItem::filter( filter );
}
if (mHidden)
{
setOpen();
}
}
if (getRoot()->getDebugFilters())
@ -1377,7 +1393,10 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
}
// when applying a filter, matching folders get their contents downloaded first
if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID())))
if (filter.isNotDefault()
&& getFiltered(filter.getMinRequiredGeneration())
&& (mListener
&& !gInventory.isCategoryComplete(mListener->getUUID())))
{
LLInventoryModelBackgroundFetch::instance().start(mListener->getUUID());
}
@ -1467,6 +1486,31 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
}
}
void LLFolderViewFolder::filterFolder(LLInventoryFilter& filter)
{
const BOOL previous_passed_filter = mPassedFolderFilter;
const BOOL passed_filter = filter.checkFolder(this);
// If our visibility will change as a result of this filter, then
// we need to be rearranged in our parent folder
if (mParentFolder)
{
if (getVisible() != passed_filter
|| previous_passed_filter != passed_filter )
{
mParentFolder->requestArrange();
}
}
setFilteredFolder(passed_filter, filter.getCurrentGeneration());
filter.decrementFilterCount();
if (getRoot()->getDebugFilters())
{
mStatusText = llformat("%d", mLastFilterGeneration);
}
}
void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation)
{
// if this folder is now filtered, but wasn't before
@ -1488,6 +1532,23 @@ void LLFolderViewFolder::dirtyFilter()
LLFolderViewItem::dirtyFilter();
}
BOOL LLFolderViewFolder::getFiltered()
{
return getFilteredFolder(getRoot()->getFilter()->getMinRequiredGeneration())
&& LLFolderViewItem::getFiltered();
}
BOOL LLFolderViewFolder::getFiltered(S32 filter_generation)
{
return getFilteredFolder(filter_generation) && LLFolderViewItem::getFiltered(filter_generation);
}
BOOL LLFolderViewFolder::hasFilteredDescendants(S32 filter_generation)
{
return mMostFilteredDescendantGeneration >= filter_generation;
}
BOOL LLFolderViewFolder::hasFilteredDescendants()
{
return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration();
@ -1743,7 +1804,7 @@ void LLFolderViewFolder::destroyView()
folderp->destroyView(); // removes entry from mFolders
}
deleteAllChildren();
//deleteAllChildren();
if (mParentFolder)
{
@ -1843,8 +1904,12 @@ void LLFolderViewFolder::sortBy(U32 order)
(*fit)->sortBy(order);
}
mFolders.sort(mSortFunction);
mItems.sort(mSortFunction);
// Don't sort the topmost folders (My Inventory and Library)
if (mListener->getUUID().notNull())
{
mFolders.sort(mSortFunction);
mItems.sort(mSortFunction);
}
if (order & LLInventoryFilter::SO_DATE)
{
@ -1981,6 +2046,13 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
item->dirtyFilter();
requestArrange();
requestSort();
LLFolderViewFolder* parentp = getParentFolder();
while (parentp && parentp->mSortFunction.isByDate())
{
// parent folder doesn't have a time stamp yet, so get it from us
parentp->requestSort();
parentp = parentp->getParentFolder();
}
return TRUE;
}
@ -2000,6 +2072,13 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
// rearrange all descendants too, as our indentation level might have changed
folder->requestArrange(TRUE);
requestSort();
LLFolderViewFolder* parentp = getParentFolder();
while (parentp && !parentp->mSortFunction.isByDate())
{
// parent folder doesn't have a time stamp yet, so get it from us
parentp->requestSort();
parentp = parentp->getParentFolder();
}
return TRUE;
}
@ -2059,7 +2138,9 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType r
(*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN); /* Flawfinder: ignore */
}
}
if (mParentFolder && (recurse == RECURSE_UP || recurse == RECURSE_UP_DOWN))
if (mParentFolder
&& (recurse == RECURSE_UP
|| recurse == RECURSE_UP_DOWN))
{
mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
}
@ -2301,13 +2382,16 @@ void LLFolderViewFolder::draw()
bool possibly_has_children = false;
bool up_to_date = mListener && mListener->isUpToDate();
if(!up_to_date && mListener && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
if(!up_to_date
&& mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
{
possibly_has_children = true;
}
BOOL loading = ( mIsOpen && possibly_has_children && !up_to_date );
BOOL loading = (mIsOpen
&& possibly_has_children
&& !up_to_date );
if ( loading && !mIsLoading )
{
@ -2330,6 +2414,41 @@ void LLFolderViewFolder::draw()
time_t LLFolderViewFolder::getCreationDate() const
{
// folders have no creation date try to create one from an item somewhere in our folder hierarchy
if (!mCreationDate)
{
for (items_t::const_iterator iit = mItems.begin();
iit != mItems.end(); ++iit)
{
LLFolderViewItem* itemp = (*iit);
const time_t item_creation_date = itemp->getCreationDate();
if (item_creation_date)
{
mCreationDate = item_creation_date;
break;
}
}
if (!mCreationDate)
{
for (folders_t::const_iterator fit = mFolders.begin();
fit != mFolders.end(); ++fit)
{
LLFolderViewFolder* folderp = (*fit);
const time_t folder_creation_date = folderp->getCreationDate();
if (folder_creation_date)
{
mCreationDate = folder_creation_date;
break;
}
}
}
}
return llmax<time_t>(mCreationDate, mSubtreeCreationDate);
}
@ -2573,7 +2692,8 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde
{
// ignore sort order for landmarks in the Favorites folder.
// they should be always sorted as in Favorites bar. See EXT-719
if (a->getSortGroup() == SG_ITEM && b->getSortGroup() == SG_ITEM
if (a->getSortGroup() == SG_ITEM
&& b->getSortGroup() == SG_ITEM
&& a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK
&& b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
{

View File

@ -66,6 +66,7 @@ public:
// Returns true if order has changed
bool updateSort(U32 order);
U32 getSort() { return mSortOrder; }
bool isByDate() { return mByDate; }
bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b);
private:
@ -94,7 +95,7 @@ public:
Optional<LLUIImage*> icon_open; // used for folders
Optional<LLUIImage*> icon_overlay; // for links
Optional<LLFolderView*> root;
Optional<LLFolderViewEventListener*> listener;
Mandatory<LLFolderViewEventListener*> listener;
Optional<LLUIImage*> folder_arrow_image;
Optional<S32> folder_indentation; // pixels
@ -135,7 +136,7 @@ protected:
std::string mSearchableLabel;
S32 mLabelWidth;
bool mLabelWidthDirty;
time_t mCreationDate;
mutable time_t mCreationDate;
LLFolderViewFolder* mParentFolder;
LLFolderViewEventListener* mListener;
BOOL mIsCurSelection;
@ -157,7 +158,6 @@ protected:
BOOL mDragAndDropTarget;
BOOL mIsLoading;
LLTimer mTimeSinceRequestStart;
bool mHidden;
bool mShowLoadStatus;
// helper function to change the selection from the root.
@ -167,13 +167,15 @@ protected:
void extendSelectionFromRoot(LLFolderViewItem* selection);
// this is an internal method used for adding items to folders. A
// no-op at this leve, but reimplemented in derived classes.
// no-op at this level, but reimplemented in derived classes.
virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
static LLFontGL* getLabelFontForStyle(U8 style);
public:
BOOL postBuild();
// This function clears the currently selected item, and records
// the specified selected item appropriately for display and use
// in the UI. If open is TRUE, then folders are opened up along
@ -202,11 +204,6 @@ public:
virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
virtual S32 getItemHeight();
// Hide the folder from the UI, such as if you want to hide the root
// folder in an inventory panel.
void setHidden(bool hidden) { mHidden = hidden; }
bool getHidden() const { return mHidden; }
// applies filters to control visibility of inventory items
virtual void filter( LLInventoryFilter& filter);
@ -366,6 +363,9 @@ public:
UNKNOWN, TRASH, NOT_TRASH
} ETrash;
typedef std::list<LLFolderViewItem*> items_t;
typedef std::list<LLFolderViewFolder*> folders_t;
private:
S32 mNumDescendantsSelected;
@ -374,8 +374,6 @@ public: // Accessed needed by LLFolderViewItem
S32 numSelected(void) const { return mNumDescendantsSelected + (isSelected() ? 1 : 0); }
protected:
typedef std::list<LLFolderViewItem*> items_t;
typedef std::list<LLFolderViewFolder*> folders_t;
items_t mItems;
folders_t mFolders;
LLInventorySort mSortFunction;
@ -392,6 +390,8 @@ protected:
S32 mCompletedFilterGeneration;
S32 mMostFilteredDescendantGeneration;
bool mNeedsSort;
bool mPassedFolderFilter;
public:
typedef enum e_recurse_type
{
@ -425,13 +425,21 @@ public:
virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
BOOL hasFilteredDescendants(S32 filter_generation) { return mMostFilteredDescendantGeneration >= filter_generation; }
BOOL hasFilteredDescendants(S32 filter_generation);
BOOL hasFilteredDescendants();
// applies filters to control visibility of inventory items
virtual void filter( LLInventoryFilter& filter);
virtual void setFiltered(BOOL filtered, S32 filter_generation);
virtual BOOL getFiltered();
virtual BOOL getFiltered(S32 filter_generation);
virtual void dirtyFilter();
// folder-specific filtering (filter status propagates top down instead of bottom up)
void filterFolder(LLInventoryFilter& filter);
void setFilteredFolder(bool filtered, S32 filter_generation);
bool getFilteredFolder(S32 filter_generation);
// Passes selection information on to children and record
// selection information if necessary.
@ -537,6 +545,10 @@ public:
time_t getCreationDate() const;
bool isTrash() const;
S32 getNumSelectedDescendants(void) const { return mNumDescendantsSelected; }
folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); }
folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); }
folders_t::size_type getFoldersCount() const { return mFolders.size(); }
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -40,6 +40,7 @@
#include "llfloateropenobject.h"
#include "llfloaterreg.h"
#include "llfloaterworldmap.h"
#include "llfolderview.h"
#include "llfriendcard.h"
#include "llgesturemgr.h"
#include "llgiveinventory.h"
@ -571,8 +572,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
}
}
// Don't allow items to be pasted directly into the COF.
if (!isCOFFolder())
// Don't allow items to be pasted directly into the COF or the inbox
if (!isCOFFolder() && !isInboxFolder())
{
items.push_back(std::string("Paste"));
}
@ -781,6 +782,18 @@ BOOL LLInvFVBridge::isCOFFolder() const
return LLAppearanceMgr::instance().getIsInCOF(mUUID);
}
BOOL LLInvFVBridge::isInboxFolder() const
{
const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false);
if (inbox_id.isNull())
{
return FALSE;
}
return gInventory.isObjectDescendentOf(mUUID, inbox_id);
}
BOOL LLInvFVBridge::isItemPermissive() const
{
return FALSE;
@ -1786,6 +1799,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
}
else
{
if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false)))
{
set_dad_inbox_object(inv_cat->getUUID());
}
// Reparent the folder and restamp children if it's moving
// into trash.
@ -2525,6 +2542,7 @@ void LLFolderBridge::folderOptionsMenu()
{
mItems.push_back(std::string("Add To Outfit"));
}
mItems.push_back(std::string("Replace Outfit"));
}
if (is_ensemble)
@ -2614,15 +2632,17 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// Not sure what the right thing is to do here.
if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT))
{
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
mItems.push_back(std::string("New Folder"));
mItems.push_back(std::string("New Script"));
mItems.push_back(std::string("New Note"));
mItems.push_back(std::string("New Gesture"));
mItems.push_back(std::string("New Clothes"));
mItems.push_back(std::string("New Body Parts"));
if (!isInboxFolder()) // don't allow creation in inbox
{
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
mItems.push_back(std::string("New Folder"));
mItems.push_back(std::string("New Script"));
mItems.push_back(std::string("New Note"));
mItems.push_back(std::string("New Gesture"));
mItems.push_back(std::string("New Clothes"));
mItems.push_back(std::string("New Body Parts"));
}
#if SUPPORT_ENSEMBLES
// Changing folder types is an unfinished unsupported feature
// and can lead to unexpected behavior if enabled.
@ -3161,6 +3181,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// (move the item, restamp if into trash)
else
{
// set up observer to select item once drag and drop from inbox is complete
if (gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false)))
{
set_dad_inbox_object(inv_item->getUUID());
}
LLInvFVBridge::changeItemParent(
model,
(LLViewerInventoryItem*)inv_item,

View File

@ -139,6 +139,7 @@ protected:
BOOL isAgentInventory() const; // false if lost or in the inventory library
BOOL isCOFFolder() const; // true if COF or descendent of
BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox
virtual BOOL isItemPermissive() const;
static void changeItemParent(LLInventoryModel* model,
LLViewerInventoryItem* item,
@ -584,6 +585,9 @@ protected:
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Recent Inventory Panel related classes
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Overridden version of the Inventory-Folder-View-Bridge for Folders
class LLRecentItemsFolderBridge : public LLFolderBridge

View File

@ -107,6 +107,32 @@ BOOL LLInventoryFilter::check(const LLFolderViewItem* item)
return passed;
}
bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder)
{
// we're showing all folders, overriding filter
if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
{
return true;
}
const LLFolderViewEventListener* listener = folder->getListener();
const LLUUID folder_id = listener->getUUID();
if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
{
// Can only filter categories for items in your inventory
// (e.g. versus in-world object contents).
const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
if (!cat)
return false;
LLFolderType::EType cat_type = cat->getPreferredType();
if (cat_type != LLFolderType::FT_NONE && (1LL << cat_type & mFilterOps.mFilterCategoryTypes) == U64(0))
return false;
}
return true;
}
BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
{
const LLFolderViewEventListener* listener = item->getListener();
@ -137,30 +163,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
}
}
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_CATEGORY
// Pass if this item is a category of the filter type, or
// if its parent is a category of the filter type.
if (filterTypes & FILTERTYPE_CATEGORY)
{
// Can only filter categories for items in your inventory
// (e.g. versus in-world object contents).
if (!object) return FALSE;
LLUUID cat_id = object_id;
if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
{
cat_id = object->getParentUUID();
}
const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
if (!cat)
return FALSE;
if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0))
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_UUID
// Pass if this item is the target UUID or if it links to the target UUID
@ -172,7 +174,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_DATE
// Pass if this item is within the date range.
@ -293,15 +294,15 @@ BOOL LLInventoryFilter::isModifiedAndClear()
return ret;
}
void LLInventoryFilter::setFilterObjectTypes(U64 types)
void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
{
if (mFilterOps.mFilterObjectTypes != types)
if (current_types != types)
{
// keep current items only if no type bits getting turned off
BOOL fewer_bits_set = (mFilterOps.mFilterObjectTypes & ~types);
BOOL more_bits_set = (~mFilterOps.mFilterObjectTypes & types);
bool fewer_bits_set = (current_types & ~types) != 0;
bool more_bits_set = (~current_types & types) != 0;
mFilterOps.mFilterObjectTypes = types;
current_types = types;
if (more_bits_set && fewer_bits_set)
{
// neither less or more restrive, both simultaneously
@ -318,62 +319,23 @@ void LLInventoryFilter::setFilterObjectTypes(U64 types)
setModified(FILTER_MORE_RESTRICTIVE);
}
}
}
void LLInventoryFilter::setFilterObjectTypes(U64 types)
{
updateFilterTypes(types, mFilterOps.mFilterObjectTypes);
mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;
}
void LLInventoryFilter::setFilterCategoryTypes(U64 types)
{
if (mFilterOps.mFilterCategoryTypes != types)
{
// keep current items only if no type bits getting turned off
BOOL fewer_bits_set = (mFilterOps.mFilterCategoryTypes & ~types);
BOOL more_bits_set = (~mFilterOps.mFilterCategoryTypes & types);
mFilterOps.mFilterCategoryTypes = types;
if (more_bits_set && fewer_bits_set)
{
// neither less or more restrive, both simultaneously
// so we need to filter from scratch
setModified(FILTER_RESTART);
}
else if (more_bits_set)
{
// target is only one of all requested types so more type bits == less restrictive
setModified(FILTER_LESS_RESTRICTIVE);
}
else if (fewer_bits_set)
{
setModified(FILTER_MORE_RESTRICTIVE);
}
}
mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;
updateFilterTypes(types, mFilterOps.mFilterCategoryTypes);
mFilterOps.mFilterTypes |= FILTERTYPE_CATEGORY;
}
void LLInventoryFilter::setFilterWearableTypes(U64 types)
{
if (mFilterOps.mFilterWearableTypes != types)
{
// keep current items only if no type bits getting turned off
BOOL fewer_bits_set = (mFilterOps.mFilterWearableTypes & ~types);
BOOL more_bits_set = (~mFilterOps.mFilterWearableTypes & types);
mFilterOps.mFilterWearableTypes = types;
if (more_bits_set && fewer_bits_set)
{
// neither less or more restrive, both simultaneously
// so we need to filter from scratch
setModified(FILTER_RESTART);
}
else if (more_bits_set)
{
// target is only one of all requested types so more type bits == less restrictive
setModified(FILTER_LESS_RESTRICTIVE);
}
else if (fewer_bits_set)
{
setModified(FILTER_MORE_RESTRICTIVE);
}
}
updateFilterTypes(types, mFilterOps.mFilterWearableTypes);
mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE;
}
@ -898,11 +860,16 @@ void LLInventoryFilter::fromLLSD(LLSD& data)
}
}
U32 LLInventoryFilter::getFilterObjectTypes() const
U64 LLInventoryFilter::getFilterObjectTypes() const
{
return mFilterOps.mFilterObjectTypes;
}
U64 LLInventoryFilter::getFilterCategoryTypes() const
{
return mFilterOps.mFilterCategoryTypes;
}
BOOL LLInventoryFilter::hasFilterString() const
{
return mFilterSubString.size() > 0;

View File

@ -31,6 +31,7 @@
#include "llpermissionsflags.h"
class LLFolderViewItem;
class LLFolderViewFolder;
class LLInventoryFilter
{
@ -81,11 +82,13 @@ public:
// + Parameters
// +-------------------------------------------------------------------+
void setFilterObjectTypes(U64 types);
U32 getFilterObjectTypes() const;
U64 getFilterObjectTypes() const;
U64 getFilterCategoryTypes() const;
BOOL isFilterObjectTypesWith(LLInventoryType::EType t) const;
void setFilterCategoryTypes(U64 types);
void setFilterUUID(const LLUUID &object_id);
void setFilterWearableTypes(U64 types);
void updateFilterTypes(U64 types, U64& current_types);
void setFilterSubString(const std::string& string);
const std::string& getFilterSubString(BOOL trim = FALSE) const;
@ -110,6 +113,7 @@ public:
// + Execution And Results
// +-------------------------------------------------------------------+
BOOL check(const LLFolderViewItem* item);
bool checkFolder(const LLFolderViewFolder* folder);
BOOL checkAgainstFilterType(const LLFolderViewItem* item) const;
BOOL checkAgainstPermissions(const LLFolderViewItem* item) const;
BOOL checkAgainstFilterLinks(const LLFolderViewItem* item) const;

View File

@ -28,9 +28,9 @@
#ifndef LL_LLINVENTORYFUNCTIONS_H
#define LL_LLINVENTORYFUNCTIONS_H
#include "llinventorytype.h"
#include "llfolderview.h"
#include "llfolderviewitem.h"
#include "llinventorymodel.h"
#include "llinventory.h"
#include "llwearabletype.h"
/********************************************************************************
** **
@ -417,6 +417,24 @@ public:
/** Inventory Collector Functions
** **
*******************************************************************************/
class LLFolderViewItem;
class LLFolderViewFolder;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFolderViewFunctor
//
// Simple abstract base class for applying a functor to folders and
// items in a folder view hierarchy. This is suboptimal for algorithms
// that only work folders or only work on items, but I'll worry about
// that later when it's determined to be too slow.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLFolderViewFunctor
{
public:
virtual ~LLFolderViewFunctor() {}
virtual void doFolder(LLFolderViewFolder* folder) = 0;
virtual void doItem(LLFolderViewItem* item) = 0;
};
class LLInventoryState
{

View File

@ -2589,7 +2589,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
LLInventoryState::sWearNewClothing = FALSE;
}
if (tid == LLInventoryState::sWearNewClothingTransactionID)
if (tid.notNull() && tid == LLInventoryState::sWearNewClothingTransactionID)
{
count = wearable_ids.size();
for (i = 0; i < count; ++i)

View File

@ -31,7 +31,9 @@
#include "llappviewer.h"
#include "llcallbacklist.h"
#include "llinventorypanel.h"
#include "llinventorymodel.h"
#include "llviewercontrol.h"
#include "llviewerinventory.h"
#include "llviewermessage.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"

View File

@ -601,6 +601,34 @@ void LLInventoryAddedObserver::changed(U32 mask)
}
}
void LLInventoryCategoryAddedObserver::changed(U32 mask)
{
if (!(mask & LLInventoryObserver::ADD))
{
return;
}
const LLInventoryModel::changed_items_t& changed_ids = gInventory.getChangedIDs();
for (LLInventoryModel::changed_items_t::const_iterator cit = changed_ids.begin(); cit != changed_ids.end(); ++cit)
{
LLViewerInventoryCategory* cat = gInventory.getCategory(*cit);
if (cat)
{
mAddedCategories.push_back(cat);
}
}
if (!mAddedCategories.empty())
{
done();
mAddedCategories.clear();
}
}
LLInventoryTransactionObserver::LLInventoryTransactionObserver(const LLTransactionID& transaction_id) :
mTransactionID(transaction_id)
{

View File

@ -218,6 +218,28 @@ protected:
uuid_vec_t mAdded;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryCategoryAddedObserver
//
// Base class for doing something when a new category is created in the
// inventory.
// It does not watch for a certain UUID, rather it acts when anything is added
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLInventoryCategoryAddedObserver : public LLInventoryObserver
{
public:
typedef std::vector<LLViewerInventoryCategory*> cat_vec_t;
LLInventoryCategoryAddedObserver() : mAddedCategories() {}
/*virtual*/ void changed(U32 mask);
protected:
virtual void done() = 0;
cat_vec_t mAddedCategories;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryTransactionObserver
//

View File

@ -35,6 +35,7 @@
#include "llavataractions.h"
#include "llfloaterinventory.h"
#include "llfloaterreg.h"
#include "llfolderview.h"
#include "llimfloater.h"
#include "llimview.h"
#include "llinventorybridge.h"
@ -42,7 +43,6 @@
#include "llinventorymodelbackgroundfetch.h"
#include "llsidepanelinventory.h"
#include "llsidetray.h"
#include "llscrollcontainer.h"
#include "llviewerattachmenu.h"
#include "llviewerfoldertype.h"
#include "llvoavatarself.h"
@ -131,9 +131,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mInventory(p.inventory),
mAllowMultiSelect(p.allow_multi_select),
mShowItemLinkOverlays(p.show_item_link_overlays),
mShowLoadStatus(p.show_load_status),
mViewsInitialized(false),
mStartFolderString(p.start_folder),
mBuildDefaultHierarchy(true),
mInvFVBridgeBuilder(NULL)
{
mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
@ -146,11 +145,88 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2));
mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars));
}
void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
{
// Determine the root folder in case specified, and
// build the views starting with that folder.
if (mStartFolderString != "")
std::string start_folder_name(params.start_folder());
const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(start_folder_name);
LLUUID root_id;
if ("LIBRARY" == params.start_folder())
{
mBuildDefaultHierarchy = false;
root_id = gInventory.getLibraryRootFolderID();
}
// leslie -- temporary HACK to work around sim not creating inbox and outbox with proper system folder type
else if (preferred_type == LLFolderType::FT_INBOX)
{
LLInventoryModel::cat_array_t* cats;
LLInventoryModel::item_array_t* items;
gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items);
if (cats)
{
for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it)
{
LLInventoryCategory* cat = *cat_it;
if (cat->getName() == "Received Items")
{
root_id = cat->getUUID();
}
}
}
}
// leslie -- temporary HACK to work around sim not creating inbox and outbox with proper system folder type
else if (preferred_type == LLFolderType::FT_OUTBOX)
{
LLInventoryModel::cat_array_t* cats;
LLInventoryModel::item_array_t* items;
gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items);
if (cats)
{
for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it)
{
LLInventoryCategory* cat = *cat_it;
if (cat->getName() == "Merchant Outbox")
{
root_id = cat->getUUID();
}
}
}
}
// leslie -- end temporary HACK
else
{
root_id = (preferred_type != LLFolderType::FT_NONE)
? gInventory.findCategoryUUIDForType(preferred_type, false, false)
: LLUUID::null;
}
if ((root_id == LLUUID::null) && !start_folder_name.empty())
{
llwarns << "No category found that matches start_folder: " << start_folder_name << llendl;
root_id = LLUUID::generateNewID();
}
LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
LLAssetType::AT_CATEGORY,
LLInventoryType::IT_CATEGORY,
this,
NULL,
root_id);
mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
}
void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
@ -159,22 +235,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
// Create root folder
{
LLRect folder_rect(0,
0,
getRect().getWidth(),
0);
LLFolderView::Params p;
p.name = getName();
p.title = getLabel();
p.rect = folder_rect;
p.parent_panel = this;
p.tool_tip = p.name;
p.use_label_suffix = params.use_label_suffix;
mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p);
mFolderRoot->setAllowMultiSelect(mAllowMultiSelect);
}
buildFolderView(params);
mCommitCallbackRegistrar.popScope();
@ -184,13 +245,9 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
{
LLRect scroller_view_rect = getRect();
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
LLScrollContainer::Params p;
p.name("Inventory Scroller");
p.rect(scroller_view_rect);
p.follows.flags(FOLLOWS_ALL);
p.reserve_scroll_corner(true);
p.tab_stop(true);
mScroller = LLUICtrlFactory::create<LLScrollContainer>(p);
LLScrollContainer::Params scroller_params(params.scroll());
scroller_params.rect(scroller_view_rect);
mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroller_params);
addChild(mScroller);
mScroller->addChild(mFolderRoot);
mFolderRoot->setScrollContainer(mScroller);
@ -206,7 +263,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
// Build view of inventory if we need default full hierarchy and inventory ready,
// otherwise wait for idle callback.
if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mViewsInitialized)
if (mInventory->isInventoryUsable() && !mViewsInitialized)
{
initializeViews();
}
@ -222,6 +279,9 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
}
mFolderRoot->setSortOrder(getFilter()->getSortOrder());
// hide inbox
getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
// Initialize base class params.
LLPanel::initFromParams(params);
}
@ -264,6 +324,15 @@ LLInventoryFilter* LLInventoryPanel::getFilter()
return NULL;
}
const LLInventoryFilter* LLInventoryPanel::getFilter() const
{
if (mFolderRoot)
{
return mFolderRoot->getFilter();
}
return NULL;
}
void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
{
if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT)
@ -272,6 +341,17 @@ void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType
getFilter()->setFilterCategoryTypes(types);
}
U32 LLInventoryPanel::getFilterObjectTypes() const
{
return mFolderRoot->getFilterObjectTypes();
}
U32 LLInventoryPanel::getFilterPermMask() const
{
return mFolderRoot->getFilterPermissions();
}
void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)
{
getFilter()->setFilterPermissions(filter_perm_mask);
@ -287,6 +367,12 @@ void LLInventoryPanel::setFilterSubString(const std::string& string)
getFilter()->setFilterSubString(string);
}
const std::string LLInventoryPanel::getFilterSubString()
{
return mFolderRoot->getFilterSubString();
}
void LLInventoryPanel::setSortOrder(U32 order)
{
getFilter()->setSortOrder(order);
@ -298,6 +384,12 @@ void LLInventoryPanel::setSortOrder(U32 order)
}
}
U32 LLInventoryPanel::getSortOrder() const
{
return mFolderRoot->getSortOrder();
}
void LLInventoryPanel::setSinceLogoff(BOOL sl)
{
getFilter()->setDateRangeLastLogoff(sl);
@ -379,7 +471,8 @@ void LLInventoryPanel::modelChanged(U32 mask)
{
view_item->destroyView();
}
buildNewViews(item_id);
view_item = buildNewViews(item_id);
view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
}
//////////////////////////////
@ -432,11 +525,10 @@ void LLInventoryPanel::modelChanged(U32 mask)
//////////////////////////////
// STRUCTURE Operation
// This item already exists in both memory and UI. It was probably reparented.
if (model_item && view_item)
else if (model_item && view_item)
{
// Don't process the item if it's hanging from the root, since its
// model_item's parent will be NULL.
if (view_item->getRoot() != view_item->getParent())
// Don't process the item if it is the root
if (view_item->getRoot() != view_item)
{
LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolderRoot->getItemByID(model_item->getParentUUID());
// Item has been moved.
@ -461,7 +553,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
//////////////////////////////
// REMOVE Operation
// This item has been removed from memory, but its associated UI element still exists.
if (!model_item && view_item)
else if (!model_item && view_item)
{
// Remove the item's UI.
view_item->destroyView();
@ -470,6 +562,12 @@ void LLInventoryPanel::modelChanged(U32 mask)
}
}
LLFolderView* LLInventoryPanel::getRootFolder()
{
return mFolderRoot;
}
// static
void LLInventoryPanel::onIdle(void *userdata)
{
@ -488,23 +586,16 @@ void LLInventoryPanel::onIdle(void *userdata)
}
}
const LLUUID& LLInventoryPanel::getRootFolderID() const
{
return mFolderRoot->getListener()->getUUID();
}
void LLInventoryPanel::initializeViews()
{
if (!gInventory.isInventoryUsable()) return;
// Determine the root folder in case specified, and
// build the views starting with that folder.
const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
if ("LIBRARY" == mStartFolderString)
{
mStartFolderID = gInventory.getLibraryRootFolderID();
}
else
{
mStartFolderID = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
}
rebuildViewsFor(mStartFolderID);
rebuildViewsFor(getRootFolderID());
mViewsInitialized = true;
@ -529,132 +620,155 @@ void LLInventoryPanel::initializeViews()
}
}
void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
{
// Destroy the old view for this ID so we can rebuild it.
LLFolderViewItem* old_view = mFolderRoot->getItemByID(id);
if (old_view && id.notNull())
if (old_view)
{
old_view->destroyView();
}
buildNewViews(id);
return buildNewViews(id);
}
void LLInventoryPanel::buildNewViews(const LLUUID& id)
LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix)
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS);
LLFolderViewItem* itemp = NULL;
LLInventoryObject* objectp = gInventory.getObject(id);
if (objectp)
LLRect folder_rect(0,
0,
getRect().getWidth(),
0);
LLFolderView::Params p;
p.name = getName();
p.title = getLabel();
p.rect = folder_rect;
p.parent_panel = this;
p.tool_tip = p.name;
p.listener = bridge;
p.use_label_suffix = useLabelSuffix;
p.allow_multiselect = mAllowMultiSelect;
p.show_load_status = mShowLoadStatus;
return LLUICtrlFactory::create<LLFolderView>(p);
}
LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
{
LLFolderViewFolder::Params params;
params.name = bridge->getDisplayName();
params.icon = bridge->getIcon();
params.icon_open = bridge->getOpenIcon();
if (mShowItemLinkOverlays) // if false, then links show up just like normal items
{
const LLUUID &parent_id = objectp->getParentUUID();
LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
if (id == mStartFolderID)
{
parent_folder = mFolderRoot;
}
else if ((mStartFolderID != LLUUID::null) && (!gInventory.isObjectDescendentOf(id, mStartFolderID)))
{
// This item exists outside the inventory's hierarchy, so don't add it.
return;
}
if (objectp->getType() <= LLAssetType::AT_NONE ||
objectp->getType() >= LLAssetType::AT_COUNT)
{
llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
<< llendl;
return;
}
if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
{
LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
objectp->getType(),
LLInventoryType::IT_CATEGORY,
this,
mFolderRoot,
objectp->getUUID());
if (new_listener)
{
LLFolderViewFolder::Params params;
params.name = new_listener->getDisplayName();
params.icon = new_listener->getIcon();
params.icon_open = new_listener->getOpenIcon();
if (mShowItemLinkOverlays) // if false, then links show up just like normal items
{
params.icon_overlay = LLUI::getUIImage("Inv_Link");
}
params.root = mFolderRoot;
params.listener = new_listener;
params.tool_tip = params.name;
LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params);
folderp->setItemSortOrder(mFolderRoot->getSortOrder());
itemp = folderp;
params.icon_overlay = LLUI::getUIImage("Inv_Link");
}
params.root = mFolderRoot;
params.listener = bridge;
params.tool_tip = params.name;
// Hide the root folder, so we can show the contents of a folder flat
// but still have the parent folder present for listener-related operations.
if (id == mStartFolderID)
{
folderp->setHidden(TRUE);
}
const LLViewerInventoryCategory *cat = dynamic_cast<LLViewerInventoryCategory *>(objectp);
if (cat && getIsHiddenFolderType(cat->getPreferredType()))
{
folderp->setHidden(TRUE);
}
}
}
else
{
// Build new view for item.
LLInventoryItem* item = (LLInventoryItem*)objectp;
LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
item->getActualType(),
item->getInventoryType(),
this,
mFolderRoot,
item->getUUID(),
item->getFlags());
return LLUICtrlFactory::create<LLFolderViewFolder>(params);
}
if (new_listener)
{
LLFolderViewItem::Params params;
params.name = new_listener->getDisplayName();
params.icon = new_listener->getIcon();
params.icon_open = new_listener->getOpenIcon();
if (mShowItemLinkOverlays) // if false, then links show up just like normal items
{
params.icon_overlay = LLUI::getUIImage("Inv_Link");
}
params.creation_date = new_listener->getCreationDate();
params.root = mFolderRoot;
params.listener = new_listener;
params.rect = LLRect (0, 0, 0, 0);
params.tool_tip = params.name;
itemp = LLUICtrlFactory::create<LLFolderViewItem> (params);
}
}
LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
{
LLFolderViewItem::Params params;
params.name = bridge->getDisplayName();
params.icon = bridge->getIcon();
params.icon_open = bridge->getOpenIcon();
if (itemp)
{
itemp->addToFolder(parent_folder, mFolderRoot);
if (mShowItemLinkOverlays) // if false, then links show up just like normal items
{
params.icon_overlay = LLUI::getUIImage("Inv_Link");
}
// Don't add children of hidden folders unless this is the panel's root folder.
if (itemp->getHidden() && (id != mStartFolderID))
{
return;
}
params.creation_date = bridge->getCreationDate();
params.root = mFolderRoot;
params.listener = bridge;
params.rect = LLRect (0, 0, 0, 0);
params.tool_tip = params.name;
return LLUICtrlFactory::create<LLFolderViewItem>(params);
}
LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
{
LLInventoryObject const* objectp = gInventory.getObject(id);
LLUUID root_id = mFolderRoot->getListener()->getUUID();
LLFolderViewFolder* parent_folder = NULL;
LLFolderViewItem* itemp = NULL;
if (id == root_id)
{
parent_folder = mFolderRoot;
}
else if (objectp)
{
const LLUUID &parent_id = objectp->getParentUUID();
parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
if (parent_folder)
{
if (objectp->getType() <= LLAssetType::AT_NONE ||
objectp->getType() >= LLAssetType::AT_COUNT)
{
llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
<< llendl;
return NULL;
}
if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
{
LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
objectp->getType(),
LLInventoryType::IT_CATEGORY,
this,
mFolderRoot,
objectp->getUUID());
if (new_listener)
{
LLFolderViewFolder* folderp = createFolderViewFolder(new_listener);
folderp->setItemSortOrder(mFolderRoot->getSortOrder());
itemp = folderp;
}
}
else
{
// Build new view for item.
LLInventoryItem* item = (LLInventoryItem*)objectp;
LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
item->getActualType(),
item->getInventoryType(),
this,
mFolderRoot,
item->getUUID(),
item->getFlags());
if (new_listener)
{
itemp = createFolderViewItem(new_listener);
}
}
if (itemp)
{
itemp->addToFolder(parent_folder, mFolderRoot);
}
}
}
// If this is a folder, add the children of the folder and recursively add any
// child folders.
if ((id == mStartFolderID) ||
(objectp && objectp->getType() == LLAssetType::AT_CATEGORY))
if (id.isNull()
|| (objectp
&& objectp->getType() == LLAssetType::AT_CATEGORY))
{
LLViewerInventoryCategory::cat_array_t* categories;
LLViewerInventoryItem::item_array_t* items;
@ -671,7 +785,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
}
}
if(items)
if(items && parent_folder)
{
for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
item_iter != items->end();
@ -683,28 +797,25 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
}
mInventory->unlockDirectDescendentArrays(id);
}
return itemp;
}
// bit of a hack to make sure the inventory is open.
void LLInventoryPanel::openStartFolderOrMyInventory()
{
if (mStartFolderString != "")
// Find My Inventory folder and open it up by name
for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child))
{
mFolderRoot->openFolder(mStartFolderString);
}
else
{
// Find My Inventory folder and open it up by name
for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child))
LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
if (fchild
&& fchild->getListener()
&& fchild->getListener()->getUUID() == gInventory.getRootFolderID())
{
LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
if (fchild && fchild->getListener() &&
(fchild->getListener()->getUUID() == gInventory.getRootFolderID()))
{
const std::string& child_name = child->getName();
mFolderRoot->openFolder(child_name);
break;
}
const std::string& child_name = child->getName();
mFolderRoot->openFolder(child_name);
mFolderRoot->clearSelection(); // No need to keep it selected though!
break;
}
}
}
@ -723,6 +834,12 @@ void LLInventoryPanel::openSelected()
bridge->openItem();
}
void LLInventoryPanel::unSelectAll()
{
mFolderRoot->setSelection(NULL, FALSE, FALSE);
}
BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask)
{
BOOL handled = LLView::handleHover(x, y, mask);
@ -802,7 +919,7 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc
mFolderRoot->setSelectionByID(obj_id, take_keyboard_focus);
}
void LLInventoryPanel::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)
{
if (mFolderRoot)
{
@ -1067,15 +1184,12 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
void LLInventoryPanel::addHideFolderType(LLFolderType::EType folder_type)
{
if (!getIsHiddenFolderType(folder_type))
{
mHiddenFolderTypes.push_back(folder_type);
}
getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << folder_type));
}
BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) const
{
return (std::find(mHiddenFolderTypes.begin(), mHiddenFolderTypes.end(), folder_type) != mHiddenFolderTypes.end());
return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));
}
@ -1092,6 +1206,13 @@ public:
struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
{};
void initFromParams(const Params& p)
{
LLInventoryPanel::initFromParams(p);
// turn on inbox for recent items
getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX));
}
protected:
LLInventoryRecentItemsPanel (const Params&);
friend class LLUICtrlFactory;

View File

@ -33,11 +33,13 @@
#include "llfloater.h"
#include "llinventory.h"
#include "llinventoryfilter.h"
#include "llfolderview.h"
#include "llinventorymodel.h"
#include "llscrollcontainer.h"
#include "lluictrlfactory.h"
#include <set>
class LLFolderView;
class LLFolderViewFolder;
class LLFolderViewItem;
class LLInventoryFilter;
class LLInventoryModel;
@ -46,7 +48,6 @@ class LLInventoryFVBridgeBuilder;
class LLMenuBarGL;
class LLCheckBoxCtrl;
class LLSpinCtrl;
class LLScrollContainer;
class LLTextBox;
class LLIconCtrl;
class LLSaveFolderState;
@ -83,6 +84,8 @@ public:
Optional<Filter> filter;
Optional<std::string> start_folder;
Optional<bool> use_label_suffix;
Optional<bool> show_load_status;
Optional<LLScrollContainer::Params> scroll;
Params()
: sort_order_setting("sort_order_setting"),
@ -91,7 +94,9 @@ public:
show_item_link_overlays("show_item_link_overlays", false),
filter("filter"),
start_folder("start_folder"),
use_label_suffix("use_label_suffix", true)
use_label_suffix("use_label_suffix", true),
show_load_status("show_load_status"),
scroll("scroll")
{}
};
@ -123,16 +128,17 @@ public:
// Call this method to set the selection.
void openAllFolders();
void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb);
void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
void clearSelection();
LLInventoryFilter* getFilter();
const LLInventoryFilter* getFilter() const;
void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
U32 getFilterObjectTypes() const { return mFolderRoot->getFilterObjectTypes(); }
U32 getFilterObjectTypes() const;
void setFilterPermMask(PermissionMask filter_perm_mask);
U32 getFilterPermMask() const { return mFolderRoot->getFilterPermissions(); }
U32 getFilterPermMask() const;
void setFilterWearableTypes(U64 filter);
void setFilterSubString(const std::string& string);
const std::string getFilterSubString() { return mFolderRoot->getFilterSubString(); }
const std::string getFilterSubString();
void setSinceLogoff(BOOL sl);
void setHoursAgo(U32 hours);
BOOL getSinceLogoff();
@ -140,10 +146,9 @@ public:
void setShowFolderState(LLInventoryFilter::EFolderShow show);
LLInventoryFilter::EFolderShow getShowFolderState();
void setAllowMultiSelect(BOOL allow) { mFolderRoot->setAllowMultiSelect(allow); }
// This method is called when something has changed about the inventory.
void modelChanged(U32 mask);
LLFolderView* getRootFolder() { return mFolderRoot; }
LLFolderView* getRootFolder();
LLScrollContainer* getScrollableContainer() { return mScroller; }
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
@ -158,7 +163,7 @@ public:
static void dumpSelectionInformation(void* user_data);
void openSelected();
void unSelectAll() { mFolderRoot->setSelection(NULL, FALSE, FALSE); }
void unSelectAll();
static void onIdle(void* user_data);
@ -175,6 +180,7 @@ protected:
LLInvPanelComplObserver* mCompletionObserver;
BOOL mAllowMultiSelect;
BOOL mShowItemLinkOverlays; // Shows link graphic over inventory item icons
BOOL mShowLoadStatus;
LLFolderView* mFolderRoot;
LLScrollContainer* mScroller;
@ -198,7 +204,7 @@ public:
static const std::string INHERIT_SORT_ORDER;
void setSortOrder(U32 order);
U32 getSortOrder() const { return mFolderRoot->getSortOrder(); }
U32 getSortOrder() const;
private:
std::string mSortOrderSetting;
@ -207,29 +213,27 @@ private:
//--------------------------------------------------------------------
public:
void addHideFolderType(LLFolderType::EType folder_type);
protected:
BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
private:
std::vector<LLFolderType::EType> mHiddenFolderTypes;
//--------------------------------------------------------------------
// Initialization routines for building up the UI ("views")
//--------------------------------------------------------------------
public:
BOOL getIsViewsInitialized() const { return mViewsInitialized; }
const LLUUID& getStartFolderID() const { return mStartFolderID; }
const std::string& getStartFolderString() { return mStartFolderString; }
const LLUUID& getRootFolderID() const;
protected:
// Builds the UI. Call this once the inventory is usable.
void initializeViews();
void rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views.
virtual void buildNewViews(const LLUUID& id);
LLFolderViewItem* rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views.
virtual void buildFolderView(const LLInventoryPanel::Params& params);
LLFolderViewItem* buildNewViews(const LLUUID& id);
BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
virtual LLFolderView* createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix);
virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge);
virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge);
private:
BOOL mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
BOOL mViewsInitialized; // Views have been generated
// UUID of category from which hierarchy should be built. Set with the
// "start_folder" xml property. Default is LLUUID::null that means total Inventory hierarchy.
std::string mStartFolderString;
LLUUID mStartFolderID;
};

View File

@ -38,6 +38,7 @@
#include "llviewermedia.h"
#include "llviewertexture.h"
#include "llviewerwindow.h"
#include "lldebugmessagebox.h"
#include "llweb.h"
#include "llrender.h"
#include "llpluginclassmedia.h"
@ -708,6 +709,8 @@ LLPluginClassMedia* LLMediaCtrl::getMediaPlugin()
//
void LLMediaCtrl::draw()
{
F32 alpha = getDrawContext().mAlpha;
if ( gRestoreGL == 1 )
{
LLRect r = getRect();
@ -746,21 +749,11 @@ void LLMediaCtrl::draw()
}
}
// if(mHidingInitialLoad)
// {
// // If we're hiding loading, don't draw at all.
// draw_media = false;
// }
bool background_visible = isBackgroundVisible();
bool background_opaque = isBackgroundOpaque();
if(draw_media)
{
// alpha off for this
LLGLSUIDefault gls_ui;
LLGLDisable gls_alphaTest( GL_ALPHA_TEST );
gGL.pushUIMatrix();
{
if (mIgnoreUIScale)
@ -775,7 +768,8 @@ void LLMediaCtrl::draw()
// scale texture to fit the space using texture coords
gGL.getTexUnit(0)->bind(media_texture);
gGL.color4fv( LLColor4::white.mV );
LLColor4 media_color = LLColor4::white % alpha;
gGL.color4fv( media_color.mV );
F32 max_u = ( F32 )media_plugin->getWidth() / ( F32 )media_plugin->getTextureWidth();
F32 max_v = ( F32 )media_plugin->getHeight() / ( F32 )media_plugin->getTextureHeight();
@ -827,7 +821,6 @@ void LLMediaCtrl::draw()
}
// draw the browser
gGL.setSceneBlendType(LLRender::BT_REPLACE);
gGL.begin( LLRender::QUADS );
if (! media_plugin->getTextureCoordsOpenGL())
{
@ -860,7 +853,6 @@ void LLMediaCtrl::draw()
gGL.vertex2i( x_offset + width, y_offset );
}
gGL.end();
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
gGL.popUIMatrix();

View File

@ -364,8 +364,8 @@ LLOutfitsList::~LLOutfitsList()
if (gInventory.containsObserver(mCategoriesObserver))
{
gInventory.removeObserver(mCategoriesObserver);
delete mCategoriesObserver;
}
delete mCategoriesObserver;
}
BOOL LLOutfitsList::postBuild()

View File

@ -31,6 +31,7 @@
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llviewerinventory.h"
//virtual
bool LLPanelAppearanceTab::canTakeOffSelected()

View File

@ -71,7 +71,7 @@ void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &ch
void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
{
updateButtons(new_state >= LLVoiceChannel::STATE_CALL_STARTED);
updateButtons(new_state);
}
void LLPanelChatControlPanel::updateCallButton()
@ -96,11 +96,15 @@ void LLPanelChatControlPanel::updateCallButton()
getChildView("call_btn")->setEnabled(enable_connect);
}
void LLPanelChatControlPanel::updateButtons(bool is_call_started)
void LLPanelChatControlPanel::updateButtons(LLVoiceChannel::EState state)
{
bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED;
getChildView("end_call_btn_panel")->setVisible( is_call_started);
getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started);
getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started && findChild<LLView>("voice_ctrls_btn_panel"));
getChildView("call_btn_panel")->setVisible( ! is_call_started);
getChildView("volume_ctrl_panel")->setVisible(state == LLVoiceChannel::STATE_CONNECTED);
updateCallButton();
}
@ -135,7 +139,7 @@ void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)
mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(boost::bind(&LLPanelChatControlPanel::onVoiceChannelStateChanged, this, _1, _2));
//call (either p2p, group or ad-hoc) can be already in started state
updateButtons(voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
updateButtons(voice_channel->getState());
}
}
@ -156,6 +160,13 @@ BOOL LLPanelIMControlPanel::postBuild()
childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this));
childSetAction("teleport_btn", boost::bind(&LLPanelIMControlPanel::onTeleportButtonClicked, this));
childSetAction("pay_btn", boost::bind(&LLPanelIMControlPanel::onPayButtonClicked, this));
childSetAction("mute_btn", boost::bind(&LLPanelIMControlPanel::onClickMuteVolume, this));
childSetAction("block_btn", boost::bind(&LLPanelIMControlPanel::onClickBlock, this));
childSetAction("unblock_btn", boost::bind(&LLPanelIMControlPanel::onClickUnblock, this));
getChild<LLUICtrl>("volume_slider")->setCommitCallback(boost::bind(&LLPanelIMControlPanel::onVolumeChange, this, _2));
getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId()));
setFocusReceivedCallback(boost::bind(&LLPanelIMControlPanel::onFocusReceived, this));
@ -163,6 +174,79 @@ BOOL LLPanelIMControlPanel::postBuild()
return LLPanelChatControlPanel::postBuild();
}
void LLPanelIMControlPanel::draw()
{
bool is_muted = LLMuteList::getInstance()->isMuted(mAvatarID);
getChild<LLUICtrl>("block_btn_panel")->setVisible(!is_muted);
getChild<LLUICtrl>("unblock_btn_panel")->setVisible(is_muted);
if (getChildView("volume_ctrl_panel")->getVisible())
{
bool is_muted_voice = LLMuteList::getInstance()->isMuted(mAvatarID, LLMute::flagVoiceChat);
LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
mute_btn->setValue( is_muted_voice );
LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
volume_slider->setEnabled( !is_muted_voice );
F32 volume;
if (is_muted_voice)
{
// it's clearer to display their volume as zero
volume = 0.f;
}
else
{
// actual volume
volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
}
volume_slider->setValue( (F64)volume );
}
LLPanelChatControlPanel::draw();
}
void LLPanelIMControlPanel::onClickMuteVolume()
{
// By convention, we only display and toggle voice mutes, not all mutes
LLMuteList* mute_list = LLMuteList::getInstance();
bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
if (!is_muted)
{
mute_list->add(mute, LLMute::flagVoiceChat);
}
else
{
mute_list->remove(mute, LLMute::flagVoiceChat);
}
}
void LLPanelIMControlPanel::onClickBlock()
{
LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
LLMuteList::getInstance()->add(mute);
}
void LLPanelIMControlPanel::onClickUnblock()
{
LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
LLMuteList::getInstance()->remove(mute);
}
void LLPanelIMControlPanel::onVolumeChange(const LLSD& data)
{
F32 volume = (F32)data.asReal();
LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
}
void LLPanelIMControlPanel::onTeleportButtonClicked()
{
LLAvatarActions::offerTeleport(mAvatarID);
@ -262,6 +346,9 @@ void LLPanelIMControlPanel::onNameCache(const LLUUID& id, const std::string& ful
std::string avatar_name = full_name;
getChild<LLTextBox>("avatar_name")->setValue(avatar_name);
getChild<LLTextBox>("avatar_name")->setToolTip(avatar_name);
bool is_linden = LLStringUtil::endsWith(full_name, " Linden");
getChild<LLUICtrl>("mute_btn")->setEnabled( !is_linden);
}
}

View File

@ -54,7 +54,7 @@ public:
virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
void updateButtons(bool is_call_started);
void updateButtons(LLVoiceChannel::EState state);
// Enables/disables call button depending on voice availability
void updateCallButton();
@ -94,6 +94,12 @@ private:
void onPayButtonClicked();
void onFocusReceived();
void onClickMuteVolume();
void onClickBlock();
void onClickUnblock();
/*virtual*/ void draw();
void onVolumeChange(const LLSD& data);
LLUUID mAvatarID;
};

View File

@ -46,6 +46,7 @@
#include "llfolderviewitem.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventorypanel.h"
#include "llinventoryfunctions.h"
#include "lllandmarkactions.h"
#include "llmenubutton.h"
#include "llplacesinventorybridge.h"
@ -529,7 +530,7 @@ void LLLandmarksPanel::setParcelID(const LLUUID& parcel_id)
// virtual
void LLLandmarksPanel::setErrorStatus(U32 status, const std::string& reason)
{
llerrs<< "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<<llendl;
llwarns << "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<<llendl;
}
@ -645,7 +646,7 @@ void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesI
// Start background fetch, mostly for My Inventory and Library
if (expanded)
{
const LLUUID &cat_id = inventory_list->getStartFolderID();
const LLUUID &cat_id = inventory_list->getRootFolderID();
// Just because the category itself has been fetched, doesn't mean its child folders have.
/*
if (!gInventory.isCategoryComplete(cat_id))
@ -1414,7 +1415,7 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin
static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list)
{
LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getStartFolderID());
LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getRootFolderID());
if (category)
{
return category->getDescendentCount() > 0;

View File

@ -1,6 +1,6 @@
/**
* @file llsidepanelmaininventory.cpp
* @brief Implementation of llsidepanelmaininventory.
* @file llpanelmaininventory.cpp
* @brief Implementation of llpanelmaininventory.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
@ -95,8 +95,8 @@ private:
/// LLPanelMainInventory
///----------------------------------------------------------------------------
LLPanelMainInventory::LLPanelMainInventory()
: LLPanel(),
LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
: LLPanel(p),
mActivePanel(NULL),
mSavedFolderState(NULL),
mFilterText(""),
@ -193,6 +193,9 @@ BOOL LLPanelMainInventory::postBuild()
mMenuAdd->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost);
mMenuAdd->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost);
// Trigger callback for focus received so we can deselect items in inbox/outbox
LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this));
return TRUE;
}
@ -572,6 +575,27 @@ void LLPanelMainInventory::updateItemcountText()
getChild<LLUICtrl>("ItemcountText")->setValue(text);
}
void LLPanelMainInventory::onFocusReceived()
{
LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
LLInventoryPanel * inbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox");
if (inbox_panel)
{
inbox_panel->clearSelection();
}
LLInventoryPanel * outbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_outbox");
if (outbox_panel)
{
outbox_panel->clearSelection();
}
sidepanel_inventory->updateVerbs();
}
void LLPanelMainInventory::setFilterTextFromFilter()
{
mFilterText = mActivePanel->getFilter()->getFilterText();

View File

@ -57,7 +57,7 @@ class LLPanelMainInventory : public LLPanel, LLInventoryObserver
public:
friend class LLFloaterInventoryFinder;
LLPanelMainInventory();
LLPanelMainInventory(const LLPanel::Params& p = getDefaultParams());
~LLPanelMainInventory();
BOOL postBuild();
@ -114,6 +114,8 @@ protected:
bool isSaveTextureEnabled(const LLSD& userdata);
void updateItemcountText();
void onFocusReceived();
private:
LLFloaterInventoryFinder* getFinder();

View File

@ -0,0 +1,248 @@
/**
* @file llpanelmarketplaceinbox.cpp
* @brief Panel for marketplace inbox
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llpanelmarketplaceinbox.h"
#include "llappviewer.h"
#include "llbutton.h"
#include "llinventorypanel.h"
#include "llfolderview.h"
#include "llsidepanelinventory.h"
#define SUPPORTING_FRESH_ITEM_COUNT 0
static LLRegisterPanelClassWrapper<LLPanelMarketplaceInbox> t_panel_marketplace_inbox("panel_marketplace_inbox");
const LLPanelMarketplaceInbox::Params& LLPanelMarketplaceInbox::getDefaultParams()
{
return LLUICtrlFactory::getDefaultParams<LLPanelMarketplaceInbox>();
}
// protected
LLPanelMarketplaceInbox::LLPanelMarketplaceInbox(const Params& p)
: LLPanel(p)
, mInventoryPanel(NULL)
{
}
LLPanelMarketplaceInbox::~LLPanelMarketplaceInbox()
{
}
// virtual
BOOL LLPanelMarketplaceInbox::postBuild()
{
LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLPanelMarketplaceInbox::handleLoginComplete, this));
LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceInbox::onFocusReceived, this));
return TRUE;
}
void LLPanelMarketplaceInbox::onSelectionChange()
{
LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory"));
sidepanel_inventory->updateVerbs();
}
void LLPanelMarketplaceInbox::handleLoginComplete()
{
// Set us up as the class to drive the badge value for the sidebar_inventory button
LLSideTray::getInstance()->setTabButtonBadgeDriver("sidebar_inventory", this);
}
void LLPanelMarketplaceInbox::setupInventoryPanel()
{
LLView * inbox_inventory_placeholder = getChild<LLView>("inbox_inventory_placeholder");
LLView * inbox_inventory_parent = inbox_inventory_placeholder->getParent();
mInventoryPanel =
LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_inbox_inventory.xml",
inbox_inventory_parent,
LLInventoryPanel::child_registry_t::instance());
// Reshape the inventory to the proper size
LLRect inventory_placeholder_rect = inbox_inventory_placeholder->getRect();
mInventoryPanel->setShape(inventory_placeholder_rect);
// Set the sort order newest to oldest, and a selection change callback
mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);
mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceInbox::onSelectionChange, this));
// Set up the note to display when the inbox is empty
mInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryInboxNoItems");
// Hide the placeholder text
inbox_inventory_placeholder->setVisible(FALSE);
}
void LLPanelMarketplaceInbox::onFocusReceived()
{
LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
if (sidepanel_inventory)
{
LLInventoryPanel * inv_panel = sidepanel_inventory->getActivePanel();
if (inv_panel)
{
inv_panel->clearSelection();
}
LLInventoryPanel * outbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_outbox");
if (outbox_panel)
{
outbox_panel->clearSelection();
}
sidepanel_inventory->updateVerbs();
}
}
BOOL LLPanelMarketplaceInbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)
{
*accept = ACCEPT_NO;
return TRUE;
}
U32 LLPanelMarketplaceInbox::getFreshItemCount() const
{
#if SUPPORTING_FRESH_ITEM_COUNT
//
// NOTE: When turning this on, be sure to test the no inbox/outbox case because this code probably
// will return "2" for the Inventory and LIBRARY top-levels when that happens.
//
U32 fresh_item_count = 0;
if (mInventoryPanel)
{
const LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();
if (inbox_folder)
{
LLFolderViewFolder::folders_t::const_iterator folders_it = inbox_folder->getFoldersBegin();
LLFolderViewFolder::folders_t::const_iterator folders_end = inbox_folder->getFoldersEnd();
for (; folders_it != folders_end; ++folders_it)
{
const LLFolderViewFolder * folder = *folders_it;
// TODO: Replace this check with new "fresh" flag
if (folder->getCreationDate() > 1500)
{
fresh_item_count++;
}
}
}
}
return fresh_item_count;
#else
return getTotalItemCount();
#endif
}
U32 LLPanelMarketplaceInbox::getTotalItemCount() const
{
U32 item_count = 0;
if (mInventoryPanel)
{
const LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();
if (inbox_folder)
{
item_count += inbox_folder->getFoldersCount();
}
}
return item_count;
}
std::string LLPanelMarketplaceInbox::getBadgeString() const
{
std::string item_count_str("");
// If the inbox is visible, and the side panel is collapsed or expanded and not the inventory panel
if (getParent()->getVisible() &&
(LLSideTray::getInstance()->getCollapsed() || !LLSideTray::getInstance()->isPanelActive("sidepanel_inventory")))
{
U32 item_count = getFreshItemCount();
if (item_count)
{
item_count_str = llformat("%d", item_count);
}
}
return item_count_str;
}
void LLPanelMarketplaceInbox::draw()
{
U32 item_count = getTotalItemCount();
LLView * fresh_new_count_view = getChildView("inbox_fresh_new_count");
if (item_count > 0)
{
std::string item_count_str = llformat("%d", item_count);
LLStringUtil::format_map_t args;
args["[NUM]"] = item_count_str;
getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelWithArg", args));
#if SUPPORTING_FRESH_ITEM_COUNT
// set green text to fresh item count
U32 fresh_item_count = getFreshItemCount();
fresh_new_count_view->setVisible((fresh_item_count > 0));
if (fresh_item_count > 0)
{
getChild<LLUICtrl>("inbox_fresh_new_count")->setTextArg("[NUM]", llformat("%d", fresh_item_count));
}
#else
fresh_new_count_view->setVisible(FALSE);
#endif
}
else
{
getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelNoArg"));
fresh_new_count_view->setVisible(FALSE);
}
LLPanel::draw();
}

View File

@ -0,0 +1,78 @@
/**
* @file llpanelmarketplaceinbox.h
* @brief Panel for marketplace inbox
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLPANELMARKETPLACEINBOX_H
#define LL_LLPANELMARKETPLACEINBOX_H
#include "llpanel.h"
#include "llsidetray.h"
class LLInventoryPanel;
class LLPanelMarketplaceInbox : public LLPanel, public LLSideTrayTabBadgeDriver
{
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
Params() {}
};
LOG_CLASS(LLPanelMarketplaceInbox);
// RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8
static const LLPanelMarketplaceInbox::Params& getDefaultParams();
LLPanelMarketplaceInbox(const Params& p = getDefaultParams());
~LLPanelMarketplaceInbox();
/*virtual*/ BOOL postBuild();
/*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();
void setupInventoryPanel();
U32 getFreshItemCount() const;
U32 getTotalItemCount() const;
std::string getBadgeString() const;
private:
void handleLoginComplete();
void onSelectionChange();
void onFocusReceived();
private:
LLInventoryPanel* mInventoryPanel;
};
#endif //LL_LLPANELMARKETPLACEINBOX_H

View File

@ -0,0 +1,167 @@
/**
* @file llpanelmarketplaceinboxinventory.cpp
* @brief LLInboxInventoryPanel class definition
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llpanelmarketplaceinboxinventory.h"
#include "llfolderview.h"
#include "llfoldervieweventlistener.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llpanellandmarks.h"
#include "llplacesinventorybridge.h"
#include "llviewerfoldertype.h"
//
// statics
//
static LLDefaultChildRegistry::Register<LLInboxInventoryPanel> r1("inbox_inventory_panel");
static LLDefaultChildRegistry::Register<LLInboxFolderViewFolder> r2("inbox_folder_view_folder");
//
// LLInboxInventoryPanel Implementation
//
LLInboxInventoryPanel::LLInboxInventoryPanel(const LLInboxInventoryPanel::Params& p)
: LLInventoryPanel(p)
{
}
LLInboxInventoryPanel::~LLInboxInventoryPanel()
{
}
// virtual
void LLInboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
{
// Determine the root folder in case specified, and
// build the views starting with that folder.
LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false);
// leslie -- temporary HACK to work around sim not creating inbox and outbox with proper system folder type
if (root_id.isNull())
{
std::string start_folder_name(params.start_folder());
LLInventoryModel::cat_array_t* cats;
LLInventoryModel::item_array_t* items;
gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items);
if (cats)
{
for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it)
{
LLInventoryCategory* cat = *cat_it;
if (cat->getName() == start_folder_name)
{
root_id = cat->getUUID();
break;
}
}
}
if (root_id == LLUUID::null)
{
llwarns << "No category found that matches inbox inventory panel start_folder: " << start_folder_name << llendl;
}
}
// leslie -- end temporary HACK
if (root_id == LLUUID::null)
{
llwarns << "Inbox inventory panel has no root folder!" << llendl;
root_id = LLUUID::generateNewID();
}
LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
LLAssetType::AT_CATEGORY,
LLInventoryType::IT_CATEGORY,
this,
NULL,
root_id);
mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
}
LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
{
LLInboxFolderViewFolder::Params params;
params.name = bridge->getDisplayName();
params.icon = bridge->getIcon();
params.icon_open = bridge->getOpenIcon();
if (mShowItemLinkOverlays) // if false, then links show up just like normal items
{
params.icon_overlay = LLUI::getUIImage("Inv_Link");
}
params.root = mFolderRoot;
params.listener = bridge;
params.tool_tip = params.name;
return LLUICtrlFactory::create<LLInboxFolderViewFolder>(params);
}
//
// LLInboxFolderViewFolder Implementation
//
LLInboxFolderViewFolder::LLInboxFolderViewFolder(const Params& p)
: LLFolderViewFolder(p)
, LLBadgeOwner(getHandle())
, mFresh(false)
{
initBadgeParams(p.new_badge());
}
LLInboxFolderViewFolder::~LLInboxFolderViewFolder()
{
}
// virtual
void LLInboxFolderViewFolder::draw()
{
if (!badgeHasParent())
{
addBadgeToParentPanel();
}
setBadgeVisibility(mFresh);
LLFolderViewFolder::draw();
}
// eof

View File

@ -0,0 +1,77 @@
/**
* @file llpanelmarketplaceinboxinventory.h
* @brief LLInboxInventoryPanel class declaration
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_INBOXINVENTORYPANEL_H
#define LL_INBOXINVENTORYPANEL_H
#include "llbadgeowner.h"
#include "llinventorypanel.h"
#include "llfolderviewitem.h"
class LLInboxInventoryPanel : public LLInventoryPanel
{
public:
struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
{
Params() {}
};
LLInboxInventoryPanel(const Params& p);
~LLInboxInventoryPanel();
// virtual
void buildFolderView(const LLInventoryPanel::Params& params);
// virtual
class LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge);
};
class LLInboxFolderViewFolder : public LLFolderViewFolder, public LLBadgeOwner
{
public:
struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
{
Optional<LLBadge::Params> new_badge;
Params()
: new_badge("new_badge")
{
}
};
LLInboxFolderViewFolder(const Params& p);
~LLInboxFolderViewFolder();
void draw();
protected:
bool mFresh;
};
#endif //LL_INBOXINVENTORYPANEL_H

View File

@ -0,0 +1,209 @@
/**
* @file llpanelmarketplaceoutbox.cpp
* @brief Panel for marketplace outbox
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llpanelmarketplaceoutbox.h"
#include "llappviewer.h"
#include "llbutton.h"
#include "llcoros.h"
#include "lleventcoro.h"
#include "llinventorypanel.h"
#include "llloadingindicator.h"
#include "llpanelmarketplaceinbox.h"
#include "llsidepanelinventory.h"
#include "llsidetray.h"
#include "lltimer.h"
static LLRegisterPanelClassWrapper<LLPanelMarketplaceOutbox> t_panel_marketplace_outbox("panel_marketplace_outbox");
const LLPanelMarketplaceOutbox::Params& LLPanelMarketplaceOutbox::getDefaultParams()
{
return LLUICtrlFactory::getDefaultParams<LLPanelMarketplaceOutbox>();
}
// protected
LLPanelMarketplaceOutbox::LLPanelMarketplaceOutbox(const Params& p)
: LLPanel(p)
, mInventoryPanel(NULL)
, mSyncButton(NULL)
, mSyncIndicator(NULL)
, mSyncInProgress(false)
{
}
LLPanelMarketplaceOutbox::~LLPanelMarketplaceOutbox()
{
}
// virtual
BOOL LLPanelMarketplaceOutbox::postBuild()
{
LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLPanelMarketplaceOutbox::handleLoginComplete, this));
LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceOutbox::onFocusReceived, this));
return TRUE;
}
void LLPanelMarketplaceOutbox::handleLoginComplete()
{
mSyncButton = getChild<LLButton>("outbox_sync_btn");
mSyncButton->setCommitCallback(boost::bind(&LLPanelMarketplaceOutbox::onSyncButtonClicked, this));
mSyncButton->setEnabled(!isOutboxEmpty());
mSyncIndicator = getChild<LLLoadingIndicator>("outbox_sync_indicator");
}
void LLPanelMarketplaceOutbox::onFocusReceived()
{
LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
if (sidepanel_inventory)
{
LLInventoryPanel * inv_panel = sidepanel_inventory->getActivePanel();
if (inv_panel)
{
inv_panel->clearSelection();
}
LLInventoryPanel * inbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox");
if (inbox_panel)
{
inbox_panel->clearSelection();
}
sidepanel_inventory->updateVerbs();
}
}
void LLPanelMarketplaceOutbox::onSelectionChange()
{
LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory"));
sidepanel_inventory->updateVerbs();
}
void LLPanelMarketplaceOutbox::setupInventoryPanel()
{
LLView * outbox_inventory_placeholder = getChild<LLView>("outbox_inventory_placeholder");
LLView * outbox_inventory_parent = outbox_inventory_placeholder->getParent();
mInventoryPanel =
LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml",
outbox_inventory_parent,
LLInventoryPanel::child_registry_t::instance());
// Reshape the inventory to the proper size
LLRect inventory_placeholder_rect = outbox_inventory_placeholder->getRect();
mInventoryPanel->setShape(inventory_placeholder_rect);
// Set the sort order newest to oldest, and a selection change callback
mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);
mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceOutbox::onSelectionChange, this));
// Set up the note to display when the outbox is empty
mInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryOutboxNoItems");
// Hide the placeholder text
outbox_inventory_placeholder->setVisible(FALSE);
}
bool LLPanelMarketplaceOutbox::isOutboxEmpty() const
{
// TODO: Check for contents of outbox
return false;
}
bool LLPanelMarketplaceOutbox::isSyncInProgress() const
{
return mSyncInProgress;
}
std::string gTimeDelayDebugFunc = "";
void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel)
{
waitForEventOn(self, "mainloop");
LLTimer delayTimer;
delayTimer.reset();
delayTimer.setTimerExpirySec(5.0f);
while (!delayTimer.hasExpired())
{
waitForEventOn(self, "mainloop");
}
outboxPanel->onSyncComplete();
gTimeDelayDebugFunc = "";
}
void LLPanelMarketplaceOutbox::onSyncButtonClicked()
{
// TODO: Actually trigger sync to marketplace
mSyncInProgress = true;
updateSyncButtonStatus();
// Set a timer (for testing only)
gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this));
}
void LLPanelMarketplaceOutbox::onSyncComplete()
{
mSyncInProgress = false;
updateSyncButtonStatus();
}
void LLPanelMarketplaceOutbox::updateSyncButtonStatus()
{
if (isSyncInProgress())
{
mSyncButton->setVisible(false);
mSyncIndicator->setVisible(true);
mSyncIndicator->reset();
mSyncIndicator->start();
}
else
{
mSyncIndicator->stop();
mSyncIndicator->setVisible(false);
mSyncButton->setVisible(true);
mSyncButton->setEnabled(!isOutboxEmpty());
}
}

View File

@ -0,0 +1,82 @@
/**
* @file llpanelmarketplaceoutbox.h
* @brief Panel for marketplace outbox
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLPANELMARKETPLACEOUTBOX_H
#define LL_LLPANELMARKETPLACEOUTBOX_H
#include "llpanel.h"
class LLButton;
class LLInventoryPanel;
class LLLoadingIndicator;
class LLPanelMarketplaceOutbox : public LLPanel
{
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
Params() {}
};
LOG_CLASS(LLPanelMarketplaceOutbox);
// RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8
static const LLPanelMarketplaceOutbox::Params& getDefaultParams();
LLPanelMarketplaceOutbox(const Params& p = getDefaultParams());
~LLPanelMarketplaceOutbox();
/*virtual*/ BOOL postBuild();
void setupInventoryPanel();
bool isOutboxEmpty() const;
bool isSyncInProgress() const;
void onSyncComplete();
protected:
void onSyncButtonClicked();
void updateSyncButtonStatus();
void handleLoginComplete();
void onFocusReceived();
void onSelectionChange();
private:
LLInventoryPanel * mInventoryPanel;
LLButton * mSyncButton;
LLLoadingIndicator * mSyncIndicator;
bool mSyncInProgress;
};
#endif //LL_LLPANELMARKETPLACEOUTBOX_H

View File

@ -44,6 +44,7 @@
#include "llcallbacklist.h"
#include "llbuycurrencyhtml.h"
#include "llfloaterreg.h"
#include "llfolderview.h"
#include "llinventorybridge.h"
#include "llinventorydefines.h"
#include "llinventoryfilter.h"
@ -58,8 +59,10 @@
#include "llselectmgr.h"
#include "llsidetray.h"
#include "llstatusbar.h"
#include "lltooldraganddrop.h"
#include "lltrans.h"
#include "llviewerassettype.h"
#include "llviewerinventory.h"
#include "llviewerregion.h"
#include "llviewerobjectlist.h"
#include "llviewermessage.h"
@ -761,7 +764,7 @@ void LLTaskCategoryBridge::openItem()
BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
{
//llinfos << "LLTaskInvFVBridge::startDrag()" << llendl;
if(mPanel)
if(mPanel && mUUID.notNull())
{
LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
if(object)
@ -1349,79 +1352,81 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
LLTaskInvFVBridge* new_bridge = NULL;
const LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(object);
const U32 itemflags = ( NULL == item ? 0 : item->getFlags() );
LLAssetType::EType type = object->getType();
LLAssetType::EType type = object ? object->getType() : LLAssetType::AT_CATEGORY;
LLUUID object_id = object ? object->getUUID() : LLUUID::null;
std::string object_name = object ? object->getName() : std::string();
switch(type)
{
case LLAssetType::AT_TEXTURE:
new_bridge = new LLTaskTextureBridge(panel,
object->getUUID(),
object->getName());
object_id,
object_name);
break;
case LLAssetType::AT_SOUND:
new_bridge = new LLTaskSoundBridge(panel,
object->getUUID(),
object->getName());
object_id,
object_name);
break;
case LLAssetType::AT_LANDMARK:
new_bridge = new LLTaskLandmarkBridge(panel,
object->getUUID(),
object->getName());
object_id,
object_name);
break;
case LLAssetType::AT_CALLINGCARD:
new_bridge = new LLTaskCallingCardBridge(panel,
object->getUUID(),
object->getName());
object_id,
object_name);
break;
case LLAssetType::AT_SCRIPT:
// OLD SCRIPTS DEPRECATED - JC
llwarns << "Old script" << llendl;
//new_bridge = new LLTaskOldScriptBridge(panel,
// object->getUUID(),
// object->getName());
// object_id,
// object_name);
break;
case LLAssetType::AT_OBJECT:
new_bridge = new LLTaskObjectBridge(panel,
object->getUUID(),
object->getName(),
object_id,
object_name,
itemflags);
break;
case LLAssetType::AT_NOTECARD:
new_bridge = new LLTaskNotecardBridge(panel,
object->getUUID(),
object->getName());
object_id,
object_name);
break;
case LLAssetType::AT_ANIMATION:
new_bridge = new LLTaskAnimationBridge(panel,
object->getUUID(),
object->getName());
object_id,
object_name);
break;
case LLAssetType::AT_GESTURE:
new_bridge = new LLTaskGestureBridge(panel,
object->getUUID(),
object->getName());
object_id,
object_name);
break;
case LLAssetType::AT_CLOTHING:
case LLAssetType::AT_BODYPART:
new_bridge = new LLTaskWearableBridge(panel,
object->getUUID(),
object->getName(),
object_id,
object_name,
itemflags);
break;
case LLAssetType::AT_CATEGORY:
new_bridge = new LLTaskCategoryBridge(panel,
object->getUUID(),
object->getName());
object_id,
object_name);
break;
case LLAssetType::AT_LSL_TEXT:
new_bridge = new LLTaskLSLBridge(panel,
object->getUUID(),
object->getName());
object_id,
object_name);
break;
case LLAssetType::AT_MESH:
new_bridge = new LLTaskMeshBridge(panel,
object->getUUID(),
object->getName());
object_id,
object_name);
break;
default:
llinfos << "Unhandled inventory type (llassetstorage.h): "
@ -1521,6 +1526,7 @@ void LLPanelObjectInventory::reset()
p.task_id = getTaskUUID();
p.parent_panel = this;
p.tool_tip= LLTrans::getString("PanelContentsTooltip");
p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
mFolders = LLUICtrlFactory::create<LLFolderView>(p);
// this ensures that we never say "searching..." or "no items found"
mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);

View File

@ -36,7 +36,7 @@
#include "lloutfitobserver.h"
#include "llcofwearables.h"
#include "llfilteredwearablelist.h"
#include "llfolderviewitem.h"
#include "llfolderview.h"
#include "llinventory.h"
#include "llinventoryitemslist.h"
#include "llviewercontrol.h"

View File

@ -174,8 +174,8 @@ LLPanelWearing::~LLPanelWearing()
if (gInventory.containsObserver(mCategoriesObserver))
{
gInventory.removeObserver(mCategoriesObserver);
delete mCategoriesObserver;
}
delete mCategoriesObserver;
}
BOOL LLPanelWearing::postBuild()

View File

@ -35,6 +35,7 @@
#include "llinventoryfunctions.h"
#include "llpanellandmarks.h"
#include "llplacesinventorybridge.h"
#include "llviewerfoldertype.h"
static LLDefaultChildRegistry::Register<LLPlacesInventoryPanel> r("places_inventory_panel");
@ -56,72 +57,44 @@ LLPlacesInventoryPanel::~LLPlacesInventoryPanel()
delete mSavedFolderState;
}
BOOL LLPlacesInventoryPanel::postBuild()
void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
{
LLInventoryPanel::postBuild();
// Determine the root folder in case specified, and
// build the views starting with that folder.
const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder);
// clear Contents();
LLUUID root_id;
if ("LIBRARY" == params.start_folder())
{
mFolderRoot->destroyView();
mFolderRoot->getParent()->removeChild(mFolderRoot);
mFolderRoot->die();
if( mScroller )
{
removeChild( mScroller );
mScroller->die();
mScroller = NULL;
}
mFolderRoot = NULL;
root_id = gInventory.getLibraryRootFolderID();
}
else
{
root_id = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
}
mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
// create root folder
{
LLRect folder_rect(0,
0,
getRect().getWidth(),
0);
LLPlacesFolderView::Params p;
p.name = getName();
p.title = getLabel();
p.rect = folder_rect;
p.parent_panel = this;
mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p);
mFolderRoot->setAllowMultiSelect(mAllowMultiSelect);
}
mCommitCallbackRegistrar.popScope();
mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
// scroller
{
LLRect scroller_view_rect = getRect();
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
LLScrollContainer::Params p;
p.name("Inventory Scroller");
p.rect(scroller_view_rect);
p.follows.flags(FOLLOWS_ALL);
p.reserve_scroll_corner(true);
p.tab_stop(true);
mScroller = LLUICtrlFactory::create<LLScrollContainer>(p);
}
addChild(mScroller);
mScroller->addChild(mFolderRoot);
mFolderRoot->setScrollContainer(mScroller);
mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
// cut subitems
mFolderRoot->setUseEllipses(true);
return TRUE;
LLRect folder_rect(0,
0,
getRect().getWidth(),
0);
LLPlacesFolderView::Params p;
p.name = getName();
p.title = getLabel();
p.rect = folder_rect;
p.listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
LLAssetType::AT_CATEGORY,
LLInventoryType::IT_CATEGORY,
this,
NULL,
root_id);
p.parent_panel = this;
p.allow_multiselect = mAllowMultiSelect;
p.use_ellipses = true; // truncate inventory item text so remove horizontal scroller
mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p);
}
// save current folder open state
void LLPlacesInventoryPanel::saveFolderState()
{

View File

@ -46,7 +46,7 @@ public:
LLPlacesInventoryPanel(const Params& p);
~LLPlacesInventoryPanel();
/*virtual*/ BOOL postBuild();
/*virtual*/ void buildFolderView(const LLInventoryPanel::Params& params);
void saveFolderState();
void restoreFolderState();

View File

@ -42,6 +42,7 @@
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llkeyboard.h"
#include "llmultigesture.h"
#include "llnotificationsutil.h"
#include "llradiogroup.h"

View File

@ -55,23 +55,18 @@ LLProgressView* LLProgressView::sInstance = NULL;
S32 gStartImageWidth = 1;
S32 gStartImageHeight = 1;
const F32 FADE_IN_TIME = 1.f;
const std::string ANIMATION_FILENAME = "Login Sequence ";
const std::string ANIMATION_SUFFIX = ".jpg";
const F32 TOTAL_LOGIN_TIME = 10.f; // seconds, wild guess at time from GL context to actual world view
S32 gLastStartAnimationFrame = 0; // human-style indexing, first image = 1
const S32 ANIMATION_FRAMES = 1; //13;
const F32 FADE_TO_WORLD_TIME = 1.0f;
static LLRegisterPanelClassWrapper<LLProgressView> r("progress_view");
// XUI: Translate
LLProgressView::LLProgressView()
: LLPanel(),
mPercentDone( 0.f ),
mMediaCtrl( NULL ),
mMouseDownInActiveArea( false ),
mUpdateEvents("LLProgressView")
mUpdateEvents("LLProgressView"),
mFadeToWorldTimer()
{
mUpdateEvents.listen("self", boost::bind(&LLProgressView::handleUpdate, this, _1));
}
@ -80,9 +75,14 @@ BOOL LLProgressView::postBuild()
{
mProgressBar = getChild<LLProgressBar>("login_progress_bar");
// media control that is used to play intro video
mMediaCtrl = getChild<LLMediaCtrl>("login_media_panel");
mMediaCtrl->setVisible( false ); // hidden initially
mMediaCtrl->addObserver( this ); // watch events
mCancelBtn = getChild<LLButton>("cancel_btn");
mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked, NULL );
mFadeTimer.stop();
mFadeToWorldTimer.stop();
getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle()));
@ -125,24 +125,43 @@ BOOL LLProgressView::handleKeyHere(KEY key, MASK mask)
return TRUE;
}
void LLProgressView::revealIntroPanel()
{
// if user hasn't yet seen intro video
std::string intro_url = gSavedSettings.getString("PostFirstLoginIntroURL");
if ( intro_url.length() > 0 &&
gSavedSettings.getBOOL("PostFirstLoginIntroViewed" ) == FALSE )
{
// navigate to intro URL and reveal widget
mMediaCtrl->navigateTo( intro_url );
mMediaCtrl->setVisible( TRUE );
// flag as having seen the new user post login intro
gSavedSettings.setBOOL("PostFirstLoginIntroViewed", TRUE );
}
else
{
// start the timer that will control the fade through to the world view
mFadeToWorldTimer.start();
}
}
void LLProgressView::setVisible(BOOL visible)
{
// hiding progress view
if (getVisible() && !visible)
{
mFadeTimer.start();
LLPanel::setVisible(FALSE);
}
// showing progress view
else if (visible && (!getVisible() || mFadeTimer.getStarted()))
else if (visible && (!getVisible() || mFadeToWorldTimer.getStarted()))
{
setFocus(TRUE);
mFadeTimer.stop();
mProgressTimer.start();
mFadeToWorldTimer.stop();
LLPanel::setVisible(TRUE);
}
}
void LLProgressView::draw()
{
static LLTimer timer;
@ -153,7 +172,7 @@ void LLProgressView::draw()
{
LLGLSUIDefault gls_ui;
gGL.getTexUnit(0)->bind(gStartTexture.get());
gGL.color4f(1.f, 1.f, 1.f, mFadeTimer.getStarted() ? clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, FADE_IN_TIME, 1.f, 0.f) : 1.f);
gGL.color4f(1.f, 1.f, 1.f, 1.f);
F32 image_aspect = (F32)gStartImageWidth / (F32)gStartImageHeight;
S32 width = getRect().getWidth();
S32 height = getRect().getHeight();
@ -180,16 +199,36 @@ void LLProgressView::draw()
}
glPopMatrix();
// Handle fade-in animation
if (mFadeTimer.getStarted())
// handle fade out to world view when we're asked to
if (mFadeToWorldTimer.getStarted())
{
// draw fading panel
F32 alpha = clamp_rescale(mFadeToWorldTimer.getElapsedTimeF32(), 0.f, FADE_TO_WORLD_TIME, 1.f, 0.f);
LLViewDrawContext context(alpha);
LLPanel::draw();
if (mFadeTimer.getElapsedTimeF32() > FADE_IN_TIME)
// faded out completely - remove panel and reveal world
if (mFadeToWorldTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME )
{
mFadeToWorldTimer.stop();
// Fade is complete, release focus
gFocusMgr.releaseFocusIfNeeded( this );
// turn off panel that hosts intro so we see the world
LLPanel::setVisible(FALSE);
mFadeTimer.stop();
// stop observing events since we no longer care
mMediaCtrl->remObserver( this );
// hide the intro
mMediaCtrl->setVisible( false );
// navigate away from intro page to something innocuous since 'unload' is broken right now
//mMediaCtrl->navigateTo( "about:blank" );
// FIXME: this causes a crash that i haven't been able to fix
mMediaCtrl->unloadMediaSource();
gStartTexture = NULL;
}
@ -307,3 +346,12 @@ bool LLProgressView::onAlertModal(const LLSD& notify)
}
return false;
}
void LLProgressView::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
{
if( event == MEDIA_EVENT_CLOSE_REQUEST )
{
// the intro web content calls javascript::window.close() when it's done
mFadeToWorldTimer.start();
}
}

View File

@ -28,6 +28,7 @@
#define LL_LLPROGRESSVIEW_H
#include "llpanel.h"
#include "llmediactrl.h"
#include "llframetimer.h"
#include "llevents.h"
@ -35,7 +36,10 @@ class LLImageRaw;
class LLButton;
class LLProgressBar;
class LLProgressView : public LLPanel
class LLProgressView :
public LLPanel,
public LLViewerMediaObserver
{
public:
LLProgressView();
@ -49,25 +53,35 @@ public:
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ void setVisible(BOOL visible);
// inherited from LLViewerMediaObserver
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
void setText(const std::string& text);
void setPercent(const F32 percent);
// Set it to NULL when you want to eliminate the message.
void setMessage(const std::string& msg);
// turns on (under certain circumstances) the into video after login
void revealIntroPanel();
void setCancelButtonVisible(BOOL b, const std::string& label);
static void onCancelButtonClicked( void* );
static void onClickMessage(void*);
bool onAlertModal(const LLSD& sd);
// note - this is not just hiding the intro panel - it also hides the parent panel
// and is used when the intro is finished and we want to show the world
void removeIntroPanel();
protected:
LLProgressBar* mProgressBar;
LLMediaCtrl* mMediaCtrl;
F32 mPercentDone;
std::string mMessage;
LLButton* mCancelBtn;
LLFrameTimer mFadeTimer;
LLFrameTimer mProgressTimer;
LLFrameTimer mFadeToWorldTimer;
LLRect mOutlineRect;
bool mMouseDownInActiveArea;

View File

@ -32,6 +32,7 @@
#include "llagentcamera.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
#include "llfolderview.h"
#include "llinventorypanel.h"
#include "llfiltereditor.h"
#include "llfloaterreg.h"

View File

@ -29,33 +29,147 @@
#include "llagent.h"
#include "llappearancemgr.h"
#include "llappviewer.h"
#include "llavataractions.h"
#include "llbutton.h"
#include "lldate.h"
#include "llfirstuse.h"
#include "llfoldertype.h"
#include "llhttpclient.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
#include "lllayoutstack.h"
#include "lloutfitobserver.h"
#include "llpanelmaininventory.h"
#include "llpanelmarketplaceinbox.h"
#include "llpanelmarketplaceoutbox.h"
#include "llselectmgr.h"
#include "llsidepaneliteminfo.h"
#include "llsidepaneltaskinfo.h"
#include "llstring.h"
#include "lltabcontainer.h"
#include "llselectmgr.h"
#include "llviewermedia.h"
#include "llweb.h"
static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_inventory");
LLSidepanelInventory::LLSidepanelInventory()
: LLPanel(),
mItemPanel(NULL),
mPanelMainInventory(NULL)
{
//
// Constants
//
static const char * const INBOX_EXPAND_TIME_SETTING = "LastInventoryInboxExpand";
static const char * const INBOX_BUTTON_NAME = "inbox_btn";
static const char * const OUTBOX_BUTTON_NAME = "outbox_btn";
static const char * const INBOX_LAYOUT_PANEL_NAME = "inbox_layout_panel";
static const char * const OUTBOX_LAYOUT_PANEL_NAME = "outbox_layout_panel";
static const char * const MAIN_INVENTORY_LAYOUT_PANEL_NAME = "main_inventory_layout_panel";
static const char * const INBOX_INVENTORY_PANEL = "inventory_inbox";
static const char * const OUTBOX_INVENTORY_PANEL = "inventory_outbox";
static const char * const INVENTORY_LAYOUT_STACK_NAME = "inventory_layout_stack";
static const char * const MARKETPLACE_INBOX_PANEL = "marketplace_inbox";
static const char * const MARKETPLACE_OUTBOX_PANEL = "marketplace_outbox";
//
// Helpers
//
class LLInboxOutboxAddedObserver : public LLInventoryCategoryAddedObserver
{
public:
LLInboxOutboxAddedObserver(LLSidepanelInventory * sidepanelInventory)
: LLInventoryCategoryAddedObserver()
, mSidepanelInventory(sidepanelInventory)
{
}
void done()
{
for (cat_vec_t::iterator it = mAddedCategories.begin(); it != mAddedCategories.end(); ++it)
{
LLViewerInventoryCategory* added_category = *it;
LLFolderType::EType added_category_type = added_category->getPreferredType();
switch (added_category_type)
{
case LLFolderType::FT_INBOX:
mSidepanelInventory->observeInboxModifications(added_category->getUUID());
break;
case LLFolderType::FT_OUTBOX:
mSidepanelInventory->observeOutboxModifications(added_category->getUUID());
break;
case LLFolderType::FT_NONE:
// HACK until sim update to properly create folder with system type
if (added_category->getName() == "Received Items")
{
mSidepanelInventory->observeInboxModifications(added_category->getUUID());
}
else if (added_category->getName() == "Merchant Outbox")
{
mSidepanelInventory->observeOutboxModifications(added_category->getUUID());
}
default:
break;
}
}
}
private:
LLSidepanelInventory * mSidepanelInventory;
};
//
// Implementation
//
LLSidepanelInventory::LLSidepanelInventory()
: LLPanel()
, mItemPanel(NULL)
, mPanelMainInventory(NULL)
, mInboxEnabled(false)
, mOutboxEnabled(false)
, mCategoriesObserver(NULL)
, mInboxOutboxAddedObserver(NULL)
{
//buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
}
LLSidepanelInventory::~LLSidepanelInventory()
{
if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
{
gInventory.removeObserver(mCategoriesObserver);
}
delete mCategoriesObserver;
if (mInboxOutboxAddedObserver && gInventory.containsObserver(mInboxOutboxAddedObserver))
{
gInventory.removeObserver(mInboxOutboxAddedObserver);
}
delete mInboxOutboxAddedObserver;
}
void handleInventoryDisplayInboxChanged()
{
LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory"));
sidepanel_inventory->enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox"));
}
void handleInventoryDisplayOutboxChanged()
{
LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory"));
sidepanel_inventory->enableOutbox(gSavedSettings.getBOOL("InventoryDisplayOutbox"));
}
BOOL LLSidepanelInventory::postBuild()
@ -85,7 +199,7 @@ BOOL LLSidepanelInventory::postBuild()
mOverflowBtn = mInventoryPanel->getChild<LLButton>("overflow_btn");
mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onOverflowButtonClicked, this));
mPanelMainInventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
mPanelMainInventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2));
LLTabContainer* tabs = mPanelMainInventory->getChild<LLTabContainer>("inventory filter tabs");
tabs->setCommitCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this));
@ -103,7 +217,7 @@ BOOL LLSidepanelInventory::postBuild()
// UI elements from item panel
{
mItemPanel = findChild<LLSidepanelItemInfo>("sidepanel__item_panel");
mItemPanel = getChild<LLSidepanelItemInfo>("sidepanel__item_panel");
LLButton* back_btn = mItemPanel->getChild<LLButton>("back_btn");
back_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onBackButtonClicked, this));
@ -119,13 +233,262 @@ BOOL LLSidepanelInventory::postBuild()
}
}
// Marketplace inbox/outbox setup
{
LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
// Disable user_resize on main inventory panel by default
stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL_NAME, false);
stack->setPanelUserResize(INBOX_LAYOUT_PANEL_NAME, false);
stack->setPanelUserResize(OUTBOX_LAYOUT_PANEL_NAME, false);
// Collapse both inbox and outbox panels
stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME), true);
stack->collapsePanel(getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME), true);
// Set up button states and callbacks
LLButton * inbox_button = getChild<LLButton>(INBOX_BUTTON_NAME);
LLButton * outbox_button = getChild<LLButton>(OUTBOX_BUTTON_NAME);
inbox_button->setToggleState(false);
outbox_button->setToggleState(false);
inbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleInboxBtn, this));
outbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleOutboxBtn, this));
// Set the inbox and outbox visible based on debug settings (final setting comes from http request below)
enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox"));
enableOutbox(gSavedSettings.getBOOL("InventoryDisplayOutbox"));
// Trigger callback for after login so we can setup to track inbox and outbox changes after initial inventory load
LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSidepanelInventory::handleLoginComplete, this));
}
gSavedSettings.getControl("InventoryDisplayInbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayInboxChanged));
gSavedSettings.getControl("InventoryDisplayOutbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayOutboxChanged));
return TRUE;
}
void LLSidepanelInventory::handleLoginComplete()
{
//
// Track inbox and outbox folder changes
//
const bool do_not_create_folder = false;
const bool do_not_find_in_library = false;
const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder, do_not_find_in_library);
const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library);
// Set up observer to listen for creation of inbox and outbox if at least one of them doesn't exist
if (inbox_id.isNull() || outbox_id.isNull())
{
observeInboxOutboxCreation();
}
// Set up observer for inbox changes, if we have an inbox already
if (!inbox_id.isNull())
{
observeInboxModifications(inbox_id);
// Enable the display of the inbox if it exists
enableInbox(true);
}
// Set up observer for outbox changes, if we have an outbox already
if (!outbox_id.isNull())
{
observeOutboxModifications(outbox_id);
// Enable the display of the outbox if it exists
enableOutbox(true);
}
}
void LLSidepanelInventory::observeInboxOutboxCreation()
{
//
// Set up observer to track inbox and outbox folder creation
//
if (mInboxOutboxAddedObserver == NULL)
{
mInboxOutboxAddedObserver = new LLInboxOutboxAddedObserver(this);
gInventory.addObserver(mInboxOutboxAddedObserver);
}
}
void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)
{
//
// Track inbox and outbox folder changes
//
if (inboxID.isNull())
{
llwarns << "Attempting to track modifications to non-existant inbox" << llendl;
return;
}
if (mCategoriesObserver == NULL)
{
mCategoriesObserver = new LLInventoryCategoriesObserver();
gInventory.addObserver(mCategoriesObserver);
}
mCategoriesObserver->addCategory(inboxID, boost::bind(&LLSidepanelInventory::onInboxChanged, this, inboxID));
//
// Trigger a load for the entire contents of the Inbox
//
LLInventoryModelBackgroundFetch::instance().start(inboxID);
//
// Set up the inbox inventory view
//
LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
inbox->setupInventoryPanel();
}
void LLSidepanelInventory::observeOutboxModifications(const LLUUID& outboxID)
{
//
// Track outbox folder changes
//
if (outboxID.isNull())
{
llwarns << "Attempting to track modifications to non-existant outbox" << llendl;
return;
}
if (mCategoriesObserver == NULL)
{
mCategoriesObserver = new LLInventoryCategoriesObserver();
gInventory.addObserver(mCategoriesObserver);
}
mCategoriesObserver->addCategory(outboxID, boost::bind(&LLSidepanelInventory::onOutboxChanged, this, outboxID));
//
// Set up the outbox inventory view
//
LLPanelMarketplaceOutbox * outbox = getChild<LLPanelMarketplaceOutbox>(MARKETPLACE_OUTBOX_PANEL);
outbox->setupInventoryPanel();
}
void LLSidepanelInventory::enableInbox(bool enabled)
{
mInboxEnabled = enabled;
getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME)->setVisible(enabled);
}
void LLSidepanelInventory::enableOutbox(bool enabled)
{
mOutboxEnabled = enabled;
getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME)->setVisible(enabled);
}
void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id)
{
// Trigger a load of the entire inbox so we always know the contents and their creation dates for sorting
LLInventoryModelBackgroundFetch::instance().start(inbox_id);
// Expand the inbox since we have fresh items
LLPanelMarketplaceInbox * inbox = findChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
if (inbox && (inbox->getFreshItemCount() > 0))
{
getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true);
onToggleInboxBtn();
}
}
void LLSidepanelInventory::onOutboxChanged(const LLUUID& outbox_id)
{
// Perhaps use this to track outbox changes?
}
bool manageInboxOutboxPanels(LLLayoutStack * stack,
LLButton * pressedButton, LLLayoutPanel * pressedPanel,
LLButton * otherButton, LLLayoutPanel * otherPanel)
{
bool expand = pressedButton->getToggleState();
bool otherExpanded = otherButton->getToggleState();
//
// NOTE: Ideally we could have two panel sizes stored for a collapsed and expanded minimum size.
// For now, leave this code disabled because it creates some bad artifacts when expanding
// and collapsing the inbox/outbox.
//
//S32 smallMinSize = (expand ? pressedPanel->getMinDim() : otherPanel->getMinDim());
//S32 pressedMinSize = (expand ? 2 * smallMinSize : smallMinSize);
//otherPanel->setMinDim(smallMinSize);
//pressedPanel->setMinDim(pressedMinSize);
if (expand && otherExpanded)
{
// Reshape pressedPanel to the otherPanel's height so we preserve the marketplace panel size
pressedPanel->reshape(pressedPanel->getRect().getWidth(), otherPanel->getRect().getHeight());
stack->collapsePanel(otherPanel, true);
otherButton->setToggleState(false);
}
stack->collapsePanel(pressedPanel, !expand);
// Enable user_resize on main inventory panel only when a marketplace box is expanded
stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL_NAME, expand);
return expand;
}
void LLSidepanelInventory::onToggleInboxBtn()
{
LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
LLButton* pressedButton = getChild<LLButton>(INBOX_BUTTON_NAME);
LLLayoutPanel* pressedPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
LLButton* otherButton = getChild<LLButton>(OUTBOX_BUTTON_NAME);
LLLayoutPanel* otherPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME);
bool inboxExpanded = manageInboxOutboxPanels(stack, pressedButton, pressedPanel, otherButton, otherPanel);
if (inboxExpanded)
{
// Save current time as a setting for future new-ness tests
gSavedSettings.setString(INBOX_EXPAND_TIME_SETTING, LLDate::now().asString());
}
}
void LLSidepanelInventory::onToggleOutboxBtn()
{
LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
LLButton* pressedButton = getChild<LLButton>(OUTBOX_BUTTON_NAME);
LLLayoutPanel* pressedPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME);
LLButton* otherButton = getChild<LLButton>(INBOX_BUTTON_NAME);
LLLayoutPanel* otherPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
manageInboxOutboxPanels(stack, pressedButton, pressedPanel, otherButton, otherPanel);
}
void LLSidepanelInventory::onOpen(const LLSD& key)
{
LLFirstUse::newInventory(false);
// Expand the inbox if we have fresh items
LLPanelMarketplaceInbox * inbox = findChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
if (inbox && (inbox->getFreshItemCount() > 0))
{
getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true);
onToggleInboxBtn();
}
if(key.size() == 0)
return;
@ -171,26 +534,29 @@ void LLSidepanelInventory::onShopButtonClicked()
void LLSidepanelInventory::performActionOnSelection(const std::string &action)
{
LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item)
{
return;
LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox");
if (inbox)
{
current_item = inbox->getRootFolder()->getCurSelectedItem();
}
if (!current_item)
{
return;
}
}
current_item->getListener()->performAction(panel_main_inventory->getActivePanel()->getModel(), action);
}
void LLSidepanelInventory::onWearButtonClicked()
{
LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
if (!panel_main_inventory)
{
llassert(panel_main_inventory != NULL);
return;
}
// Get selected items set.
const std::set<LLUUID> selected_uuids_set = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList();
const std::set<LLUUID> selected_uuids_set = LLAvatarActions::getInventorySelectedUUIDs();
if (selected_uuids_set.empty()) return; // nothing selected
// Convert the set to a vector.
@ -329,31 +695,28 @@ bool LLSidepanelInventory::canShare()
LLPanelMainInventory* panel_main_inventory =
mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
if (!panel_main_inventory)
{
llwarns << "Failed to get the main inventory panel" << llendl;
return false;
}
LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox");
// Avoid flicker in the Recent tab while inventory is being loaded.
if ( (!inbox || inbox->getRootFolder()->getSelectionList().empty())
&& (panel_main_inventory && !panel_main_inventory->getActivePanel()->getRootFolder()->hasVisibleChildren()) )
{
return false;
}
LLInventoryPanel* active_panel = panel_main_inventory->getActivePanel();
// Avoid flicker in the Recent tab while inventory is being loaded.
if (!active_panel->getRootFolder()->hasVisibleChildren()) return false;
return LLAvatarActions::canShareSelectedItems(active_panel);
return ( (panel_main_inventory ? LLAvatarActions::canShareSelectedItems(panel_main_inventory->getActivePanel()) : false)
|| (inbox ? LLAvatarActions::canShareSelectedItems(inbox) : false) );
}
bool LLSidepanelInventory::canWearSelected()
{
LLPanelMainInventory* panel_main_inventory =
mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
if (!panel_main_inventory)
{
llassert(panel_main_inventory != NULL);
std::set<LLUUID> selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
if (selected_uuids.empty())
return false;
}
std::set<LLUUID> selected_uuids = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList();
for (std::set<LLUUID>::const_iterator it = selected_uuids.begin();
it != selected_uuids.end();
++it)
@ -366,11 +729,20 @@ bool LLSidepanelInventory::canWearSelected()
LLInventoryItem *LLSidepanelInventory::getSelectedItem()
{
LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item)
{
return NULL;
LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox");
if (inbox)
{
current_item = inbox->getRootFolder()->getCurSelectedItem();
}
if (!current_item)
{
return NULL;
}
}
const LLUUID &item_id = current_item->getListener()->getUUID();
LLInventoryItem *item = gInventory.getItem(item_id);
@ -379,9 +751,20 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()
U32 LLSidepanelInventory::getSelectedCount()
{
LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
int count = 0;
LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
std::set<LLUUID> selection_list = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList();
return selection_list.size();
count += selection_list.size();
LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox");
if (inbox)
{
selection_list = inbox->getRootFolder()->getSelectionList();
count += selection_list.size();
}
return count;
}
LLInventoryPanel *LLSidepanelInventory::getActivePanel()

View File

@ -30,6 +30,8 @@
#include "llpanel.h"
class LLFolderViewItem;
class LLInboxOutboxAddedObserver;
class LLInventoryCategoriesObserver;
class LLInventoryItem;
class LLInventoryPanel;
class LLPanelMainInventory;
@ -42,6 +44,14 @@ public:
LLSidepanelInventory();
virtual ~LLSidepanelInventory();
private:
void handleLoginComplete();
public:
void observeInboxOutboxCreation();
void observeInboxModifications(const LLUUID& inboxID);
void observeOutboxModifications(const LLUUID& outboxID);
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
@ -56,6 +66,17 @@ public:
// checks can share selected item(s)
bool canShare();
void onToggleInboxBtn();
void onToggleOutboxBtn();
void enableInbox(bool enabled);
void enableOutbox(bool enabled);
bool isInboxEnabled() const { return mInboxEnabled; }
bool isOutboxEnabled() const { return mOutboxEnabled; }
void updateVerbs();
protected:
// Tracks highlighted (selected) item in inventory panel.
LLInventoryItem *getSelectedItem();
@ -63,10 +84,12 @@ protected:
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
// "wear", "teleport", etc.
void performActionOnSelection(const std::string &action);
void updateVerbs();
bool canWearSelected(); // check whether selected items can be worn
void onInboxChanged(const LLUUID& inbox_id);
void onOutboxChanged(const LLUUID& outbox_id);
//
// UI Elements
//
@ -85,6 +108,7 @@ protected:
void onTeleportButtonClicked();
void onOverflowButtonClicked();
void onBackButtonClicked();
private:
LLButton* mInfoBtn;
LLButton* mShareBtn;
@ -94,6 +118,11 @@ private:
LLButton* mOverflowBtn;
LLButton* mShopBtn;
bool mInboxEnabled;
bool mOutboxEnabled;
LLInventoryCategoriesObserver* mCategoriesObserver;
LLInboxOutboxAddedObserver* mInboxOutboxAddedObserver;
};
#endif //LL_LLSIDEPANELINVENTORY_H

View File

@ -46,8 +46,8 @@
///----------------------------------------------------------------------------
// Default constructor
LLSidepanelInventorySubpanel::LLSidepanelInventorySubpanel()
: LLPanel(),
LLSidepanelInventorySubpanel::LLSidepanelInventorySubpanel(const LLPanel::Params& p)
: LLPanel(p),
mIsDirty(TRUE),
mIsEditing(FALSE),
mCancelBtn(NULL),

View File

@ -40,7 +40,7 @@ class LLInventoryItem;
class LLSidepanelInventorySubpanel : public LLPanel
{
public:
LLSidepanelInventorySubpanel();
LLSidepanelInventorySubpanel(const LLPanel::Params& p = getDefaultParams());
virtual ~LLSidepanelInventorySubpanel();
/*virtual*/ void setVisible(BOOL visible);

View File

@ -130,9 +130,10 @@ void LLObjectInventoryObserver::inventoryChanged(LLViewerObject* object,
static LLRegisterPanelClassWrapper<LLSidepanelItemInfo> t_item_info("sidepanel_item_info");
// Default constructor
LLSidepanelItemInfo::LLSidepanelItemInfo()
: mItemID(LLUUID::null)
, mObjectInventoryObserver(NULL)
LLSidepanelItemInfo::LLSidepanelItemInfo(const LLPanel::Params& p)
: LLSidepanelInventorySubpanel(p)
, mItemID(LLUUID::null)
, mObjectInventoryObserver(NULL)
{
mPropertiesObserver = new LLItemPropertiesObserver(this);
}

View File

@ -44,7 +44,7 @@ class LLPermissions;
class LLSidepanelItemInfo : public LLSidepanelInventorySubpanel
{
public:
LLSidepanelItemInfo();
LLSidepanelItemInfo(const LLPanel::Params& p = getDefaultParams());
virtual ~LLSidepanelItemInfo();
/*virtual*/ BOOL postBuild();

View File

@ -30,6 +30,7 @@
#include "llagentcamera.h"
#include "llappviewer.h"
#include "llbadge.h"
#include "llbottomtray.h"
#include "llfloaterreg.h"
#include "llfirstuse.h"
@ -40,6 +41,7 @@
#include "llfocusmgr.h"
#include "llrootview.h"
#include "llnavigationbar.h"
#include "llpanelmarketplaceinbox.h"
#include "llaccordionctrltab.h"
@ -113,11 +115,14 @@ public:
Optional<std::string> image_selected;
Optional<std::string> tab_title;
Optional<std::string> description;
Optional<LLBadge::Params> badge;
Params()
: image("image"),
image_selected("image_selected"),
tab_title("tab_title","no title"),
description("description","no description")
description("description","no description"),
badge("badge")
{};
};
protected:
@ -140,7 +145,6 @@ public:
static LLSideTrayTab* createInstance ();
const std::string& getDescription () const { return mDescription;}
const std::string& getTabTitle() const { return mTabTitle;}
void onOpen (const LLSD& key);
@ -150,7 +154,10 @@ public:
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
LLPanel *getPanel();
LLPanel* getPanel();
LLButton* createButton(bool allowTearOff, LLUICtrl::commit_callback_t callback);
private:
std::string mTabTitle;
std::string mImage;
@ -158,6 +165,9 @@ private:
std::string mDescription;
LLView* mMainPanel;
bool mHasBadge;
LLBadge::Params mBadgeParams;
};
LLSideTrayTab::LLSideTrayTab(const Params& p)
@ -166,8 +176,10 @@ LLSideTrayTab::LLSideTrayTab(const Params& p)
mImage(p.image),
mImageSelected(p.image_selected),
mDescription(p.description),
mMainPanel(NULL)
mMainPanel(NULL),
mBadgeParams(p.badge)
{
mHasBadge = p.badge.isProvided();
}
LLSideTrayTab::~LLSideTrayTab()
@ -182,8 +194,6 @@ bool LLSideTrayTab::addChild(LLView* view, S32 tab_group)
//return res;
}
//virtual
BOOL LLSideTrayTab::postBuild()
{
@ -196,7 +206,7 @@ BOOL LLSideTrayTab::postBuild()
getChild<LLButton>("undock")->setCommitCallback(boost::bind(&LLSideTrayTab::setDocked, this, false));
getChild<LLButton>("dock")->setCommitCallback(boost::bind(&LLSideTrayTab::setDocked, this, true));
return true;
return LLPanel::postBuild();
}
static const S32 splitter_margin = 1;
@ -523,18 +533,36 @@ public:
return FALSE;
}
void setBadgeDriver(LLSideTrayTabBadgeDriver* driver)
{
mBadgeDriver = driver;
}
protected:
LLSideTrayButton(const LLButton::Params& p)
: LLButton(p)
, mDragLastScreenX(0)
, mDragLastScreenY(0)
: LLButton(p)
, mDragLastScreenX(0)
, mDragLastScreenY(0)
, mBadgeDriver(NULL)
{}
friend class LLUICtrlFactory;
void draw()
{
if (mBadgeDriver)
{
setBadgeLabel(mBadgeDriver->getBadgeString());
}
LLButton::draw();
}
private:
S32 mDragLastScreenX;
S32 mDragLastScreenY;
LLSideTrayTabBadgeDriver* mBadgeDriver;
};
//////////////////////////////////////////////////////////////////////////////
@ -615,11 +643,31 @@ BOOL LLSideTray::postBuild()
return true;
}
void LLSideTray::setTabButtonBadgeDriver(std::string tabName, LLSideTrayTabBadgeDriver* driver)
{
mTabButtonBadgeDrivers[tabName] = driver;
}
void LLSideTray::handleLoginComplete()
{
//reset tab to "home" tab if it was changesd during login process
selectTabByName("sidebar_home");
for (badge_map_t::iterator it = mTabButtonBadgeDrivers.begin(); it != mTabButtonBadgeDrivers.end(); ++it)
{
LLButton* button = mTabButtons[it->first];
LLSideTrayButton* side_button = dynamic_cast<LLSideTrayButton*>(button);
if (side_button)
{
side_button->setBadgeDriver(it->second);
}
else
{
llwarns << "Unable to find button " << it->first << " to set the badge driver. " << llendl;
}
}
detachTabs();
}
@ -766,51 +814,6 @@ bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible
return true;
}
LLButton* LLSideTray::createButton (const std::string& name,const std::string& image,const std::string& tooltip,
LLUICtrl::commit_callback_t callback)
{
static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());
LLButton::Params bparams;
LLRect rect;
rect.setOriginAndSize(0, 0, sidetray_params.default_button_width, sidetray_params.default_button_height);
bparams.name(name);
bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_TOP);
bparams.rect (rect);
bparams.tab_stop(false);
bparams.image_unselected(sidetray_params.tab_btn_image_normal);
bparams.image_selected(sidetray_params.tab_btn_image_selected);
bparams.image_disabled(sidetray_params.tab_btn_image_normal);
bparams.image_disabled_selected(sidetray_params.tab_btn_image_selected);
LLButton* button;
if (name == "sidebar_openclose")
{
// "Open/Close" button shouldn't allow "tear off"
// hence it is created as LLButton instance.
button = LLUICtrlFactory::create<LLButton>(bparams);
}
else
{
button = LLUICtrlFactory::create<LLSideTrayButton>(bparams);
}
button->setClickedCallback(callback);
button->setToolTip(tooltip);
if(image.length())
{
button->setImageOverlay(image);
}
mButtonsPanel->addChildInBack(button);
return button;
}
bool LLSideTray::addChild(LLView* view, S32 tab_group)
{
LLSideTrayTab* tab_panel = dynamic_cast<LLSideTrayTab*>(view);
@ -938,7 +941,56 @@ bool LLSideTray::addTab(LLSideTrayTab* tab)
return true;
}
void LLSideTray::createButtons ()
LLButton* LLSideTrayTab::createButton(bool allowTearOff, LLUICtrl::commit_callback_t callback)
{
static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());
LLRect rect;
rect.setOriginAndSize(0, 0, sidetray_params.default_button_width, sidetray_params.default_button_height);
LLButton::Params bparams;
// Append "_button" to the side tray tab name
std::string button_name = getName() + "_button";
bparams.name(button_name);
bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_TOP);
bparams.rect (rect);
bparams.tab_stop(false);
bparams.image_unselected(sidetray_params.tab_btn_image_normal);
bparams.image_selected(sidetray_params.tab_btn_image_selected);
bparams.image_disabled(sidetray_params.tab_btn_image_normal);
bparams.image_disabled_selected(sidetray_params.tab_btn_image_selected);
if (mHasBadge)
{
bparams.badge = mBadgeParams;
}
LLButton* button;
if (allowTearOff)
{
button = LLUICtrlFactory::create<LLSideTrayButton>(bparams);
}
else
{
// "Open/Close" button shouldn't allow "tear off"
// hence it is created as LLButton instance.
button = LLUICtrlFactory::create<LLButton>(bparams);
}
button->setClickedCallback(callback);
button->setToolTip(mTabTitle);
if(mImage.length())
{
button->setImageOverlay(mImage);
}
return button;
}
void LLSideTray::createButtons()
{
//create buttons for tabs
child_vector_const_iter_t child_it = mTabs.begin();
@ -951,17 +1003,22 @@ void LLSideTray::createButtons ()
// The "OpenClose" button will open/close the whole panel
if (name == "sidebar_openclose")
{
mCollapseButton = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(),
boost::bind(&LLSideTray::onToggleCollapse, this));
mCollapseButton = sidebar_tab->createButton(false, boost::bind(&LLSideTray::onToggleCollapse, this));
mButtonsPanel->addChildInBack(mCollapseButton);
LLHints::registerHintTarget("side_panel_btn", mCollapseButton->getHandle());
}
else
{
LLButton* button = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(),
boost::bind(&LLSideTray::onTabButtonClick, this, name));
LLButton* button = sidebar_tab->createButton(true, boost::bind(&LLSideTray::onTabButtonClick, this, name));
mButtonsPanel->addChildInBack(button);
mTabButtons[name] = button;
}
}
LLHints::registerHintTarget("inventory_btn", mTabButtons["sidebar_inventory"]->getHandle());
}

View File

@ -33,6 +33,13 @@
class LLAccordionCtrl;
class LLSideTrayTab;
// Define an interface for side tab button badge values
class LLSideTrayTabBadgeDriver
{
public:
virtual std::string getBadgeString() const = 0;
};
// Deal with LLSideTrayTab being opaque. Generic do-nothing cast...
template <class T>
T tab_cast(LLSideTrayTab* tab) { return tab; }
@ -166,6 +173,8 @@ public:
bool getCollapsed() { return mCollapsed; }
void setTabButtonBadgeDriver(std::string tabName, LLSideTrayTabBadgeDriver* driver);
public:
virtual ~LLSideTray(){};
@ -204,8 +213,6 @@ protected:
void createButtons ();
LLButton* createButton (const std::string& name,const std::string& image,const std::string& tooltip,
LLUICtrl::commit_callback_t callback);
void arrange ();
void detachTabs ();
void reflectCollapseChange();
@ -234,6 +241,8 @@ private:
LLPanel* mButtonsPanel;
typedef std::map<std::string,LLButton*> button_map_t;
button_map_t mTabButtons;
typedef std::map<std::string,LLSideTrayTabBadgeDriver*> badge_map_t;
badge_map_t mTabButtonBadgeDrivers;
child_vector_t mTabs;
child_vector_t mDetachedTabs;
tab_order_vector_t mOriginalTabOrder;

View File

@ -76,6 +76,7 @@
#include "lluserrelations.h"
#include "llversioninfo.h"
#include "llviewercontrol.h"
#include "llviewerhelp.h"
#include "llvfs.h"
#include "llxorcipher.h" // saved password, MAC address
#include "llwindow.h"
@ -1689,11 +1690,22 @@ bool idle_startup()
gViewerThrottle.setMaxBandwidth(FAST_RATE_BPS / 1024.f);
}
if (gSavedSettings.getBOOL("ShowHelpOnFirstLogin"))
{
gSavedSettings.setBOOL("HelpFloaterOpen", TRUE);
}
// Set the show start location to true, now that the user has logged
// on with this install.
gSavedSettings.setBOOL("ShowStartLocation", TRUE);
}
if (gSavedSettings.getBOOL("HelpFloaterOpen"))
{
// show default topic
LLViewerHelp::instance().showTopic("");
}
// We're successfully logged in.
gSavedSettings.setBOOL("FirstLoginThisInstall", FALSE);
@ -1950,7 +1962,8 @@ bool idle_startup()
gViewerWindow->getWindow()->resetBusyCount();
gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
LL_DEBUGS("AppInit") << "Done releasing bitmap" << LL_ENDL;
gViewerWindow->setShowProgress(FALSE);
gViewerWindow->revealIntroPanel();
//gViewerWindow->setShowProgress(FALSE); // reveal intro video now handles this
gViewerWindow->setProgressCancelButtonVisible(FALSE);
// We're not away from keyboard, even though login might have taken

View File

@ -420,7 +420,6 @@ BOOL LLFloaterTexturePicker::postBuild()
mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));
mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
mInventoryPanel->setAllowMultiSelect(FALSE);
// Disable auto selecting first filtered item because it takes away
// selection from the item set by LLTextureCtrl owning this floater.

View File

@ -128,8 +128,10 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE));
addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE));
addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "Inv_SysOpen", "Inv_SysClosed", FALSE));
addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Outbox", "Inv_SysOpen", "Inv_SysClosed", FALSE));
addEntry(LLFolderType::FT_BASIC_ROOT, new ViewerFolderEntry("Basic Root", "Inv_SysOpen", "Inv_SysClosed", FALSE));
addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "Inv_FolderOpen", "Inv_FolderClosed", FALSE, "default"));

View File

@ -101,8 +101,9 @@ void LLViewerHelp::showTopic(const std::string &topic)
// work out the URL for this topic and display it
showHelp();
std::string helpURL = LLViewerHelpUtil::buildHelpURL( help_topic );
setRawURL( helpURL );
setRawURL(helpURL);
}
std::string LLViewerHelp::defaultTopic()
@ -148,18 +149,7 @@ std::string LLViewerHelp::getTopicFromFocus()
// static
void LLViewerHelp::showHelp()
{
LLFloaterHelpBrowser* helpbrowser = dynamic_cast<LLFloaterHelpBrowser*>(LLFloaterReg::getInstance("help_browser"));
if (helpbrowser)
{
BOOL visible = TRUE;
BOOL take_focus = TRUE;
helpbrowser->setVisible(visible);
helpbrowser->setFrontmost(take_focus);
}
else
{
llwarns << "Eep, help_browser floater not found" << llendl;
}
LLFloaterReg::showInstance("help_browser");
}
// static

View File

@ -1269,7 +1269,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
{
std::string type_name = userdata.asString();
if (("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name))
if (("inbox" == type_name) || ("outbox" == type_name) || ("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name))
{
LLFolderType::EType preferred_type = LLFolderType::lookup(type_name);

View File

@ -64,8 +64,10 @@
#include "llappviewer.h"
#include "lllogininstance.h"
//#include "llfirstuse.h"
#include "llviewernetwork.h"
#include "llwindow.h"
#include "llfloatermediabrowser.h" // for handling window close requests and geometry change requests in media browser windows.
#include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows.
@ -1360,6 +1362,34 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom
}
class LLInventoryUserStatusResponder : public LLHTTPClient::Responder
{
public:
LLInventoryUserStatusResponder()
: LLCurl::Responder()
{
}
void completed(U32 status, const std::string& reason, const LLSD& content)
{
if (isGoodStatus(status))
{
// Complete success
gSavedSettings.setBOOL("InventoryDisplayInbox", true);
}
else if (status == 401)
{
// API is available for use but OpenID authorization failed
gSavedSettings.setBOOL("InventoryDisplayInbox", true);
}
else
{
// API in unavailable
llinfos << "Marketplace API is unavailable -- Inbox may be disabled, status = " << status << ", reason = " << reason << llendl;
}
}
};
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::setOpenIDCookie()
@ -1406,6 +1436,25 @@ void LLViewerMedia::setOpenIDCookie()
LLHTTPClient::get(profile_url,
new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),
headers);
std::string url = "https://marketplace.secondlife.com/";
if (!LLGridManager::getInstance()->isInProductionGrid())
{
std::string gridLabel = LLGridManager::getInstance()->getGridLabel();
url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str());
}
url += "api/1/users/";
url += gAgent.getID().getString();
url += "/user_status";
headers = LLSD::emptyMap();
headers["Accept"] = "*/*";
headers["Cookie"] = sOpenIDCookie;
headers["User-Agent"] = getCurrentUserAgent();
LLHTTPClient::get(url, new LLInventoryUserStatusResponder(), headers);
}
}
@ -2349,15 +2398,13 @@ void LLViewerMediaImpl::updateJavascriptObject()
if ( mMediaSource )
{
// flag to expose this information to internal browser or not.
bool expose_javascript_object = gSavedSettings.getBOOL("BrowserEnableJSObject");
mMediaSource->jsExposeObjectEvent( expose_javascript_object );
bool enable = gSavedSettings.getBOOL("BrowserEnableJSObject");
mMediaSource->jsEnableObject( enable );
// indicate if the values we have are valid (currently do this blanket-fashion for
// everything depending on whether you are logged in or not - this may require a
// more granular approach once variables are added that ARE valid before login
// these values are only menaingful after login so don't set them before
bool logged_in = LLLoginInstance::getInstance()->authSuccess();
mMediaSource->jsValuesValidEvent( logged_in );
if ( logged_in )
{
// current location within a region
LLVector3 agent_pos = gAgent.getPositionAgent();
double x = agent_pos.mV[ VX ];
@ -2386,6 +2433,7 @@ void LLViewerMediaImpl::updateJavascriptObject()
region_name = region->getName();
};
mMediaSource->jsAgentRegionEvent( region_name );
}
// language code the viewer is set to
mMediaSource->jsAgentLanguageEvent( LLUI::getLanguage() );

View File

@ -108,6 +108,7 @@
#include "lltrans.h"
#include "lleconomy.h"
#include "lltoolgrab.h"
#include "llwindow.h"
#include "boost/unordered_map.hpp"
using namespace LLVOAvatarDefines;

View File

@ -37,6 +37,7 @@
#include "lleconomy.h"
#include "lleventtimer.h"
#include "llfloaterreg.h"
#include "llfolderview.h"
#include "llfollowcamparams.h"
#include "llinventorydefines.h"
#include "lllslconstants.h"
@ -87,6 +88,7 @@
#include "lluri.h"
#include "llviewergenericmessage.h"
#include "llviewermenu.h"
#include "llviewerinventory.h"
#include "llviewerjoystick.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
@ -694,7 +696,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
return false;
}
static void highlight_inventory_items_in_panel(const std::vector<LLUUID>& items, LLInventoryPanel *inventory_panel)
static void highlight_inventory_objects_in_panel(const std::vector<LLUUID>& items, LLInventoryPanel *inventory_panel)
{
if (NULL == inventory_panel) return;
@ -708,7 +710,7 @@ static void highlight_inventory_items_in_panel(const std::vector<LLUUID>& items,
continue;
}
LLInventoryItem* item = gInventory.getItem(item_id);
LLInventoryObject* item = gInventory.getObject(item_id);
llassert(item);
if (!item) {
continue;
@ -787,7 +789,6 @@ class LLViewerInventoryMoveFromWorldObserver : public LLInventoryAddItemByAssetO
public:
LLViewerInventoryMoveFromWorldObserver()
: LLInventoryAddItemByAssetObserver()
, mActivePanel(NULL)
{
}
@ -798,13 +799,16 @@ private:
/*virtual */void onAssetAdded(const LLUUID& asset_id)
{
// Store active Inventory panel.
mActivePanel = LLInventoryPanel::getActiveInventoryPanel();
if (LLInventoryPanel::getActiveInventoryPanel())
{
mActivePanel = LLInventoryPanel::getActiveInventoryPanel()->getHandle();
}
// Store selected items (without destination folder)
mSelectedItems.clear();
if (mActivePanel)
if (LLInventoryPanel::getActiveInventoryPanel())
{
mSelectedItems = mActivePanel->getRootFolder()->getSelectionList();
mSelectedItems = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
}
mSelectedItems.erase(mMoveIntoFolderID);
}
@ -815,12 +819,14 @@ private:
*/
void done()
{
LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get());
// if selection is not changed since watch started lets hightlight new items.
if (mActivePanel && !isSelectionChanged())
if (active_panel && !isSelectionChanged())
{
LL_DEBUGS("Inventory_Move") << "Selecting new items..." << LL_ENDL;
mActivePanel->clearSelection();
highlight_inventory_items_in_panel(mAddedItems, mActivePanel);
active_panel->clearSelection();
highlight_inventory_objects_in_panel(mAddedItems, active_panel);
}
}
@ -828,16 +834,16 @@ private:
* Returns true if selected inventory items were changed since moved inventory items were started to watch.
*/
bool isSelectionChanged()
{
const LLInventoryPanel * const current_active_panel = LLInventoryPanel::getActiveInventoryPanel();
{
LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get());
if (NULL == mActivePanel || current_active_panel != mActivePanel)
if (NULL == active_panel)
{
return true;
}
// get selected items (without destination folder)
selected_items_t selected_items = mActivePanel->getRootFolder()->getSelectionList();
selected_items_t selected_items = active_panel->getRootFolder()->getSelectionList();
selected_items.erase(mMoveIntoFolderID);
// compare stored & current sets of selected items
@ -851,7 +857,7 @@ private:
return different_items.size() > 0;
}
LLInventoryPanel *mActivePanel;
LLHandle<LLPanel> mActivePanel;
typedef std::set<LLUUID> selected_items_t;
selected_items_t mSelectedItems;
@ -880,6 +886,75 @@ void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder
gInventoryMoveObserver->watchAsset(inv_item->getAssetUUID());
}
/**
* Class to observe moving of items and to select them in inventory.
*
* Used currently for dragging from inbox to regular inventory folders
*/
class LLViewerInventoryMoveObserver : public LLInventoryObserver
{
public:
LLViewerInventoryMoveObserver(const LLUUID& object_id)
: LLInventoryObserver()
, mObjectID(object_id)
{
if (LLInventoryPanel::getActiveInventoryPanel())
{
mActivePanel = LLInventoryPanel::getActiveInventoryPanel()->getHandle();
}
}
virtual ~LLViewerInventoryMoveObserver() {}
virtual void changed(U32 mask);
private:
LLUUID mObjectID;
LLHandle<LLPanel> mActivePanel;
};
void LLViewerInventoryMoveObserver::changed(U32 mask)
{
LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get());
if (NULL == active_panel)
{
gInventory.removeObserver(this);
return;
}
if((mask & (LLInventoryObserver::STRUCTURE)) != 0)
{
const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
std::set<LLUUID>::const_iterator id_it = changed_items.begin();
std::set<LLUUID>::const_iterator id_end = changed_items.end();
for (;id_it != id_end; ++id_it)
{
if ((*id_it) == mObjectID)
{
active_panel->clearSelection();
std::vector<LLUUID> items;
items.push_back(mObjectID);
highlight_inventory_objects_in_panel(items, active_panel);
active_panel->getRootFolder()->scrollToShowSelection();
gInventory.removeObserver(this);
break;
}
}
}
}
void set_dad_inbox_object(const LLUUID& object_id)
{
LLViewerInventoryMoveObserver* move_observer = new LLViewerInventoryMoveObserver(object_id);
gInventory.addObserver(move_observer);
}
//unlike the FetchObserver for AgentOffer, we only make one
//instance of the AddedObserver for TaskOffers
//and it never dies. We do this because we don't know the UUID of
@ -936,7 +1011,6 @@ protected:
//one global instance to bind them
LLOpenTaskOffer* gNewInventoryObserver=NULL;
class LLNewInventoryHintObserver : public LLInventoryAddedObserver
{
protected:
@ -946,6 +1020,8 @@ protected:
}
};
LLNewInventoryHintObserver* gNewInventoryHintObserver=NULL;
void start_new_inventory_observer()
{
if (!gNewInventoryObserver) //task offer observer
@ -962,7 +1038,12 @@ void start_new_inventory_observer()
gInventory.addObserver(gInventoryMoveObserver);
}
gInventory.addObserver(new LLNewInventoryHintObserver());
if (!gNewInventoryHintObserver)
{
// Observer is deleted by gInventory
gNewInventoryHintObserver = new LLNewInventoryHintObserver();
gInventory.addObserver(gNewInventoryHintObserver);
}
}
class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver
@ -4324,7 +4405,7 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
{
return;
}
// Don't play sounds from gestures if they are not enabled.
if (object_id == owner_id && !gSavedSettings.getBOOL("EnableGestureSounds"))
{
@ -6499,7 +6580,7 @@ void process_script_dialog(LLMessageSystem* msg, void**)
LLUUID owner_id;
if (gMessageSystem->getNumberOfBlocks("OwnerData") > 0)
{
msg->getUUID("OwnerData", "OwnerID", owner_id);
msg->getUUID("OwnerData", "OwnerID", owner_id);
}
if (LLMuteList::getInstance()->isMuted(object_id) || LLMuteList::getInstance()->isMuted(owner_id))

View File

@ -203,6 +203,8 @@ void open_inventory_offer(const uuid_vec_t& items, const std::string& from_name)
bool highlight_offered_object(const LLUUID& obj_id);
void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid);
void set_dad_inbox_object(const LLUUID& object_id);
class LLOfferInfo : public LLNotificationResponderInterface
{

View File

@ -33,6 +33,8 @@
// in viewer.
// It is used to precompile headers for improved build speed.
#include <boost/coroutine/coroutine.hpp>
#include "linden_common.h"
// Work around stupid Microsoft STL warning
@ -118,8 +120,8 @@
// Library includes from llvfs
#include "lldir.h"
// Library includes from llmessage project
// Library includes from llmessage project
#include "llcachename.h"
#endif

View File

@ -1979,7 +1979,10 @@ void LLViewerWindow::shutdownViews()
// destroy the nav bar, not currently part of gViewerWindow
// *TODO: Make LLNavigationBar part of gViewerWindow
if (LLNavigationBar::instanceExists())
{
delete LLNavigationBar::getInstance();
}
// destroy menus after instantiating navbar above, as it needs
// access to gMenuHolder
@ -4512,6 +4515,14 @@ void LLViewerWindow::setup3DViewport(S32 x_offset, S32 y_offset)
glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
}
void LLViewerWindow::revealIntroPanel()
{
if (mProgressView)
{
mProgressView->revealIntroPanel();
}
}
void LLViewerWindow::setShowProgress(const BOOL show)
{
if (mProgressView)

View File

@ -271,6 +271,7 @@ public:
void setProgressMessage(const std::string& msg);
void setProgressCancelButtonVisible( BOOL b, const std::string& label = LLStringUtil::null );
LLProgressView *getProgressView() const;
void revealIntroPanel();
void updateObjectUnderCursor();

View File

@ -132,6 +132,15 @@
<color
name="AvatarListItemIconVoiceLeftColor"
reference="AvatarListItemIconOfflineColor" />
<color
name="BadgeImageColor"
value="0.44 0.69 0.56 1.0" />
<color
name="BadgeBorderColor"
value="0.9 0.9 0.9 1.0" />
<color
name="BadgeLabelColor"
reference="White" />
<color
name="ButtonBorderColor"
reference="Unused?" />
@ -760,7 +769,7 @@
<color
name="MenuBarProjectBgColor"
reference="MdBlue" />
<color
name="MeshImportTableNormalColor"
value="1 1 1 1"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Some files were not shown because too many files have changed in this diff Show More