Fixed up inventory filter. Basic folders now have an 'open' icon. Tweaked the indent size for inventory (looks a little nicer imo)

This commit is contained in:
Shyotl
2012-02-27 02:53:12 -06:00
parent dcec1cb5f2
commit 2bf940e15d
26 changed files with 1656 additions and 1077 deletions

View File

@@ -73,7 +73,8 @@ LLScrollbar::LLScrollbar(
mHighlightColor ( LLUI::sColorsGroup->getColor("DefaultHighlightLight") ),
mShadowColor ( LLUI::sColorsGroup->getColor("DefaultShadowLight") ),
mOnScrollEndCallback( NULL ),
mOnScrollEndData( NULL )
mOnScrollEndData( NULL ),
mThickness( SCROLLBAR_SIZE )
{
//llassert( 0 <= mDocSize );
//llassert( 0 <= mDocPos && mDocPos <= mDocSize );
@@ -92,22 +93,22 @@ LLScrollbar::LLScrollbar(
if( LLScrollbar::VERTICAL == mOrientation )
{
line_up_rect.setLeftTopAndSize( 0, getRect().getHeight(), SCROLLBAR_SIZE, SCROLLBAR_SIZE );
line_up_rect.setLeftTopAndSize( 0, getRect().getHeight(), mThickness, mThickness );
line_up_img="UIImgBtnScrollUpOutUUID";
line_up_selected_img="UIImgBtnScrollUpInUUID";
line_down_rect.setOriginAndSize( 0, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE );
line_down_rect.setOriginAndSize( 0, 0, mThickness, mThickness );
line_down_img="UIImgBtnScrollDownOutUUID";
line_down_selected_img="UIImgBtnScrollDownInUUID";
}
else
{
// Horizontal
line_up_rect.setOriginAndSize( 0, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE );
line_up_rect.setOriginAndSize( 0, 0, mThickness, mThickness );
line_up_img="UIImgBtnScrollLeftOutUUID";
line_up_selected_img="UIImgBtnScrollLeftInUUID";
line_down_rect.setOriginAndSize( getRect().getWidth() - SCROLLBAR_SIZE, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE );
line_down_rect.setOriginAndSize( getRect().getWidth() - mThickness, 0, mThickness, mThickness );
line_down_img="UIImgBtnScrollRightOutUUID";
line_down_selected_img="UIImgBtnScrollRightInUUID";
}
@@ -158,7 +159,8 @@ void LLScrollbar::setDocParams( S32 size, S32 pos )
updateThumbRect();
}
void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
// returns true if document position really changed
bool LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
{
pos = llclamp(pos, 0, getDocPosMax());
if (pos != mDocPos)
@@ -175,7 +177,9 @@ void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
{
updateThumbRect();
}
return true;
}
return false;
}
void LLScrollbar::setDocSize(S32 size)
@@ -221,7 +225,7 @@ void LLScrollbar::updateThumbRect()
const S32 THUMB_MIN_LENGTH = 16;
S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? getRect().getWidth() : getRect().getHeight();
S32 thumb_bg_length = llmax(0, window_length - 2 * SCROLLBAR_SIZE);
S32 thumb_bg_length = llmax(0, window_length - 2 * mThickness);
S32 visible_lines = llmin( mDocSize, mPageSize );
S32 thumb_length = mDocSize ? llmin(llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH), thumb_bg_length) : thumb_bg_length;
@@ -229,24 +233,24 @@ void LLScrollbar::updateThumbRect()
if( mOrientation == LLScrollbar::VERTICAL )
{
S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE;
S32 thumb_start_min = SCROLLBAR_SIZE + THUMB_MIN_LENGTH;
S32 thumb_start_max = thumb_bg_length + mThickness;
S32 thumb_start_min = mThickness + THUMB_MIN_LENGTH;
S32 thumb_start = variable_lines ? llmin( llmax(thumb_start_max - (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_max;
mThumbRect.mLeft = 0;
mThumbRect.mTop = thumb_start;
mThumbRect.mRight = SCROLLBAR_SIZE;
mThumbRect.mRight = mThickness;
mThumbRect.mBottom = thumb_start - thumb_length;
}
else
{
// Horizontal
S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE - thumb_length;
S32 thumb_start_min = SCROLLBAR_SIZE;
S32 thumb_start_max = thumb_bg_length + mThickness - thumb_length;
S32 thumb_start_min = mThickness;
S32 thumb_start = variable_lines ? llmin(llmax( thumb_start_min + (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_min;
mThumbRect.mLeft = thumb_start;
mThumbRect.mTop = SCROLLBAR_SIZE;
mThumbRect.mTop = mThickness;
mThumbRect.mRight = thumb_start + thumb_length;
mThumbRect.mBottom = 0;
}
@@ -318,21 +322,21 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
// S32 old_pos = mThumbRect.mTop;
S32 delta_pixels = y - mDragStartY;
if( mOrigRect.mBottom + delta_pixels < SCROLLBAR_SIZE )
if( mOrigRect.mBottom + delta_pixels < mThickness )
{
delta_pixels = SCROLLBAR_SIZE - mOrigRect.mBottom - 1;
delta_pixels = mThickness - mOrigRect.mBottom - 1;
}
else
if( mOrigRect.mTop + delta_pixels > height - SCROLLBAR_SIZE )
if( mOrigRect.mTop + delta_pixels > height - mThickness )
{
delta_pixels = height - SCROLLBAR_SIZE - mOrigRect.mTop + 1;
delta_pixels = height - mThickness - mOrigRect.mTop + 1;
}
mThumbRect.mTop = mOrigRect.mTop + delta_pixels;
mThumbRect.mBottom = mOrigRect.mBottom + delta_pixels;
S32 thumb_length = mThumbRect.getHeight();
S32 thumb_track_length = height - 2 * SCROLLBAR_SIZE;
S32 thumb_track_length = height - 2 * mThickness;
if( delta_pixels != mLastDelta || mDocChanged)
@@ -343,7 +347,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
{
S32 variable_lines = getDocPosMax();
S32 pos = mThumbRect.mTop;
F32 ratio = F32(pos - SCROLLBAR_SIZE - thumb_length) / usable_track_length;
F32 ratio = F32(pos - mThickness - thumb_length) / usable_track_length;
S32 new_pos = llclamp( S32(variable_lines - ratio * variable_lines + 0.5f), 0, variable_lines );
// Note: we do not call updateThumbRect() here. Instead we let the thumb and the document go slightly
@@ -362,21 +366,21 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
S32 delta_pixels = x - mDragStartX;
if( mOrigRect.mLeft + delta_pixels < SCROLLBAR_SIZE )
if( mOrigRect.mLeft + delta_pixels < mThickness )
{
delta_pixels = SCROLLBAR_SIZE - mOrigRect.mLeft - 1;
delta_pixels = mThickness - mOrigRect.mLeft - 1;
}
else
if( mOrigRect.mRight + delta_pixels > width - SCROLLBAR_SIZE )
if( mOrigRect.mRight + delta_pixels > width - mThickness )
{
delta_pixels = width - SCROLLBAR_SIZE - mOrigRect.mRight + 1;
delta_pixels = width - mThickness - mOrigRect.mRight + 1;
}
mThumbRect.mLeft = mOrigRect.mLeft + delta_pixels;
mThumbRect.mRight = mOrigRect.mRight + delta_pixels;
S32 thumb_length = mThumbRect.getWidth();
S32 thumb_track_length = width - 2 * SCROLLBAR_SIZE;
S32 thumb_track_length = width - 2 * mThickness;
if( delta_pixels != mLastDelta || mDocChanged)
{
@@ -386,7 +390,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
{
S32 variable_lines = getDocPosMax();
S32 pos = mThumbRect.mLeft;
F32 ratio = F32(pos - SCROLLBAR_SIZE) / usable_track_length;
F32 ratio = F32(pos - mThickness) / usable_track_length;
S32 new_pos = llclamp( S32(ratio * variable_lines + 0.5f), 0, variable_lines);
@@ -405,7 +409,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
}
else
{
handled = childrenHandleMouseUp( x, y, mask ) != NULL;
handled = childrenHandleHover( x, y, mask ) != NULL;
}
// Opaque
@@ -423,8 +427,8 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
changeLine( clicks * mStepSize, TRUE );
return TRUE;
BOOL handled = changeLine( clicks * mStepSize, TRUE );
return handled;
}
BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
@@ -475,14 +479,14 @@ void LLScrollbar::reshape(S32 width, S32 height, BOOL called_from_parent)
if (mOrientation == VERTICAL)
{
up_button->reshape(up_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, SCROLLBAR_SIZE));
down_button->reshape(down_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, SCROLLBAR_SIZE));
up_button->reshape(up_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, mThickness));
down_button->reshape(down_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, mThickness));
up_button->setOrigin(up_button->getRect().mLeft, getRect().getHeight() - up_button->getRect().getHeight());
}
else
{
up_button->reshape(llmin(getRect().getWidth() / 2, SCROLLBAR_SIZE), up_button->getRect().getHeight());
down_button->reshape(llmin(getRect().getWidth() / 2, SCROLLBAR_SIZE), down_button->getRect().getHeight());
up_button->reshape(llmin(getRect().getWidth() / 2, mThickness), up_button->getRect().getHeight());
down_button->reshape(llmin(getRect().getWidth() / 2, mThickness), down_button->getRect().getHeight());
down_button->setOrigin(getRect().getWidth() - down_button->getRect().getWidth(), down_button->getRect().mBottom);
}
updateThumbRect();
@@ -513,10 +517,10 @@ void LLScrollbar::draw()
if (!rounded_rect_imagep)
{
gl_rect_2d(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0,
mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(),
mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(),
mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, mTrackColor, TRUE);
gl_rect_2d(mOrientation == HORIZONTAL ? mThickness : 0,
mOrientation == VERTICAL ? getRect().getHeight() - 2 * mThickness : getRect().getHeight(),
mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * mThickness : getRect().getWidth(),
mOrientation == VERTICAL ? mThickness : 0, mTrackColor, TRUE);
gl_rect_2d(mThumbRect, mThumbColor, TRUE);
@@ -560,9 +564,9 @@ void LLScrollbar::draw()
} // end draw
void LLScrollbar::changeLine( S32 delta, BOOL update_thumb )
bool LLScrollbar::changeLine( S32 delta, BOOL update_thumb )
{
setDocPos(mDocPos + delta, update_thumb);
return setDocPos(mDocPos + delta, update_thumb);
}
void LLScrollbar::setValue(const LLSD& value)

View File

@@ -82,7 +82,7 @@ public:
// How many "lines" the "document" has scrolled.
// 0 <= DocPos <= DocSize - DocVisibile
void setDocPos( S32 pos, BOOL update_thumb = TRUE );
bool setDocPos( S32 pos, BOOL update_thumb = TRUE );
S32 getDocPos() const { return mDocPos; }
BOOL isAtBeginning();
@@ -113,7 +113,7 @@ public:
private:
void updateThumbRect();
void changeLine(S32 delta, BOOL update_thumb );
bool changeLine(S32 delta, BOOL update_thumb );
void (*mChangeCallback)( S32 new_pos, LLScrollbar* self, void* userdata );
void* mCallbackUserData;
@@ -142,6 +142,7 @@ private:
void (*mOnScrollEndCallback)(void*);
void *mOnScrollEndData;
S32 mThickness;
};

View File

@@ -69,52 +69,31 @@ LLScrollableContainerView::LLScrollableContainerView( const std::string& name,
BOOL is_opaque,
const LLColor4& bg_color ) :
LLUICtrl( name, rect, FALSE, NULL, NULL ),
mScrolledView( scrolled_view ),
mIsOpaque( is_opaque ),
mBackgroundColor( bg_color ),
mReserveScrollCorner( FALSE ),
mAutoScrolling( FALSE ),
mAutoScrollRate( 0.f )
mAutoScrollRate( 0.f ),
mBackgroundColor( bg_color ),
mIsOpaque( is_opaque ),
mHideScrollbar( FALSE ),
mReserveScrollCorner( FALSE ),
mMinAutoScrollRate( MIN_AUTO_SCROLL_RATE ),
mMaxAutoScrollRate( MAX_AUTO_SCROLL_RATE ),
mScrolledView( scrolled_view )
{
if( mScrolledView )
{
addChild( mScrolledView );
LLView::addChild( mScrolledView );
}
init();
}
// LLUICtrl constructor
LLScrollableContainerView::LLScrollableContainerView( const std::string& name, const LLRect& rect,
LLUICtrl* scrolled_ctrl, BOOL is_opaque,
const LLColor4& bg_color) :
LLUICtrl( name, rect, FALSE, NULL, NULL ),
mScrolledView( scrolled_ctrl ),
mIsOpaque( is_opaque ),
mBackgroundColor( bg_color ),
mReserveScrollCorner( FALSE ),
mAutoScrolling( FALSE ),
mAutoScrollRate( 0.f )
{
if( scrolled_ctrl )
{
addChild( scrolled_ctrl );
}
init();
}
void LLScrollableContainerView::init()
{
S32 scrollbar_size = SCROLLBAR_SIZE;
LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );
mBorder = new LLViewBorder( std::string("scroll border"), border_rect, LLViewBorder::BEVEL_IN );
addChild( mBorder );
LLView::addChild( mBorder );
mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 );
mInnerRect.stretch( -mBorder->getBorderWidth() );
mInnerRect.stretch( -getBorderWidth() );
LLRect vertical_scroll_rect = mInnerRect;
vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - SCROLLBAR_SIZE;
vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - scrollbar_size;
mScrollbar[VERTICAL] = new LLScrollbar( std::string("scrollable vertical"),
vertical_scroll_rect,
LLScrollbar::VERTICAL,
@@ -123,14 +102,14 @@ void LLScrollableContainerView::init()
mInnerRect.getHeight(),
NULL, this,
VERTICAL_MULTIPLE);
addChild( mScrollbar[VERTICAL] );
LLView::addChild( mScrollbar[VERTICAL] );
mScrollbar[VERTICAL]->setVisible( FALSE );
mScrollbar[VERTICAL]->setFollowsRight();
mScrollbar[VERTICAL]->setFollowsTop();
mScrollbar[VERTICAL]->setFollowsBottom();
LLRect horizontal_scroll_rect = mInnerRect;
horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + SCROLLBAR_SIZE;
horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + scrollbar_size;
mScrollbar[HORIZONTAL] = new LLScrollbar( std::string("scrollable horizontal"),
horizontal_scroll_rect,
LLScrollbar::HORIZONTAL,
@@ -139,7 +118,7 @@ void LLScrollableContainerView::init()
mInnerRect.getWidth(),
NULL, this,
HORIZONTAL_MULTIPLE);
addChild( mScrollbar[HORIZONTAL] );
LLView::addChild( mScrollbar[HORIZONTAL] );
mScrollbar[HORIZONTAL]->setVisible( FALSE );
mScrollbar[HORIZONTAL]->setFollowsLeft();
mScrollbar[HORIZONTAL]->setFollowsRight();
@@ -190,8 +169,8 @@ void LLScrollableContainerView::reshape(S32 width, S32 height,
{
LLUICtrl::reshape( width, height, called_from_parent );
mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 );
mInnerRect.stretch( -mBorder->getBorderWidth() );
mInnerRect = getLocalRect();
mInnerRect.stretch( -getBorderWidth() );
if (mScrolledView)
{
@@ -201,22 +180,33 @@ void LLScrollableContainerView::reshape(S32 width, S32 height,
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() );
mScrollbar[VERTICAL]->setPageSize( visible_height );
mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() );
mScrollbar[HORIZONTAL]->setPageSize( visible_width );
updateScroll();
}
}
BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask)
{
// allow scrolled view to handle keystrokes in case it delegated keyboard focus
// to the scroll container.
// NOTE: this should not recurse indefinitely as handleKeyHere
// should not propagate to parent controls, so mScrolledView should *not*
// call LLScrollContainer::handleKeyHere in turn
if (mScrolledView && mScrolledView->handleKeyHere(key, mask))
{
return TRUE;
}
for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
{
if( mScrollbar[i]->handleKeyHere(key, mask) )
{
updateScroll();
return TRUE;
}
}
@@ -226,38 +216,37 @@ BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask)
BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks )
{
for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
{
// Note: tries vertical and then horizontal
// Give event to my child views - they may have scroll bars
// (Bad UI design, but technically possible.)
if (LLUICtrl::handleScrollWheel(x,y,clicks))
return TRUE;
// When the vertical scrollbar is visible, scroll wheel
// only affects vertical scrolling. It's confusing to have
// scroll wheel perform both vertical and horizontal in a
// single container.
LLScrollbar* vertical = mScrollbar[VERTICAL];
if (vertical->getVisible()
&& vertical->getEnabled())
{
// Pretend the mouse is over the scrollbar
if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) )
if (vertical->handleScrollWheel( 0, 0, clicks ) )
{
return TRUE;
updateScroll();
}
// Always eat the event
return TRUE;
}
// Eat scroll wheel event (to avoid scrolling nested containers?)
return TRUE;
}
BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) const
{
if(mScrollbar[axis]->getVisible())
LLScrollbar* horizontal = mScrollbar[HORIZONTAL];
// Test enablement and visibility for consistency with
// LLView::childrenHandleScrollWheel().
if (horizontal->getVisible()
&& horizontal->getEnabled()
&& horizontal->handleScrollWheel( 0, 0, clicks ) )
{
LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
const S32 AUTOSCROLL_SIZE = 10;
if(mScrollbar[axis]->getVisible())
{
inner_rect_local.mRight -= SCROLLBAR_SIZE;
inner_rect_local.mTop += AUTOSCROLL_SIZE;
inner_rect_local.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE;
}
if( inner_rect_local.pointInRect( x, y ) && (mScrollbar[axis]->getDocPos() > 0) )
{
return TRUE;
}
updateScroll();
return TRUE;
}
return FALSE;
}
@@ -269,65 +258,10 @@ BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask,
EAcceptance* accept,
std::string& tooltip_msg)
{
//S32 scrollbar_size = SCROLLBAR_SIZE;
// Scroll folder view if needed. Never accepts a drag or drop.
*accept = ACCEPT_NO;
BOOL handled = FALSE;
if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
{
const S32 AUTOSCROLL_SIZE = 10;
S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
if( mScrollbar[HORIZONTAL]->getVisible() )
{
inner_rect_local.mBottom += SCROLLBAR_SIZE;
}
if( mScrollbar[VERTICAL]->getVisible() )
{
inner_rect_local.mRight -= SCROLLBAR_SIZE;
}
if( mScrollbar[HORIZONTAL]->getVisible() )
{
LLRect left_scroll_rect = inner_rect_local;
left_scroll_rect.mRight = AUTOSCROLL_SIZE;
if( left_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() > 0) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
handled = TRUE;
}
LLRect right_scroll_rect = inner_rect_local;
right_scroll_rect.mLeft = inner_rect_local.mRight - AUTOSCROLL_SIZE;
if( right_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() < mScrollbar[HORIZONTAL]->getDocPosMax()) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
handled = TRUE;
}
}
if( mScrollbar[VERTICAL]->getVisible() )
{
LLRect bottom_scroll_rect = inner_rect_local;
bottom_scroll_rect.mTop = AUTOSCROLL_SIZE + bottom_scroll_rect.mBottom;
if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() < mScrollbar[VERTICAL]->getDocPosMax()) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
handled = TRUE;
}
LLRect top_scroll_rect = inner_rect_local;
top_scroll_rect.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE;
if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() > 0) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
handled = TRUE;
}
}
}
BOOL handled = autoScroll(x, y);
if( !handled )
{
@@ -338,6 +272,78 @@ BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask,
return TRUE;
}
bool LLScrollableContainerView::autoScroll(S32 x, S32 y)
{
S32 scrollbar_size = SCROLLBAR_SIZE;
bool scrolling = false;
if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
{
LLRect screen_local_extents;
screenRectToLocal(getRootView()->getLocalRect(), &screen_local_extents);
LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
if( mScrollbar[HORIZONTAL]->getVisible() )
{
inner_rect_local.mBottom += scrollbar_size;
}
if( mScrollbar[VERTICAL]->getVisible() )
{
inner_rect_local.mRight -= scrollbar_size;
}
// clip rect against root view
inner_rect_local.intersectWith(screen_local_extents);
S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
// autoscroll region should take up no more than one third of visible scroller area
S32 auto_scroll_region_width = llmin(inner_rect_local.getWidth() / 3, 10);
S32 auto_scroll_region_height = llmin(inner_rect_local.getHeight() / 3, 10);
if( mScrollbar[HORIZONTAL]->getVisible() )
{
LLRect left_scroll_rect = screen_local_extents;
left_scroll_rect.mRight = inner_rect_local.mLeft + auto_scroll_region_width;
if( left_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() > 0) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
scrolling = true;
}
LLRect right_scroll_rect = screen_local_extents;
right_scroll_rect.mLeft = inner_rect_local.mRight - auto_scroll_region_width;
if( right_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() < mScrollbar[HORIZONTAL]->getDocPosMax()) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
scrolling = true;
}
}
if( mScrollbar[VERTICAL]->getVisible() )
{
LLRect bottom_scroll_rect = screen_local_extents;
bottom_scroll_rect.mTop = inner_rect_local.mBottom + auto_scroll_region_height;
if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() < mScrollbar[VERTICAL]->getDocPosMax()) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
scrolling = true;
}
LLRect top_scroll_rect = screen_local_extents;
top_scroll_rect.mBottom = inner_rect_local.mTop - auto_scroll_region_height;
if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() > 0) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
scrolling = true;
}
}
}
return scrolling;
}
BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect)
{
@@ -368,42 +374,44 @@ BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, std::string& msg, LL
void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
{
const LLRect& rect = mScrolledView->getRect();
calcVisibleSize(rect, visible_width, visible_height, show_h_scrollbar, show_v_scrollbar);
}
void LLScrollableContainerView::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
{
const LLRect& doc_rect = getScrolledViewRect();
S32 scrollbar_size = SCROLLBAR_SIZE;
S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight();
*visible_width = getRect().getWidth() - 2 * mBorder->getBorderWidth();
*visible_height = getRect().getHeight() - 2 * mBorder->getBorderWidth();
S32 border_width = getBorderWidth();
*visible_width = getRect().getWidth() - 2 * border_width;
*visible_height = getRect().getHeight() - 2 * border_width;
*show_v_scrollbar = FALSE;
if( *visible_height < doc_height )
{
*show_v_scrollbar = TRUE;
*visible_width -= SCROLLBAR_SIZE;
}
*show_h_scrollbar = FALSE;
if( *visible_width < doc_width )
{
*show_h_scrollbar = TRUE;
*visible_height -= SCROLLBAR_SIZE;
// Must retest now that visible_height has changed
if( !*show_v_scrollbar && (*visible_height < doc_height) )
if (!mHideScrollbar)
{
if( *visible_height < doc_height )
{
*show_v_scrollbar = TRUE;
*visible_width -= SCROLLBAR_SIZE;
*visible_width -= scrollbar_size;
}
if( *visible_width < doc_width )
{
*show_h_scrollbar = TRUE;
*visible_height -= scrollbar_size;
// Must retest now that visible_height has changed
if( !*show_v_scrollbar && (*visible_height < doc_height) )
{
*show_v_scrollbar = TRUE;
*visible_width -= scrollbar_size;
}
}
}
}
void LLScrollableContainerView::draw()
{
S32 scrollbar_size = SCROLLBAR_SIZE;
if (mAutoScrolling)
{
// add acceleration to autoscroll
@@ -411,76 +419,79 @@ void LLScrollableContainerView::draw()
}
else
{
// reset to minimum
mAutoScrollRate = MIN_AUTO_SCROLL_RATE;
// reset to minimum for next time
mAutoScrollRate = mMinAutoScrollRate;
}
// clear this flag to be set on next call to handleDragAndDrop
// clear this flag to be set on next call to autoScroll
mAutoScrolling = FALSE;
// auto-focus when scrollbar active
// this allows us to capture user intent (i.e. stop automatically scrolling the view/etc)
if (!gFocusMgr.childHasKeyboardFocus(this) &&
(mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture()))
if (!hasFocus()
&& (mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture()))
{
focusFirstItem();
}
// Draw background
if( mIsOpaque )
if (getRect().isValid())
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4fv( mBackgroundColor.mV );
gl_rect_2d( mInnerRect );
}
// Draw background
if( mIsOpaque )
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4fv( mBackgroundColor.mV );
gl_rect_2d( mInnerRect );
}
// Draw mScrolledViews and update scroll bars.
// get a scissor region ready, and draw the scrolling view. The
// scissor region ensures that we don't draw outside of the bounds
// of the rectangle.
if( mScrolledView )
{
updateScroll();
// Draw the scrolled area.
// Draw mScrolledViews and update scroll bars.
// get a scissor region ready, and draw the scrolling view. The
// scissor region ensures that we don't draw outside of the bounds
// of the rectangle.
if( mScrolledView )
{
S32 visible_width = 0;
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
updateScroll();
LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) + visible_height,
visible_width,
mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0)
));
drawChild(mScrolledView);
// Draw the scrolled area.
{
S32 visible_width = 0;
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height,
mInnerRect.mRight - (show_v_scrollbar ? scrollbar_size: 0),
mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0)
));
drawChild(mScrolledView);
}
}
}
// Highlight border if a child of this container has keyboard focus
if( mBorder->getVisible() )
{
mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) );
}
// Highlight border if a child of this container has keyboard focus
if( mBorder->getVisible() )
{
mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) );
}
// Draw all children except mScrolledView
// Note: scrollbars have been adjusted by above drawing code
for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
child_iter != getChildList()->rend(); ++child_iter)
{
LLView *viewp = *child_iter;
if( sDebugRects )
// Draw all children except mScrolledView
// Note: scrollbars have been adjusted by above drawing code
for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
child_iter != getChildList()->rend(); ++child_iter)
{
sDepth++;
}
if( (viewp != mScrolledView) && viewp->getVisible() )
{
drawChild(viewp);
}
if( sDebugRects )
{
sDepth--;
LLView *viewp = *child_iter;
if( sDebugRects )
{
sDepth++;
}
if( (viewp != mScrolledView) && viewp->getVisible() )
{
drawChild(viewp);
}
if( sDebugRects )
{
sDepth--;
}
}
}
@@ -491,9 +502,30 @@ void LLScrollableContainerView::draw()
} // end draw
bool LLScrollableContainerView::addChild(LLView* view, S32 tab_group)
{
if (!mScrolledView)
{
// Use the first panel or container as the scrollable view (bit of a hack)
mScrolledView = view;
}
bool ret_val = LLView::addChild(view, tab_group);
//bring the scrollbars to the front
sendChildToFront( mScrollbar[HORIZONTAL] );
sendChildToFront( mScrollbar[VERTICAL] );
return ret_val;
}
void LLScrollableContainerView::updateScroll()
{
if(!mScrolledView)return;
if (!mScrolledView)
{
return;
}
S32 scrollbar_size = SCROLLBAR_SIZE;
LLRect doc_rect = mScrolledView->getRect();
S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight();
@@ -501,9 +533,9 @@ void LLScrollableContainerView::updateScroll()
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
calcVisibleSize( doc_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
S32 border_width = mBorder->getBorderWidth();
S32 border_width = getBorderWidth();
if( show_v_scrollbar )
{
if( doc_rect.mTop < getRect().getHeight() - border_width )
@@ -517,15 +549,15 @@ void LLScrollableContainerView::updateScroll()
S32 v_scrollbar_height = visible_height;
if( !show_h_scrollbar && mReserveScrollCorner )
{
v_scrollbar_height -= SCROLLBAR_SIZE;
v_scrollbar_height -= scrollbar_size;
}
mScrollbar[VERTICAL]->reshape( SCROLLBAR_SIZE, v_scrollbar_height, TRUE );
mScrollbar[VERTICAL]->reshape( scrollbar_size, v_scrollbar_height, TRUE );
// Make room for the horizontal scrollbar (or not)
S32 v_scrollbar_offset = 0;
if( show_h_scrollbar || mReserveScrollCorner )
{
v_scrollbar_offset = SCROLLBAR_SIZE;
v_scrollbar_offset = scrollbar_size;
}
LLRect r = mScrollbar[VERTICAL]->getRect();
r.translate( 0, mInnerRect.mBottom - r.mBottom + v_scrollbar_offset );
@@ -555,9 +587,9 @@ void LLScrollableContainerView::updateScroll()
S32 h_scrollbar_width = visible_width;
if( !show_v_scrollbar && mReserveScrollCorner )
{
h_scrollbar_width -= SCROLLBAR_SIZE;
h_scrollbar_width -= scrollbar_size;
}
mScrollbar[HORIZONTAL]->reshape( h_scrollbar_width, SCROLLBAR_SIZE, TRUE );
mScrollbar[HORIZONTAL]->reshape( h_scrollbar_width, scrollbar_size, TRUE );
}
else
{
@@ -577,8 +609,19 @@ void LLScrollableContainerView::updateScroll()
void LLScrollableContainerView::setBorderVisible(BOOL b)
{
mBorder->setVisible( b );
// Recompute inner rect, as border visibility changes it
mInnerRect = getLocalRect();
mInnerRect.stretch( -getBorderWidth() );
}
LLRect LLScrollableContainerView::getVisibleContentRect()
{
updateScroll();
LLRect visible_rect = getContentWindowRect();
LLRect contents_rect = mScrolledView->getRect();
visible_rect.translate(-contents_rect.mLeft, -contents_rect.mBottom);
return visible_rect;
}
LLRect LLScrollableContainerView::getContentWindowRect()
{
updateScroll();
@@ -588,7 +631,7 @@ LLRect LLScrollableContainerView::getContentWindowRect()
BOOL show_h_scrollbar = FALSE;
BOOL show_v_scrollbar = FALSE;
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
S32 border_width = mBorder->getBorderWidth();
S32 border_width = getBorderWidth();
scroller_view_rect.setOriginAndSize(border_width,
show_h_scrollbar ? mScrollbar[HORIZONTAL]->getRect().mTop : border_width,
visible_width,
@@ -596,99 +639,85 @@ LLRect LLScrollableContainerView::getContentWindowRect()
return scroller_view_rect;
}
// Scroll so that as much of rect as possible is showing (where rect is defined in the space of scroller view, not scrolled)
void LLScrollableContainerView::scrollToShowRect(const LLRect& rect, const LLCoordGL& desired_offset)
// rect is in document coordinates, constraint is in display coordinates relative to content window rect
void LLScrollableContainerView::scrollToShowRect(const LLRect& rect, const LLRect& constraint)
{
if (!mScrolledView)
{
llwarns << "LLScrollableContainerView::scrollToShowRect with no view!" << llendl;
llwarns << "LLScrollContainer::scrollToShowRect with no view!" << llendl;
return;
}
S32 visible_width = 0;
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
const LLRect& scrolled_rect = mScrolledView->getRect();
calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
LLRect content_window_rect = getContentWindowRect();
// get document rect
LLRect scrolled_rect = mScrolledView->getRect();
// can't be so far left that right side of rect goes off screen, or so far right that left side does
S32 horiz_offset = llclamp(desired_offset.mX, llmin(0, -visible_width + rect.getWidth()), 0);
// can't be so high that bottom of rect goes off screen, or so low that top does
S32 vert_offset = llclamp(desired_offset.mY, 0, llmax(0, visible_height - rect.getHeight()));
// shrink target rect to fit within constraint region, biasing towards top left
LLRect rect_to_constrain = rect;
rect_to_constrain.mBottom = llmax(rect_to_constrain.mBottom, rect_to_constrain.mTop - constraint.getHeight());
rect_to_constrain.mRight = llmin(rect_to_constrain.mRight, rect_to_constrain.mLeft + constraint.getWidth());
// Vertical
// 1. First make sure the top is visible
// 2. Then, if possible without hiding the top, make the bottom visible.
S32 vert_pos = mScrollbar[VERTICAL]->getDocPos();
// calculate allowable positions for scroller window in document coordinates
LLRect allowable_scroll_rect(rect_to_constrain.mRight - constraint.mRight,
rect_to_constrain.mBottom - constraint.mBottom,
rect_to_constrain.mLeft - constraint.mLeft,
rect_to_constrain.mTop - constraint.mTop);
// find scrollbar position to get top of rect on screen (scrolling up)
S32 top_offset = scrolled_rect.mTop - rect.mTop - vert_offset;
// find scrollbar position to get bottom of rect on screen (scrolling down)
S32 bottom_offset = vert_offset == 0 ? scrolled_rect.mTop - rect.mBottom - visible_height : top_offset;
// scroll up far enough to see top or scroll down just enough if item is bigger than visual area
if( vert_pos >= top_offset || visible_height < rect.getHeight())
{
vert_pos = top_offset;
}
// else scroll down far enough to see bottom
else
if( vert_pos <= bottom_offset )
{
vert_pos = bottom_offset;
}
// translate from allowable region for lower left corner to upper left corner
allowable_scroll_rect.translate(0, content_window_rect.getHeight());
S32 vert_pos = llclamp(mScrollbar[VERTICAL]->getDocPos(),
mScrollbar[VERTICAL]->getDocSize() - allowable_scroll_rect.mTop, // min vertical scroll
mScrollbar[VERTICAL]->getDocSize() - allowable_scroll_rect.mBottom); // max vertical scroll
mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() );
mScrollbar[VERTICAL]->setPageSize( visible_height );
mScrollbar[VERTICAL]->setPageSize( content_window_rect.getHeight() );
mScrollbar[VERTICAL]->setDocPos( vert_pos );
// Horizontal
// 1. First make sure left side is visible
// 2. Then, if possible without hiding the left side, make the right side visible.
S32 horiz_pos = mScrollbar[HORIZONTAL]->getDocPos();
S32 left_offset = rect.mLeft - scrolled_rect.mLeft + horiz_offset;
S32 right_offset = horiz_offset == 0 ? rect.mRight - scrolled_rect.mLeft - visible_width : left_offset;
S32 horizontal_pos = llclamp(mScrollbar[HORIZONTAL]->getDocPos(),
allowable_scroll_rect.mLeft,
allowable_scroll_rect.mRight);
if( horiz_pos >= left_offset || visible_width < rect.getWidth() )
{
horiz_pos = left_offset;
}
else if( horiz_pos <= right_offset )
{
horiz_pos = right_offset;
}
mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() );
mScrollbar[HORIZONTAL]->setPageSize( visible_width );
mScrollbar[HORIZONTAL]->setDocPos( horiz_pos );
mScrollbar[HORIZONTAL]->setPageSize( content_window_rect.getWidth() );
mScrollbar[HORIZONTAL]->setDocPos( horizontal_pos );
// propagate scroll to document
updateScroll();
// In case we are in accordion tab notify parent to show selected rectangle
LLRect screen_rc;
localRectToScreen(rect_to_constrain, &screen_rc);
notifyParent(LLSD().with("scrollToShowRect",screen_rc.getValue()));
}
void LLScrollableContainerView::pageUp(S32 overlap)
{
mScrollbar[VERTICAL]->pageUp(overlap);
updateScroll();
}
void LLScrollableContainerView::pageDown(S32 overlap)
{
mScrollbar[VERTICAL]->pageDown(overlap);
updateScroll();
}
void LLScrollableContainerView::goToTop()
{
mScrollbar[VERTICAL]->setDocPos(0);
updateScroll();
}
void LLScrollableContainerView::goToBottom()
{
mScrollbar[VERTICAL]->setDocPos(mScrollbar[VERTICAL]->getDocSize());
updateScroll();
}
S32 LLScrollableContainerView::getBorderWidth() const
{
if (mBorder)
if (mBorder && mBorder->getVisible())
{
return mBorder->getBorderWidth();
}

View File

@@ -63,31 +63,29 @@ public:
LLScrollableContainerView( const std::string& name, const LLRect& rect,
LLView* scrolled_view, BOOL is_opaque = FALSE,
const LLColor4& bg_color = LLColor4(0,0,0,0) );
LLScrollableContainerView( const std::string& name, const LLRect& rect,
LLUICtrl* scrolled_ctrl, BOOL is_opaque = FALSE,
const LLColor4& bg_color = LLColor4(0,0,0,0) );
virtual ~LLScrollableContainerView( void );
void setScrolledView(LLView* view) { mScrolledView = view; }
virtual void setValue(const LLSD& value) { mInnerRect.setValue(value); }
void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
void calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
void setBorderVisible( BOOL b );
void scrollToShowRect( const LLRect& rect, const LLCoordGL& desired_offset );
void scrollToShowRect( const LLRect& rect, const LLRect& constraint);
void scrollToShowRect( const LLRect& rect) { scrollToShowRect(rect, LLRect(0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0)); }
void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; }
LLRect getVisibleContentRect();
LLRect getContentWindowRect();
const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
void pageUp(S32 overlap = 0);
void pageDown(S32 overlap = 0);
void goToTop();
void goToBottom();
bool isAtTop() { return mScrollbar[VERTICAL]->isAtBeginning(); }
bool isAtBottom() { return mScrollbar[VERTICAL]->isAtEnd(); }
S32 getBorderWidth() const;
BOOL needsToScroll(S32 x, S32 y, SCROLL_ORIENTATION axis) const;
// LLView functionality
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual BOOL handleKeyHere(KEY key, MASK mask);
@@ -100,8 +98,10 @@ public:
virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect);
virtual void draw();
virtual LLXMLNodePtr getXML(bool save_children = true) const;
virtual bool addChild(LLView* view, S32 tab_group = 0);
bool autoScroll(S32 x, S32 y);
virtual LLXMLNodePtr getXML(bool save_children) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
private:
@@ -111,6 +111,9 @@ private:
virtual void scrollHorizontal( S32 new_pos );
virtual void scrollVertical( S32 new_pos );
void updateScroll();
public:
void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
private:
LLScrollbar* mScrollbar[SCROLLBAR_COUNT];
LLView* mScrolledView;
@@ -122,6 +125,9 @@ private:
BOOL mReserveScrollCorner;
BOOL mAutoScrolling;
F32 mAutoScrollRate;
F32 mMinAutoScrollRate;
F32 mMaxAutoScrollRate;
bool mHideScrollbar;
};

