Richard Linden 2011-06-23 11:28:23 -07:00
commit 70fc5af53f
106 changed files with 3011 additions and 723 deletions

View File

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

@ -93,6 +93,7 @@ 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_NONE, new FolderEntry("-1", FALSE));
};

View File

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

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
@ -119,6 +121,8 @@ set(llui_HEADER_FILES
llaccordionctrl.h
llaccordionctrltab.h
llbadge.h
llbadgeowner.h
llbutton.h
llcallbackmap.h
llcheckboxctrl.h
@ -245,11 +249,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

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

@ -0,0 +1,118 @@
/**
* @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::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);
}

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

@ -0,0 +1,58 @@
/**
* @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();
void setBadgeLabel(const LLStringExplicit& label);
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, 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, 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,7 +325,7 @@ 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)
@ -366,9 +375,9 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
if (mOrientation == HORIZONTAL)
{
// enforce minimize size constraint by default
if (panelp->getRect().getWidth() < (*panel_it)->mMinDim)
if (panelp->getRect().getWidth() < (*panel_it)->getRelevantMinDim())
{
panelp->reshape((*panel_it)->mMinDim, panelp->getRect().getHeight());
panelp->reshape((*panel_it)->getRelevantMinDim(), panelp->getRect().getHeight());
}
total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor(mOrientation));
// want n-1 panel gaps for n panels
@ -380,9 +389,9 @@ 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() < (*panel_it)->getRelevantMinDim())
{
panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinDim);
panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->getRelevantMinDim());
}
total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor(mOrientation));
if (panel_it != mPanels.begin())
@ -409,28 +418,20 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|| (!(*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;
}
S32 relevant_dimension = (mOrientation == HORIZONTAL) ? (*panel_it)->getRect().getWidth() : (*panel_it)->getRect().getHeight();
F32 relevant_min = ((*panel_it)->mCollapsed ? (*panel_it)->getRelevantMinDim() : (*panel_it)->mExpandedMinDim);
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;
}
S32 relevant_dimension = (mOrientation == HORIZONTAL) ? (*panel_it)->getRect().getWidth() : (*panel_it)->getRect().getHeight();
F32 relevant_min = ((*panel_it)->mCollapsed ? (*panel_it)->getRelevantMinDim() : (*panel_it)->mExpandedMinDim);
shrink_headroom_available += relevant_dimension - relevant_min;
shrink_headroom_total += relevant_dimension - relevant_min;
}
}
@ -452,27 +453,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 = (S32) 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 +483,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 - panelp->getRelevantMinDim()) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_width - relevant_min);
}
else
{
@ -491,7 +493,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 +506,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 +515,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 +568,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);
F32 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 +661,7 @@ void LLLayoutStack::calcMinExtents()
{
if (mOrientation == HORIZONTAL)
{
mMinWidth += (*panel_it)->mMinDim;
mMinWidth += (*panel_it)->getRelevantMinDim();
if (panel_it != mPanels.begin())
{
mMinWidth += mPanelSpacing;
@ -666,7 +669,7 @@ void LLLayoutStack::calcMinExtents()
}
else //VERTICAL
{
mMinHeight += (*panel_it)->mMinDim;
mMinHeight += (*panel_it)->getRelevantMinDim();
if (panel_it != mPanels.begin())
{
mMinHeight += mPanelSpacing;

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

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

@ -361,6 +361,8 @@ set(viewer_SOURCE_FILES
llpanellogin.cpp
llpanelloginlistener.cpp
llpanelmaininventory.cpp
llpanelmarketplaceinbox.cpp
llpanelmarketplaceoutbox.cpp
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
@ -909,6 +911,8 @@ set(viewer_HEADER_FILES
llpanellogin.h
llpanelloginlistener.h
llpanelmaininventory.h
llpanelmarketplaceinbox.h
llpanelmarketplaceoutbox.h
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
@ -1465,7 +1469,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

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

View File

@ -69,6 +69,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)
@ -444,8 +445,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 +474,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 +526,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 +567,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 +584,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 +648,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 +669,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 +723,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

@ -167,13 +167,22 @@ 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),
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 +203,12 @@ 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;
LLRect rect = p.rect;
LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
setRect( rect );
@ -424,11 +435,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 +771,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 +794,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)
@ -962,7 +969,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,12 +1651,8 @@ 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);
}
}
else
{
last_selected->setOpen( FALSE );
@ -2031,7 +2036,7 @@ void LLFolderView::removeItemID(const LLUUID& id)
LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
{
if (id.isNull())
if (id == getListener()->getUUID())
{
return this;
}
@ -2048,7 +2053,7 @@ LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id)
{
if (id.isNull())
if (id == getListener()->getUUID())
{
return this;
}
@ -2496,11 +2501,6 @@ BOOL LLFolderView::isFilterModified()
return mFilter->isNotDefault();
}
BOOL LLFolderView::getAllowMultiSelect()
{
return mAllowMultiSelect;
}
void delete_selected_item(void* user_data)
{
if(user_data)

View File

@ -89,7 +89,11 @@ 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,
use_ellipses;
Params();
};
LLFolderView(const Params&);
virtual ~LLFolderView( void );
@ -102,7 +106,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 +120,6 @@ public:
//LLInventoryFilter::EFolderShow getShowFolderState();
U32 getSortOrder() const;
BOOL isFilterModified();
BOOL getAllowMultiSelect();
// Close all folders in the view
void closeAllFolders();
@ -238,7 +240,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,6 +30,7 @@
// 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 "llinventorymodelbackgroundfetch.h"
@ -130,10 +131,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 +200,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 +356,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 +450,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 +868,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 +891,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 +1054,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 +1122,8 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
mLastCalculatedWidth(0),
mCompletedFilterGeneration(-1),
mMostFilteredDescendantGeneration(-1),
mNeedsSort(false)
mNeedsSort(false),
mPassedFolderFilter(FALSE)
{
}
@ -1131,6 +1135,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 +1172,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 +1203,11 @@ 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
bool is_hidden = folderp->getListener() && LLViewerFolderType::lookupIsHiddenType(folderp->getListener()->getPreferredType());
folderp->setVisible( !is_hidden
&& (show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS
|| (folderp->getFiltered(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
@ -1981,6 +2025,13 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
item->dirtyFilter();
requestArrange();
requestSort();
LLFolderViewFolder* parentp = getParentFolder();
while (parentp && !parentp->getCreationDate())
{
// parent folder doesn't have a time stamp yet, so get it from us
parentp->requestSort();
parentp = parentp->getParentFolder();
}
return TRUE;
}
@ -2000,6 +2051,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->getCreationDate())
{
// parent folder doesn't have a time stamp yet, so get it from us
parentp->requestSort();
parentp = parentp->getParentFolder();
}
return TRUE;
}
@ -2059,7 +2117,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 +2361,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 +2393,21 @@ void LLFolderViewFolder::draw()
time_t LLFolderViewFolder::getCreationDate() const
{
// folders have no creation date so use first non-folder descendent's date
if (!mCreationDate)
{
for(items_t::const_iterator iit = mItems.begin();
iit != mItems.end(); ++iit)
{
LLFolderViewItem* itemp = (*iit);
if (itemp->getCreationDate())
{
mCreationDate = itemp->getCreationDate();
break;
}
}
}
return llmax<time_t>(mCreationDate, mSubtreeCreationDate);
}
@ -2573,7 +2651,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

@ -135,7 +135,7 @@ protected:
std::string mSearchableLabel;
S32 mLabelWidth;
bool mLabelWidthDirty;
time_t mCreationDate;
mutable time_t mCreationDate;
LLFolderViewFolder* mParentFolder;
LLFolderViewEventListener* mListener;
BOOL mIsCurSelection;
@ -157,7 +157,6 @@ protected:
BOOL mDragAndDropTarget;
BOOL mIsLoading;
LLTimer mTimeSinceRequestStart;
bool mHidden;
bool mShowLoadStatus;
// helper function to change the selection from the root.
@ -167,13 +166,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 +203,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 +362,9 @@ public:
UNKNOWN, TRASH, NOT_TRASH
} ETrash;
typedef std::list<LLFolderViewItem*> items_t;
typedef std::list<LLFolderViewFolder*> folders_t;
private:
S32 mNumDescendantsSelected;
@ -374,8 +373,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 +389,8 @@ protected:
S32 mCompletedFilterGeneration;
S32 mMostFilteredDescendantGeneration;
bool mNeedsSort;
bool mPassedFolderFilter;
public:
typedef enum e_recurse_type
{
@ -433,6 +432,11 @@ public:
virtual void setFiltered(BOOL filtered, 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.
// Returns TRUE if this object (or a child) ends up being selected.
@ -537,6 +541,9 @@ 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(); }
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -571,8 +571,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 +781,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;
@ -2525,6 +2537,7 @@ void LLFolderBridge::folderOptionsMenu()
{
mItems.push_back(std::string("Add To Outfit"));
}
mItems.push_back(std::string("Replace Outfit"));
}
if (is_ensemble)
@ -2614,15 +2627,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.

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,31 @@ 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;
if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0))
return false;
}
return true;
}
BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
{
const LLFolderViewEventListener* listener = item->getListener();
@ -137,30 +162,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 +173,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_DATE
// Pass if this item is within the date range.
@ -293,15 +293,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);
BOOL more_bits_set = (~current_types & types);
mFilterOps.mFilterObjectTypes = types;
current_types = types;
if (more_bits_set && fewer_bits_set)
{
// neither less or more restrive, both simultaneously
@ -318,62 +318,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 +859,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

@ -42,7 +42,6 @@
#include "llinventorymodelbackgroundfetch.h"
#include "llsidepanelinventory.h"
#include "llsidetray.h"
#include "llscrollcontainer.h"
#include "llviewerattachmenu.h"
#include "llviewerfoldertype.h"
#include "llvoavatarself.h"
@ -132,8 +131,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mAllowMultiSelect(p.allow_multi_select),
mShowItemLinkOverlays(p.show_item_link_overlays),
mViewsInitialized(false),
mStartFolderString(p.start_folder),
mBuildDefaultHierarchy(true),
mInvFVBridgeBuilder(NULL)
{
mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
@ -147,20 +144,27 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars));
if (mStartFolderString != "")
{
mBuildDefaultHierarchy = false;
}
}
void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD);
// 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);
mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
LLUUID root_id;
// Create root folder
if ("LIBRARY" == params.start_folder())
{
root_id = gInventory.getLibraryRootFolderID();
}
else
{
root_id = (preferred_type != LLFolderType::FT_NONE)
? gInventory.findCategoryUUIDForType(preferred_type, false, false)
: LLUUID::null;
}
LLRect folder_rect(0,
0,
getRect().getWidth(),
@ -171,11 +175,26 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
p.rect = folder_rect;
p.parent_panel = this;
p.tool_tip = p.name;
p.listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
LLAssetType::AT_CATEGORY,
LLInventoryType::IT_CATEGORY,
this,
NULL,
root_id);
p.use_label_suffix = params.use_label_suffix;
p.allow_multiselect = mAllowMultiSelect;
mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p);
mFolderRoot->setAllowMultiSelect(mAllowMultiSelect);
}
void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD);
mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
buildFolderView(params);
mCommitCallbackRegistrar.popScope();
mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
@ -184,13 +203,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 +221,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();
}
@ -264,6 +279,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)
@ -488,23 +512,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;
@ -533,7 +550,7 @@ void 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 != mFolderRoot)
{
old_view->destroyView();
}
@ -543,28 +560,27 @@ void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
void LLInventoryPanel::buildNewViews(const LLUUID& id)
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS);
LLFolderViewItem* itemp = NULL;
LLInventoryObject* objectp = gInventory.getObject(id);
if (objectp)
{
const LLUUID &parent_id = objectp->getParentUUID();
LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
if (id == mStartFolderID)
LLInventoryObject const* objectp = gInventory.getObject(id);
LLUUID root_id = mFolderRoot->getListener()->getUUID();
LLFolderViewFolder* parent_folder = NULL;
if (id == root_id)
{
parent_folder = mFolderRoot;
}
else if ((mStartFolderID != LLUUID::null) && (!gInventory.isObjectDescendentOf(id, mStartFolderID)))
else if (objectp)
{
// This item exists outside the inventory's hierarchy, so don't add it.
return;
}
LLFolderViewItem* itemp = NULL;
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()
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
<< llendl;
return;
}
@ -594,21 +610,9 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params);
folderp->setItemSortOrder(mFolderRoot->getSortOrder());
itemp = folderp;
// 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
else
{
// Build new view for item.
LLInventoryItem* item = (LLInventoryItem*)objectp;
@ -642,19 +646,15 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
if (itemp)
{
itemp->addToFolder(parent_folder, mFolderRoot);
// Don't add children of hidden folders unless this is the panel's root folder.
if (itemp->getHidden() && (id != mStartFolderID))
{
return;
}
}
}
// 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 +671,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();
@ -688,18 +688,13 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
// bit of a hack to make sure the inventory is open.
void LLInventoryPanel::openStartFolderOrMyInventory()
{
if (mStartFolderString != "")
{
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()))
if (fchild
&& fchild->getListener()
&& fchild->getListener()->getUUID() == gInventory.getRootFolderID())
{
const std::string& child_name = child->getName();
mFolderRoot->openFolder(child_name);
@ -707,7 +702,6 @@ void LLInventoryPanel::openStartFolderOrMyInventory()
}
}
}
}
void LLInventoryPanel::onItemsCompletion()
{
@ -1067,15 +1061,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));
}

View File

@ -35,6 +35,7 @@
#include "llinventoryfilter.h"
#include "llfolderview.h"
#include "llinventorymodel.h"
#include "llscrollcontainer.h"
#include "lluictrlfactory.h"
#include <set>
@ -46,7 +47,6 @@ class LLInventoryFVBridgeBuilder;
class LLMenuBarGL;
class LLCheckBoxCtrl;
class LLSpinCtrl;
class LLScrollContainer;
class LLTextBox;
class LLIconCtrl;
class LLSaveFolderState;
@ -83,6 +83,7 @@ public:
Optional<Filter> filter;
Optional<std::string> start_folder;
Optional<bool> use_label_suffix;
Optional<LLScrollContainer::Params> scroll;
Params()
: sort_order_setting("sort_order_setting"),
@ -91,7 +92,8 @@ 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),
scroll("scroll")
{}
};
@ -126,6 +128,7 @@ public:
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb);
void clearSelection();
LLInventoryFilter* getFilter();
const LLInventoryFilter* getFilter() const;
void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
U32 getFilterObjectTypes() const { return mFolderRoot->getFilterObjectTypes(); }
void setFilterPermMask(PermissionMask filter_perm_mask);
@ -140,7 +143,6 @@ 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; }
@ -207,23 +209,18 @@ 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);
void rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views.
virtual void buildFolderView(const LLInventoryPanel::Params& params);
virtual void buildNewViews(const LLUUID& id);
BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
private:
BOOL mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
BOOL mViewsInitialized; // Views have been generated

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

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

@ -645,7 +645,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 +1414,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

@ -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,25 @@ 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();
}
}
void LLPanelMainInventory::setFilterTextFromFilter()
{
mFilterText = mActivePanel->getFilter()->getFilterText();

View File

@ -114,6 +114,8 @@ protected:
bool isSaveTextureEnabled(const LLSD& userdata);
void updateItemcountText();
void onFocusReceived();
private:
LLFloaterInventoryFinder* getFinder();

View File

@ -0,0 +1,222 @@
/**
* @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 "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()
{
mInventoryPanel = getChild<LLInventoryPanel>("inventory_inbox");
mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);
LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLPanelMarketplaceInbox::handleLoginComplete, this));
LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceInbox::onFocusReceived, this));
mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceInbox::onSelectionChange, 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::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();
}
}
}
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
U32 fresh_item_count = 0;
LLFolderView * root_folder = mInventoryPanel->getRootFolder();
const LLFolderViewFolder * inbox_folder = *(root_folder->getFoldersBegin());
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;
if (folder->getCreationDate() > 1500)
{
fresh_item_count++;
}
}
return fresh_item_count;
#else
return getTotalItemCount();
#endif
}
U32 LLPanelMarketplaceInbox::getTotalItemCount() const
{
LLInventoryModel* model = mInventoryPanel->getModel();
LLInventoryModel::cat_array_t* cats;
LLInventoryModel::item_array_t* items;
model->getDirectDescendentsOf(model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false), cats, items);
U32 item_count = 0;
if (cats)
{
item_count += cats->size();
}
if (items)
{
item_count += items->size();
}
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,76 @@
/**
* @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();
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,164 @@
/**
* @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 "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");
// protected
LLPanelMarketplaceOutbox::LLPanelMarketplaceOutbox()
: LLPanel()
, mSyncButton(NULL)
, mSyncIndicator(NULL)
, mSyncInProgress(false)
{
}
LLPanelMarketplaceOutbox::~LLPanelMarketplaceOutbox()
{
}
// virtual
BOOL LLPanelMarketplaceOutbox::postBuild()
{
mSyncButton = getChild<LLButton>("outbox_sync_btn");
mSyncButton->setCommitCallback(boost::bind(&LLPanelMarketplaceOutbox::onSyncButtonClicked, this));
mSyncIndicator = getChild<LLLoadingIndicator>("outbox_sync_indicator");
mSyncButton->setEnabled(!isOutboxEmpty());
LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceOutbox::onFocusReceived, this));
return TRUE;
}
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();
}
}
}
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,67 @@
/**
* @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 LLLoadingIndicator;
class LLPanelMarketplaceOutbox : public LLPanel
{
public:
LOG_CLASS(LLPanelMarketplaceOutbox);
LLPanelMarketplaceOutbox();
~LLPanelMarketplaceOutbox();
/*virtual*/ BOOL postBuild();
bool isOutboxEmpty() const;
bool isSyncInProgress() const;
void onSyncComplete();
protected:
void onSyncButtonClicked();
void updateSyncButtonStatus();
void onFocusReceived();
private:
LLButton * mSyncButton;
LLLoadingIndicator * mSyncIndicator;
bool mSyncInProgress;
};
#endif //LL_LLPANELMARKETPLACEOUTBOX_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

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

