aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview')
-rw-r--r--linden/indra/newview/app_settings/settings.xml2
-rw-r--r--linden/indra/newview/llfloatermap.cpp624
-rw-r--r--linden/indra/newview/llfloatermap.h46
-rw-r--r--linden/indra/newview/llnetmap.cpp13
-rw-r--r--linden/indra/newview/llnetmap.h6
-rw-r--r--linden/indra/newview/skins/default/colors_base.xml1
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_mini_map.xml97
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/panel_mini_map.xml2
8 files changed, 781 insertions, 10 deletions
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml
index 6d2f0c5..4ae2db3 100644
--- a/linden/indra/newview/app_settings/settings.xml
+++ b/linden/indra/newview/app_settings/settings.xml
@@ -5234,7 +5234,7 @@
5234 <key>Type</key> 5234 <key>Type</key>
5235 <string>F32</string> 5235 <string>F32</string>
5236 <key>Value</key> 5236 <key>Value</key>
5237 <integer>20</integer> 5237 <integer>96</integer>
5238 </map> 5238 </map>
5239 <key>NewCacheLocation</key> 5239 <key>NewCacheLocation</key>
5240 <map> 5240 <map>
diff --git a/linden/indra/newview/llfloatermap.cpp b/linden/indra/newview/llfloatermap.cpp
index 8714d4f..29a95c2 100644
--- a/linden/indra/newview/llfloatermap.cpp
+++ b/linden/indra/newview/llfloatermap.cpp
@@ -42,14 +42,39 @@
42#include "llresizebar.h" 42#include "llresizebar.h"
43#include "lluictrlfactory.h" 43#include "lluictrlfactory.h"
44 44
45// radar
46#include "llfloateravatarinfo.h"
47#include "llfloaterfriends.h"
48#include "llfloatergroupinvite.h"
49#include "llfloatergroups.h"
50#include "llfloaterreporter.h"
51#include "llimview.h"
52#include "llmutelist.h"
53#include "roles_constants.h"
54#include "llscrolllistctrl.h"
55#include "lltracker.h"
56#include "llviewerobjectlist.h"
57#include "llviewermessage.h"
58#include "llviewerregion.h"
59#include "llviewerwindow.h"
60#include "llworld.h"
61
62LLFloaterMap* LLFloaterMap::sInstance = NULL;
63
45LLFloaterMap::LLFloaterMap(const LLSD& key) 64LLFloaterMap::LLFloaterMap(const LLSD& key)
46 : 65 :
47 LLFloater(std::string("minimap")), 66 LLFloater(std::string("minimap")),
48 mPanelMap(NULL) 67 mPanelMap(NULL),
68 mUpdate(TRUE)
49{ 69{
50 LLCallbackMap::map_t factory_map; 70 LLCallbackMap::map_t factory_map;
51 factory_map["mini_mapview"] = LLCallbackMap(createPanelMiniMap, this); 71 factory_map["mini_mapview"] = LLCallbackMap(createPanelMiniMap, this);
52 LLUICtrlFactory::getInstance()->buildFloater(this, "floater_mini_map.xml", &factory_map, FALSE); 72 LLUICtrlFactory::getInstance()->buildFloater(this, "floater_mini_map.xml", &factory_map, FALSE);
73
74 mSelectedAvatar.setNull();
75 mAvatars.clear();
76
77 sInstance = this;
53} 78}
54 79
55 80
@@ -67,12 +92,37 @@ BOOL LLFloaterMap::postBuild()
67 sendChildToBack(getDragHandle()); 92 sendChildToBack(getDragHandle());
68 sendChildToFront(getChild<LLButton>("llfloater_close_btn")); 93 sendChildToFront(getChild<LLButton>("llfloater_close_btn"));
69 setIsChrome(TRUE); 94 setIsChrome(TRUE);
95
96 mRadarList = getChild<LLScrollListCtrl>("RadarList");
97 childSetCommitCallback("RadarList", onList, this);
98 mRadarList->setDoubleClickCallback(onClickIM);
99
100 childSetFocusChangedCallback("near_me_range", onRangeChange, this);
101
102 childSetAction("im_btn", onClickIM, this);
103 childSetAction("profile_btn", onClickProfile, this);
104 childSetAction("offer_teleport_btn", onClickOfferTeleport, this);
105 childSetAction("track_btn", onClickTrack, this);
106 childSetAction("invite_btn", onClickInvite, this);
107 childSetAction("add_btn", onClickAddFriend, this);
108 childSetAction("freeze_btn", onClickFreeze, this);
109 childSetAction("eject_btn", onClickEject, this);
110 childSetAction("mute_btn", onClickMute, this);
111 childSetAction("unmute_btn", onClickUnmute, this);
112 childSetAction("ar_btn", onClickAR, this);
113 childSetAction("estate_eject_btn", onClickEjectFromEstate, this);
114
115 setDefaultBtn("im_btn");
116
117 populateRadar();
118
70 return TRUE; 119 return TRUE;
71} 120}
72 121
73 122
74LLFloaterMap::~LLFloaterMap() 123LLFloaterMap::~LLFloaterMap()
75{ 124{
125 sInstance = NULL;
76} 126}
77 127
78 128
@@ -122,7 +172,6 @@ void LLFloaterMap::draw()
122 } 172 }
123} 173}
124 174
125
126// [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-05 (RLVa-1.0.0c) 175// [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-05 (RLVa-1.0.0c)
127void LLFloaterMap::open() 176void LLFloaterMap::open()
128{ 177{
@@ -132,3 +181,574 @@ void LLFloaterMap::open()
132 } 181 }
133} 182}
134// [/RLVa:KB] 183// [/RLVa:KB]
184
185// TODO: make this detachable
186// TODO: make this expand/collapse
187
188/*
189* Imprudence Radar
190* @brief inworld radar integrated with the minimap
191* by McCabe Maxsted
192* Estate tab portion by Dale Glass
193*/
194
195//static
196void LLFloaterMap::updateRadar()
197{
198 LLFloaterMap* self = sInstance;
199 self->populateRadar();
200}
201
202void LLFloaterMap::populateRadar()
203{
204 if (!mUpdate)
205 {
206 return;
207 }
208
209 if (visibleItemsSelected())
210 {
211 mSelectedAvatar = mRadarList->getSelectedValue().asUUID();
212 }
213 else
214 {
215 mSelectedAvatar.setNull();
216 }
217
218 S32 scroll_pos = mRadarList->getScrollPos();
219
220 LLVector3d current_pos = gAgent.getPositionGlobal();
221
222 // find what avatars you can see
223 std::vector<LLUUID> avatar_ids;
224 std::vector<LLVector3d> positions;
225 LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, current_pos, gSavedSettings.getF32("NearMeRange"));
226
227 // Add avatars to the list. If they're already there, update positions
228 std::pair<std::map<LLUUID, LLVector3d>::iterator, bool> ret;
229 for (U32 i=0; i<avatar_ids.size(); i++)
230 {
231 if (avatar_ids[i] == gAgent.getID() ||
232 avatar_ids[i].isNull())
233 {
234 continue;
235 }
236
237 ret = mAvatars.insert(std::pair<LLUUID, LLVector3d>(avatar_ids[i], positions[i]));
238 if (ret.second == false)
239 {
240 mAvatars[avatar_ids[i]] = positions[i];
241 }
242 }
243
244 LLSD element;
245
246 mRadarList->deleteAllItems();
247
248 // if an avatar's not in range anymore, kill it. Otherwise, populate radar
249 std::map<LLUUID, LLVector3d>::iterator mIt;
250 std::vector<LLUUID>::iterator result;
251 for (mIt = mAvatars.begin(); mIt != mAvatars.end(); )
252 {
253 result = find(avatar_ids.begin(), avatar_ids.end(), mIt->first);
254 if (result == avatar_ids.end())
255 {
256 mAvatars.erase(mIt++);
257 }
258 else
259 {
260 // Add to list only if we get their name
261 std::string fullname = getSelectedName(mIt->first);
262 if (!fullname.empty() && fullname != " ")
263 {
264 std::string mute_text = LLMuteList::getInstance()->isMuted(mIt->first) ? getString("muted") : "";
265 element["id"] = mIt->first;
266 element["columns"][0]["column"] = "avatar_name";
267 element["columns"][0]["type"] = "text";
268 element["columns"][0]["value"] = fullname + " " + mute_text;
269 element["columns"][1]["column"] = "avatar_distance";
270 element["columns"][1]["type"] = "text";
271
272 F64 distance = dist_vec(current_pos, mIt->second);
273 std::stringstream dist_formatted;
274 dist_formatted.str("");
275 dist_formatted << (double)((int)((distance + 0.05)*10.0))/10.0 << "m";
276 element["columns"][1]["value"] = dist_formatted.str();
277
278 mRadarList->addElement(element, ADD_BOTTOM);
279 }
280 ++mIt;
281 }
282 }
283
284 mRadarList->sortItems();
285 mRadarList->setScrollPos(scroll_pos);
286
287 if (mSelectedAvatar.notNull())
288 {
289 mRadarList->selectByID(mSelectedAvatar);
290 }
291
292 // set count
293 std::stringstream avatar_count;
294 avatar_count.str("");
295 if (mAvatars.empty())
296 {
297 mRadarList->addCommentText(getString("no_one_near"), ADD_TOP);
298 avatar_count << "0";
299 }
300 else
301 {
302 avatar_count << (int)mAvatars.size();
303 }
304 childSetText("lblAvatarCount", avatar_count.str());
305
306 toggleButtons();
307}
308
309void LLFloaterMap::toggleButtons()
310{
311 BOOL enabled = mRadarList->hasFocus() ? visibleItemsSelected() : FALSE;
312 BOOL unmute_enabled = mRadarList->hasFocus() ? LLMuteList::getInstance()->isMuted(mSelectedAvatar) : FALSE;
313
314 childSetEnabled("im_btn", enabled);
315 childSetEnabled("profile_btn", enabled);
316 childSetEnabled("offer_teleport_btn", enabled);
317 childSetEnabled("track_btn", enabled);
318 childSetEnabled("invite_btn", enabled);
319 childSetEnabled("add_btn", enabled);
320 childSetEnabled("freeze_btn", enabled);
321 childSetEnabled("eject_btn", enabled);
322 childSetEnabled("mute_btn", enabled);
323 childSetEnabled("unmute_btn", unmute_enabled);
324 childSetEnabled("ar_btn", enabled);
325 childSetEnabled("estate_eject_btn", enabled);
326}
327
328// static
329void LLFloaterMap::onList(LLUICtrl* ctrl, void* user_data)
330{
331 LLFloaterMap* self = (LLFloaterMap*)user_data;
332 if (self)
333 {
334 self->toggleButtons();
335 }
336}
337
338
339BOOL LLFloaterMap::visibleItemsSelected() const
340{
341 if (mRadarList->getFirstSelectedIndex() >= 0)
342 {
343 return TRUE;
344 }
345 return FALSE;
346}
347
348// static
349void LLFloaterMap::onRangeChange(LLFocusableElement* focus, void* user_data)
350{
351 LLFloaterMap* self = (LLFloaterMap*)user_data;
352 if (self)
353 {
354 self->mUpdate = !(self->childHasFocus("near_me_range"));
355 }
356}
357
358// static
359BOOL LLFloaterMap::isSelected(LLUUID agent)
360{
361 if (sInstance->mSelectedAvatar == agent)
362 {
363 return TRUE;
364 }
365 return FALSE;
366}
367
368//
369// Avatar tab
370//
371
372// static
373void LLFloaterMap::onClickIM(void* user_data)
374{
375 LLFloaterMap* self = (LLFloaterMap*) user_data;
376 LLScrollListItem *item = self->mRadarList->getFirstSelected();
377 if (item != NULL)
378 {
379 LLUUID agent_id = item->getUUID();
380 std::string fullname;
381 if(gCacheName->getFullName(agent_id, fullname))
382 {
383 gIMMgr->setFloaterOpen(TRUE);
384 gIMMgr->addSession(fullname, IM_NOTHING_SPECIAL, agent_id);
385 }
386 }
387}
388
389// static
390void LLFloaterMap::onClickProfile(void* user_data)
391{
392 LLFloaterMap* self = (LLFloaterMap*) user_data;
393 LLScrollListItem *item = self->mRadarList->getFirstSelected();
394 if (item != NULL)
395 {
396 LLUUID agent_id = item->getUUID();
397 LLFloaterAvatarInfo::show(agent_id);
398 }
399}
400
401// static
402void LLFloaterMap::onClickOfferTeleport(void* user_data)
403{
404 LLFloaterMap* self = (LLFloaterMap*) user_data;
405 LLScrollListItem *item = self->mRadarList->getFirstSelected();
406 if (item != NULL)
407 {
408 LLUUID agent_id = item->getUUID();
409 handle_lure(agent_id);
410 }
411}
412
413// static
414void LLFloaterMap::onClickTrack(void* user_data)
415{
416 LLFloaterMap* self = (LLFloaterMap*) user_data;
417 LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
418 if (LLTracker::TRACKING_AVATAR == tracking_status)
419 {
420 LLTracker::stopTracking(NULL);
421 }
422 else
423 {
424 LLScrollListItem *item = self->mRadarList->getFirstSelected();
425 if (item != NULL)
426 {
427 LLUUID agent_id = item->getUUID();
428 std::string fullname;
429 gCacheName->getFullName(agent_id, fullname);
430 LLTracker::trackAvatar(agent_id, fullname);
431 }
432 }
433}
434
435// static
436void LLFloaterMap::onClickInvite(void* user_data)
437{
438 LLFloaterMap* self = (LLFloaterMap*) user_data;
439 LLScrollListItem *item = self->mRadarList->getFirstSelected();
440 if (item != NULL)
441 {
442 LLUUID agent_id = item->getUUID();
443 LLFloaterGroupPicker* widget;
444 widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
445 if (widget)
446 {
447 widget->center();
448 widget->setPowersMask(GP_MEMBER_INVITE);
449 widget->setSelectCallback(callback_invite_to_group, (void *)&agent_id);
450 }
451 }
452}
453
454// static
455void LLFloaterMap::callback_invite_to_group(LLUUID group_id, void *user_data)
456{
457 std::vector<LLUUID> agent_ids;
458 agent_ids.push_back(*(LLUUID *)user_data);
459
460 LLFloaterGroupInvite::showForGroup(group_id, &agent_ids);
461}
462
463// static
464void LLFloaterMap::onClickAddFriend(void* user_data)
465{
466 LLFloaterMap* self = (LLFloaterMap*) user_data;
467 LLScrollListItem *item = self->mRadarList->getFirstSelected();
468 if (item != NULL)
469 {
470 LLUUID agent_id = item->getUUID();
471 std::string fullname;
472 gCacheName->getFullName(agent_id, fullname);
473 LLPanelFriends::requestFriendshipDialog(agent_id, fullname);
474 }
475}
476
477//
478// Estate tab
479//
480
481//static
482std::string LLFloaterMap::getSelectedName(LLUUID agent_id)
483{
484 std::string agent_name;
485 if(agent_id.notNull() && gCacheName->getFullName(agent_id, agent_name))
486 {
487 return agent_name;
488 }
489 return LLStringUtil::null;
490}
491
492//static
493void LLFloaterMap::callbackFreeze(S32 option, void *user_data)
494{
495 LLFloaterMap *self = (LLFloaterMap*)user_data;
496
497 if ( option == 0 )
498 {
499 sendFreeze(self->mSelectedAvatar, true);
500 }
501 else if ( option == 1 )
502 {
503 sendFreeze(self->mSelectedAvatar, false);
504 }
505}
506
507//static
508void LLFloaterMap::callbackEject(S32 option, void *user_data)
509{
510 LLFloaterMap *self = (LLFloaterMap*)user_data;
511
512 if ( option == 0 )
513 {
514 sendEject(self->mSelectedAvatar, false);
515 }
516 else if ( option == 1 )
517 {
518 sendEject(self->mSelectedAvatar, true);
519 }
520}
521
522//static
523void LLFloaterMap::callbackEjectFromEstate(S32 option, void *user_data)
524{
525 LLFloaterMap *self = (LLFloaterMap*)user_data;
526
527 if ( option == 0 )
528 {
529 cmdEstateEject(self->mSelectedAvatar);
530 }
531 else if ( option == 1 )
532 {
533 cmdEstateBan(self->mSelectedAvatar);
534 }
535}
536
537void LLFloaterMap::onClickFreeze(void *user_data)
538{
539 LLFloaterMap *self = (LLFloaterMap*)user_data;
540 LLStringUtil::format_map_t args;
541 LLSD payload;
542 args["[AVATAR_NAME]"] = self->getSelectedName(self->mSelectedAvatar);
543 gViewerWindow->alertXml("FreezeAvatarFullname", args, callbackFreeze, user_data);
544}
545
546//static
547void LLFloaterMap::onClickEject(void *user_data)
548{
549 LLFloaterMap *self = (LLFloaterMap*)user_data;
550 LLStringUtil::format_map_t args;
551 LLSD payload;
552 args["AVATAR_NAME"] = self->getSelectedName(self->mSelectedAvatar);
553 gViewerWindow->alertXml("EjectAvatarFullName", args, callbackEject, user_data);
554}
555
556//static
557void LLFloaterMap::onClickMute(void *user_data)
558{
559 LLFloaterMap *self = (LLFloaterMap*)user_data;
560
561 LLUUID agent_id = self->mSelectedAvatar;
562 std::string agent_name = self->getSelectedName(agent_id);
563 if(!agent_name.empty())
564 {
565 if (LLMuteList::getInstance()->isMuted(agent_id))
566 {
567 //LLMute mute(agent_id, agent_name, LLMute::AGENT);
568 //LLMuteList::getInstance()->remove(mute);
569 //LLFloaterMute::getInstance()->selectMute(agent_id);
570 }
571 else
572 {
573 LLMute mute(agent_id, agent_name, LLMute::AGENT);
574 LLMuteList::getInstance()->add(mute);
575 }
576 }
577}
578
579//static
580void LLFloaterMap::onClickUnmute(void *user_data)
581{
582 LLFloaterMap *self = (LLFloaterMap*)user_data;
583
584 LLUUID agent_id = self->mSelectedAvatar;
585 std::string agent_name = self->getSelectedName(agent_id);
586 if(!agent_name.empty())
587 {
588 if (LLMuteList::getInstance()->isMuted(agent_id))
589 {
590 LLMute mute(agent_id, agent_name, LLMute::AGENT);
591 LLMuteList::getInstance()->remove(mute);
592 //LLFloaterMute::getInstance()->selectMute(agent_id);
593 }
594 else
595 {
596 //LLMute mute(agent_id, agent_name, LLMute::AGENT);
597 //LLMuteList::getInstance()->add(mute);
598 }
599 }
600}
601
602//static
603void LLFloaterMap::onClickEjectFromEstate(void *user_data)
604{
605 LLFloaterMap *self = (LLFloaterMap*)user_data;
606 LLStringUtil::format_map_t args;
607 LLSD payload;
608 args["EVIL_USER"] = self->getSelectedName(self->mSelectedAvatar);
609 gViewerWindow->alertXml("EstateKickUser", args, callbackEjectFromEstate, user_data);
610}
611
612//static
613void LLFloaterMap::onClickAR(void *user_data)
614{
615 LLFloaterMap *self = (LLFloaterMap*)user_data;
616 LLUUID agent_id = self->mSelectedAvatar;
617
618 if (agent_id.notNull())
619 {
620 LLFloaterReporter::showFromObject(agent_id);
621 }
622}
623
624// static
625void LLFloaterMap::cmdEstateEject(const LLUUID &avatar)
626{
627 sendEstateMessage("teleporthomeuser", avatar);
628}
629
630// static
631void LLFloaterMap::cmdEstateBan(const LLUUID &avatar)
632{
633 sendEstateMessage("teleporthomeuser", avatar); // Kick first, just to be sure
634 sendEstateBan(avatar);
635}
636
637// static
638void LLFloaterMap::sendFreeze(const LLUUID& avatar_id, bool freeze)
639{
640 U32 flags = 0x0;
641 if (!freeze)
642 {
643 // unfreeze
644 flags |= 0x1;
645 }
646
647 LLMessageSystem* msg = gMessageSystem;
648 LLViewerObject* avatar = gObjectList.findObject(avatar_id);
649
650 if (avatar)
651 {
652 msg->newMessage("FreezeUser");
653 msg->nextBlock("AgentData");
654 msg->addUUID("AgentID", gAgent.getID());
655 msg->addUUID("SessionID", gAgent.getSessionID());
656 msg->nextBlock("Data");
657 msg->addUUID("TargetID", avatar_id );
658 msg->addU32("Flags", flags );
659 msg->sendReliable( avatar->getRegion()->getHost() );
660 }
661}
662
663// static
664void LLFloaterMap::sendEject(const LLUUID& avatar_id, bool ban)
665{
666 LLMessageSystem* msg = gMessageSystem;
667 LLViewerObject* avatar = gObjectList.findObject(avatar_id);
668
669 if (avatar)
670 {
671 U32 flags = 0x0;
672 if ( ban )
673 {
674 // eject and add to ban list
675 flags |= 0x1;
676 }
677
678 msg->newMessage("EjectUser");
679 msg->nextBlock("AgentData");
680 msg->addUUID("AgentID", gAgent.getID() );
681 msg->addUUID("SessionID", gAgent.getSessionID() );
682 msg->nextBlock("Data");
683 msg->addUUID("TargetID", avatar_id );
684 msg->addU32("Flags", flags );
685 msg->sendReliable( avatar->getRegion()->getHost() );
686 }
687}
688
689// static
690void LLFloaterMap::sendEstateMessage(const char* request, const LLUUID &target)
691{
692
693 LLMessageSystem* msg = gMessageSystem;
694 LLUUID invoice;
695
696 // This seems to provide an ID so that the sim can say which request it's
697 // replying to. I think this can be ignored for now.
698 invoice.generate();
699
700 llinfos << "Sending estate request '" << request << "'" << llendl;
701 msg->newMessage("EstateOwnerMessage");
702 msg->nextBlockFast(_PREHASH_AgentData);
703 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
704 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
705 msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
706 msg->nextBlock("MethodData");
707 msg->addString("Method", request);
708 msg->addUUID("Invoice", invoice);
709
710 // Agent id
711 msg->nextBlock("ParamList");
712 msg->addString("Parameter", gAgent.getID().asString().c_str());
713
714 // Target
715 msg->nextBlock("ParamList");
716 msg->addString("Parameter", target.asString().c_str());
717
718 msg->sendReliable(gAgent.getRegion()->getHost());
719}
720
721// static
722void LLFloaterMap::sendEstateBan(const LLUUID& agent)
723{
724 LLUUID invoice;
725 U32 flags = ESTATE_ACCESS_BANNED_AGENT_ADD;
726
727 invoice.generate();
728
729 LLMessageSystem* msg = gMessageSystem;
730 msg->newMessage("EstateOwnerMessage");
731 msg->nextBlockFast(_PREHASH_AgentData);
732 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
733 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
734 msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
735
736 msg->nextBlock("MethodData");
737 msg->addString("Method", "estateaccessdelta");
738 msg->addUUID("Invoice", invoice);
739
740 char buf[MAX_STRING]; /* Flawfinder: ignore*/
741 gAgent.getID().toString(buf);
742 msg->nextBlock("ParamList");
743 msg->addString("Parameter", buf);
744
745 snprintf(buf, MAX_STRING, "%u", flags); /* Flawfinder: ignore */
746 msg->nextBlock("ParamList");
747 msg->addString("Parameter", buf);
748
749 agent.toString(buf);
750 msg->nextBlock("ParamList");
751 msg->addString("Parameter", buf);
752
753 gAgent.sendReliableMessage();
754}
diff --git a/linden/indra/newview/llfloatermap.h b/linden/indra/newview/llfloatermap.h
index 857b1ed..0fff8a3 100644
--- a/linden/indra/newview/llfloatermap.h
+++ b/linden/indra/newview/llfloatermap.h
@@ -33,6 +33,7 @@
33#define LL_LLFLOATERMAP_H 33#define LL_LLFLOATERMAP_H
34 34
35#include "llfloater.h" 35#include "llfloater.h"
36#include "llscrolllistctrl.h"
36 37
37class LLNetMap; 38class LLNetMap;
38 39
@@ -46,6 +47,9 @@ public:
46 47
47 static void* createPanelMiniMap(void* data); 48 static void* createPanelMiniMap(void* data);
48 49
50 static void updateRadar();
51 static BOOL isSelected(LLUUID agent);
52
49 BOOL postBuild(); 53 BOOL postBuild();
50 54
51 /*virtual*/ void draw(); 55 /*virtual*/ void draw();
@@ -59,7 +63,47 @@ public:
59 63
60private: 64private:
61 LLFloaterMap(const LLSD& key = LLSD()); 65 LLFloaterMap(const LLSD& key = LLSD());
62 LLNetMap* mPanelMap; 66
67 LLNetMap* mPanelMap;
68 LLScrollListCtrl* mRadarList;
69 LLUUID mSelectedAvatar;
70 std::map<LLUUID, LLVector3d> mAvatars;
71 bool mUpdate;
72 static LLFloaterMap* sInstance;
73
74 static void onList(LLUICtrl* ctrl, void* user_data);
75 static void onRangeChange(LLFocusableElement* focus, void* user_data);
76 BOOL visibleItemsSelected() const;
77 void toggleButtons();
78 void populateRadar();
79
80 static void onClickProfile(void* user_data);
81 static void onClickIM(void* user_data);
82 static void onClickAddFriend(void* user_data);
83 static void onClickOfferTeleport(void* user_data);
84 static void onClickTrack(void* user_data);
85 static void onClickInvite(void* user_data);
86 static void callback_invite_to_group(LLUUID group_id, void *user_data);
87
88 static std::string getSelectedName(LLUUID agent_id);
89 static void onClickFreeze(void *user_data);
90 static void onClickEject(void *user_data);
91 static void onClickMute(void *user_data);
92 static void onClickUnmute(void *user_data);
93 static void onClickAR(void *user_data);
94 static void onClickEjectFromEstate(void *user_data);
95
96 static void callbackFreeze(S32 option, void *user_data);
97 static void callbackEject(S32 option, void *user_data);
98 static void callbackAR(void *user_data);
99 static void callbackEjectFromEstate(S32 option, void *user_data);
100
101 static void sendFreeze(const LLUUID &avatar, bool);
102 static void sendEject(const LLUUID &avatar, bool);
103 static void cmdEstateEject(const LLUUID &avatar);
104 static void cmdEstateBan(const LLUUID &avatar);
105 static void sendEstateBan(const LLUUID& agent);
106 static void sendEstateMessage(const char* request, const LLUUID &target);
63}; 107};
64 108
65#endif // LL_LLFLOATERMAP_H 109#endif // LL_LLFLOATERMAP_H
diff --git a/linden/indra/newview/llnetmap.cpp b/linden/indra/newview/llnetmap.cpp
index 8f5d90d..c66e816 100644
--- a/linden/indra/newview/llnetmap.cpp
+++ b/linden/indra/newview/llnetmap.cpp
@@ -45,6 +45,7 @@
45#include "llcolorscheme.h" 45#include "llcolorscheme.h"
46#include "llviewercontrol.h" 46#include "llviewercontrol.h"
47#include "llfloateravatarinfo.h" 47#include "llfloateravatarinfo.h"
48#include "llfloatermap.h"
48#include "llfloaterworldmap.h" 49#include "llfloaterworldmap.h"
49#include "llframetimer.h" 50#include "llframetimer.h"
50#include "llmutelist.h" 51#include "llmutelist.h"
@@ -117,6 +118,11 @@ LLNetMap::LLNetMap(const std::string& name) :
117 mPopupMenuHandle = menu->getHandle(); 118 mPopupMenuHandle = menu->getHandle();
118} 119}
119 120
121BOOL LLNetMap::postBuild()
122{
123 return TRUE;
124}
125
120LLNetMap::~LLNetMap() 126LLNetMap::~LLNetMap()
121{ 127{
122} 128}
@@ -330,6 +336,7 @@ void LLNetMap::draw()
330 LLColor4 avatar_color = gColors.getColor( "MapAvatar" ); 336 LLColor4 avatar_color = gColors.getColor( "MapAvatar" );
331 LLColor4 friend_color = gColors.getColor( "MapFriend" ); 337 LLColor4 friend_color = gColors.getColor( "MapFriend" );
332 LLColor4 muted_color = gColors.getColor( "MapMuted" ); 338 LLColor4 muted_color = gColors.getColor( "MapMuted" );
339 LLColor4 selected_color = gColors.getColor( "MapSelected" );
333 LLColor4 glyph_color; 340 LLColor4 glyph_color;
334 341
335 std::vector<LLUUID> avatar_ids; 342 std::vector<LLUUID> avatar_ids;
@@ -350,6 +357,10 @@ void LLNetMap::draw()
350 { 357 {
351 glyph_color = friend_color; 358 glyph_color = friend_color;
352 } 359 }
360 else if (LLFloaterMap::isSelected(avatar_ids[i]))
361 {
362 glyph_color = selected_color;
363 }
353 else 364 else
354 { 365 {
355 glyph_color = avatar_color; 366 glyph_color = avatar_color;
@@ -460,6 +471,8 @@ void LLNetMap::draw()
460 setDirectionPos( getChild<LLTextBox>("se_label"), rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2); 471 setDirectionPos( getChild<LLTextBox>("se_label"), rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2);
461 472
462 LLView::draw(); 473 LLView::draw();
474
475 LLFloaterMap::updateRadar();
463} 476}
464 477
465void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent) 478void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent)
diff --git a/linden/indra/newview/llnetmap.h b/linden/indra/newview/llnetmap.h
index ef046d8..45b5e2d 100644
--- a/linden/indra/newview/llnetmap.h
+++ b/linden/indra/newview/llnetmap.h
@@ -52,6 +52,8 @@ class LLNetMap : public LLPanel
52{ 52{
53public: 53public:
54 LLNetMap(const std::string& name); 54 LLNetMap(const std::string& name);
55
56 virtual BOOL postBuild();
55 virtual ~LLNetMap(); 57 virtual ~LLNetMap();
56 58
57 virtual void draw(); 59 virtual void draw();
@@ -111,8 +113,8 @@ private:
111 LLPointer<LLImageGL> mObjectImagep; 113 LLPointer<LLImageGL> mObjectImagep;
112 114
113private: 115private:
114 LLUUID mClosestAgentToCursor; 116 LLUUID mClosestAgentToCursor;
115 LLUUID mClosestAgentAtLastRightClick; 117 LLUUID mClosestAgentAtLastRightClick;
116 118
117 static BOOL sRotateMap; 119 static BOOL sRotateMap;
118 static LLNetMap* sInstance; 120 static LLNetMap* sInstance;
diff --git a/linden/indra/newview/skins/default/colors_base.xml b/linden/indra/newview/skins/default/colors_base.xml
index d0f1049..9ad1787 100644
--- a/linden/indra/newview/skins/default/colors_base.xml
+++ b/linden/indra/newview/skins/default/colors_base.xml
@@ -162,6 +162,7 @@
162<MapAvatar value="0, 255, 0, 255" /> <!-- Your avatar's glyph color --> 162<MapAvatar value="0, 255, 0, 255" /> <!-- Your avatar's glyph color -->
163<MapFriend value="255, 255, 0, 255" /> <!-- Your friends' glyph color --> 163<MapFriend value="255, 255, 0, 255" /> <!-- Your friends' glyph color -->
164<MapMuted value="128, 128, 128, 255" /> <!-- Muted avatars' glyph color --> 164<MapMuted value="128, 128, 128, 255" /> <!-- Muted avatars' glyph color -->
165<MapSelected value="255, 0, 0, 255" /> <!-- Selected avatars' glyph color -->
165 166
166 <!-- MINI-MAP --> 167 <!-- MINI-MAP -->
167<NetMapBackgroundColor value="0, 0, 0, 77" /> <!-- Mini-map floater background --> 168<NetMapBackgroundColor value="0, 0, 0, 77" /> <!-- Mini-map floater background -->
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_mini_map.xml b/linden/indra/newview/skins/default/xui/en-us/floater_mini_map.xml
index 9f1e164..3425c65 100644
--- a/linden/indra/newview/skins/default/xui/en-us/floater_mini_map.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/floater_mini_map.xml
@@ -1,7 +1,98 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<floater can_close="true" can_drag_on_left="false" can_minimize="false" can_resize="true" 2<floater can_close="true" can_drag_on_left="false" can_minimize="false" can_resize="true"
3 can_tear_off="false" follows="top|right" height="220" min_height="64" min_width="64" 3 can_tear_off="false" follows="top|right" height="455" min_height="64" min_width="64"
4 name="minimap" rect_control="FloaterMiniMapRect" width="200"> 4 name="minimap" rect_control="FloaterMiniMapRect" width="200">
5 <panel bottom="2" follows="left|top|right|bottom" height="216" label="Mini Map" 5
6 left="2" mouse_opaque="false" name="mini_mapview" width="196" /> 6 <panel label="Mini Map" name="mini_mapview"
7 top="-2" left="2" bottom="196" right="196"
8 follows="left|top|right|bottom" mouse_opaque="false" />
9
10 <panel name="RadarPanel" label="Radar"
11 background_visible="true" bg_alpha_color="NetMapBackgroundColor"
12 left="2" top="196" right="196" height="120"
13 follows="left|right|bottom" border="false" mouse_opaque="true">
14
15 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
16 bottom="-20" drop_shadow_visible="true" follows="left|top"
17 font="SansSerifSmall" h_pad="0" halign="left" height="16" left="10"
18 mouse_opaque="true" name="lblAvatarCount" v_pad="0"
19 width="220">
20 0
21 </text>
22 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
23 bottom="-20" drop_shadow_visible="true" follows="left|top"
24 font="SansSerifSmall" h_pad="0" halign="left" height="16" left="27"
25 mouse_opaque="true" name="avatars_in" v_pad="0"
26 width="220">
27 Avatars in
28 </text>
29 <slider bottom_delta="0" left_delta="55" follows="left|top" width="110" height="15"
30 name="near_me_range" label="" control_name="NearMeRange"
31 min_val="5" max_val="512" increment="1" initial_val="96" decimal_digits="0" />
32 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
33 bottom_delta="0" left="190" drop_shadow_visible="true" follows="left|top"
34 font="SansSerifSmall" h_pad="0" halign="left" height="15"
35 mouse_opaque="true" name="meters" v_pad="0"
36 width="40">
37 Meters
38 </text>
39 <tab_container border="false" bottom_delta="-179" height="174" left="0" mouse_opaque="false"
40 name="button_container" tab_position="top" follows="left|right|bottom" width="198">
41 <panel border="true" bottom="-180" follows="left|top|right|bottom" height="160"
42 label="Avatars" left="1" mouse_opaque="true" name="avatar_tab" width="198">
43 <button bottom="-25" follows="top|right" height="22" label="IM/Call"
44 left="-85" name="im_btn" tool_tip="Open Instant Message session"
45 width="80" />
46 <button bottom_delta="-25" follows="top|right" height="22" label="Profile"
47 left_delta="0" name="profile_btn"
48 tool_tip="Show picture, groups, and other information" width="80" />
49 <button bottom_delta="-25" follows="top|right" height="22" label="Teleport..."
50 left_delta="0" name="offer_teleport_btn"
51 tool_tip="Offer this friend a teleport to your current location" width="80" />
52 <button bottom_delta="-25" follows="top|right" height="22" label="Track"
53 left_delta="0" name="track_btn"
54 tool_tip="Create a beacon to track this avatar" width="80" />
55 <button bottom_delta="-25" follows="top|right" height="22" label="Invite..."
56 left_delta="0" name="invite_btn"
57 tool_tip="Remove this person from your friends list" width="80" />
58 <button bottom_delta="-25" follows="top|right" height="22" label="Add..."
59 left_delta="0" name="add_btn" tool_tip="Offer friendship to a resident"
60 width="80" />
61 </panel>
62 <panel border="true" bottom="-160" follows="left|top|right|bottom" height="160"
63 label="Estate" left="1" mouse_opaque="true" name="estate_tab" width="198">
64 <button bottom="-25" follows="top|right" height="22" label="Freeze..."
65 left="-85" name="freeze_btn" tool_tip=""
66 width="80" />
67 <button bottom_delta="-25" follows="top|right" height="22" label="Eject..."
68 left_delta="0" name="eject_btn"
69 tool_tip="" width="80" />
70 <button bottom_delta="-25" follows="top|right" height="22" label="Mute..."
71 left_delta="0" name="mute_btn"
72 tool_tip="" width="80" />
73 <button bottom_delta="-25" follows="top|right" height="22" label="Unmute..."
74 left_delta="0" name="unmute_btn"
75 tool_tip="" width="80" />
76 <button bottom_delta="-25" follows="top|right" height="22" label="Report..."
77 left_delta="0" name="ar_btn"
78 tool_tip="" width="80" />
79 <button bottom_delta="-25" follows="top|right" height="22" label="Estate..."
80 left_delta="0" name="estate_eject_btn" tool_tip=""
81 width="80" />
82 </panel>
83 </tab_container>
84 <scroll_list bottom="-187" width="96" height="140" left="10"
85 follows="left|bottom|right" draw_border="false" draw_heading="true"
86 draw_stripes="true" column_padding="5" sort_column="1" mouse_opaque="true"
87 background_visible="true" multi_select="false" name="RadarList">
88 <column name="avatar_name" label="Name" dynamicwidth="true" />
89 <column name="avatar_distance" label="Dist." width="55" />
90 </scroll_list>
91 </panel>
92 <string name="no_one_near">
93 No avatars within range
94 </string>
95 <string name="muted">
96 (muted)
97 </string>
7</floater> 98</floater>
diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_mini_map.xml b/linden/indra/newview/skins/default/xui/en-us/panel_mini_map.xml
index 1a93341..19faa62 100644
--- a/linden/indra/newview/skins/default/xui/en-us/panel_mini_map.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/panel_mini_map.xml
@@ -1,6 +1,6 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<panel background_opaque="false" background_visible="true" bg_alpha_color="NetMapBackgroundColor" 2<panel background_opaque="false" background_visible="true" bg_alpha_color="NetMapBackgroundColor"
3 border="false" follows="left|top|right|bottom" height="216" label="Mini Map" 3 border="false" follows="left|top|right|bottom" height="716" label="Mini Map"
4 mouse_opaque="false" name="mini_mapview" width="196"> 4 mouse_opaque="false" name="mini_mapview" width="196">
5 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 5 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
6 bottom="-40" drop_shadow_visible="false" font="SansSerifSmall" h_pad="0" 6 bottom="-40" drop_shadow_visible="false" font="SansSerifSmall" h_pad="0"