View File

@@ -3024,6 +3024,13 @@ LLSD LLView::getValue() const
return LLSD();
}
S32 LLView::notifyParent(const LLSD& info)
{
LLView* parent = getParent();
if(parent)
return parent->notifyParent(info);
return 0;
}
LLView* LLView::createWidget(LLXMLNodePtr xml_node) const
{
// forward requests to ui ctrl factory

View File

@@ -583,10 +583,14 @@ public:
static LLWindow* getWindow(void) { return LLUI::sWindow; }
virtual void handleReshape(const LLRect& rect, bool by_user);
protected:
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
//send custom notification to LLView parent
virtual S32 notifyParent(const LLSD& info);
protected:
void drawDebugRect();
void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE);
void drawChildren();

View File

@@ -71,6 +71,7 @@ void LLBuildNewViewsScheduler::buildNewViews(LLInventoryPanel* panelp, LLInvento
if (new_listener)
{
LLFolderViewFolder* folderp = new LLFolderViewFolder(new_listener->getDisplayName(),
new_listener->getIcon(),
new_listener->getIcon(),
NULL,
panelp->getRootFolder(),
@@ -96,6 +97,7 @@ void LLBuildNewViewsScheduler::buildNewViews(LLInventoryPanel* panelp, LLInvento
itemp = new LLFolderViewItem(new_listener->getDisplayName(),
new_listener->getIcon(),
NULL,
NULL,
new_listener->getCreationDate(),
panelp->getRootFolder(),
new_listener);

View File

@@ -35,7 +35,6 @@
#include "llfolderview.h"
#include "llcallbacklist.h"
#include "llfloaterinventory.h"
#include "llinventorybridge.h"
#include "llinventoryclipboard.h" // *TODO: remove this once hack below gone.
#include "llinventoryfilter.h"
@@ -43,6 +42,7 @@
#include "llinventorymodelbackgroundfetch.h"
#include "llinventorypanel.h"
#include "llfoldertype.h"
#include "llfloaterinventory.h"// hacked in for the bonus context menu items.
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "llmenugl.h"
@@ -196,13 +196,13 @@ void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
///----------------------------------------------------------------------------
// Default constructor
LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_icon,
LLFolderView::LLFolderView( const std::string& name,
const LLRect& rect, const LLUUID& source_id, LLPanel *parent_view, LLFolderViewEventListener* listener ) :
#if LL_WINDOWS
#pragma warning( push )
#pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list
#endif
LLFolderViewFolder( name, root_folder_icon, NULL, this, listener ),
LLFolderViewFolder( name, NULL, NULL, NULL, this, listener ),
#if LL_WINDOWS
#pragma warning( pop )
#endif
@@ -210,17 +210,18 @@ LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_ic
mScrollContainer( NULL ),
mPopupMenuHandle(),
mAllowMultiSelect(TRUE),
mShowEmptyMessage(TRUE),
mShowFolderHierarchy(FALSE),
mSourceID(source_id),
mRenameItem( NULL ),
mNeedsScroll( FALSE ),
mLastScrollItem( NULL ),
mUseLabelSuffix( TRUE ),
mPinningSelectedItem(FALSE),
mNeedsAutoSelect( FALSE ),
mAutoSelectOverride(FALSE),
mNeedsAutoRename(FALSE),
mDebugFilters(FALSE),
mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME), // This gets overridden by a pref immediately
mSearchType(1),
mFilter( new LLInventoryFilter(name) ),
mShowSelectionContext(FALSE),
mShowSingleSelection(FALSE),
@@ -228,9 +229,14 @@ LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_ic
mSignalSelectCallback(0),
mMinWidth(0),
mDragAndDropThisFrame(FALSE),
mParentPanel(parent_view)
mParentPanel(parent_view),
mUseEllipses(FALSE),
mSearchType(1)
{
mRoot = this;
mShowLoadStatus = TRUE;
LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
setRect( rect );
reshape(rect.getWidth(), rect.getHeight());
@@ -310,18 +316,6 @@ BOOL LLFolderView::canFocusChildren() const
return FALSE;
}
void LLFolderView::checkTreeResortForModelChanged()
{
if (mSortOrder & LLInventoryFilter::SO_DATE && !(mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_NAME))
{
// This is the case where something got added or removed. If we are date sorting
// everything including folders, then we need to rebuild the whole tree.
// Just set to something not SO_DATE to force the folder most resent date resort.
mSortOrder = mSortOrder & ~LLInventoryFilter::SO_DATE;
setSortOrder(mSortOrder | LLInventoryFilter::SO_DATE);
}
}
static LLFastTimer::DeclareTimer FTM_SORT("Sort Inventory");
void LLFolderView::setSortOrder(U32 order)
@@ -329,15 +323,10 @@ void LLFolderView::setSortOrder(U32 order)
if (order != mSortOrder)
{
LLFastTimer t(FTM_SORT);
mSortOrder = order;
for (folders_t::iterator iter = mFolders.begin();
iter != mFolders.end();)
{
folders_t::iterator fit = iter++;
(*fit)->sortBy(order);
}
sortBy(order);
arrangeAll();
}
}
@@ -412,10 +401,7 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
{
mFolders.insert(mFolders.begin(), folder);
}
if (folder->numSelected())
{
recursiveIncrementNumDescendantsSelected(folder->numSelected());
}
folder->setShowLoadStatus(mShowLoadStatus);
folder->setOrigin(0, 0);
folder->reshape(getRect().getWidth(), 0);
folder->setVisible(FALSE);
@@ -432,16 +418,6 @@ void LLFolderView::closeAllFolders()
arrangeAll();
}
void LLFolderView::openFolder(const std::string& foldername)
{
LLFolderViewFolder* inv = getChild<LLFolderViewFolder>(foldername);
if (inv)
{
setSelection(inv, FALSE, FALSE);
inv->setOpen(TRUE);
}
}
void LLFolderView::openTopLevelFolders()
{
for (folders_t::iterator iter = mFolders.begin();
@@ -508,6 +484,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
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
}
if (folderp->getVisible())
{
S32 child_height = 0;
@@ -604,6 +581,11 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
}
width = llmax(mMinWidth, scroll_rect.getWidth());
height = llmax(mRunningHeight, scroll_rect.getHeight());
// restrict width with scroll container's width
if (mUseEllipses)
width = scroll_rect.getWidth();
LLView::reshape(width, height, called_from_parent);
mReshapeSignal(mSelectedItems, FALSE);
@@ -696,6 +678,30 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
return rv;
}
void LLFolderView::setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus)
{
LLFolderViewItem* itemp = getItemByID(obj_id);
if(itemp && itemp->getListener())
{
itemp->arrangeAndSet(TRUE, take_keyboard_focus);
mSelectThisID.setNull();
return;
}
else
{
// save the desired item to be selected later (if/when ready)
mSelectThisID = obj_id;
}
}
void LLFolderView::updateSelection()
{
if (mSelectThisID.notNull())
{
setSelectionByID(mSelectThisID, false);
}
}
BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
{
BOOL rv = FALSE;
@@ -738,26 +744,6 @@ BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
return rv;
}
void LLFolderView::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items)
{
// now store resulting selection
if (mAllowMultiSelect)
{
LLFolderViewItem *cur_selection = getCurSelectedItem();
LLFolderViewFolder::extendSelection(selection, cur_selection, items);
for (S32 i = 0; i < items.count(); i++)
{
addToSelectionList(items[i]);
}
}
else
{
setSelection(selection, FALSE, FALSE);
}
mSignalSelectCallback = SIGNAL_KEYBOARD_FOCUS;
}
static LLFastTimer::DeclareTimer FTM_SANITIZE_SELECTION("Sanitize Selection");
void LLFolderView::sanitizeSelection()
{
@@ -874,23 +860,27 @@ void LLFolderView::sanitizeSelection()
void LLFolderView::clearSelection()
{
if (mSelectedItems.size() > 0)
for (selected_items_t::const_iterator item_it = mSelectedItems.begin();
item_it != mSelectedItems.end();
++item_it)
{
recursiveDeselect(FALSE);
mSelectedItems.clear();
(*item_it)->setUnselected();
}
mSelectedItems.clear();
mSelectThisID.setNull();
}
BOOL LLFolderView::getSelectionList(std::set<LLUUID> &selection)
std::set<LLUUID> LLFolderView::getSelectionList() const
{
std::set<LLUUID> selection;
for (selected_items_t::const_iterator item_it = mSelectedItems.begin();
item_it != mSelectedItems.end();
++item_it)
{
selection.insert((*item_it)->getListener()->getUUID());
}
return (selection.size() != 0);
return selection;
}
BOOL LLFolderView::startDrag(LLToolDragAndDrop::ESource source)
@@ -972,7 +962,7 @@ void LLFolderView::draw()
{
mStatusText.clear();
}
else
else if (mShowEmptyMessage)
{
static LLCachedControl<LLColor4> sSearchStatusColor(gColors, "InventorySearchStatusColor", LLColor4::white );
if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())
@@ -987,7 +977,7 @@ void LLFolderView::draw()
}
}
LLFolderViewFolder::draw();
LLView::draw();
mDragAndDropThisFrame = FALSE;
}
@@ -1013,10 +1003,8 @@ void LLFolderView::closeRenamer( void )
{
if (mRenamer && mRenamer->getVisible())
{
if(mRenamer == gFocusMgr.getTopCtrl())
gFocusMgr.setTopCtrl( NULL );
// Triggers onRenamerLost() that actually closes the renamer.
//gFocusMgr.setTopCtrl( NULL );
gFocusMgr.setTopCtrl( NULL );
}
}
@@ -1255,7 +1243,9 @@ void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
mAutoOpenItems.push(item);
item->setOpen(TRUE);
scrollToShowItem(item);
LLRect content_rect = mScrollContainer->getContentWindowRect();
LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0);
scrollToShowItem(item, constraint_rect);
}
void LLFolderView::closeAutoOpenedFolders()
@@ -1865,8 +1855,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
menu->needsArrange(); // update menu height if needed
//menu->needsArrange(); // update menu height if needed
}
else
{
@@ -1922,9 +1911,28 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
std::string& tooltip_msg)
{
mDragAndDropThisFrame = TRUE;
// have children handle it first
BOOL handled = LLView::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data,
accept, tooltip_msg);
// when drop is not handled by child, it should be handled
// by the folder which is the hierarchy root.
if (!handled)
{
if (getListener()->getUUID().notNull())
{
handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
else
{
if (!mFolders.empty())
{
// dispatch to last folder as a hack to support "Contents" folder in object inventory
handled = mFolders.back()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
}
}
}
if (handled)
{
lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderView" << llendl;
@@ -1970,50 +1978,41 @@ void LLFolderView::scrollToShowSelection()
// If the parent is scroll containter, scroll it to make the selection
// is maximally visible.
void LLFolderView::scrollToShowItem(LLFolderViewItem* item)
void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect)
{
if (!mScrollContainer) return;
// don't scroll to items when mouse is being used to scroll/drag and drop
if (gFocusMgr.childHasMouseCapture(mScrollContainer))
{
mNeedsScroll = FALSE;
return;
}
if(item && mScrollContainer)
// if item exists and is in visible portion of parent folder...
if(item)
{
LLRect local_rect = item->getRect();
LLRect local_rect = item->getLocalRect();
LLRect item_scrolled_rect; // item position relative to display area of scroller
LLRect visible_doc_rect = mScrollContainer->getVisibleContentRect();
S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight();
S32 label_height = llround(sFont->getLineHeight());
// when navigating with keyboard, only move top of folders on screen, otherwise show whole folder
S32 max_height_to_show = gFocusMgr.childHasKeyboardFocus(this) ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight();
item->localPointToOtherView(item->getIndentation(), llmax(0, local_rect.getHeight() - max_height_to_show), &item_scrolled_rect.mLeft, &item_scrolled_rect.mBottom, mScrollContainer);
item->localPointToOtherView(local_rect.getWidth(), local_rect.getHeight(), &item_scrolled_rect.mRight, &item_scrolled_rect.mTop, mScrollContainer);
// when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder
S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight();
// get portion of item that we want to see...
LLRect item_local_rect = LLRect(item->getIndentation(),
local_rect.getHeight(),
llmin(MIN_ITEM_WIDTH_VISIBLE, local_rect.getWidth()),
llmax(0, local_rect.getHeight() - max_height_to_show));
item_scrolled_rect.mRight = llmin(item_scrolled_rect.mLeft + MIN_ITEM_WIDTH_VISIBLE, item_scrolled_rect.mRight);
LLCoordGL scroll_offset(-mScrollContainer->getBorderWidth() - item_scrolled_rect.mLeft,
mScrollContainer->getRect().getHeight() - item_scrolled_rect.mTop - 1);
LLRect item_doc_rect;
S32 max_scroll_offset = getVisibleRect().getHeight() - item_scrolled_rect.getHeight();
if (item != mLastScrollItem || // if we're scrolling to focus on a new item
// or the item has just appeared on screen and it wasn't onscreen before
(scroll_offset.mY > 0 && scroll_offset.mY < max_scroll_offset &&
(mLastScrollOffset.mY < 0 || mLastScrollOffset.mY > max_scroll_offset)))
{
// we now have a position on screen that we want to keep stable
// offset of selection relative to top of visible area
mLastScrollOffset = scroll_offset;
mLastScrollItem = item;
}
item->localRectToOtherView(item_local_rect, &item_doc_rect, this);
mScrollContainer->scrollToShowRect( item_scrolled_rect, mLastScrollOffset );
mScrollContainer->scrollToShowRect( item_doc_rect, constraint_rect );
// after scrolling, store new offset
// in case we don't have room to maintain the original position
LLCoordGL new_item_left_top;
item->localPointToOtherView(item->getIndentation(), item->getRect().getHeight(), &new_item_left_top.mX, &new_item_left_top.mY, mScrollContainer);
mLastScrollOffset.set(-mScrollContainer->getBorderWidth() - new_item_left_top.mX, mScrollContainer->getRect().getHeight() - new_item_left_top.mY - 1);
}
}
@@ -2141,7 +2140,7 @@ void LLFolderView::doIdle()
LLFastTimer t3(FTM_AUTO_SELECT);
// select new item only if a filtered item not currently selected
LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
if (selected_itemp != NULL && sFolderViewItems.count(selected_itemp) == 0)
/*if (selected_itemp != NULL && sFolderViewItems.count(selected_itemp) == 0)
{
// There is a crash bug due to a race condition: when a folder view item is
// destroyed, its address may still appear in mSelectedItems a couple of doIdle()
@@ -2153,7 +2152,7 @@ void LLFolderView::doIdle()
clearSelection();
requestArrange();
}
else if ((selected_itemp && !selected_itemp->getFiltered()) && !mAutoSelectOverride)
else */if ((selected_itemp && !selected_itemp->getFiltered()) && !mAutoSelectOverride)
{
// select first filtered item
LLSelectFirstFilteredItem filter;
@@ -2171,6 +2170,59 @@ void LLFolderView::doIdle()
scrollToShowSelection();
}
// during filtering process, try to pin selected item's location on screen
// this will happen when searching your inventory and when new items arrive
if (filter_modified_and_active)
{
// calculate rectangle to pin item to at start of animated rearrange
if (!mPinningSelectedItem && !mSelectedItems.empty())
{
// lets pin it!
mPinningSelectedItem = TRUE;
LLRect visible_content_rect = mScrollContainer->getVisibleContentRect();
LLFolderViewItem* selected_item = mSelectedItems.back();
LLRect item_rect;
selected_item->localRectToOtherView(selected_item->getLocalRect(), &item_rect, this);
// if item is visible in scrolled region
if (visible_content_rect.overlaps(item_rect))
{
// then attempt to keep it in same place on screen
mScrollConstraintRect = item_rect;
mScrollConstraintRect.translate(-visible_content_rect.mLeft, -visible_content_rect.mBottom);
}
else
{
// otherwise we just want it onscreen somewhere
LLRect content_rect = mScrollContainer->getContentWindowRect();
mScrollConstraintRect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
}
}
}
else
{
// stop pinning selected item after folders stop rearranging
if (!needsArrange())
{
mPinningSelectedItem = FALSE;
}
}
LLRect constraint_rect;
if (mPinningSelectedItem)
{
// use last known constraint rect for pinned item
constraint_rect = mScrollConstraintRect;
}
else
{
// during normal use (page up/page down, etc), just try to fit item on screen
LLRect content_rect = mScrollContainer->getContentWindowRect();
constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
}
BOOL is_visible = isInVisibleChain();
if ( is_visible )
@@ -2184,10 +2236,10 @@ void LLFolderView::doIdle()
if (mSelectedItems.size() && mNeedsScroll)
{
scrollToShowItem(mSelectedItems.back());
scrollToShowItem(mSelectedItems.back(), constraint_rect);
// continue scrolling until animated layout change is done
if (getCompletedFilterGeneration() >= mFilter->getMinRequiredGeneration() &&
(!needsArrange() || !is_visible))
if (!filter_modified_and_active
&& (!needsArrange() || !is_visible))
{
mNeedsScroll = FALSE;
}
@@ -2286,6 +2338,87 @@ void LLFolderView::updateMenu()
menu->needsArrange(); // update menu height if needed
}
}
bool LLFolderView::selectFirstItem()
{
for (folders_t::iterator iter = mFolders.begin();
iter != mFolders.end();++iter)
{
LLFolderViewFolder* folder = (*iter );
if (folder->getVisible())
{
LLFolderViewItem* itemp = folder->getNextFromChild(0,true);
if(itemp)
setSelection(itemp,FALSE,TRUE);
return true;
}
}
for(items_t::iterator iit = mItems.begin();
iit != mItems.end(); ++iit)
{
LLFolderViewItem* itemp = (*iit);
if (itemp->getVisible())
{
setSelection(itemp,FALSE,TRUE);
return true;
}
}
return false;
}
bool LLFolderView::selectLastItem()
{
for(items_t::reverse_iterator iit = mItems.rbegin();
iit != mItems.rend(); ++iit)
{
LLFolderViewItem* itemp = (*iit);
if (itemp->getVisible())
{
setSelection(itemp,FALSE,TRUE);
return true;
}
}
for (folders_t::reverse_iterator iter = mFolders.rbegin();
iter != mFolders.rend();++iter)
{
LLFolderViewFolder* folder = (*iter);
if (folder->getVisible())
{
LLFolderViewItem* itemp = folder->getPreviousFromChild(0,true);
if(itemp)
setSelection(itemp,FALSE,TRUE);
return true;
}
}
return false;
}
S32 LLFolderView::notify(const LLSD& info)
{
if(info.has("action"))
{
std::string str_action = info["action"];
if(str_action == "select_first")
{
setFocus(true);
selectFirstItem();
scrollToShowSelection();
return 1;
}
else if(str_action == "select_last")
{
setFocus(true);
selectLastItem();
scrollToShowSelection();
return 1;
}
}
return 0;
}
///----------------------------------------------------------------------------
/// Local function definitions
///----------------------------------------------------------------------------
@@ -2322,9 +2455,9 @@ bool LLFolderView::getFilterWorn() const
return mFilter->getFilterWorn();
}
U32 LLFolderView::getFilterTypes() const
U32 LLFolderView::getFilterObjectTypes() const
{
return mFilter->getFilterTypes();
return mFilter->getFilterObjectTypes();
}
PermissionMask LLFolderView::getFilterPermissions() const
@@ -2381,27 +2514,3 @@ void properties_selected_items(void* user_data)
fv->propertiesSelectedItems();
}
}
///----------------------------------------------------------------------------
/// Class LLFolderViewEventListener
///----------------------------------------------------------------------------
void LLFolderViewEventListener::arrangeAndSet(LLFolderViewItem* focus,
BOOL set_selection,
BOOL take_keyboard_focus)
{
if(!focus) return;
LLFolderView* root = focus->getRoot();
if(focus->getParentFolder())
focus->getParentFolder()->requestArrange();
if(set_selection)
{
focus->setSelectionFromRoot(focus, TRUE, take_keyboard_focus);
if(root)
{
root->scrollToShowSelection();
}
}
}