@ -29,33 +29,87 @@
#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 "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 = "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";
//
// Helpers
//
//
// Implementation
//
LLSidepanelInventory::LLSidepanelInventory()
: LLPanel()
, mItemPanel(NULL)
, mPanelMainInventory(NULL)
, mInboxEnabled(false)
, mOutboxEnabled(false)
, mCategoriesObserver(NULL)
{
//buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
}
LLSidepanelInventory::~LLSidepanelInventory()
{
if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
{
gInventory.removeObserver(mCategoriesObserver);
}
delete mCategoriesObserver;
}
void handleInventoryDisplayInboxChanged()
{
LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory"));
sidepanel_inventory->enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox"));
}
BOOL LLSidepanelInventory::postBuild()
@ -119,13 +173,171 @@ BOOL LLSidepanelInventory::postBuild()
}
}
// Marketplace inbox/outbox setup
{
LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
LLLayoutPanel * inbox_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
LLLayoutPanel * outbox_panel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME);
stack->collapsePanel(inbox_panel, true);
stack->collapsePanel(outbox_panel, true);
// Disable user_resize on main inventory panel by default
stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL, false);
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));
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);
mCategoriesObserver = new LLInventoryCategoriesObserver();
gInventory.addObserver(mCategoriesObserver);
mCategoriesObserver->addCategory(inbox_id, boost::bind(&LLSidepanelInventory::onInboxChanged, this, inbox_id));
mCategoriesObserver->addCategory(outbox_id, boost::bind(&LLSidepanelInventory::onOutboxChanged, this, outbox_id));
//
// Trigger a load for the entire contents of the Inbox
//
LLInventoryModelBackgroundFetch::instance().start(inbox_id);
}
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 = getChild<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, 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 = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
if (inbox && (inbox->getFreshItemCount() > 0))
{
getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true);
onToggleInboxBtn();
}
if(key.size() == 0)
return;
@ -175,22 +387,24 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action)
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 +543,24 @@ 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");
LLInventoryPanel* active_panel = panel_main_inventory->getActivePanel();
return ( (panel_main_inventory ? LLAvatarActions::canShareSelectedItems(panel_main_inventory->getActivePanel()) : false)
|| (inbox ? LLAvatarActions::canShareSelectedItems(inbox) : false) );
// Avoid flicker in the Recent tab while inventory is being loaded.
if (!active_panel->getRootFolder()->hasVisibleChildren()) return false;
return LLAvatarActions::canShareSelectedItems(active_panel);
//if (!active_panel->getRootFolder()->hasVisibleChildren()) return 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)
@ -370,7 +577,15 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()
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 +594,20 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()
U32 LLSidepanelInventory::getSelectedCount()
{
int count = 0;
LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<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,7 @@
#include "llpanel.h"
class LLFolderViewItem;
class LLInventoryCategoriesObserver;
class LLInventoryItem;
class LLInventoryPanel;
class LLPanelMainInventory;
@ -42,6 +43,10 @@ public:
LLSidepanelInventory();
virtual ~LLSidepanelInventory();
private:
void handleLoginComplete();
public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
@ -56,6 +61,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 +79,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 +103,7 @@ protected:
void onTeleportButtonClicked();
void onOverflowButtonClicked();
void onBackButtonClicked();
private:
LLButton* mInfoBtn;
LLButton* mShareBtn;
@ -94,6 +113,10 @@ private:
LLButton* mOverflowBtn;
LLButton* mShopBtn;
bool mInboxEnabled;
bool mOutboxEnabled;
LLInventoryCategoriesObserver* mCategoriesObserver;
};
#endif //LL_LLSIDEPANELINVENTORY_H

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

