From 13a2431cb3ca24be1de51c041a046df6fe641b9e Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 7 Oct 2011 21:07:03 +0300
Subject: [PATCH] EXP-1255 FIXED (More spillover does not contain separator and
 "Open Landmarks" menuitem)

- Added menu item "Open landmarks" as the last menu item in favorites menu
---
 indra/llui/lltoolbar.h                        |   2 +
 indra/newview/llfavoritesbar.cpp              | 197 ++++++++++++------
 indra/newview/llfavoritesbar.h                |  14 ++
 .../default/xui/en/panel_navigation_bar.xml   |  18 +-
 .../newview/skins/default/xui/en/strings.xml  |   2 +
 5 files changed, 161 insertions(+), 72 deletions(-)

diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 4fac081130..e4534dea5f 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -173,6 +173,8 @@ public:
 
 	LLToolBarButton* createButton(const LLCommandId& id);
 
+	bool hasButtons() { return !mButtons.empty(); }
+
 protected:
 	friend class LLUICtrlFactory;
 	LLToolBar(const Params&);
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 6dcfa95a0e..98de418878 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -31,6 +31,7 @@
 #include "llfocusmgr.h"
 #include "llinventory.h"
 #include "lllandmarkactions.h"
+#include "lltoolbarview.h"
 #include "lltrans.h"
 #include "lluictrlfactory.h"
 #include "llmenugl.h"
@@ -54,6 +55,7 @@
 static LLDefaultChildRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar");
 
 const S32 DROP_DOWN_MENU_WIDTH = 250;