View File

@@ -71,16 +71,13 @@ class LLTextBox;
// manages the screen region of the folder view.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLUICtrl;
class LLLineEditor;
class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
{
public:
typedef void (*SelectCallback)(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data);
LLFolderView( const std::string& name, LLUIImagePtr root_folder_icon, const LLRect& rect,
LLFolderView( const std::string& name, const LLRect& rect,
const LLUUID& source_id, LLPanel *parent_view, LLFolderViewEventListener* listener );
virtual ~LLFolderView( void );
@@ -91,7 +88,6 @@ public:
// FolderViews default to sort by name. This will change that,
// and resort the items if necessary.
void setSortOrder(U32 order);
void checkTreeResortForModelChanged();
void setFilterPermMask(PermissionMask filter_perm_mask);
typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
@@ -102,7 +98,7 @@ public:
LLInventoryFilter* getFilter();
const std::string getFilterSubString(BOOL trim = FALSE);
bool getFilterWorn() const;
U32 getFilterTypes() const;
U32 getFilterObjectTypes() const;
PermissionMask getFilterPermissions() const;
// *NOTE: use getFilter()->getShowFolderState();
//LLInventoryFilter::EFolderShow getShowFolderState();
@@ -116,7 +112,6 @@ public:
// Close all folders in the view
void closeAllFolders();
void openFolder(const std::string& foldername);
void openTopLevelFolders();
virtual void toggleOpen() {};
@@ -140,13 +135,17 @@ public:
virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
BOOL take_keyboard_focus);
// Used by menu callbacks
void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
// Called once a frame to update the selection if mSelectThisID has been set
void updateSelection();
// This method is used to toggle the selection of an item. Walks
// children, and keeps track of selected objects.
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items);
virtual BOOL getSelectionList(std::set<LLUUID> &selection);
virtual std::set<LLUUID> getSelectionList() const;
// make sure if ancestor is selected, descendents are not
void sanitizeSelection();
@@ -216,7 +215,7 @@ public:
virtual void deleteAllChildren();
void scrollToShowSelection();
void scrollToShowItem(LLFolderViewItem* item);
void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
void setScrollContainer( LLScrollableContainerView* parent ) { mScrollContainer = parent; }
LLRect getVisibleRect();
@@ -226,6 +225,7 @@ public:
void setShowSingleSelection(BOOL show);
BOOL getShowSingleSelection() { return mShowSingleSelection; }
F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
bool getUseEllipses() { return mUseEllipses; }
void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
void removeItemID(const LLUUID& id);
@@ -238,6 +238,8 @@ public:
BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }
BOOL needsAutoRename() { return mNeedsAutoRename; }
void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }
void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; }
BOOL getDebugFilters() { return mDebugFilters; }
@@ -245,6 +247,9 @@ public:
// DEBUG only
void dumpSelectionInformation();
virtual S32 notify(const LLSD& info) ;
bool useLabelSuffix() { return mUseLabelSuffix; }
void updateMenu();
private:
@@ -260,6 +265,8 @@ protected:
void finishRenamingItem( void );
void closeRenamer( void );
bool selectFirstItem();
bool selectLastItem();
BOOL addNoOptions(LLMenuGL* menu) const;
protected:
@@ -269,6 +276,7 @@ protected:
selected_items_t mSelectedItems;
BOOL mKeyboardSelection;
BOOL mAllowMultiSelect;
BOOL mShowEmptyMessage;
BOOL mShowFolderHierarchy;
LLUUID mSourceID;
@@ -277,11 +285,12 @@ protected:
LLLineEditor* mRenamer;
BOOL mNeedsScroll;
LLFolderViewItem* mLastScrollItem;
LLCoordGL mLastScrollOffset;
BOOL mPinningSelectedItem;
LLRect mScrollConstraintRect;
BOOL mNeedsAutoSelect;
BOOL mAutoSelectOverride;
BOOL mNeedsAutoRename;
bool mUseLabelSuffix;
BOOL mDebugFilters;
U32 mSortOrder;
@@ -305,8 +314,16 @@ protected:
std::map<LLUUID, LLFolderViewItem*> mItemMap;
BOOL mDragAndDropThisFrame;
LLUUID mSelectThisID; // if non null, select this item
LLPanel* mParentPanel;
/**
* Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
* NOTE: For now it uses only to cut LLFolderViewItem::mLabel text to be used for Landmarks in Places Panel.
*/
bool mUseEllipses; // See EXT-719
/**
* Contains item under mouse pointer while dragging
*/

