VWR-13221 (SNOW-188) FIXED Allow panning of the minimap

Imported from Snowglobe.
master
Aimee Linden 2010-09-01 14:14:35 +01:00
parent 3cabca8df6
commit 2b5cfc2a4d
7 changed files with 198 additions and 92 deletions

View File

@ -49,6 +49,7 @@ Aimee Trescothick
VWR-12631
VWR-12696
VWR-12748
VWR-13221
VWR-14087
VWR-14267
VWR-14278

View File

@ -4669,6 +4669,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>MiniMapAutoCenter</key>
<map>
<key>Comment</key>
<string>Center the focal point of the minimap.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>Marker</key>
<map>
<key>Comment</key>

View File

@ -47,7 +47,10 @@
//
// Constants
//
const F32 MAP_MINOR_DIR_THRESHOLD = 0.08f;
// The minor cardinal direction labels are hidden if their height is more
// than this proportion of the map.
const F32 MAP_MINOR_DIR_THRESHOLD = 0.07f;
const S32 MAP_PADDING_LEFT = 0;
const S32 MAP_PADDING_TOP = 2;
const S32 MAP_PADDING_RIGHT = 2;
@ -93,7 +96,7 @@ BOOL LLFloaterMap::postBuild()
mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest");
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("Minimap.Zoom", boost::bind(&LLFloaterMap::handleZoom, this, _2));
registrar.add("Minimap.Tracker", boost::bind(&LLFloaterMap::handleStopTracking, this, _2));
@ -255,7 +258,7 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)
void LLFloaterMap::handleZoom(const LLSD& userdata)
{
std::string level = userdata.asString();
F32 scale = 0.0f;
if (level == std::string("close"))
scale = LLNetMap::MAP_SCALE_MAX;

View File

@ -55,6 +55,7 @@
#include "llviewermenu.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "llworld.h"
#include "llworldmapview.h" // shared draw code
@ -69,6 +70,7 @@ const F32 MAP_SCALE_ZOOM_FACTOR = 1.04f; // Zoom in factor per click of scroll w
const F32 MIN_DOT_RADIUS = 3.5f;
const F32 DOT_SCALE = 0.75f;
const F32 MIN_PICK_SCALE = 2.f;
const S32 MOUSE_DRAG_SLOP = 2; // How far the mouse needs to move before we think it's a drag
LLNetMap::LLNetMap (const Params & p)
: LLUICtrl (p),
@ -77,11 +79,12 @@ LLNetMap::LLNetMap (const Params & p)
mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ),
mObjectMapTPM(0.f),
mObjectMapPixels(0.f),
mTargetPanX(0.f),
mTargetPanY(0.f),
mCurPanX(0.f),
mCurPanY(0.f),
mUpdateNow(FALSE),
mTargetPan(0.f, 0.f),
mCurPan(0.f, 0.f),
mStartPan(0.f, 0.f),
mMouseDown(0, 0),
mPanning(false),
mUpdateNow(false),
mObjectImageCenterGlobal( gAgentCamera.getCameraPositionGlobal() ),
mObjectRawImagep(),
mObjectImagep(),
@ -98,7 +101,9 @@ LLNetMap::~LLNetMap()
void LLNetMap::setScale( F32 scale )
{
mScale = llclamp(scale, 0.1f, 16.f*1024.f); // [reasonably small , unreasonably large]
scale = llclamp(scale, MAP_SCALE_MIN, MAP_SCALE_MAX);
mCurPan *= scale / mScale;
mScale = scale;
if (mObjectImagep.notNull())
{
@ -115,13 +120,7 @@ void LLNetMap::setScale( F32 scale )
mPixelsPerMeter = mScale / REGION_WIDTH_METERS;
mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);
mUpdateNow = TRUE;
}
void LLNetMap::translatePan( F32 delta_x, F32 delta_y )
{
mTargetPanX += delta_x;
mTargetPanY += delta_y;
mUpdateNow = true;
}
@ -141,9 +140,12 @@ void LLNetMap::draw()
{
createObjectImage();
}
mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f));
mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f));
static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
if (auto_center)
{
mCurPan = lerp(mCurPan, mTargetPan, LLCriticalDamp::getInterpolant(0.1f));
}
// Prepare a scissor region
F32 rotation = 0;
@ -174,8 +176,8 @@ void LLNetMap::draw()
}
// region 0,0 is in the middle
S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPanX);
S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPanY);
S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPan.mV[VX]);
S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPan.mV[VY]);
gGL.pushMatrix();
@ -256,26 +258,24 @@ void LLNetMap::draw()
}
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
LLVector3d old_center = mObjectImageCenterGlobal;
LLVector3d new_center = gAgentCamera.getCameraPositionGlobal();
new_center.mdV[0] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[0]);
new_center.mdV[1] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[1]);
new_center.mdV[2] = 0.f;
// Redraw object layer periodically
if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f))
{
mUpdateNow = FALSE;
mObjectImageCenterGlobal = new_center;
mUpdateNow = false;
// Locate the centre of the object layer, accounting for panning
LLVector3 new_center = globalPosToView(gAgentCamera.getCameraPositionGlobal());
new_center.mV[VX] -= mCurPan.mV[VX];
new_center.mV[VY] -= mCurPan.mV[VY];
new_center.mV[VZ] = 0.f;
mObjectImageCenterGlobal = viewPosToGlobal(new_center.mV[VX], new_center.mV[VY]);
// Center moved enough.
// Create the base texture.
U8 *default_texture = mObjectRawImagep->getData();
memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() );
// Draw buildings
// Draw objects
gObjectList.renderObjectsForMap(*this);
mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight());
@ -392,12 +392,16 @@ void LLNetMap::draw()
// Draw dot for self avatar position
pos_global = gAgent.getPositionGlobal();
pos_map = globalPosToView(pos_global);
LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage;
S32 dot_width = llround(mDotRadius * 2.f);
you->draw(llround(pos_map.mV[VX] - mDotRadius),
llround(pos_map.mV[VY] - mDotRadius),
dot_width,
dot_width);
LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage;
if (you)
{
you->draw(llround(pos_map.mV[VX] - mDotRadius),
llround(pos_map.mV[VY] - mDotRadius),
dot_width,
dot_width);
}
// Draw frustum
F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters();
@ -472,8 +476,8 @@ LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos )
pos_local.rotVec( rot );
}
pos_local.mV[VX] += getRect().getWidth() / 2 + mCurPanX;
pos_local.mV[VY] += getRect().getHeight() / 2 + mCurPanY;
pos_local.mV[VX] += getRect().getWidth() / 2 + mCurPan.mV[VX];
pos_local.mV[VY] += getRect().getHeight() / 2 + mCurPan.mV[VY];
return pos_local;
}
@ -506,8 +510,8 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color,
LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
{
x -= llround(getRect().getWidth() / 2 + mCurPanX);
y -= llround(getRect().getHeight() / 2 + mCurPanY);
x -= llround(getRect().getWidth() / 2 + mCurPan.mV[VX]);
y -= llround(getRect().getHeight() / 2 + mCurPan.mV[VY]);
LLVector3 pos_local( (F32)x, (F32)y, 0 );
@ -532,10 +536,20 @@ 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 scale = mScale;
scale *= pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
setScale(llclamp(scale, MAP_SCALE_MIN, MAP_SCALE_MAX));
F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
F32 old_scale = mScale;
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;
}
return TRUE;
}
@ -715,5 +729,99 @@ void LLNetMap::createObjectImage()
mObjectImagep = LLViewerTextureManager::getLocalTexture( mObjectRawImagep.get(), FALSE);
}
setScale(mScale);
mUpdateNow = TRUE;
mUpdateNow = true;
}
BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask )
{
if (!(mask & MASK_SHIFT)) return FALSE;
// Start panning
gFocusMgr.setMouseCapture(this);
mStartPan = mCurPan;
mMouseDown.mX = x;
mMouseDown.mY = y;
return TRUE;
}
BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK 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::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;
}
// static
bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop )
{
S32 dx = x - start_x;
S32 dy = y - start_y;
return (dx <= -slop || slop <= dx || dy <= -slop || slop <= dy);
}
BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
{
if (hasMouseCapture())
{
if (mPanning || outsideSlop(x, y, mMouseDown.mX, mMouseDown.mY, MOUSE_DRAG_SLOP))
{
if (!mPanning)
{
// just started panning, so hide cursor
mPanning = true;
gViewerWindow->hideCursor();
}
LLVector2 delta(static_cast<F32>(gViewerWindow->getCurrentMouseDX()),
static_cast<F32>(gViewerWindow->getCurrentMouseDY()));
// 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 );
}
}
return TRUE;
}