@ -1953,7 +1953,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

@ -40,6 +40,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry
const std::string &icon_name_open, // name of the folder icon
const std::string &icon_name_closed,
BOOL is_quiet, // folder doesn't need a UI update when changed
bool is_hidden = false,
const std::string &dictionary_name = empty_string // no reverse lookup needed on non-ensembles, so in most cases just leave this blank
)
:
@ -47,7 +48,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry
mNewCategoryName(new_category_name),
mIconNameOpen(icon_name_open),
mIconNameClosed(icon_name_closed),
mIsQuiet(is_quiet)
mIsQuiet(is_quiet),
mIsHidden(is_hidden)
{
mAllowedNames.clear();
}
@ -66,7 +68,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry
*/
mIconNameOpen("Inv_FolderOpen"), mIconNameClosed("Inv_FolderClosed"),
mNewCategoryName(new_category_name),
mIsQuiet(FALSE)
mIsQuiet(FALSE),
mIsHidden(false)
{
const std::string delims (",");
LLStringUtilBase<char>::getTokens(allowed_names, mAllowedNames, delims);
@ -91,6 +94,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry
typedef std::vector<std::string> name_vec_t;
name_vec_t mAllowedNames;
BOOL mIsQuiet;
bool mIsHidden;
};
class LLViewerFolderDictionary : public LLSingleton<LLViewerFolderDictionary>,
@ -128,10 +132,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_INBOX, new ViewerFolderEntry("Inbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Outbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "Inv_FolderOpen", "Inv_FolderClosed", FALSE, "default"));
addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "Inv_FolderOpen", "Inv_FolderClosed", FALSE, false, "default"));
#if SUPPORT_ENSEMBLES
initEnsemblesFromFile();
@ -258,6 +262,17 @@ BOOL LLViewerFolderType::lookupIsQuietType(LLFolderType::EType folder_type)
}
BOOL LLViewerFolderType::lookupIsHiddenType(LLFolderType::EType folder_type)
{
const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type);
if (entry)
{
return entry->mIsHidden;
}
return FALSE;
}
const std::string &LLViewerFolderType::lookupNewCategoryName(LLFolderType::EType folder_type)
{
const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type);