View File

@@ -57,6 +57,7 @@ public:
virtual PermissionMask getPermissionMask() const = 0;
virtual LLFolderType::EType getPreferredType() const = 0;
virtual LLPointer<LLUIImage> getIcon() const = 0;
virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
virtual std::string getLabelSuffix() const = 0;
virtual void openItem( void ) = 0;
@@ -101,11 +102,6 @@ public:
// bridge is actually dropped. This allows for cleanup of the old
// view, reference counting, etc.
// virtual void dropped() = 0;
// this method accesses the parent and arranges and sets it as
// specified.
void arrangeAndSet(LLFolderViewItem* focus, BOOL set_selection,
BOOL take_keyboard_focus = TRUE);
};

File diff suppressed because it is too large Load Diff

View File

@@ -60,10 +60,10 @@ class LLInventorySort
public:
LLInventorySort()
: mSortOrder(0),
mByDate(false),
mSystemToTop(false),
mFoldersByName(false) { }
mByDate(false),
mSystemToTop(false),
mFoldersByName(false) { }
// Returns true if order has changed
bool updateSort(U32 order);
U32 getSort() { return mSortOrder; }
@@ -92,7 +92,7 @@ public:
friend class LLFolderViewEventListener;
static const S32 LEFT_PAD = 5;
static const S32 LEFT_INDENTATION = 13;
static const S32 LEFT_INDENTATION = 6;
static const S32 ICON_PAD = 2;
static const S32 ICON_WIDTH = 16;
static const S32 TEXT_PAD = 1;
@@ -101,6 +101,9 @@ public:
// animation parameters
static const F32 FOLDER_CLOSE_TIME_CONSTANT;
static const F32 FOLDER_OPEN_TIME_CONSTANT;
BOOL isLoading() const { return mIsLoading; }
private:
BOOL mIsSelected;
@@ -114,9 +117,9 @@ protected:
std::string mSearchableLabel;
std::string mSearchableLabelDesc;
std::string mSearchableLabelCreator;
std::string mSearchable;
S32 mLabelWidth;
U32 mCreationDate;
bool mLabelWidthDirty;
time_t mCreationDate;
LLFolderViewFolder* mParentFolder;
LLFolderViewEventListener* mListener;
BOOL mIsCurSelection;
@@ -125,9 +128,11 @@ protected:
std::string mLabelSuffix;
LLUIImagePtr mIcon;
std::string mStatusText;
LLUIImagePtr mIconOpen;
LLUIImagePtr mIconOverlay;
BOOL mHasVisibleChildren;
S32 mIndentation;
S32 mItemHeight;
BOOL mPassedFilter;
S32 mLastFilterGeneration;
std::string::size_type mStringMatchOffset;
@@ -136,18 +141,26 @@ protected:
BOOL mDragAndDropTarget;
BOOL mIsLoading;
LLTimer mTimeSinceRequestStart;
bool mShowLoadStatus;
std::string mSearchable;
U32 mSearchType;
// helper function to change the selection from the root.
void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
// helper function to change the selection from the root.
void extendSelectionFromRoot(LLFolderViewItem* selection);
//Sets extra search criteria 'labels' to be compared against by filter.
void updateExtraSearchCriteria();
//Update mSearchable string based on roots search flags. (Name, creator, desc)
void updateSearchLabelType();
// 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; }
virtual void setCreationDate(time_t creation_date_utc) { mCreationDate = creation_date_utc; }
public:
BOOL postBuild();
@@ -158,16 +171,16 @@ public:
void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem,
BOOL take_keyboard_focus = TRUE);
// This function is called when the folder view is dirty. It's
// implemented here but called by derived classes when folding the
// views.
void arrangeFromRoot();
void filterFromRoot( void );
void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus);
// creation_date is in UTC seconds
LLFolderViewItem( const std::string& name, LLUIImagePtr icon, LLUIImagePtr icon_overlay, S32 creation_date, LLFolderView* root, LLFolderViewEventListener* listener );
LLFolderViewItem( const std::string& name, LLUIImagePtr icon, LLUIImagePtr icon_open, LLUIImagePtr icon_overlay, S32 creation_date, LLFolderView* root, LLFolderViewEventListener* listener );
virtual ~LLFolderViewItem( void );
// addToFolder() returns TRUE if it succeeds. FALSE otherwise
@@ -198,9 +211,6 @@ public:
// Returns TRUE if the selection state of this item was changed.
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
// this method is used to group select items
virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items) { }
// this method is used to deselect this element
void deselectItem();
@@ -208,7 +218,7 @@ public:
virtual void selectItem();
// gets multiple-element selection
virtual BOOL getSelectionList(std::set<LLUUID> &selection){return TRUE;}
virtual std::set<LLUUID> getSelectionList() const;
// Returns true is this object and all of its children can be removed (deleted by user)
virtual BOOL isRemovable();
@@ -221,12 +231,16 @@ public:
BOOL isSelected() const { return mIsSelected; }
void setUnselected() { mIsSelected = FALSE; }
void setIsCurSelection(BOOL select) { mIsCurSelection = select; }
BOOL getIsCurSelection() { return mIsCurSelection; }
BOOL hasVisibleChildren() { return mHasVisibleChildren; }
void setShowLoadStatus(bool status) { mShowLoadStatus = status; }
// Call through to the viewed object and return true if it can be
// removed. Returns true if it's removed.
//virtual BOOL removeRecursively(BOOL single_item);
@@ -239,7 +253,7 @@ public:
// viewed. This method will ask the viewed object itself.
const std::string& getName( void ) const;
std::string& getSearchableLabel( void );
const std::string& getSearchableLabel( void );
// This method returns the label displayed on the view. This
// method was primarily added to allow sorting on the folder
@@ -248,10 +262,10 @@ public:
// Used for sorting, like getLabel() above.
virtual time_t getCreationDate() const { return mCreationDate; }
LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
@@ -271,7 +285,7 @@ public:
// Show children (unfortunate that this is called "open")
virtual void setOpen(BOOL open = TRUE) {};
virtual BOOL isOpen() { return FALSE; }
virtual BOOL isOpen() const { return FALSE; }
virtual LLFolderView* getRoot();
BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor );
@@ -300,13 +314,21 @@ public:
virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual LLView* getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const
{
if(create_if_missing)
return LLView::getChildView(name, recurse, TRUE);
else
return NULL;
}
// virtual void handleDropped();
virtual void draw();
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg);
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg);
};
@@ -326,6 +348,7 @@ class LLFolderViewFolder : public LLFolderViewItem
{
protected:
LLFolderViewFolder( const std::string& name, LLUIImagePtr icon,
LLUIImagePtr icon_open,
LLUIImagePtr icon_link,
LLFolderView* root,
LLFolderViewEventListener* listener );
@@ -343,13 +366,6 @@ public:
typedef std::list<LLFolderViewItem*> items_t;
typedef std::list<LLFolderViewFolder*> folders_t;
private:
S32 mNumDescendantsSelected;
public: // Accessed needed by LLFolderViewItem
void recursiveIncrementNumDescendantsSelected(S32 increment);
S32 numSelected(void) const { return mNumDescendantsSelected + (isSelected() ? 1 : 0); }
protected:
items_t mItems;
folders_t mFolders;
@@ -367,6 +383,8 @@ protected:
S32 mCompletedFilterGeneration;
S32 mMostFilteredDescendantGeneration;
bool mNeedsSort;
bool mPassedFolderFilter;
public:
typedef enum e_recurse_type
{
@@ -406,7 +424,15 @@ public:
// applies filters to control visibility of inventory items
virtual void filter( LLInventoryFilter& filter);
virtual void setFiltered(BOOL filtered, S32 filter_generation);
virtual BOOL getFiltered();
virtual BOOL getFiltered(S32 filter_generation);
virtual void dirtyFilter();
// folder-specific filtering (filter status propagates top down instead of bottom up)
void filterFolder(LLInventoryFilter& filter);
void setFilteredFolder(bool filtered, S32 filter_generation);
bool getFilteredFolder(S32 filter_generation);
// Passes selection information on to children and record
// selection information if necessary.
@@ -421,10 +447,7 @@ public:
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
// this method is used to group select items
virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items);
// Deselect this folder and all folder/items it contains recursively.
void recursiveDeselect(BOOL deselect_self);
void extendSelectionTo(LLFolderViewItem* selection);
// Returns true is this object and all of its children can be removed.
virtual BOOL isRemovable();
@@ -480,15 +503,15 @@ public:
virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO);
// Get the current state of the folder.
virtual BOOL isOpen() { return mIsOpen; }
virtual BOOL isOpen() const { return mIsOpen; }
// special case if an object is dropped on the child.
BOOL handleDragAndDropFromChild(MASK mask,
BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg);
BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg);
void applyFunctorRecursively(LLFolderViewFunctor& functor);
virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
@@ -519,7 +542,6 @@ 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