View File

@ -37,7 +37,6 @@
class LLColor4U;
class LLCoordGL;
class LLImageRaw;
class LLTextBox;
class LLViewerTexture;
class LLNetMap : public LLUICtrl
@ -66,17 +65,17 @@ public:
/*virtual*/ void draw();
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
/*virtual*/ BOOL handleToolTip( S32 x, S32 y, MASK mask);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
void setScale( F32 scale );
void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius );
private:
void translatePan( F32 delta_x, F32 delta_y );
void setPan( F32 x, F32 y ) { mTargetPanX = x; mTargetPanY = y; }
private:
const LLVector3d& getObjectImageCenterGlobal() { return mObjectImageCenterGlobal; }
void renderPoint(const LLVector3 &pos, const LLColor4U &color,
S32 diameter, S32 relative_height = 0);
@ -91,6 +90,10 @@ private:
void createObjectImage();
private:
static bool outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop);
bool mUpdateNow;
LLUIColor mBackgroundColor;
F32 mScale; // Size of a region in pixels
@ -98,11 +101,13 @@ private:
F32 mObjectMapTPM; // texels per meter on map
F32 mObjectMapPixels; // Width of object map in pixels
F32 mDotRadius; // Size of avatar markers
F32 mTargetPanX;
F32 mTargetPanY;
F32 mCurPanX;
F32 mCurPanY;
BOOL mUpdateNow;
bool mPanning; // map is being dragged
LLVector2 mTargetPan;
LLVector2 mCurPan;
LLVector2 mStartPan; // pan offset at start of drag
LLCoordGL mMouseDown; // pointer position at start of drag
LLVector3d mObjectImageCenterGlobal;
LLPointer<LLImageRaw> mObjectRawImagep;
LLPointer<LLViewerTexture> mObjectImagep;

