Files
SingularityViewer/indra/newview/llfloaterworldmap.cpp
Lirusaito db39bab95b Fix a ton of run-time warnings about UI.
Cleans up some related code, probably looks nicer with space changes off.. though this is a pretty straightforward change.
Comments out code that still exists in xmls or might likely be added in future.
Each piece tested quite a bit.
2013-03-05 20:20:59 -05:00

1664 lines
45 KiB
C++

/**
* @file llfloaterworldmap.cpp
* @author James Cook, Tom Yedwab
* @brief LLFloaterWorldMap class implementation
*
* $LicenseInfo:firstyear=2003&license=viewergpl$
*
* Copyright (c) 2003-2009, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
/*
* Map of the entire world, with multiple background images,
* avatar tracking, teleportation by double-click, etc.
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterworldmap.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llviewerwindow.h"
#include "llwindow.h"
#include "llbutton.h"
#include "llcallingcard.h"
#include "llcolorscheme.h"
#include "llcombobox.h"
#include "llviewercontrol.h"
#include "lldraghandle.h"
#include "llfirstuse.h"
#include "llfocusmgr.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryobserver.h"
#include "lllandmarklist.h"
#include "llnotificationsutil.h"
#include "lllineeditor.h"
#include "llpreviewlandmark.h"
#include "llregionhandle.h"
#include "llscrolllistctrl.h"
#include "lltextbox.h"
#include "lltracker.h"
#include "lltrans.h"
#include "llurldispatcher.h"
#include "llviewermenu.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llworldmap.h"
#include "llworldmapmessage.h"
#include "llworldmapview.h"
#include "lluictrlfactory.h"
#include "llappviewer.h"
#include "llmapimagetype.h"
#include "llweb.h"
#include "llglheaders.h"
// [RLVa:KB]
#include "rlvhandler.h"
// [/RLVa:KB]
//---------------------------------------------------------------------------
// Constants
//---------------------------------------------------------------------------
static const F32 MAP_ZOOM_TIME = 0.2f;
// Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed
// width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across
// sessions and doesn't prevent the user to pan the world if it was to grow a lot beyond that limit.
// Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window.
static const S32 MAX_VISIBLE_REGIONS = 512;
// It would be more logical to have this inside the method where it is used but to compile under gcc this
// struct has to be here.
struct SortRegionNames
{
inline bool operator ()(std::pair <U64, LLSimInfo*> const& _left, std::pair <U64, LLSimInfo*> const& _right)
{
return(LLStringUtil::compareInsensitive(_left.second->getName(), _right.second->getName()) < 0);
}
};
enum EPanDirection
{
PAN_UP,
PAN_DOWN,
PAN_LEFT,
PAN_RIGHT
};
// Values in pixels per region
static const F32 ZOOM_MAX = 128.f;
static const F32 SIM_COORD_DEFAULT = 128.f;
//---------------------------------------------------------------------------
// Globals
//---------------------------------------------------------------------------
LLFloaterWorldMap* gFloaterWorldMap = NULL;
class LLMapInventoryObserver : public LLInventoryObserver
{
public:
LLMapInventoryObserver() {}
virtual ~LLMapInventoryObserver() {}
virtual void changed(U32 mask);
};
void LLMapInventoryObserver::changed(U32 mask)
{
// if there's a change we're interested in.
if((mask & (LLInventoryObserver::CALLING_CARD | LLInventoryObserver::ADD |
LLInventoryObserver::REMOVE)) != 0)
{
gFloaterWorldMap->inventoryChanged();
}
}
class LLMapFriendObserver : public LLFriendObserver
{
public:
LLMapFriendObserver() {}
virtual ~LLMapFriendObserver() {}
virtual void changed(U32 mask);
};
void LLMapFriendObserver::changed(U32 mask)
{
// if there's a change we're interested in.
if((mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE | LLFriendObserver::POWERS)) != 0)
{
gFloaterWorldMap->friendsChanged();
}
}
//---------------------------------------------------------------------------
// Statics
//---------------------------------------------------------------------------
// Used as a pretend asset and inventory id to mean "landmark at my home location."
const LLUUID LLFloaterWorldMap::sHomeID( "10000000-0000-0000-0000-000000000001" );
//---------------------------------------------------------------------------
// Construction and destruction
//---------------------------------------------------------------------------
LLFloaterWorldMap::LLFloaterWorldMap()
: LLFloater(std::string("worldmap")),
mInventory(NULL),
mInventoryObserver(NULL),
mFriendObserver(NULL),
mCompletingRegionName(),
mCompletingRegionPos(),
mWaitingForTracker(FALSE),
mIsClosing(FALSE),
mSetToUserPosition(TRUE),
mTrackedLocation(0,0,0),
mTrackedStatus(LLTracker::TRACKING_NOTHING),
mListFriendCombo(NULL),
mListLandmarkCombo(NULL),
mListSearchResults(NULL)
{
LLCallbackMap::map_t factory_map;
factory_map["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL);
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_world_map.xml", &factory_map);
}
// static
void* LLFloaterWorldMap::createWorldMapView(void* data)
{
return new LLWorldMapView(std::string("mapview"), LLRect(0,300,400,0));
}
BOOL LLFloaterWorldMap::postBuild()
{
// The following callback syncs the worlmap tabs with the images.
// Commented out since it was crashing when LLWorldMap became a singleton.
// We should be fine without it but override the onOpen method and put it
// there if it turns out to be needed. -MG
//
//onCommitBackground((void*)this, false);
mPanel = getChild<LLPanel>("objects_mapview");
LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
avatar_combo->selectFirstItem();
avatar_combo->setPrearrangeCallback( onAvatarComboPrearrange );
avatar_combo->setTextEntryCallback( onComboTextEntry );
mListFriendCombo = dynamic_cast<LLCtrlListInterface *>(avatar_combo);
LLLineEditor *location_editor = getChild<LLLineEditor>("location");
location_editor->setFocusChangedCallback(boost::bind(&LLFloaterWorldMap::onLocationFocusChanged, this, _1));
location_editor->setKeystrokeCallback( onSearchTextEntry );
LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("search_results");
search_results->setDoubleClickCallback(boost::bind(&LLFloaterWorldMap::onClickTeleportBtn,this));
mListSearchResults = dynamic_cast<LLCtrlListInterface *>(search_results);
LLComboBox *landmark_combo = getChild<LLComboBox>( "landmark combo");
landmark_combo->selectFirstItem();
landmark_combo->setPrearrangeCallback( onLandmarkComboPrearrange );
landmark_combo->setTextEntryCallback( onComboTextEntry );
mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo);
avatar_combo->setCommitCallback( boost::bind(&LLFloaterWorldMap::onAvatarComboCommit,this) );
search_results->setCommitCallback( boost::bind(&LLFloaterWorldMap::onCommitSearchResult,this) );
landmark_combo->setCommitCallback( boost::bind(&LLFloaterWorldMap::onLandmarkComboCommit,this) );
getChild<LLUICtrl>("spin x")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCoordinatesCommit,this) );
getChild<LLUICtrl>("spin y")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCoordinatesCommit,this) );
getChild<LLUICtrl>("spin z")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCoordinatesCommit,this) );
getChild<LLButton>("DoSearch")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onLocationCommit,this) );
getChild<LLButton>("Go Home")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onGoHome,this) );
getChild<LLButton>("Teleport")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onClickTeleportBtn,this) );
getChild<LLButton>("Show Destination")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onShowTargetBtn,this) );
getChild<LLButton>("Show My Location")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onShowAgentBtn,this) );
getChild<LLButton>("Clear")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onClearBtn,this) );
getChild<LLButton>("copy_slurl")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCopySLURL,this) );
mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f);
childSetValue("zoom slider", mCurZoomVal);
setDefaultBtn(NULL);
mZoomTimer.stop();
onChangeMaturity();
return TRUE;
}
// virtual
LLFloaterWorldMap::~LLFloaterWorldMap()
{
// All cleaned up by LLView destructor
mPanel = NULL;
// Inventory deletes all observers on shutdown
mInventory = NULL;
mInventoryObserver = NULL;
// avatar tracker will delete this for us.
mFriendObserver = NULL;
gFloaterWorldMap = NULL;
}
// virtual
void LLFloaterWorldMap::onClose(bool app_quitting)
{
setVisible(FALSE);
}
// static
void LLFloaterWorldMap::show(void*, BOOL center_on_target)
{
// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0c)
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWWORLDMAP))
{
return;
}
// [/RLVa:KB]
BOOL was_visible = gFloaterWorldMap->getVisible();
gFloaterWorldMap->mIsClosing = FALSE;
gFloaterWorldMap->open(); /* Flawfinder: ignore */
LLWorldMapView* map_panel;
map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
map_panel->clearLastClick();
if (!was_visible)
{
// reset pan on show, so it centers on you again
if (!center_on_target)
{
LLWorldMapView::setPan(0, 0, TRUE);
}
map_panel->updateVisibleBlocks();
// Reload items as they may have changed
LLWorldMap::getInstance()->reloadItems();
// We may already have a bounding box for the regions of the world,
// so use that to adjust the view.
gFloaterWorldMap->adjustZoomSliderBounds();
// Could be first show
LLFirstUse::useMap();
// Start speculative download of landmarks
LLUUID landmark_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
LLInventoryModelBackgroundFetch::instance().start(landmark_folder_id);
gFloaterWorldMap->childSetFocus("location", TRUE);
gFocusMgr.triggerFocusFlash();
gFloaterWorldMap->buildAvatarIDList();
gFloaterWorldMap->buildLandmarkIDLists();
// If nothing is being tracked, set flag so the user position will be found
gFloaterWorldMap->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
}
if (center_on_target)
{
gFloaterWorldMap->centerOnTarget(FALSE);
}
}
// static
void LLFloaterWorldMap::reloadIcons(void*)
{
LLWorldMap::getInstance()->reloadItems();
}
// static
void LLFloaterWorldMap::toggle(void*)
{
BOOL visible = gFloaterWorldMap->getVisible();
if (!visible)
{
show(NULL, FALSE);
}
else
{
gFloaterWorldMap->mIsClosing = TRUE;
gFloaterWorldMap->close();
}
}
// static
void LLFloaterWorldMap::hide(void*)
{
gFloaterWorldMap->mIsClosing = TRUE;
gFloaterWorldMap->close();
}
// virtual
void LLFloaterWorldMap::setVisible( BOOL visible )
{
LLFloater::setVisible( visible );
gSavedSettings.setBOOL( "ShowWorldMap", visible );
if( !visible )
{
// While we're not visible, discard the overlay images we're using
LLWorldMap::getInstance()->clearImageRefs();
}
}
// virtual
BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask)
{
BOOL handled;
handled = LLFloater::handleHover(x, y, mask);
return handled;
}
BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
if (!isMinimized() && isFrontmost())
{
if(mPanel->pointInView(x, y))
{
F32 slider_value = (F32)childGetValue("zoom slider").asReal();
slider_value += ((F32)clicks * -0.3333f);
childSetValue("zoom slider", LLSD(slider_value));
return TRUE;
}
}
return LLFloater::handleScrollWheel(x, y, clicks);
}
// virtual
void LLFloaterWorldMap::reshape( S32 width, S32 height, BOOL called_from_parent )
{
LLFloater::reshape( width, height, called_from_parent );
// Might have changed size of world display area
// JC: Technically, this is correct, but it makes the slider "pop"
// if you resize the window, then draw the slider. Just leaving it
// the way it was when you opened the window seems better.
// adjustZoomSliderBounds();
}
// virtual
void LLFloaterWorldMap::draw()
{
// On orientation island, users don't have a home location yet, so don't
// let them teleport "home". It dumps them in an often-crowed welcome
// area (infohub) and they get confused. JC
LLViewerRegion* regionp = gAgent.getRegion();
bool agent_on_prelude = (regionp && regionp->isPrelude());
bool enable_go_home = gAgent.isGodlike() || !agent_on_prelude;
childSetEnabled("Go Home", enable_go_home);
updateLocation();
LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
if (LLTracker::TRACKING_AVATAR == tracking_status)
{
childSetColor("avatar_icon", gTrackColor);
}
else
{
childSetColor("avatar_icon", gDisabledTrackColor);
}
if (LLTracker::TRACKING_LANDMARK == tracking_status)
{
childSetColor("landmark_icon", gTrackColor);
}
else
{
childSetColor("landmark_icon", gDisabledTrackColor);
}
if (LLTracker::TRACKING_LOCATION == tracking_status)
{
childSetColor("location_icon", gTrackColor);
}
else
{
if (mCompletingRegionName != "")
{
F64 seconds = LLTimer::getElapsedSeconds();
double value = fmod(seconds, 2);
value = 0.5 + 0.5*cos(value * F_PI);
LLColor4 loading_color(0.0, F32(value/2), F32(value), 1.0);
childSetColor("location_icon", loading_color);
}
else
{
childSetColor("location_icon", gDisabledTrackColor);
}
}
// check for completion of tracking data
if (mWaitingForTracker)
{
centerOnTarget(TRUE);
}
childSetEnabled("Teleport", (BOOL)tracking_status);
// childSetEnabled("Clear", (BOOL)tracking_status);
childSetEnabled("Show Destination", (BOOL)tracking_status || LLWorldMap::getInstance()->isTracking());
childSetEnabled("copy_slurl", (mSLURL.size() > 0) );
setMouseOpaque(TRUE);
getDragHandle()->setMouseOpaque(TRUE);
//RN: snaps to zoom value because interpolation caused jitter in the text rendering
if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal())
{
mZoomTimer.start();
}
F32 interp = mZoomTimer.getStarted() ? mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME : 1.f;
if (interp > 1.f)
{
interp = 1.f;
mZoomTimer.stop();
}
mCurZoomVal = lerp(mCurZoomVal, (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal(), interp);
F32 map_scale = 256.f*pow(2.f, mCurZoomVal);
LLWorldMapView::setScale( map_scale );
onChangeMaturity();
LLFloater::draw();
}
//-------------------------------------------------------------------------
// Internal utility functions
//-------------------------------------------------------------------------
void LLFloaterWorldMap::trackAvatar( const LLUUID& avatar_id, const std::string& name )
{
LLCtrlSelectionInterface *iface = childGetSelectionInterface("friend combo");
if (!iface) return;
buildAvatarIDList();
if(iface->setCurrentByID(avatar_id) || gAgent.isGodlike())
{
// *HACK: Adjust Z values automatically for liaisons & gods so
// they swoop down when they click on the map. Requested
// convenience.
if(gAgent.isGodlike())
{
childSetValue("spin z", LLSD(200.f));
}
// Don't re-request info if we already have it or we won't have it in time to teleport
if (mTrackedStatus != LLTracker::TRACKING_AVATAR || name != mTrackedAvatarName)
{
mTrackedStatus = LLTracker::TRACKING_AVATAR;
mTrackedAvatarName = name;
LLTracker::trackAvatar(avatar_id, name);
}
}
else
{
LLTracker::stopTracking(NULL);
}
setDefaultBtn("Teleport");
}
void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id )
{
LLCtrlSelectionInterface *iface = childGetSelectionInterface("landmark combo");
if (!iface) return;
buildLandmarkIDLists();
BOOL found = FALSE;
S32 idx;
for (idx = 0; idx < mLandmarkItemIDList.count(); idx++)
{
if ( mLandmarkItemIDList.get(idx) == landmark_item_id)
{
found = TRUE;
break;
}
}
if (found && iface->setCurrentByID( landmark_item_id ) )
{
LLUUID asset_id = mLandmarkAssetIDList.get( idx );
std::string name;
LLComboBox* combo = getChild<LLComboBox>( "landmark combo");
if (combo) name = combo->getSimple();
mTrackedStatus = LLTracker::TRACKING_LANDMARK;
LLTracker::trackLandmark(mLandmarkAssetIDList.get( idx ), // assetID
mLandmarkItemIDList.get( idx ), // itemID
name); // name
if( asset_id != sHomeID )
{
// start the download process
gLandmarkList.getAsset( asset_id);
}
// We have to download both region info and landmark data, so set busy. JC
// getWindow()->incBusyCount();
}
else
{
LLTracker::stopTracking(NULL);
}
setDefaultBtn("Teleport");
}
void LLFloaterWorldMap::trackEvent(const LLItemInfo &event_info)
{
mTrackedStatus = LLTracker::TRACKING_LOCATION;
LLTracker::trackLocation(event_info.getGlobalPosition(), event_info.getName(), event_info.getToolTip(), LLTracker::LOCATION_EVENT);
setDefaultBtn("Teleport");
}
void LLFloaterWorldMap::trackGenericItem(const LLItemInfo &item)
{
mTrackedStatus = LLTracker::TRACKING_LOCATION;
LLTracker::trackLocation(item.getGlobalPosition(), item.getName(), item.getToolTip(), LLTracker::LOCATION_ITEM);
setDefaultBtn("Teleport");
}
void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
{
LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global);
if (!sim_info)
{
// We haven't found a region for that point yet, leave the tracking to the world map
LLWorldMap::getInstance()->setTracking(pos_global);
LLTracker::stopTracking(NULL);
S32 world_x = S32(pos_global.mdV[0] / 256);
S32 world_y = S32(pos_global.mdV[1] / 256);
LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true);
setDefaultBtn("");
// clicked on a non-region - turn off coord display
enableTeleportCoordsDisplay( false );
return;
}
if (sim_info->isDown())
{
// Down region. Show the blue circle of death!
// i.e. let the world map that this and tell it it's invalid
LLWorldMap::getInstance()->setTracking(pos_global);
LLWorldMap::getInstance()->setTrackingInvalid();
LLTracker::stopTracking(NULL);
setDefaultBtn("");
// clicked on a down region - turn off coord display
enableTeleportCoordsDisplay( false );
return;
}
std::string sim_name = sim_info->getName();
F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
std::string full_name = llformat("%s (%d, %d, %d)",
// sim_name.c_str(),
// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-04 (RLVa-1.0.0a)
(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? sim_name.c_str() : RlvStrings::getString(RLV_STRING_HIDDEN_REGION).c_str(),
// [/RLVa:KB]
llround(region_x),
llround(region_y),
llround((F32)pos_global.mdV[VZ]));
std::string tooltip("");
mTrackedStatus = LLTracker::TRACKING_LOCATION;
LLTracker::trackLocation(pos_global, full_name, tooltip);
LLWorldMap::getInstance()->cancelTracking(); // The floater is taking over the tracking
LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal();
updateTeleportCoordsDisplay( coord_pos );
// we have a valid region - turn on coord display
enableTeleportCoordsDisplay( true );
setDefaultBtn("Teleport");
}
// enable/disable teleport destination coordinates
void LLFloaterWorldMap::enableTeleportCoordsDisplay( bool enabled )
{
childSetEnabled("spin x", enabled );
childSetEnabled("spin y", enabled );
childSetEnabled("spin z", enabled );
}
// update display of teleport destination coordinates - pos is in global coordinates
void LLFloaterWorldMap::updateTeleportCoordsDisplay( const LLVector3d& pos )
{
// if we're going to update their value, we should also enable them
enableTeleportCoordsDisplay( true );
// convert global specified position to a local one
F32 region_local_x = (F32)fmod( pos.mdV[VX], (F64)REGION_WIDTH_METERS );
F32 region_local_y = (F32)fmod( pos.mdV[VY], (F64)REGION_WIDTH_METERS );
F32 region_local_z = (F32)llclamp( pos.mdV[VZ], 0.0, (F64)REGION_HEIGHT_METERS );
// write in the values
childSetValue("spin x", region_local_x );
childSetValue("spin y", region_local_y );
childSetValue("spin z", region_local_z );
}
void LLFloaterWorldMap::updateLocation()
{
bool gotSimName;
LLTracker::ETrackingStatus status = LLTracker::getTrackingStatus();
// These values may get updated by a message, so need to check them every frame
// The fields may be changed by the user, so only update them if the data changes
LLVector3d pos_global = LLTracker::getTrackedPositionGlobal();
if (pos_global.isExactlyZero())
{
LLVector3d agentPos = gAgent.getPositionGlobal();
// Set to avatar's current postion if nothing is selected
if ( status == LLTracker::TRACKING_NOTHING && mSetToUserPosition )
{
// Make sure we know where we are before setting the current user position
std::string agent_sim_name;
gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal( agentPos, agent_sim_name );
if ( gotSimName )
{
mSetToUserPosition = FALSE;
// Fill out the location field
childSetValue("location", agent_sim_name);
// update the coordinate display with location of avatar in region
updateTeleportCoordsDisplay( agentPos );
S32 x = llround( (F32)fmod( (F32)agentPos[VX], (F32)REGION_WIDTH_METERS ) );
S32 y = llround( (F32)fmod( (F32)agentPos[VY], (F32)REGION_WIDTH_METERS ) );
S32 z = llround( (F32)agentPos[VZ] );
// Figure out where user is
// Set the current SLURL
mSLURL = LLURLDispatcher::buildSLURL(agent_sim_name, x, y, z);
// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
{
childSetValue("location", RlvStrings::getString(RLV_STRING_HIDDEN_REGION));
mSLURL.clear();
}
// [/RLVa:KB]
}
}
return; // invalid location
}
std::string sim_name;
gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal( pos_global, sim_name );
if ((status != LLTracker::TRACKING_NOTHING) &&
(status != mTrackedStatus || pos_global != mTrackedLocation || sim_name != mTrackedSimName))
{
mTrackedStatus = status;
mTrackedLocation = pos_global;
mTrackedSimName = sim_name;
if (status == LLTracker::TRACKING_AVATAR)
{
// *HACK: Adjust Z values automatically for liaisons &
// gods so they swoop down when they click on the
// map. Requested convenience.
if(gAgent.isGodlike())
{
pos_global[2] = 200;
}
}
childSetValue("location", sim_name);
// refresh coordinate display to reflect where user clicked.
LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal();
updateTeleportCoordsDisplay( coord_pos );
// simNameFromPosGlobal can fail, so don't give the user an invalid SLURL
if ( gotSimName )
{
LLVector3d agentPos = gAgent.getPositionGlobal();
S32 x = llround( (F32)fmod( (F32)agentPos[VX], (F32)REGION_WIDTH_METERS ) );
S32 y = llround( (F32)fmod( (F32)agentPos[VY], (F32)REGION_WIDTH_METERS ) );
S32 z = llround( (F32)agentPos[VZ] );
mSLURL = LLURLDispatcher::buildSLURL(sim_name, x, y, z);
}
else
{ // Empty SLURL will disable the "Copy SLURL to clipboard" button
mSLURL = "";
}
// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
{
childSetValue("location", RlvStrings::getString(RLV_STRING_HIDDEN_REGION));
mSLURL.clear();
}
// [/RLVa:KB]
}
}
void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S32 y_coord, S32 z_coord)
{
LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromName(region_name);
z_coord = llclamp(z_coord, 0, 4096);
if (sim_info)
{
LLVector3 local_pos;
local_pos.mV[VX] = (F32)x_coord;
local_pos.mV[VY] = (F32)y_coord;
local_pos.mV[VZ] = (F32)z_coord;
LLVector3d global_pos = sim_info->getGlobalPos(local_pos);
trackLocation(global_pos);
setDefaultBtn("Teleport");
}
else
{
// fill in UI based on URL
gFloaterWorldMap->childSetValue("location", region_name);
// Save local coords to highlight position after region global
// position is returned.
gFloaterWorldMap->mCompletingRegionPos.set(
(F32)x_coord, (F32)y_coord, (F32)z_coord);
// pass sim name to combo box
gFloaterWorldMap->mCompletingRegionName = region_name;
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name);
LLStringUtil::toLower(gFloaterWorldMap->mCompletingRegionName);
LLWorldMap::getInstance()->setTrackingCommit();
}
}
void LLFloaterWorldMap::observeInventory(LLInventoryModel* model)
{
if(mInventory)
{
mInventory->removeObserver(mInventoryObserver);
delete mInventoryObserver;
mInventory = NULL;
mInventoryObserver = NULL;
}
if(model)
{
mInventory = model;
mInventoryObserver = new LLMapInventoryObserver;
// Inventory deletes all observers on shutdown
mInventory->addObserver(mInventoryObserver);
inventoryChanged();
}
}
void LLFloaterWorldMap::inventoryChanged()
{
if(!LLTracker::getTrackedLandmarkItemID().isNull())
{
LLUUID item_id = LLTracker::getTrackedLandmarkItemID();
buildLandmarkIDLists();
trackLandmark(item_id);
}
}
void LLFloaterWorldMap::observeFriends()
{
if(!mFriendObserver)
{
mFriendObserver = new LLMapFriendObserver;
LLAvatarTracker::instance().addObserver(mFriendObserver);
friendsChanged();
}
}
void LLFloaterWorldMap::friendsChanged()
{
LLAvatarTracker& t = LLAvatarTracker::instance();
const LLUUID& avatar_id = t.getAvatarID();
buildAvatarIDList();
if(avatar_id.notNull())
{
LLCtrlSelectionInterface *iface = childGetSelectionInterface("friend combo");
const LLRelationship* buddy_info = t.getBuddyInfo(avatar_id);
if(!iface ||
!iface->setCurrentByID(avatar_id) ||
(buddy_info && !buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)) ||
gAgent.isGodlike())
{
LLTracker::stopTracking(NULL);
}
}
}
// No longer really builds a list. Instead, just updates mAvatarCombo.
void LLFloaterWorldMap::buildAvatarIDList()
{
LLCtrlListInterface *list = mListFriendCombo;
if (!list) return;
// Delete all but the "None" entry
S32 list_size = list->getItemCount();
if (list_size > 1)
{
list->selectItemRange(1, -1);
list->operateOnSelection(LLCtrlListInterface::OP_DELETE);
}
// Get all of the calling cards for avatar that are currently online
LLCollectMappableBuddies collector;
LLAvatarTracker::instance().applyFunctor(collector);
LLCollectMappableBuddies::buddy_map_t::iterator it;
LLCollectMappableBuddies::buddy_map_t::iterator end;
it = collector.mMappable.begin();
end = collector.mMappable.end();
for( ; it != end; ++it)
{
list->addSimpleElement((*it).first, ADD_BOTTOM, (*it).second);
}
list->setCurrentByID( LLAvatarTracker::instance().getAvatarID() );
list->selectFirstItem();
}
void LLFloaterWorldMap::buildLandmarkIDLists()
{
LLCtrlListInterface *list = mListLandmarkCombo;
if (!list) return;
// Delete all but the "None" entry
S32 list_size = list->getItemCount();
if (list_size > 1)
{
list->selectItemRange(1, -1);
list->operateOnSelection(LLCtrlListInterface::OP_DELETE);
}
mLandmarkItemIDList.reset();
mLandmarkAssetIDList.reset();
// Get all of the current landmarks
mLandmarkAssetIDList.put( LLUUID::null );
mLandmarkItemIDList.put( LLUUID::null );
mLandmarkAssetIDList.put( sHomeID );
mLandmarkItemIDList.put( sHomeID );
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLIsType is_landmark(LLAssetType::AT_LANDMARK);
gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
is_landmark);
std::sort(items.begin(), items.end(), LLViewerInventoryItem::comparePointers());
S32 count = items.count();
for(S32 i = 0; i < count; ++i)
{
LLInventoryItem* item = items.get(i);
list->addSimpleElement(item->getName(), ADD_BOTTOM, item->getUUID());
mLandmarkAssetIDList.put( item->getAssetUUID() );
mLandmarkItemIDList.put( item->getUUID() );
}
list->sortByColumn(std::string("landmark name"), TRUE);
list->selectFirstItem();
}
F32 LLFloaterWorldMap::getDistanceToDestination(const LLVector3d &destination,
F32 z_attenuation) const
{
LLVector3d delta = destination - gAgent.getPositionGlobal();
// by attenuating the z-component we effectively
// give more weight to the x-y plane
delta.mdV[VZ] *= z_attenuation;
F32 distance = (F32)delta.magVec();
return distance;
}
void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui)
{
LLCtrlListInterface *list = mListSearchResults;
if (list)
{
list->operateOnAll(LLCtrlListInterface::OP_DELETE);
}
if (!childHasKeyboardFocus("spin x"))
{
childSetValue("spin x", SIM_COORD_DEFAULT);
}
if (!childHasKeyboardFocus("spin y"))
{
childSetValue("spin y", SIM_COORD_DEFAULT);
}
if (!childHasKeyboardFocus("spin z"))
{
childSetValue("spin z", 0);
}
//Singu Note: Don't do this. It basically 'eats' the first click onto void space if the previous tracked target was a valid sim.
//LLWorldMap::getInstance()->cancelTracking();
mCompletingRegionName = "";
}
void LLFloaterWorldMap::clearLandmarkSelection(BOOL clear_ui)
{
if (clear_ui || !childHasKeyboardFocus("landmark combo"))
{
LLCtrlListInterface *list = mListLandmarkCombo;
if (list)
{
list->selectByValue( "None" );
}
}
}
void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui)
{
if (clear_ui || !childHasKeyboardFocus("friend combo"))
{
mTrackedStatus = LLTracker::TRACKING_NOTHING;
LLCtrlListInterface *list = mListFriendCombo;
if (list)
{
list->selectByValue( "None" );
}
}
}
// Adjust the maximally zoomed out limit of the zoom slider so you
// can see the whole world, plus a little.
void LLFloaterWorldMap::adjustZoomSliderBounds()
{
// Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed
// width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across
// sessions and doesn't prevent the user to pan the world if it was to grow a lot beyond that limit.
// Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window.
S32 world_width_regions = MAX_VISIBLE_REGIONS;
S32 world_height_regions = MAX_VISIBLE_REGIONS;
// Find how much space we have to display the world
LLWorldMapView* map_panel;
map_panel = (LLWorldMapView*)mPanel;
LLRect view_rect = map_panel->getRect();
// View size in pixels
S32 view_width = view_rect.getWidth();
S32 view_height = view_rect.getHeight();
// Pixels per region to display entire width/height
F32 width_pixels_per_region = (F32) view_width / (F32) world_width_regions;
F32 height_pixels_per_region = (F32) view_height / (F32) world_height_regions;
F32 pixels_per_region = llmin(width_pixels_per_region,
height_pixels_per_region);
// Round pixels per region to an even number of slider increments
S32 slider_units = llfloor(pixels_per_region / 0.2f);
pixels_per_region = slider_units * 0.2f;
// Make sure the zoom slider can be moved at least a little bit.
// Likewise, less than the increment pixels per region is just silly.
pixels_per_region = llclamp(pixels_per_region, 1.f, ZOOM_MAX);
F32 min_power = log(pixels_per_region/256.f)/log(2.f);
childSetMinValue("zoom slider", min_power);
}
//-------------------------------------------------------------------------
// User interface widget callbacks
//-------------------------------------------------------------------------
void LLFloaterWorldMap::onGoHome()
{
gAgent.teleportHome();
close();
}
// static
void LLFloaterWorldMap::onLandmarkComboPrearrange( LLUICtrl* ctrl, void* userdata )
{
LLFloaterWorldMap* self = gFloaterWorldMap;
if( !self || self->mIsClosing )
{
return;
}
LLCtrlListInterface *list = self->childGetListInterface("landmark combo");
if (!list) return;
LLUUID current_choice = list->getCurrentID();
gFloaterWorldMap->buildLandmarkIDLists();
if( current_choice.isNull() || !list->setCurrentByID( current_choice ) )
{
LLTracker::stopTracking(NULL);
}
}
void LLFloaterWorldMap::onComboTextEntry( LLLineEditor* ctrl, void* userdata )
{
// Reset the tracking whenever we start typing into any of the search fields,
// so that hitting <enter> does an auto-complete versus teleporting us to the
// previously selected landmark/friend.
LLTracker::stopTracking(NULL);
}
// static
void LLFloaterWorldMap::onSearchTextEntry( LLLineEditor* ctrl, void* userdata )
{
onComboTextEntry(ctrl, userdata);
gFloaterWorldMap->updateSearchEnabled();
}
// static
void LLFloaterWorldMap::onLandmarkComboCommit()
{
if( mIsClosing )
{
return;
}
LLCtrlListInterface *list = mListLandmarkCombo;
if (!list) return;
LLUUID asset_id;
LLUUID item_id = list->getCurrentID();
LLTracker::stopTracking(NULL);
//RN: stopTracking() clears current combobox selection, need to reassert it here
list->setCurrentByID(item_id);
if( item_id.isNull() )
{
}
else if( item_id == sHomeID )
{
asset_id = sHomeID;
}
else
{
LLInventoryItem* item = gInventory.getItem( item_id );
if( item )
{
asset_id = item->getAssetUUID();
}
else
{
// Something went wrong, so revert to a safe value.
item_id.setNull();
}
}
trackLandmark( item_id);
onShowTargetBtn();
// Reset to user postion if nothing is tracked
mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
}
// static
void LLFloaterWorldMap::onAvatarComboPrearrange( LLUICtrl* ctrl, void* userdata )
{
LLFloaterWorldMap* self = gFloaterWorldMap;
if( !self || self->mIsClosing )
{
return;
}
LLCtrlListInterface *list = self->childGetListInterface("friend combo");
if (!list) return;
LLUUID current_choice;
if( LLAvatarTracker::instance().haveTrackingInfo() )
{
current_choice = LLAvatarTracker::instance().getAvatarID();
}
self->buildAvatarIDList();
if( !list->setCurrentByID( current_choice ) || current_choice.isNull() )
{
LLTracker::stopTracking(NULL);
}
}
void LLFloaterWorldMap::onAvatarComboCommit()
{
if( mIsClosing )
{
return;
}
LLCtrlListInterface *list = mListFriendCombo;
if (!list) return;
const LLUUID& new_avatar_id = list->getCurrentID();
if (new_avatar_id.notNull())
{
std::string name;
LLComboBox* combo = getChild<LLComboBox>("friend combo");
if (combo) name = combo->getSimple();
trackAvatar(new_avatar_id, name);
onShowTargetBtn();
}
else
{ // Reset to user postion if nothing is tracked
mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
}
}
void LLFloaterWorldMap::onLocationFocusChanged( LLFocusableElement* focus )
{
updateSearchEnabled();
}
void LLFloaterWorldMap::updateSearchEnabled()
{
if (childHasKeyboardFocus("location") &&
childGetValue("location").asString().length() > 0)
{
setDefaultBtn("DoSearch");
}
else
{
setDefaultBtn(NULL);
}
}
void LLFloaterWorldMap::onLocationCommit()
{
if( mIsClosing )
{
return;
}
clearLocationSelection(FALSE);
mCompletingRegionName = "";
mLastRegionName = "";
std::string str = childGetValue("location").asString();
// Trim any leading and trailing spaces in the search target
std::string saved_str = str;
LLStringUtil::trim( str );
if ( str != saved_str )
{ // Set the value in the UI if any spaces were removed
childSetValue("location", str);
}
// Don't try completing empty name (STORM-1427).
if (str.empty())
{
return;
}
LLStringUtil::toLower(str);
mCompletingRegionName = str;
LLWorldMap::getInstance()->setTrackingCommit();
if (str.length() >= 3)
{
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(str);
}
else
{
str += "#";
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(str);
}
}
void LLFloaterWorldMap::onCoordinatesCommit()
{
if( mIsClosing )
{
return;
}
S32 x_coord = (S32)childGetValue("spin x").asReal();
S32 y_coord = (S32)childGetValue("spin y").asReal();
S32 z_coord = (S32)childGetValue("spin z").asReal();
const std::string region_name = childGetValue("location").asString();
trackURL( region_name, x_coord, y_coord, z_coord );
}
void LLFloaterWorldMap::onClearBtn()
{
mTrackedStatus = LLTracker::TRACKING_NOTHING;
LLTracker::stopTracking((void *)(intptr_t)TRUE);
LLWorldMap::getInstance()->cancelTracking();
mSLURL = ""; // Clear the SLURL since it's invalid
mSetToUserPosition = TRUE; // Revert back to the current user position
}
void LLFloaterWorldMap::onShowTargetBtn()
{
centerOnTarget(TRUE);
}
void LLFloaterWorldMap::onShowAgentBtn()
{
LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate
// Set flag so user's location will be displayed if not tracking anything else
mSetToUserPosition = TRUE;
}
void LLFloaterWorldMap::onClickTeleportBtn()
{
teleport();
}
void LLFloaterWorldMap::onCopySLURL()
{
getWindow()->copyTextToClipboard(utf8str_to_wstring(mSLURL));
LLSD args;
args["SLURL"] = mSLURL;
LLNotificationsUtil::add("CopySLURL", args);
}
// protected
void LLFloaterWorldMap::centerOnTarget(BOOL animate)
{
LLVector3d pos_global;
if(LLTracker::getTrackingStatus() != LLTracker::TRACKING_NOTHING)
{
LLVector3d tracked_position = LLTracker::getTrackedPositionGlobal();
//RN: tracker doesn't allow us to query completion, so we check for a tracking position of
// absolute zero, and keep trying in the draw loop
if (tracked_position.isExactlyZero())
{
mWaitingForTracker = TRUE;
return;
}
else
{
// We've got the position finally, so we're no longer busy. JC
// getWindow()->decBusyCount();
pos_global = LLTracker::getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal();
}
}
else if(LLWorldMap::getInstance()->isTracking())
{
pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal();;
}
else
{
// default behavior = center on agent
pos_global.clearVec();
}
LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sPixelsPerMeter)),
-llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sPixelsPerMeter)),
!animate);
mWaitingForTracker = FALSE;
}
// protected
void LLFloaterWorldMap::fly()
{
LLVector3d pos_global = LLTracker::getTrackedPositionGlobal();
// Start the autopilot and close the floater,
// so we can see where we're flying
if (!pos_global.isExactlyZero())
{
gAgent.startAutoPilotGlobal( pos_global );
close();
}
else
{
make_ui_sound("UISndInvalidOp");
}
}
// protected
void LLFloaterWorldMap::teleport()
{
BOOL teleport_home = FALSE;
LLVector3d pos_global;
LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
if (LLTracker::TRACKING_AVATAR == tracking_status
&& av_tracker.haveTrackingInfo() )
{
pos_global = av_tracker.getGlobalPos();
pos_global.mdV[VZ] = childGetValue("spin z");
}
else if ( LLTracker::TRACKING_LANDMARK == tracking_status)
{
if( LLTracker::getTrackedLandmarkAssetID() == sHomeID )
{
teleport_home = TRUE;
}
else
{
LLLandmark* landmark = gLandmarkList.getAsset( LLTracker::getTrackedLandmarkAssetID() );
LLUUID region_id;
if(landmark
&& !landmark->getGlobalPos(pos_global)
&& landmark->getRegionID(region_id))
{
LLLandmark::requestRegionHandle(
gMessageSystem,
gAgent.getRegionHost(),
region_id,
NULL);
}
}
}
else if ( LLTracker::TRACKING_LOCATION == tracking_status)
{
pos_global = LLTracker::getTrackedPositionGlobal();
}
else
{
make_ui_sound("UISndInvalidOp");
}
// Do the teleport, which will also close the floater
if (teleport_home)
{
gAgent.teleportHome();
}
else if (!pos_global.isExactlyZero())
{
if(LLTracker::TRACKING_LANDMARK == tracking_status)
{
gAgent.teleportViaLandmark(LLTracker::getTrackedLandmarkAssetID());
}
else
{
gAgent.teleportViaLocation( pos_global );
}
}
}
void LLFloaterWorldMap::flyToLandmark()
{
LLVector3d destination_pos_global;
if( !LLTracker::getTrackedLandmarkAssetID().isNull() )
{
if (LLTracker::hasLandmarkPosition())
{
gAgent.startAutoPilotGlobal( LLTracker::getTrackedPositionGlobal() );
}
}
}
void LLFloaterWorldMap::teleportToLandmark()
{
BOOL has_destination = FALSE;
LLUUID destination_id; // Null means "home"
if( LLTracker::getTrackedLandmarkAssetID() == sHomeID )
{
has_destination = TRUE;
}
else
{
LLLandmark* landmark = gLandmarkList.getAsset( LLTracker::getTrackedLandmarkAssetID() );
LLVector3d global_pos;
if(landmark && landmark->getGlobalPos(global_pos))
{
destination_id = LLTracker::getTrackedLandmarkAssetID();
has_destination = TRUE;
}
else if(landmark)
{
// pop up an anonymous request request.
LLUUID region_id;
if(landmark->getRegionID(region_id))
{
LLLandmark::requestRegionHandle(
gMessageSystem,
gAgent.getRegionHost(),
region_id,
NULL);
}
}
}
if( has_destination )
{
gAgent.teleportViaLandmark( destination_id );
}
}
void LLFloaterWorldMap::teleportToAvatar()
{
LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
if(av_tracker.haveTrackingInfo())
{
LLVector3d pos_global = av_tracker.getGlobalPos();
gAgent.teleportViaLocation( pos_global );
}
}
void LLFloaterWorldMap::flyToAvatar()
{
if( LLAvatarTracker::instance().haveTrackingInfo() )
{
gAgent.startAutoPilotGlobal( LLAvatarTracker::instance().getGlobalPos() );
}
}
void LLFloaterWorldMap::updateSims(bool found_null_sim)
{
if (mCompletingRegionName == "")
{
return;
}
LLScrollListCtrl *list = getChild<LLScrollListCtrl>("search_results");
list->operateOnAll(LLCtrlListInterface::OP_DELETE);
S32 name_length = mCompletingRegionName.length();
LLSD match;
S32 num_results = 0;
std::vector<std::pair <U64, LLSimInfo*> > sim_info_vec(LLWorldMap::getInstance()->getRegionMap().begin(), LLWorldMap::getInstance()->getRegionMap().end());
std::sort(sim_info_vec.begin(), sim_info_vec.end(), SortRegionNames());
for (std::vector<std::pair <U64, LLSimInfo*> >::const_iterator it = sim_info_vec.begin(); it != sim_info_vec.end(); ++it)
{
LLSimInfo* info = it->second;
std::string sim_name_lower = info->getName();
LLStringUtil::toLower(sim_name_lower);
if (sim_name_lower.substr(0, name_length) == mCompletingRegionName)
{
if (sim_name_lower == mCompletingRegionName)
{
match = info->getName();
}
LLSD value;
value["id"] = info->getName();
value["columns"][0]["column"] = "sim_name";
value["columns"][0]["value"] = info->getName();
list->addElement(value);
num_results++;
}
}
if (found_null_sim || match.isDefined())
{
mCompletingRegionName = "";
}
if (num_results > 0)
{
// if match found, highlight it and go
if (!match.isUndefined())
{
list->selectByValue(match);
}
// else select first found item
else
{
list->selectFirstItem();
}
childSetFocus("search_results");
onCommitSearchResult();
}
else
{
// if we found nothing, say "none"
list->setCommentText(LLTrans::getString("worldmap_results_none_found"));
list->operateOnAll(LLCtrlListInterface::OP_DESELECT);
}
}
void LLFloaterWorldMap::onCommitSearchResult()
{
LLCtrlListInterface *list = mListSearchResults;
if (!list) return;
LLSD selected_value = list->getSelectedValue();
std::string sim_name = selected_value.asString();
if (sim_name.empty())
{
return;
}
LLStringUtil::toLower(sim_name);
std::map<U64, LLSimInfo*>::const_iterator it;
for (it = LLWorldMap::getInstance()->getRegionMap().begin(); it != LLWorldMap::getInstance()->getRegionMap().end(); ++it)
{
LLSimInfo* info = it->second;
if (info->isName(sim_name))
{
LLVector3d pos_global = info->getGlobalOrigin();
const F64 SIM_COORD_DEFAULT = 128.0;
LLVector3 pos_local(SIM_COORD_DEFAULT, SIM_COORD_DEFAULT, 0.0f);
// Did this value come from a trackURL() request?
if (!mCompletingRegionPos.isExactlyZero())
{
pos_local = mCompletingRegionPos;
mCompletingRegionPos.clear();
}
pos_global.mdV[VX] += (F64)pos_local.mV[VX];
pos_global.mdV[VY] += (F64)pos_local.mV[VY];
pos_global.mdV[VZ] = (F64)pos_local.mV[VZ];
childSetValue("location", sim_name);
trackLocation(pos_global);
setDefaultBtn("Teleport");
break;
}
}
onShowTargetBtn();
}
void LLFloaterWorldMap::onChangeMaturity()
{
bool can_access_mature = gAgent.canAccessMature();
bool can_access_adult = gAgent.canAccessAdult();
childSetVisible("events_mature_icon", can_access_mature);
childSetVisible("event_mature_chk", can_access_mature);
childSetVisible("events_adult_icon", can_access_adult);
childSetVisible("event_adult_chk", can_access_adult);
// disable mature / adult events.
if (!can_access_mature)
{
static LLCachedControl<bool> show_mature("MapShowMatureEvents",false);
show_mature = false;
}
if (!can_access_adult)
{
static LLCachedControl<bool> show_adult("MapShowAdultEvents",false);
show_adult = false;
}
}