@@ -129,8 +129,7 @@ bool doToSelected(LLFolderView* folder, std::string action)
LLInventoryClipboard::instance().reset();
}
std::set<LLUUID> selected_items;
folder->getSelectionList(selected_items);
std::set<LLUUID> selected_items = folder->getSelectionList();
LLMultiPreview* multi_previewp = NULL;
LLMultiProperties* multi_propertiesp = NULL;
@@ -232,7 +231,7 @@ class LLNewWindow : public inventory_listener_t
LLInventoryView* iv = new LLInventoryView(std::string("Inventory"),
rect,
mPtr->getActivePanel()->getModel());
iv->getActivePanel()->setFilterTypes(mPtr->getActivePanel()->getFilterTypes());
iv->getActivePanel()->setFilterTypes(mPtr->getActivePanel()->getFilterObjectTypes());
iv->getActivePanel()->setFilterSubString(mPtr->getActivePanel()->getFilterSubString());
iv->open(); /*Flawfinder: ignore*/
@@ -537,8 +536,7 @@ class LLBeginIMSession : public inventory_panel_listener_t
LLInventoryPanel *panel = mPtr;
LLInventoryModel* model = panel->getModel();
if(!model) return true;
std::set<LLUUID> selected_items;
panel->getRootFolder()->getSelectionList(selected_items);
std::set<LLUUID> selected_items = panel->getRootFolder()->getSelectionList();
std::string name;
static int session_num = 1;
@@ -643,8 +641,7 @@ class LLAttachObject : public inventory_panel_listener_t
LLFolderView* folder = panel->getRootFolder();
if(!folder) return true;
std::set<LLUUID> selected_items;
folder->getSelectionList(selected_items);
std::set<LLUUID> selected_items = folder->getSelectionList();
LLUUID id = *selected_items.begin();
std::string joint_name = userdata.asString();

View File

@@ -489,8 +489,7 @@ void LLInventoryBackup::save(LLFolderView* folder)
{
LLInventoryModel* model = &gInventory;
std::set<LLUUID> selected_items;
folder->getSelectionList(selected_items);
std::set<LLUUID> selected_items = folder->getSelectionList();
if(selected_items.size() < 1)
{

View File

@@ -5548,6 +5548,7 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
hide_context_entries(menu, items, disabled_items);
}
// +=================================================+
// | LLLinkBridge |
// +=================================================+
@@ -5555,8 +5556,22 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
std::string LLLinkFolderBridge::sPrefix("Link: ");
LLUIImagePtr LLLinkFolderBridge::getIcon() const
{
//For now, all inv links share this icon. There is no 'overlay' mechanism yet.
return LLUI::getUIImage("inv_link_folder.tga");
LLFolderType::EType folder_type = LLFolderType::FT_NONE;
const LLInventoryObject *obj = getInventoryObject();
if (obj)
{
LLViewerInventoryCategory* cat = NULL;
LLInventoryModel* model = getInventoryModel();
if(model)
{
cat = (LLViewerInventoryCategory*)model->getCategory(obj->getLinkedUUID());
if (cat)
{
folder_type = cat->getPreferredType();
}
}
}
return LLFolderBridge::getIcon(folder_type);
}
void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)

View File