View File

@ -7,8 +7,8 @@
follows="top|right"
height="174"
layout="topleft"
min_height="174"
min_width="174"
min_height="128"
min_width="128"
name="Map"
title=""
help_topic="map"
@ -18,41 +18,9 @@
left="0"
top="0"
width="200">
<floater.string
name="mini_map_north">
N
</floater.string>
<floater.string
name="mini_map_east">
E
</floater.string>
<floater.string
name="mini_map_west">
W
</floater.string>
<floater.string
name="mini_map_south">
S
</floater.string>
<floater.string
name="mini_map_southeast">
SE
</floater.string>
<floater.string
name="mini_map_northeast">
NE
</floater.string>
<floater.string
name="mini_map_southwest">
SW
</floater.string>
<floater.string
name="mini_map_northwest">
NW
</floater.string>
<floater.string
name="ToolTipMsg">
[AGENT][REGION](Double-click to open Map)
[AGENT][REGION](Double-click to open Map, shift-drag to pan)
</floater.string>
<floater.string name="mini_map_caption">
MINIMAP

View File

@ -29,6 +29,7 @@
function="Minimap.Zoom"
parameter="far" />
</menu_item_call>
<menu_item_separator />
<menu_item_check
label="Rotate Map"
name="Rotate Map">
@ -38,6 +39,15 @@
function="ToggleControl"
parameter="MiniMapRotate" />
</menu_item_check>
<menu_item_check
label="Auto Center"
name="Auto Center">
<menu_item_check.on_check
control="MiniMapAutoCenter" />
<menu_item_check.on_click
function="ToggleControl"
parameter="MiniMapAutoCenter" />
</menu_item_check>
<menu_item_separator />
<menu_item_call
label="Stop Tracking"