summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorSteve Bennetts <steve@lindenlab.com>2009-11-20 14:43:58 -0800
committerSteve Bennetts <steve@lindenlab.com>2009-11-20 14:43:58 -0800
commit0bdf520f4f399e1a368893db066d829b0ae3890e (patch)
treefeb30880a5573ac39b2f7b360fce3835dec50569 /indra
parent3bb86f91bc345f74057debe1f8f680098895a40e (diff)
parentc9101f603a7969f4d46a7d8d911fa8805d926548 (diff)
Merge from product-engine
Diffstat (limited to 'indra')
-rw-r--r--indra/llui/llcheckboxctrl.h1
-rw-r--r--indra/llui/llflatlistview.cpp241
-rw-r--r--indra/llui/llflatlistview.h25
-rw-r--r--indra/llui/llresizebar.cpp6
-rw-r--r--indra/newview/llbottomtray.cpp117
-rw-r--r--indra/newview/llbottomtray.h11
-rw-r--r--indra/newview/llchiclet.cpp105
-rw-r--r--indra/newview/llchiclet.h487
-rw-r--r--indra/newview/llfloatergesture.cpp313
-rw-r--r--indra/newview/llfloatergesture.h42
-rw-r--r--indra/newview/lllandmarkactions.cpp18
-rw-r--r--indra/newview/lllandmarkactions.h6
-rw-r--r--indra/newview/llnotificationofferhandler.cpp26
-rw-r--r--indra/newview/llpanellandmarkinfo.cpp2
-rw-r--r--indra/newview/llpanellandmarks.cpp198
-rw-r--r--indra/newview/llpanellandmarks.h13
-rw-r--r--indra/newview/llpanelpeople.cpp7
-rw-r--r--indra/newview/llparticipantlist.cpp3
-rw-r--r--indra/newview/llscreenchannel.cpp14
-rw-r--r--indra/newview/llspeakbutton.cpp21
-rw-r--r--indra/newview/llspeakbutton.h12
-rw-r--r--indra/newview/lltoastalertpanel.cpp104
-rw-r--r--indra/newview/llviewerinventory.cpp6
-rw-r--r--indra/newview/llviewerinventory.h1
-rw-r--r--indra/newview/llviewermessage.cpp7
-rw-r--r--indra/newview/skins/default/xui/en/alert_button.xml14
-rw-r--r--indra/newview/skins/default/xui/en/alert_check_box.xml7
-rw-r--r--indra/newview/skins/default/xui/en/alert_icon.xml8
-rw-r--r--indra/newview/skins/default/xui/en/alert_line_editor.xml11
-rw-r--r--indra/newview/skins/default/xui/en/floater_gesture.xml12
-rw-r--r--indra/newview/skins/default/xui/en/menu_gesture_gear.xml75
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml9
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml4
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/en/widgets/talk_button.xml3
35 files changed, 1354 insertions, 578 deletions
diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h
index 2f8e8fdd23..b14e66b915 100644
--- a/indra/llui/llcheckboxctrl.h
+++ b/indra/llui/llcheckboxctrl.h
@@ -107,6 +107,7 @@ public:
std::string getLabel() const;
void setFont( const LLFontGL* font ) { mFont = font; }
+ const LLFontGL* getFont() { return mFont; }
virtual void setControlName(const std::string& control_name, LLView* context);
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 19f203b80c..8de3a8a96f 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -94,6 +94,9 @@ bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null*
item->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
item->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, new_pair, _4));
+ // Children don't accept the focus
+ item->setTabStop(false);
+
rearrangeItems();
notifyParentItemsRectChanged();
return true;
@@ -282,6 +285,9 @@ void LLFlatListView::resetSelection(bool no_commit_on_deselection /*= false*/)
{
onCommit();
}
+
+ // Stretch selected items rect to ensure it won't be clipped
+ mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1));
}
void LLFlatListView::setNoItemsCommentText(const std::string& comment_text)
@@ -381,8 +387,34 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
//we don't need to stretch in vertical direction on reshaping by a parent
//no bottom following!
mItemsPanel->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP);
+
+ LLViewBorder::Params params;
+ params.name("scroll border");
+ params.rect(getSelectedItemsRect());
+ params.visible(false);
+ params.bevel_style(LLViewBorder::BEVEL_IN);
+ mSelectedItemsBorder = LLUICtrlFactory::create<LLViewBorder> (params);
+ mItemsPanel->addChild( mSelectedItemsBorder );
};
+// virtual
+void LLFlatListView::draw()
+{
+ // Highlight border if a child of this container has keyboard focus
+ if( mSelectedItemsBorder->getVisible() )
+ {
+ mSelectedItemsBorder->setKeyboardFocusHighlight( hasFocus() );
+ }
+ LLScrollContainer::draw();
+}
+
+// virtual
+BOOL LLFlatListView::postBuild()
+{
+ setTabStop(true);
+ return LLScrollContainer::postBuild();
+}
+
void LLFlatListView::rearrangeItems()
{
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
@@ -444,6 +476,9 @@ void LLFlatListView::rearrangeItems()
// move top for next item in list
item_new_top -= (rc.getHeight() + mItemPad);
}
+
+ // Stretch selected items rect to ensure it won't be clipped
+ mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1));
}
void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
@@ -473,6 +508,64 @@ void LLFlatListView::onItemRightMouseClick(item_pair_t* item_pair, MASK mask)
onItemMouseClick(item_pair, mask);
}
+BOOL LLFlatListView::handleKeyHere(KEY key, MASK mask)
+{
+ BOOL reset_selection = (mask != MASK_SHIFT);
+ BOOL handled = FALSE;
+ switch (key)
+ {
+ case KEY_RETURN:
+ {
+ if (mSelectedItemPairs.size() && mask == MASK_NONE)
+ {
+ mOnReturnSignal(this, getValue());
+ handled = TRUE;
+ }
+ break;
+ }
+ case KEY_UP:
+ {
+ if ( !selectNextItemPair(true, reset_selection) && reset_selection)
+ {
+ // If case we are in accordion tab notify parent to go to the previous accordion
+ notifyParent(LLSD().insert("action","select_prev"));
+ }
+ break;
+ }
+ case KEY_DOWN:
+ {
+ if ( !selectNextItemPair(false, reset_selection) && reset_selection)
+ {
+ // If case we are in accordion tab notify parent to go to the next accordion
+ notifyParent(LLSD().insert("action","select_next"));
+ }
+ break;
+ }
+ case 'A':
+ {
+ if(MASK_CONTROL & mask)
+ {
+ selectAll();
+ handled = TRUE;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if ( key == KEY_UP || key == KEY_DOWN )
+ {
+ LLRect selcted_rect = getLastSelectedItemRect().stretch(1);
+ LLRect visible_rect = getVisibleContentRect();
+ if ( !visible_rect.contains (selcted_rect) )
+ scrollToShowRect(selcted_rect);
+ handled = TRUE;
+ }
+
+ return handled ? handled : LLScrollContainer::handleKeyHere(key, mask);
+}
+
LLFlatListView::item_pair_t* LLFlatListView::getItemPair(LLPanel* item) const
{
llassert(item);
@@ -552,6 +645,143 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select)
onCommit();
}
+ setFocus(TRUE);
+
+ // Stretch selected items rect to ensure it won't be clipped
+ mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1));
+
+ return true;
+}
+
+LLRect LLFlatListView::getLastSelectedItemRect()
+{
+ if (!mSelectedItemPairs.size())
+ {
+ return LLRect::null;
+ }
+
+ return mSelectedItemPairs.back()->first->getRect();
+}
+
+LLRect LLFlatListView::getSelectedItemsRect()
+{
+ if (!mSelectedItemPairs.size())
+ {
+ return LLRect::null;
+ }
+ LLRect rc = getLastSelectedItemRect();
+ for ( pairs_const_iterator_t
+ it = mSelectedItemPairs.begin(),
+ it_end = mSelectedItemPairs.end();
+ it != it_end; ++it )
+ {
+ rc.unionWith((*it)->first->getRect());
+ }
+ return rc;
+}
+
+// virtual
+bool LLFlatListView::selectNextItemPair(bool is_up_direction, bool reset_selection)
+{
+ // No items - no actions!
+ if ( !mItemPairs.size() )
+ return false;
+
+ item_pair_t* cur_sel_pair = NULL;
+ item_pair_t* to_sel_pair = NULL;
+
+ if ( mSelectedItemPairs.size() )
+ {
+ // Take the last selected pair
+ cur_sel_pair = mSelectedItemPairs.back();
+ }
+ else
+ {
+ // If there weren't selected items then choose the first one bases on given direction
+ cur_sel_pair = (is_up_direction) ? mItemPairs.back() : mItemPairs.front();
+ // Force selection to first item
+ to_sel_pair = cur_sel_pair;
+ }
+
+ // Bases on given direction choose next item to select
+ if ( is_up_direction )
+ {
+ // Find current selected item position in mItemPairs list
+ pairs_list_t::reverse_iterator sel_it = std::find(mItemPairs.rbegin(), mItemPairs.rend(), cur_sel_pair);
+
+ for (;++sel_it != mItemPairs.rend();)
+ {
+ // skip invisible items
+ if ( (*sel_it)->first->getVisible() )
+ {
+ to_sel_pair = *sel_it;
+ break;
+ }
+ }
+ }
+ else
+ {
+ // Find current selected item position in mItemPairs list
+ pairs_list_t::iterator sel_it = std::find(mItemPairs.begin(), mItemPairs.end(), cur_sel_pair);
+
+ for (;++sel_it != mItemPairs.end();)
+ {
+ // skip invisible items
+ if ( (*sel_it)->first->getVisible() )
+ {
+ to_sel_pair = *sel_it;
+ break;
+ }
+ }
+ }
+
+ if ( to_sel_pair )
+ {
+ bool select = true;
+
+ if ( reset_selection )
+ {
+ // Reset current selection if we were asked about it
+ resetSelection();
+ }
+ else
+ {
+ // If item already selected and no reset request than we should deselect last selected item.
+ select = (mSelectedItemPairs.end() == std::find(mSelectedItemPairs.begin(), mSelectedItemPairs.end(), to_sel_pair));
+ }
+
+ // Select/Deselect next item
+ selectItemPair(select ? to_sel_pair : cur_sel_pair, select);
+
+ return true;
+ }
+ return false;
+}
+
+bool LLFlatListView::selectAll()
+{
+ if (!mAllowSelection)
+ return false;
+
+ mSelectedItemPairs.clear();
+
+ for (pairs_const_iterator_t it= mItemPairs.begin(); it != mItemPairs.end(); ++it)
+ {
+ item_pair_t* item_pair = *it;
+ mSelectedItemPairs.push_back(item_pair);
+ //a way of notifying panel of selection state changes
+ LLPanel* item = item_pair->first;
+ item->setValue(SELECTED_EVENT);
+ }
+
+ if (mCommitOnSelectionChange)
+ {
+ onCommit();
+ }
+
+ // Stretch selected items rect to ensure it won't be clipped
+ mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1));
+
return true;
}
@@ -670,4 +900,15 @@ void LLFlatListView::getValues(std::vector<LLSD>& values) const
}
}
+// virtual
+void LLFlatListView::onFocusReceived()
+{
+ mSelectedItemsBorder->setVisible(TRUE);
+}
+// virtual
+void LLFlatListView::onFocusLost()
+{
+ mSelectedItemsBorder->setVisible(FALSE);
+}
+
//EOF
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index 97772bc677..eac947a0d7 100644
--- a/indra/llui/llflatlistview.h
+++ b/indra/llui/llflatlistview.h
@@ -113,6 +113,10 @@ public:
virtual ~LLFlatListView() { clear(); };
+ /**
+ * Connects callback to signal called when Return key is pressed.
+ */
+ boost::signals2::connection setReturnCallback( const commit_signal_t::slot_type& cb ) { return mOnReturnSignal.connect(cb); }
/** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
@@ -318,6 +322,10 @@ protected:
virtual bool selectItemPair(item_pair_t* item_pair, bool select);
+ virtual bool selectNextItemPair(bool is_up_direction, bool reset_selection);
+
+ virtual bool selectAll();
+
virtual bool isSelected(item_pair_t* item_pair) const;
virtual bool removeItemPair(item_pair_t* item_pair);
@@ -331,6 +339,19 @@ protected:
*/
void notifyParentItemsRectChanged();
+ virtual BOOL handleKeyHere(KEY key, MASK mask);
+
+ virtual BOOL postBuild();
+
+ virtual void onFocusReceived();
+
+ virtual void onFocusLost();
+
+ virtual void draw();
+
+ LLRect getLastSelectedItemRect();
+
+ LLRect getSelectedItemsRect();
private:
@@ -381,6 +402,10 @@ private:
LLRect mPrevNotifyParentRect;
LLTextBox* mNoItemsCommentTextbox;
+
+ LLViewBorder* mSelectedItemsBorder;
+
+ commit_signal_t mOnReturnSignal;
};
#endif
diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp
index 304ac64f31..a7cf9be277 100644
--- a/indra/llui/llresizebar.cpp
+++ b/indra/llui/llresizebar.cpp
@@ -143,6 +143,12 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
if( valid_rect.localPointInRect( screen_x, screen_y ) && mResizingView )
{
+ // undock floater when user resize it
+ if (((LLFloater*)getParent())->isDocked())
+ {
+ ((LLFloater*)getParent())->setDocked(false, false);
+ }
+
// Resize the parent
LLRect orig_rect = mResizingView->getRect();
LLRect scaled_rect = orig_rect;
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 7985ccc2a1..c4f0fa53a7 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -48,6 +48,7 @@
LLBottomTray::LLBottomTray(const LLSD&)
: mChicletPanel(NULL),
mSysWell(NULL),
+ mSpeakPanel(NULL),
mSpeakBtn(NULL),
mNearbyChatBar(NULL),
mToolbarStack(NULL)
@@ -304,6 +305,7 @@ BOOL LLBottomTray::postBuild()
mSnapshotPanel = getChild<LLPanel>("snapshot_panel");
setRightMouseDownCallback(boost::bind(&LLBottomTray::showBottomTrayContextMenu,this, _2, _3,_4));
+ mSpeakPanel = getChild<LLPanel>("speak_panel");
mSpeakBtn = getChild<LLSpeakButton>("talk");
// Speak button should be initially disabled because
@@ -320,6 +322,7 @@ BOOL LLBottomTray::postBuild()
mObjectDefaultWidthMap[RS_BUTTON_GESTURES] = mGesturePanel->getRect().getWidth();
mObjectDefaultWidthMap[RS_BUTTON_MOVEMENT] = mMovementPanel->getRect().getWidth();
mObjectDefaultWidthMap[RS_BUTTON_CAMERA] = mCamPanel->getRect().getWidth();
+ mObjectDefaultWidthMap[RS_BUTTON_SPEAK] = mSpeakPanel->getRect().getWidth();
return TRUE;
}
@@ -476,7 +479,7 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
S32 buttons_freed_width = 0;
if (still_should_be_processed)
{
- processShrinkButtons(&delta_width);
+ processShrinkButtons(&delta_width, &buttons_freed_width);
if (delta_width < 0)
{
@@ -532,38 +535,43 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
const S32 available_width_chiclet = chiclet_panel_width - chiclet_panel_min_width;
// how many room we have to show hidden buttons
- S32 available_width = delta_width + chatbar_available_shrink_width + available_width_chiclet;
- S32 buttons_required_width = 0; //How many room will take shown buttons
+ S32 total_available_width = delta_width + chatbar_available_shrink_width + available_width_chiclet;
+ lldebugs << "Processing extending, available width:"
+ << ", chatbar - " << chatbar_available_shrink_width
+ << ", chiclets - " << available_width_chiclet
+ << ", total - " << total_available_width
+ << llendl;
+
+ S32 available_width = total_available_width;
if (available_width > 0)
{
- lldebugs << "Trying to process: RS_BUTTON_GESTURES" << llendl;
- processShowButton(RS_BUTTON_GESTURES, &available_width, &buttons_required_width);
+ processShowButton(RS_BUTTON_GESTURES, &available_width);
}
if (available_width > 0)
{
- lldebugs << "Trying to process: RS_BUTTON_MOVEMENT" << llendl;
- processShowButton(RS_BUTTON_MOVEMENT, &available_width, &buttons_required_width);
+ processShowButton(RS_BUTTON_MOVEMENT, &available_width);
}
if (available_width > 0)
{
- lldebugs << "Trying to process: RS_BUTTON_CAMERA" << llendl;
- processShowButton(RS_BUTTON_CAMERA, &available_width, &buttons_required_width);
+ processShowButton(RS_BUTTON_CAMERA, &available_width);
}
if (available_width > 0)
{
- lldebugs << "Trying to process: RS_BUTTON_SNAPSHOT" << llendl;
- processShowButton(RS_BUTTON_SNAPSHOT, &available_width, &buttons_required_width);
+ processShowButton(RS_BUTTON_SNAPSHOT, &available_width);
}
- // if we have to show some buttons but width increasing is not enough...
- if (buttons_required_width > 0 && delta_width < buttons_required_width)
+ processExtendButtons(&available_width);
+
+ // if we have to show/extend some buttons but resized delta width is not enough...
+ S32 processed_width = total_available_width - available_width;
+ if (processed_width > delta_width)
{
// ... let's shrink nearby chat & chiclet panels
- S32 required_to_process_width = buttons_required_width;
+ S32 required_to_process_width = processed_width;
// 1. use delta width of resizing
required_to_process_width -= delta_width;
@@ -593,9 +601,8 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
}
// shown buttons take some space, rest should be processed by nearby chatbar & chiclet panels
- delta_width -= buttons_required_width;
+ delta_width -= processed_width;
- processExtendButtons(&delta_width);
// how many space can nearby chatbar take?
S32 chatbar_panel_width_ = mNearbyChatBar->getRect().getWidth();
@@ -603,13 +610,21 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
{
S32 delta_panel_max = chatbar_panel_max_width - chatbar_panel_width_;
S32 delta_panel = llmin(delta_width, delta_panel_max);
+ lldebugs << "Unprocesed delta width: " << delta_width
+ << ", can be applied to chatbar: " << delta_panel_max
+ << ", will be applied: " << delta_panel
+ << llendl;
+
delta_width -= delta_panel_max;
mNearbyChatBar->reshape(chatbar_panel_width_ + delta_panel, mNearbyChatBar->getRect().getHeight());
+ log(mNearbyChatBar, "applied unprocessed delta width");
}
}
-bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* available_width, S32* buttons_required_width)
+bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* available_width)
{
+ lldebugs << "Trying to show object type: " << shown_object_type << llendl;
+
LLPanel* panel = mStateProcessedObjectMap[shown_object_type];
if (NULL == panel)
{
@@ -625,12 +640,11 @@ bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* availa
if (can_be_shown)
{
*available_width -= required_width;
- *buttons_required_width += required_width;
setTrayButtonVisible(shown_object_type, true);
- lldebugs << "processing object type: " << shown_object_type
- << ", buttons_required_width: " << *buttons_required_width
+ lldebugs << "processed object type: " << shown_object_type
+ << ", rest available width: " << *available_width
<< llendl;
mResizeState &= ~shown_object_type;
}
@@ -640,6 +654,8 @@ bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* availa
void LLBottomTray::processHideButton(EResizeState processed_object_type, S32* required_width, S32* buttons_freed_width)
{
+ lldebugs << "Trying to hide object type: " << processed_object_type << llendl;
+
LLPanel* panel = mStateProcessedObjectMap[processed_object_type];
if (NULL == panel)
{
@@ -666,7 +682,7 @@ void LLBottomTray::processHideButton(EResizeState processed_object_type, S32* re
}
}
-void LLBottomTray::processShrinkButtons(S32* required_width)
+void LLBottomTray::processShrinkButtons(S32* required_width, S32* buttons_freed_width)
{
processShrinkButton(RS_BUTTON_CAMERA, required_width);
@@ -678,9 +694,44 @@ void LLBottomTray::processShrinkButtons(S32* required_width)
{
processShrinkButton(RS_BUTTON_GESTURES, required_width);
}
+ if (*required_width < 0)
+ {
+
+ S32 panel_min_width = 0;
+ std::string panel_name = mSpeakPanel->getName();
+ bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width, NULL);
+ if (!success)
+ {
+ lldebugs << "Panel was not found to get its min width: " << panel_name << llendl;
+ }
+ else
+ {
+ //
+ mSpeakBtn->setLabelVisible(false);
+ S32 panel_width = mSpeakPanel->getRect().getWidth();
+ S32 possible_shrink_width = panel_width - panel_min_width;
+
+ if (possible_shrink_width > 0)
+ {
+ mSpeakPanel->reshape(panel_width - possible_shrink_width, mSpeakPanel->getRect().getHeight());
+
+ *required_width += possible_shrink_width;
+
+ if (*required_width > 0)
+ {
+ *buttons_freed_width += *required_width;
+ }
+
+ lldebugs << "Shrunk panel: " << panel_name
+ << ", shrunk width: " << possible_shrink_width
+ << ", rest width to process: " << *required_width
+ << llendl;
+ }
+ }
+ }
}
-void LLBottomTray::processShrinkButton(EResizeState processed_object_type, /*const std::string& panel_name, */S32* required_width)
+void LLBottomTray::processShrinkButton(EResizeState processed_object_type, S32* required_width)
{
LLPanel* panel = mStateProcessedObjectMap[processed_object_type];
if (NULL == panel)
@@ -729,6 +780,9 @@ void LLBottomTray::processShrinkButton(EResizeState processed_object_type, /*con
void LLBottomTray::processExtendButtons(S32* available_width)
{
+ // do not allow extending any buttons if we have some buttons hidden
+ if (mResizeState & RS_BUTTONS_CAN_BE_HIDDEN) return;
+
processExtendButton(RS_BUTTON_GESTURES, available_width);
if (*available_width > 0)
@@ -739,6 +793,25 @@ void LLBottomTray::processExtendButtons(S32* available_width)
{
processExtendButton(RS_BUTTON_MOVEMENT, available_width);
}
+ if (*available_width > 0)
+ {
+ S32 panel_max_width = mObjectDefaultWidthMap[RS_BUTTON_SPEAK];
+ S32 panel_width = mSpeakPanel->getRect().getWidth();
+ S32 possible_extend_width = panel_max_width - panel_width;
+ if (possible_extend_width > 0 && possible_extend_width <= *available_width)
+ {
+ mSpeakBtn->setLabelVisible(true);
+ mSpeakPanel->reshape(panel_max_width, mSpeakPanel->getRect().getHeight());
+ log(mSpeakBtn, "speak button is extended");
+
+ *available_width -= possible_extend_width;
+
+ lldebugs << "Extending panel: " << mSpeakPanel->getName()
+ << ", extended width: " << possible_extend_width
+ << ", rest width to process: " << *available_width
+ << llendl;
+ }
+ }
}
void LLBottomTray::processExtendButton(EResizeState processed_object_type, S32* available_width)
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 97bcc23403..7640cdcf9d 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -98,12 +98,18 @@ private:
, RS_BUTTON_MOVEMENT = 0x0010
, RS_BUTTON_GESTURES = 0x0020
, RS_BUTTON_SPEAK = 0x0040
+
+ /**
+ * Specifies buttons which can be hidden when bottom tray is shrunk.
+ * They are: Gestures, Movement (Move), Camera (View), Snapshot
+ */
+ , RS_BUTTONS_CAN_BE_HIDDEN = RS_BUTTON_SNAPSHOT | RS_BUTTON_CAMERA | RS_BUTTON_MOVEMENT | RS_BUTTON_GESTURES
}EResizeState;
S32 processWidthDecreased(S32 delta_width);
void processWidthIncreased(S32 delta_width);
void log(LLView* panel, const std::string& descr);
- bool processShowButton(EResizeState shown_object_type, S32* available_width, S32* buttons_required_width);
+ bool processShowButton(EResizeState shown_object_type, S32* available_width);
void processHideButton(EResizeState processed_object_type, S32* required_width, S32* buttons_freed_width);
/**
@@ -112,7 +118,7 @@ private:
* @param - required_width - width which buttons can use to be shrunk. It is a negative value.
* It is increased on the value processed by buttons.
*/
- void processShrinkButtons(S32* required_width);
+ void processShrinkButtons(S32* required_width, S32* buttons_freed_width);
void processShrinkButton(EResizeState processed_object_type, S32* required_width);
/**
@@ -175,6 +181,7 @@ protected:
LLChicletPanel* mChicletPanel;
LLNotificationChiclet* mSysWell;
+ LLPanel* mSpeakPanel;
LLSpeakButton* mSpeakBtn;
LLNearbyChatBar* mNearbyChatBar;
LLLayoutStack* mToolbarStack;
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 9845664c74..6a5877f673 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -1,34 +1,34 @@
/**
-* @file llchiclet.cpp
-* @brief LLChiclet class implementation
-*
-* $LicenseInfo:firstyear=2002&license=viewergpl$
-*
-* Copyright (c) 2002-2009, Linden Research, Inc.
-*
-* Second Life Viewer Source Code
-* The source code in this file ("Source Code") is provided by Linden Lab
-* to you under the terms of the GNU General Public License, version 2.0
-* ("GPL"), unless you have obtained a separate licensing agreement
-* ("Other License"), formally executed by you and Linden Lab. Terms of
-* the GPL can be found in doc/GPL-license.txt in this distribution, or
-* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
-*
-* There are special exceptions to the terms and conditions of the GPL as
-* it is applied to this Source Code. View the full text of the exception
-* in the file doc/FLOSS-exception.txt in this software distribution, or
-* online at
-* http://secondlifegrid.net/programs/open_source/licensing/flossexception
-*
-* By copying, modifying or distributing this software, you acknowledge
-* that you have read and understood your obligations described above,
-* and agree to abide by those obligations.
-*
-* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
-* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
-* COMPLETENESS OR PERFORMANCE.
-* $/LicenseInfo$
-*/
+ * @file llchiclet.cpp
+ * @brief LLChiclet class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
#include "llviewerprecompiledheaders.h" // must be first include
#include "llchiclet.h"
@@ -922,34 +922,45 @@ void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id)
s_previous_active_voice_session_id = session_id;
}
-S32 LLChicletPanel::calcChickletPanleWidth()
-{
- S32 res = 0;
-
- for (chiclet_list_t::iterator it = mChicletList.begin(); it
- != mChicletList.end(); it++)
- {
- res = (*it)->getRect().getWidth() + getChicletPadding();
- }
- return res;
-}
-
bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)
{
if(mScrollArea->addChild(chiclet))
{
- // chicklets should be aligned to right edge of scroll panel
- S32 offset = 0;
+ // chiclets should be aligned to right edge of scroll panel
+ S32 left_shift = 0;
if (!canScrollLeft())
{
- offset = mScrollArea->getRect().getWidth()
- - chiclet->getRect().getWidth() - calcChickletPanleWidth();
+ // init left shift for the first chiclet in the list...
+ if (mChicletList.empty())
+ {
+ // ...start from the right border of the scroll area for the first added chiclet
+ left_shift = mScrollArea->getRect().getWidth();
+ }
+ else
+ {
+ // ... start from the left border of the first chiclet minus padding
+ left_shift = getChiclet(0)->getRect().mLeft - getChicletPadding();
+ }
+
+ // take into account width of the being added chiclet
+ left_shift -= chiclet->getRequiredRect().getWidth();
+
+ // if we overflow the scroll area we do not need to shift chiclets
+ if (left_shift < 0)
+ {
+ left_shift = 0;
+ }
}
mChicletList.insert(mChicletList.begin() + index, chiclet);
- getChiclet(0)->translate(offset, 0);
+ // shift first chiclet to place it in correct position.
+ // rest ones will be placed in arrange()
+ if (!canScrollLeft())
+ {
+ getChiclet(0)->translate(left_shift - getChiclet(0)->getRect().mLeft, 0);
+ }
chiclet->setLeftButtonClickCallback(boost::bind(&LLChicletPanel::onChicletClick, this, _1, _2));
chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index));
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index bb5dc1e550..03935d21a6 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -1,34 +1,34 @@
/**
-* @file llchiclet.h
-* @brief LLChiclet class header file
-*
-* $LicenseInfo:firstyear=2002&license=viewergpl$
-*
-* Copyright (c) 2002-2009, Linden Research, Inc.
-*
-* Second Life Viewer Source Code
-* The source code in this file ("Source Code") is provided by Linden Lab
-* to you under the terms of the GNU General Public License, version 2.0
-* ("GPL"), unless you have obtained a separate licensing agreement
-* ("Other License"), formally executed by you and Linden Lab. Terms of
-* the GPL can be found in doc/GPL-license.txt in this distribution, or
-* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
-*
-* There are special exceptions to the terms and conditions of the GPL as
-* it is applied to this Source Code. View the full text of the exception
-* in the file doc/FLOSS-exception.txt in this software distribution, or
-* online at
-* http://secondlifegrid.net/programs/open_source/licensing/flossexception
-*
-* By copying, modifying or distributing this software, you acknowledge
-* that you have read and understood your obligations described above,
-* and agree to abide by those obligations.
-*
-* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
-* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
-* COMPLETENESS OR PERFORMANCE.
-* $/LicenseInfo$
-*/
+ * @file llchiclet.h
+ * @brief LLChiclet class header file
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
#ifndef LL_LLCHICLET_H
#define LL_LLCHICLET_H
@@ -44,9 +44,9 @@ class LLVoiceControlPanel;
class LLMenuGL;
class LLIMFloater;
-/*
+/**
* Class for displaying amount of messages/notifications(unread).
-*/
+ */
class LLChicletNotificationCounterCtrl : public LLTextBox
{
public:
@@ -57,30 +57,30 @@ public:
{};
};
- /*
+ /**
* Sets number of notifications
- */
+ */
virtual void setCounter(S32 counter);
- /*
+ /**
* Returns number of notifications
- */
+ */
virtual S32 getCounter() const { return mCounter; }
- /*
+ /**
* Returns width, required to display amount of notifications in text form.
* Width is the only valid value.
- */
+ */
/*virtual*/ LLRect getRequiredRect();
- /*
+ /**
* Sets number of notifications using LLSD
- */
+ */
/*virtual*/ void setValue(const LLSD& value);
- /*
+ /**
* Returns number of notifications wrapped in LLSD
- */
+ */
/*virtual*/ LLSD getValue() const;
protected:
@@ -94,9 +94,9 @@ private:
S32 mInitialWidth;
};
-/*
+/**
* Class for displaying avatar's icon in P2P chiclet.
-*/
+ */
class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl
{
public:
@@ -147,9 +147,9 @@ protected:
std::string mDefaultIcon;
};
-/*
+/**
* Class for displaying of speaker's voice indicator
-*/
+ */
class LLChicletSpeakerCtrl : public LLOutputMonitorCtrl
{
public:
@@ -164,7 +164,7 @@ protected:
friend class LLUICtrlFactory;
};
-/*
+/**
* Base class for all chiclets.
*/
class LLChiclet : public LLUICtrl
@@ -180,59 +180,59 @@ public:
/*virtual*/ ~LLChiclet();
- /*
+ /**
* Associates chat session id with chiclet.
- */
+ */
virtual void setSessionId(const LLUUID& session_id) { mSessionId = session_id; }
- /*
+ /**
* Returns associated chat session.
- */
+ */
virtual const LLUUID& getSessionId() const { return mSessionId; }
- /*
+ /**
* Sets number of unread notifications.
- */
+ */
virtual void setCounter(S32 counter) = 0;
- /*
+ /**
* Returns number of unread notifications.
- */
+ */
virtual S32 getCounter() = 0;
- /*
+ /**
* Sets show counter state.
- */
+ */
virtual void setShowCounter(bool show) { mShowCounter = show; }
- /*
+ /**
* Returns show counter state.
- */
+ */
virtual bool getShowCounter() {return mShowCounter;};
- /*
+ /**
* Connects chiclet clicked event with callback.
- */
+ */
/*virtual*/ boost::signals2::connection setLeftButtonClickCallback(
const commit_callback_t& cb);
typedef boost::function<void (LLChiclet* ctrl, const LLSD& param)>
chiclet_size_changed_callback_t;
- /*
+ /**
* Connects chiclets size changed event with callback.
- */
+ */
virtual boost::signals2::connection setChicletSizeChangedCallback(
const chiclet_size_changed_callback_t& cb);
- /*
+ /**
* Sets IM Session id using LLSD
- */
+ */
/*virtual*/ LLSD getValue() const;
- /*
+ /**
* Returns IM Session id using LLSD
- */
+ */
/*virtual*/ void setValue(const LLSD& value);
protected:
@@ -240,14 +240,14 @@ protected:
friend class LLUICtrlFactory;
LLChiclet(const Params& p);
- /*
+ /**
* Notifies subscribers about click on chiclet.
- */
+ */
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- /*
+ /**
* Notifies subscribers about chiclet size changed event.
- */
+ */
virtual void onChicletSizeChanged();
private:
@@ -263,11 +263,11 @@ private:
};
-/*
-* Base class for Instant Message chiclets.
-* IMChiclet displays icon, number of unread messages(optional)
-* and voice chat status(optional).
-*/
+/**
+ * Base class for Instant Message chiclets.
+ * IMChiclet displays icon, number of unread messages(optional)
+ * and voice chat status(optional).
+ */
class LLIMChiclet : public LLChiclet
{
public:
@@ -288,50 +288,50 @@ public:
/*virtual*/ ~LLIMChiclet() {};
- /*
+ /**
* Sets IM session name. This name will be displayed in chiclet tooltip.
- */
+ */
virtual void setIMSessionName(const std::string& name) { setToolTip(name); }
- /*
+ /**
* Sets id of person/group user is chatting with.
* Session id should be set before calling this
- */
+ */
virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; }
- /*
+ /**
* Gets id of person/group user is chatting with.
*/
virtual LLUUID getOtherParticipantId() { return mOtherParticipantId; }
- /*
- * Init Speaker Control with speaker's ID
- */
+ /**
+ * Init Speaker Control with speaker's ID
+ */
virtual void initSpeakerControl();
- /*
+ /**
* set status (Shows/Hide) for voice control.
- */
+ */
virtual void setShowSpeaker(bool show);
- /*
+ /**
* Returns voice chat status control visibility.
- */
+ */
virtual bool getShowSpeaker() {return mShowSpeaker;};
- /*
- * Shows/Hides for voice control for a chiclet.
- */
+ /**
+ * Shows/Hides for voice control for a chiclet.
+ */
virtual void toggleSpeakerControl();
- /*
- * Shows/hides overlay icon concerning new unread messages.
- */
+ /**
+ * Shows/hides overlay icon concerning new unread messages.
+ */
virtual void setShowNewMessagesIcon(bool show);
- /*
- * Returns visibility of overlay icon concerning new unread messages.
- */
+ /**
+ * Returns visibility of overlay icon concerning new unread messages.
+ */
virtual bool getShowNewMessagesIcon();
virtual void draw();
@@ -418,45 +418,45 @@ public:
/* virtual */ void setOtherParticipantId(const LLUUID& other_participant_id);
- /*
- * Sets number of unread messages. Will update chiclet's width if number text
- * exceeds size of counter and notify it's parent about size change.
- */
+ /**
+ * Sets number of unread messages. Will update chiclet's width if number text
+ * exceeds size of counter and notify it's parent about size change.
+ */
/*virtual*/ void setCounter(S32);
- /*
- * Init Speaker Control with speaker's ID
- */
+ /**
+ * Init Speaker Control with speaker's ID
+ */
/*virtual*/ void initSpeakerControl();
- /*
- * Returns number of unread messages.
- */
+ /**
+ * Returns number of unread messages.
+ */
/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
protected:
LLIMP2PChiclet(const Params& p);
friend class LLUICtrlFactory;
- /*
- * Creates chiclet popup menu. Will create P2P or Group IM Chat menu
- * based on other participant's id.
- */
+ /**
+ * Creates chiclet popup menu. Will create P2P or Group IM Chat menu
+ * based on other participant's id.
+ */
virtual void createPopupMenu();
- /*
- * Processes clicks on chiclet popup menu.
- */
+ /**
+ * Processes clicks on chiclet popup menu.
+ */
virtual void onMenuItemClicked(const LLSD& user_data);
- /*
- * Displays popup menu.
- */
+ /**
+ * Displays popup menu.
+ */
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
- /*
- * Enables/disables menus based on relationship with other participant.
- */
+ /**
+ * Enables/disables menus based on relationship with other participant.
+ */
virtual void updateMenuItems();
private:
@@ -492,39 +492,39 @@ public:
*/
/*virtual*/ void setSessionId(const LLUUID& session_id);
- /*
- * Sets number of unread messages. Will update chiclet's width if number text
- * exceeds size of counter and notify it's parent about size change.
- */
+ /**
+ * Sets number of unread messages. Will update chiclet's width if number text
+ * exceeds size of counter and notify it's parent about size change.
+ */
/*virtual*/ void setCounter(S32);
- /*
- * Keep Speaker Control with actual speaker's ID
- */
+ /**
+ * Keep Speaker Control with actual speaker's ID
+ */
/*virtual*/ void draw();
- /*
- * Init Speaker Control with speaker's ID
- */
+ /**
+ * Init Speaker Control with speaker's ID
+ */
/*virtual*/ void initSpeakerControl();
- /*
- * Returns number of unread messages.
- */
+ /**
+ * Returns number of unread messages.
+ */
/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
protected:
LLAdHocChiclet(const Params& p);
friend class LLUICtrlFactory;
- /*
- * Displays popup menu.
- */
+ /**
+ * Displays popup menu.
+ */
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
- /*
- * Finds a current speaker and resets the SpeakerControl with speaker's ID
- */
+ /**
+ * Finds a current speaker and resets the SpeakerControl with speaker's ID
+ */
/*virtual*/ void switchToCurrentSpeaker();
private:
@@ -559,9 +559,9 @@ public:
*/
/*virtual*/ void setSessionId(const LLUUID& session_id);
- /*
- * Keep Speaker Control with actual speaker's ID
- */
+ /**
+ * Keep Speaker Control with actual speaker's ID
+ */
/*virtual*/ void draw();
/**
@@ -570,20 +570,20 @@ public:
*/
/*virtual*/ void changed(LLGroupChange gc);
- /*
- * Sets number of unread messages. Will update chiclet's width if number text
- * exceeds size of counter and notify it's parent about size change.
- */
+ /**
+ * Sets number of unread messages. Will update chiclet's width if number text
+ * exceeds size of counter and notify it's parent about size change.
+ */
/*virtual*/ void setCounter(S32);
- /*
- * Init Speaker Control with speaker's ID
- */
+ /**
+ * Init Speaker Control with speaker's ID
+ */
/*virtual*/ void initSpeakerControl();
- /*
- * Returns number of unread messages.
- */
+ /**
+ * Returns number of unread messages.
+ */
/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
~LLIMGroupChiclet();
@@ -592,25 +592,25 @@ protected:
LLIMGroupChiclet(const Params& p);
friend class LLUICtrlFactory;
- /*
- * Finds a current speaker and resets the SpeakerControl with speaker's ID
- */
+ /**
+ * Finds a current speaker and resets the SpeakerControl with speaker's ID
+ */
/*virtual*/ void switchToCurrentSpeaker();
- /*
- * Creates chiclet popup menu. Will create P2P or Group IM Chat menu
- * based on other participant's id.
- */
+ /**
+ * Creates chiclet popup menu. Will create P2P or Group IM Chat menu
+ * based on other participant's id.
+ */
virtual void createPopupMenu();
- /*
- * Processes clicks on chiclet popup menu.
- */
+ /**
+ * Processes clicks on chiclet popup menu.
+ */
virtual void onMenuItemClicked(const LLSD& user_data);
- /*
- * Displays popup menu.
- */
+ /**
+ * Displays popup menu.
+ */
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
private:
@@ -619,10 +619,10 @@ private:
LLMenuGL* mPopupMenu;
};
-/*
+/**
* Implements notification chiclet. Used to display total amount of unread messages
* across all IM sessions, total amount of system notifications.
-*/
+ */
class LLNotificationChiclet : public LLChiclet
{
public:
@@ -666,10 +666,10 @@ protected:
S32 mCounter;
};
-/*
+/**
* Storage class for all IM chiclets. Provides mechanism to display,
* scroll, create, remove chiclets.
-*/
+ */
class LLChicletPanel : public LLPanel
{
public:
@@ -686,62 +686,62 @@ public:
virtual ~LLChicletPanel();
- /*
+ /**
* Creates chiclet and adds it to chiclet list at specified index.
- */
+ */
template<class T> T* createChiclet(const LLUUID& session_id, S32 index);
- /*
+ /**
* Creates chiclet and adds it to chiclet list at right.
- */
+ */
template<class T> T* createChiclet(const LLUUID& session_id);
- /*
+ /**
* Returns pointer to chiclet of specified type at specified index.
- */
+ */
template<class T> T* getChiclet(S32 index);
- /*
+ /**
* Returns pointer to LLChiclet at specified index.
- */
+ */
LLChiclet* getChiclet(S32 index) { return getChiclet<LLChiclet>(index); }
- /*
+ /**
* Searches a chiclet using IM session id.
- */
+ */
template<class T> T* findChiclet(const LLUUID& im_session_id);
- /*
+ /**
* Returns number of hosted chiclets.
- */
+ */
S32 getChicletCount() {return mChicletList.size();};
- /*
+ /**
* Returns index of chiclet in list.
- */
+ */
S32 getChicletIndex(const LLChiclet* chiclet);
- /*
+ /**
* Removes chiclet by index.
- */
+ */
void removeChiclet(S32 index);
- /*
+ /**
* Removes chiclet by pointer.
- */
+ */
void removeChiclet(LLChiclet* chiclet);
- /*
+ /**
* Removes chiclet by IM session id.
- */
+ */
void removeChiclet(const LLUUID& im_session_id);
- /*
+ /**
* Removes all chiclets.
- */
+ */
void removeAll();
- /*
+ /**
* Scrolls the panel to the specified chiclet
*/
void scrollToChiclet(const LLChiclet* chiclet);
@@ -751,14 +751,14 @@ public:
/*virtual*/ BOOL postBuild();
- /*
- * Handler for the Voice Client's signal. Finds a corresponding chiclet and toggles its SpeakerControl
- */
+ /**
+ * Handler for the Voice Client's signal. Finds a corresponding chiclet and toggles its SpeakerControl
+ */
void onCurrentVoiceChannelChanged(const LLUUID& session_id);
- /*
+ /**
* Reshapes controls and rearranges chiclets if needed.
- */
+ */
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE );
/*virtual*/ void draw();
@@ -769,100 +769,107 @@ protected:
LLChicletPanel(const Params&p);
friend class LLUICtrlFactory;
- S32 calcChickletPanleWidth();
-
- /*
- * Adds chiclet to list and rearranges all chiclets.
- */
+ /**
+ * Adds chiclet to list and rearranges all chiclets.
+ * They should be right aligned, most recent right. See EXT-1293
+ *
+ * It calculates position of the first chiclet in the list. Other chiclets are placed in arrange().
+ *
+ * @see arrange()
+ */
bool addChiclet(LLChiclet*, S32 index);
- /*
- * Arranges chiclets.
- */
+ /**
+ * Arranges chiclets to have them in correct positions.
+ *
+ * Method bases on assumption that first chiclet has correct rect and starts from the its position.
+ *
+ * @see addChiclet()
+ */
void arrange();
- /*
+ /**
* Returns true if chiclets can be scrolled right.
- */
+ */
bool canScrollRight();
- /*
- * Returns true if chiclets can be scrolled left.
- */
+ /**
+ * Returns true if chiclets can be scrolled left.
+ */
bool canScrollLeft();
- /*
- * Shows or hides chiclet scroll buttons if chiclets can or can not be scrolled.
- */
+ /**
+ * Shows or hides chiclet scroll buttons if chiclets can or can not be scrolled.
+ */
void showScrollButtonsIfNeeded();
- /*
+ /**
* Shifts chiclets left or right.
- */
+ */
void shiftChiclets(S32 offset, S32 start_index = 0);
- /*
+ /**
* Removes gaps between first chiclet and scroll area left side,
* last chiclet and scroll area right side.
- */
+ */
void trimChiclets();
- /*
+ /**
* Scrolls chiclets to right or left.
- */
+ */
void scroll(S32 offset);
- /*
+ /**
* Verifies that chiclets can be scrolled left, then calls scroll()
- */
+ */
void scrollLeft();
- /*
+ /**
* Verifies that chiclets can be scrolled right, then calls scroll()
- */
+ */
void scrollRight();
- /*
+ /**
* Callback for left scroll button clicked
- */
+ */
void onLeftScrollClick();
- /*
- * Callback for right scroll button clicked
- */
+ /**
+ * Callback for right scroll button clicked
+ */
void onRightScrollClick();
- /*
- * Callback for right scroll button held down event
- */
+ /**
+ * Callback for right scroll button held down event
+ */
void onLeftScrollHeldDown();
- /*
+ /**
* Callback for left scroll button held down event
*/
void onRightScrollHeldDown();
- /*
+ /**
* Callback for mouse wheel scrolled, calls scrollRight() or scrollLeft()
- */
+ */
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
- /*
+ /**
* Notifies subscribers about click on chiclet.
* Do not place any code here, instead subscribe on event (see setChicletClickedCallback).
- */
+ */
void onChicletClick(LLUICtrl*ctrl,const LLSD&param);
- /*
+ /**
* Callback for chiclet size changed event, rearranges chiclets.
- */
+ */
void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param);
typedef std::vector<LLChiclet*> chiclet_list_t;
- /*
+ /**
* Removes chiclet from scroll area and chiclet list.
- */
+ */
void removeChiclet(chiclet_list_t::iterator it);
S32 getChicletPadding() { return mChicletPadding; }
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index af86274472..0f8e4c10d7 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -34,32 +34,24 @@
#include "llfloatergesture.h"
-#include "lldir.h"
#include "llinventory.h"
-#include "llmultigesture.h"
+#include "llinventorybridge.h"
+#include "llinventorymodel.h"
+#include "llinventoryclipboard.h"
#include "llagent.h"
-#include "llviewerwindow.h"
-#include "llbutton.h"
-#include "llcombobox.h"
+#include "llappearancemgr.h"
+#include "llclipboard.h"
#include "llgesturemgr.h"
-#include "llinventorymodel.h"
-#include "llinventorypanel.h"
-#include "llfloaterinventory.h"
#include "llkeyboard.h"
-#include "lllineeditor.h"
+#include "llmenugl.h"
+#include "llmultigesture.h"
#include "llpreviewgesture.h"
-#include "llresizehandle.h"
-#include "llscrollbar.h"
-#include "llscrollcontainer.h"
#include "llscrolllistctrl.h"
-#include "lltextbox.h"
#include "lltrans.h"
-#include "lluictrlfactory.h"
#include "llviewergesture.h"
-#include "llviewertexturelist.h"
+#include "llviewermenu.h"
#include "llviewerinventory.h"
-#include "llvoavatar.h"
#include "llviewercontrol.h"
BOOL item_name_precedes( LLInventoryItem* a, LLInventoryItem* b )
@@ -77,6 +69,35 @@ public:
private:
LLFloaterGesture* mFloater;
};
+//-----------------------------
+// GestureCallback
+//-----------------------------
+
+class GestureShowCallback : public LLInventoryCallback
+{
+public:
+ void fire(const LLUUID &inv_item)
+ {
+ LLPreviewGesture::show(inv_item, LLUUID::null);
+ }
+};
+
+class GestureCopiedCallback : public LLInventoryCallback
+{
+private:
+ LLFloaterGesture* mFloater;
+
+public:
+ GestureCopiedCallback(LLFloaterGesture* floater): mFloater(floater)
+ {}
+ void fire(const LLUUID &inv_item)
+ {
+ if(mFloater)
+ {
+ mFloater->addGesture(inv_item,NULL,mFloater->getChild<LLScrollListCtrl>("gesture_list"));
+ }
+ }
+};
//---------------------------------------------------------------------------
// LLFloaterGesture
@@ -86,7 +107,13 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)
{
mObserver = new LLFloaterGestureObserver(this);
LLGestureManager::instance().addObserver(mObserver);
- //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_gesture.xml");
+
+ mCommitCallbackRegistrar.add("Gesture.Action.ToogleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
+ mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this));
+ mCommitCallbackRegistrar.add("Gesture.Action.CopyPast", boost::bind(&LLFloaterGesture::onCopyPastAction, this, _2));
+ mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this));
+
+ mEnableCallbackRegistrar.add("Gesture.EnableAction", boost::bind(&LLFloaterGesture::isActionEnabled, this, _2));
}
void LLFloaterGesture::done()
@@ -151,19 +178,18 @@ BOOL LLFloaterGesture::postBuild()
label = getTitle();
setTitle(label);
-
- getChild<LLUICtrl>("gesture_list")->setCommitCallback(boost::bind(&LLFloaterGesture::onCommitList, this));
- getChild<LLScrollListCtrl>("gesture_list")->setDoubleClickCallback(boost::bind(&LLFloaterGesture::onClickPlay, this));
-
- getChild<LLUICtrl>("inventory_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickInventory, this));
+ mGestureList = getChild<LLScrollListCtrl>("gesture_list");
+ mGestureList->setCommitCallback(boost::bind(&LLFloaterGesture::onCommitList, this));
+ mGestureList->setDoubleClickCallback(boost::bind(&LLFloaterGesture::onClickPlay, this));
getChild<LLUICtrl>("edit_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickEdit, this));
getChild<LLUICtrl>("play_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickPlay, this));
getChild<LLUICtrl>("stop_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickPlay, this));
getChild<LLButton>("activate_btn")->setClickedCallback(boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
-
+
getChild<LLUICtrl>("new_gesture_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickNew, this));
+ getChild<LLButton>("del_btn")->setClickedCallback(boost::bind(&LLFloaterGesture::onDeleteSelected, this));
childSetVisible("play_btn", true);
childSetVisible("stop_btn", false);
@@ -178,14 +204,13 @@ BOOL LLFloaterGesture::postBuild()
buildGestureList();
- childSetFocus("gesture_list");
+ mGestureList->setFocus(TRUE);
- LLCtrlListInterface *list = getGestureList();
- if (list)
+ if (mGestureList)
{
const BOOL ascending = TRUE;
- list->sortByColumn(std::string("name"), ascending);
- list->selectFirstItem();
+ mGestureList->sortByColumn(std::string("name"), ascending);
+ mGestureList->selectFirstItem();
}
// Update button labels
@@ -199,18 +224,17 @@ void LLFloaterGesture::refreshAll()
{
buildGestureList();
- LLCtrlListInterface *list = getGestureList();
- if (!list) return;
+ if (!mGestureList) return;
if (mSelectedID.isNull())
{
- list->selectFirstItem();
+ mGestureList->selectFirstItem();
}
else
{
- if (! list->setCurrentByID(mSelectedID))
+ if (! mGestureList->setCurrentByID(mSelectedID))
{
- list->selectFirstItem();
+ mGestureList->selectFirstItem();
}
}
@@ -220,20 +244,16 @@ void LLFloaterGesture::refreshAll()
void LLFloaterGesture::buildGestureList()
{
- LLCtrlListInterface *list = getGestureList();
- LLCtrlScrollInterface *scroll = childGetScrollInterface("gesture_list");
-
- if (! (list && scroll)) return;
-
- LLUUID selected_item = list->getCurrentID();
+ std::vector<LLUUID> selected_items;
+ getSelectedIds(selected_items);
LL_DEBUGS("Gesture")<< "Rebuilding gesture list "<< LL_ENDL;
- list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+ mGestureList->deleteAllItems();
LLGestureManager::item_map_t::const_iterator it;
const LLGestureManager::item_map_t& active_gestures = LLGestureManager::instance().getActiveGestures();
for (it = active_gestures.begin(); it != active_gestures.end(); ++it)
{
- addGesture(it->first,it->second, list);
+ addGesture(it->first,it->second, mGestureList);
}
if (gInventory.isCategoryComplete(mGestureFolderID))
{
@@ -249,16 +269,17 @@ void LLFloaterGesture::buildGestureList()
if (active_gestures.find(item->getUUID()) == active_gestures.end())
{
// if gesture wasn't loaded yet, we can display only name
- addGesture(item->getUUID(), NULL, list);
+ addGesture(item->getUUID(), NULL, mGestureList);
}
}
}
// attempt to preserve scroll position through re-builds
// since we do re-build any time anything dirties
- if(list->selectByValue(LLSD(selected_item)))
+ for(std::vector<LLUUID>::iterator it = selected_items.begin(); it != selected_items.end(); it++)
{
- scroll->scrollToShowSelected();
+ mGestureList->selectByID(*it);
}
+ mGestureList->scrollToShowSelected();
}
void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gesture,LLCtrlListInterface * list )
@@ -346,33 +367,59 @@ void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gestur
list->addElement(element, ADD_BOTTOM);
}
-void LLFloaterGesture::onClickInventory()
+void LLFloaterGesture::getSelectedIds(std::vector<LLUUID>& ids)
+{
+ std::vector<LLScrollListItem*> items = mGestureList->getAllSelected();
+ for(std::vector<LLScrollListItem*>::const_iterator it = items.begin(); it != items.end(); it++)
+ {
+ ids.push_back((*it)->getUUID());
+ }
+}
+
+bool LLFloaterGesture::isActionEnabled(const LLSD& command)
{
- LLCtrlListInterface *list = getGestureList();
- if (!list) return;
- const LLUUID& item_id = list->getCurrentID();
+ // paste copy_uuid edit_gesture
+ std::string command_name = command.asString();
+ if("paste" == command_name)
+ {
+ if(!LLInventoryClipboard::instance().hasContents())
+ return false;
- LLFloaterInventory* inv = LLFloaterInventory::showAgentInventory();
- if (!inv) return;
- inv->getPanel()->setSelection(item_id, TRUE);
+ LLDynamicArray<LLUUID> ids;
+ LLInventoryClipboard::instance().retrieve(ids);
+ for(LLDynamicArray<LLUUID>::iterator it = ids.begin(); it != ids.end(); it++)
+ {
+ LLInventoryItem* item = gInventory.getItem(*it);
+
+ if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if("copy_uuid" == command_name || "edit_gesture" == command_name
+ || "inspect" == command_name)
+ {
+ return mGestureList->getAllSelected().size() == 1;
+ }
+ return true;
}
void LLFloaterGesture::onClickPlay()
{
- LLCtrlListInterface *list = getGestureList();
- if (!list) return;
- const LLUUID& item_id = list->getCurrentID();
+ const LLUUID& item_id = mGestureList->getCurrentID();
if(item_id.isNull()) return;
LL_DEBUGS("Gesture")<<" Trying to play gesture id: "<< item_id <<LL_ENDL;
if(!LLGestureManager::instance().isGestureActive(item_id))
{
- // we need to inform server about gesture activating to be consistent with LLPreviewGesture.
+ // we need to inform server about gesture activating to be consistent with LLPreviewGesture and LLGestureComboBox.
BOOL inform_server = TRUE;
BOOL deactivate_similar = FALSE;
+ LLGestureManager::instance().setGestureLoadedCallback(item_id, boost::bind(&LLFloaterGesture::playGesture, this, item_id));
LLGestureManager::instance().activateGestureWithAsset(item_id, gInventory.getItem(item_id)->getAssetUUID(), inform_server, deactivate_similar);
LL_DEBUGS("Gesture")<< "Activating gesture with inventory ID: " << item_id <<LL_ENDL;
- LLGestureManager::instance().setGestureLoadedCallback(item_id, boost::bind(&LLFloaterGesture::playGesture, this, item_id));
}
else
{
@@ -380,15 +427,6 @@ void LLFloaterGesture::onClickPlay()
}
}
-class GestureShowCallback : public LLInventoryCallback
-{
-public:
- void fire(const LLUUID &inv_item)
- {
- LLPreviewGesture::show(inv_item, LLUUID::null);
- }
-};
-
void LLFloaterGesture::onClickNew()
{
LLPointer<LLInventoryCallback> cb = new GestureShowCallback();
@@ -399,27 +437,96 @@ void LLFloaterGesture::onClickNew()
void LLFloaterGesture::onActivateBtnClick()
{
- LLCtrlListInterface* list = getGestureList();
-
- LLUUID gesture_inv_id = list->getSelectedValue();
+ std::vector<LLUUID> ids;
+ getSelectedIds(ids);
+ if(ids.empty())
+ return;
+
LLGestureManager* gm = LLGestureManager::getInstance();
-
- if(gm->isGestureActive(gesture_inv_id))
+ std::vector<LLUUID>::const_iterator it = ids.begin();
+ BOOL first_gesture_state = gm->isGestureActive(*it);
+ BOOL is_mixed = FALSE;
+ while( ++it != ids.end() )
{
- gm->deactivateGesture(gesture_inv_id);
+ if(first_gesture_state != gm->isGestureActive(*it))
+ {
+ is_mixed = TRUE;
+ break;
+ }
}
- else
+ for(std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); it++)
{
- gm->activateGesture(gesture_inv_id);
+ if(is_mixed)
+ {
+ gm->activateGesture(*it);
+ }
+ else
+ {
+ if(first_gesture_state)
+ {
+ gm->deactivateGesture(*it);
+ }
+ else
+ {
+ gm->activateGesture(*it);
+ }
+ }
}
}
+void LLFloaterGesture::onCopyPastAction(const LLSD& command)
+{
+ std::string command_name = command.asString();
+ // since we select this comman inventory item had already arrived .
+ if("copy_gesture" == command_name)
+ {
+ std::vector<LLUUID> ids;
+ getSelectedIds(ids);
+ // make sure that clopboard is empty
+ LLInventoryClipboard::instance().reset();
+ for(std::vector<LLUUID>::iterator it = ids.begin(); it != ids.end(); it++)
+ {
+ LLInventoryItem* item = gInventory.getItem(*it);
+ if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE)
+ {
+ LLInventoryClipboard::instance().add(item->getUUID());
+ }
+ }
+ }
+ else if ("paste" == command_name)
+ {
+ LLInventoryClipboard& clipbord = LLInventoryClipboard::instance();
+ LLDynamicArray<LLUUID> ids;
+ clipbord.retrieve(ids);
+ if(ids.empty() || !gInventory.isCategoryComplete(mGestureFolderID))
+ return;
+ LLInventoryCategory* gesture_dir = gInventory.getCategory(mGestureFolderID);
+ LLPointer<GestureCopiedCallback> cb = new GestureCopiedCallback(this);
+
+ for(LLDynamicArray<LLUUID>::iterator it = ids.begin(); it != ids.end(); it++)
+ {
+ LLInventoryItem* item = gInventory.getItem(*it);
+ LLStringUtil::format_map_t string_args;
+ string_args["[COPY_NAME]"] = item->getName();
+ if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE)
+ {
+ LL_DEBUGS("Gesture")<< "Copying gesture " << item->getName() << " "<< item->getUUID() << " into "
+ << gesture_dir->getName() << " "<< gesture_dir->getUUID() << LL_ENDL;
+ copy_inventory_item(gAgent.getID(), item->getPermissions().getOwner(), item->getUUID(),
+ gesture_dir->getUUID(), getString("copy_name", string_args), cb);
+ }
+ }
+ clipbord.reset();
+ }
+ else if ("copy_uuid" == command_name)
+ {
+ gClipboard.copyFromString(utf8str_to_wstring(mGestureList->getCurrentID().asString()), mGestureList->getCurrentID());
+ }
+}
void LLFloaterGesture::onClickEdit()
{
- LLCtrlListInterface *list = getGestureList();
- if (!list) return;
- const LLUUID& item_id = list->getCurrentID();
+ const LLUUID& item_id = mGestureList->getCurrentID();
LLInventoryItem* item = gInventory.getItem(item_id);
if (!item) return;
@@ -433,7 +540,7 @@ void LLFloaterGesture::onClickEdit()
void LLFloaterGesture::onCommitList()
{
- const LLUUID& item_id = childGetValue("gesture_list").asUUID();
+ const LLUUID& item_id = mGestureList->getCurrentID();
mSelectedID = item_id;
if (LLGestureManager::instance().isGesturePlaying(item_id))
@@ -447,8 +554,60 @@ void LLFloaterGesture::onCommitList()
childSetVisible("stop_btn", false);
}
}
+
+void LLFloaterGesture::onDeleteSelected()
+{
+ std::vector<LLUUID> ids;
+ getSelectedIds(ids);
+ if(ids.empty())
+ return;
+
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ LLGestureManager* gm = LLGestureManager::getInstance();
+ for(std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); it++)
+ {
+ const LLUUID& selected_item = *it;
+ LLInventoryItem* inv_item = gInventory.getItem(selected_item);
+ if (inv_item && inv_item->getInventoryType() == LLInventoryType::IT_GESTURE)
+ {
+ if(gm->isGestureActive(selected_item))
+ {
+ gm->deactivateGesture(selected_item);
+ }
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate old_folder(inv_item->getParentUUID(), -1);
+ update.push_back(old_folder);
+ LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1);
+ update.push_back(new_folder);
+ gInventory.accountForUpdate(update);
+
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item);
+ new_item->setParent(trash_id);
+ // no need to restamp it though it's a move into trash because
+ // it's a brand new item already.
+ new_item->updateParentOnServer(FALSE);
+ gInventory.updateItem(new_item);
+ }
+ }
+ gInventory.notifyObservers();
+ buildGestureList();
+}
+
+void LLFloaterGesture::addToCurrentOutFit()
+{
+ std::vector<LLUUID> ids;
+ getSelectedIds(ids);
+ LLAppearanceManager* am = LLAppearanceManager::getInstance();
+ for(std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); it++)
+ {
+ am->addCOFItemLink(*it);
+ }
+}
+
void LLFloaterGesture::playGesture(LLUUID item_id)
{
+ LL_DEBUGS("Gesture")<<"Playing gesture "<< item_id<<LL_ENDL;
+
if (LLGestureManager::instance().isGesturePlaying(item_id))
{
LLGestureManager::instance().stopGesture(item_id);
diff --git a/indra/newview/llfloatergesture.h b/indra/newview/llfloatergesture.h
index 50bef818da..14e132900d 100644
--- a/indra/newview/llfloatergesture.h
+++ b/indra/newview/llfloatergesture.h
@@ -36,11 +36,10 @@
#ifndef LL_LLFLOATERGESTURE_H
#define LL_LLFLOATERGESTURE_H
+#include <vector>
#include "llfloater.h"
-#include "llinventorymodel.h"
#include "llinventoryobserver.h"
-#include "lldarray.h"
class LLScrollContainer;
class LLView;
@@ -53,6 +52,7 @@ class LLScrollListCtrl;
class LLFloaterGestureObserver;
class LLFloaterGestureInventoryObserver;
class LLMultiGesture;
+class LLMenuGL;
class LLFloaterGesture
: public LLFloater, LLInventoryFetchDescendentsObserver
@@ -65,26 +65,46 @@ public:
virtual BOOL postBuild();
virtual void done ();
void refreshAll();
+ /**
+ * @brief Add new scrolllistitem into gesture_list.
+ * @param item_id inventory id of gesture
+ * @param gesture can be NULL , if item was not loaded yet
+ */
+ void addGesture(const LLUUID& item_id, LLMultiGesture* gesture, LLCtrlListInterface * list);
protected:
// Reads from the gesture manager's list of active gestures
// and puts them in this list.
void buildGestureList();
- void addGesture(const LLUUID& item_id, LLMultiGesture* gesture, LLCtrlListInterface * list);
- void onClickInventory();
+ void playGesture(LLUUID item_id);
+private:
+ void addToCurrentOutFit();
+ /**
+ * @brief This method is using to collect selected items.
+ * In some places gesture_list can be rebuilt by gestureObservers during iterating data from LLScrollListCtrl::getAllSelected().
+ * Therefore we have to copy these items to avoid viewer crash.
+ * @see LLFloaterGesture::onActivateBtnClick
+ */
+ void getSelectedIds(std::vector<LLUUID>& ids);
+ bool isActionEnabled(const LLSD& command);
+ /**
+ * @brief Activation rules:
+ * According to Gesture Spec:
+ * 1. If all selected gestures are active: set to inactive
+ * 2. If all selected gestures are inactive: set to active
+ * 3. If selected gestures are in a mixed state: set all to active
+ */
+ void onActivateBtnClick();
void onClickEdit();
void onClickPlay();
void onClickNew();
void onCommitList();
- void playGesture(LLUUID item_id);
- LLCtrlListInterface* getGestureList() const
- {
- return childGetListInterface("gesture_list");
- }
- void onActivateBtnClick();
-protected:
+ void onCopyPastAction(const LLSD& command);
+ void onDeleteSelected();
+
LLUUID mSelectedID;
LLUUID mGestureFolderID;
+ LLScrollListCtrl* mGestureList;
LLFloaterGestureObserver* mObserver;
};
diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp
index 003afafa87..d50b68b624 100644
--- a/indra/newview/lllandmarkactions.cpp
+++ b/indra/newview/lllandmarkactions.cpp
@@ -374,22 +374,34 @@ void LLLandmarkActions::onRegionResponseNameAndCoords(region_name_and_coords_cal
bool LLLandmarkActions::getLandmarkGlobalPos(const LLUUID& landmarkInventoryItemID, LLVector3d& posGlobal)
{
- LLLandmark* landmark = LLLandmarkActions::getLandmark(landmarkInventoryItemID);
+ LLViewerInventoryItem* item = gInventory.getItem(landmarkInventoryItemID);
+ if (NULL == item)
+ return false;
+
+ const LLUUID& asset_id = item->getAssetUUID();
+ LLLandmark* landmark = gLandmarkList.getAsset(asset_id, NULL);
if (NULL == landmark)
return false;
return landmark->getGlobalPos(posGlobal);
}
-LLLandmark* LLLandmarkActions::getLandmark(const LLUUID& landmarkInventoryItemID)
+LLLandmark* LLLandmarkActions::getLandmark(const LLUUID& landmarkInventoryItemID, LLLandmarkList::loaded_callback_t cb)
{
LLViewerInventoryItem* item = gInventory.getItem(landmarkInventoryItemID);
if (NULL == item)
return NULL;
const LLUUID& asset_id = item->getAssetUUID();
- return gLandmarkList.getAsset(asset_id, NULL);
+
+ LLLandmark* landmark = gLandmarkList.getAsset(asset_id, cb);
+ if (landmark)
+ {
+ return landmark;
+ }
+
+ return NULL;
}
void LLLandmarkActions::copySLURLtoClipboard(const LLUUID& landmarkInventoryItemID)
diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h
index c65b831f3e..987caf0936 100644
--- a/indra/newview/lllandmarkactions.h
+++ b/indra/newview/lllandmarkactions.h
@@ -35,7 +35,10 @@
#include "llinventorymodel.h"
+#include "lllandmarklist.h"
+
class LLLandmark;
+
/**
* @brief Provides helper functions to manage landmarks
*/
@@ -112,10 +115,11 @@ public:
/**
* @brief Retrieve a landmark from gLandmarkList by inventory item's id
+ * If a landmark is not currently in the gLandmarkList a callback "cb" is called when it is loaded.
*
* @return pointer to loaded landmark from gLandmarkList or NULL if landmark does not exist or wasn't loaded.
*/
- static LLLandmark* getLandmark(const LLUUID& landmarkInventoryItemID);
+ static LLLandmark* getLandmark(const LLUUID& landmarkInventoryItemID, LLLandmarkList::loaded_callback_t cb = NULL);
/**
* @brief Performs standard action of copying of SLURL from landmark to user's clipboard.
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 598d021703..0a595765a9 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -92,16 +92,26 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
{
// add message to IM
- LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, notification->getPayload()["from_id"]);
- if (!LLIMMgr::instance().hasSession(session_id))
+ const std::string
+ name =
+ notification->getSubstitutions().has("NAME") ? notification->getSubstitutions()["NAME"]
+ : notification->getSubstitutions()["[NAME]"];
+
+ // don't create IM session with objects
+ if (notification->getName() != "ObjectGiveItem"
+ && notification->getName() != "ObjectGiveItemUnknownUser")
{
- session_id = LLIMMgr::instance().addSession(
- notification->getSubstitutions()["OBJECTFROMNAME"], IM_NOTHING_SPECIAL,
- notification->getPayload()["from_id"]);
+ LLUUID from_id = notification->getPayload()["from_id"];
+ LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL,
+ from_id);
+ if (!LLIMMgr::instance().hasSession(session_id))
+ {
+ session_id = LLIMMgr::instance().addSession(name,
+ IM_NOTHING_SPECIAL, from_id);
+ }
+ LLIMMgr::instance().addMessage(session_id, LLUUID(), name,
+ notification->getMessage());
}
- LLIMMgr::instance().addMessage(session_id, LLUUID(),
- notification->getSubstitutions()["OBJECTFROMNAME"],
- notification->getMessage());
LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index f94a59ecef..5de7c3f851 100644
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -352,6 +352,8 @@ void LLPanelLandmarkInfo::createLandmark(const LLUUID& folder_id)
}
LLStringUtil::replaceChar(desc, '\n', ' ');
+ LLViewerInventoryItem::insertDefaultSortField(name);
+
// If no folder chosen use the "Landmarks" folder.
LLLandmarkActions::createLandmarkHere(name, desc,
folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index e199db37ab..10b419dfdb 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -148,20 +148,13 @@ void LLLandmarksPanel::onShowOnMap()
llwarns << "There are no selected list. No actions are performed." << llendl;
return;
}
- LLLandmark* landmark = getCurSelectedLandmark();
- if (!landmark)
- return;
- LLVector3d landmark_global_pos;
- if (!landmark->getGlobalPos(landmark_global_pos))
- return;
-
- LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
- if (!landmark_global_pos.isExactlyZero() && worldmap_instance)
- {
- worldmap_instance->trackLocation(landmark_global_pos);
- LLFloaterReg::showInstance("world_map", "center");
- }
+ // Disable the "Map" button because loading landmark can take some time.
+ // During this time the button is useless. It will be enabled on callback finish
+ // or upon switching to other item.
+ mShowOnMapBtn->setEnabled(FALSE);
+
+ doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doShowOnMap, this, _1));
}
// virtual
@@ -256,15 +249,18 @@ bool LLLandmarksPanel::isReceivedFolderSelected() const
return false;
}
-LLLandmark* LLLandmarksPanel::getCurSelectedLandmark() const
-{
+void LLLandmarksPanel::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb)
+{
LLFolderViewItem* cur_item = getCurSelectedItem();
if(cur_item && cur_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
- return LLLandmarkActions::getLandmark(cur_item->getListener()->getUUID());
+ LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getListener()->getUUID(), cb);
+ if (landmark)
+ {
+ cb(landmark);
+ }
}
- return NULL;
}
LLFolderViewItem* LLLandmarksPanel::getCurSelectedItem() const
@@ -294,45 +290,11 @@ void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data)
// We have to make request to sever to get parcel_id and snaption_id.
if(isLandmarkSelected())
{
- LLLandmark* landmark = getCurSelectedLandmark();
LLFolderViewItem* cur_item = getCurSelectedItem();
LLUUID id = cur_item->getListener()->getUUID();
- LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id);
- if(landmark)
- {
- LLPanelPickEdit* panel_pick = LLPanelPickEdit::create();
- LLVector3d landmark_global_pos;
- landmark->getGlobalPos(landmark_global_pos);
-
- // let's toggle pick panel into panel places
- LLPanel* panel_places = LLSideTray::getInstance()->getChild<LLPanel>("panel_places");//-> sidebar_places
- panel_places->addChild(panel_pick);
- LLRect paren_rect(panel_places->getRect());
- panel_pick->reshape(paren_rect.getWidth(),paren_rect.getHeight(), TRUE);
- panel_pick->setRect(paren_rect);
- panel_pick->onOpen(LLSD());
-
- LLPickData data;
- data.pos_global = landmark_global_pos;
- data.name = cur_item->getName();
- data.desc = inv_item->getDescription();
- data.snapshot_id = parcel_data.snapshot_id;
- data.parcel_id = parcel_data.parcel_id;
- panel_pick->setPickData(&data);
-
- LLSD params;
- params["parcel_id"] =parcel_data.parcel_id;
- /* set exit callback to get back onto panel places
- in callback we will make cleaning up( delete pick_panel instance,
- remove landmark panel from observer list
- */
- panel_pick->setExitCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- panel_pick->setSaveCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- panel_pick->setCancelCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- }
+ LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id);
+ doActionOnCurSelectedLandmark(boost::bind(
+ &LLLandmarksPanel::doProcessParcelInfo, this, _1, cur_item, inv_item, parcel_data));
}
}
@@ -747,42 +709,7 @@ void LLLandmarksPanel::onCustomAction(const LLSD& userdata)
}
else if ("create_pick" == command_name)
{
- LLLandmark* landmark = getCurSelectedLandmark();
- if(!landmark) return;
-
- LLViewerRegion* region = gAgent.getRegion();
- if (!region) return;
-
- LLGlobalVec pos_global;
- LLUUID region_id;
- landmark->getGlobalPos(pos_global);
- landmark->getRegionID(region_id);
- LLVector3 region_pos((F32)fmod(pos_global.mdV[VX], (F64)REGION_WIDTH_METERS),
- (F32)fmod(pos_global.mdV[VY], (F64)REGION_WIDTH_METERS),
- (F32)pos_global.mdV[VZ]);
-
- LLSD body;
- std::string url = region->getCapability("RemoteParcelRequest");
- if (!url.empty())
- {
- body["location"] = ll_sd_from_vector3(region_pos);
- if (!region_id.isNull())
- {
- body["region_id"] = region_id;
- }
- if (!pos_global.isExactlyZero())
- {
- U64 region_handle = to_region_handle(pos_global);
- body["region_handle"] = ll_sd_from_U64(region_handle);
- }
- LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(getObserverHandle()));
- }
- else
- {
- llwarns << "Can't create pick for landmark for region" << region_id
- << ". Region: " << region->getName()
- << " does not support RemoteParcelRequest" << llendl;
- }
+ doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doCreatePick, this, _1));
}
}
@@ -931,6 +858,97 @@ void LLLandmarksPanel::updateFilteredAccordions()
mDirtyFilter = false;
}
+void LLLandmarksPanel::doShowOnMap(LLLandmark* landmark)
+{
+ LLVector3d landmark_global_pos;
+ if (!landmark->getGlobalPos(landmark_global_pos))
+ return;
+
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+ if (!landmark_global_pos.isExactlyZero() && worldmap_instance)
+ {
+ worldmap_instance->trackLocation(landmark_global_pos);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
+
+ mShowOnMapBtn->setEnabled(TRUE);
+}
+
+void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
+ LLFolderViewItem* cur_item,
+ LLInventoryItem* inv_item,
+ const LLParcelData& parcel_data)
+{
+ LLPanelPickEdit* panel_pick = LLPanelPickEdit::create();
+ LLVector3d landmark_global_pos;
+ landmark->getGlobalPos(landmark_global_pos);
+
+ // let's toggle pick panel into panel places
+ LLPanel* panel_places = LLSideTray::getInstance()->getChild<LLPanel>("panel_places");//-> sidebar_places
+ panel_places->addChild(panel_pick);
+ LLRect paren_rect(panel_places->getRect());
+ panel_pick->reshape(paren_rect.getWidth(),paren_rect.getHeight(), TRUE);
+ panel_pick->setRect(paren_rect);
+ panel_pick->onOpen(LLSD());
+
+ LLPickData data;
+ data.pos_global = landmark_global_pos;
+ data.name = cur_item->getName();
+ data.desc = inv_item->getDescription();
+ data.snapshot_id = parcel_data.snapshot_id;
+ data.parcel_id = parcel_data.parcel_id;
+ panel_pick->setPickData(&data);
+
+ LLSD params;
+ params["parcel_id"] = parcel_data.parcel_id;
+ /* set exit callback to get back onto panel places
+ in callback we will make cleaning up( delete pick_panel instance,
+ remove landmark panel from observer list
+ */
+ panel_pick->setExitCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
+ panel_pick, panel_places,params));
+ panel_pick->setSaveCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
+ panel_pick, panel_places,params));
+ panel_pick->setCancelCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
+ panel_pick, panel_places,params));
+}
+
+void LLLandmarksPanel::doCreatePick(LLLandmark* landmark)
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region) return;
+
+ LLGlobalVec pos_global;
+ LLUUID region_id;
+ landmark->getGlobalPos(pos_global);
+ landmark->getRegionID(region_id);
+ LLVector3 region_pos((F32)fmod(pos_global.mdV[VX], (F64)REGION_WIDTH_METERS),
+ (F32)fmod(pos_global.mdV[VY], (F64)REGION_WIDTH_METERS),
+ (F32)pos_global.mdV[VZ]);
+
+ LLSD body;
+ std::string url = region->getCapability("RemoteParcelRequest");
+ if (!url.empty())
+ {
+ body["location"] = ll_sd_from_vector3(region_pos);
+ if (!region_id.isNull())
+ {
+ body["region_id"] = region_id;
+ }
+ if (!pos_global.isExactlyZero())
+ {
+ U64 region_handle = to_region_handle(pos_global);
+ body["region_handle"] = ll_sd_from_U64(region_handle);
+ }
+ LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(getObserverHandle()));
+ }
+ else
+ {
+ llwarns << "Can't create pick for landmark for region" << region_id
+ << ". Region: " << region->getName()
+ << " does not support RemoteParcelRequest" << llendl;
+ }
+}
//////////////////////////////////////////////////////////////////////////
// HELPER FUNCTIONS
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index 097d79badf..777ee562d2 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -37,6 +37,7 @@
// newview
#include "llinventorymodel.h"
+#include "lllandmarklist.h"
#include "llpanelplacestab.h"
#include "llpanelpick.h"
#include "llremoteparcelrequest.h"
@@ -68,7 +69,7 @@ protected:
*/
bool isLandmarkSelected() const;
bool isReceivedFolderSelected() const;
- LLLandmark* getCurSelectedLandmark() const;
+ void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);
LLFolderViewItem* getCurSelectedItem() const;
void updateSortOrder(LLInventoryPanel* panel, bool byDate);
@@ -127,6 +128,16 @@ private:
*/
void updateFilteredAccordions();
+ /**
+ * Landmark actions callbacks. Fire when a landmark is loaded from the list.
+ */
+ void doShowOnMap(LLLandmark* landmark);
+ void doProcessParcelInfo(LLLandmark* landmark,
+ LLFolderViewItem* cur_item,
+ LLInventoryItem* inv_item,
+ const LLParcelData& parcel_data);
+ void doCreatePick(LLLandmark* landmark);
+
private:
LLInventorySubTreePanel* mFavoritesInventoryPanel;
LLInventorySubTreePanel* mLandmarksInventoryPanel;
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 4dc8872557..29f7cc1851 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -536,8 +536,15 @@ BOOL LLPanelPeople::postBuild()
mNearbyList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mNearbyList));
mRecentList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mRecentList));
+ // Set openning IM as default on return action for avatar lists
+ mOnlineFriendList->setReturnCallback(boost::bind(&LLPanelPeople::onImButtonClicked, this));
+ mAllFriendList->setReturnCallback(boost::bind(&LLPanelPeople::onImButtonClicked, this));
+ mNearbyList->setReturnCallback(boost::bind(&LLPanelPeople::onImButtonClicked, this));
+ mRecentList->setReturnCallback(boost::bind(&LLPanelPeople::onImButtonClicked, this));
+
mGroupList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onChatButtonClicked, this));
mGroupList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this));
+ mGroupList->setReturnCallback(boost::bind(&LLPanelPeople::onChatButtonClicked, this));
LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>("tab_all");
accordion_tab->setDropDownStateChangedCallback(
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 13bd059d45..4ee9cba69c 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -65,6 +65,8 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av
mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
mAvatarList->setDoubleClickCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList));
mAvatarList->setRefreshCompleteCallback(boost::bind(&LLParticipantList::onAvatarListRefreshed, this, _1, _2));
+ // Set onAvatarListDoubleClicked as default on_return action.
+ mAvatarList->setReturnCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList));
mParticipantListMenu = new LLParticipantListMenu(*this);
mAvatarList->setContextMenu(mParticipantListMenu);
@@ -99,6 +101,7 @@ void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible)
void LLParticipantList::onAvatarListDoubleClicked(LLAvatarList* list)
{
+ // NOTE(EM): Should we check if there is multiple selection and start conference if it is so?
LLUUID clicked_id = list->getSelectedUUID();
if (clicked_id.isNull() || clicked_id == gAgent.getID())
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index d1cf4a0810..24505f6bd6 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -533,19 +533,7 @@ void LLScreenChannel::createStartUpToast(S32 notif_num, F32 timer)
LLTextBox* text_box = mStartUpToastPanel->getChild<LLTextBox>("toast_text");
- std::string mStartUpFormatString;
-
- if(notif_num == 1)
- {
- mStartUpFormatString = LLTrans::getString("StartUpNotification");
- }
- else
- {
- mStartUpFormatString = LLTrans::getString("StartUpNotifications");
- }
-
-
- std::string text = llformat(mStartUpFormatString.c_str(), notif_num);
+ std::string text = LLTrans::getString("StartUpNotifications");
toast_rect = mStartUpToastPanel->getRect();
mStartUpToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true);
diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp
index 51d53b2674..54f776ca6a 100644
--- a/indra/newview/llspeakbutton.cpp
+++ b/indra/newview/llspeakbutton.cpp
@@ -143,6 +143,27 @@ void LLSpeakButton::setShowToolTip(const std::string& msg)
mShowBtn->setToolTip(msg);
}
+void LLSpeakButton::setLabelVisible(bool visible)
+{
+ static std::string label_selected = mSpeakBtn->getLabelSelected();
+ static std::string label_unselected = mSpeakBtn->getLabelUnselected();
+
+ if (visible)
+ {
+ mSpeakBtn->setLabelSelected(label_selected);
+ mSpeakBtn->setLabelUnselected(label_unselected);
+ }
+ else
+ {
+ static LLStringExplicit empty_string("");
+ mSpeakBtn->setLabelSelected(empty_string);
+ mSpeakBtn->setLabelUnselected(empty_string);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+/// PROTECTED SECTION
+//////////////////////////////////////////////////////////////////////////
void LLSpeakButton::onMouseDown_SpeakBtn()
{
bool down = true;
diff --git a/indra/newview/llspeakbutton.h b/indra/newview/llspeakbutton.h
index 02c8ab3890..424ee5357a 100644
--- a/indra/newview/llspeakbutton.h
+++ b/indra/newview/llspeakbutton.h
@@ -67,6 +67,18 @@ public:
void setSpeakToolTip(const std::string& msg);
void setShowToolTip(const std::string& msg);
+ /**
+ * Sets visibility of speak button's label according to passed parameter.
+ *
+ * It removes label/selected label if "visible" is false and restores otherwise.
+ *
+ * @param visible if true - show label and selected label.
+ *
+ * @see mSpeakBtn
+ * @see LLBottomTray::processShrinkButtons()
+ */
+ void setLabelVisible(bool visible);
+
protected:
friend class LLUICtrlFactory;
LLSpeakButton(const Params& p);
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index beb31bc833..a4f5164a8d 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -53,6 +53,7 @@
#include "lluictrlfactory.h"
#include "llnotifications.h"
#include "llfunctorregistry.h"
+#include "llrootview.h"
const S32 MAX_ALLOWED_MSG_WIDTH = 400;
const F32 DEFAULT_BUTTON_DELAY = 0.5f;
@@ -220,16 +221,13 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
static LLUIColor alert_text_color = LLUIColorTable::instance().getColor("AlertTextColor");
if (mCaution)
{
- LLIconCtrl::Params params;
- params.name("icon");
- params.rect(LLRect(msg_x, msg_y, msg_x+32, msg_y-32));
- params.mouse_opaque(false);
- params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
- params.tab_stop(false);
- LLIconCtrl * icon = LLUICtrlFactory::create<LLIconCtrl> (params);
- icon->setValue ("notify_caution_icon.tga");
- icon->setMouseOpaque(FALSE);
- LLToastPanel::addChild(icon);
+ LLIconCtrl* icon = LLUICtrlFactory::getInstance()->createFromFile<LLIconCtrl>("alert_icon.xml", this, LLPanel::child_registry_t::instance());
+ if(icon)
+ {
+ icon->setRect(LLRect(msg_x, msg_y, msg_x+32, msg_y-32));
+ LLToastPanel::addChild(icon);
+ }
+
msg_x += 32 + HPAD;
msg_box->setColor( alert_caution_text_color );
}
@@ -245,29 +243,30 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
// Buttons
S32 button_left = (LLToastPanel::getRect().getWidth() - btn_total_width) / 2;
-
+
for( S32 i = 0; i < num_options; i++ )
{
LLRect button_rect;
- button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT );
-
- LLButton::Params p;
- p.name(options[i].first);
- p.rect(button_rect);
- p.click_callback.function(boost::bind(&LLToastAlertPanel::onButtonPressed, this, _2, i));
- p.font(font);
- p.label(options[i].second);
+
+ LLButton* btn = LLUICtrlFactory::getInstance()->createFromFile<LLButton>("alert_button.xml", this, LLPanel::child_registry_t::instance());
+ if(btn)
+ {
+ btn->setName(options[i].first);
+ btn->setRect(button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT ));
+ btn->setLabel(options[i].second);
+ btn->setFont(font);
+
+ btn->setClickedCallback(boost::bind(&LLToastAlertPanel::onButtonPressed, this, _2, i));
- LLButton* btn = LLUICtrlFactory::create<LLButton>(p);
- mButtonData[i].mButton = btn;
+ mButtonData[i].mButton = btn;
- LLToastPanel::addChild(btn);
+ LLToastPanel::addChild(btn);
- if( i == mDefaultOption )
- {
- btn->setFocus(TRUE);
+ if( i == mDefaultOption )
+ {
+ btn->setFocus(TRUE);
+ }
}
-
button_left += button_width + BTN_HPAD;
}
@@ -275,25 +274,26 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
if (!edit_text_name.empty())
{
S32 y = VPAD + BTN_HEIGHT + VPAD/2;
+ mLineEditor = LLUICtrlFactory::getInstance()->createFromFile<LLLineEditor>("alert_line_editor.xml", this, LLPanel::child_registry_t::instance());
+
+ if (mLineEditor)
+ {
+ LLRect leditor_rect = LLRect( HPAD, y+EDITOR_HEIGHT, dialog_width-HPAD, y);
+ mLineEditor->setName(edit_text_name);
+ mLineEditor->reshape(leditor_rect.getWidth(), leditor_rect.getHeight());
+ mLineEditor->setRect(leditor_rect);
+ mLineEditor->setText(edit_text_contents);
+ mLineEditor->setMaxTextLength(STD_STRING_STR_LEN);
- LLLineEditor::Params params;
- params.name(edit_text_name);
- params.rect(LLRect( HPAD, y+EDITOR_HEIGHT, dialog_width-HPAD, y));
- params.default_text(edit_text_contents);
- params.max_length_bytes(STD_STRING_STR_LEN);
- mLineEditor = LLUICtrlFactory::create<LLLineEditor> (params);
+ // make sure all edit keys get handled properly (DEV-22396)
+ mLineEditor->setHandleEditKeysDirectly(TRUE);
- // make sure all edit keys get handled properly (DEV-22396)
- mLineEditor->setHandleEditKeysDirectly(TRUE);
+ LLToastPanel::addChild(mLineEditor);
- LLToastPanel::addChild(mLineEditor);
- }
-
- if (mLineEditor)
- {
- mLineEditor->setDrawAsterixes(is_password);
+ mLineEditor->setDrawAsterixes(is_password);
- setEditTextArgs(notification->getSubstitutions());
+ setEditTextArgs(notification->getSubstitutions());
+ }
}
std::string ignore_label;
@@ -323,7 +323,14 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std::string& check_control )
{
- const LLFontGL* font = LLFontGL::getFontSansSerif();
+ mCheck = LLUICtrlFactory::getInstance()->createFromFile<LLCheckBoxCtrl>("alert_check_box.xml", this, LLPanel::child_registry_t::instance());
+
+ if(!mCheck)
+ {
+ return false;
+ }
+
+ const LLFontGL* font = mCheck->getFont();
const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f);
// Extend dialog for "check next time"
@@ -339,14 +346,13 @@ bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std::
LLToastPanel::reshape( dialog_width, dialog_height, FALSE );
S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2;
+
+ // set check_box's attributes
+ LLRect check_rect;
+ mCheck->setRect(check_rect.setOriginAndSize(msg_x, VPAD+BTN_HEIGHT+LINE_HEIGHT/2, max_msg_width, LINE_HEIGHT));
+ mCheck->setLabel(check_title);
+ mCheck->setCommitCallback(boost::bind(&LLToastAlertPanel::onClickIgnore, this, _1));
- LLCheckBoxCtrl::Params p;
- p.name("check");
- p.rect.left(msg_x).bottom(VPAD+BTN_HEIGHT+LINE_HEIGHT/2).width(max_msg_width).height(LINE_HEIGHT);
- p.label(check_title);
- p.font(font);
- p.commit_callback.function(boost::bind(&LLToastAlertPanel::onClickIgnore, this, _1));
- mCheck = LLUICtrlFactory::create<LLCheckBoxCtrl>(p);
LLToastPanel::addChild(mCheck);
return true;
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 089535dfab..87d256b60a 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1336,6 +1336,12 @@ BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(const std::string& na
return result;
}
+void LLViewerInventoryItem::insertDefaultSortField(std::string& name)
+{
+ name.insert(0, std::string("1") + getSeparator());
+}
+
+
// This returns true if the item that this item points to
// doesn't exist in memory (i.e. LLInventoryModel). The baseitem
// might still be in the database but just not loaded yet.
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 529425aa25..d27faffdd9 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -81,6 +81,7 @@ public:
virtual U32 getCRC32() const; // really more of a checksum.
static BOOL extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName);
+ static void insertDefaultSortField(std::string& name);
// construct a complete viewer inventory item
LLViewerInventoryItem(const LLUUID& uuid, const LLUUID& parent_uuid,
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 11b2f07f1b..8db6d5917a 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1372,7 +1372,8 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
payload["from_id"] = info->mFromID;
args["OBJECTFROMNAME"] = info->mFromName;
- args["NAME"] = LLSLURL::buildCommand("agent", info->mFromID, "about");
+ args["NAME"] = info->mFromName;
+ args["NAME_SLURL"] = LLSLURL::buildCommand("agent", info->mFromID, "about");
std::string verb = "highlight?name=" + msg;
args["ITEM_SLURL"] = LLSLURL::buildCommand("inventory", info->mObjectID, verb.c_str());
@@ -2115,7 +2116,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
send_generic_message("requestonlinenotification", strings);
args["NAME"] = name;
- LLNotifications::instance().add("FriendshipAccepted", args);
+ LLSD payload;
+ payload["from_id"] = from_id;
+ LLNotifications::instance().add("FriendshipAccepted", args, payload);
}
break;
diff --git a/indra/newview/skins/default/xui/en/alert_button.xml b/indra/newview/skins/default/xui/en/alert_button.xml
new file mode 100644
index 0000000000..48c67a3770
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/alert_button.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+
+<button
+ label_shadow="true"
+ auto_resize="false"
+ image_overlay_alignment="center"
+ use_ellipses="flse"
+ pad_right="10"
+ pad_left="10"
+ is_toggle="false"
+ scale_image="true"
+ commit_on_return="true"
+ font="SansSerifSmall"
+ follows="bottom"/>
diff --git a/indra/newview/skins/default/xui/en/alert_check_box.xml b/indra/newview/skins/default/xui/en/alert_check_box.xml
new file mode 100644
index 0000000000..9f1bdb5193
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/alert_check_box.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<check_box
+ text_enabled_color="LabelTextColor"
+ text_disabled_color="LabelDisabledColor"
+ font="SansSerif"
+ follows="left|top"
+ name="check"/> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/alert_icon.xml b/indra/newview/skins/default/xui/en/alert_icon.xml
new file mode 100644
index 0000000000..b0886fce06
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/alert_icon.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<icon color="1.0 1.0 1.0 1.0"
+ tab_stop="false"
+ mouse_opaque="false"
+ name="icon"
+ image_name="notify_caution_icon.tga"
+ follows="left|top">
+</icon>
diff --git a/indra/newview/skins/default/xui/en/alert_line_editor.xml b/indra/newview/skins/default/xui/en/alert_line_editor.xml
new file mode 100644
index 0000000000..ab708adb06
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/alert_line_editor.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<line_editor
+ select_on_focus="false"
+ handle_edit_keys_directly="false"
+ revert_on_esc="true"
+ commit_on_focus_lost="true"
+ ignore_tab="true"
+ max_length="254"
+ text_pad_right="0"
+ text_pad_left="0"
+ mouse_opaque="true"/>
diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml
index 21d292847a..9f5e6828d2 100644
--- a/indra/newview/skins/default/xui/en/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_gesture.xml
@@ -21,12 +21,16 @@
name="playing">
(Playing)
</floater.string>
+ <!-- It's used to build new name for gesture created by "Copy" menu item -->
+ <floater.string
+ name="copy_name">Copy of [COPY_NAME]</floater.string>
<scroll_list
bottom_delta="400"
draw_heading="true"
follows="all"
layout="topleft"
left="0"
+ multi_select="true"
top="20"
name="gesture_list">
<scroll_list.columns
@@ -57,18 +61,18 @@
left="0"
name="bottom_panel"
width="313">
- <button
+ <menu_button
follows="bottom|left"
- font="SansSerifBigBold"
- tool_tip="Change sort and view of recent residents list"
height="18"
image_disabled="OptionsMenu_Disabled"
image_selected="OptionsMenu_Press"
image_unselected="OptionsMenu_Off"
layout="topleft"
left="10"
- name="recent_viewsort_btn"
+ menu_filename="menu_gesture_gear.xml"
+ name="gear_btn"
top="5"
+ tool_tip="More options"
width="18" />
<button
follows="bottom|left"
diff --git a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
new file mode 100644
index 0000000000..4642e82c0b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ layout="topleft"
+ mouse_opaque="false"
+ name="menu_gesture_gear"
+ visible="false">
+ <menu_item_call
+ font="SansSerifBold"
+ label="Add/Remove from Favorites"
+ layout="topleft"
+ name="activate">
+ <on_click
+ function="Gesture.Action.ToogleActiveState" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="copy_gesture">
+ <on_click
+ function="Gesture.Action.CopyPast"
+ parameter="copy_gesture" />
+ <on_enable
+ function="Gesture.EnableAction"
+ parameter="copy_gesture" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="paste">
+ <on_click
+ function="Gesture.Action.CopyPast"
+ parameter="paste" />
+ <on_enable
+ function="Gesture.EnableAction"
+ parameter="paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy UUID"
+ layout="topleft"
+ name="copy_uuid">
+ <on_click
+ function="Gesture.Action.CopyPast"
+ parameter="copy_uuid" />
+ <on_enable
+ function="Gesture.EnableAction"
+ parameter="copy_uuid" />
+ </menu_item_call>
+ <menu_item_call
+ label="Save to current outfit"
+ layout="topleft"
+ name="save_to_outfit">
+ <on_click
+ function="Gesture.Action.SaveToCOF" />
+ </menu_item_call>
+ <menu_item_call
+ label="Edit"
+ layout="topleft"
+ name="edit_gesture">
+ <on_click
+ function="Gesture.Action.ShowPreview" />
+ <on_enable
+ function="Gesture.EnableAction"
+ parameter="edit_gesture" />
+ </menu_item_call>
+ <menu_item_call
+ label="Inspect"
+ layout="topleft"
+ name="inspect">
+ <on_click
+ function="Gesture.Action.ShowPreview" />
+ <on_enable
+ function="Gesture.EnableAction"
+ parameter="inspect" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 0d1ed6fc64..f1bca887a4 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4959,7 +4959,7 @@ No valid parcel could be found.
icon="notify.tga"
name="ObjectGiveItem"
type="offer">
-An object named [OBJECTFROMNAME] owned by [NAME] has offered you [OBJECTTYPE]:
+An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has offered you [OBJECTTYPE]:
[ITEM_SLURL]
<form name="form">
<button
@@ -4980,8 +4980,9 @@ An object named [OBJECTFROMNAME] owned by [NAME] has offered you [OBJECTTYPE]:
<notification
icon="notify.tga"
name="ObjectGiveItemUnknownUser"
- type="notify">
-An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you a [OBJECTTYPE] named [OBJECTNAME].
+ type="offer">
+An object named [OBJECTFROMNAME] owned by (an unknown Resident) has offered you [OBJECTTYPE]:
+[ITEM_SLURL]
<form name="form">
<button
index="0"
@@ -5002,7 +5003,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you a
icon="notify.tga"
name="UserGiveItem"
type="offer">
-[NAME] has offered you [OBJECTTYPE]:
+[NAME_SLURL] has offered you [OBJECTTYPE]:
[ITEM_SLURL]
<form name="form">
<button
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 00711a29e0..6480469f43 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -60,11 +60,11 @@
min_height="28"
width="104"
top_delta="0"
- min_width="104"
+ min_width="54"
name="speak_panel"
user_resize="false">
<talk_button
- follows="right"
+ follows="left|right"
height="23"
speak_button.tab_stop="true"
show_button.tab_stop="true"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index e76763d7eb..b3728cb425 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -1782,8 +1782,7 @@ Clears (deletes) the media and all params from the given face.
<string name="GroupNotifySaveAttachment">Save Attachment</string>
<string name="TeleportOffer">Teleport offering</string>
<!-- start-up toast's string-->
- <string name="StartUpNotification">%d new notification arrived while you were away...</string>
- <string name="StartUpNotifications">%d new notifications arrived while you were away...</string>
+ <string name="StartUpNotifications">New notifications arrived while you were away.</string>
<!-- overflow toast's string-->
<string name="OverflowInfoChannelString">You have %d more notification</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/talk_button.xml b/indra/newview/skins/default/xui/en/widgets/talk_button.xml
index 1d8257fbc8..64c2e65a6e 100644
--- a/indra/newview/skins/default/xui/en/widgets/talk_button.xml
+++ b/indra/newview/skins/default/xui/en/widgets/talk_button.xml
@@ -6,6 +6,7 @@
image_unselected="SegmentedBtn_Left_Off"
-->
<speak_button
+ follows="left|right"
name="left"
label="Speak"
label_selected="Speak"
@@ -13,6 +14,7 @@
tab_stop="false"
/>
<show_button
+ follows="right"
name="right"
label=""
left="0"
@@ -25,6 +27,7 @@
image_unselected="ComboButton_UpOff"
/>
<monitor
+ follows="right"
name="monitor"
left="0"
top="18"