@@ -30,7 +30,7 @@
// viewer includes
#include "llfoldervieweventlistener.h"
#include "llfolderview.h"
#include "llfolderviewitem.h"
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llviewercontrol.h"
@@ -44,12 +44,21 @@
#include "lltrans.h"
LLInventoryFilter::FilterOps::FilterOps() :
mFilterTypes(0xffffffff),
mFilterObjectTypes(0xffffffffffffffffULL),
mFilterCategoryTypes(0xffffffffffffffffULL),
mFilterWearableTypes(0xffffffffffffffffULL),
mMinDate(time_min()),
mMaxDate(time_max()),
mHoursAgo(0),
mShowFolderState(SHOW_NON_EMPTY_FOLDERS),
mPermissions(PERM_NONE) {}
mPermissions(PERM_NONE),
mFilterTypes(FILTERTYPE_OBJECT),
mFilterWorn(false),
mFilterUUID(LLUUID::null),
mFilterLinks(FILTERLINK_INCLUDE_LINKS)
{
}
///----------------------------------------------------------------------------
/// Class LLInventoryFilter
///----------------------------------------------------------------------------
@@ -62,7 +71,6 @@ LLInventoryFilter::LLInventoryFilter(const std::string& name)
mSubStringMatchOffset = 0;
mFilterSubString.clear();
mFilterWorn = false;
mFilterGeneration = 0;
mMustPassGeneration = S32_MAX;
mMinRequiredGeneration = 0;
@@ -82,36 +90,184 @@ LLInventoryFilter::~LLInventoryFilter()
BOOL LLInventoryFilter::check(LLFolderViewItem* item)
{
LLFolderViewEventListener* listener = item->getListener();
const LLUUID& item_id = listener->getUUID();
const LLInventoryObject *obj = gInventory.getObject(item_id);
if (isActive() && obj && obj->getIsLinkType())
// If it's a folder and we're showing all folders, return TRUE automatically.
const BOOL is_folder = (dynamic_cast<const LLFolderViewFolder*>(item) != NULL);
if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
{
// When filtering is active, omit links.
return FALSE;
return TRUE;
}
time_t earliest;
const LLFolderViewEventListener* listener = item->getListener();
const LLUUID item_id = listener ? listener->getUUID() : LLUUID::null;
earliest = time_corrected() - mFilterOps.mHoursAgo * 3600;
if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
{
earliest = mFilterOps.mMinDate;
}
else if (!mFilterOps.mHoursAgo)
{
earliest = 0;
}
mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
BOOL passed = (0x1 << listener->getInventoryType() & mFilterOps.mFilterTypes || listener->getInventoryType() == LLInventoryType::IT_NONE)
&& (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos)
&& (mFilterWorn == false || gAgentWearables.isWearingItem(item_id) ||
(gAgentAvatarp && gAgentAvatarp->isWearingAttachment(item_id)))
&& ((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions)
&& (listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate);
const BOOL passed_filtertype = checkAgainstFilterType(item);
const BOOL passed_permissions = checkAgainstPermissions(item);
const BOOL passed_filterlink = checkAgainstFilterLinks(item);
const BOOL passed_wearable = !mFilterOps.mFilterWorn || (gAgentWearables.isWearingItem(item_id) || (gAgentAvatarp && gAgentAvatarp->isWearingAttachment(item_id)));
const BOOL passed = (passed_filtertype &&
passed_permissions &&
passed_filterlink &&
passed_wearable &&
(mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
return passed;
}
bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder)
{
// we're showing all folders, overriding filter
if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
{
return true;
}
const LLFolderViewEventListener* listener = folder->getListener();
const LLUUID folder_id = listener->getUUID();
if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
{
// Can only filter categories for items in your inventory
// (e.g. versus in-world object contents).
const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
if (!cat)
return false;
LLFolderType::EType cat_type = cat->getPreferredType();
if (cat_type != LLFolderType::FT_NONE && (1LL << cat_type & mFilterOps.mFilterCategoryTypes) == U64(0))
return false;
}
return true;
}
BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
{
const LLFolderViewEventListener* listener = item->getListener();
if (!listener) return FALSE;
LLInventoryType::EType object_type = listener->getInventoryType();
const LLUUID object_id = listener->getUUID();
const LLInventoryObject *object = gInventory.getObject(object_id);
const U32 filterTypes = mFilterOps.mFilterTypes;
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_OBJECT
// Pass if this item's type is of the correct filter type
if (filterTypes & FILTERTYPE_OBJECT)
{
// If it has no type, pass it, unless it's a link.
if (object_type == LLInventoryType::IT_NONE)
{
if (object && object->getIsLinkType())
{
return FALSE;
}
}
else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
{
return FALSE;
}
}
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_UUID
// Pass if this item is the target UUID or if it links to the target UUID
if (filterTypes & FILTERTYPE_UUID)
{
if (!object) return FALSE;
if (object->getLinkedUUID() != mFilterOps.mFilterUUID)
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_DATE
// Pass if this item is within the date range.
if (filterTypes & FILTERTYPE_DATE)
{
const U16 HOURS_TO_SECONDS = 3600;
time_t earliest = time_corrected() - mFilterOps.mHoursAgo * HOURS_TO_SECONDS;
if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
{
earliest = mFilterOps.mMinDate;
}
else if (!mFilterOps.mHoursAgo)
{
earliest = 0;
}
if (listener->getCreationDate() < earliest ||
listener->getCreationDate() > mFilterOps.mMaxDate)
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_WEARABLE
// Pass if this item is a wearable of the appropriate type
if (filterTypes & FILTERTYPE_WEARABLE)
{
LLWearableType::EType type = listener->getWearableType();
if ((0x1LL << type & mFilterOps.mFilterWearableTypes) == 0)
{
return FALSE;
}
}
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_EMPTYFOLDERS
// Pass if this item is a folder and is not a system folder that should be hidden
if (filterTypes & FILTERTYPE_EMPTYFOLDERS)
{
if (object_type == LLInventoryType::IT_CATEGORY)
{
bool is_hidden_if_empty = LLViewerFolderType::lookupIsHiddenIfEmpty(listener->getPreferredType());
if (is_hidden_if_empty)
{
// Force the fetching of those folders so they are hidden iff they really are empty...
gInventory.fetchDescendentsOf(object_id);
return FALSE;
}
}
}
return TRUE;
}
BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
{
const LLFolderViewEventListener* listener = item->getListener();
if (!listener) return FALSE;
PermissionMask perm = listener->getPermissionMask();
const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(item->getListener());
if (bridge && bridge->isLink())
{
const LLUUID& linked_uuid = gInventory.getLinkedItemID(bridge->getUUID());
const LLViewerInventoryItem *linked_item = gInventory.getItem(linked_uuid);
if (linked_item)
perm = linked_item->getPermissionMask();
}
return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions;
}
BOOL LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
{
const LLFolderViewEventListener* listener = item->getListener();
if (!listener) return TRUE;
const LLUUID object_id = listener->getUUID();
const LLInventoryObject *object = gInventory.getObject(object_id);
if (!object) return TRUE;
const BOOL is_link = object->getIsLinkType();
if (is_link && (mFilterOps.mFilterLinks == FILTERLINK_EXCLUDE_LINKS))
return FALSE;
if (!is_link && (mFilterOps.mFilterLinks == FILTERLINK_ONLY_LINKS))
return FALSE;
return TRUE;
}
const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
{
return mFilterSubString;
@@ -125,20 +281,32 @@ std::string::size_type LLInventoryFilter::getStringMatchOffset() const
// has user modified default filter params?
BOOL LLInventoryFilter::isNotDefault() const
{
return mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes
|| mFilterSubString.size()
|| mFilterWorn
|| mFilterOps.mPermissions != mDefaultFilterOps.mPermissions
|| mFilterOps.mMinDate != mDefaultFilterOps.mMinDate
|| mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate
|| mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo;
BOOL not_default = FALSE;
not_default |= (mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes);
not_default |= (mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes);
not_default |= (mFilterOps.mFilterWearableTypes != mDefaultFilterOps.mFilterWearableTypes);
not_default |= (mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes);
not_default |= (mFilterOps.mFilterLinks != mDefaultFilterOps.mFilterLinks);
not_default |= (mFilterSubString.size());
not_default |= (mFilterOps.mFilterWorn != mDefaultFilterOps.mFilterWorn);
not_default |= (mFilterOps.mPermissions != mDefaultFilterOps.mPermissions);
not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate);
not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate);
not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo);
return not_default;
}
BOOL LLInventoryFilter::isActive() const
{
return mFilterOps.mFilterTypes != 0xffffffff
return mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL
|| mFilterOps.mFilterCategoryTypes != 0xffffffffffffffffULL
|| mFilterOps.mFilterWearableTypes != 0xffffffffffffffffULL
|| mFilterOps.mFilterTypes != FILTERTYPE_OBJECT
|| mFilterOps.mFilterLinks != FILTERLINK_INCLUDE_LINKS
|| mFilterSubString.size()
|| mFilterWorn
|| mFilterOps.mFilterWorn != false
|| mFilterOps.mPermissions != PERM_NONE
|| mFilterOps.mMinDate != time_min()
|| mFilterOps.mMaxDate != time_max()
@@ -157,15 +325,15 @@ BOOL LLInventoryFilter::isModifiedAndClear()
return ret;
}
void LLInventoryFilter::setFilterTypes(U32 types)
void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
{
if (mFilterOps.mFilterTypes != types)
if (current_types != types)
{
// keep current items only if no type bits getting turned off
BOOL fewer_bits_set = (mFilterOps.mFilterTypes & ~types);
BOOL more_bits_set = (~mFilterOps.mFilterTypes & types);
mFilterOps.mFilterTypes = types;
bool fewer_bits_set = (current_types & ~types) != 0;
bool more_bits_set = (~current_types & types) != 0;
current_types = types;
if (more_bits_set && fewer_bits_set)
{
// neither less or more restrive, both simultaneously
@@ -181,10 +349,46 @@ void LLInventoryFilter::setFilterTypes(U32 types)
{
setModified(FILTER_MORE_RESTRICTIVE);
}
}
}
void LLInventoryFilter::setFilterObjectTypes(U64 types)
{
updateFilterTypes(types, mFilterOps.mFilterObjectTypes);
mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;
}
void LLInventoryFilter::setFilterCategoryTypes(U64 types)
{
updateFilterTypes(types, mFilterOps.mFilterCategoryTypes);
mFilterOps.mFilterTypes |= FILTERTYPE_CATEGORY;
}
void LLInventoryFilter::setFilterWearableTypes(U64 types)
{
updateFilterTypes(types, mFilterOps.mFilterWearableTypes);
mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE;
}
void LLInventoryFilter::setFilterEmptySystemFolders()
{
mFilterOps.mFilterTypes |= FILTERTYPE_EMPTYFOLDERS;
}
void LLInventoryFilter::setFilterUUID(const LLUUID& object_id)
{
if (mFilterOps.mFilterUUID == LLUUID::null)
{
setModified(FILTER_MORE_RESTRICTIVE);
}
else
{
setModified(FILTER_RESTART);
}
mFilterOps.mFilterUUID = object_id;
mFilterOps.mFilterTypes = FILTERTYPE_UUID;
}
void LLInventoryFilter::setFilterSubString(const std::string& string)
{
std::string filter_sub_string_new = string;
@@ -215,6 +419,19 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
{
setModified(FILTER_RESTART);
}
// Cancel out UUID once the search string is modified
if (mFilterOps.mFilterTypes == FILTERTYPE_UUID)
{
mFilterOps.mFilterTypes &= ~FILTERTYPE_UUID;
mFilterOps.mFilterUUID == LLUUID::null;
setModified(FILTER_RESTART);
}
// Cancel out filter links once the search string is modified
{
mFilterOps.mFilterLinks = FILTERLINK_INCLUDE_LINKS;
}
}
}
@@ -256,6 +473,7 @@ void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date)
mFilterOps.mMaxDate = llmax(mFilterOps.mMinDate, max_date);
setModified();
}
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
}
void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
@@ -270,12 +488,18 @@ void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
setDateRange(0, time_max());
setModified();
}
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
}
BOOL LLInventoryFilter::isSinceLogoff() const
{
return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
(mFilterOps.mMaxDate == time_max());
bool min_date = (mFilterOps.mMinDate == (time_t)mLastLogoff);
bool max_date = (mFilterOps.mMaxDate == time_max());
bool is_filter = (mFilterOps.mFilterTypes & FILTERTYPE_DATE);
return min_date && max_date && is_filter;
//return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
// (mFilterOps.mMaxDate == time_max()) &&
// (mFilterOps.mFilterTypes & FILTERTYPE_DATE);
}
void LLInventoryFilter::clearModified()
@@ -313,7 +537,22 @@ void LLInventoryFilter::setHoursAgo(U32 hours)
setModified(FILTER_RESTART);
}
}
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
}
void LLInventoryFilter::setFilterLinks(U64 filter_links)
{
if (mFilterOps.mFilterLinks != filter_links)
{
if (mFilterOps.mFilterLinks == FILTERLINK_EXCLUDE_LINKS ||
mFilterOps.mFilterLinks == FILTERLINK_ONLY_LINKS)
setModified(FILTER_MORE_RESTRICTIVE);
else
setModified(FILTER_LESS_RESTRICTIVE);
}
mFilterOps.mFilterLinks = filter_links;
}
void LLInventoryFilter::setShowFolderState(EFolderShow state)
{
if (mFilterOps.mShowFolderState != state)
@@ -403,9 +642,9 @@ void LLInventoryFilter::setModified(EFilterBehavior behavior)
}
}
BOOL LLInventoryFilter::isFilterWith(LLInventoryType::EType t) const
BOOL LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const
{
return mFilterOps.mFilterTypes & (0x01 << t);
return mFilterOps.mFilterObjectTypes & (1LL << t);
}
const std::string& LLInventoryFilter::getFilterText()
@@ -423,7 +662,7 @@ const std::string& LLInventoryFilter::getFilterText()
S32 num_filter_types = 0;
mFilterText.clear();
if (isFilterWith(LLInventoryType::IT_ANIMATION))
if (isFilterObjectTypesWith(LLInventoryType::IT_ANIMATION))
{
filtered_types += " Animations,";
filtered_by_type = TRUE;
@@ -435,7 +674,7 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
if (isFilterWith(LLInventoryType::IT_CALLINGCARD))
if (isFilterObjectTypesWith(LLInventoryType::IT_CALLINGCARD))
{
filtered_types += " Calling Cards,";
filtered_by_type = TRUE;
@@ -447,7 +686,7 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
if (isFilterWith(LLInventoryType::IT_WEARABLE))
if (isFilterObjectTypesWith(LLInventoryType::IT_WEARABLE))
{
filtered_types += " Clothing,";
filtered_by_type = TRUE;
@@ -459,7 +698,7 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
if (isFilterWith(LLInventoryType::IT_GESTURE))
if (isFilterObjectTypesWith(LLInventoryType::IT_GESTURE))
{
filtered_types += " Gestures,";
filtered_by_type = TRUE;
@@ -471,7 +710,7 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
if (isFilterWith(LLInventoryType::IT_LANDMARK))
if (isFilterObjectTypesWith(LLInventoryType::IT_LANDMARK))
{
filtered_types += " Landmarks,";
filtered_by_type = TRUE;
@@ -483,7 +722,7 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
if (isFilterWith(LLInventoryType::IT_NOTECARD))
if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD))
{
filtered_types += " Notecards,";
filtered_by_type = TRUE;
@@ -495,7 +734,7 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
if (isFilterWith(LLInventoryType::IT_OBJECT) && isFilterWith(LLInventoryType::IT_ATTACHMENT))
if (isFilterObjectTypesWith(LLInventoryType::IT_OBJECT) && isFilterObjectTypesWith(LLInventoryType::IT_ATTACHMENT))
{
filtered_types += " Objects,";
filtered_by_type = TRUE;
@@ -507,7 +746,7 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
if (isFilterWith(LLInventoryType::IT_LSL))
if (isFilterObjectTypesWith(LLInventoryType::IT_LSL))
{
filtered_types += " Scripts,";
filtered_by_type = TRUE;
@@ -519,7 +758,7 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
if (isFilterWith(LLInventoryType::IT_SOUND))
if (isFilterObjectTypesWith(LLInventoryType::IT_SOUND))
{
filtered_types += " Sounds,";
filtered_by_type = TRUE;
@@ -531,7 +770,7 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
if (isFilterWith(LLInventoryType::IT_TEXTURE))
if (isFilterObjectTypesWith(LLInventoryType::IT_TEXTURE))
{
filtered_types += " Textures,";
filtered_by_type = TRUE;
@@ -543,7 +782,7 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
if (isFilterWith(LLInventoryType::IT_SNAPSHOT))
if (isFilterObjectTypesWith(LLInventoryType::IT_SNAPSHOT))
{
filtered_types += " Snapshots,";
filtered_by_type = TRUE;
@@ -588,7 +827,7 @@ const std::string& LLInventoryFilter::getFilterText()
void LLInventoryFilter::toLLSD(LLSD& data) const
{
data["filter_types"] = (LLSD::Integer)getFilterTypes();
data["filter_types"] = (LLSD::Integer)getFilterObjectTypes();
data["min_date"] = (LLSD::Integer)getMinDate();
data["max_date"] = (LLSD::Integer)getMaxDate();
data["hours_ago"] = (LLSD::Integer)getHoursAgo();
@@ -603,7 +842,7 @@ void LLInventoryFilter::fromLLSD(LLSD& data)
{
if(data.has("filter_types"))
{
setFilterTypes((U32)data["filter_types"].asInteger());
setFilterObjectTypes((U32)data["filter_types"].asInteger());
}
if(data.has("min_date") && data.has("max_date"))
@@ -642,6 +881,16 @@ void LLInventoryFilter::fromLLSD(LLSD& data)
}
}
U64 LLInventoryFilter::getFilterObjectTypes() const
{
return mFilterOps.mFilterObjectTypes;
}
U64 LLInventoryFilter::getFilterCategoryTypes() const
{
return mFilterOps.mFilterCategoryTypes;
}
BOOL LLInventoryFilter::hasFilterString() const
{
return mFilterSubString.size() > 0;
@@ -665,6 +914,10 @@ U32 LLInventoryFilter::getHoursAgo() const
{
return mFilterOps.mHoursAgo;
}
U64 LLInventoryFilter::getFilterLinks() const
{
return mFilterOps.mFilterLinks;
}
LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const
{
return mFilterOps.mShowFolderState;

View File

@@ -51,8 +51,26 @@ public:
FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one
};
enum EFilterType {
FILTERTYPE_NONE = 0,
FILTERTYPE_OBJECT = 0x1 << 0, // normal default search-by-object-type
FILTERTYPE_CATEGORY = 0x1 << 1, // search by folder type
FILTERTYPE_UUID = 0x1 << 2, // find the object with UUID and any links to it
FILTERTYPE_DATE = 0x1 << 3, // search by date range
FILTERTYPE_WEARABLE = 0x1 << 4, // search by wearable type
FILTERTYPE_EMPTYFOLDERS = 0x1 << 5 // pass if folder is not a system folder to be hidden if empty
};
enum EFilterLink
{
FILTERLINK_INCLUDE_LINKS, // show links too
FILTERLINK_EXCLUDE_LINKS, // don't show links
FILTERLINK_ONLY_LINKS // only show links
};
enum ESortOrderType
{
SO_NAME = 0, // Sort inventory by name
SO_DATE = 0x1, // Sort inventory by date
SO_FOLDERS_BY_NAME = 0x1 << 1, // Force folder sort by name
SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2 // Force system folders to be on top
@@ -61,17 +79,26 @@ public:
LLInventoryFilter(const std::string& name);
virtual ~LLInventoryFilter();
void setFilterTypes(U32 types);
BOOL isFilterWith(LLInventoryType::EType t) const;
U32 getFilterTypes() const { return mFilterOps.mFilterTypes; }
// +-------------------------------------------------------------------+
// + Parameters
// +-------------------------------------------------------------------+
void setFilterObjectTypes(U64 types);
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 setFilterEmptySystemFolders();
void updateFilterTypes(U64 types, U64& current_types);
void setFilterSubString(const std::string& string);
const std::string& getFilterSubString(BOOL trim = FALSE) const;
const std::string& getFilterSubStringOrig() const { return mFilterSubStringOrig; }
BOOL hasFilterString() const;
void setFilterWorn(bool worn) { mFilterWorn = worn; }
bool getFilterWorn() const { return mFilterWorn; }
void setFilterWorn(bool worn) { mFilterOps.mFilterWorn = worn; }
bool getFilterWorn() const { return mFilterOps.mFilterWorn; }
void setFilterPermissions(PermissionMask perms);
PermissionMask getFilterPermissions() const;
@@ -84,10 +111,18 @@ public:
void setHoursAgo(U32 hours);
U32 getHoursAgo() const;
void setFilterLinks(U64 filter_link);
U64 getFilterLinks() const;
// +-------------------------------------------------------------------+
// + Execution And Results
// +-------------------------------------------------------------------+
BOOL check(LLFolderViewItem* item);
BOOL check(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;
std::string::size_type getStringMatchOffset() const;
// +-------------------------------------------------------------------+
@@ -146,12 +181,20 @@ private:
struct FilterOps
{
FilterOps();
U32 mFilterTypes;
U32 mFilterTypes;
U64 mFilterObjectTypes; // For _OBJECT
U64 mFilterWearableTypes;
U64 mFilterCategoryTypes; // For _CATEGORY
LLUUID mFilterUUID; // for UUID
time_t mMinDate;
time_t mMaxDate;
U32 mHoursAgo;
EFolderShow mShowFolderState;
PermissionMask mPermissions;
U64 mFilterLinks;
bool mFilterWorn;
};
U32 mOrder;
@@ -163,21 +206,19 @@ private:
std::string::size_type mSubStringMatchOffset;
std::string mFilterSubString;
std::string mFilterSubStringOrig;
bool mFilterWorn;
const std::string mName;
S32 mFilterGeneration;
S32 mMustPassGeneration;
S32 mMinRequiredGeneration;
S32 mNextFilterGeneration;
const std::string mName;
S32 mFilterCount;
EFilterBehavior mFilterBehavior;
S32 mFilterGeneration;
S32 mMustPassGeneration;
S32 mMinRequiredGeneration;
S32 mNextFilterGeneration;
BOOL mModified;
BOOL mNeedTextRebuild;
std::string mFilterText;
S32 mFilterCount;
EFilterBehavior mFilterBehavior;
BOOL mModified;
BOOL mNeedTextRebuild;
std::string mFilterText;
};
#endif

View File

@@ -204,10 +204,8 @@ BOOL LLInventoryPanel::postBuild()
{
setSortOrder(gSavedSettings.getU32(DEFAULT_SORT_ORDER));
}
mFolderRoot->setSortOrder(mFolderRoot->getFilter()->getSortOrder());
return TRUE;
getFilter()->setFilterEmptySystemFolders();
return LLPanel::postBuild();
}
LLInventoryPanel::~LLInventoryPanel()
@@ -273,11 +271,8 @@ LLView* LLInventoryPanel::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
void LLInventoryPanel::draw()
{
// select the desired item (in case it wasn't loaded when the selection was requested)
if (mSelectThisID.notNull())
{
setSelection(mSelectThisID, false);
}
// Select the desired item (in case it wasn't loaded when the selection was requested)
mFolderRoot->updateSelection();
LLPanel::draw();
}
@@ -299,14 +294,17 @@ const LLInventoryFilter* LLInventoryPanel::getFilter() const
return NULL;
}
void LLInventoryPanel::setFilterTypes(U32 filter_types)
void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
{
getFilter()->setFilterTypes(filter_types);
}
if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT)
getFilter()->setFilterObjectTypes(types);
if (filter_type == LLInventoryFilter::FILTERTYPE_CATEGORY)
getFilter()->setFilterCategoryTypes(types);
}
U32 LLInventoryPanel::getFilterTypes() const
U32 LLInventoryPanel::getFilterObjectTypes() const
{
return mFolderRoot->getFilterTypes();
return mFolderRoot->getFilterObjectTypes();
}
U32 LLInventoryPanel::getFilterPermMask() const
@@ -314,11 +312,17 @@ U32 LLInventoryPanel::getFilterPermMask() const
return mFolderRoot->getFilterPermissions();
}
void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)
{
getFilter()->setFilterPermissions(filter_perm_mask);
}
void LLInventoryPanel::setFilterWearableTypes(U64 types)
{
getFilter()->setFilterWearableTypes(types);
}
void LLInventoryPanel::setFilterWorn(bool worn)
{
getFilter()->setFilterWorn(worn);
@@ -334,6 +338,7 @@ const std::string LLInventoryPanel::getFilterSubString()
return mFolderRoot->getFilterSubString();
}
void LLInventoryPanel::setSortOrder(U32 order)
{
getFilter()->setSortOrder(order);
@@ -365,6 +370,11 @@ void LLInventoryPanel::setHoursAgo(U32 hours)
getFilter()->setHoursAgo(hours);
}
void LLInventoryPanel::setFilterLinks(U64 filter_links)
{
getFilter()->setFilterLinks(filter_links);
}
void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show)
{
getFilter()->setShowFolderState(show);
@@ -599,9 +609,7 @@ LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool u
0);
LLFolderView* ret = new LLFolderView(
getName(),
NULL,
folder_rect,
LLUUID::null,
this,
@@ -615,6 +623,7 @@ LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * br
return new LLFolderViewFolder(
bridge->getDisplayName(),
bridge->getIcon(),
bridge->getOpenIcon(),
LLUI::getUIImage("inv_link_overlay.tga"),
mFolderRoot,
bridge);
@@ -625,6 +634,7 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
return new LLFolderViewItem(
bridge->getDisplayName(),
bridge->getIcon(),
bridge->getOpenIcon(),
LLUI::getUIImage("inv_link_overlay.tga"),
bridge->getCreationDate(),
mFolderRoot,
@@ -833,19 +843,29 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EAcceptance* accept,
std::string& tooltip_msg)
{
BOOL handled = FALSE;
BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
if (handled)
//if (mAcceptsDragAndDrop)
{
mFolderRoot->setDragAndDropThisFrame();
handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
// If folder view is empty the (x, y) point won't be in its rect
// so the handler must be called explicitly.
// but only if was not handled before. See EXT-6746.
if (!handled && !mFolderRoot->hasVisibleChildren())
{
handled = mFolderRoot->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
if (handled)
{
mFolderRoot->setDragAndDropThisFrame();
}
}
return handled;
}
void LLInventoryPanel::onFocusLost()
{
// inventory no longer handles cut/copy/paste/delete
@@ -886,22 +906,18 @@ void LLInventoryPanel::openDefaultFolderForType(LLAssetType::EType type)
void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus)
{
LLFolderViewItem* itemp = mFolderRoot->getItemByID(obj_id);
if(itemp && itemp->getListener())
// Don't select objects in COF (e.g. to prevent refocus when items are worn).
const LLInventoryObject *obj = gInventory.getObject(obj_id);
if (obj && obj->getParentUUID() == LLAppearanceMgr::instance().getCOF())
{
itemp->getListener()->arrangeAndSet(itemp, TRUE, take_keyboard_focus);
mSelectThisID.setNull();
return;
}
else
{
// save the desired item to be selected later (if/when ready)
mSelectThisID = obj_id;
}
mFolderRoot->setSelectionByID(obj_id, take_keyboard_focus);
}
void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)
{
if (mFolderRoot)
if (mFolderRoot)
{
mFolderRoot->setSelectCallback(cb);
}
@@ -910,7 +926,6 @@ void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::
void LLInventoryPanel::clearSelection()
{
mFolderRoot->clearSelection();
mSelectThisID.setNull();
}
void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)
@@ -1005,4 +1020,13 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
res = floater_inventory->getActivePanel();
}
return res;
}
}
void LLInventoryPanel::addHideFolderType(LLFolderType::EType folder_type)
{
getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << folder_type));
}
BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) const
{
return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));
}

