Files
SingularityViewer/indra/newview/lltoolbar.cpp
Inusaito Sayori ee785f0f17 Allow turning flying on and off while seated, if using Continue Fly On Unsit
Note: Redundant code, but these functions will likely be merged eventually(FUI-esque project), so it doesn't matter for now.
2013-05-20 12:14:58 -04:00

578 lines
15 KiB
C++

/**
* @file lltoolbar.cpp
* @author James Cook, Richard Nelson
* @brief Large friendly buttons at bottom of screen.
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-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$
*/
#include "llviewerprecompiledheaders.h"
#include "lltoolbar.h"
#include "imageids.h"
#include "llfontgl.h"
#include "llrect.h"
#include "llparcel.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llagentwearables.h"
#include "llbutton.h"
#include "llfocusmgr.h"
#include "llviewercontrol.h"
#include "llmenucommands.h"
#include "llimview.h"
#include "lluiconstants.h"
#include "llvoavatarself.h"
#include "lltooldraganddrop.h"
#include "llfloaterchatterbox.h"
#include "llfloaterfriends.h"
#include "llfloaterinventory.h"
#include "llfloatersnapshot.h"
#include "llfloateravatarlist.h"
#include "lltoolmgr.h"
#include "llui.h"
#include "llviewermenu.h"
#include "llfirstuse.h"
#include "llviewerparcelmgr.h"
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
#include "lltoolgrab.h"
#include "llcombobox.h"
#include "llfloaterchat.h"
#include "llfloatermute.h"
#include "llimpanel.h"
#include "llscrolllistctrl.h"
#include "llfloatercustomize.h"
// [RLVa:KB]
#include "rlvhandler.h"
// [/RLVa:KB]
#if LL_DARWIN
#include "llresizehandle.h"
// This class draws like an LLResizeHandle but has no interactivity.
// It's just there to provide a cue to the user that the lower right corner of the window functions as a resize handle.
class LLFakeResizeHandle : public LLResizeHandle
{
public:
LLFakeResizeHandle(const std::string& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner = RIGHT_BOTTOM )
: LLResizeHandle(name, rect, min_width, min_height, corner )
{
}
virtual BOOL handleHover(S32 x, S32 y, MASK mask) { return FALSE; };
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; };
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) { return FALSE; };
};
#endif // LL_DARWIN
//
// Globals
//
LLToolBar *gToolBar = NULL;
S32 TOOL_BAR_HEIGHT = 20;
//
// Statics
//
F32 LLToolBar::sInventoryAutoOpenTime = 1.f;
//
// Functions
//
LLToolBar::LLToolBar()
: LLPanel()
#if LL_DARWIN
, mResizeHandle(NULL)
#endif // LL_DARWIN
{
setIsChrome(TRUE);
setFocusRoot(TRUE);
}
BOOL LLToolBar::postBuild()
{
childSetCommitCallback("communicate_btn", onClickCommunicate, this);
childSetAction("chat_btn", onClickChat, this);
childSetControlName("chat_btn", "ChatVisible");
//childSetAction("appearance_btn", onClickAppearance, this);
//childSetControlName("appearance_btn", "");
childSetAction("radar_list_btn", onClickRadarList, this);
childSetControlName("radar_list_btn", "ShowRadar");
childSetAction("fly_btn", onClickFly, this);
childSetControlName("fly_btn", "FlyBtnState");
//childSetAction("sit_btn", onClickSit, this);
//childSetControlName("sit_btn", "SitBtnState");
childSetAction("snapshot_btn", onClickSnapshot, this);
childSetControlName("snapshot_btn", "SnapshotBtnState");
childSetAction("directory_btn", onClickDirectory, this);
childSetControlName("directory_btn", "ShowDirectory");
childSetAction("build_btn", onClickBuild, this);
childSetControlName("build_btn", "BuildBtnState");
childSetAction("radar_btn", onClickRadar, this);
childSetControlName("radar_btn", "ShowMiniMap");
childSetAction("map_btn", onClickMap, this);
childSetControlName("map_btn", "ShowWorldMap");
childSetAction("inventory_btn", onClickInventory, this);
childSetControlName("inventory_btn", "ShowInventory");
mCommunicateBtn.connect(this, "communicate_btn");
mFlyBtn.connect(this, "fly_btn");
mBuildBtn.connect(this, "build_btn");
mMapBtn.connect(this, "map_btn");
mRadarBtn.connect(this, "radar_btn");
mInventoryBtn.connect(this, "inventory_btn");
for (child_list_const_iter_t child_iter = getChildList()->begin();
child_iter != getChildList()->end(); ++child_iter)
{
LLView *view = *child_iter;
LLButton* buttonp = dynamic_cast<LLButton*>(view);
if(buttonp)
{
buttonp->setSoundFlags(LLView::SILENT);
}
}
#if LL_DARWIN
if(mResizeHandle == NULL)
{
LLRect rect(0, 0, RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT);
mResizeHandle = new LLFakeResizeHandle(std::string(""), rect, RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT);
this->addChildInBack(mResizeHandle);
LLLayoutStack* toolbar_stack = getChild<LLLayoutStack>("toolbar_stack");
toolbar_stack->reshape(toolbar_stack->getRect().getWidth() - RESIZE_HANDLE_WIDTH, toolbar_stack->getRect().getHeight());
}
#endif // LL_DARWIN
layoutButtons();
return TRUE;
}
LLToolBar::~LLToolBar()
{
// LLView destructor cleans up children
}
BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg)
{
LLButton* inventory_btn = getChild<LLButton>("inventory_btn");
if (!inventory_btn) return FALSE;
LLInventoryView* active_inventory = LLInventoryView::getActiveInventory();
if(active_inventory && active_inventory->getVisible())
{
mInventoryAutoOpen = FALSE;
}
else if (inventory_btn->getRect().pointInRect(x, y))
{
if (mInventoryAutoOpen)
{
if (!(active_inventory && active_inventory->getVisible()) &&
mInventoryAutoOpenTimer.getElapsedTimeF32() > sInventoryAutoOpenTime)
{
LLInventoryView::showAgentInventory();
}
}
else
{
mInventoryAutoOpen = TRUE;
mInventoryAutoOpenTimer.reset();
}
}
return LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
// static
void LLToolBar::toggle(void*)
{
BOOL show = gSavedSettings.getBOOL("ShowToolBar");
gSavedSettings.setBOOL("ShowToolBar", !show);
gToolBar->setVisible(!show);
}
// static
BOOL LLToolBar::visible(void*)
{
return gToolBar->getVisible();
}
void LLToolBar::layoutButtons()
{
#if LL_DARWIN
const S32 FUDGE_WIDTH_OF_SCREEN = 4;
S32 width = gViewerWindow->getWindowWidth() + FUDGE_WIDTH_OF_SCREEN;
S32 pad = 2;
// this function may be called before postBuild(), in which case mResizeHandle won't have been set up yet.
if(mResizeHandle != NULL)
{
if(!gViewerWindow->getWindow()->getFullscreen())
{
// Only when running in windowed mode on the Mac, leave room for a resize widget on the right edge of the bar.
width -= RESIZE_HANDLE_WIDTH;
LLRect r;
r.mLeft = width - pad;
r.mBottom = 0;
r.mRight = r.mLeft + RESIZE_HANDLE_WIDTH;
r.mTop = r.mBottom + RESIZE_HANDLE_HEIGHT;
mResizeHandle->setRect(r);
mResizeHandle->setVisible(TRUE);
}
else
{
mResizeHandle->setVisible(FALSE);
}
}
#endif // LL_DARWIN
}
// virtual
void LLToolBar::reshape(S32 width, S32 height, BOOL called_from_parent)
{
LLPanel::reshape(width, height, called_from_parent);
layoutButtons();
}
// Per-frame updates of visibility
void LLToolBar::refresh()
{
if(!isAgentAvatarValid())
return;
static LLCachedControl<bool> show("ShowToolBar", true);
static LLCachedControl<bool> ascent_fly_always_enabled("AscentFlyAlwaysEnabled", true);
static LLCachedControl<bool> ascent_build_always_enabled("AscentBuildAlwaysEnabled", true);
BOOL mouselook = gAgentCamera.cameraMouselook();
setVisible(show && !mouselook);
BOOL sitting = FALSE;
static LLCachedControl<bool> continue_flying_on_unsit("LiruContinueFlyingOnUnsit");
if (continue_flying_on_unsit)
{
sitting = false;
}
else if (gAgentAvatarp)
{
sitting = gAgentAvatarp->isSitting();
}
mFlyBtn->setEnabled((gAgent.canFly() || gAgent.getFlying() || ascent_fly_always_enabled) && !sitting );
mBuildBtn->setEnabled((LLViewerParcelMgr::getInstance()->allowAgentBuild() || ascent_build_always_enabled));
// Check to see if we're in build mode
BOOL build_mode = LLToolMgr::getInstance()->inEdit();
// And not just clicking on a scripted object
if (LLToolGrab::getInstance()->getHideBuildHighlight())
{
build_mode = FALSE;
}
static LLCachedControl<bool> build_btn_state("BuildBtnState",false);
if(build_btn_state!=(bool)build_mode)
build_btn_state = build_mode;
// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-10 (RLVa-1.0.0g)
// Called per-frame so this really can't be slow
if (rlv_handler_t::isEnabled())
{
// If we're rez-restricted, we can still edit => allow build floater
// If we're edit-restricted, we can still rez => allow build floater
mBuildBtn->setEnabled(!(gRlvHandler.hasBehaviour(RLV_BHVR_REZ) && gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)));
mMapBtn->setEnabled(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWWORLDMAP));
mRadarBtn->setEnabled(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWMINIMAP));
mInventoryBtn->setEnabled(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWINV));
}
// [/RLVa:KB]
if (isInVisibleChain())
{
updateCommunicateList();
}
}
void LLToolBar::updateCommunicateList()
{
LLFlyoutButton* communicate_button = mCommunicateBtn;
LLSD selected = communicate_button->getValue();
communicate_button->removeall();
LLFloater* frontmost_floater = LLFloaterChatterBox::getInstance()->getActiveFloater();
LLScrollListItem* itemp = NULL;
itemp = communicate_button->add(LLFloaterMyFriends::getInstance()->getShortTitle(), LLSD("contacts"), ADD_TOP);
if (LLFloaterMyFriends::getInstance() == frontmost_floater)
{
((LLScrollListText*)itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD);
// make sure current tab is selected in list
if (selected.isUndefined())
{
selected = itemp->getValue();
}
}
itemp = communicate_button->add(LLFloaterChat::getInstance()->getShortTitle(), LLSD("local chat"), ADD_TOP);
if (LLFloaterChat::getInstance() == frontmost_floater)
{
((LLScrollListText*)itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD);
if (selected.isUndefined())
{
selected = itemp->getValue();
}
}
communicate_button->addSeparator(ADD_TOP);
communicate_button->add(getString("Redock Windows"), LLSD("redock"), ADD_TOP);
communicate_button->addSeparator(ADD_TOP);
communicate_button->add(LLFloaterMute::getInstance()->getShortTitle(), LLSD("mute list"), ADD_TOP);
std::set<LLHandle<LLFloater> >::const_iterator floater_handle_it;
if (gIMMgr->getIMFloaterHandles().size() > 0)
{
communicate_button->addSeparator(ADD_TOP);
}
for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it)
{
LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)floater_handle_it->get();
if (im_floaterp)
{
std::string floater_title = im_floaterp->getNumUnreadMessages() > 0 ? "*" : "";
floater_title.append(im_floaterp->getShortTitle());
itemp = communicate_button->add(floater_title, im_floaterp->getSessionID(), ADD_TOP);
if (im_floaterp == frontmost_floater)
{
((LLScrollListText*)itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD);
if (selected.isUndefined())
{
selected = itemp->getValue();
}
}
}
}
communicate_button->setToggleState(gSavedSettings.getBOOL("ShowCommunicate"));
communicate_button->setValue(selected);
}
// static
void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, void* user_data)
{
LLToolBar* toolbar = (LLToolBar*)user_data;
LLFlyoutButton* communicate_button = toolbar->getChild<LLFlyoutButton>("communicate_btn");
LLSD selected_option = communicate_button->getValue();
if (selected_option.asString() == "contacts")
{
LLFloaterMyFriends::showInstance();
}
else if (selected_option.asString() == "local chat")
{
LLFloaterChat::showInstance();
}
else if (selected_option.asString() == "redock")
{
LLFloaterChatterBox::getInstance()->addFloater(LLFloaterMyFriends::getInstance(), FALSE);
LLFloaterChatterBox::getInstance()->addFloater(LLFloaterChat::getInstance(), FALSE);
LLUUID session_to_show;
std::set<LLHandle<LLFloater> >::const_iterator floater_handle_it;
for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it)
{
LLFloater* im_floaterp = floater_handle_it->get();
if (im_floaterp)
{
if (im_floaterp->isFrontmost())
{
session_to_show = ((LLFloaterIMPanel*)im_floaterp)->getSessionID();
}
LLFloaterChatterBox::getInstance()->addFloater(im_floaterp, FALSE);
}
}
LLFloaterChatterBox::showInstance(session_to_show);
}
else if (selected_option.asString() == "mute list")
{
LLFloaterMute::showInstance();
}
else if (selected_option.isUndefined()) // user just clicked the communicate button, treat as toggle
{
if (LLFloaterChatterBox::getInstance()->getFloaterCount() == 0)
{
LLFloaterMyFriends::toggleInstance();
}
else
{
LLFloaterChatterBox::toggleInstance();
}
}
else // otherwise selection_option is a specific IM session id
{
LLFloaterChatterBox::showInstance(selected_option);
}
}
// static
void LLToolBar::onClickChat(void* user_data)
{
handle_chat(NULL);
}
// static
void LLToolBar::onClickAppearance(void*)
{
if (gAgentWearables.areWearablesLoaded())
{
LLFloaterCustomize::show();
}
}
// static
void LLToolBar::onClickRadarList(void*)
{
LLFloaterAvatarList::toggle(0);
}
// static
void LLToolBar::onClickFly(void*)
{
gAgent.toggleFlying();
}
// static
void LLToolBar::onClickSit(void*)
{
if (!(gAgent.getControlFlags() & AGENT_CONTROL_SIT_ON_GROUND))
{
// sit down
gAgent.setFlying(FALSE);
gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
// Might be first sit
LLFirstUse::useSit();
}
else
{
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g)
// NOTE-RLVa: dead code?
if (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT))
{
return;
}
// [/RLVa:KB]
// stand up
gAgent.setFlying(FALSE);
gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
}
}
// static
void LLToolBar::onClickSnapshot(void*)
{
LLFloaterSnapshot::show (0);
}
// static
void LLToolBar::onClickDirectory(void*)
{
handle_find(NULL);
}
// static
void LLToolBar::onClickBuild(void*)
{
LLToolMgr::getInstance()->toggleBuildMode();
}
// static
void LLToolBar::onClickRadar(void*)
{
handle_mini_map(NULL);
}
// static
void LLToolBar::onClickMap(void*)
{
handle_map(NULL);
}
// static
void LLToolBar::onClickInventory(void*)
{
handle_inventory(NULL);
}