summaryrefslogtreecommitdiff
path: root/indra/newview/llnetmap.cpp
diff options
context:
space:
mode:
authorCallum Linden <callum@lindenlab.com>2022-10-24 17:48:16 -0700
committerCallum Linden <callum@lindenlab.com>2022-10-24 17:48:16 -0700
commit80585d56fd6ccb0875c6353c7620a8ada749d66d (patch)
tree139699b14e49609532ca717f9086f2039795801e /indra/newview/llnetmap.cpp
parentb0d69a20c262441125261c4949e59a8a1b9e9628 (diff)
parente45b6159666b3aa271eaaa366fb4bcade2c2a28b (diff)
Merge master into DRTVWR-568 (and fix conflicts)
Diffstat (limited to 'indra/newview/llnetmap.cpp')
-rwxr-xr-x[-rw-r--r--]indra/newview/llnetmap.cpp602
1 files changed, 418 insertions, 184 deletions
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 1240ce7c0f..b34be80b07 100644..100755
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -37,6 +37,7 @@
#include "llfocusmgr.h"
#include "lllocalcliprect.h"
#include "llrender.h"
+#include "llresmgr.h"
#include "llui.h"
#include "lltooltip.h"
@@ -47,11 +48,16 @@
#include "llagentcamera.h"
#include "llappviewer.h" // for gDisconnected
#include "llcallingcard.h" // LLAvatarTracker
+#include "llfloaterland.h"
#include "llfloaterworldmap.h"
+#include "llparcel.h"
#include "lltracker.h"
#include "llsurface.h"
+#include "llurlmatch.h"
+#include "llurlregistry.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
+#include "llviewerparcelmgr.h"
#include "llviewertexture.h"
#include "llviewertexturelist.h"
#include "llviewermenu.h"
@@ -64,7 +70,10 @@
static LLDefaultChildRegistry::Register<LLNetMap> r1("net_map");
const F32 LLNetMap::MAP_SCALE_MIN = 32;
-const F32 LLNetMap::MAP_SCALE_MID = 1024;
+const F32 LLNetMap::MAP_SCALE_FAR = 32;
+const F32 LLNetMap::MAP_SCALE_MEDIUM = 128;
+const F32 LLNetMap::MAP_SCALE_CLOSE = 256;
+const F32 LLNetMap::MAP_SCALE_VERY_CLOSE = 1024;
const F32 LLNetMap::MAP_SCALE_MAX = 4096;
const F32 MAP_SCALE_ZOOM_FACTOR = 1.04f; // Zoom in factor per click of scroll wheel (4%)
@@ -78,13 +87,13 @@ const F64 COARSEUPDATE_MAX_Z = 1020.0f;
LLNetMap::LLNetMap (const Params & p)
: LLUICtrl (p),
mBackgroundColor (p.bg_color()),
- mScale( MAP_SCALE_MID ),
- mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ),
+ mScale( MAP_SCALE_MEDIUM ),
+ mPixelsPerMeter( MAP_SCALE_MEDIUM / REGION_WIDTH_METERS ),
mObjectMapTPM(0.f),
mObjectMapPixels(0.f),
- mTargetPan(0.f, 0.f),
mCurPan(0.f, 0.f),
mStartPan(0.f, 0.f),
+ mPopupWorldPos(0.f, 0.f, 0.f),
mMouseDown(0, 0),
mPanning(false),
mUpdateNow(false),
@@ -97,6 +106,13 @@ LLNetMap::LLNetMap (const Params & p)
mPopupMenu(NULL)
{
mScale = gSavedSettings.getF32("MiniMapScale");
+ if (gAgent.isFirstLogin())
+ {
+ // *HACK: On first run, set this to false for new users, otherwise the
+ // default is true to maintain consistent experience for existing
+ // users.
+ gSavedSettings.setBOOL("MiniMapRotate", false);
+ }
mPixelsPerMeter = mScale / REGION_WIDTH_METERS;
mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);
}
@@ -107,13 +123,22 @@ LLNetMap::~LLNetMap()
BOOL LLNetMap::postBuild()
{
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-
- registrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2));
- registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- return TRUE;
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commitRegistrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enableRegistrar;
+
+ enableRegistrar.add("Minimap.Zoom.Check", boost::bind(&LLNetMap::isZoomChecked, this, _2));
+ commitRegistrar.add("Minimap.Zoom.Set", boost::bind(&LLNetMap::setZoom, this, _2));
+ commitRegistrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
+ commitRegistrar.add("Minimap.Center.Activate", boost::bind(&LLNetMap::activateCenterMap, this, _2));
+ enableRegistrar.add("Minimap.MapOrientation.Check", boost::bind(&LLNetMap::isMapOrientationChecked, this, _2));
+ commitRegistrar.add("Minimap.MapOrientation.Set", boost::bind(&LLNetMap::setMapOrientation, this, _2));
+ commitRegistrar.add("Minimap.AboutLand", boost::bind(&LLNetMap::popupShowAboutLand, this, _2));
+
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder,
+ LLViewerMenuHolderGL::child_registry_t::instance());
+ mPopupMenu->setItemEnabled("Re-center map", false);
+
+ return true;
}
void LLNetMap::setScale( F32 scale )
@@ -158,18 +183,32 @@ void LLNetMap::draw()
static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
//static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);
- static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white);
+ static LLUIColor map_parcel_outline_color = LLUIColorTable::instance().getColor("MapParcelOutlineColor", LLColor4(LLColor3(LLColor4::yellow), 0.5f));
if (mObjectImagep.isNull())
{
createObjectImage();
}
- static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
- if (auto_center)
+ static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
+ bool auto_centering = auto_center && !mPanning;
+ mCentering = mCentering && !mPanning;
+
+ if (auto_centering || mCentering)
{
- mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f));
+ mCurPan = lerp(mCurPan, LLVector2(0.0f, 0.0f) , LLSmoothInterpolation::getInterpolant(0.1f));
}
+ bool centered = abs(mCurPan.mV[VX]) < 0.5f && abs(mCurPan.mV[VY]) < 0.5f;
+ if (centered)
+ {
+ mCurPan.mV[0] = 0.0f;
+ mCurPan.mV[1] = 0.0f;
+ mCentering = false;
+ }
+
+ bool can_recenter_map = !(centered || mCentering || auto_centering);
+ mPopupMenu->setItemEnabled("Re-center map", can_recenter_map);
+ updateAboutLandPopupButton();
// Prepare a scissor region
F32 rotation = 0;
@@ -216,7 +255,8 @@ void LLNetMap::draw()
}
// figure out where agent is
- S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+ const S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+ const F32 scale_pixels_per_meter = mScale / region_width;
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -225,8 +265,8 @@ void LLNetMap::draw()
// Find x and y position relative to camera's center.
LLVector3 origin_agent = regionp->getOriginAgent();
LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
- F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale;
- F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale;
+ F32 relative_x = rel_region_pos.mV[0] * scale_pixels_per_meter;
+ F32 relative_y = rel_region_pos.mV[1] * scale_pixels_per_meter;
// background region rectangle
F32 bottom = relative_y;
@@ -249,6 +289,7 @@ void LLNetMap::draw()
}
+
// Draw using texture.
gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture());
gGL.begin(LLRender::QUADS);
@@ -310,8 +351,8 @@ void LLNetMap::draw()
LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
LLVector3 camera_position = gAgentCamera.getCameraPositionAgent();
map_center_agent -= camera_position;
- map_center_agent.mV[VX] *= mScale/region_width;
- map_center_agent.mV[VY] *= mScale/region_width;
+ map_center_agent.mV[VX] *= scale_pixels_per_meter;
+ map_center_agent.mV[VY] *= scale_pixels_per_meter;
gGL.getTexUnit(0)->bind(mObjectImagep);
F32 image_half_width = 0.5f*mObjectMapPixels;
@@ -327,6 +368,13 @@ void LLNetMap::draw()
gGL.texCoord2f(1.f, 1.f);
gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]);
gGL.end();
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* regionp = *iter;
+ regionp->renderPropertyLinesOnMinimap(scale_pixels_per_meter, map_parcel_outline_color.get().mV);
+ }
gGL.popMatrix();
@@ -451,41 +499,34 @@ void LLNetMap::draw()
F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
F32 far_clip_pixels = far_clip_meters * meters_to_pixels;
-
- F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 );
- F32 half_width_pixels = half_width_meters * meters_to_pixels;
- F32 ctr_x = (F32)center_sw_left;
- F32 ctr_y = (F32)center_sw_bottom;
-
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- if( rotate_map )
- {
- gGL.color4fv((map_frustum_color()).mV);
-
- gGL.begin( LLRender::TRIANGLES );
- gGL.vertex2f( ctr_x, ctr_y );
- gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels );
- gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels );
- gGL.end();
- }
- else
- {
- gGL.color4fv((map_frustum_rotating_color()).mV);
-
- // If we don't rotate the map, we have to rotate the frustum.
- gGL.pushMatrix();
- gGL.translatef( ctr_x, ctr_y, 0 );
- gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
- gGL.begin( LLRender::TRIANGLES );
- gGL.vertex2f( 0, 0 );
- gGL.vertex2f( -half_width_pixels, far_clip_pixels );
- gGL.vertex2f( half_width_pixels, far_clip_pixels );
- gGL.end();
- gGL.popMatrix();
- }
+ F32 ctr_x = (F32)center_sw_left;
+ F32 ctr_y = (F32)center_sw_bottom;
+
+ const F32 steps_per_circle = 40.0f;
+ const F32 steps_per_radian = steps_per_circle / F_TWO_PI;
+ const F32 arc_start = -(horiz_fov / 2.0f) + F_PI_BY_TWO;
+ const F32 arc_end = (horiz_fov / 2.0f) + F_PI_BY_TWO;
+ const S32 steps = llmax(1, (S32)((horiz_fov * steps_per_radian) + 0.5f));
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ if( rotate_map )
+ {
+ gGL.pushMatrix();
+ gGL.translatef( ctr_x, ctr_y, 0 );
+ gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color());
+ gGL.popMatrix();
+ }
+ else
+ {
+ gGL.pushMatrix();
+ gGL.translatef( ctr_x, ctr_y, 0 );
+ // If we don't rotate the map, we have to rotate the frustum.
+ gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
+ gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color());
+ gGL.popMatrix();
+ }
}
gGL.popMatrix();
@@ -552,6 +593,65 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color,
}
}
+bool LLNetMap::isMouseOnPopupMenu()
+{
+ if (!mPopupMenu->isOpen())
+ {
+ return false;
+ }
+
+ S32 popup_x;
+ S32 popup_y;
+ LLUI::getInstance()->getMousePositionLocal(mPopupMenu, &popup_x, &popup_y);
+ // *NOTE: Tolerance is larger than it needs to be because the context menu is offset from the mouse when the menu is opened from certain
+ // directions. This may be a quirk of LLMenuGL::showPopup. -Cosmic,2022-03-22
+ constexpr S32 tolerance = 10;
+ // Test tolerance from all four corners, as the popup menu can appear from a different direction if there's not enough space.
+ // Assume the size of the popup menu is much larger than the provided tolerance.
+ // In practice, this is a [tolerance]px margin around the popup menu.
+ for (S32 sign_x = -1; sign_x <= 1; sign_x += 2)
+ {
+ for (S32 sign_y = -1; sign_y <= 1; sign_y += 2)
+ {
+ if (mPopupMenu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance)))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void LLNetMap::updateAboutLandPopupButton()
+{
+ if (!mPopupMenu->isOpen())
+ {
+ return;
+ }
+
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mPopupWorldPos);
+ if (!region)
+ {
+ mPopupMenu->setItemEnabled("About Land", false);
+ }
+ else
+ {
+ // Check if the mouse is in the bounds of the popup. If so, it's safe to assume no other hover function will be called, so the hover
+ // parcel can be used to check if location-sensitive tooltip options are available.
+ if (isMouseOnPopupMenu())
+ {
+ LLViewerParcelMgr::getInstance()->setHoverParcel(mPopupWorldPos);
+ LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ bool valid_parcel = false;
+ if (hover_parcel)
+ {
+ valid_parcel = hover_parcel->getOwnerID().notNull();
+ }
+ mPopupMenu->setItemEnabled("About Land", valid_parcel);
+ }
+ }
+}
+
LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
{
x -= ll_round(getRect().getWidth() / 2 + mCurPan.mV[VX]);
@@ -579,66 +679,152 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
- F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
+ // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
+ F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
F32 old_scale = mScale;
- setScale(new_scale);
+ setScale(new_scale);
- static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
- if (!auto_center)
- {
- // Adjust pan to center the zoom on the mouse pointer
- LLVector2 zoom_offset;
- zoom_offset.mV[VX] = x - getRect().getWidth() / 2;
- zoom_offset.mV[VY] = y - getRect().getHeight() / 2;
- mCurPan -= zoom_offset * mScale / old_scale - zoom_offset;
- }
+ static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
+ if (!auto_center)
+ {
+ // Adjust pan to center the zoom on the mouse pointer
+ LLVector2 zoom_offset;
+ zoom_offset.mV[VX] = x - getRect().getWidth() / 2;
+ zoom_offset.mV[VY] = y - getRect().getHeight() / 2;
+ mCurPan -= zoom_offset * mScale / old_scale - zoom_offset;
+ }
- return TRUE;
+ return true;
}
-BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask)
{
- if (gDisconnected)
- {
- return FALSE;
- }
+ if (gDisconnected)
+ {
+ return false;
+ }
- // If the cursor is near an avatar on the minimap, a mini-inspector will be
- // shown for the avatar, instead of the normal map tooltip.
- if (handleToolTipAgent(mClosestAgentToCursor))
- {
- return TRUE;
- }
+ // If the cursor is near an avatar on the minimap, a mini-inspector will be
+ // shown for the avatar, instead of the normal map tooltip.
+ if (handleToolTipAgent(mClosestAgentToCursor))
+ {
+ return true;
+ }
- LLRect sticky_rect;
- std::string region_name;
- LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) );
- if(region)
- {
- // set sticky_rect
- S32 SLOP = 4;
- localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom));
- sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP;
- sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP;
-
- region_name = region->getName();
- if (!region_name.empty())
- {
- region_name += "\n";
- }
- }
+ // The popup menu uses the hover parcel when it is open and the mouse is on
+ // top of it, with some additional tolerance. Returning early here prevents
+ // fighting over that hover parcel when getting tooltip info in the
+ // tolerance region.
+ if (isMouseOnPopupMenu())
+ {
+ return false;
+ }
- LLStringUtil::format_map_t args;
- args["[REGION]"] = region_name;
- std::string msg = mToolTipMsg;
- LLStringUtil::format(msg, args);
- LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(msg)
- .sticky_rect(sticky_rect));
-
- return TRUE;
+ LLRect sticky_rect;
+ S32 SLOP = 4;
+ localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom));
+ sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP;
+ sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP;
+
+ std::string parcel_name_msg;
+ std::string parcel_sale_price_msg;
+ std::string parcel_sale_area_msg;
+ std::string parcel_owner_msg;
+ std::string region_name_msg;
+
+ LLVector3d posGlobal = viewPosToGlobal(x, y);
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(posGlobal);
+ if (region)
+ {
+ std::string region_name = region->getName();
+ if (!region_name.empty())
+ {
+ region_name_msg = mRegionNameMsg;
+ LLStringUtil::format(region_name_msg, {{"[REGION_NAME]", region_name}});
+ }
+
+ // Only show parcel information in the tooltip if property lines are visible. Otherwise, the parcel the tooltip is referring to is
+ // ambiguous.
+ if (gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
+ {
+ LLViewerParcelMgr::getInstance()->setHoverParcel(posGlobal);
+ LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ if (hover_parcel)
+ {
+ std::string parcel_name = hover_parcel->getName();
+ if (!parcel_name.empty())
+ {
+ parcel_name_msg = mParcelNameMsg;
+ LLStringUtil::format(parcel_name_msg, {{"[PARCEL_NAME]", parcel_name}});
+ }
+
+ const LLUUID parcel_owner = hover_parcel->getOwnerID();
+ std::string parcel_owner_name_url = LLSLURL("agent", parcel_owner, "inspect").getSLURLString();
+ static LLUrlMatch parcel_owner_name_url_match;
+ LLUrlRegistry::getInstance()->findUrl(parcel_owner_name_url, parcel_owner_name_url_match);
+ if (!parcel_owner_name_url_match.empty())
+ {
+ parcel_owner_msg = mParcelOwnerMsg;
+ std::string parcel_owner_name = parcel_owner_name_url_match.getLabel();
+ LLStringUtil::format(parcel_owner_msg, {{"[PARCEL_OWNER]", parcel_owner_name}});
+ }
+
+ if (hover_parcel->getForSale())
+ {
+ const LLUUID auth_buyer_id = hover_parcel->getAuthorizedBuyerID();
+ const LLUUID agent_id = gAgent.getID();
+ bool show_for_sale = auth_buyer_id.isNull() || auth_buyer_id == agent_id || parcel_owner == agent_id;
+ if (show_for_sale)
+ {
+ S32 price = hover_parcel->getSalePrice();
+ S32 area = hover_parcel->getArea();
+ F32 cost_per_sqm = 0.0f;
+ if (area > 0)
+ {
+ cost_per_sqm = F32(price) / area;
+ }
+ std::string formatted_price = LLResMgr::getInstance()->getMonetaryString(price);
+ std::string formatted_cost_per_meter = llformat("%.1f", cost_per_sqm);
+ parcel_sale_price_msg = mParcelSalePriceMsg;
+ LLStringUtil::format(parcel_sale_price_msg,
+ {{"[PRICE]", formatted_price}, {"[PRICE_PER_SQM]", formatted_cost_per_meter}});
+ std::string formatted_area = llformat("%d", area);
+ parcel_sale_area_msg = mParcelSaleAreaMsg;
+ LLStringUtil::format(parcel_sale_area_msg, {{"[AREA]", formatted_area}});
+ }
+ }
+ }
+ }
+ }
+
+ std::string tool_tip_hint_msg;
+ if (gSavedSettings.getBOOL("DoubleClickTeleport"))
+ {
+ tool_tip_hint_msg = mAltToolTipHintMsg;
+ }
+ else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap"))
+ {
+ tool_tip_hint_msg = mToolTipHintMsg;
+ }
+
+ LLStringUtil::format_map_t args;
+ args["[PARCEL_NAME_MSG]"] = parcel_name_msg.empty() ? "" : parcel_name_msg + '\n';
+ args["[PARCEL_SALE_PRICE_MSG]"] = parcel_sale_price_msg.empty() ? "" : parcel_sale_price_msg + '\n';
+ args["[PARCEL_SALE_AREA_MSG]"] = parcel_sale_area_msg.empty() ? "" : parcel_sale_area_msg + '\n';
+ args["[PARCEL_OWNER_MSG]"] = parcel_owner_msg.empty() ? "" : parcel_owner_msg + '\n';
+ args["[REGION_NAME_MSG]"] = region_name_msg.empty() ? "" : region_name_msg + '\n';
+ args["[TOOL_TIP_HINT_MSG]"] = tool_tip_hint_msg.empty() ? "" : tool_tip_hint_msg + '\n';
+
+ std::string msg = mToolTipMsg;
+ LLStringUtil::format(msg, args);
+ if (msg.back() == '\n')
+ {
+ msg.resize(msg.size() - 1);
+ }
+ LLToolTipMgr::instance().show(LLToolTip::Params().message(msg).sticky_rect(sticky_rect));
+
+ return true;
}
BOOL LLNetMap::handleToolTipAgent(const LLUUID& avatar_id)
@@ -811,59 +997,58 @@ void LLNetMap::createObjectImage()
mUpdateNow = true;
}
-BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleMouseDown(S32 x, S32 y, MASK mask)
{
- if (!(mask & MASK_SHIFT)) return FALSE;
-
- // Start panning
- gFocusMgr.setMouseCapture(this);
+ // Start panning
+ gFocusMgr.setMouseCapture(this);
- mStartPan = mCurPan;
- mMouseDown.mX = x;
- mMouseDown.mY = y;
- return TRUE;
+ mStartPan = mCurPan;
+ mMouseDown.mX = x;
+ mMouseDown.mY = y;
+ return true;
}
-BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleMouseUp(S32 x, S32 y, MASK mask)
{
- if(abs(mMouseDown.mX-x)<3 && abs(mMouseDown.mY-y)<3)
- handleClick(x,y,mask);
+ if (abs(mMouseDown.mX - x) < 3 && abs(mMouseDown.mY - y) < 3)
+ {
+ handleClick(x, y, mask);
+ }
- if (hasMouseCapture())
- {
- if (mPanning)
- {
- // restore mouse cursor
- S32 local_x, local_y;
- local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]);
- local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]);
- LLRect clip_rect = getRect();
- clip_rect.stretch(-8);
- clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y);
- LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y);
-
- // finish the pan
- mPanning = false;
-
- mMouseDown.set(0, 0);
-
- // auto centre
- mTargetPan.setZero();
- }
- gViewerWindow->showCursor();
- gFocusMgr.setMouseCapture(NULL);
- return TRUE;
- }
- return FALSE;
+ if (hasMouseCapture())
+ {
+ if (mPanning)
+ {
+ // restore mouse cursor
+ S32 local_x, local_y;
+ local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]);
+ local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]);
+ LLRect clip_rect = getRect();
+ clip_rect.stretch(-8);
+ clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y);
+ LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y);
+
+ // finish the pan
+ mPanning = false;
+
+ mMouseDown.set(0, 0);
+ }
+ gViewerWindow->showCursor();
+ gFocusMgr.setMouseCapture(NULL);
+ return true;
+ }
+
+ return false;
}
BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if (mPopupMenu)
{
+ mPopupWorldPos = viewPosToGlobal(x, y);
mPopupMenu->buildDrawLabels();
mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
- mPopupMenu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0));
+ mPopupMenu->setItemEnabled("Stop tracking", LLTracker::isTracking(0));
LLMenuGL::showPopup(this, mPopupMenu, x, y);
}
return TRUE;
@@ -911,6 +1096,27 @@ BOOL LLNetMap::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
+F32 LLNetMap::getScaleForName(std::string scale_name)
+{
+ if (scale_name == "very close")
+ {
+ return LLNetMap::MAP_SCALE_VERY_CLOSE;
+ }
+ else if (scale_name == "close")
+ {
+ return LLNetMap::MAP_SCALE_CLOSE;
+ }
+ else if (scale_name == "medium")
+ {
+ return LLNetMap::MAP_SCALE_MEDIUM;
+ }
+ else if (scale_name == "far")
+ {
+ return LLNetMap::MAP_SCALE_FAR;
+ }
+ return 0.0f;
+}
+
// static
bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop )
{
@@ -928,7 +1134,7 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
{
if (!mPanning)
{
- // just started panning, so hide cursor
+ // Just started panning. Hide cursor.
mPanning = true;
gViewerWindow->hideCursor();
}
@@ -938,61 +1144,89 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
// Set pan to value at start of drag + offset
mCurPan += delta;
- mTargetPan = mCurPan;
gViewerWindow->moveCursorToCenter();
}
-
- // Doesn't really matter, cursor should be hidden
- gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
- }
- else
- {
- if (mask & MASK_SHIFT)
- {
- // If shift is held, change the cursor to hint that the map can be dragged
- gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
- }
- else
- {
- gViewerWindow->setCursor( UI_CURSOR_CROSS );
- }
}
+ if (mask & MASK_SHIFT)
+ {
+ // If shift is held, change the cursor to hint that the map can be
+ // dragged. However, holding shift is not required to drag the map.
+ gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
+ }
+ else
+ {
+ gViewerWindow->setCursor( UI_CURSOR_CROSS );
+ }
+
return TRUE;
}
-void LLNetMap::handleZoom(const LLSD& userdata)
+bool LLNetMap::isZoomChecked(const LLSD &userdata)
{
- std::string level = userdata.asString();
-
- F32 scale = 0.0f;
- if (level == std::string("default"))
- {
- LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale");
- if(pvar)
- {
- pvar->resetToDefault();
- scale = gSavedSettings.getF32("MiniMapScale");
- }
- }
- else if (level == std::string("close"))
- scale = LLNetMap::MAP_SCALE_MAX;
- else if (level == std::string("medium"))
- scale = LLNetMap::MAP_SCALE_MID;
- else if (level == std::string("far"))
- scale = LLNetMap::MAP_SCALE_MIN;
- if (scale != 0.0f)
- {
- setScale(scale);
- }
+ std::string level = userdata.asString();
+ F32 scale = getScaleForName(level);
+ return scale == mScale;
+}
+
+void LLNetMap::setZoom(const LLSD &userdata)
+{
+ std::string level = userdata.asString();
+ F32 scale = getScaleForName(level);
+ if (scale != 0.0f)
+ {
+ setScale(scale);
+ }
}
void LLNetMap::handleStopTracking (const LLSD& userdata)
{
if (mPopupMenu)
{
- mPopupMenu->setItemEnabled ("Stop Tracking", false);
+ mPopupMenu->setItemEnabled ("Stop tracking", false);
LLTracker::stopTracking (LLTracker::isTracking(NULL));
}
}
+
+void LLNetMap::activateCenterMap(const LLSD &userdata) { mCentering = true; }
+
+bool LLNetMap::isMapOrientationChecked(const LLSD &userdata)
+{
+ const std::string command_name = userdata.asString();
+ const bool rotate_map = gSavedSettings.getBOOL("MiniMapRotate");
+ if (command_name == "north_at_top")
+ {
+ return !rotate_map;
+ }
+
+ if (command_name == "camera_at_top")
+ {
+ return rotate_map;
+ }
+
+ return false;
+}
+
+void LLNetMap::setMapOrientation(const LLSD &userdata)
+{
+ const std::string command_name = userdata.asString();
+ if (command_name == "north_at_top")
+ {
+ gSavedSettings.setBOOL("MiniMapRotate", false);
+ }
+ else if (command_name == "camera_at_top")
+ {
+ gSavedSettings.setBOOL("MiniMapRotate", true);
+ }
+}
+
+void LLNetMap::popupShowAboutLand(const LLSD &userdata)
+{
+ // Update parcel selection. It's important to deselect land first so the "About Land" floater doesn't refresh with the old selection.
+ LLViewerParcelMgr::getInstance()->deselectLand();
+ LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt(mPopupWorldPos);
+ gMenuHolder->setParcelSelection(selection);
+
+ LLFloaterReg::showInstance("about_land", LLSD(), false);
+}