View File

@@ -105,10 +105,11 @@ public:
void clearSelection();
LLInventoryFilter* getFilter();
const LLInventoryFilter* getFilter() const;
void setFilterTypes(U32 filter);
U32 getFilterTypes() const;
void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
U32 getFilterObjectTypes() const;
void setFilterPermMask(PermissionMask filter_perm_mask);
U32 getFilterPermMask() const;
void setFilterWearableTypes(U64 filter);
void setFilterSubString(const std::string& string);
const std::string getFilterSubString();
void setFilterWorn(bool worn);
@@ -117,7 +118,8 @@ public:
void setSinceLogoff(BOOL sl);
void setHoursAgo(U32 hours);
BOOL getSinceLogoff();
void setFilterLinks(U64 filter_links);
void setShowFolderState(LLInventoryFilter::EFolderShow show);
LLInventoryFilter::EFolderShow getShowFolderState();
void setAllowMultiSelect(BOOL allow) { mFolderRoot->setAllowMultiSelect(allow); }
@@ -187,8 +189,13 @@ public:
private:
const std::string mSortOrderSetting;
LLUUID mSelectThisID; // if non null, select this item
//--------------------------------------------------------------------
// Hidden folders
//--------------------------------------------------------------------
public:
void addHideFolderType(LLFolderType::EType folder_type);
public:
BOOL getIsViewsInitialized() const { return mViewsInitialized; }
const LLUUID& getRootFolderID() const;
@@ -199,6 +206,7 @@ protected:
virtual void buildFolderView();
LLFolderViewItem* buildNewViews(const LLUUID& id);
BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
virtual LLFolderView* createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix);
virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge);

View File

