summaryrefslogtreecommitdiff
path: root/indra/newview/llnavigationbar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llnavigationbar.cpp')
-rw-r--r--indra/newview/llnavigationbar.cpp434
1 files changed, 222 insertions, 212 deletions
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 4a9dadfc7a..cf1d9a5d86 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -34,31 +34,127 @@
#include "llnavigationbar.h"
-#include "llfocusmgr.h"
-#include "llmenugl.h"
-#include "llparcel.h"
-#include "llregistry.h"
-#include "llwindow.h"
+#include <llfloaterreg.h>
+#include <llfocusmgr.h>
+#include <lliconctrl.h>
+#include <llmenugl.h>
+#include <llwindow.h>
#include "llagent.h"
#include "llfloaterhtmlhelp.h"
-#include "llfloaterreg.h"
#include "lllocationhistory.h"
#include "lllocationinputctrl.h"
#include "llteleporthistory.h"
#include "llslurl.h"
#include "llurlsimstring.h"
+#include "llviewerinventory.h"
+#include "llviewermenu.h"
#include "llviewerparcelmgr.h"
-#include "llviewerregion.h"
#include "llworldmap.h"
+//-- LLTeleportHistoryMenuItem -----------------------------------------------
+
+/**
+ * Item look varies depending on the type (backward/current/forward).
+ */
+class LLTeleportHistoryMenuItem : public LLMenuItemCallGL
+{
+public:
+ typedef enum e_item_type
+ {
+ TYPE_BACKWARD,
+ TYPE_CURRENT,
+ TYPE_FORWARD,
+ } EType;
+
+ struct Params : public LLInitParam::Block<Params, LLMenuItemCallGL::Params>
+ {
+ Mandatory<EType> item_type;
+
+ Params() {}
+ Params(EType type, std::string title);
+ };
+
+ /*virtual*/ void draw();
+ /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
+ /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
+
+private:
+ LLTeleportHistoryMenuItem(const Params&);
+ friend class LLUICtrlFactory;
+
+ 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;
+
+ name(title);
+ label(title);
+}
+
+LLTeleportHistoryMenuItem::LLTeleportHistoryMenuItem(const Params& p)
+: LLMenuItemCallGL(p),
+ mArrowIcon(NULL)
+{
+ LLIconCtrl::Params icon_params;
+ icon_params.name("icon");
+ icon_params.rect(LLRect(0, ICON_HEIGHT, ICON_WIDTH, 0));
+ 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);
+ else if (p.item_type == TYPE_FORWARD)
+ mArrowIcon->setValue(ICON_IMG_FORWARD);
+
+ addChild(mArrowIcon);
+}
+
+void LLTeleportHistoryMenuItem::draw()
+{
+ // Draw menu item itself.
+ LLMenuItemCallGL::draw();
+
+ // Draw children if any. *TODO: move this to LLMenuItemGL?
+ LLUICtrl::draw();
+}
+
+void LLTeleportHistoryMenuItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ mArrowIcon->setVisible(TRUE);
+}
+
+void LLTeleportHistoryMenuItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ mArrowIcon->setVisible(FALSE);
+}
+
+//-- LNavigationBar ----------------------------------------------------------
/*
TODO:
- Load navbar height from saved settings (as it's done for status bar) or think of a better way.
-- Share location info formatting code with LLStatusBar.
-- Fix notifications appearing below navbar.
-- Navbar should not be visible in mouselook mode.
*/
S32 NAVIGATION_BAR_HEIGHT = 60; // *HACK
@@ -78,18 +174,20 @@ LLNavigationBar::LLNavigationBar()
mBtnBack(NULL),
mBtnForward(NULL),
mBtnHome(NULL),
- mBtnInfo(NULL),
mBtnHelp(NULL),
mCmbLocation(NULL),
mLeSearch(NULL)
{
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");
// navigation bar can never get a tab
setFocusRoot(FALSE);
-
}
LLNavigationBar::~LLNavigationBar()
@@ -102,14 +200,15 @@ BOOL LLNavigationBar::postBuild()
mBtnBack = getChild<LLButton>("back_btn");
mBtnForward = getChild<LLButton>("forward_btn");
mBtnHome = getChild<LLButton>("home_btn");
- mBtnInfo = getChild<LLButton>("info_btn");
mBtnHelp = getChild<LLButton>("help_btn");
mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");
mLeSearch = getChild<LLLineEditor>("search_input");
- if (!mBtnBack || !mBtnForward || !mBtnHome || !mBtnInfo || !mBtnHelp ||
- !mCmbLocation || !mLeSearch)
+ LLButton* search_btn = getChild<LLButton>("search_btn");
+
+ if (!mBtnBack || !mBtnForward || !mBtnHome || !mBtnHelp ||
+ !mCmbLocation || !mLeSearch || !search_btn)
{
llwarns << "Malformed navigation bar" << llendl;
return FALSE;
@@ -124,23 +223,15 @@ BOOL LLNavigationBar::postBuild()
mBtnForward->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _2));
mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this));
- mBtnInfo->setClickedCallback(boost::bind(&LLNavigationBar::onInfoButtonClicked, this));
mBtnHelp->setClickedCallback(boost::bind(&LLNavigationBar::onHelpButtonClicked, this));
- mCmbLocation->setFocusReceivedCallback(boost::bind(&LLNavigationBar::onLocationFocusReceived, this));
- mCmbLocation->setFocusLostCallback(boost::bind(&LLNavigationBar::onLocationFocusLost, this));
- mCmbLocation->setTextEntryCallback(boost::bind(&LLNavigationBar::onLocationTextEntry, this, _1));
- mCmbLocation->setPrearrangeCallback(boost::bind(&LLNavigationBar::onLocationPrearrange, this, _2));
mCmbLocation->setSelectionCallback(boost::bind(&LLNavigationBar::onLocationSelection, this));
mLeSearch->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this));
+ search_btn->setClickedCallback(boost::bind(&LLNavigationBar::onSearchCommit, this));
- // Register callbacks and load the location field context menu (NB: the order matters).
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit_registrar;
- LLMenuItemGL::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
- commit_registrar.add("Navbar.Action", boost::bind(&LLNavigationBar::onLocationContextMenuItemClicked, this, _2));
- enable_registrar.add("Navbar.EnableMenuItem", boost::bind(&LLNavigationBar::onLocationContextMenuItemEnabled, this, _2));
- mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_navbar.xml", 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;
@@ -150,49 +241,34 @@ BOOL LLNavigationBar::postBuild()
// we'll be notified on teleport history changes
LLTeleportHistory::getInstance()->setHistoryChangedCallback(
boost::bind(&LLNavigationBar::onTeleportHistoryChanged, this));
-
- LLLocationHistory::getInstance()->setLoadedCallback(
- boost::bind(&LLNavigationBar::onLocationHistoryLoaded, this));
-
- LLLocationHistory::getInstance()->load(); // *TODO: temporary, remove this after debugging
- LLTeleportHistory::getInstance()->load(); // *TODO: temporary, remove this after debugging
-
+
return TRUE;
}
void LLNavigationBar::draw()
{
- // *TODO: It doesn't look very optimal to refresh location every frame.
- refreshLocation();
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))
{
-
- // Pass the focus to the line editor when it is righ-clicked
+ // Pass the focus to the line editor when it is right-clicked
mCmbLocation->setFocus(TRUE);
- // IAN BUG why do the individual items need to be enabled individually here?
- // where are they disabled?
-
if (mLocationContextMenu)
{
- mLocationContextMenu->setItemEnabled("Cut", mCmbLocation->canCut());
- mLocationContextMenu->setItemEnabled("Copy", mCmbLocation->canCopy());
- mLocationContextMenu->setItemEnabled("Paste", mCmbLocation->canPaste());
- mLocationContextMenu->setItemEnabled("Delete", mCmbLocation->canDeselect());
- mLocationContextMenu->setItemEnabled("Select All", mCmbLocation->canSelectAll());
-
mLocationContextMenu->buildDrawLabels();
mLocationContextMenu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, mLocationContextMenu, x, y);
}
+ return TRUE;
}
- return TRUE;
+ return LLPanel:: handleRightMouseDown(x, y, mask);
}
void LLNavigationBar::onBackButtonClicked()
@@ -216,13 +292,6 @@ void LLNavigationBar::onHomeButtonClicked()
gAgent.teleportHome();
}
-void LLNavigationBar::onInfoButtonClicked()
-{
- // XXX temporary
- LLTeleportHistory::getInstance()->dump();
- LLLocationHistory::getInstance()->dump();
-}
-
void LLNavigationBar::onHelpButtonClicked()
{
gViewerHtmlHelp.show();
@@ -230,17 +299,7 @@ void LLNavigationBar::onHelpButtonClicked()
void LLNavigationBar::onSearchCommit()
{
- std::string search_text = mLeSearch->getText();
- LLFloaterReg::showInstance("search", LLSD().insert("panel", "all").insert("id", LLSD(search_text)));
-}
-
-void LLNavigationBar::onLocationFocusReceived()
-{
- mCmbLocation->setTextEntry(gAgent.getSLURL());
-}
-
-void LLNavigationBar::onLocationFocusLost()
-{
+ invokeSearch(mLeSearch->getText());
}
void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)
@@ -253,51 +312,37 @@ void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)
// or selects a location from the typed locations dropdown.
void LLNavigationBar::onLocationSelection()
{
- std::string loc_str = mCmbLocation->getSimple();
+ std::string typed_location = mCmbLocation->getSimple();
// Will not teleport to empty location.
- if (loc_str.empty())
+ if (typed_location.empty())
return;
-
- // *TODO: validate location before adding it to the history.
- S32 selected_item = mCmbLocation->getCurrentIndex();
- if (selected_item == -1) // user has typed text
+
+ std::string region_name;
+ LLVector3 local_coords(128, 128, 0);
+
+ // Is the typed location a SLURL?
+ if (LLSLURL::isSLURL(typed_location))
{
- LLLocationHistory* lh = LLLocationHistory::getInstance();
- mCmbLocation->add(loc_str);
- lh->addItem(loc_str);
- lh->save();
+ // Yes. Extract region name and local coordinates from it.
+ S32 x = 0, y = 0, z = 0;
+ if (LLURLSimString::parse(LLSLURL::stripProtocol(typed_location), &region_name, &x, &y, &z))
+ local_coords.set(x, y, z);
+ else
+ return;
}
-
- // If the input is not a SLURL treat it as a region name.
- if (!LLSLURL::isSLURL(loc_str))
+ else
{
- loc_str = LLSLURL::buildSLURL(loc_str, 128, 128, 0);
+ // Treat it as region name.
+ region_name = typed_location;
}
-
- teleport(loc_str);
-}
-void LLNavigationBar::onLocationTextEntry(LLUICtrl* ctrl)
-{
- LLLineEditor* editor = dynamic_cast<LLLineEditor*>(ctrl);
- if (!editor)
- return;
-
- // *TODO: decide whether to populate the list here on in LLLocationInputCtrl.
- std::string text = editor->getText();
- //rebuildLocationHistory(text);
-}
-
-void LLNavigationBar::onLocationPrearrange(const LLSD& data)
-{
- std::string filter = data.asString();
- rebuildLocationHistory(filter);
-}
-
-void LLNavigationBar::onLocationHistoryLoaded()
-{
- rebuildLocationHistory();
+ // Resolve the region name to its global coordinates.
+ // If resolution succeeds we'll teleport.
+ LLWorldMap::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);
}
void LLNavigationBar::onTeleportHistoryChanged()
@@ -309,57 +354,13 @@ void LLNavigationBar::onTeleportHistoryChanged()
mBtnForward->setEnabled(cur_item < ((int)h->getItems().size() - 1));
}
-void LLNavigationBar::refreshLocation()
-{
- // Update location field.
- if (mCmbLocation && !mCmbLocation->childHasFocus())
- {
- std::string location_name;
-
- if (!gAgent.buildLocationString(location_name, LLAgent::LOCATION_FORMAT_FULL))
- location_name = "Unknown";
-
- mCmbLocation->setText(location_name);
- }
-}
-
-void LLNavigationBar::rebuildLocationHistory(std::string filter)
-{
- if (!mCmbLocation)
- {
- llwarns << "Cannot find location history control" << llendl;
- return;
- }
-
- LLLocationHistory::location_list_t filtered_items;
- const LLLocationHistory::location_list_t* itemsp = NULL;
- LLLocationHistory* lh = LLLocationHistory::getInstance();
-
- if (filter.empty())
- itemsp = &lh->getItems();
- else
- {
- lh->getMatchingItems(filter, filtered_items);
- itemsp = &filtered_items;
- }
-
- mCmbLocation->removeall();
- for (LLLocationHistory::location_list_t::const_reverse_iterator it = itemsp->rbegin(); it != itemsp->rend(); it++)
- mCmbLocation->add(*it);
-}
-
void LLNavigationBar::rebuildTeleportHistoryMenu()
{
// Has the pop-up menu been built?
if (mTeleportHistoryMenu)
{
// Clear it.
- // *TODO: LLMenuGL should have a method for removing all items.
- while (mTeleportHistoryMenu->getItemCount())
- {
- LLMenuItemGL* itemp = mTeleportHistoryMenu->getItem(0);
- mTeleportHistoryMenu->removeChild(itemp);
- }
+ mTeleportHistoryMenu->empty();
}
else
{
@@ -369,6 +370,7 @@ void LLNavigationBar::rebuildTeleportHistoryMenu()
menu_p.can_tear_off(false);
menu_p.visible(false);
menu_p.bg_visible(true);
+ menu_p.scrollable(true);
mTeleportHistoryMenu = LLUICtrlFactory::create<LLMenuGL>(menu_p);
addChild(mTeleportHistoryMenu);
@@ -382,26 +384,44 @@ void LLNavigationBar::rebuildTeleportHistoryMenu()
// Items will be shown in the reverse order, just like in Firefox.
for (int i = (int)hist_items.size()-1; i >= 0; i--)
{
- LLMenuItemCallGL::Params item_params;
- std::string title = hist_items[i].mTitle;
-
- if (i == cur_item)
- item_params.font.style("BOLD");
+ LLTeleportHistoryMenuItem::EType type;
+ if (i < cur_item)
+ type = LLTeleportHistoryMenuItem::TYPE_BACKWARD;
+ else if (i > cur_item)
+ type = LLTeleportHistoryMenuItem::TYPE_FORWARD;
else
- title = " " + title;
+ type = LLTeleportHistoryMenuItem::TYPE_CURRENT;
- item_params.name(title);
- item_params.label(title);
+ LLTeleportHistoryMenuItem::Params item_params(type, hist_items[i].mTitle);
item_params.on_click.function(boost::bind(&LLNavigationBar::onTeleportHistoryMenuItemClicked, this, i));
- mTeleportHistoryMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
+ mTeleportHistoryMenu->addChild(LLUICtrlFactory::create<LLTeleportHistoryMenuItem>(item_params));
}
}
-// static
void LLNavigationBar::onRegionNameResponse(
+ std::string typed_location,
+ std::string region_name,
LLVector3 local_coords,
U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)
{
+ // Invalid location?
+ if (!region_handle)
+ {
+ invokeSearch(typed_location);
+ 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;
@@ -409,25 +429,6 @@ void LLNavigationBar::onRegionNameResponse(
gAgent.teleportViaLocation(global_pos);
}
-// static
-void LLNavigationBar::teleport(std::string slurl)
-{
- std::string sim_string = LLSLURL::stripProtocol(slurl);
- std::string region_name;
- S32 x = 128;
- S32 y = 128;
- S32 z = 0;
-
- LLURLSimString::parse(sim_string, &region_name, &x, &y, &z);
-
- // Resolve region name to global coords.
- LLVector3 local_coords(x, y, z);
- LLWorldMap::getInstance()->sendNamedRegionRequest(region_name,
- boost::bind(&LLNavigationBar::onRegionNameResponse, local_coords, _1, _2, _3, _4),
- slurl,
- false); // don't teleport
-}
-
void LLNavigationBar::showTeleportHistoryMenu()
{
// Don't show the popup if teleport history is empty.
@@ -449,75 +450,84 @@ void LLNavigationBar::showTeleportHistoryMenu()
LLMenuGL::showPopup(this, mTeleportHistoryMenu, btnBackRect.mLeft, btnBackRect.mBottom);
// *HACK pass the mouse capturing to the drop-down menu
- gFocusMgr.setMouseCapture( mTeleportHistoryMenu );
+ gFocusMgr.setMouseCapture( NULL );
}
void LLNavigationBar::onLocationContextMenuItemClicked(const LLSD& userdata)
{
- std::string level = userdata.asString();
+ std::string item = userdata.asString();
+ LLLineEditor* location_entry = mCmbLocation->getTextEntry();
- if (level == std::string("copy_url"))
+ if (item == std::string("copy_url"))
{
- LLUIString url(gAgent.getSLURL());
- LLView::getWindow()->copyTextToClipboard(url.getWString());
- lldebugs << "Copy SLURL" << llendl;
+ 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);
}
- else if (level == std::string("landmark"))
+ else if (item == std::string("landmark"))
{
- // *TODO To be implemented
- lldebugs << "Add Landmark" << llendl;
+ LLFloaterReg::showInstance("add_landmark");
}
- else if (level == std::string("cut"))
+ else if (item == std::string("cut"))
{
- mCmbLocation->cut();
- lldebugs << "Cut" << llendl;
+ location_entry->cut();
}
- else if (level == std::string("copy"))
+ else if (item == std::string("copy"))
{
- mCmbLocation->copy();
- lldebugs << "Copy" << llendl;
+ location_entry->copy();
}
- else if (level == std::string("paste"))
+ else if (item == std::string("paste"))
{
- mCmbLocation->paste();
- lldebugs << "Paste" << llendl;
+ location_entry->paste();
}
- else if (level == std::string("delete"))
+ else if (item == std::string("delete"))
{
- mCmbLocation->deleteSelection();
- lldebugs << "Delete" << llendl;
+ location_entry->deleteSelection();
}
- else if (level == std::string("select_all"))
+ else if (item == std::string("select_all"))
{
- mCmbLocation->selectAll();
- lldebugs << "Select All" << llendl;
+ location_entry->selectAll();
}
}
bool LLNavigationBar::onLocationContextMenuItemEnabled(const LLSD& userdata)
{
- std::string level = userdata.asString();
+ std::string item = userdata.asString();
+ const LLLineEditor* location_entry = mCmbLocation->getTextEntry();
- if (level == std::string("can_cut"))
+ if (item == std::string("can_cut"))
{
- return mCmbLocation->canCut();
+ return location_entry->canCut();
}
- else if (level == std::string("can_copy"))
+ else if (item == std::string("can_copy"))
{
- return mCmbLocation->canCopy();
+ return location_entry->canCopy();
}
- else if (level == std::string("can_paste"))
+ else if (item == std::string("can_paste"))
{
- return mCmbLocation->canPaste();
+ return location_entry->canPaste();
}
- else if (level == std::string("can_delete"))
+ else if (item == std::string("can_delete"))
{
- return mCmbLocation->canDeselect();
+ return location_entry->canDeselect();
}
- else if (level == std::string("can_select_all"))
+ else if (item == std::string("can_select_all"))
{
- return mCmbLocation->canSelectAll();
+ return location_entry->canSelectAll();
}
return false;
}
+
+void LLNavigationBar::handleLoginComplete()
+{
+ mCmbLocation->handleLoginComplete();
+}
+
+void LLNavigationBar::invokeSearch(std::string search_text)
+{
+ LLFloaterReg::showInstance("search", LLSD().insert("panel", "all").insert("id", LLSD(search_text)));
+}