View File

@ -40,6 +40,7 @@ public:
static const std::string& lookupIconName(EType folder_type, BOOL is_open = FALSE); // folder icon name
static BOOL lookupIsQuietType(EType folder_type); // folder doesn't require UI update when changes have occured
static BOOL lookupIsHiddenType(EType folder_type); // folder doesn't require UI update when changes have occured
static const std::string& lookupNewCategoryName(EType folder_type); // default name when creating new category
static LLFolderType::EType lookupTypeFromNewCategoryName(const std::string& name); // default name when creating new category

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 Disabled" << 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);
}
}

View File

@ -936,7 +936,6 @@ protected:
//one global instance to bind them
LLOpenTaskOffer* gNewInventoryObserver=NULL;
class LLNewInventoryHintObserver : public LLInventoryAddedObserver
{
protected:
@ -946,6 +945,8 @@ protected:
}
};
LLNewInventoryHintObserver* gNewInventoryHintObserver=NULL;
void start_new_inventory_observer()
{
if (!gNewInventoryObserver) //task offer observer
@ -962,7 +963,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 +4330,7 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
{
return;
}
// Don't play sounds from gestures if they are not enabled.
if (!gSavedSettings.getBOOL("EnableGestureSounds")) return;
@ -6484,7 +6490,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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -72,8 +72,11 @@ with the same filename but different name
<texture name="BackButton_Over" file_name="icons/back_arrow_over.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" />
<texture name="BackButton_Press" file_name="icons/back_arrow_press.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" />
<texture name="Badge_Background" file_name="widgets/Badge_Background.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />
<texture name="Badge_Border" file_name="widgets/Badge_Border.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />
<texture name="Blank" file_name="Blank.png" preload="false" />
<texture name="BreadCrumbBtn_Left_Disabled" file_name="widgets/BreadCrumbBtn_Left_Disabled.png" preload="false"/>
<texture name="BreadCrumbBtn_Left_Off" file_name="widgets/BreadCrumbBtn_Left_Off.png" preload="false"/>
<texture name="BreadCrumbBtn_Left_Over" file_name="widgets/BreadCrumbBtn_Left_Over.png" preload="false"/>
@ -88,7 +91,6 @@ with the same filename but different name
<texture name="BreadCrumbBtn_Right_Off" file_name="widgets/BreadCrumbBtn_Right_Off.png" preload="false"/>
<texture name="BreadCrumbBtn_Right_Over" file_name="widgets/BreadCrumbBtn_Right_Over.png" preload="false"/>
<texture name="BreadCrumbBtn_Right_Press" file_name="widgets/BreadCrumbBtn_Right_Press.png" preload="false"/>
<texture name="BuyArrow_Over" file_name="navbar/BuyArrow_Over.png" preload="true" scale.left="0" scale.top="1" scale.right="0" scale.bottom="0" />
<texture name="BuyArrow_Press" file_name="navbar/BuyArrow_Press.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" />
@ -266,6 +268,8 @@ with the same filename but different name
<texture name="Locked_Icon" file_name="icons/Locked_Icon.png" preload="false" />
<texture name="MarketplaceBtn_Off" file_name="widgets/MarketplaceBtn_Off.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" />
<texture name="MarketplaceBtn_Selected" file_name="widgets/MarketplaceBtn_Selected.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" />
<texture name="Microphone_On" file_name="icons/Microphone_On.png" preload="false" />
@ -349,6 +353,23 @@ with the same filename but different name
<texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" />
<texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" />
<texture name="OutboxPush_Disabled" file_name="icons/OutboxPush_Disabled.png" preload="true" />
<texture name="OutboxPush_Off" file_name="icons/OutboxPush_Off.png" preload="true" />
<texture name="OutboxPush_On" file_name="icons/OutboxPush_On.png" preload="true" />
<texture name="OutboxPush_On_Over" file_name="icons/OutboxPush_On_Over.png" preload="true" />
<texture name="OutboxPush_Over" file_name="icons/OutboxPush_Over.png" preload="true" />
<texture name="OutboxPush_Press" file_name="icons/OutboxPush_Press.png" preload="true" />
<texture name="OutboxPush_Progress_1" file_name="icons/OutboxPush_Progress_1.png" preload="true" />
<texture name="OutboxPush_Progress_2" file_name="icons/OutboxPush_Progress_2.png" preload="true" />
<texture name="OutboxPush_Progress_3" file_name="icons/OutboxPush_Progress_3.png" preload="true" />
<texture name="OutboxPush_Progress_4" file_name="icons/OutboxPush_Progress_4.png" preload="true" />
<texture name="OutboxPush_Progress_5" file_name="icons/OutboxPush_Progress_5.png" preload="true" />
<texture name="OutboxPush_Progress_6" file_name="icons/OutboxPush_Progress_6.png" preload="true" />
<texture name="OutboxPush_Selected" file_name="icons/OutboxPush_Selected.png" preload="true" />
<texture name="OutboxPush_Selected_Disabled" file_name="icons/OutboxPush_Selected_Disabled.png" preload="true" />
<texture name="OutboxPush_Selected_Over" file_name="icons/OutboxPush_Selected_Over.png" preload="true" />
<texture name="OutboxPush_Selected_Press" file_name="icons/OutboxPush_Selected_Press.png" preload="true" />
<texture name="PanOrbit_Off" file_name="bottomtray/PanOrbit_Off.png" preload="false" />
<texture name="Parcel_Exp_Color" file_name="icons/Parcel_Exp_Color.png" preload="false" />
@ -496,6 +517,15 @@ with the same filename but different name
<texture name="StopReload_Off" file_name="icons/StopReload_Off.png" preload="false" />
<texture name="StopReload_Over" file_name="icons/StopReload_Over.png" preload="false" />
<texture name="Sync_Disabled" file_name="icons/Sync_Disabled.png" preload="true" />
<texture name="Sync_Enabled" file_name="icons/Sync_Enabled.png" preload="true" />
<texture name="Sync_Progress_1" file_name="icons/Sync_Progress_1.png" preload="true" />
<texture name="Sync_Progress_2" file_name="icons/Sync_Progress_2.png" preload="true" />
<texture name="Sync_Progress_3" file_name="icons/Sync_Progress_3.png" preload="true" />
<texture name="Sync_Progress_4" file_name="icons/Sync_Progress_4.png" preload="true" />
<texture name="Sync_Progress_5" file_name="icons/Sync_Progress_5.png" preload="true" />
<texture name="Sync_Progress_6" file_name="icons/Sync_Progress_6.png" preload="true" />
<texture name="TabIcon_Appearance_Off" file_name="taskpanel/TabIcon_Appearance_Off.png" preload="false" />
<texture name="TabIcon_Appearance_Selected" file_name="taskpanel/TabIcon_Appearance_Selected.png" preload="false" />
<texture name="TabIcon_Close_Off" file_name="taskpanel/TabIcon_Close_Off.png" preload="false" />
@ -649,6 +679,7 @@ with the same filename but different name
<texture name="inv_folder_mesh.tga"/>
<texture name="inv_item_mesh.tga"/>
<texture name="lag_status_critical.tga" />
<texture name="lag_status_good.tga" />
<texture name="lag_status_warning.tga" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -42,7 +42,7 @@
<menu_item_call.on_enable
function="File.EnableUpload" />
</menu_item_call>
<menu_item_call
<menu_item_call
label="Model..."
layout="topleft"
name="Upload Model">
@ -263,4 +263,4 @@
parameter="eyes" />
</menu_item_call>
</menu>
</menu>
</menu>

View File

@ -132,4 +132,12 @@
name="cancel_btn"
top="700"
width="90" />
<web_browser
follows="all"
layout="topleft"
left="0"
name="login_media_panel"
width="1024"
height="768"
top="0"/>
</panel>

View File

@ -142,6 +142,7 @@
mouse_opaque="false"
background_visible="true"
>
<badge location="top_left" location_percent_vcenter="50" location_percent_hcenter="95" />
<panel
class="sidepanel_inventory"
name="sidepanel_inventory"

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