@@ -333,8 +333,7 @@ void LLLocalInventory::loadInvCache(std::string filename)
void LLLocalInventory::saveInvCache(std::string filename, LLFolderView* folder)
{
LLInventoryModel* model = &gInventory;
std::set<LLUUID> selected_items;
folder->getSelectionList(selected_items);
std::set<LLUUID> selected_items = folder->getSelectionList();
if(selected_items.size() < 1)
{
// No items selected? Wtfboom

View File

@@ -71,7 +71,6 @@ public:
BOOL getCheckSinceLogoff();
static void onTimeAgo(LLUICtrl*, void *);
static void onCheckSinceLogoff(LLUICtrl*, void *);
static void onCloseBtn(void* user_data);
static void selectAllTypes(void* user_data);
static void selectNoTypes(void* user_data);
@@ -153,6 +152,7 @@ BOOL LLInventoryView::postBuild()
mActivePanel->getFilter()->markDefault();
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
mActivePanel->setSelectCallback(boost::bind(&LLInventoryView::onSelectionChange, this, mActivePanel, _1, _2));
mResortActivePanel = true;
}
LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
if (recent_items_panel)
@@ -221,8 +221,6 @@ BOOL LLInventoryView::postBuild()
childSetAction("Inventory.ResetAll",onResetAll,this);
childSetAction("Inventory.ExpandAll",onExpandAll,this);
childSetAction("collapse_btn", onCollapseAll, this);
//panel->getFilter()->markDefault();
return TRUE;
}
@@ -349,12 +347,12 @@ BOOL LLInventoryView::handleKeyHere(KEY key, MASK mask)
&& mask == MASK_NONE)
{
// move focus to inventory proper
root_folder->setFocus(TRUE);
mActivePanel->setFocus(TRUE);
root_folder->scrollToShowSelection();
return TRUE;
}
if (root_folder->hasFocus() && key == KEY_UP)
if (mActivePanel->hasFocus() && key == KEY_UP)
{
startSearch();
}
@@ -528,6 +526,7 @@ void LLInventoryView::onClearSearch(void* user_data)
{
self->mActivePanel->setFilterSubString(LLStringUtil::null);
self->mActivePanel->setFilterTypes(0xffffffff);
self->mActivePanel->setFilterLinks(LLInventoryFilter::FILTERLINK_INCLUDE_LINKS);
}
if (finder)
@@ -544,6 +543,7 @@ void LLInventoryView::onClearSearch(void* user_data)
self->mActivePanel->getRootFolder()->applyFunctorRecursively(opener);
self->mActivePanel->getRootFolder()->scrollToShowSelection();
}
self->mFilterSubString = "";
}
//static
@@ -561,10 +561,8 @@ void LLInventoryView::onSearchEdit(const std::string& search_string, void* user_
LLInventoryModelBackgroundFetch::instance().start();
std::string filter_text = search_string;
std::string uppercase_search_string = filter_text;
LLStringUtil::toUpper(uppercase_search_string);
if (self->mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty())
self->mFilterSubString = search_string;
if (self->mActivePanel->getFilterSubString().empty() && self->mFilterSubString.empty())
{
// current filter and new filter empty, do nothing
return;
@@ -578,7 +576,7 @@ void LLInventoryView::onSearchEdit(const std::string& search_string, void* user_
}
// set new filter string
self->mActivePanel->setFilterSubString(uppercase_search_string);
self->setFilterSubString(self->mFilterSubString);
}
struct FilterEntry : public LLDictionaryEntry
@@ -677,7 +675,7 @@ void LLInventoryView::refreshQuickFilter(LLUICtrl* ctrl)
return;
}
U32 filter_type = view->mActivePanel->getFilterTypes();
U32 filter_type = view->mActivePanel->getFilterObjectTypes();
if(!LLFilterDictionary::instanceExists())
LLFilterDictionary::instance().init(view);
@@ -688,12 +686,12 @@ void LLInventoryView::refreshQuickFilter(LLUICtrl* ctrl)
for (LLFilterDictionary::const_iterator_t dictionary_iter = LLFilterDictionary::instance().map_t::begin();
dictionary_iter != LLFilterDictionary::instance().map_t::end(); dictionary_iter++)
{
if(filter_mask != 0xffffffff)
if(dictionary_iter->first != 0xffffffff)
filter_mask |= dictionary_iter->first;
}
filter_type &= filter_mask;
//llinfos << "filter_type: " << filter_type << llendl;
std::string selection;
@@ -705,7 +703,7 @@ void LLInventoryView::refreshQuickFilter(LLUICtrl* ctrl)
{
const FilterEntry *entry = LLFilterDictionary::instance().lookup(filter_type);
if(entry)
selection = view->getString(entry->mName);
selection = entry->mName;
else
selection = view->getString("filter_type_custom");
}
@@ -767,9 +765,6 @@ void LLInventoryView::onCollapseAll(void* userdata)
void LLInventoryView::onFilterSelected(void* userdata, bool from_click)
{
LLInventoryView* self = (LLInventoryView*) userdata;
LLInventoryFilter* filter;
LLFloaterInventoryFinder *finder = self->getFinder();
// Find my index
self->mActivePanel = (LLInventoryPanel*)self->childGetVisibleTab("inventory filter tabs");
@@ -777,7 +772,10 @@ void LLInventoryView::onFilterSelected(void* userdata, bool from_click)
{
return;
}
filter = self->mActivePanel->getFilter();
self->setFilterSubString(self->mFilterSubString);
LLInventoryFilter* filter = self->mActivePanel->getFilter();
LLFloaterInventoryFinder *finder = self->getFinder();
if (finder)
{
finder->changeFilter(filter);
@@ -810,7 +808,7 @@ BOOL LLInventoryView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
{
// Check to see if we are auto scrolling from the last frame
LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel();
BOOL needsToScroll = panel->getScrollableContainer()->needsToScroll(x, y, LLScrollableContainerView::VERTICAL);
BOOL needsToScroll = panel->getScrollableContainer()->autoScroll(x, y);
if(mFilterTabs)
{
if(needsToScroll)
@@ -825,6 +823,39 @@ BOOL LLInventoryView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
}
void LLInventoryView::changed(U32 mask)
{
updateItemcountText();
}
void LLInventoryView::draw()
{
if (mActivePanel && mSearchEditor)
{
mSearchEditor->setText(mActivePanel->getFilterSubString());
}
if (mActivePanel && mQuickFilterCombo)
{
refreshQuickFilter( mQuickFilterCombo );
}
if (mActivePanel && mResortActivePanel)
{
// EXP-756: Force resorting of the list the first time we draw the list:
// In the case of date sorting, we don't have enough information at initialization time
// to correctly sort the folders. Later manual resort doesn't do anything as the order value is
// set correctly. The workaround is to reset the order to alphabetical (or anything) then to the correct order.
U32 order = mActivePanel->getSortOrder();
mActivePanel->setSortOrder(LLInventoryFilter::SO_NAME);
mActivePanel->setSortOrder(order);
mResortActivePanel = false;
}
updateItemcountText();
LLFloater::draw();
}
void LLInventoryView::updateItemcountText()
{
std::ostringstream title;
title << "Inventory";
@@ -839,33 +870,6 @@ void LLInventoryView::changed(U32 mask)
setTitle(title.str());
}
void LLInventoryView::draw()
{
if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
{
LLLocale locale(LLLocale::USER_LOCALE);
std::ostringstream title;
title << "Inventory";
std::string item_count_string;
LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount());
title << " (" << item_count_string << " items)";
title << mFilterText;
setTitle(title.str());
}
if (mActivePanel && mSearchEditor)
{
mSearchEditor->setText(mActivePanel->getFilterSubString());
}
if (mActivePanel && mQuickFilterCombo)
{
refreshQuickFilter( mQuickFilterCombo );
}
LLFloater::draw();
}
void LLInventoryView::setFilterTextFromFilter()
{
mFilterText = mActivePanel->getFilter()->getFilterText();
@@ -935,6 +939,9 @@ LLFloaterInventoryFinder::LLFloaterInventoryFinder(const std::string& name,
BOOL LLFloaterInventoryFinder::postBuild()
{
const LLRect& viewrect = mInventoryView->getRect();
setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight()));
childSetAction("All", selectAllTypes, this);
childSetAction("None", selectNoTypes, this);
@@ -944,30 +951,12 @@ BOOL LLFloaterInventoryFinder::postBuild()
mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago");
childSetCommitCallback("spin_days_ago", onTimeAgo, this);
// mCheckSinceLogoff = getChild<LLSpinCtrl>("check_since_logoff");
childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this);
childSetAction("Close", onCloseBtn, this);
updateElementsFromFilter();
return TRUE;
}
void LLFloaterInventoryFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data)
{
LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
if (!self) return;
bool since_logoff= self->childGetValue("check_since_logoff");
if (!since_logoff &&
!( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) )
{
self->mSpinSinceHours->set(1.0f);
}
}
void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data)
{
LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
@@ -993,7 +982,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
return;
// Get data needed for filter display
U32 filter_types = mFilter->getFilterTypes();
U32 filter_types = mFilter->getFilterObjectTypes();
std::string filter_string = mFilter->getFilterSubString();
LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
U32 hours = mFilter->getHoursAgo();
@@ -1101,9 +1090,9 @@ void LLFloaterInventoryFinder::draw()
}
// update the panel, panel will update the filter
mInventoryView->mActivePanel->setShowFolderState(getCheckShowEmpty() ?
mInventoryView->getPanel()->setShowFolderState(getCheckShowEmpty() ?
LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
mInventoryView->mActivePanel->setFilterTypes(filter);
mInventoryView->getPanel()->setFilterTypes(filter);
if (getCheckSinceLogoff())
{
mSpinSinceDays->set(0);
@@ -1119,8 +1108,8 @@ void LLFloaterInventoryFinder::draw()
mSpinSinceHours->set((F32)hours);
}
hours += days * 24;
mInventoryView->mActivePanel->setHoursAgo(hours);
mInventoryView->mActivePanel->setSinceLogoff(getCheckSinceLogoff());
mInventoryView->getPanel()->setHoursAgo(hours);
mInventoryView->getPanel()->setSinceLogoff(getCheckSinceLogoff());
mInventoryView->setFilterTextFromFilter();
LLFloater::draw();
@@ -1174,18 +1163,6 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
self->childSetValue("check_sound", TRUE);
self->childSetValue("check_texture", TRUE);
self->childSetValue("check_snapshot", TRUE);
/*
self->mCheckCallingCard->set(TRUE);
self->mCheckClothing->set(TRUE);
self->mCheckGesture->set(TRUE);
self->mCheckLandmark->set(TRUE);
self->mCheckNotecard->set(TRUE);
self->mCheckObject->set(TRUE);
self->mCheckScript->set(TRUE);
self->mCheckSound->set(TRUE);
self->mCheckTexture->set(TRUE);
self->mCheckSnapshot->set(TRUE);*/
}
//static
@@ -1194,20 +1171,6 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
if(!self) return;
/*
self->childSetValue("check_animation", FALSE);
self->mCheckCallingCard->set(FALSE);
self->mCheckClothing->set(FALSE);
self->mCheckGesture->set(FALSE);
self->mCheckLandmark->set(FALSE);
self->mCheckNotecard->set(FALSE);
self->mCheckObject->set(FALSE);
self->mCheckScript->set(FALSE);
self->mCheckSound->set(FALSE);
self->mCheckTexture->set(FALSE);
self->mCheckSnapshot->set(FALSE);*/
self->childSetValue("check_animation", FALSE);
self->childSetValue("check_calling_card", FALSE);
self->childSetValue("check_clothing", FALSE);

View File

@@ -124,7 +124,7 @@ public:
void updateSortControls();
void resetFilters();
void updateItemcountText();
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g)
static void closeAll()
@@ -166,9 +166,10 @@ protected:
LLTabContainer* mFilterTabs;
LLHandle<LLFloater> mFinderHandle;
LLInventoryPanel* mActivePanel;
bool mResortActivePanel;
LLSaveFolderState* mSavedFolderState;
std::string mFilterText;
std::string mFilterSubString;
// This container is used to hold all active inventory views. This

View File

@@ -328,15 +328,15 @@ const std::string& LLTaskInvFVBridge::getDisplayName() const
if(!copy)
{
mDisplayName.append(" (no copy)");
mDisplayName.append(LLTrans::getString("no_copy"));
}
if(!mod)
{
mDisplayName.append(" (no modify)");
mDisplayName.append(LLTrans::getString("no_modify"));
}
if(!xfer)
{
mDisplayName.append(" (no transfer)");
mDisplayName.append(LLTrans::getString("no_transfer"));
}
}
@@ -852,7 +852,7 @@ void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
std::vector<std::string> items;
std::vector<std::string> disabled_items;
items.push_back(std::string("Task Open")); // *TODO: Translate
//items.push_back(std::string("Task Open")); // *TODO: Translate
hide_context_entries(menu, items, disabled_items);
}
@@ -1108,9 +1108,9 @@ void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
}
}
else
else if (canOpenItem())
{
items.push_back(std::string("Task Open"));
//items.push_back(std::string("Task Open"));
if (!isItemCopyable())
{
disabled_items.push_back(std::string("Task Open"));
@@ -1618,7 +1618,7 @@ void LLPanelObjectInventory::reset()
setBorderVisible(FALSE);
LLRect dummy_rect(0, 1, 1, 0);
mFolders = new LLFolderView(std::string("task inventory"), NULL, dummy_rect, getTaskUUID(), this, LLTaskInvFVBridge::createObjectBridge(this, NULL));
mFolders = new LLFolderView(std::string("task inventory"), dummy_rect, getTaskUUID(), this, LLTaskInvFVBridge::createObjectBridge(this, NULL));
// this ensures that we never say "searching..." or "no items found"
mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
@@ -1681,9 +1681,9 @@ void LLPanelObjectInventory::updateInventory()
// We're still interested in this task's inventory.
std::set<LLUUID> selected_items;
BOOL inventory_has_focus = FALSE;
if (mHaveInventory && mFolders->getNumSelectedDescendants())
if (mHaveInventory)
{
mFolders->getSelectionList(selected_items);
selected_items = mFolders->getSelectionList();
inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders);
}
@@ -1737,7 +1737,7 @@ void LLPanelObjectInventory::updateInventory()
}
}
mFolders->arrangeFromRoot();
mFolders->requestArrange();
mInventoryNeedsUpdate = FALSE;
}
@@ -1760,6 +1760,7 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
LLFolderViewFolder* new_folder = NULL;
new_folder = new LLFolderViewFolder(inventory_root->getName(),
bridge->getIcon(),
bridge->getOpenIcon(),
NULL,
mFolders,
bridge);
@@ -1798,6 +1799,7 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
{
view = new LLFolderViewFolder(obj->getName(),
bridge->getIcon(),
bridge->getOpenIcon(),
NULL,
mFolders,
bridge);
@@ -1808,6 +1810,7 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
{
view = new LLFolderViewItem(obj->getName(),
bridge->getIcon(),
bridge->getOpenIcon(),
NULL,
bridge->getCreationDate(),
mFolders,
@@ -1975,3 +1978,22 @@ void LLPanelObjectInventory::idle(void* user_data)
self->updateInventory();
}
}
void LLPanelObjectInventory::onFocusLost()
{
// inventory no longer handles cut/copy/paste/delete
if (LLEditMenuHandler::gEditMenuHandler == mFolders)
{
LLEditMenuHandler::gEditMenuHandler = NULL;
}
LLPanel::onFocusLost();
}
void LLPanelObjectInventory::onFocusReceived()
{
// inventory now handles cut/copy/paste/delete
LLEditMenuHandler::gEditMenuHandler = mFolders;
LLPanel::onFocusReceived();
}

View File

@@ -61,7 +61,9 @@ public:
virtual void deleteAllChildren();
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 onFocusLost();
/*virtual*/ void onFocusReceived();
static void idle(void* user_data);
protected:

View File

@@ -66,7 +66,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry
mIconNameOpen(icon_name),
mIconNameClosed(icon_name),
*/
mIconNameOpen("inv_folder_plain_closed.tga"), mIconNameClosed("inv_folder_plain_closed.tga"),
mIconNameOpen("inv_folder_plain_open.tga"), mIconNameClosed("inv_folder_plain_closed.tga"),
mNewCategoryName(new_category_name),
mIsQuiet(FALSE),
mHideIfEmpty(false)
@@ -117,7 +117,7 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
addEntry(LLFolderType::FT_CLOTHING, new ViewerFolderEntry("Clothing", "inv_folder_clothing.tga", "inv_folder_clothing.tga", FALSE, false));
addEntry(LLFolderType::FT_OBJECT, new ViewerFolderEntry("Objects", "inv_folder_object.tga", "inv_folder_object.tga", FALSE, false));
addEntry(LLFolderType::FT_NOTECARD, new ViewerFolderEntry("Notecards", "inv_folder_notecard.tga", "inv_folder_notecard.tga", FALSE, false));
addEntry(LLFolderType::FT_ROOT_INVENTORY, new ViewerFolderEntry("My Inventory", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry(LLFolderType::FT_ROOT_INVENTORY, new ViewerFolderEntry("My Inventory", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry(LLFolderType::FT_LSL_TEXT, new ViewerFolderEntry("Scripts", "inv_folder_script.tga", "inv_folder_script.tga", FALSE, false));
addEntry(LLFolderType::FT_BODYPART, new ViewerFolderEntry("Body Parts", "inv_folder_bodypart.tga", "inv_folder_bodypart.tga", FALSE, false));
addEntry(LLFolderType::FT_TRASH, new ViewerFolderEntry("Trash", "inv_folder_trash.tga", "inv_folder_trash.tga", TRUE, false));
@@ -125,26 +125,26 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
addEntry(LLFolderType::FT_LOST_AND_FOUND, new ViewerFolderEntry("Lost And Found", "inv_folder_lostandfound.tga", "inv_folder_lostandfound.tga", TRUE, false));
addEntry(LLFolderType::FT_ANIMATION, new ViewerFolderEntry("Animations", "inv_folder_animation.tga", "inv_folder_animation.tga", FALSE, false));
addEntry(LLFolderType::FT_GESTURE, new ViewerFolderEntry("Gestures", "inv_folder_gesture.tga", "inv_folder_gesture.tga", FALSE, false));
addEntry(LLFolderType::FT_FAVORITE, new ViewerFolderEntry("Favorites", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry(LLFolderType::FT_FAVORITE, new ViewerFolderEntry("Favorites", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry(LLFolderType::FT_CURRENT_OUTFIT, new ViewerFolderEntry("Current Outfit", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", TRUE, false));
addEntry(LLFolderType::FT_OUTFIT, new ViewerFolderEntry("New Outfit", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", TRUE, false));
addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", TRUE, false));
addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry(LLFolderType::FT_CURRENT_OUTFIT, new ViewerFolderEntry("Current Outfit", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", TRUE, false));
addEntry(LLFolderType::FT_OUTFIT, new ViewerFolderEntry("New Outfit", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", TRUE, false));
addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", TRUE, false));
addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Outbox", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Outbox", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry(LLFolderType::FT_BASIC_ROOT, new ViewerFolderEntry("Basic Root", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry(LLFolderType::FT_BASIC_ROOT, new ViewerFolderEntry("Basic Root", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false, "default"));
addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, false, "default"));
#if SUPPORT_ENSEMBLES
initEnsemblesFromFile();
#else
for (U32 type = (U32)LLFolderType::FT_ENSEMBLE_START; type <= (U32)LLFolderType::FT_ENSEMBLE_END; ++type)
{
addEntry((LLFolderType::EType)type, new ViewerFolderEntry("New Folder", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
addEntry((LLFolderType::EType)type, new ViewerFolderEntry("New Folder", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, false));
}
#endif
}

View File

@@ -308,7 +308,7 @@ template<> bool SH_SpamHandler<std::string>::isAgent(const std::string &owner)
bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLMessageSystem* msg = gMessageSystem;
const LLSD& payload = notification["payload"];
switch(option)
@@ -730,7 +730,7 @@ void send_sound_trigger(const LLUUID& sound_id, F32 gain)
bool join_group_response(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
BOOL delete_context_data = TRUE;
bool accept_invite = false;
@@ -919,7 +919,7 @@ private:
mSelectedItems.clear();
if (LLInventoryPanel::getActiveInventoryPanel())
{
LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList(mSelectedItems);
mSelectedItems = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
}
mSelectedItems.erase(mMoveIntoFolderID);
}
@@ -954,8 +954,7 @@ private:
}
// get selected items (without destination folder)
selected_items_t selected_items;
active_panel->getRootFolder()->getSelectionList(selected_items);
selected_items_t selected_items = active_panel->getRootFolder()->getSelectionList();
selected_items.erase(mMoveIntoFolderID);
// compare stored & current sets of selected items