+const S32 DROP_DOWN_MENU_TOP_PAD = 13;
 
 /**
  * Helper for LLFavoriteLandmarkButton and LLFavoriteLandmarkMenuItem.
@@ -893,84 +895,155 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 {
 	if (mOverflowMenuHandle.isDead())
 	{
-		LLToggleableMenu::Params menu_p;
-		menu_p.name("favorites menu");
-		menu_p.can_tear_off(false);
-		menu_p.visible(false);
-		menu_p.scrollable(true);
-		menu_p.max_scrollable_items = 10;
-		menu_p.preferred_width = DROP_DOWN_MENU_WIDTH;
-
-		LLToggleableMenu* menu = LLUICtrlFactory::create<LLFavoriteLandmarkToggleableMenu>(menu_p);
-		mOverflowMenuHandle = menu->getHandle();
+		createOverflowMenu();
 	}
 
 	LLToggleableMenu* menu = (LLToggleableMenu*)mOverflowMenuHandle.get();
+	if (menu && menu->toggleVisibility())
+	{
+		if (mUpdateDropDownItems)
+		{
+			updateMenuItems(menu);
+		}
+
+		menu->buildDrawLabels();
+		menu->updateParent(LLMenuGL::sMenuContainer);
+		menu->setButtonRect(mMoreTextBox->getRect(), this);
+		positionAndShowMenu(menu);
+	}
+}
+
+void LLFavoritesBarCtrl::createOverflowMenu()
+{
+	LLToggleableMenu::Params menu_p;
+	menu_p.name("favorites menu");
+	menu_p.can_tear_off(false);
+	menu_p.visible(false);
+	menu_p.scrollable(true);
+	menu_p.max_scrollable_items = 10;
+	menu_p.preferred_width = DROP_DOWN_MENU_WIDTH;
+
+	LLToggleableMenu* menu = LLUICtrlFactory::create<LLFavoriteLandmarkToggleableMenu>(menu_p);
+	mOverflowMenuHandle = menu->getHandle();
+}
 
-	if (menu)
+void LLFavoritesBarCtrl::updateMenuItems(LLToggleableMenu* menu)
+{
+	menu->empty();
+
+	U32 widest_item = 0;
+
+	for (S32 i = mFirstDropDownItem; i < mItems.count(); i++)
 	{
-		if (!menu->toggleVisibility())
-			return;
+		LLViewerInventoryItem* item = mItems.get(i);
+		const std::string& item_name = item->getName();
 
-		U32 max_width = llmin(DROP_DOWN_MENU_WIDTH, getRect().getWidth());
-		if (mUpdateDropDownItems)
+		LLFavoriteLandmarkMenuItem::Params item_params;
+		item_params.name(item_name);
+		item_params.label(item_name);
+		item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
+
+		LLFavoriteLandmarkMenuItem *menu_item = LLUICtrlFactory::create<LLFavoriteLandmarkMenuItem>(item_params);
+		menu_item->initFavoritesBarPointer(this);
+		menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3, _4));
+		menu_item->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4));
+		menu_item->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4));
+		menu_item->setLandmarkID(item->getUUID());
+
+		fitLabelWidth(menu_item);
+
+		widest_item = llmax(widest_item, menu_item->getNominalWidth());
+
+		menu->addChild(menu_item);
+	}
+
+	addOpenLandmarksMenuItem(menu);
+	mUpdateDropDownItems = false;
+}
+
+void LLFavoritesBarCtrl::fitLabelWidth(LLMenuItemCallGL* menu_item)
+{
+	U32 max_width = llmin(DROP_DOWN_MENU_WIDTH, getRect().getWidth());
+	std::string item_name = menu_item->getName();
+
+	// Check whether item name wider than menu
+	if (menu_item->getNominalWidth() > max_width)
+	{
+		S32 chars_total = item_name.length();
+		S32 chars_fitted = 1;
+		menu_item->setLabel(LLStringExplicit(""));
+		S32 label_space = max_width - menu_item->getFont()->getWidth("...") -
+				menu_item->getNominalWidth();// This returns width of menu item with empty label (pad pixels)
+
+		while (chars_fitted < chars_total
+				&& menu_item->getFont()->getWidth(item_name, 0, chars_fitted) < label_space)
 		{
-			menu->empty();
+			chars_fitted++;
+		}
+		chars_fitted--; // Rolling back one char, that doesn't fit
 
-			U32 widest_item = 0;
+		menu_item->setLabel(item_name.substr(0, chars_fitted) + "...");
+	}
+}
 
-			for (S32 i = mFirstDropDownItem; i < mItems.count(); i++)
-			{
-				LLViewerInventoryItem* item = mItems.get(i);
-				const std::string& item_name = item->getName();
-
-				LLFavoriteLandmarkMenuItem::Params item_params;
-				item_params.name(item_name);
-				item_params.label(item_name);
-
-				item_params.on_click.function(boost::bind(
-						&LLFavoritesBarCtrl::onButtonClick, this,
-						item->getUUID()));
-				LLFavoriteLandmarkMenuItem *menu_item = LLUICtrlFactory::create<LLFavoriteLandmarkMenuItem>(item_params);
-				menu_item->initFavoritesBarPointer(this);
-				menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3, _4));
-				menu_item->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4));
-				menu_item->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4));
-				menu_item->setLandmarkID(item->getUUID());
-
-				// Check whether item name wider than menu
-				if (menu_item->getNominalWidth() > max_width)
-				{
-					S32 chars_total = item_name.length();
-					S32 chars_fitted = 1;
-					menu_item->setLabel(LLStringExplicit(""));
-					S32 label_space = max_width - menu_item->getFont()->getWidth("...") - 
-							menu_item->getNominalWidth();// This returns width of menu item with empty label (pad pixels) 
-
-					while (chars_fitted < chars_total
-							&& menu_item->getFont()->getWidth(item_name, 0, chars_fitted) < label_space)
-					{
-						chars_fitted++;
-					}
-					chars_fitted--; // Rolling back one char, that doesn't fit
+void LLFavoritesBarCtrl::addOpenLandmarksMenuItem(LLToggleableMenu* menu)
+{
+	std::string label_untrans = "Open landmarks";
+	std::string	label_transl;
+	bool translated = LLTrans::findString(label_transl, label_untrans);
+
+	LLMenuItemCallGL::Params item_params;
+	item_params.name("open_my_landmarks");
+	item_params.label(translated ? label_transl: label_untrans);
+	item_params.on_click.function(boost::bind(&LLFloaterSidePanelContainer::showPanel, "places", LLSD()));
+	LLMenuItemCallGL* menu_item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+
+	fitLabelWidth(menu_item);
+
+	LLMenuItemSeparatorGL::Params sep_params;
+	sep_params.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor");
+	sep_params.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor");
+	sep_params.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor");
+	sep_params.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");
+	LLMenuItemSeparatorGL* separator = LLUICtrlFactory::create<LLMenuItemSeparatorGL>(sep_params);
+
+	menu->addChild(separator);
+	menu->addChild(menu_item);
+}
 
-					menu_item->setLabel(item_name.substr(0, chars_fitted)
-							+ "...");
-				}
-				widest_item = llmax(widest_item, menu_item->getNominalWidth());
+void LLFavoritesBarCtrl::positionAndShowMenu(LLToggleableMenu* menu)
+{
+	U32 max_width = llmin(DROP_DOWN_MENU_WIDTH, getRect().getWidth());
 
-				menu->addChild(menu_item);
-			}
-			mUpdateDropDownItems = false;
+	S32 menu_x = getRect().getWidth() - max_width;
+	S32 menu_y = getParent()->getRect().mBottom - DROP_DOWN_MENU_TOP_PAD;
+
+	// the menu should be offset of the right edge of the window
+	// so it's no covered by buttons in the right-side toolbar.
+	LLToolBar* right_toolbar = gToolBarView->getChild<LLToolBar>("toolbar_right");
+	if (right_toolbar && right_toolbar->hasButtons())
+	{
+		S32 toolbar_top = 0;
+
+		if (LLView* top_border_panel = right_toolbar->getChild<LLView>("button_panel"))
+		{
+			toolbar_top = top_border_panel->calcScreenRect().mTop;
 		}
 
-		menu->buildDrawLabels();
-		menu->updateParent(LLMenuGL::sMenuContainer);
+		// Calculating the bottom (in screen coord) of the drop down menu
+		S32 menu_top = getParent()->getRect().mBottom - DROP_DOWN_MENU_TOP_PAD;
+		S32 menu_bottom = menu_top - menu->getRect().getHeight();
+		S32 menu_bottom_screen = 0;
 
-		menu->setButtonRect(mMoreTextBox->getRect(), this);
+		localPointToScreen(0, menu_bottom, &menu_top, &menu_bottom_screen);
 
-		LLMenuGL::showPopup(this, menu, getRect().getWidth() - max_width, 0);
+		if (menu_bottom_screen < toolbar_top)
+		{
+			menu_x -= right_toolbar->getRect().getWidth();
+		}
 	}
+
+	LLMenuGL::showPopup(this, menu, menu_x, menu_y);
 }
 
 void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id)
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index a41795a080..1b11d6196e 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -34,6 +34,9 @@
 #include "llinventoryobserver.h"
 #include "llinventorymodel.h"
 
+class LLMenuItemCallGL;
+class LLToggleableMenu;
+
 class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 {
 public:
@@ -132,6 +135,17 @@ private:
 	// finds an item by it's UUID in the items array
 	LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
 
+	void createOverflowMenu();
+
+	void updateMenuItems(LLToggleableMenu* menu);
+
+	// Fits menu item label width with favorites menu width
+	void fitLabelWidth(LLMenuItemCallGL* menu_item);
+
+	void addOpenLandmarksMenuItem(LLToggleableMenu* menu);
+
+	void positionAndShowMenu(LLToggleableMenu* menu);
+
 	BOOL mShowDragMarker;
 	LLUICtrl* mLandingTab;
 	LLUICtrl* mLastTab;
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 21c9eb7437..bf9eeb6d26 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -60,9 +60,9 @@
            layout="topleft"
            auto_resize="true"
            user_resize="true"
-           min_width="340"
+           min_width="480"
            name="navigation_layout_panel"
-           width="340">
+           width="480">
 	<panel
 	 background_visible="false"
 	 follows="left|top|right"
@@ -71,7 +71,7 @@
 	 layout="topleft"
                left="0"
 	 name="navigation_panel"
-               width="340">
+     width="480">
 	     <pull_button
 	     follows="left|top"
 	     direction="down"
@@ -118,7 +118,7 @@
 	     mouse_opaque="false"
 	     name="location_combo"
 	     top_delta="0"
-                   width="215">
+            width="355">
          <combo_list
          mouse_wheel_opaque="true"/>
 	    </location_input>
@@ -149,9 +149,9 @@
 	     layout="topleft"
            auto_resize="true"
            user_resize="true"
-           min_width="335"
+           min_width="315"
            name="favorites_layout_panel"
-           width="335">
+           width="315">
     <favorites_bar
      follows="left|right|top"
      font="SansSerifSmall"
@@ -161,7 +161,7 @@
      name="favorite"
      image_drag_indication="Accordion_ArrowOpened_Off"
      tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"
-               width="331">
+               width="311">
         <label
          follows="left|top"
          height="15"
@@ -177,14 +177,12 @@
                  <!-- More button actually is a text box. -->
                  <more_button
                    follows="left|bottom"
-                   font.name="SansSerifSmall"
-                   font.style="UNDERLINE"
                    name=">>"
                      tab_stop="false"
                      tool_tip="Show more of My Favorites"
 		     top="15"
                    width="50">
-                   More...
+                   More &#9660;
                    </more_button>
   </favorites_bar>
          </layout_panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f021fdd6a1..be1ed234fc 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2051,6 +2051,8 @@ Returns a string with the requested data about the region
 	<string name="Marketplace Error Unsellable Item">Error: This item can not be sold on the marketplace.</string>
 	<string name="Marketplace Error Internal Import">Error: There was a problem with this item.  Try again later.</string>
 
+	<string name="Open landmarks">Open landmarks</string>
+
 	<!-- use value="" because they have preceding spaces -->
 	<string name="no_transfer" value=" (no transfer)" />
 	<string name="no_modify"   value=" (no modify)" />
-- 
GitLab