phoenix-firestorm/indra/newview/llfloatertools.cpp

1171 lines
36 KiB
C++

/**
* @file llfloatertools.cpp
* @brief The edit tools, including move, position, land, etc.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatertools.h"
#include "llfontgl.h"
#include "llcoord.h"
//#include "llgl.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "lldraghandle.h"
#include "llerror.h"
#include "llfloaterbuildoptions.h"
#include "llfloatermediasettings.h"
#include "llfloateropenobject.h"
#include "llfloaterobjectweights.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llmediaentry.h"
#include "llmenugl.h"
#include "llnotificationsutil.h"
#include "llpanelcontents.h"
#include "llpanelface.h"
#include "llpanelland.h"
#include "llpanelobjectinventory.h"
#include "llpanelobject.h"
#include "llpanelvolume.h"
#include "llpanelpermissions.h"
#include "llparcel.h"
#include "llradiogroup.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llslider.h"
#include "llstatusbar.h"
#include "lltabcontainer.h"
#include "lltextbox.h"
#include "lltoolbrush.h"
#include "lltoolcomp.h"
#include "lltooldraganddrop.h"
#include "lltoolface.h"
#include "lltoolfocus.h"
#include "lltoolgrab.h"
#include "lltoolgrab.h"
#include "lltoolindividual.h"
#include "lltoolmgr.h"
#include "lltoolpie.h"
#include "lltoolpipette.h"
#include "lltoolplacer.h"
#include "lltoolselectland.h"
#include "lltrans.h"
#include "llui.h"
#include "llviewercontrol.h"
#include "llviewerjoystick.h"
#include "llviewerregion.h"
#include "llviewermenu.h"
#include "llviewerparcelmgr.h"
#include "llviewerwindow.h"
#include "llvovolume.h"
#include "lluictrlfactory.h"
#include "llmeshrepository.h"
// Globals
LLFloaterTools *gFloaterTools = NULL;
bool LLFloaterTools::sShowObjectCost = true;
bool LLFloaterTools::sPreviousFocusOnAvatar = false;
const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] =
{
std::string("General"), // PANEL_GENERAL,
std::string("Object"), // PANEL_OBJECT,
std::string("Features"), // PANEL_FEATURES,
std::string("Texture"), // PANEL_FACE,
std::string("Content"), // PANEL_CONTENTS,
};
// Local prototypes
void commit_grid_mode(LLUICtrl *ctrl);
void commit_select_component(void *data);
void click_show_more(void*);
void click_popup_info(void*);
void click_popup_done(void*);
void click_popup_minimize(void*);
void commit_slider_dozer_force(LLUICtrl *);
void click_apply_to_selection(void*);
void commit_radio_group_focus(LLUICtrl* ctrl);
void commit_radio_group_move(LLUICtrl* ctrl);
void commit_radio_group_edit(LLUICtrl* ctrl);
void commit_radio_group_land(LLUICtrl* ctrl);
void commit_slider_zoom(LLUICtrl *ctrl);
/**
* Class LLLandImpactsObserver
*
* An observer class to monitor parcel selection and update
* the land impacts data from a parcel containing the selected object.
*/
class LLLandImpactsObserver : public LLParcelObserver
{
public:
virtual void changed()
{
LLFloaterTools* tools_floater = LLFloaterReg::getTypedInstance<LLFloaterTools>("build");
if(tools_floater)
{
tools_floater->updateLandImpacts();
}
}
};
//static
void* LLFloaterTools::createPanelPermissions(void* data)
{
LLFloaterTools* floater = (LLFloaterTools*)data;
floater->mPanelPermissions = new LLPanelPermissions();
return floater->mPanelPermissions;
}
//static
void* LLFloaterTools::createPanelObject(void* data)
{
LLFloaterTools* floater = (LLFloaterTools*)data;
floater->mPanelObject = new LLPanelObject();
return floater->mPanelObject;
}
//static
void* LLFloaterTools::createPanelVolume(void* data)
{
LLFloaterTools* floater = (LLFloaterTools*)data;
floater->mPanelVolume = new LLPanelVolume();
return floater->mPanelVolume;
}
//static
void* LLFloaterTools::createPanelFace(void* data)
{
LLFloaterTools* floater = (LLFloaterTools*)data;
floater->mPanelFace = new LLPanelFace();
return floater->mPanelFace;
}
//static
void* LLFloaterTools::createPanelContents(void* data)
{
LLFloaterTools* floater = (LLFloaterTools*)data;
floater->mPanelContents = new LLPanelContents();
return floater->mPanelContents;
}
//static
void* LLFloaterTools::createPanelLandInfo(void* data)
{
LLFloaterTools* floater = (LLFloaterTools*)data;
floater->mPanelLandInfo = new LLPanelLandInfo();
return floater->mPanelLandInfo;
}
static const std::string toolNames[]={
"ToolCube",
"ToolPrism",
"ToolPyramid",
"ToolTetrahedron",
"ToolCylinder",
"ToolHemiCylinder",
"ToolCone",
"ToolHemiCone",
"ToolSphere",
"ToolHemiSphere",
"ToolTorus",
"ToolTube",
"ToolRing",
"ToolTree",
"ToolGrass"};
LLPCode toolData[]={
LL_PCODE_CUBE,
LL_PCODE_PRISM,
LL_PCODE_PYRAMID,
LL_PCODE_TETRAHEDRON,
LL_PCODE_CYLINDER,
LL_PCODE_CYLINDER_HEMI,
LL_PCODE_CONE,
LL_PCODE_CONE_HEMI,
LL_PCODE_SPHERE,
LL_PCODE_SPHERE_HEMI,
LL_PCODE_TORUS,
LLViewerObject::LL_VO_SQUARE_TORUS,
LLViewerObject::LL_VO_TRIANGLE_TORUS,
LL_PCODE_LEGACY_TREE,
LL_PCODE_LEGACY_GRASS};
BOOL LLFloaterTools::postBuild()
{
// Hide until tool selected
setVisible(FALSE);
// Since we constantly show and hide this during drags, don't
// make sounds on visibility changes.
setSoundFlags(LLView::SILENT);
getDragHandle()->setEnabled( !gSavedSettings.getBOOL("ToolboxAutoMove") );
LLRect rect;
mBtnFocus = getChild<LLButton>("button focus");//btn;
mBtnMove = getChild<LLButton>("button move");
mBtnEdit = getChild<LLButton>("button edit");
mBtnCreate = getChild<LLButton>("button create");
mBtnLand = getChild<LLButton>("button land" );
mTextStatus = getChild<LLTextBox>("text status");
mRadioGroupFocus = getChild<LLRadioGroup>("focus_radio_group");
mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
mBtnGridOptions = getChild<LLButton>("Options...");
mBtnLink = getChild<LLButton>("link_btn");
mBtnUnlink = getChild<LLButton>("unlink_btn");
mCheckSelectIndividual = getChild<LLCheckBoxCtrl>("checkbox edit linked parts");
getChild<LLUICtrl>("checkbox edit linked parts")->setValue((BOOL)gSavedSettings.getBOOL("EditLinkedParts"));
mCheckSnapToGrid = getChild<LLCheckBoxCtrl>("checkbox snap to grid");
getChild<LLUICtrl>("checkbox snap to grid")->setValue((BOOL)gSavedSettings.getBOOL("SnapEnabled"));
mCheckStretchUniform = getChild<LLCheckBoxCtrl>("checkbox uniform");
getChild<LLUICtrl>("checkbox uniform")->setValue((BOOL)gSavedSettings.getBOOL("ScaleUniform"));
mCheckStretchTexture = getChild<LLCheckBoxCtrl>("checkbox stretch textures");
getChild<LLUICtrl>("checkbox stretch textures")->setValue((BOOL)gSavedSettings.getBOOL("ScaleStretchTextures"));
mComboGridMode = getChild<LLComboBox>("combobox grid mode");
//
// Create Buttons
//
for(size_t t=0; t<LL_ARRAY_SIZE(toolNames); ++t)
{
LLButton *found = getChild<LLButton>(toolNames[t]);
if(found)
{
found->setClickedCallback(boost::bind(&LLFloaterTools::setObjectType, toolData[t]));
mButtons.push_back( found );
}else{
LL_WARNS() << "Tool button not found! DOA Pending." << LL_ENDL;
}
}
mCheckCopySelection = getChild<LLCheckBoxCtrl>("checkbox copy selection");
getChild<LLUICtrl>("checkbox copy selection")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolCopySelection"));
mCheckSticky = getChild<LLCheckBoxCtrl>("checkbox sticky");
getChild<LLUICtrl>("checkbox sticky")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolKeepSelected"));
mCheckCopyCenters = getChild<LLCheckBoxCtrl>("checkbox copy centers");
getChild<LLUICtrl>("checkbox copy centers")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolCopyCenters"));
mCheckCopyRotates = getChild<LLCheckBoxCtrl>("checkbox copy rotates");
getChild<LLUICtrl>("checkbox copy rotates")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolCopyRotates"));
mRadioGroupLand = getChild<LLRadioGroup>("land_radio_group");
mBtnApplyToSelection = getChild<LLButton>("button apply to selection");
mSliderDozerSize = getChild<LLSlider>("slider brush size");
getChild<LLUICtrl>("slider brush size")->setValue(gSavedSettings.getF32("LandBrushSize"));
mSliderDozerForce = getChild<LLSlider>("slider force");
// the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here
getChild<LLUICtrl>("slider force")->setValue(log10(gSavedSettings.getF32("LandBrushForce")));
mCostTextBorder = getChild<LLViewBorder>("cost_text_border");
mTab = getChild<LLTabContainer>("Object Info Tabs");
if(mTab)
{
mTab->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT);
mTab->setBorderVisible(FALSE);
mTab->selectFirstTab();
}
mStatusText["rotate"] = getString("status_rotate");
mStatusText["scale"] = getString("status_scale");
mStatusText["move"] = getString("status_move");
mStatusText["modifyland"] = getString("status_modifyland");
mStatusText["camera"] = getString("status_camera");
mStatusText["grab"] = getString("status_grab");
mStatusText["place"] = getString("status_place");
mStatusText["selectland"] = getString("status_selectland");
sShowObjectCost = gSavedSettings.getBOOL("ShowObjectRenderingCost");
return TRUE;
}
// Create the popupview with a dummy center. It will be moved into place
// during LLViewerWindow's per-frame hover processing.
LLFloaterTools::LLFloaterTools(const LLSD& key)
: LLFloater(key),
mBtnFocus(NULL),
mBtnMove(NULL),
mBtnEdit(NULL),
mBtnCreate(NULL),
mBtnLand(NULL),
mTextStatus(NULL),
mRadioGroupFocus(NULL),
mRadioGroupMove(NULL),
mRadioGroupEdit(NULL),
mCheckSelectIndividual(NULL),
mCheckSnapToGrid(NULL),
mBtnGridOptions(NULL),
mComboGridMode(NULL),
mCheckStretchUniform(NULL),
mCheckStretchTexture(NULL),
mCheckStretchUniformLabel(NULL),
mBtnRotateLeft(NULL),
mBtnRotateReset(NULL),
mBtnRotateRight(NULL),
mBtnLink(NULL),
mBtnUnlink(NULL),
mBtnDelete(NULL),
mBtnDuplicate(NULL),
mBtnDuplicateInPlace(NULL),
mCheckSticky(NULL),
mCheckCopySelection(NULL),
mCheckCopyCenters(NULL),
mCheckCopyRotates(NULL),
mRadioGroupLand(NULL),
mSliderDozerSize(NULL),
mSliderDozerForce(NULL),
mBtnApplyToSelection(NULL),
mTab(NULL),
mPanelPermissions(NULL),
mPanelObject(NULL),
mPanelVolume(NULL),
mPanelContents(NULL),
mPanelFace(NULL),
mPanelLandInfo(NULL),
mCostTextBorder(NULL),
mTabLand(NULL),
mLandImpactsObserver(NULL),
mDirty(TRUE),
mHasSelection(TRUE)
{
gFloaterTools = this;
setAutoFocus(FALSE);
mFactoryMap["General"] = LLCallbackMap(createPanelPermissions, this);//LLPanelPermissions
mFactoryMap["Object"] = LLCallbackMap(createPanelObject, this);//LLPanelObject
mFactoryMap["Features"] = LLCallbackMap(createPanelVolume, this);//LLPanelVolume
mFactoryMap["Texture"] = LLCallbackMap(createPanelFace, this);//LLPanelFace
mFactoryMap["Contents"] = LLCallbackMap(createPanelContents, this);//LLPanelContents
mFactoryMap["land info panel"] = LLCallbackMap(createPanelLandInfo, this);//LLPanelLandInfo
mCommitCallbackRegistrar.add("BuildTool.setTool", boost::bind(&LLFloaterTools::setTool,this, _2));
mCommitCallbackRegistrar.add("BuildTool.commitZoom", boost::bind(&commit_slider_zoom, _1));
mCommitCallbackRegistrar.add("BuildTool.commitRadioFocus", boost::bind(&commit_radio_group_focus, _1));
mCommitCallbackRegistrar.add("BuildTool.commitRadioMove", boost::bind(&commit_radio_group_move,_1));
mCommitCallbackRegistrar.add("BuildTool.commitRadioEdit", boost::bind(&commit_radio_group_edit,_1));
mCommitCallbackRegistrar.add("BuildTool.gridMode", boost::bind(&commit_grid_mode,_1));
mCommitCallbackRegistrar.add("BuildTool.selectComponent", boost::bind(&commit_select_component, this));
mCommitCallbackRegistrar.add("BuildTool.gridOptions", boost::bind(&LLFloaterTools::onClickGridOptions,this));
mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this));
mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1));
mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1));
mCommitCallbackRegistrar.add("BuildTool.LinkObjects", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance()));
mCommitCallbackRegistrar.add("BuildTool.UnlinkObjects", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
mLandImpactsObserver = new LLLandImpactsObserver();
LLViewerParcelMgr::getInstance()->addObserver(mLandImpactsObserver);
}
LLFloaterTools::~LLFloaterTools()
{
// children automatically deleted
gFloaterTools = NULL;
LLViewerParcelMgr::getInstance()->removeObserver(mLandImpactsObserver);
delete mLandImpactsObserver;
}
void LLFloaterTools::setStatusText(const std::string& text)
{
std::map<std::string, std::string>::iterator iter = mStatusText.find(text);
if (iter != mStatusText.end())
{
mTextStatus->setText(iter->second);
}
else
{
mTextStatus->setText(text);
}
}
void LLFloaterTools::refresh()
{
const S32 INFO_WIDTH = getRect().getWidth();
const S32 INFO_HEIGHT = 384;
LLRect object_info_rect(0, 0, INFO_WIDTH, -INFO_HEIGHT);
BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME );
S32 idx_features = mTab->getPanelIndexByTitle(PANEL_NAMES[PANEL_FEATURES]);
S32 idx_face = mTab->getPanelIndexByTitle(PANEL_NAMES[PANEL_FACE]);
S32 idx_contents = mTab->getPanelIndexByTitle(PANEL_NAMES[PANEL_CONTENTS]);
S32 selected_index = mTab->getCurrentPanelIndex();
if (!all_volume && (selected_index == idx_features || selected_index == idx_face ||
selected_index == idx_contents))
{
mTab->selectFirstTab();
}
mTab->enableTabButton(idx_features, all_volume);
mTab->enableTabButton(idx_face, all_volume);
mTab->enableTabButton(idx_contents, all_volume);
// Refresh object and prim count labels
LLLocale locale(LLLocale::USER_LOCALE);
#if 0
if (!gMeshRepo.meshRezEnabled())
{
std::string obj_count_string;
LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount());
getChild<LLUICtrl>("selection_count")->setTextArg("[OBJ_COUNT]", obj_count_string);
std::string prim_count_string;
LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount());
getChild<LLUICtrl>("selection_count")->setTextArg("[PRIM_COUNT]", prim_count_string);
// calculate selection rendering cost
if (sShowObjectCost)
{
std::string prim_cost_string;
S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost();
LLResMgr::getInstance()->getIntegerString(prim_cost_string, render_cost);
getChild<LLUICtrl>("RenderingCost")->setTextArg("[COUNT]", prim_cost_string);
}
// disable the object and prim counts if nothing selected
bool have_selection = ! LLSelectMgr::getInstance()->getSelection()->isEmpty();
getChildView("obj_count")->setEnabled(have_selection);
getChildView("prim_count")->setEnabled(have_selection);
getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost);
}
else
#endif
{
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
F32 link_cost = selection->getSelectedLinksetCost();
S32 link_count = selection->getRootObjectCount();
S32 object_count = selection->getObjectCount();
LLCrossParcelFunctor func;
if (!LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true))
{
// Unless multiple parcels selected, higlight parcel object is at.
LLViewerObject* selected_object = mObjectSelection->getFirstObject();
if (selected_object)
{
// Select a parcel at the currently selected object's position.
LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal());
}
else
{
LL_WARNS() << "Failed to get selected object" << LL_ENDL;
}
}
if (object_count == 1)
{
// "selection_faces" shouldn't be visible if not LLToolFace::getInstance()
// But still need to be populated in case user switches
std::string faces_str = "";
for (LLObjectSelection::iterator iter = selection->begin(); iter != selection->end();)
{
LLObjectSelection::iterator nextiter = iter++; // not strictly needed, we have only one object
LLSelectNode* node = *nextiter;
LLViewerObject* object = (*nextiter)->getObject();
if (!object)
continue;
S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
for (S32 te = 0; te < num_tes; ++te)
{
if (node->isTESelected(te))
{
if (!faces_str.empty())
{
faces_str += ", ";
}
faces_str += llformat("%d", te);
}
}
}
childSetTextArg("selection_faces", "[FACES_STRING]", faces_str);
}
bool show_faces = (object_count == 1)
&& LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool();
getChildView("selection_faces")->setVisible(show_faces);
LLStringUtil::format_map_t selection_args;
selection_args["OBJ_COUNT"] = llformat("%.1d", link_count);
selection_args["LAND_IMPACT"] = llformat("%.1d", (S32)link_cost);
std::ostringstream selection_info;
selection_info << getString("status_selectcount", selection_args);
getChild<LLTextBox>("selection_count")->setText(selection_info.str());
}
// Refresh child tabs
mPanelPermissions->refresh();
mPanelObject->refresh();
mPanelVolume->refresh();
mPanelFace->refresh();
mPanelFace->refreshMedia();
mPanelContents->refresh();
mPanelLandInfo->refresh();
// Refresh the advanced weights floater
LLFloaterObjectWeights* object_weights_floater = LLFloaterReg::findTypedInstance<LLFloaterObjectWeights>("object_weights");
if(object_weights_floater && object_weights_floater->getVisible())
{
object_weights_floater->refresh();
}
}
void LLFloaterTools::draw()
{
BOOL has_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
if(!has_selection && (mHasSelection != has_selection))
{
mDirty = TRUE;
}
mHasSelection = has_selection;
if (mDirty)
{
refresh();
mDirty = FALSE;
}
// mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts"));
LLFloater::draw();
}
void LLFloaterTools::dirty()
{
mDirty = TRUE;
LLFloaterOpenObject* instance = LLFloaterReg::findTypedInstance<LLFloaterOpenObject>("openobject");
if (instance) instance->dirty();
}
// Clean up any tool state that should not persist when the
// floater is closed.
void LLFloaterTools::resetToolState()
{
gCameraBtnZoom = TRUE;
gCameraBtnOrbit = FALSE;
gCameraBtnPan = FALSE;
gGrabBtnSpin = FALSE;
gGrabBtnVertical = FALSE;
}
void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
{
LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
// HACK to allow seeing the buttons when you have the app in a window.
// Keep the visibility the same as it
if (tool == gToolNull)
{
return;
}
if ( isMinimized() )
{ // SL looks odd if we draw the tools while the window is minimized
return;
}
// Focus buttons
BOOL focus_visible = ( tool == LLToolCamera::getInstance() );
mBtnFocus ->setToggleState( focus_visible );
mRadioGroupFocus->setVisible( focus_visible );
getChildView("slider zoom")->setVisible( focus_visible);
getChildView("slider zoom")->setEnabled(gCameraBtnZoom);
if (!gCameraBtnOrbit &&
!gCameraBtnPan &&
!(mask == MASK_ORBIT) &&
!(mask == (MASK_ORBIT | MASK_ALT)) &&
!(mask == MASK_PAN) &&
!(mask == (MASK_PAN | MASK_ALT)) )
{
mRadioGroupFocus->setValue("radio zoom");
}
else if ( gCameraBtnOrbit ||
(mask == MASK_ORBIT) ||
(mask == (MASK_ORBIT | MASK_ALT)) )
{
mRadioGroupFocus->setValue("radio orbit");
}
else if ( gCameraBtnPan ||
(mask == MASK_PAN) ||
(mask == (MASK_PAN | MASK_ALT)) )
{
mRadioGroupFocus->setValue("radio pan");
}
// multiply by correction factor because volume sliders go [0, 0.5]
getChild<LLUICtrl>("slider zoom")->setValue(gAgentCamera.getCameraZoomFraction() * 0.5f);
// Move buttons
BOOL move_visible = (tool == LLToolGrab::getInstance());
if (mBtnMove) mBtnMove ->setToggleState( move_visible );
// HACK - highlight buttons for next click
mRadioGroupMove->setVisible(move_visible);
if (!(gGrabBtnSpin ||
gGrabBtnVertical ||
(mask == MASK_VERTICAL) ||
(mask == MASK_SPIN)))
{
mRadioGroupMove->setValue("radio move");
}
else if ((mask == MASK_VERTICAL) ||
(gGrabBtnVertical && (mask != MASK_SPIN)))
{
mRadioGroupMove->setValue("radio lift");
}
else if ((mask == MASK_SPIN) ||
(gGrabBtnSpin && (mask != MASK_VERTICAL)))
{
mRadioGroupMove->setValue("radio spin");
}
// Edit buttons
BOOL edit_visible = tool == LLToolCompTranslate::getInstance() ||
tool == LLToolCompRotate::getInstance() ||
tool == LLToolCompScale::getInstance() ||
tool == LLToolFace::getInstance() ||
tool == LLToolIndividual::getInstance() ||
tool == LLToolPipette::getInstance();
mBtnEdit ->setToggleState( edit_visible );
mRadioGroupEdit->setVisible( edit_visible );
//bool linked_parts = gSavedSettings.getBOOL("EditLinkedParts");
//getChildView("RenderingCost")->setVisible( !linked_parts && (edit_visible || focus_visible || move_visible) && sShowObjectCost);
mBtnLink->setVisible(edit_visible);
mBtnUnlink->setVisible(edit_visible);
mBtnLink->setEnabled(LLSelectMgr::instance().enableLinkObjects());
mBtnUnlink->setEnabled(LLSelectMgr::instance().enableUnlinkObjects());
if (mCheckSelectIndividual)
{
mCheckSelectIndividual->setVisible(edit_visible);
//mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts"));
}
if ( tool == LLToolCompTranslate::getInstance() )
{
mRadioGroupEdit->setValue("radio position");
}
else if ( tool == LLToolCompRotate::getInstance() )
{
mRadioGroupEdit->setValue("radio rotate");
}
else if ( tool == LLToolCompScale::getInstance() )
{
mRadioGroupEdit->setValue("radio stretch");
}
else if ( tool == LLToolFace::getInstance() )
{
mRadioGroupEdit->setValue("radio select face");
}
if (mComboGridMode)
{
mComboGridMode->setVisible( edit_visible );
S32 index = mComboGridMode->getCurrentIndex();
mComboGridMode->removeall();
switch (mObjectSelection->getSelectType())
{
case SELECT_TYPE_HUD:
mComboGridMode->add(getString("grid_screen_text"));
mComboGridMode->add(getString("grid_local_text"));
break;
case SELECT_TYPE_WORLD:
mComboGridMode->add(getString("grid_world_text"));
mComboGridMode->add(getString("grid_local_text"));
mComboGridMode->add(getString("grid_reference_text"));
break;
case SELECT_TYPE_ATTACHMENT:
mComboGridMode->add(getString("grid_attachment_text"));
mComboGridMode->add(getString("grid_local_text"));
mComboGridMode->add(getString("grid_reference_text"));
break;
}
mComboGridMode->setCurrentByIndex(index);
}
// Snap to grid disabled for grab tool - very confusing
if (mCheckSnapToGrid) mCheckSnapToGrid->setVisible( edit_visible /* || tool == LLToolGrab::getInstance() */ );
if (mBtnGridOptions) mBtnGridOptions->setVisible( edit_visible /* || tool == LLToolGrab::getInstance() */ );
//mCheckSelectLinked ->setVisible( edit_visible );
if (mCheckStretchUniform) mCheckStretchUniform->setVisible( edit_visible );
if (mCheckStretchTexture) mCheckStretchTexture->setVisible( edit_visible );
if (mCheckStretchUniformLabel) mCheckStretchUniformLabel->setVisible( edit_visible );
// Create buttons
BOOL create_visible = (tool == LLToolCompCreate::getInstance());
mBtnCreate ->setToggleState( tool == LLToolCompCreate::getInstance() );
if (mCheckCopySelection
&& mCheckCopySelection->get())
{
// don't highlight any placer button
for (std::vector<LLButton*>::size_type i = 0; i < mButtons.size(); i++)
{
mButtons[i]->setToggleState(FALSE);
mButtons[i]->setVisible( create_visible );
}
}
else
{
// Highlight the correct placer button
for( S32 t = 0; t < (S32)mButtons.size(); t++ )
{
LLPCode pcode = LLToolPlacer::getObjectType();
LLPCode button_pcode = toolData[t];
BOOL state = (pcode == button_pcode);
mButtons[t]->setToggleState( state );
mButtons[t]->setVisible( create_visible );
}
}
if (mCheckSticky) mCheckSticky ->setVisible( create_visible );
if (mCheckCopySelection) mCheckCopySelection ->setVisible( create_visible );
if (mCheckCopyCenters) mCheckCopyCenters ->setVisible( create_visible );
if (mCheckCopyRotates) mCheckCopyRotates ->setVisible( create_visible );
if (mCheckCopyCenters && mCheckCopySelection) mCheckCopyCenters->setEnabled( mCheckCopySelection->get() );
if (mCheckCopyRotates && mCheckCopySelection) mCheckCopyRotates->setEnabled( mCheckCopySelection->get() );
// Land buttons
BOOL land_visible = (tool == LLToolBrushLand::getInstance() || tool == LLToolSelectLand::getInstance() );
mCostTextBorder->setVisible(!land_visible);
if (mBtnLand) mBtnLand ->setToggleState( land_visible );
mRadioGroupLand->setVisible( land_visible );
if ( tool == LLToolSelectLand::getInstance() )
{
mRadioGroupLand->setValue("radio select land");
}
else if ( tool == LLToolBrushLand::getInstance() )
{
S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction");
switch(dozer_mode)
{
case 0:
mRadioGroupLand->setValue("radio flatten");
break;
case 1:
mRadioGroupLand->setValue("radio raise");
break;
case 2:
mRadioGroupLand->setValue("radio lower");
break;
case 3:
mRadioGroupLand->setValue("radio smooth");
break;
case 4:
mRadioGroupLand->setValue("radio noise");
break;
case 5:
mRadioGroupLand->setValue("radio revert");
break;
default:
break;
}
}
if (mBtnApplyToSelection)
{
mBtnApplyToSelection->setVisible( land_visible );
mBtnApplyToSelection->setEnabled( land_visible && !LLViewerParcelMgr::getInstance()->selectionEmpty() && tool != LLToolSelectLand::getInstance());
}
if (mSliderDozerSize)
{
mSliderDozerSize ->setVisible( land_visible );
getChildView("Bulldozer:")->setVisible( land_visible);
getChildView("Dozer Size:")->setVisible( land_visible);
}
if (mSliderDozerForce)
{
mSliderDozerForce ->setVisible( land_visible );
getChildView("Strength:")->setVisible( land_visible);
}
bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
getChildView("selection_count")->setVisible(!land_visible && have_selection);
getChildView("selection_faces")->setVisible(LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()
&& LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1);
getChildView("selection_empty")->setVisible(!land_visible && !have_selection);
mTab->setVisible(!land_visible);
mPanelLandInfo->setVisible(land_visible);
}
// virtual
BOOL LLFloaterTools::canClose()
{
// don't close when quitting, so camera will stay put
return !LLApp::isExiting();
}
// virtual
void LLFloaterTools::onOpen(const LLSD& key)
{
mParcelSelection = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
std::string panel = key.asString();
if (!panel.empty())
{
mTab->selectTabByName(panel);
}
LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
if (tool == LLToolCompInspect::getInstance()
|| tool == LLToolDragAndDrop::getInstance())
{
// Something called floater up while it was supressed (during drag n drop, inspect),
// so it won't be getting any layout or visibility updates, update once
// further updates will come from updateLayout()
LLCoordGL select_center_screen;
MASK mask = gKeyboard->currentMask(TRUE);
updatePopup(select_center_screen, mask);
}
//gMenuBarView->setItemVisible("BuildTools", TRUE);
}
// virtual
void LLFloaterTools::onClose(bool app_quitting)
{
mTab->setVisible(FALSE);
LLViewerJoystick::getInstance()->moveAvatar(false);
// destroy media source used to grab media title
mPanelFace->unloadMedia();
// Different from handle_reset_view in that it doesn't actually
// move the camera if EditCameraMovement is not set.
gAgentCamera.resetView(gSavedSettings.getBOOL("EditCameraMovement"));
// exit component selection mode
LLSelectMgr::getInstance()->promoteSelectionToRoot();
gSavedSettings.setBOOL("EditLinkedParts", FALSE);
gViewerWindow->showCursor();
resetToolState();
mParcelSelection = NULL;
mObjectSelection = NULL;
// Switch back to basic toolset
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
// we were already in basic toolset, using build tools
// so manually reset tool to default (pie menu tool)
LLToolMgr::getInstance()->getCurrentToolset()->selectFirstTool();
//gMenuBarView->setItemVisible("BuildTools", FALSE);
LLFloaterReg::hideInstance("media_settings");
// hide the advanced object weights floater
LLFloaterReg::hideInstance("object_weights");
// hide gltf material editor
LLFloaterReg::hideInstance("live_material_editor");
// prepare content for next call
mPanelContents->clearContents();
if(sPreviousFocusOnAvatar)
{
sPreviousFocusOnAvatar = false;
gAgentCamera.setAllowChangeToFollow(TRUE);
}
}
void click_popup_info(void*)
{
}
void click_popup_done(void*)
{
handle_reset_view();
}
void commit_radio_group_move(LLUICtrl* ctrl)
{
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
if (selected == "radio move")
{
gGrabBtnVertical = FALSE;
gGrabBtnSpin = FALSE;
}
else if (selected == "radio lift")
{
gGrabBtnVertical = TRUE;
gGrabBtnSpin = FALSE;
}
else if (selected == "radio spin")
{
gGrabBtnVertical = FALSE;
gGrabBtnSpin = TRUE;
}
}
void commit_radio_group_focus(LLUICtrl* ctrl)
{
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
if (selected == "radio zoom")
{
gCameraBtnZoom = TRUE;
gCameraBtnOrbit = FALSE;
gCameraBtnPan = FALSE;
}
else if (selected == "radio orbit")
{
gCameraBtnZoom = FALSE;
gCameraBtnOrbit = TRUE;
gCameraBtnPan = FALSE;
}
else if (selected == "radio pan")
{
gCameraBtnZoom = FALSE;
gCameraBtnOrbit = FALSE;
gCameraBtnPan = TRUE;
}
}
void commit_slider_zoom(LLUICtrl *ctrl)
{
// renormalize value, since max "volume" level is 0.5 for some reason
F32 zoom_level = (F32)ctrl->getValue().asReal() * 2.f; // / 0.5f;
gAgentCamera.setCameraZoomFraction(zoom_level);
}
void commit_slider_dozer_force(LLUICtrl *ctrl)
{
// the slider is logarithmic, so we exponentiate to get the actual force multiplier
F32 dozer_force = pow(10.f, (F32)ctrl->getValue().asReal());
gSavedSettings.setF32("LandBrushForce", dozer_force);
}
void click_apply_to_selection(void*)
{
LLToolBrushLand::getInstance()->modifyLandInSelectionGlobal();
}
void commit_radio_group_edit(LLUICtrl *ctrl)
{
S32 show_owners = gSavedSettings.getBOOL("ShowParcelOwners");
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
if (selected == "radio position")
{
LLFloaterTools::setEditTool( LLToolCompTranslate::getInstance() );
}
else if (selected == "radio rotate")
{
LLFloaterTools::setEditTool( LLToolCompRotate::getInstance() );
}
else if (selected == "radio stretch")
{
LLFloaterTools::setEditTool( LLToolCompScale::getInstance() );
}
else if (selected == "radio select face")
{
LLFloaterTools::setEditTool( LLToolFace::getInstance() );
}
gSavedSettings.setBOOL("ShowParcelOwners", show_owners);
}
void commit_radio_group_land(LLUICtrl* ctrl)
{
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
if (selected == "radio select land")
{
LLFloaterTools::setEditTool( LLToolSelectLand::getInstance() );
}
else
{
LLFloaterTools::setEditTool( LLToolBrushLand::getInstance() );
S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction");
if (selected == "radio flatten")
dozer_mode = 0;
else if (selected == "radio raise")
dozer_mode = 1;
else if (selected == "radio lower")
dozer_mode = 2;
else if (selected == "radio smooth")
dozer_mode = 3;
else if (selected == "radio noise")
dozer_mode = 4;
else if (selected == "radio revert")
dozer_mode = 5;
gSavedSettings.setS32("RadioLandBrushAction", dozer_mode);
}
}
void commit_select_component(void *data)
{
LLFloaterTools* floaterp = (LLFloaterTools*)data;
//forfeit focus
if (gFocusMgr.childHasKeyboardFocus(floaterp))
{
gFocusMgr.setKeyboardFocus(NULL);
}
BOOL select_individuals = floaterp->mCheckSelectIndividual->get();
gSavedSettings.setBOOL("EditLinkedParts", select_individuals);
floaterp->dirty();
if (select_individuals)
{
LLSelectMgr::getInstance()->demoteSelectionToIndividuals();
}
else
{
LLSelectMgr::getInstance()->promoteSelectionToRoot();
}
}
// static
void LLFloaterTools::setObjectType( LLPCode pcode )
{
LLToolPlacer::setObjectType( pcode );
gSavedSettings.setBOOL("CreateToolCopySelection", FALSE);
gFocusMgr.setMouseCapture(NULL);
}
void commit_grid_mode(LLUICtrl *ctrl)
{
LLComboBox* combo = (LLComboBox*)ctrl;
LLSelectMgr::getInstance()->setGridMode((EGridMode)combo->getCurrentIndex());
}
// static
void LLFloaterTools::setGridMode(S32 mode)
{
LLFloaterTools* tools_floater = LLFloaterReg::getTypedInstance<LLFloaterTools>("build");
if (!tools_floater || !tools_floater->mComboGridMode)
{
return;
}
tools_floater->mComboGridMode->setCurrentByIndex(mode);
}
void LLFloaterTools::onClickGridOptions()
{
LLFloater* floaterp = LLFloaterReg::showInstance("build_options");
// position floater next to build tools, not over
floaterp->setShape(gFloaterView->findNeighboringPosition(this, floaterp), true);
}
// static
void LLFloaterTools::setEditTool(void* tool_pointer)
{
LLTool *tool = (LLTool *)tool_pointer;
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( tool );
}
void LLFloaterTools::setTool(const LLSD& user_data)
{
std::string control_name = user_data.asString();
if(control_name == "Focus")
LLToolMgr::getInstance()->getCurrentToolset()->selectTool((LLTool *) LLToolCamera::getInstance() );
else if (control_name == "Move" )
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *)LLToolGrab::getInstance() );
else if (control_name == "Edit" )
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompTranslate::getInstance());
else if (control_name == "Create" )
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompCreate::getInstance());
else if (control_name == "Land" )
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolSelectLand::getInstance());
else
LL_WARNS()<<" no parameter name "<<control_name<<" found!! No Tool selected!!"<< LL_ENDL;
}
void LLFloaterTools::onFocusReceived()
{
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
LLFloater::onFocusReceived();
}
void LLFloaterTools::updateLandImpacts()
{
LLParcel *parcel = mParcelSelection->getParcel();
if (!parcel)
{
return;
}
// Update land impacts info in the weights floater
LLFloaterObjectWeights* object_weights_floater = LLFloaterReg::findTypedInstance<LLFloaterObjectWeights>("object_weights");
if(object_weights_floater)
{
object_weights_floater->updateLandImpacts(parcel);
}
}