diff options
Diffstat (limited to 'indra/newview/llbottomtray.cpp')
-rw-r--r-- | indra/newview/llbottomtray.cpp | 140 |
1 files changed, 109 insertions, 31 deletions
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 35e4548483..d8ec4b605c 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -67,10 +67,11 @@ BOOL LLBottomtrayButton::handleHover(S32 x, S32 y, MASK mask) { if (mCanDrag) { - S32 screenX, screenY; - localPointToScreen(x, y, &screenX, &screenY); - // pass hover to bottomtray - LLBottomTray::getInstance()->onDraggableButtonHover(screenX, screenY); + // pass hover to bottomtray + S32 screenX, screenY; + localPointToScreen(x, y, &screenX, &screenY); + LLBottomTray::getInstance()->onDraggableButtonHover(screenX, screenY); + return TRUE; } else @@ -200,6 +201,7 @@ LLBottomTray::LLBottomTray(const LLSD&) mSpeakBtn(NULL), mNearbyChatBar(NULL), mChatBarContainer(NULL), + mNearbyCharResizeHandlePanel(NULL), mToolbarStack(NULL), mMovementButton(NULL), mResizeState(RS_NORESIZE), @@ -505,6 +507,23 @@ void LLBottomTray::showSnapshotButton(BOOL visible) setTrayButtonVisibleIfPossible(RS_BUTTON_SNAPSHOT, visible); } +void LLBottomTray::showSpeakButton(bool visible) +{ + // Show/hide the button + setTrayButtonVisible(RS_BUTTON_SPEAK, visible); + + // and adjust other panels according to the occupied/freed space. + const S32 panel_width = mSpeakPanel->getRect().getWidth(); + if (visible) + { + processWidthDecreased(-panel_width); + } + else + { + processWidthIncreased(panel_width); + } +} + void LLBottomTray::toggleMovementControls() { if (mMovementButton) @@ -533,6 +552,7 @@ BOOL LLBottomTray::postBuild() LLHints::registerHintTarget("chat_bar", mNearbyChatBar->LLView::getHandle()); mChatBarContainer = getChild<LLLayoutPanel>("chat_bar_layout_panel"); + mNearbyCharResizeHandlePanel = getChild<LLPanel>("chat_bar_resize_handle_panel"); mToolbarStack = getChild<LLLayoutStack>("toolbar_stack"); mMovementButton = getChild<LLButton>("movement_btn"); @@ -651,12 +671,20 @@ void LLBottomTray::onDraggableButtonHover(S32 x, S32 y) gViewerWindow->getWindow()->setCursor(UI_CURSOR_NO); } } + else + { + // Reset cursor in case you move your mouse from the drag handle to a button. + getWindow()->setCursor(UI_CURSOR_ARROW); + + } } bool LLBottomTray::isCursorOverDraggableArea(S32 x, S32 y) { + // Draggable area lasts from the nearby chat input resize handle + // to the chiclet area (exlusively). bool result = getRect().pointInRect(x, y); - result = result && mNearbyChatBar->calcScreenRect().mRight < x; + result = result && mNearbyCharResizeHandlePanel->calcScreenRect().mRight < x; result = result && mChicletPanel->calcScreenRect().mRight > x; return result; } @@ -667,10 +695,7 @@ void LLBottomTray::updateButtonsOrdersAfterDnD() // (and according to future possible changes in the way button order is saved between sessions). state_object_map_t::const_iterator it = mStateProcessedObjectMap.begin(); state_object_map_t::const_iterator it_end = mStateProcessedObjectMap.end(); - // Speak button is currently the only draggable button not in mStateProcessedObjectMap, - // so if dragged_state is not found in that map, it should be RS_BUTTON_SPEAK. Change this code if any other - // exclusions from mStateProcessedObjectMap will become draggable. - EResizeState dragged_state = RS_BUTTON_SPEAK; + EResizeState dragged_state = RS_NORESIZE; EResizeState landing_state = RS_NORESIZE; bool landing_state_found = false; // Find states for dragged item and landing tab @@ -686,7 +711,17 @@ void LLBottomTray::updateButtonsOrdersAfterDnD() landing_state_found = true; } } - + + if (dragged_state == RS_NORESIZE) + { + llwarns << "Cannot determine what button is being dragged" << llendl; + llassert(dragged_state != RS_NORESIZE); + return; + } + + lldebugs << "Will place " << resizeStateToString(dragged_state) + << " before " << resizeStateToString(landing_state) << llendl; + // Update order of buttons according to drag'n'drop mButtonsOrder.erase(std::find(mButtonsOrder.begin(), mButtonsOrder.end(), dragged_state)); if (!landing_state_found && mLandingTab == getChild<LLPanel>(PANEL_CHICLET_NAME)) @@ -695,9 +730,10 @@ void LLBottomTray::updateButtonsOrdersAfterDnD() } else { - if (!landing_state_found) landing_state = RS_BUTTON_SPEAK; + if (!landing_state_found) landing_state = RS_BUTTON_SPEAK; // just a random fallback mButtonsOrder.insert(std::find(mButtonsOrder.begin(), mButtonsOrder.end(), landing_state), dragged_state); } + // Synchronize button process order with their order resize_state_vec_t::const_iterator it1 = mButtonsOrder.begin(); const resize_state_vec_t::const_iterator it_end1 = mButtonsOrder.end(); @@ -774,11 +810,12 @@ void LLBottomTray::loadButtonsOrder() // placing panels in layout stack according to button order which we loaded in previous for for (resize_state_vec_t::const_reverse_iterator it = mButtonsOrder.rbegin(); it != it_end; ++it, ++i) { - LLPanel* panel_to_move = *it == RS_BUTTON_SPEAK ? mSpeakPanel : mStateProcessedObjectMap[*it]; + LLPanel* panel_to_move = getButtonPanel(*it); mToolbarStack->movePanel(panel_to_move, NULL, true); // prepend } // Nearbychat is not stored in order settings file, but it must be the first of the panels, so moving it - // manually here + // (along with its drag handle) manually here. + mToolbarStack->movePanel(getChild<LLLayoutPanel>("chat_bar_resize_handle_panel"), NULL, true); mToolbarStack->movePanel(mChatBarContainer, NULL, true); } @@ -1178,9 +1215,8 @@ void LLBottomTray::processShowButtons(S32& available_width) bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32& available_width) { lldebugs << "Trying to show object type: " << shown_object_type << llendl; - llassert(mStateProcessedObjectMap[shown_object_type] != NULL); - LLPanel* panel = mStateProcessedObjectMap[shown_object_type]; + LLPanel* panel = getButtonPanel(shown_object_type); if (NULL == panel) { lldebugs << "There is no object to process for state: " << shown_object_type << llendl; @@ -1226,9 +1262,7 @@ void LLBottomTray::processHideButtons(S32& required_width, S32& buttons_freed_wi void LLBottomTray::processHideButton(EResizeState processed_object_type, S32& required_width, S32& buttons_freed_width) { lldebugs << "Trying to hide object type: " << processed_object_type << llendl; - llassert(mStateProcessedObjectMap[processed_object_type] != NULL); - - LLPanel* panel = mStateProcessedObjectMap[processed_object_type]; + LLPanel* panel = getButtonPanel(processed_object_type); if (NULL == panel) { lldebugs << "There is no object to process for state: " << processed_object_type << llendl; @@ -1273,7 +1307,6 @@ void LLBottomTray::processShrinkButtons(S32& required_width, S32& buttons_freed_ // then shrink Speak button if (required_width < 0) { - S32 panel_min_width = 0; std::string panel_name = mSpeakPanel->getName(); bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width); @@ -1309,8 +1342,7 @@ void LLBottomTray::processShrinkButtons(S32& required_width, S32& buttons_freed_ void LLBottomTray::processShrinkButton(EResizeState processed_object_type, S32& required_width) { - llassert(mStateProcessedObjectMap[processed_object_type] != NULL); - LLPanel* panel = mStateProcessedObjectMap[processed_object_type]; + LLPanel* panel = getButtonPanel(processed_object_type); if (NULL == panel) { lldebugs << "There is no object to process for type: " << processed_object_type << llendl; @@ -1411,8 +1443,7 @@ void LLBottomTray::processExtendButtons(S32& available_width) void LLBottomTray::processExtendButton(EResizeState processed_object_type, S32& available_width) { - llassert(mStateProcessedObjectMap[processed_object_type] != NULL); - LLPanel* panel = mStateProcessedObjectMap[processed_object_type]; + LLPanel* panel = getButtonPanel(processed_object_type); if (NULL == panel) { lldebugs << "There is no object to process for type: " << processed_object_type << llendl; @@ -1480,6 +1511,7 @@ bool LLBottomTray::canButtonBeShown(EResizeState processed_object_type) const void LLBottomTray::initResizeStateContainers() { // init map with objects should be processed for each type + mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SPEAK, getChild<LLPanel>("speak_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_GESTURES, getChild<LLPanel>("gesture_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_MOVEMENT, getChild<LLPanel>("movement_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_CAMERA, getChild<LLPanel>("cam_panel"))); @@ -1512,22 +1544,22 @@ void LLBottomTray::initResizeStateContainers() { const EResizeState button_type = *it; // is there an appropriate object? - llassert(mStateProcessedObjectMap.count(button_type) > 0); - if (0 == mStateProcessedObjectMap.count(button_type)) continue; + LLPanel* button_panel = getButtonPanel(button_type); + if (!button_panel) continue; // set default width for it. - mObjectDefaultWidthMap[button_type] = mStateProcessedObjectMap[button_type]->getRect().getWidth(); + mObjectDefaultWidthMap[button_type] = button_panel->getRect().getWidth(); } // ... and add Speak button because it also can be shrunk. mObjectDefaultWidthMap[RS_BUTTON_SPEAK] = mSpeakPanel->getRect().getWidth(); - } // this method must be called before restoring of the chat entry field on startup // because it resets chatbar's width according to resize logic. void LLBottomTray::initButtonsVisibility() { + setVisibleAndFitWidths(RS_BUTTON_SPEAK, gSavedSettings.getBOOL("EnableVoiceChat")); setVisibleAndFitWidths(RS_BUTTON_GESTURES, gSavedSettings.getBOOL("ShowGestureButton")); setVisibleAndFitWidths(RS_BUTTON_MOVEMENT, gSavedSettings.getBOOL("ShowMoveButton")); setVisibleAndFitWidths(RS_BUTTON_CAMERA, gSavedSettings.getBOOL("ShowCameraButton")); @@ -1540,6 +1572,7 @@ void LLBottomTray::initButtonsVisibility() void LLBottomTray::setButtonsControlsAndListeners() { + gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SPEAK, _2)); gSavedSettings.getControl("ShowGestureButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_GESTURES, _2)); gSavedSettings.getControl("ShowMoveButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_MOVEMENT, _2)); gSavedSettings.getControl("ShowCameraButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_CAMERA, _2)); @@ -1568,8 +1601,7 @@ bool LLBottomTray::toggleShowButton(LLBottomTray::EResizeState button_type, cons void LLBottomTray::setTrayButtonVisible(EResizeState shown_object_type, bool visible) { - llassert(mStateProcessedObjectMap[shown_object_type] != NULL); - LLPanel* panel = mStateProcessedObjectMap[shown_object_type]; + LLPanel* panel = getButtonPanel(shown_object_type); if (NULL == panel) { lldebugs << "There is no object to show for state: " << shown_object_type << llendl; @@ -1592,7 +1624,15 @@ void LLBottomTray::setTrayButtonVisibleIfPossible(EResizeState shown_object_type bool LLBottomTray::setVisibleAndFitWidths(EResizeState object_type, bool visible) { - LLPanel* cur_panel = mStateProcessedObjectMap[object_type]; + // The Speak button is treated specially: if voice is enabled, + // the button should be displayed no matter how much space we've got. + if (object_type == RS_BUTTON_SPEAK) + { + showSpeakButton(visible); + return true; + } + + LLPanel* cur_panel = getButtonPanel(object_type); if (NULL == cur_panel) { lldebugs << "There is no object to process for state: " << object_type << llendl; @@ -1637,7 +1677,7 @@ bool LLBottomTray::setVisibleAndFitWidths(EResizeState object_type, bool visible for (; it != it_end; ++it) { - LLPanel * cur_panel = mStateProcessedObjectMap[*it]; + LLPanel* cur_panel = getButtonPanel(*it); sum_of_min_widths += get_panel_min_width(mToolbarStack, cur_panel); sum_of_curr_widths += get_curr_width(cur_panel); } @@ -1695,6 +1735,19 @@ bool LLBottomTray::setVisibleAndFitWidths(EResizeState object_type, bool visible return is_set; } +LLPanel* LLBottomTray::getButtonPanel(EResizeState button_type) +{ + // Don't use the operator[] because it inserts a NULL value if the key is not found. + if (mStateProcessedObjectMap.count(button_type) == 0) + { + llwarns << "Cannot find a panel for " << resizeStateToString(button_type) << llendl; + llassert(mStateProcessedObjectMap.count(button_type) == 1); + return NULL; + } + + return mStateProcessedObjectMap[button_type]; +} + void LLBottomTray::showWellButton(EResizeState object_type, bool visible) { llassert( ((RS_NOTIFICATION_WELL | RS_IM_WELL) & object_type) == object_type ); @@ -1752,4 +1805,29 @@ void LLBottomTray::processChatbarCustomization(S32 new_width) } } +// static +std::string LLBottomTray::resizeStateToString(EResizeState state) +{ + switch (state) + { + case RS_NORESIZE: return "RS_NORESIZE"; + case RS_CHICLET_PANEL: return "RS_CHICLET_PANEL"; + case RS_CHATBAR_INPUT: return "RS_CHATBAR_INPUT"; + case RS_BUTTON_SNAPSHOT: return "RS_BUTTON_SNAPSHOT"; + case RS_BUTTON_CAMERA: return "RS_BUTTON_CAMERA"; + case RS_BUTTON_MOVEMENT: return "RS_BUTTON_MOVEMENT"; + case RS_BUTTON_GESTURES: return "RS_BUTTON_GESTURES"; + case RS_BUTTON_SPEAK: return "RS_BUTTON_SPEAK"; + case RS_IM_WELL: return "RS_IM_WELL"; + case RS_NOTIFICATION_WELL: return "RS_NOTIFICATION_WELL"; + case RS_BUTTON_BUILD: return "RS_BUTTON_BUILD"; + case RS_BUTTON_SEARCH: return "RS_BUTTON_SEARCH"; + case RS_BUTTON_WORLD_MAP: return "RS_BUTTON_WORLD_MAP"; + case RS_BUTTON_MINI_MAP: return "RS_BUTTON_MINI_MAP"; + case RS_BUTTONS_CAN_BE_HIDDEN: return "RS_BUTTONS_CAN_BE_HIDDEN"; + // No default to track additions. + } + return "UNKNOWN_BUTTON"; +} + //EOF |