Merged Ascent progress - title picker
This commit is contained in:
@@ -76,11 +76,13 @@ set(viewer_SOURCE_FILES
|
||||
dofloaterhex.cpp
|
||||
dohexeditor.cpp
|
||||
floatersculptpreview.cpp
|
||||
hbfloatergrouptitles.cpp
|
||||
hgfloatertexteditor.cpp
|
||||
hippogridmanager.cpp
|
||||
hipporestrequest.cpp
|
||||
jcfloaterareasearch.cpp
|
||||
chatbar_as_cmdline.cpp
|
||||
qtoolalign.cpp
|
||||
llagent.cpp
|
||||
llagentaccess.cpp
|
||||
llagentdata.cpp
|
||||
@@ -530,11 +532,13 @@ set(viewer_HEADER_FILES
|
||||
dofloaterhex.h
|
||||
dohexeditor.h
|
||||
floatersculptpreview.h
|
||||
hbfloatergrouptitles.h
|
||||
hgfloatertexteditor.h
|
||||
hippogridmanager.h
|
||||
hipporestrequest.h
|
||||
jcfloaterareasearch.h
|
||||
chatbar_as_cmdline.h
|
||||
qtoolalign.h
|
||||
llagent.h
|
||||
llagentaccess.h
|
||||
llagentdata.h
|
||||
|
||||
@@ -343,6 +343,226 @@
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<!--Expanded settings from Vanilla SL -->
|
||||
<key>BeauchampUseInventoryLinks</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When making a new outfit, use links for no-copy items</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>MoyFastMiniMap</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When making a new outfit, use links for no-copy items</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>MoyMiniMapCustomColor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Custom minimap color you wish to have.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Color4</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>0.375</real>
|
||||
<real>1.0</real>
|
||||
<real>1.0</real>
|
||||
<real>1.0</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>BeauchampFloaterGroupTitlesRect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Rectangle for group titles window</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Rect</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<integer>0</integer>
|
||||
<integer>400</integer>
|
||||
<integer>500</integer>
|
||||
<integer>0</integer>
|
||||
</array>
|
||||
</map>
|
||||
<key>ShyotlRenderUseStreamVBO</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use VBO's for stream buffers</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OptionShowGroupNameInChatIM</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show group name in IM notification</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AscentInstantMessageAnnounceIncoming</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Start IM window as soon as the person starts typing</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AscentShowLookAt</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show Others' Lookat points</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<real>0</real>
|
||||
</map>
|
||||
<key>AscentUseStatusColors</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show special colors for statuses like Friend, Linden, so on</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<real>0</real>
|
||||
</map>
|
||||
<key>AscentAvatarXModifier</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Avatar position modifier (X)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.0</real>
|
||||
</map>
|
||||
<key>AscentAvatarYModifier</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Avatar position modifier (Y)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.0</real>
|
||||
</map>
|
||||
<key>AscentAvatarZModifier</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Avatar position modifier (Z)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.0</real>
|
||||
</map>
|
||||
<key>AscentUseSystemFolder</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enables the System folder for setting and non-permanent asset storage.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AscentSystemTemporary</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When enabled, temporary uploads are put in the System Asset folder (if System Folder exists).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AscentShowFriendsTag</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show friends client tags as (Friend), and colorize them specially.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AscentUseTag</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Broadcast client tag</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AscentShowIdleTime</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show client tags for others.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AscentShowOthersTag</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show client tags for others.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AscentShowOthersTagColor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show avatar names in the color of their client.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AscentBuildAlwaysEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -14300,7 +14520,7 @@
|
||||
<key>FloaterUploadRect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Rectangle for DicksDongs</string>
|
||||
<string>Rectangle for Uploader</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
@@ -14313,6 +14533,33 @@
|
||||
<integer>400</integer>
|
||||
</array>
|
||||
</map>
|
||||
<key>FloaterContactRect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Rectangle for Contact Group Manager</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Rect</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<integer>500</integer>
|
||||
<integer>450</integer>
|
||||
<integer>850</integer>
|
||||
<integer>400</integer>
|
||||
</array>
|
||||
</map>
|
||||
<key>ContactListCollapsed</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Send a digest of texture info to the sim</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FloaterHexRect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "llscrolllistctrl.h" //List box for filenames
|
||||
#include "lluictrlfactory.h" //Loads the XUI
|
||||
#include "llresmgr.h"
|
||||
// project includes
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llsdserialize.h"
|
||||
@@ -45,17 +44,16 @@ void ASFloaterContactGroups::show(LLDynamicArray<LLUUID> ids)
|
||||
{
|
||||
if (!sInstance)
|
||||
sInstance = new ASFloaterContactGroups();
|
||||
|
||||
mSelectedUUIDs = ids;
|
||||
|
||||
sInstance->open();
|
||||
sInstance->populateGroupList();
|
||||
sInstance->populateFriendList();
|
||||
|
||||
sInstance->childSetAction("Cancel", onBtnClose, sInstance);
|
||||
sInstance->childSetAction("Save", onBtnSave, sInstance);
|
||||
sInstance->childSetAction("Create", onBtnCreate, sInstance);
|
||||
sInstance->childSetAction("Delete", onBtnDelete, sInstance);
|
||||
sInstance->childSetAction("combo_group_add", onBtnAdd, sInstance);
|
||||
sInstance->childSetAction("combo_group_remove", onBtnRemove, sInstance);
|
||||
//sInstance->childSetAction("New", onBtnCreate, sInstance);
|
||||
//sInstance->childSetAction("Delete", onBtnDelete, sInstance);
|
||||
}
|
||||
|
||||
void ASFloaterContactGroups::onBtnDelete(void* userdata)
|
||||
@@ -73,7 +71,28 @@ void ASFloaterContactGroups::onBtnDelete(void* userdata)
|
||||
}
|
||||
}
|
||||
|
||||
void ASFloaterContactGroups::onBtnSave(void* userdata)
|
||||
void ASFloaterContactGroups::onBtnAdd(void* userdata)
|
||||
{
|
||||
ASFloaterContactGroups* self = (ASFloaterContactGroups*)userdata;
|
||||
llinfos << "Button Add Begin" << llendl;
|
||||
if(self)
|
||||
{
|
||||
LLComboBox* combo = self->getChild<LLComboBox>("buddy_group_combobox");
|
||||
if (combo->getCurrentIndex() == -1) //Entered text is a new group name, create a group first
|
||||
{
|
||||
std::string name = combo->getSimple();
|
||||
self->createContactGroup(name);
|
||||
combo->selectByValue(name);
|
||||
}
|
||||
for (S32 i = (self->mSelectedUUIDs.count() - 1); i >= 0; --i)
|
||||
{
|
||||
//self->addContactMember(combo->getSimple(), self->mSelectedUUIDs.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ASFloaterContactGroups::onBtnRemove(void* userdata)
|
||||
{
|
||||
ASFloaterContactGroups* self = (ASFloaterContactGroups*)userdata;
|
||||
|
||||
@@ -98,12 +117,6 @@ void ASFloaterContactGroups::onBtnSave(void* userdata)
|
||||
}
|
||||
}
|
||||
|
||||
void ASFloaterContactGroups::onBtnClose(void* userdata)
|
||||
{
|
||||
ASFloaterContactGroups* self = (ASFloaterContactGroups*)userdata;
|
||||
if(self) self->close();
|
||||
}
|
||||
|
||||
void ASFloaterContactGroups::onBtnCreate(void* userdata)
|
||||
{
|
||||
ASFloaterContactGroups* self = (ASFloaterContactGroups*)userdata;
|
||||
@@ -112,12 +125,12 @@ void ASFloaterContactGroups::onBtnCreate(void* userdata)
|
||||
LLLineEditor* editor = self->getChild<LLLineEditor>("add_group_lineedit");
|
||||
if (editor)
|
||||
{
|
||||
LLScrollListCtrl* scroller = self->getChild<LLScrollListCtrl>("friend_scroll_list");
|
||||
/*LLScrollListCtrl* scroller = self->getChild<LLScrollListCtrl>("friend_scroll_list");
|
||||
if(scroller != NULL)
|
||||
{
|
||||
self->createContactGroup(editor->getValue().asString());
|
||||
self->populateGroupList();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -139,17 +152,58 @@ ASFloaterContactGroups::~ASFloaterContactGroups()
|
||||
|
||||
void ASFloaterContactGroups::populateFriendList()
|
||||
{
|
||||
LLScrollListCtrl* scroller = getChild<LLScrollListCtrl>("friend_scroll_list");
|
||||
/*LLScrollListCtrl* scroller = getChild<LLScrollListCtrl>("friend_scroll_list");
|
||||
if(scroller != NULL)
|
||||
{
|
||||
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void ASFloaterContactGroups::addContactMember(std::string contact_grp, LLUUID to_add)
|
||||
{
|
||||
ASFloaterContactGroups::mContactGroupData[contact_grp].append(to_add.asString());
|
||||
gSavedPerAccountSettings.setLLSD("AscentContactGroups", ASFloaterContactGroups::mContactGroupData);
|
||||
BOOL is_new = true;
|
||||
S32 entrycount = ASFloaterContactGroups::mContactGroupData["ASC_MASTER_GROUP_LIST"][contact_grp].size();
|
||||
for(S32 i = 0; i < entrycount; i++)
|
||||
{
|
||||
if (ASFloaterContactGroups::mContactGroupData["ASC_MASTER_GROUP_LIST"][contact_grp][i].asString() == to_add.asString())
|
||||
{
|
||||
is_new = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_new)
|
||||
{
|
||||
ASFloaterContactGroups::mContactGroupData[contact_grp].append(to_add.asString());
|
||||
gSavedPerAccountSettings.setLLSD("AscentContactGroups", ASFloaterContactGroups::mContactGroupData);
|
||||
}
|
||||
populateActiveGroupList(to_add);
|
||||
}
|
||||
|
||||
void ASFloaterContactGroups::populateActiveGroupList(LLUUID user_key)
|
||||
{
|
||||
LLScrollListCtrl* scroller = getChild<LLScrollListCtrl>("group_scroll_list");
|
||||
if(scroller != NULL)
|
||||
{
|
||||
llinfos << "Cleaning and rebuilding group list" << llendl;
|
||||
scroller->deleteAllItems();
|
||||
|
||||
S32 count = ASFloaterContactGroups::mContactGroupData["ASC_MASTER_GROUP_LIST"].size();
|
||||
for (S32 index = 0; index < count; index++)
|
||||
{
|
||||
llinfos << "Entries for " << ASFloaterContactGroups::mContactGroupData["ASC_MASTER_GROUP_LIST"][index].asString() << llendl;
|
||||
S32 entrycount = ASFloaterContactGroups::mContactGroupData["ASC_MASTER_GROUP_LIST"][index].size();
|
||||
for(S32 i = 0; i < entrycount; i++)
|
||||
{
|
||||
llinfos << "Subentries for " << ASFloaterContactGroups::mContactGroupData["ASC_MASTER_GROUP_LIST"][index][i].asString() << llendl;
|
||||
if (ASFloaterContactGroups::mContactGroupData["ASC_MASTER_GROUP_LIST"][index][i].asString() == user_key.asString())
|
||||
{
|
||||
|
||||
scroller->addSimpleElement(ASFloaterContactGroups::mContactGroupData["ASC_MASTER_GROUP_LIST"][index].asString(), ADD_BOTTOM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ASFloaterContactGroups::deleteContactGroup(std::string contact_grp)
|
||||
@@ -167,21 +221,21 @@ void ASFloaterContactGroups::createContactGroup(std::string contact_grp)
|
||||
void ASFloaterContactGroups::populateGroupList()
|
||||
{
|
||||
ASFloaterContactGroups::mContactGroupData = gSavedPerAccountSettings.getLLSD("AscentContactGroups");
|
||||
LLScrollListCtrl* scroller = getChild<LLScrollListCtrl>("group_scroll_list");
|
||||
if(scroller != NULL)
|
||||
LLComboBox* combo = getChild<LLComboBox>("buddy_group_combobox");
|
||||
if(combo != NULL)
|
||||
{
|
||||
scroller->deleteAllItems();
|
||||
combo->removeall();
|
||||
|
||||
S32 count = ASFloaterContactGroups::mContactGroupData["ASC_MASTER_GROUP_LIST"].size();
|
||||
S32 index;
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
scroller->addSimpleElement(ASFloaterContactGroups::mContactGroupData["ASC_MASTER_GROUP_LIST"][index].asString(), ADD_BOTTOM);
|
||||
std::string group = ASFloaterContactGroups::mContactGroupData["ASC_MASTER_GROUP_LIST"][index].asString();
|
||||
if (group != "")
|
||||
{
|
||||
llinfos << "Adding " << group << llendl;
|
||||
combo->add(ASFloaterContactGroups::mContactGroupData["ASC_MASTER_GROUP_LIST"][index].asString(), ADD_BOTTOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLChat msg("Null Scroller");
|
||||
LLFloaterChat::addChat(msg);
|
||||
}
|
||||
}
|
||||
@@ -32,14 +32,15 @@ public:
|
||||
static void show(LLDynamicArray<LLUUID> ids);
|
||||
|
||||
void populateGroupList();
|
||||
void populateActiveGroupList(LLUUID to_add);
|
||||
void populateFriendList();
|
||||
void addContactMember(std::string contact_grp, LLUUID to_add);
|
||||
void createContactGroup(std::string contact_grp);
|
||||
void deleteContactGroup(std::string contact_grp);
|
||||
|
||||
// Buttons
|
||||
static void onBtnClose(void* userdata);
|
||||
static void onBtnSave(void* userdata);
|
||||
static void onBtnAdd(void* userdata);
|
||||
static void onBtnRemove(void* userdata);
|
||||
static void onBtnCreate(void* userdata);
|
||||
static void onBtnDelete(void* userdata);
|
||||
|
||||
|
||||
@@ -36,12 +36,14 @@ ASFloaterUploadBrowser* ASFloaterUploadBrowser::sInstance = NULL;
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLFloaterAbout
|
||||
/// Class ASFloaterUploadBrowser
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
// Default constructor
|
||||
ASFloaterUploadBrowser::ASFloaterUploadBrowser()
|
||||
: LLFloater(std::string("floater_upload_browser"), std::string("FloaterUploadRect"), LLStringUtil::null)
|
||||
: LLFloater(std::string("floater_upload_browser"),
|
||||
std::string("FloaterUploadRect"),
|
||||
LLStringUtil::null)
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_upload_browser.xml");
|
||||
|
||||
@@ -185,6 +187,8 @@ void ASFloaterUploadBrowser::refreshUploadOptions()
|
||||
llinfos << "Selected multiple files." << llendl;
|
||||
name = "(Multiple)";
|
||||
show_multiple = true;
|
||||
/*LLButton* expand_button = getChild<LLButton>("expand_collapse_btn");
|
||||
expand_button->setLabelArg("[COST]", std::string(mFileList->getAllSelected().size() * 10));*/
|
||||
childSetValue("multiple_uploads_label", "Multiple files selected. Total cost is: " + llformat("%d", mFileList->getAllSelected().size() * 10));
|
||||
}
|
||||
else
|
||||
|
||||
246
indra/newview/hbfloatergrouptitles.cpp
Normal file
246
indra/newview/hbfloatergrouptitles.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
/**
|
||||
* @file hbfloatergrouptitles.h
|
||||
* @brief HBFloaterGroupTitles class implementation
|
||||
*
|
||||
* This class implements a floater where all available group titles are
|
||||
* listed, allowing the user to activate any via simple double-click.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2010, Henri Beauchamp.
|
||||
*
|
||||
* 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 "message.h"
|
||||
#include "roles_constants.h"
|
||||
|
||||
#include "hbfloatergrouptitles.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
// static variable
|
||||
HBFloaterGroupTitles* HBFloaterGroupTitles::sInstance = NULL;
|
||||
|
||||
// helper function
|
||||
void update_titles_list(HBFloaterGroupTitles* self);
|
||||
|
||||
|
||||
// HBFloaterGroupTitlesObserver class
|
||||
|
||||
HBFloaterGroupTitlesObserver::HBFloaterGroupTitlesObserver(HBFloaterGroupTitles* instance, const LLUUID& group_id)
|
||||
: LLGroupMgrObserver(group_id),
|
||||
mFloaterInstance(instance)
|
||||
{
|
||||
LLGroupMgr::getInstance()->addObserver(this);
|
||||
}
|
||||
|
||||
// virtual
|
||||
HBFloaterGroupTitlesObserver::~HBFloaterGroupTitlesObserver()
|
||||
{
|
||||
LLGroupMgr::getInstance()->removeObserver(this);
|
||||
}
|
||||
|
||||
// virtual
|
||||
void HBFloaterGroupTitlesObserver::changed(LLGroupChange gc)
|
||||
{
|
||||
if (gc == GC_TITLES)
|
||||
{
|
||||
update_titles_list(mFloaterInstance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// HBFloaterGroupTitles class
|
||||
|
||||
HBFloaterGroupTitles::HBFloaterGroupTitles()
|
||||
: LLFloater(std::string("group titles")),
|
||||
mFirstUse(true)
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_group_titles.xml", NULL);
|
||||
sInstance = this;
|
||||
}
|
||||
|
||||
// virtual
|
||||
HBFloaterGroupTitles::~HBFloaterGroupTitles()
|
||||
{
|
||||
while (!mObservers.empty())
|
||||
{
|
||||
HBFloaterGroupTitlesObserver* observer = mObservers.back();
|
||||
delete observer;
|
||||
mObservers.pop_back();
|
||||
}
|
||||
sInstance = NULL;
|
||||
}
|
||||
|
||||
// static
|
||||
void HBFloaterGroupTitles::toggle()
|
||||
{
|
||||
// I hate things that don't toggle -- MC
|
||||
if (!sInstance)
|
||||
{
|
||||
sInstance = new HBFloaterGroupTitles();
|
||||
sInstance->setFocus(TRUE);
|
||||
sInstance->open();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sInstance->getVisible())
|
||||
{
|
||||
sInstance->close();
|
||||
}
|
||||
else
|
||||
{
|
||||
sInstance->open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL HBFloaterGroupTitles::postBuild()
|
||||
{
|
||||
mTitlesList = getChild<LLScrollListCtrl>("titles_list");
|
||||
if (!mTitlesList)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
mTitlesList->setCallbackUserData(this);
|
||||
mTitlesList->setDoubleClickCallback(onActivate);
|
||||
childSetAction("activate", onActivate, this);
|
||||
update_titles_list(this);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
void HBFloaterGroupTitles::onActivate(void* userdata)
|
||||
{
|
||||
HBFloaterGroupTitles* self = (HBFloaterGroupTitles*) userdata;
|
||||
LLScrollListItem *item = self->mTitlesList->getFirstSelected();
|
||||
if (!item) return;
|
||||
|
||||
// Set the group if needed.
|
||||
LLUUID old_group_id = gAgent.getGroupID();
|
||||
LLUUID group_id = item->getColumn(LIST_GROUP_ID)->getValue().asUUID();
|
||||
if (group_id != old_group_id)
|
||||
{
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_ActivateGroup);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->addUUIDFast(_PREHASH_GroupID, group_id);
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
// Set the title
|
||||
LLGroupMgr::getInstance()->sendGroupTitleUpdate(group_id, item->getUUID());
|
||||
// Force a refresh via the observer
|
||||
if (group_id == LLUUID::null)
|
||||
{
|
||||
group_id = old_group_id;
|
||||
}
|
||||
LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id);
|
||||
}
|
||||
|
||||
void update_titles_list(HBFloaterGroupTitles* self)
|
||||
{
|
||||
S32 i;
|
||||
S32 count = gAgent.mGroups.count();
|
||||
LLUUID id;
|
||||
LLUUID highlight_id = LLUUID::null;
|
||||
LLUUID current_group_id = gAgent.getGroupID();
|
||||
std::vector<LLGroupTitle>::const_iterator citer;
|
||||
std::string style;
|
||||
LLGroupData* group_datap;
|
||||
LLGroupMgrGroupData* gmgr_datap;
|
||||
|
||||
if (!self || !self->mTitlesList) return;
|
||||
LLCtrlListInterface *title_list = self->mTitlesList->getListInterface();
|
||||
|
||||
self->mTitlesList->deleteAllItems();
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
group_datap = &gAgent.mGroups.get(i);
|
||||
id = group_datap->mID;
|
||||
if (self->mFirstUse)
|
||||
{
|
||||
HBFloaterGroupTitlesObserver* observer = new HBFloaterGroupTitlesObserver(self, id);
|
||||
self->mObservers.push_back(observer);
|
||||
}
|
||||
gmgr_datap = LLGroupMgr::getInstance()->getGroupData(id);
|
||||
if (!gmgr_datap)
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendGroupTitlesRequest(id);
|
||||
continue;
|
||||
}
|
||||
for (citer = gmgr_datap->mTitles.begin(); citer != gmgr_datap->mTitles.end(); citer++)
|
||||
{
|
||||
style = "NORMAL";
|
||||
if (current_group_id == id && citer->mSelected)
|
||||
{
|
||||
style = "BOLD";
|
||||
highlight_id = citer->mRoleID;
|
||||
}
|
||||
LLSD element;
|
||||
element["id"] = citer->mRoleID;
|
||||
element["columns"][LIST_TITLE]["column"] = "title";
|
||||
element["columns"][LIST_TITLE]["value"] = citer->mTitle;
|
||||
element["columns"][LIST_TITLE]["font-style"] = style;
|
||||
element["columns"][LIST_GROUP_NAME]["column"] = "group_name";
|
||||
element["columns"][LIST_GROUP_NAME]["value"] = group_datap->mName;
|
||||
element["columns"][LIST_GROUP_NAME]["font-style"] = style;
|
||||
element["columns"][LIST_GROUP_ID]["column"] = "group_id";
|
||||
element["columns"][LIST_GROUP_ID]["value"] = id;
|
||||
|
||||
title_list->addElement(element, ADD_SORTED);
|
||||
}
|
||||
}
|
||||
|
||||
// add "none" to list at top
|
||||
{
|
||||
style = "NORMAL";
|
||||
if (current_group_id.isNull())
|
||||
{
|
||||
style = "BOLD";
|
||||
}
|
||||
LLSD element;
|
||||
element["id"] = LLUUID::null;
|
||||
element["columns"][LIST_TITLE]["column"] = "title";
|
||||
element["columns"][LIST_TITLE]["value"] = "none";
|
||||
element["columns"][LIST_TITLE]["font-style"] = style;
|
||||
element["columns"][LIST_GROUP_NAME]["column"] = "group_name";
|
||||
element["columns"][LIST_GROUP_NAME]["value"] = "none";
|
||||
element["columns"][LIST_GROUP_NAME]["font-style"] = style;
|
||||
element["columns"][LIST_GROUP_ID]["column"] = "group_id";
|
||||
element["columns"][LIST_GROUP_ID]["value"] = LLUUID::null;
|
||||
|
||||
title_list->addElement(element, ADD_TOP);
|
||||
}
|
||||
|
||||
title_list->selectByValue(highlight_id);
|
||||
self->mFirstUse = false;
|
||||
}
|
||||
82
indra/newview/hbfloatergrouptitles.h
Normal file
82
indra/newview/hbfloatergrouptitles.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* @file hbfloatergrouptitles.h
|
||||
* @brief HBFloaterGroupTitles class definition
|
||||
*
|
||||
* This class implements a floater where all available group titles are
|
||||
* listed, allowing the user to activate any via simple double-click.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2010, Henri Beauchamp.
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#ifndef LL_HBFLOATERGROUPTITLES_H
|
||||
#define LL_HBFLOATERGROUPTITLES_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llgroupmgr.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
|
||||
enum TITLES_COLUMN_ORDER
|
||||
{
|
||||
LIST_TITLE,
|
||||
LIST_GROUP_NAME,
|
||||
LIST_GROUP_ID
|
||||
};
|
||||
class HBFloaterGroupTitles;
|
||||
|
||||
class HBFloaterGroupTitlesObserver : public LLGroupMgrObserver
|
||||
{
|
||||
public:
|
||||
HBFloaterGroupTitlesObserver(HBFloaterGroupTitles* instance, const LLUUID& group_id);
|
||||
/* virtual */ ~HBFloaterGroupTitlesObserver();
|
||||
|
||||
/* virtual */ void changed(LLGroupChange gc);
|
||||
|
||||
private:
|
||||
HBFloaterGroupTitles* mFloaterInstance;
|
||||
};
|
||||
|
||||
class HBFloaterGroupTitles : public LLFloater
|
||||
{
|
||||
public:
|
||||
HBFloaterGroupTitles();
|
||||
virtual ~HBFloaterGroupTitles();
|
||||
|
||||
static void toggle();
|
||||
|
||||
BOOL postBuild();
|
||||
|
||||
bool mFirstUse;
|
||||
LLScrollListCtrl* mTitlesList;
|
||||
std::vector<HBFloaterGroupTitlesObserver*> mObservers;
|
||||
|
||||
private:
|
||||
static void onActivate(void* data);
|
||||
|
||||
static HBFloaterGroupTitles* sInstance;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -371,9 +371,7 @@ void LLFloaterAO::addAnimations()
|
||||
std::string none_text = getString("none_text");
|
||||
mAnimListCombo->add(none_text, LLUUID::null);
|
||||
|
||||
// Add all the default (legacy) animations
|
||||
S32 i;
|
||||
|
||||
// Get all inventory items that are animations
|
||||
LLViewerInventoryCategory::cat_array_t cats;
|
||||
LLViewerInventoryItem::item_array_t items;
|
||||
|
||||
@@ -385,13 +385,14 @@ BOOL LLPanelFriends::postBuild()
|
||||
|
||||
childSetAction("im_btn", onClickIM, this);
|
||||
childSetAction("assign_btn", onClickAssign, this);
|
||||
childSetAction("expand_collapse_btn", onClickExpand, this);
|
||||
childSetAction("profile_btn", onClickProfile, this);
|
||||
childSetAction("offer_teleport_btn", onClickOfferTeleport, this);
|
||||
childSetAction("pay_btn", onClickPay, this);
|
||||
childSetAction("add_btn", onClickAddFriend, this);
|
||||
childSetAction("remove_btn", onClickRemove, this);
|
||||
childSetAction("export_btn", onClickExport, this);
|
||||
childSetAction("import_btn", onClickImport, this);
|
||||
//childSetAction("export_btn", onClickExport, this); Making Dummy View -HgB
|
||||
//childSetAction("import_btn", onClickImport, this); Making Dummy View -HgB
|
||||
|
||||
setDefaultBtn("im_btn");
|
||||
|
||||
@@ -402,6 +403,8 @@ BOOL LLPanelFriends::postBuild()
|
||||
mFriendsList->sortByColumn(std::string("friend_name"), TRUE);
|
||||
mFriendsList->sortByColumn(std::string("icon_online_status"), FALSE);
|
||||
|
||||
updateColumns(this);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -551,7 +554,7 @@ void LLPanelFriends::refreshRightsChangeList()
|
||||
bool can_offer_teleport = num_selected >= 1;
|
||||
bool selected_friends_online = true;
|
||||
|
||||
LLTextBox* processing_label = getChild<LLTextBox>("process_rights_label");
|
||||
/*LLTextBox* processing_label = getChild<LLTextBox>("process_rights_label");
|
||||
|
||||
if(!mAllowRightsChange)
|
||||
{
|
||||
@@ -566,7 +569,7 @@ void LLPanelFriends::refreshRightsChangeList()
|
||||
else if(processing_label)
|
||||
{
|
||||
processing_label->setVisible(false);
|
||||
}
|
||||
} Making Dummy View -HgB */
|
||||
const LLRelationship* friend_status = NULL;
|
||||
for(LLDynamicArray<LLUUID>::iterator itr = friends.begin(); itr != friends.end(); ++itr)
|
||||
{
|
||||
@@ -602,7 +605,7 @@ void LLPanelFriends::refreshRightsChangeList()
|
||||
// to be consistent with context menus in inventory and because otherwise
|
||||
// offline friends would be silently dropped from the session
|
||||
childSetEnabled("im_btn", selected_friends_online || num_selected == 1);
|
||||
childSetEnabled("assign_btn", TRUE);
|
||||
childSetEnabled("assign_btn", num_selected == 1);
|
||||
childSetEnabled("offer_teleport_btn", can_offer_teleport);
|
||||
}
|
||||
}
|
||||
@@ -727,29 +730,20 @@ void LLPanelFriends::refreshUI()
|
||||
single_selected = TRUE;
|
||||
if(num_selected > 1)
|
||||
{
|
||||
childSetText("friend_name_label", getString("Multiple"));
|
||||
multiple_selected = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetText("friend_name_label", mFriendsList->getFirstSelected()->getColumn(LIST_FRIEND_NAME)->getValue().asString() + "...");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetText("friend_name_label", LLStringUtil::null);
|
||||
}
|
||||
|
||||
//Options that can only be performed with one friend selected
|
||||
childSetEnabled("profile_btn", single_selected && !multiple_selected);
|
||||
childSetEnabled("pay_btn", single_selected && !multiple_selected);
|
||||
childSetEnabled("assign_btn", single_selected && !multiple_selected);
|
||||
|
||||
//Options that can be performed with up to MAX_FRIEND_SELECT friends selected
|
||||
//(single_selected will always be true in this situations)
|
||||
childSetEnabled("remove_btn", single_selected);
|
||||
childSetEnabled("im_btn", single_selected);
|
||||
childSetEnabled("assign_btn", single_selected);
|
||||
childSetEnabled("friend_rights", single_selected);
|
||||
//childSetEnabled("friend_rights", single_selected); Making Dummy View -HgB
|
||||
|
||||
refreshRightsChangeList();
|
||||
}
|
||||
@@ -814,6 +808,47 @@ void LLPanelFriends::onClickAssign(void* user_data)
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelFriends::onClickExpand(void* user_data)
|
||||
{
|
||||
BOOL collapsed = gSavedSettings.getBOOL("ContactListCollapsed");
|
||||
gSavedSettings.setBOOL("ContactListCollapsed", !collapsed);
|
||||
updateColumns(user_data);
|
||||
}
|
||||
|
||||
void LLPanelFriends::updateColumns(void* user_data)
|
||||
{
|
||||
LLPanelFriends* panelp = (LLPanelFriends*)user_data;
|
||||
if (panelp)
|
||||
{
|
||||
LLButton* expand_button = panelp->getChild<LLButton>("expand_collapse_btn");
|
||||
LLScrollListCtrl* list = panelp->getChild<LLScrollListCtrl>("friend_list");
|
||||
//llinfos << "Refreshing UI" << llendl;
|
||||
S32 width = 22;
|
||||
std::string button = ">";
|
||||
if (gSavedSettings.getBOOL("ContactListCollapsed"))
|
||||
{
|
||||
width = 0;
|
||||
button = "<";
|
||||
}
|
||||
expand_button->setLabel(button);
|
||||
LLScrollListColumn* column = list->getColumn(5);
|
||||
list->updateStaticColumnWidth(column, width);
|
||||
column->setWidth(width);
|
||||
column = list->getColumn(6);
|
||||
list->updateStaticColumnWidth(column, width);
|
||||
column->setWidth(width);
|
||||
column = list->getColumn(7);
|
||||
list->updateStaticColumnWidth(column, width);
|
||||
column->setWidth(width);
|
||||
list->updateLayout();
|
||||
if (!gSavedSettings.getBOOL("ContactListCollapsed"))
|
||||
{
|
||||
panelp->updateFriends(LLFriendObserver::ADD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelFriends::onClickIM(void* user_data)
|
||||
{
|
||||
LLPanelFriends* panelp = (LLPanelFriends*)user_data;
|
||||
|
||||
@@ -138,6 +138,8 @@ private:
|
||||
static void onContactSearchKeystroke(LLLineEditor* caller, void* user_data);
|
||||
static void onClickIM(void* user_data);
|
||||
static void onClickAssign(void* user_data);
|
||||
static void onClickExpand(void* user_data);
|
||||
static void updateColumns(void* user_data);
|
||||
static void onClickProfile(void* user_data);
|
||||
static void onClickAddFriend(void* user_data);
|
||||
static void onClickRemove(void* user_data);
|
||||
|
||||
@@ -40,10 +40,12 @@
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloatergroups.h"
|
||||
#include "llfloatergroupinvite.h"
|
||||
|
||||
#include "message.h"
|
||||
#include "roles_constants.h"
|
||||
|
||||
#include "hbfloatergrouptitles.h"
|
||||
#include "llagent.h"
|
||||
#include "llbutton.h"
|
||||
#include "llfloatergroupinfo.h"
|
||||
@@ -61,7 +63,7 @@
|
||||
std::map<const LLUUID, LLFloaterGroupPicker*> LLFloaterGroupPicker::sInstances;
|
||||
|
||||
// helper functions
|
||||
void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 powers_mask = GP_ALL_POWERS);
|
||||
void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const std::string& none_text, U64 powers_mask = GP_ALL_POWERS);
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLFloaterGroupPicker
|
||||
@@ -116,7 +118,9 @@ void LLFloaterGroupPicker::setPowersMask(U64 powers_mask)
|
||||
|
||||
BOOL LLFloaterGroupPicker::postBuild()
|
||||
{
|
||||
init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID(), mPowersMask);
|
||||
|
||||
const std::string none_text = getString("none");
|
||||
init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID(), none_text, mPowersMask);
|
||||
|
||||
childSetAction("OK", onBtnOK, this);
|
||||
|
||||
@@ -200,7 +204,8 @@ void LLPanelGroups::reset()
|
||||
childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count()));
|
||||
childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS));
|
||||
|
||||
init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID());
|
||||
const std::string none_text = getString("none");
|
||||
init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID(), none_text);
|
||||
enableButtons();
|
||||
}
|
||||
|
||||
@@ -211,7 +216,8 @@ BOOL LLPanelGroups::postBuild()
|
||||
childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count()));
|
||||
childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS));
|
||||
|
||||
init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID());
|
||||
const std::string none_text = getString("none");
|
||||
init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID(), none_text);
|
||||
|
||||
childSetAction("Activate", onBtnActivate, this);
|
||||
|
||||
@@ -224,6 +230,10 @@ BOOL LLPanelGroups::postBuild()
|
||||
childSetAction("Create", onBtnCreate, this);
|
||||
|
||||
childSetAction("Search...", onBtnSearch, this);
|
||||
|
||||
childSetAction("Invite...", onBtnInvite, this);
|
||||
|
||||
childSetAction("Titles...", onBtnTitles, this);
|
||||
|
||||
setDefaultBtn("IM");
|
||||
|
||||
@@ -272,6 +282,14 @@ void LLPanelGroups::enableButtons()
|
||||
{
|
||||
childDisable("Create");
|
||||
}
|
||||
if (group_id.notNull() && gAgent.hasPowerInGroup(group_id, GP_MEMBER_INVITE))
|
||||
{
|
||||
LLPanelGroups::childEnable("Invite...");
|
||||
}
|
||||
else
|
||||
{
|
||||
LLPanelGroups::childDisable("Invite...");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -281,6 +299,12 @@ void LLPanelGroups::onBtnCreate(void* userdata)
|
||||
if(self) self->create();
|
||||
}
|
||||
|
||||
void LLPanelGroups::onBtnInvite(void* userdata)
|
||||
{
|
||||
LLPanelGroups* self = (LLPanelGroups*)userdata;
|
||||
if(self) self->invite();
|
||||
}
|
||||
|
||||
void LLPanelGroups::onBtnActivate(void* userdata)
|
||||
{
|
||||
LLPanelGroups* self = (LLPanelGroups*)userdata;
|
||||
@@ -311,6 +335,12 @@ void LLPanelGroups::onBtnSearch(void* userdata)
|
||||
if(self) self->search();
|
||||
}
|
||||
|
||||
void LLPanelGroups::onBtnTitles(void* userdata)
|
||||
{
|
||||
LLPanelGroups* self = (LLPanelGroups*)userdata;
|
||||
if(self) self->titles();
|
||||
}
|
||||
|
||||
void LLPanelGroups::create()
|
||||
{
|
||||
llinfos << "LLPanelGroups::create" << llendl;
|
||||
@@ -403,6 +433,27 @@ void LLPanelGroups::search()
|
||||
LLFloaterDirectory::showGroups();
|
||||
}
|
||||
|
||||
void LLPanelGroups::invite()
|
||||
{
|
||||
LLCtrlListInterface *group_list = childGetListInterface("group list");
|
||||
LLUUID group_id;
|
||||
|
||||
//if (group_list && (group_id = group_list->getCurrentID()).notNull())
|
||||
|
||||
if (group_list)
|
||||
{
|
||||
group_id = group_list->getCurrentID();
|
||||
}
|
||||
|
||||
LLFloaterGroupInvite::showForGroup(group_id);
|
||||
}
|
||||
|
||||
void LLPanelGroups::titles()
|
||||
{
|
||||
HBFloaterGroupTitles::toggle();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
bool LLPanelGroups::callbackLeaveGroup(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
@@ -428,7 +479,7 @@ void LLPanelGroups::onGroupList(LLUICtrl* ctrl, void* userdata)
|
||||
if(self) self->enableButtons();
|
||||
}
|
||||
|
||||
void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 powers_mask)
|
||||
void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const std::string& none_text, U64 powers_mask)
|
||||
{
|
||||
S32 count = gAgent.mGroups.count();
|
||||
LLUUID id;
|
||||
@@ -470,7 +521,7 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 pow
|
||||
LLSD element;
|
||||
element["id"] = LLUUID::null;
|
||||
element["columns"][0]["column"] = "name";
|
||||
element["columns"][0]["value"] = "none"; // *TODO: Translate
|
||||
element["columns"][0]["value"] = none_text;
|
||||
element["columns"][0]["font"] = "SANSSERIF";
|
||||
element["columns"][0]["font-style"] = style;
|
||||
|
||||
|
||||
@@ -111,6 +111,8 @@ protected:
|
||||
static void onBtnLeave(void* userdata);
|
||||
static void onBtnSearch(void* userdata);
|
||||
static void onBtnVote(void* userdata);
|
||||
static void onBtnInvite(void* userdata);
|
||||
static void onBtnTitles(void* userdata);
|
||||
static void onDoubleClickGroup(void* userdata);
|
||||
|
||||
void create();
|
||||
@@ -120,6 +122,8 @@ protected:
|
||||
void leave();
|
||||
void search();
|
||||
void callVote();
|
||||
void invite();
|
||||
void titles();
|
||||
|
||||
static bool callbackLeaveGroup(const LLSD& notification, const LLSD& response);
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
#include "llviewerjoystick.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
#include "qtoolalign.h" //Thank Qarl!
|
||||
|
||||
// Globals
|
||||
LLFloaterTools *gFloaterTools = NULL;
|
||||
@@ -222,6 +223,8 @@ BOOL LLFloaterTools::postBuild()
|
||||
childSetCommitCallback("radio stretch",commit_select_tool,LLToolCompScale::getInstance());
|
||||
mRadioSelectFace = getChild<LLCheckBoxCtrl>("radio select face");
|
||||
childSetCommitCallback("radio select face",commit_select_tool,LLToolFace::getInstance());
|
||||
mRadioAlign = getChild<LLCheckBoxCtrl>("radio align");
|
||||
childSetCommitCallback("radio align",commit_select_tool,QToolAlign::getInstance());
|
||||
mCheckSelectIndividual = getChild<LLCheckBoxCtrl>("checkbox edit linked parts");
|
||||
childSetValue("checkbox edit linked parts",(BOOL)gSavedSettings.getBOOL("EditLinkedParts"));
|
||||
childSetCommitCallback("checkbox edit linked parts",commit_select_component,this);
|
||||
@@ -332,6 +335,7 @@ BOOL LLFloaterTools::postBuild()
|
||||
mStatusText["rotate"] = getString("status_rotate");
|
||||
mStatusText["scale"] = getString("status_scale");
|
||||
mStatusText["move"] = getString("status_move");
|
||||
mStatusText["align"] = getString("status_align");
|
||||
mStatusText["modifyland"] = getString("status_modifyland");
|
||||
mStatusText["camera"] = getString("status_camera");
|
||||
mStatusText["grab"] = getString("status_grab");
|
||||
@@ -364,6 +368,7 @@ LLFloaterTools::LLFloaterTools()
|
||||
mRadioRotate(NULL),
|
||||
mRadioStretch(NULL),
|
||||
mRadioSelectFace(NULL),
|
||||
mRadioAlign(NULL),
|
||||
mCheckSelectIndividual(NULL),
|
||||
|
||||
mCheckSnapToGrid(NULL),
|
||||
@@ -627,6 +632,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
|
||||
tool == LLToolCompRotate::getInstance() ||
|
||||
tool == LLToolCompScale::getInstance() ||
|
||||
tool == LLToolFace::getInstance() ||
|
||||
tool == QToolAlign::getInstance() ||
|
||||
tool == LLToolIndividual::getInstance() ||
|
||||
tool == LLToolPipette::getInstance();
|
||||
|
||||
@@ -635,6 +641,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
|
||||
mRadioPosition ->setVisible( edit_visible );
|
||||
mRadioRotate ->setVisible( edit_visible );
|
||||
mRadioStretch ->setVisible( edit_visible );
|
||||
mRadioAlign ->setVisible( edit_visible );
|
||||
if (mRadioSelectFace)
|
||||
{
|
||||
mRadioSelectFace->setVisible( edit_visible );
|
||||
@@ -650,6 +657,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
|
||||
mRadioPosition ->set( tool == LLToolCompTranslate::getInstance() );
|
||||
mRadioRotate ->set( tool == LLToolCompRotate::getInstance() );
|
||||
mRadioStretch ->set( tool == LLToolCompScale::getInstance() );
|
||||
mRadioAlign ->set( tool == QToolAlign::getInstance() );
|
||||
|
||||
if (mComboGridMode)
|
||||
{
|
||||
|
||||
@@ -134,6 +134,7 @@ public:
|
||||
LLCheckBoxCtrl *mRadioRotate;
|
||||
LLCheckBoxCtrl *mRadioStretch;
|
||||
LLCheckBoxCtrl *mRadioSelectFace;
|
||||
LLCheckBoxCtrl *mRadioAlign;
|
||||
|
||||
LLCheckBoxCtrl *mCheckSelectIndividual;
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include "llfloaterchat.h"
|
||||
#include "llkeyboard.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llnotify.h"
|
||||
#include "llresmgr.h"
|
||||
#include "lltabcontainer.h"
|
||||
@@ -1283,6 +1284,8 @@ BOOL LLFloaterIMPanel::postBuild()
|
||||
|
||||
if (checkRequirements())
|
||||
{
|
||||
mRPMode = false;
|
||||
|
||||
mInputEditor = getChild<LLLineEditor>("chat_editor");
|
||||
mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this );
|
||||
mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this );
|
||||
@@ -1297,6 +1300,7 @@ BOOL LLFloaterIMPanel::postBuild()
|
||||
childSetAction("profile_tele_btn", onClickTeleport, this);
|
||||
childSetAction("group_info_btn", onClickGroupInfo, this);
|
||||
childSetAction("history_btn", onClickHistory, this);
|
||||
childSetCommitCallback("rp_mode", onRPMode, this);
|
||||
|
||||
childSetAction("start_call_btn", onClickStartCall, this);
|
||||
childSetAction("end_call_btn", onClickEndCall, this);
|
||||
@@ -1796,6 +1800,13 @@ void LLFloaterIMPanel::onClickTeleport( void* userdata )
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterIMPanel::onRPMode(LLUICtrl* source, void* user_data)
|
||||
{
|
||||
LLFloaterIMPanel* self = (LLFloaterIMPanel*) user_data;
|
||||
self->mRPMode = source->getValue().asBoolean();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterIMPanel::onClickHistory( void* userdata )
|
||||
{
|
||||
@@ -2022,7 +2033,7 @@ void LLFloaterIMPanel::sendMsg()
|
||||
if (mInputEditor) mInputEditor->updateHistory();
|
||||
// Truncate and convert to UTF8 for transport
|
||||
std::string utf8text = wstring_to_utf8str(text);
|
||||
if (gSavedSettings.getBOOL("AscentAutoCloseOOC") && (utf8text.length() > 1))
|
||||
if (gSavedSettings.getBOOL("AscentAutoCloseOOC") && (utf8text.length() > 1) && !mRPMode)
|
||||
{
|
||||
// Chalice - OOC autoclosing patch based on code by Henri Beauchamp
|
||||
int needsClosingType=0;
|
||||
@@ -2066,7 +2077,12 @@ void LLFloaterIMPanel::sendMsg()
|
||||
utf8text.replace(0, 1, "/me ");
|
||||
}
|
||||
}
|
||||
|
||||
utf8text = utf8str_truncate(utf8text, MAX_MSG_BUF_SIZE - 1);
|
||||
|
||||
std::string prefix = utf8text.substr(0, 4);
|
||||
if (prefix != "/me " && prefix != "/me'")
|
||||
if (mRPMode) utf8text = "[[" + utf8text + "]]";
|
||||
|
||||
// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-1.0.0g
|
||||
if (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM))
|
||||
|
||||
@@ -215,6 +215,7 @@ public:
|
||||
void selectAll();
|
||||
void selectNone();
|
||||
void setVisible(BOOL b);
|
||||
BOOL mRPMode;
|
||||
|
||||
S32 getNumUnreadMessages() { return mNumUnreadMessages; }
|
||||
|
||||
@@ -232,6 +233,7 @@ public:
|
||||
|
||||
static void onClickProfile( void* userdata );
|
||||
static void onClickHistory( void* userdata );
|
||||
static void onRPMode(LLUICtrl* source, void* user_data);
|
||||
static void onClickTeleport( void* userdata );
|
||||
static void onClickGroupInfo( void* userdata );
|
||||
static void onClickClose( void* userdata );
|
||||
|
||||
@@ -4072,7 +4072,6 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
|
||||
|
||||
|
||||
|
||||
//if( !isInTrash() )
|
||||
if( !isInTrash() && !(LLXmlImport::sImportInProgress && LLXmlImport::sImportHasAttachments))
|
||||
// </edit>
|
||||
@@ -5716,3 +5715,144 @@ void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,
|
||||
delete item_id;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
// +=================================================+
|
||||
// | LLLinkItemBridge |
|
||||
// +=================================================+
|
||||
// For broken links
|
||||
|
||||
std::string LLLinkItemBridge::sPrefix("Link: ");
|
||||
|
||||
|
||||
LLUIImagePtr LLLinkItemBridge::getIcon() const
|
||||
{
|
||||
if (LLViewerInventoryItem *item = getItem())
|
||||
{
|
||||
U32 attachment_point = (item->getFlags() & 0xff); // low byte of inventory flags
|
||||
bool is_multi = LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS & item->getFlags();
|
||||
|
||||
return get_item_icon(item->getActualType(), item->getInventoryType(), attachment_point, is_multi);
|
||||
}
|
||||
return get_item_icon(LLAssetType::AT_LINK, LLInventoryType::IT_NONE, 0, FALSE);
|
||||
}
|
||||
|
||||
void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
{
|
||||
// *TODO: Translate
|
||||
lldebugs << "LLLink::buildContextMenu()" << llendl;
|
||||
std::vector<std::string> items;
|
||||
std::vector<std::string> disabled_items;
|
||||
|
||||
items.push_back(std::string("Find Original"));
|
||||
disabled_items.push_back(std::string("Find Original"));
|
||||
|
||||
if (isInTrash())
|
||||
{
|
||||
disabled_items.push_back(std::string("Find Original"));
|
||||
if (isLinkedObjectMissing())
|
||||
{
|
||||
disabled_items.push_back(std::string("Find Original"));
|
||||
}
|
||||
items.push_back(std::string("Purge Item"));
|
||||
items.push_back(std::string("Restore Item"));
|
||||
}
|
||||
else
|
||||
{
|
||||
items.push_back(std::string("Properties"));
|
||||
items.push_back(std::string("Find Original"));
|
||||
if (isLinkedObjectMissing())
|
||||
{
|
||||
disabled_items.push_back(std::string("Find Original"));
|
||||
}
|
||||
items.push_back(std::string("Delete"));
|
||||
}
|
||||
hideContextEntries(menu, items, disabled_items);
|
||||
}
|
||||
|
||||
|
||||
// +=================================================+
|
||||
// | LLLinkBridge |
|
||||
// +=================================================+
|
||||
// For broken links.
|
||||
|
||||
std::string LLLinkFolderBridge::sPrefix("Link: ");
|
||||
|
||||
|
||||
LLUIImagePtr LLLinkFolderBridge::getIcon() const
|
||||
{
|
||||
return LLUI::getUIImage("inv_link_folder.tga");
|
||||
}
|
||||
|
||||
void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
{
|
||||
// *TODO: Translate
|
||||
lldebugs << "LLLink::buildContextMenu()" << llendl;
|
||||
std::vector<std::string> items;
|
||||
std::vector<std::string> disabled_items;
|
||||
|
||||
if (isInTrash())
|
||||
{
|
||||
items.push_back(std::string("Find Original"));
|
||||
if (isLinkedObjectMissing())
|
||||
{
|
||||
disabled_items.push_back(std::string("Find Original"));
|
||||
}
|
||||
items.push_back(std::string("Purge Item"));
|
||||
items.push_back(std::string("Restore Item"));
|
||||
}
|
||||
else
|
||||
{
|
||||
items.push_back(std::string("Find Original"));
|
||||
if (isLinkedObjectMissing())
|
||||
{
|
||||
disabled_items.push_back(std::string("Find Original"));
|
||||
}
|
||||
items.push_back(std::string("Delete"));
|
||||
}
|
||||
hideContextEntries(menu, items, disabled_items);
|
||||
}
|
||||
|
||||
void LLLinkFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
|
||||
{
|
||||
if ("goto" == action)
|
||||
{
|
||||
gotoItem(folder);
|
||||
return;
|
||||
}
|
||||
LLItemBridge::performAction(folder,model,action);
|
||||
}
|
||||
|
||||
void LLLinkFolderBridge::gotoItem(LLFolderView *folder)
|
||||
{
|
||||
const LLUUID &cat_uuid = getFolderID();
|
||||
if (!cat_uuid.isNull())
|
||||
{
|
||||
if (LLFolderViewItem *base_folder = folder->getItemByID(cat_uuid))
|
||||
{
|
||||
if (LLInventoryModel* model = mInventoryPanel->getModel())
|
||||
{
|
||||
model->fetchDescendentsOf(cat_uuid);
|
||||
}
|
||||
base_folder->setOpen(TRUE);
|
||||
folder->setSelectionFromRoot(base_folder,TRUE);
|
||||
folder->scrollToShowSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const LLUUID &LLLinkFolderBridge::getFolderID() const
|
||||
{
|
||||
if (LLViewerInventoryItem *link_item = getItem())
|
||||
{
|
||||
if (const LLViewerInventoryCategory *cat = link_item->getLinkedCategory())
|
||||
{
|
||||
const LLUUID& cat_uuid = cat->getUUID();
|
||||
return cat_uuid;
|
||||
}
|
||||
}
|
||||
return LLUUID::null;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@@ -44,10 +44,10 @@
|
||||
#include "lllineeditor.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lluictrlfactory.h"
|
||||
// <edit>
|
||||
#include "llviewerwindow.h" // for alert
|
||||
#include "llappviewer.h" // gStaticVFS
|
||||
// </edit>
|
||||
// <edit>
|
||||
#include "llviewerwindow.h" // for alert
|
||||
#include "llappviewer.h" // gStaticVFS
|
||||
// </edit>
|
||||
|
||||
extern LLAgent gAgent;
|
||||
|
||||
@@ -58,9 +58,6 @@ LLPreviewAnim::LLPreviewAnim(const std::string& name, const LLRect& rect, const
|
||||
|
||||
childSetAction("Anim play btn",playAnim,this);
|
||||
childSetAction("Anim audition btn",auditionAnim,this);
|
||||
// <edit>
|
||||
childSetAction("Anim copy uuid btn", copyAnimID, this);
|
||||
// </edit>
|
||||
|
||||
const LLInventoryItem* item = getItem();
|
||||
|
||||
@@ -188,240 +185,240 @@ void LLPreviewAnim::auditionAnim( void *userdata )
|
||||
}
|
||||
}
|
||||
|
||||
// <edit>
|
||||
// static
|
||||
/*
|
||||
void LLPreviewAnim::copyAnim(void *userdata)
|
||||
{
|
||||
LLPreviewAnim* self = (LLPreviewAnim*) userdata;
|
||||
const LLInventoryItem *item = self->getItem();
|
||||
|
||||
if(item)
|
||||
{
|
||||
// Some animations aren't hosted on the servers
|
||||
// I guess they're in this static vfs thing
|
||||
bool static_vfile = false;
|
||||
LLVFile* anim_file = new LLVFile(gStaticVFS, item->getAssetUUID(), LLAssetType::AT_ANIMATION);
|
||||
if (anim_file && anim_file->getSize())
|
||||
{
|
||||
//S32 anim_file_size = anim_file->getSize();
|
||||
//U8* anim_data = new U8[anim_file_size];
|
||||
//if(anim_file->read(anim_data, anim_file_size))
|
||||
//{
|
||||
// static_vfile = true;
|
||||
//}
|
||||
static_vfile = true; // for method 2
|
||||
LLPreviewAnim::gotAssetForCopy(gStaticVFS, item->getAssetUUID(), LLAssetType::AT_ANIMATION, self, 0, 0);
|
||||
}
|
||||
delete anim_file;
|
||||
anim_file = NULL;
|
||||
|
||||
if(!static_vfile)
|
||||
{
|
||||
// Get it from the servers
|
||||
gAssetStorage->getAssetData(item->getAssetUUID(), LLAssetType::AT_ANIMATION, LLPreviewAnim::gotAssetForCopy, self, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LLSaveInfo
|
||||
{
|
||||
LLSaveInfo(const LLUUID& item_id, const LLUUID& object_id, const std::string& desc,
|
||||
const LLTransactionID tid)
|
||||
: mItemUUID(item_id), mObjectUUID(object_id), mDesc(desc), mTransactionID(tid)
|
||||
{
|
||||
}
|
||||
|
||||
LLUUID mItemUUID;
|
||||
LLUUID mObjectUUID;
|
||||
std::string mDesc;
|
||||
LLTransactionID mTransactionID;
|
||||
};
|
||||
|
||||
// static
|
||||
void LLPreviewAnim::gotAssetForCopy(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLPreviewAnim* self = (LLPreviewAnim*) user_data;
|
||||
//const LLInventoryItem *item = self->getItem();
|
||||
|
||||
LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
|
||||
S32 size = file.getSize();
|
||||
|
||||
char* buffer = new char[size];
|
||||
if (buffer == NULL)
|
||||
{
|
||||
llerrs << "Memory Allocation Failed" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
file.read((U8*)buffer, size);
|
||||
|
||||
// Write it back out...
|
||||
|
||||
LLTransactionID tid;
|
||||
LLAssetID asset_id;
|
||||
tid.generate();
|
||||
asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
|
||||
|
||||
LLVFile ofile(gVFS, asset_id, LLAssetType::AT_ANIMATION, LLVFile::APPEND);
|
||||
|
||||
ofile.setMaxSize(size);
|
||||
ofile.write((U8*)buffer, size);
|
||||
|
||||
// Upload that asset to the database
|
||||
LLSaveInfo* info = new LLSaveInfo(self->mItemUUID, self->mObjectUUID, "animation", tid);
|
||||
gAssetStorage->storeAssetData(tid, LLAssetType::AT_ANIMATION, onSaveCopyComplete, info, FALSE);
|
||||
|
||||
delete[] buffer;
|
||||
buffer = NULL;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPreviewAnim::onSaveCopyComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLSaveInfo* info = (LLSaveInfo*)user_data;
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
std::string item_name = "New Animation";
|
||||
std::string item_desc = "";
|
||||
// Saving into user inventory
|
||||
LLViewerInventoryItem* item;
|
||||
item = (LLViewerInventoryItem*)gInventory.getItem(info->mItemUUID);
|
||||
if(item)
|
||||
{
|
||||
item_name = item->getName();
|
||||
item_desc = item->getDescription();
|
||||
}
|
||||
gMessageSystem->newMessageFast(_PREHASH_CreateInventoryItem);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
gMessageSystem->nextBlockFast(_PREHASH_InventoryBlock);
|
||||
gMessageSystem->addU32Fast(_PREHASH_CallbackID, 0);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_FolderID, LLUUID::null);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_TransactionID, info->mTransactionID);
|
||||
gMessageSystem->addU32Fast(_PREHASH_NextOwnerMask, 2147483647);
|
||||
gMessageSystem->addS8Fast(_PREHASH_Type, LLAssetType::AT_ANIMATION);
|
||||
gMessageSystem->addS8Fast(_PREHASH_InvType, LLInventoryType::IT_ANIMATION);
|
||||
gMessageSystem->addU8Fast(_PREHASH_WearableType, 0);
|
||||
gMessageSystem->addStringFast(_PREHASH_Name, item_name);
|
||||
gMessageSystem->addStringFast(_PREHASH_Description, item_desc);
|
||||
gMessageSystem->sendReliable(gAgent.getRegionHost());
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Problem saving animation: " << status << llendl;
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
gViewerWindow->alertXml("CannotUploadReason",args);
|
||||
}
|
||||
}
|
||||
*/
|
||||
void LLPreviewAnim::copyAnimID(void *userdata)
|
||||
{
|
||||
LLPreviewAnim* self = (LLPreviewAnim*) userdata;
|
||||
const LLInventoryItem *item = self->getItem();
|
||||
|
||||
if(item)
|
||||
{
|
||||
gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(item->getAssetUUID().asString()));
|
||||
}
|
||||
}
|
||||
// </edit>
|
||||
|
||||
// <edit>
|
||||
// virtual
|
||||
BOOL LLPreviewAnim::canSaveAs() const
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPreviewAnim::saveAs()
|
||||
{
|
||||
const LLInventoryItem *item = getItem();
|
||||
|
||||
if(item)
|
||||
{
|
||||
// Some animations aren't hosted on the servers
|
||||
// I guess they're in this static vfs thing
|
||||
bool static_vfile = false;
|
||||
LLVFile* anim_file = new LLVFile(gStaticVFS, item->getAssetUUID(), LLAssetType::AT_ANIMATION);
|
||||
if (anim_file && anim_file->getSize())
|
||||
{
|
||||
//S32 anim_file_size = anim_file->getSize();
|
||||
//U8* anim_data = new U8[anim_file_size];
|
||||
//if(anim_file->read(anim_data, anim_file_size))
|
||||
//{
|
||||
// static_vfile = true;
|
||||
//}
|
||||
static_vfile = true; // for method 2
|
||||
LLPreviewAnim::gotAssetForSave(gStaticVFS, item->getAssetUUID(), LLAssetType::AT_ANIMATION, this, 0, 0);
|
||||
}
|
||||
delete anim_file;
|
||||
anim_file = NULL;
|
||||
|
||||
if(!static_vfile)
|
||||
{
|
||||
gAssetStorage->getAssetData(item->getAssetUUID(), LLAssetType::AT_ANIMATION, LLPreviewAnim::gotAssetForSave, this, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPreviewAnim::gotAssetForSave(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLPreviewAnim* self = (LLPreviewAnim*) user_data;
|
||||
//const LLInventoryItem *item = self->getItem();
|
||||
|
||||
LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
|
||||
S32 size = file.getSize();
|
||||
|
||||
char* buffer = new char[size];
|
||||
if (buffer == NULL)
|
||||
{
|
||||
llerrs << "Memory Allocation Failed" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
file.read((U8*)buffer, size);
|
||||
|
||||
// Write it back out...
|
||||
|
||||
LLFilePicker& file_picker = LLFilePicker::instance();
|
||||
if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_ANIMATN, LLDir::getScrubbedFileName(self->getItem()->getName())) )
|
||||
{
|
||||
// User canceled or we failed to acquire save file.
|
||||
return;
|
||||
}
|
||||
// remember the user-approved/edited file name.
|
||||
std::string filename = file_picker.getFirstFile();
|
||||
|
||||
std::ofstream export_file(filename.c_str(), std::ofstream::binary);
|
||||
export_file.write(buffer, size);
|
||||
export_file.close();
|
||||
|
||||
delete[] buffer;
|
||||
buffer = NULL;
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLUUID LLPreviewAnim::getItemID()
|
||||
{
|
||||
const LLViewerInventoryItem* item = getItem();
|
||||
if(item)
|
||||
{
|
||||
return item->getUUID();
|
||||
}
|
||||
return LLUUID::null;
|
||||
}
|
||||
// <edit>
|
||||
// static
|
||||
/*
|
||||
void LLPreviewAnim::copyAnim(void *userdata)
|
||||
{
|
||||
LLPreviewAnim* self = (LLPreviewAnim*) userdata;
|
||||
const LLInventoryItem *item = self->getItem();
|
||||
|
||||
if(item)
|
||||
{
|
||||
// Some animations aren't hosted on the servers
|
||||
// I guess they're in this static vfs thing
|
||||
bool static_vfile = false;
|
||||
LLVFile* anim_file = new LLVFile(gStaticVFS, item->getAssetUUID(), LLAssetType::AT_ANIMATION);
|
||||
if (anim_file && anim_file->getSize())
|
||||
{
|
||||
//S32 anim_file_size = anim_file->getSize();
|
||||
//U8* anim_data = new U8[anim_file_size];
|
||||
//if(anim_file->read(anim_data, anim_file_size))
|
||||
//{
|
||||
// static_vfile = true;
|
||||
//}
|
||||
static_vfile = true; // for method 2
|
||||
LLPreviewAnim::gotAssetForCopy(gStaticVFS, item->getAssetUUID(), LLAssetType::AT_ANIMATION, self, 0, 0);
|
||||
}
|
||||
delete anim_file;
|
||||
anim_file = NULL;
|
||||
|
||||
if(!static_vfile)
|
||||
{
|
||||
// Get it from the servers
|
||||
gAssetStorage->getAssetData(item->getAssetUUID(), LLAssetType::AT_ANIMATION, LLPreviewAnim::gotAssetForCopy, self, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LLSaveInfo
|
||||
{
|
||||
LLSaveInfo(const LLUUID& item_id, const LLUUID& object_id, const std::string& desc,
|
||||
const LLTransactionID tid)
|
||||
: mItemUUID(item_id), mObjectUUID(object_id), mDesc(desc), mTransactionID(tid)
|
||||
{
|
||||
}
|
||||
|
||||
LLUUID mItemUUID;
|
||||
LLUUID mObjectUUID;
|
||||
std::string mDesc;
|
||||
LLTransactionID mTransactionID;
|
||||
};
|
||||
|
||||
// static
|
||||
void LLPreviewAnim::gotAssetForCopy(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLPreviewAnim* self = (LLPreviewAnim*) user_data;
|
||||
//const LLInventoryItem *item = self->getItem();
|
||||
|
||||
LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
|
||||
S32 size = file.getSize();
|
||||
|
||||
char* buffer = new char[size];
|
||||
if (buffer == NULL)
|
||||
{
|
||||
llerrs << "Memory Allocation Failed" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
file.read((U8*)buffer, size);
|
||||
|
||||
// Write it back out...
|
||||
|
||||
LLTransactionID tid;
|
||||
LLAssetID asset_id;
|
||||
tid.generate();
|
||||
asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
|
||||
|
||||
LLVFile ofile(gVFS, asset_id, LLAssetType::AT_ANIMATION, LLVFile::APPEND);
|
||||
|
||||
ofile.setMaxSize(size);
|
||||
ofile.write((U8*)buffer, size);
|
||||
|
||||
// Upload that asset to the database
|
||||
LLSaveInfo* info = new LLSaveInfo(self->mItemUUID, self->mObjectUUID, "animation", tid);
|
||||
gAssetStorage->storeAssetData(tid, LLAssetType::AT_ANIMATION, onSaveCopyComplete, info, FALSE);
|
||||
|
||||
delete[] buffer;
|
||||
buffer = NULL;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPreviewAnim::onSaveCopyComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLSaveInfo* info = (LLSaveInfo*)user_data;
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
std::string item_name = "New Animation";
|
||||
std::string item_desc = "";
|
||||
// Saving into user inventory
|
||||
LLViewerInventoryItem* item;
|
||||
item = (LLViewerInventoryItem*)gInventory.getItem(info->mItemUUID);
|
||||
if(item)
|
||||
{
|
||||
item_name = item->getName();
|
||||
item_desc = item->getDescription();
|
||||
}
|
||||
gMessageSystem->newMessageFast(_PREHASH_CreateInventoryItem);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
gMessageSystem->nextBlockFast(_PREHASH_InventoryBlock);
|
||||
gMessageSystem->addU32Fast(_PREHASH_CallbackID, 0);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_FolderID, LLUUID::null);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_TransactionID, info->mTransactionID);
|
||||
gMessageSystem->addU32Fast(_PREHASH_NextOwnerMask, 2147483647);
|
||||
gMessageSystem->addS8Fast(_PREHASH_Type, LLAssetType::AT_ANIMATION);
|
||||
gMessageSystem->addS8Fast(_PREHASH_InvType, LLInventoryType::IT_ANIMATION);
|
||||
gMessageSystem->addU8Fast(_PREHASH_WearableType, 0);
|
||||
gMessageSystem->addStringFast(_PREHASH_Name, item_name);
|
||||
gMessageSystem->addStringFast(_PREHASH_Description, item_desc);
|
||||
gMessageSystem->sendReliable(gAgent.getRegionHost());
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Problem saving animation: " << status << llendl;
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
gViewerWindow->alertXml("CannotUploadReason",args);
|
||||
}
|
||||
}
|
||||
*/
|
||||
void LLPreviewAnim::copyAnimID(void *userdata)
|
||||
{
|
||||
LLPreviewAnim* self = (LLPreviewAnim*) userdata;
|
||||
const LLInventoryItem *item = self->getItem();
|
||||
|
||||
if(item)
|
||||
{
|
||||
gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(item->getAssetUUID().asString()));
|
||||
}
|
||||
}
|
||||
// </edit>
|
||||
|
||||
// <edit>
|
||||
// virtual
|
||||
BOOL LLPreviewAnim::canSaveAs() const
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPreviewAnim::saveAs()
|
||||
{
|
||||
const LLInventoryItem *item = getItem();
|
||||
|
||||
if(item)
|
||||
{
|
||||
// Some animations aren't hosted on the servers
|
||||
// I guess they're in this static vfs thing
|
||||
bool static_vfile = false;
|
||||
LLVFile* anim_file = new LLVFile(gStaticVFS, item->getAssetUUID(), LLAssetType::AT_ANIMATION);
|
||||
if (anim_file && anim_file->getSize())
|
||||
{
|
||||
//S32 anim_file_size = anim_file->getSize();
|
||||
//U8* anim_data = new U8[anim_file_size];
|
||||
//if(anim_file->read(anim_data, anim_file_size))
|
||||
//{
|
||||
// static_vfile = true;
|
||||
//}
|
||||
static_vfile = true; // for method 2
|
||||
LLPreviewAnim::gotAssetForSave(gStaticVFS, item->getAssetUUID(), LLAssetType::AT_ANIMATION, this, 0, 0);
|
||||
}
|
||||
delete anim_file;
|
||||
anim_file = NULL;
|
||||
|
||||
if(!static_vfile)
|
||||
{
|
||||
gAssetStorage->getAssetData(item->getAssetUUID(), LLAssetType::AT_ANIMATION, LLPreviewAnim::gotAssetForSave, this, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPreviewAnim::gotAssetForSave(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLPreviewAnim* self = (LLPreviewAnim*) user_data;
|
||||
//const LLInventoryItem *item = self->getItem();
|
||||
|
||||
LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
|
||||
S32 size = file.getSize();
|
||||
|
||||
char* buffer = new char[size];
|
||||
if (buffer == NULL)
|
||||
{
|
||||
llerrs << "Memory Allocation Failed" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
file.read((U8*)buffer, size);
|
||||
|
||||
// Write it back out...
|
||||
|
||||
LLFilePicker& file_picker = LLFilePicker::instance();
|
||||
if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_ANIMATN, LLDir::getScrubbedFileName(self->getItem()->getName())) )
|
||||
{
|
||||
// User canceled or we failed to acquire save file.
|
||||
return;
|
||||
}
|
||||
// remember the user-approved/edited file name.
|
||||
std::string filename = file_picker.getFirstFile();
|
||||
|
||||
std::ofstream export_file(filename.c_str(), std::ofstream::binary);
|
||||
export_file.write(buffer, size);
|
||||
export_file.close();
|
||||
|
||||
delete[] buffer;
|
||||
buffer = NULL;
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLUUID LLPreviewAnim::getItemID()
|
||||
{
|
||||
const LLViewerInventoryItem* item = getItem();
|
||||
if(item)
|
||||
{
|
||||
return item->getUUID();
|
||||
}
|
||||
return LLUUID::null;
|
||||
}
|
||||
// </edit>
|
||||
|
||||
void LLPreviewAnim::onClose(bool app_quitting)
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "llviewerwindow.h"
|
||||
#include "llagent.h"
|
||||
#include "llfloatertools.h"
|
||||
#include "qtoolalign.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
const S32 BUTTON_HEIGHT = 16;
|
||||
@@ -278,13 +279,20 @@ BOOL LLToolCompTranslate::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
|
||||
LLTool* LLToolCompTranslate::getOverrideTool(MASK mask)
|
||||
{
|
||||
if (mask == MASK_CONTROL)
|
||||
if (gKeyboard->getKeyDown('A') && mask & MASK_CONTROL)
|
||||
{
|
||||
return LLToolCompRotate::getInstance();
|
||||
return QToolAlign::getInstance();
|
||||
}
|
||||
else if (mask == (MASK_CONTROL | MASK_SHIFT))
|
||||
else
|
||||
{
|
||||
return LLToolCompScale::getInstance();
|
||||
if (mask == MASK_CONTROL)
|
||||
{
|
||||
return LLToolCompRotate::getInstance();
|
||||
}
|
||||
else if (mask == (MASK_CONTROL | MASK_SHIFT))
|
||||
{
|
||||
return LLToolCompScale::getInstance();
|
||||
}
|
||||
}
|
||||
return LLToolComposite::getOverrideTool(mask);
|
||||
}
|
||||
@@ -397,11 +405,14 @@ BOOL LLToolCompScale::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
|
||||
LLTool* LLToolCompScale::getOverrideTool(MASK mask)
|
||||
{
|
||||
if (mask == MASK_CONTROL)
|
||||
if (gKeyboard->getKeyDown('A') && mask & MASK_CONTROL)
|
||||
{
|
||||
return QToolAlign::getInstance();
|
||||
}
|
||||
else if (mask == MASK_CONTROL)
|
||||
{
|
||||
return LLToolCompRotate::getInstance();
|
||||
}
|
||||
|
||||
return LLToolComposite::getOverrideTool(mask);
|
||||
}
|
||||
|
||||
@@ -597,7 +608,11 @@ BOOL LLToolCompRotate::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
|
||||
LLTool* LLToolCompRotate::getOverrideTool(MASK mask)
|
||||
{
|
||||
if (mask == (MASK_CONTROL | MASK_SHIFT))
|
||||
if (gKeyboard->getKeyDown('A') && mask & MASK_CONTROL)
|
||||
{
|
||||
return QToolAlign::getInstance();
|
||||
}
|
||||
else if (mask == (MASK_CONTROL | MASK_SHIFT))
|
||||
{
|
||||
return LLToolCompScale::getInstance();
|
||||
}
|
||||
|
||||
@@ -5740,16 +5740,40 @@ BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset)
|
||||
{
|
||||
gAgent.sendAnimationRequest(LLAO::mLastAnimation, ANIM_REQUEST_STOP);
|
||||
stopMotion(LLAO::mLastAnimation, true);
|
||||
llinfos << "Stopping old animation." << llendl;
|
||||
}
|
||||
LLAO::mAnimationIndex++;
|
||||
if (LLAO::mAnimationOverrides[ao_id].size() <= LLAO::mAnimationIndex)
|
||||
std::string anim_name;
|
||||
LLUUID new_anim = LLUUID::null;
|
||||
|
||||
while (new_anim.isNull())
|
||||
{
|
||||
LLAO::mAnimationIndex = 0;
|
||||
LLAO::mAnimationIndex++;
|
||||
if (LLAO::mAnimationOverrides[ao_id].size() <= LLAO::mAnimationIndex)
|
||||
{
|
||||
LLAO::mAnimationIndex = 0;
|
||||
}
|
||||
anim_name = static_cast<const std::string&> (LLAO::mAnimationOverrides[ao_id][LLAO::mAnimationIndex]);
|
||||
new_anim = LLAO::getAssetIDByName(anim_name);
|
||||
|
||||
if (new_anim.isNull())
|
||||
{
|
||||
LLChat chat;
|
||||
chat.mSourceType = CHAT_SOURCE_SYSTEM;
|
||||
chat.mText = llformat("Could not find animation %s, skipping and moving to next.", anim_name.c_str());
|
||||
LLFloaterChat::addChat(chat);
|
||||
}
|
||||
}
|
||||
LLUUID new_anim = LLAO::getAssetIDByName(LLAO::mAnimationOverrides[ao_id][LLAO::mAnimationIndex]);
|
||||
llinfos << "Switching to anim #" << LLAO::mAnimationIndex << ": " << LLAO::mAnimationOverrides[ao_id][LLAO::mAnimationIndex] << llendl;
|
||||
llinfos << "Switching to anim #" << LLAO::mAnimationIndex << ": " << anim_name << "(UUID " << new_anim << ")" << llendl;
|
||||
gAgent.sendAnimationRequest(new_anim, ANIM_REQUEST_START);
|
||||
startMotion(new_anim, time_offset);
|
||||
|
||||
//LLMotion* motion = findMotion(new_anim);
|
||||
|
||||
/*if (motion)
|
||||
{
|
||||
motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLHandle<LLFloater>(self->getHandle())));
|
||||
}*/
|
||||
|
||||
LLAO::mLastAnimation = new_anim;
|
||||
}
|
||||
/*if(LLAO::mOverrides.find(id) != LLAO::mOverrides.end())
|
||||
@@ -5858,8 +5882,9 @@ BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate)
|
||||
}
|
||||
else //if this code ever works without crashing the viewer -HgB
|
||||
{
|
||||
if (LLAO::mLastAnimation != LLUUID::null)
|
||||
if (!LLAO::mLastAnimation.isNull())
|
||||
{
|
||||
llinfos << "Stopped last animation automatically. May not have needed to be stopped yet." << llendl;
|
||||
gAgent.sendAnimationRequest(LLAO::mLastAnimation, ANIM_REQUEST_STOP);
|
||||
LLAO::mLastAnimation = LLUUID::null;
|
||||
}
|
||||
|
||||
629
indra/newview/qtoolalign.cpp
Normal file
629
indra/newview/qtoolalign.cpp
Normal file
@@ -0,0 +1,629 @@
|
||||
/**
|
||||
* @file lltoolface.cpp
|
||||
* @brief A tool to align objects
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
// File includes
|
||||
#include "qtoolalign.h"
|
||||
|
||||
// Library includes
|
||||
#include "llbbox.h"
|
||||
#include "v3math.h"
|
||||
|
||||
// Viewer includes
|
||||
#include "llagent.h"
|
||||
#include "llbox.h"
|
||||
#include "llcylinder.h"
|
||||
#include "llfloatertools.h"
|
||||
#include "llmanip.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "lltoolcomp.h"
|
||||
#include "llviewercamera.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llviewerwindow.h"
|
||||
|
||||
|
||||
const F32 MANIPULATOR_SIZE = 5.0;
|
||||
const F32 MANIPULATOR_SELECT_SIZE = 20.0;
|
||||
|
||||
|
||||
|
||||
QToolAlign::QToolAlign()
|
||||
: LLToolComposite(std::string("Align"))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QToolAlign::~QToolAlign()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL QToolAlign::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if (mHighlightedAxis != -1)
|
||||
{
|
||||
align();
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->pickAsync(x, y, mask, pickCallback);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL QToolAlign::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
// first, perform normal processing in case this was a quick-click
|
||||
handleHover(x, y, mask);
|
||||
LLSelectMgr::getInstance()->updateSelectionCenter();
|
||||
BOOL handled = FALSE;
|
||||
if( hasMouseCapture() )
|
||||
{
|
||||
handled = TRUE;
|
||||
setMouseCapture( FALSE );
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
BOOL QToolAlign::handleDoubleClick(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LLTool* QToolAlign::getOverrideTool(MASK mask)
|
||||
{
|
||||
if (!gKeyboard->getKeyDown('A'))
|
||||
{
|
||||
if (mask == MASK_CONTROL)
|
||||
{
|
||||
return LLToolCompRotate::getInstance();
|
||||
}
|
||||
else if (mask == (MASK_CONTROL | MASK_SHIFT))
|
||||
{
|
||||
return LLToolCompScale::getInstance();
|
||||
}
|
||||
}
|
||||
return LLToolComposite::getOverrideTool(mask);
|
||||
}
|
||||
|
||||
void QToolAlign::pickCallback(const LLPickInfo& pick_info)
|
||||
{
|
||||
LLViewerObject* object = pick_info.getObject();
|
||||
|
||||
if (object)
|
||||
{
|
||||
if (object->isAvatar())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (pick_info.mKeyMask & MASK_SHIFT)
|
||||
{
|
||||
// If object not selected, select it
|
||||
if ( !object->isSelected() )
|
||||
{
|
||||
LLSelectMgr::getInstance()->selectObjectAndFamily(object);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSelectMgr::getInstance()->deselectObjectAndFamily(object);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSelectMgr::getInstance()->deselectAll();
|
||||
LLSelectMgr::getInstance()->selectObjectAndFamily(object);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(pick_info.mKeyMask == MASK_SHIFT))
|
||||
{
|
||||
LLSelectMgr::getInstance()->deselectAll();
|
||||
}
|
||||
}
|
||||
|
||||
LLSelectMgr::getInstance()->promoteSelectionToRoot();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void QToolAlign::handleSelect()
|
||||
{
|
||||
// no parts, please
|
||||
|
||||
//llwarns << "in select" << llendl;
|
||||
LLSelectMgr::getInstance()->promoteSelectionToRoot();
|
||||
LLSelectMgr::getInstance()->updateSelectionCenter();
|
||||
gFloaterTools->setStatusText("align");
|
||||
}
|
||||
|
||||
|
||||
void QToolAlign::handleDeselect()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL QToolAlign::findSelectedManipulator(S32 x, S32 y)
|
||||
{
|
||||
mHighlightedAxis = -1;
|
||||
mHighlightedDirection = 0;
|
||||
|
||||
LLMatrix4 transform;
|
||||
if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD)
|
||||
{
|
||||
LLVector4 translation(mBBox.getCenterAgent());
|
||||
transform.initRotTrans(mBBox.getRotation(), translation);
|
||||
LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
|
||||
transform *= cfr;
|
||||
LLMatrix4 window_scale;
|
||||
F32 zoom_level = 2.f * gAgent.mHUDCurZoom;
|
||||
window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstance()->getAspect(), zoom_level, 0.f),
|
||||
LLQuaternion::DEFAULT,
|
||||
LLVector3::zero);
|
||||
transform *= window_scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
transform.initAll(LLVector3(1.f, 1.f, 1.f), mBBox.getRotation(), mBBox.getCenterAgent());
|
||||
|
||||
LLMatrix4 projection_matrix = LLViewerCamera::getInstance()->getProjection();
|
||||
LLMatrix4 model_matrix = LLViewerCamera::getInstance()->getModelview();
|
||||
|
||||
transform *= model_matrix;
|
||||
transform *= projection_matrix;
|
||||
}
|
||||
|
||||
|
||||
F32 half_width = (F32)gViewerWindow->getWindowWidth() / 2.f;
|
||||
F32 half_height = (F32)gViewerWindow->getWindowHeight() / 2.f;
|
||||
LLVector2 manip2d;
|
||||
LLVector2 mousePos((F32)x - half_width, (F32)y - half_height);
|
||||
LLVector2 delta;
|
||||
|
||||
LLVector3 bbox_scale = mBBox.getMaxLocal() - mBBox.getMinLocal();
|
||||
|
||||
for (S32 axis = VX; axis <= VZ; axis++)
|
||||
{
|
||||
for (F32 direction = -1.0; direction <= 1.0; direction += 2.0)
|
||||
{
|
||||
LLVector3 axis_vector = LLVector3(0,0,0);
|
||||
axis_vector.mV[axis] = direction * bbox_scale.mV[axis] / 2.0;
|
||||
|
||||
LLVector4 manipulator_center = LLVector4(axis_vector);
|
||||
|
||||
LLVector4 screen_center = manipulator_center * transform;
|
||||
screen_center /= screen_center.mV[VW];
|
||||
|
||||
manip2d.setVec(screen_center.mV[VX] * half_width, screen_center.mV[VY] * half_height);
|
||||
|
||||
delta = manip2d - mousePos;
|
||||
|
||||
if (delta.magVecSquared() < MANIPULATOR_SELECT_SIZE * MANIPULATOR_SELECT_SIZE)
|
||||
{
|
||||
mHighlightedAxis = axis;
|
||||
mHighlightedDirection = direction;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL QToolAlign::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if (mask & MASK_SHIFT)
|
||||
{
|
||||
mForce = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mForce = TRUE;
|
||||
}
|
||||
|
||||
gViewerWindow->setCursor(UI_CURSOR_ARROW);
|
||||
return findSelectedManipulator(x, y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void setup_transforms_bbox(LLBBox bbox)
|
||||
{
|
||||
// translate to center
|
||||
LLVector3 center = bbox.getCenterAgent();
|
||||
gGL.translatef(center.mV[VX], center.mV[VY], center.mV[VZ]);
|
||||
|
||||
// rotate
|
||||
LLQuaternion rotation = bbox.getRotation();
|
||||
F32 angle_radians, x, y, z;
|
||||
rotation.getAngleAxis(&angle_radians, &x, &y, &z);
|
||||
// gGL has no rotate method (despite having translate and scale) presumably because
|
||||
// its authors smoke crack. so we hack.
|
||||
gGL.flush();
|
||||
glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
|
||||
|
||||
// scale
|
||||
LLVector3 scale = bbox.getMaxLocal() - bbox.getMinLocal();
|
||||
gGL.scalef(scale.mV[VX], scale.mV[VY], scale.mV[VZ]);
|
||||
}
|
||||
|
||||
|
||||
void render_bbox(LLBBox bbox)
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gGL.pushMatrix();
|
||||
|
||||
setup_transforms_bbox(bbox);
|
||||
|
||||
gGL.flush();
|
||||
gBox.render();
|
||||
|
||||
gGL.popMatrix();
|
||||
}
|
||||
|
||||
void render_cone_bbox(LLBBox bbox)
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gGL.pushMatrix();
|
||||
|
||||
setup_transforms_bbox(bbox);
|
||||
|
||||
gGL.flush();
|
||||
gCone.render(CONE_LOD_HIGHEST);
|
||||
|
||||
gGL.popMatrix();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// the selection bbox isn't axis aligned, so we must construct one
|
||||
// should this be cached in the selection manager? yes.
|
||||
LLBBox get_selection_axis_aligned_bbox()
|
||||
{
|
||||
LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
|
||||
LLVector3 position = selection_bbox.getPositionAgent();
|
||||
|
||||
LLBBox axis_aligned_bbox = LLBBox(position, LLQuaternion(), LLVector3(), LLVector3());
|
||||
axis_aligned_bbox.addPointLocal(LLVector3());
|
||||
|
||||
// cycle over the nodes in selection
|
||||
for (LLObjectSelection::iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->begin();
|
||||
selection_iter != LLSelectMgr::getInstance()->getSelection()->end();
|
||||
++selection_iter)
|
||||
{
|
||||
LLSelectNode *select_node = *selection_iter;
|
||||
if (select_node)
|
||||
{
|
||||
LLViewerObject* object = select_node->getObject();
|
||||
if (object)
|
||||
{
|
||||
axis_aligned_bbox.addBBoxAgent(object->getBoundingBoxAgent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return axis_aligned_bbox;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void QToolAlign::computeManipulatorSize()
|
||||
{
|
||||
if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD)
|
||||
{
|
||||
mManipulatorSize = MANIPULATOR_SIZE / (LLViewerCamera::getInstance()->getViewHeightInPixels() *
|
||||
gAgent.mHUDCurZoom);
|
||||
}
|
||||
else
|
||||
{
|
||||
F32 distance = dist_vec(gAgent.getCameraPositionAgent(), mBBox.getCenterAgent());
|
||||
|
||||
if (distance > 0.001f)
|
||||
{
|
||||
// range != zero
|
||||
F32 fraction_of_fov = MANIPULATOR_SIZE /LLViewerCamera::getInstance()->getViewHeightInPixels();
|
||||
F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians
|
||||
mManipulatorSize = MANIPULATOR_SIZE * distance * tan(apparent_angle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// range == zero
|
||||
mManipulatorSize = MANIPULATOR_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LLColor4 manipulator_color[3] = { LLColor4(0.7f, 0.0f, 0.0f, 0.5f),
|
||||
LLColor4(0.0f, 0.7f, 0.0f, 0.5f),
|
||||
LLColor4(0.0f, 0.0f, 0.7f, 0.5f) };
|
||||
|
||||
|
||||
void QToolAlign::renderManipulators()
|
||||
{
|
||||
computeManipulatorSize();
|
||||
LLVector3 bbox_center = mBBox.getCenterAgent();
|
||||
LLVector3 bbox_scale = mBBox.getMaxLocal() - mBBox.getMinLocal();
|
||||
|
||||
for (S32 axis = VX; axis <= VZ; axis++)
|
||||
for (F32 direction = -1.0; direction <= 1.0; direction += 2.0)
|
||||
{
|
||||
F32 size = mManipulatorSize;
|
||||
LLColor4 color = manipulator_color[axis];
|
||||
|
||||
if ((axis == mHighlightedAxis) && (direction == mHighlightedDirection))
|
||||
{
|
||||
size *= 2.0;
|
||||
color *= 1.5;
|
||||
}
|
||||
|
||||
S32 arrows = 1;
|
||||
if (mForce)
|
||||
{
|
||||
arrows = 2;
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < arrows; i++)
|
||||
{
|
||||
LLVector3 axis_vector = LLVector3(0,0,0);
|
||||
axis_vector.mV[axis] = direction * (bbox_scale.mV[axis] / 2.0 + i * (size/3.0));
|
||||
|
||||
LLVector3 manipulator_center = bbox_center + axis_vector;
|
||||
|
||||
LLQuaternion manipulator_rotation;
|
||||
manipulator_rotation.shortestArc(LLVector3(0,0,1), -1.0 * axis_vector);
|
||||
|
||||
LLBBox manipulator_bbox = LLBBox(manipulator_center, manipulator_rotation,
|
||||
LLVector3(), LLVector3());
|
||||
|
||||
manipulator_bbox.addPointLocal(LLVector3(-1, -1, -0.75) * size * 0.5);
|
||||
manipulator_bbox.addPointLocal(LLVector3(1, 1, 0.75) * size * 0.5);
|
||||
|
||||
gGL.color4fv(color.mV);
|
||||
// sadly, gCone doesn't use gGL like gBox does (presumably because its author smokes crack) so we
|
||||
// also set the raw GL color. hopefully this won't screw-up later rendering.
|
||||
glColor4fv(color.mV);
|
||||
|
||||
render_cone_bbox(manipulator_bbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QToolAlign::render()
|
||||
{
|
||||
mBBox = get_selection_axis_aligned_bbox();
|
||||
|
||||
// Draw bounding box
|
||||
LLGLSUIDefault gls_ui;
|
||||
LLGLEnable gl_blend(GL_BLEND);
|
||||
LLGLEnable gls_alpha_test(GL_ALPHA_TEST);
|
||||
LLGLDepthTest gls_depth(GL_FALSE);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
// render box
|
||||
LLColor4 default_normal_color( 0.7f, 0.7f, 0.7f, 0.1f );
|
||||
gGL.color4fv( default_normal_color.mV );
|
||||
|
||||
|
||||
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getEditSelection();
|
||||
BOOL can_move = selection->getObjectCount() != 0;
|
||||
if (can_move)
|
||||
{
|
||||
struct f : public LLSelectedObjectFunctor
|
||||
{
|
||||
virtual bool apply(LLViewerObject* objectp)
|
||||
{
|
||||
return objectp->permMove() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||
}
|
||||
} func;
|
||||
can_move = selection->applyToObjects(&func);
|
||||
}
|
||||
if (can_move)
|
||||
{
|
||||
render_bbox(mBBox);
|
||||
renderManipulators();
|
||||
}
|
||||
}
|
||||
|
||||
// only works for our specialized (AABB, position centered) bboxes
|
||||
BOOL bbox_overlap(LLBBox bbox1, LLBBox bbox2)
|
||||
{
|
||||
const F32 FUDGE = 0.001f; // because of stupid SL precision/rounding
|
||||
|
||||
LLVector3 delta = bbox1.getCenterAgent() - bbox2.getCenterAgent();
|
||||
|
||||
LLVector3 half_extent = (bbox1.getExtentLocal() + bbox2.getExtentLocal()) / 2.0;
|
||||
|
||||
return ((fabs(delta.mV[VX]) < half_extent.mV[VX] - FUDGE) &&
|
||||
(fabs(delta.mV[VY]) < half_extent.mV[VY] - FUDGE) &&
|
||||
(fabs(delta.mV[VZ]) < half_extent.mV[VZ] - FUDGE));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// used to sort bboxes before packing
|
||||
class BBoxCompare
|
||||
{
|
||||
public:
|
||||
BBoxCompare(S32 axis, F32 direction, std::map<LLPointer<LLViewerObject>, LLBBox >& bboxes) :
|
||||
mAxis(axis), mDirection(direction), mBBoxes(bboxes) {}
|
||||
|
||||
BOOL operator() (LLViewerObject* object1, LLViewerObject* object2)
|
||||
{
|
||||
LLVector3 corner1 = mBBoxes[object1].getCenterAgent() -
|
||||
mDirection * mBBoxes[object1].getExtentLocal()/2.0;
|
||||
|
||||
LLVector3 corner2 = mBBoxes[object2].getCenterAgent() -
|
||||
mDirection * mBBoxes[object2].getExtentLocal()/2.0;
|
||||
|
||||
|
||||
return mDirection * corner1.mV[mAxis] < mDirection * corner2.mV[mAxis];
|
||||
}
|
||||
|
||||
S32 mAxis;
|
||||
F32 mDirection;
|
||||
std::map<LLPointer<LLViewerObject>, LLBBox >& mBBoxes;
|
||||
};
|
||||
|
||||
|
||||
void QToolAlign::align()
|
||||
{
|
||||
// no linkset parts, please
|
||||
LLSelectMgr::getInstance()->promoteSelectionToRoot();
|
||||
|
||||
std::vector<LLPointer<LLViewerObject> > objects;
|
||||
std::map<LLPointer<LLViewerObject>, LLBBox > original_bboxes;
|
||||
|
||||
// cycle over the nodes in selection and collect them into an array
|
||||
for (LLObjectSelection::root_iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
|
||||
selection_iter != LLSelectMgr::getInstance()->getSelection()->root_end();
|
||||
++selection_iter)
|
||||
{
|
||||
LLSelectNode *select_node = *selection_iter;
|
||||
if (select_node)
|
||||
{
|
||||
LLViewerObject* object = select_node->getObject();
|
||||
if (object)
|
||||
{
|
||||
LLVector3 position = object->getPositionAgent();
|
||||
|
||||
LLBBox bbox = LLBBox(position, LLQuaternion(), LLVector3(), LLVector3());
|
||||
bbox.addPointLocal(LLVector3());
|
||||
|
||||
// add the parent's bbox
|
||||
bbox.addBBoxAgent(object->getBoundingBoxAgent());
|
||||
LLViewerObject::const_child_list_t& children = object->getChildren();
|
||||
|
||||
for (LLViewerObject::const_child_list_t::const_iterator i = children.begin();
|
||||
i != children.end(); i++)
|
||||
{
|
||||
// add the child's bbox
|
||||
LLViewerObject* child = *i;
|
||||
bbox.addBBoxAgent(child->getBoundingBoxAgent());
|
||||
}
|
||||
|
||||
objects.push_back(object);
|
||||
original_bboxes[object] = bbox;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
S32 axis = mHighlightedAxis;
|
||||
F32 direction = mHighlightedDirection;
|
||||
|
||||
// sort them into positional order for proper packing
|
||||
BBoxCompare compare(axis, direction, original_bboxes);
|
||||
sort(objects.begin(), objects.end(), compare);
|
||||
|
||||
// storage for their new position after alignment - start with original position first
|
||||
std::map<LLPointer<LLViewerObject>, LLBBox > new_bboxes = original_bboxes;
|
||||
|
||||
// find new positions
|
||||
for (S32 i = 0; i < (S32)objects.size(); i++)
|
||||
{
|
||||
LLBBox target_bbox = mBBox;
|
||||
LLVector3 target_corner = target_bbox.getCenterAgent() -
|
||||
direction * target_bbox.getExtentLocal() / 2.0;
|
||||
|
||||
LLViewerObject* object = objects[i];
|
||||
|
||||
LLBBox this_bbox = original_bboxes[object];
|
||||
LLVector3 this_corner = this_bbox.getCenterAgent() -
|
||||
direction * this_bbox.getExtentLocal() / 2.0;
|
||||
|
||||
// for packing, we cycle over several possible positions, taking the smallest that does not overlap
|
||||
F32 smallest = direction * 9999999; // 999999 guarenteed not to be the smallest
|
||||
for (S32 j = 0; j <= i; j++)
|
||||
{
|
||||
// how far must it move?
|
||||
LLVector3 delta = target_corner - this_corner;
|
||||
|
||||
// new position moves only on one axis, please
|
||||
LLVector3 delta_one_axis = LLVector3(0,0,0);
|
||||
delta_one_axis.mV[axis] = delta.mV[axis];
|
||||
|
||||
LLVector3 new_position = this_bbox.getCenterAgent() + delta_one_axis;
|
||||
|
||||
// construct the new bbox
|
||||
LLBBox new_bbox = LLBBox(new_position, LLQuaternion(), LLVector3(), LLVector3());
|
||||
new_bbox.addPointLocal(this_bbox.getExtentLocal() / 2.0);
|
||||
new_bbox.addPointLocal(-1.0 * this_bbox.getExtentLocal() / 2.0);
|
||||
|
||||
// check to see if it overlaps the previously placed objects
|
||||
BOOL overlap = FALSE;
|
||||
|
||||
llwarns << "i=" << i << " j=" << j << llendl;
|
||||
|
||||
if (!mForce) // well, don't check if in force mode
|
||||
{
|
||||
for (S32 k = 0; k < i; k++)
|
||||
{
|
||||
LLViewerObject* other_object = objects[k];
|
||||
LLBBox other_bbox = new_bboxes[other_object];
|
||||
|
||||
BOOL overlaps_this = bbox_overlap(other_bbox, new_bbox);
|
||||
|
||||
if (overlaps_this)
|
||||
{
|
||||
llwarns << "overlap" << new_bbox.getCenterAgent() << other_bbox.getCenterAgent() << llendl;
|
||||
llwarns << "extent" << new_bbox.getExtentLocal() << other_bbox.getExtentLocal() << llendl;
|
||||
}
|
||||
|
||||
overlap = (overlap || overlaps_this);
|
||||
}
|
||||
}
|
||||
|
||||
if (!overlap)
|
||||
{
|
||||
F32 this_value = (new_bbox.getCenterAgent() -
|
||||
direction * new_bbox.getExtentLocal() / 2.0).mV[axis];
|
||||
|
||||
if (direction * this_value < direction * smallest)
|
||||
{
|
||||
smallest = this_value;
|
||||
// store it
|
||||
new_bboxes[object] = new_bbox;
|
||||
}
|
||||
}
|
||||
|
||||
// update target for next time through the loop
|
||||
if (j < (S32)objects.size())
|
||||
{
|
||||
LLBBox next_bbox = new_bboxes[objects[j]];
|
||||
target_corner = next_bbox.getCenterAgent() +
|
||||
direction * next_bbox.getExtentLocal() / 2.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now move them
|
||||
for (S32 i = 0; i < (S32)objects.size(); i++)
|
||||
{
|
||||
LLViewerObject* object = objects[i];
|
||||
|
||||
LLBBox original_bbox = original_bboxes[object];
|
||||
LLBBox new_bbox = new_bboxes[object];
|
||||
|
||||
LLVector3 delta = new_bbox.getCenterAgent() - original_bbox.getCenterAgent();
|
||||
|
||||
LLVector3 original_position = object->getPositionAgent();
|
||||
LLVector3 new_position = original_position + delta;
|
||||
|
||||
object->setPosition(new_position);
|
||||
}
|
||||
|
||||
|
||||
LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION);
|
||||
}
|
||||
49
indra/newview/qtoolalign.h
Normal file
49
indra/newview/qtoolalign.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @file qtoolalign.h
|
||||
* @brief A tool to align objects
|
||||
*/
|
||||
|
||||
#ifndef Q_QTOOLALIGN_H
|
||||
#define Q_QTOOLALIGN_H
|
||||
|
||||
#include "lltool.h"
|
||||
#include "llbbox.h"
|
||||
#include "lltoolcomp.h"
|
||||
|
||||
class LLViewerObject;
|
||||
class LLPickInfo;
|
||||
class LLToolSelectRect;
|
||||
|
||||
class QToolAlign
|
||||
: public LLToolComposite, public LLSingleton<QToolAlign>
|
||||
{
|
||||
public:
|
||||
QToolAlign();
|
||||
virtual ~QToolAlign();
|
||||
|
||||
virtual void handleSelect();
|
||||
virtual void handleDeselect();
|
||||
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
virtual void render();
|
||||
|
||||
virtual LLTool* getOverrideTool(MASK mask);
|
||||
|
||||
static void pickCallback(const LLPickInfo& pick_info);
|
||||
|
||||
private:
|
||||
void align();
|
||||
void computeManipulatorSize();
|
||||
void renderManipulators();
|
||||
BOOL findSelectedManipulator(S32 x, S32 y);
|
||||
|
||||
LLBBox mBBox;
|
||||
F32 mManipulatorSize;
|
||||
S32 mHighlightedAxis;
|
||||
F32 mHighlightedDirection;
|
||||
BOOL mForce;
|
||||
};
|
||||
|
||||
#endif // Q_QTOOLALIGN_H
|
||||
@@ -7,7 +7,7 @@
|
||||
follows="left|top|right|bottom" font="SansSerifSmall" height="168" left="6"
|
||||
max_length="65536" mouse_opaque="true" name="credits_editor" width="458"
|
||||
word_wrap="true">
|
||||
Ascent is developed and maintained by Hg Beeks and Charley Levenque, with code contributions from: Hazim Gazov, Zwagoth Klaar, and viewers like you. Ascent is based off the Inertia source base.
|
||||
Ascent is developed and maintained by Hg Beeks and Charley Levenque, with code contributions from Hazim Gazov, Zwagoth Klaar, Qarl Fizz, and viewers like you. Ascent is based off the Inertia source base.
|
||||
|
||||
Ascent includes source code contributions of the following residents: Able Whitman, Adam Marker, Agathos Frascati, Aimee Trescothick, Alejandro Rosenthal, Aleric Inglewood, Alissa Sabre, Angus Boyd, Ann Congrejo, Argent Stonecutter, Asuka Neely, Balp Allen, Benja Kepler, Biancaluce Robbiani, Blakar Ogre, blino Nakamura, Boroondas Gupte, Bulli Schumann, bushing Spatula, Carjay McGinnis, Catherine Pfeffer, Celierra Darling, Cron Stardust, Dale Glass, Drewan Keats, Dylan Haskell, Dzonatas Sol, Eddy Stryker, EponymousDylan Ra, Eva Nowicka, Farallon Greyskin, Feep Larsson, Flemming Congrejo, Fluf Fredriksson, Fremont Cunningham, Geneko Nemeth, Gigs Taggart, Ginko Bayliss, Grazer Kline, Gudmund Shepherd, Hamncheese Omlet, HappySmurf Papp, Henri Beauchamp, Hikkoshi Sakai, Hiro Sommambulist, Hoze Menges, Ian Kas, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Joghert LeSabre, Kage Pixel, Ken March, Kerutsen Sellery, Khyota Wulluf, Kunnis Basiat, Lisa Lowe, Lockhart Cordoso, maciek marksman, Magnus Balczo, Malwina Dollinger, march Korda, Matthew Dowd, McCabe Maxsted, Michelle2 Zenovka, Mm Alder, Mr Greggan, Nicholaz Beresford, Nounouch Hapmouche, Patric Mills, Paul Churchill, Paula Innis, Peekay Semyorka, Peter Lameth, Pf Shan, princess niven, Renault Clio, Ringo Tuxing, Robin Cornelius, Ryozu Kojima, Salahzar Stenvaag, Sammy Frederix, Scrippy Scofield, Seg Baphomet, Sergen Davies, SignpostMarv Martin, Simon Nolan, SpacedOut Frye, Sporked Friis, Stevex Janus, Still Defiant, Strife Onizuka, Tayra Dagostino, TBBle Kurosawa, Teardrops Fall, tenebrous pau, Tharax Ferraris, Thickbrick Sleaford, Thraxis Epsilon, tiamat bingyi, TraductoresAnonimos Alter, Tue Torok, Vadim Bigbear, Vixen Heron, Whoops Babii, Wilton Lundquist, Zarkonnen Decosta, Zi Ree, Zipherius Turas
|
||||
|
||||
|
||||
@@ -18,4 +18,7 @@
|
||||
<button bottom="-236" font="SansSerif" halign="center" height="20" label="Cancel"
|
||||
label_selected="Cancel" left_delta="88" mouse_opaque="true" name="Cancel"
|
||||
width="80" />
|
||||
<string name="none">
|
||||
none
|
||||
</string>
|
||||
</floater>
|
||||
|
||||
@@ -4,53 +4,35 @@
|
||||
<!-- Floaters can optionally have their titlebar drag handle on the left.
|
||||
If so, the title is not visible.
|
||||
When a floater is resizable, a min_width and min_height must be specified. -->
|
||||
<floater
|
||||
name="floater_contact_groups"
|
||||
title="Manage Contact Groups"
|
||||
rect_control="FloaterContactRect"
|
||||
can_resize="true"
|
||||
can_minimize="false"
|
||||
can_close="true"
|
||||
can_drag_on_left="false"
|
||||
width="335"
|
||||
height="275"
|
||||
min_width="335"
|
||||
min_height="275"
|
||||
>
|
||||
<tab_container bottom="30" follows="left|right|top|bottom" height="220" left="4"
|
||||
name="ContactTabs" tab_position="top" tab_width="65" width="330">
|
||||
<panel name="AddPanel" label="Add Contact"
|
||||
border="true" bottom_delta="-10" height="150" left="6" width="135"
|
||||
mouse_opaque="true">
|
||||
<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="16" left="10"
|
||||
mouse_opaque="true" name="InstructManageContacts" v_pad="0"
|
||||
width="240">
|
||||
Create a new group or select an existing one:
|
||||
</text>
|
||||
<line_editor bevel_style="in" border_style="line"
|
||||
border_thickness="1" bottom_delta="-20" enabled="true" follows="left|top|right"
|
||||
font="SansSerifSmall" height="16" left="10" right="-120"
|
||||
max_length="254" mouse_opaque="true" name="add_group_lineedit"
|
||||
width="112" />
|
||||
<button bottom_delta="-3" follows="top|right" font="SansSerif" halign="center"
|
||||
height="20" label="Create" label_selected="Create" left_delta="20" right="-10"
|
||||
mouse_opaque="true" name="Create" scale_image="TRUE" width="90" />
|
||||
<button bottom_delta="-25" follows="top|right" font="SansSerif" halign="center"
|
||||
height="20" label="Delete" label_selected="Delete" right="-15"
|
||||
mouse_opaque="true" name="Delete" scale_image="TRUE" width="90" />
|
||||
<scroll_list background_visible="true" bottom_delta="-125" column_padding="5"
|
||||
draw_border="true" draw_heading="false" draw_stripes="true"
|
||||
follows="left|top|right" height="120" left="10" mouse_opaque="true"
|
||||
multi_select="false" name="group_scroll_list" width="115" />
|
||||
</panel>
|
||||
</tab_container>
|
||||
|
||||
<button bottom="6" left="10" follows="left|bottom" font="SansSerif" halign="center"
|
||||
width="95" height="20" label="Save" label_selected="Save" mouse_opaque="true"
|
||||
name="Save" scale_image="TRUE" />
|
||||
<button bottom_delta="0" right="240" follows="left|bottom" font="SansSerif" halign="center"
|
||||
width="95" height="20" label="Cancel" label_selected="Cancel" mouse_opaque="true"
|
||||
name="Cancel" scale_image="TRUE" />
|
||||
<floater name="floater_contact_groups" title="Manage Contact Groups" rect_control="FloaterContactRect"
|
||||
can_resize="true" can_minimize="false" can_close="true" can_drag_on_left="false" width="335"
|
||||
height="275" min_width="260" min_height="275">
|
||||
<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-35" drop_shadow_visible="true" follows="left|top"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="16" left="10"
|
||||
mouse_opaque="true" name="InstructManageContacts" v_pad="0"
|
||||
width="240">
|
||||
Select a group (Or press New to create one):
|
||||
</text>
|
||||
<combo_box allow_text_entry="true" enabled="true" follows="left|top|right"
|
||||
bottom_delta="-20" height="18" hidden="false" left="10" right="-96" max_chars="20" mouse_opaque="true"
|
||||
tool_tip="Buddy group" name="buddy_group_combobox" width="200">
|
||||
<combo_item type="string" length="20" enabled="true" name="All" value="All">
|
||||
All
|
||||
</combo_item>
|
||||
</combo_box>
|
||||
<button follows="top|right" bottom_delta="-1" height="20" label="+" right="-71" name="combo_group_add" width="21" />
|
||||
<button follows="top|right" bottom_delta="0" height="20" label="-" left_delta="22" name="combo_group_remove" width="21" />
|
||||
<button follows="top|right" bottom_delta="0" height="20" label="New" left_delta="22" name="combo_group_create" width="40" />
|
||||
<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom_delta="-18" drop_shadow_visible="true" follows="left|top"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="16" left="10"
|
||||
mouse_opaque="true" name="contact_list_text" v_pad="0"
|
||||
width="240">
|
||||
Currently in:
|
||||
</text>
|
||||
<scroll_list background_visible="true" bottom="15" column_padding="5"
|
||||
draw_border="true" draw_heading="false" draw_stripes="true"
|
||||
follows="left|top|right|bottom" left="10" right="-10" mouse_opaque="true"
|
||||
multi_select="false" name="group_scroll_list" top="-75" />
|
||||
</floater>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater name="goup titles" title="Group Titles" rect_control="BeauchampFloaterGroupTitlesRect"
|
||||
can_close="true" can_drag_on_left="false" can_minimize="true" can_resize="true"
|
||||
min_width="300" min_height="150" width="400" height="500">
|
||||
<scroll_list name="titles_list" can_resize="true" multi_select="false"
|
||||
background_visible="true" draw_border="true" draw_stripes="true" draw_heading="true"
|
||||
height="450" width="380" bottom_delta="-470" top="10" left="10" follows="left|top|right|bottom">
|
||||
<column name="title" label="Title" dynamicwidth="true" />
|
||||
<column name="group_name" label="Group" dynamicwidth="true" />
|
||||
<!--Hidden field, used as storage for UUID, please keep at width 0-->
|
||||
<column name="group_id" label="" width="0" />
|
||||
</scroll_list>
|
||||
<button name="activate" label="Activate" tool_tip="Activate the selected group title"
|
||||
enabled="true" mouse_opaque="true" font="SansSerif" halign="center"
|
||||
height="20" width="90" bottom_delta="-24" left="10" follows="left|bottom"
|
||||
/>
|
||||
</floater>
|
||||
@@ -37,46 +37,16 @@
|
||||
<string name="unavailable_text_label">
|
||||
Text chat is not available for this call.
|
||||
</string>
|
||||
<!--[$PLOTR$]-->
|
||||
<string name="otr_empty_string"></string>
|
||||
<string name="otr_gen_key_please_wait">OTR is generating keys. This will happen once for each of your avatars and should take less than 45 seconds.</string>
|
||||
<string name="otr_generic_name">Your buddy</string>
|
||||
<string name="otr_err_send_in_finished">[NAME] has ended the private conversation, so your message was not sent. You should restart the private conversation, or end the private conversation.</string>
|
||||
<string name="otr_err_deacivated">OTR has been deactivated by preferences (edit > preferences > Extras tab > IM tab)</string>
|
||||
<string name="otr_err_failed_sending">Unable to encrypt your message for some reason; it has not been sent.</string>
|
||||
<string name="otr_err_failed_starting">Unable to start private conversation.</string>
|
||||
<string name="otr_err_offline_start">[NAME] appears offline; OTR will not try to start a private conversation.</string>
|
||||
<string name="otr_err_offline_send">[NAME] appears offline; You may "End private conversation" and send your message un-encrypted.</string>
|
||||
<string name="otr_prog_I_start">Attempting to start a private conversation with [NAME].</string>
|
||||
<string name="otr_prog_I_stop_unverified">You have ended the unverified conversation with [NAME].</string>
|
||||
<string name="otr_prog_I_stop_private" >You have ended the private conversation with [NAME].</string>
|
||||
<string name="otr_prog_I_stop" >You have ended the OTR conversation with [NAME].</string>
|
||||
<string name="otr_prog_they_start">[NAME] is attempting to start a private conversation.</string>
|
||||
<string name="otr_prog_they_stop_unverified">[NAME] has ended the unverified conversation.</string>
|
||||
<string name="otr_prog_they_stop_private" >[NAME] has ended the private conversation.</string>
|
||||
<string name="otr_prog_they_stop" >[NAME] has ended the OTR conversation.</string>
|
||||
<string name="otr_log_authenticated" >[NAME] is now authenticated.</string>
|
||||
<string name="otr_log_start_private" >Private conversation with [NAME] started.</string>
|
||||
<string name="otr_log_start_unverified">Unverified conversation started. [NAME] has not been authenticated, you should "authenticate buddy," see http://www.cypherpunks.ca/otr/help/3.2.0/authenticate.php</string>
|
||||
<string name="otr_log_gone_insecure">Private conversation ended.</string>
|
||||
<string name="otr_log_still_private" >Private conversation with [NAME] resumed.</string>
|
||||
<string name="otr_log_still_unverified">Unverified conversation resumed. [NAME] has not been authenticated, you should "authenticate buddy," see http://www.cypherpunks.ca/otr/help/3.2.0/authenticate.php</string>
|
||||
<string name="otr_not_private">OTR: Not Private</string>
|
||||
<string name="otr_unverified" >OTR: Unverified</string>
|
||||
<string name="otr_private" >OTR: Private</string>
|
||||
<string name="otr_finished" >OTR: Finished</string>
|
||||
<string name="otr_start" >Start private conversation</string>
|
||||
<string name="otr_refresh">Refresh private conversation</string>
|
||||
<string name="otr_restart">Restart private conversation</string>
|
||||
<string name="otr_stop" >End private conversation</string>
|
||||
<string name="otr_auth" >Authenticate buddy</string>
|
||||
<!--[/$PLOTR$]-->
|
||||
<button bottom="-40" follows="left|top" height="20" label="Profile" left="5"
|
||||
name="profile_callee_btn" width="80" />
|
||||
<button bottom="-40" follows="left|top" halign="center" height="20" label="Teleport" left_delta="80"
|
||||
name="profile_tele_btn" width="80" />
|
||||
<button bottom="-40" follows="left|top" halign="center" height="20" label="History" left_delta="80"
|
||||
name="history_btn" pad_right="10" visible="true" width="80" />
|
||||
name="history_btn" visible="true" width="80" />
|
||||
<check_box bottom="-40" follows="left|top" halign="center" height="20" left_delta="80"
|
||||
name="rp_mode" pad_right="10" >
|
||||
RP Mode
|
||||
</check_box>
|
||||
<button bottom="-40" follows="left|top" halign="right" height="20"
|
||||
image_overlay="icn_voice-call-start.tga" image_overlay_alignment="left"
|
||||
label="Call" left_delta="80" name="start_call_btn" width="53" />
|
||||
|
||||
@@ -73,12 +73,15 @@
|
||||
<check_box bottom_delta="-15" follows="left|top" font="SansSerifSmall" height="16"
|
||||
initial_value="false" label="Select Texture" left="4" mouse_opaque="true"
|
||||
name="radio select face" radio_style="true" width="114" />
|
||||
<check_box bottom_delta="-19" control_name="EditLinkedParts" follows="left|top"
|
||||
<check_box bottom_delta="-15" follows="left|top" font="SansSerifSmall" height="16"
|
||||
initial_value="false" label="Align (Ctrl-A)" left="4" mouse_opaque="true"
|
||||
name="radio align" radio_style="true" width="114" />
|
||||
<check_box bottom_delta="-15" control_name="EditLinkedParts" follows="left|top"
|
||||
font="SansSerifSmall" height="16" initial_value="false"
|
||||
label="Edit linked parts" left="4" mouse_opaque="true"
|
||||
name="checkbox edit linked parts" width="114" />
|
||||
<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom_delta="-20" drop_shadow_visible="true" follows="left|top"
|
||||
bottom_delta="-17" drop_shadow_visible="true" follows="left|top"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="14" left="6"
|
||||
mouse_opaque="true" name="text ruler mode" v_pad="0" width="68">
|
||||
Ruler:
|
||||
@@ -1388,6 +1391,9 @@
|
||||
<string name="status_move">
|
||||
Drag to move, shift-drag to copy
|
||||
</string>
|
||||
<string name="status_align">
|
||||
Click an arrow to align objects in that direction
|
||||
</string>
|
||||
<string name="status_modifyland">
|
||||
Click and hold to modify land
|
||||
</string>
|
||||
|
||||
@@ -25,28 +25,31 @@
|
||||
tool_tip="You can edit this friend's objects" width="20" />
|
||||
<column name="friend_last_update_generation" width="0" />
|
||||
</scroll_list>
|
||||
<text bottom_delta="-40" follows="left|top" font="SansSerif" height="16" left_delta="10"
|
||||
<text bottom_delta="-40" follows="left|top" font="SansSerifSmall" height="16" left_delta="0"
|
||||
name="friends" width="110">
|
||||
Contact Group:
|
||||
</text>
|
||||
<text bottom_delta="-20" follows="left|top" font="SansSerif" height="16" left_delta="0"
|
||||
<text bottom_delta="-20" follows="left|top" font="SansSerifSmall" height="16" left_delta="0"
|
||||
name="friends" width="110">
|
||||
Contact Search:
|
||||
</text>
|
||||
<combo_box allow_text_entry="false" enabled="true" follows="right|top"
|
||||
bottom_delta="20" height="18" hidden="false" left="-235" max_chars="20" mouse_opaque="true"
|
||||
bottom_delta="20" height="18" hidden="false" left="-255" max_chars="20" mouse_opaque="true"
|
||||
tool_tip="Buddy group" name="buddy_group_combobox" width="130">
|
||||
<combo_item type="string" length="20" enabled="true" name="All" value="All">
|
||||
All
|
||||
</combo_item>
|
||||
</combo_box>
|
||||
<line_editor bottom_delta="-20" enabled="true" follows="right|top" font="SansSerif"
|
||||
height="18" left="-235" name="buddy_search_lineedit"
|
||||
height="18" left_delta="0" name="buddy_search_lineedit"
|
||||
tool_tip="The friend name you want to search for" width="130" />
|
||||
<button bottom_delta="-3" follows="top|right" height="22" label="0"
|
||||
left_delta="132" name="expand_collapse_btn" tool_tip="Expand/Collapse extra info"
|
||||
width="22" />
|
||||
<pad bottom="-7" height="0" left="-90" width="1" />
|
||||
<button bottom_delta="-25" follows="top|right" height="22" label="Set Contact"
|
||||
left_delta="0" name="assign_btn" tool_tip="Asign a friend to a Contact Group"
|
||||
width="80" />
|
||||
<button bottom_delta="-25" follows="top|right" height="22" label="Set Contact"
|
||||
left_delta="0" name="assign_btn" tool_tip="Assign a friend to a Contact Group"
|
||||
width="80" />-->
|
||||
<button bottom_delta="-25" follows="top|right" height="22" label="IM/Call"
|
||||
left_delta="0" name="im_btn" tool_tip="Open Instant Message session"
|
||||
width="80" />
|
||||
|
||||
@@ -34,7 +34,11 @@
|
||||
label="Create..." name="Create" width="80" />
|
||||
<button bottom_delta="-25" follows="top|right" font="SansSerif" height="22"
|
||||
label="Search..." name="Search..." width="80" />
|
||||
<button bottom_delta="-25" follows="top|right" font="SansSerif" height="22"
|
||||
<button bottom_delta="-25" follows="top|right" font="SansSerif" height="22"
|
||||
label="Invite..." name="Invite..." width="80" />
|
||||
|
||||
<button bottom_delta="-25" follows="top|right" font="SansSerif" height="22"
|
||||
label="Titles..." name="Titles..." width="80" />
|
||||
<string name="none">
|
||||
none
|
||||
</string>
|
||||
</panel>
|
||||
|
||||
Reference in New Issue
Block a user