diff options
Diffstat (limited to 'indra/newview/llbottomtray.cpp')
-rw-r--r-- | indra/newview/llbottomtray.cpp | 485 |
1 files changed, 390 insertions, 95 deletions
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 41f5fe64a1..29c2b7565e 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -2,31 +2,25 @@ * @file llbottomtray.cpp * @brief LLBottomTray class implementation * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * 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 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * 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 + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * 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. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,6 +41,7 @@ #include "llagentcamera.h" #include "llchiclet.h" #include "llfloatercamera.h" +#include "llhints.h" #include "llimfloater.h" // for LLIMFloater #include "llnearbychatbar.h" #include "llspeakbutton.h" @@ -55,11 +50,53 @@ #include "lltoolmgr.h" #include "llviewerparcelmgr.h" +#include "llviewerwindow.h" +#include "llsdserialize.h" + +// Distance from mouse down on which drag'n'drop should be started. +#define DRAG_START_DISTANCE 3 + +static const std::string SORTING_DATA_FILE_NAME = "bottomtray_buttons_order.xml"; + +LLDefaultChildRegistry::Register<LLBottomtrayButton> bottomtray_button("bottomtray_button"); + +// LLBottomtrayButton methods + +// virtual +BOOL LLBottomtrayButton::handleHover(S32 x, S32 y, MASK mask) +{ + S32 screenX, screenY; + localPointToScreen(x, y, &screenX, &screenY); + // pass hover to bottomtray + LLBottomTray::getInstance()->onDraggableButtonHover(screenX, screenY); + return FALSE; +} +//virtual +BOOL LLBottomtrayButton::handleMouseUp(S32 x, S32 y, MASK mask) +{ + S32 screenX, screenY; + localPointToScreen(x, y, &screenX, &screenY); + // pass mouse up to bottomtray + LLBottomTray::getInstance()->onDraggableButtonMouseUp(this, screenX, screenY); + LLButton::handleMouseUp(x, y, mask); + return FALSE; +} +//virtual +BOOL LLBottomtrayButton::handleMouseDown(S32 x, S32 y, MASK mask) +{ + S32 screenX, screenY; + localPointToScreen(x, y, &screenX, &screenY); + // pass mouse up to bottomtray + LLBottomTray::getInstance()->onDraggableButtonMouseDown(this, screenX, screenY); + LLButton::handleMouseDown(x, y, mask); + return FALSE; +} + static void update_build_button_enable_state() { bool can_edit = LLToolMgr::getInstance()->canEdit(); - LLBottomTray::getInstance()->childSetEnabled("build_btn", can_edit); + LLBottomTray::getInstance()->getChildView("build_btn")->setEnabled(can_edit); } // Build time optimization, generate extern template once in .cpp file @@ -68,10 +105,6 @@ template class LLBottomTray* LLSingleton<class LLBottomTray>::getInstance(); namespace { const std::string& PANEL_CHICLET_NAME = "chiclet_list_panel"; - const std::string& PANEL_CHATBAR_NAME = "chat_bar"; - const std::string& PANEL_MOVEMENT_NAME = "movement_panel"; - const std::string& PANEL_CAMERA_NAME = "cam_panel"; - const std::string& PANEL_GESTURE_NAME = "gesture_panel"; S32 get_panel_min_width(LLLayoutStack* stack, LLView* panel) { @@ -79,7 +112,7 @@ namespace llassert(stack); if ( stack && panel && panel->getVisible() ) { - stack->getPanelMinSize(panel->getName(), &minimal_width, NULL); + stack->getPanelMinSize(panel->getName(), &minimal_width); } return minimal_width; } @@ -90,7 +123,7 @@ namespace llassert(stack); if ( stack && panel && panel->getVisible() ) { - stack->getPanelMaxSize(panel->getName(), &max_width, NULL); + stack->getPanelMaxSize(panel->getName(), &max_width); } return max_width; } @@ -112,26 +145,30 @@ class LLBottomTrayLite public: LLBottomTrayLite() : mNearbyChatBar(NULL), + mChatBarContainer(NULL), mGesturePanel(NULL) { mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL); - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_bottomtray_lite.xml"); + buildFromFile("panel_bottomtray_lite.xml"); // Necessary for focus movement among child controls setFocusRoot(TRUE); } BOOL postBuild() { - mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar"); + mNearbyChatBar = findChild<LLNearbyChatBar>("chat_bar"); + mChatBarContainer = getChild<LLLayoutPanel>("chat_bar_layout_panel"); mGesturePanel = getChild<LLPanel>("gesture_panel"); // Hide "show_nearby_chat" button - LLLineEditor* chat_box = mNearbyChatBar->getChatBox(); - LLUICtrl* show_btn = mNearbyChatBar->getChild<LLUICtrl>("show_nearby_chat"); - S32 delta_width = show_btn->getRect().getWidth(); - show_btn->setVisible(FALSE); - chat_box->reshape(chat_box->getRect().getWidth() + delta_width, chat_box->getRect().getHeight()); - + if (mNearbyChatBar) + { + LLLineEditor* chat_box = mNearbyChatBar->getChatBox(); + LLUICtrl* show_btn = mNearbyChatBar->getChild<LLUICtrl>("show_nearby_chat"); + S32 delta_width = show_btn->getRect().getWidth(); + show_btn->setVisible(FALSE); + chat_box->reshape(chat_box->getRect().getWidth() + delta_width, chat_box->getRect().getHeight()); + } return TRUE; } @@ -144,6 +181,7 @@ public: } LLNearbyChatBar* mNearbyChatBar; + LLLayoutPanel* mChatBarContainer; LLPanel* mGesturePanel; }; @@ -152,13 +190,18 @@ LLBottomTray::LLBottomTray(const LLSD&) mSpeakPanel(NULL), mSpeakBtn(NULL), mNearbyChatBar(NULL), - mToolbarStack(NULL) -, mMovementButton(NULL) -, mResizeState(RS_NORESIZE) -, mBottomTrayContextMenu(NULL) -, mCamButton(NULL) -, mBottomTrayLite(NULL) -, mIsInLiteMode(false) + mChatBarContainer(NULL), + mToolbarStack(NULL), + mMovementButton(NULL), + mResizeState(RS_NORESIZE), + mBottomTrayContextMenu(NULL), + mCamButton(NULL), + mBottomTrayLite(NULL), + mIsInLiteMode(false), + mDragStarted(false), + mDraggedItem(NULL), + mLandingTab(NULL), + mCheckForDrag(false) { // Firstly add ourself to IMSession observers, so we catch session events // before chiclets do that. @@ -166,7 +209,7 @@ LLBottomTray::LLBottomTray(const LLSD&) mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL); - LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml"); + buildFromFile("panel_bottomtray.xml"); LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("CameraPresets.ChangeView", boost::bind(&LLFloaterCamera::onClickCameraItem, _2)); @@ -183,6 +226,9 @@ LLBottomTray::LLBottomTray(const LLSD&) mBottomTrayLite->setFollowsAll(); mBottomTrayLite->setVisible(FALSE); } + + mImageDragIndication = LLUI::getUIImage(getString("DragIndicationImageName")); + mDesiredNearbyChatWidth = mNearbyChatBar ? mNearbyChatBar->getRect().getWidth() : 0; } LLBottomTray::~LLBottomTray() @@ -195,7 +241,7 @@ LLBottomTray::~LLBottomTray() if (mNearbyChatBar) { // store custom width of chatbar panel. - S32 custom_width = mNearbyChatBar->getRect().getWidth(); + S32 custom_width = mChatBarContainer->getRect().getWidth(); gSavedSettings.setS32("ChatBarCustomWidth", custom_width); } @@ -390,7 +436,7 @@ S32 LLBottomTray::notifyParent(const LLSD& info) const std::string& name = info["view_name"]; // expected only resize of nearby chatbar - if (mNearbyChatBar->getName() != name) return LLPanel::notifyParent(info); + if (mChatBarContainer->getName() != name) return LLPanel::notifyParent(info); const S32 new_width = info["new_width"]; @@ -420,8 +466,8 @@ void LLBottomTray::updateContextMenu(S32 x, S32 y, MASK mask) { LLUICtrl* edit_box = mNearbyChatBar->getChild<LLUICtrl>("chat_box"); - S32 local_x = x - mNearbyChatBar->getRect().mLeft - edit_box->getRect().mLeft; - S32 local_y = y - mNearbyChatBar->getRect().mBottom - edit_box->getRect().mBottom; + S32 local_x = x - mChatBarContainer->getRect().mLeft - edit_box->getRect().mLeft; + S32 local_y = y - mChatBarContainer->getRect().mBottom - edit_box->getRect().mBottom; bool in_edit_box = edit_box->pointInView(local_x, local_y); @@ -474,10 +520,14 @@ BOOL LLBottomTray::postBuild() mBottomTrayContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_bottomtray.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); gMenuHolder->addChild(mBottomTrayContextMenu); + mNearbyChatBar = findChild<LLNearbyChatBar>("chat_bar"); + LLHints::registerHintTarget("chat_bar", mNearbyChatBar->LLView::getHandle()); + + mChatBarContainer = getChild<LLLayoutPanel>("chat_bar_layout_panel"); - mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar"); mToolbarStack = getChild<LLLayoutStack>("toolbar_stack"); mMovementButton = getChild<LLButton>("movement_btn"); + LLHints::registerHintTarget("move_btn", mMovementButton->getHandle()); mCamButton = getChild<LLButton>("camera_btn"); setRightMouseDownCallback(boost::bind(&LLBottomTray::showBottomTrayContextMenu,this, _2, _3,_4)); @@ -510,11 +560,251 @@ BOOL LLBottomTray::postBuild() showWellButton(RS_IM_WELL, !LLIMWellWindow::getInstance()->isWindowEmpty()); showWellButton(RS_NOTIFICATION_WELL, !LLNotificationWellWindow::getInstance()->isWindowEmpty()); + loadButtonsOrder(); + LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&update_build_button_enable_state)); return TRUE; } +//Drag-n-drop + +void LLBottomTray::onDraggableButtonMouseDown(LLUICtrl* ctrl, S32 x, S32 y) +{ + if (ctrl == NULL) return; + LLView* parent_view = ctrl->getParent(); + if(parent_view != NULL) + { + // we actually drag'n'drop panel (not button) in code, so have to find a parent + // of button which called this method on mouse down. + LLPanel* parent = dynamic_cast<LLPanel*>(parent_view); + // It may happen that we clicked not usual button, but button inside widget(speak, gesture) + // so we'll need to get a level higher to reach layout panel as a parent. + if(parent == NULL) parent = dynamic_cast<LLPanel*>(parent_view->getParent()); + if (parent && parent->getVisible()) + { + mDraggedItem = parent; + mCheckForDrag = true; + mStartX = x; + mStartY = y; + } + } +} + +LLPanel* LLBottomTray::findChildPanelByLocalCoords(S32 x, S32 y) +{ + LLPanel* ctrl = 0; + S32 screenX, screenY; + const child_list_t* list = mToolbarStack->getChildList(); + + localPointToScreen(x, y, &screenX, &screenY); + + // look for a child panel which contains the point (screenX, screenY) in it's rectangle + for (child_list_const_iter_t i = list->begin(); i != list->end(); ++i) + { + LLRect rect; + localRectToScreen((*i)->getRect(), &rect); + + if (rect.pointInRect(screenX, screenY)) + { + ctrl = dynamic_cast<LLPanel*>(*i); + break; + } + } + + return ctrl; +} + +void LLBottomTray::onDraggableButtonHover(S32 x, S32 y) +{ + // if mouse down on draggable item was done, check whether we should start DnD + if (mCheckForDrag) + { + // Start drag'n'drop if mouse cursor was dragged away frome mouse down location enough + if(sqrt((float)((mStartX-x)*(mStartX-x)+(mStartY-y)*(mStartY-y))) > DRAG_START_DISTANCE) + { + mDragStarted = true; + mCheckForDrag = false; + } + } + if (mDragStarted) + { + // Check whether the cursor is over draggable area, find which panel it is and set is as + // landing tab for drag'n'drop + if(isCursorOverDraggableArea(x, y)) + { + LLPanel* panel = findChildPanelByLocalCoords(x,y); + if (panel && panel != mDraggedItem) mLandingTab = panel; + gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROWDRAG); + } + else + { + gViewerWindow->getWindow()->setCursor(UI_CURSOR_NO); + } + } +} + +bool LLBottomTray::isCursorOverDraggableArea(S32 x, S32 y) +{ + bool result = getRect().pointInRect(x, y); + result = result && mNearbyChatBar->calcScreenRect().mRight < x; + result = result && mChicletPanel->calcScreenRect().mRight > x; + return result; +} + +void LLBottomTray::updateButtonsOrdersAfterDnD() +{ + // *TODO: change implementation of this method to support simplify it + // (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 landing_state = RS_NORESIZE; + bool landing_state_found = false; + // Find states for dragged item and landing tab + for (; it != it_end; ++it) + { + if (it->second == mDraggedItem) + { + dragged_state = it->first; + } + else if (it->second == mLandingTab) + { + landing_state = it->first; + landing_state_found = true; + } + } + + // 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)) + { + mButtonsOrder.push_back(dragged_state); + } + else + { + if (!landing_state_found) landing_state = RS_BUTTON_SPEAK; + 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(); + resize_state_vec_t::iterator it2 = mButtonsProcessOrder.begin(); + for (; it1 != it_end1; ++it1) + { + // Skip Speak because it is not in mButtonsProcessOrder(it's the reason why mButtonsOrder was introduced). + // If any other draggable items will be added to bottomtray later, they should also be skipped here. + if (*it1 != RS_BUTTON_SPEAK) + { + *it2 = *it1; + ++it2; + } + } + + saveButtonsOrder(); +} + +void LLBottomTray::saveButtonsOrder() +{ + std::string user_dir = gDirUtilp->getLindenUserDir(); + if (user_dir.empty()) return; + + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME); + LLSD settings_llsd; + int i = 0; + const resize_state_vec_t::const_iterator it_end = mButtonsOrder.end(); + // we use numbers as keys for map which is saved in file and contains resize states as its values + for (resize_state_vec_t::const_iterator it = mButtonsOrder.begin(); it != it_end; ++it, i++) + { + std::string str = llformat("%d", i); + settings_llsd[str] = *it; + } + llofstream file; + file.open(filename); + LLSDSerialize::toPrettyXML(settings_llsd, file); +} + +void LLBottomTray::loadButtonsOrder() +{ + // load per-resident sorting information + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME); + + LLSD settings_llsd; + llifstream file; + file.open(filename); + if (!file.is_open()) return; + + LLSDSerialize::fromXML(settings_llsd, file); + + + mButtonsOrder.clear(); + mButtonsProcessOrder.clear(); + int i = 0; + // getting button order from file + for (LLSD::map_const_iterator iter = settings_llsd.beginMap(); + iter != settings_llsd.endMap(); ++iter, ++i) + { + std::string str = llformat("%d", i); + EResizeState state = (EResizeState)settings_llsd[str].asInteger(); + mButtonsOrder.push_back(state); + // RS_BUTTON_SPEAK is skipped, because it shouldn't be in mButtonsProcessOrder (it does not hide or shrink). + if (state != RS_BUTTON_SPEAK) + { + mButtonsProcessOrder.push_back(state); + } + } + + // There are other panels in layout stack order of which is not saved. Also, panels order of which is saved, + // are already in layout stack but in wrong order. The most convenient way to place them is moving them + // to front one by one (because in this case we don't have to pass the panel before which we want to insert our + // panel to movePanel()). So panels are moved in order from the end of mButtonsOrder vector(reverse iterator is used). + const resize_state_vec_t::const_reverse_iterator it_end = mButtonsOrder.rend(); + // 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]; + 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 + mToolbarStack->movePanel(mChatBarContainer, NULL, true); +} + +void LLBottomTray::onDraggableButtonMouseUp(LLUICtrl* ctrl, S32 x, S32 y) +{ + //if mouse up happened over area where drop is possible, change order of buttons + if (mLandingTab != NULL && mDraggedItem != NULL && mDragStarted) + { + if(isCursorOverDraggableArea(x, y)) + { + // change order of panels in layout stack + mToolbarStack->movePanel(mDraggedItem, (LLPanel*)mLandingTab); + // change order of buttons in order vectors + updateButtonsOrdersAfterDnD(); + } + } + gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); + mDragStarted = false; + mDraggedItem = NULL; + mLandingTab = NULL; + mCheckForDrag = false; +} + +void LLBottomTray::draw() +{ + LLPanel::draw(); + if (mLandingTab) + { + static S32 w = mImageDragIndication->getWidth(); + static S32 h = mImageDragIndication->getHeight(); + LLRect rect = mLandingTab->calcScreenRect(); + mImageDragIndication->draw(rect.mLeft - w/2, rect.getHeight(), w, h); + } +} + bool LLBottomTray::onContextMenuItemEnabled(const LLSD& userdata) { std::string item = userdata.asString(); @@ -679,14 +969,15 @@ void LLBottomTray::reshape(S32 width, S32 height, BOOL called_from_parent) // we can not to do this from postBuild because reshape is called from parent view on startup // creation after it and reset width according to resize logic. static bool needs_restore_custom_state = true; - if (mNearbyChatBar && needs_restore_custom_state) + if (mChatBarContainer && needs_restore_custom_state) { // restore custom width of chatbar panel. S32 new_width = gSavedSettings.getS32("ChatBarCustomWidth"); if (new_width > 0) { + mDesiredNearbyChatWidth = new_width; processChatbarCustomization(new_width); - mNearbyChatBar->reshape(new_width, mNearbyChatBar->getRect().getHeight()); + mChatBarContainer->reshape(new_width, mChatBarContainer->getRect().getHeight()); } needs_restore_custom_state = false; } @@ -700,6 +991,9 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width) const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth(); const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth(); + // There are four steps of processing width decrease. If in one of them required width was reached, + // further are not needed. + // 1. Decreasing width of chiclet panel. if (chiclet_panel_width > chiclet_panel_min_width) { // we have some space to decrease chiclet panel @@ -725,8 +1019,15 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width) << llendl; } - const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth(); - const S32 chatbar_panel_min_width = get_panel_min_width(mToolbarStack, mNearbyChatBar); + S32 buttons_freed_width = 0; + // 2. Decreasing width of buttons. + if (still_should_be_processed) + { + processShrinkButtons(delta_width, buttons_freed_width); + } + // 3. Decreasing width of nearby chat. + const S32 chatbar_panel_min_width = get_panel_min_width(mToolbarStack, mChatBarContainer); + const S32 chatbar_panel_width = mChatBarContainer->getRect().getWidth(); if (still_should_be_processed && chatbar_panel_width > chatbar_panel_min_width) { // we have some space to decrease chatbar panel @@ -739,7 +1040,11 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width) still_should_be_processed = delta_width < 0; - mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() - delta_panel, mNearbyChatBar->getRect().getHeight()); + // chatbar should only be shrunk here, not stretched + if(delta_panel > 0) + { + mChatBarContainer->reshape(mNearbyChatBar->getRect().getWidth() - delta_panel, mChatBarContainer->getRect().getHeight()); + } log(mNearbyChatBar, "after processing panel decreasing via nearby chatbar panel"); @@ -750,11 +1055,9 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width) } S32 extra_shrink_width = 0; - S32 buttons_freed_width = 0; + // 4. Hiding buttons if needed. if (still_should_be_processed) { - processShrinkButtons(delta_width, buttons_freed_width); - processHideButtons(delta_width, buttons_freed_width); if (delta_width < 0) @@ -766,10 +1069,15 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width) if (buttons_freed_width > 0) { - log(mNearbyChatBar, "before applying compensative width"); - mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() + buttons_freed_width, mNearbyChatBar->getRect().getHeight() ); - log(mNearbyChatBar, "after applying compensative width"); - lldebugs << buttons_freed_width << llendl; + S32 nearby_needed_width = mDesiredNearbyChatWidth - mNearbyChatBar->getRect().getWidth(); + if (nearby_needed_width > 0) + { + S32 compensative_width = nearby_needed_width > buttons_freed_width ? buttons_freed_width : nearby_needed_width; + log(mNearbyChatBar, "before applying compensative width"); + mChatBarContainer->reshape(mChatBarContainer->getRect().getWidth() + compensative_width, mChatBarContainer->getRect().getHeight() ); + log(mNearbyChatBar, "after applying compensative width"); + lldebugs << buttons_freed_width << llendl; + } } } @@ -783,18 +1091,12 @@ void LLBottomTray::processWidthIncreased(S32 delta_width) const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth(); static const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth(); - const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth(); - static const S32 chatbar_panel_min_width = get_panel_min_width(mToolbarStack, mNearbyChatBar); - static const S32 chatbar_panel_max_width = get_panel_max_width(mToolbarStack, mNearbyChatBar); - - const S32 chatbar_available_shrink_width = chatbar_panel_width - chatbar_panel_min_width; const S32 available_width_chiclet = chiclet_panel_width - chiclet_panel_min_width; // how many room we have to show hidden buttons - S32 total_available_width = delta_width + chatbar_available_shrink_width + available_width_chiclet; + S32 total_available_width = delta_width + available_width_chiclet; lldebugs << "Processing extending, available width:" - << ", chatbar - " << chatbar_available_shrink_width << ", chiclets - " << available_width_chiclet << ", total - " << total_available_width << llendl; @@ -803,8 +1105,6 @@ void LLBottomTray::processWidthIncreased(S32 delta_width) processShowButtons(available_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) @@ -815,21 +1115,7 @@ void LLBottomTray::processWidthIncreased(S32 delta_width) // 1. use delta width of resizing required_to_process_width -= delta_width; - // 2. use width available via decreasing of nearby chat panel - S32 chatbar_shrink_width = required_to_process_width; - if (chatbar_available_shrink_width < chatbar_shrink_width) - { - chatbar_shrink_width = chatbar_available_shrink_width; - } - - log(mNearbyChatBar, "increase width: before applying compensative width"); - mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() - chatbar_shrink_width, mNearbyChatBar->getRect().getHeight() ); - if (mNearbyChatBar) log(mNearbyChatBar, "after applying compensative width"); - lldebugs << chatbar_shrink_width << llendl; - - // 3. use width available via decreasing of chiclet panel - required_to_process_width -= chatbar_shrink_width; - + // 2. use width available via decreasing of chiclet panel if (required_to_process_width > 0) { mChicletPanel->getParent()->reshape(mChicletPanel->getParent()->getRect().getWidth() - required_to_process_width, mChicletPanel->getParent()->getRect().getHeight()); @@ -844,10 +1130,10 @@ void LLBottomTray::processWidthIncreased(S32 delta_width) // how many space can nearby chatbar take? - S32 chatbar_panel_width_ = mNearbyChatBar->getRect().getWidth(); - if (delta_width > 0 && chatbar_panel_width_ < chatbar_panel_max_width) + S32 chatbar_panel_width_ = mChatBarContainer->getRect().getWidth(); + if (delta_width > 0 && chatbar_panel_width_ < mDesiredNearbyChatWidth) { - S32 delta_panel_max = chatbar_panel_max_width - chatbar_panel_width_; + S32 delta_panel_max = mDesiredNearbyChatWidth - 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 @@ -855,9 +1141,13 @@ void LLBottomTray::processWidthIncreased(S32 delta_width) << llendl; delta_width -= delta_panel_max; - mNearbyChatBar->reshape(chatbar_panel_width_ + delta_panel, mNearbyChatBar->getRect().getHeight()); + mChatBarContainer->reshape(chatbar_panel_width_ + delta_panel, mChatBarContainer->getRect().getHeight()); log(mNearbyChatBar, "applied unprocessed delta width"); } + if (delta_width > 0) + { + processExtendButtons(delta_width); + } } void LLBottomTray::processShowButtons(S32& available_width) @@ -977,7 +1267,7 @@ void LLBottomTray::processShrinkButtons(S32& required_width, S32& buttons_freed_ S32 panel_min_width = 0; std::string panel_name = mSpeakPanel->getName(); - bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width, NULL); + bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width); if (!success) { lldebugs << "Panel was not found to get its min width: " << panel_name << llendl; @@ -1023,7 +1313,7 @@ void LLBottomTray::processShrinkButton(EResizeState processed_object_type, S32& S32 panel_width = panel->getRect().getWidth(); S32 panel_min_width = 0; std::string panel_name = panel->getName(); - bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width, NULL); + bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width); S32 possible_shrink_width = panel_width - panel_min_width; if (!success) @@ -1187,6 +1477,9 @@ void LLBottomTray::initResizeStateContainers() mButtonsProcessOrder.push_back(RS_BUTTON_WORLD_MAP); mButtonsProcessOrder.push_back(RS_BUTTON_MINI_MAP); + mButtonsOrder.push_back(RS_BUTTON_SPEAK); + mButtonsOrder.insert(mButtonsOrder.end(), mButtonsProcessOrder.begin(), mButtonsProcessOrder.end()); + // init default widths // process buttons that can be hidden on resize... @@ -1239,7 +1532,7 @@ void LLBottomTray::setButtonsControlsAndListeners() // set control name for Build button. It is not enough to link it with Button.SetFloaterToggle in xml std::string vis_control_name = LLFloaterReg::declareVisibilityControl("build"); // Set the button control value (toggle state) to the floater visibility control (Sets the value as well) - build_btn->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name)); + build_btn->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name)); } bool LLBottomTray::toggleShowButton(LLBottomTray::EResizeState button_type, const LLSD& new_visibility) @@ -1312,7 +1605,7 @@ bool LLBottomTray::setVisibleAndFitWidths(EResizeState object_type, bool visible { // Calculate the possible shrunk width as difference between current and minimal widths const S32 chatbar_shrunk_width = - mNearbyChatBar->getRect().getWidth() - get_panel_min_width(mToolbarStack, mNearbyChatBar); + mChatBarContainer->getRect().getWidth() - get_panel_min_width(mToolbarStack, mChatBarContainer); S32 sum_of_min_widths = get_panel_min_width(mToolbarStack, mSpeakPanel); S32 sum_of_curr_widths = get_curr_width(mSpeakPanel); @@ -1332,7 +1625,7 @@ bool LLBottomTray::setVisibleAndFitWidths(EResizeState object_type, bool visible // Minimal width of current panel S32 minimal_width = 0; - mToolbarStack->getPanelMinSize(cur_panel->getName(), &minimal_width, NULL); + mToolbarStack->getPanelMinSize(cur_panel->getName(), &minimal_width); if ( (available_width + possible_shrunk_width) >= minimal_width) { @@ -1409,10 +1702,12 @@ void LLBottomTray::processChatbarCustomization(S32 new_width) { if (NULL == mNearbyChatBar) return; - const S32 delta_width = mNearbyChatBar->getRect().getWidth() - new_width; + const S32 delta_width = mChatBarContainer->getRect().getWidth() - new_width; if (delta_width == 0) return; + mDesiredNearbyChatWidth = new_width; + LLView * chiclet_layout_panel = mChicletPanel->getParent(); const S32 chiclet_min_width = get_panel_min_width(mToolbarStack, chiclet_layout_panel); const S32 chiclet_panel_width = chiclet_layout_panel->getRect().getWidth(); |