/** * @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 "llfloaterreg.h" #include "llfontgl.h" #include "llflyoutbutton.h" #include "llrect.h" #include "llparcel.h" #include "llagent.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 "llfloaterinventory.h" #include "llfloaterchatterbox.h" #include "llfloaterfriends.h" #include "llfloatersnapshot.h" #include "lltoolmgr.h" #include "llui.h" #include "llviewermenu.h" #include "llfirstuse.h" #include "llscrolllistctrl.h" #include "llscrolllistitem.h" #include "llscrolllistcell.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 "lllayoutstack.h" #if LL_DARWIN #include "llresizehandle.h" #endif // LL_DARWIN // // Globals // LLToolBar *gToolBar = NULL; // // Statics // F32 LLToolBar::sInventoryAutoOpenTime = 1.f; // // Functions // LLToolBar::LLToolBar() : LLPanel() #if LL_DARWIN , mResizeHandle(NULL) #endif // LL_DARWIN { setIsChrome(TRUE); setFocusRoot(TRUE); mCommitCallbackRegistrar.add("HandleCommunicate", &LLToolBar::onClickCommunicate); } BOOL LLToolBar::postBuild() { for (child_list_const_iter_t child_iter = getChildList()->begin(); child_iter != getChildList()->end(); ++child_iter) { LLView *view = *child_iter; LLButton* buttonp = dynamic_cast(view); if(buttonp) { buttonp->setSoundFlags(LLView::SILENT); } } #if LL_DARWIN if(mResizeHandle == NULL) { LLRect rect(0, 0, RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT); LLResizeHandle::Params p; p.name(""); p.rect(rect); p.min_width(RESIZE_HANDLE_WIDTH); p.min_height(RESIZE_HANDLE_HEIGHT); p.enabled(false); mResizeHandle = LLUICtrlFactory::create(p); addChildInBack(mResizeHandle); LLLayoutStack* toolbar_stack = getChild("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("inventory_btn"); if (!inventory_btn) return FALSE; LLFloaterInventory* active_inventory = LLFloaterInventory::getActiveInventory(); LLRect button_screen_rect; inventory_btn->localRectToScreen(inventory_btn->getRect(),&button_screen_rect); if(active_inventory && active_inventory->getVisible()) { mInventoryAutoOpen = FALSE; } else if (button_screen_rect.pointInRect(x, y)) { if (mInventoryAutoOpen) { if (!(active_inventory && active_inventory->getVisible()) && mInventoryAutoOpenTimer.getElapsedTimeF32() > sInventoryAutoOpenTime) { LLFloaterInventory::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() { BOOL show = gSavedSettings.getBOOL("ShowToolBar"); BOOL mouselook = gAgent.cameraMouselook(); setVisible(show && !mouselook); BOOL sitting = FALSE; if (gAgent.getAvatarObject()) { sitting = gAgent.getAvatarObject()->mIsSitting; } if (!gAgent.canFly()) { gSavedSettings.setBOOL("FlyBtnEnabled", gAgent.getFlying() ? true : false); gSavedSettings.setBOOL("FlyBtnState", false); } else { gSavedSettings.setBOOL("FlyBtnEnabled", sitting ? false : true); } // Check to see if we're in build mode bool build_enabled = LLToolMgr::getInstance()->canEdit(); if (build_enabled) { gSavedSettings.setBOOL("BuildBtnEnabled", true); bool build_mode = LLToolMgr::getInstance()->inEdit(); // HACK: Not in mouselook and not just clicking on a scripted object if (gAgent.cameraMouselook() || LLToolGrab::getInstance()->getHideBuildHighlight()) { build_mode = FALSE; } gSavedSettings.setBOOL("BuildBtnState", build_mode); } else { gSavedSettings.setBOOL("BuildBtnEnabled", false); gSavedSettings.setBOOL("BuildBtnState", false); } if (isInVisibleChain()) { updateCommunicateList(); } } void LLToolBar::updateCommunicateList() { LLFlyoutButton* communicate_button = getChild("communicate_btn"); LLSD selected = communicate_button->getValue(); communicate_button->removeall(); LLFloater* frontmost_floater = LLFloaterChatterBox::getInstance()->getActiveFloater(); LLScrollListItem* itemp = NULL; LLSD contact_sd; contact_sd["value"] = "contacts"; contact_sd["columns"][0]["value"] = LLFloaterMyFriends::getInstance()->getShortTitle(); if (LLFloaterMyFriends::getInstance() == frontmost_floater) { contact_sd["columns"][0]["font"]["style"] = "BOLD"; // make sure current tab is selected in list if (selected.isUndefined()) { selected = "contacts"; } } itemp = communicate_button->addElement(contact_sd, ADD_TOP); LLSD communicate_sd; communicate_sd["value"] = "local chat"; communicate_sd["columns"][0]["value"] = LLFloaterChat::getInstance()->getShortTitle(); if (LLFloaterChat::getInstance() == frontmost_floater) { communicate_sd["columns"][0]["font"]["style"] = "BOLD"; if (selected.isUndefined()) { selected = "local chat"; } } itemp = communicate_button->addElement(communicate_sd, ADD_TOP); communicate_button->addSeparator(ADD_TOP); communicate_button->add(getString("Redock Windows"), LLSD("redock"), ADD_TOP); communicate_button->addSeparator(ADD_TOP); LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance("mute"); if(mute_instance) { communicate_button->add(mute_instance->getShortTitle(), LLSD("mute list"), ADD_TOP); } std::set >::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()); LLSD im_sd; im_sd["value"] = im_floaterp->getSessionID(); im_sd["columns"][0]["value"] = floater_title; if (im_floaterp == frontmost_floater) { im_sd["columns"][0]["font"]["style"] = "BOLD"; if (selected.isUndefined()) { selected = im_floaterp->getSessionID(); } } itemp = communicate_button->addElement(im_sd, ADD_TOP); } } communicate_button->setValue(selected); } // static void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, const LLSD& user_data) { LLFlyoutButton* communicate_button = dynamic_cast(ctrl); llassert_always(communicate_button); LLSD selected_option = communicate_button->getValue(); if (selected_option.asString() == "contacts") { LLFloaterReg::showInstance("contacts", "friends"); } else if (selected_option.asString() == "local chat") { LLFloaterReg::showInstance("communicate", "local"); } else if (selected_option.asString() == "redock") { LLFloaterChatterBox* chatterbox_instance = LLFloaterChatterBox::getInstance(); if(chatterbox_instance) { chatterbox_instance->addFloater(LLFloaterMyFriends::getInstance(), FALSE); chatterbox_instance->addFloater(LLFloaterChat::getInstance(), FALSE); LLUUID session_to_show; std::set >::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(); } chatterbox_instance->addFloater(im_floaterp, FALSE); } } LLFloaterReg::showInstance("communicate", session_to_show); } } else if (selected_option.asString() == "mute list") { LLFloaterReg::showInstance("mute"); } else if (selected_option.isUndefined()) // user just clicked the communicate button, treat as toggle { LLFloaterReg::toggleInstance("communicate"); } else // otherwise selection_option is undifined or a specific IM session id { LLFloaterReg::showInstance("communicate", selected_option); } }