diff options
Diffstat (limited to 'indra/newview/llnavigationbar.cpp')
-rw-r--r-- | indra/newview/llnavigationbar.cpp | 794 |
1 files changed, 573 insertions, 221 deletions
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index cf1d9a5d86..58849393b4 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -2,31 +2,25 @@ * @file llnavigationbar.cpp * @brief Navigation bar 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. * - * 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 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. * - * 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. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,23 +28,43 @@ #include "llnavigationbar.h" -#include <llfloaterreg.h> -#include <llfocusmgr.h> -#include <lliconctrl.h> -#include <llmenugl.h> -#include <llwindow.h> +#include "v2math.h" + +#include "llregionhandle.h" + +#include "llfloaterreg.h" +#include "llfocusmgr.h" +#include "lliconctrl.h" +#include "llmenugl.h" #include "llagent.h" -#include "llfloaterhtmlhelp.h" +#include "llviewerregion.h" +#include "lllandmarkactions.h" #include "lllocationhistory.h" #include "lllocationinputctrl.h" +#include "llpaneltopinfobar.h" #include "llteleporthistory.h" +#include "llsearchcombobox.h" +#include "llsidetray.h" #include "llslurl.h" -#include "llurlsimstring.h" +#include "llurlregistry.h" +#include "llurldispatcher.h" #include "llviewerinventory.h" #include "llviewermenu.h" #include "llviewerparcelmgr.h" -#include "llworldmap.h" +#include "llworldmapmessage.h" +#include "llappviewer.h" +#include "llviewercontrol.h" +#include "llfloatermediabrowser.h" +#include "llweb.h" + +#include "llinventorymodel.h" +#include "lllandmarkactions.h" + +#include "llfavoritesbar.h" +#include "llagentui.h" + +#include <boost/regex.hpp> //-- LLTeleportHistoryMenuItem ----------------------------------------------- @@ -69,10 +83,24 @@ public: struct Params : public LLInitParam::Block<Params, LLMenuItemCallGL::Params> { - Mandatory<EType> item_type; - - Params() {} - Params(EType type, std::string title); + Mandatory<EType> item_type; + Optional<const LLFontGL*> back_item_font, + current_item_font, + forward_item_font; + Optional<std::string> back_item_image, + forward_item_image; + Optional<S32> image_hpad, + image_vpad; + Params() + : item_type(), + back_item_font("back_item_font"), + current_item_font("current_item_font"), + forward_item_font("forward_item_font"), + back_item_image("back_item_image"), + forward_item_image("forward_item_image"), + image_hpad("image_hpad"), + image_vpad("image_vpad") + {} }; /*virtual*/ void draw(); @@ -85,48 +113,47 @@ private: static const S32 ICON_WIDTH = 16; static const S32 ICON_HEIGHT = 16; - static const std::string ICON_IMG_BACKWARD; - static const std::string ICON_IMG_FORWARD; LLIconCtrl* mArrowIcon; }; -const std::string LLTeleportHistoryMenuItem::ICON_IMG_BACKWARD("teleport_history_backward.tga"); -const std::string LLTeleportHistoryMenuItem::ICON_IMG_FORWARD("teleport_history_forward.tga"); - -LLTeleportHistoryMenuItem::Params::Params(EType type, std::string title) -{ - item_type(type); - font.name("SansSerif"); - - if (type == TYPE_CURRENT) - font.style("BOLD"); - else - title = " " + title; +static LLDefaultChildRegistry::Register<LLTeleportHistoryMenuItem> r("teleport_history_menu_item"); - name(title); - label(title); -} LLTeleportHistoryMenuItem::LLTeleportHistoryMenuItem(const Params& p) : LLMenuItemCallGL(p), mArrowIcon(NULL) { + // Set appearance depending on the item type. + if (p.item_type == TYPE_BACKWARD) + { + setFont( p.back_item_font ); + } + else if (p.item_type == TYPE_CURRENT) + { + setFont( p.current_item_font ); + } + else + { + setFont( p.forward_item_font ); + } + LLIconCtrl::Params icon_params; icon_params.name("icon"); - icon_params.rect(LLRect(0, ICON_HEIGHT, ICON_WIDTH, 0)); + LLRect rect(0, ICON_HEIGHT, ICON_WIDTH, 0); + rect.translate( p.image_hpad, p.image_vpad ); + icon_params.rect( rect ); icon_params.mouse_opaque(false); icon_params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP); - icon_params.tab_stop(false); icon_params.visible(false); mArrowIcon = LLUICtrlFactory::create<LLIconCtrl> (icon_params); // no image for the current item if (p.item_type == TYPE_BACKWARD) - mArrowIcon->setValue(ICON_IMG_BACKWARD); + mArrowIcon->setValue( p.back_item_image() ); else if (p.item_type == TYPE_FORWARD) - mArrowIcon->setValue(ICON_IMG_FORWARD); + mArrowIcon->setValue( p.forward_item_image() ); addChild(mArrowIcon); } @@ -150,93 +177,151 @@ void LLTeleportHistoryMenuItem::onMouseLeave(S32 x, S32 y, MASK mask) mArrowIcon->setVisible(FALSE); } -//-- LNavigationBar ---------------------------------------------------------- +static LLDefaultChildRegistry::Register<LLPullButton> menu_button("pull_button"); -/* -TODO: -- Load navbar height from saved settings (as it's done for status bar) or think of a better way. -*/ +LLPullButton::LLPullButton(const LLPullButton::Params& params) : + LLButton(params) +{ + setDirectionFromName(params.direction); +} +boost::signals2::connection LLPullButton::setClickDraggingCallback(const commit_signal_t::slot_type& cb) +{ + return mClickDraggingSignal.connect(cb); +} + +/*virtual*/ +void LLPullButton::onMouseLeave(S32 x, S32 y, MASK mask) +{ + LLButton::onMouseLeave(x, y, mask); -S32 NAVIGATION_BAR_HEIGHT = 60; // *HACK -LLNavigationBar* LLNavigationBar::sInstance = 0; + if (mMouseDownTimer.getStarted()) //an user have done a mouse down, if the timer started. see LLButton::handleMouseDown for details + { + const LLVector2 cursor_direction = LLVector2(F32(x), F32(y)) - mLastMouseDown; + /* For now cursor_direction points to the direction of mouse movement + * Need to decide whether should we fire a signal. + * We fire if angle between mDraggingDirection and cursor_direction is less that 45 degree + * Note: + * 0.5 * F_PI_BY_TWO equals to PI/4 radian that equals to angle of 45 degrees + */ + if (angle_between(mDraggingDirection, cursor_direction) < 0.5 * F_PI_BY_TWO)//call if angle < pi/4 + { + mClickDraggingSignal(this, LLSD()); + } + } -LLNavigationBar* LLNavigationBar::getInstance() +} + +/*virtual*/ +BOOL LLPullButton::handleMouseDown(S32 x, S32 y, MASK mask) { - if (!sInstance) - sInstance = new LLNavigationBar(); + BOOL handled = LLButton::handleMouseDown(x, y, mask); + if (handled) + { + //if mouse down was handled by button, + //capture mouse position to calculate the direction of mouse move after mouseLeave event + mLastMouseDown.set(F32(x), F32(y)); + } + return handled; +} - return sInstance; +/*virtual*/ +BOOL LLPullButton::handleMouseUp(S32 x, S32 y, MASK mask) +{ + // reset data to get ready for next circle + mLastMouseDown.clear(); + return LLButton::handleMouseUp(x, y, mask); +} +/** + * this function is setting up dragging direction vector. + * Last one is just unit vector. It points to direction of mouse drag that we need to handle + */ +void LLPullButton::setDirectionFromName(const std::string& name) +{ + if (name == "left") + { + mDraggingDirection.set(F32(-1), F32(0)); + } + else if (name == "right") + { + mDraggingDirection.set(F32(0), F32(1)); + } + else if (name == "down") + { + mDraggingDirection.set(F32(0), F32(-1)); + } + else if (name == "up") + { + mDraggingDirection.set(F32(0), F32(1)); + } } +//-- LNavigationBar ---------------------------------------------------------- + +/* +TODO: +- Load navbar height from saved settings (as it's done for status bar) or think of a better way. +*/ + LLNavigationBar::LLNavigationBar() : mTeleportHistoryMenu(NULL), - mLocationContextMenu(NULL), mBtnBack(NULL), mBtnForward(NULL), mBtnHome(NULL), - mBtnHelp(NULL), mCmbLocation(NULL), - mLeSearch(NULL) + mSearchComboBox(NULL), + mPurgeTPHistoryItems(false), + mSaveToLocationHistory(false) { - setIsChrome(TRUE); - - // Register callbacks and load the location field context menu (NB: the order matters). - mCommitCallbackRegistrar.add("Navbar.Action", boost::bind(&LLNavigationBar::onLocationContextMenuItemClicked, this, _2)); - mEnableCallbackRegistrar.add("Navbar.EnableMenuItem", boost::bind(&LLNavigationBar::onLocationContextMenuItemEnabled, this, _2)); - - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_navigation_bar.xml"); + buildFromFile( "panel_navigation_bar.xml"); - // navigation bar can never get a tab - setFocusRoot(FALSE); + // set a listener function for LoginComplete event + LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLNavigationBar::handleLoginComplete, this)); + + // Necessary for focus movement among child controls + setFocusRoot(TRUE); } LLNavigationBar::~LLNavigationBar() { - sInstance = 0; + mTeleportFinishConnection.disconnect(); + mTeleportFailedConnection.disconnect(); } BOOL LLNavigationBar::postBuild() { - mBtnBack = getChild<LLButton>("back_btn"); - mBtnForward = getChild<LLButton>("forward_btn"); + mBtnBack = getChild<LLPullButton>("back_btn"); + mBtnForward = getChild<LLPullButton>("forward_btn"); mBtnHome = getChild<LLButton>("home_btn"); - mBtnHelp = getChild<LLButton>("help_btn"); mCmbLocation= getChild<LLLocationInputCtrl>("location_combo"); - mLeSearch = getChild<LLLineEditor>("search_input"); - - LLButton* search_btn = getChild<LLButton>("search_btn"); + mSearchComboBox = getChild<LLSearchComboBox>("search_combo_box"); + + fillSearchComboBox(); - if (!mBtnBack || !mBtnForward || !mBtnHome || !mBtnHelp || - !mCmbLocation || !mLeSearch || !search_btn) - { - llwarns << "Malformed navigation bar" << llendl; - return FALSE; - } - mBtnBack->setEnabled(FALSE); mBtnBack->setClickedCallback(boost::bind(&LLNavigationBar::onBackButtonClicked, this)); - mBtnBack->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _2)); - + mBtnBack->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this,_1, _2)); + mBtnBack->setClickDraggingCallback(boost::bind(&LLNavigationBar::showTeleportHistoryMenu, this,_1)); + mBtnForward->setEnabled(FALSE); mBtnForward->setClickedCallback(boost::bind(&LLNavigationBar::onForwardButtonClicked, this)); - mBtnForward->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _2)); + mBtnForward->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _1, _2)); + mBtnForward->setClickDraggingCallback(boost::bind(&LLNavigationBar::showTeleportHistoryMenu, this,_1)); mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this)); - mBtnHelp->setClickedCallback(boost::bind(&LLNavigationBar::onHelpButtonClicked, this)); - mCmbLocation->setSelectionCallback(boost::bind(&LLNavigationBar::onLocationSelection, this)); + mCmbLocation->setCommitCallback(boost::bind(&LLNavigationBar::onLocationSelection, this)); - mLeSearch->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this)); - search_btn->setClickedCallback(boost::bind(&LLNavigationBar::onSearchCommit, this)); + mSearchComboBox->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this)); - // Load the location field context menu - mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_navbar.xml", gMenuHolder); - if (!mLocationContextMenu) - { - llwarns << "Error loading navigation bar context menu" << llendl; - return FALSE; - } + mTeleportFinishConnection = LLViewerParcelMgr::getInstance()-> + setTeleportFinishedCallback(boost::bind(&LLNavigationBar::onTeleportFinished, this, _1)); + + mTeleportFailedConnection = LLViewerParcelMgr::getInstance()-> + setTeleportFailedCallback(boost::bind(&LLNavigationBar::onTeleportFailed, this)); + + mDefaultNbRect = getRect(); + mDefaultFpRect = getChild<LLFavoritesBarCtrl>("favorite")->getRect(); // we'll be notified on teleport history changes LLTeleportHistory::getInstance()->setHistoryChangedCallback( @@ -245,30 +330,69 @@ BOOL LLNavigationBar::postBuild() return TRUE; } +void LLNavigationBar::setVisible(BOOL visible) +{ + // change visibility of grandparent layout_panel to animate in and out + if (getParent()) + { + //to avoid some mysterious bugs like EXT-3352, at least try to log an incorrect parent to ping about a problem. + if(getParent()->getName() != "nav_bar_container") + { + LL_WARNS("LLNavigationBar")<<"NavigationBar has an unknown name of the parent: "<<getParent()->getName()<< LL_ENDL; + } + getParent()->setVisible(visible); + } +} + + +void LLNavigationBar::fillSearchComboBox() +{ + if(!mSearchComboBox) + { + return; + } + + LLSearchHistory::getInstance()->load(); + + LLSearchHistory::search_history_list_t search_list = + LLSearchHistory::getInstance()->getSearchHistoryList(); + LLSearchHistory::search_history_list_t::const_iterator it = search_list.begin(); + for( ; search_list.end() != it; ++it) + { + LLSearchHistory::LLSearchHistoryItem item = *it; + mSearchComboBox->add(item.search_query); + } +} + void LLNavigationBar::draw() { + if(mPurgeTPHistoryItems) + { + LLTeleportHistory::getInstance()->purgeItems(); + mPurgeTPHistoryItems = false; + } + + if (isBackgroundVisible()) + { + static LLUICachedControl<S32> drop_shadow_floater ("DropShadowFloater", 0); + static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow"); + gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, + color_drop_shadow, drop_shadow_floater ); + } + LLPanel::draw(); } BOOL LLNavigationBar::handleRightMouseDown(S32 x, S32 y, MASK mask) { - // *HACK. We should use mCmbLocation's right click callback instead. - - // If the location field is clicked then show its context menu. - if (mCmbLocation->getRect().pointInRect(x, y)) + BOOL handled = childrenHandleRightMouseDown( x, y, mask) != NULL; + if(!handled && !gMenuHolder->hasVisibleMenu()) { - // Pass the focus to the line editor when it is right-clicked - mCmbLocation->setFocus(TRUE); - - if (mLocationContextMenu) - { - mLocationContextMenu->buildDrawLabels(); - mLocationContextMenu->updateParent(LLMenuGL::sMenuContainer); - LLMenuGL::showPopup(this, mLocationContextMenu, x, y); - } - return TRUE; + show_navbar_context_menu(this,x,y); + handled = true; } - return LLPanel:: handleRightMouseDown(x, y, mask); + + return handled; } void LLNavigationBar::onBackButtonClicked() @@ -276,10 +400,10 @@ void LLNavigationBar::onBackButtonClicked() LLTeleportHistory::getInstance()->goBack(); } -void LLNavigationBar::onBackOrForwardButtonHeldDown(const LLSD& param) +void LLNavigationBar::onBackOrForwardButtonHeldDown(LLUICtrl* ctrl, const LLSD& param) { if (param["count"].asInteger() == 0) - showTeleportHistoryMenu(); + showTeleportHistoryMenu(ctrl); } void LLNavigationBar::onForwardButtonClicked() @@ -292,14 +416,14 @@ void LLNavigationBar::onHomeButtonClicked() gAgent.teleportHome(); } -void LLNavigationBar::onHelpButtonClicked() -{ - gViewerHtmlHelp.show(); -} - void LLNavigationBar::onSearchCommit() { - invokeSearch(mLeSearch->getText()); + std::string search_query = mSearchComboBox->getSimple(); + if(!search_query.empty()) + { + LLSearchHistory::getInstance()->addEntry(search_query); + } + invokeSearch(search_query); } void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata) @@ -313,36 +437,142 @@ void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata) void LLNavigationBar::onLocationSelection() { std::string typed_location = mCmbLocation->getSimple(); + LLStringUtil::trim(typed_location); // Will not teleport to empty location. if (typed_location.empty()) return; + //get selected item from combobox item + LLSD value = mCmbLocation->getSelectedValue(); + if(value.isUndefined() && !mCmbLocation->getTextEntry()->isDirty()) + { + // At this point we know that: there is no selected item in list and text field has NOT been changed + // So there is no sense to try to change the location + return; + } + /* since navbar list support autocompletion it contains several types of item: landmark, teleport hystory item, + * typed by user slurl or region name. Let's find out which type of item the user has selected + * to make decision about adding this location into typed history. see mSaveToLocationHistory + * Note: + * Only TYPED_REGION_SLURL item will be added into LLLocationHistory + */ + + if(value.has("item_type")) + { + switch(value["item_type"].asInteger()) + { + case LANDMARK: + + if(value.has("AssetUUID")) + { + + gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString())); + return; + } + else + { + LLInventoryModel::item_array_t landmark_items = + LLLandmarkActions::fetchLandmarksByName(typed_location, + FALSE); + if (!landmark_items.empty()) + { + gAgent.teleportViaLandmark( landmark_items[0]->getAssetUUID()); + return; + } + } + break; + + case TELEPORT_HISTORY: + //in case of teleport item was selected, teleport by position too. + case TYPED_REGION_SLURL: + if(value.has("global_pos")) + { + gAgent.teleportViaLocation(LLVector3d(value["global_pos"])); + return; + } + break; + + default: + break; + } + } + //Let's parse slurl or region name + std::string region_name; LLVector3 local_coords(128, 128, 0); - // Is the typed location a SLURL? - if (LLSLURL::isSLURL(typed_location)) + LLSLURL slurl = LLSLURL(typed_location); + if (slurl.getType() == LLSLURL::LOCATION) { - // Yes. Extract region name and local coordinates from it. - S32 x = 0, y = 0, z = 0; - if (LLURLSimString::parse(LLSLURL::stripProtocol(typed_location), ®ion_name, &x, &y, &z)) - local_coords.set(x, y, z); - else - return; + region_name = slurl.getRegion(); + local_coords = slurl.getPosition(); + } + else if(!slurl.isValid()) + { + // we have to do this check after previous, because LLUrlRegistry contains handlers for slurl too + // but we need to know whether typed_location is a simple http url. + if (LLUrlRegistry::instance().isUrl(typed_location)) + { + // display http:// URLs in the media browser, or + // anything else is sent to the search floater + LLWeb::loadURL(typed_location); + return; + } + else + { + // assume that an user has typed the {region name} or possible {region_name, parcel} + region_name = typed_location.substr(0,typed_location.find(',')); + } } else { - // Treat it as region name. - region_name = typed_location; + // was an app slurl, home, whatever. Bail + return; } - + // Resolve the region name to its global coordinates. // If resolution succeeds we'll teleport. - LLWorldMap::url_callback_t cb = boost::bind( + LLWorldMapMessage::url_callback_t cb = boost::bind( &LLNavigationBar::onRegionNameResponse, this, typed_location, region_name, local_coords, _1, _2, _3, _4); - LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, cb, std::string("unused"), false); + mSaveToLocationHistory = true; + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name, cb, std::string("unused"), false); +} + +void LLNavigationBar::onTeleportFailed() +{ + mSaveToLocationHistory = false; +} + +void LLNavigationBar::onTeleportFinished(const LLVector3d& global_agent_pos) +{ + if (!mSaveToLocationHistory) + return; + LLLocationHistory* lh = LLLocationHistory::getInstance(); + + //TODO*: do we need convert slurl into readable format? + std::string location; + /*NOTE: + * We can't use gAgent.getPositionAgent() in case of local teleport to build location. + * At this moment gAgent.getPositionAgent() contains previous coordinates. + * according to EXT-65 agent position is being reseted on each frame. + */ + LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_NO_MATURITY, + gAgent.getPosAgentFromGlobal(global_agent_pos)); + std::string tooltip (LLSLURL(gAgent.getRegion()->getName(), global_agent_pos).getSLURLString()); + + LLLocationHistoryItem item (location, + global_agent_pos, tooltip,TYPED_REGION_SLURL);// we can add into history only TYPED location + //Touch it, if it is at list already, add new location otherwise + if ( !lh->touchItem(item) ) { + lh->addItem(item); + } + + lh->save(); + + mSaveToLocationHistory = false; + } void LLNavigationBar::onTeleportHistoryChanged() @@ -392,9 +622,13 @@ void LLNavigationBar::rebuildTeleportHistoryMenu() else type = LLTeleportHistoryMenuItem::TYPE_CURRENT; - LLTeleportHistoryMenuItem::Params item_params(type, hist_items[i].mTitle); + LLTeleportHistoryMenuItem::Params item_params; + item_params.label = item_params.name = hist_items[i].mTitle; + item_params.item_type = type; item_params.on_click.function(boost::bind(&LLNavigationBar::onTeleportHistoryMenuItemClicked, this, i)); - mTeleportHistoryMenu->addChild(LLUICtrlFactory::create<LLTeleportHistoryMenuItem>(item_params)); + LLTeleportHistoryMenuItem* new_itemp = LLUICtrlFactory::create<LLTeleportHistoryMenuItem>(item_params); + //new_itemp->setFont() + mTeleportHistoryMenu->addChild(new_itemp); } } @@ -411,25 +645,15 @@ void LLNavigationBar::onRegionNameResponse( return; } - // Location is valid. Add it to the typed locations history. - S32 selected_item = mCmbLocation->getCurrentIndex(); - if (selected_item == -1) // user has typed text - { - LLLocationHistory* lh = LLLocationHistory::getInstance(); - mCmbLocation->add(typed_location); - lh->addItem(typed_location); - lh->save(); - } - // Teleport to the location. LLVector3d region_pos = from_region_handle(region_handle); LLVector3d global_pos = region_pos + (LLVector3d) local_coords; - - llinfos << "Teleporting to: " << global_pos << llendl; + + llinfos << "Teleporting to: " << LLSLURL(region_name, global_pos).getSLURLString() << llendl; gAgent.teleportViaLocation(global_pos); } -void LLNavigationBar::showTeleportHistoryMenu() +void LLNavigationBar::showTeleportHistoryMenu(LLUICtrl* btn_ctrl) { // Don't show the popup if teleport history is empty. if (LLTeleportHistory::getInstance()->isEmpty()) @@ -443,91 +667,219 @@ void LLNavigationBar::showTeleportHistoryMenu() if (mTeleportHistoryMenu == NULL) return; - // *TODO: why to draw/update anything before showing the menu? - mTeleportHistoryMenu->buildDrawLabels(); mTeleportHistoryMenu->updateParent(LLMenuGL::sMenuContainer); - LLRect btnBackRect = mBtnBack->getRect(); - LLMenuGL::showPopup(this, mTeleportHistoryMenu, btnBackRect.mLeft, btnBackRect.mBottom); - + const S32 MENU_SPAWN_PAD = -1; + LLMenuGL::showPopup(btn_ctrl, mTeleportHistoryMenu, 0, MENU_SPAWN_PAD); + LLButton* nav_button = dynamic_cast<LLButton*>(btn_ctrl); + if(nav_button) + { + if(mHistoryMenuConnection.connected()) + { + LL_WARNS("Navgationbar")<<"mHistoryMenuConnection should be disconnected at this moment."<<LL_ENDL; + mHistoryMenuConnection.disconnect(); + } + mHistoryMenuConnection = gMenuHolder->setMouseUpCallback(boost::bind(&LLNavigationBar::onNavigationButtonHeldUp, this, nav_button)); + // pressed state will be update after mouseUp in onBackOrForwardButtonHeldUp(); + nav_button->setForcePressedState(true); + } // *HACK pass the mouse capturing to the drop-down menu - gFocusMgr.setMouseCapture( NULL ); + // it need to let menu handle mouseup event + gFocusMgr.setMouseCapture(gMenuHolder); } - -void LLNavigationBar::onLocationContextMenuItemClicked(const LLSD& userdata) +/** + * Taking into account the HACK above, this callback-function is responsible for correct handling of mouseUp event in case of holding-down the navigation buttons.. + * We need to process this case separately to update a pressed state of navigation button. + */ +void LLNavigationBar::onNavigationButtonHeldUp(LLButton* nav_button) { - std::string item = userdata.asString(); - LLLineEditor* location_entry = mCmbLocation->getTextEntry(); - - if (item == std::string("copy_url")) + if(nav_button) { - std::string sl_url = gAgent.getSLURL(); - LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(sl_url)); - - LLSD args; - args["SLURL"] = sl_url; - LLNotifications::instance().add("CopySLURL", args); + nav_button->setForcePressedState(false); } - else if (item == std::string("landmark")) + if(gFocusMgr.getMouseCapture() == gMenuHolder) { - LLFloaterReg::showInstance("add_landmark"); - } - else if (item == std::string("cut")) - { - location_entry->cut(); - } - else if (item == std::string("copy")) - { - location_entry->copy(); - } - else if (item == std::string("paste")) - { - location_entry->paste(); - } - else if (item == std::string("delete")) - { - location_entry->deleteSelection(); - } - else if (item == std::string("select_all")) - { - location_entry->selectAll(); + // we had passed mouseCapture in showTeleportHistoryMenu() + // now we MUST release mouseCapture to continue a proper mouseevent workflow. + gFocusMgr.setMouseCapture(NULL); } + //gMenuHolder is using to display bunch of menus. Disconnect signal to avoid unnecessary calls. + mHistoryMenuConnection.disconnect(); } -bool LLNavigationBar::onLocationContextMenuItemEnabled(const LLSD& userdata) +void LLNavigationBar::handleLoginComplete() { - std::string item = userdata.asString(); - const LLLineEditor* location_entry = mCmbLocation->getTextEntry(); + LLTeleportHistory::getInstance()->handleLoginComplete(); + LLPanelTopInfoBar::instance().handleLoginComplete(); + mCmbLocation->handleLoginComplete(); +} - if (item == std::string("can_cut")) - { - return location_entry->canCut(); - } - else if (item == std::string("can_copy")) +void LLNavigationBar::invokeSearch(std::string search_text) +{ + LLFloaterReg::showInstance("search", LLSD().with("category", "all").with("id", LLSD(search_text))); +} + +void LLNavigationBar::clearHistoryCache() +{ + mCmbLocation->removeall(); + LLLocationHistory* lh = LLLocationHistory::getInstance(); + lh->removeItems(); + lh->save(); + mPurgeTPHistoryItems= true; +} + +int LLNavigationBar::getDefNavBarHeight() +{ + return mDefaultNbRect.getHeight(); +} +int LLNavigationBar::getDefFavBarHeight() +{ + return mDefaultFpRect.getHeight(); +} + +void LLNavigationBar::showNavigationPanel(BOOL visible) +{ + bool fpVisible = gSavedSettings.getBOOL("ShowNavbarFavoritesPanel"); + + LLFavoritesBarCtrl* fb = getChild<LLFavoritesBarCtrl>("favorite"); + LLPanel* navPanel = getChild<LLPanel>("navigation_panel"); + + LLRect nbRect(getRect()); + LLRect fbRect(fb->getRect()); + + navPanel->setVisible(visible); + + if (visible) { - return location_entry->canCopy(); + if (fpVisible) + { + // Navigation Panel must be shown. Favorites Panel is visible. + + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), mDefaultNbRect.getHeight()); + fbRect.setLeftTopAndSize(fbRect.mLeft, mDefaultFpRect.mTop, fbRect.getWidth(), fbRect.getHeight()); + + // this is duplicated in 'else' section because it should be called BEFORE fb->reshape + reshape(nbRect.getWidth(), nbRect.getHeight()); + setRect(nbRect); + // propagate size to parent container + getParent()->reshape(nbRect.getWidth(), nbRect.getHeight()); + + fb->reshape(fbRect.getWidth(), fbRect.getHeight()); + fb->setRect(fbRect); + } + else + { + // Navigation Panel must be shown. Favorites Panel is hidden. + + S32 height = mDefaultNbRect.getHeight() - mDefaultFpRect.getHeight() - FAVBAR_TOP_PADDING; + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), height); + + reshape(nbRect.getWidth(), nbRect.getHeight()); + setRect(nbRect); + getParent()->reshape(nbRect.getWidth(), nbRect.getHeight()); + } } - else if (item == std::string("can_paste")) + else { - return location_entry->canPaste(); + if (fpVisible) + { + // Navigation Panel must be hidden. Favorites Panel is visible. + + S32 fpHeight = mDefaultFpRect.getHeight() + FAVBAR_TOP_PADDING; + S32 fpTop = fpHeight - (mDefaultFpRect.getHeight() / 2) + 1; + + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), fpHeight); + fbRect.setLeftTopAndSize(fbRect.mLeft, fpTop, fbRect.getWidth(), mDefaultFpRect.getHeight()); + + // this is duplicated in 'else' section because it should be called BEFORE fb->reshape + reshape(nbRect.getWidth(), nbRect.getHeight()); + setRect(nbRect); + getParent()->reshape(nbRect.getWidth(), nbRect.getHeight()); + + fb->reshape(fbRect.getWidth(), fbRect.getHeight()); + fb->setRect(fbRect); + } + else + { + // Navigation Panel must be hidden. Favorites Panel is hidden. + + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), 0); + + reshape(nbRect.getWidth(), nbRect.getHeight()); + setRect(nbRect); + getParent()->reshape(nbRect.getWidth(), nbRect.getHeight()); + } } - else if (item == std::string("can_delete")) + + getChildView("bg_icon")->setVisible( visible && fpVisible); + getChildView("bg_icon_no_fav_bevel")->setVisible( visible && !fpVisible); + getChildView("bg_icon_no_nav_bevel")->setVisible( !visible && fpVisible); +} + +void LLNavigationBar::showFavoritesPanel(BOOL visible) +{ + bool npVisible = gSavedSettings.getBOOL("ShowNavbarNavigationPanel"); + + LLFavoritesBarCtrl* fb = getChild<LLFavoritesBarCtrl>("favorite"); + + LLRect nbRect(getRect()); + LLRect fbRect(fb->getRect()); + + if (visible) { - return location_entry->canDeselect(); + if (npVisible) + { + // Favorites Panel must be shown. Navigation Panel is visible. + + S32 fbHeight = fbRect.getHeight(); + S32 newHeight = nbRect.getHeight() + fbHeight + FAVBAR_TOP_PADDING; + + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), newHeight); + fbRect.setLeftTopAndSize(mDefaultFpRect.mLeft, mDefaultFpRect.mTop, fbRect.getWidth(), fbRect.getHeight()); + } + else + { + // Favorites Panel must be shown. Navigation Panel is hidden. + + S32 fpHeight = mDefaultFpRect.getHeight() + FAVBAR_TOP_PADDING; + S32 fpTop = fpHeight - (mDefaultFpRect.getHeight() / 2) + 1; + + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), fpHeight); + fbRect.setLeftTopAndSize(fbRect.mLeft, fpTop, fbRect.getWidth(), mDefaultFpRect.getHeight()); + } + + reshape(nbRect.getWidth(), nbRect.getHeight()); + setRect(nbRect); + getParent()->reshape(nbRect.getWidth(), nbRect.getHeight()); + + fb->reshape(fbRect.getWidth(), fbRect.getHeight()); + fb->setRect(fbRect); } - else if (item == std::string("can_select_all")) + else { - return location_entry->canSelectAll(); - } + if (npVisible) + { + // Favorites Panel must be hidden. Navigation Panel is visible. - return false; -} + S32 fbHeight = fbRect.getHeight(); + S32 newHeight = nbRect.getHeight() - fbHeight - FAVBAR_TOP_PADDING; -void LLNavigationBar::handleLoginComplete() -{ - mCmbLocation->handleLoginComplete(); -} + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), newHeight); + } + else + { + // Favorites Panel must be hidden. Navigation Panel is hidden. -void LLNavigationBar::invokeSearch(std::string search_text) -{ - LLFloaterReg::showInstance("search", LLSD().insert("panel", "all").insert("id", LLSD(search_text))); + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), 0); + } + + reshape(nbRect.getWidth(), nbRect.getHeight()); + setRect(nbRect); + getParent()->reshape(nbRect.getWidth(), nbRect.getHeight()); + } + + getChildView("bg_icon")->setVisible( npVisible && visible); + getChildView("bg_icon_no_fav_bevel")->setVisible( npVisible && !visible); + getChildView("bg_icon_no_nav_bevel")->setVisible( !npVisible && visible); + + fb->setVisible(visible); } |