diff --git a/doc/contributions.txt b/doc/contributions.txt index a4647f005d..c18d3eb171 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -44,6 +44,7 @@ Aleric Inglewood VWR-10001 VWR-10759 VWR-10837 + VWR-13996 Ales Beaumont VWR-9352 Alissa Sabre diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index ad7529ea0a..2a70263446 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -192,7 +192,7 @@ endif (DARWIN) if (LINUX OR DARWIN) - set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-non-virtual-dtor") + set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-non-virtual-dtor -Woverloaded-virtual") if (NOT GCC_DISABLE_FATAL_WARNINGS) set(GCC_WARNINGS "${GCC_WARNINGS} -Werror") @@ -227,7 +227,6 @@ else (STANDALONE) glib-2.0 gstreamer-0.10 gtk-2.0 - llfreetype2 pango-1.0 ) endif (STANDALONE) diff --git a/indra/develop.py b/indra/develop.py index cee3329c60..78d9ca9705 100755 --- a/indra/develop.py +++ b/indra/develop.py @@ -76,6 +76,7 @@ class PlatformSetup(object): build_type = build_types['relwithdebinfo'] standalone = 'OFF' unattended = 'OFF' + universal = 'OFF' project_name = 'SecondLife' distcc = True cmake_opts = [] @@ -414,11 +415,11 @@ class DarwinSetup(UnixSetup): def os(self): return 'darwin' - #def arch(self): - # if self.unattended == 'ON': - # return 'universal' - # else: - # return UnixSetup.arch(self) + def arch(self): + if self.universal == 'ON': + return 'universal' + else: + return UnixSetup.arch(self) def cmake_commandline(self, src_dir, build_dir, opts, simple): args = dict( @@ -429,12 +430,11 @@ class DarwinSetup(UnixSetup): word_size=self.word_size, unattended=self.unattended, project_name=self.project_name, - universal='', + universal=self.universal, type=self.build_type.upper(), ) - if self.unattended == 'ON': - #args['universal'] = '-DCMAKE_OSX_ARCHITECTURES:STRING=\'i386;ppc\'' - pass + if self.universal == 'ON': + args['universal'] = '-DCMAKE_OSX_ARCHITECTURES:STRING=\'i386;ppc\'' #if simple: # return 'cmake %(opts)s %(dir)r' % args return ('cmake -G %(generator)r ' @@ -673,6 +673,7 @@ Options: --standalone build standalone, without Linden prebuild libraries --unattended build unattended, do not invoke any tools requiring a human response + --universal build a universal binary on Mac OS X (unsupported) -t | --type=NAME build type ("Debug", "Release", or "RelWithDebInfo") -m32 | -m64 build architecture (32-bit or 64-bit) -N | --no-distcc disable use of distcc @@ -718,7 +719,7 @@ def main(arguments): opts, args = getopt.getopt( arguments, '?hNt:p:G:m:', - ['help', 'standalone', 'no-distcc', 'unattended', 'type=', 'incredibuild', 'generator=', 'project=']) + ['help', 'standalone', 'no-distcc', 'unattended', 'universal', 'type=', 'incredibuild', 'generator=', 'project=']) except getopt.GetoptError, err: print >> sys.stderr, 'Error:', err print >> sys.stderr, """ @@ -735,6 +736,8 @@ For example: develop.py configure -DSERVER:BOOL=OFF""" setup.standalone = 'ON' elif o in ('--unattended',): setup.unattended = 'ON' + elif o in ('--universal',): + setup.universal = 'ON' elif o in ('-m',): if a in ('32', '64'): setup.word_size = int(a) diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp index f8caa7990b..3d433fdfdc 100644 --- a/indra/integration_tests/llui_libtest/llui_libtest.cpp +++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp @@ -41,6 +41,7 @@ #include "lldir.h" #include "llerrorcontrol.h" #include "llfloater.h" +#include "llfontfreetype.h" #include "llfontgl.h" #include "lltrans.h" #include "llui.h" @@ -51,6 +52,11 @@ // *TODO: switch to using TUT // *TODO: teach Parabuild about this program, run automatically after full builds +// I believe these must be globals, not stack variables. JC +LLControlGroup gSavedSettings("Global"); // saved at end of session +LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session +LLControlGroup gWarningSettings("Warnings"); // persists ignored dialogs/warnings + // We can't create LLImageGL objects because we have no window or rendering // context. Provide enough of an LLUIImage to test the LLUI library without // an underlying image. @@ -72,6 +78,8 @@ public: } }; + +class LLTexture ; // We need to supply dummy images class TestImageProvider : public LLImageProviderInterface { @@ -92,68 +100,71 @@ public: LLPointer makeImage() { - LLPointer image_gl; - LLPointer image = new LLUIImage( std::string(), image_gl); + LLPointer image_gl; + LLPointer image = new TestUIImage(); //LLUIImage( std::string(), image_gl); + mImageList.push_back(image); return image; } + +public: + // Unclear if we need this, hold on to one copy of each image we make + std::vector > mImageList; }; +TestImageProvider gTestImageProvider; static std::string get_xui_dir() { std::string delim = gDirUtilp->getDirDelimiter(); - return gDirUtilp->getAppRODataDir() + delim + std::string("skins") + delim + "default" + delim + "xui" + delim; + return gDirUtilp->getSkinBaseDir() + delim + "default" + delim + "xui" + delim; } -int main(int argc, char** argv) +void init_llui() { - // Must init LLError for llerrs to actually cause errors. - LLError::initForApplication("."); - // Font lookup needs directory support - gDirUtilp->initAppDirs("SecondLife", "../../../newview"); +#if LL_DARWIN + const char* newview_path = "../../../../newview"; +#else + const char* newview_path = "../../../newview"; +#endif + gDirUtilp->initAppDirs("SecondLife", newview_path); gDirUtilp->setSkinFolder("default"); + + // colors are no longer stored in a LLControlGroup file + LLUIColorTable::instance().loadFromSettings(); std::string config_filename = gDirUtilp->getExpandedFilename( - LL_PATH_APP_SETTINGS, "settings.xml"); - LLControlGroup config_group("config"); - config_group.loadFromFile(config_filename); - - std::string color_filename = gDirUtilp->getExpandedFilename( - LL_PATH_DEFAULT_SKIN, "colors.xml"); - LLControlGroup color_group("color"); - color_group.loadFromFile(color_filename); - - LLControlGroup floater_group("floater"); - LLControlGroup ignores_group("ignores"); + LL_PATH_APP_SETTINGS, "settings.xml"); + gSavedSettings.loadFromFile(config_filename); + + // See LLAppViewer::init() LLUI::settings_map_t settings; - settings["config"] = &config_group; - settings["color"] = &color_group; - settings["floater"] = &floater_group; - settings["ignores"] = &ignores_group; - + settings["config"] = &gSavedSettings; + settings["ignores"] = &gWarningSettings; + settings["floater"] = &gSavedSettings; + settings["account"] = &gSavedPerAccountSettings; + // Don't use real images as we don't have a GL context - TestImageProvider image_provider; - LLUI::initClass(settings, &image_provider); - + LLUI::initClass(settings, &gTestImageProvider); + const bool no_register_widgets = false; LLWidgetReg::initClass( no_register_widgets ); - + // Unclear if this is needed LLUI::setupPaths(); // Otherwise we get translation warnings when setting up floaters // (tooltips for buttons) std::set default_args; LLTrans::parseStrings("strings.xml", default_args); - + LLTrans::parseLanguageStrings("language_settings.xml"); LLFontManager::initClass(); - + // Creating widgets apparently requires fonts to be initialized, // otherwise it crashes. LLFontGL::initClass(96.f, 1.f, 1.f, - gDirUtilp->getAppRODataDir(), - LLUI::getXUIPaths(), - false ); // don't create gl textures - + gDirUtilp->getAppRODataDir(), + LLUI::getXUIPaths(), + false ); // don't create gl textures + LLFloaterView::Params fvparams; fvparams.name("Floater View"); fvparams.rect( LLRect(0,480,640,0) ); @@ -161,7 +172,10 @@ int main(int argc, char** argv) fvparams.follows.flags(FOLLOWS_ALL); fvparams.tab_stop(false); gFloaterView = LLUICtrlFactory::create (fvparams); +} +void export_test_floaters() +{ // Convert all test floaters to new XML format std::string delim = gDirUtilp->getDirDelimiter(); std::string xui_dir = get_xui_dir() + "en" + delim; @@ -176,21 +190,32 @@ int main(int argc, char** argv) llinfos << "Converting " << filename << llendl; // Build a floater and output new attributes LLXMLNodePtr output_node = new LLXMLNode(); - LLFloater* floater = new LLFloater(); + LLFloater* floater = new LLFloater(LLSD()); LLUICtrlFactory::getInstance()->buildFloater(floater, - filename, - FALSE, // don't open floater - output_node); + filename, + // FALSE, // don't open floater + output_node); std::string out_filename = xui_dir + filename; std::string::size_type extension_pos = out_filename.rfind(".xml"); out_filename.resize(extension_pos); out_filename += "_new.xml"; - + llinfos << "Output: " << out_filename << llendl; LLFILE* floater_file = LLFile::fopen(out_filename.c_str(), "w"); LLXMLNode::writeHeaderToFile(floater_file); output_node->writeToFile(floater_file); fclose(floater_file); } +} + +int main(int argc, char** argv) +{ + // Must init LLError for llerrs to actually cause errors. + LLError::initForApplication("."); + + init_llui(); + + export_test_floaters(); + return 0; } diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.cpp b/indra/integration_tests/llui_libtest/llwidgetreg.cpp index 417f3059d6..5a97f2aefd 100644 --- a/indra/integration_tests/llui_libtest/llwidgetreg.cpp +++ b/indra/integration_tests/llui_libtest/llwidgetreg.cpp @@ -42,6 +42,7 @@ #include "llmultisliderctrl.h" #include "llprogressbar.h" #include "llradiogroup.h" +#include "llsearcheditor.h" #include "llscrollcontainer.h" #include "llscrollingpanellist.h" #include "llscrolllistctrl.h" @@ -53,7 +54,7 @@ #include "lltextbox.h" #include "lltexteditor.h" #include "llflyoutbutton.h" -#include "llsearcheditor.h" +#include "llfiltereditor.h" #include "lllayoutstack.h" void LLWidgetReg::initClass(bool register_widgets) @@ -62,45 +63,46 @@ void LLWidgetReg::initClass(bool register_widgets) // references to the object files. if (register_widgets) { - LLDefaultWidgetRegistry::Register button("button"); - LLDefaultWidgetRegistry::Register check_box("check_box"); - LLDefaultWidgetRegistry::Register combo_box("combo_box"); - LLDefaultWidgetRegistry::Register flyout_button("flyout_button"); - LLDefaultWidgetRegistry::Register container_view("container_view"); - LLDefaultWidgetRegistry::Register icon("icon"); - LLDefaultWidgetRegistry::Register line_editor("line_editor"); - LLDefaultWidgetRegistry::Register search_editor("search_editor"); - LLDefaultWidgetRegistry::Register menu_item_separator("menu_item_separator"); - LLDefaultWidgetRegistry::Register menu_item_call_gl("menu_item_call"); - LLDefaultWidgetRegistry::Register menu_item_check_gl("menu_item_check"); - LLDefaultWidgetRegistry::Register menu("menu"); - LLDefaultWidgetRegistry::Register menu_bar("menu_bar"); - LLDefaultWidgetRegistry::Register context_menu("context_menu"); - LLDefaultWidgetRegistry::Register multi_slider_bar("multi_slider_bar"); - LLDefaultWidgetRegistry::Register multi_slider("multi_slider"); - LLDefaultWidgetRegistry::Register panel("panel", &LLPanel::fromXML); - LLDefaultWidgetRegistry::Register layout_stack("layout_stack", &LLLayoutStack::fromXML); - LLDefaultWidgetRegistry::Register progress_bar("progress_bar"); - LLDefaultWidgetRegistry::Register radio_group("radio_group"); - LLDefaultWidgetRegistry::Register radio_item("radio_item"); - LLDefaultWidgetRegistry::Register scroll_container("scroll_container"); - LLDefaultWidgetRegistry::Register scrolling_panel_list("scrolling_panel_list"); - LLDefaultWidgetRegistry::Register scroll_list("scroll_list"); - LLDefaultWidgetRegistry::Register slider_bar("slider_bar"); - LLDefaultWidgetRegistry::Register slider("slider"); - LLDefaultWidgetRegistry::Register spinner("spinner"); - LLDefaultWidgetRegistry::Register stat_bar("stat_bar"); - //LLDefaultWidgetRegistry::Register placeholder("placeholder"); - LLDefaultWidgetRegistry::Register tab_container("tab_container"); - LLDefaultWidgetRegistry::Register text("text"); - LLDefaultWidgetRegistry::Register simple_text_editor("simple_text_editor"); - LLDefaultWidgetRegistry::Register ui_ctrl("ui_ctrl"); - LLDefaultWidgetRegistry::Register stat_view("stat_view"); - //LLDefaultWidgetRegistry::Register locate("locate"); - //LLDefaultWidgetRegistry::Register pad("pad"); - LLDefaultWidgetRegistry::Register view_border("view_border"); + LLDefaultChildRegistry::Register button("button"); + LLDefaultChildRegistry::Register check_box("check_box"); + LLDefaultChildRegistry::Register combo_box("combo_box"); + LLDefaultChildRegistry::Register filter_editor("filter_editor"); + LLDefaultChildRegistry::Register flyout_button("flyout_button"); + LLDefaultChildRegistry::Register container_view("container_view"); + LLDefaultChildRegistry::Register icon("icon"); + LLDefaultChildRegistry::Register line_editor("line_editor"); + LLDefaultChildRegistry::Register menu_item_separator("menu_item_separator"); + LLDefaultChildRegistry::Register menu_item_call_gl("menu_item_call"); + LLDefaultChildRegistry::Register menu_item_check_gl("menu_item_check"); + LLDefaultChildRegistry::Register menu("menu"); + LLDefaultChildRegistry::Register menu_bar("menu_bar"); + LLDefaultChildRegistry::Register context_menu("context_menu"); + LLDefaultChildRegistry::Register multi_slider_bar("multi_slider_bar"); + LLDefaultChildRegistry::Register multi_slider("multi_slider"); + LLDefaultChildRegistry::Register panel("panel", &LLPanel::fromXML); + LLDefaultChildRegistry::Register layout_stack("layout_stack", &LLLayoutStack::fromXML); + LLDefaultChildRegistry::Register progress_bar("progress_bar"); + LLDefaultChildRegistry::Register radio_group("radio_group"); + LLDefaultChildRegistry::Register radio_item("radio_item"); + LLDefaultChildRegistry::Register search_editor("search_editor"); + LLDefaultChildRegistry::Register scroll_container("scroll_container"); + LLDefaultChildRegistry::Register scrolling_panel_list("scrolling_panel_list"); + LLDefaultChildRegistry::Register scroll_list("scroll_list"); + LLDefaultChildRegistry::Register slider_bar("slider_bar"); + LLDefaultChildRegistry::Register slider("slider"); + LLDefaultChildRegistry::Register spinner("spinner"); + LLDefaultChildRegistry::Register stat_bar("stat_bar"); + //LLDefaultChildRegistry::Register placeholder("placeholder"); + LLDefaultChildRegistry::Register tab_container("tab_container"); + LLDefaultChildRegistry::Register text("text"); + LLDefaultChildRegistry::Register simple_text_editor("simple_text_editor"); + LLDefaultChildRegistry::Register ui_ctrl("ui_ctrl"); + LLDefaultChildRegistry::Register stat_view("stat_view"); + //LLDefaultChildRegistry::Register locate("locate"); + //LLDefaultChildRegistry::Register pad("pad"); + LLDefaultChildRegistry::Register view_border("view_border"); } // *HACK: Usually this is registered as a viewer text editor - LLDefaultWidgetRegistry::Register text_editor("text_editor"); + LLDefaultChildRegistry::Register text_editor("text_editor"); } diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.h b/indra/integration_tests/llui_libtest/llwidgetreg.h index eac818608d..4e0bc5377a 100644 --- a/indra/integration_tests/llui_libtest/llwidgetreg.h +++ b/indra/integration_tests/llui_libtest/llwidgetreg.h @@ -33,7 +33,7 @@ // Register all widgets with the builder registry. // Useful on Windows where linker discards all references to the -// static LLDefaultWidgetRegistry::Register<> calls. +// static LLDefaultChildRegistry::Register<> calls. class LLWidgetReg { public: diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index b1a0b74f85..0473d1599a 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -174,7 +174,7 @@ public: void clampRotation(LLQuaternion old_rot, LLQuaternion new_rot); - virtual BOOL isAnimatable() { return TRUE; } + virtual BOOL isAnimatable() const { return TRUE; } S32 getJointNum() const { return mJointNum; } void setJointNum(S32 joint_num) { mJointNum = joint_num; } diff --git a/indra/llcharacter/llmultigesture.cpp b/indra/llcharacter/llmultigesture.cpp index 701d6889ca..05d1bc0cd9 100644 --- a/indra/llcharacter/llmultigesture.cpp +++ b/indra/llcharacter/llmultigesture.cpp @@ -50,6 +50,7 @@ const S32 GESTURE_VERSION = 2; LLMultiGesture::LLMultiGesture() : mKey(), mMask(), + mName(), mTrigger(), mReplaceText(), mSteps(), diff --git a/indra/llcharacter/llmultigesture.h b/indra/llcharacter/llmultigesture.h index fdffb35c31..fdcf32dc67 100644 --- a/indra/llcharacter/llmultigesture.h +++ b/indra/llcharacter/llmultigesture.h @@ -65,11 +65,13 @@ protected: const LLMultiGesture& operator=(const LLMultiGesture& rhs); public: - // name is stored at asset level - // desc is stored at asset level KEY mKey; MASK mMask; + // This name can be empty if the inventory item is not around and + // the gesture manager has not yet set the name + std::string mName; + // String, like "/foo" or "hello" that makes it play std::string mTrigger; diff --git a/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp index 93255d702c..dd4880dbb9 100644 --- a/indra/llcharacter/llpose.cpp +++ b/indra/llcharacter/llpose.cpp @@ -516,9 +516,9 @@ BOOL LLPoseBlender::addMotion(LLMotion* motion) void LLPoseBlender::blendAndApply() { for (blender_list_t::iterator iter = mActiveBlenders.begin(); - iter != mActiveBlenders.end(); ++iter) + iter != mActiveBlenders.end(); ) { - LLJointStateBlender* jsbp = *iter; + LLJointStateBlender* jsbp = *iter++; jsbp->blendJointStates(); } diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 410cd0f6b2..7fe4491a8b 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -74,6 +74,7 @@ set(llcommon_SOURCE_FILES llsdserialize_xml.cpp llsdutil.cpp llsecondlifeurls.cpp + llsingleton.cpp llstat.cpp llstacktrace.cpp llstreamtools.cpp diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index e4102a622d..d431071c25 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -44,19 +44,29 @@ struct AssetEntry : public LLDictionaryEntry { AssetEntry(const char *desc_name, const char *type_name, // 8 character limit! - const char *human_name, + const char *human_name, // for decoding to human readable form; put any and as many printable characters you want in each one const char *category_name, // used by llinventorymodel when creating new categories EDragAndDropType dad_type, - bool can_link); + bool can_link, // can you create a link to this type? + bool is_protected) // can the viewer change categories of this type? + : + LLDictionaryEntry(desc_name), + mTypeName(type_name), + mHumanName(human_name), + mCategoryName(category_name), + mDadType(dad_type), + mCanLink(can_link), + mIsProtected(is_protected) + { + llassert(strlen(mTypeName) <= 8); + } - // limited to 8 characters const char *mTypeName; - // human readable form. Put as many printable characters you want in each one. - // (c.f. llinventory.cpp INVENTORY_TYPE_HUMAN_NAMES). const char *mHumanName; const char *mCategoryName; EDragAndDropType mDadType; bool mCanLink; + bool mIsProtected; }; class LLAssetDictionary : public LLSingleton, @@ -68,53 +78,50 @@ public: LLAssetDictionary::LLAssetDictionary() { - addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", "Textures", DAD_TEXTURE, FALSE)); - addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", "Sounds", DAD_SOUND, FALSE)); - addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", "Calling Cards", DAD_CALLINGCARD, FALSE)); - addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", "Landmarks", DAD_LANDMARK, FALSE)); - addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", "Scripts", DAD_NONE, FALSE)); - addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", "Clothing", DAD_CLOTHING, TRUE)); - addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", "Objects", DAD_OBJECT, TRUE)); - addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", "Notecards", DAD_NOTECARD, FALSE)); - addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", "New Folder", DAD_CATEGORY, TRUE)); - addEntry(LLAssetType::AT_ROOT_CATEGORY, new AssetEntry("ROOT_CATEGORY", "root", "root", "Inventory", DAD_ROOT_CATEGORY, TRUE)); - addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", "Scripts", DAD_SCRIPT, FALSE)); - addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", "Scripts", DAD_NONE, FALSE)); - addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", "Uncompressed Images", DAD_NONE, FALSE)); - addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", "Body Parts", DAD_BODYPART, TRUE)); - addEntry(LLAssetType::AT_TRASH, new AssetEntry("TRASH", "trash", "trash", "Trash", DAD_NONE, FALSE)); - addEntry(LLAssetType::AT_SNAPSHOT_CATEGORY, new AssetEntry("SNAPSHOT_CATEGORY", "snapshot", "snapshot", "Photo Album", DAD_NONE, FALSE)); - addEntry(LLAssetType::AT_LOST_AND_FOUND, new AssetEntry("LOST_AND_FOUND", "lstndfnd", "lost and found", "Lost And Found", DAD_NONE, FALSE)); - addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", "Uncompressed SoundS", DAD_NONE, FALSE)); - addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", "Uncompressed Images", DAD_NONE, FALSE)); - addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", "Uncompressed Images", DAD_NONE, FALSE)); - addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", "Animations", DAD_ANIMATION, FALSE)); - addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", "Gestures", DAD_GESTURE, FALSE)); - addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", "New Folder", DAD_NONE, FALSE)); - addEntry(LLAssetType::AT_FAVORITE, new AssetEntry("FAVORITE", "favorite", "favorite", "favorite", DAD_NONE, FALSE)); + // DESCRIPTION TYPE NAME HUMAN NAME CATEGORY NAME DRAG&DROP CAN LINK? PROTECTED? + // |--------------------|-----------|-------------------|-------------------|---------------|-----------|-----------| + addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", "Textures", DAD_TEXTURE, FALSE, TRUE)); + addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", "Sounds", DAD_SOUND, FALSE, TRUE)); + addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", "Calling Cards", DAD_CALLINGCARD, FALSE, TRUE)); + addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", "Landmarks", DAD_LANDMARK, FALSE, TRUE)); + addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", "Scripts", DAD_NONE, FALSE, TRUE)); + addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", "Clothing", DAD_CLOTHING, TRUE, TRUE)); + addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", "Objects", DAD_OBJECT, TRUE, TRUE)); + addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", "Notecards", DAD_NOTECARD, FALSE, TRUE)); + addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", "New Folder", DAD_CATEGORY, TRUE, TRUE)); + addEntry(LLAssetType::AT_ROOT_CATEGORY, new AssetEntry("ROOT_CATEGORY", "root", "root", "Inventory", DAD_ROOT_CATEGORY, TRUE, TRUE)); + addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", "Scripts", DAD_SCRIPT, FALSE, TRUE)); + addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", "Scripts", DAD_NONE, FALSE, TRUE)); + addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", "Uncompressed Images", DAD_NONE, FALSE, TRUE)); + addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", "Body Parts", DAD_BODYPART, TRUE, TRUE)); + addEntry(LLAssetType::AT_TRASH, new AssetEntry("TRASH", "trash", "trash", "Trash", DAD_NONE, FALSE, TRUE)); + addEntry(LLAssetType::AT_SNAPSHOT_CATEGORY, new AssetEntry("SNAPSHOT_CATEGORY", "snapshot", "snapshot", "Photo Album", DAD_NONE, FALSE, TRUE)); + addEntry(LLAssetType::AT_LOST_AND_FOUND, new AssetEntry("LOST_AND_FOUND", "lstndfnd", "lost and found", "Lost And Found", DAD_NONE, FALSE, TRUE)); + addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", "Uncompressed SoundS", DAD_NONE, FALSE, TRUE)); + addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", "Uncompressed Images", DAD_NONE, FALSE, TRUE)); + addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", "Uncompressed Images", DAD_NONE, FALSE, TRUE)); + addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", "Animations", DAD_ANIMATION, FALSE, TRUE)); + addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", "Gestures", DAD_GESTURE, FALSE, TRUE)); + addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", "New Folder", DAD_NONE, FALSE, TRUE)); + addEntry(LLAssetType::AT_FAVORITE, new AssetEntry("FAVORITE", "favorite", "favorite", "favorite", DAD_NONE, FALSE, TRUE)); - addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "symbolic link", "New Folder", DAD_NONE, FALSE)); - addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "symbolic folder link", "New Folder", DAD_NONE, FALSE)); + addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "symbolic link", "Link", DAD_LINK, FALSE, TRUE)); + addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "symbolic folder link", "New Folder", DAD_LINK, FALSE, TRUE)); - addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, "New Folder", DAD_NONE, FALSE)); + for (S32 ensemble_num = S32(LLAssetType::AT_FOLDER_ENSEMBLE_START); + ensemble_num <= S32(LLAssetType::AT_FOLDER_ENSEMBLE_END); + ensemble_num++) + { + addEntry(LLAssetType::EType(ensemble_num), new AssetEntry("ENSEMBLE", "ensemble", "ensemble", "New Folder", DAD_CATEGORY, TRUE, FALSE)); + } + + addEntry(LLAssetType::AT_CURRENT_OUTFIT, new AssetEntry("CURRENT", "current", "current outfit", "Current Outfit", DAD_CATEGORY, FALSE, TRUE)); + addEntry(LLAssetType::AT_OUTFIT, new AssetEntry("OUTFIT", "outfit", "outfit", "Outfit", DAD_CATEGORY, TRUE, FALSE)); + addEntry(LLAssetType::AT_MY_OUTFITS, new AssetEntry("MY_OUTFITS", "my_otfts", "my outfits", "My Outfits", DAD_CATEGORY, FALSE, TRUE)); + + addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, "New Folder", DAD_NONE, FALSE, FALSE)); }; -AssetEntry::AssetEntry(const char *desc_name, - const char *type_name, - const char *human_name, - const char *category_name, - EDragAndDropType dad_type, - bool can_link) : - LLDictionaryEntry(desc_name), - mTypeName(type_name), - mHumanName(human_name), - mCategoryName(category_name), - mDadType(dad_type), - mCanLink(can_link) -{ - llassert(strlen(mTypeName) <= 8); -} - // static LLAssetType::EType LLAssetType::getType(const std::string& desc_name) { @@ -128,11 +135,11 @@ const std::string &LLAssetType::getDesc(LLAssetType::EType asset_type) { const AssetEntry *entry = LLAssetDictionary::getInstance()->lookup(asset_type); if (entry) -{ + { return entry->mName; } else - { + { static const std::string error_string = "BAD TYPE"; return error_string; } @@ -154,7 +161,7 @@ const char *LLAssetType::lookup(LLAssetType::EType asset_type) } // static -LLAssetType::EType LLAssetType::lookup( const char* name ) +LLAssetType::EType LLAssetType::lookup(const char* name) { return lookup(ll_safe_string(name)); } @@ -191,7 +198,7 @@ const char *LLAssetType::lookupHumanReadable(LLAssetType::EType asset_type) } // static -LLAssetType::EType LLAssetType::lookupHumanReadable( const char* name ) +LLAssetType::EType LLAssetType::lookupHumanReadable(const char* name) { return lookupHumanReadable(ll_safe_string(name)); } @@ -261,6 +268,21 @@ bool LLAssetType::lookupIsLinkType(EType asset_type) return false; } +// static +// Only ensembles and plain folders aren't protected. "Protected" means +// you can't change certain properties such as their type. +bool LLAssetType::lookupIsProtectedCategoryType(EType asset_type) +{ + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + const AssetEntry *entry = dict->lookup(asset_type); + if (entry) + { + return entry->mIsProtected; + } + return true; +} + + // static. Generate a good default description void LLAssetType::generateDescriptionFor(LLAssetType::EType asset_type, std::string& description) diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 8d524f1e28..eb6ad494db 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -125,7 +125,7 @@ public: AT_SIMSTATE = 22, // Simstate file. - + AT_FAVORITE = 23, // favorite items @@ -135,21 +135,35 @@ public: AT_LINK_FOLDER = 25, // Inventory folder link - AT_COUNT = 26, + AT_FOLDER_ENSEMBLE_START = 26, + AT_FOLDER_ENSEMBLE_END = 45, + // This range is reserved for special clothing folder types. - // +************************************************+ - // | TO ADD AN ELEMENT TO THIS ENUM: | - // +************************************************+ - // | 1. INSERT BEFORE AT_COUNT | - // | 2. INCREMENT AT_COUNT BY 1 | - // | 3. ADD TO LLAssetDictionary in llassettype.cpp | - // +************************************************+ + AT_CURRENT_OUTFIT = 46, + // Current outfit + + AT_OUTFIT = 47, + // Predefined outfit ("look") + + AT_MY_OUTFITS = 48, + // Folder that holds your outfits. + + + AT_COUNT = 49, + // +*********************************************************+ + // | TO ADD AN ELEMENT TO THIS ENUM: | + // +*********************************************************+ + // | 1. INSERT BEFORE AT_COUNT | + // | 2. INCREMENT AT_COUNT BY 1 | + // | 3. ADD TO LLAssetDictionary in LLAssetType.cpp | + // | 3. ADD TO DEFAULT_ASSET_FOR_INV in LLInventoryType.cpp | + // +*********************************************************+ AT_NONE = -1 }; // machine transation between type and strings - static EType lookup(const char* name); // safe conversion to std::string, *TODO: deprecate + static EType lookup(const char* name); // safe conversion to std::string, *TODO: deprecate static EType lookup(const std::string& type_name); static const char* lookup(EType asset_type); @@ -158,8 +172,6 @@ public: static EType lookupHumanReadable(const std::string& readable_name); static const char* lookupHumanReadable(EType asset_type); - static const char* lookupCategoryName(EType asset_type); - // Generate a good default description. You may want to add a verb // or agent name after this depending on your application. static void generateDescriptionFor(LLAssetType::EType asset_type, @@ -168,9 +180,13 @@ public: static EType getType(const std::string& desc_name); static const std::string& getDesc(EType asset_type); static EDragAndDropType lookupDragAndDropType(EType asset_type); + static bool lookupCanLink(EType asset_type); static bool lookupIsLinkType(EType asset_type); + static const char* lookupCategoryName(EType asset_type); + static bool lookupIsProtectedCategoryType(EType asset_type); + /* TODO: Change return types from "const char *" to "const std::string &". This is fairly straightforward, but requires changing some calls to use .c_str(). e.g.: @@ -180,8 +196,8 @@ public: private: // don't instantiate or derive one of these objects - LLAssetType() {} - ~LLAssetType() {} + LLAssetType( void ) {} + ~LLAssetType( void ) {} }; #endif // LL_LLASSETTYPE_H diff --git a/indra/llcommon/lldependencies.h b/indra/llcommon/lldependencies.h index 754557cf31..e6229db834 100644 --- a/indra/llcommon/lldependencies.h +++ b/indra/llcommon/lldependencies.h @@ -581,6 +581,8 @@ public: return sorted_range(begin, end); } + using LLDependenciesBase::describe; // unhide virtual std::string describe(bool full=true) const; + /// Override base-class describe() with actual implementation virtual std::ostream& describe(std::ostream& out, bool full=true) const { @@ -597,6 +599,7 @@ public: return out; } + /// describe() helper: report a DepNodeEntry static std::ostream& describe(std::ostream& out, std::string& sep, const DepNodeMapEntry& entry, bool full) diff --git a/indra/llcommon/lldictionary.h b/indra/llcommon/lldictionary.h index 856947def8..436b689ca6 100644 --- a/indra/llcommon/lldictionary.h +++ b/indra/llcommon/lldictionary.h @@ -95,6 +95,10 @@ public: protected: void addEntry(Index index, Entry *entry) { + if (lookup(index)) + { + llerrs << "Dictionary entry already added (attempted to add duplicate entry)" << llendl; + } (*this)[index] = entry; } }; diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index 6df418fe5a..b999bfafa7 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -21,7 +21,16 @@ #include #include #include +#if LL_WINDOWS + #pragma warning (push) + #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch + #pragma warning (disable : 4264) +#endif #include +#if LL_WINDOWS + #pragma warning (pop) +#endif + #include #include #include diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index 671e85b16f..f135beed6a 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -116,8 +116,10 @@ #pragma warning( 3 : 4702 ) // "unreachable code" Treat this as level 3, not level 4. #pragma warning( 3 : 4189 ) // "local variable initialized but not referenced" Treat this as level 3, not level 4. //#pragma warning( 3 : 4018 ) // "signed/unsigned mismatch" Treat this as level 3, not level 4. +#pragma warning( 3 : 4263 ) // 'function' : member function does not override any base class virtual member function +#pragma warning( 3 : 4264 ) // "'virtual_function' : no override available for virtual member function from base 'class'; function is hidden" #pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual" -#pragma warning( disable : 4786 ) // silly MS warning deep inside their include file +#pragma warning( 3 : 4266 ) // 'function' : no override available for virtual member function from base 'type'; function is hidden #pragma warning( disable : 4284 ) // silly MS warning deep inside their include file #pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation. #pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 2cc94c2914..ba0f798dbb 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -162,6 +162,7 @@ namespace virtual LLSD::Type type() const { return T; } + using LLSD::Impl::assign; // Unhiding base class virtuals... virtual void assign(LLSD::Impl*& var, DataRef value) { if (shared()) { @@ -349,6 +350,10 @@ namespace virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } virtual bool has(const LLSD::String&) const; + + using LLSD::Impl::get; // Unhiding get(LLSD::Integer) + using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer) + using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer) virtual LLSD get(const LLSD::String&) const; LLSD& insert(const LLSD::String& k, const LLSD& v); virtual void erase(const LLSD::String&); @@ -439,6 +444,9 @@ namespace virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } + using LLSD::Impl::get; // Unhiding get(LLSD::String) + using LLSD::Impl::erase; // Unhiding erase(LLSD::String) + using LLSD::Impl::ref; // Unhiding ref(LLSD::String) virtual int size() const; virtual LLSD get(LLSD::Integer) const; void set(LLSD::Integer, const LLSD&); diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp new file mode 100644 index 0000000000..62988cdc64 --- /dev/null +++ b/indra/llcommon/llsingleton.cpp @@ -0,0 +1,38 @@ +/** + * @file llsingleton.cpp + * @author Brad Kittenbrink + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llsingleton.h" + +std::map LLSingletonRegistry::sSingletonMap; + diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index dc1457e4f7..00c87821c2 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -33,7 +33,30 @@ #include "llerror.h" // *TODO: eliminate this +#include #include +#include + +/// @brief A global registry of all singletons to prevent duplicate allocations +/// across shared library boundaries +class LL_COMMON_API LLSingletonRegistry { + private: + typedef std::map TypeMap; + static TypeMap sSingletonMap; + + public: + template static void * & get() + { + std::string name(typeid(T).name()); + + if(0 == sSingletonMap.count(name)) + { + sSingletonMap[name] = NULL; + } + + return sSingletonMap[typeid(T).name()]; + } +}; // LLSingleton implements the getInstance() method part of the Singleton // pattern. It can't make the derived class constructors protected, though, so @@ -107,8 +130,16 @@ public: static SingletonInstanceData& getData() { + void * & registry = LLSingletonRegistry::get(); static SingletonInstanceData data; - return data; + + // *TODO - look into making this threadsafe + if(NULL == registry) + { + registry = &data; + } + + return *static_cast(registry); } static DERIVED_TYPE* getInstance() @@ -143,7 +174,14 @@ public: { return *getInstance(); } - + + // Has this singleton been created uet? + // Use this to avoid accessing singletons before the can safely be constructed + static bool instanceExists() + { + return getData().mInitState == INITIALIZED; + } + // Has this singleton already been deleted? // Use this to avoid accessing singletons from a static object's destructor static bool destroyed() diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h index c0fc06ee6e..23e39ceb08 100644 --- a/indra/llcommon/llversionserver.h +++ b/indra/llcommon/llversionserver.h @@ -36,7 +36,7 @@ const S32 LL_VERSION_MAJOR = 1; const S32 LL_VERSION_MINOR = 29; const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 120909; +const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Server"; diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h index 41da51fce3..1a5678dde1 100644 --- a/indra/llcommon/stdenums.h +++ b/indra/llcommon/stdenums.h @@ -54,7 +54,8 @@ enum EDragAndDropType DAD_BODYPART = 11, DAD_ANIMATION = 12, DAD_GESTURE = 13, - DAD_COUNT = 14, // number of types in this enum + DAD_LINK = 14, + DAD_COUNT = 15, // number of types in this enum }; // Reasons for drags to be denied. diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 597e19e7ea..59aca12de2 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -310,6 +310,7 @@ LLInventoryItem::LLInventoryItem( { LLStringUtil::replaceNonstandardASCII(mDescription, ' '); LLStringUtil::replaceChar(mDescription, '|', ' '); + mPermissions.initMasks(inv_type); } LLInventoryItem::LLInventoryItem() : @@ -432,6 +433,9 @@ void LLInventoryItem::setDescription(const std::string& d) void LLInventoryItem::setPermissions(const LLPermissions& perm) { mPermissions = perm; + + // Override permissions to unrestricted if this is a landmark + mPermissions.initMasks(mInventoryType); } void LLInventoryItem::setInventoryType(LLInventoryType::EType inv_type) @@ -503,6 +507,7 @@ BOOL LLInventoryItem::unpackMessage(LLMessageSystem* msg, const char* block, S32 mType = static_cast(type); msg->getS8(block, "InvType", type, block_num); mInventoryType = static_cast(type); + mPermissions.initMasks(mInventoryType); msg->getU32Fast(block, _PREHASH_Flags, mFlags, block_num); @@ -693,6 +698,9 @@ BOOL LLInventoryItem::importFile(LLFILE* fp) lldebugs << "Resetting inventory type for " << mUUID << llendl; mInventoryType = LLInventoryType::defaultForAssetType(mType); } + + mPermissions.initMasks(mInventoryType); + return success; } @@ -896,6 +904,9 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream) lldebugs << "Resetting inventory type for " << mUUID << llendl; mInventoryType = LLInventoryType::defaultForAssetType(mType); } + + mPermissions.initMasks(mInventoryType); + return success; } @@ -1118,6 +1129,8 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd) mInventoryType = LLInventoryType::defaultForAssetType(mType); } + mPermissions.initMasks(mInventoryType); + return true; fail: return false; @@ -1624,7 +1637,7 @@ LLSD ll_create_sd_from_inventory_category(LLPointer cat) rv[INV_PARENT_ID_LABEL] = cat->getParentUUID(); rv[INV_NAME_LABEL] = cat->getName(); rv[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(cat->getType()); - if(LLAssetType::AT_NONE != cat->getPreferredType()) + if(LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())) { rv[INV_PREFERRED_TYPE_LABEL] = LLAssetType::lookup(cat->getPreferredType()); diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp index 2dc229226f..a445466b26 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -44,9 +44,23 @@ static const std::string empty_string; ///---------------------------------------------------------------------------- struct InventoryEntry : public LLDictionaryEntry { - InventoryEntry(const std::string &name, - const std::string &human_name, - int num_asset_types = 0, ...); + InventoryEntry(const std::string &name, // unlike asset type names, not limited to 8 characters; need not match asset type names + const std::string &human_name, // for decoding to human readable form; put any and as many printable characters you want in each one. + int num_asset_types = 0, ...) + : + LLDictionaryEntry(name), + mHumanName(human_name) + { + va_list argp; + va_start(argp, num_asset_types); + // Read in local textures + for (U8 i=0; i < num_asset_types; i++) + { + LLAssetType::EType t = (LLAssetType::EType)va_arg(argp,int); + mAssetTypes.push_back(t); + } + } + const std::string mHumanName; typedef std::vector asset_vec_t; asset_vec_t mAssetTypes; @@ -115,25 +129,35 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] = LLInventoryType::IT_GESTURE, // AT_GESTURE LLInventoryType::IT_NONE, // AT_SIMSTATE LLInventoryType::IT_FAVORITE, // AT_FAVORITE + LLInventoryType::IT_NONE, // AT_LINK LLInventoryType::IT_NONE, // AT_LINK_FOLDER -}; -InventoryEntry::InventoryEntry(const std::string &name, - const std::string &human_name, - int num_asset_types, ...) : - LLDictionaryEntry(name), - mHumanName(human_name) -{ - va_list argp; - va_start(argp, num_asset_types); - // Read in local textures - for (U8 i=0; i < num_asset_types; i++) - { - LLAssetType::EType t = (LLAssetType::EType)va_arg(argp,int); - mAssetTypes.push_back(t); - } -} + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + LLInventoryType::IT_CATEGORY, // AT_ENSEMBLE + + LLInventoryType::IT_CATEGORY, // AT_CURRENT_OUTFIT + LLInventoryType::IT_CATEGORY, // AT_OUTFIT + LLInventoryType::IT_CATEGORY, // AT_MY_OUTFITS +}; // static const std::string &LLInventoryType::lookup(EType type) @@ -173,6 +197,21 @@ LLInventoryType::EType LLInventoryType::defaultForAssetType(LLAssetType::EType a } } + +// add any types that we don't want the user to be able to change permissions on. +// static +bool LLInventoryType::cannotRestrictPermissions(LLInventoryType::EType type) +{ + switch(type) + { + case IT_CALLINGCARD: + case IT_LANDMARK: + return true; + default: + return false; + } +} + bool inventory_and_asset_types_match(LLInventoryType::EType inventory_type, LLAssetType::EType asset_type) { diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h index 1aad90d51b..14b28bfe4b 100644 --- a/indra/llinventory/llinventorytype.h +++ b/indra/llinventory/llinventorytype.h @@ -83,10 +83,13 @@ public: // return the default inventory for the given asset type. static EType defaultForAssetType(LLAssetType::EType asset_type); + // true if this type cannot have restricted permissions. + static bool cannotRestrictPermissions(EType type); + private: // don't instantiate or derive one of these objects - LLInventoryType() {} - ~LLInventoryType() {} + LLInventoryType( void ); + ~LLInventoryType( void ); }; // helper function that returns true if inventory type and asset type diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 7b7896f74f..71baac8d89 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -447,8 +447,10 @@ public: BOOL getAllowFly() const { return (mParcelFlags & PF_ALLOW_FLY) ? TRUE : FALSE; } + // Remove permission restrictions for creating landmarks. + // We should eventually remove this flag completely. BOOL getAllowLandmark() const - { return (mParcelFlags & PF_ALLOW_LANDMARK) ? TRUE : FALSE; } + { return TRUE; } BOOL getAllowGroupScripts() const { return (mParcelFlags & PF_ALLOW_GROUP_SCRIPTS) ? TRUE : FALSE; } diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index 559a5631dc..0babf26457 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -83,6 +83,17 @@ void LLPermissions::initMasks(PermissionMask base, PermissionMask owner, fix(); } +// ! BACKWARDS COMPATIBILITY ! Override masks for inventory types that +// no longer can have restricted permissions. This takes care of previous +// version landmarks that could have had no copy/mod/transfer bits set. +void LLPermissions::initMasks(LLInventoryType::EType type) +{ + if (LLInventoryType::cannotRestrictPermissions(type)) + { + initMasks(PERM_ALL, PERM_ALL, PERM_ALL, PERM_ALL, PERM_ALL); + } +} + BOOL LLPermissions::getOwnership(LLUUID& owner_id, BOOL& is_group_owned) const { if(mOwner.notNull()) diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index 2035b57f5c..d4ec399436 100644 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -38,6 +38,7 @@ #include "lluuid.h" #include "llxmlnode.h" #include "reflective.h" +#include "llinventorytype.h" // prototypes class LLMessageSystem; @@ -129,6 +130,8 @@ public: void initMasks(PermissionMask base, PermissionMask owner, PermissionMask everyone, PermissionMask group, PermissionMask next); + // adjust permissions based on inventory type. + void initMasks(LLInventoryType::EType type); // // ACCESSORS diff --git a/indra/llinventory/llpermissionsflags.h b/indra/llinventory/llpermissionsflags.h index afa2adbd90..f810929d68 100644 --- a/indra/llinventory/llpermissionsflags.h +++ b/indra/llinventory/llpermissionsflags.h @@ -32,9 +32,6 @@ #ifndef LL_LLPERMISSIONSFLAGS_H #define LL_LLPERMISSIONSFLAGS_H -// llpermissionsflags.h -// Copyright 2002, Linden Research, Inc. -// // Flags for various permissions bits. // Shared between viewer and simulator. diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index c26749cd23..3970c7a92c 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -10,6 +10,7 @@ include_directories( ) set(llmath_SOURCE_FILES + llbbox.cpp llbboxlocal.cpp llcamera.cpp llcoordframe.cpp @@ -39,6 +40,7 @@ set(llmath_HEADER_FILES camera.h coordframe.h + llbbox.h llbboxlocal.h llcamera.h llcoord.h diff --git a/indra/llmath/llbbox.cpp b/indra/llmath/llbbox.cpp new file mode 100644 index 0000000000..914cbfdc12 --- /dev/null +++ b/indra/llmath/llbbox.cpp @@ -0,0 +1,162 @@ +/** + * @file llbbox.cpp + * @brief General purpose bounding box class (Not axis aligned) + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +// self include +#include "llbbox.h" + +// library includes +#include "m4math.h" + +void LLBBox::addPointLocal(const LLVector3& p) +{ + if (mEmpty) + { + mMinLocal = p; + mMaxLocal = p; + mEmpty = FALSE; + } + else + { + mMinLocal.mV[VX] = llmin( p.mV[VX], mMinLocal.mV[VX] ); + mMinLocal.mV[VY] = llmin( p.mV[VY], mMinLocal.mV[VY] ); + mMinLocal.mV[VZ] = llmin( p.mV[VZ], mMinLocal.mV[VZ] ); + mMaxLocal.mV[VX] = llmax( p.mV[VX], mMaxLocal.mV[VX] ); + mMaxLocal.mV[VY] = llmax( p.mV[VY], mMaxLocal.mV[VY] ); + mMaxLocal.mV[VZ] = llmax( p.mV[VZ], mMaxLocal.mV[VZ] ); + } +} + +void LLBBox::addPointAgent( LLVector3 p) +{ + p -= mPosAgent; + p.rotVec( ~mRotation ); + addPointLocal( p ); +} + + +void LLBBox::addBBoxAgent(const LLBBox& b) +{ + if (mEmpty) + { + mPosAgent = b.mPosAgent; + mRotation = b.mRotation; + mMinLocal.clearVec(); + mMaxLocal.clearVec(); + } + LLVector3 vertex[8]; + vertex[0].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] ); + vertex[1].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + vertex[2].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] ); + vertex[3].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + vertex[4].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] ); + vertex[5].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + vertex[6].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] ); + vertex[7].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + + LLMatrix4 m( b.mRotation ); + m.translate( b.mPosAgent ); + m.translate( -mPosAgent ); + m.rotate( ~mRotation ); + + for( S32 i=0; i<8; i++ ) + { + addPointLocal( vertex[i] * m ); + } +} + + +void LLBBox::expand( F32 delta ) +{ + mMinLocal.mV[VX] -= delta; + mMinLocal.mV[VY] -= delta; + mMinLocal.mV[VZ] -= delta; + mMaxLocal.mV[VX] += delta; + mMaxLocal.mV[VY] += delta; + mMaxLocal.mV[VZ] += delta; +} + +LLVector3 LLBBox::localToAgent(const LLVector3& v) const +{ + LLMatrix4 m( mRotation ); + m.translate( mPosAgent ); + return v * m; +} + +LLVector3 LLBBox::agentToLocal(const LLVector3& v) const +{ + LLMatrix4 m; + m.translate( -mPosAgent ); + m.rotate( ~mRotation ); // inverse rotation + return v * m; +} + +LLVector3 LLBBox::localToAgentBasis(const LLVector3& v) const +{ + LLMatrix4 m( mRotation ); + return v * m; +} + +LLVector3 LLBBox::agentToLocalBasis(const LLVector3& v) const +{ + LLMatrix4 m( ~mRotation ); // inverse rotation + return v * m; +} + +BOOL LLBBox::containsPointLocal(const LLVector3& p) const +{ + if ( (p.mV[VX] < mMinLocal.mV[VX]) + ||(p.mV[VX] > mMaxLocal.mV[VX]) + ||(p.mV[VY] < mMinLocal.mV[VY]) + ||(p.mV[VY] > mMaxLocal.mV[VY]) + ||(p.mV[VZ] < mMinLocal.mV[VZ]) + ||(p.mV[VZ] > mMaxLocal.mV[VZ])) + { + return FALSE; + } + return TRUE; +} + +BOOL LLBBox::containsPointAgent(const LLVector3& p) const +{ + LLVector3 point_local = agentToLocal(p); + return containsPointLocal(point_local); +} + + +/* +LLBBox operator*(const LLBBox &a, const LLMatrix4 &b) +{ + return LLBBox( a.mMin * b, a.mMax * b ); +} +*/ diff --git a/indra/llmath/llbbox.h b/indra/llmath/llbbox.h new file mode 100644 index 0000000000..cd29551b01 --- /dev/null +++ b/indra/llmath/llbbox.h @@ -0,0 +1,103 @@ +/** + * @file llbbox.h + * @brief General purpose bounding box class + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_BBOX_H +#define LL_BBOX_H + +#include "v3math.h" +#include "llquaternion.h" + +// Note: "local space" for an LLBBox is defined relative to agent space in terms of +// a translation followed by a rotation. There is no scale term since the LLBBox's min and +// max are not necessarily symetrical and define their own extents. + +class LLBBox +{ +public: + LLBBox() {mEmpty = TRUE;} + LLBBox( const LLVector3& pos_agent, + const LLQuaternion& rot, + const LLVector3& min_local, + const LLVector3& max_local ) + : + mMinLocal( min_local ), mMaxLocal( max_local ), mPosAgent(pos_agent), mRotation( rot), mEmpty( TRUE ) + {} + + // Default copy constructor is OK. + + const LLVector3& getPositionAgent() const { return mPosAgent; } + const LLQuaternion& getRotation() const { return mRotation; } + + const LLVector3& getMinLocal() const { return mMinLocal; } + void setMinLocal( const LLVector3& min ) { mMinLocal = min; } + + const LLVector3& getMaxLocal() const { return mMaxLocal; } + void setMaxLocal( const LLVector3& max ) { mMaxLocal = max; } + + LLVector3 getCenterLocal() const { return (mMaxLocal - mMinLocal) * 0.5f + mMinLocal; } + LLVector3 getCenterAgent() const { return localToAgent( getCenterLocal() ); } + + LLVector3 getExtentLocal() const { return mMaxLocal - mMinLocal; } + + BOOL containsPointLocal(const LLVector3& p) const; + BOOL containsPointAgent(const LLVector3& p) const; + + void addPointAgent(LLVector3 p); + void addBBoxAgent(const LLBBox& b); + + void addPointLocal(const LLVector3& p); + void addBBoxLocal(const LLBBox& b) { addPointLocal( b.mMinLocal ); addPointLocal( b.mMaxLocal ); } + + void expand( F32 delta ); + + LLVector3 localToAgent( const LLVector3& v ) const; + LLVector3 agentToLocal( const LLVector3& v ) const; + + // Changes rotation but not position + LLVector3 localToAgentBasis(const LLVector3& v) const; + LLVector3 agentToLocalBasis(const LLVector3& v) const; + + +// friend LLBBox operator*(const LLBBox& a, const LLMatrix4& b); + +private: + LLVector3 mMinLocal; + LLVector3 mMaxLocal; + LLVector3 mPosAgent; // Position relative to Agent's Region + LLQuaternion mRotation; + BOOL mEmpty; // Nothing has been added to this bbox yet +}; + +//LLBBox operator*(const LLBBox &a, const LLMatrix4 &b); + + +#endif // LL_BBOX_H diff --git a/indra/llmath/llbboxlocal.h b/indra/llmath/llbboxlocal.h index d69028e3aa..0d1e5a3ae5 100644 --- a/indra/llmath/llbboxlocal.h +++ b/indra/llmath/llbboxlocal.h @@ -53,9 +53,6 @@ public: LLVector3 getCenter() const { return (mMax - mMin) * 0.5f + mMin; } LLVector3 getExtent() const { return mMax - mMin; } - BOOL containsPoint(const LLVector3& p) const; - BOOL intersects(const LLBBoxLocal& b) const; - void addPoint(const LLVector3& p); void addBBox(const LLBBoxLocal& b) { addPoint( b.mMin ); addPoint( b.mMax ); } diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index bced84cb1c..ba8776690a 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -65,11 +65,10 @@ public: }; template -class LLOctreeTraveler : public LLTreeTraveler +class LLOctreeTraveler { public: - virtual void traverse(const LLTreeNode* node); - virtual void visit(const LLTreeNode* state) { } + virtual void traverse(const LLOctreeNode* node); virtual void visit(const LLOctreeNode* branch) = 0; }; @@ -700,19 +699,16 @@ public: } }; - //======================== // LLOctreeTraveler //======================== template -void LLOctreeTraveler::traverse(const LLTreeNode* tree_node) +void LLOctreeTraveler::traverse(const LLOctreeNode* node) { - const LLOctreeNode* node = (const LLOctreeNode*) tree_node; node->accept(this); for (U32 i = 0; i < node->getChildCount(); i++) { traverse(node->getChild(i)); } } - #endif diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h index 16bfdde658..894f0a7ed0 100644 --- a/indra/llmath/llrect.h +++ b/indra/llmath/llrect.h @@ -71,10 +71,10 @@ public: void setValue(const LLSD& sd) { - mLeft = sd[0].asInteger(); - mTop = sd[1].asInteger(); - mRight = sd[2].asInteger(); - mBottom = sd[3].asInteger(); + mLeft = (Type)sd[0].asInteger(); + mTop = (Type)sd[1].asInteger(); + mRight = (Type)sd[2].asInteger(); + mBottom = (Type)sd[3].asInteger(); } LLSD getValue() const diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index 2966b602d7..b3087bcc3f 100644 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -1025,12 +1025,12 @@ LLSD LLAssetStorage::getPendingDetails(LLAssetStorage::ERequestType rt, { const request_list_t* requests = getRequestList(rt); LLSD sd; - sd["requests"] = getPendingDetails(requests, asset_type, detail_prefix); + sd["requests"] = getPendingDetailsImpl(requests, asset_type, detail_prefix); return sd; } // virtual -LLSD LLAssetStorage::getPendingDetails(const LLAssetStorage::request_list_t* requests, +LLSD LLAssetStorage::getPendingDetailsImpl(const LLAssetStorage::request_list_t* requests, LLAssetType::EType asset_type, const std::string& detail_prefix) const { @@ -1113,11 +1113,11 @@ LLSD LLAssetStorage::getPendingRequest(LLAssetStorage::ERequestType rt, const LLUUID& asset_id) const { const request_list_t* requests = getRequestList(rt); - return getPendingRequest(requests, asset_type, asset_id); + return getPendingRequestImpl(requests, asset_type, asset_id); } // virtual -LLSD LLAssetStorage::getPendingRequest(const LLAssetStorage::request_list_t* requests, +LLSD LLAssetStorage::getPendingRequestImpl(const LLAssetStorage::request_list_t* requests, LLAssetType::EType asset_type, const LLUUID& asset_id) const { @@ -1136,7 +1136,7 @@ bool LLAssetStorage::deletePendingRequest(LLAssetStorage::ERequestType rt, const LLUUID& asset_id) { request_list_t* requests = getRequestList(rt); - if (deletePendingRequest(requests, asset_type, asset_id)) + if (deletePendingRequestImpl(requests, asset_type, asset_id)) { llinfos << "Asset " << getRequestName(rt) << " request for " << asset_id << "." << LLAssetType::lookup(asset_type) @@ -1147,7 +1147,7 @@ bool LLAssetStorage::deletePendingRequest(LLAssetStorage::ERequestType rt, } // virtual -bool LLAssetStorage::deletePendingRequest(LLAssetStorage::request_list_t* requests, +bool LLAssetStorage::deletePendingRequestImpl(LLAssetStorage::request_list_t* requests, LLAssetType::EType asset_type, const LLUUID& asset_id) { diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index f01ee6a8e8..56adbd5ccf 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -306,15 +306,15 @@ public: void markAssetToxic( const LLUUID& uuid ); protected: - virtual LLSD getPendingDetails(const request_list_t* requests, + virtual LLSD getPendingDetailsImpl(const request_list_t* requests, LLAssetType::EType asset_type, const std::string& detail_prefix) const; - virtual LLSD getPendingRequest(const request_list_t* requests, + virtual LLSD getPendingRequestImpl(const request_list_t* requests, LLAssetType::EType asset_type, const LLUUID& asset_id) const; - virtual bool deletePendingRequest(request_list_t* requests, + virtual bool deletePendingRequestImpl(request_list_t* requests, LLAssetType::EType asset_type, const LLUUID& asset_id); diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 1a432cd7df..a4af8e989b 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -120,7 +120,7 @@ LLCurl::Responder::~Responder() } // virtual -void LLCurl::Responder::error( +void LLCurl::Responder::errorWithContent( U32 status, const std::string& reason, const LLSD&) @@ -161,7 +161,7 @@ void LLCurl::Responder::completed(U32 status, const std::string& reason, const L } else { - error(status, reason, content); + errorWithContent(status, reason, content); } } diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index ff63904c91..fbd3077cbf 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -85,7 +85,7 @@ public: return((200 <= status) && (status < 300)); } - virtual void error( + virtual void errorWithContent( U32 status, const std::string& reason, const LLSD& content); diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp index dfdad59e2a..49dbdbd56d 100644 --- a/indra/llmessage/llhttpassetstorage.cpp +++ b/indra/llmessage/llhttpassetstorage.cpp @@ -626,7 +626,7 @@ LLSD LLHTTPAssetStorage::getPendingRequest(LLAssetStorage::ERequestType rt, const request_list_t* running = getRunningList(rt); if (running) { - LLSD sd = LLAssetStorage::getPendingRequest(running, asset_type, asset_id); + LLSD sd = LLAssetStorage::getPendingRequestImpl(running, asset_type, asset_id); if (sd) { sd["is_running"] = true; diff --git a/indra/llmessage/llhttpassetstorage.h b/indra/llmessage/llhttpassetstorage.h index 5786c5df32..231437dad4 100644 --- a/indra/llmessage/llhttpassetstorage.h +++ b/indra/llmessage/llhttpassetstorage.h @@ -62,6 +62,8 @@ public: virtual ~LLHTTPAssetStorage(); + using LLAssetStorage::storeAssetData; // Unhiding virtuals... + virtual void storeAssetData( const LLUUID& uuid, LLAssetType::EType atype, diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp index 2ba900a533..440b91fcfa 100644 --- a/indra/llmessage/llhttpnode.cpp +++ b/indra/llmessage/llhttpnode.cpp @@ -98,19 +98,19 @@ namespace { } // virtual -LLSD LLHTTPNode::get() const +LLSD LLHTTPNode::simpleGet() const { throw NotImplemented(); } // virtual -LLSD LLHTTPNode::put(const LLSD& input) const +LLSD LLHTTPNode::simplePut(const LLSD& input) const { throw NotImplemented(); } // virtual -LLSD LLHTTPNode::post(const LLSD& input) const +LLSD LLHTTPNode::simplePost(const LLSD& input) const { throw NotImplemented(); } @@ -121,7 +121,7 @@ void LLHTTPNode::get(LLHTTPNode::ResponsePtr response, const LLSD& context) cons { try { - response->result(get()); + response->result(simpleGet()); } catch (NotImplemented) { @@ -134,7 +134,7 @@ void LLHTTPNode::put(LLHTTPNode::ResponsePtr response, const LLSD& context, cons { try { - response->result(put(input)); + response->result(simplePut(input)); } catch (NotImplemented) { @@ -147,7 +147,7 @@ void LLHTTPNode::post(LLHTTPNode::ResponsePtr response, const LLSD& context, con { try { - response->result(post(input)); + response->result(simplePost(input)); } catch (NotImplemented) { @@ -160,7 +160,7 @@ void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) cons { try { - response->result(del(context)); + response->result(simpleDel(context)); } catch (NotImplemented) { @@ -170,7 +170,7 @@ void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) cons } // virtual -LLSD LLHTTPNode::del(const LLSD&) const +LLSD LLHTTPNode::simpleDel(const LLSD&) const { throw NotImplemented(); } @@ -388,7 +388,7 @@ LLHTTPNode::Response::~Response() { } -void LLHTTPNode::Response::status(S32 code) +void LLHTTPNode::Response::statusUnknownError(S32 code) { status(code, "Unknown Error"); } diff --git a/indra/llmessage/llhttpnode.h b/indra/llmessage/llhttpnode.h index 3f4da69a1d..915aacb7cc 100644 --- a/indra/llmessage/llhttpnode.h +++ b/indra/llmessage/llhttpnode.h @@ -84,10 +84,10 @@ public: //@{ public: - virtual LLSD get() const; - virtual LLSD put(const LLSD& input) const; - virtual LLSD post(const LLSD& input) const; - virtual LLSD del(const LLSD& context) const; + virtual LLSD simpleGet() const; + virtual LLSD simplePut(const LLSD& input) const; + virtual LLSD simplePost(const LLSD& input) const; + virtual LLSD simpleDel(const LLSD& context) const; /** * @brief Abstract Base Class declaring Response interface. @@ -117,7 +117,7 @@ public: /** * @brief Return no body, just status code and 'UNKNOWN ERROR'. */ - virtual void status(S32 code); + virtual void statusUnknownError(S32 code); virtual void notFound(const std::string& message); virtual void notFound(); @@ -293,6 +293,7 @@ public: void result(const LLSD& result); void extendedResult(S32 code, const std::string& body, const LLSD& headers); + void status(S32 code, const std::string& message); void print(std::ostream& out) const; diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index 83dfa94f00..a00dbd1809 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -105,6 +105,7 @@ private: // from LLHTTPNode::Response virtual void result(const LLSD&); virtual void extendedResult(S32 code, const std::string& body, const LLSD& headers); + virtual void status(S32 code, const std::string& message); void nullPipe(); diff --git a/indra/llmessage/llregionpresenceverifier.h b/indra/llmessage/llregionpresenceverifier.h index 10602450d8..54ad6226d6 100644 --- a/indra/llmessage/llregionpresenceverifier.h +++ b/indra/llmessage/llregionpresenceverifier.h @@ -82,6 +82,7 @@ public: public: VerifiedDestinationResponder(ResponsePtr data, const LLSD& content); virtual void result(const LLSD& content); + virtual void error(U32 status, const std::string& reason); private: void retry(); diff --git a/indra/llmessage/llsdappservices.cpp b/indra/llmessage/llsdappservices.cpp index dc135c51b2..b87c0cd6b7 100644 --- a/indra/llmessage/llsdappservices.cpp +++ b/indra/llmessage/llsdappservices.cpp @@ -56,7 +56,7 @@ public: desc.source(__FILE__, __LINE__); } - virtual LLSD get() const + virtual LLSD simpleGet() const { LLSD result; LLApp* app = LLApp::instance(); @@ -82,7 +82,7 @@ public: desc.source(__FILE__, __LINE__); } - virtual LLSD get() const + virtual LLSD simpleGet() const { return LLApp::instance()->getOptionData( LLApp::PRIORITY_RUNTIME_OVERRIDE); diff --git a/indra/llmessage/llsdhttpserver.cpp b/indra/llmessage/llsdhttpserver.cpp index 00fc170c59..704c375ffc 100644 --- a/indra/llmessage/llsdhttpserver.cpp +++ b/indra/llmessage/llsdhttpserver.cpp @@ -62,7 +62,7 @@ public: desc.source(__FILE__, __LINE__); } - virtual LLSD get() const + virtual LLSD simpleGet() const { LLSD result = "hello"; return result; @@ -86,7 +86,7 @@ public: desc.source(__FILE__, __LINE__); } - virtual LLSD post(const LLSD& params) const + virtual LLSD simplePost(const LLSD& params) const { return params; } diff --git a/indra/llmessage/llsdmessage.cpp b/indra/llmessage/llsdmessage.cpp index ad6b8284aa..2cb742e261 100644 --- a/indra/llmessage/llsdmessage.cpp +++ b/indra/llmessage/llsdmessage.cpp @@ -94,7 +94,7 @@ void LLSDMessage::EventResponder::result(const LLSD& data) } } -void LLSDMessage::EventResponder::error(U32 status, const std::string& reason, const LLSD& content) +void LLSDMessage::EventResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content) { // If our caller passed an empty errorPump name, they're not // listening: "default error handling is acceptable." Only post to an @@ -138,7 +138,7 @@ bool LLSDMessage::ResponderAdapter::listener(const LLSD& payload, bool success) } else { - mResponder->error(payload["status"].asInteger(), payload["reason"], payload["content"]); + mResponder->errorWithContent(payload["status"].asInteger(), payload["reason"], payload["content"]); } /*---------------- MUST BE LAST STATEMENT BEFORE RETURN ----------------*/ diff --git a/indra/llmessage/llsdmessage.h b/indra/llmessage/llsdmessage.h index 672da6d3a6..6ee00fd41d 100644 --- a/indra/llmessage/llsdmessage.h +++ b/indra/llmessage/llsdmessage.h @@ -133,7 +133,7 @@ private: {} virtual void result(const LLSD& data); - virtual void error(U32 status, const std::string& reason, const LLSD& content); + virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content); private: LLEventPumps& mPumps; diff --git a/indra/llmessage/lltransfersourceasset.cpp b/indra/llmessage/lltransfersourceasset.cpp index c715e16e34..5a1cd95ffc 100644 --- a/indra/llmessage/lltransfersourceasset.cpp +++ b/indra/llmessage/lltransfersourceasset.cpp @@ -296,10 +296,10 @@ bool is_asset_id_knowable(LLAssetType::EType type) case LLAssetType::AT_FAVORITE: case LLAssetType::AT_LINK: case LLAssetType::AT_LINK_FOLDER: - rv = true; - break; - default: - break; + rv = true; + break; + default: + break; } return rv; } diff --git a/indra/llmessage/tests/llcurl_stub.cpp b/indra/llmessage/tests/llcurl_stub.cpp index d6be54336a..5dc5932fde 100644 --- a/indra/llmessage/tests/llcurl_stub.cpp +++ b/indra/llmessage/tests/llcurl_stub.cpp @@ -34,7 +34,7 @@ void LLCurl::Responder::completed(U32 status, std::basic_string, std::allocator > const&, LLSD const&) { diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 0bb835970f..aac650bec9 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -26,7 +26,7 @@ include_directories( set(llrender_SOURCE_FILES llcubemap.cpp - llfont.cpp + llfontfreetype.cpp llfontgl.cpp llfontbitmapcache.cpp llfontregistry.cpp @@ -36,6 +36,7 @@ set(llrender_SOURCE_FILES llpostprocess.cpp llrendersphere.cpp llshadermgr.cpp + lltexture.cpp llvertexbuffer.cpp ) @@ -44,7 +45,7 @@ set(llrender_HEADER_FILES llcubemap.h llfontgl.h - llfont.h + llfontfreetype.h llfontbitmapcache.h llfontregistry.h llgl.h @@ -58,6 +59,7 @@ set(llrender_HEADER_FILES llrender.h llrendersphere.h llshadermgr.h + lltexture.h llvertexbuffer.h ) diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h index 4beea0d026..4a57052b91 100644 --- a/indra/llrender/llfontbitmapcache.h +++ b/indra/llrender/llfontbitmapcache.h @@ -36,7 +36,7 @@ #include // Maintain a collection of bitmaps containing rendered glyphs. -// Generalizes the single-bitmap logic from LLFont and LLFontGL. +// Generalizes the single-bitmap logic from LLFontFreetype and LLFontGL. class LLFontBitmapCache: public LLRefCount { public: diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp new file mode 100644 index 0000000000..62534969b7 --- /dev/null +++ b/indra/llrender/llfontfreetype.cpp @@ -0,0 +1,630 @@ +/** + * @file llfontfreetype.cpp + * @brief Freetype font library wrapper + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llfontfreetype.h" + +// Freetype stuff +#include + +// For some reason, this won't work if it's not wrapped in the ifdef +#ifdef FT_FREETYPE_H +#include FT_FREETYPE_H +#endif + +#include "llerror.h" +#include "llimage.h" +//#include "llimagej2c.h" +#include "llmath.h" // Linden math +#include "llstring.h" +//#include "imdebug.h" +#include "llfontbitmapcache.h" +#include "llgl.h" + +FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL; + +LLFontManager *gFontManagerp = NULL; + +FT_Library gFTLibrary = NULL; + +//static +void LLFontManager::initClass() +{ + gFontManagerp = new LLFontManager; +} + +//static +void LLFontManager::cleanupClass() +{ + delete gFontManagerp; + gFontManagerp = NULL; +} + +LLFontManager::LLFontManager() +{ + int error; + error = FT_Init_FreeType(&gFTLibrary); + if (error) + { + // Clean up freetype libs. + llerrs << "Freetype initialization failure!" << llendl; + FT_Done_FreeType(gFTLibrary); + } +} + +LLFontManager::~LLFontManager() +{ + FT_Done_FreeType(gFTLibrary); +} + + +LLFontGlyphInfo::LLFontGlyphInfo(U32 index) +: mGlyphIndex(index), + mXBitmapOffset(0), // Offset to the origin in the bitmap + mYBitmapOffset(0), // Offset to the origin in the bitmap + mXBearing(0), // Distance from baseline to left in pixels + mYBearing(0), // Distance from baseline to top in pixels + mWidth(0), // In pixels + mHeight(0), // In pixels + mXAdvance(0.f), // In pixels + mYAdvance(0.f), // In pixels + mIsRendered(FALSE), + mMetricsValid(FALSE) +{ +} + +LLFontFreetype::LLFontFreetype() +: mFontBitmapCachep(new LLFontBitmapCache), + mValid(FALSE), + mAscender(0.f), + mDescender(0.f), + mLineHeight(0.f), + mIsFallback(FALSE), + mFTFace(NULL), + mRenderGlyphCount(0), + mAddGlyphCount(0), + mPointSize(0) +{ +} + + +LLFontFreetype::~LLFontFreetype() +{ + // Clean up freetype libs. + if (mFTFace) + FT_Done_Face(mFTFace); + mFTFace = NULL; + + // Delete glyph info + std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer()); + + // mFontBitmapCachep will be cleaned up by LLPointer destructor. + // mFallbackFonts cleaned up by LLPointer destructor +} + +BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) +{ + // Don't leak face objects. This is also needed to deal with + // changed font file names. + if (mFTFace) + { + FT_Done_Face(mFTFace); + mFTFace = NULL; + } + + int error; + + error = FT_New_Face( gFTLibrary, + filename.c_str(), + 0, + &mFTFace ); + + if (error) + { + return FALSE; + } + + mIsFallback = is_fallback; + F32 pixels_per_em = (point_size / 72.f)*vert_dpi; // Size in inches * dpi + + error = FT_Set_Char_Size(mFTFace, /* handle to face object */ + 0, /* char_width in 1/64th of points */ + (S32)(point_size*64), /* char_height in 1/64th of points */ + (U32)horz_dpi, /* horizontal device resolution */ + (U32)vert_dpi); /* vertical device resolution */ + + if (error) + { + // Clean up freetype libs. + FT_Done_Face(mFTFace); + mFTFace = NULL; + return FALSE; + } + + F32 y_max, y_min, x_max, x_min; + F32 ems_per_unit = 1.f/ mFTFace->units_per_EM; + F32 pixels_per_unit = pixels_per_em * ems_per_unit; + + // Get size of bbox in pixels + y_max = mFTFace->bbox.yMax * pixels_per_unit; + y_min = mFTFace->bbox.yMin * pixels_per_unit; + x_max = mFTFace->bbox.xMax * pixels_per_unit; + x_min = mFTFace->bbox.xMin * pixels_per_unit; + mAscender = mFTFace->ascender * pixels_per_unit; + mDescender = -mFTFace->descender * pixels_per_unit; + mLineHeight = mFTFace->height * pixels_per_unit; + + S32 max_char_width = llround(0.5f + (x_max - x_min)); + S32 max_char_height = llround(0.5f + (y_max - y_min)); + + mFontBitmapCachep->init(components, max_char_width, max_char_height); + + if (!mFTFace->charmap) + { + //llinfos << " no unicode encoding, set whatever encoding there is..." << llendl; + FT_Set_Charmap(mFTFace, mFTFace->charmaps[0]); + } + + if (!mIsFallback) + { + // Add the default glyph + addGlyph(0, 0); + } + + mName = filename; + mPointSize = point_size; + + return TRUE; +} + +void LLFontFreetype::setFallbackFonts(const font_vector_t &font) +{ + mFallbackFonts = font; +} + +const LLFontFreetype::font_vector_t &LLFontFreetype::getFallbackFonts() const +{ + return mFallbackFonts; +} + +F32 LLFontFreetype::getLineHeight() const +{ + return mLineHeight; +} + +F32 LLFontFreetype::getAscenderHeight() const +{ + return mAscender; +} + +F32 LLFontFreetype::getDescenderHeight() const +{ + return mDescender; +} + +F32 LLFontFreetype::getXAdvance(llwchar wch) const +{ + if (mFTFace == NULL) + return 0.0; + + //llassert(!mIsFallback); + U32 glyph_index; + + // Return existing info only if it is current + LLFontGlyphInfo* gi = getGlyphInfo(wch); + if (gi && gi->mMetricsValid) + { + return gi->mXAdvance; + } + + const LLFontFreetype* fontp = this; + + // Initialize char to glyph map + glyph_index = FT_Get_Char_Index(mFTFace, wch); + if (glyph_index == 0) + { + font_vector_t::const_iterator iter; + for(iter = mFallbackFonts.begin(); (iter != mFallbackFonts.end()) && (glyph_index == 0); iter++) + { + glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch); + if(glyph_index) + { + fontp = *iter; + } + } + } + + if (glyph_index) + { + // This font has this glyph + fontp->renderGlyph(glyph_index); + + // Create the entry if it's not there + char_glyph_info_map_t::iterator iter2 = mCharGlyphInfoMap.find(wch); + if (iter2 == mCharGlyphInfoMap.end()) + { + gi = new LLFontGlyphInfo(glyph_index); + insertGlyphInfo(wch, gi); + } + else + { + gi = iter2->second; + } + + gi->mWidth = fontp->mFTFace->glyph->bitmap.width; + gi->mHeight = fontp->mFTFace->glyph->bitmap.rows; + + // Convert these from 26.6 units to float pixels. + gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f; + gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f; + gi->mMetricsValid = TRUE; + return gi->mXAdvance; + } + else + { + gi = get_if_there(mCharGlyphInfoMap, (llwchar)0, (LLFontGlyphInfo*)NULL); + if (gi) + { + return gi->mXAdvance; + } + } + + // Last ditch fallback - no glyphs defined at all. + return (F32)mFontBitmapCachep->getMaxCharWidth(); +} + +F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const +{ + if (mFTFace == NULL) + return 0.0; + + //llassert(!mIsFallback); + LLFontGlyphInfo* left_glyph_info = get_if_there(mCharGlyphInfoMap, char_left, (LLFontGlyphInfo*)NULL); + U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0; + // Kern this puppy. + LLFontGlyphInfo* right_glyph_info = get_if_there(mCharGlyphInfoMap, char_right, (LLFontGlyphInfo*)NULL); + U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0; + + FT_Vector delta; + + llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta)); + + return delta.x*(1.f/64.f); +} + +BOOL LLFontFreetype::hasGlyph(llwchar wch) const +{ + llassert(!mIsFallback); + const LLFontGlyphInfo* gi = getGlyphInfo(wch); + if (gi && gi->mIsRendered) + { + return TRUE; + } + else + { + return FALSE; + } +} + +BOOL LLFontFreetype::addChar(llwchar wch) const +{ + if (mFTFace == NULL) + return FALSE; + + llassert(!mIsFallback); + //lldebugs << "Adding new glyph for " << wch << " to font" << llendl; + + FT_UInt glyph_index; + + // Initialize char to glyph map + glyph_index = FT_Get_Char_Index(mFTFace, wch); + if (glyph_index == 0) + { + //llinfos << "Trying to add glyph from fallback font!" << llendl + font_vector_t::const_iterator iter; + for(iter = mFallbackFonts.begin(); iter != mFallbackFonts.end(); iter++) + { + glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch); + if (glyph_index) + { + addGlyphFromFont(*iter, wch, glyph_index); + return TRUE; + } + } + } + + char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch); + if (iter == mCharGlyphInfoMap.end() || !(iter->second->mIsRendered)) + { + BOOL result = addGlyph(wch, glyph_index); + return result; + } + return FALSE; +} + +BOOL LLFontFreetype::addGlyph(llwchar wch, U32 glyph_index) const +{ + return addGlyphFromFont(this, wch, glyph_index); +} + +BOOL LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const +{ + if (mFTFace == NULL) + return FALSE; + + llassert(!mIsFallback); + fontp->renderGlyph(glyph_index); + S32 width = fontp->mFTFace->glyph->bitmap.width; + S32 height = fontp->mFTFace->glyph->bitmap.rows; + + S32 pos_x, pos_y; + S32 bitmap_num; + mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_num); + mAddGlyphCount++; + + LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index); + gi->mXBitmapOffset = pos_x; + gi->mYBitmapOffset = pos_y; + gi->mBitmapNum = bitmap_num; + gi->mWidth = width; + gi->mHeight = height; + gi->mXBearing = fontp->mFTFace->glyph->bitmap_left; + gi->mYBearing = fontp->mFTFace->glyph->bitmap_top; + // Convert these from 26.6 units to float pixels. + gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f; + gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f; + gi->mIsRendered = TRUE; + gi->mMetricsValid = TRUE; + + insertGlyphInfo(wch, gi); + + llassert(fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO + || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY); + + if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO + || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) + { + U8 *buffer_data = fontp->mFTFace->glyph->bitmap.buffer; + S32 buffer_row_stride = fontp->mFTFace->glyph->bitmap.pitch; + U8 *tmp_graydata = NULL; + + if (fontp->mFTFace->glyph->bitmap.pixel_mode + == FT_PIXEL_MODE_MONO) + { + // need to expand 1-bit bitmap to 8-bit graymap. + tmp_graydata = new U8[width * height]; + S32 xpos, ypos; + for (ypos = 0; ypos < height; ++ypos) + { + S32 bm_row_offset = buffer_row_stride * ypos; + for (xpos = 0; xpos < width; ++xpos) + { + U32 bm_col_offsetbyte = xpos / 8; + U32 bm_col_offsetbit = 7 - (xpos % 8); + U32 bit = + !!(buffer_data[bm_row_offset + + bm_col_offsetbyte + ] & (1 << bm_col_offsetbit) ); + tmp_graydata[width*ypos + xpos] = + 255 * bit; + } + } + // use newly-built graymap. + buffer_data = tmp_graydata; + buffer_row_stride = width; + } + + switch (mFontBitmapCachep->getNumComponents()) + { + case 1: + mFontBitmapCachep->getImageRaw(bitmap_num)->setSubImage(pos_x, + pos_y, + width, + height, + buffer_data, + buffer_row_stride, + TRUE); + break; + case 2: + setSubImageLuminanceAlpha(pos_x, + pos_y, + bitmap_num, + width, + height, + buffer_data, + buffer_row_stride); + break; + default: + break; + } + + if (tmp_graydata) + delete[] tmp_graydata; + } else { + // we don't know how to handle this pixel format from FreeType; + // omit it from the font-image. + } + + return TRUE; +} + +LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(llwchar wch) const +{ + char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch); + if (iter != mCharGlyphInfoMap.end()) + { + return iter->second; + } + return NULL; +} + +void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const +{ + char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch); + if (iter != mCharGlyphInfoMap.end()) + { + delete iter->second; + iter->second = gi; + } + else + { + mCharGlyphInfoMap[wch] = gi; + } +} + +void LLFontFreetype::renderGlyph(U32 glyph_index) const +{ + if (mFTFace == NULL) + return; + + int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT ); + llassert(!error); + + error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode); + + mRenderGlyphCount++; + + llassert(!error); +} + +void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi) +{ + if (!mIsFallback) + { + // This is the head of the list - need to rebuild ourself and all fallbacks. + loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mFontBitmapCachep->getNumComponents(), mIsFallback); + + if (mFallbackFonts.empty()) + { + llwarns << "LLFontGL::reset(), no fallback fonts present" << llendl; + } + else + { + for(font_vector_t::iterator it = mFallbackFonts.begin(); + it != mFallbackFonts.end(); + ++it) + { + (*it)->reset(vert_dpi, horz_dpi); + } + } + } + resetBitmapCache(); +} + +void LLFontFreetype::resetBitmapCache() +{ + // Iterate through glyphs and clear the mIsRendered flag + for (char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.begin(); + iter != mCharGlyphInfoMap.end(); ++iter) + { + iter->second->mIsRendered = FALSE; + //FIXME: this is only strictly necessary when resetting the entire font, + //not just flushing the bitmap + iter->second->mMetricsValid = FALSE; + } + mFontBitmapCachep->reset(); + + // Add the empty glyph`5 + addGlyph(0, 0); +} + +void LLFontFreetype::destroyGL() +{ + mFontBitmapCachep->destroyGL(); +} + +BOOL LLFontFreetype::getIsFallback() const +{ + return mIsFallback; +} + +const std::string &LLFontFreetype::getName() const +{ + return mName; +} + +F32 LLFontFreetype::getPointSize() const +{ + return mPointSize; +} + +const LLPointer LLFontFreetype::getFontBitmapCache() const +{ + return mFontBitmapCachep; +} + +void LLFontFreetype::setStyle(U8 style) +{ + mStyle = style; +} + +U8 LLFontFreetype::getStyle() const +{ + return mStyle; +} + +void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride) const +{ + LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num); + + llassert(!mIsFallback); + llassert(image_raw && (image_raw->getComponents() == 2)); + + + U8 *target = image_raw->getData(); + + if (!data) + { + return; + } + + if (0 == stride) + stride = width; + + U32 i, j; + U32 to_offset; + U32 from_offset; + U32 target_width = image_raw->getWidth(); + for (i = 0; i < height; i++) + { + to_offset = (y + i)*target_width + x; + from_offset = (height - 1 - i)*stride; + for (j = 0; j < width; j++) + { + *(target + to_offset*2 + 1) = *(data + from_offset); + to_offset++; + from_offset++; + } + } +} + diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h new file mode 100644 index 0000000000..0520ef2cd6 --- /dev/null +++ b/indra/llrender/llfontfreetype.h @@ -0,0 +1,380 @@ +/** + * @file llfontfreetype.h + * @brief Font library wrapper + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLFONTFREETYPE_H +#define LL_LLFONTFREETYPE_H + +#include +#include "llpointer.h" +#include "llstl.h" + +#include "llimagegl.h" +#include "llfontbitmapcache.h" + +// Hack. FT_Face is just a typedef for a pointer to a struct, +// but there's no simple forward declarations file for FreeType, +// and the main include file is 200K. +// We'll forward declare the struct here. JC +struct FT_FaceRec_; +typedef struct FT_FaceRec_* LLFT_Face; + +class LLFontManager +{ +public: + static void initClass(); + static void cleanupClass(); + +private: + LLFontManager(); + ~LLFontManager(); +}; + +class LLFontGlyphInfo +{ +public: + LLFontGlyphInfo(U32 index); + + U32 mGlyphIndex; + + // Metrics + S32 mWidth; // In pixels + S32 mHeight; // In pixels + F32 mXAdvance; // In pixels + F32 mYAdvance; // In pixels + BOOL mMetricsValid; // We have up-to-date metrics for this glyph + + // Information for actually rendering + BOOL mIsRendered; // We actually have rendered this glyph + S32 mXBitmapOffset; // Offset to the origin in the bitmap + S32 mYBitmapOffset; // Offset to the origin in the bitmap + S32 mXBearing; // Distance from baseline to left in pixels + S32 mYBearing; // Distance from baseline to top in pixels + S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph +}; + +extern LLFontManager *gFontManagerp; + +class LLFontFreetype : public LLRefCount +{ +public: + LLFontFreetype(); + ~LLFontFreetype(); + + // is_fallback should be true for fallback fonts that aren't used + // to render directly (Unicode backup, primarily) + BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback); + + typedef std::vector > font_vector_t; + + void setFallbackFonts(const font_vector_t &font); + const font_vector_t &getFallbackFonts() const; + + // Global font metrics - in units of pixels + F32 getLineHeight() const; + F32 getAscenderHeight() const; + F32 getDescenderHeight() const; + + +// For a lowercase "g": +// +// ------------------------------ +// ^ ^ +// | | +// xxx x |Ascender +// x x v | +// --------- xxxx-------------- Baseline +// ^ x | +// | Descender x | +// v xxxx |LineHeight +// ----------------------- | +// v +// ------------------------------ + + enum + { + FIRST_CHAR = 32, + NUM_CHARS = 127 - 32, + LAST_CHAR_BASIC = 127, + + // Need full 8-bit ascii range for spanish + NUM_CHARS_FULL = 255 - 32, + LAST_CHAR_FULL = 255 + }; + + F32 getXAdvance(llwchar wc) const; + F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters + + BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character + BOOL addChar(llwchar wch) const; // Add a new character to the font if necessary + BOOL addGlyph(llwchar wch, U32 glyph_index) const; // Add a new glyph to the existing font + BOOL addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) + + LLFontGlyphInfo* getGlyphInfo(llwchar wch) const; + + void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const; + void renderGlyph(U32 glyph_index) const; + + void reset(F32 vert_dpi, F32 horz_dpi); + void resetBitmapCache(); + + void destroyGL(); + + BOOL getIsFallback() const; + + const std::string& getName() const; + + F32 getPointSize() const; + + const LLPointer getFontBitmapCache() const; + + void setStyle(U8 style); + U8 getStyle() const; + +private: + void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const; + + std::string mName; + + U8 mStyle; + + F32 mPointSize; + F32 mAscender; + F32 mDescender; + F32 mLineHeight; + + LLFT_Face mFTFace; + + BOOL mIsFallback; + font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars) + + BOOL mValid; + + typedef std::map char_glyph_info_map_t; + mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap + + mutable LLPointer mFontBitmapCachep; + + mutable S32 mRenderGlyphCount; + mutable S32 mAddGlyphCount; +}; + +#endif // LL_FONTFREETYPE_H +/** + * @file llfontfreetype.h + * @brief Font library wrapper + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLFONTFREETYPE_H +#define LL_LLFONTFREETYPE_H + +#include +#include "llpointer.h" +#include "llstl.h" + +#include "llimagegl.h" +#include "llfontbitmapcache.h" + +// Hack. FT_Face is just a typedef for a pointer to a struct, +// but there's no simple forward declarations file for FreeType, +// and the main include file is 200K. +// We'll forward declare the struct here. JC +struct FT_FaceRec_; +typedef struct FT_FaceRec_* LLFT_Face; + +class LLFontManager +{ +public: + static void initClass(); + static void cleanupClass(); + +private: + LLFontManager(); + ~LLFontManager(); +}; + +class LLFontGlyphInfo +{ +public: + LLFontGlyphInfo(U32 index); + + U32 mGlyphIndex; + + // Metrics + S32 mWidth; // In pixels + S32 mHeight; // In pixels + F32 mXAdvance; // In pixels + F32 mYAdvance; // In pixels + BOOL mMetricsValid; // We have up-to-date metrics for this glyph + + // Information for actually rendering + BOOL mIsRendered; // We actually have rendered this glyph + S32 mXBitmapOffset; // Offset to the origin in the bitmap + S32 mYBitmapOffset; // Offset to the origin in the bitmap + S32 mXBearing; // Distance from baseline to left in pixels + S32 mYBearing; // Distance from baseline to top in pixels + S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph +}; + +extern LLFontManager *gFontManagerp; + +class LLFontFreetype : public LLRefCount +{ +public: + LLFontFreetype(); + ~LLFontFreetype(); + + // is_fallback should be true for fallback fonts that aren't used + // to render directly (Unicode backup, primarily) + BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback); + + typedef std::vector > font_vector_t; + + void setFallbackFonts(const font_vector_t &font); + const font_vector_t &getFallbackFonts() const; + + // Global font metrics - in units of pixels + F32 getLineHeight() const; + F32 getAscenderHeight() const; + F32 getDescenderHeight() const; + + +// For a lowercase "g": +// +// ------------------------------ +// ^ ^ +// | | +// xxx x |Ascender +// x x v | +// --------- xxxx-------------- Baseline +// ^ x | +// | Descender x | +// v xxxx |LineHeight +// ----------------------- | +// v +// ------------------------------ + + enum + { + FIRST_CHAR = 32, + NUM_CHARS = 127 - 32, + LAST_CHAR_BASIC = 127, + + // Need full 8-bit ascii range for spanish + NUM_CHARS_FULL = 255 - 32, + LAST_CHAR_FULL = 255 + }; + + F32 getXAdvance(llwchar wc) const; + F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters + + BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character + BOOL addChar(llwchar wch) const; // Add a new character to the font if necessary + BOOL addGlyph(llwchar wch, U32 glyph_index) const; // Add a new glyph to the existing font + BOOL addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) + + LLFontGlyphInfo* getGlyphInfo(llwchar wch) const; + + void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const; + void renderGlyph(U32 glyph_index) const; + + void reset(F32 vert_dpi, F32 horz_dpi); + void resetBitmapCache(); + + void destroyGL(); + + BOOL getIsFallback() const; + + const std::string& getName() const; + + F32 getPointSize() const; + + const LLPointer getFontBitmapCache() const; + + void setStyle(U8 style); + U8 getStyle() const; + +private: + void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const; + + std::string mName; + + U8 mStyle; + + F32 mPointSize; + F32 mAscender; + F32 mDescender; + F32 mLineHeight; + + LLFT_Face mFTFace; + + BOOL mIsFallback; + font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars) + + BOOL mValid; + + typedef std::map char_glyph_info_map_t; + mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap + + mutable LLPointer mFontBitmapCachep; + + mutable S32 mRenderGlyphCount; + mutable S32 mAddGlyphCount; +}; + +#endif // LL_FONTFREETYPE_H diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 048bfe8e0d..32a008047c 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -35,7 +35,7 @@ #include "llfontgl.h" // Linden library includes -#include "llfont.h" +#include "llfontfreetype.h" #include "llfontbitmapcache.h" #include "llfontregistry.h" #include "llgl.h" @@ -43,6 +43,7 @@ #include "llrender.h" #include "llstl.h" #include "v4color.h" +#include "lltexture.h" // Third party library includes #include @@ -72,54 +73,25 @@ const F32 PIXEL_CORRECTION_DISTANCE = 0.01f; const F32 PAD_UVY = 0.5f; // half of vertical padding between glyphs in the glyph texture const F32 DROP_SHADOW_SOFT_STRENGTH = 0.3f; -F32 llfont_round_x(F32 x) +static F32 llfont_round_x(F32 x) { //return llfloor((x-LLFontGL::sCurOrigin.mX)/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleX+LLFontGL::sCurOrigin.mX; //return llfloor(x/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleY; return x; } -F32 llfont_round_y(F32 y) +static F32 llfont_round_y(F32 y) { //return llfloor((y-LLFontGL::sCurOrigin.mY)/LLFontGL::sScaleY+0.5f)*LLFontGL::sScaleY+LLFontGL::sCurOrigin.mY; //return llfloor(y+0.5f); return y; } -// static -U8 LLFontGL::getStyleFromString(const std::string &style) -{ - S32 ret = 0; - if (style.find("NORMAL") != style.npos) - { - ret |= NORMAL; - } - if (style.find("BOLD") != style.npos) - { - ret |= BOLD; - } - if (style.find("ITALIC") != style.npos) - { - ret |= ITALIC; - } - if (style.find("UNDERLINE") != style.npos) - { - ret |= UNDERLINE; - } - return ret; -} - LLFontGL::LLFontGL() - : LLFont() { clearEmbeddedChars(); } -LLFontGL::LLFontGL(const LLFontGL &source) -{ - llerrs << "Not implemented!" << llendl; -} - LLFontGL::~LLFontGL() { clearEmbeddedChars(); @@ -127,293 +99,26 @@ LLFontGL::~LLFontGL() void LLFontGL::reset() { - if (!mIsFallback) - { - // This is the head of the list - need to rebuild ourself and all fallbacks. - loadFace(mName,mPointSize,sVertDPI,sHorizDPI,mFontBitmapCachep->getNumComponents(),mIsFallback); - if (mFallbackFontp==NULL) - { - llwarns << "LLFontGL::reset(), no fallback fonts present" << llendl; - } - else - { - for (LLFontList::iterator it = mFallbackFontp->begin(); - it != mFallbackFontp->end(); - ++it) - { - (*it)->reset(); - } - } - } - resetBitmapCache(); -} - -// static -std::string LLFontGL::getFontPathSystem() -{ - std::string system_path; - - // Try to figure out where the system's font files are stored. - char *system_root = NULL; -#if LL_WINDOWS - system_root = getenv("SystemRoot"); /* Flawfinder: ignore */ - if (!system_root) - { - llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl; - } -#endif - - if (system_root) - { - system_path = llformat("%s/fonts/", system_root); - } - else - { -#if LL_WINDOWS - // HACK for windows 98/Me - system_path = "/WINDOWS/FONTS/"; -#elif LL_DARWIN - // HACK for Mac OS X - system_path = "/System/Library/Fonts/"; -#endif - } - return system_path; -} - - -// static -std::string LLFontGL::getFontPathLocal() -{ - std::string local_path; - - // Backup files if we can't load from system fonts directory. - // We could store this in an end-user writable directory to allow - // end users to switch fonts. - if (LLFontGL::sAppDir.length()) - { - // use specified application dir to look for fonts - local_path = LLFontGL::sAppDir + "/fonts/"; - } - else - { - // assume working directory is executable directory - local_path = "./fonts/"; - } - return local_path; -} - -bool findOrCreateFont(LLFontGL*& fontp, const LLFontDescriptor& desc) -{ - // Don't delete existing fonts, if any, here, because they've - // already been deleted by LLFontRegistry::clear() - fontp = LLFontGL::getFont(desc); - return (fontp != NULL); -} - -// static -void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, - const std::string& app_dir, - const std::vector& xui_paths, - bool create_gl_textures) -{ - sVertDPI = (F32)llfloor(screen_dpi * y_scale); - sHorizDPI = (F32)llfloor(screen_dpi * x_scale); - sScaleX = x_scale; - sScaleY = y_scale; - sAppDir = app_dir; - - // Font registry init - if (!sFontRegistry) - { - sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures); - sFontRegistry->parseFontInfo("fonts.xml"); - } - else - { - sFontRegistry->reset(); - } -} - -// Force standard fonts to get generated up front. -// This is primarily for error detection purposes. -// Don't do this during initClass because it can be slow and we want to get -// the viewer window on screen first. JC -// static -bool LLFontGL::loadDefaultFonts() -{ - bool succ = true; - succ &= (NULL != getFontSansSerifSmall()); - succ &= (NULL != getFontSansSerif()); - succ &= (NULL != getFontSansSerifBig()); - succ &= (NULL != getFontSansSerifHuge()); - succ &= (NULL != getFontSansSerifBold()); - succ &= (NULL != getFontMonospace()); - succ &= (NULL != getFontExtChar()); - return succ; -} - - - -// static -void LLFontGL::destroyDefaultFonts() -{ - // Remove the actual fonts. - delete sFontRegistry; - sFontRegistry = NULL; -} - -//static -void LLFontGL::destroyAllGL() -{ - if (sFontRegistry) - { - sFontRegistry->destroyGL(); - } + mFontFreetype->reset(sVertDPI, sHorizDPI); } void LLFontGL::destroyGL() { - mFontBitmapCachep->destroyGL(); + mFontFreetype->destroyGL(); } - - -LLFontGL &LLFontGL::operator=(const LLFontGL &source) +BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) { - llerrs << "Not implemented" << llendl; - return *this; -} - -BOOL LLFontGL::loadFace(const std::string& filename, - const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, - const S32 components, BOOL is_fallback) -{ - if (!LLFont::loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback)) + if(mFontFreetype == reinterpret_cast(NULL)) { - return FALSE; - } - return TRUE; -} - -//static -LLFontGL* LLFontGL::getFontMonospace() -{ - return getFont(LLFontDescriptor("Monospace","Monospace",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerifSmall() -{ - return getFont(LLFontDescriptor("SansSerif","Small",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerif() -{ - return getFont(LLFontDescriptor("SansSerif","Medium",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerifBig() -{ - return getFont(LLFontDescriptor("SansSerif","Large",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerifHuge() -{ - return getFont(LLFontDescriptor("SansSerif","Huge",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerifBold() -{ - return getFont(LLFontDescriptor("SansSerif","Medium",BOLD)); -} - -//static -LLFontGL* LLFontGL::getFontExtChar() -{ - return getFontSansSerif(); -} - -//static -LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc) -{ - return sFontRegistry->getFont(desc); -} - -//static -LLFontGL* LLFontGL::getFontByName(const std::string& name) -{ - // check for most common fonts first - if (name == "SANSSERIF") - { - return getFontSansSerif(); - } - else if (name == "SANSSERIF_SMALL") - { - return getFontSansSerifSmall(); - } - else if (name == "SANSSERIF_BIG") - { - return getFontSansSerifBig(); - } - else if (name == "SMALL" || name == "OCRA") - { - // *BUG: Should this be "MONOSPACE"? Do we use "OCRA" anymore? - // Does "SMALL" mean "SERIF"? - return getFontMonospace(); - } - else - { - return NULL; - } -} - -BOOL LLFontGL::addChar(const llwchar wch) const -{ - if (!LLFont::addChar(wch)) - { - return FALSE; + mFontFreetype = new LLFontFreetype; } - stop_glerror(); - - LLFontGlyphInfo *glyph_info = getGlyphInfo(wch); - U32 bitmap_num = glyph_info->mBitmapNum; - LLImageGL *image_gl = mFontBitmapCachep->getImageGL(bitmap_num); - LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num); - image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight()); - return TRUE; + return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback); } - -S32 LLFontGL::renderUTF8(const std::string &text, const S32 offset, - const F32 x, const F32 y, - const LLColor4 &color, - const HAlign halign, const VAlign valign, - U8 style, - ShadowType shadow, - const S32 max_chars, const S32 max_pixels, - F32* right_x, - BOOL use_ellipses) const -{ - LLWString wstr = utf8str_to_wstring(text); - return render(wstr, offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, FALSE, use_ellipses); -} - -S32 LLFontGL::render(const LLWString &wstr, - const S32 begin_offset, - const F32 x, const F32 y, - const LLColor4 &color, - const HAlign halign, const VAlign valign, - U8 style, - ShadowType shadow, - const S32 max_chars, S32 max_pixels, - F32* right_x, - BOOL use_embedded, - BOOL use_ellipses) const +S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, + ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_embedded, BOOL use_ellipses) const { if(!sDisplayFont) //do not display texts { @@ -429,8 +134,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX); - // Strip off any style bits that are already accounted for by the font. - style = style & (~getFontDesc().getStyle()); + // determine which style flags need to be added programmatically by striping off the + // style bits that are drawn by the underlying Freetype font + U8 style_to_add = (style | mFontDescriptor.getStyle()) & ~mFontFreetype->getStyle(); F32 drop_shadow_strength = 0.f; if (shadow != NO_SHADOW) @@ -482,13 +188,13 @@ S32 LLFontGL::render(const LLWString &wstr, switch (valign) { case TOP: - cur_y -= mAscender; + cur_y -= mFontFreetype->getAscenderHeight(); break; case BOTTOM: - cur_y += mDescender; + cur_y += mFontFreetype->getDescenderHeight(); break; case VCENTER: - cur_y -= ((mAscender - mDescender)/2.f); + cur_y -= ((mFontFreetype->getAscenderHeight() - mFontFreetype->getDescenderHeight())/2.f); break; case BASELINE: // Baseline, do nothing. @@ -516,10 +222,12 @@ S32 LLFontGL::render(const LLWString &wstr, F32 start_x = cur_x; - F32 inv_width = 1.f / mFontBitmapCachep->getBitmapWidth(); - F32 inv_height = 1.f / mFontBitmapCachep->getBitmapHeight(); + const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); - const S32 LAST_CHARACTER = LLFont::LAST_CHAR_FULL; + F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth(); + F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight(); + + const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL; BOOL draw_ellipses = FALSE; @@ -575,11 +283,11 @@ S32 LLFontGL::render(const LLWString &wstr, // snap origin to whole screen pixel const F32 ext_x = (F32)llround(cur_render_x + (EXT_X_BEARING * sScaleX)); - const F32 ext_y = (F32)llround(cur_render_y + (EXT_Y_BEARING * sScaleY + mAscender - mLineHeight)); + const F32 ext_y = (F32)llround(cur_render_y + (EXT_Y_BEARING * sScaleY + mFontFreetype->getAscenderHeight() - mFontFreetype->getLineHeight())); LLRectf uv_rect(0.f, 1.f, 1.f, 0.f); LLRectf screen_rect(ext_x, ext_y + ext_height, ext_x + ext_width, ext_y); - drawGlyph(screen_rect, uv_rect, LLColor4::white, style, shadow, drop_shadow_strength); + drawGlyph(screen_rect, uv_rect, LLColor4::white, style_to_add, shadow, drop_shadow_strength); if (!label.empty()) { @@ -608,19 +316,19 @@ S32 LLFontGL::render(const LLWString &wstr, } else { - if (!hasGlyph(wch)) + if (!mFontFreetype->hasGlyph(wch)) { addChar(wch); } - const LLFontGlyphInfo* fgi= getGlyphInfo(wch); + const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch); if (!fgi) { llerrs << "Missing Glyph Info" << llendl; break; } // Per-glyph bitmap texture. - LLImageGL *image_gl = mFontBitmapCachep->getImageGL(fgi->mBitmapNum); + LLImageGL *image_gl = mFontFreetype->getFontBitmapCache()->getImageGL(fgi->mBitmapNum); if (last_bound_texture != image_gl) { gGL.getTexUnit(0)->bind(image_gl); @@ -645,7 +353,7 @@ S32 LLFontGL::render(const LLWString &wstr, llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth, llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight); - drawGlyph(screen_rect, uv_rect, color, style, shadow, drop_shadow_strength); + drawGlyph(screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength); chars_drawn++; cur_x += fgi->mXAdvance; @@ -655,11 +363,11 @@ S32 LLFontGL::render(const LLWString &wstr, if (next_char && (next_char < LAST_CHARACTER)) { // Kern this puppy. - if (!hasGlyph(next_char)) + if (!mFontFreetype->hasGlyph(next_char)) { addChar(next_char); } - cur_x += getXKerning(wch, next_char); + cur_x += mFontFreetype->getXKerning(wch, next_char); } // Round after kerning. @@ -679,12 +387,14 @@ S32 LLFontGL::render(const LLWString &wstr, *right_x = cur_x / sScaleX; } - if (style & UNDERLINE) + if (style_to_add & UNDERLINE) { + F32 descender = mFontFreetype->getDescenderHeight(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.begin(LLRender::LINES); - gGL.vertex2f(start_x, cur_y - (mDescender)); - gGL.vertex2f(cur_x, cur_y - (mDescender)); + gGL.vertex2f(start_x, cur_y - (descender)); + gGL.vertex2f(cur_x, cur_y - (descender)); gGL.end(); } @@ -702,7 +412,7 @@ S32 LLFontGL::render(const LLWString &wstr, cur_x / sScaleX, (F32)y, color, LEFT, valign, - style, + style_to_add, shadow, S32_MAX, max_pixels, right_x, @@ -715,6 +425,41 @@ S32 LLFontGL::render(const LLWString &wstr, return chars_drawn; } +S32 LLFontGL::render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const +{ + return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE, FALSE); +} + +S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const +{ + return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, FALSE, use_ellipses); +} + +S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const +{ + return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE); +} + +S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow) const +{ + return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow, S32_MAX, S32_MAX, NULL, FALSE); +} + +// font metrics - override for LLFontFreetype that returns units of virtual pixels +F32 LLFontGL::getLineHeight() const +{ + return (F32)llround(mFontFreetype->getLineHeight() / sScaleY); +} + +F32 LLFontGL::getAscenderHeight() const +{ + return (F32)llround(mFontFreetype->getAscenderHeight() / sScaleY); +} + +F32 LLFontGL::getDescenderHeight() const +{ + return (F32)llround(mFontFreetype->getDescenderHeight() / sScaleY); +} S32 LLFontGL::getWidth(const std::string& utf8text) const { @@ -727,13 +472,13 @@ S32 LLFontGL::getWidth(const llwchar* wchars) const return getWidth(wchars, 0, S32_MAX); } -S32 LLFontGL::getWidth(const std::string& utf8text, const S32 begin_offset, const S32 max_chars) const +S32 LLFontGL::getWidth(const std::string& utf8text, S32 begin_offset, S32 max_chars) const { LLWString wtext = utf8str_to_wstring(utf8text); return getWidth(wtext.c_str(), begin_offset, max_chars); } -S32 LLFontGL::getWidth(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const +S32 LLFontGL::getWidth(const llwchar* wchars, S32 begin_offset, S32 max_chars, BOOL use_embedded) const { F32 width = getWidthF32(wchars, begin_offset, max_chars, use_embedded); return llround(width); @@ -750,15 +495,15 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars) const return getWidthF32(wchars, 0, S32_MAX); } -F32 LLFontGL::getWidthF32(const std::string& utf8text, const S32 begin_offset, const S32 max_chars ) const +F32 LLFontGL::getWidthF32(const std::string& utf8text, S32 begin_offset, S32 max_chars ) const { LLWString wtext = utf8str_to_wstring(utf8text); return getWidthF32(wtext.c_str(), begin_offset, max_chars); } -F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const +F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars, BOOL use_embedded) const { - const S32 LAST_CHARACTER = LLFont::LAST_CHAR_FULL; + const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL; F32 cur_x = 0; const S32 max_index = begin_offset + max_chars; @@ -782,7 +527,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S } else { - cur_x += getXAdvance(wch); + cur_x += mFontFreetype->getXAdvance(wch); llwchar next_char = wchars[i+1]; if (((i + 1) < max_chars) @@ -790,7 +535,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S && (next_char < LAST_CHARACTER)) { // Kern this puppy. - cur_x += getXKerning(wch, next_char); + cur_x += mFontFreetype->getXKerning(wch, next_char); } } // Round after kerning. @@ -800,12 +545,8 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S return cur_x / sScaleX; } - - // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels -S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, - BOOL end_on_word_boundary, const BOOL use_embedded, - F32* drawn_pixels) const +S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, BOOL end_on_word_boundary, BOOL use_embedded, F32* drawn_pixels) const { if (!wchars || !wchars[0] || max_chars == 0) { @@ -898,7 +639,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch } } - cur_x += getXAdvance(wch); + cur_x += mFontFreetype->getXAdvance(wch); if (scaled_max_pixels < cur_x) { @@ -909,7 +650,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch if (((i+1) < max_chars) && wchars[i+1]) { // Kern this puppy. - cur_x += getXKerning(wch, wchars[i+1]); + cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]); } } // Round after kerning. @@ -928,7 +669,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch return i; } - S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos, S32 max_chars) const { if (!wchars || !wchars[0] || max_chars == 0) @@ -947,7 +687,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ llwchar wch = wchars[i]; const embedded_data_t* ext_data = getEmbeddedCharData(wch); - F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : getXAdvance(wch); + F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : mFontFreetype->getXAdvance(wch); if( scaled_max_pixels < (total_width + char_width) ) { @@ -965,7 +705,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ if ( i > 0 ) { // kerning - total_width += ext_data ? (EXT_KERNING * sScaleX) : getXKerning(wchars[i-1], wch); + total_width += ext_data ? (EXT_KERNING * sScaleX) : mFontFreetype->getXKerning(wchars[i-1], wch); } // Round after kerning. @@ -975,8 +715,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ return start_pos - drawable_chars; } - -S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const +S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const { if (!wchars || !wchars[0] || max_chars == 0) { @@ -1040,7 +779,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, } else { - F32 char_width = getXAdvance(wch); + F32 char_width = mFontFreetype->getXAdvance(wch); if (round) { @@ -1069,7 +808,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, { llwchar next_char = wchars[i + 1]; // Kern this puppy. - cur_x += getXKerning(wch, next_char); + cur_x += mFontFreetype->getXKerning(wch, next_char); } // Round after kerning. @@ -1080,8 +819,342 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, return pos; } +void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label ) const +{ + LLWString wlabel = utf8str_to_wstring(label); + addEmbeddedChar(wc, image, wlabel); +} -const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(const llwchar wch) const +void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& wlabel ) const +{ + embedded_data_t* ext_data = new embedded_data_t(image->getGLTexture(), wlabel); + mEmbeddedChars[wc] = ext_data; +} + +void LLFontGL::removeEmbeddedChar(llwchar wc) const +{ + embedded_map_t::iterator iter = mEmbeddedChars.find(wc); + if (iter != mEmbeddedChars.end()) + { + delete iter->second; + mEmbeddedChars.erase(wc); + } +} + +BOOL LLFontGL::addChar(llwchar wch) const +{ + if (!mFontFreetype->addChar(wch)) + { + return FALSE; + } + + stop_glerror(); + + LLFontGlyphInfo *glyph_info = mFontFreetype->getGlyphInfo(wch); + U32 bitmap_num = glyph_info->mBitmapNum; + + const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); + LLImageGL *image_gl = font_bitmap_cache->getImageGL(bitmap_num); + LLImageRaw *image_raw = font_bitmap_cache->getImageRaw(bitmap_num); + image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight()); + return TRUE; +} + +const LLFontDescriptor& LLFontGL::getFontDesc() const +{ + return mFontDescriptor; +} + +// static +void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector& xui_paths, bool create_gl_textures) +{ + sVertDPI = (F32)llfloor(screen_dpi * y_scale); + sHorizDPI = (F32)llfloor(screen_dpi * x_scale); + sScaleX = x_scale; + sScaleY = y_scale; + sAppDir = app_dir; + + // Font registry init + if (!sFontRegistry) + { + sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures); + sFontRegistry->parseFontInfo("fonts.xml"); + } + else + { + sFontRegistry->reset(); + } +} + +// Force standard fonts to get generated up front. +// This is primarily for error detection purposes. +// Don't do this during initClass because it can be slow and we want to get +// the viewer window on screen first. JC +// static +bool LLFontGL::loadDefaultFonts() +{ + bool succ = true; + succ &= (NULL != getFontSansSerifSmall()); + succ &= (NULL != getFontSansSerif()); + succ &= (NULL != getFontSansSerifBig()); + succ &= (NULL != getFontSansSerifHuge()); + succ &= (NULL != getFontSansSerifBold()); + succ &= (NULL != getFontMonospace()); + succ &= (NULL != getFontExtChar()); + return succ; +} + +// static +void LLFontGL::destroyDefaultFonts() +{ + // Remove the actual fonts. + delete sFontRegistry; + sFontRegistry = NULL; +} + +//static +void LLFontGL::destroyAllGL() +{ + if (sFontRegistry) + { + sFontRegistry->destroyGL(); + } +} + +// static +U8 LLFontGL::getStyleFromString(const std::string &style) +{ + S32 ret = 0; + if (style.find("NORMAL") != style.npos) + { + ret |= NORMAL; + } + if (style.find("BOLD") != style.npos) + { + ret |= BOLD; + } + if (style.find("ITALIC") != style.npos) + { + ret |= ITALIC; + } + if (style.find("UNDERLINE") != style.npos) + { + ret |= UNDERLINE; + } + return ret; +} + +// static +std::string LLFontGL::nameFromFont(const LLFontGL* fontp) +{ + return fontp->mFontDescriptor.getName(); +} + +// static +std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align) +{ + if (align == LEFT) return std::string("left"); + else if (align == RIGHT) return std::string("right"); + else if (align == HCENTER) return std::string("center"); + else return std::string(); +} + +// static +LLFontGL::HAlign LLFontGL::hAlignFromName(const std::string& name) +{ + LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT; + if (name == "left") + { + gl_hfont_align = LLFontGL::LEFT; + } + else if (name == "right") + { + gl_hfont_align = LLFontGL::RIGHT; + } + else if (name == "center") + { + gl_hfont_align = LLFontGL::HCENTER; + } + //else leave left + return gl_hfont_align; +} + +// static +std::string LLFontGL::nameFromVAlign(LLFontGL::VAlign align) +{ + if (align == TOP) return std::string("top"); + else if (align == VCENTER) return std::string("center"); + else if (align == BASELINE) return std::string("baseline"); + else if (align == BOTTOM) return std::string("bottom"); + else return std::string(); +} + +// static +LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name) +{ + LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE; + if (name == "top") + { + gl_vfont_align = LLFontGL::TOP; + } + else if (name == "center") + { + gl_vfont_align = LLFontGL::VCENTER; + } + else if (name == "baseline") + { + gl_vfont_align = LLFontGL::BASELINE; + } + else if (name == "bottom") + { + gl_vfont_align = LLFontGL::BOTTOM; + } + //else leave baseline + return gl_vfont_align; +} + +//static +LLFontGL* LLFontGL::getFontMonospace() +{ + return getFont(LLFontDescriptor("Monospace","Monospace",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerifSmall() +{ + return getFont(LLFontDescriptor("SansSerif","Small",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerif() +{ + return getFont(LLFontDescriptor("SansSerif","Medium",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerifBig() +{ + return getFont(LLFontDescriptor("SansSerif","Large",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerifHuge() +{ + return getFont(LLFontDescriptor("SansSerif","Huge",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerifBold() +{ + return getFont(LLFontDescriptor("SansSerif","Medium",BOLD)); +} + +//static +LLFontGL* LLFontGL::getFontExtChar() +{ + return getFontSansSerif(); +} + +//static +LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc) +{ + return sFontRegistry->getFont(desc); +} + +//static +LLFontGL* LLFontGL::getFontByName(const std::string& name) +{ + // check for most common fonts first + if (name == "SANSSERIF") + { + return getFontSansSerif(); + } + else if (name == "SANSSERIF_SMALL") + { + return getFontSansSerifSmall(); + } + else if (name == "SANSSERIF_BIG") + { + return getFontSansSerifBig(); + } + else if (name == "SMALL" || name == "OCRA") + { + // *BUG: Should this be "MONOSPACE"? Do we use "OCRA" anymore? + // Does "SMALL" mean "SERIF"? + return getFontMonospace(); + } + else + { + return NULL; + } +} + +// static +std::string LLFontGL::getFontPathSystem() +{ + std::string system_path; + + // Try to figure out where the system's font files are stored. + char *system_root = NULL; +#if LL_WINDOWS + system_root = getenv("SystemRoot"); /* Flawfinder: ignore */ + if (!system_root) + { + llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl; + } +#endif + + if (system_root) + { + system_path = llformat("%s/fonts/", system_root); + } + else + { +#if LL_WINDOWS + // HACK for windows 98/Me + system_path = "/WINDOWS/FONTS/"; +#elif LL_DARWIN + // HACK for Mac OS X + system_path = "/System/Library/Fonts/"; +#endif + } + return system_path; +} + + +// static +std::string LLFontGL::getFontPathLocal() +{ + std::string local_path; + + // Backup files if we can't load from system fonts directory. + // We could store this in an end-user writable directory to allow + // end users to switch fonts. + if (LLFontGL::sAppDir.length()) + { + // use specified application dir to look for fonts + local_path = LLFontGL::sAppDir + "/fonts/"; + } + else + { + // assume working directory is executable directory + local_path = "./fonts/"; + } + return local_path; +} + +LLFontGL::LLFontGL(const LLFontGL &source) +{ + llerrs << "Not implemented!" << llendl; +} + +LLFontGL &LLFontGL::operator=(const LLFontGL &source) +{ + llerrs << "Not implemented" << llendl; + return *this; +} + +const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(llwchar wch) const { // Handle crappy embedded hack embedded_map_t::const_iterator iter = mEmbeddedChars.find(wch); @@ -1092,7 +1165,6 @@ const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(const llwchar wch return NULL; } - F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const { const LLWString& label = ext_data->mLabel; @@ -1107,35 +1179,12 @@ F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const return (EXT_X_BEARING * sScaleX) + ext_width; } - void LLFontGL::clearEmbeddedChars() { for_each(mEmbeddedChars.begin(), mEmbeddedChars.end(), DeletePairedPointer()); mEmbeddedChars.clear(); } -void LLFontGL::addEmbeddedChar( llwchar wc, LLImageGL* image, const std::string& label ) const -{ - LLWString wlabel = utf8str_to_wstring(label); - addEmbeddedChar(wc, image, wlabel); -} - -void LLFontGL::addEmbeddedChar( llwchar wc, LLImageGL* image, const LLWString& wlabel ) const -{ - embedded_data_t* ext_data = new embedded_data_t(image, wlabel); - mEmbeddedChars[wc] = ext_data; -} - -void LLFontGL::removeEmbeddedChar( llwchar wc ) const -{ - embedded_map_t::iterator iter = mEmbeddedChars.find(wc); - if (iter != mEmbeddedChars.end()) - { - delete iter->second; - mEmbeddedChars.erase(wc); - } -} - void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const { @@ -1159,7 +1208,7 @@ void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F3 void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const { F32 slant_offset; - slant_offset = ((style & ITALIC) ? ( -mAscender * 0.2f) : 0.f); + slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f); gGL.begin(LLRender::QUADS); { @@ -1229,71 +1278,3 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con } gGL.end(); } - -std::string LLFontGL::nameFromFont(const LLFontGL* fontp) -{ - return fontp->getFontDesc().getName(); -} - -// static -std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align) -{ - if (align == LEFT) return std::string("left"); - else if (align == RIGHT) return std::string("right"); - else if (align == HCENTER) return std::string("center"); - else return std::string(); -} - -// static -LLFontGL::HAlign LLFontGL::hAlignFromName(const std::string& name) -{ - LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT; - if (name == "left") - { - gl_hfont_align = LLFontGL::LEFT; - } - else if (name == "right") - { - gl_hfont_align = LLFontGL::RIGHT; - } - else if (name == "center") - { - gl_hfont_align = LLFontGL::HCENTER; - } - //else leave left - return gl_hfont_align; -} - -// static -std::string LLFontGL::nameFromVAlign(LLFontGL::VAlign align) -{ - if (align == TOP) return std::string("top"); - else if (align == VCENTER) return std::string("center"); - else if (align == BASELINE) return std::string("baseline"); - else if (align == BOTTOM) return std::string("bottom"); - else return std::string(); -} - -// static -LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name) -{ - LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE; - if (name == "top") - { - gl_vfont_align = LLFontGL::TOP; - } - else if (name == "center") - { - gl_vfont_align = LLFontGL::VCENTER; - } - else if (name == "baseline") - { - gl_vfont_align = LLFontGL::BASELINE; - } - else if (name == "bottom") - { - gl_vfont_align = LLFontGL::BOTTOM; - } - //else leave baseline - return gl_vfont_align; -} diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 204c6908af..42ed7a381f 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -35,21 +35,21 @@ #define LL_LLFONTGL_H #include "llcoord.h" -#include "llfont.h" #include "llfontregistry.h" +#include "llimagegl.h" #include "llpointer.h" #include "llrect.h" #include "v2math.h" class LLColor4; -class LLImageGL; // Key used to request a font. class LLFontDescriptor; +class LLFontFreetype; // Structure used to store previously requested fonts. class LLFontRegistry; -class LLFontGL : public LLFont +class LLFontGL { public: enum HAlign @@ -85,130 +85,72 @@ public: DROP_SHADOW, DROP_SHADOW_SOFT }; - - // Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC" - static U8 getStyleFromString(const std::string &style); LLFontGL(); - LLFontGL(const LLFontGL &source); ~LLFontGL(); - void init(); // Internal init, or reinitialization + void reset(); // Reset a font after GL cleanup. ONLY works on an already loaded font. - LLFontGL &operator=(const LLFontGL &source); + void destroyGL(); - static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, - const std::string& app_dir, - const std::vector& xui_paths, - bool create_gl_textures = true); + BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback); + + S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign = LEFT, VAlign valign = BASELINE, U8 style = NORMAL, + ShadowType shadow = NO_SHADOW, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x=NULL, BOOL use_embedded = FALSE, BOOL use_ellipses = FALSE) const; + S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const; + + // renderUTF8 does a conversion, so is slower! + S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const; + S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const; + S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const; + + // font metrics - override for LLFontFreetype that returns units of virtual pixels + F32 getLineHeight() const; + F32 getAscenderHeight() const; + F32 getDescenderHeight() const; + + S32 getWidth(const std::string& utf8text) const; + S32 getWidth(const llwchar* wchars) const; + S32 getWidth(const std::string& utf8text, S32 offset, S32 max_chars ) const; + S32 getWidth(const llwchar* wchars, S32 offset, S32 max_chars, BOOL use_embedded = FALSE) const; + + F32 getWidthF32(const std::string& utf8text) const; + F32 getWidthF32(const llwchar* wchars) const; + F32 getWidthF32(const std::string& text, S32 offset, S32 max_chars ) const; + F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars, BOOL use_embedded = FALSE ) const; + + // The following are called often, frequently with large buffers, so do not use a string interface + + // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels + S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, BOOL end_on_word_boundary = FALSE, BOOL use_embedded = FALSE, F32* drawn_pixels = NULL) const; + + // Returns the index of the first complete characters from text that can be drawn in max_pixels + // given that the character at start_pos should be the last character (or as close to last as possible). + S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const; + + // Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars) + S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE, BOOL use_embedded = FALSE) const; + + void addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label) const; + void addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const; + void removeEmbeddedChar( llwchar wc ) const; + + BOOL addChar(const llwchar wch) const; + + const LLFontDescriptor& getFontDesc() const; + + + static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector& xui_paths, bool create_gl_textures = true); // Load sans-serif, sans-serif-small, etc. // Slow, requires multiple seconds to load fonts. static bool loadDefaultFonts(); static void destroyDefaultFonts(); static void destroyAllGL(); - void destroyGL(); - /* virtual*/ BOOL loadFace(const std::string& filename, - const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, - const S32 components, BOOL is_fallback); - - - S32 renderUTF8(const std::string &text, const S32 begin_offset, - S32 x, S32 y, - const LLColor4 &color) const - { - return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, - LEFT, BASELINE, NORMAL, NO_SHADOW, - S32_MAX, S32_MAX, NULL, FALSE); - } - - S32 renderUTF8(const std::string &text, const S32 begin_offset, - S32 x, S32 y, - const LLColor4 &color, - HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const - { - return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, - halign, valign, style, shadow, - S32_MAX, S32_MAX, NULL, FALSE); - } - - // renderUTF8 does a conversion, so is slower! - S32 renderUTF8(const std::string &text, - S32 begin_offset, - F32 x, F32 y, - const LLColor4 &color, - HAlign halign, - VAlign valign, - U8 style, - ShadowType shadow, - S32 max_chars, - S32 max_pixels, - F32* right_x, - BOOL use_ellipses) const; - - S32 render(const LLWString &text, const S32 begin_offset, - F32 x, F32 y, - const LLColor4 &color) const - { - return render(text, begin_offset, x, y, color, - LEFT, BASELINE, NORMAL, NO_SHADOW, - S32_MAX, S32_MAX, NULL, FALSE, FALSE); - } - - - S32 render(const LLWString &text, - S32 begin_offset, - F32 x, F32 y, - const LLColor4 &color, - HAlign halign = LEFT, - VAlign valign = BASELINE, - U8 style = NORMAL, - ShadowType shadow = NO_SHADOW, - S32 max_chars = S32_MAX, - S32 max_pixels = S32_MAX, - F32* right_x=NULL, - BOOL use_embedded = FALSE, - BOOL use_ellipses = FALSE) const; - - // font metrics - override for LLFont that returns units of virtual pixels - /*virtual*/ F32 getLineHeight() const { return (F32)llround(mLineHeight / sScaleY); } - /*virtual*/ F32 getAscenderHeight() const { return (F32)llround(mAscender / sScaleY); } - /*virtual*/ F32 getDescenderHeight() const { return (F32)llround(mDescender / sScaleY); } - - virtual S32 getWidth(const std::string& utf8text) const; - virtual S32 getWidth(const llwchar* wchars) const; - virtual S32 getWidth(const std::string& utf8text, const S32 offset, const S32 max_chars ) const; - virtual S32 getWidth(const llwchar* wchars, const S32 offset, const S32 max_chars, BOOL use_embedded = FALSE) const; - - virtual F32 getWidthF32(const std::string& utf8text) const; - virtual F32 getWidthF32(const llwchar* wchars) const; - virtual F32 getWidthF32(const std::string& text, const S32 offset, const S32 max_chars ) const; - virtual F32 getWidthF32(const llwchar* wchars, const S32 offset, const S32 max_chars, BOOL use_embedded = FALSE ) const; - - // The following are called often, frequently with large buffers, so do not use a string interface - - // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels - virtual S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, - BOOL end_on_word_boundary = FALSE, const BOOL use_embedded = FALSE, - F32* drawn_pixels = NULL) const; - - // Returns the index of the first complete characters from text that can be drawn in max_pixels - // given that the character at start_pos should be the last character (or as close to last as possible). - virtual S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const; - - // Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars) - virtual S32 charFromPixelOffset(const llwchar* wchars, const S32 char_offset, - F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, - BOOL round = TRUE, BOOL use_embedded = FALSE) const; - - - LLImageGL *getImageGL() const; - - void addEmbeddedChar( llwchar wc, LLImageGL* image, const std::string& label) const; - void addEmbeddedChar( llwchar wc, LLImageGL* image, const LLWString& label) const; - void removeEmbeddedChar( llwchar wc ) const; + // Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC" + static U8 getStyleFromString(const std::string &style); static std::string nameFromFont(const LLFontGL* fontp); @@ -218,28 +160,7 @@ public: static std::string nameFromVAlign(LLFontGL::VAlign align); static LLFontGL::VAlign vAlignFromName(const std::string& name); - static void setFontDisplay(BOOL flag) { sDisplayFont = flag ; } - -protected: - struct embedded_data_t - { - embedded_data_t(LLImageGL* image, const LLWString& label) : mImage(image), mLabel(label) {} - LLPointer mImage; - LLWString mLabel; - }; - const embedded_data_t* getEmbeddedCharData(const llwchar wch) const; - F32 getEmbeddedCharAdvance(const embedded_data_t* ext_data) const; - void clearEmbeddedChars(); - void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const; - void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const; - -public: - static F32 sVertDPI; - static F32 sHorizDPI; - static F32 sScaleX; - static F32 sScaleY; - static BOOL sDisplayFont ; - static std::string sAppDir; // For loading fonts + static void setFontDisplay(BOOL flag) { sDisplayFont = flag; } static LLFontGL* getFontMonospace(); static LLFontGL* getFontSansSerifSmall(); @@ -252,32 +173,50 @@ public: // Use with legacy names like "SANSSERIF_SMALL" or "OCRA" static LLFontGL* getFontByName(const std::string& name); - static LLColor4 sShadowColor; - - friend class LLTextBillboard; - friend class LLHUDText; - -protected: - /*virtual*/ BOOL addChar(const llwchar wch) const; - -protected: - typedef std::map embedded_map_t; - mutable embedded_map_t mEmbeddedChars; - - LLFontDescriptor mFontDesc; - - // Registry holds all instantiated fonts. - static LLFontRegistry* sFontRegistry; - -public: static std::string getFontPathLocal(); static std::string getFontPathSystem(); static LLCoordFont sCurOrigin; static std::vector sOriginStack; - const LLFontDescriptor &getFontDesc() const { return mFontDesc; } - void setFontDesc(const LLFontDescriptor& font_desc) { mFontDesc = font_desc; } + static LLColor4 sShadowColor; + + static F32 sVertDPI; + static F32 sHorizDPI; + static F32 sScaleX; + static F32 sScaleY; + static BOOL sDisplayFont ; + static std::string sAppDir; // For loading fonts + +private: + friend class LLFontRegistry; + friend class LLTextBillboard; + friend class LLHUDText; + + LLFontGL(const LLFontGL &source); + LLFontGL &operator=(const LLFontGL &source); + + LLFontDescriptor mFontDescriptor; + LLPointer mFontFreetype; + + struct embedded_data_t + { + embedded_data_t(LLImageGL* image, const LLWString& label) : mImage(image), mLabel(label) {} + LLPointer mImage; + LLWString mLabel; + }; + + typedef std::map embedded_map_t; + mutable embedded_map_t mEmbeddedChars; + + const embedded_data_t* getEmbeddedCharData(llwchar wch) const; + F32 getEmbeddedCharAdvance(const embedded_data_t* ext_data) const; + void clearEmbeddedChars(); + void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const; + void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const; + + // Registry holds all instantiated fonts. + static LLFontRegistry* sFontRegistry; }; #endif diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 455a68ca81..553e7b8f9d 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -33,8 +33,9 @@ #include "linden_common.h" #include "llgl.h" -#include "llfontregistry.h" +#include "llfontfreetype.h" #include "llfontgl.h" +#include "llfontregistry.h" #include #include "llcontrol.h" #include "lldir.h" @@ -104,7 +105,7 @@ bool removeSubString(std::string& str, const std::string& substr) size_t pos = str.find(substr); if (pos != string::npos) { - str.replace(pos,substr.length(), "", 0); + str.erase(pos); return true; } return false; @@ -382,7 +383,14 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) if (it != mFontMap.end()) { llinfos << "-- matching font exists: " << nearest_exact_desc.getName() << " size " << nearest_exact_desc.getSize() << " style " << ((S32) nearest_exact_desc.getStyle()) << llendl; - return it->second; + + // copying underlying Freetype font, and storing in LLFontGL with requested font descriptor + LLFontGL *font = new LLFontGL; + font->mFontDescriptor = desc; + font->mFontFreetype = it->second->mFontFreetype; + mFontMap[desc] = font; + + return font; } // Build list of font names to look for. @@ -410,10 +418,11 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) llwarns << "createFont failed, no file names specified" << llendl; return NULL; } - LLFontList *fontlistp = new LLFontList; + + LLFontFreetype::font_vector_t fontlist; LLFontGL *result = NULL; - // Snarf all fonts we can into fontlistp. First will get pulled + // Snarf all fonts we can into fontlist. First will get pulled // off the list and become the "head" font, set to non-fallback. // Rest will consitute the fallback list. BOOL is_first_found = TRUE; @@ -455,23 +464,28 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) is_first_found = false; } else - fontlistp->addAtEnd(fontp); + { + fontlist.push_back(fontp->mFontFreetype); + } } } - if (result && !fontlistp->empty()) + + if (result && !fontlist.empty()) { - result->setFallbackFont(fontlistp); + result->mFontFreetype->setFallbackFonts(fontlist); } - norm_desc.setStyle(match_desc->getStyle()); if (result) - result->setFontDesc(norm_desc); - - if (!result) + { + result->mFontFreetype->setStyle(match_desc->getStyle()); + result->mFontDescriptor = desc; + } + else { llwarns << "createFont failed in some way" << llendl; } - mFontMap[norm_desc] = result; + + mFontMap[desc] = result; return result; } @@ -511,21 +525,19 @@ void LLFontRegistry::destroyGL() } } -LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& orig_desc) +LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& desc) { - LLFontDescriptor norm_desc = orig_desc.normalize(); - - font_reg_map_t::iterator it = mFontMap.find(norm_desc); + font_reg_map_t::iterator it = mFontMap.find(desc); if (it != mFontMap.end()) return it->second; else { - LLFontGL *fontp = createFont(orig_desc); + LLFontGL *fontp = createFont(desc); if (!fontp) { - llwarns << "getFont failed, name " << orig_desc.getName() - <<" style=[" << ((S32) orig_desc.getStyle()) << "]" - << " size=[" << orig_desc.getSize() << "]" << llendl; + llwarns << "getFont failed, name " << desc.getName() + <<" style=[" << ((S32) desc.getStyle()) << "]" + << " size=[" << desc.getSize() << "]" << llendl; } return fontp; } @@ -653,3 +665,8 @@ void LLFontRegistry::dump() } } } + +const string_vec_t& LLFontRegistry::getUltimateFallbackList() const +{ + return mUltimateFallbackList; +} diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h index 198ca0b920..4da4ca48bb 100644 --- a/indra/llrender/llfontregistry.h +++ b/indra/llrender/llfontregistry.h @@ -98,7 +98,7 @@ public: void dump(); - const string_vec_t& getUltimateFallbackList() const { return mUltimateFallbackList; } + const string_vec_t& getUltimateFallbackList() const; private: LLFontGL *createFont(const LLFontDescriptor& desc); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index e1231eeeb4..c3d1d9e894 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -46,7 +46,6 @@ //---------------------------------------------------------------------------- - const F32 MIN_TEXTURE_LIFETIME = 10.f; //statics @@ -61,7 +60,7 @@ S32 LLImageGL::sCount = 0; BOOL LLImageGL::sGlobalUseAnisotropic = FALSE; F32 LLImageGL::sLastFrameTime = 0.f; - +LLImageGL* LLImageGL::sDefaultGLTexture = NULL ; std::set LLImageGL::sImageList; //************************************************************************************** @@ -264,6 +263,7 @@ void LLImageGL::restoreGL() //---------------------------------------------------------------------------- +//for server side use only. //static BOOL LLImageGL::create(LLPointer& dest, BOOL usemipmaps) { @@ -271,12 +271,14 @@ BOOL LLImageGL::create(LLPointer& dest, BOOL usemipmaps) return TRUE; } +//for server side use only. BOOL LLImageGL::create(LLPointer& dest, U32 width, U32 height, U8 components, BOOL usemipmaps) { dest = new LLImageGL(width, height, components, usemipmaps); return TRUE; } +//for server side use only. BOOL LLImageGL::create(LLPointer& dest, const LLImageRaw* imageraw, BOOL usemipmaps) { dest = new LLImageGL(imageraw, usemipmaps); @@ -331,7 +333,6 @@ void LLImageGL::init(BOOL usemipmaps) #endif mPickMask = NULL; - mTextureState = NO_DELETE ; mTextureMemory = 0; mLastBindTime = 0.f; @@ -351,8 +352,7 @@ void LLImageGL::init(BOOL usemipmaps) mComponents = 0; mMaxDiscardLevel = MAX_DISCARD_LEVEL; - mCurrentDiscardLevel = -1; - mDontDiscard = FALSE; + mCurrentDiscardLevel = -1; mFormatInternal = -1; mFormatPrimary = (LLGLenum) 0; @@ -362,6 +362,7 @@ void LLImageGL::init(BOOL usemipmaps) mGLTextureCreated = FALSE ; mIsMask = FALSE; + mNeedsAlphaAndPickMask = TRUE ; } void LLImageGL::cleanup() @@ -462,7 +463,7 @@ void LLImageGL::dump() //---------------------------------------------------------------------------- -void LLImageGL::updateBindStats(void) const +BOOL LLImageGL::updateBindStats(S32 tex_mem) const { if (mTexName != 0) { @@ -474,38 +475,18 @@ void LLImageGL::updateBindStats(void) const { // we haven't accounted for this texture yet this frame sUniqueCount++; - updateBoundTexMem(mTextureMemory); + updateBoundTexMem(tex_mem); mLastBindTime = sLastFrameTime; - if(LLFastTimer::sMetricLog) - { - updateTestStats() ; - } + return TRUE ; } } + return FALSE ; } -//virtual -void LLImageGL::updateTestStats(void) const +F32 LLImageGL::getTimePassedSinceLastBound() { -} - -//virtual -bool LLImageGL::bindError(const S32 stage) const -{ - return false; -} - -//virtual -bool LLImageGL::bindDefaultImage(const S32 stage) const -{ - return false; -} - -//virtual -void LLImageGL::forceImmediateUpdate() -{ - return ; + return sLastFrameTime - mLastBindTime ; } void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes ) @@ -1052,7 +1033,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ mTextureMemory = getMipBytes(discard_level); sGlobalTextureMemoryInBytes += mTextureMemory; - setActive() ; // mark this as bound at this point, so we don't throw it out immediately mLastBindTime = sLastFrameTime; @@ -1068,12 +1048,7 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level) discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); - if (mDontDiscard) - { - // don't discard! - return FALSE; - } - else if (discard_level == mCurrentDiscardLevel) + if (discard_level == mCurrentDiscardLevel) { // nothing to do return FALSE; @@ -1255,8 +1230,7 @@ void LLImageGL::destroyGLTexture() sGlobalTextureMemoryInBytes -= mTextureMemory; mTextureMemory = 0; - LLImageGL::deleteTextures(1, &mTexName); - mTextureState = DELETED ; + LLImageGL::deleteTextures(1, &mTexName); mTexName = 0; mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. mGLTextureCreated = FALSE ; @@ -1383,6 +1357,11 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) { + if(!mNeedsAlphaAndPickMask) + { + return ; + } + if (mFormatType != GL_UNSIGNED_BYTE) { llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl; @@ -1440,60 +1419,14 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) } } -BOOL LLImageGL::isDeleted() -{ - return mTextureState == DELETED ; -} - -BOOL LLImageGL::isInactive() -{ - return mTextureState == INACTIVE ; -} - -BOOL LLImageGL::isDeletionCandidate() -{ - return mTextureState == DELETION_CANDIDATE ; -} - -void LLImageGL::setDeletionCandidate() -{ - if(mTexName && (mTextureState == INACTIVE)) - { - mTextureState = DELETION_CANDIDATE ; - } -} - -void LLImageGL::forceActive() -{ - mTextureState = ACTIVE ; -} - -void LLImageGL::setActive() -{ - if(mTextureState != NO_DELETE) - { - mTextureState = ACTIVE ; - } -} - -//set the texture inactive -void LLImageGL::setInactive() -{ - if(mTexName && (mTextureState == ACTIVE) && !getBoundRecently()) - { - mTextureState = INACTIVE ; - } -} - -//set the texture to stay in memory -void LLImageGL::setNoDelete() -{ - mTextureState = NO_DELETE ; -} - //---------------------------------------------------------------------------- void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) { + if(!mNeedsAlphaAndPickMask) + { + return ; + } + if (mFormatType != GL_UNSIGNED_BYTE || mFormatPrimary != GL_RGBA) { diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 1775ae7de9..5f32b23356 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -57,8 +57,8 @@ public: static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height); static S32 dataFormatComponents(S32 dataformat); - void updateBindStats(void) const; - virtual void updateTestStats(void) const; + BOOL updateBindStats(S32 tex_mem) const ; + F32 getTimePassedSinceLastBound(); // needs to be called every frame static void updateStats(F32 current_time); @@ -71,13 +71,14 @@ public: static S32 updateBoundTexMem(const S32 delta); static bool checkSize(S32 width, S32 height); - + + //for server side use only. // Not currently necessary for LLImageGL, but required in some derived classes, // so include for compatability static BOOL create(LLPointer& dest, BOOL usemipmaps = TRUE); static BOOL create(LLPointer& dest, U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE); static BOOL create(LLPointer& dest, const LLImageRaw* imageraw, BOOL usemipmaps = TRUE); - + public: LLImageGL(BOOL usemipmaps = TRUE); LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE); @@ -90,11 +91,9 @@ protected: public: virtual void dump(); // debugging info to llinfos - virtual bool bindError(const S32 stage = 0) const; - virtual bool bindDefaultImage(const S32 stage = 0) const; - virtual void forceImmediateUpdate() ; - + void setSize(S32 width, S32 height, S32 ncomponents); + void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;} // These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D() // for tracking purposes and will be deprecated in the future @@ -116,7 +115,6 @@ public: void destroyGLTexture(); void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); - void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; } S32 getDiscardLevel() const { return mCurrentDiscardLevel; } S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; } @@ -145,9 +143,7 @@ public: void setGLTextureCreated (bool initialized) { mGLTextureCreated = initialized; } BOOL getUseMipMaps() const { return mUseMipMaps; } - void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; } - BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } - BOOL getDontDiscard() const { return mDontDiscard; } + void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; } BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ; @@ -168,19 +164,10 @@ public: void setFilteringOption(LLTexUnit::eTextureFilterOptions option); LLTexUnit::eTextureFilterOptions getFilteringOption(void) const { return mFilterOption; } - BOOL isDeleted() ; - BOOL isInactive() ; - BOOL isDeletionCandidate(); - void setDeletionCandidate() ; - void setInactive() ; - void setActive() ; - void forceActive() ; - void setNoDelete() ; - -protected: void init(BOOL usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors + void setNeedsAlphaAndPickMask(BOOL need_mask) {mNeedsAlphaAndPickMask = need_mask;} public: // Various GL/Rendering options S32 mTextureMemory; @@ -194,6 +181,7 @@ private: S8 mAutoGenMips; BOOL mIsMask; + BOOL mNeedsAlphaAndPickMask; bool mGLTextureCreated ; LLGLuint mTexName; @@ -210,28 +198,15 @@ protected: S8 mComponents; S8 mMaxDiscardLevel; - S8 mDontDiscard; // Keep full res version of this image (for UI, etc) - + bool mTexOptionsDirty; LLTexUnit::eTextureAddressMode mAddressMode; // Defaults to TAM_WRAP LLTexUnit::eTextureFilterOptions mFilterOption; // Defaults to TFO_TRILINEAR - LLGLint mFormatInternal; // = GL internalformat LLGLenum mFormatPrimary; // = GL format (pixel data format) LLGLenum mFormatType; BOOL mFormatSwapBytes;// if true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1) - -protected: - typedef enum - { - DELETED = 0, //removed from memory - DELETION_CANDIDATE, //ready to be removed from memory - INACTIVE, //not be used for the last certain period (i.e., 30 seconds). - ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds). - NO_DELETE = 99 //stay in memory, can not be removed. - } LLGLTexureState; - LLGLTexureState mTextureState ; // STATICS public: @@ -249,6 +224,7 @@ public: static U32 sBindCount; // Tracks number of texture binds for current frame static U32 sUniqueCount; // Tracks number of unique texture binds for current frame static BOOL sGlobalUseAnisotropic; + static LLImageGL* sDefaultGLTexture ; #if DEBUG_MISS BOOL mMissed; // Missed on last bind? diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index d3a230b37b..d577daf3f4 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -38,6 +38,7 @@ #include "llcubemap.h" #include "llimagegl.h" #include "llrendertarget.h" +#include "lltexture.h" LLRender gGL; @@ -177,20 +178,21 @@ void LLTexUnit::disable(void) } } -bool LLTexUnit::bind(LLImageGL* texture, bool forceBind) +bool LLTexUnit::bind(LLTexture* texture, bool forceBind) { stop_glerror(); if (mIndex < 0) return false; gGL.flush(); - if (texture == NULL) + LLImageGL* gl_tex = NULL ; + if (texture == NULL || !(gl_tex = texture->getGLTexture())) { llwarns << "NULL LLTexUnit::bind texture" << llendl; return false; } - if (!texture->getTexName()) //if texture does not exist + if (!gl_tex->getTexName()) //if texture does not exist { //if deleted, will re-generate it immediately texture->forceImmediateUpdate() ; @@ -198,14 +200,57 @@ bool LLTexUnit::bind(LLImageGL* texture, bool forceBind) return texture->bindDefaultImage(mIndex); } + if ((mCurrTexture != gl_tex->getTexName()) || forceBind) + { + activate(); + enable(gl_tex->getTarget()); + mCurrTexture = gl_tex->getTexName(); + glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); + if(gl_tex->updateBindStats(gl_tex->mTextureMemory)) + { + texture->setActive() ; + texture->updateBindStatsForTester() ; + } + mHasMipMaps = gl_tex->mHasMipMaps; + if (gl_tex->mTexOptionsDirty) + { + gl_tex->mTexOptionsDirty = false; + setTextureAddressMode(gl_tex->mAddressMode); + setTextureFilteringOption(gl_tex->mFilterOption); + } + } + return true; +} + +bool LLTexUnit::bind(LLImageGL* texture, bool forceBind) +{ + stop_glerror(); + if (mIndex < 0) return false; + + if(!texture) + { + llwarns << "NULL LLTexUnit::bind texture" << llendl; + return false; + } + + if(!texture->getTexName()) + { + if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName()) + { + return bind(LLImageGL::sDefaultGLTexture) ; + } + return false ; + } + + gGL.flush(); + if ((mCurrTexture != texture->getTexName()) || forceBind) { activate(); enable(texture->getTarget()); mCurrTexture = texture->getTexName(); glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); - texture->updateBindStats(); - texture->setActive() ; + texture->updateBindStats(texture->mTextureMemory); mHasMipMaps = texture->mHasMipMaps; if (texture->mTexOptionsDirty) { @@ -238,7 +283,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap) mCurrTexture = cubeMap->mImages[0]->getTexName(); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture); mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps; - cubeMap->mImages[0]->updateBindStats(); + cubeMap->mImages[0]->updateBindStats(cubeMap->mImages[0]->mTextureMemory); if (cubeMap->mImages[0]->mTexOptionsDirty) { cubeMap->mImages[0]->mTexOptionsDirty = false; @@ -279,15 +324,21 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips) { - if (mIndex < 0 || mCurrTexture == texture) return false; + if (mIndex < 0) + { + return false; + } - gGL.flush(); - - activate(); - enable(type); - mCurrTexture = texture; - glBindTexture(sGLTextureType[type], texture); - mHasMipMaps = hasMips; + if(mCurrTexture != texture) + { + gGL.flush(); + + activate(); + enable(type); + mCurrTexture = texture; + glBindTexture(sGLTextureType[type], texture); + mHasMipMaps = hasMips; + } return true; } diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 31083d8286..74f87f6d40 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -51,6 +51,7 @@ class LLVertexBuffer; class LLCubeMap; class LLImageGL; class LLRenderTarget; +class LLTexture ; class LLTexUnit { @@ -149,6 +150,7 @@ public: // Binds the LLImageGL to this texture unit // (automatically enables the unit for the LLImageGL's texture type) bool bind(LLImageGL* texture, bool forceBind = false); + bool bind(LLTexture* texture, bool forceBind = false); // Binds a cubemap to this texture unit // (automatically enables the texture unit for cubemaps) diff --git a/indra/llrender/lltexture.cpp b/indra/llrender/lltexture.cpp new file mode 100644 index 0000000000..156ffb953c --- /dev/null +++ b/indra/llrender/lltexture.cpp @@ -0,0 +1,37 @@ +/** + * @file lltexture.cpp + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "linden_common.h" +#include "lltexture.h" + +//virtual +LLTexture::~LLTexture() +{ +} diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h new file mode 100644 index 0000000000..c18917b663 --- /dev/null +++ b/indra/llrender/lltexture.h @@ -0,0 +1,77 @@ +/** + * @file lltexture.h + * @brief LLTexture definition + * + * This class acts as a wrapper for OpenGL calls. + * The goal of this class is to minimize the number of api calls due to legacy rendering + * code, to define an interface for a multiple rendering API abstraction of the UI + * rendering, and to abstract out direct rendering calls in a way that is cleaner and easier to maintain. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_TEXTURE_H +#define LL_TEXTURE_H + +#include "llrefcount.h" +class LLImageGL ; +class LLTexUnit ; +class LLFontGL ; + +// +//this is an abstract class as the parent for the class LLViewerTexture +//through the following virtual functions, the class LLViewerTexture can be reached from /llrender. +// +class LLTexture : public LLRefCount +{ + friend class LLTexUnit ; + friend class LLFontGL ; + +protected: + virtual ~LLTexture(); + +public: + LLTexture(){} + + // + //interfaces to access LLViewerTexture + // + virtual bool bindDefaultImage(const S32 stage = 0) const = 0 ; + virtual void forceImmediateUpdate() = 0 ; + virtual void setActive() = 0 ; + virtual S32 getWidth(S32 discard_level = -1) const = 0 ; + virtual S32 getHeight(S32 discard_level = -1) const = 0 ; + +private: + //note: do not make this function public. + virtual LLImageGL* getGLTexture() const = 0 ; + + virtual void updateBindStatsForTester() = 0 ; +}; +#endif + diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index a6a5ef1f92..269c02263d 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -37,6 +37,7 @@ set(llui_SOURCE_FILES lldraghandle.cpp lleditmenuhandler.cpp llf32uictrl.cpp + llfiltereditor.cpp llfloater.cpp llfloaterreg.cpp llflyoutbutton.cpp @@ -60,6 +61,7 @@ set(llui_SOURCE_FILES llresizebar.cpp llresizehandle.cpp llresmgr.cpp + llrngwriter.cpp llscrollbar.cpp llscrollcontainer.cpp llscrollingpanellist.cpp @@ -68,7 +70,7 @@ set(llui_SOURCE_FILES llscrolllistctrl.cpp llscrolllistitem.cpp llsdparam.cpp - llsearcheditor.cpp + llsearcheditor.cpp llslider.cpp llsliderctrl.cpp llspinctrl.cpp @@ -82,6 +84,7 @@ set(llui_SOURCE_FILES lltextparser.cpp lltrans.cpp llui.cpp + lluicolor.cpp lluicolortable.cpp lluictrl.cpp lluictrlfactory.cpp @@ -109,11 +112,13 @@ set(llui_HEADER_FILES lldraghandle.h lleditmenuhandler.h llf32uictrl.h + llfiltereditor.h llfloater.h llfloaterreg.h llflyoutbutton.h llfocusmgr.h llfunctorregistry.h + llhandle.h llhtmlhelp.h lliconctrl.h llinitparam.h @@ -135,6 +140,7 @@ set(llui_HEADER_FILES llresizebar.h llresizehandle.h llresmgr.h + llrngwriter.h llsearcheditor.h llscrollbar.h llscrollcontainer.h @@ -156,6 +162,7 @@ set(llui_HEADER_FILES lltexteditor.h lltextparser.h lltrans.h + lluicolor.h lluicolortable.h lluiconstants.h lluictrlfactory.h diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index f2aa9c0d4c..fc3af34951 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -32,7 +32,6 @@ #include "linden_common.h" -#define INSTANTIATE_GETCHILD_BUTTON #include "llbutton.h" // Linden library includes @@ -53,7 +52,7 @@ #include "llrender.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register r("button"); +static LLDefaultChildRegistry::Register r("button"); // globals loaded from settings.xml S32 LLBUTTON_H_PAD = 0; @@ -61,11 +60,9 @@ S32 LLBUTTON_V_PAD = 0; S32 BTN_HEIGHT_SMALL= 0; S32 BTN_HEIGHT = 0; -template LLButton* LLView::getChild( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - LLButton::Params::Params() : label_selected("label_selected"), // requires is_toggle true - label_dropshadow("label_shadow", true), + label_shadow("label_shadow", true), auto_resize("auto_resize", false), image_unselected("image_unselected"), image_selected("image_selected"), @@ -136,7 +133,7 @@ LLButton::LLButton(const LLButton::Params& p) mImageOverlayAlignment(LLFontGL::hAlignFromName(p.image_overlay_alignment)), mIsToggle(p.is_toggle), mScaleImage(p.scale_image), - mDropShadowedText(p.label_dropshadow), + mDropShadowedText(p.label_shadow), mAutoResize(p.auto_resize), mHAlign(p.font_halign), mLeftHPad(p.pad_left), @@ -146,7 +143,7 @@ LLButton::LLButton(const LLButton::Params& p) mFadeWhenDisabled(FALSE) { static LLUICachedControl llbutton_orig_h_pad ("UIButtonOrigHPad", 0); - static Params default_params(LLUICtrlFactory::getDefaultParams()); + static Params default_params(LLUICtrlFactory::getDefaultParams()); //if we aren't a picture_style button set label as name if not provided if (!p.picture_style.isProvided() || !p.picture_style) @@ -328,25 +325,27 @@ BOOL LLButton::handleKeyHere(KEY key, MASK mask ) BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) { - // Route future Mouse messages here preemptively. (Release on mouse up.) - gFocusMgr.setMouseCapture( this ); - - if (hasTabStop() && !getIsChrome()) + if (!childrenHandleMouseDown(x, y, mask)) { - setFocus(TRUE); + // Route future Mouse messages here preemptively. (Release on mouse up.) + gFocusMgr.setMouseCapture( this ); + + if (hasTabStop() && !getIsChrome()) + { + setFocus(TRUE); + } + + mMouseDownSignal(this, LLSD()); + + mMouseDownTimer.start(); + mMouseDownFrame = (S32) LLFrameTimer::getFrameCount(); + mMouseHeldDownCount = 0; + + if (getSoundFlags() & MOUSE_DOWN) + { + make_ui_sound("UISndClick"); + } } - - mMouseDownSignal(this, LLSD()); - - mMouseDownTimer.start(); - mMouseDownFrame = (S32) LLFrameTimer::getFrameCount(); - mMouseHeldDownCount = 0; - - if (getSoundFlags() & MOUSE_DOWN) - { - make_ui_sound("UISndClick"); - } - return TRUE; } @@ -381,20 +380,26 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) LLUICtrl::onCommit(); } } + else + { + childrenHandleMouseUp(x, y, mask); + } return TRUE; } BOOL LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask) { - // Route future Mouse messages here preemptively. (Release on mouse up.) - gFocusMgr.setMouseCapture( this ); - - if (hasTabStop() && !getIsChrome()) + if (!childrenHandleRightMouseDown(x, y, mask)) { - setFocus(TRUE); - } + // Route future Mouse messages here preemptively. (Release on mouse up.) + gFocusMgr.setMouseCapture( this ); + if (hasTabStop() && !getIsChrome()) + { + setFocus(TRUE); + } + } return TRUE; } @@ -412,6 +417,10 @@ BOOL LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask) mRightClickSignal(this, getValue()); } } + else + { + childrenHandleRightMouseUp(x, y, mask); + } return TRUE; } @@ -429,21 +438,23 @@ void LLButton::onMouseLeave(S32 x, S32 y, MASK mask) BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) { - if (mMouseDownTimer.getStarted()) + if (!childrenHandleHover(x, y, mask)) { - F32 elapsed = getHeldDownTime(); - if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame) + if (mMouseDownTimer.getStarted()) { - LLSD param; - param["count"] = mMouseHeldDownCount++; - mHeldDownSignal(this, param); + F32 elapsed = getHeldDownTime(); + if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame) + { + LLSD param; + param["count"] = mMouseHeldDownCount++; + mHeldDownSignal(this, param); + } } + + // We only handle the click if the click both started and ended within us + getWindow()->setCursor(UI_CURSOR_ARROW); + lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; } - - // We only handle the click if the click both started and ended within us - getWindow()->setCursor(UI_CURSOR_ARROW); - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; - return TRUE; } diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 1398e5c14b..e387c91a17 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -74,7 +74,7 @@ public: { // text label Optional label_selected; - Optional label_dropshadow; + Optional label_shadow; Optional auto_resize; // images @@ -105,9 +105,9 @@ public: // callbacks Optional click_callback, // alias -> commit_callback - mouse_down_callback, - mouse_up_callback, - mouse_held_callback; + mouse_down_callback, + mouse_up_callback, + mouse_held_callback; // misc Optional is_toggle, @@ -352,11 +352,5 @@ private: LLFrameTimer mFlashingTimer; }; -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_BUTTON -#pragma warning (disable : 4231) -extern template LLButton* LLView::getChild( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif #endif // LL_LLBUTTON_H diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 932a1b6297..b43f91e766 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -31,8 +31,6 @@ */ // The mutants are coming! -#define INSTANTIATE_GETCHILD_CHECKBOX - #include "linden_common.h" #include "llcheckboxctrl.h" @@ -50,9 +48,7 @@ const U32 MAX_STRING_LENGTH = 10; -template LLCheckBoxCtrl* LLView::getChild( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - -static LLDefaultWidgetRegistry::Register r("check_box"); +static LLDefaultChildRegistry::Register r("check_box"); LLCheckBoxCtrl::Params::Params() : text_enabled_color("text_enabled_color"), diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h index 2f8f088a3e..2f8e8fdd23 100644 --- a/indra/llui/llcheckboxctrl.h +++ b/indra/llui/llcheckboxctrl.h @@ -126,11 +126,4 @@ protected: }; -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_CHECKBOX -#pragma warning (disable : 4231) -extern template LLCheckBoxCtrl* LLView::getChild( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif - #endif // LL_LLCHECKBOXCTRL_H diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 51ab3326fe..f8c6204afb 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -33,8 +33,6 @@ // A control that displays the name of the chosen item, which when // clicked shows a scrolling box of options. -#define INSTANTIATE_GETCHILD_COMBOBOX - #include "linden_common.h" // file includes @@ -63,9 +61,7 @@ S32 LLCOMBOBOX_HEIGHT = 0; S32 LLCOMBOBOX_WIDTH = 0; S32 MAX_COMBO_WIDTH = 500; -template LLComboBox* LLView::getChild( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - -static LLDefaultWidgetRegistry::Register register_combo_box("combo_box"); +static LLDefaultChildRegistry::Register register_combo_box("combo_box"); void LLComboBox::PreferredPositionValues::declareValues() { @@ -83,12 +79,12 @@ LLComboBox::Params::Params() : allow_text_entry("allow_text_entry", false), show_text_as_tentative("show_text_as_tentative", true), max_chars("max_chars", 20), - arrow_image("arrow_image"), list_position("list_position", BELOW), items("item"), combo_button("combo_button"), combo_list("combo_list"), - combo_editor("combo_editor") + combo_editor("combo_editor"), + drop_down_button("drop_down_button") { addSynonym(items, "combo_item"); } @@ -104,19 +100,32 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) mPrearrangeCallback(p.prearrange_callback()), mTextEntryCallback(p.text_entry_callback()), mSelectionCallback(p.selection_callback()), - mArrowImage(p.arrow_image), - mListPosition(p.list_position) + mListPosition(p.list_position), + mLastSelectedIndex(-1) { // Text label button - LLButton::Params button_params = p.combo_button; + LLButton::Params button_params = (mAllowTextEntry ? p.combo_button : p.drop_down_button); button_params.mouse_down_callback.function(boost::bind(&LLComboBox::onButtonDown, this)); button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT); button_params.rect(p.rect); - button_params.pad_right(2); + + if(mAllowTextEntry) + { + button_params.pad_right(2); + } + + mArrowImage = button_params.image_unselected; mButton = LLUICtrlFactory::create(button_params); - mButton->setRightHPad(2); //redo to compensate for button hack that leaves space for a character + + + if(mAllowTextEntry) + { + //redo to compensate for button hack that leaves space for a character + //unless it is a "minimal combobox"(drop down) + mButton->setRightHPad(2); + } addChild(mButton); LLScrollListCtrl::Params params = p.combo_list; @@ -135,7 +144,7 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) LLScrollListItem::Params item_params = *it; if (it->label.isProvided()) { - item_params.cells.add().value(it->label()); + item_params.columns.add().value(it->label()); } mList->addRow(item_params); @@ -424,7 +433,8 @@ void LLComboBox::setButtonVisible(BOOL visible) LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); if (visible) { - text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * drop_shadow_button; + S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0; + text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button; } //mTextEntry->setRect(text_entry_rect); mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE); @@ -466,14 +476,15 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p) LLRect rect = getLocalRect(); if (mAllowTextEntry) { + S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0; S32 shadow_size = drop_shadow_button; - mButton->setRect(LLRect( getRect().getWidth() - llmax(8,mArrowImage->getWidth()) - 2 * shadow_size, + mButton->setRect(LLRect( getRect().getWidth() - llmax(8,arrow_width) - 2 * shadow_size, rect.mTop, rect.mRight, rect.mBottom)); mButton->setTabStop(FALSE); mButton->setHAlign(LLFontGL::HCENTER); LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); - text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * drop_shadow_button; + text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button; // clear label on button std::string cur_label = mButton->getLabelSelected(); LLLineEditor::Params params = p.combo_editor; @@ -615,15 +626,15 @@ void LLComboBox::showList() mList->setVisible(TRUE); setUseBoundingRect(TRUE); + + mList->sortItems(); + mLastSelectedIndex = mList->getFirstSelectedIndex(); } void LLComboBox::hideList() { - //*HACK: store the original value explicitly somewhere, not just in label - std::string orig_selection = mAllowTextEntry ? mTextEntry->getText() : mButton->getLabelSelected(); - // assert selection in list - mList->selectItemByLabel(orig_selection, FALSE); + mList->selectNthItem(mLastSelectedIndex); mButton->setToggleState(FALSE); mList->setVisible(FALSE); @@ -681,6 +692,7 @@ void LLComboBox::onItemSelected(const LLSD& data) const std::string name = mList->getSelectedItemLabel(); S32 cur_id = getCurrentIndex(); + mLastSelectedIndex = cur_id; if (cur_id != -1) { setLabel(name); @@ -732,12 +744,7 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_re msg = tool_tip; // Convert rect local to screen coordinates - localPointToScreen( - 0, 0, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - getRect().getWidth(), getRect().getHeight(), - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); + *sticky_rect_screen = calcScreenRect(); } return TRUE; } diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index bc98690a01..db97b0df75 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -39,7 +39,6 @@ #include "llbutton.h" #include "lluictrl.h" #include "llctrlselectioninterface.h" -#include "llimagegl.h" #include "llrect.h" #include "llscrolllistctrl.h" #include "lllineeditor.h" @@ -84,7 +83,6 @@ public: Optional prearrange_callback, text_entry_callback, selection_callback; - Optional arrow_image; Optional list_position; @@ -93,6 +91,8 @@ public: Optional combo_list; Optional combo_editor; + Optional drop_down_button; + Multiple items; Params(); @@ -232,13 +232,6 @@ private: commit_callback_t mPrearrangeCallback; commit_callback_t mTextEntryCallback; commit_callback_t mSelectionCallback; + S32 mLastSelectedIndex; }; - -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_COMBOBOX -#pragma warning (disable : 4231) -extern template LLComboBox* LLView::getChild( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif - #endif diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp index f1fc3d8f43..1e8b8a5537 100644 --- a/indra/llui/llconsole.cpp +++ b/indra/llui/llconsole.cpp @@ -177,8 +177,8 @@ void LLConsole::draw() // F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f); F32 console_opacity = llclamp(LLUI::sSettingGroups["config"]->getF32("ConsoleBackgroundOpacity"), 0.f, 1.f); -// LLColor4 color = gSavedSkinSettings.getColor("ConsoleBackground"); - LLColor4 color = LLUI::sSettingGroups["color"]->getColor("ConsoleBackground"); +// LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground"); + LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground"); color.mV[VALPHA] *= console_opacity; F32 line_height = mFont->getLineHeight(); diff --git a/indra/llui/llconsole.h b/indra/llui/llconsole.h index 65149b217f..56e1614948 100644 --- a/indra/llui/llconsole.h +++ b/indra/llui/llconsole.h @@ -58,7 +58,8 @@ public: Optional font_size_index; Params() : max_lines("max_lines", LLUI::sSettingGroups["config"]->getS32("ConsoleMaxLines")), - persist_time("persist_time", 0.f) // forever + persist_time("persist_time", 0.f), // forever + font_size_index("font_size_index") { mouse_opaque(false); } diff --git a/indra/llui/llcontainerview.cpp b/indra/llui/llcontainerview.cpp index 40cc430e25..96948b659f 100644 --- a/indra/llui/llcontainerview.cpp +++ b/indra/llui/llcontainerview.cpp @@ -42,7 +42,7 @@ #include "llscrollcontainer.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register r("container_view"); +static LLDefaultChildRegistry::Register r("container_view"); LLContainerView::LLContainerView(const LLContainerView::Params& p) : LLView(p), diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index 8ecbdb98e1..6e8e37ded3 100644 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -317,6 +317,23 @@ BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask) S32 delta_x = screen_x - mDragLastScreenX; S32 delta_y = screen_y - mDragLastScreenY; + // if dragging a docked floater we want to undock + if (((LLFloater*)getParent())->isDocked()) + { + const S32 SLOP = 12; + + if (delta_y <= -SLOP || + delta_y >= SLOP) + { + ((LLFloater*)getParent())->setDocked(false, false); + return TRUE; + } + else + { + return FALSE; + } + } + LLRect original_rect = getParent()->getRect(); LLRect translated_rect = getParent()->getRect(); translated_rect.translate(delta_x, delta_y); diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h index 8b53c46ae9..88ec1d21f8 100644 --- a/indra/llui/lldraghandle.h +++ b/indra/llui/lldraghandle.h @@ -53,8 +53,9 @@ public: Optional drag_shadow_color; Params() - : drag_highlight_color("", LLUI::getCachedColorFunctor("DefaultHighlightLight")), - drag_shadow_color("", LLUI::getCachedColorFunctor("DefaultShadowDark")) + : label("label"), + drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")), + drag_shadow_color("drag_shadow_color", LLUIColorTable::instance().getColor("DefaultShadowDark")) { mouse_opaque(true); follows.flags(FOLLOWS_ALL); diff --git a/indra/llui/llfiltereditor.cpp b/indra/llui/llfiltereditor.cpp new file mode 100644 index 0000000000..0f36483fc2 --- /dev/null +++ b/indra/llui/llfiltereditor.cpp @@ -0,0 +1,110 @@ +/** + * @file llfiltereditor.cpp + * @brief LLFilterEditor implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +// Text editor widget to let users enter a single line. + +#include "linden_common.h" + +#include "llfiltereditor.h" + +LLFilterEditor::LLFilterEditor(const LLFilterEditor::Params& p) +: LLUICtrl(p) +{ + LLLineEditor::Params line_editor_p(p); + line_editor_p.name("filter edit box"); + line_editor_p.rect(getLocalRect()); + line_editor_p.follows.flags(FOLLOWS_ALL); + line_editor_p.text_pad_right(getRect().getHeight()); + line_editor_p.keystroke_callback(boost::bind(&LLUICtrl::onCommit, this)); + + mFilterEditor = LLUICtrlFactory::create(line_editor_p); + addChild(mFilterEditor); + + S32 btn_width = getRect().getHeight(); // button is square, and as tall as search editor + LLRect clear_btn_rect(getRect().getWidth() - btn_width, getRect().getHeight(), getRect().getWidth(), 0); + LLButton::Params button_params(p.clear_filter_button); + button_params.name(std::string("clear filter")); + button_params.rect(clear_btn_rect) ; + button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP); + button_params.tab_stop(false); + button_params.click_callback.function(boost::bind(&LLFilterEditor::onClearFilter, this, _2)); + + mClearFilterButton = LLUICtrlFactory::create(button_params); + mFilterEditor->addChild(mClearFilterButton); +} + +//virtual +void LLFilterEditor::setValue(const LLSD& value ) +{ + mFilterEditor->setValue(value); +} + +//virtual +LLSD LLFilterEditor::getValue() const +{ + return mFilterEditor->getValue(); +} + +//virtual +BOOL LLFilterEditor::setTextArg( const std::string& key, const LLStringExplicit& text ) +{ + return mFilterEditor->setTextArg(key, text); +} + +//virtual +BOOL LLFilterEditor::setLabelArg( const std::string& key, const LLStringExplicit& text ) +{ + return mFilterEditor->setLabelArg(key, text); +} + +//virtual +void LLFilterEditor::clear() +{ + if (mFilterEditor) + { + mFilterEditor->clear(); + } +} + +void LLFilterEditor::draw() +{ + mClearFilterButton->setVisible(!mFilterEditor->getWText().empty()); + + LLUICtrl::draw(); +} + +void LLFilterEditor::onClearFilter(const LLSD& data) +{ + setText(LLStringUtil::null); + onCommit(); +} + diff --git a/indra/llui/llfiltereditor.h b/indra/llui/llfiltereditor.h new file mode 100644 index 0000000000..4240fd770c --- /dev/null +++ b/indra/llui/llfiltereditor.h @@ -0,0 +1,86 @@ +/** + * @file llfiltereditor.h + * @brief Text editor widget that represents a filter operation + * + * Features: + * Text entry of a single line (text, delete, left and right arrow, insert, return). + * Callbacks either on every keystroke or just on the return key. + * Focus (allow multiple text entry widgets) + * Clipboard (cut, copy, and paste) + * Horizontal scrolling to allow strings longer than widget size allows + * Pre-validation (limit which keys can be used) + * Optional line history so previous entries can be recalled by CTRL UP/DOWN + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_FILTEREDITOR_H +#define LL_FILTEREDITOR_H + +#include "lllineeditor.h" +#include "llbutton.h" + +class LLFilterEditor : public LLUICtrl +{ +public: + struct Params : public LLInitParam::Block + { + Optional clear_filter_button; + + Params() + : clear_filter_button("clear_filter_button") + { + name = "filter_editor"; + } + }; + +protected: + LLFilterEditor(const Params&); + friend class LLUICtrlFactory; +public: + virtual ~LLFilterEditor() {} + + /*virtual*/ void draw(); + + void setText(const LLStringExplicit &new_text) { mFilterEditor->setText(new_text); } + + // LLUICtrl interface + virtual void setValue(const LLSD& value ); + virtual LLSD getValue() const; + virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); + virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); + virtual void clear(); + +private: + void onClearFilter(const LLSD& data); + + LLLineEditor* mFilterEditor; + LLButton* mClearFilterButton; +}; + +#endif // LL_FILTEREDITOR_H diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 8932a7ccf2..d420d1141e 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -66,29 +66,37 @@ const S32 TABBED_FLOATER_OFFSET = 0; std::string LLFloater::sButtonActiveImageNames[BUTTON_COUNT] = { - "closebox.tga", //BUTTON_CLOSE + "Icon_Close_Foreground", //BUTTON_CLOSE "restore.tga", //BUTTON_RESTORE "minimize.tga", //BUTTON_MINIMIZE "tearoffbox.tga", //BUTTON_TEAR_OFF "closebox.tga", //BUTTON_EDIT + "Icon_Dock_Foreground", + "Icon_Undock_Foreground" }; -std::string LLFloater::sButtonInactiveImageNames[BUTTON_COUNT] = +// Empty string means programmatic glow effect, achieved by +// not setting explicit image. +std::string LLFloater::sButtonHoveredImageNames[BUTTON_COUNT] = { - "close_inactive_blue.tga", //BUTTON_CLOSE - "restore_inactive.tga", //BUTTON_RESTORE - "minimize_inactive.tga", //BUTTON_MINIMIZE - "tearoffbox.tga", //BUTTON_TEAR_OFF - "close_inactive_blue.tga", //BUTTON_EDIT + "", //BUTTON_CLOSE + "restore_pressed.tga", //BUTTON_RESTORE + "minimize_pressed.tga", //BUTTON_MINIMIZE + "tearoff_pressed.tga", //BUTTON_TEAR_OFF + "close_in_blue.tga", //BUTTON_EDIT + "", //BUTTON_DOCK + "", //BUTTON_UNDOCK }; std::string LLFloater::sButtonPressedImageNames[BUTTON_COUNT] = { - "close_in_blue.tga", //BUTTON_CLOSE + "Icon_Close_Press", //BUTTON_CLOSE "restore_pressed.tga", //BUTTON_RESTORE "minimize_pressed.tga", //BUTTON_MINIMIZE "tearoff_pressed.tga", //BUTTON_TEAR_OFF "close_in_blue.tga", //BUTTON_EDIT + "Icon_Dock_Press", + "Icon_Undock_Press" }; std::string LLFloater::sButtonNames[BUTTON_COUNT] = @@ -98,22 +106,25 @@ std::string LLFloater::sButtonNames[BUTTON_COUNT] = "llfloater_minimize_btn", //BUTTON_MINIMIZE "llfloater_tear_off_btn", //BUTTON_TEAR_OFF "llfloater_edit_btn", //BUTTON_EDIT + "llfloater_dock_btn", + "llfloater_undock_btn" }; -std::string LLFloater::sButtonToolTips[BUTTON_COUNT] = {}; - +std::string LLFloater::sButtonToolTips[BUTTON_COUNT]; std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]= { #ifdef LL_DARWIN - "BUTTON_CLOSE_DARWIN",//LLTrans::getString("BUTTON_CLOSE_DARWIN"), //"Close (Cmd-W)", //BUTTON_CLOSE + "BUTTON_CLOSE_DARWIN", //"Close (Cmd-W)", //BUTTON_CLOSE #else - "BUTTON_CLOSE_WIN", //LLTrans::getString("BUTTON_CLOSE_WIN"), //"Close (Ctrl-W)", //BUTTON_CLOSE + "BUTTON_CLOSE_WIN", //"Close (Ctrl-W)", //BUTTON_CLOSE #endif - "BUTTON_RESTORE",//LLTrans::getString("BUTTON_RESTORE"), //"Restore", //BUTTON_RESTORE - "BUTTON_MINIMIZE",//LLTrans::getString("BUTTON_MINIMIZE"), //"Minimize", //BUTTON_MINIMIZE - "BUTTON_TEAR_OFF",//LLTrans::getString("BUTTON_TEAR_OFF"), //"Tear Off", //BUTTON_TEAR_OFF - "BUTTON_EDIT", //LLTrans::getString("BUTTON_EDIT"), // "Edit", //BUTTON_EDIT + "BUTTON_RESTORE", //"Restore", //BUTTON_RESTORE + "BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE + "BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF + "BUTTON_EDIT", //"Edit", //BUTTON_EDIT + "BUTTON_DOCK", + "BUTTON_UNDOCK" }; LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] = @@ -123,10 +134,13 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] = LLFloater::onClickMinimize, //BUTTON_MINIMIZE LLFloater::onClickTearOff, //BUTTON_TEAR_OFF LLFloater::onClickEdit, //BUTTON_EDIT + LLFloater::onClickDock, + LLFloater::onClickDock }; LLMultiFloater* LLFloater::sHostp = NULL; -BOOL LLFloater::sEditModeEnabled; +BOOL LLFloater::sEditModeEnabled = FALSE; +BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting LLFloater::handle_map_t LLFloater::sFloaterMap; LLFloaterView* gFloaterView = NULL; @@ -188,12 +202,44 @@ bool LLFloater::KeyCompare::equate(const LLSD& a, const LLSD& b) //************************************ +LLFloater::Params::Params() +: title("title"), + short_title("short_title"), + single_instance("single_instance", false), + auto_tile("auto_tile", false), + can_resize("can_resize", false), + can_minimize("can_minimize", true), + can_close("can_close", true), + can_drag_on_left("can_drag_on_left", false), + can_tear_off("can_tear_off", true), + save_rect("save_rect", false), + save_visibility("save_visibility", false), + open_callback("open_callback"), + close_callback("close_callback"), + can_dock("can_dock", false) +{ + name = "floater"; + // defaults that differ from LLPanel: + background_visible = true; + visible = false; +} + + //static const LLFloater::Params& LLFloater::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams(); + return LLUICtrlFactory::getDefaultParams(); } +//static +void LLFloater::initClass() +{ + // translate tooltips for floater buttons + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + sButtonToolTips[i] = LLTrans::getString( sButtonToolTipsIndex[i] ); + } +} LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) : LLPanel(), @@ -216,30 +262,21 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) mEditing(FALSE), mButtonScale(1.0f), mAutoFocus(TRUE), // automatically take focus when opened + mCanDock(false), + mDocked(false), mHasBeenDraggedWhileMinimized(FALSE), mPreviousMinimizedBottom(0), mPreviousMinimizedLeft(0), mNotificationContext(NULL) { - static LLUICachedControl default_background_color ("FloaterDefaultBackgroundColor", *(new LLColor4)); - static LLUICachedControl focus_background_color ("FloaterFocusBackgroundColor", *(new LLColor4)); - - for (S32 i = 0; i < BUTTON_COUNT; i++) - { - sButtonToolTips[i] =LLTrans::getString( sButtonToolTipsIndex[i]); - } + static LLUIColor default_background_color = LLUIColorTable::instance().getColor("FloaterDefaultBackgroundColor"); + static LLUIColor focus_background_color = LLUIColorTable::instance().getColor("FloaterFocusBackgroundColor"); mHandle.bind(this); mNotificationContext = new LLFloaterNotificationContext(getHandle()); mBgColorAlpha = default_background_color; mBgColorOpaque = focus_background_color; - for (S32 i = 0; i < 4; i++) - { - mResizeBar[i] = NULL; - mResizeHandle[i] = NULL; - } - // Clicks stop here. setMouseOpaque(TRUE); @@ -288,6 +325,11 @@ void LLFloater::initFloater() mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; } + if(mCanDock) + { + mButtonsEnabled[BUTTON_DOCK] = TRUE; + } + buildButtons(); // Floaters are created in the invisible state @@ -399,6 +441,9 @@ void LLFloater::addResizeCtrls() // Resize handles (corners) LLResizeHandle::Params handle_p; + // handles must not be mouse-opaque, otherwise they block hover events + // to other buttons like the close box. JC + handle_p.mouse_opaque(false); handle_p.rect(LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0)); handle_p.min_width(mMinWidth); handle_p.min_height(mMinHeight); @@ -473,7 +518,7 @@ void LLFloater::storeRectControl() void LLFloater::storeVisibilityControl() { - if( mVisibilityControl.size() > 1 ) + if( !sQuitting && mVisibilityControl.size() > 1 ) { LLUI::sSettingGroups["floater"]->setBOOL( mVisibilityControl, getVisible() ); } @@ -481,7 +526,7 @@ void LLFloater::storeVisibilityControl() void LLFloater::setVisible( BOOL visible ) { - LLPanel::setVisible(visible); + LLPanel::setVisible(visible); // calls handleVisibilityChange() if( visible && mFirstLook ) { mFirstLook = FALSE; @@ -516,14 +561,14 @@ void LLFloater::setVisible( BOOL visible ) } // virtual -void LLFloater::onVisibilityChange ( BOOL new_visibility ) +void LLFloater::handleVisibilityChange ( BOOL new_visibility ) { if (new_visibility) { if (getHost()) getHost()->setFloaterFlashing(this, FALSE); } - LLPanel::onVisibilityChange ( new_visibility ); + LLPanel::handleVisibilityChange ( new_visibility ); } void LLFloater::openFloater(const LLSD& key) @@ -560,11 +605,17 @@ void LLFloater::openFloater(const LLSD& key) setVisibleAndFrontmost(mAutoFocus); } + mOpenSignal(this, key); onOpen(key); } void LLFloater::closeFloater(bool app_quitting) { + if (app_quitting) + { + LLFloater::sQuitting = true; + } + // Always unminimize before trying to close. // Most of the time the user will never see this state. setMinimized(FALSE); @@ -622,8 +673,27 @@ void LLFloater::closeFloater(bool app_quitting) } } - // Let floater do cleanup. - onClose(app_quitting); + // Close callback + mCloseSignal(this, LLSD(app_quitting)); + + // Hide or Destroy + if (mSingleInstance) + { + // Hide the instance + if (getHost()) + { + getHost()->setVisible(FALSE); + } + else + { + setVisible(FALSE); + } + } + else + { + setVisible(FALSE); // hide before destroying (so handleVisibilityChange() gets called) + destroy(); + } } } @@ -1296,6 +1366,36 @@ void LLFloater::setFrontmost(BOOL take_focus) } } +void LLFloater::setCanDock(bool b) +{ + if(b != mCanDock) + { + mCanDock = b; + if(mCanDock) + { + mButtonsEnabled[BUTTON_DOCK] = !mDocked; + mButtonsEnabled[BUTTON_UNDOCK] = mDocked; + } + else + { + mButtonsEnabled[BUTTON_DOCK] = FALSE; + mButtonsEnabled[BUTTON_UNDOCK] = FALSE; + } + } + updateButtons(); +} + +void LLFloater::setDocked(bool docked, bool pop_on_undock) +{ + if(docked != mDocked && mCanDock) + { + mDocked = docked; + mButtonsEnabled[BUTTON_DOCK] = !mDocked; + mButtonsEnabled[BUTTON_UNDOCK] = mDocked; + updateButtons(); + } +} + //static void LLFloater::setEditModeEnabled(BOOL enable) { @@ -1372,6 +1472,15 @@ void LLFloater::onClickEdit(LLFloater* self) self->mEditing = self->mEditing ? FALSE : TRUE; } +// static +void LLFloater::onClickDock(LLFloater* self) +{ + if(self && self->mCanDock) + { + self->setDocked(!self->mDocked, true); + } +} + // static LLFloater* LLFloater::getClosableFloaterFromFocus() { @@ -1449,7 +1558,7 @@ void LLFloater::draw() S32 bottom = LLPANEL_BORDER_WIDTH; static LLUICachedControl shadow_offset_S32 ("DropShadowFloater", 0); - static LLUICachedControl shadow_color_cached ("ColorDropShadow", *(new LLColor4)); + static LLUIColor shadow_color_cached = LLUIColorTable::instance().getColor("ColorDropShadow"); LLColor4 shadow_color = shadow_color_cached; F32 shadow_offset = (F32)shadow_offset_S32; @@ -1474,7 +1583,7 @@ void LLFloater::draw() if(gFocusMgr.childHasKeyboardFocus(this) && !getIsChrome() && !getCurrentTitle().empty()) { - static LLUICachedControl titlebar_focus_color ("TitleBarFocusColor", *(new LLColor4)); + static LLUIColor titlebar_focus_color = LLUIColorTable::instance().getColor("TitleBarFocusColor"); // draw highlight on title bar to indicate focus. RDW const LLFontGL* font = LLFontGL::getFontSansSerif(); LLRect r = getRect(); @@ -1533,10 +1642,10 @@ void LLFloater::draw() { // add in a border to improve spacialized visual aclarity ;) // use lines instead of gl_rect_2d so we can round the edges as per james' recommendation - static LLUICachedControl focus_border_color ("FloaterFocusBorderColor", *(new LLColor4)); - static LLUICachedControl unfocus_border_color ("FloaterUnfocusBorderColor", *(new LLColor4)); + static LLUIColor focus_border_color = LLUIColorTable::instance().getColor("FloaterFocusBorderColor"); + static LLUIColor unfocus_border_color = LLUIColorTable::instance().getColor("FloaterUnfocusBorderColor"); LLUI::setLineWidth(1.5f); - LLColor4 outlineColor = gFocusMgr.childHasKeyboardFocus(this) ? focus_border_color() : unfocus_border_color; + LLColor4 outlineColor = gFocusMgr.childHasKeyboardFocus(this) ? focus_border_color : unfocus_border_color; gl_rect_2d_offset_local(0, getRect().getHeight() + 1, getRect().getWidth() + 1, 0, outlineColor, -LLPANEL_BORDER_WIDTH, FALSE); LLUI::setLineWidth(1.f); } @@ -1692,14 +1801,24 @@ void LLFloater::buildButtons() p.rect(btn_rect); p.label(""); p.image_unselected.name(sButtonActiveImageNames[i]); + // Selected, no matter if hovered or not, is "pressed" p.image_selected.name(sButtonPressedImageNames[i]); p.image_hover_selected.name(sButtonPressedImageNames[i]); - p.image_hover_unselected.name(sButtonPressedImageNames[i]); + // Empty string means programmatic glow effect, achieved by + // not setting explicit image. + if (sButtonHoveredImageNames[i].empty()) + { + // These icons are really small, need glow amount increased + p.hover_glow_amount( 0.22f ); + } + else + { + p.image_hover_unselected.name(sButtonHoveredImageNames[i]); + } p.click_callback.function(boost::bind(sButtonCallbacks[i], this)); p.tab_stop(false); p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT); p.tool_tip(sButtonToolTips[i]); - p.image_color(LLUI::getCachedColorFunctor("FloaterButtonImageColor")); p.scale_image(true); LLButton* buttonp = LLUICtrlFactory::create(p); @@ -2149,7 +2268,8 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out // convert to local coordinate frame LLRect snap_rect_local = getLocalSnapRect(); - if( floater->isResizable() ) + // only automatically resize non-minimized, resizable floaters + if( floater->isResizable() && !floater->isMinimized() ) { LLRect view_rect = floater->getRect(); S32 old_width = view_rect.getWidth(); @@ -2447,6 +2567,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p) setCanTearOff(p.can_tear_off); setCanMinimize(p.can_minimize); setCanClose(p.can_close); + setCanDock(p.can_dock); mDragOnLeft = p.can_drag_on_left; mResizable = p.can_resize; @@ -2463,18 +2584,25 @@ void LLFloater::initFromParams(const LLFloater::Params& p) { mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set } + + // open callback + if (p.open_callback.isProvided()) + initCommitCallback(p.open_callback, mOpenSignal); + // close callback + if (p.close_callback.isProvided()) + initCommitCallback(p.close_callback, mCloseSignal); } -void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floater, LLXMLNodePtr output_node) +void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { - Params params(LLUICtrlFactory::getDefaultParams()); + Params params(LLUICtrlFactory::getDefaultParams()); LLXUIParser::instance().readXUI(node, params); if (output_node) { Params output_params(params); setupParamsForExport(output_params, parent); - Params default_params(LLUICtrlFactory::getDefaultParams()); + Params default_params(LLUICtrlFactory::getDefaultParams()); output_node->setName(node->getName()->mString); LLXUIParser::instance().writeXUI( output_node, output_params, &default_params); @@ -2491,7 +2619,7 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floa LLFloater::setFloaterHost((LLMultiFloater*) this); } - LLUICtrlFactory::createChildren(this, node, output_node); + LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node); if (node->hasName("multi_floater")) { @@ -2508,38 +2636,6 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floa applyRectControl(); // If we have a saved rect control, apply it gFloaterView->adjustToFitScreen(this, FALSE); // Floaters loaded from XML should all fit on screen - if (open_floater) - { - this->openFloater(getKey()); - } - moveResizeHandlesToFront(); } -// visibility methods -bool VisibilityPolicy::visible(LLFloater* instance, const LLSD& key) -{ - if (instance) - { - return !instance->isMinimized() && instance->isInVisibleChain(); - } - return FALSE; -} - -void VisibilityPolicy::show(LLFloater* instance, const LLSD& key) -{ - if (instance) - { - instance->openFloater(key); - if (instance->getHost()) - { - instance->getHost()->openFloater(key); - } - } -} - -void VisibilityPolicy::hide(LLFloater* instance, const LLSD& key) -{ - if (instance) instance->closeFloater(); -} - diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 3e80f1b284..ee066317e0 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -97,11 +97,13 @@ public: enum EFloaterButtons { - BUTTON_CLOSE, + BUTTON_CLOSE = 0, BUTTON_RESTORE, BUTTON_MINIMIZE, BUTTON_TEAR_OFF, BUTTON_EDIT, + BUTTON_DOCK, + BUTTON_UNDOCK, BUTTON_COUNT }; @@ -119,32 +121,22 @@ public: can_drag_on_left, can_tear_off, save_rect, - save_visibility; - - Params() : - title("title"), - short_title("short_title"), - single_instance("single_instance", false), - auto_tile("auto_tile", false), - can_resize("can_resize", false), - can_minimize("can_minimize", true), - can_close("can_close", true), - can_drag_on_left("can_drag_on_left", false), - can_tear_off("can_tear_off", true), - save_rect("save_rect", false), - save_visibility("save_visibility", false) - { - name = "floater"; - // defaults that differ from LLPanel: - background_visible = true; - visible = false; - } + save_visibility, + can_dock; + + Optional open_callback, + close_callback; + + Params(); }; // use this to avoid creating your own default LLFloater::Param instance static const Params& getDefaultParams(); - LLFloater(const LLSD& key = LLSD(), const Params& params = getDefaultParams()); + // Load translations for tooltips for standard buttons + static void initClass(); + + LLFloater(const LLSD& key, const Params& params = getDefaultParams()); virtual ~LLFloater(); @@ -152,7 +144,7 @@ public: static void setupParamsForExport(Params& p, LLView* parent); void initFromParams(const LLFloater::Params& p); - void initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floater = TRUE, LLXMLNodePtr output_node = NULL); + void initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false); /*virtual*/ BOOL canSnapTo(const LLView* other_view); @@ -166,7 +158,6 @@ public: void openFloater(const LLSD& key = LLSD()); // If allowed, close the floater cleanly, releasing focus. - // app_quitting is passed to onClose() below. void closeFloater(bool app_quitting = false); /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -216,20 +207,16 @@ public: virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); virtual void draw(); - + + // *TODO: Eliminate this in favor of mOpenSignal virtual void onOpen(const LLSD& key) {} - // Call destroy() to free memory, or setVisible(FALSE) to keep it - // If app_quitting, you might not want to save your visibility. - // Defaults to destroy(). - virtual void onClose(bool app_quitting) { destroy(); } - // This cannot be "const" until all derived floater canClose() // methods are const as well. JC virtual BOOL canClose() { return TRUE; } - virtual void setVisible(BOOL visible); - virtual void onVisibilityChange ( BOOL curVisibilityIn ); + /*virtual*/ void setVisible(BOOL visible); // do not override + /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // do not override void setFrontmost(BOOL take_focus = TRUE); @@ -245,6 +232,14 @@ public: LLHandle getHandle() const { return mHandle; } const LLSD& getKey() { return mKey; } BOOL matchesKey(const LLSD& key) { return mSingleInstance || KeyCompare::equate(key, mKey); } + + const std::string& getInstanceName() { return mInstanceName; } + + bool isDockable() const { return mCanDock; } + void setCanDock(bool b); + + bool isDocked() const { return mDocked; } + virtual void setDocked(bool docked, bool pop_on_undock = true); // Return a closeable floater, if any, given the current focus. static LLFloater* getClosableFloaterFromFocus(); @@ -262,6 +257,7 @@ public: static void onClickMinimize(LLFloater* floater); static void onClickTearOff(LLFloater* floater); static void onClickEdit(LLFloater* floater); + static void onClickDock(LLFloater* floater); static void setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; } static void setEditModeEnabled(BOOL enable); @@ -287,10 +283,9 @@ protected: void setAutoFocus(BOOL focus) { mAutoFocus = focus; } // whether to automatically take focus when opened LLDragHandle* getDragHandle() const { return mDragHandle; } - void destroy() { die(); } // Don't call this directly. You probably want to call close(). JC + void destroy() { die(); } // Don't call this directly. You probably want to call closeFloater() private: - void setForeground(BOOL b); // called only by floaterview void cleanupHandles(); // remove handles to dead floaters void createMinimizeButton(); @@ -299,18 +294,20 @@ private: BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index); void addResizeCtrls(); void addDragHandle(); - + protected: std::string mRectControl; std::string mVisibilityControl; - + commit_signal_t mOpenSignal; // Called when floater is opened, passes mKey + commit_signal_t mCloseSignal; // Called when floater is closed, passes app_qitting as LLSD() LLSD mKey; // Key used for retrieving instances; set (for now) by LLFLoaterReg - -private: - LLRect mExpandedRect; + LLDragHandle* mDragHandle; LLResizeBar* mResizeBar[4]; LLResizeHandle* mResizeHandle[4]; + +private: + LLRect mExpandedRect; LLUIString mTitle; LLUIString mShortTitle; @@ -349,10 +346,15 @@ private: LLHandle mHostHandle; LLHandle mLastHostHandle; + bool mCanDock; + bool mDocked; + static LLMultiFloater* sHostp; static BOOL sEditModeEnabled; + static BOOL sQuitting; static std::string sButtonActiveImageNames[BUTTON_COUNT]; - static std::string sButtonInactiveImageNames[BUTTON_COUNT]; + // Images to use when cursor hovered over an enabled button + static std::string sButtonHoveredImageNames[BUTTON_COUNT]; static std::string sButtonPressedImageNames[BUTTON_COUNT]; static std::string sButtonNames[BUTTON_COUNT]; static std::string sButtonToolTips[BUTTON_COUNT]; @@ -378,6 +380,7 @@ private: LLRootHandle mHandle; }; + ///////////////////////////////////////////////////////////// // LLFloaterView // Parent of all floating panels @@ -441,33 +444,6 @@ private: S32 mSnapOffsetRight; }; -// singleton implementation for floaters -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=164990 - -//******************************************************* -//* TO BE DEPRECATED -//******************************************************* -// visibility policy specialized for floaters -template<> -class VisibilityPolicy -{ -public: - // visibility methods - static bool visible(LLFloater* instance, const LLSD& key); - - static void show(LLFloater* instance, const LLSD& key); - - static void hide(LLFloater* instance, const LLSD& key); -}; - - -// singleton implementation for floaters (provides visibility policy) -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=164990 - -template class LLFloaterSingleton : public LLUISingleton > -{ -}; - // // Globals // diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index faa763cea9..a63b1b085c 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -121,8 +121,7 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key) res = build_func(key); - const bool DONT_OPEN_FLOATER = false; - LLUICtrlFactory::getInstance()->buildFloater(res, xui_file, DONT_OPEN_FLOATER); + LLUICtrlFactory::getInstance()->buildFloater(res, xui_file, NULL); // Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe res->mKey = key; @@ -363,6 +362,24 @@ std::string LLFloaterReg::declareVisibilityControl(const std::string& name) return controlname; } +//static +void LLFloaterReg::registerControlVariables() +{ + // Iterate through alll registered instance names and register rect and visibility control variables + for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter) + { + const std::string& name = iter->first; + if (LLUI::sSettingGroups["floater"]->controlExists(getRectControlName(name))) + { + declareRectControl(name); + } + if (LLUI::sSettingGroups["floater"]->controlExists(getVisibilityControlName(name))) + { + declareVisibilityControl(name); + } + } +} + // Callbacks // static diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index ef2f71ad18..7edac43c96 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -120,6 +120,7 @@ public: static std::string declareRectControl(const std::string& name); static std::string getVisibilityControlName(const std::string& name); static std::string declareVisibilityControl(const std::string& name); + static void registerControlVariables(); // Callback wrappers static void initUICtrlToFloaterVisibilityControl(LLUICtrl* ctrl, const LLSD& sdname); diff --git a/indra/llui/llflyoutbutton.cpp b/indra/llui/llflyoutbutton.cpp index 8846f2a8c4..536919c072 100644 --- a/indra/llui/llflyoutbutton.cpp +++ b/indra/llui/llflyoutbutton.cpp @@ -35,7 +35,7 @@ // file includes #include "llflyoutbutton.h" -//static LLDefaultWidgetRegistry::Register r2("flyout_button"); +//static LLDefaultChildRegistry::Register r2("flyout_button"); const S32 FLYOUT_BUTTON_ARROW_WIDTH = 24; @@ -54,11 +54,6 @@ LLFlyoutButton::LLFlyoutButton(const Params& p) mActionButton = LLUICtrlFactory::create(bp); addChild(mActionButton); - - mButton->setOrigin(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, 0); - mButton->reshape(FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight()); - mButton->setFollows(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); - mButton->setImageOverlay(mListPosition == BELOW ? "down_arrow.tga" : "up_arrow.tga", LLFontGL::RIGHT); } void LLFlyoutButton::onActionButtonClick(const LLSD& data) @@ -75,7 +70,7 @@ void LLFlyoutButton::draw() //FIXME: this should be an attribute of comboboxes, whether they have a distinct label or // the label reflects the last selected item, for now we have to manually remove the label - mButton->setLabel(LLStringUtil::null); + setLabel(LLStringUtil::null); LLComboBox::draw(); } diff --git a/indra/llui/llflyoutbutton.h b/indra/llui/llflyoutbutton.h index f60fe1eb35..1f1716593a 100644 --- a/indra/llui/llflyoutbutton.h +++ b/indra/llui/llflyoutbutton.h @@ -46,10 +46,14 @@ public: struct Params : public LLInitParam::Block { Optional action_button; + Deprecated allow_text_entry; Params() - : action_button("action_button") - {} + : action_button("action_button"), + allow_text_entry("allow_text_entry") + { + LLComboBox::Params::allow_text_entry = false; + } }; protected: diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 9a4ec7627e..a66f147dcc 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -323,7 +323,7 @@ F32 LLFocusMgr::getFocusFlashAmt() const LLColor4 LLFocusMgr::getFocusColor() const { - static LLUICachedControl focus_color_cached ("FocusColor", *(new LLColor4)); + static LLUIColor focus_color_cached = LLUIColorTable::instance().getColor("FocusColor"); LLColor4 focus_color = lerp(focus_color_cached, LLColor4::white, getFocusFlashAmt()); // de-emphasize keyboard focus when app has lost focus (to avoid typing into wrong window problem) if (!mAppHasFocus) diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h new file mode 100644 index 0000000000..10a7fd4544 --- /dev/null +++ b/indra/llui/llhandle.h @@ -0,0 +1,171 @@ +/** +* @file llhandle.h +* @brief "Handle" to an object (usually a floater) whose lifetime you don't +* control. +* +* $LicenseInfo:firstyear=2001&license=viewergpl$ +* +* Copyright (c) 2001-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#ifndef LLHANDLE_H +#define LLHANDLE_H + +#include "llpointer.h" + +template +class LLTombStone : public LLRefCount +{ +public: + LLTombStone(T* target = NULL) : mTarget(target) {} + + void setTarget(T* target) { mTarget = target; } + T* getTarget() const { return mTarget; } +private: + T* mTarget; +}; + +// LLHandles are used to refer to objects whose lifetime you do not control or influence. +// Calling get() on a handle will return a pointer to the referenced object or NULL, +// if the object no longer exists. Note that during the lifetime of the returned pointer, +// you are assuming that the object will not be deleted by any action you perform, +// or any other thread, as normal when using pointers, so avoid using that pointer outside of +// the local code block. +// +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 + +template +class LLHandle +{ +public: + LLHandle() : mTombStone(sDefaultTombStone) {} + const LLHandle& operator =(const LLHandle& other) + { + mTombStone = other.mTombStone; + return *this; + } + + bool isDead() const + { + return mTombStone->getTarget() == NULL; + } + + void markDead() + { + mTombStone = sDefaultTombStone; + } + + T* get() const + { + return mTombStone->getTarget(); + } + + friend bool operator== (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone == rhs.mTombStone; + } + friend bool operator!= (const LLHandle& lhs, const LLHandle& rhs) + { + return !(lhs == rhs); + } + friend bool operator< (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone < rhs.mTombStone; + } + friend bool operator> (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone > rhs.mTombStone; + } +protected: + +protected: + LLPointer > mTombStone; + +private: + static LLPointer > sDefaultTombStone; +}; + +// initialize static "empty" tombstone pointer +template LLPointer > LLHandle::sDefaultTombStone = new LLTombStone(); + + +template +class LLRootHandle : public LLHandle +{ +public: + LLRootHandle(T* object) { bind(object); } + LLRootHandle() {}; + ~LLRootHandle() { unbind(); } + + // this is redundant, since a LLRootHandle *is* an LLHandle + LLHandle getHandle() { return LLHandle(*this); } + + void bind(T* object) + { + // unbind existing tombstone + if (LLHandle::mTombStone.notNull()) + { + if (LLHandle::mTombStone->getTarget() == object) return; + LLHandle::mTombStone->setTarget(NULL); + } + // tombstone reference counted, so no paired delete + LLHandle::mTombStone = new LLTombStone(object); + } + + void unbind() + { + LLHandle::mTombStone->setTarget(NULL); + } + + //don't allow copying of root handles, since there should only be one +private: + LLRootHandle(const LLRootHandle& other) {}; +}; + +// Use this as a mixin for simple classes that need handles and when you don't +// want handles at multiple points of the inheritance hierarchy +template +class LLHandleProvider +{ +protected: + typedef LLHandle handle_type_t; + LLHandleProvider() + { + // provided here to enforce T deriving from LLHandleProvider + } + + LLHandle getHandle() + { + // perform lazy binding to avoid small tombstone allocations for handle + // providers whose handles are never referenced + mHandle.bind(static_cast(this)); + return mHandle; + } + +private: + LLRootHandle mHandle; +}; + +#endif diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp index eddfc71284..5c6ea663f3 100644 --- a/indra/llui/lliconctrl.cpp +++ b/indra/llui/lliconctrl.cpp @@ -42,7 +42,7 @@ #include "lluictrlfactory.h" #include "lluiimage.h" -static LLDefaultWidgetRegistry::Register r("icon"); +static LLDefaultChildRegistry::Register r("icon"); LLIconCtrl::Params::Params() : image("image_name"), diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h index a6cab0e9ee..ff25b0d53e 100644 --- a/indra/llui/lliconctrl.h +++ b/indra/llui/lliconctrl.h @@ -37,7 +37,6 @@ #include "v4color.h" #include "lluictrl.h" #include "stdenums.h" -#include "llimagegl.h" class LLTextBox; class LLUICtrlFactory; diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 39dac296ea..702d8e4a39 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -38,7 +38,7 @@ #include "llresizebar.h" #include "llcriticaldamp.h" -static LLDefaultWidgetRegistry::Register register_layout_stack("layout_stack", &LLLayoutStack::fromXML); +static LLDefaultChildRegistry::Register register_layout_stack("layout_stack", &LLLayoutStack::fromXML); // @@ -120,7 +120,8 @@ struct LLLayoutStack::LayoutPanel LLLayoutStack::Params::Params() : orientation("orientation", std::string("vertical")), - animate("animate", TRUE), + animate("animate", true), + clip("clip", true), border_size("border_size", LLCachedControl(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0)) { name="stack"; @@ -132,7 +133,8 @@ LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p) mMinHeight(0), mPanelSpacing(p.border_size), mOrientation((p.orientation() == "vertical") ? VERTICAL : HORIZONTAL), - mAnimate(p.animate) + mAnimate(p.animate), + mClip(p.clip) {} LLLayoutStack::~LLLayoutStack() @@ -163,7 +165,7 @@ void LLLayoutStack::draw() LLPanel* panelp = (*panel_it)->mPanel; - LLLocalClipRect clip(clip_rect); + LLLocalClipRect clip(clip_rect, mClip); // only force drawing invisible children if visible amount is non-zero drawChild(panelp, 0, 0, !clip_rect.isNull()); } @@ -223,7 +225,7 @@ static void get_attribute_bool_and_write(LLXMLNodePtr node, //static LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { - LLLayoutStack::Params p(LLUICtrlFactory::getDefaultParams()); + LLLayoutStack::Params p(LLUICtrlFactory::getDefaultParams()); LLXUIParser::instance().readXUI(node, p); // Export must happen before setupParams() mungles rectangles and before @@ -233,7 +235,7 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr o { Params output_params(p); setupParamsForExport(output_params, parent); - LLLayoutStack::Params default_params(LLUICtrlFactory::getDefaultParams()); + LLLayoutStack::Params default_params(LLUICtrlFactory::getDefaultParams()); output_node->setName(node->getName()->mString); LLXUIParser::instance().writeXUI( output_node, output_params, &default_params); @@ -296,7 +298,7 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr o LLPanel::Params p; LLPanel* panelp = LLUICtrlFactory::create(p); - LLView* new_child = LLUICtrlFactory::getInstance()->createFromXML(child_node, panelp, LLStringUtil::null, output_child, parent ? parent->getChildRegistry() : LLDefaultWidgetRegistry::instance()); + LLView* new_child = LLUICtrlFactory::getInstance()->createFromXML(child_node, panelp, LLStringUtil::null, LLPanel::child_registry_t::instance(), output_child); if (new_child) { // put child in new embedded panel diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 480bdb5c17..9459b9990c 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -43,7 +43,8 @@ public: { Optional orientation; Optional border_size; - Optional animate; + Optional animate; + Optional clip; // mMinWidth and mMinHeight are calculated, not set in XML Params(); @@ -100,6 +101,7 @@ private: S32 mPanelSpacing; bool mAnimate; + bool mClip; }; // end class LLLayoutStack #endif diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 5ea45e13cf..f94eb7fcc3 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -34,8 +34,6 @@ #include "linden_common.h" -#define INSTANTIATE_GETCHILD_LINEEDITOR - #include "lllineeditor.h" #include "lltexteditor.h" @@ -72,9 +70,7 @@ const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing const F32 AUTO_SCROLL_TIME = 0.05f; const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. *TODO: make this equal to the double click interval? -static LLDefaultWidgetRegistry::Register r1("line_editor"); - -template LLLineEditor* LLView::getChild( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; +static LLDefaultChildRegistry::Register r1("line_editor"); // // Member functions @@ -95,7 +91,11 @@ void LLLineEditor::PrevalidateNamedFuncs::declareValues() LLLineEditor::Params::Params() : max_length_bytes("max_length", 254), + keystroke_callback("keystroke_callback"), + prevalidate_callback("prevalidate_callback"), background_image("background_image"), + background_image_disabled("background_image_disabled"), + background_image_focused("background_image_focused"), select_on_focus("select_on_focus", false), handle_edit_keys_directly("handle_edit_keys_directly", false), commit_on_focus_lost("commit_on_focus_lost", true), @@ -104,9 +104,8 @@ LLLineEditor::Params::Params() text_color("text_color"), text_readonly_color("text_readonly_color"), text_tentative_color("text_tentative_color"), - bg_readonly_color("bg_readonly_color"), - bg_writeable_color("bg_writeable_color"), - bg_focus_color("bg_focus_color"), + highlight_color("highlight_color"), + preedit_bg_color("preedit_bg_color"), border(""), is_unicode("is_unicode"), drop_shadow_visible("drop_shadow_visible"), @@ -119,6 +118,7 @@ LLLineEditor::Params::Params() mouse_opaque = true; addSynonym(select_on_focus, "select_all_on_focus_received"); addSynonym(border, "border"); + addSynonym(label, "watermark_text"); } LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) @@ -128,6 +128,8 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mScrollHPos( 0 ), mTextPadLeft(p.text_pad_left), mTextPadRight(p.text_pad_right), + mMinHPixels(0), // computed in updateTextPadding() below + mMaxHPixels(0), // computed in updateTextPadding() below mCommitOnFocusLost( p.commit_on_focus_lost ), mRevertOnEsc( TRUE ), mKeystrokeCallback( p.keystroke_callback() ), @@ -146,18 +148,18 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mSelectAllonFocusReceived( p.select_on_focus ), mPassDelete(FALSE), mReadOnly(FALSE), - mImage( NULL ), + mBgImage( p.background_image ), + mBgImageDisabled( p.background_image_disabled ), + mBgImageFocused( p.background_image_focused ), mReplaceNewlinesWithSpaces( TRUE ), mLabel(p.label), mCursorColor(p.cursor_color()), mFgColor(p.text_color()), mReadOnlyFgColor(p.text_readonly_color()), mTentativeFgColor(p.text_tentative_color()), - mWriteableBgColor(p.bg_writeable_color()), - mReadOnlyBgColor(p.bg_readonly_color()), - mFocusBgColor(p.bg_focus_color()), - mGLFont(p.font), - mGLFontStyle(LLFontGL::getStyleFromString(p.font.style)) + mHighlightColor(p.highlight_color()), + mPreeditBgColor(p.preedit_bg_color()), + mGLFont(p.font) { llassert( mMaxLengthBytes > 0 ); @@ -180,7 +182,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) LLViewBorder::Params border_p(p.border); border_p.rect = border_rect; border_p.follows.flags = FOLLOWS_ALL; - border_p.bevel_type = LLViewBorder::BEVEL_IN; + border_p.bevel_style = LLViewBorder::BEVEL_IN; mBorder = LLUICtrlFactory::create(border_p); addChild( mBorder ); @@ -233,6 +235,7 @@ void LLLineEditor::onFocusLost() LLUICtrl::onFocusLost(); } +// virtual void LLLineEditor::onCommit() { // put current line into the line history @@ -243,6 +246,33 @@ void LLLineEditor::onCommit() selectAll(); } +// Returns TRUE if user changed value at all +// virtual +BOOL LLLineEditor::isDirty() const +{ + return mText.getString() != mPrevText; +} + +// Clear dirty state +// virtual +void LLLineEditor::resetDirty() +{ + mPrevText = mText.getString(); +} + +// assumes UTF8 text +// virtual +void LLLineEditor::setValue(const LLSD& value ) +{ + setText(value.asString()); +} + +//virtual +LLSD LLLineEditor::getValue() const +{ + return LLSD(getText()); +} + // line history support void LLLineEditor::updateHistory() @@ -1493,6 +1523,33 @@ void LLLineEditor::doDelete() } +void LLLineEditor::drawBackground() +{ + bool has_focus = hasFocus(); + LLUIImage* image; + if ( mReadOnly ) + { + image = mBgImageDisabled; + } + else if ( has_focus ) + { + image = mBgImageFocused; + } + else + { + image = mBgImage; + } + + // optionally draw programmatic border + if (has_focus) + { + image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), + gFocusMgr.getFocusColor(), + gFocusMgr.getFocusFlashWidth()); + } + image->draw(getLocalRect()); +} + void LLLineEditor::draw() { S32 text_len = mText.length(); @@ -1523,37 +1580,12 @@ void LLLineEditor::draw() LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 ); background.stretch( -mBorderThickness ); - LLColor4 bg_color = mReadOnlyBgColor.get(); - -#if 0 // for when we're ready for image art. - if( hasFocus()) - { - mImage->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); - } - mImage->draw(getLocalRect(), mReadOnly ? mReadOnlyBgColor : mWriteableBgColor ); -#else // the old programmer art. - // drawing solids requires texturing be disabled - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - // draw background for text - if( !mReadOnly ) - { - if( gFocusMgr.getKeyboardFocus() == this ) - { - bg_color = mFocusBgColor.get(); - } - else - { - bg_color = mWriteableBgColor.get(); - } - } - gl_rect_2d(background, bg_color); - } -#endif - + drawBackground(); + // draw text - S32 cursor_bottom = background.mBottom + 1; + // With viewer-2 art files, input region is 2 pixels up + S32 cursor_bottom = background.mBottom + 2; S32 cursor_top = background.mTop - 1; LLColor4 text_color; @@ -1595,7 +1627,8 @@ void LLLineEditor::draw() background.mBottom + preedit_standout_position, preedit_pixels_right - preedit_standout_gap - 1, background.mBottom + preedit_standout_position - preedit_standout_thickness, - (text_color * preedit_standout_brightness + bg_color * (1 - preedit_standout_brightness)).setAlpha(1.0f)); + (text_color * preedit_standout_brightness + + mPreeditBgColor * (1 - preedit_standout_brightness)).setAlpha(1.0f)); } else { @@ -1603,7 +1636,8 @@ void LLLineEditor::draw() background.mBottom + preedit_marker_position, preedit_pixels_right - preedit_marker_gap - 1, background.mBottom + preedit_marker_position - preedit_marker_thickness, - (text_color * preedit_marker_brightness + bg_color * (1 - preedit_marker_brightness)).setAlpha(1.0f)); + (text_color * preedit_marker_brightness + + mPreeditBgColor * (1 - preedit_marker_brightness)).setAlpha(1.0f)); } } } @@ -1636,7 +1670,7 @@ void LLLineEditor::draw() rendered_pixels_right, text_bottom, text_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, select_left - mScrollHPos, mMaxHPixels - llround(rendered_pixels_right), @@ -1645,7 +1679,7 @@ void LLLineEditor::draw() if( (rendered_pixels_right < (F32)mMaxHPixels) && (rendered_text < text_len) ) { - LLColor4 color(1.f - bg_color.mV[0], 1.f - bg_color.mV[1], 1.f - bg_color.mV[2], 1.f); + LLColor4 color = mHighlightColor; // selected middle S32 width = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos + rendered_text, select_right - mScrollHPos - rendered_text); width = llmin(width, mMaxHPixels - llround(rendered_pixels_right)); @@ -1656,7 +1690,7 @@ void LLLineEditor::draw() rendered_pixels_right, text_bottom, LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ), LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, select_right - mScrollHPos - rendered_text, mMaxHPixels - llround(rendered_pixels_right), @@ -1671,7 +1705,7 @@ void LLLineEditor::draw() rendered_pixels_right, text_bottom, text_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, S32_MAX, mMaxHPixels - llround(rendered_pixels_right), @@ -1685,13 +1719,13 @@ void LLLineEditor::draw() rendered_pixels_right, text_bottom, text_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, S32_MAX, mMaxHPixels - llround(rendered_pixels_right), &rendered_pixels_right); } -#if 0 // for when we're ready for image art. +#if 1 // for when we're ready for image art. mBorder->setVisible(FALSE); // no more programmatic art. #endif @@ -1723,7 +1757,7 @@ void LLLineEditor::draw() mGLFont->render(mText, getCursor(), (F32)(cursor_left + lineeditor_cursor_thickness / 2), text_bottom, LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ), LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, 1); } @@ -1749,7 +1783,7 @@ void LLLineEditor::draw() label_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, S32_MAX, mMaxHPixels - llround(rendered_pixels_right), @@ -1774,7 +1808,7 @@ void LLLineEditor::draw() label_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, S32_MAX, mMaxHPixels - llround(rendered_pixels_right), diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index eb021bace9..0986ce5a87 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -84,7 +84,9 @@ public: Optional border; - Optional background_image; + Optional background_image, + background_image_disabled, + background_image_focused; Optional select_on_focus, handle_edit_keys_directly, @@ -96,10 +98,9 @@ public: text_color, text_readonly_color, text_tentative_color, - bg_readonly_color, - bg_writeable_color, - bg_focus_color; - + highlight_color, + preedit_bg_color; + Optional text_pad_left, text_pad_right; @@ -107,7 +108,7 @@ public: drop_shadow_visible, border_drop_shadow_visible, bg_visible; - + Params(); }; protected: @@ -163,12 +164,12 @@ public: virtual void setRect(const LLRect& rect); virtual BOOL acceptsTextInput() const; virtual void onCommit(); - virtual BOOL isDirty() const { return mText.getString() != mPrevText; } // Returns TRUE if user changed value at all - virtual void resetDirty() { mPrevText = mText.getString(); } // Clear dirty state + virtual BOOL isDirty() const; // Returns TRUE if user changed value at all + virtual void resetDirty(); // Clear dirty state // assumes UTF8 text - virtual void setValue(const LLSD& value ) { setText(value.asString()); } - virtual LLSD getValue() const { return LLSD(getText()); } + virtual void setValue(const LLSD& value ); + virtual LLSD getValue() const; virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); @@ -197,16 +198,10 @@ public: void setFgColor( const LLColor4& c ) { mFgColor = c; } void setReadOnlyFgColor( const LLColor4& c ) { mReadOnlyFgColor = c; } void setTentativeFgColor(const LLColor4& c) { mTentativeFgColor = c; } - void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; } - void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } - void setFocusBgColor(const LLColor4& c) { mFocusBgColor = c; } const LLColor4& getFgColor() const { return mFgColor.get(); } const LLColor4& getReadOnlyFgColor() const { return mReadOnlyFgColor.get(); } const LLColor4& getTentativeFgColor() const { return mTentativeFgColor.get(); } - const LLColor4& getWriteableBgColor() const { return mWriteableBgColor.get(); } - const LLColor4& getReadOnlyBgColor() const { return mReadOnlyBgColor.get(); } - const LLColor4& getFocusBgColor() const { return mFocusBgColor.get(); } void setIgnoreArrowKeys(BOOL b) { mIgnoreArrowKeys = b; } void setIgnoreTab(BOOL b) { mIgnoreTab = b; } @@ -266,6 +261,9 @@ private: BOOL handleControlKey(KEY key, MASK mask); S32 handleCommitKey(KEY key, MASK mask); void updateTextPadding(); + + // Draw the background image depending on enabled/focused state. + void drawBackground(); // // private data members @@ -294,7 +292,6 @@ protected: LLViewBorder* mBorder; const LLFontGL* mGLFont; - U8 mGLFontStyle; S32 mMaxLengthBytes; // Max length of the UTF8 string in bytes S32 mCursorPos; // I-beam is just after the mCursorPos-th character. S32 mScrollHPos; // Horizontal offset from the start of mText. Used for scrolling. @@ -326,9 +323,8 @@ protected: LLUIColor mFgColor; LLUIColor mReadOnlyFgColor; LLUIColor mTentativeFgColor; - LLUIColor mWriteableBgColor; - LLUIColor mReadOnlyBgColor; - LLUIColor mFocusBgColor; + LLUIColor mHighlightColor; // background for selected text + LLUIColor mPreeditBgColor; // preedit marker background color S32 mBorderThickness; @@ -349,7 +345,9 @@ protected: private: // Instances that by default point to the statics but can be overidden in XML. - LLPointer mImage; + LLPointer mBgImage; + LLPointer mBgImageDisabled; + LLPointer mBgImageFocused; BOOL mReplaceNewlinesWithSpaces; // if false, will replace pasted newlines with paragraph symbol. @@ -392,12 +390,6 @@ private: }; // end class LLLineEditor -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_LINEEDITOR -#pragma warning (disable : 4231) -extern template LLLineEditor* LLView::getChild( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif namespace LLInitParam { diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 4af1c1241b..e355cfda8b 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -49,12 +49,12 @@ #include "llmath.h" #include "llrender.h" #include "llfocusmgr.h" -#include "llfont.h" #include "llcoord.h" #include "llwindow.h" #include "llcriticaldamp.h" #include "lluictrlfactory.h" +#include "llbutton.h" #include "llfontgl.h" #include "llresmgr.h" #include "llui.h" @@ -89,7 +89,6 @@ const U32 RIGHT_PAD_PIXELS = 2; const U32 RIGHT_WIDTH_PIXELS = 15; const U32 RIGHT_PLAIN_PIXELS = RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS; -const U32 ACCEL_PAD_PIXELS = 10; const U32 PLAIN_PAD_PIXELS = LEFT_PAD_PIXELS + LEFT_WIDTH_PIXELS + RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS; const U32 BRIEF_PAD_PIXELS = 2; @@ -119,16 +118,12 @@ const F32 PIE_SHRINK_TIME = 0.2f; // time of transition between unbounded and bo const F32 ACTIVATE_HIGHLIGHT_TIME = 0.3f; -// widget registrars -struct MenuRegistry : public LLWidgetRegistry -{}; - static MenuRegistry::Register register_separator("menu_item_separator"); static MenuRegistry::Register register_menu_item_call("menu_item_call"); static MenuRegistry::Register register_menu_item_check("menu_item_check"); static MenuRegistry::Register register_menu("menu"); -static LLDefaultWidgetRegistry::Register register_menu_default("menu"); +static LLDefaultChildRegistry::Register register_menu_default("menu"); @@ -306,7 +301,7 @@ U32 LLMenuItemGL::getNominalHeight( void ) const // Get the parent menu for this item -LLMenuGL* LLMenuItemGL::getMenu() +LLMenuGL* LLMenuItemGL::getMenu() const { return (LLMenuGL*) getParent(); } @@ -330,7 +325,7 @@ U32 LLMenuItemGL::getNominalWidth( void ) const if( KEY_NONE != mAcceleratorKey ) { - width += ACCEL_PAD_PIXELS; + width += getMenu()->getShortcutPad(); std::string temp; appendAcceleratorString( temp ); width += mFont->getWidth( temp ); @@ -519,12 +514,13 @@ BOOL LLMenuItemGL::setLabelArg( const std::string& key, const LLStringExplicit& return TRUE; } -void LLMenuItemGL::onVisibilityChange(BOOL new_visibility) +void LLMenuItemGL::handleVisibilityChange(BOOL new_visibility) { if (getMenu()) { getMenu()->needsArrange(); } + LLView::handleVisibilityChange(new_visibility); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -797,6 +793,16 @@ BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask ) return FALSE; } +BOOL LLMenuItemCallGL::handleRightMouseUp(S32 x, S32 y, MASK mask) +{ + if (pointInView(x, y)) + { + mRightClickSignal(this, getValue()); + } + + return TRUE; +} + ///============================================================================ /// Class LLMenuItemCheckGL ///============================================================================ @@ -1061,13 +1067,13 @@ void LLMenuItemBranchGL::updateBranchParent(LLView* parentp) } } -void LLMenuItemBranchGL::onVisibilityChange( BOOL new_visibility ) +void LLMenuItemBranchGL::handleVisibilityChange( BOOL new_visibility ) { if (new_visibility == FALSE && getBranch() && !getBranch()->getTornOff()) { getBranch()->setVisible(FALSE); } - LLMenuItemGL::onVisibilityChange(new_visibility); + LLMenuItemGL::handleVisibilityChange(new_visibility); } BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask ) @@ -1457,6 +1463,7 @@ void LLMenuItemBranchDownGL::draw( void ) setHover(FALSE); } + class LLMenuScrollItem : public LLMenuItemCallGL { public: @@ -1465,10 +1472,18 @@ public: ARROW_DOWN, ARROW_UP }; + struct ArrowTypes : public LLInitParam::TypeValuesHelper + { + static void declareValues() + { + declare("up", ARROW_UP); + declare("down", ARROW_DOWN); + } + }; struct Params : public LLInitParam::Block { - Optional arrow_type; + Optional arrow_type; Optional scroll_callback; }; @@ -1572,7 +1587,8 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p) mJumpKey(p.jump_key), mCreateJumpKeys(p.create_jump_keys), mParentFloaterHandle(p.parent_floater), - mNeedsArrange(FALSE) + mNeedsArrange(FALSE), + mShortcutPad(p.shortcut_pad) { typedef boost::tokenizer > tokenizer; boost::char_separator sep("_"); @@ -1646,15 +1662,17 @@ bool LLMenuGL::addChild(LLView* view, S32 tab_group) void LLMenuGL::removeChild( LLView* ctrl) { - LLMenuItemGL* itemp = dynamic_cast(ctrl); - if (itemp) + // previously a dynamic_cast with if statement to check validity + // unfortunately removeChild is called by ~LLView, and at that point the + // object being deleted is no longer a LLMenuItemGL so a dynamic_cast will fail + LLMenuItemGL* itemp = static_cast(ctrl); + + item_list_t::iterator found_it = std::find(mItems.begin(), mItems.end(), (itemp)); + if (found_it != mItems.end()) { - item_list_t::iterator found_it = std::find(mItems.begin(), mItems.end(), (itemp)); - if (found_it != mItems.end()) - { - mItems.erase(found_it); - } + mItems.erase(found_it); } + return LLUICtrl::removeChild(ctrl); } @@ -1664,12 +1682,6 @@ BOOL LLMenuGL::postBuild() return LLUICtrl::postBuild(); } -const widget_registry_t& LLMenuGL::getChildRegistry() const -{ - return MenuRegistry::instance(); -} - - // are we the childmost active menu and hence our jump keys should be enabled? // or are we a free-standing torn-off menu (which uses jump keys too) BOOL LLMenuGL::jumpKeysActive() @@ -2331,10 +2343,10 @@ BOOL LLMenuGL::appendMenu( LLMenuGL* menu ) p.label = menu->getLabel(); p.branch = menu; p.jump_key = menu->getJumpKey(); - p.enabled_color=LLUI::getCachedColorFunctor("MenuItemEnabledColor"); - p.disabled_color=LLUI::getCachedColorFunctor("MenuItemDisabledColor"); - p.highlight_bg_color=LLUI::getCachedColorFunctor("MenuItemHighlightBgColor"); - p.highlight_fg_color=LLUI::getCachedColorFunctor("MenuItemHighlightFgColor"); + p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor"); + p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor"); + p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor"); + p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor"); LLMenuItemBranchGL* branch = LLUICtrlFactory::create(p); success &= append( branch ); @@ -2741,7 +2753,7 @@ void LLMenuGL::draw( void ) if (mDropShadowed && !mTornOff) { static LLUICachedControl drop_shadow_floater ("DropShadowFloater", 0); - static LLUICachedControl color_drop_shadow ("ColorDropShadow", *(new LLColor4)); + static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow"); gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, color_drop_shadow, drop_shadow_floater ); } @@ -2883,7 +2895,7 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) /// Class LLMenuBarGL ///============================================================================ -static LLDefaultWidgetRegistry::Register r2("menu_bar"); +static LLDefaultChildRegistry::Register r2("menu_bar"); LLMenuBarGL::LLMenuBarGL( const Params& p ) : LLMenuGL(p), @@ -3115,10 +3127,10 @@ BOOL LLMenuBarGL::appendMenu( LLMenuGL* menu ) p.label = menu->getLabel(); p.visible = menu->getVisible(); p.branch = menu; - p.enabled_color=LLUI::getCachedColorFunctor("MenuItemEnabledColor"); - p.disabled_color=LLUI::getCachedColorFunctor("MenuItemDisabledColor"); - p.highlight_bg_color=LLUI::getCachedColorFunctor("MenuItemHighlightBgColor"); - p.highlight_fg_color=LLUI::getCachedColorFunctor("MenuItemHighlightFgColor"); + p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor"); + p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor"); + p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor"); + p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor"); LLMenuItemBranchDownGL* branch = LLUICtrlFactory::create(p); success &= branch->addToAcceleratorList(&mAccelerators); @@ -3202,6 +3214,8 @@ BOOL LLMenuBarGL::handleHover( S32 x, S32 y, MASK mask ) ///============================================================================ /// Class LLMenuHolderGL ///============================================================================ +LLCoordGL LLMenuHolderGL::sContextMenuSpawnPos(S32_MAX, S32_MAX); + LLMenuHolderGL::LLMenuHolderGL() : LLPanel() { @@ -3258,6 +3272,32 @@ BOOL LLMenuHolderGL::handleRightMouseDown( S32 x, S32 y, MASK mask ) return handled; } +// This occurs when you mouse-down to spawn a context menu, hold the button +// down, move off the menu, then mouse-up. We want this to close the menu. +BOOL LLMenuHolderGL::handleRightMouseUp( S32 x, S32 y, MASK mask ) +{ + const S32 SLOP = 2; + S32 spawn_dx = (x - sContextMenuSpawnPos.mX); + S32 spawn_dy = (y - sContextMenuSpawnPos.mY); + if (-SLOP <= spawn_dx && spawn_dx <= SLOP + && -SLOP <= spawn_dy && spawn_dy <= SLOP) + { + // we're still inside the slop region from spawning this menu + // so interpret the mouse-up as a single-click to show and leave on + // screen + sContextMenuSpawnPos.set(S32_MAX, S32_MAX); + return TRUE; + } + + BOOL handled = LLView::childrenHandleRightMouseUp(x, y, mask) != NULL; + if (!handled) + { + // clicked off of menu, hide them all + hideMenus(); + } + return handled; +} + void LLMenuHolderGL::reshape(S32 width, S32 height, BOOL called_from_parent) { if (width != getRect().getWidth() || height != getRect().getHeight()) @@ -3320,7 +3360,7 @@ void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item) /// Class LLTearOffMenu ///============================================================================ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : - LLFloater() + LLFloater(LLSD()) { static LLUICachedControl floater_header_size ("UIFloaterHeaderSize", 0); @@ -3353,6 +3393,16 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : mMenu->highlightNextItem(NULL); } +LLTearOffMenu::~LLTearOffMenu() +{ +} + +// virtual +BOOL LLTearOffMenu::postBuild() +{ + mCloseSignal.connect(boost::bind(&LLTearOffMenu::closeTearOff, this)); + return TRUE; +} void LLTearOffMenu::draw() { @@ -3452,7 +3502,7 @@ LLTearOffMenu* LLTearOffMenu::create(LLMenuGL* menup) return tearoffp; } -void LLTearOffMenu::onClose(bool app_quitting) +void LLTearOffMenu::closeTearOff() { removeChild(mMenu); mOldParent->addChild(mMenu); @@ -3462,7 +3512,6 @@ void LLTearOffMenu::onClose(bool app_quitting) mMenu->setVisible(FALSE); mMenu->setTornOff(FALSE); mMenu->setDropShadowed(TRUE); - destroy(); } @@ -3540,7 +3589,7 @@ void LLContextMenuBranch::showSubMenu() S32 center_x; S32 center_y; localPointToScreen(getRect().getWidth(), getRect().getHeight() , ¢er_x, ¢er_y); - mBranch->show( center_x, center_y, FALSE); + mBranch->show( center_x, center_y); } // onCommit() - do the primary funcationality of the menu item. @@ -3569,7 +3618,7 @@ void LLContextMenuBranch::setHighlight( BOOL highlight ) // class LLContextMenu // A context menu //----------------------------------------------------------------------------- -static LLDefaultWidgetRegistry::Register context_menu_register("context_menu"); +static LLDefaultChildRegistry::Register context_menu_register("context_menu"); static MenuRegistry::Register context_menu_register2("context_menu"); @@ -3577,7 +3626,6 @@ LLContextMenu::LLContextMenu(const Params& p) : LLMenuGL(p), mHoveredAnyItem(FALSE), mHoverItem(NULL) - { //setBackgroundVisible(TRUE); } @@ -3588,8 +3636,14 @@ void LLContextMenu::setVisible(BOOL visible) hide(); } -void LLContextMenu::show(S32 x, S32 y,BOOL adjustCursor) +// Takes cursor position in screen space? +void LLContextMenu::show(S32 x, S32 y) { + // Save click point for detecting cursor moves before mouse-up. + // Must be in local coords to compare with mouseUp events. + // If the mouse doesn't move, the menu will stay open ala the Mac. + LLMenuHolderGL::sContextMenuSpawnPos.set(x,y); + arrangeAndClear(); S32 width = getRect().getWidth(); @@ -3597,29 +3651,41 @@ void LLContextMenu::show(S32 x, S32 y,BOOL adjustCursor) const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect(); LLView* parent_view = getParent(); - if(getParentMenuItem()) + // Open upwards if menu extends past bottom + if (y - height < menu_region_rect.mBottom) { - S32 parent_width = getParentMenuItem()->getRect().getWidth(); - - if(x + width > menu_region_rect.getWidth()) - x -= parent_width + width; + if (getParentMenuItem()) // Adjust if this is a submenu + { + y += height - getParentMenuItem()->getNominalHeight(); + } + else + { + y += height; + } + } + + // Open out to the left if menu extends past right edge + if (x + width > menu_region_rect.mRight) + { + if (getParentMenuItem()) + { + x -= getParentMenuItem()->getRect().getWidth() + width; + } + else + { + x -= width; + } } S32 local_x, local_y; parent_view->screenPointToLocal(x, y, &local_x, &local_y); - // HACK: casting away const. Should use setRect or some helper function instead. - const_cast(getRect()).setCenterAndSize(local_x + width/2, local_y - height/2, width, height); + LLRect rect; + rect.setLeftTopAndSize(local_x, local_y, width, height); + setRect(rect); arrange(); - - if (translateIntoRect(menu_region_rect,FALSE) && adjustCursor) - { - LLUI::setCursorPositionLocal(getParent(), getRect().mLeft , getRect().mTop); - } - LLView::setVisible(TRUE); - } void LLContextMenu::hide() @@ -3679,58 +3745,8 @@ BOOL LLContextMenu::handleHover( S32 x, S32 y, MASK mask ) return handled; } -BOOL LLContextMenu::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - // The click was somewhere within our rectangle - LLMenuItemGL *item = getHighlightedItem(); +// handleMouseDown and handleMouseUp are handled by LLMenuGL - if (item) - { - // lie to the item about where the click happened - // to make sure it's within the item's rectangle - handled = item->handleMouseDown( 0, 0, mask ); - } - else - { - // call hidemenus to make sure transient selections get cleared - ((LLMenuHolderGL*)getParent())->hideMenus(); - } - - // always handle mouse down as mouse up will close open menus - return handled; -} -BOOL LLContextMenu::handleMouseUp( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - - // The click was somewhere within our rectangle - LLMenuItemGL *item = getHighlightedItem(); - - if (item) - { - // lie to the item about where the click happened - // to make sure it's within the item's rectangle - if (item->getEnabled()) - { - handled = item->handleMouseUp( 0, 0, mask ); - hide(); - } - } - else - { - // call hidemenus to make sure transient selections get cleared - ((LLMenuHolderGL*)getParent())->hideMenus(); - } - - if (!handled) - { - // call hidemenus to make sure transient selections get cleared - sMenuContainer->hideMenus(); - } - - return handled; -} BOOL LLContextMenu::handleRightMouseDown(S32 x, S32 y, MASK mask) { @@ -3766,8 +3782,6 @@ BOOL LLContextMenu::handleRightMouseDown(S32 x, S32 y, MASK mask) BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask ) { - // release mouse capture when right mouse button released, and we're past the shrink time - S32 local_x = x - getRect().mLeft; S32 local_y = y - getRect().mBottom; @@ -3802,10 +3816,10 @@ BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu) p.name = menu->getName(); p.label = menu->getLabel(); p.branch = menu; - p.enabled_color=LLUI::getCachedColorFunctor("MenuItemEnabledColor"); - p.disabled_color=LLUI::getCachedColorFunctor("MenuItemDisabledColor"); - p.highlight_bg_color=LLUI::getCachedColorFunctor("MenuItemHighlightBgColor"); - p.highlight_fg_color=LLUI::getCachedColorFunctor("MenuItemHighlightFgColor"); + p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor"); + p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor"); + p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor"); + p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor"); item = LLUICtrlFactory::create(p); LLMenuGL::sMenuContainer->addChild(item->getBranch()); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 526e1c2583..828956a217 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -81,7 +81,7 @@ public: Params() : shortcut("shortcut"), - jump_key("", KEY_NONE), + jump_key("jump_key", KEY_NONE), use_mac_ctrl("use_mac_ctrl", false), rect("rect"), left("left"), @@ -106,7 +106,7 @@ protected: friend class LLUICtrlFactory; public: virtual void setValue(const LLSD& value) { setLabel(value.asString()); } - /*virtual*/ void onVisibilityChange(BOOL new_visibility); + /*virtual*/ void handleVisibilityChange(BOOL new_visibility); virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleAcceleratorKey(KEY key, MASK mask); @@ -137,7 +137,7 @@ public: virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); // Get the parent menu for this item - virtual class LLMenuGL* getMenu(); + virtual class LLMenuGL* getMenu() const; // returns the normal width of this control in pixels - this is // used for calculating the widest item, as well as for horizontal @@ -283,6 +283,7 @@ public: virtual BOOL handleAcceleratorKey(KEY key, MASK mask); virtual BOOL handleKeyHere(KEY key, MASK mask); + virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); //virtual void draw(); @@ -295,6 +296,11 @@ public: { return mEnableSignal.connect(cb); } + + boost::signals2::connection setRightClickedCallback( const commit_signal_t::slot_type& cb ) + { + return mRightClickSignal.connect(cb); + } private: enable_signal_t mEnableSignal; @@ -356,6 +362,11 @@ private: // it in the appendMenu() method. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// child widget registry +struct MenuRegistry : public LLChildRegistry +{}; + + class LLMenuGL : public LLUICtrl { @@ -372,15 +383,18 @@ public: keep_fixed_size, scrollable; Optional bg_color; + Optional shortcut_pad; Params() - : jump_key("", KEY_NONE), + : jump_key("jump_key", KEY_NONE), + horizontal_layout("horizontal_layout"), can_tear_off("tear_off", false), drop_shadow("drop_shadow", true), bg_visible("bg_visible", true), create_jump_keys("create_jump_keys", false), - bg_color("bg_color", LLUI::getCachedColorFunctor( "MenuDefaultBgColor" )), - scrollable("scrollable", false) + bg_color("bg_color", LLUIColorTable::instance().getColor( "MenuDefaultBgColor" )), + scrollable("scrollable", false), + shortcut_pad("shortcut_pad") { addSynonym(bg_visible, "opaque"); addSynonym(bg_color, "color"); @@ -388,6 +402,10 @@ public: name = "menu"; } }; + + // my valid children are contained in MenuRegistry + typedef MenuRegistry child_registry_t; + void initFromParams(const Params&); protected: @@ -410,7 +428,6 @@ public: /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0); /*virtual*/ void removeChild( LLView* ctrl); /*virtual*/ BOOL postBuild(); - /*virtual*/ const widget_registry_t& getChildRegistry() const; virtual BOOL handleAcceleratorKey(KEY key, MASK mask); @@ -498,6 +515,8 @@ public: static void setKeyboardMode(BOOL mode) { sKeyboardMode = mode; } static BOOL getKeyboardMode() { return sKeyboardMode; } + S32 getShortcutPad() { return mShortcutPad; } + void scrollItemsUp(); void scrollItemsDown(); BOOL isScrollable() const { return mScrollable; } @@ -551,6 +570,7 @@ private: LLHandle mParentFloaterHandle; KEY mJumpKey; BOOL mCreateJumpKeys; + S32 mShortcutPad; }; // end class LLMenuGL @@ -606,7 +626,7 @@ public: virtual void updateBranchParent( LLView* parentp ); // LLView Functionality - virtual void onVisibilityChange( BOOL curVisibilityIn ); + virtual void handleVisibilityChange( BOOL curVisibilityIn ); virtual void draw(); @@ -651,16 +671,12 @@ public: virtual void draw (); - virtual void show (S32 x, S32 y, BOOL adjustCursor = TRUE); + virtual void show (S32 x, S32 y); virtual void hide (); - - virtual BOOL handleHover ( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseDown ( S32 x, S32 y, MASK mask ); virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleRightMouseUp ( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseUp ( S32 x, S32 y, MASK mask ); virtual bool addChild (LLView* view, S32 tab_group = 0); @@ -749,11 +765,18 @@ public: virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + // Close context menus on right mouse up not handled by menus. + /*virtual*/ BOOL handleRightMouseUp( S32 x, S32 y, MASK mask ); + virtual const LLRect getMenuRect() const { return getLocalRect(); } virtual BOOL hasVisibleMenu() const; static void setActivatedItem(LLMenuItemGL* item); + // Need to detect if mouse-up after context menu spawn has moved. + // If not, need to keep the menu up. + static LLCoordGL sContextMenuSpawnPos; + private: static LLHandle sItemLastSelectedHandle; static LLFrameTimer sItemActivationTimer; @@ -771,8 +794,10 @@ class LLTearOffMenu : public LLFloater { public: static LLTearOffMenu* create(LLMenuGL* menup); - virtual ~LLTearOffMenu() {} - virtual void onClose(bool app_quitting); + virtual ~LLTearOffMenu(); + + virtual BOOL postBuild(); + virtual void draw(void); virtual void onFocusReceived(); virtual void onFocusLost(); @@ -782,7 +807,9 @@ public: private: LLTearOffMenu(LLMenuGL* menup); - + + void closeTearOff(); + LLView* mOldParent; LLMenuGL* mMenu; F32 mTargetHeight; diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index 8779eee28d..11fa290de1 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -44,12 +44,11 @@ // static std::list LLModalDialog::sModalStack; -LLModalDialog::LLModalDialog( const std::string& title, S32 width, S32 height, BOOL modal ) - : LLFloater(), +LLModalDialog::LLModalDialog( const LLSD& key, S32 width, S32 height, BOOL modal ) + : LLFloater(key), mModal( modal ) { setRect(LLRect( 0, height, width, 0 )); - setTitle(title); if (modal) { setCanMinimize(FALSE); @@ -59,6 +58,7 @@ LLModalDialog::LLModalDialog( const std::string& title, S32 width, S32 height, B setBackgroundVisible(TRUE); setBackgroundOpaque(TRUE); centerOnScreen(); // default position + mCloseSignal.connect(boost::bind(&LLModalDialog::stopModal, this)); } LLModalDialog::~LLModalDialog() @@ -68,6 +68,18 @@ LLModalDialog::~LLModalDialog() { gFocusMgr.unlockFocus(); } + + std::list::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this); + if (iter != sModalStack.end()) + { + llerrs << "Attempt to delete dialog while still in sModalStack!" << llendl; + } +} + +// virtual +BOOL LLModalDialog::postBuild() +{ + return LLFloater::postBuild(); } // virtual @@ -235,16 +247,10 @@ BOOL LLModalDialog::handleKeyHere(KEY key, MASK mask ) } } -void LLModalDialog::onClose(bool app_quitting) -{ - stopModal(); - LLFloater::onClose(app_quitting); -} - // virtual void LLModalDialog::draw() { - static LLUICachedControl shadow_color ("ColorDropShadow", *(new LLColor4)); + static LLUIColor shadow_color = LLUIColorTable::instance().getColor("ColorDropShadow"); static LLUICachedControl shadow_lines ("DropShadowFloater", 0); gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0, diff --git a/indra/llui/llmodaldialog.h b/indra/llui/llmodaldialog.h index dad92ab82a..4d5073024b 100644 --- a/indra/llui/llmodaldialog.h +++ b/indra/llui/llmodaldialog.h @@ -45,9 +45,11 @@ class LLModalDialog; class LLModalDialog : public LLFloater { public: - LLModalDialog( const std::string& title, S32 width, S32 height, BOOL modal = true ); + LLModalDialog( const LLSD& key, S32 width, S32 height, BOOL modal = true ); /*virtual*/ ~LLModalDialog(); - + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void openFloater(const LLSD& key = LLSD()); /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -63,8 +65,6 @@ public: /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask ); - /*virtual*/ void onClose(bool app_quitting); - /*virtual*/ void setVisible(BOOL visible); /*virtual*/ void draw(); diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp index c0fe7ff32d..9f9e3aecac 100644 --- a/indra/llui/llmultifloater.cpp +++ b/indra/llui/llmultifloater.cpp @@ -42,8 +42,8 @@ // LLMultiFloater // -LLMultiFloater::LLMultiFloater(const LLFloater::Params& params) - : LLFloater(), +LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params) + : LLFloater(key), mTabContainer(NULL), mTabPos(LLTabContainer::TOP), mAutoResize(TRUE), @@ -74,20 +74,12 @@ void LLMultiFloater::buildTabContainer() void LLMultiFloater::onOpen(const LLSD& key) { - if (mTabContainer->getTabCount() <= 0) - { - // for now, don't allow multifloaters - // without any child floaters - closeFloater(); - } -} - -void LLMultiFloater::onClose(bool app_quitting) -{ - if(closeAllFloaters() == TRUE) - { - LLFloater::onClose(app_quitting); - }//else not all tabs could be closed... +// if (mTabContainer->getTabCount() <= 0) +// { +// // for now, don't allow multifloaters +// // without any child floaters +// closeFloater(); +// } } void LLMultiFloater::draw() @@ -124,7 +116,8 @@ BOOL LLMultiFloater::closeAllFloaters() //Tab did not actually close, possibly due to a pending Save Confirmation dialog.. //so try and close the next one in the list... tabToClose++; - }else + } + else { //Tab closed ok. lastTabCount = mTabContainer->getTabCount(); @@ -246,6 +239,9 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, { floaterp->setVisible(FALSE); } + + // Tabs sometimes overlap resize handle + moveResizeHandlesToFront(); } /** @@ -275,6 +271,7 @@ void LLMultiFloater::selectPrevFloater() void LLMultiFloater::showFloater(LLFloater* floaterp, LLTabContainer::eInsertionPoint insertion_point) { + if(!floaterp) return; // we won't select a panel that already is selected // it is hard to do this internally to tab container // as tab selection is handled via index and the tab at a given @@ -288,7 +285,7 @@ void LLMultiFloater::showFloater(LLFloater* floaterp, LLTabContainer::eInsertion void LLMultiFloater::removeFloater(LLFloater* floaterp) { - if ( floaterp->getHost() != this ) + if (!floaterp || floaterp->getHost() != this ) return; floater_data_map_t::iterator found_data_it = mFloaterDataMap.find(floaterp->getHandle()); @@ -447,6 +444,8 @@ void LLMultiFloater::setCanResize(BOOL can_resize) BOOL LLMultiFloater::postBuild() { + mCloseSignal.connect(boost::bind(&LLMultiFloater::closeAllFloaters, this)); + // remember any original xml minimum size getResizeLimits(&mOrigMinWidth, &mOrigMinHeight); diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h index 7f4c1c040a..bbf2c56fe7 100644 --- a/indra/llui/llmultifloater.h +++ b/indra/llui/llmultifloater.h @@ -44,14 +44,13 @@ class LLMultiFloater : public LLFloater { public: - LLMultiFloater(const LLFloater::Params& params = LLFloater::getDefaultParams()); + LLMultiFloater(const LLSD& key, const Params& params = getDefaultParams()); virtual ~LLMultiFloater() {}; void buildTabContainer(); virtual BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void draw(); /*virtual*/ void setVisible(BOOL visible); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 099a79278a..68e496aed1 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -40,12 +40,11 @@ #include "llfocusmgr.h" #include "llkeyboard.h" // for the MASK constants #include "llcontrol.h" -#include "llimagegl.h" #include "lluictrlfactory.h" #include -static LLDefaultWidgetRegistry::Register r("multi_slider_bar"); +static LLDefaultChildRegistry::Register r("multi_slider_bar"); const F32 FLOAT_THRESHOLD = 0.00001f; diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index 312aceaaa2..1523d5d527 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -52,7 +52,7 @@ #include "llresmgr.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register r("multi_slider"); +static LLDefaultChildRegistry::Register r("multi_slider"); const U32 MAX_STRING_LENGTH = 10; LLMultiSliderCtrl::Params::Params() diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index 4855ed4926..16d07541f2 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -90,8 +90,8 @@ public: void setCurSlider(const std::string& name); void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mMultiSlider->getCurSlider(), val, from_event); } - virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); } - virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); } + virtual void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); } + virtual void setMaxValue(const LLSD& max_value) { setMaxValue((F32)max_value.asReal()); } BOOL isMouseHeldDown(); @@ -108,8 +108,8 @@ public: void deleteSlider(const std::string& name); void deleteCurSlider() { deleteSlider(mMultiSlider->getCurSlider()); } - F32 getMinValue() { return mMultiSlider->getMinValue(); } - F32 getMaxValue() { return mMultiSlider->getMaxValue(); } + F32 getMinValue() const { return mMultiSlider->getMinValue(); } + F32 getMaxValue() const { return mMultiSlider->getMaxValue(); } void setLabel(const std::string& label) { if (mLabelBox) mLabelBox->setText(label); } void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; } diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index ec92e57b6e..2b4aad5e83 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -385,7 +385,7 @@ LLNotificationTemplate::LLNotificationTemplate() : } LLNotification::LLNotification(const LLNotification::Params& p) : - mTimestamp(p.timestamp), + mTimestamp(p.time_stamp), mSubstitutions(p.substitutions), mPayload(p.payload), mExpiresAt(0), @@ -711,6 +711,15 @@ LLBoundListener LLNotificationChannelBase::connectChangedImpl(const LLEventListe return mChanged.connect(slot); } +LLBoundListener LLNotificationChannelBase::connectAtFrontChangedImpl(const LLEventListener& slot) +{ + for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it) + { + slot(LLSD().insert("sigtype", "load").insert("id", (*it)->id())); + } + return mChanged.connect(slot, boost::signals2::at_front); +} + LLBoundListener LLNotificationChannelBase::connectPassedFilterImpl(const LLEventListener& slot) { // these two filters only fire for notifications added after the current one, because @@ -1079,10 +1088,13 @@ void LLNotifications::createDefaultChannels() // connect action methods to these channels LLNotifications::instance().getChannel("Expiration")-> connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1)); + // uniqueHandler slot should be added as first slot of the signal due to + // usage LLStopWhenHandled combiner in LLStandardSignal LLNotifications::instance().getChannel("Unique")-> - connectChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1)); - LLNotifications::instance().getChannel("Unique")-> - connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1)); + connectAtFrontChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1)); +// failedUniquenessTest slot isn't necessary +// LLNotifications::instance().getChannel("Unique")-> +// connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1)); LLNotifications::instance().getChannel("Ignore")-> connectFailedFilter(&handleIgnoredNotification); } diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index c534267fca..0335a265b6 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -100,8 +100,9 @@ // and we need this to manage the notification callbacks #include "llevents.h" #include "llfunctorregistry.h" -#include "llui.h" -#include "llmemory.h" +#include "llpointer.h" +#include "llinitparam.h" +#include "llxmlnode.h" #include "llnotificationslistener.h" class LLNotification; @@ -159,7 +160,8 @@ public: LLNotificationForm(); LLNotificationForm(const LLSD& sd); - LLNotificationForm(const std::string& name, const LLXMLNodePtr xml_node); + LLNotificationForm(const std::string& name, + const LLPointer xml_node); LLSD asLLSD() const; @@ -295,7 +297,7 @@ public: Optional payload; Optional priority; Optional form_elements; - Optional timestamp; + Optional time_stamp; Optional context; struct Functor : public LLInitParam::Choice @@ -313,19 +315,23 @@ public: Params() : name("name"), priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), - timestamp("time_stamp") + time_stamp("time_stamp"), + payload("payload"), + form_elements("form_elements") { - timestamp = LLDate::now(); + time_stamp = LLDate::now(); } Params(const std::string& _name) - : name("name"), - priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), - timestamp("time_stamp") + : name("name"), + priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), + time_stamp("time_stamp"), + payload("payload"), + form_elements("form_elements") { functor.name = _name; name = _name; - timestamp = LLDate::now(); + time_stamp = LLDate::now(); } }; @@ -689,6 +695,14 @@ public: boost::bind(&LLNotificationChannelBase::connectChangedImpl, this, _1)); + } + template + LLBoundListener connectAtFrontChanged(const LISTENER& slot) + { + return LLEventDetail::visit_and_connect(slot, + boost::bind(&LLNotificationChannelBase::connectAtFrontChangedImpl, + this, + _1)); } template LLBoundListener connectPassedFilter(const LISTENER& slot) @@ -715,6 +729,7 @@ public: protected: LLBoundListener connectChangedImpl(const LLEventListener& slot); + LLBoundListener connectAtFrontChangedImpl(const LLEventListener& slot); LLBoundListener connectPassedFilterImpl(const LLEventListener& slot); LLBoundListener connectFailedFilterImpl(const LLEventListener& slot); @@ -822,7 +837,7 @@ public: // load notification descriptions from file; // OK to call more than once because it will reload bool loadTemplates(); - LLXMLNodePtr checkForXMLTemplate(LLXMLNodePtr item); + LLPointer checkForXMLTemplate(LLPointer item); // Add a simple notification (from XUI) void addFromCallback(const LLSD& name); @@ -905,7 +920,7 @@ private: std::string mFileName; - typedef std::map XMLTemplateMap; + typedef std::map > XMLTemplateMap; XMLTemplateMap mXmlTemplates; LLNotificationMap mUniqueNotifications; diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 0136a41d61..1a948fdd00 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -43,6 +43,7 @@ #include "llerror.h" #include "lltimer.h" +#include "llbutton.h" #include "llmenugl.h" //#include "llstatusbar.h" #include "llui.h" @@ -53,18 +54,18 @@ #include "lluictrl.h" #include "lluictrlfactory.h" #include "llviewborder.h" -#include "llbutton.h" #include "lltabcontainer.h" -static LLDefaultWidgetRegistry::Register r1("panel", &LLPanel::fromXML); +static LLDefaultChildRegistry::Register r1("panel", &LLPanel::fromXML); const LLPanel::Params& LLPanel::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams(); + return LLUICtrlFactory::getDefaultParams(); } LLPanel::Params::Params() : has_border("border", false), + border(""), bg_opaque_color("bg_opaque_color"), bg_alpha_color("bg_alpha_color"), background_visible("background_visible", false), @@ -73,7 +74,8 @@ LLPanel::Params::Params() min_height("min_height", 100), strings("string"), filename("filename"), - class_name("class") + class_name("class"), + visible_callback("visible_callback") { name = "panel"; addSynonym(background_visible, "bg_visible"); @@ -306,6 +308,12 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask ) return handled; } +void LLPanel::handleVisibilityChange ( BOOL new_visibility ) +{ + LLUICtrl::handleVisibilityChange ( new_visibility ); + mVisibleSignal(this, LLSD(new_visibility) ); // Pass BOOL as LLSD +} + BOOL LLPanel::checkRequirements() { if (!mRequirementsError.empty()) @@ -418,26 +426,31 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_ void LLPanel::initFromParams(const LLPanel::Params& p) { + //setting these here since panel constructor not called with params + //and LLView::initFromParams will use them to set visible and enabled + setVisible(p.visible); + setEnabled(p.enabled); + // control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible LLUICtrl::initFromParams(p); - + + // visible callback + if (p.visible_callback.isProvided()) + initCommitCallback(p.visible_callback, mVisibleSignal); + for (LLInitParam::ParamIterator::const_iterator it = p.strings().begin(); it != p.strings().end(); ++it) { - mUIStrings[it->name] = it->text; + mUIStrings[it->name] = it->value; } - setName(p.name()); setLabel(p.label()); - setShape(p.rect); parseFollowsFlags(p); - setEnabled(p.enabled); - setVisible(p.visible); setToolTip(p.tool_tip()); - setSaveToXML(p.serializable); + setSaveToXML(p.from_xui); mHoverCursor = getCursorFromString(p.hover_cursor); @@ -466,7 +479,7 @@ static LLFastTimer::DeclareTimer FTM_PANEL_POSTBUILD("Panel PostBuild"); BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { - const LLPanel::Params& default_params(LLUICtrlFactory::getDefaultParams()); + const LLPanel::Params& default_params(LLUICtrlFactory::getDefaultParams()); Params params(default_params); { @@ -503,7 +516,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu // add children using dimensions from referenced xml for consistent layout setShape(params.rect); - LLUICtrlFactory::createChildren(this, referenced_xml); + LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance()); } LLXUIParser::instance().readXUI(node, params); @@ -524,7 +537,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu } // add children - LLUICtrlFactory::createChildren(this, node, output_node); + LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node); // Connect to parent after children are built, because tab containers // do a reshape() on their child panels, which requires that the children @@ -543,12 +556,6 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu return TRUE; } -const widget_registry_t& LLPanel::getChildRegistry() const -{ - // use default widget registry - return LLDefaultWidgetRegistry::instance(); -} - bool LLPanel::hasString(const std::string& name) { return mUIStrings.find(name) != mUIStrings.end(); @@ -804,24 +811,6 @@ BOOL LLPanel::childSetToolTipArg(const std::string& id, const std::string& key, return FALSE; } -void LLPanel::childSetMinValue(const std::string& id, LLSD min_value) -{ - LLUICtrl* child = findChild(id); - if (child) - { - child->setMinValue(min_value); - } -} - -void LLPanel::childSetMaxValue(const std::string& id, LLSD max_value) -{ - LLUICtrl* child = findChild(id); - if (child) - { - child->setMaxValue(max_value); - } -} - void LLPanel::childShowTab(const std::string& id, const std::string& tabname, bool visible) { LLTabContainer* child = findChild(id); @@ -869,12 +858,12 @@ void LLPanel::childSetAction(const std::string& id, boost::function } } -void LLPanel::childSetActionTextbox(const std::string& id, void(*function)(void*), void* value) +void LLPanel::childSetActionTextbox(const std::string& id, boost::function function, void* value) { LLTextBox* textbox = findChild(id); if (textbox) { - textbox->setClickedCallback(function, value); + textbox->setClickedCallback(boost::bind(function, value)); } } diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index fc40cd77eb..552a621a8e 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -37,8 +37,6 @@ #include "llcallbackmap.h" #include "lluictrl.h" -#include "llbutton.h" -#include "lllineeditor.h" #include "llviewborder.h" #include "lluistring.h" #include "v4color.h" @@ -49,6 +47,7 @@ const S32 LLPANEL_BORDER_WIDTH = 1; const BOOL BORDER_YES = TRUE; const BOOL BORDER_NO = FALSE; +class LLButton; /* * General purpose concrete view base class. @@ -62,11 +61,11 @@ public: struct LocalizedString : public LLInitParam::Block { Mandatory name; - Mandatory text; + Mandatory value; LocalizedString() : name("name"), - text("value") + value("value") {} }; @@ -89,10 +88,15 @@ public: Optional class_name; Multiple strings; - + + Optional visible_callback; + Params(); }; + // valid children for LLPanel are stored in this registry + typedef LLDefaultChildRegistry child_registry_t; + protected: friend class LLUICtrlFactory; // RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8 @@ -109,6 +113,7 @@ public: /*virtual*/ BOOL isPanel() const; /*virtual*/ void draw(); /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask ); + /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // Override to set not found list: /*virtual*/ LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; @@ -165,7 +170,6 @@ public: void initFromParams(const Params& p); BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); - /*virtual*/ const widget_registry_t& getChildRegistry() const; bool hasString(const std::string& name); std::string getString(const std::string& name, const LLStringUtil::format_map_t& args) const; @@ -213,10 +217,6 @@ public: BOOL childSetLabelArg(const std::string& id, const std::string& key, const LLStringExplicit& text); BOOL childSetToolTipArg(const std::string& id, const std::string& key, const LLStringExplicit& text); - // LLSlider / LLMultiSlider / LLSpinCtrl - void childSetMinValue(const std::string& id, LLSD min_value); - void childSetMaxValue(const std::string& id, LLSD max_value); - // LLTabContainer void childShowTab(const std::string& id, const std::string& tabname, bool visible = true); LLPanel *childGetVisibleTab(const std::string& id) const; @@ -235,7 +235,10 @@ public: // LLButton void childSetAction(const std::string& id, boost::function function, void* value = NULL); - void childSetActionTextbox(const std::string& id, void(*function)(void*), void* value = NULL); + + // LLTextBox + void childSetActionTextbox(const std::string& id, boost::function function, void* value = NULL); + void childSetControlName(const std::string& id, const std::string& control_name); // Error reporting @@ -254,6 +257,8 @@ protected: CommitCallbackRegistry::ScopedRegistrar mCommitCallbackRegistrar; EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar; + commit_signal_t mVisibleSignal; // Called when visibilit changes, passes new visibility as LLSD() + private: // Unified error reporting for the child* functions typedef std::set expected_members_list_t; @@ -273,7 +278,7 @@ private: ui_string_map_t mUIStrings; std::string mRequirementsError; - + }; // end class LLPanel #endif diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp index 779967940a..c8b6e814e1 100644 --- a/indra/llui/llprogressbar.cpp +++ b/indra/llui/llprogressbar.cpp @@ -39,22 +39,18 @@ #include "llgl.h" #include "llui.h" #include "llfontgl.h" -#include "llimagegl.h" #include "lltimer.h" #include "llglheaders.h" #include "llfocusmgr.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register r("progress_bar"); +static LLDefaultChildRegistry::Register r("progress_bar"); LLProgressBar::Params::Params() : image_bar("image_bar"), image_fill("image_fill"), - image_shadow("image_shadow"), color_bar("color_bar"), - color_bar2("color_bar2"), - color_shadow("color_shadow"), color_bg("color_bg") {} @@ -62,12 +58,9 @@ LLProgressBar::Params::Params() LLProgressBar::LLProgressBar(const LLProgressBar::Params& p) : LLView(p), mImageBar(p.image_bar), - mImageShadow(p.image_shadow), mImageFill(p.image_fill), mColorBackground(p.color_bg()), mColorBar(p.color_bar()), - mColorBar2(p.color_bar2()), - mColorShadow(p.color_shadow()), mPercentDone(0.f) {} @@ -86,10 +79,10 @@ void LLProgressBar::draw() F32 alpha = 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32())); LLColor4 bar_color = mColorBar.get(); - bar_color.mV[3] = alpha; + bar_color.mV[VALPHA] *= alpha; // modulate alpha LLRect progress_rect = getLocalRect(); progress_rect.mRight = llround(getRect().getWidth() * (mPercentDone / 100.f)); - mImageFill->draw(progress_rect); + mImageFill->draw(progress_rect, bar_color); } void LLProgressBar::setPercent(const F32 percent) diff --git a/indra/llui/llprogressbar.h b/indra/llui/llprogressbar.h index 5c2f73ef9e..b6a5b0400d 100644 --- a/indra/llui/llprogressbar.h +++ b/indra/llui/llprogressbar.h @@ -43,12 +43,9 @@ public: struct Params : public LLInitParam::Block { Optional image_bar, - image_fill, - image_shadow; + image_fill; Optional color_bar, - color_bar2, - color_shadow, color_bg; Params(); @@ -65,10 +62,7 @@ private: LLPointer mImageBar; LLUIColor mColorBar; - LLUIColor mColorBar2; - LLPointer mImageShadow; - LLUIColor mColorShadow; LLUIColor mColorBackground; LLPointer mImageFill; diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 70f98bd908..30adbb023c 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -44,10 +44,8 @@ #include "llfocusmgr.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register r1("radio_group"); +static LLDefaultChildRegistry::Register r1("radio_group"); -struct RadioGroupRegistry : public LLWidgetRegistry -{}; static RadioGroupRegistry::Register register_radio_ctrl("radio_item"); @@ -72,7 +70,7 @@ LLRadioGroup::LLRadioGroup(const LLRadioGroup::Params& p) LLViewBorder::Params params; params.name("radio group border"); params.rect(LLRect(0, getRect().getHeight(), getRect().getWidth(), 0)); - params.bevel_type(LLViewBorder::BEVEL_NONE); + params.bevel_style(LLViewBorder::BEVEL_NONE); LLViewBorder * vb = LLUICtrlFactory::create (params); addChild (vb); } @@ -82,11 +80,6 @@ LLRadioGroup::~LLRadioGroup() { } -const widget_registry_t& LLRadioGroup::getChildRegistry() const -{ - return RadioGroupRegistry::instance(); -} - // virtual BOOL LLRadioGroup::postBuild() { diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h index 850d896e29..d04473fa44 100644 --- a/indra/llui/llradiogroup.h +++ b/indra/llui/llradiogroup.h @@ -70,6 +70,10 @@ protected: friend class LLUICtrlFactory; }; + +struct RadioGroupRegistry : public LLChildRegistry +{}; + /* * An invisible view containing multiple mutually exclusive toggling * buttons (usually radio buttons). Automatically handles the mutex @@ -86,6 +90,9 @@ public: Params(); }; + // my valid children are stored in this registry + typedef RadioGroupRegistry child_registry_t; + protected: LLRadioGroup(const Params&); friend class LLUICtrlFactory; @@ -118,8 +125,6 @@ public: // Update the control as needed. Userdata must be a pointer to the button. void onClickButton(LLUICtrl* clicked_radio); - virtual const widget_registry_t& getChildRegistry() const; - //======================================================================== LLCtrlSelectionInterface* getSelectionInterface() { return (LLCtrlSelectionInterface*)this; }; diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h index 4ad3d5035a..a7bc3c60f5 100644 --- a/indra/llui/llresizebar.h +++ b/indra/llui/llresizebar.h @@ -52,11 +52,11 @@ public: Optional allow_double_click_snapping; Params() - : max_size("", S32_MAX), - snapping_enabled("", true), + : max_size("max_size", S32_MAX), + snapping_enabled("snapping_enabled", true), resizing_view("resizing_view"), side("side"), - allow_double_click_snapping("", true) + allow_double_click_snapping("allow_double_click_snapping", true) { name = "resize_bar"; } diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp index 943e2f55f1..7449c339a0 100644 --- a/indra/llui/llresizehandle.cpp +++ b/indra/llui/llresizehandle.cpp @@ -45,7 +45,9 @@ const S32 RESIZE_BORDER_WIDTH = 3; LLResizeHandle::Params::Params() -: corner("corner") +: corner("corner"), + min_width("min_width"), + min_height("min_height") { name = "resize_handle"; } @@ -63,7 +65,7 @@ LLResizeHandle::LLResizeHandle(const LLResizeHandle::Params& p) { if( RIGHT_BOTTOM == mCorner) { - mImage = LLUI::getUIImage("resize_handle_bottom_right_blue.tga"); + mImage = LLUI::getUIImage("Resize_Corner"); } switch( p.corner ) { diff --git a/indra/llui/llresizehandle.h b/indra/llui/llresizehandle.h index e4e3c81cec..1560a03796 100644 --- a/indra/llui/llresizehandle.h +++ b/indra/llui/llresizehandle.h @@ -35,7 +35,6 @@ #include "stdtypes.h" #include "llview.h" -#include "llimagegl.h" #include "llcoord.h" diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp new file mode 100644 index 0000000000..cf23e3af15 --- /dev/null +++ b/indra/llui/llrngwriter.cpp @@ -0,0 +1,315 @@ +/** + * @file llrngwriter.cpp + * @brief Generates Relax NG schema from param blocks + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llrngwriter.h" +#include "lluicolor.h" +#include "lluictrlfactory.h" + +// +// LLRNGWriter - writes Relax NG schema files based on a param block +// +LLRNGWriter::LLRNGWriter() +{ + // register various callbacks for inspecting the contents of a param block + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "boolean", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedByte", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "signedByte", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedShort", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "signedShort", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedInt", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "integer", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "float", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "double", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); +} + +void LLRNGWriter::writeRNG(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace) +{ + mGrammarNode = node; + mGrammarNode->setName("grammar"); + mGrammarNode->createChild("xmlns", true)->setStringValue("http://relaxng.org/ns/structure/1.0"); + mGrammarNode->createChild("datatypeLibrary", true)->setStringValue("http://www.w3.org/2001/XMLSchema-datatypes"); + mGrammarNode->createChild("ns", true)->setStringValue(xml_namespace); + + node = mGrammarNode->createChild("start", false); + node = node->createChild("ref", false); + node->createChild("name", true)->setStringValue(type_name); + + addDefinition(type_name, block); +} + +void LLRNGWriter::addDefinition(const std::string& type_name, const LLInitParam::BaseBlock& block) +{ + if (mDefinedElements.find(type_name) != mDefinedElements.end()) return; + mDefinedElements.insert(type_name); + + LLXMLNodePtr node = mGrammarNode->createChild("define", false); + node->createChild("name", true)->setStringValue(type_name); + + mElementNode = node->createChild("element", false); + mElementNode->createChild("name", true)->setStringValue(type_name); + mChildrenNode = mElementNode->createChild("zeroOrMore", false)->createChild("choice", false); + + mAttributesWritten.first = mElementNode; + mAttributesWritten.second.clear(); + mElementsWritten.clear(); + + block.inspectBlock(*this); + + // add includes for all possible children + const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); + + // add include declarations for all valid children + for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); + it != widget_registryp->currentRegistrar().endItems(); + ++it) + { + std::string child_name = it->first; + if (child_name == type_name) + { + continue; + } + + LLXMLNodePtr old_element_node = mElementNode; + LLXMLNodePtr old_child_node = mChildrenNode; + addDefinition(child_name, (*LLDefaultParamBlockRegistry::instance().getValue(type))()); + mElementNode = old_element_node; + mChildrenNode = old_child_node; + + mChildrenNode->createChild("ref", false)->createChild("name", true)->setStringValue(child_name); + } + + if (mChildrenNode->mChildren.isNull()) + { + // remove unused children node + mChildrenNode->mParent->mParent->deleteChild(mChildrenNode->mParent); + } +} + +void LLRNGWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector* possible_values) +{ + if (max_count == 0) return; + + name_stack_t non_empty_names; + std::string attribute_name; + for (name_stack_t::const_iterator it = stack.begin(); + it != stack.end(); + ++it) + { + const std::string& name = it->first; + if (!name.empty()) + { + non_empty_names.push_back(*it); + } + } + + if (non_empty_names.empty()) return; + + for (name_stack_t::const_iterator it = non_empty_names.begin(); + it != non_empty_names.end(); + ++it) + { + if (!attribute_name.empty()) + { + attribute_name += "."; + } + attribute_name += it->first; + } + + // singular attribute, e.g. + if (non_empty_names.size() == 1 && max_count == 1) + { + if (mAttributesWritten.second.find(attribute_name) == mAttributesWritten.second.end()) + { + LLXMLNodePtr node = createCardinalityNode(mElementNode, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(attribute_name); + node->createChild("data", false)->createChild("type", true)->setStringValue(type); + + mAttributesWritten.second.insert(attribute_name); + } + } + // compound attribute + else + { + std::string element_name; + + // traverse all but last element, leaving that as an attribute name + name_stack_t::const_iterator end_it = non_empty_names.end(); + end_it--; + + for (name_stack_t::const_iterator it = non_empty_names.begin(); + it != end_it; + ++it) + { + if (it != non_empty_names.begin()) + { + element_name += "."; + } + element_name += it->first; + } + + elements_map_t::iterator found_it = mElementsWritten.find(element_name); + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + + if (found_it != mElementsWritten.end()) + { + // reuse existing element + LLXMLNodePtr choice_node = found_it->second.first; + + // attribute with this name not already written? + if (found_it->second.second.find(attribute_name) == found_it->second.second.end()) + { + // append to + LLXMLNodePtr node = choice_node->mChildren->head; + node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(attribute_name); + addTypeNode(node, type, possible_values); + + // append to + node = choice_node->mChildren->head->mNext->mChildren->head; + node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(non_empty_names.back().first); + addTypeNode(node, type, possible_values); + + // append to + //node = choice_node->mChildren->head->mNext->mNext->mChildren->head; + //node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + //node->createChild("name", true)->setStringValue(non_empty_names.back().first); + //addTypeNode(node, type, possible_values); + + found_it->second.second.insert(attribute_name); + } + } + else + { + LLXMLNodePtr choice_node = mElementNode->createChild("choice", false); + + LLXMLNodePtr node = choice_node->createChild("group", false); + node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(attribute_name); + addTypeNode(node, type, possible_values); + + node = choice_node->createChild("optional", false); + node = node->createChild("element", false); + node->createChild("name", true)->setStringValue(element_name); + node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(non_empty_names.back().first); + addTypeNode(node, type, possible_values); + + //node = choice_node->createChild("optional", false); + //node = node->createChild("element", false); + //node->createChild("name", true)->setStringValue(mDefinitionName + "." + element_name); + //node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + //node->createChild("name", true)->setStringValue(non_empty_names.back().first); + //addTypeNode(node, type, possible_values); + + attribute_data_t& attribute_data = mElementsWritten[element_name]; + attribute_data.first = choice_node; + attribute_data.second.insert(attribute_name); + } + } +} + +void LLRNGWriter::addTypeNode(LLXMLNodePtr parent_node, const std::string& type, const std::vector* possible_values) +{ + if (possible_values) + { + LLXMLNodePtr enum_node = parent_node->createChild("choice", false); + for (std::vector::const_iterator it = possible_values->begin(); + it != possible_values->end(); + ++it) + { + enum_node->createChild("value", false)->setStringValue(*it); + } + } + else + { + parent_node->createChild("data", false)->createChild("type", true)->setStringValue(type); + } +} + +LLXMLNodePtr LLRNGWriter::createCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count) +{ + // unlinked by default, meaning this attribute is forbidden + LLXMLNodePtr count_node = new LLXMLNode(); + if (min_count == 0) + { + if (max_count == 1) + { + count_node = parent_node->createChild("optional", false); + } + else if (max_count > 1) + { + count_node = parent_node->createChild("zeroOrMore", false); + } + } + else if (min_count >= 1) + { + if (max_count == 1 && min_count == 1) + { + // just add raw element, will count as 1 and only 1 + count_node = parent_node; + } + else + { + count_node = parent_node->createChild("oneOrMore", false); + } + } + return count_node; +} diff --git a/indra/llui/llrngwriter.h b/indra/llui/llrngwriter.h new file mode 100644 index 0000000000..66807577b5 --- /dev/null +++ b/indra/llui/llrngwriter.h @@ -0,0 +1,69 @@ +/** + * @file llrngwriter.h + * @brief Generates Relax NG schema files from a param block + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLRNGWRITER_H +#define LLRNGWRITER_H + +#include "llinitparam.h" +#include "llxmlnode.h" + +class LLRNGWriter : public LLInitParam::Parser +{ + LOG_CLASS(LLRNGWriter); +public: + void writeRNG(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace); + void addDefinition(const std::string& type_name, const LLInitParam::BaseBlock& block); + + /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; } + + LLRNGWriter(); + +private: + LLXMLNodePtr createCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count); + void addTypeNode(LLXMLNodePtr parent_node, const std::string& type, const std::vector* possible_values); + + void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector* possible_values); + LLXMLNodePtr mElementNode; + LLXMLNodePtr mChildrenNode; + LLXMLNodePtr mGrammarNode; + std::string mDefinitionName; + + typedef std::pair > attribute_data_t; + typedef std::map elements_map_t; + typedef std::set defined_elements_t; + + defined_elements_t mDefinedElements; + attribute_data_t mAttributesWritten; + elements_map_t mElementsWritten; +}; + +#endif //LLRNGWRITER_H diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 3f1ff34419..bc489592d4 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -48,7 +48,7 @@ #include "llrender.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register register_scrollbar("scroll_bar"); +static LLDefaultChildRegistry::Register register_scrollbar("scroll_bar"); LLScrollbar::Params::Params() : orientation ("orientation", HORIZONTAL), @@ -56,8 +56,10 @@ LLScrollbar::Params::Params() doc_pos ("doc_pos", 0), page_size ("page_size", 0), step_size ("step_size", 1), - thumb_image("thumb_image"), - track_image("track_image"), + thumb_image_vertical("thumb_image_vertical"), + thumb_image_horizontal("thumb_image_horizontal"), + track_image_vertical("track_image_vertical"), + track_image_horizontal("track_image_horizontal"), track_color("track_color"), thumb_color("thumb_color"), thickness("thickness"), @@ -86,8 +88,10 @@ LLScrollbar::LLScrollbar(const Params & p) mThumbColor ( p.thumb_color() ), mOnScrollEndCallback( NULL ), mOnScrollEndData( NULL ), - mThumbImage(p.thumb_image), - mTrackImage(p.track_image), + mThumbImageV(p.thumb_image_vertical), + mThumbImageH(p.thumb_image_horizontal), + mTrackImageV(p.track_image_vertical), + mTrackImageH(p.track_image_horizontal), mThickness(p.thickness.isProvided() ? p.thickness : LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize")) { updateThumbRect(); @@ -493,7 +497,8 @@ void LLScrollbar::draw() } // Draw background and thumb. - if (mTrackImage.isNull() || mThumbImage.isNull()) + if ( ( mOrientation == VERTICAL&&(mThumbImageV.isNull() || mThumbImageV.isNull()) ) + || (mOrientation == HORIZONTAL&&(mTrackImageH.isNull() || mThumbImageH.isNull()) )) { gl_rect_2d(mOrientation == HORIZONTAL ? mThickness : 0, mOrientation == VERTICAL ? getRect().getHeight() - 2 * mThickness : getRect().getHeight(), @@ -505,30 +510,54 @@ void LLScrollbar::draw() } else { - // Background - mTrackImage->drawSolid(mOrientation == HORIZONTAL ? mThickness : 0, - mOrientation == VERTICAL ? mThickness : 0, - mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * mThickness : getRect().getWidth(), - mOrientation == VERTICAL ? getRect().getHeight() - 2 * mThickness : getRect().getHeight(), - mTrackColor.get()); - // Thumb LLRect outline_rect = mThumbRect; outline_rect.stretch(2); - - if (gFocusMgr.getKeyboardFocus() == this) + S32 rect_fix = 0; + // Background + + if(mOrientation == HORIZONTAL) { - mTrackImage->draw(outline_rect, gFocusMgr.getFocusColor()); + mTrackImageH->drawSolid(mThickness //S32 x + , 0 //S32 y + , getRect().getWidth() - 2 * mThickness //S32 width + , getRect().getHeight()- rect_fix //S32 height + , mTrackColor.get()); //const LLColor4& color + + if (gFocusMgr.getKeyboardFocus() == this) + { + mTrackImageH->draw(outline_rect, gFocusMgr.getFocusColor()); + } + + mThumbImageH->draw(mThumbRect, mThumbColor.get()); + if (mCurGlowStrength > 0.01f) + { + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + mThumbImageH->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } + } - - mThumbImage->draw(mThumbRect, mThumbColor.get()); - if (mCurGlowStrength > 0.01f) + else if(mOrientation == VERTICAL) { - gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - mThumbImage->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + mTrackImageV->drawSolid( 0+rect_fix //S32 x + , mThickness //S32 y + , getRect().getWidth() //S32 width + , getRect().getHeight() - 2 * mThickness //S32 height + , mTrackColor.get()); //const LLColor4& color + if (gFocusMgr.getKeyboardFocus() == this) + { + mTrackImageV->draw(outline_rect, gFocusMgr.getFocusColor()); + } + + mThumbImageV->draw(mThumbRect, mThumbColor.get()); + if (mCurGlowStrength > 0.01f) + { + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + mThumbImageV->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } } - } BOOL was_scrolled_to_bottom = (getDocPos() == getDocPosMax()); diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index 43604d37b7..5522e5d0fa 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -61,8 +61,10 @@ public: Optional step_size; Optional thickness; - Optional thumb_image, - track_image; + Optional thumb_image_vertical, + thumb_image_horizontal, + track_image_horizontal, + track_image_vertical; Optional track_color, thumb_color; @@ -155,8 +157,10 @@ private: LLUIColor mTrackColor; LLUIColor mThumbColor; - LLUIImagePtr mThumbImage; - LLUIImagePtr mTrackImage; + LLUIImagePtr mThumbImageV; + LLUIImagePtr mThumbImageH; + LLUIImagePtr mTrackImageV; + LLUIImagePtr mTrackImageH; S32 mThickness; diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 2a2e56a92c..402c050d2e 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -63,7 +63,7 @@ static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; /// Class LLScrollContainer ///---------------------------------------------------------------------------- -static LLDefaultWidgetRegistry::Register r("scroll_container"); +static LLDefaultChildRegistry::Register r("scroll_container"); LLScrollContainer::Params::Params() : is_opaque("opaque"), @@ -91,7 +91,7 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) LLViewBorder::Params params; params.name("scroll border"); params.rect(border_rect); - params.bevel_type(LLViewBorder::BEVEL_IN); + params.bevel_style(LLViewBorder::BEVEL_IN); mBorder = LLUICtrlFactory::create (params); LLView::addChild( mBorder ); @@ -333,34 +333,6 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, return TRUE; } - -BOOL LLScrollContainer::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect) -{ - S32 local_x, local_y; - for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) - { - local_x = x - mScrollbar[i]->getRect().mLeft; - local_y = y - mScrollbar[i]->getRect().mBottom; - if( mScrollbar[i]->handleToolTip(local_x, local_y, msg, sticky_rect) ) - { - return TRUE; - } - } - // Handle 'child' view. - if( mScrolledView ) - { - local_x = x - mScrolledView->getRect().mLeft; - local_y = y - mScrolledView->getRect().mBottom; - if( mScrolledView->handleToolTip(local_x, local_y, msg, sticky_rect) ) - { - return TRUE; - } - } - - // Opaque - return TRUE; -} - void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { const LLRect& rect = mScrolledView->getRect(); @@ -500,12 +472,8 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group) { if (!mScrolledView) { - //*TODO: Move LLFolderView to llui and enable this check -// if (dynamic_cast(view) || dynamic_cast(view) || dynamic_cast(view) || dynamic_cast(view)) - { - // Use the first panel or container as the scrollable view (bit of a hack) - mScrolledView = view; - } + // Use the first panel or container as the scrollable view (bit of a hack) + mScrolledView = view; } bool ret_val = LLView::addChild(view, tab_group); @@ -517,12 +485,6 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group) return ret_val; } -const widget_registry_t& LLScrollContainer::getChildRegistry() const -{ - // a scroll container can contain any default widget - return LLDefaultWidgetRegistry::instance(); -} - void LLScrollContainer::updateScroll() { if (!mScrolledView) diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index 26d8cc824e..c2d4d2c861 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -68,6 +68,10 @@ public: Params(); }; + + // my valid children are stored in this registry + typedef LLDefaultChildRegistry child_registry_t; + protected: LLScrollContainer(const Params&); friend class LLUICtrlFactory; @@ -101,10 +105,8 @@ public: EAcceptance* accept, std::string& tooltip_msg); - virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); virtual void draw(); virtual bool addChild(LLView* view, S32 tab_group = 0); - virtual const widget_registry_t& getChildRegistry() const; private: // internal scrollbar handlers diff --git a/indra/llui/llscrollingpanellist.cpp b/indra/llui/llscrollingpanellist.cpp index 1f3a7f9fcf..0159cdd12c 100644 --- a/indra/llui/llscrollingpanellist.cpp +++ b/indra/llui/llscrollingpanellist.cpp @@ -35,7 +35,7 @@ #include "llscrollingpanellist.h" -static LLDefaultWidgetRegistry::Register r("scrolling_panel_list"); +static LLDefaultChildRegistry::Register r("scrolling_panel_list"); ///////////////////////////////////////////////////////////////////// diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 4e6de24160..cd43e194d2 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -177,7 +177,6 @@ LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p) mFont(p.font), mColor(p.color), mUseColor(p.color.isProvided()), - mFontStyle(LLFontGL::NORMAL), mFontAlignment(p.font_halign), mVisible(p.visible), mHighlightCount( 0 ), @@ -240,6 +239,13 @@ void LLScrollListText::setText(const LLStringExplicit& text) mText = text; } +void LLScrollListText::setFontStyle(const U8 font_style) +{ + LLFontDescriptor new_desc(mFont->getFontDesc()); + new_desc.setStyle(font_style); + mFont = LLFontGL::getFont(new_desc); +} + //virtual void LLScrollListText::setValue(const LLSD& text) { @@ -308,7 +314,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col display_color, mFontAlignment, LLFontGL::BOTTOM, - mFontStyle, + 0, LLFontGL::NO_SHADOW, string_chars, getWidth(), diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index 2ab13f7618..9d3fa65f64 100644 --- a/indra/llui/llscrolllistcell.h +++ b/indra/llui/llscrolllistcell.h @@ -145,14 +145,13 @@ public: /*virtual*/ BOOL isText() const; void setText(const LLStringExplicit& text); - void setFontStyle(const U8 font_style) { mFontStyle = font_style; } + void setFontStyle(const U8 font_style); private: LLUIString mText; const LLFontGL* mFont; LLColor4 mColor; U8 mUseColor; - U8 mFontStyle; LLFontGL::HAlign mFontAlignment; BOOL mVisible; S32 mHighlightCount; diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index 02f09bd9b4..073e14386f 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -65,8 +65,6 @@ LLScrollColumnHeader::LLScrollColumnHeader(const LLScrollColumnHeader::Params& p resize_bar_p.enabled(false); mResizeBar = LLUICtrlFactory::create(resize_bar_p); addChild(mResizeBar); - - setToolTip(p.label()); } LLScrollColumnHeader::~LLScrollColumnHeader() @@ -291,7 +289,7 @@ void LLScrollListColumn::SortNames::declareValues() //static const LLScrollListColumn::Params& LLScrollListColumn::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams(); + return LLUICtrlFactory::getDefaultParams(); } diff --git a/indra/llui/llscrolllistcolumn.h b/indra/llui/llscrolllistcolumn.h index 712ea56454..23318fd7c4 100644 --- a/indra/llui/llscrolllistcolumn.h +++ b/indra/llui/llscrolllistcolumn.h @@ -121,7 +121,7 @@ public: Alternative relative_width; Width() - : dynamic_width("dynamicwidth", false), + : dynamic_width("dynamic_width", false), pixel_width("width"), relative_width("relative_width", -1.f) { diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 6d91c784f7..79f0f9d71b 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -31,8 +31,6 @@ * $/LicenseInfo$ */ -#define INSTANTIATE_GETCHILD_SCROLLLIST - #include "linden_common.h" #include "llscrolllistctrl.h" @@ -60,9 +58,7 @@ #include "lltextbox.h" #include "llsdparam.h" -template LLScrollListCtrl* LLView::getChild( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - -static LLDefaultWidgetRegistry::Register r("scroll_list"); +static LLDefaultChildRegistry::Register r("scroll_list"); // local structures & classes. struct SortScrollListItem @@ -106,11 +102,11 @@ struct SortScrollListItem //--------------------------------------------------------------------------- LLScrollListCtrl::Contents::Contents() -: columns("columns"), - rows("rows") +: columns("column"), + rows("row") { - addSynonym(columns, "column"); - addSynonym(rows, "row"); + addSynonym(columns, "columns"); + addSynonym(rows, "rows"); } LLScrollListCtrl::Params::Params() @@ -130,10 +126,11 @@ LLScrollListCtrl::Params::Params() bg_selected_color("bg_selected_color"), fg_disable_color("fg_disable_color"), bg_writeable_color("bg_writeable_color"), - bg_read_only_color("bg_read_only_color"), + bg_readonly_color("bg_readonly_color"), bg_stripe_color("bg_stripe_color"), hovered_color("hovered_color"), - highlighted_color("highlighted_color") + highlighted_color("highlighted_color"), + contents("") { name = "scroll_list"; mouse_opaque = true; @@ -166,7 +163,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mSorted(FALSE), mDirty(FALSE), mOriginalSelection(-1), - mDrewSelected(FALSE), mLastSelected(NULL), mHeadingHeight(p.heading_height), mAllowMultipleSelection(p.multi_select), @@ -174,7 +170,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mBackgroundVisible(p.background_visible), mDrawStripes(p.draw_stripes), mBgWriteableColor(p.bg_writeable_color()), - mBgReadOnlyColor(p.bg_read_only_color()), + mBgReadOnlyColor(p.bg_readonly_color()), mBgSelectedColor(p.bg_selected_color()), mBgStripeColor(p.bg_stripe_color()), mFgSelectedColor(p.fg_selected_color()), @@ -225,7 +221,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) LLViewBorder::Params params; params.name("dig border"); params.rect(border_rect); - params.bevel_type(LLViewBorder::BEVEL_IN); + params.bevel_style(LLViewBorder::BEVEL_IN); mBorder = LLUICtrlFactory::create (params); addChild(mBorder); } @@ -1086,12 +1082,12 @@ LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos) { LLScrollListItem::Params separator_params; separator_params.enabled(false); - LLScrollListCell::Params cell_params; - cell_params.type = "icon"; - cell_params.value = "menu_separator"; - cell_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f); - cell_params.font_halign = LLFontGL::HCENTER; - separator_params.cells.add(cell_params); + LLScrollListCell::Params column_params; + column_params.type = "icon"; + column_params.value = "menu_separator"; + column_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f); + column_params.font_halign = LLFontGL::HCENTER; + separator_params.columns.add(column_params); return addRow( separator_params, pos ); } @@ -1253,7 +1249,7 @@ LLScrollListItem* LLScrollListCtrl::addStringUUIDItem(const std::string& item_te LLScrollListItem::Params item_p; item_p.enabled(enabled); item_p.value(id); - item_p.cells.add().value(item_text).type("text"); + item_p.columns.add().value(item_text).type("text"); return addRow( item_p, pos ); } @@ -1356,8 +1352,6 @@ void LLScrollListCtrl::drawItems() S32 cur_y = y; - mDrewSelected = FALSE; - S32 line = 0; S32 max_columns = 0; @@ -1378,11 +1372,6 @@ void LLScrollListCtrl::drawItems() //llinfos << item_rect.getWidth() << llendl; - if (item->getSelected()) - { - mDrewSelected = TRUE; - } - max_columns = llmax(max_columns, item->getNumColumns()); LLColor4 fg_color; @@ -1447,10 +1436,7 @@ void LLScrollListCtrl::draw() LLLocalClipRect clip(getLocalRect()); // if user specifies sort, make sure it is maintained - if (needsSorting() && !isSorted()) - { - sortItems(); - } + sortItems(); if (mNeedsScroll) { @@ -1516,19 +1502,12 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti if (hit_cell && hit_cell->isText()) { - S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft; S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item)); LLRect cell_rect; cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->getWidth(), mLineHeight); // Convert rect local to screen coordinates - localPointToScreen( - cell_rect.mLeft, cell_rect.mBottom, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - cell_rect.mRight, cell_rect.mTop, - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); - + localRectToScreen(cell_rect, sticky_rect_screen); msg = hit_cell->getValue().asString(); } handled = TRUE; @@ -1853,8 +1832,7 @@ S32 LLScrollListCtrl::getColumnOffsetFromIndex(S32 index) S32 LLScrollListCtrl::getRowOffsetFromIndex(S32 index) { - S32 row_bottom = ((mItemListRect.mTop - (index - mScrollLines)) * mLineHeight) - - mLineHeight; + S32 row_bottom = (mItemListRect.mTop - ((index - mScrollLines + 1) * mLineHeight) ); return row_bottom; } @@ -2219,6 +2197,8 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending) sort_column->mSortDirection = ascending ? LLScrollListColumn::ASCENDING : LLScrollListColumn::DESCENDING; sort_column_t new_sort_column(column_idx, ascending); + + setSorted(FALSE); if (mSortColumns.empty()) { @@ -2259,21 +2239,22 @@ void LLScrollListCtrl::sortByColumn(const std::string& name, BOOL ascending) // First column is column 0 void LLScrollListCtrl::sortByColumnIndex(U32 column, BOOL ascending) { - if (setSort(column, ascending)) - { - sortItems(); - } + setSort(column, ascending); + sortItems(); } void LLScrollListCtrl::sortItems() { - // do stable sort to preserve any previous sorts - std::stable_sort( - mItemList.begin(), - mItemList.end(), - SortScrollListItem(mSortColumns)); + if (hasSortOrder() && !isSorted()) + { + // do stable sort to preserve any previous sorts + std::stable_sort( + mItemList.begin(), + mItemList.end(), + SortScrollListItem(mSortColumns)); - setSorted(TRUE); + setSorted(TRUE); + } } // for one-shot sorts, does not save sort column/order @@ -2329,10 +2310,7 @@ void LLScrollListCtrl::scrollToShowSelected() return; } - if (needsSorting() && !isSorted()) - { - sortItems(); - } + sortItems(); S32 index = getFirstSelectedIndex(); if (index < 0) @@ -2573,7 +2551,7 @@ std::string LLScrollListCtrl::getSortColumnName() else return ""; } -BOOL LLScrollListCtrl::needsSorting() +BOOL LLScrollListCtrl::hasSortOrder() { return !mSortColumns.empty(); } @@ -2647,8 +2625,8 @@ LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_ // Add any columns we don't already have S32 col_index = 0; - for(LLInitParam::ParamIterator::const_iterator itor = item_p.cells().begin(); - itor != item_p.cells().end(); + for(LLInitParam::ParamIterator::const_iterator itor = item_p.columns().begin(); + itor != item_p.columns().end(); ++itor) { LLScrollListCell::Params cell_p = *itor; @@ -2699,7 +2677,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_ col_index++; } - if (item_p.cells().empty()) + if (item_p.columns().empty()) { if (mColumns.empty()) { @@ -2754,7 +2732,7 @@ LLScrollListItem* LLScrollListCtrl::addSimpleElement(const std::string& value, E LLScrollListItem::Params item_params; item_params.value(entry_id); - item_params.cells.add() + item_params.columns.add() .value(value) .font(LLFontGL::getFontSansSerifSmall()); diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 8d200fb73f..e699711bd4 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -44,7 +44,6 @@ #include "llfontgl.h" #include "llui.h" #include "llstring.h" // LLWString -//#include "llimagegl.h" #include "lleditmenuhandler.h" #include "llframetimer.h" @@ -100,7 +99,7 @@ public: bg_selected_color, fg_disable_color, bg_writeable_color, - bg_read_only_color, + bg_readonly_color, bg_stripe_color, hovered_color, highlighted_color; @@ -330,7 +329,7 @@ public: std::string getSortColumnName(); BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; } - BOOL needsSorting(); + BOOL hasSortOrder(); S32 selectMultiple( std::vector ids ); void sortItems(); @@ -375,9 +374,6 @@ private: void commitIfChanged(); BOOL setSort(S32 column, BOOL ascending); - S32 mCurIndex; // For get[First/Next]Data - S32 mCurSelectedIndex; // For get[First/Next]Selected - S32 mLineHeight; // the max height of a single line S32 mScrollLines; // how many lines we've scrolled down S32 mPageLines; // max number of lines is it possible to see on the screen given mRect and mLineHeight @@ -446,18 +442,6 @@ private: typedef std::pair sort_column_t; std::vector mSortColumns; - - // HACK: Did we draw one selected item this frame? - BOOL mDrewSelected; - - LLTextBox* mCommentTextBox; }; // end class LLScrollListCtrl -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_SCROLLLIST -#pragma warning (disable : 4231) -extern template LLScrollListCtrl* LLView::getChild( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif - #endif // LL_SCROLLLISTCTRL_H diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h index 4237d5b304..c2b7effbc7 100644 --- a/indra/llui/llscrolllistitem.h +++ b/indra/llui/llscrolllistitem.h @@ -68,7 +68,7 @@ public: Ignored type; Ignored length; - Multiple cells; + Multiple columns; Params() : enabled("enabled", true), @@ -76,9 +76,9 @@ public: name("name"), type("type"), length("length"), - cells("columns") + columns("columns") { - addSynonym(cells, "column"); + addSynonym(columns, "column"); addSynonym(value, "id"); } }; diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index 9522d32a8b..fbcbb55b85 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -1,6 +1,6 @@ /** - * @file lllineeditor.cpp - * @brief LLLineEditor base class + * @file llsearcheditor.cpp + * @brief LLSearchEditor implementation * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -36,89 +36,63 @@ #include "llsearcheditor.h" -//static LLDefaultWidgetRegistry::Register r2("search_editor"); - LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p) : LLUICtrl(p) { - LLLineEditor::Params line_editor_p(p); - line_editor_p.name("search edit box"); - line_editor_p.rect(getLocalRect()); - line_editor_p.follows.flags(FOLLOWS_ALL); - line_editor_p.text_pad_right(getRect().getHeight()); - line_editor_p.keystroke_callback(boost::bind(&LLSearchEditor::onSearchEdit, this, _1)); + S32 btn_top = p.search_button.top_pad + p.search_button.rect.height; + S32 btn_right = p.search_button.rect.width + p.search_button.left_pad; + LLRect search_btn_rect(p.search_button.left_pad, btn_top, btn_right, p.search_button.top_pad); - mSearchEdit = LLUICtrlFactory::create(line_editor_p); - addChild(mSearchEdit); + LLLineEditor::Params line_editor_params(p); + line_editor_params.name("filter edit box"); + line_editor_params.rect(getLocalRect()); + line_editor_params.follows.flags(FOLLOWS_ALL); + line_editor_params.text_pad_left(p.text_pad_left + search_btn_rect.getWidth()); + line_editor_params.commit_callback.function(boost::bind(&LLUICtrl::onCommit, this)); - S32 btn_width = getRect().getHeight(); // button is square, and as tall as search editor - LLRect clear_btn_rect(getRect().getWidth() - btn_width, getRect().getHeight(), getRect().getWidth(), 0); - LLButton::Params button_params(p.clear_search_button); - button_params.name(std::string("clear search")); - button_params.rect(clear_btn_rect) ; + mSearchEditor = LLUICtrlFactory::create(line_editor_params); + addChild(mSearchEditor); + + LLButton::Params button_params(p.search_button); + button_params.name(std::string("clear filter")); + button_params.rect(search_btn_rect) ; button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP); button_params.tab_stop(false); - button_params.click_callback.function(boost::bind(&LLSearchEditor::onClearSearch, this, _2)); + button_params.click_callback.function(boost::bind(&LLUICtrl::onCommit, this)); - mClearSearchButton = LLUICtrlFactory::create(button_params); - mSearchEdit->addChild(mClearSearchButton); + mSearchButton = LLUICtrlFactory::create(button_params); + mSearchEditor->addChild(mSearchButton); } //virtual void LLSearchEditor::setValue(const LLSD& value ) { - mSearchEdit->setValue(value); + mSearchEditor->setValue(value); } //virtual LLSD LLSearchEditor::getValue() const { - return mSearchEdit->getValue(); + return mSearchEditor->getValue(); } //virtual BOOL LLSearchEditor::setTextArg( const std::string& key, const LLStringExplicit& text ) { - return mSearchEdit->setTextArg(key, text); + return mSearchEditor->setTextArg(key, text); } //virtual BOOL LLSearchEditor::setLabelArg( const std::string& key, const LLStringExplicit& text ) { - return mSearchEdit->setLabelArg(key, text); + return mSearchEditor->setLabelArg(key, text); } //virtual void LLSearchEditor::clear() { - if (mSearchEdit) + if (mSearchEditor) { - mSearchEdit->clear(); + mSearchEditor->clear(); } } - -void LLSearchEditor::draw() -{ - mClearSearchButton->setVisible(!mSearchEdit->getWText().empty()); - - LLUICtrl::draw(); -} - - -void LLSearchEditor::onSearchEdit(LLLineEditor* caller ) -{ - if (mSearchCallback) - { - mSearchCallback(caller->getText()); - } -} - -void LLSearchEditor::onClearSearch(const LLSD& data) -{ - setText(LLStringUtil::null); - if (mSearchCallback) - { - mSearchCallback(LLStringUtil::null); - } -} - diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h index d8c5093fbf..368b68baa3 100644 --- a/indra/llui/llsearcheditor.h +++ b/indra/llui/llsearcheditor.h @@ -39,28 +39,21 @@ * $/LicenseInfo$ */ -#ifndef LL_LLSEARCHEDITOR_H -#define LL_LLSEARCHEDITOR_H +#ifndef LL_SEARCHEDITOR_H +#define LL_SEARCHEDITOR_H #include "lllineeditor.h" #include "llbutton.h" -#include - -/* - * @brief A line editor with a button to clear it and a callback to call on every edit event. - */ class LLSearchEditor : public LLUICtrl { public: struct Params : public LLInitParam::Block { - Optional > search_callback; - - Optional clear_search_button; + Optional search_button; Params() - : clear_search_button("clear_search_button") + : search_button("search_button") { name = "search_editor"; } @@ -69,15 +62,11 @@ public: protected: LLSearchEditor(const Params&); friend class LLUICtrlFactory; + public: virtual ~LLSearchEditor() {} - /*virtual*/ void draw(); - - void setText(const LLStringExplicit &new_text) { mSearchEdit->setText(new_text); } - - typedef boost::function search_callback_t; - void setSearchCallback(search_callback_t cb) { mSearchCallback = cb; } + void setText(const LLStringExplicit &new_text) { mSearchEditor->setText(new_text); } // LLUICtrl interface virtual void setValue(const LLSD& value ); @@ -87,12 +76,8 @@ public: virtual void clear(); private: - void onSearchEdit(LLLineEditor* caller ); - void onClearSearch(const LLSD& data); - - LLLineEditor* mSearchEdit; - LLButton* mClearSearchButton; - search_callback_t mSearchCallback; + LLLineEditor* mSearchEditor; + LLButton* mSearchButton; }; -#endif // LL_LLSEARCHEDITOR_H +#endif // LL_SEARCHEDITOR_H diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp index 8070dc4d02..9483cca104 100644 --- a/indra/llui/llslider.cpp +++ b/indra/llui/llslider.cpp @@ -40,10 +40,9 @@ #include "llfocusmgr.h" #include "llkeyboard.h" // for the MASK constants #include "llcontrol.h" -#include "llimagegl.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register r1("slider_bar"); +static LLDefaultChildRegistry::Register r1("slider_bar"); //FIXME: make this into an unregistered template so that code constructed sliders don't // have ambigious template lookup problem diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h index dad65fcce0..088fd20d94 100644 --- a/indra/llui/llslider.h +++ b/indra/llui/llslider.h @@ -36,8 +36,6 @@ #include "llf32uictrl.h" #include "v4color.h" -class LLImageGL; - class LLSlider : public LLF32UICtrl { public: @@ -64,6 +62,9 @@ public: void setValue( F32 value, BOOL from_event = FALSE ); // overrides for LLF32UICtrl methods virtual void setValue(const LLSD& value ) { setValue((F32)value.asReal(), TRUE); } + + virtual void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); } + virtual void setMaxValue(const LLSD& max_value) { setMaxValue((F32)max_value.asReal()); } virtual void setMinValue(F32 min_value) { LLF32UICtrl::setMinValue(min_value); updateThumbRect(); } virtual void setMaxValue(F32 max_value) { LLF32UICtrl::setMaxValue(max_value); updateThumbRect(); } diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index 8bdeddcf75..3176938ea2 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -53,7 +53,7 @@ const U32 MAX_STRING_LENGTH = 10; -static LLDefaultWidgetRegistry::Register r("slider"); +static LLDefaultChildRegistry::Register r("slider"); LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p) : LLF32UICtrl(p), diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h index 5bdbbfcbcc..4a1574d502 100644 --- a/indra/llui/llsliderctrl.h +++ b/indra/llui/llsliderctrl.h @@ -100,12 +100,15 @@ public: /*virtual*/ void setEnabled( BOOL b ); /*virtual*/ void clear(); + + /*virtual*/ void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); } + /*virtual*/ void setMaxValue(const LLSD& max_value) { setMaxValue((F32)max_value.asReal()); } /*virtual*/ void setMinValue(F32 min_value) { mSlider->setMinValue(min_value); updateText(); } /*virtual*/ void setMaxValue(F32 max_value) { mSlider->setMaxValue(max_value); updateText(); } /*virtual*/ void setIncrement(F32 increment) { mSlider->setIncrement(increment);} - F32 getMinValue() { return mSlider->getMinValue(); } - F32 getMaxValue() { return mSlider->getMaxValue(); } + F32 getMinValue() const { return mSlider->getMinValue(); } + F32 getMaxValue() const { return mSlider->getMaxValue(); } void setLabel(const LLStringExplicit& label) { if (mLabelBox) mLabelBox->setText(label); } void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; } diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 72329a4b32..2d70432182 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -53,14 +53,16 @@ const U32 MAX_STRING_LENGTH = 32; -static LLDefaultWidgetRegistry::Register r2("spinner"); +static LLDefaultChildRegistry::Register r2("spinner"); LLSpinCtrl::Params::Params() : label_width("label_width"), decimal_digits("decimal_digits"), allow_text_entry("allow_text_entry", true), text_enabled_color("text_enabled_color"), - text_disabled_color("text_disabled_color") + text_disabled_color("text_disabled_color"), + up_button("up_button"), + down_button("down_button") {} LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) @@ -103,38 +105,28 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) S32 btn_right = btn_left + spinctrl_btn_width; // Spin buttons - LLButton::Params up_button_params; - up_button_params.name(std::string("SpinCtrl Up")); + LLButton::Params up_button_params(p.up_button); up_button_params.rect .left(btn_left) .top(top) .right(btn_right) .height(spinctrl_btn_height); - up_button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM); - up_button_params.image_unselected.name("spin_up_out_blue.tga"); - up_button_params.image_selected.name("spin_up_in_blue.tga"); up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); - up_button_params.tab_stop(false); mUpBtn = LLUICtrlFactory::create(up_button_params); addChild(mUpBtn); LLRect down_rect( btn_left, top - spinctrl_btn_height, btn_right, bottom ); - LLButton::Params down_button_params; - down_button_params.name(std::string("SpinCtrl Down")); + LLButton::Params down_button_params(p.down_button); down_button_params.rect .left(btn_left) .right(btn_right) .bottom(bottom) .height(spinctrl_btn_height); - down_button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM); - down_button_params.image_unselected.name("spin_down_out_blue.tga"); - down_button_params.image_selected.name("spin_down_in_blue.tga"); down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); - down_button_params.tab_stop(false); mDownBtn = LLUICtrlFactory::create(down_button_params); addChild(mDownBtn); diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h index eb1a2eb8a7..0e610b7741 100644 --- a/indra/llui/llspinctrl.h +++ b/indra/llui/llspinctrl.h @@ -35,6 +35,7 @@ #include "stdtypes.h" +#include "llbutton.h" #include "llf32uictrl.h" #include "v4color.h" #include "llrect.h" @@ -53,6 +54,9 @@ public: Optional text_enabled_color; Optional text_disabled_color; + Optional up_button; + Optional down_button; + Params(); }; protected: diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp index 3bd2c9f9e7..55d6b3159f 100644 --- a/indra/llui/llstatgraph.cpp +++ b/indra/llui/llstatgraph.cpp @@ -107,10 +107,10 @@ void LLStatGraph::draw() } //gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, - // gSavedSkinSettings.getColor("ColorDropShadow"), + // LLUIColorTable::instance().getColor("ColorDropShadow"), // (S32) gSavedSettings.getF32("DropShadowFloater") ); - color = LLUI::sSettingGroups["color"]->getColor( "MenuDefaultBgColor" ); + color = LLUIColorTable::instance().getColor( "MenuDefaultBgColor" ); gGL.color4fv(color.mV); gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, TRUE); diff --git a/indra/llui/llstatview.cpp b/indra/llui/llstatview.cpp index 6691f16c1e..ab4b0be97a 100644 --- a/indra/llui/llstatview.cpp +++ b/indra/llui/llstatview.cpp @@ -65,16 +65,6 @@ LLStatView::~LLStatView() } -// widget registrars -struct StatViewRegistry : public LLWidgetRegistry -{}; - static StatViewRegistry::Register r1("stat_bar"); -const widget_registry_t& LLStatView::getChildRegistry() const -{ - return StatViewRegistry::instance(); -} - - diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h index 20aba7782b..eee4e2b7e4 100644 --- a/indra/llui/llstatview.h +++ b/indra/llui/llstatview.h @@ -39,6 +39,10 @@ class LLStatBar; +// widget registrars +struct StatViewRegistry : public LLChildRegistry +{}; + class LLStatView : public LLContainerView { public: @@ -51,9 +55,11 @@ public: follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT); } }; - ~LLStatView(); - virtual const widget_registry_t& getChildRegistry() const; + // my valid children are stored in this registry + typedef StatViewRegistry child_registry_t; + + ~LLStatView(); protected: LLStatView(const Params&); diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index 890abc7d67..32ddded2c8 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -34,7 +34,6 @@ #define LL_LLSTYLE_H #include "v4color.h" -#include "llfont.h" #include "llui.h" class LLFontGL; @@ -106,7 +105,7 @@ protected: private: BOOL mVisible; - LLColor4 mColor; + LLUIColor mColor; std::string mFontName; LLFontGL* mFont; // cached for performance std::string mLink; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 3391b1275c..29c30004ef 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -99,8 +99,8 @@ struct LLPlaceHolderPanel : public LLPanel LLPlaceHolderPanel(const Params& p) : LLPanel(p) {} }; -static LLDefaultWidgetRegistry::Register r1("placeholder"); -static LLDefaultWidgetRegistry::Register r2("tab_container"); +static LLDefaultChildRegistry::Register r1("placeholder"); +static LLDefaultChildRegistry::Register r2("tab_container"); LLTabContainer::Params::Params() : tab_width("tab_width"), @@ -108,6 +108,7 @@ LLTabContainer::Params::Params() tab_min_width("tab_min_width"), tab_max_width("tab_max_width"), hide_tabs("hide_tabs", false), + tab_padding_right("tab_padding_right"), tab_top_image_unselected("tab_top_image_unselected"), tab_top_image_selected("tab_top_image_selected"), tab_bottom_image_unselected("tab_bottom_image_unselected"), diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index ac8232bbb1..78592a0f9a 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -122,6 +122,10 @@ public: TabPanelParams() : panel("panel", NULL), + label("label"), + select_tab("select_tab"), + is_placeholder("is_placeholder"), + indent("indent"), insert_at("insert_at", END) {} }; diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 464e4be809..3dd8d21f6b 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -30,17 +30,13 @@ * $/LicenseInfo$ */ -#define INSTANTIATE_GETCHILD_TEXTBOX - #include "linden_common.h" #include "lltextbox.h" #include "lluictrlfactory.h" #include "llfocusmgr.h" #include "llwindow.h" -template LLTextBox* LLView::getChild( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - -static LLDefaultWidgetRegistry::Register r("text"); +static LLDefaultChildRegistry::Register r("text"); LLTextBox::Params::Params() : text_color("text_color"), @@ -86,8 +82,7 @@ LLTextBox::LLTextBox(const LLTextBox::Params& p) mHAlign(p.font_halign), mLineSpacing(p.line_spacing), mWordWrap( p.word_wrap ), - mDidWordWrap(FALSE), - mFontStyle(LLFontGL::getStyleFromString(p.font.style)) + mDidWordWrap(FALSE) { setText( p.text() ); } @@ -314,7 +309,7 @@ void LLTextBox::draw() if( mBorderDropShadowVisible ) { - static LLUICachedControl color_drop_shadow ("ColorDropShadow", *(new LLColor4)); + static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow"); static LLUICachedControl drop_shadow_tooltip ("DropShadowTooltip", 0); gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, color_drop_shadow, drop_shadow_tooltip); @@ -386,7 +381,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) { mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color, mHAlign, mVAlign, - mFontStyle, + 0, mShadowType, S32_MAX, getRect().getWidth(), NULL, TRUE, mUseEllipses); } @@ -399,7 +394,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) S32 line_length = *iter; mFontGL->render(mText.getWString(), cur_pos, (F32)x, (F32)y, color, mHAlign, mVAlign, - mFontStyle, + 0, mShadowType, line_length, getRect().getWidth(), NULL, TRUE, mUseEllipses ); cur_pos += line_length + 1; diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index dca906decc..d807fe7639 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -143,7 +143,6 @@ private: BOOL mWordWrap; BOOL mDidWordWrap; - U8 mFontStyle; // style bit flags for font LLFontGL::ShadowType mShadowType; BOOL mBorderDropShadowVisible; BOOL mUseEllipses; @@ -159,11 +158,4 @@ private: callback_t mClickedCallback; }; -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_TEXTBOX -#pragma warning (disable : 4231) -extern template LLTextBox* LLView::getChild( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif - #endif diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 34bced064e..48816e4b9e 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -36,6 +36,7 @@ #include "lltexteditor.h" +#include "llfontfreetype.h" // for LLFontFreetype::FIRST_CHAR #include "llfontgl.h" #include "llrender.h" #include "llui.h" @@ -55,7 +56,6 @@ #include "llundo.h" #include "llviewborder.h" #include "llcontrol.h" -#include "llimagegl.h" #include "llwindow.h" #include "lltextparser.h" #include @@ -63,7 +63,7 @@ // // Globals // -static LLDefaultWidgetRegistry::Register r("simple_text_editor"); +static LLDefaultChildRegistry::Register r("simple_text_editor"); // // Constants @@ -75,7 +75,7 @@ const S32 CURSOR_THICKNESS = 2; const S32 SPACES_PER_TAB = 4; -LLColor4 LLTextEditor::mLinkColor = LLColor4::blue; +LLUIColor LLTextEditor::mLinkColor = LLColor4::blue; void (* LLTextEditor::mURLcallback)(const std::string&) = NULL; bool (* LLTextEditor::mSecondlifeURLcallback)(const std::string&) = NULL; bool (* LLTextEditor::mSecondlifeURLcallbackRightClick)(const std::string&) = NULL; @@ -228,6 +228,29 @@ private: /////////////////////////////////////////////////////////////////// +LLTextEditor::Params::Params() +: default_text("default_text"), + max_text_length("max_length", 255), + read_only("read_only", false), + embedded_items("embedded_items", false), + hide_scrollbar("hide_scrollbar", false), + hide_border("hide_border", false), + word_wrap("word_wrap", false), + ignore_tab("ignore_tab", true), + track_bottom("track_bottom", false), + takes_non_scroll_clicks("takes_non_scroll_clicks", true), + cursor_color("cursor_color"), + default_color("default_color"), + text_color("text_color"), + text_readonly_color("text_readonly_color"), + bg_readonly_color("bg_readonly_color"), + bg_writeable_color("bg_writeable_color"), + bg_focus_color("bg_focus_color"), + length("length"), // ignored + type("type"), // ignored + is_unicode("is_unicode")// ignored +{} + LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) : LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)), mMaxTextByteLength( p.max_text_length ), @@ -255,8 +278,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) mHideScrollbarForShortDocs( FALSE ), mTakesNonScrollClicks( p.takes_non_scroll_clicks ), mTrackBottom( p.track_bottom ), - mAllowEmbeddedItems( p.allow_embedded_items ), - mAcceptCallingCardNames(FALSE), + mAllowEmbeddedItems( p.embedded_items ), mHandleEditKeysDirectly( FALSE ), mMouseDownX(0), mMouseDownY(0), @@ -264,9 +286,10 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) mReflowNeeded(FALSE), mScrollNeeded(FALSE), mLastSelectionY(-1), + mParseHTML(FALSE), + mParseHighlights(FALSE), mTabsToNextField(p.ignore_tab), - mGLFont(p.font), - mGLFontStyle(LLFontGL::getStyleFromString(p.font.style)) + mGLFont(p.font) { static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); @@ -304,7 +327,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) LLViewBorder::Params params; params.name("text ed border"); params.rect(getLocalRect()); - params.bevel_type(LLViewBorder::BEVEL_IN); + params.bevel_style(LLViewBorder::BEVEL_IN); params.border_thickness(text_editor_border); mBorder = LLUICtrlFactory::create (params); addChild( mBorder ); @@ -314,7 +337,6 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) setHideScrollbarForShortDocs(p.hide_scrollbar); - mParseHTML=FALSE; mHTML.clear(); } @@ -377,6 +399,7 @@ void LLTextEditor::updateLineStartList(S32 startpos) S32 seg_idx = 0; S32 seg_offset = 0; + if (!mLineStartList.empty()) { getSegmentAndOffset(startpos, &seg_idx, &seg_offset); @@ -1932,7 +1955,7 @@ void LLTextEditor::pasteHelper(bool is_primary) for( S32 i = 0; i < len; i++ ) { llwchar wc = clean_string[i]; - if( (wc < LLFont::FIRST_CHAR) && (wc != LF) ) + if( (wc < LLFontFreetype::FIRST_CHAR) && (wc != LF) ) { clean_string[i] = LL_UNKNOWN_CHAR; } @@ -3083,8 +3106,8 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 if (style->getIsEmbeddedItem()) { - static LLUICachedControl text_embedded_item_readonly_color ("TextEmbeddedItemReadOnlyColor", *(new LLColor4)); - static LLUICachedControl text_embedded_item_color ("TextEmbeddedItemColor", *(new LLColor4)); + static LLUIColor text_embedded_item_readonly_color = LLUIColorTable::instance().getColor("TextEmbeddedItemReadOnlyColor"); + static LLUIColor text_embedded_item_color = LLUIColorTable::instance().getColor("TextEmbeddedItemColor"); if (mReadOnly) { color = text_embedded_item_readonly_color; @@ -3103,7 +3126,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 S32 start = seg_start; S32 end = llmin( selection_left, seg_end ); S32 length = end - start; - font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, mGLFontStyle, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); + font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); } x = *right_x; @@ -3116,7 +3139,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 font->render(text, start, x, y_top, LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ), - LLFontGL::LEFT, LLFontGL::TOP, mGLFontStyle, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); + LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); } x = *right_x; if( selection_right < seg_end ) @@ -3125,7 +3148,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 S32 start = llmax( selection_right, seg_start ); S32 end = seg_end; S32 length = end - start; - font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, mGLFontStyle, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); + font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); } } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index f64353555e..0babd7ba58 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -63,7 +63,7 @@ public: Optional max_text_length; Optional read_only, - allow_embedded_items, + embedded_items, hide_scrollbar, word_wrap, ignore_tab, @@ -86,30 +86,7 @@ public: length, is_unicode; - - Params() - : max_text_length("max_length", 255), - read_only("read_only", false), - allow_embedded_items("embedded_items", false), - hide_scrollbar("hide_scrollbar", false), - hide_border("hide_border", false), - word_wrap("word_wrap", false), - ignore_tab("ignore_tab", true), - track_bottom("track_bottom", false), - takes_non_scroll_clicks("takes_non_scroll_clicks", true), - cursor_color("cursor_color"), - default_color("default_color"), - text_color("text_color"), - text_readonly_color("text_readonly_color"), - bg_readonly_color("bg_readonly_color"), - bg_writeable_color("bg_writeable_color"), - bg_focus_color("bg_focus_color"), - length("length"), - type("type"), - is_unicode("is_unicode") - {} - - + Params(); }; void initFromParams(const Params&); @@ -268,8 +245,6 @@ public: void setSourceID(const LLUUID& id) { mSourceID = id; } const LLUUID& getSourceID() const { return mSourceID; } - void setAcceptCallingCardNames(BOOL enable) { mAcceptCallingCardNames = enable; } - BOOL acceptsCallingCardNames() const { return mAcceptCallingCardNames; } void setHandleEditKeysDirectly( BOOL b ) { mHandleEditKeysDirectly = b; } @@ -512,7 +487,7 @@ private: // Data // LLKeywords mKeywords; - static LLColor4 mLinkColor; + static LLUIColor mLinkColor; static void (*mURLcallback) (const std::string& url); static bool (*mSecondlifeURLcallback) (const std::string& url); static bool (*mSecondlifeURLcallbackRightClick) (const std::string& url); @@ -526,7 +501,6 @@ private: S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes const LLFontGL* mGLFont; - U8 mGLFontStyle; // the font style from xml class LLViewBorder* mBorder; @@ -541,6 +515,7 @@ private: S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be LLRect mTextRect; // The rect in which text is drawn. Excludes borders. // List of offsets and segment index of the start of each line. Always has at least one node (0). + struct pred; struct line_info { line_info(S32 segment, S32 offset) : mSegment(segment), mOffset(offset) {} @@ -586,8 +561,6 @@ private: BOOL mAllowEmbeddedItems; - BOOL mAcceptCallingCardNames; - LLUUID mSourceID; // If true, the standard edit keys (Ctrl-X, Delete, etc,) are handled here diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 1d3e5d7a15..fab8f61356 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -43,7 +43,6 @@ #include "v4color.h" #include "llrender.h" #include "llrect.h" -#include "llimagegl.h" #include "lldir.h" #include "llfontgl.h" @@ -59,8 +58,9 @@ #include "llwindow.h" // for registration -#include "llsearcheditor.h" +#include "llfiltereditor.h" #include "llflyoutbutton.h" +#include "llsearcheditor.h" // for XUIParse #include "llquaternion.h" @@ -89,9 +89,10 @@ std::list gUntranslated; /*static*/ std::vector LLUI::sXUIPaths; -// register searcheditor here -static LLDefaultWidgetRegistry::Register register_search_editor("search_editor"); -static LLDefaultWidgetRegistry::Register register_flyout_button("flyout_button"); +// register filtereditor here +static LLDefaultChildRegistry::Register register_filter_editor("filter_editor"); +static LLDefaultChildRegistry::Register register_flyout_button("flyout_button"); +static LLDefaultChildRegistry::Register register_search_editor("search_editor"); // @@ -424,7 +425,7 @@ void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max } -void gl_draw_image( S32 x, S32 y, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect ) +void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect ) { if (NULL == image) { @@ -434,7 +435,7 @@ void gl_draw_image( S32 x, S32 y, LLImageGL* image, const LLColor4& color, const gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect ); } -void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) +void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) { if (NULL == image) { @@ -444,7 +445,7 @@ void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect ); } -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLImageGL* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect) +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect) { if (NULL == image) { @@ -460,7 +461,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect); } -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, const LLRectf& scale_rect) +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, const LLRectf& scale_rect) { stop_glerror(); @@ -646,12 +647,12 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLIma } } -void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) +void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) { gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect ); } -void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) +void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) { if (NULL == image) { @@ -697,7 +698,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre } -void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) +void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) { if (NULL == image) { @@ -1579,7 +1580,6 @@ void LLUI::initClass(const settings_map_t& settings, sSettingGroups = settings; if ((get_ptr_in_map(sSettingGroups, std::string("config")) == NULL) || - (get_ptr_in_map(sSettingGroups, std::string("color")) == NULL) || (get_ptr_in_map(sSettingGroups, std::string("floater")) == NULL) || (get_ptr_in_map(sSettingGroups, std::string("ignores")) == NULL)) { @@ -1590,7 +1590,7 @@ void LLUI::initClass(const settings_map_t& settings, sAudioCallback = audio_callback; sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor; sWindow = NULL; // set later in startup - LLFontGL::sShadowColor = LLUI::sSettingGroups["color"]->getColor("ColorDropShadow"); + LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow"); static LLUICachedControl show_xui_names ("ShowXUINames", false); LLUI::sShowXUINames = show_xui_names; @@ -1855,22 +1855,16 @@ void LLUI::setHtmlHelp(LLHtmlHelp* html_help) LLUI::sHtmlHelp = html_help; } -// static -boost::function LLUI::getCachedColorFunctor(const std::string& color_name) -{ - return LLCachedControl(*sSettingGroups["color"], color_name, LLColor4::magenta); -} - -// static LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname) { for (settings_map_t::iterator itor = sSettingGroups.begin(); itor != sSettingGroups.end(); ++itor) { - if(itor->second!= NULL) + LLControlGroup* control_group = itor->second; + if(control_group != NULL) { - if (sSettingGroups[(itor->first)]->controlExists(controlname)) - return *sSettingGroups[(itor->first)]; + if (control_group->controlExists(controlname)) + return *control_group; } } @@ -1942,8 +1936,8 @@ LLLocalClipRect::LLLocalClipRect(const LLRect &rect, BOOL enabled) namespace LLInitParam { - TypedParam::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func) - : super_t(descriptor, name, value, func), + TypedParam::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count), red("red"), green("green"), blue("blue"), @@ -1972,11 +1966,22 @@ namespace LLInitParam declare("blue", LLColor4::blue); } - TypedParam::TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL*const value, ParamDescriptor::validation_func_t func) - : super_t(descriptor, name, value, func), - name("", std::string("")), - size("size", std::string("")), - style("style", std::string("")) + template<> + class ParamCompare + { + public: + static bool equals(const LLFontGL* a, const LLFontGL* b) + { + return !(a->getFontDesc() < b->getFontDesc()) + && !(b->getFontDesc() < a->getFontDesc()); + } + }; + + TypedParam::TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count), + name(""), + size("size"), + style("style") {} const LLFontGL* TypedParam::getValueFromBlock() const @@ -2003,8 +2008,8 @@ namespace LLInitParam return mData.mValue; } - TypedParam::TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func) - : super_t(descriptor, name, value, func), + TypedParam::TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count), left("left"), top("top"), right("right"), diff --git a/indra/llui/llui.h b/indra/llui/llui.h index dbd295d4e8..b1943a7b02 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -39,14 +39,17 @@ #include "llrect.h" #include "llcontrol.h" #include "llcoord.h" -//#include "llhtmlhelp.h" #include "llgl.h" // *TODO: break this dependency #include #include "lluiimage.h" // *TODO: break this dependency, need to add #include "lluiimage.h" to all widgets that hold an Optional in their paramblocks #include "llinitparam.h" #include "llregistry.h" +#include "lluicolor.h" +#include "lluicolortable.h" #include #include "lllazyvalue.h" +#include "llhandle.h" // *TODO: remove this dependency, added as a + // convenience when LLHandle moved to llhandle.h // LLUIFactory #include "llsd.h" @@ -56,7 +59,6 @@ class LLColor4; class LLHtmlHelp; -class LLImageGL; class LLVector3; class LLVector2; class LLUIImage; @@ -97,14 +99,14 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color); void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color); -void gl_draw_image(S32 x, S32 y, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLImageGL* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); // Flip vertical, used for LLFloaterHTML -void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom); void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); @@ -202,7 +204,6 @@ public: static void screenRectToGL(const LLRect& screen, LLRect *gl); static void glRectToScreen(const LLRect& gl, LLRect *screen); static void setHtmlHelp(LLHtmlHelp* html_help); - static boost::function getCachedColorFunctor(const std::string& color_name); // Returns the control group containing the control name, or the default group static LLControlGroup& getControlControlGroup (const std::string& controlname); @@ -221,188 +222,6 @@ private: static std::vector sXUIPaths; }; -// FactoryPolicy is a static class that controls the creation and lookup of UI elements, -// such as floaters. -// The key parameter is used to provide a unique identifier and/or associated construction -// parameters for a given UI instance -// -// Specialize this traits for different types, or provide a class with an identical interface -// in the place of the traits parameter -// -// For example: -// -// template <> -// class FactoryPolicy /* FactoryPolicy specialized for MyClass */ -// { -// public: -// static MyClass* findInstance(const LLSD& key = LLSD()) -// { -// /* return instance of MyClass associated with key */ -// } -// -// static MyClass* createInstance(const LLSD& key = LLSD()) -// { -// /* create new instance of MyClass using key for construction parameters */ -// } -// } -// -// class MyClass : public LLUIFactory -// { -// /* uses FactoryPolicy by default */ -// } - -template -class FactoryPolicy -{ -public: - // basic factory methods - static T* findInstance(const LLSD& key); // unimplemented, provide specialiation - static T* createInstance(const LLSD& key); // unimplemented, provide specialiation -}; - -// VisibilityPolicy controls the visibility of UI elements, such as floaters. -// The key parameter is used to store the unique identifier of a given UI instance -// -// Specialize this traits for different types, or duplicate this interface for specific instances -// (see above) - -template -class VisibilityPolicy -{ -public: - // visibility methods - static bool visible(T* instance, const LLSD& key); // unimplemented, provide specialiation - static void show(T* instance, const LLSD& key); // unimplemented, provide specialiation - static void hide(T* instance, const LLSD& key); // unimplemented, provide specialiation -}; - -// Manages generation of UI elements by LLSD, such that (generally) there is -// a unique instance per distinct LLSD parameter -// Class T is the instance type being managed, and the FACTORY_POLICY and VISIBILITY_POLICY -// classes provide static methods for creating, accessing, showing and hiding the associated -// element T -template , class VISIBILITY_POLICY = VisibilityPolicy > -class LLUIFactory -{ -public: - // give names to the template parameters so derived classes can refer to them - // except this doesn't work in gcc - typedef FACTORY_POLICY factory_policy_t; - typedef VISIBILITY_POLICY visibility_policy_t; - - LLUIFactory() - { - } - - virtual ~LLUIFactory() - { - } - - // default show and hide methods - static T* showInstance(const LLSD& key = LLSD()) - { - T* instance = getInstance(key); - if (instance != NULL) - { - VISIBILITY_POLICY::show(instance, key); - } - return instance; - } - - static void hideInstance(const LLSD& key = LLSD()) - { - T* instance = getInstance(key); - if (instance != NULL) - { - VISIBILITY_POLICY::hide(instance, key); - } - } - - static void toggleInstance(const LLSD& key = LLSD()) - { - if (instanceVisible(key)) - { - hideInstance(key); - } - else - { - showInstance(key); - } - } - - static bool instanceVisible(const LLSD& key = LLSD()) - { - T* instance = FACTORY_POLICY::findInstance(key); - return instance != NULL && VISIBILITY_POLICY::visible(instance, key); - } - - static T* getInstance(const LLSD& key = LLSD()) - { - T* instance = FACTORY_POLICY::findInstance(key); - if (instance == NULL) - { - instance = FACTORY_POLICY::createInstance(key); - } - return instance; - } - -}; - - -// Creates a UI singleton by ignoring the identifying parameter -// and always generating the same instance via the LLUIFactory interface. -// Note that since UI elements can be destroyed by their hierarchy, this singleton -// pattern uses a static pointer to an instance that will be re-created as needed. -// -// Usage Pattern: -// -// class LLFloaterFoo : public LLFloater, public LLUISingleton -// { -// friend class LLUISingleton; -// private: -// LLFloaterFoo(const LLSD& key); -// }; -// -// Note that LLUISingleton takes an option VisibilityPolicy parameter that defines -// how showInstance(), hideInstance(), etc. work. -// -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLUISingleton&oldid=79352 - -template > -class LLUISingleton: public LLUIFactory, VISIBILITY_POLICY> -{ -protected: - - // T must derive from LLUISingleton - LLUISingleton() { sInstance = static_cast(this); } - ~LLUISingleton() { sInstance = NULL; } - -public: - static T* findInstance(const LLSD& key = LLSD()) - { - return sInstance; - } - - static T* createInstance(const LLSD& key = LLSD()) - { - if (sInstance == NULL) - { - sInstance = new T(key); - } - return sInstance; - } - - static void destroyInstance() - { - delete sInstance; - sInstance = NULL; - } - -private: - static T* sInstance; -}; - -template T* LLUISingleton::sInstance = NULL; class LLScreenClipRect { @@ -428,139 +247,7 @@ public: LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE); }; -template -class LLTombStone : public LLRefCount -{ -public: - LLTombStone(T* target = NULL) : mTarget(target) {} - - void setTarget(T* target) { mTarget = target; } - T* getTarget() const { return mTarget; } -private: - T* mTarget; -}; - -// LLHandles are used to refer to objects whose lifetime you do not control or influence. -// Calling get() on a handle will return a pointer to the referenced object or NULL, -// if the object no longer exists. Note that during the lifetime of the returned pointer, -// you are assuming that the object will not be deleted by any action you perform, -// or any other thread, as normal when using pointers, so avoid using that pointer outside of -// the local code block. -// -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 - -template -class LLHandle -{ -public: - LLHandle() : mTombStone(sDefaultTombStone) {} - const LLHandle& operator =(const LLHandle& other) - { - mTombStone = other.mTombStone; - return *this; - } - - bool isDead() const - { - return mTombStone->getTarget() == NULL; - } - - void markDead() - { - mTombStone = sDefaultTombStone; - } - - T* get() const - { - return mTombStone->getTarget(); - } - - friend bool operator== (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone == rhs.mTombStone; - } - friend bool operator!= (const LLHandle& lhs, const LLHandle& rhs) - { - return !(lhs == rhs); - } - friend bool operator< (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone < rhs.mTombStone; - } - friend bool operator> (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone > rhs.mTombStone; - } -protected: - -protected: - LLPointer > mTombStone; - -private: - static LLPointer > sDefaultTombStone; -}; - -// initialize static "empty" tombstone pointer -template LLPointer > LLHandle::sDefaultTombStone = new LLTombStone(); - - -template -class LLRootHandle : public LLHandle -{ -public: - LLRootHandle(T* object) { bind(object); } - LLRootHandle() {}; - ~LLRootHandle() { unbind(); } - - // this is redundant, since a LLRootHandle *is* an LLHandle - LLHandle getHandle() { return LLHandle(*this); } - - void bind(T* object) - { - // unbind existing tombstone - if (LLHandle::mTombStone.notNull()) - { - if (LLHandle::mTombStone->getTarget() == object) return; - LLHandle::mTombStone->setTarget(NULL); - } - // tombstone reference counted, so no paired delete - LLHandle::mTombStone = new LLTombStone(object); - } - - void unbind() - { - LLHandle::mTombStone->setTarget(NULL); - } - - //don't allow copying of root handles, since there should only be one -private: - LLRootHandle(const LLRootHandle& other) {}; -}; - -// Use this as a mixin for simple classes that need handles and when you don't -// want handles at multiple points of the inheritance hierarchy -template -class LLHandleProvider -{ -protected: - typedef LLHandle handle_type_t; - LLHandleProvider() - { - // provided here to enforce T deriving from LLHandleProvider - } - - LLHandle getHandle() - { - // perform lazy binding to avoid small tombstone allocations for handle - // providers whose handles are never referenced - mHandle.bind(static_cast(this)); - return mHandle; - } - -private: - LLRootHandle mHandle; -}; - +// Moved all LLHandle-related code to llhandle.h //RN: maybe this needs to moved elsewhere? class LLImageProviderInterface @@ -690,8 +377,6 @@ public: {} }; -typedef LLLazyValue LLUIColor; - namespace LLInitParam { template<> @@ -707,7 +392,7 @@ namespace LLInitParam width, height; - TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func); + TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); LLRect getValueFromBlock() const; }; @@ -730,7 +415,7 @@ namespace LLInitParam Optional alpha; Optional control; - TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func); + TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); LLUIColor getValueFromBlock() const; }; @@ -744,7 +429,7 @@ namespace LLInitParam Optional size; Optional style; - TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func); + TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); const LLFontGL* getValueFromBlock() const; }; @@ -767,11 +452,4 @@ namespace LLInitParam }; } -namespace LLInitParam -{ - template<> - bool ParamCompare >::equals( - const LLLazyValue &a, const LLLazyValue &b); -} - #endif diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp index 27ba6cc8b4..087a99c2b0 100644 --- a/indra/llui/lluicolortable.cpp +++ b/indra/llui/lluicolortable.cpp @@ -11,7 +11,10 @@ #include +#include "lldir.h" +#include "llui.h" #include "lluicolortable.h" +#include "lluictrlfactory.h" LLUIColorTable::ColorParams::ColorParams() : value("value"), @@ -26,17 +29,16 @@ LLUIColorTable::ColorEntryParams::ColorEntryParams() } LLUIColorTable::Params::Params() -: color_entries("color_entries") +: color_entries("color") { } -void LLUIColorTable::init(const Params& p) +void LLUIColorTable::insertFromParams(const Params& p) { // this map will contain all color references after the following loop typedef std::map string_string_map_t; string_string_map_t unresolved_refs; - mColors.clear(); for(LLInitParam::ParamIterator::const_iterator it = p.color_entries().begin(); it != p.color_entries().end(); ++it) @@ -44,7 +46,7 @@ void LLUIColorTable::init(const Params& p) ColorEntryParams color_entry = *it; if(color_entry.color.value.isChosen()) { - mColors.insert(string_color_map_t::value_type(color_entry.name, color_entry.color.value)); + setColor(color_entry.name, color_entry.color.value, mLoadedColors); } else { @@ -66,19 +68,21 @@ void LLUIColorTable::init(const Params& p) // we haven't visited any references yet visited_refs.clear(); - string_string_map_t::iterator it = unresolved_refs.begin(); + string_string_map_t::iterator current = unresolved_refs.begin(); + string_string_map_t::iterator previous; + while(true) { - if(it != unresolved_refs.end()) + if(current != unresolved_refs.end()) { // locate the current reference in the previously visited references... - string_color_ref_iter_map_t::iterator visited = visited_refs.lower_bound(it->first); + string_color_ref_iter_map_t::iterator visited = visited_refs.lower_bound(current->first); if(visited != visited_refs.end() - && !(visited_refs.key_comp()(it->first, visited->first))) + && !(visited_refs.key_comp()(current->first, visited->first))) { // ...if we find the current reference in the previously visited references // we know that there is a cycle - std::string ending_ref = it->first; + std::string ending_ref = current->first; std::string warning("The following colors form a cycle: "); // warn about the references in the chain and remove them from @@ -102,17 +106,17 @@ void LLUIColorTable::init(const Params& p) else { // ...continue along the reference chain - ref_chain.push(it->first); - visited_refs.insert(visited, string_color_ref_iter_map_t::value_type(it->first, it)); + ref_chain.push(current->first); + visited_refs.insert(visited, string_color_ref_iter_map_t::value_type(current->first, current)); } } else { // since this reference does not refer to another reference it must refer to an // actual color, lets find it... - string_color_map_t::iterator color_value = mColors.find(it->second); + string_color_map_t::iterator color_value = mLoadedColors.find(previous->second); - if(color_value != mColors.end()) + if(color_value != mLoadedColors.end()) { // ...we found the color, and we now add every reference in the reference chain // to the color map @@ -120,7 +124,7 @@ void LLUIColorTable::init(const Params& p) iter != visited_refs.end(); ++iter) { - mColors.insert(string_color_map_t::value_type(iter->first, color_value->second)); + setColor(iter->first, color_value->second, mLoadedColors); unresolved_refs.erase(iter->second); } @@ -143,13 +147,148 @@ void LLUIColorTable::init(const Params& p) } // find the next color reference in the reference chain - it = unresolved_refs.find(it->second); + previous = current; + current = unresolved_refs.find(current->second); } } } -const LLColor4& LLUIColorTable::getColor(const std::string& name) const +void LLUIColorTable::clear() { - string_color_map_t::const_iterator iter = mColors.find(name); - return (iter != mColors.end() ? iter->second : LLColor4::magenta); + clearTable(mLoadedColors); + clearTable(mUserSetColors); +} + +LLUIColor LLUIColorTable::getColor(const std::string& name, const LLColor4& default_color) const +{ + string_color_map_t::const_iterator iter = mUserSetColors.find(name); + if(iter != mUserSetColors.end()) + { + return LLUIColor(&iter->second); + } + + iter = mLoadedColors.find(name); + return (iter != mLoadedColors.end() ? LLUIColor(&iter->second) : LLUIColor(default_color)); +} + +// update user color, loaded colors are parsed on initialization +void LLUIColorTable::setColor(const std::string& name, const LLColor4& color) +{ + setColor(name, color, mUserSetColors); +} + +bool LLUIColorTable::loadFromSettings() +{ + bool result = false; + + std::string default_filename = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "colors.xml"); + result |= loadFromFilename(default_filename); + + std::string current_filename = gDirUtilp->getExpandedFilename(LL_PATH_TOP_SKIN, "colors.xml"); + if(current_filename != default_filename) + { + result |= loadFromFilename(current_filename); + } + + std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml"); + loadFromFilename(user_filename); + + return result; +} + +void LLUIColorTable::saveUserSettings() const +{ + Params params; + + for(string_color_map_t::const_iterator it = mUserSetColors.begin(); + it != mUserSetColors.end(); + ++it) + { + ColorEntryParams color_entry; + color_entry.name = it->first; + color_entry.color.value = it->second; + + params.color_entries.add(color_entry); + } + + LLXMLNodePtr output_node = new LLXMLNode("colors", false); + LLXUIParser::instance().writeXUI(output_node, params); + + if(!output_node->isNull()) + { + const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml"); + LLFILE *fp = LLFile::fopen(filename, "w"); + + if(fp != NULL) + { + LLXMLNode::writeHeaderToFile(fp); + output_node->writeToFile(fp); + + fclose(fp); + } + } +} + +bool LLUIColorTable::colorExists(const std::string& color_name) const +{ + return ((mLoadedColors.find(color_name) != mLoadedColors.end()) + || (mUserSetColors.find(color_name) != mUserSetColors.end())); +} + +void LLUIColorTable::clearTable(string_color_map_t& table) +{ + for(string_color_map_t::iterator it = table.begin(); + it != table.end(); + ++it) + { + it->second = LLColor4::magenta; + } +} + +// this method inserts a color into the table if it does not exist +// if the color already exists it changes the color +void LLUIColorTable::setColor(const std::string& name, const LLColor4& color, string_color_map_t& table) +{ + string_color_map_t::iterator it = table.lower_bound(name); + if(it != table.end() + && !(table.key_comp()(name, it->first))) + { + it->second = color; + } + else + { + table.insert(it, string_color_map_t::value_type(name, color)); + } +} + +bool LLUIColorTable::loadFromFilename(const std::string& filename) +{ + LLXMLNodePtr root; + + if(!LLXMLNode::parseFile(filename, root, NULL)) + { + llwarns << "Unable to parse color file " << filename << llendl; + return false; + } + + if(!root->hasName("colors")) + { + llwarns << filename << " is not a valid color definition file" << llendl; + return false; + } + + Params params; + LLXUIParser::instance().readXUI(root, params); + + if(params.validateBlock()) + { + insertFromParams(params); + } + else + { + llwarns << filename << " failed to load" << llendl; + return false; + } + + return true; } diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h index dcbb1ee5cb..f102a573b8 100644 --- a/indra/llui/lluicolortable.h +++ b/indra/llui/lluicolortable.h @@ -17,8 +17,11 @@ #include "v4color.h" +class LLUIColor; + class LLUIColorTable : public LLSingleton { +LOG_CLASS(LLUIColorTable); public: struct ColorParams : LLInitParam::Choice { @@ -44,15 +47,37 @@ public: }; // define colors by passing in a param block that can be generated via XUI file or manually - void init(const Params& p); + void insertFromParams(const Params& p); + + // reset all colors to default magenta color + void clear(); // color lookup - const LLColor4& getColor(const std::string& name) const; + LLUIColor getColor(const std::string& name, const LLColor4& default_color = LLColor4::magenta) const; + + // if the color is in the table, it's value is changed, otherwise it is added + void setColor(const std::string& name, const LLColor4& color); + + // returns true if color_name exists in the table + bool colorExists(const std::string& color_name) const; + + // loads colors from settings files + bool loadFromSettings(); + + // saves colors specified by the user to the users skin directory + void saveUserSettings() const; private: - // consider using sorted vector + bool loadFromFilename(const std::string& filename); + + // consider using sorted vector, can be much faster typedef std::map string_color_map_t; - string_color_map_t mColors; + + void clearTable(string_color_map_t& table); + void setColor(const std::string& name, const LLColor4& color, string_color_map_t& table); + + string_color_map_t mLoadedColors; + string_color_map_t mUserSetColors; }; #endif // LL_LLUICOLORTABLE_H diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 7b378fd9c7..19d1d4040c 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -38,21 +38,21 @@ #include "llpanel.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register r("ui_ctrl"); +static LLDefaultChildRegistry::Register r("ui_ctrl"); LLUICtrl::Params::Params() : tab_stop("tab_stop", true), label("label"), - initial_value("initial_value"), + initial_value("value"), init_callback("init_callback"), commit_callback("commit_callback"), validate_callback("validate_callback"), rightclick_callback("rightclick_callback"), + mouseenter_callback("mouseenter_callback"), + mouseleave_callback("mouseleave_callback"), control_name("control_name") { - addSynonym(initial_value, "initial_val"); - // this is the canonical name for text contents of an xml node - addSynonym(initial_value, "value"); + addSynonym(initial_value, "initial_value"); } LLFocusableElement::LLFocusableElement() @@ -114,7 +114,7 @@ void LLFocusableElement::setFocus(BOOL b) //static const LLUICtrl::Params& LLUICtrl::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams(); + return LLUICtrlFactory::getDefaultParams(); } @@ -125,7 +125,9 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel) mViewModel(viewmodel), mControlVariable(NULL), mEnabledControlVariable(NULL), - mDisabledControlVariable(NULL) + mDisabledControlVariable(NULL), + mMakeVisibleControlVariable(NULL), + mMakeInvisibleControlVariable(NULL) { mUICtrlHandle.bind(this); } @@ -189,7 +191,7 @@ void LLUICtrl::initFromParams(const Params& p) } else { - commit_callback_t* initfunc = (CallbackRegistry::getValue(p.init_callback.function_name)); + commit_callback_t* initfunc = (CommitCallbackRegistry::getValue(p.init_callback.function_name)); if (initfunc) { (*initfunc)(this, p.init_callback.parameter); @@ -200,6 +202,11 @@ void LLUICtrl::initFromParams(const Params& p) if(p.rightclick_callback.isProvided()) initCommitCallback(p.rightclick_callback, mRightClickSignal); + if(p.mouseenter_callback.isProvided()) + initCommitCallback(p.mouseenter_callback, mMouseEnterSignal); + + if(p.mouseleave_callback.isProvided()) + initCommitCallback(p.mouseleave_callback, mMouseLeaveSignal); } @@ -226,7 +233,7 @@ void LLUICtrl::initCommitCallback(const CommitCallbackParam& cb, commit_signal_t else { std::string function_name = cb.function_name; - commit_callback_t* func = (CallbackRegistry::getValue(function_name)); + commit_callback_t* func = (CommitCallbackRegistry::getValue(function_name)); if (func) { if (cb.parameter.isProvided()) @@ -264,6 +271,17 @@ void LLUICtrl::initEnableCallback(const EnableCallbackParam& cb, enable_signal_t } } +// virtual +void LLUICtrl::onMouseEnter(S32 x, S32 y, MASK mask) +{ + mMouseEnterSignal(this, getValue()); +} + +// virtual +void LLUICtrl::onMouseLeave(S32 x, S32 y, MASK mask) +{ + mMouseLeaveSignal(this, getValue()); +} void LLUICtrl::onCommit() { @@ -788,38 +806,6 @@ LLUICtrl* LLUICtrl::findRootMostFocusRoot() return focus_root; } - -/* -// Don't let the children handle the tool tip. Handle it here instead. -BOOL LLUICtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) -{ - BOOL handled = FALSE; - if (getVisible() && pointInView( x, y ) ) - { - if( !mToolTipMsg.empty() ) - { - msg = mToolTipMsg; - - // Convert rect local to screen coordinates - localPointToScreen( - 0, 0, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - getRect().getWidth(), getRect().getHeight(), - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); - - handled = TRUE; - } - } - - if (!handled) - { - return LLView::handleToolTip(x, y, msg, sticky_rect_screen); - } - - return handled; -}*/ - // Skip over any parents that are not LLUICtrl's // Used in focus logic since only LLUICtrl elements can have focus LLUICtrl* LLUICtrl::getParentUICtrl() const @@ -865,14 +851,6 @@ BOOL LLUICtrl::getTentative() const void LLUICtrl::setColor(const LLColor4& color) { } -// virtual -void LLUICtrl::setMinValue(LLSD min_value) -{ } - -// virtual -void LLUICtrl::setMaxValue(LLSD max_value) -{ } - namespace LLInitParam @@ -900,12 +878,4 @@ namespace LLInitParam { return false; } - - template<> - bool ParamCompare >::equals( - const LLLazyValue &a, - const LLLazyValue &b) - { - return a.get() == b.get(); - } } diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 6dfbd9cf8b..cf6634f370 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -108,7 +108,7 @@ public: { Optional function; }; - + struct EnableCallbackParam : public LLInitParam::Block { Optional function; @@ -130,8 +130,8 @@ public: Alternative invisible; ControlVisibility() - : visible("make_visible_control"), - invisible("make_invisible_control") + : visible("visiblity_control"), + invisible("invisiblity_control") {} }; struct Params : public LLInitParam::Block @@ -145,6 +145,9 @@ public: Optional validate_callback; Optional rightclick_callback; + + Optional mouseenter_callback; + Optional mouseleave_callback; Optional focus_lost_callback; @@ -181,6 +184,8 @@ public: /*virtual*/ BOOL isCtrl() const; /*virtual*/ void setTentative(BOOL b); /*virtual*/ BOOL getTentative() const; + /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); + /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); // From LLFocusableElement /*virtual*/ void setFocus( BOOL b ); @@ -227,8 +232,6 @@ public: virtual void onTabInto(); virtual void clear(); virtual void setColor(const LLColor4& color); - virtual void setMinValue(LLSD min_value); - virtual void setMaxValue(LLSD max_value); BOOL focusNextItem(BOOL text_entry_only); BOOL focusPrevItem(BOOL text_entry_only); @@ -246,6 +249,9 @@ public: boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ) { return mCommitSignal.connect(cb); } boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ) { return mValidateSignal.connect(cb); } + + boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb ) { return mMouseEnterSignal.connect(cb); } + boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb ) { return mMouseLeaveSignal.connect(cb); } // *TODO: Deprecate; for backwards compatability only: boost::signals2::connection setCommitCallback( boost::function cb, void* data); @@ -261,11 +267,11 @@ public: } }; - template class CallbackRegistry : public LLRegistrySingleton > + template class CallbackRegistry : public LLRegistrySingleton {}; - typedef CallbackRegistry CommitCallbackRegistry; - typedef CallbackRegistry EnableCallbackRegistry; + class CommitCallbackRegistry : public CallbackRegistry{}; + class EnableCallbackRegistry : public CallbackRegistry{}; protected: @@ -275,6 +281,9 @@ protected: enable_signal_t mValidateSignal; commit_signal_t mRightClickSignal; + commit_signal_t mMouseEnterSignal; + commit_signal_t mMouseLeaveSignal; + LLViewModelPtr mViewModel; LLControlVariable* mControlVariable; @@ -313,6 +322,10 @@ namespace LLInitParam bool ParamCompare::equals( const LLUICtrl::focus_callback_t &a, const LLUICtrl::focus_callback_t &b); + + template<> + bool ParamCompare >::equals( + const LLLazyValue &a, const LLLazyValue &b); } #endif // LL_LLUICTRL_H diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 24e4ad18e6..586b988c43 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -77,6 +77,7 @@ const S32 HPAD = 4; const S32 VPAD = 4; const S32 FLOATER_H_MARGIN = 15; const S32 MIN_WIDGET_HEIGHT = 10; +const S32 MAX_STRING_ATTRIBUTE_SIZE = 40; LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION("Widget Construction"); LLFastTimer::DeclareTimer FTM_INIT_FROM_PARAMS("Widget InitFromParams"); @@ -85,7 +86,8 @@ LLFastTimer::DeclareTimer FTM_WIDGET_SETUP("Widget Setup"); //----------------------------------------------------------------------------- // Register widgets that are purely data driven here so they get linked in #include "llstatview.h" -static LLDefaultWidgetRegistry::Register register_stat_view("stat_view"); +static LLDefaultChildRegistry::Register + register_stat_view("stat_view"); //----------------------------------------------------------------------------- @@ -107,7 +109,7 @@ public: }; -static LLDefaultWidgetRegistry::Register r1("locate"); +static LLDefaultChildRegistry::Register r1("locate"); //----------------------------------------------------------------------------- // LLUICtrlFactory() @@ -135,7 +137,7 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa } //static -void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, LLXMLNodePtr output_node) +void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t& registry, LLXMLNodePtr output_node) { if (node.isNull()) return; @@ -147,7 +149,7 @@ void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, LLXMLNode outputChild = output_node->createChild("", FALSE); } - if (!instance().createFromXML(child_node, viewp, LLStringUtil::null, outputChild, viewp->getChildRegistry())) + if (!instance().createFromXML(child_node, viewp, LLStringUtil::null, registry, outputChild)) { std::string child_name = std::string(child_node->getName()->mString); llwarns << "Could not create widget named " << child_node->getName()->mString << llendl; @@ -194,7 +196,7 @@ static LLFastTimer::DeclareTimer BUILD_FLOATERS("Build Floaters"); //----------------------------------------------------------------------------- // buildFloater() //----------------------------------------------------------------------------- -void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename, BOOL open_floater, LLXMLNodePtr output_node) +void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename, LLXMLNodePtr output_node) { LLFastTimer timer(BUILD_FLOATERS); LLXMLNodePtr root; @@ -234,7 +236,7 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen floaterp->getCommitCallbackRegistrar().pushScope(); floaterp->getEnableCallbackRegistrar().pushScope(); - floaterp->initFloaterXML(root, floaterp->getParent(), open_floater, output_node); + floaterp->initFloaterXML(root, floaterp->getParent(), output_node); if (LLUI::sShowXUINames) { @@ -252,13 +254,6 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen mFileNames.pop_back(); } -LLFloater* LLUICtrlFactory::buildFloaterFromXML(const std::string& filename, BOOL open_floater) -{ - LLFloater* floater = new LLFloater(); - buildFloater(floater, filename, open_floater); - return floater; -} - //----------------------------------------------------------------------------- // saveToXML() //----------------------------------------------------------------------------- @@ -338,12 +333,12 @@ BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename, L LLFastTimer::DeclareTimer FTM_CREATE_FROM_XML("Create child widget"); -LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, LLXMLNodePtr output_node, const widget_registry_t& registry) +LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t& registry, LLXMLNodePtr output_node) { LLFastTimer timer(FTM_CREATE_FROM_XML); std::string ctrl_type = node->getName()->mString; LLStringUtil::toLower(ctrl_type); - + const LLWidgetCreatorFunc* funcp = registry.getValue(ctrl_type); if (funcp == NULL) { @@ -398,11 +393,11 @@ BOOL LLUICtrlFactory::getAttributeColor(LLXMLNodePtr node, const std::string& na { std::string colorstring; BOOL res = node->getAttributeString(name.c_str(), colorstring); - if (res && LLUI::sSettingGroups["color"]) + if (res) { - if (LLUI::sSettingGroups["color"]->controlExists(colorstring)) + if (LLUIColorTable::instance().colorExists(colorstring)) { - color.setVec(LLUI::sSettingGroups["color"]->getColor(colorstring)); + color.setVec(LLUIColorTable::instance().getColor(colorstring)); } else { @@ -448,11 +443,326 @@ void LLUICtrlFactory::popFactoryFunctions() } } -const widget_registry_t& LLUICtrlFactory::getWidgetRegistry(LLView* viewp) +// +// LLXSDWriter +// +LLXSDWriter::LLXSDWriter() { - return viewp->getChildRegistry(); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:boolean", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedByte", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:signedByte", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedShort", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:signedShort", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedInt", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:integer", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:float", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:double", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); } +void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace) +{ + mSchemaNode = node; + node->setName("xs:schema"); + node->createChild("attributeFormDefault", true)->setStringValue("unqualified"); + node->createChild("elementFormDefault", true)->setStringValue("qualified"); + node->createChild("targetNamespace", true)->setStringValue(xml_namespace); + node->createChild("xmlns:xs", true)->setStringValue("http://www.w3.org/2001/XMLSchema"); + node->createChild("xmlns", true)->setStringValue(xml_namespace); + + node = node->createChild("xs:complexType", false); + node->createChild("name", true)->setStringValue(type_name); + node->createChild("mixed", true)->setStringValue("true"); + + mAttributeNode = node; + mElementNode = node->createChild("xs:choice", false); + mElementNode->createChild("minOccurs", true)->setStringValue("0"); + mElementNode->createChild("maxOccurs", true)->setStringValue("unbounded"); + block.inspectBlock(*this); + + // duplicate element choices + LLXMLNodeList children; + mElementNode->getChildren("xs:element", children, FALSE); + for (LLXMLNodeList::iterator child_it = children.begin(); child_it != children.end(); ++child_it) + { + LLXMLNodePtr child_copy = child_it->second->deepCopy(); + std::string child_name; + child_copy->getAttributeString("name", child_name); + child_copy->setAttributeString("name", type_name + "." + child_name); + mElementNode->addChild(child_copy); + } + + LLXMLNodePtr element_declaration_node = mSchemaNode->createChild("xs:element", false); + element_declaration_node->createChild("name", true)->setStringValue(type_name); + element_declaration_node->createChild("type", true)->setStringValue(type_name); +} + +void LLXSDWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector* possible_values) +{ + name_stack_t non_empty_names; + std::string attribute_name; + for (name_stack_t::const_iterator it = stack.begin(); + it != stack.end(); + ++it) + { + const std::string& name = it->first; + if (!name.empty()) + { + non_empty_names.push_back(*it); + } + } + + for (name_stack_t::const_iterator it = non_empty_names.begin(); + it != non_empty_names.end(); + ++it) + { + if (!attribute_name.empty()) + { + attribute_name += "."; + } + attribute_name += it->first; + } + + // only flag non-nested attributes as mandatory, nested attributes have variant syntax + // that can't be properly constrained in XSD + // e.g. vs + bool attribute_mandatory = min_count == 1 && max_count == 1 && non_empty_names.size() == 1; + + // don't bother supporting "Multiple" params as xml attributes + if (max_count <= 1) + { + // add compound attribute to root node + addAttributeToSchema(mAttributeNode, attribute_name, type, attribute_mandatory, possible_values); + } + + // now generated nested elements for compound attributes + if (non_empty_names.size() > 1 && !attribute_mandatory) + { + std::string element_name; + + // traverse all but last element, leaving that as an attribute name + name_stack_t::const_iterator end_it = non_empty_names.end(); + end_it--; + + for (name_stack_t::const_iterator it = non_empty_names.begin(); + it != end_it; + ++it) + { + if (it != non_empty_names.begin()) + { + element_name += "."; + } + element_name += it->first; + } + + std::string short_attribute_name = non_empty_names.back().first; + + LLXMLNodePtr complex_type_node; + + // find existing element node here, starting at tail of child list + if (mElementNode->mChildren.notNull()) + { + for(LLXMLNodePtr element = mElementNode->mChildren->tail; + element.notNull(); + element = element->mPrev) + { + std::string name; + if(element->getAttributeString("name", name) && name == element_name) + { + complex_type_node = element->mChildren->head; + break; + } + } + } + //create complex_type node + // + // + // + // + // + if(complex_type_node.isNull()) + { + complex_type_node = mElementNode->createChild("xs:element", false); + + complex_type_node->createChild("minOccurs", true)->setIntValue(min_count); + complex_type_node->createChild("maxOccurs", true)->setIntValue(max_count); + complex_type_node->createChild("name", true)->setStringValue(element_name); + complex_type_node = complex_type_node->createChild("xs:complexType", false); + } + + addAttributeToSchema(complex_type_node, short_attribute_name, type, false, possible_values); + } +} + +void LLXSDWriter::addAttributeToSchema(LLXMLNodePtr type_declaration_node, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector* possible_values) +{ + if (!attribute_name.empty()) + { + LLXMLNodePtr new_enum_type_node; + if (possible_values != NULL) + { + // custom attribute type, for example + // + // + // + // + // + // + new_enum_type_node = new LLXMLNode("xs:simpleType", false); + + LLXMLNodePtr restriction_node = new_enum_type_node->createChild("xs:restriction", false); + restriction_node->createChild("base", true)->setStringValue("xs:string"); + + for (std::vector::const_iterator it = possible_values->begin(); + it != possible_values->end(); + ++it) + { + LLXMLNodePtr enum_node = restriction_node->createChild("xs:enumeration", false); + enum_node->createChild("value", true)->setStringValue(*it); + } + } + + string_set_t& attributes_written = mAttributesWritten[type_declaration_node]; + + string_set_t::iterator found_it = attributes_written.lower_bound(attribute_name); + + // attribute not yet declared + if (found_it == attributes_written.end() || attributes_written.key_comp()(attribute_name, *found_it)) + { + attributes_written.insert(found_it, attribute_name); + + LLXMLNodePtr attribute_node = type_declaration_node->createChild("xs:attribute", false); + + // attribute name + attribute_node->createChild("name", true)->setStringValue(attribute_name); + + if (new_enum_type_node.notNull()) + { + attribute_node->addChild(new_enum_type_node); + } + else + { + // simple attribute type + attribute_node->createChild("type", true)->setStringValue(type); + } + + // required or optional + attribute_node->createChild("use", true)->setStringValue(mandatory ? "required" : "optional"); + } + // attribute exists...handle collision of same name attributes with potentially different types + else + { + LLXMLNodePtr attribute_declaration; + if (type_declaration_node.notNull()) + { + for(LLXMLNodePtr node = type_declaration_node->mChildren->tail; + node.notNull(); + node = node->mPrev) + { + std::string name; + if (node->getAttributeString("name", name) && name == attribute_name) + { + attribute_declaration = node; + break; + } + } + } + + bool new_type_is_enum = new_enum_type_node.notNull(); + bool existing_type_is_enum = !attribute_declaration->hasAttribute("type"); + + // either type is enum, revert to string in collision + // don't bother to check for enum equivalence + if (new_type_is_enum || existing_type_is_enum) + { + if (attribute_declaration->hasAttribute("type")) + { + attribute_declaration->setAttributeString("type", "xs:string"); + } + else + { + attribute_declaration->createChild("type", true)->setStringValue("xs:string"); + } + attribute_declaration->deleteChildren("xs:simpleType"); + } + else + { + // check for collision of different standard types + std::string existing_type; + attribute_declaration->getAttributeString("type", existing_type); + // if current type is not the same as the new type, revert to strnig + if (existing_type != type) + { + // ...than use most general type, string + attribute_declaration->setAttributeString("type", "string"); + } + } + } + } +} + +// +// LLXUIXSDWriter +// +void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& path, const LLInitParam::BaseBlock& block) +{ + std::string file_name(path); + file_name += type_name + ".xsd"; + LLXMLNodePtr root_nodep = new LLXMLNode(); + + LLXSDWriter::writeXSD(type_name, root_nodep, block, "http://www.lindenlab.com/xui"); + + // add includes for all possible children + const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); + + // add include declarations for all valid children + for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); + it != widget_registryp->currentRegistrar().endItems(); + ++it) + { + std::string widget_name = it->first; + if (widget_name == type_name) + { + continue; + } + LLXMLNodePtr nodep = new LLXMLNode("xs:include", false); + nodep->createChild("schemaLocation", true)->setStringValue(widget_name + ".xsd"); + + // add to front of schema + mSchemaNode->addChild(nodep, mSchemaNode); + } + + // add choices for valid children + if (widget_registryp) + { + for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); + it != widget_registryp->currentRegistrar().endItems(); + ++it) + { + std::string widget_name = it->first; + // + LLXMLNodePtr widget_node = mElementNode->createChild("xs:element", false); + widget_node->createChild("name", true)->setStringValue(widget_name); + widget_node->createChild("type", true)->setStringValue(widget_name); + } + } + + LLFILE* xsd_file = LLFile::fopen(file_name.c_str(), "w"); + LLXMLNode::writeHeaderToFile(xsd_file); + root_nodep->writeToFile(xsd_file); + fclose(xsd_file); +} // // LLXUIParser @@ -510,142 +820,6 @@ void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, bool } } -void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block) -{ - mLastWriteGeneration = -1; - mWriteRootNode = node; - block.serializeBlock(*this, Parser::name_stack_t(), diff_block); -} - -// go from a stack of names to a specific XML node -LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack) -{ - name_stack_t name_stack; - - for (name_stack_t::const_iterator it = stack.begin(); - it != stack.end(); - ++it) - { - if (!it->first.empty()) - { - name_stack.push_back(*it); - } - } - - if (name_stack.empty() || mWriteRootNode.isNull()) return NULL; - - std::string attribute_name = name_stack.front().first; - - // heuristic to make font always attribute of parent node - bool is_font = (attribute_name == "font"); - // XML spec says that attributes have their whitespace normalized - // on parse: http://www.w3.org/TR/REC-xml/#AVNormalize - // Therefore text-oriented widgets that might have carriage returns - // have their values serialized as text contents, not the - // initial_value attribute. JC - if (attribute_name == "initial_value") - { - const char* root_node_name = mWriteRootNode->getName()->mString; - if (!strcmp(root_node_name, "text") // LLTextBox - || !strcmp(root_node_name, "text_editor") - || !strcmp(root_node_name, "line_editor")) // for consistency - { - // writeStringValue will write to this node - return mWriteRootNode; - } - } - - for (name_stack_t::const_iterator it = ++name_stack.begin(); - it != name_stack.end(); - ++it) - { - attribute_name += "."; - attribute_name += it->first; - } - - // *NOTE: elements for translation need to have whitespace - // preserved like "initial_value" above, however, the node - // becomes an attribute of the containing floater or panel. - // Because all elements must have a "name" attribute, and - // "name" is parsed first, just put the value into the last written - // child. - if (attribute_name == "string.value") - { - // The caller of will shortly call writeStringValue(), which sets - // this node's type to string, but we don't want to export type="string". - // Set the default for this node to suppress the export. - static LLXMLNodePtr default_node; - if (default_node.isNull()) - { - default_node = new LLXMLNode(); - // Force the node to have a string type - default_node->setStringValue( std::string() ); - } - mLastWrittenChild->setDefault(default_node); - // mLastWrittenChild is the "string" node part of "string.value", - // so the caller will call writeStringValue() into that node, - // setting the node text contents. - return mLastWrittenChild; - } - - LLXMLNodePtr attribute_node; - - const char* attribute_cstr = attribute_name.c_str(); - if (name_stack.size() != 1 - && !is_font) - { - std::string child_node_name(mWriteRootNode->getName()->mString); - child_node_name += "."; - child_node_name += name_stack.front().first; - - LLXMLNodePtr child_node; - - if (mLastWriteGeneration == name_stack.front().second) - { - child_node = mLastWrittenChild; - } - else - { - mLastWriteGeneration = name_stack.front().second; - child_node = mWriteRootNode->createChild(child_node_name.c_str(), false); - } - - mLastWrittenChild = child_node; - - name_stack_t::const_iterator it = ++name_stack.begin(); - std::string short_attribute_name(it->first); - - for (++it; - it != name_stack.end(); - ++it) - { - short_attribute_name += "."; - short_attribute_name += it->first; - } - - if (child_node->hasAttribute(short_attribute_name.c_str())) - { - llerrs << "Attribute " << short_attribute_name << " already exists!" << llendl; - } - - attribute_node = child_node->createChild(short_attribute_name.c_str(), true); - } - else - { - if (mWriteRootNode->hasAttribute(attribute_cstr)) - { - mWriteRootNode->getAttribute(attribute_cstr, attribute_node); - } - else - { - attribute_node = mWriteRootNode->createChild(attribute_name.c_str(), true); - } - } - - return attribute_node; -} - - bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLInitParam::BaseBlock& block) { typedef boost::tokenizer > tokenizer; @@ -665,8 +839,15 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLIn // child nodes are not necessarily valid parameters (could be a child widget) // so don't complain once we've recursed bool silent = mCurReadDepth > 0; - block.submitValue(mNameStack, *this, silent); - mNameStack.pop_back(); + if (!block.submitValue(mNameStack, *this, true)) + { + mNameStack.pop_back(); + block.submitValue(mNameStack, *this, silent); + } + else + { + mNameStack.pop_back(); + } } // then traverse children @@ -784,6 +965,62 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo return any_parsed; } +void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block) +{ + mWriteRootNode = node; + block.serializeBlock(*this, Parser::name_stack_t(), diff_block); + mOutNodes.clear(); +} + +// go from a stack of names to a specific XML node +LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack) +{ + name_stack_t name_stack; + for (name_stack_t::const_iterator it = stack.begin(); + it != stack.end(); + ++it) + { + if (!it->first.empty()) + { + name_stack.push_back(*it); + } + } + + LLXMLNodePtr out_node = mWriteRootNode; + + name_stack_t::const_iterator next_it = name_stack.begin(); + for (name_stack_t::const_iterator it = name_stack.begin(); + it != name_stack.end(); + it = next_it) + { + ++next_it; + if (it->first.empty()) + { + continue; + } + + out_nodes_t::iterator found_it = mOutNodes.lower_bound(it->second); + + // node with this name not yet written + if (found_it == mOutNodes.end() || mOutNodes.key_comp()(found_it->first, it->second)) + { + // make an attribute if we are the last element on the name stack + bool is_attribute = next_it == name_stack.end(); + LLXMLNodePtr new_node = new LLXMLNode(it->first.c_str(), is_attribute); + out_node->addChild(new_node); + mOutNodes.insert(found_it, std::make_pair(it->second, new_node)); + out_node = new_node; + } + else + { + out_node = found_it->second; + } + } + + return (out_node == mWriteRootNode ? LLXMLNodePtr(NULL) : out_node); +} + + bool LLXUIParser::readBoolValue(void* val_ptr) { S32 value; @@ -814,7 +1051,27 @@ bool LLXUIParser::writeStringValue(const void* val_ptr, const name_stack_t& stac LLXMLNodePtr node = getNode(stack); if (node.notNull()) { - node->setStringValue(*((std::string*)val_ptr)); + const std::string* string_val = reinterpret_cast(val_ptr); + if (string_val->find('\n') != std::string::npos + || string_val->size() > MAX_STRING_ATTRIBUTE_SIZE) + { + // don't write strings with newlines into attributes + std::string attribute_name = node->getName()->mString; + LLXMLNodePtr parent_node = node->mParent; + parent_node->deleteChild(node); + // write results in text contents of node + if (attribute_name == "value") + { + // "value" is implicit, just write to parent + node = parent_node; + } + else + { + // create a child that is not an attribute, but with same name + node = parent_node->createChild(attribute_name.c_str(), false); + } + } + node->setStringValue(*string_val); return true; } return false; @@ -1010,7 +1267,7 @@ bool LLXUIParser::writeUIColorValue(const void* val_ptr, const name_stack_t& sta LLUIColor color = *((LLUIColor*)val_ptr); //RN: don't write out the color that is represented by a function // rely on param block exporting to get the reference to the color settings - if (color.isUsingFunction()) return false; + if (color.isReference()) return false; node->setFloatValue(4, color.get().mV); return true; } @@ -1051,7 +1308,26 @@ bool LLXUIParser::writeSDValue(const void* val_ptr, const name_stack_t& stack) LLXMLNodePtr node = getNode(stack); if (node.notNull()) { - node->setStringValue(((LLSD*)val_ptr)->asString()); + std::string string_val = ((LLSD*)val_ptr)->asString(); + if (string_val.find('\n') != std::string::npos || string_val.size() > MAX_STRING_ATTRIBUTE_SIZE) + { + // don't write strings with newlines into attributes + std::string attribute_name = node->getName()->mString; + LLXMLNodePtr parent_node = node->mParent; + parent_node->deleteChild(node); + // write results in text contents of node + if (attribute_name == "value") + { + // "value" is implicit, just write to parent + node = parent_node; + } + else + { + node = parent_node->createChild(attribute_name.c_str(), false); + } + } + + node->setStringValue(string_val); return true; } return false; diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index b9c61b1fed..9dbe458bae 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -41,11 +41,42 @@ #include #include #include +#include class LLPanel; class LLFloater; class LLView; +class LLXSDWriter : public LLInitParam::Parser +{ + LOG_CLASS(LLXSDWriter); +public: + void writeXSD(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace); + + /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; } + + LLXSDWriter(); + +protected: + void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector* possible_values); + void addAttributeToSchema(LLXMLNodePtr nodep, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector* possible_values); + LLXMLNodePtr mAttributeNode; + LLXMLNodePtr mElementNode; + LLXMLNodePtr mSchemaNode; + + typedef std::set string_set_t; + typedef std::map attributes_map_t; + attributes_map_t mAttributesWritten; +}; + +// NOTE: DOES NOT WORK YET +// should support child widgets for XUI +class LLXUIXSDWriter : public LLXSDWriter +{ +public: + void writeXSD(const std::string& name, const std::string& path, const LLInitParam::BaseBlock& block); +}; + class LLXUIParser : public LLInitParam::Parser, public LLSingleton { LOG_CLASS(LLXUIParser); @@ -108,6 +139,9 @@ private: LLXMLNodePtr mCurReadNode; // Root of the widget XML sub-tree, for example, "line_editor" LLXMLNodePtr mWriteRootNode; + + typedef std::map out_nodes_t; + out_nodes_t mOutNodes; S32 mLastWriteGeneration; LLXMLNodePtr mLastWrittenChild; S32 mCurReadDepth; @@ -118,31 +152,7 @@ typedef boost::function widget_registry_t; -template -class LLWidgetRegistry : public LLRegistrySingleton -{ -public: - typedef LLRegistrySingleton super_t; - // local static instance for registering a particular widget - template - class Register : public super_t::StaticRegistrar - { - public: - // register with either the provided builder, or the generic templated builder - Register(const char* tag, LLWidgetCreatorFunc func = NULL); - }; - -protected: - LLWidgetRegistry() {} -}; - -class LLDefaultWidgetRegistry : public LLWidgetRegistry -{ -protected: - LLDefaultWidgetRegistry() {} - friend class LLSingleton; -}; - +// sort functor for typeid maps struct LLCompareTypeID { bool operator()(const std::type_info* lhs, const std::type_info* rhs) const @@ -151,17 +161,56 @@ struct LLCompareTypeID } }; +// lookup widget constructor funcs by widget name +template +class LLChildRegistry : public LLRegistrySingleton +{ +public: + typedef LLRegistrySingleton super_t; + // local static instance for registering a particular widget + template + class Register : public super_t::StaticRegistrar + { + public: + // register with either the provided builder, or the generic templated builder + Register(const char* tag, LLWidgetCreatorFunc func = NULL); + }; -class LLWidgetTemplateRegistry -: public LLRegistrySingleton +protected: + LLChildRegistry() {} +}; + +class LLDefaultChildRegistry : public LLChildRegistry +{ +protected: + LLDefaultChildRegistry(){} + friend class LLSingleton; +}; + +// lookup widget name by type +class LLWidgetNameRegistry +: public LLRegistrySingleton {}; -// function used to create new default widgets via LLView::getChild -typedef LLView* (*dummy_widget_creator_func_t)(const std::string&); +// lookup widget type by name +class LLWidgetTypeRegistry +: public LLRegistrySingleton +{}; -// used to register factory functions for default widget instances -class LLDummyWidgetRegistry -: public LLRegistrySingleton +// lookup factory functions for default widget instances by widget type +typedef LLView* (*dummy_widget_creator_func_t)(const std::string&); +class LLDefaultWidgetRegistry +: public LLRegistrySingleton +{}; + +// lookup function for generating empty param block by widget type +typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)(); +class LLDefaultParamBlockRegistry +: public LLRegistrySingleton +{}; + +class LLChildRegistryRegistry +: public LLRegistrySingleton {}; extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP; @@ -176,26 +225,26 @@ private: ~LLUICtrlFactory(); // only partial specialization allowed in inner classes, so use extra dummy parameter - template - class ParamDefaults : public LLSingleton > + template + class ParamDefaults : public LLSingleton > { public: ParamDefaults() { // recursively initialize from base class param block - ((typename T::base_block_t&)mPrototype).fillFrom(ParamDefaults::instance().get()); + ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults::instance().get()); // after initializing base classes, look up template file for this param block - std::string* param_block_tag = LLWidgetTemplateRegistry::instance().getValue(&typeid(T)); + std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK)); if (param_block_tag) { LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, mPrototype); } } - const T& get() { return mPrototype; } + const PARAM_BLOCK& get() { return mPrototype; } private: - T mPrototype; + PARAM_BLOCK mPrototype; }; // base case for recursion, there are NO base classes of LLInitParam::BaseBlock @@ -210,15 +259,15 @@ private: public: + // get default parameter block for widget of a specific type template - static const T& getDefaultParams() + static const typename T::Params& getDefaultParams() { //#pragma message("Generating ParamDefaults") - return ParamDefaults::instance().get(); + return ParamDefaults::instance().get(); } - void buildFloater(LLFloater* floaterp, const std::string &filename, BOOL open_floater = TRUE, LLXMLNodePtr output_node = NULL); - LLFloater* buildFloaterFromXML(const std::string& filename, BOOL open_floater = TRUE); + void buildFloater(LLFloater* floaterp, const std::string &filename, LLXMLNodePtr output_node); BOOL buildPanel(LLPanel* panelp, const std::string &filename, LLXMLNodePtr output_node = NULL); // Does what you want for LLFloaters and LLPanels @@ -252,12 +301,10 @@ public: return widget; } - LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, LLXMLNodePtr output_node, const widget_registry_t& ); + LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t&, LLXMLNodePtr output_node ); - static const widget_registry_t& getWidgetRegistry(LLView*); - template - static T* createFromFile(const std::string &filename, LLView *parent, LLXMLNodePtr output_node = NULL) + static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry, LLXMLNodePtr output_node = NULL) { //#pragma message("Generating LLUICtrlFactory::createFromFile") T* widget = NULL; @@ -283,7 +330,7 @@ public: goto fail; } - LLView* view = getInstance()->createFromXML(root_node, parent, filename, output_node, getWidgetRegistry(parent)); + LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, output_node); if (view) { widget = dynamic_cast(view); @@ -304,8 +351,8 @@ fail: template static T* getDefaultWidget(const std::string& name) { - dummy_widget_creator_func_t* dummy_func = LLDummyWidgetRegistry::instance().getValue(&typeid(T)); - return dynamic_cast((*dummy_func)(name)); + dummy_widget_creator_func_t* dummy_func = LLDefaultWidgetRegistry::instance().getValue(&typeid(T)); + return dummy_func ? dynamic_cast((*dummy_func)(name)) : NULL; } template @@ -317,23 +364,23 @@ fail: return create(params); } - template + template static T* defaultBuilder(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { LLFastTimer timer(FTM_WIDGET_SETUP); //#pragma message("Generating LLUICtrlFactory::defaultBuilder") - PARAM_BLOCK params(getDefaultParams()); + typename T::Params params(getDefaultParams()); LLXUIParser::instance().readXUI(node, params); if (output_node) { // We always want to output top-left coordinates - PARAM_BLOCK output_params(params); + typename T::Params output_params(params); T::setupParamsForExport(output_params, parent); // Export only the differences between this any default params - PARAM_BLOCK default_params(getDefaultParams()); + typename T::Params default_params(getDefaultParams()); output_node->setName(node->getName()->mString); LLXUIParser::instance().writeXUI( output_node, output_params, &default_params); @@ -361,8 +408,10 @@ fail: S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : -1; setCtrlParent(widget, parent, tab_group); } + + typedef typename T::child_registry_t registry_t; - createChildren(widget, node, output_node); + createChildren(widget, node, registry_t::instance(), output_node); if (!widget->postBuild()) { @@ -373,7 +422,7 @@ fail: return widget; } - static void createChildren(LLView* viewp, LLXMLNodePtr node, LLXMLNodePtr output_node = NULL); + static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL); static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root); @@ -395,20 +444,32 @@ private: std::vector mFileNames; }; +template +const LLInitParam::BaseBlock& getEmptyParamBlock() +{ + static typename T::Params params; + return params; +} + // this is here to make gcc happy with reference to LLUICtrlFactory template -template -LLWidgetRegistry::Register::Register(const char* tag, LLWidgetCreatorFunc func) -: LLWidgetRegistry::StaticRegistrar(tag, func.empty() ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder : func) +template +LLChildRegistry::Register::Register(const char* tag, LLWidgetCreatorFunc func) +: LLChildRegistry::StaticRegistrar(tag, func.empty() ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder : func) { + const std::type_info* widget_type_infop = &typeid(T); // associate parameter block type with template .xml file - LLWidgetTemplateRegistry::instance().defaultRegistrar().add(&typeid(PARAM_BLOCK), tag); + LLWidgetNameRegistry ::instance().defaultRegistrar().add(&typeid(typename T::Params), tag); // associate widget type with factory function - LLDummyWidgetRegistry::instance().defaultRegistrar().add(&typeid(T), &LLUICtrlFactory::createDefaultWidget); + LLDefaultWidgetRegistry::instance().defaultRegistrar().add(widget_type_infop, &LLUICtrlFactory::createDefaultWidget); + LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type_infop); + LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type_infop, &getEmptyParamBlock); + typedef typename T::child_registry_t registry_t; + LLChildRegistryRegistry::instance().defaultRegistrar().add(widget_type_infop, registry_t::instance()); } -typedef boost::function LLPannelClassCreatorFunc; +typedef boost::function LLPanelClassCreatorFunc; // local static instance for registering a particular panel class @@ -417,15 +478,15 @@ class LLRegisterPanelClass { public: // reigister with either the provided builder, or the generic templated builder - void addPanelClass(const std::string& tag,LLPannelClassCreatorFunc func) + void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func) { - mPannelClassesNames[tag] = func; + mPanelClassesNames[tag] = func; } LLPanel* createPanelClass(const std::string& tag) { - param_name_map_t::iterator iT = mPannelClassesNames.find(tag); - if(iT == mPannelClassesNames.end()) + param_name_map_t::iterator iT = mPanelClassesNames.find(tag); + if(iT == mPanelClassesNames.end()) return 0; return iT->second(); } @@ -437,9 +498,9 @@ public: } private: - typedef std::map< std::string, LLPannelClassCreatorFunc> param_name_map_t; + typedef std::map< std::string, LLPanelClassCreatorFunc> param_name_map_t; - param_name_map_t mPannelClassesNames; + param_name_map_t mPanelClassesNames; }; diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp index 8e0de0cb0c..ab0d65e731 100644 --- a/indra/llui/lluiimage.cpp +++ b/indra/llui/lluiimage.cpp @@ -39,7 +39,7 @@ #include "lluiimage.h" #include "llui.h" -LLUIImage::LLUIImage(const std::string& name, LLPointer image) : +LLUIImage::LLUIImage(const std::string& name, LLPointer image) : mName(name), mImage(image), mScaleRegion(0.f, 1.f, 1.f, 0.f), @@ -74,7 +74,7 @@ void LLUIImage::setScaleRegion(const LLRectf& region) //TODO: move drawing implementation inside class void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const { - gl_draw_image(x, y, mImage, color, mClipRegion); + gl_draw_scaled_image(x, y, getWidth(), getHeight(), mImage, color, mClipRegion); } void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h index e35026cd3d..4ec24e98dc 100644 --- a/indra/llui/lluiimage.h +++ b/indra/llui/lluiimage.h @@ -33,26 +33,28 @@ #ifndef LL_LLUIIMAGE_H #define LL_LLUIIMAGE_H -//#include "llgl.h" -#include "llimagegl.h" +#include "v4color.h" +#include "llpointer.h" +#include "llrefcount.h" #include "llrefcount.h" #include "llrect.h" #include #include "llinitparam.h" +#include "lltexture.h" extern const LLColor4 UI_VERTEX_COLOR; class LLUIImage : public LLRefCount { public: - LLUIImage(const std::string& name, LLPointer image); + LLUIImage(const std::string& name, LLPointer image); virtual ~LLUIImage(); void setClipRegion(const LLRectf& region); void setScaleRegion(const LLRectf& region); - LLPointer getImage() { return mImage; } - const LLPointer& getImage() const { return mImage; } + LLPointer getImage() { return mImage; } + const LLPointer& getImage() const { return mImage; } void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const; void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const; @@ -60,11 +62,11 @@ public: void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const; void drawSolid(const LLRect& rect, const LLColor4& color) const { drawSolid(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); } - void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, mImage->getWidth(0), mImage->getHeight(0), color); } + void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, getWidth(), getHeight(), color); } void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const; void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); } - void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, mImage->getWidth(0), mImage->getHeight(0), color, border_width); } + void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); } const std::string& getName() const { return mName; } @@ -79,7 +81,7 @@ protected: std::string mName; LLRectf mScaleRegion; LLRectf mClipRegion; - LLPointer mImage; + LLPointer mImage; BOOL mUniformScaling; BOOL mNoClip; }; @@ -95,8 +97,8 @@ namespace LLInitParam public: Optional name; - TypedParam(BlockDescriptor& descriptor, const char* name, super_t::value_assignment_t value, ParamDescriptor::validation_func_t func) - : super_t(descriptor, name, value, func) + TypedParam(BlockDescriptor& descriptor, const char* name, super_t::value_assignment_t value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count) { } diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index d225ad2767..d94472a8e5 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -99,10 +99,15 @@ LLView::Params::Params() left_delta("left_delta", S32_MAX), center_horiz("center_horiz", false), center_vert("center_vert", false), - serializable("", false), + from_xui("from_xui", false), user_resize("user_resize"), auto_resize("auto_resize"), - needs_translate("translate") + needs_translate("translate"), + xmlns("xmlns"), + xmlns_xsi("xmlns:xsi"), + xsi_schemaLocation("xsi:schemaLocation"), + xsi_type("xsi:type") + { addSynonym(rect, ""); } @@ -111,7 +116,7 @@ LLView::LLView(const LLView::Params& p) : mName(p.name), mParentView(NULL), mReshapeFlags(FOLLOWS_NONE), - mSaveToXML(p.serializable), + mSaveToXML(p.from_xui), mIsFocusRoot(FALSE), mLastVisible(FALSE), mNextInsertionOrdinal(0), @@ -396,32 +401,28 @@ bool LLCompareByTabOrder::operator() (const LLView* const a, const LLView* const return (a_score == b_score) ? a < b : a_score < b_score; } -BOOL LLView::isInVisibleChain() const +bool LLView::trueToRoot(const boost::function& predicate) const { const LLView* cur_view = this; while(cur_view) { - if (!cur_view->getVisible()) + if(!predicate(cur_view)) { - return FALSE; + return false; } cur_view = cur_view->getParent(); } - return TRUE; + return true; +} + +BOOL LLView::isInVisibleChain() const +{ + return trueToRoot(&LLView::getVisible); } BOOL LLView::isInEnabledChain() const { - const LLView* cur_view = this; - while(cur_view) - { - if (!cur_view->getEnabled()) - { - return FALSE; - } - cur_view = cur_view->getParent(); - } - return TRUE; + return trueToRoot(&LLView::getEnabled); } // virtual @@ -602,14 +603,14 @@ void LLView::setVisible(BOOL visible) if (!getParent() || getParent()->isInVisibleChain()) { // tell all children of this view that the visibility may have changed - onVisibilityChange( visible ); + handleVisibilityChange( visible ); } updateBoundingRect(); } } // virtual -void LLView::onVisibilityChange ( BOOL new_visibility ) +void LLView::handleVisibilityChange ( BOOL new_visibility ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { @@ -617,7 +618,7 @@ void LLView::onVisibilityChange ( BOOL new_visibility ) // only views that are themselves visible will have their overall visibility affected by their ancestors if (viewp->getVisible()) { - viewp->onVisibilityChange ( new_visibility ); + viewp->handleVisibilityChange ( new_visibility ); } } } @@ -738,12 +739,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_s msg = tool_tip; // Convert rect local to screen coordinates - localPointToScreen( - 0, 0, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - mRect.getWidth(), mRect.getHeight(), - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); + *sticky_rect_screen = calcScreenRect(); } // don't allow any siblings to handle this event // even if we don't have a tooltip @@ -1325,13 +1321,6 @@ void LLView::draw() LLRect rootRect = getRootView()->getRect(); LLRect screenRect; - // draw focused control on top of everything else - LLView* focus_view = gFocusMgr.getKeyboardFocus(); - if (focus_view && focus_view->getParent() != this) - { - focus_view = NULL; - } - ++sDepth; for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend();) // ++child_iter) @@ -1339,7 +1328,7 @@ void LLView::draw() child_list_reverse_iter_t child = child_iter++; LLView *viewp = *child; - if (viewp->getVisible() && viewp != focus_view && viewp->getRect().isValid()) + if (viewp->getVisible() && viewp->getRect().isValid()) { // Only draw views that are within the root view localRectToScreen(viewp->getRect(),&screenRect); @@ -1357,11 +1346,6 @@ void LLView::draw() } --sDepth; - - if (focus_view && focus_view->getVisible()) - { - drawChild(focus_view); - } } gGL.getTexUnit(0)->disable(); @@ -1398,7 +1382,7 @@ void LLView::drawDebugRect() } else { - static LLUICachedControl scroll_highlighted_color ("ScrollHighlightedColor", *(new LLColor4)); + static LLUIColor scroll_highlighted_color = LLUIColorTable::instance().getColor("ScrollHighlightedColor"); border_color = scroll_highlighted_color; } } @@ -2303,13 +2287,6 @@ LLControlVariable *LLView::findControl(const std::string& name) return control_group.getControl(name); } -const widget_registry_t& LLView::getChildRegistry() const -{ - static widget_registry_t empty_registry; - return empty_registry; -} - - const S32 FLOATER_H_MARGIN = 15; const S32 MIN_WIDGET_HEIGHT = 10; const S32 VPAD = 4; @@ -2430,7 +2407,7 @@ void LLView::setupParams(LLView::Params& p, LLView* parent) const S32 VPAD = 4; const S32 MIN_WIDGET_HEIGHT = 10; - p.serializable(true); + p.from_xui(true); // *NOTE: This will confuse export of floater/panel coordinates unless // the default is also "topleft". JC diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 422f62f602..ee49276139 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -93,7 +93,7 @@ virtual void setEnabled(BOOL enabled) { mEnabled = enabled; } LLCheckBoxCtrl, LLComboBox, LLLineEditor, LLMenuGL, LLRadioGroup, etc virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ) { return FALSE; } LLUICtrl, LLButton, LLCheckBoxCtrl, LLLineEditor, LLMenuGL, LLSliderCtrl -virtual void onVisibilityChange ( BOOL curVisibilityIn ); +virtual void handleVisibilityChange ( BOOL curVisibilityIn ); LLMenuGL virtual LLRect getSnapRect() const { return mRect; } *TODO: Make non virtual LLFloater @@ -138,6 +138,9 @@ virtual BOOL handleUnicodeCharHere(llwchar uni_char); * */ +class LLViewWidgetRegistry : public LLChildRegistry +{}; + class LLView : public LLMouseHandler, public LLMortician { public: @@ -157,15 +160,16 @@ public: Mandatory name; Optional enabled, - visible; - Optional mouse_opaque; - Optional use_bounding_rect; + visible, + mouse_opaque, + use_bounding_rect; + Optional tab_group, default_tab_group; Optional tool_tip; Optional sound_flags; - Optional serializable; + Optional from_xui; Optional follows; Optional hover_cursor; @@ -192,10 +196,17 @@ public: //FIXME: get parent context involved in parsing traversal Ignored user_resize, auto_resize, - needs_translate; + needs_translate, + xmlns, + xmlns_xsi, + xsi_schemaLocation, + xsi_type; Params(); }; + + typedef LLViewWidgetRegistry child_registry_t; + void initFromParams(const LLView::Params&); protected: @@ -310,6 +321,7 @@ public: S32 getDefaultTabGroup() const { return mDefaultTabGroup; } S32 getLastTabGroup() { return mLastTabGroup; } + bool trueToRoot(const boost::function& predicate) const; BOOL isInVisibleChain() const; BOOL isInEnabledChain() const; @@ -337,7 +349,7 @@ public: virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); - virtual void onVisibilityChange ( BOOL curVisibilityIn ); + virtual void handleVisibilityChange ( BOOL new_visibility ); void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); } void popVisible() { setVisible(mLastVisible); } @@ -496,9 +508,6 @@ public: return dynamic_cast(found_it->second); } - // determines allowable children when parsing XUI - virtual const widget_registry_t& getChildRegistry() const; - ////////////////////////////////////////////// // statics ////////////////////////////////////////////// @@ -647,6 +656,9 @@ template T* LLView::getChild(const std::string& name, BOOL recurse, BO if (result) { + // *NOTE: You cannot call mFoo = getChild("bar") + // in a floater or panel constructor. The widgets will not + // be ready. Instead, put it in postBuild(). llwarns << "Making dummy " << typeid(T).name() << " named \"" << name << "\" in " << getName() << llendl; } else diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp index a5b09671bb..860aa3302e 100644 --- a/indra/llui/llviewborder.cpp +++ b/indra/llui/llviewborder.cpp @@ -35,7 +35,7 @@ #include "llfocusmgr.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register r("view_border"); +static LLDefaultChildRegistry::Register r("view_border"); void LLViewBorder::BevelValues::declareValues() { @@ -52,7 +52,7 @@ void LLViewBorder::StyleValues::declareValues() } LLViewBorder::Params::Params() -: bevel_type("bevel_style", BEVEL_OUT), +: bevel_style("bevel_style", BEVEL_OUT), render_style("border_style", STYLE_LINE), border_thickness("border_thickness"), highlight_light_color("highlight_light_color"), @@ -60,6 +60,8 @@ LLViewBorder::Params::Params() shadow_light_color("shadow_light_color"), shadow_dark_color("shadow_dark_color") { + addSynonym(border_thickness, "thickness"); + addSynonym(render_style, "style"); name = "view_border"; mouse_opaque = false; follows.flags = FOLLOWS_ALL; @@ -75,7 +77,7 @@ LLViewBorder::LLViewBorder(const LLViewBorder::Params& p) mHighlightDark(p.highlight_dark_color()), mShadowLight(p.shadow_light_color()), mShadowDark(p.shadow_dark_color()), - mBevel(p.bevel_type), + mBevel(p.bevel_style), mStyle(p.render_style) {} diff --git a/indra/llui/llviewborder.h b/indra/llui/llviewborder.h index 37e13fb181..92fd569325 100644 --- a/indra/llui/llviewborder.h +++ b/indra/llui/llviewborder.h @@ -55,7 +55,7 @@ public: struct Params : public LLInitParam::Block { - Optional bevel_type; + Optional bevel_style; Optional render_style; Optional border_thickness; diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index 54af8b43ad..0c65047d4d 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -293,11 +293,7 @@ const std::string& LLDir::getDefaultSkinDir() const const std::string LLDir::getSkinBaseDir() const { - std::string dir = getAppRODataDir(); - dir += mDirDelimiter; - dir += "skins"; - - return dir; + return mSkinBaseDir; } @@ -385,9 +381,7 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd break; case LL_PATH_SKINS: - prefix = getAppRODataDir(); - prefix += mDirDelimiter; - prefix += "skins"; + prefix = getSkinBaseDir(); break; case LL_PATH_LOCAL_ASSETS: @@ -612,9 +606,7 @@ void LLDir::setPerAccountChatLogsDir(const std::string &first, const std::string void LLDir::setSkinFolder(const std::string &skin_folder) { - mSkinDir = getAppRODataDir(); - mSkinDir += mDirDelimiter; - mSkinDir += "skins"; + mSkinDir = getSkinBaseDir(); mSkinDir += mDirDelimiter; mSkinDir += skin_folder; @@ -628,9 +620,7 @@ void LLDir::setSkinFolder(const std::string &skin_folder) // base skin which is used as fallback for all skinned files // e.g. c:\program files\secondlife\skins\default - mDefaultSkinDir = getAppRODataDir(); - mDefaultSkinDir += mDirDelimiter; - mDefaultSkinDir += "skins"; + mDefaultSkinDir = getSkinBaseDir(); mDefaultSkinDir += mDirDelimiter; mDefaultSkinDir += "default"; } @@ -675,6 +665,7 @@ void LLDir::dumpCurrentDirectories() LL_DEBUGS2("AppInit","Directories") << " LindenUserDir: " << getLindenUserDir() << LL_ENDL; LL_DEBUGS2("AppInit","Directories") << " TempDir: " << getTempDir() << LL_ENDL; LL_DEBUGS2("AppInit","Directories") << " CAFile: " << getCAFile() << LL_ENDL; + LL_DEBUGS2("AppInit","Directories") << " SkinBaseDir: " << getSkinBaseDir() << LL_ENDL; LL_DEBUGS2("AppInit","Directories") << " SkinDir: " << getSkinDir() << LL_ENDL; #if LL_LIBXUL_ENABLED diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h index a33f7a2914..a1f9df007d 100644 --- a/indra/llvfs/lldir.h +++ b/indra/llvfs/lldir.h @@ -161,6 +161,7 @@ protected: std::string mDefaultCacheDir; // default cache diretory std::string mOSCacheDir; // operating system cache dir std::string mDirDelimiter; + std::string mSkinBaseDir; // Base for skins paths. std::string mSkinDir; // Location for current skin info. std::string mDefaultSkinDir; // Location for default skin info. std::string mUserSkinDir; // Location for user-modified skin info. diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp index 2d724f0f9f..d7a0dc8528 100644 --- a/indra/llvfs/lldir_linux.cpp +++ b/indra/llvfs/lldir_linux.cpp @@ -99,6 +99,7 @@ LLDir_Linux::LLDir_Linux() #else mAppRODataDir = tmp_str; #endif + mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; mOSUserDir = getCurrentUserHome(tmp_str); mOSUserAppDir = ""; mLindenUserDir = tmp_str; @@ -146,6 +147,7 @@ void LLDir_Linux::initAppDirs(const std::string &app_name, if (!app_read_only_data_dir.empty()) { mAppRODataDir = app_read_only_data_dir; + mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; } mAppName = app_name; diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp index 04577bfc3b..7f703464bc 100644 --- a/indra/llvfs/lldir_mac.cpp +++ b/indra/llvfs/lldir_mac.cpp @@ -142,9 +142,30 @@ LLDir_Mac::LLDir_Mac() CFURLRefToLLString(executableParentURLRef, mExecutableDir, true); // mAppRODataDir - CFURLRef resourcesURLRef = CFBundleCopyResourcesDirectoryURL(mainBundleRef); + + CFURLRef resourcesURLRef = CFBundleCopyResourcesDirectoryURL(mainBundleRef); CFURLRefToLLString(resourcesURLRef, mAppRODataDir, true); + // *NOTE: When running in a dev tree, use the copy of + // skins in indra/newview/ rather than in the application bundle. This + // mirrors Windows dev environment behavior and allows direct checkin + // of edited skins/xui files. JC + + U32 indra_pos = mExecutableDir.find("/indra"); + if (indra_pos != std::string::npos) + { + // ...we're in a dev checkout + mSkinBaseDir = mExecutableDir.substr(0, indra_pos) + + "/indra/newview/skins"; + llinfos << "Running in dev checkout with mSkinBaseDir " + << mSkinBaseDir << llendl; + } + else + { + // ...normal installation running + mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; + } + // mOSUserDir error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, true, &fileRef); if (error == noErr) @@ -210,6 +231,7 @@ void LLDir_Mac::initAppDirs(const std::string &app_name, if (!app_read_only_data_dir.empty()) { mAppRODataDir = app_read_only_data_dir; + mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; } mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem"); diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp index 1fdd31c635..da80a95922 100644 --- a/indra/llvfs/lldir_win32.cpp +++ b/indra/llvfs/lldir_win32.cpp @@ -130,6 +130,7 @@ LLDir_Win32::LLDir_Win32() else mAppRODataDir = mExecutableDir; + mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; // Build the default cache directory mDefaultCacheDir = buildSLOSCacheDir(); @@ -158,6 +159,7 @@ void LLDir_Win32::initAppDirs(const std::string &app_name, if (!app_read_only_data_dir.empty()) { mAppRODataDir = app_read_only_data_dir; + mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; } mAppName = app_name; mOSUserAppDir = mOSUserDir; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 3c203d9f5c..bf40353410 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -1940,11 +1940,6 @@ void LLWindowSDL::setCursor(ECursorType cursor) } } -ECursorType LLWindowSDL::getCursor() -{ - return mCurrentCursor; -} - void LLWindowSDL::initCursors() { int i; diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 1e4dffd7a6..dcf41291ec 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -77,7 +77,6 @@ public: /*virtual*/ void hideCursorUntilMouseMove(); /*virtual*/ BOOL isCursorHidden(); /*virtual*/ void setCursor(ECursorType cursor); - /*virtual*/ ECursorType getCursor(); /*virtual*/ void captureMouse(); /*virtual*/ void releaseMouse(); /*virtual*/ void setMouseClipping( BOOL b ); diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 37939a0908..0864940866 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -56,7 +56,16 @@ #endif #include + +#if LL_WINDOWS + #pragma warning (push) + #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch + #pragma warning (disable : 4264) +#endif #include +#if LL_WINDOWS + #pragma warning (pop) +#endif #if LL_WINDOWS # if (_MSC_VER >= 1300 && _MSC_VER < 1400) diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index e97aa55190..07cc612a0a 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -149,7 +149,7 @@ LLXMLNodePtr LLXMLNode::deepCopy() if (mChildren.notNull()) { for (LLXMLChildList::iterator iter = mChildren->map.begin(); - iter != mChildren->map.end(); ++iter) + iter != mChildren->map.end(); ++iter) { newnode->addChild(iter->second->deepCopy()); } @@ -302,6 +302,22 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child) mChildren->tail = new_child; } } + // if after_child == parent, then put new_child at beginning + else if (after_child == this) + { + // add to front of list + new_child->mNext = mChildren->head; + if (mChildren->head) + { + mChildren->head->mPrev = new_child; + mChildren->head = new_child; + } + else // no children + { + mChildren->head = new_child; + mChildren->tail = new_child; + } + } else { if (after_child->mNext.notNull()) @@ -906,7 +922,7 @@ void LLXMLNode::writeHeaderToFile(LLFILE *out_file) fprintf(out_file, "\n"); } -void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent) +void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent, bool use_type_decorations) { if (isFullyDefault()) { @@ -915,7 +931,7 @@ void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent) } std::ostringstream ostream; - writeToOstream(ostream, indent); + writeToOstream(ostream, indent, use_type_decorations); std::string outstring = ostream.str(); size_t written = fwrite(outstring.c_str(), 1, outstring.length(), out_file); if (written != outstring.length()) @@ -924,7 +940,7 @@ void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent) } } -void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& indent) +void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& indent, bool use_type_decorations) { if (isFullyDefault()) { @@ -940,77 +956,80 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i // stream the name output_stream << indent << "<" << mName->mString << "\n"; - // ID - if (mID != "") + if (use_type_decorations) { - output_stream << indent << " id=\"" << mID << "\"\n"; - } - - // Type - if (!has_default_type) - { - switch (mType) + // ID + if (mID != "") { - case TYPE_BOOLEAN: - output_stream << indent << " type=\"boolean\"\n"; - break; - case TYPE_INTEGER: - output_stream << indent << " type=\"integer\"\n"; - break; - case TYPE_FLOAT: - output_stream << indent << " type=\"float\"\n"; - break; - case TYPE_STRING: - output_stream << indent << " type=\"string\"\n"; - break; - case TYPE_UUID: - output_stream << indent << " type=\"uuid\"\n"; - break; - case TYPE_NODEREF: - output_stream << indent << " type=\"noderef\"\n"; - break; - default: - // default on switch(enum) eliminates a warning on linux - break; - }; - } + output_stream << indent << " id=\"" << mID << "\"\n"; + } - // Encoding - if (!has_default_encoding) - { - switch (mEncoding) + // Type + if (!has_default_type) { - case ENCODING_DECIMAL: - output_stream << indent << " encoding=\"decimal\"\n"; - break; - case ENCODING_HEX: - output_stream << indent << " encoding=\"hex\"\n"; - break; - /*case ENCODING_BASE32: - output_stream << indent << " encoding=\"base32\"\n"; - break;*/ - default: - // default on switch(enum) eliminates a warning on linux - break; - }; - } + switch (mType) + { + case TYPE_BOOLEAN: + output_stream << indent << " type=\"boolean\"\n"; + break; + case TYPE_INTEGER: + output_stream << indent << " type=\"integer\"\n"; + break; + case TYPE_FLOAT: + output_stream << indent << " type=\"float\"\n"; + break; + case TYPE_STRING: + output_stream << indent << " type=\"string\"\n"; + break; + case TYPE_UUID: + output_stream << indent << " type=\"uuid\"\n"; + break; + case TYPE_NODEREF: + output_stream << indent << " type=\"noderef\"\n"; + break; + default: + // default on switch(enum) eliminates a warning on linux + break; + }; + } - // Precision - if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT)) - { - output_stream << indent << " precision=\"" << mPrecision << "\"\n"; - } + // Encoding + if (!has_default_encoding) + { + switch (mEncoding) + { + case ENCODING_DECIMAL: + output_stream << indent << " encoding=\"decimal\"\n"; + break; + case ENCODING_HEX: + output_stream << indent << " encoding=\"hex\"\n"; + break; + /*case ENCODING_BASE32: + output_stream << indent << " encoding=\"base32\"\n"; + break;*/ + default: + // default on switch(enum) eliminates a warning on linux + break; + }; + } - // Version - if (mVersionMajor > 0 || mVersionMinor > 0) - { - output_stream << indent << " version=\"" << mVersionMajor << "." << mVersionMinor << "\"\n"; - } + // Precision + if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT)) + { + output_stream << indent << " precision=\"" << mPrecision << "\"\n"; + } - // Array length - if (!has_default_length && mLength > 0) - { - output_stream << indent << " length=\"" << mLength << "\"\n"; + // Version + if (mVersionMajor > 0 || mVersionMinor > 0) + { + output_stream << indent << " version=\"" << mVersionMajor << "." << mVersionMinor << "\"\n"; + } + + // Array length + if (!has_default_length && mLength > 0) + { + output_stream << indent << " length=\"" << mLength << "\"\n"; + } } { @@ -1023,12 +1042,13 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i if (child->mDefault.isNull() || child->mDefault->mValue != child->mValue) { std::string attr = child->mName->mString; - if (attr == "id" || - attr == "type" || - attr == "encoding" || - attr == "precision" || - attr == "version" || - attr == "length") + if (use_type_decorations + && (attr == "id" || + attr == "type" || + attr == "encoding" || + attr == "precision" || + attr == "version" || + attr == "length")) { continue; // skip built-in attributes } @@ -1058,7 +1078,7 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i std::string next_indent = indent + " "; for (LLXMLNode* child = getFirstChild(); child; child = child->getNextSibling()) { - child->writeToOstream(output_stream, next_indent); + child->writeToOstream(output_stream, next_indent, use_type_decorations); } } if (!mValue.empty()) diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index c983a14410..818d774f73 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -48,6 +48,7 @@ #include "llthread.h" // LLThreadSafeRefCount #include "llstring.h" #include "llstringtable.h" +#include "llfile.h" class LLVector3; @@ -164,8 +165,8 @@ public: // Write XML to file with one attribute per line. // XML escapes values as they are written. - void writeToFile(LLFILE *out_file, const std::string& indent = std::string()); - void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string()); + void writeToFile(LLFILE *out_file, const std::string& indent = std::string(), bool use_type_decorations=true); + void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string(), bool use_type_decorations=true); // Utility void findName(const std::string& name, LLXMLNodeList &results); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index a908b058f0..4a9a715b34 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -61,7 +61,8 @@ include_directories( ) set(viewer_SOURCE_FILES - llaccordionpanel.cpp + llaccordionctrltab.cpp + llaccordionctrl.cpp llagent.cpp llagentlistener.cpp llagentaccess.cpp @@ -75,24 +76,26 @@ set(viewer_SOURCE_FILES llassetuploadresponders.cpp llassetuploadqueue.cpp llaudiosourcevo.cpp + llavataractions.cpp llavatariconctrl.cpp llavatarlist.cpp llavatarlistitem.cpp llavatarpropertiesprocessor.cpp - llbbox.cpp llbottomtray.cpp llbox.cpp + llbreadcrumbview.cpp llcallbacklist.cpp llcallingcard.cpp llcapabilitylistener.cpp llcaphttpsender.cpp + llchannelmanager.cpp llchatbar.cpp - llchathistoryscroll.cpp + llchatitemscontainerctrl.cpp + llchatmsgbox.cpp llchiclet.cpp llclassifiedinfo.cpp llclassifiedstatsresponder.cpp llcloud.cpp - llcollapsiblectrl.cpp llcolorswatch.cpp llcommandhandler.cpp llcommandlineparser.cpp @@ -104,7 +107,6 @@ set(viewer_SOURCE_FILES lldebugview.cpp lldelayedgestureerror.cpp lldirpicker.cpp - lldraggerbar.cpp lldrawable.cpp lldrawpoolalpha.cpp lldrawpoolavatar.cpp @@ -129,13 +131,13 @@ set(viewer_SOURCE_FILES llfeaturemanager.cpp llfilepicker.cpp llfirstuse.cpp + llfirsttimetipmanager.cpp llflexibleobject.cpp llfloaterabout.cpp llfloateractivespeakers.cpp llfloateraddlandmark.cpp llfloateranimpreview.cpp llfloaterauction.cpp - llfloateravatarinfo.cpp llfloateravatarpicker.cpp llfloateravatartextures.cpp llfloaterbeacons.cpp @@ -150,13 +152,12 @@ set(viewer_SOURCE_FILES llfloatercamera.cpp llfloaterchat.cpp llfloaterchatterbox.cpp - llfloaterclassified.cpp llfloatercolorpicker.cpp llfloatercustomize.cpp llfloaterdaycycle.cpp llfloaterdirectory.cpp llfloaterenvsettings.cpp - llfloaterevent.cpp + llfloaterfirsttimetip.cpp llfloaterfriends.cpp llfloaterfonttest.cpp llfloatergesture.cpp @@ -173,6 +174,7 @@ set(viewer_SOURCE_FILES llfloaterhud.cpp llfloaterimagepreview.cpp llfloaterinspect.cpp + llfloaterinventory.cpp llfloaterjoystick.cpp llfloaterlagmeter.cpp llfloaterland.cpp @@ -183,7 +185,6 @@ set(viewer_SOURCE_FILES llfloatermute.cpp llfloaternamedesc.cpp llfloaternotificationsconsole.cpp - llfloaterobjectiminfo.cpp llfloateropenobject.cpp llfloaterparcel.cpp llfloaterperms.cpp @@ -198,6 +199,7 @@ set(viewer_SOURCE_FILES llfloatersettingsdebug.cpp llfloatersnapshot.cpp llfloatertelehub.cpp + llfloatertestlistview.cpp llfloatertools.cpp llfloatertopobjects.cpp llfloatertos.cpp @@ -208,9 +210,10 @@ set(viewer_SOURCE_FILES llfloaterwater.cpp llfloaterwindlight.cpp llfloaterworldmap.cpp + llfoldertype.cpp llfolderview.cpp + llfolderviewitem.cpp llfollowcam.cpp - llfriendactions.cpp llgesturemgr.cpp llgivemoney.cpp llglsandbox.cpp @@ -236,10 +239,14 @@ set(viewer_SOURCE_FILES llimcontrolpanel.cpp llinventorybridge.cpp llinventoryclipboard.cpp + llinventoryfilter.cpp llinventorymodel.cpp - llinventoryview.cpp lljoystickbutton.cpp + lllandmarkactions.cpp lllandmarklist.cpp + lllistbrowser.cpp + lllistview.cpp + lllocaltextureobject.cpp lllocationhistory.cpp lllocationinputctrl.cpp lllogchat.cpp @@ -262,14 +269,22 @@ set(viewer_SOURCE_FILES llnameeditor.cpp llnamelistctrl.cpp llnavigationbar.cpp - llnearbychathistory.cpp + llnearbychat.cpp + llnearbychatbar.cpp + llnearbychathandler.cpp llnetmap.cpp + llnotificationalerthandler.cpp + llnotificationgrouphandler.cpp + llnotificationinfohandler.cpp + llnotificationmanager.cpp llnotify.cpp lloutputmonitorctrl.cpp lloverlaybar.cpp llpanelavatar.cpp llpanelavatarrow.cpp + llpanelavatartag.cpp llpanelclassified.cpp + llsidetraypanelcontainer.cpp llpanelcontents.cpp llpaneldirbrowser.cpp llpaneldirclassified.cpp @@ -288,11 +303,14 @@ set(viewer_SOURCE_FILES llpanelgroupnotices.cpp llpanelgrouproles.cpp llpanelinventory.cpp + llpanelimcontrolpanel.cpp llpanelland.cpp llpanellandmarks.cpp llpanellandmedia.cpp llpanellogin.cpp + llpanelmedia.cpp llpanelmeprofile.cpp + llpanelmovetip.cpp llpanelobject.cpp llpanelpeople.cpp llpanelpermissions.cpp @@ -303,6 +321,7 @@ set(viewer_SOURCE_FILES llpanelshower.cpp llpanelplaces.cpp llpanelplacestab.cpp + llpanelprofile.cpp llpanelprofileview.cpp llpanelteleporthistory.cpp llpanelvolume.cpp @@ -324,11 +343,13 @@ set(viewer_SOURCE_FILES llregionposition.cpp llremoteparcelrequest.cpp llsavedsettingsglue.cpp + llscreenchannel.cpp llselectmgr.cpp llsidetray.cpp llsky.cpp llslurl.cpp llspatialpartition.cpp + llsplitbutton.cpp llsprite.cpp llstartup.cpp llstatusbar.cpp @@ -343,6 +364,12 @@ set(viewer_SOURCE_FILES lltexturectrl.cpp lltexturefetch.cpp lltextureview.cpp + lltoast.cpp + lltoastalertpanel.cpp + lltoastgroupnotifypanel.cpp + lltoastnotifypanel.cpp + lltoastpanel.cpp + lltoggleablemenu.cpp lltoolbar.cpp lltoolbrush.cpp lltoolcomp.cpp @@ -379,9 +406,7 @@ set(viewer_SOURCE_FILES llviewerdisplay.cpp llviewerfloaterreg.cpp llviewergenericmessage.cpp - llviewergesture.cpp - llviewerimage.cpp - llviewerimagelist.cpp + llviewergesture.cpp llviewerinventory.cpp llviewerjointattachment.cpp llviewerjoint.cpp @@ -409,7 +434,9 @@ set(viewer_SOURCE_FILES llviewershadermgr.cpp llviewerstats.cpp llviewertexteditor.cpp + llviewertexture.cpp llviewertextureanim.cpp + llviewertexturelist.cpp llviewerthrottle.cpp llviewervisualparam.cpp llviewerwindow.cpp @@ -478,7 +505,8 @@ endif (LINUX) set(viewer_HEADER_FILES CMakeLists.txt ViewerInstall.cmake - llaccordionpanel.h + llaccordionctrltab.h + llaccordionctrl.h llagent.h llagentlistener.h llagentaccess.h @@ -493,25 +521,27 @@ set(viewer_HEADER_FILES llassetuploadresponders.h llassetuploadqueue.h llaudiosourcevo.h + llavataractions.h llavatariconctrl.h llavatarlist.h llavatarlistitem.h llavatarpropertiesprocessor.h - llbbox.h llbottomtray.h llbox.h + llbreadcrumbview.h llcallbacklist.h llcallingcard.h llcapabilitylistener.h llcapabilityprovider.h llcaphttpsender.h + llchannelmanager.h llchatbar.h - llchathistoryscroll.h + llchatitemscontainerctrl.h + llchatmsgbox.h llchiclet.h llclassifiedinfo.h llclassifiedstatsresponder.h llcloud.h - llcollapsiblectrl.h llcolorswatch.h llcommandhandler.h llcommandlineparser.h @@ -523,7 +553,6 @@ set(viewer_HEADER_FILES lldebugview.h lldelayedgestureerror.h lldirpicker.h - lldraggerbar.h lldrawable.h lldrawpool.h lldrawpoolalpha.h @@ -549,13 +578,13 @@ set(viewer_HEADER_FILES llfeaturemanager.h llfilepicker.h llfirstuse.h + llfirsttimetipmanager.h llflexibleobject.h llfloaterabout.h llfloateractivespeakers.h llfloateraddlandmark.h llfloateranimpreview.h llfloaterauction.h - llfloateravatarinfo.h llfloateravatarpicker.h llfloateravatartextures.h llfloaterbeacons.h @@ -570,13 +599,12 @@ set(viewer_HEADER_FILES llfloatercamera.h llfloaterchat.h llfloaterchatterbox.h - llfloaterclassified.h llfloatercolorpicker.h llfloatercustomize.h llfloaterdaycycle.h llfloaterdirectory.h llfloaterenvsettings.h - llfloaterevent.h + llfloaterfirsttimetip.h llfloaterfonttest.h llfloaterfriends.h llfloatergesture.h @@ -593,6 +621,7 @@ set(viewer_HEADER_FILES llfloaterhud.h llfloaterimagepreview.h llfloaterinspect.h + llfloaterinventory.h llfloaterjoystick.h llfloaterlagmeter.h llfloaterland.h @@ -603,7 +632,6 @@ set(viewer_HEADER_FILES llfloatermute.h llfloaternamedesc.h llfloaternotificationsconsole.h - llfloaterobjectiminfo.h llfloateropenobject.h llfloaterparcel.h llfloaterpostcard.h @@ -618,6 +646,7 @@ set(viewer_HEADER_FILES llfloatersettingsdebug.h llfloatersnapshot.h llfloatertelehub.h + llfloatertestlistview.h llfloatertools.h llfloatertopobjects.h llfloatertos.h @@ -628,9 +657,11 @@ set(viewer_HEADER_FILES llfloaterwater.h llfloaterwindlight.h llfloaterworldmap.h + llfoldertype.h llfolderview.h + llfoldervieweventlistener.h + llfolderviewitem.h llfollowcam.h - llfriendactions.h llgesturemgr.h llgivemoney.h llgroupactions.h @@ -655,11 +686,15 @@ set(viewer_HEADER_FILES llimcontrolpanel.h llinventorybridge.h llinventoryclipboard.h + llinventoryfilter.h llinventorymodel.h - llinventoryview.h lljoystickbutton.h + lllandmarkactions.h lllandmarklist.h lllightconstants.h + lllistbrowser.h + lllistview.h + lllocaltextureobject.h lllocationhistory.h lllocationinputctrl.h lllogchat.h @@ -682,14 +717,20 @@ set(viewer_HEADER_FILES llnameeditor.h llnamelistctrl.h llnavigationbar.h - llnearbychathistory.h + llnearbychat.h + llnearbychatbar.h + llnearbychathandler.h llnetmap.h + llnotificationhandler.h + llnotificationmanager.h llnotify.h lloutputmonitorctrl.h lloverlaybar.h llpanelavatar.h llpanelavatarrow.h + llpanelavatartag.h llpanelclassified.h + llsidetraypanelcontainer.h llpanelcontents.h llpaneldirbrowser.h llpaneldirclassified.h @@ -708,11 +749,14 @@ set(viewer_HEADER_FILES llpanelgroupnotices.h llpanelgrouproles.h llpanelinventory.h + llpanelimcontrolpanel.h llpanelland.h llpanellandmarks.h llpanellandmedia.h llpanellogin.h + llpanelmedia.h llpanelmeprofile.h + llpanelmovetip.h llpanelobject.h llpanelpeople.h llpanelpermissions.h @@ -723,6 +767,7 @@ set(viewer_HEADER_FILES llpanelshower.h llpanelplaces.h llpanelplacestab.h + llpanelprofile.h llpanelprofileview.h llpanelteleporthistory.h llpanelvolume.h @@ -745,12 +790,14 @@ set(viewer_HEADER_FILES llremoteparcelrequest.h llresourcedata.h llrootview.h + llscreenchannel.h llsavedsettingsglue.h llselectmgr.h llsidetray.h llsky.h llslurl.h llspatialpartition.h + llsplitbutton.h llsprite.h llstartup.h llstatusbar.h @@ -766,6 +813,12 @@ set(viewer_HEADER_FILES lltexturectrl.h lltexturefetch.h lltextureview.h + lltoast.h + lltoastalertpanel.h + lltoastgroupnotifypanel.h + lltoastnotifypanel.h + lltoastpanel.h + lltoggleablemenu.h lltool.h lltoolbar.h lltoolbrush.h @@ -804,9 +857,7 @@ set(viewer_HEADER_FILES llviewerdisplay.h llviewerfloaterreg.h llviewergenericmessage.h - llviewergesture.h - llviewerimage.h - llviewerimagelist.h + llviewergesture.h llviewerinventory.h llviewerjoint.h llviewerjointattachment.h @@ -832,7 +883,9 @@ set(viewer_HEADER_FILES llviewershadermgr.h llviewerstats.h llviewertexteditor.h + llviewertexture.h llviewertextureanim.h + llviewertexturelist.h llviewerthrottle.h llviewervisualparam.h llviewerwindow.h diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 0a1235b85d..735424c647 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -2,6 +2,6 @@ CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 1.24.0.0"; -CFBundleGetInfoString = "Second Life version 1.24.0.0, Copyright 2004-2008 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 2.0.0.0"; +CFBundleGetInfoString = "Second Life version 2.0.0.0, Copyright 2004-2009 Linden Research, Inc."; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index baa5ccf1b9..7264044d37 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -32,7 +32,7 @@ CFBundleVersion - 1.24.0.0 + 2.0.0.0 CSResourcesFileMapped diff --git a/indra/newview/app_settings/foldertypes.xml b/indra/newview/app_settings/foldertypes.xml new file mode 100644 index 0000000000..4d4d479bdd --- /dev/null +++ b/indra/newview/app_settings/foldertypes.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 71878d02db..1432365d38 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -275,6 +275,17 @@ F32 Value 0.5 + + AudioSteamingMedia + + Comment + Enable streaming + Persist + 1 + Type + Boolean + Value + 0 AudioStreamingMusic @@ -573,17 +584,6 @@ Value 40 - BeaconAlwaysOn - - Comment - Beacons / highlighting always on - Persist - 1 - Type - Boolean - Value - 0 - BottomPanelNew Comment @@ -914,17 +914,6 @@ Value 1 - BulkChangeIncludeLandmarks - - Comment - Bulk permission changes affect landmarks - Persist - 1 - Type - Boolean - Value - 1 - BulkChangeIncludeNotecards Comment @@ -1112,6 +1101,28 @@ Value + CacheLocationTopFolder + + Comment + Controls the top folder location of the local disk cache + Persist + 1 + Type + String + Value + + + CacheLocationTopFolder + + Comment + Controls the location of the local disk cache + Persist + 1 + Type + String + Value + + CacheSize Comment @@ -2753,6 +2764,17 @@ Boolean Value 0 + + FirstSelectedEnabledPopups + + Comment + Return false if there is not enable popup selected in the list of floater preferences popups + Persist + 0 + Type + Boolean + Value + 0 FixedWeather @@ -3329,17 +3351,6 @@ Value 0 - NotFullScreen - - Comment - Run SL in non fullscreen mode - Persist - 1 - Type - Boolean - Value - 1 - FullScreenAspectRatio Comment @@ -4571,7 +4582,7 @@ Type Boolean Value - 1 + 0 NearMeRange @@ -4628,6 +4639,17 @@ Value + NewCacheLocationTopFolder + + Comment + Change the top folder location of the local disk cache to this + Persist + 1 + Type + String + Value + + NextLoginLocation Comment @@ -4716,6 +4738,94 @@ Value 350 + NotificationToastTime + + Comment + Width of notification messages + Persist + 1 + Type + S32 + Value + 5 + + ToastOpaqueTime + + Comment + Width of notification messages + Persist + 1 + Type + S32 + Value + 4 + + StartUpToastTime + + Comment + Width of notification messages + Persist + 1 + Type + S32 + Value + 5 + + ToastMargin + + Comment + Width of notification messages + Persist + 1 + Type + S32 + Value + 5 + + ChannelBottomPanelMargin + + Comment + Width of notification messages + Persist + 1 + Type + S32 + Value + 35 + + NotificationChannelRightMargin + + Comment + Width of notification messages + Persist + 1 + Type + S32 + Value + 10 + + NavBarMargin + + Comment + Width of notification messages + Persist + 1 + Type + S32 + Value + 60 + + OverflowToastHeight + + Comment + Width of notification messages + Persist + 1 + Type + S32 + Value + 72 + NotifyMoneyChange Comment @@ -5471,17 +5581,6 @@ Value 1 - RenderCustomSettings - - Comment - Do you want to set the graphics settings yourself - Persist - 1 - Type - Boolean - Value - 0 - RenderDebugAlphaMask Comment @@ -5769,6 +5868,21 @@ Value 2 + RenderGlowLumWeights + + Comment + Weights for each color channel to be used in calculating luminance (should add up to 1.0) + Persist + 1 + Type + Vector3 + Value + + 0.299 + 0.587 + 0.114 + + RenderGlowMaxExtractAlpha Comment @@ -5824,6 +5938,21 @@ Value 0.0 + RenderGlowWarmthWeights + + Comment + Weight of each color channel used before finding the max warmth + Persist + 1 + Type + Vector3 + Value + + 1.0 + 0.5 + 0.7 + + RenderGlowWidth Comment @@ -5890,7 +6019,7 @@ Value 0 - RenderHideGroupTitleAll + RenderShowGroupTitleAll Comment Show group titles in name labels @@ -5899,7 +6028,7 @@ Type Boolean Value - 0 + 1 RenderInitError @@ -5967,17 +6096,6 @@ Value 512 - RenderName - - Comment - Controls display of names above avatars (0 = never, 1 = fade, 2 = always) - Persist - 1 - Type - S32 - Value - 2 - RenderNameFadeDuration Comment @@ -5989,16 +6107,16 @@ Value 1.0 - RenderNameHideSelf + RenderNameShowSelf Comment - Don't display own name above avatar + Display own name above avatar Persist 1 Type Boolean Value - 0 + 1 RenderNameShowTime @@ -6589,10 +6707,10 @@ Value 0 - ShowActiveSpeakers + ShowAdvancedGraphicsSettings Comment - Display active speakers list on login + Show advanced graphics settings Persist 1 Type @@ -6610,6 +6728,17 @@ Boolean Value 0 + + AvatarNameTagMode + + Comment + Select Avatar Name Tag Mode + Persist + 1 + Type + S32 + Value + 1 ShowAxes @@ -6633,17 +6762,6 @@ Value 1 - ShowCameraControls - - Comment - Display camera controls on login - Persist - 1 - Type - Boolean - Value - 1 - ShowConsoleWindow Comment @@ -6656,6 +6774,17 @@ 0 ShowCrosshairs + + Comment + Show Coordinates in Location Input Field + Persist + 1 + Type + Boolean + Value + 0 + + ShowCoordinatesOption Comment Display crosshairs when in mouselook mode @@ -6677,17 +6806,6 @@ Value 0 - ShowDirectory - - Comment - - Persist - 0 - Type - Boolean - Value - 0 - ShowEmptyFoldersWhenSearching Comment @@ -6721,17 +6839,6 @@ Value 0 - ShowLeaders - - Comment - - Persist - 0 - Type - Boolean - Value - 0 - ShowPGSearchAll Comment @@ -6966,17 +7073,6 @@ Value 0 - ShowMovementControls - - Comment - Display movement controls on login - Persist - 1 - Type - Boolean - Value - 1 - ShowNearClip Comment @@ -7107,7 +7203,7 @@ Type Boolean Value - 0 + 1 ShowTangentBasis @@ -7130,17 +7226,6 @@ Boolean Value 1 - - ShowTools - - Comment - - Persist - 0 - Type - Boolean - Value - 0 ShowTutorial @@ -7241,6 +7326,21 @@ Value 0 + SkyNightColorShift + + Comment + Controls moonlight color (base color applied to moon as light source) + Persist + 1 + Type + Color3 + Value + + 0.67 + 0.67 + 1.0 + + SkyOverrideSimSunPosition Comment @@ -7575,6 +7675,17 @@ Value 0.699999988079 + ToolTipFadeTime + + Comment + Seconds over which tooltip fades away + Persist + 1 + Type + F32 + Value + 0.2 + ToolboxAutoMove Comment @@ -8002,7 +8113,7 @@ Type S32 Value - 1 + 3 UIMaxComboWidth @@ -8079,7 +8190,7 @@ Type S32 Value - 1 + 4 UIPreeditMarkerThickness @@ -8123,7 +8234,7 @@ Type S32 Value - 2 + 4 UIPreeditStandoutThickness @@ -8134,7 +8245,7 @@ Type S32 Value - 2 + 2 UIResizeBarHeight @@ -8178,7 +8289,7 @@ Type S32 Value - 16 + 15 UISliderctrlHeight @@ -9325,6 +9436,17 @@ Value 1 + WindowFullScreen + + Comment + Run SL in fullscreen mode + Persist + 1 + Type + Boolean + Value + 0 + WindowHeight Comment @@ -9391,6 +9513,17 @@ Value 150000.0 + XUIEditor + + Comment + Path to program used to edit XUI files + Persist + 1 + Type + String + Value + 150000.0 + YawFromMousePosition Comment @@ -9512,5 +9645,16 @@ Value 0 + GroupTeleportMembersLimit + + Comment + Max number of members of group to offer teleport + Persist + 1 + Type + U32 + Value + 100 + diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index dab88a5ec3..893e7acd7a 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -22,17 +22,28 @@ Value |TOKEN COPY BusyModeResponse| - IMLogTimestamp + IMLogOptions Comment - Log Timestamp of Instant Messages + Log options for Instant Messages Persist 1 Type - Boolean + S32 Value - 1 + 2 + InstantMessageLogFolder + + Comment + Top level folder to your log files. + Persist + 1 + Type + String + Value + + InstantMessageLogPath Comment @@ -77,10 +88,10 @@ Value 0 - LogChatTimestamp + LogTimestamp Comment - Log Timestamp of Chat + Log Timestamp Persist 1 Type diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 13546347b9..e3d3d66d87 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -38,13 +38,11 @@ #include "llagentlistener.h" #include "llanimationstates.h" #include "llcallingcard.h" -#include "llchatbar.h" #include "llconsole.h" #include "lldrawable.h" #include "llfirstuse.h" #include "llfloaterreg.h" #include "llfloateractivespeakers.h" -#include "llfloateravatarinfo.h" #include "llfloatercamera.h" #include "llfloatercustomize.h" #include "llfloaterdirectory.h" @@ -100,6 +98,7 @@ #include "pipeline.h" #include "lltrans.h" #include "llbottomtray.h" +#include "llnearbychatbar.h" #include "stringize.h" #include "llcapabilitylistener.h" @@ -363,7 +362,7 @@ LLAgent::LLAgent() : mAutoPilotFinishedCallback(NULL), mAutoPilotCallbackData(NULL), - mEffectColor(0.f, 1.f, 1.f, 1.f), + mEffectColor(LLColor4(0.f, 1.f, 1.f, 1.f)), mHaveHomePosition(FALSE), mHomeRegionHandle( 0 ), @@ -417,7 +416,7 @@ void LLAgent::init() mCameraZoomFraction = 1.f; mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject"); - mEffectColor = gSavedSkinSettings.getColor4("EffectColor"); + mEffectColor = LLUIColorTable::instance().getColor("EffectColor"); gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2)); gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2)); @@ -503,12 +502,16 @@ void LLAgent::resetView(BOOL reset_camera, BOOL change_camera) LLViewerJoystick::getInstance()->moveAvatar(true); } - LLFloaterReg::hideInstance("build"); + //Camera Tool is needed for Free Camera Control Mode + if (!LLFloaterCamera::inFreeCameraMode()) + { + LLFloaterReg::hideInstance("build"); + + // Switch back to basic toolset + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + } gViewerWindow->showCursor(); - - // Switch back to basic toolset - LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); } @@ -759,7 +762,7 @@ void LLAgent::setFlying(BOOL fly) } // don't allow taking off while sitting - if (fly && mAvatarObject->mIsSitting) + if (fly && mAvatarObject->isSitting()) { return; } @@ -788,6 +791,11 @@ void LLAgent::setFlying(BOOL fly) clearControlFlags(AGENT_CONTROL_FLY); gSavedSettings.setBOOL("FlyBtnState", FALSE); } + + + // Update Movement Controls according to Fly mode + LLFloaterMove::setFlyingMode(fly); + mbFlagsDirty = TRUE; } @@ -811,11 +819,16 @@ bool LLAgent::enableFlying() BOOL sitting = FALSE; if (gAgent.getAvatarObject()) { - sitting = gAgent.getAvatarObject()->mIsSitting; + sitting = gAgent.getAvatarObject()->isSitting(); } return !sitting; } +void LLAgent::standUp() +{ + setControlFlags(AGENT_CONTROL_STAND_UP); +} + //----------------------------------------------------------------------------- // setRegion() @@ -1246,7 +1259,7 @@ F32 LLAgent::clampPitchToLimits(F32 angle) F32 angle_from_skyward = acos( mFrameAgent.getAtAxis() * skyward ); - if (mAvatarObject.notNull() && mAvatarObject->mIsSitting) + if (mAvatarObject.notNull() && mAvatarObject->isSitting()) { look_down_limit = 130.f * DEG_TO_RAD; } @@ -2157,7 +2170,6 @@ void LLAgent::setBusy() { gBusyMenu->setLabel(LLTrans::getString("AvatarSetNotBusy")); } - LLFloaterReg::getTypedInstance("mute")->updateButtons(); } //----------------------------------------------------------------------------- @@ -2171,7 +2183,6 @@ void LLAgent::clearBusy() { gBusyMenu->setLabel(LLTrans::getString("AvatarSetBusy")); } - LLFloaterReg::getTypedInstance("mute")->updateButtons(); } //----------------------------------------------------------------------------- @@ -2494,13 +2505,11 @@ void LLAgent::autoPilot(F32 *delta_yaw) void LLAgent::propagate(const F32 dt) { // Update UI based on agent motion - LLFloaterMove *floater_move = LLFloaterMove::getInstance(); + LLFloaterMove *floater_move = LLFloaterReg::findTypedInstance("moveview"); if (floater_move) { floater_move->mForwardButton ->setToggleState( mAtKey > 0 || mWalkKey > 0 ); floater_move->mBackwardButton ->setToggleState( mAtKey < 0 || mWalkKey < 0 ); - floater_move->mSlideLeftButton ->setToggleState( mLeftKey > 0 ); - floater_move->mSlideRightButton->setToggleState( mLeftKey < 0 ); floater_move->mTurnLeftButton ->setToggleState( mYawKey > 0.f ); floater_move->mTurnRightButton ->setToggleState( mYawKey < 0.f ); floater_move->mMoveUpButton ->setToggleState( mUpKey > 0 ); @@ -2585,7 +2594,7 @@ void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y) else { // *FIX: rotate mframeagent by sit object's rotation? - LLQuaternion look_rotation = mAvatarObject->mIsSitting ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); // use camera's current rotation + LLQuaternion look_rotation = mAvatarObject->isSitting() ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); // use camera's current rotation LLVector3 look_offset = LLVector3(2.f, 0.f, 0.f) * look_rotation * av_inv_rot; setLookAt(LOOKAT_TARGET_IDLE, mAvatarObject, look_offset); } @@ -2728,7 +2737,7 @@ void LLAgent::startTyping() { sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START); } - LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE); + LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE); } //----------------------------------------------------------------------------- @@ -2740,7 +2749,7 @@ void LLAgent::stopTyping() { clearRenderState(AGENT_STATE_TYPING); sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP); - LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE); + LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE); } } @@ -2821,6 +2830,8 @@ void LLAgent::endAnimationUpdateUI() LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + LLFloaterCamera::toPrevModeIfInAvatarViewMode(); + // Only pop if we have pushed... if (TRUE == mViewsPushed) { @@ -2915,6 +2926,10 @@ void LLAgent::endAnimationUpdateUI() // JC - Added for always chat in third person option gFocusMgr.setKeyboardFocus(NULL); + //Making sure Camera Controls floater is in the right state + //when entering Mouse Look using wheel scrolling + LLFloaterCamera::updateIfNotInAvatarViewMode(); + LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset); mViewsPushed = TRUE; @@ -3025,7 +3040,7 @@ void LLAgent::updateCamera() validateFocusObject(); if (mAvatarObject.notNull() && - mAvatarObject->mIsSitting && + mAvatarObject->isSitting() && camera_mode == CAMERA_MODE_MOUSELOOK) { //Ventrella @@ -3056,21 +3071,25 @@ void LLAgent::updateCamera() } // Update UI with our camera inputs - LLFloaterCamera::getInstance()->mRotate->setToggleState( + LLFloaterCamera* camera_floater = LLFloaterReg::findTypedInstance("camera"); + if (camera_floater) + { + camera_floater->mRotate->setToggleState( mOrbitRightKey > 0.f, // left mOrbitUpKey > 0.f, // top mOrbitLeftKey > 0.f, // right mOrbitDownKey > 0.f); // bottom - LLFloaterCamera::getInstance()->mZoom->setToggleState( + camera_floater->mZoom->setToggleState( mOrbitInKey > 0.f, // top mOrbitOutKey > 0.f); // bottom - LLFloaterCamera::getInstance()->mTrack->setToggleState( + camera_floater->mTrack->setToggleState( mPanLeftKey > 0.f, // left mPanUpKey > 0.f, // top mPanRightKey > 0.f, // right mPanDownKey > 0.f); // bottom + } // Handle camera movement based on keyboard. const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD; // radians per second @@ -3146,7 +3165,7 @@ void LLAgent::updateCamera() // (2) focus, and (3) upvector. They can then be queried elsewhere in llAgent. //-------------------------------------------------------------------------------- // *TODO: use combined rotation of frameagent and sit object - LLQuaternion avatarRotationForFollowCam = mAvatarObject->mIsSitting ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); + LLQuaternion avatarRotationForFollowCam = mAvatarObject->isSitting() ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); LLFollowCamParams* current_cam = LLFollowCamMgr::getActiveFollowCamParams(); if (current_cam) @@ -3326,7 +3345,7 @@ void LLAgent::updateCamera() } mLastPositionGlobal = global_pos; - if (LLVOAvatar::sVisibleInFirstPerson && mAvatarObject.notNull() && !mAvatarObject->mIsSitting && cameraMouselook()) + if (LLVOAvatar::sVisibleInFirstPerson && mAvatarObject.notNull() && !mAvatarObject->isSitting() && cameraMouselook()) { LLVector3 head_pos = mAvatarObject->mHeadp->getWorldPosition() + LLVector3(0.08f, 0.f, 0.05f) * mAvatarObject->mHeadp->getWorldRotation() + @@ -3506,7 +3525,7 @@ LLVector3d LLAgent::calcFocusPositionTargetGlobal() } return mFocusTargetGlobal; } - else if (mSitCameraEnabled && mAvatarObject.notNull() && mAvatarObject->mIsSitting && mSitCameraReferenceObject.notNull()) + else if (mSitCameraEnabled && mAvatarObject.notNull() && mAvatarObject->isSitting() && mSitCameraReferenceObject.notNull()) { // sit camera LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition(); @@ -3630,7 +3649,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) return LLVector3d::zero; } head_offset.clearVec(); - if (mAvatarObject->mIsSitting && mAvatarObject->getParent()) + if (mAvatarObject->isSitting() && mAvatarObject->getParent()) { mAvatarObject->updateHeadOffset(); head_offset.mdV[VX] = mAvatarObject->mHeadOffset.mV[VX]; @@ -3644,7 +3663,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) else { head_offset.mdV[VZ] = mAvatarObject->mHeadOffset.mV[VZ]; - if (mAvatarObject->mIsSitting) + if (mAvatarObject->isSitting()) { head_offset.mdV[VZ] += 0.1; } @@ -3660,7 +3679,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) if (mSitCameraEnabled && mAvatarObject.notNull() - && mAvatarObject->mIsSitting + && mAvatarObject->isSitting() && mSitCameraReferenceObject.notNull()) { // sit camera @@ -3692,7 +3711,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) local_camera_offset = mFrameAgent.rotateToAbsolute( local_camera_offset ); } - if (!mCameraCollidePlane.isExactlyZero() && (mAvatarObject.isNull() || !mAvatarObject->mIsSitting)) + if (!mCameraCollidePlane.isExactlyZero() && (mAvatarObject.isNull() || !mAvatarObject->isSitting())) { LLVector3 plane_normal; plane_normal.setVec(mCameraCollidePlane.mV); @@ -4118,7 +4137,7 @@ void LLAgent::changeCameraToThirdPerson(BOOL animate) if (mAvatarObject.notNull()) { - if (!mAvatarObject->mIsSitting) + if (!mAvatarObject->isSitting()) { mAvatarObject->mPelvisp->setPosition(LLVector3::zero); } @@ -4200,7 +4219,7 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani return; } - setControlFlags(AGENT_CONTROL_STAND_UP); // force stand up + standUp(); // force stand up gViewerWindow->getWindow()->resetBusyCount(); if (gFaceEditToolset) @@ -5480,13 +5499,8 @@ void update_group_floaters(const LLUUID& group_id) { LLFloaterGroupInfo::refreshGroup(group_id); - //*TODO Implement group update for Profile View - // update avatar info -// LLFloaterAvatarInfo* fa = LLFloaterReg::findTypedInstance("preview_avatar", LLSD(gAgent.getID())); -// if(fa) -// { -// fa->resetGroupList(); -// } + //*TODO Implement group update for Profile View + // still actual as of July 31, 2009 (DZ) if (gIMMgr) { @@ -5555,7 +5569,7 @@ class LLAgentDropGroupViewerNode : public LLHTTPNode !input.has("body") ) { //what to do with badly formed message? - response->status(400); + response->statusUnknownError(400); response->result(LLSD("Invalid message parameters")); } @@ -5628,7 +5642,7 @@ class LLAgentDropGroupViewerNode : public LLHTTPNode else { //what to do with badly formed message? - response->status(400); + response->statusUnknownError(400); response->result(LLSD("Invalid message parameters")); } } @@ -6074,7 +6088,7 @@ bool LLAgent::teleportCore(bool is_local) LLFloaterReg::hideInstance("search"); // hide land floater too - it'll be out of date - LLFloaterLand::hideInstance(); + LLFloaterReg::hideInstance("about_land"); LLViewerParcelMgr::getInstance()->deselectLand(); @@ -6448,7 +6462,7 @@ void LLAgent::sendAgentSetAppearance() const LLWearable* wearable = gAgentWearables.getWearable(wearable_type,0); if (wearable) { - hash ^= wearable->getID(); + hash ^= wearable->getAssetID(); } } if (hash.notNull()) @@ -6578,49 +6592,6 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename) }//end for (all message sets in xml file) } -// static -void LLAgent::createLandmarkHere() -{ - std::string landmark_name, landmark_desc; - - gAgent.buildLocationString(landmark_name, LLAgent::LOCATION_FORMAT_LANDMARK); - gAgent.buildLocationString(landmark_desc, LLAgent::LOCATION_FORMAT_FULL); - LLUUID folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); - - createLandmarkHere(landmark_name, landmark_desc, folder_id); -} - -// static -void LLAgent::createLandmarkHere(const std::string& name, const std::string& desc, const LLUUID& folder_id) -{ - LLViewerRegion* agent_region = gAgent.getRegion(); - if(!agent_region) - { - llwarns << "No agent region" << llendl; - return; - } - LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if (!agent_parcel) - { - llwarns << "No agent parcel" << llendl; - return; - } - if (!agent_parcel->getAllowLandmark() - && !LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK)) - { - LLNotifications::instance().add("CannotCreateLandmarkNotOwner"); - return; - } - - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), - folder_id, LLTransactionID::tnull, - name, desc, - LLAssetType::AT_LANDMARK, - LLInventoryType::IT_LANDMARK, - NOT_WEARABLE, PERM_ALL, - NULL); -} - void LLAgent::sendAgentUpdateUserInfo(bool im_via_email, const std::string& directory_visibility ) { gMessageSystem->newMessageFast(_PREHASH_UpdateUserInfo); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 22e7ccc0e5..35ebc41909 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -44,6 +44,7 @@ #include "llcharacter.h" // LLAnimPauseRequest #include "llfollowcam.h" // Ventrella #include "llagentdata.h" // gAgentID, gAgentSessionID +#include "lluicolor.h" #include "llvoavatardefines.h" extern const BOOL ANIMATE; @@ -185,10 +186,7 @@ private: public: LLVOAvatarSelf* getAvatarObject() const { return mAvatarObject; } - const LLUUID& getInventoryRootID() const { return mInventoryRootID; } - LLUUID& getInventoryRootID() { return mInventoryRootID; } private: - LLUUID mInventoryRootID; LLPointer mAvatarObject; // NULL until avatar object sent down from simulator /** General Accessors @@ -269,8 +267,6 @@ public: std::string getSLURL() const; BOOL inPrelude(); BOOL buildLocationString(std::string& str, ELocationFormat fmt = LOCATION_FORMAT_LANDMARK); // Utility to build a location string - static void createLandmarkHere(); - static void createLandmarkHere(const std::string& name, const std::string& desc, const LLUUID& folder_id); private: LLViewerRegion *mRegionp; @@ -381,6 +377,12 @@ private: bool mbAlwaysRun; // Should the avatar run by default rather than walk? bool mbRunning; // Is the avatar trying to run right now? + //-------------------------------------------------------------------- + // Sit and stand + //-------------------------------------------------------------------- +public: + void standUp(); + //-------------------------------------------------------------------- // Busy //-------------------------------------------------------------------- @@ -833,7 +835,7 @@ public: F32 mHUDTargetZoom; // Target zoom level for HUD objects (used when editing) F32 mHUDCurZoom; // Current animated zoom level for HUD objects private: - LLColor4 mEffectColor; + LLUIColor mEffectColor; /** Camera ** ** diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 1da54ad08c..22875cbca2 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -36,7 +36,7 @@ #include "llagentwearables.h" #include "llfloatercustomize.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llinventorymodel.h" #include "llnotify.h" #include "llviewerregion.h" @@ -44,6 +44,9 @@ #include "llwearable.h" #include "llwearablelist.h" +#include + + LLAgentWearables gAgentWearables; BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE; @@ -59,22 +62,23 @@ void LLAgentWearables::dump() llinfos << "Type: " << i << " count " << count << llendl; for (U32 j=0; jmWearable == NULL) + LLWearable* wearable = getWearable((EWearableType)i,j); + if (wearable == NULL) { llinfos << " " << j << " NULL wearable" << llendl; - continue; } - llinfos << " " << j << " Name " << wearable_entry->mWearable->getName() - << " description " << wearable_entry->mWearable->getDescription() << llendl; + llinfos << " " << j << " Name " << wearable->getName() + << " description " << wearable->getDescription() << llendl; } } + llinfos << "Total items awaiting wearable update " << mItemsAwaitingWearableUpdate.size() << llendl; + for (std::set::iterator it = mItemsAwaitingWearableUpdate.begin(); + it != mItemsAwaitingWearableUpdate.end(); + ++it) + { + llinfos << (*it).asString() << llendl; + } } // MULTI-WEARABLE: debugging @@ -105,7 +109,7 @@ LLAgentWearables::LLAgentWearables() : // MULTI-WEARABLE: TODO remove null entries. for (U32 i = 0; i < WT_COUNT; i++) { - mWearableDatas[(EWearableType)i].push_back(new LLWearableInv); + mWearableDatas[(EWearableType)i].push_back(NULL); } } @@ -116,18 +120,6 @@ LLAgentWearables::~LLAgentWearables() void LLAgentWearables::cleanup() { - for (wearableentry_map_t::iterator iter = mWearableDatas.begin(); - iter != mWearableDatas.end(); - iter++) - { - wearableentry_vec_t &wearables = iter->second; - for (U32 i = 0; i < wearables.size(); i++) - { - LLWearableInv *wearable = wearables[i]; - delete wearable; - wearables[i] = NULL; - } - } mAvatarObject = NULL; } @@ -207,11 +199,13 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type, if (item_id.isNull()) return; - LLWearableInv* wearable_entry = getWearableInv((EWearableType)type, index); + LLUUID old_item_id = getWearableItemID((EWearableType)type,index); + if (wearable) + { + wearable->setItemID(item_id); + } + setWearable((EWearableType)type,index,wearable); - LLUUID old_item_id = wearable_entry->mItemID; - wearable_entry->mItemID = item_id; - wearable_entry->mWearable = wearable; if (old_item_id.notNull()) gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); @@ -221,7 +215,7 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type, // We're changing the asset id, so we both need to set it // locally via setAssetUUID() and via setTransactionID() which // will be decoded on the server. JC - item->setAssetUUID(wearable->getID()); + item->setAssetUUID(wearable->getAssetID()); item->setTransactionID(wearable->getTransactionID()); gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id); item->updateServer(FALSE); @@ -237,11 +231,10 @@ void LLAgentWearables::sendAgentWearablesUpdate() { for (U32 j=0; j < getWearableCount((EWearableType)i); j++) { - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i,j); - LLWearable* wearable = wearable_entry->mWearable; + LLWearable* wearable = getWearable((EWearableType)i,j); if (wearable) { - if (wearable_entry->mItemID.isNull()) + if (wearable->getItemID().isNull()) { LLPointer cb = new addWearableToAgentInventoryCallback( @@ -255,7 +248,7 @@ void LLAgentWearables::sendAgentWearablesUpdate() else { gInventory.addChangedMask(LLInventoryObserver::LABEL, - wearable_entry->mItemID); + wearable->getItemID()); } } } @@ -281,12 +274,11 @@ void LLAgentWearables::sendAgentWearablesUpdate() gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8); // MULTI-WEARABLE: TODO: hacked index to 0, needs to loop over all once messages support this. - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i, 0); - LLWearable* wearable = wearable_entry->mWearable; + LLWearable* wearable = getWearable((EWearableType)i, 0); if (wearable) { //llinfos << "Sending wearable " << wearable->getName() << llendl; - gMessageSystem->addUUIDFast(_PREHASH_ItemID, wearable_entry->mItemID); + gMessageSystem->addUUIDFast(_PREHASH_ItemID, wearable->getItemID()); } else { @@ -294,7 +286,7 @@ void LLAgentWearables::sendAgentWearablesUpdate() gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null); } - lldebugs << " " << LLWearableDictionary::getTypeLabel((EWearableType)i) << ": " << (wearable ? wearable->getID() : LLUUID::null) << llendl; + lldebugs << " " << LLWearableDictionary::getTypeLabel((EWearableType)i) << ": " << (wearable ? wearable->getAssetID() : LLUUID::null) << llendl; } gAgent.sendReliableMessage(); } @@ -302,14 +294,15 @@ void LLAgentWearables::sendAgentWearablesUpdate() // MULTI-WEARABLE: add index. void LLAgentWearables::saveWearable(const EWearableType type, const U32 index, BOOL send_update) { - LLWearableInv* wearable_entry = getWearableInv(type, index); - LLWearable* old_wearable = wearable_entry ? wearable_entry->mWearable : NULL; + LLWearable* old_wearable = getWearable(type, index); if (old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion())) { + LLUUID old_item_id = old_wearable->getItemID(); LLWearable* new_wearable = LLWearableList::instance().createCopyFromAvatar(old_wearable); - wearable_entry->mWearable = new_wearable; + new_wearable->setItemID(old_item_id); // should this be in LLWearable::copyDataFrom()? + setWearable(type,index,new_wearable); - LLInventoryItem* item = gInventory.getItem(wearable_entry->mItemID); + LLInventoryItem* item = gInventory.getItem(old_item_id); if (item) { // Update existing inventory item @@ -317,7 +310,7 @@ void LLAgentWearables::saveWearable(const EWearableType type, const U32 index, B new LLViewerInventoryItem(item->getUUID(), item->getParentUUID(), item->getPermissions(), - new_wearable->getID(), + new_wearable->getAssetID(), new_wearable->getAssetType(), item->getInventoryType(), item->getName(), @@ -368,15 +361,14 @@ void LLAgentWearables::saveWearableAs(const EWearableType type, llwarns << "LLAgent::saveWearableAs() not copyable." << llendl; return; } - LLWearableInv* wearable_entry = getWearableInv(type, index); - LLWearable* old_wearable = wearable_entry->mWearable; + LLWearable* old_wearable = getWearable(type, index); if (!old_wearable) { llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl; return; } - LLInventoryItem* item = gInventory.getItem(wearable_entry->mItemID); + LLInventoryItem* item = gInventory.getItem(getWearableItemID(type,index)); if (!item) { llwarns << "LLAgent::saveWearableAs() no inventory item." << llendl; @@ -417,8 +409,7 @@ void LLAgentWearables::saveWearableAs(const EWearableType type, void LLAgentWearables::revertWearable(const EWearableType type, const U32 index) { - LLWearableInv* wearable_entry = getWearableInv(type, index); - LLWearable* wearable = wearable_entry->mWearable; + LLWearable* wearable = getWearable(type, index); if (wearable) { wearable->writeToAvatar(TRUE); @@ -448,15 +439,16 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& { for (U32 j=0; j < getWearableCount((EWearableType)i); j++) { - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i,j); - if (wearable_entry->mItemID == item_id) + LLUUID curr_item_id = getWearableItemID((EWearableType)i,j); + if (curr_item_id == item_id) { - LLWearable* old_wearable = wearable_entry->mWearable; + LLWearable* old_wearable = getWearable((EWearableType)i,j); llassert(old_wearable); std::string old_name = old_wearable->getName(); old_wearable->setName(new_name); LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); + new_wearable->setItemID(item_id); LLInventoryItem* item = gInventory.getItem(item_id); if (item) { @@ -464,7 +456,7 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& } old_wearable->setName(old_name); - wearable_entry->mWearable = new_wearable; + setWearable((EWearableType)i,j,new_wearable); sendAgentWearablesUpdate(); break; } @@ -475,7 +467,7 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& BOOL LLAgentWearables::isWearableModifiable(EWearableType type, U32 index) const { - LLUUID item_id = getWearableItem(type, index); + LLUUID item_id = getWearableItemID(type, index); if (!item_id.isNull()) { LLInventoryItem* item = gInventory.getItem(item_id); @@ -490,7 +482,7 @@ BOOL LLAgentWearables::isWearableModifiable(EWearableType type, U32 index) const BOOL LLAgentWearables::isWearableCopyable(EWearableType type, U32 index) const { - LLUUID item_id = getWearableItem(type, index); + LLUUID item_id = getWearableItemID(type, index); if (!item_id.isNull()) { LLInventoryItem* item = gInventory.getItem(item_id); @@ -506,7 +498,7 @@ BOOL LLAgentWearables::isWearableCopyable(EWearableType type, U32 index) const /* U32 LLAgentWearables::getWearablePermMask(EWearableType type) { - LLUUID item_id = getWearableItem(type); + LLUUID item_id = getWearableItemID(type); if (!item_id.isNull()) { LLInventoryItem* item = gInventory.getItem(item_id); @@ -521,7 +513,7 @@ BOOL LLAgentWearables::isWearableCopyable(EWearableType type, U32 index) const LLInventoryItem* LLAgentWearables::getWearableInventoryItem(EWearableType type, U32 index) { - LLUUID item_id = getWearableItem(type,index); + LLUUID item_id = getWearableItemID(type,index); LLInventoryItem* item = NULL; if (item_id.notNull()) { @@ -530,16 +522,16 @@ LLInventoryItem* LLAgentWearables::getWearableInventoryItem(EWearableType type, return item; } -LLWearable* LLAgentWearables::getWearableFromWearableItem(const LLUUID& item_id) const +const LLWearable* LLAgentWearables::getWearableFromWearableItem(const LLUUID& item_id) const { for (S32 i=0; i < WT_COUNT; i++) { for (U32 j=0; j < getWearableCount((EWearableType)i); j++) { - const LLWearableInv* wearable_entry = getWearableInv((EWearableType)i, j); - if (wearable_entry->mItemID == item_id) + LLUUID curr_item_id = getWearableItemID((EWearableType)i, j); + if (curr_item_id == item_id) { - return wearable_entry->mWearable; + return getWearable((EWearableType)i, j); } } } @@ -558,40 +550,13 @@ void LLAgentWearables::sendAgentWearablesRequest() // MULTI-WEARABLE: update for multiple items per type. // Used to enable/disable menu items. // static -BOOL LLAgentWearables::selfHasWearable(void* userdata) +BOOL LLAgentWearables::selfHasWearable(EWearableType type) { - EWearableType type = (EWearableType)(intptr_t)userdata; // MULTI-WEARABLE: TODO could be getWearableCount > 0, once null entries have been eliminated. - return gAgentWearables.getWearableInv(type,0)->mWearable != NULL; + return gAgentWearables.getWearable(type,0) != NULL; } -const LLAgentWearables::LLWearableInv LLAgentWearables::s_null_wearable; - LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) -{ - LLWearableInv* inv = getWearableInv(type,index); - return inv->mWearable; -} - -const LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) const -{ - const LLWearableInv* inv = getWearableInv(type,index); - return inv->mWearable; -} - -//MULTI-WEARABLE: this will give wrong values until we get rid of the "always one empty object" scheme. -U32 LLAgentWearables::getWearableCount(const EWearableType type) const -{ - wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); - if (wearable_iter == mWearableDatas.end()) - { - return 0; - } - const wearableentry_vec_t& wearable_vec = wearable_iter->second; - return wearable_vec.size(); -} - -LLAgentWearables::LLWearableInv* LLAgentWearables::getWearableInv(const EWearableType type, U32 index) { wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); if (wearable_iter == mWearableDatas.end()) @@ -609,22 +574,73 @@ LLAgentWearables::LLWearableInv* LLAgentWearables::getWearableInv(const EWearabl } } -const LLAgentWearables::LLWearableInv* LLAgentWearables::getWearableInv(const EWearableType type, U32 index) const +void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearable *wearable) +{ + wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); + if (wearable_iter == mWearableDatas.end()) + { + llwarns << "invalid type, type " << type << " index " << index << llendl; + return; + } + wearableentry_vec_t& wearable_vec = wearable_iter->second; + if (index>=wearable_vec.size()) + { + llwarns << "invalid index, type " << type << " index " << index << llendl; + } + else + { + wearable_vec[index] = wearable; + } +} + +const LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) const { wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); - if (wearable_iter == mWearableDatas.end()) return &s_null_wearable; + if (wearable_iter == mWearableDatas.end()) + { + return NULL; + } const wearableentry_vec_t& wearable_vec = wearable_iter->second; if (index>=wearable_vec.size()) - return &s_null_wearable; + { + return NULL; + } else + { return wearable_vec[index]; + } } -const LLUUID& LLAgentWearables::getWearableItem(EWearableType type, U32 index) const +//MULTI-WEARABLE: this will give wrong values until we get rid of the "always one empty object" scheme. +U32 LLAgentWearables::getWearableCount(const EWearableType type) const { - return getWearableInv(type,index)->mItemID; + wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); + if (wearable_iter == mWearableDatas.end()) + { + return 0; + } + const wearableentry_vec_t& wearable_vec = wearable_iter->second; + return wearable_vec.size(); } +BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const +{ + return mItemsAwaitingWearableUpdate.find(item_id) != mItemsAwaitingWearableUpdate.end(); +} + +U32 LLAgentWearables::itemUpdatePendingCount() const +{ + return mItemsAwaitingWearableUpdate.size(); +} + +const LLUUID LLAgentWearables::getWearableItemID(EWearableType type, U32 index) const +{ + const LLWearable *wearable = getWearable(type,index); + if (wearable) + return wearable->getItemID(); + else + return LLUUID(); +} // Warning: include_linked_items = TRUE makes this operation expensive. BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id, BOOL include_linked_items) const @@ -646,6 +662,13 @@ BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id, BOOL include_linked_ return FALSE; } +struct InitialWearableData +{ + S32 mType; + U32 mIndex; + LLUUID mItemID; +}; + // MULTI-WEARABLE: update for multiple // static void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data) @@ -676,7 +699,9 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs //lldebugs << "processAgentInitialWearablesUpdate()" << llendl; // Add wearables LLUUID asset_id_array[WT_COUNT]; + LLUUID item_id_array[WT_COUNT]; // MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element. + gAgentWearables.mItemsAwaitingWearableUpdate.clear(); for (S32 i=0; i < num_wearables; i++) { U8 type_u8 = 0; @@ -703,9 +728,10 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs { continue; } - // MULTI-WEARABLE: TODO FIXME: assumes zeroth element always exists and can be safely written to. - LLWearableInv* wearable_entry = gAgentWearables.getWearableInv(type,0); - wearable_entry->mItemID = item_id; + + // MULTI-WEARABLE: extend arrays to index by type + index. + gAgentWearables.mItemsAwaitingWearableUpdate.insert(item_id); + item_id_array[type] = item_id; asset_id_array[type] = asset_id; } @@ -715,14 +741,18 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs // now that we have the asset ids...request the wearable assets for (S32 i = 0; i < WT_COUNT; i++) { - // MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element. - LLWearableInv* wearable_entry = gAgentWearables.getWearableInv((EWearableType)i, 0); - if (!wearable_entry->mItemID.isNull()) + // MULTI-WEARABLE: TODO: update once messages change. + // Currently use results to populate the zeroth element. + if (!item_id_array[i].isNull()) { + InitialWearableData *wear_data = new InitialWearableData; + wear_data->mType = i; + wear_data->mIndex = 0; // MULTI-WEARABLE: update + wear_data->mItemID = item_id_array[i]; LLWearableList::instance().getAsset(asset_id_array[i], LLStringUtil::null, LLWearableDictionary::getAssetType((EWearableType) i), - onInitialWearableAssetArrived, (void*)(intptr_t)i); + onInitialWearableAssetArrived, (void*)wear_data); } } } @@ -732,7 +762,9 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs // static void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* userdata) { - const EWearableType type = (EWearableType)(intptr_t)userdata; + boost::scoped_ptr wear_data((InitialWearableData*)userdata); + const EWearableType type = (EWearableType)wear_data->mType; + const U32 index = wear_data->mIndex; LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); if (!avatar) @@ -743,44 +775,31 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* if (wearable) { llassert(type == wearable->getType()); - // MULTI-WEARABLE: is this always zeroth element? Change sometime. - LLWearableInv* wearable_entry = gAgentWearables.getWearableInv(type,0); - wearable_entry->mWearable = wearable; - + wearable->setItemID(wear_data->mItemID); + gAgentWearables.setWearable(type,index,wearable); + gAgentWearables.mItemsAwaitingWearableUpdate.erase(wear_data->mItemID); + // disable composites if initial textures are baked avatar->setupComposites(); - gAgentWearables.queryWearableCache(); wearable->writeToAvatar(FALSE); avatar->setCompositeUpdatesEnabled(TRUE); - gInventory.addChangedMask(LLInventoryObserver::LABEL, wearable_entry->mItemID); + gInventory.addChangedMask(LLInventoryObserver::LABEL, wearable->getItemID()); } else { // Somehow the asset doesn't exist in the database. // MULTI-WEARABLE: assuming zeroth elt - gAgentWearables.recoverMissingWearable(type,0); + gAgentWearables.recoverMissingWearable(type,index); } gInventory.notifyObservers(); // Have all the wearables that the avatar was wearing at log-in arrived? // MULTI-WEARABLE: update when multiple wearables can arrive per type. - if (!gAgentWearables.mWearablesLoaded) - { - gAgentWearables.mWearablesLoaded = TRUE; - for (S32 i = 0; i < WT_COUNT; i++) - { - LLWearableInv* wearable_entry = gAgentWearables.getWearableInv((EWearableType)i,0); - if (!wearable_entry->mItemID.isNull() && !wearable_entry->mWearable) - { - gAgentWearables.mWearablesLoaded = FALSE; - break; - } - } - } - if (gAgentWearables.mWearablesLoaded) + gAgentWearables.updateWearablesLoaded(); + if (gAgentWearables.areWearablesLoaded()) { // Can't query cache until all wearables have arrived, so calling this earlier is a no-op. @@ -809,8 +828,7 @@ void LLAgentWearables::recoverMissingWearable(const EWearableType type, U32 inde LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type); S32 type_s32 = (S32) type; - LLWearableInv* wearable_entry = getWearableInv(type, index); - wearable_entry->mWearable = new_wearable; + setWearable(type,index,new_wearable); new_wearable->writeToAvatar(TRUE); // Add a new one in the lost and found folder. @@ -831,19 +849,8 @@ void LLAgentWearables::recoverMissingWearable(const EWearableType type, U32 inde void LLAgentWearables::recoverMissingWearableDone() { // Have all the wearables that the avatar was wearing at log-in arrived or been fabricated? - mWearablesLoaded = TRUE; - for (S32 i = 0; i < WT_COUNT; i++) - { - // MULTI-WEARABLE: assuming zeroth elt - fix when messages change. - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i,0); - if (!wearable_entry->mItemID.isNull() && !wearable_entry->mWearable) - { - mWearablesLoaded = FALSE; - break; - } - } - - if (mWearablesLoaded) + updateWearablesLoaded(); + if (areWearablesLoaded()) { // Make sure that the server's idea of the avatar's wearables actually match the wearables. gAgent.sendAgentSetAppearance(); @@ -855,6 +862,17 @@ void LLAgentWearables::recoverMissingWearableDone() } } +void LLAgentWearables::addLocalTextureObject(const EWearableType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index) +{ + LLWearable* wearable = getWearable((EWearableType)wearable_type, wearable_index); + if (!wearable) + { + llerrs << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << llendl; + } + + wearable->setLocalTextureObject(texture_type, new LLLocalTextureObject()); +} + void LLAgentWearables::createStandardWearables(BOOL female) { llwarns << "Creating Standard " << (female ? "female" : "male") @@ -896,10 +914,9 @@ void LLAgentWearables::createStandardWearables(BOOL female) donecb = new createStandardWearablesAllDoneCallback; } // MULTI_WEARABLE: only elt 0, may be the right thing? - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i,0); - llassert(wearable_entry->mWearable == NULL); + llassert(getWearable((EWearableType)i,0) == NULL); LLWearable* wearable = LLWearableList::instance().createNewWearable((EWearableType)i); - wearable_entry->mWearable = wearable; + setWearable((EWearableType)i,0,wearable); // no need to update here... // MULTI_WEARABLE: hardwired index = 0 here. LLPointer cb = @@ -929,6 +946,8 @@ void LLAgentWearables::createStandardWearablesAllDone() // ... because sendAgentWearablesUpdate will notify inventory // observers. mWearablesLoaded = TRUE; + checkWearablesLoaded(); + updateServer(); // Treat this as the first texture entry message, if none received yet @@ -968,8 +987,7 @@ void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name, const S32 type = wearables_to_include[i]; for (U32 j=0; jmWearable; + LLWearable* old_wearable = getWearable((EWearableType)type, j); if (old_wearable) { std::string new_name; @@ -984,7 +1002,7 @@ void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name, new_wearable->setName(new_name); } - LLViewerInventoryItem* item = gInventory.getItem(wearable_entry->mItemID); + LLViewerInventoryItem* item = gInventory.getItem(getWearableItemID((EWearableType)type,j)); S32 todo = addWearableToAgentInventoryCallback::CALL_NONE; if (!found_first_item) { @@ -1071,12 +1089,11 @@ void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name, void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index) { - LLWearableInv* wearable_entry = getWearableInv((EWearableType)type, index); - LLUUID first_item_id = wearable_entry->mItemID; + LLUUID first_item_id = getWearableItemID((EWearableType)type, index); // Open the inventory and select the first item we added. if (first_item_id.notNull()) { - LLInventoryView* view = LLInventoryView::getActiveInventory(); + LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); if (view) { view->getPanel()->setSelection(first_item_id, TAKE_FOCUS_NO); @@ -1178,17 +1195,15 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem S32 max_entry = mWearableDatas[type].size()-1; for (S32 i=max_entry; i>=0; i--) { - LLWearableInv *wearable_entry = getWearableInv(type,i); - LLWearable* old_wearable = wearable_entry->mWearable; - gInventory.addChangedMask(LLInventoryObserver::LABEL, wearable_entry->mItemID); - wearable_entry->mWearable = NULL; - wearable_entry->mItemID.setNull(); - //queryWearableCache(); // BAP moved below + LLWearable* old_wearable = getWearable(type,i); + gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID(type,i)); + setWearable(type,i,NULL); + + //queryWearableCache(); // moved below // MULTI_WEARABLE: FIXME - currently we keep a null entry, so can't delete the last one. if (i>0) { mWearableDatas[type].pop_back(); - delete wearable_entry; } if (old_wearable) { @@ -1198,15 +1213,12 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem } else { - LLWearableInv* wearable_entry = getWearableInv(type, index); - LLWearable* old_wearable = wearable_entry->mWearable; + LLWearable* old_wearable = getWearable(type, index); - gInventory.addChangedMask(LLInventoryObserver::LABEL, wearable_entry->mItemID); + gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID(type,index)); + setWearable(type,index,NULL); - wearable_entry->mWearable = NULL; - wearable_entry->mItemID.setNull(); - - //queryWearableCache(); // BAP moved below + //queryWearableCache(); // moved below if (old_wearable) { @@ -1221,7 +1233,6 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem llassert_always(wearable_iter != mWearableDatas.end()); wearableentry_vec_t& wearable_vec = wearable_iter->second; wearable_vec.erase( wearable_vec.begin() + index ); - delete(wearable_entry); } } @@ -1268,12 +1279,11 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it wearables_to_remove[type] = FALSE; // MULTI_WEARABLE: using 0th - LLWearableInv* old_wearable_entry = getWearableInv(type, 0); - LLWearable* old_wearable = old_wearable_entry->mWearable; + LLWearable* old_wearable = getWearable(type, 0); if (old_wearable) { - const LLUUID& old_item_id = old_wearable_entry->mItemID; - if ((old_wearable->getID() == new_wearable->getID()) && + const LLUUID& old_item_id = getWearableItemID(type, 0); + if ((old_wearable->getAssetID() == new_wearable->getAssetID()) && (old_item_id == new_item->getUUID())) { lldebugs << "No change to wearable asset and item: " << LLWearableDictionary::getInstance()->getWearableEntry(type) << llendl; @@ -1290,8 +1300,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it } } - old_wearable_entry->mItemID = new_item->getUUID(); - old_wearable_entry->mWearable = new_wearable; + setWearable(type,0,new_wearable); + if (new_wearable) + new_wearable->setItemID(new_item->getUUID()); } std::vector wearables_being_removed; @@ -1301,12 +1312,13 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it if (wearables_to_remove[i]) { // MULTI_WEARABLE: assuming 0th - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i, 0); - wearables_being_removed.push_back(wearable_entry->mWearable); - wearable_entry->mWearable = NULL; - - gInventory.addChangedMask(LLInventoryObserver::LABEL, wearable_entry->mItemID); - wearable_entry->mItemID.setNull(); + LLWearable* wearable = getWearable((EWearableType)i, 0); + gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID((EWearableType)i,0)); + if (wearable) + { + wearables_being_removed.push_back(wearable); + } + setWearable((EWearableType)i,0,NULL); } } @@ -1334,6 +1346,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it // Start rendering & update the server mWearablesLoaded = TRUE; + checkWearablesLoaded(); updateServer(); lldebugs << "setWearableOutfit() end" << llendl; @@ -1341,9 +1354,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it // User has picked "wear on avatar" from a menu. -void LLAgentWearables::setWearable(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append) +void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append) { - //LLAgentDumper dumper("setWearable"); + //LLAgentDumper dumper("setWearableItem"); if (isWearingItem(new_item->getUUID())) { llwarns << "wearable " << new_item->getUUID() << " is already worn" << llendl; @@ -1356,12 +1369,11 @@ void LLAgentWearables::setWearable(LLInventoryItem* new_item, LLWearable* new_we { // Remove old wearable, if any // MULTI_WEARABLE: hardwired to 0 - LLWearableInv* old_wearable_entry = getWearableInv(type,0); - LLWearable* old_wearable = old_wearable_entry->mWearable; + LLWearable* old_wearable = getWearable(type,0); if (old_wearable) { - const LLUUID& old_item_id = old_wearable_entry->mItemID; - if ((old_wearable->getID() == new_wearable->getID()) && + const LLUUID& old_item_id = old_wearable->getItemID(); + if ((old_wearable->getAssetID() == new_wearable->getAssetID()) && (old_item_id == new_item->getUUID())) { lldebugs << "No change to wearable asset and item: " << LLWearableDictionary::getInstance()->getWearableEntry(type) << llendl; @@ -1417,29 +1429,32 @@ bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& return false; } -// Called from setWearable() and onSetWearableDialog() to actually set the wearable. +// Called from setWearableItem() and onSetWearableDialog() to actually set the wearable. // MULTI_WEARABLE: unify code after null objects are gone. void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append) { const EWearableType type = new_wearable->getType(); - if (do_append && getWearableInv(type,0)->mItemID.notNull()) + if (do_append && getWearableItemID(type,0).notNull()) { - LLWearableInv *new_wearable_entry = new LLWearableInv; - new_wearable_entry->mItemID = new_item->getUUID(); - new_wearable_entry->mWearable = new_wearable; - mWearableDatas[type].push_back(new_wearable_entry); + new_wearable->setItemID(new_item->getUUID()); + mWearableDatas[type].push_back(new_wearable); llinfos << "Added additional wearable for type " << type << " size is now " << mWearableDatas[type].size() << llendl; } else { - LLWearableInv* wearable_entry = getWearableInv(type,0); // Replace the old wearable with a new one. - llassert(new_item->getAssetUUID() == new_wearable->getID()); - LLUUID old_item_id = wearable_entry->mItemID; - wearable_entry->mItemID = new_item->getUUID(); - wearable_entry->mWearable = new_wearable; + llassert(new_item->getAssetUUID() == new_wearable->getAssetID()); + + LLWearable *old_wearable = getWearable(type,0); + LLUUID old_item_id; + if (old_wearable) + { + old_item_id = old_wearable->getItemID(); + } + new_wearable->setItemID(new_item->getUUID()); + setWearable(type,0,new_wearable); if (old_item_id.notNull()) { @@ -1450,7 +1465,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n << " size is now " << mWearableDatas[type].size() << llendl; } - //llinfos << "LLVOAvatar::setWearable()" << llendl; + //llinfos << "LLVOAvatar::setWearableItem()" << llendl; queryWearableCache(); new_wearable->writeToAvatar(TRUE); @@ -1459,7 +1474,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n void LLAgentWearables::queryWearableCache() { - if (!mWearablesLoaded) + if (!areWearablesLoaded()) { return; } @@ -1489,10 +1504,10 @@ void LLAgentWearables::queryWearableCache() // EWearableType baked_type = gBakedWearableMap[baked_index][baked_num]; const EWearableType baked_type = baked_dict->mWearables[i]; // MULTI_WEARABLE: assuming 0th - const LLWearable* wearable = getWearableInv(baked_type,0)->mWearable; + const LLWearable* wearable = getWearable(baked_type,0); if (wearable) { - hash ^= wearable->getID(); + hash ^= wearable->getAssetID(); } } if (hash.notNull()) @@ -1592,6 +1607,29 @@ void LLAgentWearables::userRemoveAllAttachments(void* userdata) gMessageSystem->sendReliable(gAgent.getRegionHost()); } +void LLAgentWearables::checkWearablesLoaded() const +{ +#ifdef SHOW_ASSERT + U32 item_pend_count = itemUpdatePendingCount(); + if (mWearablesLoaded) + { + llassert(item_pend_count==0); + } +#endif +} + +BOOL LLAgentWearables::areWearablesLoaded() const +{ + checkWearablesLoaded(); + return mWearablesLoaded; +} + +// MULTI-WEARABLE: update for multiple indices. +void LLAgentWearables::updateWearablesLoaded() +{ + mWearablesLoaded = (itemUpdatePendingCount()==0); +} + void LLAgentWearables::updateServer() { sendAgentWearablesUpdate(); diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 31d6e30069..977efd71b4 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -66,32 +66,37 @@ public: BOOL isWearingItem(const LLUUID& item_id, const BOOL include_linked_items = FALSE) const; BOOL isWearableModifiable(EWearableType type, U32 index /*= 0*/) const; BOOL isWearableCopyable(EWearableType type, U32 index /*= 0*/) const; - BOOL areWearablesLoaded() const { return mWearablesLoaded; } + BOOL areWearablesLoaded() const; + void updateWearablesLoaded(); + void checkWearablesLoaded() const; + //-------------------------------------------------------------------- // Accessors //-------------------------------------------------------------------- public: - const LLUUID& getWearableItem(EWearableType type, U32 index /*= 0*/) const; - LLWearable* getWearableFromWearableItem(const LLUUID& item_id) const; + const LLUUID getWearableItemID(EWearableType type, U32 index /*= 0*/) const; + const LLWearable* getWearableFromWearableItem(const LLUUID& item_id) const; LLInventoryItem* getWearableInventoryItem(EWearableType type, U32 index /*= 0*/); // MULTI-WEARABLE: assuming one per type. - static BOOL selfHasWearable(void* userdata); // userdata is EWearableType + static BOOL selfHasWearable(EWearableType type); LLWearable* getWearable(const EWearableType type, U32 index /*= 0*/); const LLWearable* getWearable(const EWearableType type, U32 index /*= 0*/) const; U32 getWearableCount(const EWearableType type) const; + private: - struct LLWearableInv; - LLWearableInv* getWearableInv(const EWearableType type, U32 index /*= 0*/); - const LLWearableInv* getWearableInv(const EWearableType type, U32 /*index = 0*/) const; + // Low-level data structure setter - public access is via setWearableItem, etc. + void setWearable(const EWearableType type, U32 index, LLWearable *wearable); + //-------------------------------------------------------------------- // Setters //-------------------------------------------------------------------- public: - void setWearable(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false); + void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false); void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove); void setWearableName(const LLUUID& item_id, const std::string& new_name); + void addLocalTextureObject(const EWearableType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index); protected: void setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append = false); static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable); @@ -160,16 +165,20 @@ public: static void userRemoveAllClothes(void* userdata); // userdata is NULL static void userRemoveAllAttachments(void* userdata); // userdata is NULL + BOOL itemUpdatePending(const LLUUID& item_id) const; + U32 itemUpdatePendingCount() const; + //-------------------------------------------------------------------- // Member variables //-------------------------------------------------------------------- private: - typedef std::vector wearableentry_vec_t; // all wearables of a certain type (EG all shirts) + typedef std::vector wearableentry_vec_t; // all wearables of a certain type (EG all shirts) typedef std::map wearableentry_map_t; // wearable "categories" arranged by wearable type wearableentry_map_t mWearableDatas; static BOOL mInitialWearablesUpdateReceived; BOOL mWearablesLoaded; + std::set mItemsAwaitingWearableUpdate; LLPointer mAvatarObject; // NULL until avatar object sent down from simulator //-------------------------------------------------------------------------------- @@ -215,15 +224,6 @@ private: LLPointer mCB; }; - struct LLWearableInv // Make this subclass of llwearable? - { - LLWearableInv() : mItemID(LLUUID::null), mWearable(NULL) {} - // BOOL exists() const; - LLUUID mItemID; // ID of the inventory item in the agent's inventory. - LLWearable* mWearable; - }; - const static LLWearableInv s_null_wearable; - }; // LLAgentWearables extern LLAgentWearables gAgentWearables; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 5a1ccb2047..92db908059 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -42,7 +42,7 @@ #include "lltexteditor.h" #include "llalertdialog.h" #include "llerrorcontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llgroupmgr.h" #include "llagent.h" #include "llagentwearables.h" @@ -156,8 +156,9 @@ #include "llviewerfloaterreg.h" #include "llcommandlineparser.h" #include "llfloatermemleak.h" +#include "llfloaterreg.h" #include "llfloatersnapshot.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" // includes for idle() idleShutdown() #include "llviewercontrol.h" @@ -239,9 +240,6 @@ LLTimer gLogoutTimer; static const F32 LOGOUT_REQUEST_TIME = 6.f; // this will be cut short by the LogoutReply msg. F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME; -LLUUID gInventoryLibraryOwner; -LLUUID gInventoryLibraryRoot; - BOOL gDisconnected = FALSE; // Map scale in pixels per region @@ -672,7 +670,6 @@ bool LLAppViewer::init() // Widget construction depends on LLUI being initialized LLUI::settings_map_t settings_map; settings_map["config"] = &gSavedSettings; - settings_map["color"] = &gSavedSkinSettings; settings_map["ignores"] = &gWarningSettings; settings_map["floater"] = &gSavedSettings; // *TODO: New settings file settings_map["account"] = &gSavedPerAccountSettings; @@ -685,13 +682,15 @@ bool LLAppViewer::init() // Setup paths and LLTrans after LLUI::initClass has been called LLUI::setupPaths(); LLTrans::parseStrings("strings.xml", default_trans_args); - + LLTrans::parseLanguageStrings("language_settings.xml"); LLWeb::initClass(); // do this after LLUI LLTextEditor::setURLCallbacks(&LLWeb::loadURL, &LLURLDispatcher::dispatchFromTextEditor, &LLURLDispatcher::dispatchFromTextEditor); - + + // Load translations for tooltips + LLFloater::initClass(); ///////////////////////////////////////////////// @@ -940,9 +939,10 @@ bool LLAppViewer::mainLoop() #endif //memory leaking simulation - if(LLFloaterMemLeak::getInstance()) + LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::getTypedInstance("mem_leaking"); + if(mem_leak_instance) { - LLFloaterMemLeak::getInstance()->idle() ; + mem_leak_instance->idle() ; } // canonical per-frame event @@ -1109,9 +1109,10 @@ bool LLAppViewer::mainLoop() catch(std::bad_alloc) { //stop memory leaking simulation - if(LLFloaterMemLeak::getInstance()) + LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::getTypedInstance("mem_leaking"); + if(mem_leak_instance) { - LLFloaterMemLeak::getInstance()->stop() ; + mem_leak_instance->stop() ; llwarns << "Bad memory allocation in LLAppViewer::mainLoop()!" << llendl ; } else @@ -1136,9 +1137,10 @@ bool LLAppViewer::mainLoop() llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ; //stop memory leaking simulation - if(LLFloaterMemLeak::getInstance()) + LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::getTypedInstance("mem_leaking"); + if(mem_leak_instance) { - LLFloaterMemLeak::getInstance()->stop() ; + mem_leak_instance->stop() ; } } } @@ -1369,8 +1371,8 @@ bool LLAppViewer::cleanup() // save their rects on delete. gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); - //*FIX: don't overwrite user color tweaks with *all* colors - gSavedSkinSettings.saveToFile(gSavedSettings.getString("SkinningSettingsFile"), TRUE); + LLUIColorTable::instance().saveUserSettings(); + // PerAccountSettingsFile should be empty if no use has been logged on. // *FIX:Mani This should get really saved in a "logoff" mode. gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE); @@ -1384,7 +1386,7 @@ bool LLAppViewer::cleanup() gWarningSettings.saveToFile(warnings_settings_filename, TRUE); gSavedSettings.cleanup(); - gSavedSkinSettings.cleanup(); + LLUIColorTable::instance().clear(); gCrashSettings.cleanup(); // Save URL history file @@ -1463,10 +1465,10 @@ bool LLAppViewer::cleanup() LLMetricPerformanceTester::cleanClass() ; //Note: - //LLViewerMedia::cleanupClass() has to be put before gImageList.shutdown() + //LLViewerMedia::cleanupClass() has to be put before gTextureList.shutdown() //because some new image might be generated during cleaning up media. --bao LLViewerMedia::cleanupClass(); - gImageList.shutdown(); // shutdown again in case a callback added something + gTextureList.shutdown(); // shutdown again in case a callback added something LLUIImageList::getInstance()->cleanUp(); // This should eventually be done in LLAppViewer @@ -1724,43 +1726,7 @@ std::string LLAppViewer::getSettingsFilename(const std::string& location_key, void LLAppViewer::loadColorSettings() { - gSavedSkinSettings.cleanup(); - - loadSettingsFromDirectory("DefaultSkin"); - loadSettingsFromDirectory("CurrentSkin", true); - loadSettingsFromDirectory("UserSkin"); - - class ColorConverterFunctor : public LLControlGroup::ApplyFunctor - { - public: - explicit ColorConverterFunctor(LLUIColorTable::Params& result) - :mResult(result) - { - } - - void apply(const std::string& name, LLControlVariable* control) - { - if(control->isType(TYPE_COL4)) - { - LLUIColorTable::ColorParams color; - color.value = (LLColor4)control->getValue(); - - LLUIColorTable::ColorEntryParams color_entry; - color_entry.name = name; - color_entry.color = color; - - mResult.color_entries.add(color_entry); - } - } - - private: - LLUIColorTable::Params& mResult; - }; - - LLUIColorTable::Params params; - ColorConverterFunctor ccf(params); - LLControlGroup::getInstance("Skinning")->applyToAll(&ccf); - LLUIColorTable::instance().init(params); + LLUIColorTable::instance().loadFromSettings(); } bool LLAppViewer::initConfiguration() @@ -1798,15 +1764,12 @@ bool LLAppViewer::initConfiguration() LLUI::setupPaths(); // setup paths for LLTrans based on settings files only LLTrans::parseStrings("strings.xml", default_trans_args); - + LLTrans::parseLanguageStrings("language_settings.xml"); // - set procedural settings // Note: can't use LL_PATH_PER_SL_ACCOUNT for any of these since we haven't logged in yet gSavedSettings.setString("ClientSettingsFile", gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global"))); - gSavedSettings.setString("SkinningSettingsFile", - gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("UserSkin", "Skinning"))); - gSavedSettings.setString("VersionChannelName", LL_CHANNEL); #ifndef LL_RELEASE_FOR_DOWNLOAD @@ -1837,7 +1800,7 @@ bool LLAppViewer::initConfiguration() LLFirstUse::addConfigVariable("FirstMap"); LLFirstUse::addConfigVariable("FirstGoTo"); LLFirstUse::addConfigVariable("FirstBuild"); - LLFirstUse::addConfigVariable("FirstLeftClickNoHit"); +// LLFirstUse::addConfigVariable("FirstLeftClickNoHit"); LLFirstUse::addConfigVariable("FirstTeleport"); LLFirstUse::addConfigVariable("FirstOverrideKeys"); LLFirstUse::addConfigVariable("FirstAttach"); @@ -1856,6 +1819,7 @@ bool LLAppViewer::initConfiguration() LLControlGroupCLP clp; std::string cmd_line_config = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "cmd_line.xml"); + clp.configure(cmd_line_config, &gSavedSettings); if(!initParseCommandLine(clp)) @@ -2061,10 +2025,9 @@ bool LLAppViewer::initConfiguration() const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) { - gDirUtilp->setSkinFolder(skinfolder->getValue().asString()); - - gSavedSettings.setString("SkinningSettingsFile", - gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("UserSkin", "Skinning"))); + // hack to force the skin to default. + //gDirUtilp->setSkinFolder(skinfolder->getValue().asString()); + gDirUtilp->setSkinFolder("default"); } mYieldTime = gSavedSettings.getS32("YieldTime"); @@ -2288,10 +2251,10 @@ bool LLAppViewer::initWindow() gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"), FALSE, ignorePixelDepth); - if (!gSavedSettings.getBOOL("NotFullScreen")) + if (gSavedSettings.getBOOL("WindowFullScreen")) { + // request to go full screen... which will be delayed until login gViewerWindow->toggleFullscreen(FALSE); - // request to go full screen... which will be delayed until login } if (gSavedSettings.getBOOL("WindowMaximized")) @@ -2939,12 +2902,14 @@ bool LLAppViewer::initCache() gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")); purgeCache(); // purge old cache gSavedSettings.setString("CacheLocation", new_cache_location); + gSavedSettings.setString("CacheLocationTopFolder", gDirUtilp->getBaseFileName(new_cache_location)); } if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"))) { LL_WARNS("AppCache") << "Unable to set cache location" << LL_ENDL; gSavedSettings.setString("CacheLocation", ""); + gSavedSettings.setString("CacheLocationTopFolder", ""); } if (mPurgeCache) @@ -3496,7 +3461,7 @@ void LLAppViewer::idle() { // Handle pending gesture processing - gGestureManager.update(); + LLGestureManager::instance().update(); gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY); } @@ -3937,20 +3902,20 @@ void LLAppViewer::disconnectViewer() LLSelectMgr::getInstance()->deselectAll(); } - if (!gNoRender) + // save inventory if appropriate + gInventory.cache(gInventory.getRootFolderID(), gAgent.getID()); + if (gInventory.getLibraryRootFolderID().notNull() + && gInventory.getLibraryOwnerID().notNull()) { - // save inventory if appropriate - gInventory.cache(gAgent.getInventoryRootID(), gAgent.getID()); - if(gInventoryLibraryRoot.notNull() && gInventoryLibraryOwner.notNull()) - { - gInventory.cache(gInventoryLibraryRoot, gInventoryLibraryOwner); - } + gInventory.cache( + gInventory.getLibraryRootFolderID(), + gInventory.getLibraryOwnerID()); } saveNameCache(); // close inventory interface, close all windows - LLInventoryView::cleanup(); + LLFloaterInventory::cleanup(); gAgentWearables.cleanup(); @@ -4069,8 +4034,6 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) void LLAppViewer::handleLoginComplete() { - gViewerWindow->handleLoginComplete(); - initMainloopTimeout("Mainloop Init"); // Store some data to DebugInfo in case of a freeze. @@ -4106,6 +4069,9 @@ void LLAppViewer::handleLoginComplete() { gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); } + + mOnLoginCompleted(); + writeDebugInfo(); } @@ -4267,4 +4233,5 @@ void LLAppViewer::launchUpdater() // *REMOVE:Mani - Saving for reference... // LLAppViewer::instance()->forceQuit(); -} \ No newline at end of file +} + diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index d0a934c87e..f95d7cb412 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -163,6 +163,13 @@ public: LLAllocator & getAllocator() { return mAlloc; } + // On LoginCompleted callback + typedef boost::signals2::signal login_completed_signal_t; + login_completed_signal_t mOnLoginCompleted; + boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) { return mOnLoginCompleted.connect(cb); } + + void purgeCache(); // Clear the local cache. + protected: virtual bool initWindow(); // Initialize the viewer's window. virtual bool initLogging(); // Initialize log files, logging system, return false on failure. @@ -184,7 +191,7 @@ private: void initGridChoice(); bool initCache(); // Initialize local client cache. - void purgeCache(); // Clear the local cache. + // We have switched locations of both Mac and Windows cache, make sure // files migrate and old cache is cleared out. @@ -317,9 +324,6 @@ extern LLTimer gLogoutTimer; extern F32 gSimLastTime; extern F32 gSimFrames; -extern LLUUID gInventoryLibraryOwner; -extern LLUUID gInventoryLibraryRoot; - extern BOOL gDisconnected; // Map scale in pixels per region diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 1379073bba..bb3b9087a1 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -41,7 +41,7 @@ #include "llfilepicker.h" #include "llnotify.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llpermissionsflags.h" #include "llpreviewnotecard.h" #include "llpreviewscript.h" @@ -285,7 +285,7 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) // Show the preview panel for textures and sounds to let // user know that the image (or snapshot) arrived intact. - LLInventoryView* view = LLInventoryView::getActiveInventory(); + LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); if(view) { LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); @@ -295,7 +295,7 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) { view->getPanel()->openSelected(); } - //LLInventoryView::dumpSelectionInformation((void*)view); + //LLFloaterInventory::dumpSelectionInformation((void*)view); // restore keyboard focus gFocusMgr.setKeyboardFocus(focus_ctrl); } @@ -465,10 +465,10 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content) { // If this gesture is active, then we need to update the in-memory // active map with the new pointer. - if (gGestureManager.isGestureActive(item_id)) + if (LLGestureManager::instance().isGestureActive(item_id)) { LLUUID asset_id = new_item->getAssetUUID(); - gGestureManager.replaceGesture(item_id, asset_id); + LLGestureManager::instance().replaceGesture(item_id, asset_id); gInventory.notifyObservers(); } diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h index 9ab571ae99..a08d70213c 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -47,6 +47,7 @@ public: const std::string& file_name, LLAssetType::EType asset_type); ~LLAssetUploadResponder(); + virtual void error(U32 statusNum, const std::string& reason); virtual void result(const LLSD& content); virtual void uploadUpload(const LLSD& content); diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp new file mode 100644 index 0000000000..281d73b18b --- /dev/null +++ b/indra/newview/llavataractions.cpp @@ -0,0 +1,279 @@ +/** + * @file llavataractions.cpp + * @brief Friend-related actions (add, remove, offer teleport, etc) + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" + +#include "llavataractions.h" + +#include "llsd.h" +#include "lldarray.h" +#include "llnotifications.h" + +#include "llagent.h" +#include "llappviewer.h" // for gLastVersionChannel +#include "llcallingcard.h" // for LLAvatarTracker +#include "llinventorymodel.h" +#include "llimview.h" // for gIMMgr +#include "llsidetray.h" +#include "llviewermessage.h" // for handle_lure +#include "llviewerregion.h" + +// static +void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name) +{ + if(id == gAgentID) + { + LLNotifications::instance().add("AddSelfFriend"); + return; + } + + LLSD args; + args["NAME"] = name; + LLSD payload; + payload["id"] = id; + payload["name"] = name; + // Look for server versions like: Second Life Server 1.24.4.95600 + if (gLastVersionChannel.find(" 1.24.") != std::string::npos) + { + // Old and busted server version, doesn't support friend + // requests with messages. + LLNotifications::instance().add("AddFriend", args, payload, &callbackAddFriend); + } + else + { + LLNotifications::instance().add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage); + } + + // add friend to recent people list + LLRecentPeople::instance().add(id); +} + +// static +void LLAvatarActions::removeFriendDialog(const LLUUID& id) +{ + if (id.isNull()) + return; + + std::vector ids; + ids.push_back(id); + removeFriendsDialog(ids); +} + +// static +void LLAvatarActions::removeFriendsDialog(const std::vector& ids) +{ + if(ids.size() == 0) + return; + + LLSD args; + std::string msgType; + if(ids.size() == 1) + { + LLUUID agent_id = ids[0]; + std::string first, last; + if(gCacheName->getName(agent_id, first, last)) + { + args["FIRST_NAME"] = first; + args["LAST_NAME"] = last; + } + + msgType = "RemoveFromFriends"; + } + else + { + msgType = "RemoveMultipleFromFriends"; + } + + LLSD payload; + for (std::vector::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + payload["ids"].append(*it); + } + + LLNotifications::instance().add(msgType, + args, + payload, + &handleRemove); +} + +// static +void LLAvatarActions::offerTeleport(const LLUUID& invitee) +{ + if (invitee.isNull()) + return; + + LLDynamicArray ids; + ids.push_back(invitee); + offerTeleport(ids); +} + +// static +void LLAvatarActions::offerTeleport(const std::vector& ids) +{ + if (ids.size() > 0) + handle_lure(ids); +} + +// static +void LLAvatarActions::startIM(const LLUUID& id) +{ + if (id.isNull()) + return; + + std::string name; + gCacheName->getFullName(id, name); + gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id); + make_ui_sound("UISndStartIM"); +} + +// static +void LLAvatarActions::startConference(const std::vector& ids) +{ + // *HACK: Copy into dynamic array + LLDynamicArray id_array; + for (std::vector::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + id_array.push_back(*it); + } + gIMMgr->addSession("Friends Conference", IM_SESSION_CONFERENCE_START, ids[0], id_array); + make_ui_sound("UISndStartIM"); +} + +// static +void LLAvatarActions::showProfile(const LLUUID& id) +{ + if (id.notNull()) + { + LLSD params; + params["id"] = id; + params["open_tab_name"] = "panel_profile"; + + //Show own profile + if(gAgent.getID() == id) + { + LLSideTray::getInstance()->showPanel("panel_me_profile", params); + } + //Show other user profile + else + { + LLSideTray::getInstance()->showPanel("panel_profile_view", params); + } + } +} + +//== private methods ======================================================================================== + +// static +bool LLAvatarActions::handleRemove(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + + const LLSD& ids = notification["payload"]["ids"]; + for (LLSD::array_const_iterator itr = ids.beginArray(); itr != ids.endArray(); ++itr) + { + LLUUID id = itr->asUUID(); + const LLRelationship* ip = LLAvatarTracker::instance().getBuddyInfo(id); + if (ip) + { + switch (option) + { + case 0: // YES + if( ip->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS)) + { + LLAvatarTracker::instance().empower(id, FALSE); + LLAvatarTracker::instance().notifyObservers(); + } + LLAvatarTracker::instance().terminateBuddy(id); + LLAvatarTracker::instance().notifyObservers(); + gInventory.addChangedMask(LLInventoryObserver::LABEL | LLInventoryObserver::CALLING_CARD, LLUUID::null); + gInventory.notifyObservers(); + break; + + case 1: // NO + default: + llinfos << "No removal performed." << llendl; + break; + } + } + } + return false; +} + +// static +bool LLAvatarActions::callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option == 0) + { + requestFriendship(notification["payload"]["id"].asUUID(), + notification["payload"]["name"].asString(), + response["message"].asString()); + } + return false; +} + +// static +bool LLAvatarActions::callbackAddFriend(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option == 0) + { + // Servers older than 1.25 require the text of the message to be the + // calling card folder ID for the offering user. JC + LLUUID calling_card_folder_id = + gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD); + std::string message = calling_card_folder_id.asString(); + requestFriendship(notification["payload"]["id"].asUUID(), + notification["payload"]["name"].asString(), + message); + } + return false; +} + +// static +void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message) +{ + LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD); + send_improved_im(target_id, + target_name, + message, + IM_ONLINE, + IM_FRIENDSHIP_OFFERED, + calling_card_folder_id); +} + +//static +bool LLAvatarActions::isFriend(const LLUUID& id) +{ + return ( NULL != LLAvatarTracker::instance().getBuddyInfo(id) ); +} diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h new file mode 100644 index 0000000000..73325d21f1 --- /dev/null +++ b/indra/newview/llavataractions.h @@ -0,0 +1,88 @@ +/** + * @file llavataractions.h + * @brief Friend-related actions (add, remove, offer teleport, etc) + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLAVATARACTIONS_H +#define LL_LLAVATARACTIONS_H + +/** + * Friend-related actions (add, remove, offer teleport, etc) + */ +class LLAvatarActions +{ +public: + /** + * Show a dialog explaining what friendship entails, then request friendship. + */ + static void requestFriendshipDialog(const LLUUID& id, const std::string& name); + + /** + * Show a friend removal dialog. + */ + static void removeFriendDialog(const LLUUID& id); + static void removeFriendsDialog(const std::vector& ids); + + /** + * Show teleport offer dialog. + */ + static void offerTeleport(const LLUUID& invitee); + static void offerTeleport(const std::vector& ids); + + /** + * Start instant messaging session. + */ + static void startIM(const LLUUID& id); + + /** + * Start conference chat with the given avatars. + */ + static void startConference(const std::vector& ids); + + /** + * Show avatar profile. + */ + static void showProfile(const LLUUID& id); + + /** + * Return true if avatar with "id" is a friend + */ + static bool isFriend(const LLUUID& id); + +private: + static bool callbackAddFriend(const LLSD& notification, const LLSD& response); + static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response); + static bool handleRemove(const LLSD& notification, const LLSD& response); + + // Just request friendship, no dialog. + static void requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message); +}; + +#endif // LL_LLAVATARACTIONS_H diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 3cd6126739..f6eb7f6494 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -36,17 +36,20 @@ #include "llavatarconstants.h" #include "llavatariconctrl.h" #include "llcallingcard.h" // for LLAvatarTracker -#include "llfriendactions.h" +#include "llavataractions.h" #include "llimview.h" #include "llmenugl.h" #include "lluictrlfactory.h" #include "llcachename.h" +#include "llagentdata.h" #define MENU_ITEM_VIEW_PROFILE 0 #define MENU_ITEM_SEND_IM 1 -static LLDefaultWidgetRegistry::Register r("avatar_icon"); +static LLDefaultChildRegistry::Register r("avatar_icon"); + +LLAvatarIconCtrl::avatar_image_map_t LLAvatarIconCtrl::sImagesCache; LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p) : LLIconCtrl(p), @@ -106,7 +109,7 @@ LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p) registrar.add("AvatarIcon.Action", boost::bind(&LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked, this, _2)); - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_avatar_icon.xml", gMenuHolder); + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mPopupMenuHandle = menu->getHandle(); } @@ -137,7 +140,17 @@ void LLAvatarIconCtrl::setValue(const LLSD& value) LLAvatarPropertiesProcessor::getInstance()->addObserver(value.asUUID(), this); LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(value.asUUID(),APT_PROPERTIES); mAvatarId = value.asUUID(); + + // Check if cache already contains image_id for that avatar + avatar_image_map_t::iterator it; + + it = sImagesCache.find(mAvatarId); + if (it != sImagesCache.end()) + { + updateFromCache(it->second); + } } + } else { @@ -147,6 +160,37 @@ void LLAvatarIconCtrl::setValue(const LLSD& value) gCacheName->get(mAvatarId, FALSE, boost::bind(&LLAvatarIconCtrl::nameUpdatedCallback, this, _1, _2, _3, _4)); } +void LLAvatarIconCtrl::updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data) +{ + // Update the avatar + if (data.image_id.notNull()) + { + LLIconCtrl::setValue(data.image_id); + } + else + { + LLIconCtrl::setValue("default_profile_picture.j2c"); + } + + // Update color of status symbol and tool tip + if (data.flags & AVATAR_ONLINE) + { + mStatusSymbol->setColor(LLColor4::green); + if (mDrawTooltip) + { + setToolTip((LLStringExplicit)"Online"); + } + } + else + { + mStatusSymbol->setColor(LLColor4::grey); + if (mDrawTooltip) + { + setToolTip((LLStringExplicit)"Offline"); + } + } +} + //virtual void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type) { @@ -160,33 +204,10 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type) return; } - // Update the avatar - if (avatar_data->image_id.notNull()) - { - LLIconCtrl::setValue(avatar_data->image_id); - } - else - { - LLIconCtrl::setValue("default_profile_picture.j2c"); - } + LLAvatarIconCtrl::LLImagesCacheItem data(avatar_data->image_id, avatar_data->flags); - // Update color of status symbol and tool tip - if (avatar_data->flags & AVATAR_ONLINE) - { - mStatusSymbol->setColor(LLColor4::green); - if (mDrawTooltip) - { - setToolTip((LLStringExplicit)"Online"); - } - } - else - { - mStatusSymbol->setColor(LLColor4::grey); - if (mDrawTooltip) - { - setToolTip((LLStringExplicit)"Offline"); - } - } + updateFromCache(data); + sImagesCache.insert(std::pair(mAvatarId, data)); } } } @@ -198,10 +219,17 @@ BOOL LLAvatarIconCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) if(menu) { bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarId) != NULL; - + menu->setItemEnabled("Add Friend", !is_friend); menu->setItemEnabled("Remove Friend", is_friend); + if(gAgentID == mAvatarId) + { + menu->setItemEnabled("Add Friend", false); + menu->setItemEnabled("Send IM", false); + menu->setItemEnabled("Remove Friend", false); + } + menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); LLMenuGL::showPopup(this, menu, x, y); @@ -230,7 +258,7 @@ void LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked(const LLSD& userdata) if (level == "profile") { - LLFriendActions::showProfile(id); + LLAvatarActions::showProfile(id); } else if (level == "im") { @@ -248,10 +276,10 @@ void LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked(const LLSD& userdata) name.append(" "); name.append(getLastName()); - LLFriendActions::requestFriendshipDialog(id, name); + LLAvatarActions::requestFriendshipDialog(id, name); } else if (level == "remove") { - LLFriendActions::removeFriendDialog(id); + LLAvatarActions::removeFriendDialog(id); } } diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h index cb1e9584ba..10ce827d6d 100644 --- a/indra/newview/llavatariconctrl.h +++ b/indra/newview/llavatariconctrl.h @@ -46,9 +46,10 @@ public: Optional avatar_id; Optional draw_tooltip; Params() + : avatar_id("avatar_id"), + draw_tooltip("draw_tooltip", true) { name = "avatar_icon"; - draw_tooltip = TRUE; } }; protected: @@ -84,6 +85,20 @@ protected: std::string mLastName; LLHandle mPopupMenuHandle; bool mDrawTooltip; + + struct LLImagesCacheItem + { + LLUUID image_id; + U32 flags; + + LLImagesCacheItem(LLUUID image_id_, U32 flags_) : image_id(image_id_), flags(flags_) {} + }; + + typedef std::map avatar_image_map_t; + + static avatar_image_map_t sImagesCache; + + void updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data); }; #endif // LL_LLAVATARICONCTRL_H diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 08f0cf8842..40dd20dfa4 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -37,24 +37,40 @@ // newview #include "llcallingcard.h" // for LLAvatarTracker #include "llcachename.h" +#include "lloutputmonitorctrl.h" +#include "llvoiceclient.h" -static LLDefaultWidgetRegistry::Register r("avatar_list"); +static LLDefaultChildRegistry::Register r("avatar_list"); LLAvatarList::Params::Params() +: + volume_column_width("volume_column_width", 0) + , online_go_first("online_go_first", true) { draw_heading = true; draw_stripes = false; multi_select = false; column_padding = 0; - search_column = LIST_NAME; - sort_column = LIST_NAME; + search_column = COL_NAME; + sort_column = COL_NAME; } LLAvatarList::LLAvatarList(const Params& p) : LLScrollListCtrl(p) + , mHaveVolumeColumn(p.volume_column_width > 0) + , mOnlineGoFirst(p.online_go_first) { setCommitOnSelectionChange(TRUE); // there's no such param in LLScrollListCtrl::Params + // "volume" column + { + LLScrollListColumn::Params col_params; + col_params.name = "volume"; + col_params.header.label = "Volume"; // *TODO: localize or remove the header + col_params.width.pixel_width = p.volume_column_width; + addColumn(col_params); + } + // "name" column { LLScrollListColumn::Params col_params; @@ -63,18 +79,60 @@ LLAvatarList::LLAvatarList(const Params& p) col_params.width.dynamic_width = true; addColumn(col_params); } + + // "online status" column + { + LLScrollListColumn::Params col_params; + col_params.name = "online"; + col_params.header.label = "Online"; // *TODO: localize or remove the header + col_params.width.pixel_width = 0; // invisible column + addColumn(col_params); + } + // invisible "id" column { LLScrollListColumn::Params col_params; col_params.name = "id"; + col_params.header.label = "ID"; // *TODO: localize or remove the header col_params.width.pixel_width = 0; addColumn(col_params); } - // The corresponding parameters don't work because we create columns dynamically. - sortByColumnIndex(LIST_NAME, TRUE); - setSearchColumn(LIST_NAME); + // Primary sort = online status, secondary sort = name + // The corresponding parameters don't work because we create columns dynamically. + sortByColumnIndex(COL_NAME, TRUE); + if (mOnlineGoFirst) + sortByColumnIndex(COL_ONLINE, FALSE); + setSearchColumn(COL_NAME); +} + +// virtual +void LLAvatarList::draw() +{ + LLScrollListCtrl::draw(); + if (mHaveVolumeColumn) + { + updateVolume(); + } +} + +//virtual +BOOL LLAvatarList::handleMouseDown(S32 x, S32 y, MASK mask) +{ + LLScrollListItem* hit_item = hitItem(x, y); + if (NULL == hit_item) + { + std::vector selectedItems = getAllSelected(); + std::vector::const_iterator it = selectedItems.begin(); + + for (; it != selectedItems.end(); ++it) + { + (*it)->setSelected(FALSE); + } + return TRUE; + } + return LLScrollListCtrl::handleMouseDown(x, y, mask); } std::vector LLAvatarList::getSelectedIDs() @@ -97,17 +155,30 @@ void LLAvatarList::addItem(const LLUUID& id, const std::string& name, BOOL is_bo LLSD element; element["id"] = id; - LLSD& friend_column = element["columns"][LIST_NAME]; + // Update volume column (if we have one) + { + std::string icon = mHaveVolumeColumn ? getVolumeIcon(id) : ""; + LLSD& volume_column = element["columns"][COL_VOLUME]; + volume_column["column"] = "volume"; + volume_column["type"] = "icon"; + volume_column["value"] = icon; + } + + LLSD& friend_column = element["columns"][COL_NAME]; friend_column["column"] = "name"; friend_column["value"] = name; + LLSD& online_column = element["columns"][COL_ONLINE]; + online_column["column"] = "online"; + online_column["value"] = is_bold ? "1" : "0"; + LLScrollListItem* new_itemp = addElement(element, pos); // Indicate buddy online status. // (looks like parsing font parameters from LLSD is broken) if (is_bold) { - LLScrollListText* name_textp = dynamic_cast(new_itemp->getColumn(LIST_NAME)); + LLScrollListText* name_textp = dynamic_cast(new_itemp->getColumn(COL_NAME)); if (name_textp) name_textp->setFontStyle(LLFontGL::BOLD); else @@ -117,7 +188,13 @@ void LLAvatarList::addItem(const LLUUID& id, const std::string& name, BOOL is_bo } } -BOOL LLAvatarList::updateList(const std::vector& all_buddies) +static bool findInsensitive(std::string haystack, const std::string& needle_upper) +{ + LLStringUtil::toUpper(haystack); + return haystack.find(needle_upper) != std::string::npos; +} + +BOOL LLAvatarList::update(const std::vector& all_buddies, const std::string& name_filter) { BOOL have_names = TRUE; @@ -133,6 +210,8 @@ BOOL LLAvatarList::updateList(const std::vector& all_buddies) std::string name; const LLUUID& buddy_id = *buddy_it; have_names &= gCacheName->getFullName(buddy_id, name); + if (name_filter != LLStringUtil::null && !findInsensitive(name, name_filter)) + continue; addItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id)); } @@ -161,3 +240,70 @@ BOOL LLAvatarList::updateList(const std::vector& all_buddies) return have_names; } + +// static +std::string LLAvatarList::getVolumeIcon(const LLUUID& id) +{ + // + // Determine icon appropriate for the current avatar volume. + // + // *TODO: remove this in favor of LLOutputMonitorCtrl + // when ListView widget is implemented + // which is capable of containing arbitrary widgets. + // + static LLOutputMonitorCtrl::Params default_monitor_params(LLUICtrlFactory::getDefaultParams()); + bool muted = gVoiceClient->getIsModeratorMuted(id) || gVoiceClient->getOnMuteList(id); + F32 power = gVoiceClient->getCurrentPower(id); + std::string icon; + + if (muted) + { + icon = default_monitor_params.image_mute.name; + } + else if (power == 0.f) + { + icon = default_monitor_params.image_off.name; + } + else if (power < LLVoiceClient::OVERDRIVEN_POWER_LEVEL) + { + S32 icon_image_idx = llmin(2, llfloor((power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f)); + switch(icon_image_idx) + { + default: + case 0: + icon = default_monitor_params.image_on.name; + break; + case 1: + icon = default_monitor_params.image_level_1.name; + break; + case 2: + icon = default_monitor_params.image_level_2.name; + break; + } + } + else + { + // overdriven + icon = default_monitor_params.image_level_3.name; + } + + return icon; +} + +// Update volume column for all list rows. +void LLAvatarList::updateVolume() +{ + item_list& items = getItemList(); + + for (item_list::iterator item_it = items.begin(); + item_it != items.end(); + ++item_it) + { + LLScrollListItem* itemp = (*item_it); + LLUUID speaker_id = itemp->getUUID(); + + LLScrollListCell* icon_cell = itemp->getColumn(COL_VOLUME); + if (icon_cell) + icon_cell->setValue(getVolumeIcon(speaker_id)); + } +} diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index 9bd9ce8e0e..991e9fa145 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -42,22 +42,45 @@ class LLAvatarList : public LLScrollListCtrl public: struct Params : public LLInitParam::Block { + Optional volume_column_width; + Optional online_go_first; Params(); }; - enum AVATAR_LIST_COLUMN_ORDER + enum EColumnOrder { - LIST_NAME, + COL_VOLUME, + COL_NAME, + COL_ONLINE, + COL_ID, }; LLAvatarList(const Params&); virtual ~LLAvatarList() {} - BOOL updateList(const std::vector& all_buddies); + /*virtual*/ void draw(); + /** + * Overrides base-class behavior of Mouse Down Event. + * + * LLScrollListCtrl::handleMouseDown version calls setFocus which select the first item if nothing selected. + * We need to deselect all items if perform click not over the any item. Otherwise calls base method. + * See EXT-246 + */ + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + + BOOL update(const std::vector& all_buddies, + const std::string& name_filter = LLStringUtil::null); protected: std::vector getSelectedIDs(); void addItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM); + +private: + static std::string getVolumeIcon(const LLUUID& id); /// determine volume icon from current avatar volume + void updateVolume(); // update volume for all avatars + + bool mHaveVolumeColumn; + bool mOnlineGoFirst; }; #endif // LL_LLAVATARLIST_H diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 5835a4c6b4..dc73f187a7 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -57,7 +57,9 @@ public: {}; } buttons; - Params() : avatar_icon("avatar_icon",LLUUID()), user_name("user_name","") + Params() + : avatar_icon("avatar_icon"), + user_name("user_name") {}; }; diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index e27da5663b..ecd67e44ae 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -102,6 +102,7 @@ void LLAvatarPropertiesProcessor::sendDataRequest(const LLUUID& avatar_id, EAvat if (data) { sendPickInfoRequest(avatar_id, *static_cast(data)); } + break; case APT_NOTES: sendGenericRequest(avatar_id, "avatarnotesrequest"); break; @@ -305,7 +306,7 @@ void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, voi msg->getS32(_PREHASH_Data, _PREHASH_SortOrder, pick_data.sort_order); msg->getBOOL(_PREHASH_Data, _PREHASH_Enabled, pick_data.enabled); - notifyObservers(pick_data.agent_id, &pick_data, APT_PICK_INFO); + notifyObservers(pick_data.creator_id, &pick_data, APT_PICK_INFO); } void LLAvatarPropertiesProcessor::processAvatarGroupsReply(LLMessageSystem* msg, void**) diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 616cbb1fdb..9eb8369c4c 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -32,29 +32,52 @@ #include "llviewerprecompiledheaders.h" // must be first include #include "llbottomtray.h" + #include "llagent.h" #include "llchiclet.h" -#include "lllayoutstack.h" -#include "llkeyboard.h" -#include "llgesturemgr.h" -#include "llanimationstates.h" +#include "llfloaterreg.h" +#include "llflyoutbutton.h" +#include "llnearbychatbar.h" +#include "llsplitbutton.h" +#include "llfloatercamera.h" +#include "llimpanel.h" -//FIXME: temporary, for send_chat_from_viewer() proto -#include "llchatbar.h" - -LLBottomTray::LLBottomTray() - :mLastSpecialChatChannel(0) +LLBottomTray::LLBottomTray(const LLSD&) +: mChicletPanel(NULL), + mIMWell(NULL), + mSysWell(NULL), + mTalkBtn(NULL), + mNearbyChatBar(NULL) { + mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL); + LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml"); mChicletPanel = getChild("chiclet_list",TRUE,FALSE); + mIMWell = getChild("im_well",TRUE,FALSE); + mSysWell = getChild("sys_well",TRUE,FALSE); - LLLineEditor* chat_box = getChatBox(); - chat_box->setCommitCallback(boost::bind(&LLBottomTray::onChatBoxCommit, this)); - chat_box->setKeystrokeCallback(&onChatBoxKeystroke, this); - chat_box->setFocusLostCallback(&onChatBoxFocusLost, this); + mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1)); + + LLSplitButton* presets = getChild("presets", TRUE, FALSE); + if (presets) presets->setSelectionCallback(LLFloaterCamera::onClickCameraPresets); LLIMMgr::getInstance()->addSessionObserver(this); + + //this is to fix a crash that occurs because LLBottomTray is a singleton + //and thus is deleted at the end of the viewers lifetime, but to be cleanly + //destroyed LLBottomTray requires some subsystems that are long gone + LLUI::getRootView()->addChild(this); + + // Necessary for focus movement among child controls + setFocusRoot(TRUE); +} + +BOOL LLBottomTray::postBuild() +{ + mNearbyChatBar = getChild("chat_bar"); + + return TRUE; } LLBottomTray::~LLBottomTray() @@ -65,179 +88,41 @@ LLBottomTray::~LLBottomTray() } } -LLLineEditor* LLBottomTray::getChatBox() +void LLBottomTray::onChicletClick(LLUICtrl* ctrl) { - return getChild("chat_box",TRUE,FALSE); -} - -void LLBottomTray::onChatBoxCommit() -{ - if (getChatBox()->getText().length() > 0) + LLIMChiclet* chiclet = dynamic_cast(ctrl); + if (chiclet) { - sendChat(CHAT_TYPE_NORMAL); - - LLLineEditor* chat_box = getChatBox(); + // Until you can type into an IM Window and have a conversation, + // still show the old communicate window + //LLFloaterReg::showInstance("communicate", chiclet->getSessionId()); - if (chat_box) - { - chat_box->setText(LLStringExplicit("")); - } - - gAgent.stopTyping(); + // Show after comm window so it is frontmost (and hence will not + // auto-hide) + LLIMFloater::show(chiclet->getSessionId()); + chiclet->setCounter(0); } } -void LLBottomTray::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate) +void* LLBottomTray::createNearbyChatBar(void* userdata) { - sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate); + return new LLNearbyChatBar(); } -void LLBottomTray::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate) -{ - // Look for "/20 foo" channel chats. - S32 channel = 0; - LLWString out_text = stripChannelNumber(wtext, &channel); - std::string utf8_out_text = wstring_to_utf8str(out_text); - std::string utf8_text = wstring_to_utf8str(wtext); - - utf8_text = utf8str_trim(utf8_text); - if (!utf8_text.empty()) - { - utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); - } - - // Don't animate for chats people can't hear (chat to scripts) - if (animate && (channel == 0)) - { - if (type == CHAT_TYPE_WHISPER) - { - lldebugs << "You whisper " << utf8_text << llendl; - gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START); - } - else if (type == CHAT_TYPE_NORMAL) - { - lldebugs << "You say " << utf8_text << llendl; - gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START); - } - else if (type == CHAT_TYPE_SHOUT) - { - lldebugs << "You shout " << utf8_text << llendl; - gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START); - } - else - { - llinfos << "send_chat_from_viewer() - invalid volume" << llendl; - return; - } - } - else - { - if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) - { - lldebugs << "Channel chat: " << utf8_text << llendl; - } - } - - send_chat_from_viewer(utf8_out_text, type, channel); -} - -// static -void LLBottomTray::onChatBoxKeystroke(LLLineEditor* caller, void* userdata) -{ - LLBottomTray* self = (LLBottomTray *)userdata; - - LLWString raw_text; - if (self->getChatBox()) raw_text = self->getChatBox()->getWText(); - - // Can't trim the end, because that will cause autocompletion - // to eat trailing spaces that might be part of a gesture. - LLWStringUtil::trimHead(raw_text); - - S32 length = raw_text.length(); - - if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences - { - gAgent.startTyping(); - } - else - { - gAgent.stopTyping(); - } - - /* Doesn't work -- can't tell the difference between a backspace - that killed the selection vs. backspace at the end of line. - if (length > 1 - && text[0] == '/' - && key == KEY_BACKSPACE) - { - // the selection will already be deleted, but we need to trim - // off the character before - std::string new_text = raw_text.substr(0, length-1); - self->mInputEditor->setText( new_text ); - self->mInputEditor->setCursorToEnd(); - length = length - 1; - } - */ - - KEY key = gKeyboard->currentKey(); - - // Ignore "special" keys, like backspace, arrows, etc. - if (length > 1 - && raw_text[0] == '/' - && key < KEY_SPECIAL) - { - // we're starting a gesture, attempt to autocomplete - - std::string utf8_trigger = wstring_to_utf8str(raw_text); - std::string utf8_out_str(utf8_trigger); - - if (gGestureManager.matchPrefix(utf8_trigger, &utf8_out_str)) - { - if (self->getChatBox()) - { - std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); - self->getChatBox()->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part - S32 outlength = self->getChatBox()->getLength(); // in characters - - // Select to end of line, starting from the character - // after the last one the user typed. - self->getChatBox()->setSelection(length, outlength); - } - } - - //llinfos << "GESTUREDEBUG " << trigger - // << " len " << length - // << " outlen " << out_str.getLength() - // << llendl; - } -} - -// static -void LLBottomTray::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata) -{ - // stop typing animation - gAgent.stopTyping(); -} - - //virtual void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) { if(getChicletPanel()) { - LLSD sid(session_id); - - if(getChicletPanel()->findIMChiclet(&sid)) + if(getChicletPanel()->findChiclet(session_id)) { } else { - LLIMChiclet* chicklet = (LLIMChiclet *)getChicletPanel()->createChiclet(&sid); - chicklet->setIMSessionName(name); - chicklet->setOtherParticipantId(other_participant_id); - - getChicletPanel()->arrange(); + LLIMChiclet* chiclet = getChicletPanel()->createChiclet(session_id); + chiclet->setIMSessionName(name); + chiclet->setOtherParticipantId(other_participant_id); } } } @@ -247,100 +132,42 @@ void LLBottomTray::sessionRemoved(const LLUUID& session_id) { if(getChicletPanel()) { - LLSD sid(session_id); - getChicletPanel()->removeIMChiclet(&sid); - getChicletPanel()->arrange(); + getChicletPanel()->removeChiclet(session_id); } } -void LLBottomTray::sendChat( EChatType type ) +//virtual +void LLBottomTray::onFocusLost() { - LLLineEditor* chat_box = getChatBox(); - - if (chat_box) + if (gAgent.cameraMouselook()) { - LLWString text = chat_box->getConvertedText(); - if (!text.empty()) + setVisible(FALSE); + } +} + +//virtual +// setVisible used instead of onVisibilityChange, since LLAgent calls it on entering/leaving mouselook mode. +// If bottom tray is already visible in mouselook mode, then onVisibilityChange will not be called from setVisible(true), +void LLBottomTray::setVisible(BOOL visible) +{ + LLPanel::setVisible(visible); + + LLView* stack = getChild("toolbar_stack",TRUE,FALSE); + + if (stack) + { + BOOL visibility = gAgent.cameraMouselook() ? false : true; + + for ( child_list_const_iter_t child_it = stack->getChildList()->begin(); child_it != stack->getChildList()->end(); child_it++) { - // store sent line in history, duplicates will get filtered - chat_box->updateHistory(); - // Check if this is destined for another channel - S32 channel = 0; - stripChannelNumber(text, &channel); + LLView* viewp = *child_it; - std::string utf8text = wstring_to_utf8str(text); - // Try to trigger a gesture, if not chat to a script. - std::string utf8_revised_text; - if (0 == channel) + if ("chat_bar" == viewp->getName()) + continue; + else { - // discard returned "found" boolean - gGestureManager.triggerAndReviseString(utf8text, &utf8_revised_text); - } - else - { - utf8_revised_text = utf8text; - } - - utf8_revised_text = utf8str_trim(utf8_revised_text); - - if (!utf8_revised_text.empty()) - { - // Chat with animation - sendChatFromViewer(utf8_revised_text, type, TRUE); + viewp->setVisible(visibility); } } } - - gAgent.stopTyping(); -} - -// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20. -// Otherwise returns input and channel 0. -LLWString LLBottomTray::stripChannelNumber(const LLWString &mesg, S32* channel) -{ - if (mesg[0] == '/' - && mesg[1] == '/') - { - // This is a "repeat channel send" - *channel = mLastSpecialChatChannel; - return mesg.substr(2, mesg.length() - 2); - } - else if (mesg[0] == '/' - && mesg[1] - && LLStringOps::isDigit(mesg[1])) - { - // This a special "/20" speak on a channel - S32 pos = 0; - - // Copy the channel number into a string - LLWString channel_string; - llwchar c; - do - { - c = mesg[pos+1]; - channel_string.push_back(c); - pos++; - } - while(c && pos < 64 && LLStringOps::isDigit(c)); - - // Move the pointer forward to the first non-whitespace char - // Check isspace before looping, so we can handle "/33foo" - // as well as "/33 foo" - while(c && iswspace(c)) - { - c = mesg[pos+1]; - pos++; - } - - mLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10); - *channel = mLastSpecialChatChannel; - return mesg.substr(pos, mesg.length() - pos); - } - else - { - // This is normal chat. - *channel = 0; - return mesg; - } } - diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index 780e1b270d..ffb0f9ae4f 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -34,58 +34,52 @@ #define LL_LLBOTTOMPANEL_H #include "llpanel.h" -#include "llflyoutbutton.h" #include "llimview.h" -#include "llchat.h" class LLChicletPanel; -class LLNotificationChiclet; +class LLLineEditor; class LLNotificationChiclet; class LLTalkButton; +class LLNearbyChatBar; class LLBottomTray : public LLSingleton , public LLPanel , public LLIMSessionObserver { + friend class LLSingleton; public: - LLBottomTray(); - ~LLBottomTray(); - LLLineEditor* getChatBox(); + BOOL postBuild(); - LLChicletPanel* getChicletPanel() {return mChicletPanel;}; + LLChicletPanel* getChicletPanel() {return mChicletPanel;} + LLNotificationChiclet* getIMWell() {return mIMWell;} + LLNotificationChiclet* getSysWell() {return mSysWell;} + LLNearbyChatBar* getNearbyChatBar() {return mNearbyChatBar;} - LLNotificationChiclet* getIMWell() {return mIMWell;}; - - LLNotificationChiclet* getNotificationWell(){return mNotificationWell;}; - - void onChatBoxCommit(); - void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate); - void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); - static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata); - static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata); + void onCommitGesture(LLUICtrl* ctrl); // LLIMSessionObserver observe triggers virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id); virtual void sessionRemoved(const LLUUID& session_id); + virtual void onFocusLost(); + virtual void setVisible(BOOL visible); + protected: - void sendChat( EChatType type ); - LLWString stripChannelNumber(const LLWString &mesg, S32* channel); + LLBottomTray(const LLSD& key = LLSD()); - // Which non-zero channel did we last chat on? - S32 mLastSpecialChatChannel; + void onChicletClick(LLUICtrl* ctrl); - LLChicletPanel* mChicletPanel; - LLNotificationChiclet* mIMWell; - LLNotificationChiclet* mNotificationWell; - LLTalkButton* mTalkBtn; + static void* createNearbyChatBar(void* userdata); + + LLChicletPanel* mChicletPanel; + LLNotificationChiclet* mIMWell; + LLNotificationChiclet* mSysWell; + LLTalkButton* mTalkBtn; + LLNearbyChatBar* mNearbyChatBar; }; -extern LLBottomTray* gBottomTray; -extern S32 BOTTOM_TRAY_HEIGHT; - #endif // LL_LLBOTTOMPANEL_H diff --git a/indra/newview/llbreadcrumbview.cpp b/indra/newview/llbreadcrumbview.cpp new file mode 100644 index 0000000000..342994ee30 --- /dev/null +++ b/indra/newview/llbreadcrumbview.cpp @@ -0,0 +1,37 @@ +/** + * @file llbreadcrumbview.cpp + * @brief UI widget for displaying position in a folder hierarchy and allowing + * the user to click on a location in the hierarchy. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llbreadcrumbview.h" + +// TODO diff --git a/indra/newview/llbreadcrumbview.h b/indra/newview/llbreadcrumbview.h new file mode 100644 index 0000000000..ca6fbe7fb2 --- /dev/null +++ b/indra/newview/llbreadcrumbview.h @@ -0,0 +1,36 @@ +/** + * @file llbreadcrumbview.h + * @brief UI widget for displaying position in a folder hierarchy and allowing + * the user to click on a location in the hierarchy. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#ifndef LLBREADCRUMBVIEW_H +#define LLBREADCRUMBVIEW_H + +#endif // LLBREADCRUMBVIEW_H diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 1844934e6a..355a90209a 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -684,7 +684,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) { std::string notifyMsg = notification->getMessage(); if (!notifyMsg.empty()) - floater->addHistoryLine(notifyMsg,gSavedSkinSettings.getColor4("SystemChatColor")); + floater->addHistoryLine(notifyMsg,LLUIColorTable::instance().getColor("SystemChatColor")); } } diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp new file mode 100644 index 0000000000..118385ab58 --- /dev/null +++ b/indra/newview/llchannelmanager.cpp @@ -0,0 +1,183 @@ +/** + * @file llchannelmanager.cpp + * @brief This class rules screen notification channels. + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "llchannelmanager.h" + +#include "llappviewer.h" +#include "llviewercontrol.h" + +#include + +using namespace LLNotificationsUI; + +//-------------------------------------------------------------------------- +LLChannelManager::LLChannelManager() +{ + LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLChannelManager::onLoginCompleted, this)); + mChannelList.clear(); + mStartUpChannel = NULL; +} + +//-------------------------------------------------------------------------- +LLChannelManager::~LLChannelManager() +{ + //All channels are being deleted by Parent View +} + +//-------------------------------------------------------------------------- +void LLChannelManager::onLoginCompleted() +{ + S32 hidden_notifications = 0; + + for(std::vector::iterator it = mChannelList.begin(); it != mChannelList.end(); ++it) + { + //(*it).channel->showToasts(); + hidden_notifications +=(*it).channel->getNumberOfHiddenToasts(); + } + + if(!hidden_notifications) + { + LLScreenChannel::setStartUpToastShown(); + return; + } + + LLChannelManager::Params p; + p.id = LLUUID(STARTUP_CHANNEL_ID); + p.channel_right_bound = getRootView()->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); + p.channel_width = gSavedSettings.getS32("NotifyBoxWidth"); + mStartUpChannel = createChannel(p); + + if(!mStartUpChannel) + return; + + static_cast(mStartUpChannel)->setCommitCallback(boost::bind(&LLChannelManager::enableShowToasts, this)); + mStartUpChannel->setNumberOfHiddenToasts(hidden_notifications); + mStartUpChannel->createOverflowToast(gSavedSettings.getS32("ChannelBottomPanelMargin"), gSavedSettings.getS32("StartUpToastTime")); +} + +//-------------------------------------------------------------------------- +void LLChannelManager::enableShowToasts() +{ + LLScreenChannel::setStartUpToastShown(); + delete mStartUpChannel; + mStartUpChannel = NULL; +} + +//-------------------------------------------------------------------------- +LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p) +{ + LLScreenChannel* new_channel = NULL; + + if(!p.chiclet) + { + new_channel = getChannelByID(p.id); + } + else + { + new_channel = getChannelByChiclet(p.chiclet); + } + + if(new_channel) + return new_channel; + + new_channel = new LLScreenChannel(); + getRootView()->addChild(new_channel); + new_channel->init(p.channel_right_bound - p.channel_width, p.channel_right_bound); + new_channel->setToastAlignment(p.align); + + ChannelElem new_elem; + new_elem.id = p.id; + new_elem.chiclet = p.chiclet; + new_elem.channel = new_channel; + + mChannelList.push_back(new_elem); //TODO: remove chiclet from ScreenChannel? + + return new_channel; +} + +//-------------------------------------------------------------------------- +LLScreenChannel* LLChannelManager::getChannelByID(const LLUUID id) +{ + std::vector::iterator it = find(mChannelList.begin(), mChannelList.end(), id); + if(it != mChannelList.end()) + { + return (*it).channel; + } + + return NULL; +} + +//-------------------------------------------------------------------------- +LLScreenChannel* LLChannelManager::getChannelByChiclet(const LLChiclet* chiclet) +{ + std::vector::iterator it = find(mChannelList.begin(), mChannelList.end(), chiclet); + if(it != mChannelList.end()) + { + return (*it).channel; + } + + return NULL; +} + +//-------------------------------------------------------------------------- +void LLChannelManager::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + for(std::vector::iterator it = mChannelList.begin(); it != mChannelList.end(); ++it) + { + if((*it).channel->getToastAlignment() == NA_CENTRE) + { + LLRect channel_rect = (*it).channel->getRect(); + S32 screen_width = getRootView()->getRect().getWidth(); + channel_rect.setLeftTopAndSize(screen_width/2, channel_rect.mTop, channel_rect.getWidth(), channel_rect.getHeight()); + (*it).channel->setRect(channel_rect); + (*it).channel->showToasts(); + } + } +} + +//-------------------------------------------------------------------------- + +LLScreenChannel* LLChannelManager::getStartUpChannel() +{ + return mStartUpChannel; +} + +//-------------------------------------------------------------------------- + + + + + + + diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h new file mode 100644 index 0000000000..ac8e81d7ef --- /dev/null +++ b/indra/newview/llchannelmanager.h @@ -0,0 +1,125 @@ +/** + * @file llchannelmanager.h + * @brief This class rules screen notification channels. + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLCHANNELMANAGER_H +#define LL_LLCHANNELMANAGER_H + + +#include "llchiclet.h" +#include "llscreenchannel.h" + +#include "lluuid.h" + +#include +#include + +namespace LLNotificationsUI +{ + +#define STARTUP_CHANNEL_ID "AEED3193-8709-4693-8558-7452CCA97AE5" + +/** + * Manager for screen channels. + * Responsible for instantiating and retrieving screen channels. + */ +class LLChannelManager : public LLUICtrl, public LLSingleton +{ +public: + struct Params : public LLInitParam::Block + { + Optional id; + Optional chiclet; + Optional channel_right_bound; + Optional channel_width; + Optional align; + + Params(): id("id", LLUUID("")), + chiclet("chiclet", NULL), + channel_right_bound("channel_right_bound", 0), + channel_width("channel_width", 0), + align("align", NA_BOTTOM) + {} + }; + + struct ChannelElem + { + LLUUID id; + LLChiclet* chiclet; + LLScreenChannel* channel; + + ChannelElem() : id(LLUUID("")), chiclet(NULL), channel(NULL) { } + + ChannelElem(const ChannelElem &elem) + { + id = elem.id; + chiclet = elem.chiclet; + channel = elem.channel; + } + + bool operator == (const LLUUID &id_op) const + { + return (id == id_op); + } + + bool operator == (const LLChiclet* chiclet_op) const + { + return (chiclet == chiclet_op); + } + + }; + + LLChannelManager(); + virtual ~LLChannelManager(); + + // On LoginCompleted - show StartUp toast + void onLoginCompleted(); + void enableShowToasts(); + + //TODO: make protected? in order to be shure that channels are created only by notification handlers + LLScreenChannel* createChannel(LLChannelManager::Params& p); + + LLScreenChannel* getChannelByID(const LLUUID id); + LLScreenChannel* getChannelByChiclet(const LLChiclet* chiclet); + + void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + + LLScreenChannel* getStartUpChannel(); + +private: + + LLScreenChannel* mStartUpChannel; + std::vector mChannelList; +}; + +} +#endif + diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 5e97157694..46a2179e8d 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -87,6 +87,8 @@ private: }; +extern void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); + // // Functions // @@ -110,7 +112,7 @@ LLChatBar::LLChatBar() LLChatBar::~LLChatBar() { - gGestureManager.removeObserver(mObserver); + LLGestureManager::instance().removeObserver(mObserver); delete mObserver; mObserver = NULL; // LLView destructor cleans up children @@ -211,7 +213,7 @@ void LLChatBar::refreshGestures() // collect list of unique gestures std::map unique; LLGestureManager::item_map_t::iterator it; - for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it) + for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it) { LLMultiGesture* gesture = (*it).second; if (gesture) @@ -296,7 +298,7 @@ void LLChatBar::setGestureCombo(LLComboBox* combo) // now register observer since we have a place to put the results mObserver = new LLChatBarGestureObserver(this); - gGestureManager.addObserver(mObserver); + LLGestureManager::instance().addObserver(mObserver); // refresh list from current active gestures refreshGestures(); @@ -377,7 +379,7 @@ void LLChatBar::sendChat( EChatType type ) if (0 == channel) { // discard returned "found" boolean - gGestureManager.triggerAndReviseString(utf8text, &utf8_revised_text); + LLGestureManager::instance().triggerAndReviseString(utf8text, &utf8_revised_text); } else { @@ -415,10 +417,11 @@ void LLChatBar::sendChat( EChatType type ) void LLChatBar::startChat(const char* line) { //TODO* remove DUMMY chat - if(LLBottomTray::getInstance()->getChatBox()) - { - LLBottomTray::getInstance()->getChatBox()->setFocus(TRUE); - } + //if(gBottomTray && gBottomTray->getChatBox()) + //{ + // gBottomTray->setVisible(TRUE); + // gBottomTray->getChatBox()->setFocus(TRUE); + //} // *TODO Vadim: Why was this code commented out? @@ -441,10 +444,10 @@ void LLChatBar::startChat(const char* line) void LLChatBar::stopChat() { //TODO* remove DUMMY chat - if(LLBottomTray::getInstance()->getChatBox()) - { - LLBottomTray::getInstance()->getChatBox()->setFocus(FALSE); - } + //if(gBottomTray && gBottomTray->getChatBox()) + ///{ + // gBottomTray->getChatBox()->setFocus(FALSE); + //} // *TODO Vadim: Why was this code commented out? @@ -515,7 +518,7 @@ void LLChatBar::onInputEditorKeystroke( LLLineEditor* caller, void* userdata ) std::string utf8_trigger = wstring_to_utf8str(raw_text); std::string utf8_out_str(utf8_trigger); - if (gGestureManager.matchPrefix(utf8_trigger, &utf8_out_str)) + if (LLGestureManager::instance().matchPrefix(utf8_trigger, &utf8_out_str)) { if (self->mInputEditor) { @@ -617,7 +620,7 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL send_chat_from_viewer(utf8_out_text, type, channel); } - +/* void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) { LLMessageSystem* msg = gMessageSystem; @@ -634,7 +637,7 @@ void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); } - +*/ void LLChatBar::onCommitGesture(LLUICtrl* ctrl) { @@ -652,7 +655,7 @@ void LLChatBar::onCommitGesture(LLUICtrl* ctrl) // substitution and logging. std::string text(trigger); std::string revised_text; - gGestureManager.triggerAndReviseString(text, &revised_text); + LLGestureManager::instance().triggerAndReviseString(text, &revised_text); revised_text = utf8str_trim(revised_text); if (!revised_text.empty()) @@ -688,4 +691,4 @@ public: }; // Creating the object registers with the dispatcher. -LLChatHandler gChatHandler; +//LLChatHandler gChatHandler; diff --git a/indra/newview/llchatbar.h b/indra/newview/llchatbar.h index e0e324af6b..a41947218d 100644 --- a/indra/newview/llchatbar.h +++ b/indra/newview/llchatbar.h @@ -45,8 +45,6 @@ class LLFrameTimer; class LLChatBarGestureObserver; class LLComboBox; -// legacy calllback glue -void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); class LLChatBar : public LLPanel diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp new file mode 100644 index 0000000000..2b455485ca --- /dev/null +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -0,0 +1,585 @@ +/** + * @file llchatitemscontainer.cpp + * @brief chat history scrolling panel implementation + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llchatitemscontainerctrl.h" +#include "lltextbox.h" + +#include "llchatmsgbox.h" +#include "llavatariconctrl.h" +#include "llfloaterreg.h" +#include "lltrans.h" + +#include "llviewercontrol.h" +#include "llagentdata.h" + +static const S32 BORDER_MARGIN = 2; +static const S32 PARENT_BORDER_MARGIN = 0; + +static const S32 HORIZONTAL_MULTIPLE = 8; +static const S32 VERTICAL_MULTIPLE = 16; +static const F32 MIN_AUTO_SCROLL_RATE = 120.f; +static const F32 MAX_AUTO_SCROLL_RATE = 500.f; +static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; + +static const S32 msg_left_offset = 30; +static const S32 msg_right_offset = 10; + +#define MAX_CHAT_HISTORY 100 + + +static LLDefaultChildRegistry::Register t2("chat_items_container"); + + + +//******************************************************************************************************************* +//LLChatItemCtrl +//******************************************************************************************************************* + +LLChatItemCtrl* LLChatItemCtrl::createInstance() +{ + LLChatItemCtrl* item = new LLChatItemCtrl(); + LLUICtrlFactory::getInstance()->buildPanel(item, "panel_chat_item.xml"); + return item; +} + +void LLChatItemCtrl::draw() +{ + LLPanel::draw(); +} + +void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent ) +{ + LLPanel::reshape(width, height,called_from_parent); + + LLPanel* caption = getChild("msg_caption",false,false); + LLChatMsgBox* msg_text = getChild("msg_text",false,false); + if(caption && msg_text) + { + LLRect caption_rect = caption->getRect(); + caption_rect.setLeftTopAndSize( 2, height, width - 4, caption_rect.getHeight()); + caption->reshape( width - 4, caption_rect.getHeight(), 1); + caption->setRect(caption_rect); + + + LLRect msg_text_rect = msg_text->getRect(); + msg_text_rect.setLeftTopAndSize( msg_left_offset, height - caption_rect.getHeight() , width - msg_left_offset - msg_right_offset, height - caption_rect.getHeight()); + msg_text->reshape( width - msg_left_offset - msg_right_offset, height - caption_rect.getHeight(), 1); + msg_text->setRect(msg_text_rect); + } + +} + +BOOL LLChatItemCtrl::postBuild() +{ + return LLPanel::postBuild(); +} + + +std::string LLChatItemCtrl::appendTime() +{ + time_t utc_time; + utc_time = time_corrected(); + std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" + +LLTrans::getString("TimeMin")+"] "; + + LLSD substitution; + + substitution["datetime"] = (S32) utc_time; + LLStringUtil::format (timeStr, substitution); + + return timeStr; +} + + + +void LLChatItemCtrl::addText (const std::string& message) +{ + LLChatMsgBox* msg_text = getChild("msg_text",false,false); + if(msg_text) + msg_text->addText(message); + mMessages.push_back(message); +} + +void LLChatItemCtrl::setMessage (const LLChat& msg) +{ + LLPanel* caption = getChild("msg_caption",false,false); + if(!caption) + return; + + std::string str_sender; + + + if(gAgentID != msg.mFromID) + str_sender = msg.mFromName; + else + str_sender = LLTrans::getString("You");; + + caption->getChild("sender_name",false,false)->setText(str_sender); + + std::string tt = appendTime(); + + caption->getChild("msg_time",false,false)->setText(tt); + + + caption->getChild("avatar_icon",false,false)->setValue(msg.mFromID); + + mOriginalMessage = msg; + + LLChatMsgBox* msg_text = getChild("msg_text",false,false); + if(msg_text) + msg_text->setText(msg.mText); + + LLUICtrl* msg_inspector = caption->getChild("msg_inspector"); + if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT) + msg_inspector->setVisible(false); + + mMessages.clear(); + +} + +void LLChatItemCtrl::snapToMessageHeight () +{ + LLChatMsgBox* text_box = getChild("msg_text",false,false); + if(!text_box) + return;///actually assert fits better + S32 new_height = text_box->getTextPixelHeight(); + LLRect panel_rect = getRect(); + + S32 caption_height = 0; + LLPanel* caption = getChild("msg_caption",false,false); + if(caption) + caption_height = caption->getRect().getHeight(); + + + panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth() , caption_height + new_height); + + reshape( getRect().getWidth(), caption_height + new_height, 1); + + setRect(panel_rect); + +} + + +void LLChatItemCtrl::setWidth(S32 width) +{ + LLChatMsgBox* text_box = getChild("msg_text",false,false); + if(!text_box) + return;///actually assert fits better + + text_box->reshape(width - msg_left_offset - msg_right_offset,100/*its not magic number, we just need any number*/); + + LLChatMsgBox* msg_text = getChild("msg_text",false,false); + if(msg_text && mOriginalMessage.mText.length()) + msg_text->setText(mOriginalMessage.mText); + + for(size_t i=0;iaddText(mMessages[i]); + + setRect(LLRect(getRect().mLeft, getRect().mTop, getRect().mLeft + width , getRect().mBottom)); + snapToMessageHeight (); +} + +void LLChatItemCtrl::onMouseLeave (S32 x, S32 y, MASK mask) +{ + LLPanel* caption = getChild("msg_caption",false,false); + if(!caption) + return; + LLUICtrl* msg_inspector = caption->getChild("msg_inspector"); + if(msg_inspector) + msg_inspector->setVisible(false); + +} +void LLChatItemCtrl::onMouseEnter (S32 x, S32 y, MASK mask) +{ + if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT) + return; + LLPanel* caption = getChild("msg_caption",false,false); + if(!caption) + return; + LLUICtrl* msg_inspector = caption->getChild("msg_inspector"); + if(msg_inspector) + msg_inspector->setVisible(true); +} + +BOOL LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask) +{ + if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT) + return LLPanel::handleMouseDown(x,y,mask); + LLPanel* caption = getChild("msg_caption",false,false); + if(caption) + { + LLUICtrl* msg_inspector = caption->getChild("msg_inspector"); + if(msg_inspector) + { + S32 local_x = x - msg_inspector->getRect().mLeft - caption->getRect().mLeft; + S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom; + if(msg_inspector->pointInView(local_x, local_y)) + { + LLFloaterReg::showInstance("mini_inspector", mOriginalMessage.mFromID); + } + } + } + return LLPanel::handleMouseDown(x,y,mask); +} + +void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e) +{ + LLPanel* caption = getChild("msg_caption",false,false); + if(!caption) + return; + + LLUICtrl* icon = caption->getChild("avatar_icon",false,false); + LLUICtrl* name = caption->getChild("sender_name",false,false); + + if(icon == 0 || name == 0) + return; + + icon->setVisible(e == CHATITEMHEADER_SHOW_ONLY_ICON || e==CHATITEMHEADER_SHOW_BOTH); + name->setVisible(e == CHATITEMHEADER_SHOW_ONLY_NAME || e==CHATITEMHEADER_SHOW_BOTH); + +} + +bool LLChatItemCtrl::canAddText () +{ + LLChatMsgBox* msg_text = getChild("msg_text",false,false); + if(!msg_text ) + return false; + return msg_text->getTextLinesNum()<10; +} + +BOOL LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + LLPanel* caption = getChild("msg_caption",false,false); + if(!caption) + return LLPanel::handleRightMouseDown(x,y,mask); + LLUICtrl* avatar_icon = caption->getChild("avatar_icon",false,false); + if(!avatar_icon) + return LLPanel::handleRightMouseDown(x,y,mask); + S32 local_x = x - avatar_icon->getRect().mLeft - caption->getRect().mLeft; + S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom; + + //eat message for avatar icon if msg was from object + if(avatar_icon->pointInView(local_x, local_y) && mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT) + return TRUE; + return LLPanel::handleRightMouseDown(x,y,mask); +} + + +//******************************************************************************************************************* +//LLChatItemsContainerCtrl +//******************************************************************************************************************* + +LLChatItemsContainerCtrl::LLChatItemsContainerCtrl(const Params& params):LLPanel(params) +{ + mEShowItemHeader = CHATITEMHEADER_SHOW_BOTH; +} + + +void LLChatItemsContainerCtrl::addMessage(const LLChat& msg) +{ + /* + if(msg.mChatType == CHAT_TYPE_DEBUG_MSG) + return; + */ + if(mItems.size() >= MAX_CHAT_HISTORY) + { + LLChatItemCtrl* item = mItems[0]; + removeChild(item); + delete item; + mItems.erase(mItems.begin()); + } + + + if(mItems.size() > 0 + && msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID + && (msg.mTime-mItems[mItems.size()-1]->getMessage().mTime)<60 + && mItems[mItems.size()-1]->canAddText() + ) + { + mItems[mItems.size()-1]->addText(msg.mText); + mItems[mItems.size()-1]->snapToMessageHeight(); + } + else + { + LLChatItemCtrl* item = LLChatItemCtrl::createInstance(); + mItems.push_back(item); + addChild(item,0); + item->setWidth(getRect().getWidth() - 16); + item->setMessage(msg); + item->snapToMessageHeight(); + + item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names")); + + item->setVisible(true); + } + + arrange(getRect().getWidth(),getRect().getHeight()); + updateLayout(getRect().getWidth(),getRect().getHeight()); + scrollToBottom(); +} + +void LLChatItemsContainerCtrl::scrollToBottom () +{ + if(mScrollbar->getVisible()) + { + mScrollbar->setDocPos(mScrollbar->getDocPosMax()); + onScrollPosChangeCallback(0,0); + } +} + +void LLChatItemsContainerCtrl::draw() +{ + LLLocalClipRect clip(getRect()); + LLPanel::draw(); +} + +void LLChatItemsContainerCtrl::reshape (S32 width, S32 height, BOOL called_from_parent ) +{ + S32 delta_width = width - getRect().getWidth(); + S32 delta_height = height - getRect().getHeight(); + + if (delta_width || delta_height || sForceReshape) + { + arrange(width, height); + } + + updateBoundingRect(); +} + +void LLChatItemsContainerCtrl::arrange (S32 width, S32 height) +{ + S32 delta_width = width - getRect().getWidth(); + if(delta_width)//width changed...too bad. now we need to reformat all items + reformatHistoryScrollItems(width); + + calcRecuiredHeight(); + + show_hide_scrollbar(width,height); + + updateLayout(width,height); +} + +void LLChatItemsContainerCtrl::reformatHistoryScrollItems(S32 width) +{ + for(std::vector::iterator it = mItems.begin(); it != mItems.end();++it) + { + (*it)->setWidth(width); + } +} + +S32 LLChatItemsContainerCtrl::calcRecuiredHeight () +{ + S32 rec_height = 0; + + std::vector::iterator it; + for(it=mItems.begin(); it!=mItems.end(); ++it) + { + rec_height += (*it)->getRect().getHeight(); + } + + mInnerRect.setLeftTopAndSize(0,rec_height + BORDER_MARGIN*2,getRect().getWidth(),rec_height + BORDER_MARGIN); + + return mInnerRect.getHeight(); +} + + +void LLChatItemsContainerCtrl::updateLayout (S32 width, S32 height) +{ + S32 panel_top = height - BORDER_MARGIN ; + S32 panel_width = width; + if(mScrollbar->getVisible()) + { + static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); + + panel_top+=mScrollbar->getDocPos(); + panel_width-=scrollbar_size; + } + + + //set sizes for first panels and dragbars + for(size_t i=0;igetRect(); + panelSetLeftTopAndSize(mItems[i],panel_rect.mLeft,panel_top,panel_width,panel_rect.getHeight()); + panel_top-=panel_rect.getHeight(); + } +} + +void LLChatItemsContainerCtrl::show_hide_scrollbar (S32 width, S32 height) +{ + calcRecuiredHeight(); + if(getRecuiredHeight() > height ) + showScrollbar(width, height); + else + hideScrollbar(width, height); +} + +void LLChatItemsContainerCtrl::showScrollbar (S32 width, S32 height) +{ + bool was_visible = mScrollbar->getVisible(); + + mScrollbar->setVisible(true); + + static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); + + panelSetLeftTopAndSize(mScrollbar,width-scrollbar_size + ,height-PARENT_BORDER_MARGIN,scrollbar_size,height-2*PARENT_BORDER_MARGIN); + + mScrollbar->setPageSize(height); + mScrollbar->setDocParams(mInnerRect.getHeight(),mScrollbar->getDocPos()); + + if(was_visible) + { + S32 scroll_pos = llmin(mScrollbar->getDocPos(), getRecuiredHeight() - height - 1); + mScrollbar->setDocPos(scroll_pos); + updateLayout(width,height); + return; + } +} + +void LLChatItemsContainerCtrl::hideScrollbar (S32 width, S32 height) +{ + if(mScrollbar->getVisible() == false) + return; + mScrollbar->setVisible(false); + + mScrollbar->setDocPos(0); + + if(mItems.size()>0) + { + S32 panel_top = height - BORDER_MARGIN; // Top coordinate of the first panel + S32 diff = panel_top - mItems[0]->getRect().mTop; + shiftPanels(diff); + } +} + +//--------------------------------------------------------------------------------- +void LLChatItemsContainerCtrl::panelSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S32 width, S32 height) +{ + if(!panel) + return; + LLRect panel_rect = panel->getRect(); + panel_rect.setLeftTopAndSize( left, top, width, height); + panel->reshape( width, height, 1); + panel->setRect(panel_rect); +} + +void LLChatItemsContainerCtrl::panelShiftVertical(LLView* panel,S32 delta) +{ + if(!panel) + return; + panel->translate(0,delta); +} + +void LLChatItemsContainerCtrl::shiftPanels(S32 delta) +{ + //Arrange panels + for(std::vector::iterator it = mItems.begin(); it != mItems.end();++it) + { + panelShiftVertical((*it),delta); + } + +} + +//--------------------------------------------------------------------------------- + +void LLChatItemsContainerCtrl::onScrollPosChangeCallback(S32, LLScrollbar*) +{ + updateLayout(getRect().getWidth(),getRect().getHeight()); +} + +BOOL LLChatItemsContainerCtrl::postBuild() +{ + static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); + + LLRect scroll_rect; + scroll_rect.setOriginAndSize( + getRect().getWidth() - scrollbar_size, + 1, + scrollbar_size, + getRect().getHeight() - 1); + + + LLScrollbar::Params sbparams; + sbparams.name("scrollable vertical"); + sbparams.rect(scroll_rect); + sbparams.orientation(LLScrollbar::VERTICAL); + sbparams.doc_size(mInnerRect.getHeight()); + sbparams.doc_pos(0); + sbparams.page_size(mInnerRect.getHeight()); + sbparams.step_size(VERTICAL_MULTIPLE); + sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); + sbparams.change_callback(boost::bind(&LLChatItemsContainerCtrl::onScrollPosChangeCallback, this, _1, _2)); + + mScrollbar = LLUICtrlFactory::create (sbparams); + LLView::addChild( mScrollbar ); + mScrollbar->setVisible( true ); + mScrollbar->setFollowsRight(); + mScrollbar->setFollowsTop(); + mScrollbar->setFollowsBottom(); + + reformatHistoryScrollItems(getRect().getWidth()); + arrange(getRect().getWidth(),getRect().getHeight()); + + return LLPanel::postBuild(); +} +BOOL LLChatItemsContainerCtrl::handleMouseDown (S32 x, S32 y, MASK mask) +{ + return LLPanel::handleMouseDown(x,y,mask); +} +BOOL LLChatItemsContainerCtrl::handleKeyHere (KEY key, MASK mask) +{ + if( mScrollbar->getVisible() && mScrollbar->handleKeyHere( key,mask ) ) + return TRUE; + return LLPanel::handleKeyHere(key,mask); +} +BOOL LLChatItemsContainerCtrl::handleScrollWheel ( S32 x, S32 y, S32 clicks ) +{ + if( mScrollbar->getVisible() && mScrollbar->handleScrollWheel( 0, 0, clicks ) ) + return TRUE; + return false; +} + +void LLChatItemsContainerCtrl::setHeaderVisibility(EShowItemHeader e) +{ + if(e == mEShowItemHeader) + return; + mEShowItemHeader = e; + for(std::vector::iterator it = mItems.begin(); it != mItems.end();++it) + { + (*it)->setHeaderVisibility(e); + } +} + + diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h new file mode 100644 index 0000000000..de16cf9505 --- /dev/null +++ b/indra/newview/llchatitemscontainerctrl.h @@ -0,0 +1,154 @@ +/** + * @file llchatitemscontainer.h + * @brief chat history scrolling panel implementation + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLCHATITEMSCONTAINER_H_ +#define LL_LLCHATITEMSCONTAINER_H_ + +#include "llpanel.h" +#include "llscrollbar.h" +#include "string" +#include "llchat.h" + +typedef enum e_show_item_header +{ + CHATITEMHEADER_SHOW_ONLY_NAME = 0, + CHATITEMHEADER_SHOW_ONLY_ICON = 1, + CHATITEMHEADER_SHOW_BOTH +} EShowItemHeader; + +class LLChatItemCtrl: public LLPanel +{ +protected: + LLChatItemCtrl(){}; +public: + + + ~LLChatItemCtrl(){} + + static LLChatItemCtrl* createInstance(); + + void draw(); + + const LLChat& getMessage() const { return mOriginalMessage;} + + void addText (const std::string& message); + void setMessage (const LLChat& msg); + void setWidth (S32 width); + void snapToMessageHeight (); + + bool canAddText (); + + void onMouseLeave (S32 x, S32 y, MASK mask); + void onMouseEnter (S32 x, S32 y, MASK mask); + BOOL handleMouseDown (S32 x, S32 y, MASK mask); + + virtual BOOL postBuild(); + + void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE); + + void setHeaderVisibility(EShowItemHeader e); + BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); +private: + + std::string appendTime (); + +private: + LLChat mOriginalMessage; + + std::vector mMessages; +}; + +class LLChatItemsContainerCtrl: public LLPanel +{ +public: + struct Params + : public LLInitParam::Block + { + Params(){}; + }; + + LLChatItemsContainerCtrl(const Params& params); + + + ~LLChatItemsContainerCtrl(){} + + void addMessage (const LLChat& msg); + + void draw(); + + void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE); + + void onScrollPosChangeCallback(S32, LLScrollbar*); + + virtual BOOL postBuild(); + + BOOL handleMouseDown (S32 x, S32 y, MASK mask); + BOOL handleKeyHere (KEY key, MASK mask); + BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); + + void scrollToBottom (); + + void setHeaderVisibility(EShowItemHeader e); + EShowItemHeader getHeaderVisibility() const { return mEShowItemHeader;}; + + +private: + void reformatHistoryScrollItems(S32 width); + void arrange (S32 width, S32 height); + + S32 calcRecuiredHeight (); + S32 getRecuiredHeight () const { return mInnerRect.getHeight(); } + + void updateLayout (S32 width, S32 height); + + void show_hide_scrollbar (S32 width, S32 height); + + void showScrollbar (S32 width, S32 height); + void hideScrollbar (S32 width, S32 height); + + void panelSetLeftTopAndSize (LLView* panel, S32 left, S32 top, S32 width, S32 height); + void panelShiftVertical (LLView* panel,S32 delta); + void shiftPanels (S32 delta); + +private: + std::vector mItems; + + EShowItemHeader mEShowItemHeader; + + LLRect mInnerRect; + LLScrollbar* mScrollbar; + +}; + +#endif + + diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp new file mode 100644 index 0000000000..933d9b8771 --- /dev/null +++ b/indra/newview/llchatmsgbox.cpp @@ -0,0 +1,389 @@ +/** + * @file llchatmsgbox.cpp + * @brief chat history text box, able to show array of strings with separator + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" + +#include "llchatmsgbox.h" +#include "llwindow.h" +#include "llfocusmgr.h" + +static LLDefaultChildRegistry::Register r("text_chat"); + +LLChatMsgBox::Params::Params() +: text_color("text_color"), + highlight_on_hover("hover", false), + border_visible("border_visible", false), + border_drop_shadow_visible("border_drop_shadow_visible", false), + bg_visible("bg_visible", false), + use_ellipses("use_ellipses"), + word_wrap("word_wrap", false), + hover_color("hover_color"), + disabled_color("disabled_color"), + background_color("background_color"), + border_color("border_color"), + line_spacing("line_spacing", 4), + block_spacing("block_spacing",10), + text("text"), + font_shadow("font_shadow", LLFontGL::NO_SHADOW) +{} + +LLChatMsgBox::LLChatMsgBox(const LLChatMsgBox::Params& p) +: LLUICtrl(p), + mFontGL(p.font), + mHoverActive( p.highlight_on_hover ), + mHasHover( FALSE ), + mBackgroundVisible( p.bg_visible ), + mBorderVisible( p.border_visible ), + mShadowType( p.font_shadow ), + mBorderDropShadowVisible( p.border_drop_shadow_visible ), + mUseEllipses( p.use_ellipses ), + mVAlign( LLFontGL::TOP ), + mClickedCallback(NULL), + mTextColor(p.text_color()), + mDisabledColor(p.disabled_color()), + mBackgroundColor(p.background_color()), + mBorderColor(p.border_color()), + mHoverColor(p.hover_color()), + mHAlign(p.font_halign), + mLineSpacing(p.line_spacing), + mBlockSpasing(p.block_spacing), + mWordWrap( p.word_wrap ), + mFontStyle(LLFontGL::getStyleFromString(p.font.style)) +{ + setText( p.text() ); +} + +BOOL LLChatMsgBox::handleMouseDown(S32 x, S32 y, MASK mask) +{ + BOOL handled = FALSE; + + // HACK: Only do this if there actually is a click callback, so that + // overly large text boxes in the older UI won't start eating clicks. + if (mClickedCallback) + { + handled = TRUE; + + // Route future Mouse messages here preemptively. (Release on mouse up.) + gFocusMgr.setMouseCapture( this ); + + if (getSoundFlags() & MOUSE_DOWN) + { + make_ui_sound("UISndClick"); + } + } + + return handled; +} + +BOOL LLChatMsgBox::handleMouseUp(S32 x, S32 y, MASK mask) +{ + BOOL handled = FALSE; + + // We only handle the click if the click both started and ended within us + + // HACK: Only do this if there actually is a click callback, so that + // overly large text boxes in the older UI won't start eating clicks. + if (mClickedCallback + && hasMouseCapture()) + { + handled = TRUE; + + // Release the mouse + gFocusMgr.setMouseCapture( NULL ); + + if (getSoundFlags() & MOUSE_UP) + { + make_ui_sound("UISndClickRelease"); + } + + // DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked. + // If mouseup in the widget, it's been clicked + if (mClickedCallback) + { + mClickedCallback(); + } + } + + return handled; +} + +BOOL LLChatMsgBox::handleHover(S32 x, S32 y, MASK mask) +{ + BOOL handled = LLView::handleHover(x,y,mask); + if(mHoverActive) + { + mHasHover = TRUE; // This should be set every frame during a hover. + getWindow()->setCursor(UI_CURSOR_ARROW); + } + + return (handled || mHasHover); +} + +void LLChatMsgBox::addText( const LLStringExplicit& text ) +{ + boost::shared_ptr t(new text_block()); + t->text = wrapText(text); + setLineLengths(*t); + mTextStrings.push_back(t); +} + +void LLChatMsgBox::setText(const LLStringExplicit& text) +{ + mTextStrings.clear(); + + addText(text); + +} + +void LLChatMsgBox::resetLineLengths() +{ + for(std::vector< boost::shared_ptr >::iterator it = mTextStrings.begin(); + it!=mTextStrings.end();++it) + { + boost::shared_ptr tblock = *it; + setLineLengths(*tblock); + } +} + +void LLChatMsgBox::setLineLengths(text_block& t) +{ + t.lines.clear(); + + std::string::size_type cur = 0; + std::string::size_type len = t.text.length(); + + while (cur < len) + { + std::string::size_type end = t.text.getWString().find('\n', cur); + std::string::size_type runLen; + + if (end == std::string::npos) + { + runLen = len - cur; + cur = len; + } + else + { + runLen = end - cur; + cur = end + 1; // skip the new line character + } + + t.lines.push_back( (S32)runLen ); + } +} + +std::string LLChatMsgBox::wrapText(const LLStringExplicit& in_text, F32 max_width) +{ + if (max_width < 0.0f) + { + max_width = (F32)getRect().getWidth(); + } + + LLWString wtext = utf8str_to_wstring(in_text); + LLWString final_wtext; + + LLWString::size_type cur = 0;; + LLWString::size_type len = wtext.size(); + while (cur < len) + { + LLWString::size_type end = wtext.find('\n', cur); + if (end == LLWString::npos) + { + end = len; + } + + LLWString::size_type runLen = end - cur; + if (runLen > 0) + { + LLWString run(wtext, cur, runLen); + LLWString::size_type useLen = + mFontGL->maxDrawableChars(run.c_str(), max_width, runLen, TRUE); + + final_wtext.append(wtext, cur, useLen); + cur += useLen; + // not enough room to add any more characters + if (useLen == 0) break; + } + + if (cur < len) + { + if (wtext[cur] == '\n') + cur += 1; + else + final_wtext += '\n'; + } + } + + std::string final_text = wstring_to_utf8str(final_wtext); + return final_text; +} + +S32 LLChatMsgBox::getTextLinesNum() +{ + S32 num_lines = 0; + for(std::vector< boost::shared_ptr >::iterator it = mTextStrings.begin(); + it!=mTextStrings.end();++it) + { + boost::shared_ptr tblock = *it; + num_lines+=tblock->lines.size(); + } + + if( num_lines < 1 ) + { + num_lines = 1; + } + + return num_lines; +} + +S32 LLChatMsgBox::getTextPixelHeight() +{ + S32 num_lines = getTextLinesNum(); + return (S32)(num_lines * mFontGL->getLineHeight() + (num_lines-1)*mLineSpacing + mBlockSpasing*(mTextStrings.size()-1) + 2*mLineSpacing);//some extra space +} + +void LLChatMsgBox::setValue(const LLSD& value ) +{ + setText(value.asString()); +} + + +void LLChatMsgBox::draw() +{ + if (mBorderVisible) + { + gl_rect_2d_offset_local(getLocalRect(), 2, FALSE); + } + + if( mBorderDropShadowVisible ) + { + static LLUICachedControl color_drop_shadow ("ColorDropShadow", *(new LLColor4)); + static LLUICachedControl drop_shadow_tooltip ("DropShadowTooltip", 0); + gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, + color_drop_shadow, drop_shadow_tooltip); + } + + if (mBackgroundVisible) + { + LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 ); + gl_rect_2d( r, mBackgroundColor.get() ); + } + + S32 text_x = 0; + switch( mHAlign ) + { + case LLFontGL::LEFT: + break; + case LLFontGL::HCENTER: + text_x = getRect().getWidth() / 2; + break; + case LLFontGL::RIGHT: + text_x = getRect().getWidth() ; + break; + } + + S32 text_y = getRect().getHeight() ; + + if ( getEnabled() ) + { + if(mHasHover) + { + drawText( text_x, text_y, mHoverColor.get() ); + } + else + { + drawText( text_x, text_y, mTextColor.get() ); + } + } + else + { + drawText( text_x, text_y, mDisabledColor.get() ); + } + + if (sDebugRects) + { + drawDebugRect(); + } + + //// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview) + //std::set::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this); + //if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights)) + //{ + // drawDebugRect(); + //} + + mHasHover = FALSE; // This is reset every frame. +} + +void LLChatMsgBox::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + // reparse line lengths + LLView::reshape(width, height, called_from_parent); + resetLineLengths(); +} + +void LLChatMsgBox::drawText( S32 x, S32 y, const LLColor4& color ) +{ + S32 width = getRect().getWidth()-10; + + + for(std::vector< boost::shared_ptr >::iterator it = mTextStrings.begin(); + it!=mTextStrings.end();++it) + { + boost::shared_ptr tblock = *it; + + S32 cur_pos = 0; + for (std::vector::iterator iter = tblock->lines.begin(); + iter != tblock->lines.end(); ++iter) + { + S32 line_length = *iter; + mFontGL->render(tblock->text, cur_pos, (F32)x, (F32)y, color, + mHAlign, mVAlign, + mFontStyle, + mShadowType, + line_length, getRect().getWidth(), NULL, TRUE, mUseEllipses ); + cur_pos += line_length + 1; + y -= llfloor(mFontGL->getLineHeight()) + mLineSpacing; + + } + std::vector< boost::shared_ptr >::iterator next = it; + ++next; + if(next == mTextStrings.end()) + break; + //separator + gl_line_2d(5,y-mBlockSpasing/2,width,y-mBlockSpasing/2,LLColor4::grey); + y-=mBlockSpasing; + } + +} + diff --git a/indra/newview/llchatmsgbox.h b/indra/newview/llchatmsgbox.h new file mode 100644 index 0000000000..61035499c7 --- /dev/null +++ b/indra/newview/llchatmsgbox.h @@ -0,0 +1,160 @@ +/** + * @file llchatmsgbox.h + * @brief chat history text box, able to show array of strings with separator + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLCHATMSGBOX_H +#define LL_LLCHATMSGBOX_H + + +#include "lluictrl.h" +#include "v4color.h" +#include "llstring.h" +#include "lluistring.h" + + +class LLChatMsgBox +: public LLUICtrl +{ +protected: + struct text_block + { + LLUIString text; + std::vector lines; + }; +public: + typedef boost::function callback_t; + + struct Params : public LLInitParam::Block + { + Optional text; + + Optional highlight_on_hover, + border_visible, + border_drop_shadow_visible, + bg_visible, + use_ellipses, + word_wrap; + + Optional font_shadow; + + Optional text_color, + hover_color, + disabled_color, + background_color, + border_color; + + Optional line_spacing; + + Optional block_spacing; + + Params(); + }; +protected: + LLChatMsgBox(const Params&); + friend class LLUICtrlFactory; +public: + virtual void draw(); + virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + virtual BOOL handleHover(S32 x, S32 y, MASK mask); + + void setColor( const LLColor4& c ) { mTextColor = c; } + void setDisabledColor( const LLColor4& c) { mDisabledColor = c; } + void setBackgroundColor( const LLColor4& c) { mBackgroundColor = c; } + void setBorderColor( const LLColor4& c) { mBorderColor = c; } + + void setHoverColor( const LLColor4& c ) { mHoverColor = c; } + void setHoverActive( BOOL active ) { mHoverActive = active; } + + void setText( const LLStringExplicit& text ); + void addText( const LLStringExplicit& text ); + + void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; } + + void setBackgroundVisible(BOOL visible) { mBackgroundVisible = visible; } + void setBorderVisible(BOOL visible) { mBorderVisible = visible; } + void setBorderDropshadowVisible(BOOL visible){ mBorderDropShadowVisible = visible; } + void setRightAlign() { mHAlign = LLFontGL::RIGHT; } + void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } + void setClickedCallback( boost::function cb, void* userdata = NULL ){ mClickedCallback = boost::bind(cb, userdata); } // mouse down and up within button + + const LLFontGL* getFont() const { return mFontGL; } + + S32 getTextPixelHeight(); + S32 getTextLinesNum(); + + virtual void setValue(const LLSD& value ); + + + +private: + std::string wrapText (const LLStringExplicit& in_text, F32 max_width = -1.0); + + void setLineLengths (text_block& t); + void resetLineLengths (); + void drawText (S32 x, S32 y, const LLColor4& color ); + + const LLFontGL* mFontGL; + LLUIColor mTextColor; + LLUIColor mDisabledColor; + LLUIColor mBackgroundColor; + LLUIColor mBorderColor; + LLUIColor mHoverColor; + + BOOL mHoverActive; + BOOL mHasHover; + BOOL mBackgroundVisible; + BOOL mBorderVisible; + BOOL mWordWrap; + + U8 mFontStyle; // style bit flags for font + LLFontGL::ShadowType mShadowType; + BOOL mBorderDropShadowVisible; + BOOL mUseEllipses; + + S32 mLineSpacing; + S32 mBlockSpasing; + + LLFontGL::HAlign mHAlign; + LLFontGL::VAlign mVAlign; + + callback_t mClickedCallback; + + + //same as mLineLengthList and mText in LLTextBox + std::vector< boost::shared_ptr > mTextStrings; + +}; + +#endif + diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index d8e844d291..3b88bcfe20 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -32,72 +32,61 @@ #include "llviewerprecompiledheaders.h" // must be first include #include "llchiclet.h" -#include "llfloaterreg.h" -#include "llvoiceclient.h" #include "llagent.h" -#include "lltextbox.h" -#include "lliconctrl.h" -#include "llvoicecontrolpanel.h" -#include "lloutputmonitorctrl.h" -#include "llimview.h" +#include "llavataractions.h" #include "llbottomtray.h" +#include "llgroupactions.h" +#include "lliconctrl.h" +#include "llimpanel.h" // LLFloaterIMPanel +#include "llimview.h" +#include "llfloatergroupinfo.h" +#include "llfloaterreg.h" +#include "llmenugl.h" +#include "lloutputmonitorctrl.h" +#include "lltextbox.h" +#include "llvoiceclient.h" +#include "llvoicecontrolpanel.h" -static const S32 CHICLET_HEIGHT = 25; -static const S32 CHICLET_SPACING = 0; -static const S32 CHICLET_PADDING = 3; -static const S32 AVATAR_WIDTH = 25; -static const S32 SPEAKER_WIDTH = 20; -static const S32 COUNTER_WIDTH = 20; -static const S32 SCROLL_BUTTON_WIDTH = 19; -static const S32 SCROLL_BUTTON_HEIGHT = 20; -static const S32 NOTIFICATION_TEXT_TOP_PAD = 5; +static const std::string P2P_MENU_NAME = "IMChiclet P2P Menu"; +static const std::string GROUP_MENU_NAME = "IMChiclet Group Menu"; -static LLDefaultWidgetRegistry::Register t1("chiclet_panel"); -static LLDefaultWidgetRegistry::Register t2("chiclet_talk"); -static LLDefaultWidgetRegistry::Register t3("chiclet_notification"); -static LLDefaultWidgetRegistry::Register t4("chiclet_panel"); +static LLDefaultChildRegistry::Register t1("chiclet_panel"); +static LLDefaultChildRegistry::Register t2("chiclet_talk"); +static LLDefaultChildRegistry::Register t3("chiclet_notification"); +static LLDefaultChildRegistry::Register t4("chiclet_im"); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// LLNotificationChiclet::Params::Params() -: image_unselected("image_unselected") -, image_selected("image_selected") -, image_overlay("image_overlay") +: button("button") +, unread_notifications("unread_notifications") { + button.name("button"); + button.tab_stop(FALSE); + button.label(LLStringUtil::null); + + unread_notifications.name("unread"); + unread_notifications.font(LLFontGL::getFontSansSerif()); + unread_notifications.text_color=(LLColor4::white); + unread_notifications.font_halign(LLFontGL::HCENTER); + unread_notifications.mouse_opaque(FALSE); } LLNotificationChiclet::LLNotificationChiclet(const Params& p) : LLChiclet(p) , mButton(NULL) -, mCounterText(NULL) +, mCounterCtrl(NULL) { - LLRect rc(p.rect); - - LLButton::Params button_params; - button_params.name("btn"); - button_params.label(LLStringUtil::null); - button_params.rect(LLRect(0,rc.getHeight(),rc.getWidth(),0)); - button_params.image_overlay(p.image_overlay); - button_params.image_unselected(p.image_unselected); - button_params.image_selected(p.image_selected); - button_params.tab_stop(false); + LLButton::Params button_params = p.button; + button_params.rect(p.rect()); mButton = LLUICtrlFactory::create(button_params); addChild(mButton); - LLTextBox::Params textbox_params; - textbox_params.name("txt"); - textbox_params.rect(LLRect(p.label_left,rc.getHeight(), - rc.getWidth()-p.label_left,0)); - textbox_params.mouse_opaque(false); - textbox_params.v_pad(NOTIFICATION_TEXT_TOP_PAD); - textbox_params.font.style("SansSerif"); - textbox_params.font_halign(LLFontGL::HCENTER); - mCounterText = LLUICtrlFactory::create(textbox_params); - addChild(mCounterText); - mCounterText->setColor(LLColor4::white); - mCounterText->setText(LLStringUtil::null); + LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; + mCounterCtrl = LLUICtrlFactory::create(unread_params); + addChild(mCounterCtrl); } LLNotificationChiclet::~LLNotificationChiclet() @@ -105,18 +94,15 @@ LLNotificationChiclet::~LLNotificationChiclet() } -LLChiclet* LLNotificationChiclet::create(const Params& p) -{ - LLChiclet* chiclet = new LLNotificationChiclet(p); - return chiclet; -} - void LLNotificationChiclet::setCounter(S32 counter) { - std::stringstream stream; - mCounter = counter; - stream << mCounter; - mCounterText->setText(stream.str()); + mCounterCtrl->setCounter(counter); +} + +void LLNotificationChiclet::setShowCounter(bool show) +{ + LLChiclet::setShowCounter(show); + mCounterCtrl->setVisible(getShowCounter()); } boost::signals2::connection LLNotificationChiclet::setClickCallback( @@ -129,10 +115,16 @@ boost::signals2::connection LLNotificationChiclet::setClickCallback( ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +LLChiclet::Params::Params() + : show_counter("show_counter") +{ + show_counter = true; +} + LLChiclet::LLChiclet(const Params& p) : LLUICtrl(p) -, mCounter(0) -, mShowCounter(true) +, mSessionId(LLUUID::null) +, mShowCounter(p.show_counter) { } @@ -155,47 +147,80 @@ BOOL LLChiclet::handleMouseDown(S32 x, S32 y, MASK mask) return TRUE; } -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -LLIMChiclet::LLIMChiclet(const LLChiclet::Params& p) -: LLChiclet(p) -, mAvatar(NULL) -, mCounterText(NULL) -, mSpeaker(NULL) -, mIMSessionId() -, mShowSpeaker(false) -, mSpeakerStatus(SPEAKER_IDLE) +boost::signals2::connection LLChiclet::setChicletSizeChangedCallback( + const chiclet_size_changed_callback_t& cb) { - LLAvatarIconCtrl::Params avatar_params; - avatar_params.control_name("avatar"); - avatar_params.draw_tooltip = FALSE; - mAvatar = LLUICtrlFactory::create(avatar_params); + return mChicletSizeChangedSignal.connect(cb); +} - addChild(mAvatar); +void LLChiclet::onChicletSizeChanged() +{ + mChicletSizeChangedSignal(this, getValue()); +} + +LLSD LLChiclet::getValue() const +{ + return LLSD(getSessionId()); +} + +void LLChiclet::setValue(const LLSD& value) +{ + if(value.isUUID()) + setSessionId(value.asUUID()); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLIMChiclet::Params::Params() +: avatar_icon("avatar_icon") +, unread_notifications("unread_notifications") +, speaker("speaker") +, show_speaker("show_speaker") +{ + rect(LLRect(0, 25, 45, 0)); + + avatar_icon.name("avatar_icon"); + avatar_icon.rect(LLRect(0, 25, 25, 0)); + + unread_notifications.name("unread"); + unread_notifications.rect(LLRect(25, 25, 45, 0)); + unread_notifications.font(LLFontGL::getFontSansSerif()); + unread_notifications.font_halign(LLFontGL::HCENTER); + unread_notifications.v_pad(5); + unread_notifications.text_color(LLColor4::white); + + speaker.name("speaker"); + speaker.rect(LLRect(45, 25, 65, 0)); + + show_speaker = false; +} + +LLIMChiclet::LLIMChiclet(const Params& p) +: LLChiclet(p) +, mAvatarCtrl(NULL) +, mCounterCtrl(NULL) +, mSpeakerCtrl(NULL) +, mShowSpeaker(p.show_speaker) +, mPopupMenu(NULL) +{ + LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon; + mAvatarCtrl = LLUICtrlFactory::create(avatar_params); + addChild(mAvatarCtrl); + + LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; + mCounterCtrl = LLUICtrlFactory::create(unread_params); + addChild(mCounterCtrl); - LLTextBox::Params unread_params; - unread_params.font.style("SansSerif"); - unread_params.font_halign(LLFontGL::HCENTER); - unread_params.v_pad(5); - mCounterText = LLUICtrlFactory::create(unread_params); - addChild(mCounterText); - mCounterText->setColor(LLColor4::white); setCounter(getCounter()); + setShowCounter(getShowCounter()); - LLIconCtrl::Params speaker_params; - speaker_params.image( LLUI::getUIImage("icn_voice_ptt-on-lvl2.tga") ); - mSpeaker = LLUICtrlFactory::create(speaker_params); - addChild(mSpeaker); - mSpeaker->setVisible(getShowSpeaker()); + LLChicletSpeakerCtrl::Params speaker_params = p.speaker; + mSpeakerCtrl = LLUICtrlFactory::create(speaker_params); + addChild(mSpeakerCtrl); - S32 left = 0; - mAvatar->setRect(LLRect(left,CHICLET_HEIGHT,AVATAR_WIDTH,0)); - left += AVATAR_WIDTH + CHICLET_SPACING; - mCounterText->setRect(LLRect(left,CHICLET_HEIGHT,left + COUNTER_WIDTH,0)); - left += COUNTER_WIDTH + CHICLET_SPACING; - mSpeaker->setRect(LLRect(left,CHICLET_HEIGHT,left + SPEAKER_WIDTH,0)); + setShowSpeaker(getShowSpeaker()); } LLIMChiclet::~LLIMChiclet() @@ -203,43 +228,53 @@ LLIMChiclet::~LLIMChiclet() } -LLChiclet* LLIMChiclet::create(LLSD* imSessionId /* = NULL */) -{ - LLIMChiclet* chiclet = new LLIMChiclet(LLChiclet::Params()); - chiclet->setIMSessionId(imSessionId); - return chiclet; -} void LLIMChiclet::setCounter(S32 counter) { - mCounter = counter; - std::stringstream stream; - stream << mCounter; - mCounterText->setText(stream.str()); + mCounterCtrl->setCounter(counter); - LLRect rc = mCounterText->getRect(); - rc.mRight = rc.mLeft + calcCounterWidth(); - mCounterText->setRect(rc); + if(getShowCounter()) + { + LLRect counter_rect = mCounterCtrl->getRect(); + LLRect required_rect = mCounterCtrl->getRequiredRect(); + bool needs_resize = required_rect.getWidth() != counter_rect.getWidth(); + + if(needs_resize) + { + counter_rect.mRight = counter_rect.mLeft + required_rect.getWidth(); + mCounterCtrl->reshape(counter_rect.getWidth(), counter_rect.getHeight()); + mCounterCtrl->setRect(counter_rect); + + onChicletSizeChanged(); + } + } } LLRect LLIMChiclet::getRequiredRect() { - LLRect rect(0,CHICLET_HEIGHT,AVATAR_WIDTH,0); + LLRect rect(0, 0, mAvatarCtrl->getRect().getWidth(), 0); if(getShowCounter()) { - rect.mRight += CHICLET_SPACING + calcCounterWidth(); + rect.mRight += mCounterCtrl->getRequiredRect().getWidth(); } if(getShowSpeaker()) { - rect.mRight += CHICLET_SPACING + SPEAKER_WIDTH; + rect.mRight += mSpeakerCtrl->getRect().getWidth(); } return rect; } void LLIMChiclet::setShowCounter(bool show) { + bool needs_resize = getShowCounter() != show; + LLChiclet::setShowCounter(show); - mCounterText->setVisible(getShowCounter()); + mCounterCtrl->setVisible(getShowCounter()); + + if(needs_resize) + { + onChicletSizeChanged(); + } } void LLIMChiclet::setIMSessionName(const std::string& name) @@ -249,63 +284,201 @@ void LLIMChiclet::setIMSessionName(const std::string& name) void LLIMChiclet::setOtherParticipantId(const LLUUID& other_participant_id) { - if (mAvatar) + if (mAvatarCtrl) { - mAvatar->setValue(other_participant_id); + mAvatarCtrl->setValue(other_participant_id); + } +} + +void LLIMChiclet::updateMenuItems() +{ + if(!mPopupMenu) + return; + if(getSessionId().isNull()) + return; + + if(P2P_MENU_NAME == mPopupMenu->getName()) + { + bool is_friend = LLAvatarActions::isFriend(mAvatarCtrl->getAvatarId()); + + mPopupMenu->getChild("Add Friend")->setEnabled(!is_friend); + mPopupMenu->getChild("Remove Friend")->setEnabled(is_friend); } } void LLIMChiclet::setShowSpeaker(bool show) { + bool needs_resize = getShowSpeaker() != show; + mShowSpeaker = show; - mSpeaker->setVisible(getShowSpeaker()); + mSpeakerCtrl->setVisible(getShowSpeaker()); + + if(needs_resize) + { + onChicletSizeChanged(); + } } void LLIMChiclet::draw() { LLUICtrl::draw(); - gl_rect_2d(1, getRect().getHeight(), getRect().getWidth(), 1, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE); + + //if we have a docked floater, we want to position it relative to us + LLIMFloater* im_floater = LLFloaterReg::findTypedInstance("impanel", getSessionId()); + + if (im_floater && im_floater->isDocked()) + { + S32 x, y; + getParent()->localPointToScreen(getRect().getCenterX(), 0, &x, &y); + im_floater->translate(x - im_floater->getRect().getCenterX(), 10 - im_floater->getRect().mBottom); + //set this so the docked floater knows it's been positioned and can now draw + im_floater->setPositioned(true); + } + + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE); } -S32 LLIMChiclet::calcCounterWidth() +BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) { - S32 font_width = mCounterText->getFont()->getWidth("0"); - S32 text_size = mCounterText->getText().size(); + if(!mPopupMenu) + createPopupMenu(); - return llmax(font_width * text_size, COUNTER_WIDTH); + updateMenuItems(); + + if (mPopupMenu) + { + mPopupMenu->arrangeAndClear(); + } + + LLMenuGL::showPopup(this, mPopupMenu, x, y); + + return TRUE; +} + +void LLIMChiclet::createPopupMenu() +{ + if(mPopupMenu) + { + llwarns << "Menu already exists" << llendl; + return; + } + if(getSessionId().isNull()) + return; + + LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId()); + if(!floater) + return; + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + registrar.add("IMChicletMenu.Action", boost::bind(&LLIMChiclet::onMenuItemClicked, this, _2)); + + switch(floater->getDialogType()) + { + case IM_SESSION_GROUP_START: + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile + ("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + break; + case IM_NOTHING_SPECIAL: + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile + ("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + break; + default: + llwarns << "Unexpected dialog type" << llendl; + break; + } +} + +void LLIMChiclet::onMenuItemClicked(const LLSD& user_data) +{ + std::string level = user_data.asString(); + LLUUID other_participant_id = mAvatarCtrl->getAvatarId(); + + if("profile" == level) + { + LLAvatarActions::showProfile(other_participant_id); + } + else if("im" == level) + { + LLAvatarActions::startIM(other_participant_id); + } + else if("add" == level) + { + std::string name; + gCacheName->getFullName(other_participant_id,name); + LLAvatarActions::requestFriendshipDialog(other_participant_id,name); + } + else if("remove" == level) + { + LLAvatarActions::removeFriendDialog(other_participant_id); + } + else if("group chat" == level) + { + LLGroupActions::startChat(other_participant_id); + } + else if("info" == level) + { + LLFloaterGroupInfo::showFromUUID(other_participant_id); + } } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +LLChicletPanel::Params::Params() +: chiclet_padding("chiclet_padding") +, scrolling_offset("scrolling_offset") +, left_scroll_button("left_scroll_button") +, right_scroll_button("right_scroll_button") +, min_width("min_width") +{ + chiclet_padding = 3; + scrolling_offset = 40; + min_width = 70; + + LLRect scroll_button_rect(0, 25, 19, 5); + + left_scroll_button.name("left_scroll"); + left_scroll_button.label(LLStringUtil::null); + left_scroll_button.rect(scroll_button_rect); + left_scroll_button.tab_stop(false); + left_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); + left_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); + left_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); + + right_scroll_button.name("right_scroll"); + right_scroll_button.label(LLStringUtil::null); + right_scroll_button.rect(scroll_button_rect); + right_scroll_button.tab_stop(false); + right_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); + right_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); + right_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); +}; + LLChicletPanel::LLChicletPanel(const Params&p) : LLPanel(p) -, mLeftScroll(NULL) -, mRightScroll(NULL) -, mFirstToShow(0) +, mScrollArea(NULL) +, mLeftScrollButton(NULL) +, mRightScrollButton(NULL) +, mChicletPadding(p.chiclet_padding) +, mScrollingOffset(p.scrolling_offset) +, mMinWidth(p.min_width) +, mShowControls(true) { - LLButton::Params params; + LLButton::Params scroll_button_params = p.left_scroll_button; - params.name("scroll_left"); - params.label(LLStringUtil::null); - params.tab_stop(false); - params.image_selected(LLUI::getUIImage("scroll_left.tga")); - params.image_unselected(LLUI::getUIImage("scroll_left.tga")); - params.image_hover_selected(LLUI::getUIImage("scroll_left.tga")); - mLeftScroll = LLUICtrlFactory::create(params); - addChild(mLeftScroll); - mLeftScroll->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this)); - mLeftScroll->setEnabled(false); + mLeftScrollButton = LLUICtrlFactory::create(scroll_button_params); + addChild(mLeftScrollButton); - params.name("scroll_right"); - params.image_selected(LLUI::getUIImage("scroll_right.tga")); - params.image_unselected(LLUI::getUIImage("scroll_right.tga")); - params.image_hover_selected(LLUI::getUIImage("scroll_right.tga")); - mRightScroll = LLUICtrlFactory::create(params); - addChild(mRightScroll); - mRightScroll->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this)); - mRightScroll->setEnabled(false); + mLeftScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this)); + mLeftScrollButton->setEnabled(false); + + scroll_button_params = p.right_scroll_button; + mRightScrollButton = LLUICtrlFactory::create(scroll_button_params); + addChild(mRightScrollButton); + + mRightScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this)); + mRightScrollButton->setEnabled(false); LLPanel::Params panel_params; mScrollArea = LLUICtrlFactory::create(panel_params,this); @@ -317,44 +490,55 @@ LLChicletPanel::~LLChicletPanel() } -LLChicletPanel* LLChicletPanel::create() -{ - LLChicletPanel* panel = new LLChicletPanel(LLChicletPanel::Params()); - return panel; +void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){ + + LLUUID session_id = data["session_id"].asUUID(); + LLChiclet* chiclet = panel->findChiclet(session_id); + + if (chiclet) + { + chiclet->setCounter(data["num_unread"].asInteger()); + } + else + { + llwarns << "Unable to set counter for chiclet " << session_id << llendl; + } } + BOOL LLChicletPanel::postBuild() { LLPanel::postBuild(); + LLIMModel::instance().addChangedCallback(boost::bind(im_chiclet_callback, this, _1)); return TRUE; } -LLChiclet* LLChicletPanel::createChiclet(LLSD* imSessionId, S32 pos) -{ - LLChiclet* chiclet = LLIMChiclet::create(imSessionId); - if(!chiclet) - { - assert(false); - return NULL; - } - - if(!addChiclet(chiclet, pos)) - { - assert(false); - return NULL; - } - - return chiclet; -} - -bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 pos) +bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index) { if(mScrollArea->addChild(chiclet)) { - mChicletList.insert(mChicletList.begin() + pos, chiclet); + S32 offset = 0; + // Do not scroll chiclets if chiclets are scrolled right and new + // chiclet is added to the beginning of the list + if(canScrollLeft()) + { + offset = - (chiclet->getRequiredRect().getWidth() + getChicletPadding()); + if(0 == index) + { + offset += getChiclet(0)->getRect().mLeft; + } + } + + mChicletList.insert(mChicletList.begin() + index, chiclet); + + getChiclet(0)->translate(offset, 0); chiclet->setLeftButtonClickCallback(boost::bind(&LLChicletPanel::onChicletClick, this, _1, _2)); + chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index)); + + arrange(); + showScrollButtonsIfNeeded(); return true; } @@ -362,57 +546,65 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 pos) return false; } +void LLChicletPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param) +{ + S32 chiclet_width = ctrl->getRect().getWidth(); + S32 chiclet_new_width = ctrl->getRequiredRect().getWidth(); + + if(chiclet_new_width == chiclet_width) + { + return; + } + + LLRect chiclet_rect = ctrl->getRect(); + chiclet_rect.mRight = chiclet_rect.mLeft + chiclet_new_width; + + ctrl->setRect(chiclet_rect); + + S32 offset = chiclet_new_width - chiclet_width; + S32 index = getChicletIndex(ctrl); + + shiftChiclets(offset, index + 1); + trimChiclets(); + showScrollButtonsIfNeeded(); +} + void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD¶m) { - LLIMChiclet* chiclet = dynamic_cast(ctrl); - if (chiclet) - { - LLFloaterReg::showInstance("communicate", chiclet->getIMSessionId().asUUID()); - } - mCommitSignal(ctrl,param); } -LLChiclet* LLChicletPanel::findIMChiclet(LLSD* imSessionId) -{ - chiclet_list_t::const_iterator it = mChicletList.begin(); - for( ; mChicletList.end() != it; ++it) - { - LLIMChiclet* chiclet = dynamic_cast(*it); - if(!chiclet) - { - continue; - } - - if(chiclet->getIMSessionId().asUUID() == imSessionId->asUUID()) - { - return chiclet; - } - } - return NULL; -} - -LLChiclet* LLChicletPanel::getChiclet(S32 pos) -{ - return mChicletList.at(pos); -} - void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it) { mScrollArea->removeChild(*it); - delete *it; mChicletList.erase(it); - mLeftScroll->setEnabled(canScrollLeft()); - mRightScroll->setEnabled(canScrollRight()); + + arrange(); + trimChiclets(); + showScrollButtonsIfNeeded(); } -void LLChicletPanel::removeChiclet(S32 pos) +void LLChicletPanel::removeChiclet(S32 index) { - if(0 > pos || getChicletCount() >= pos) + if(index >= 0 && index < getChicletCount()) { - return; + removeChiclet(mChicletList.begin() + index); } - removeChiclet(mChicletList.begin() + pos); +} + +S32 LLChicletPanel::getChicletIndex(const LLChiclet* chiclet) +{ + if(mChicletList.empty()) + return -1; + + S32 size = getChicletCount(); + for(int n = 0; n < size; ++n) + { + if(chiclet == mChicletList[n]) + return n; + } + + return -1; } void LLChicletPanel::removeChiclet(LLChiclet*chiclet) @@ -429,18 +621,14 @@ void LLChicletPanel::removeChiclet(LLChiclet*chiclet) } } -void LLChicletPanel::removeIMChiclet(LLSD* imSessionId) +void LLChicletPanel::removeChiclet(const LLUUID& im_session_id) { chiclet_list_t::iterator it = mChicletList.begin(); for( ; mChicletList.end() != it; ++it) { LLIMChiclet* chiclet = dynamic_cast(*it); - if(!chiclet) - { - continue; - } - if(chiclet->getIMSessionId().asUUID() == imSessionId->asUUID()) + if(chiclet->getSessionId() == im_session_id) { removeChiclet(it); return; @@ -450,54 +638,104 @@ void LLChicletPanel::removeIMChiclet(LLSD* imSessionId) void LLChicletPanel::removeAll() { - mScrollArea->deleteAllChildren(); + S32 size = getChicletCount(); + for(S32 n = 0; n < size; ++n) + { + mScrollArea->removeChild(mChicletList[n]); + } mChicletList.erase(mChicletList.begin(), mChicletList.end()); - mLeftScroll->setEnabled(false); - mRightScroll->setEnabled(false); + + showScrollButtonsIfNeeded(); } void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent ) { LLPanel::reshape(width,height,called_from_parent); - mLeftScroll->setRect(LLRect(0,CHICLET_HEIGHT,SCROLL_BUTTON_WIDTH, - CHICLET_HEIGHT - SCROLL_BUTTON_HEIGHT)); - mRightScroll->setRect(LLRect(getRect().getWidth()-SCROLL_BUTTON_WIDTH,CHICLET_HEIGHT, - getRect().getWidth(),CHICLET_HEIGHT - SCROLL_BUTTON_HEIGHT)); + static const S32 SCROLL_BUTTON_PAD = 5; - mScrollArea->setRect(LLRect(SCROLL_BUTTON_WIDTH + 5,CHICLET_HEIGHT + 1, - getRect().getWidth() - SCROLL_BUTTON_WIDTH - 5, 0)); + LLRect scroll_button_rect = mLeftScrollButton->getRect(); + mLeftScrollButton->setRect(LLRect(0,height,scroll_button_rect.getWidth(), + height - scroll_button_rect.getHeight())); + scroll_button_rect = mRightScrollButton->getRect(); + mRightScrollButton->setRect(LLRect(width - scroll_button_rect.getWidth(),height, + width, height - scroll_button_rect.getHeight())); - arrange(); + mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD, + height + 7, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0)); + + mShowControls = width > mMinWidth; + mScrollArea->setVisible(mShowControls); + + trimChiclets(); + + showScrollButtonsIfNeeded(); } void LLChicletPanel::arrange() { - S32 left = 0; - S32 size = getChicletCount(); + if(mChicletList.empty()) + return; - for( int n = mFirstToShow; n < size; ++n) + S32 chiclet_left = getChiclet(0)->getRect().mLeft; + + S32 size = getChicletCount(); + for( int n = 0; n < size; ++n) { LLChiclet* chiclet = getChiclet(n); + S32 chiclet_width = chiclet->getRequiredRect().getWidth(); - LLRect rc(left, CHICLET_HEIGHT, left + chiclet_width, 0); + LLRect rect = chiclet->getRect(); + rect.set(chiclet_left, rect.mTop, chiclet_left + chiclet_width, rect.mBottom); - chiclet->setRect(rc); - chiclet->reshape(rc.getWidth(),rc.getHeight()); + chiclet->setRect(rect); - left += chiclet_width + CHICLET_PADDING; + chiclet_left += chiclet_width + getChicletPadding(); + } +} + +void LLChicletPanel::trimChiclets() +{ + // trim right + if(canScrollLeft() && !canScrollRight()) + { + S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight; + S32 scroll_width = mScrollArea->getRect().getWidth(); + if(last_chiclet_right < scroll_width) + { + shiftChiclets(scroll_width - last_chiclet_right); + } } - mLeftScroll->setEnabled(canScrollLeft()); - mRightScroll->setEnabled(canScrollRight()); + // trim left + if(!mChicletList.empty()) + { + LLRect first_chiclet_rect = getChiclet(0)->getRect(); + if(first_chiclet_rect.mLeft > 0) + { + shiftChiclets( - first_chiclet_rect.mLeft); + } + } +} + +void LLChicletPanel::showScrollButtonsIfNeeded() +{ + bool can_scroll_left = canScrollLeft(); + bool can_scroll_right = canScrollRight(); + + mLeftScrollButton->setEnabled(can_scroll_left); + mRightScrollButton->setEnabled(can_scroll_right); + + bool show_scroll_buttons = (can_scroll_left || can_scroll_right) && mShowControls; + + mLeftScrollButton->setVisible(show_scroll_buttons); + mRightScrollButton->setVisible(show_scroll_buttons); } void LLChicletPanel::draw() { - //gl_rect_2d(0,getRect().getHeight(),getRect().getWidth(),0,LLColor4(0.f,1.f,1.f,1.f),TRUE); - child_list_const_iter_t it = getChildList()->begin(); for( ; getChildList()->end() != it; ++it) { @@ -516,38 +754,39 @@ void LLChicletPanel::draw() bool LLChicletPanel::canScrollRight() { - S32 width = 0; - LLRect visible_rect = mScrollArea->getRect(); + if(mChicletList.empty()) + return false; + + S32 scroll_width = mScrollArea->getRect().getWidth(); + S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight; + + if(last_chiclet_right > scroll_width) + return true; - chiclet_list_t::const_iterator it = mChicletList.begin() + mFirstToShow; - for(;mChicletList.end() != it; ++it) - { - LLChiclet* chiclet = *it; - width += chiclet->getRect().getWidth() + CHICLET_PADDING; - if(width > visible_rect.getWidth()) - return true; - } return false; } bool LLChicletPanel::canScrollLeft() { - return mFirstToShow > 0; + if(mChicletList.empty()) + return false; + + return getChiclet(0)->getRect().mLeft < 0; } -void LLChicletPanel::scroll(ScrollDirection direction) +void LLChicletPanel::scroll(S32 offset) { - S32 elem = 0; - if(SCROLL_LEFT == direction) - elem = mFirstToShow; - else if(SCROLL_RIGHT) - elem = mFirstToShow - 1; + shiftChiclets(offset); +} - S32 offset = mChicletList[elem]->getRect().getWidth() + - CHICLET_PADDING; - offset *= direction; +void LLChicletPanel::shiftChiclets(S32 offset, S32 start_index /* = 0 */) +{ + if(start_index < 0 || start_index >= getChicletCount()) + { + return; + } - chiclet_list_t::const_iterator it = mChicletList.begin(); + chiclet_list_t::const_iterator it = mChicletList.begin() + start_index; for(;mChicletList.end() != it; ++it) { LLChiclet* chiclet = *it; @@ -559,10 +798,18 @@ void LLChicletPanel::scrollLeft() { if(canScrollLeft()) { - --mFirstToShow; - scroll(SCROLL_LEFT); - mLeftScroll->setEnabled(canScrollLeft()); - mRightScroll->setEnabled(canScrollRight()); + S32 offset = getScrollingOffset(); + LLRect first_chiclet_rect = getChiclet(0)->getRect(); + + // shift chiclets in case first chiclet is partially visible + if(first_chiclet_rect.mLeft < 0 && first_chiclet_rect.mRight > 0) + { + offset = llabs(first_chiclet_rect.mLeft); + } + + scroll(offset); + + showScrollButtonsIfNeeded(); } } @@ -570,10 +817,20 @@ void LLChicletPanel::scrollRight() { if(canScrollRight()) { - ++mFirstToShow; - scroll(SCROLL_RIGHT); - mLeftScroll->setEnabled(canScrollLeft()); - mRightScroll->setEnabled(canScrollRight()); + S32 offset = - getScrollingOffset(); + + S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight; + S32 scroll_rect_width = mScrollArea->getRect().getWidth(); + // if after scrolling, the last chiclet will not be aligned to + // scroll area right side - align it. + if( last_chiclet_right + offset < scroll_rect_width ) + { + offset = scroll_rect_width - last_chiclet_right; + } + + scroll(offset); + + showScrollButtonsIfNeeded(); } } @@ -587,7 +844,7 @@ void LLChicletPanel::onRightScrollClick() scrollRight(); } -boost::signals2::connection LLChicletPanel::setChicletClickCallback( +boost::signals2::connection LLChicletPanel::setChicletClickedCallback( const commit_callback_t& cb) { return mCommitSignal.connect(cb); @@ -606,62 +863,88 @@ BOOL LLChicletPanel::handleScrollWheel(S32 x, S32 y, S32 clicks) return TRUE; } -LLTalkButton::LLTalkButton(const LLUICtrl::Params& p) -: LLUICtrl(p) +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLTalkButton::Params::Params() + : speak_button("speak_button") + , show_button("show_button") + , monitor("monitor") { - static S32 DROPDOWN_BTN_WIDTH = 20; + speak_button.name("left"); + speak_button.label("Speak"); + speak_button.label_selected("Speak"); + speak_button.font(LLFontGL::getFontSansSerifSmall()); + speak_button.tab_stop(false); + speak_button.is_toggle(true); + speak_button.picture_style(true); + speak_button.image_selected(LLUI::getUIImage("SegmentedBtn_Left_Selected")); + speak_button.image_unselected(LLUI::getUIImage("SegmentedBtn_Left_Off")); - LLRect rc(p.rect); + show_button.name("right"); + show_button.label(LLStringUtil::null); + show_button.rect(LLRect(0, 0, 20, 0)); + show_button.tab_stop(false); + show_button.is_toggle(true); + show_button.picture_style(true); + show_button.image_selected(LLUI::getUIImage("ComboButton_Selected")); + show_button.image_unselected(LLUI::getUIImage("ComboButton_Off")); - LLButton::Params speak_params; - speak_params.name("left"); - speak_params.rect(LLRect(0,rc.getHeight(),rc.getWidth()-DROPDOWN_BTN_WIDTH,0)); - speak_params.label("Speak"); - speak_params.label_selected("Speak"); - speak_params.font(LLFontGL::getFontSansSerifSmall()); - speak_params.label_color(LLColor4::black); - speak_params.label_color_selected(LLColor4::black); - speak_params.tab_stop(false); - speak_params.is_toggle(true); - speak_params.picture_style(true); - speak_params.image_selected(LLUI::getUIImage("flyout_btn_left_selected.tga")); - speak_params.image_unselected(LLUI::getUIImage("flyout_btn_left.tga")); + monitor.name("monitor"); + // *TODO: Make this data driven. + monitor.rect(LLRect(0, 18, 18, 0)); +} + +LLTalkButton::LLTalkButton(const Params& p) +: LLUICtrl(p) +, mPrivateCallPanel(NULL) +, mOutputMonitor(NULL) +, mSpeakBtn(NULL) +, mShowBtn(NULL) +{ + LLRect rect = p.rect(); + LLRect speak_rect(0, rect.getHeight(), rect.getWidth(), 0); + LLRect show_rect = p.show_button.rect(); + show_rect.set(0, rect.getHeight(), show_rect.getWidth(), 0); + + speak_rect.mRight -= show_rect.getWidth(); + show_rect.mLeft = speak_rect.getWidth(); + show_rect.mRight = rect.getWidth(); + + LLButton::Params speak_params = p.speak_button; + speak_params.rect(speak_rect); mSpeakBtn = LLUICtrlFactory::create(speak_params); addChild(mSpeakBtn); mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this)); - mSpeakBtn->setToggleState(false); + mSpeakBtn->setToggleState(FALSE); - LLButton::Params show_params; - show_params.name("right"); - show_params.rect(LLRect(rc.getWidth()-DROPDOWN_BTN_WIDTH,rc.getHeight(),rc.getWidth(),0)); - show_params.label(""); - show_params.tab_stop(false); - show_params.is_toggle(true); - show_params.picture_style(true); - show_params.image_selected(LLUI::getUIImage("show_btn_selected.tga")); - show_params.image_unselected(LLUI::getUIImage("show_btn.tga")); + LLButton::Params show_params = p.show_button; + show_params.rect(show_rect); mShowBtn = LLUICtrlFactory::create(show_params); addChild(mShowBtn); mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this)); - mShowBtn->setToggleState(false); - - mSpeakBtn->setToggleState(FALSE); mShowBtn->setToggleState(FALSE); - rc = mSpeakBtn->getRect(); + static const S32 MONITOR_RIGHT_PAD = 2; - LLOutputMonitorCtrl::Params monitor_param; - monitor_param.name("monitor"); - monitor_param.draw_border(false); - monitor_param.rect(LLRect(rc.getWidth()-20,18,rc.getWidth()-3,2)); - monitor_param.visible(true); - mOutputMonitor = LLUICtrlFactory::create(monitor_param); + LLRect monitor_rect = p.monitor.rect(); + S32 monitor_height = monitor_rect.getHeight(); + monitor_rect.mLeft = speak_rect.getWidth() - monitor_rect.getWidth() - MONITOR_RIGHT_PAD; + monitor_rect.mRight = speak_rect.getWidth() - MONITOR_RIGHT_PAD; + monitor_rect.mBottom = (rect.getHeight() / 2) - (monitor_height / 2); + monitor_rect.mTop = monitor_rect.mBottom + monitor_height; + LLOutputMonitorCtrl::Params monitor_params = p.monitor; + monitor_params.draw_border(false); + monitor_params.rect(monitor_rect); + mOutputMonitor = LLUICtrlFactory::create(monitor_params); mSpeakBtn->addChild(mOutputMonitor); - mPrivateCallPanel = NULL; + // never show "muted" because you can't mute yourself + mOutputMonitor->setIsMuted(false); } LLTalkButton::~LLTalkButton() @@ -670,19 +953,24 @@ LLTalkButton::~LLTalkButton() void LLTalkButton::draw() { - if(mSpeakBtn->getToggleState()) - { - mOutputMonitor->setPower(gVoiceClient->getCurrentPower(gAgent.getID())); - } + // Always provide speaking feedback. User can trigger speaking + // with keyboard or middle-mouse shortcut. + mOutputMonitor->setPower(gVoiceClient->getCurrentPower(gAgent.getID())); + mOutputMonitor->setIsTalking( gVoiceClient->getUserPTTState() ); + mSpeakBtn->setToggleState( gVoiceClient->getUserPTTState() ); LLUICtrl::draw(); } +void LLTalkButton::setSpeakBtnToggleState(bool state) +{ + mSpeakBtn->setToggleState(state); +} + void LLTalkButton::onClick_SpeakBtn() { bool speaking = mSpeakBtn->getToggleState(); gVoiceClient->setUserPTTState(speaking); - mOutputMonitor->setIsMuted(!speaking); } void LLTalkButton::onClick_ShowBtn() @@ -704,8 +992,7 @@ void LLTalkButton::onClick_ShowBtn() mPrivateCallPanel = new LLVoiceControlPanel; getRootView()->addChild(mPrivateCallPanel); - y = LLBottomTray::getInstance()->getRect().getHeight() - + mPrivateCallPanel->getRect().getHeight(); + y = LLBottomTray::getInstance()->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight(); LLRect rect; rect.setLeftTopAndSize(x, y, mPrivateCallPanel->getRect().getWidth(), mPrivateCallPanel->getRect().getHeight()); @@ -723,3 +1010,70 @@ void LLTalkButton::onClick_ShowBtn() mShowBtn->setToggleState(TRUE); } + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p) + : LLTextBox(p) + , mCounter(0) + , mInitialWidth(0) +{ + mInitialWidth = getRect().getWidth(); +} + +void LLChicletNotificationCounterCtrl::setCounter(S32 counter) +{ + mCounter = counter; + + std::stringstream stream; + stream << getCounter(); + if(mCounter != 0) + { + setText(stream.str()); + } + else + { + setText(std::string("")); + } +} + +LLRect LLChicletNotificationCounterCtrl::getRequiredRect() +{ + LLRect rc; + S32 text_width = getFont()->getWidth(getText()); + + rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth); + + return rc; +} + +void LLChicletNotificationCounterCtrl::setValue(const LLSD& value) +{ + if(value.isInteger()) + setCounter(value.asInteger()); +} + +LLSD LLChicletNotificationCounterCtrl::getValue() const +{ + return LLSD(getCounter()); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p) + : LLAvatarIconCtrl(p) +{ +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p) + : LLIconCtrl(p) +{ +} diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 11c3356c46..a748141a14 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -33,134 +33,335 @@ #ifndef LL_LLCHICLET_H #define LL_LLCHICLET_H +#include "llavatariconctrl.h" +#include "llbutton.h" #include "llpanel.h" +#include "lltextbox.h" +#include "lloutputmonitorctrl.h" -class LLTextBox; -class LLIconCtrl; -class LLAvatarIconCtrl; class LLVoiceControlPanel; -class LLOutputMonitorCtrl; +class LLMenuGL; +class LLIMFloater; +/* + * Class for displaying amount of messages/notifications(unread). +*/ +class LLChicletNotificationCounterCtrl : public LLTextBox +{ +public: + + struct Params : public LLInitParam::Block + { + Params() + {}; + }; + + /* + * Sets number of notifications + */ + virtual void setCounter(S32 counter); + + /* + * Returns number of notifications + */ + virtual S32 getCounter() const { return mCounter; } + + /* + * Returns width, required to display amount of notifications in text form. + * Width is the only valid value. + */ + /*virtual*/ LLRect getRequiredRect(); + + /* + * Sets number of notifications using LLSD + */ + /*virtual*/ void setValue(const LLSD& value); + + /* + * Returns number of notifications wrapped in LLSD + */ + /*virtual*/ LLSD getValue() const; + +protected: + + LLChicletNotificationCounterCtrl(const Params& p); + friend class LLUICtrlFactory; + +private: + + S32 mCounter; + S32 mInitialWidth; +}; + +/* + * Class for displaying avatar's icon. +*/ +class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl +{ +public: + + struct Params : public LLInitParam::Block + { + Params() + { + draw_tooltip(FALSE); + mouse_opaque(FALSE); + }; + }; + +protected: + + LLChicletAvatarIconCtrl(const Params& p); + friend class LLUICtrlFactory; +}; + +/* + * Class for displaying status of Voice Chat +*/ +class LLChicletSpeakerCtrl : public LLIconCtrl +{ +public: + + struct Params : public LLInitParam::Block + { + Params(){}; + }; +protected: + + LLChicletSpeakerCtrl(const Params&p); + friend class LLUICtrlFactory; +}; + +/* + * Base class for all chiclets. + */ class LLChiclet : public LLUICtrl { public: struct Params : public LLInitParam::Block { - Params(){}; + Optional show_counter; + + Params(); }; - virtual ~LLChiclet(); + /*virtual*/ ~LLChiclet(); + /* + * Associates chat session id with chiclet. + */ + virtual void setSessionId(const LLUUID& session_id) { mSessionId = session_id; } + + /* + * Returns associated chat session. + */ + virtual const LLUUID& getSessionId() const { return mSessionId; } + + /* + * Sets number of unread notifications. + */ virtual void setCounter(S32 counter) = 0; + /* + * Returns number of unread notifications. + */ virtual S32 getCounter() = 0; - virtual void setShowCounter(bool show) {mShowCounter = show;}; + /* + * Sets show counter state. + */ + virtual void setShowCounter(bool show) { mShowCounter = show; } + /* + * Returns show counter state. + */ virtual bool getShowCounter() {return mShowCounter;}; - virtual boost::signals2::connection setLeftButtonClickCallback( + /* + * Connects chiclet clicked event with callback. + */ + /*virtual*/ boost::signals2::connection setLeftButtonClickCallback( const commit_callback_t& cb); + typedef boost::function + chiclet_size_changed_callback_t; + + /* + * Connects chiclets size changed event with callback. + */ + virtual boost::signals2::connection setChicletSizeChangedCallback( + const chiclet_size_changed_callback_t& cb); + + /* + * Sets IM Session id using LLSD + */ + /*virtual*/ LLSD getValue() const; + + /* + * Returns IM Session id using LLSD + */ + /*virtual*/ void setValue(const LLSD& value); + protected: friend class LLUICtrlFactory; LLChiclet(const Params& p); - virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + /* + * Notifies subscribers about click on chiclet. + */ + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + + /* + * Notifies subscribers about chiclet size changed event. + */ + virtual void onChicletSizeChanged(); + +private: + + LLUUID mSessionId; -protected: - S32 mCounter; bool mShowCounter; + + typedef boost::signals2::signal + chiclet_size_changed_signal_t; + + chiclet_size_changed_signal_t mChicletSizeChangedSignal; }; +/* +* Implements Instant Message chiclet. +* IMChiclet displays avatar's icon, number of unread messages(optional) +* and voice chat status(optional). +*/ class LLIMChiclet : public LLChiclet { public: - static LLChiclet* create(LLSD* imSessionId = NULL); - - void setCounter(S32); - - S32 getCounter() {return mCounter;}; - - const LLSD& getIMSessionId() const {return mIMSessionId;}; - - void setIMSessionId(LLSD* imSessionId) {if (imSessionId) mIMSessionId = *imSessionId;}; - void setIMSessionName(const std::string& name); - void setOtherParticipantId(const LLUUID& other_participant_id); - - void setShowSpeaker(bool show); - - bool getShowSpeaker() {return mShowSpeaker;}; - - enum SpeakerStatus + struct Params : public LLInitParam::Block { - SPREAKER_ACTIVE, - SPEAKER_IDLE + Optional avatar_icon; + + Optional unread_notifications; + + Optional speaker; + + Optional show_speaker; + + Params(); }; - void setSpeakerStatus(SpeakerStatus status); + /*virtual*/ ~LLIMChiclet(); - SpeakerStatus getSpeakerStatus() {return mSpeakerStatus;}; + /* + * Sets IM session name. This name will be displayed in chiclet tooltip. + */ + virtual void setIMSessionName(const std::string& name); - ~LLIMChiclet(); + /* + * Sets id of person/group user is chatting with. + */ + virtual void setOtherParticipantId(const LLUUID& other_participant_id); + + /* + * Shows/hides voice chat status control. + */ + virtual void setShowSpeaker(bool show); + + /* + * Returns voice chat status control visibility. + */ + virtual bool getShowSpeaker() {return mShowSpeaker;}; + + /* + * Sets number of unread messages. Will update chiclet's width if number text + * exceeds size of counter and notify it's parent about size change. + */ + /*virtual*/ void setCounter(S32); + + /* + * Returns number of unread messages. + */ + /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } + + /* + * Shows/hides number of unread messages. + */ + /*virtual*/ void setShowCounter(bool show); + + /* + * Draws border around chiclet. + */ + /*virtual*/ void draw(); + + /* + * Returns rect, required to display chiclet. + * Width is the only valid value. + */ + /*virtual*/ LLRect getRequiredRect(); protected: - LLIMChiclet(const LLChiclet::Params& p); + + LLIMChiclet(const Params& p); friend class LLUICtrlFactory; - S32 calcCounterWidth(); + /* + * Creates chiclet popup menu. Will create P2P or Group IM Chat menu + * based on other participant's id. + */ + virtual void createPopupMenu(); - //overrides -public: + /* + * Processes clicks on chiclet popup menu. + */ + virtual void onMenuItemClicked(const LLSD& user_data); - void setShowCounter(bool show); + /* + * Enables/disables menus based on relationship with other participant. + */ + virtual void updateMenuItems(); - void draw(); - - LLRect getRequiredRect(); + /* + * Displays popup menu. + */ + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); protected: - LLAvatarIconCtrl* mAvatar; - LLTextBox* mCounterText; - LLIconCtrl* mSpeaker; + LLChicletAvatarIconCtrl* mAvatarCtrl; + LLChicletNotificationCounterCtrl* mCounterCtrl; + LLChicletSpeakerCtrl* mSpeakerCtrl; + + LLMenuGL* mPopupMenu; - LLSD mIMSessionId; bool mShowSpeaker; - SpeakerStatus mSpeakerStatus; }; +/* + * Implements notification chiclet. Used to display total amount of unread messages + * across all IM sessions, total amount of system notifications. +*/ class LLNotificationChiclet : public LLChiclet { public: struct Params : public LLInitParam::Block { - Optional - image_unselected, - image_selected, - image_hover_selected, - image_hover_unselected, - image_disabled_selected, - image_disabled, - image_overlay; + Optional button; - Optional - label_left; + Optional unread_notifications; Params(); }; - static LLChiclet* create(const Params& p); + /*virtual*/ void setCounter(S32 counter); - void setCounter(S32 counter); + /*virtual*/S32 getCounter() { return mCounterCtrl->getCounter(); } - S32 getCounter() {return mCounter;}; + /*virtual*/ void setShowCounter(bool show); boost::signals2::connection setClickCallback(const commit_callback_t& cb); - virtual ~ LLNotificationChiclet(); + /*virtual*/ ~ LLNotificationChiclet(); protected: LLNotificationChiclet(const Params& p); @@ -168,113 +369,228 @@ protected: protected: LLButton* mButton; - LLTextBox* mCounterText; + LLChicletNotificationCounterCtrl* mCounterCtrl; }; +/* + * Storage class for all IM chiclets. Provides mechanism to display, + * scroll, create, remove chiclets. +*/ class LLChicletPanel : public LLPanel { public: struct Params : public LLInitParam::Block { - Params(){}; + Optional chiclet_padding, + scrolling_offset; + + Optional left_scroll_button, + right_scroll_button; + + Optional min_width; + + Params(); }; - static LLChicletPanel* create(); + virtual ~LLChicletPanel(); - LLChiclet* createChiclet(LLSD* imSessionId = NULL, S32 pos = 0); + /* + * Creates chiclet and adds it to chiclet list. + */ + template T* createChiclet(const LLUUID& session_id = LLUUID::null, S32 index = 0); - bool addChiclet(LLChiclet*, S32 pos); + /* + * Returns pointer to chiclet of specified type at specified index. + */ + template T* getChiclet(S32 index); - LLChiclet* getChiclet(S32 pos); + /* + * Returns pointer to LLChiclet at specified index. + */ + LLChiclet* getChiclet(S32 index) { return getChiclet(index); } - LLChiclet* findIMChiclet(LLSD* imSessionId); + /* + * Searches a chiclet using IM session id. + */ + template T* findChiclet(const LLUUID& im_session_id); + /* + * Returns number of hosted chiclets. + */ S32 getChicletCount() {return mChicletList.size();}; - void removeChiclet(S32 pos); + /* + * Returns index of chiclet in list. + */ + S32 getChicletIndex(const LLChiclet* chiclet); - void removeChiclet(LLChiclet*); + /* + * Removes chiclet by index. + */ + void removeChiclet(S32 index); - void removeIMChiclet(LLSD* imSessionId); + /* + * Removes chiclet by pointer. + */ + void removeChiclet(LLChiclet* chiclet); + /* + * Removes chiclet by IM session id. + */ + void removeChiclet(const LLUUID& im_session_id); + + /* + * Removes all chiclets. + */ void removeAll(); - void arrange(); - - ~LLChicletPanel(); - - void scrollLeft(); - - void scrollRight(); - - void onLeftScrollClick(); - - void onRightScrollClick(); - - boost::signals2::connection setChicletClickCallback( + boost::signals2::connection setChicletClickedCallback( const commit_callback_t& cb); - void onChicletClick(LLUICtrl*ctrl,const LLSD¶m); + /*virtual*/ BOOL postBuild(); - //overrides -public: + /* + * Reshapes controls and rearranges chiclets if needed. + */ + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE ); - void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE ); - - void draw(); - - BOOL postBuild(); + /*virtual*/ void draw(); protected: LLChicletPanel(const Params&p); friend class LLUICtrlFactory; - bool needsScrolling(); + /* + * Adds chiclet to list and rearranges all chiclets. + */ + bool addChiclet(LLChiclet*, S32 index); + /* + * Arranges chiclets. + */ + void arrange(); + + /* + * Returns true if chiclets can be scrolled right. + */ bool canScrollRight(); + /* + * Returns true if chiclets can be scrolled left. + */ bool canScrollLeft(); - enum ScrollDirection - { - SCROLL_LEFT = 1, - SCROLL_RIGHT = -1 - }; + /* + * Shows or hides chiclet scroll buttons if chiclets can or can not be scrolled. + */ + void showScrollButtonsIfNeeded(); - void scroll(ScrollDirection direction); + /* + * Shifts chiclets left or right. + */ + void shiftChiclets(S32 offset, S32 start_index = 0); + + /* + * Removes gaps between first chiclet and scroll area left side, + * last chiclet and scroll area right side. + */ + void trimChiclets(); + + /* + * Scrolls chiclets to right or left. + */ + void scroll(S32 offset); + + /* + * Verifies that chiclets can be scrolled left, then calls scroll() + */ + void scrollLeft(); + + /* + * Verifies that chiclets can be scrolled right, then calls scroll() + */ + void scrollRight(); + + /* + * Callback for left scroll button clicked + */ + void onLeftScrollClick(); + + /* + * Callback for right scroll button clicked + */ + void onRightScrollClick(); + + /* + * Callback for mouse wheel scrolled, calls scrollRight() or scrollLeft() + */ + BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + + /* + * Notifies subscribers about click on chiclet. + * Do not place any code here, instead subscribe on event (see setChicletClickedCallback). + */ + void onChicletClick(LLUICtrl*ctrl,const LLSD¶m); + + /* + * Callback for chiclet size changed event, rearranges chiclets. + */ + void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param); typedef std::vector chiclet_list_t; + /* + * Removes chiclet from scroll area and chiclet list. + */ void removeChiclet(chiclet_list_t::iterator it); - BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + S32 getChicletPadding() { return mChicletPadding; } + + S32 getScrollingOffset() { return mScrollingOffset; } protected: chiclet_list_t mChicletList; - LLButton* mLeftScroll; - LLButton* mRightScroll; - S32 mFirstToShow; - S32 mLastToShow; + LLButton* mLeftScrollButton; + LLButton* mRightScrollButton; LLPanel* mScrollArea; + + S32 mChicletPadding; + S32 mScrollingOffset; + S32 mMinWidth; + bool mShowControls; }; - +/* + * Button displaying voice chat status. Displays voice chat options When clicked. +*/ class LLTalkButton : public LLUICtrl { public: - virtual ~LLTalkButton(); + struct Params : public LLInitParam::Block + { + Optional speak_button, + show_button; - void onClick_SpeakBtn(); - void onClick_ShowBtn(); + Optional monitor; - void draw(); + Params(); + }; + + /*virtual*/ ~LLTalkButton(); + + /*virtual*/ void draw(); + void setSpeakBtnToggleState(bool state); protected: friend class LLUICtrlFactory; - LLTalkButton(const LLUICtrl::Params& p); + LLTalkButton(const Params& p); + + void onClick_SpeakBtn(); + + void onClick_ShowBtn(); private: LLButton* mSpeakBtn; @@ -283,4 +599,68 @@ private: LLOutputMonitorCtrl* mOutputMonitor; }; +template +T* LLChicletPanel::createChiclet(const LLUUID& session_id /*= LLUUID::null*/, S32 index /*= 0*/) +{ + typename T::Params params; + T* chiclet = LLUICtrlFactory::create(params); + if(!chiclet) + { + llwarns << "Could not create chiclet" << llendl; + return NULL; + } + if(!addChiclet(chiclet, index)) + { + delete chiclet; + llwarns << "Could not add chiclet to chiclet panel" << llendl; + return NULL; + } + + chiclet->setSessionId(session_id); + + return chiclet; +} + +template +T* LLChicletPanel::findChiclet(const LLUUID& im_session_id) +{ + if(im_session_id.isNull()) + { + return NULL; + } + + chiclet_list_t::const_iterator it = mChicletList.begin(); + for( ; mChicletList.end() != it; ++it) + { + LLChiclet* chiclet = *it; + + if(chiclet->getSessionId() == im_session_id) + { + T* result = dynamic_cast(chiclet); + if(!result && chiclet) + { + llwarns << "Found chiclet but of wrong type " << llendl; + } + return result; + } + } + return NULL; +} + +template T* LLChicletPanel::getChiclet(S32 index) +{ + if(index < 0 || index >= getChicletCount()) + { + return NULL; + } + + LLChiclet* chiclet = mChicletList[index]; + T*result = dynamic_cast(chiclet); + if(!result && chiclet) + { + llwarns << "Found chiclet but of wrong type " << llendl; + } + return result; +} + #endif // LL_LLCHICLET_H diff --git a/indra/newview/llclassifiedstatsresponder.h b/indra/newview/llclassifiedstatsresponder.h index c4591df8de..9c52ed5ae1 100644 --- a/indra/newview/llclassifiedstatsresponder.h +++ b/indra/newview/llclassifiedstatsresponder.h @@ -44,6 +44,7 @@ public: //If we get back a normal response, handle it here virtual void result(const LLSD& content); //If we get back an error (not found, etc...), handle it here + virtual void error(U32 status, const std::string& reason); protected: diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index 33aaac542b..31c2d93c05 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -48,10 +48,10 @@ #include "lltextbox.h" #include "llfloatercolorpicker.h" #include "llviewborder.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llfocusmgr.h" -static LLDefaultWidgetRegistry::Register r("color_swatch"); +static LLDefaultChildRegistry::Register r("color_swatch"); LLColorSwatchCtrl::Params::Params() : color("color", LLColor4::white), @@ -227,7 +227,7 @@ void LLColorSwatchCtrl::draw() { if (!mFallbackImageName.empty()) { - LLPointer fallback_image = gImageList.getImageFromFile(mFallbackImageName); + LLPointer fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); if( fallback_image->getComponents() == 4 ) { gl_rect_2d_checkerboard( interior ); diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h index a05926c2f5..e3e267f831 100644 --- a/indra/newview/llcolorswatch.h +++ b/indra/newview/llcolorswatch.h @@ -36,7 +36,7 @@ #include "lluictrl.h" #include "v4color.h" #include "llfloater.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "lltextbox.h" // @@ -45,7 +45,7 @@ class LLColor4; class LLTextBox; class LLFloaterColorPicker; -class LLViewerImage; +class LLViewerTexture; class LLColorSwatchCtrl : public LLUICtrl @@ -60,13 +60,13 @@ public: struct Params : public LLInitParam::Block { - Optional color; - Optional can_apply_immediately; - Optional alpha_background_image; - Optional cancel_callback; - Optional select_callback; - Optional border_color; - Optional label_width; + Optional color; + Optional can_apply_immediately; + Optional alpha_background_image; + Optional cancel_callback; + Optional select_callback; + Optional border_color; + Optional label_width; Optional caption_text; Optional border; diff --git a/indra/newview/lldebugmessagebox.cpp b/indra/newview/lldebugmessagebox.cpp index 9eee3b239c..786473eb9b 100644 --- a/indra/newview/lldebugmessagebox.cpp +++ b/indra/newview/lldebugmessagebox.cpp @@ -50,7 +50,7 @@ std::map LLDebugVarMessageBox::sInstances; LLDebugVarMessageBox::LLDebugVarMessageBox(const std::string& title, EDebugVarType var_type, void *var) : - LLFloater(), + LLFloater(LLSD()), mVarType(var_type), mVarData(var), mAnimate(FALSE) { setRect(LLRect(10,160,400,10)); @@ -250,11 +250,6 @@ void LLDebugVarMessageBox::onAnimateClicked(const LLSD& data) mAnimateButton->setToggleState(mAnimate); } -void LLDebugVarMessageBox::onClose(bool app_quitting) -{ - setVisible(FALSE); -} - void LLDebugVarMessageBox::draw() { std::string text; diff --git a/indra/newview/lldebugmessagebox.h b/indra/newview/lldebugmessagebox.h index 76e128cfc1..0def0ee7af 100644 --- a/indra/newview/lldebugmessagebox.h +++ b/indra/newview/lldebugmessagebox.h @@ -76,7 +76,6 @@ public: static void show(const std::string& title, LLVector3 *var, LLVector3 max_value = LLVector3(100.f, 100.f, 100.f), LLVector3 increment = LLVector3(0.1f, 0.1f, 0.1f)); //static void show(const std::string& title, LLVector4 *var, LLVector4 max_value = LLVector4(100.f, 100.f, 100.f, 100.f), LLVector4 increment = LLVector4(0.1f, 0.1f, 0.1f, 0.1f)); - virtual void onClose(bool app_quitting); virtual void draw(); protected: diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index cb368974ae..d8bd32382f 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -229,7 +229,7 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep) return count; } -LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep) +LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) { LLMemType mt(LLMemType::MTYPE_DRAWABLE); @@ -253,7 +253,7 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep) return face; } -LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerImage *texturep) +LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) { LLMemType mt(LLMemType::MTYPE_DRAWABLE); @@ -275,7 +275,7 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerImage *texturep) } -void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerImage *texturep) +void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep) { if (newFaces == (S32)mFaces.size()) { @@ -298,7 +298,7 @@ void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerImag llassert_always(mFaces.size() == newFaces); } -void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerImage *texturep) +void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep) { if (newFaces <= (S32)mFaces.size() && newFaces >= (S32)mFaces.size()/2) { diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index f3ef0753e7..940e1fc968 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -58,7 +58,7 @@ class LLSpatialGroup; class LLSpatialBridge; class LLSpatialPartition; class LLVOVolume; -class LLViewerImage; +class LLViewerTexture; // Can have multiple silhouettes for each object const U32 SILHOUETTE_HIGHLIGHT = 0; @@ -125,11 +125,11 @@ public: inline S32 getNumFaces() const; //void removeFace(const S32 i); // SJB: Avoid using this, it's slow - LLFace* addFace(LLFacePool *poolp, LLViewerImage *texturep); - LLFace* addFace(const LLTextureEntry *te, LLViewerImage *texturep); + LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep); + LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep); void deleteFaces(S32 offset, S32 count); - void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerImage *texturep); - void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerImage *texturep); + void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep); + void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep); void mergeFaces(LLDrawable* src); void init(); diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 9f05ce3c46..3a064a4e7d 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -60,7 +60,7 @@ S32 LLDrawPool::sNumDrawPools = 0; //============================= // Draw Pool Implementation //============================= -LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0) +LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0) { LLDrawPool *poolp = NULL; switch (type) @@ -129,7 +129,7 @@ LLDrawPool::~LLDrawPool() } -LLViewerImage *LLDrawPool::getDebugTexture() +LLViewerTexture *LLDrawPool::getDebugTexture() { return NULL; } @@ -244,7 +244,7 @@ void LLFacePool::destroy() } } -void LLFacePool::dirtyTextures(const std::set& textures) +void LLFacePool::dirtyTextures(const std::set& textures) { } @@ -279,7 +279,7 @@ S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage) iter != face_list.end(); iter++) { LLFace *facep = *iter; - gGL.getTexUnit(stage)->bind(facep->getTexture()); + gGL.getTexUnit(stage)->bind(facep->getTexture()) ; gGL.getTexUnit(0)->activate(); res += facep->renderIndexed(); } @@ -295,13 +295,6 @@ void LLFacePool::drawLoop() } } -void LLFacePool::renderFaceSelected(LLFace *facep, - LLImageGL *image, - const LLColor4 &color, - const S32 index_offset, const S32 index_count) -{ -} - void LLFacePool::enqueue(LLFace* facep) { mDrawFace.push_back(facep); @@ -330,7 +323,7 @@ void LLFacePool::resetDrawOrders() mDrawFace.resize(0); } -LLViewerImage *LLFacePool::getTexture() +LLViewerTexture *LLFacePool::getTexture() { return NULL; } @@ -481,7 +474,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) { if (params.mTexture.notNull()) { - gGL.getTexUnit(0)->bind(params.mTexture.get()); + gGL.getTexUnit(0)->bind(params.mTexture) ; if (params.mTextureMatrix) { glMatrixMode(GL_TEXTURE); diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 87c3ccaffe..966de41df3 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -39,8 +39,8 @@ #include "llvertexbuffer.h" class LLFace; -class LLImageGL; -class LLViewerImage; +class LLViewerTexture; +class LLViewerFetchedTexture; class LLSpatialGroup; class LLDrawInfo; @@ -77,7 +77,7 @@ public: S32 getId() const { return mId; } U32 getType() const { return mType; } - virtual LLViewerImage *getDebugTexture(); + virtual LLViewerTexture *getDebugTexture(); virtual void beginRenderPass( S32 pass ); virtual void endRenderPass( S32 pass ); virtual S32 getNumPasses(); @@ -103,9 +103,9 @@ public: virtual BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct! virtual S32 getVertexShaderLevel() const { return mVertexShaderLevel; } - static LLDrawPool* createPool(const U32 type, LLViewerImage *tex0 = NULL); + static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL); virtual LLDrawPool *instancePool() = 0; // Create an empty new instance of the pool. - virtual LLViewerImage* getTexture() = 0; + virtual LLViewerTexture* getTexture() = 0; virtual BOOL isFacePool() { return FALSE; } virtual void resetDrawOrders() = 0; @@ -139,8 +139,8 @@ public: LLRenderPass(const U32 type); virtual ~LLRenderPass(); /*virtual*/ LLDrawPool* instancePool(); - /*virtual*/ LLViewerImage* getDebugTexture() { return NULL; } - LLViewerImage* getTexture() { return NULL; } + /*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; } + LLViewerTexture* getTexture() { return NULL; } BOOL isDead() { return FALSE; } void resetDrawOrders() { } @@ -169,11 +169,9 @@ public: virtual void renderForSelect() = 0; BOOL isDead() { return mReferences.empty(); } - virtual void renderFaceSelected(LLFace *facep, LLImageGL *image, const LLColor4 &color, - const S32 index_offset = 0, const S32 index_count = 0); - - virtual LLViewerImage *getTexture(); - virtual void dirtyTextures(const std::set& textures); + + virtual LLViewerTexture *getTexture(); + virtual void dirtyTextures(const std::set& textures); virtual void enqueue(LLFace *face); virtual BOOL addFace(LLFace *face); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 7e470bd01f..267f83f295 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -46,7 +46,7 @@ #include "lldrawable.h" #include "llface.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" // For debugging +#include "llviewertexturelist.h" // For debugging #include "llviewerobjectlist.h" // For debugging #include "llviewerwindow.h" #include "pipeline.h" @@ -218,8 +218,8 @@ void LLDrawPoolAlpha::render(S32 pass) } gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); glColor4f(1,0,0,1); - LLViewerImage::sSmokeImagep->addTextureStats(1024.f*1024.f); - gGL.getTexUnit(0)->bind(LLViewerImage::sSmokeImagep.get()); + LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f); + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep) ; renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); } @@ -294,7 +294,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) if (params.mTexture.notNull()) { gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->bind(params.mTexture.get()); + gGL.getTexUnit(0)->bind(params.mTexture) ; params.mTexture->addTextureStats(params.mVSize); if (params.mTextureMatrix) { diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 51f4bbac5c..b15cd0b0dc 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -633,7 +633,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if (pass==1 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0)) { // debug code to draw a sphere in place of avatar - gGL.getTexUnit(0)->bind(LLViewerImage::sWhiteImagep.get()); + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); gGL.setColorMask(true, true); LLVector3 pos = avatarp->getPositionAgent(); gGL.color4f(1.0f, 1.0f, 1.0f, 0.7f); @@ -819,7 +819,7 @@ void LLDrawPoolAvatar::renderForSelect() //----------------------------------------------------------------------------- // getDebugTexture() //----------------------------------------------------------------------------- -LLViewerImage *LLDrawPoolAvatar::getDebugTexture() +LLViewerTexture *LLDrawPoolAvatar::getDebugTexture() { if (mReferences.empty()) { diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 1e2630e1fb..6a2b7fc218 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -105,7 +105,7 @@ public: void endDeferredRigid(); void endDeferredSkinned(); - /*virtual*/ LLViewerImage *getDebugTexture(); + /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null. diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index ed6e55b7bc..971949e885 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -37,7 +37,6 @@ #include "llstl.h" #include "llviewercontrol.h" #include "lldir.h" -#include "llimagegl.h" #include "m3math.h" #include "m4math.h" #include "v4math.h" @@ -51,7 +50,7 @@ #include "llsky.h" #include "lltextureentry.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "pipeline.h" #include "llspatialpartition.h" #include "llviewershadermgr.h" @@ -143,9 +142,10 @@ void LLStandardBumpmap::restoreGL() // llinfos << "Loading bumpmap: " << bump_image_id << " from viewerart" << llendl; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = - gImageList.getImage(LLUUID(bump_image_id), + LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id), TRUE, FALSE, + LLViewerTexture::LOD_TEXTURE, 0, 0); gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL ); @@ -569,22 +569,23 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL // static BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) { - LLImageGL* bump = NULL; + LLViewerTexture* bump = NULL; U8 bump_code = params.mBump; - LLViewerImage* tex = params.mTexture; + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params.mTexture) ; + if(!tex) + { + //if the texture is not a fetched texture + return FALSE; + } switch( bump_code ) { - case BE_NO_BUMP: - bump = NULL; + case BE_NO_BUMP: break; case BE_BRIGHTNESS: case BE_DARKNESS: - if( tex ) - { - bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); - } + bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); break; default: @@ -812,7 +813,7 @@ LLBumpImageList::~LLBumpImageList() void LLBumpImageList::addTextureStats(U8 bump, const LLUUID& base_image_id, F32 virtual_size) { bump &= TEM_BUMP_MASK; - LLViewerImage* bump_image = gStandardBumpmapList[bump].mImage; + LLViewerFetchedTexture* bump_image = gStandardBumpmapList[bump].mImage; if( bump_image ) { bump_image->addTextureStats(virtual_size); @@ -826,11 +827,11 @@ void LLBumpImageList::updateImages() for (bump_image_map_t::iterator iter = mBrightnessEntries.begin(); iter != mBrightnessEntries.end(); ) { bump_image_map_t::iterator curiter = iter++; - LLImageGL* image = curiter->second; + LLViewerTexture* image = curiter->second; if( image ) { BOOL destroy = TRUE; - if( image->getHasGLTexture()) + if( image->hasValidGLTexture()) { if( image->getBoundRecently() ) { @@ -853,11 +854,11 @@ void LLBumpImageList::updateImages() for (bump_image_map_t::iterator iter = mDarknessEntries.begin(); iter != mDarknessEntries.end(); ) { bump_image_map_t::iterator curiter = iter++; - LLImageGL* image = curiter->second; + LLViewerTexture* image = curiter->second; if( image ) { BOOL destroy = TRUE; - if( image->getHasGLTexture()) + if( image->hasValidGLTexture()) { if( image->getBoundRecently() ) { @@ -881,16 +882,16 @@ void LLBumpImageList::updateImages() // Note: the caller SHOULD NOT keep the pointer that this function returns. It may be updated as more data arrives. -LLImageGL* LLBumpImageList::getBrightnessDarknessImage(LLViewerImage* src_image, U8 bump_code ) +LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code ) { llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) ); - LLImageGL* bump = NULL; + LLViewerTexture* bump = NULL; const F32 BRIGHTNESS_DARKNESS_PIXEL_AREA_THRESHOLD = 1000; - if( src_image->mMaxVirtualSize > BRIGHTNESS_DARKNESS_PIXEL_AREA_THRESHOLD ) + if( src_image->getMaxVirtualSize() > BRIGHTNESS_DARKNESS_PIXEL_AREA_THRESHOLD ) { bump_image_map_t* entries_list = NULL; - void (*callback_func)( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL; + void (*callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL; switch( bump_code ) { @@ -917,14 +918,8 @@ LLImageGL* LLBumpImageList::getBrightnessDarknessImage(LLViewerImage* src_image, LLPointer raw = new LLImageRaw(1,1,1); raw->clear(0x77, 0x77, 0x77, 0xFF); - //------------------------------ - bump = new LLImageGL( raw, TRUE); - //immediately assign bump to a global smart pointer in case some local smart pointer - //accidently releases it. - (*entries_list)[src_image->getID()] = bump; - //------------------------------ - - bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA); + (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE); + (*entries_list)[src_image->getID()]->setExplicitFormat(GL_ALPHA8, GL_ALPHA); // Note: this may create an LLImageGL immediately src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()) ); @@ -940,7 +935,7 @@ LLImageGL* LLBumpImageList::getBrightnessDarknessImage(LLViewerImage* src_image, // static -void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) +void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { LLUUID* source_asset_id = (LLUUID*)userdata; LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS ); @@ -951,7 +946,7 @@ void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerImage *src } // static -void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) +void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { LLUUID* source_asset_id = (LLUUID*)userdata; LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_DARKNESS ); @@ -961,7 +956,7 @@ void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerImage *src_v } } -void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerImage* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) +void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { if (success && LLPipeline::sRenderDeferred) { @@ -1028,7 +1023,7 @@ void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nr } // static -void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code ) +void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code ) { if( success ) { @@ -1147,7 +1142,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerImage *src_vi, LLIma //--------------------------------------------------- //immediately assign bump to a global smart pointer in case some local smart pointer //accidently releases it. - LLPointer bump = new LLImageGL( TRUE); + LLPointer bump = LLViewerTextureManager::getLocalTexture( TRUE); if (!LLPipeline::sRenderDeferred) { @@ -1220,7 +1215,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) { if (params.mTexture.notNull()) { - gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); + gGL.getTexUnit(diffuse_channel)->bind(params.mTexture) ; params.mTexture->addTextureStats(params.mVSize); } else diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index 34c1e9c29f..bf940cf1e4 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -41,6 +41,7 @@ class LLImageRaw; class LLSpatialGroup; class LLDrawInfo; +class LLViewerFetchedTexture; class LLDrawPoolBump : public LLRenderPass { @@ -110,7 +111,7 @@ public: LLStandardBumpmap( const std::string& label ) : mLabel(label) {} std::string mLabel; - LLPointer mImage; + LLPointer mImage; static U32 sStandardBumpmapCount; // Number of valid values in gStandardBumpmapList[] @@ -140,21 +141,20 @@ public: void updateImages(); - LLImageGL* getBrightnessDarknessImage(LLViewerImage* src_image, U8 bump_code); -// LLImageGL* getTestImage(); + LLViewerTexture* getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code); void addTextureStats(U8 bump, const LLUUID& base_image_id, F32 virtual_size); - static void onSourceBrightnessLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); - static void onSourceDarknessLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); - static void onSourceStandardLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); + static void onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); + static void onSourceDarknessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); + static void onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); static void generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nrm_image); private: - static void onSourceLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump ); + static void onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump ); private: - typedef std::map > bump_image_map_t; + typedef std::map > bump_image_map_t; bump_image_map_t mBrightnessEntries; bump_image_map_t mDarknessEntries; }; diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index a9e0948ecf..8428be194f 100644 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -41,7 +41,7 @@ #include "llface.h" #include "llsky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "llvosky.h" #include "llworld.h" // To get water height diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 2c644b0fd5..a01c9026c8 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -49,7 +49,7 @@ #include "llviewerparceloverlay.h" #include "llvosurfacepatch.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" // To get alpha gradients +#include "llviewertexturelist.h" // To get alpha gradients #include "llworld.h" #include "pipeline.h" #include "llviewershadermgr.h" @@ -62,28 +62,32 @@ S32 LLDrawPoolTerrain::sDetailMode = 1; F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE; static LLGLSLShader* sShader = NULL; -LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerImage *texturep) : +LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : LLFacePool(POOL_TERRAIN), mTexturep(texturep) { // Hack! sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale"); sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); - mAlphaRampImagep = gImageList.getImageFromFile("alpha_gradient.tga", - TRUE, TRUE, GL_ALPHA8, GL_ALPHA, + mAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga", + TRUE, TRUE, + LLViewerTexture::FETCHED_TEXTURE, + GL_ALPHA8, GL_ALPHA, LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb")); - gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); + gGL.getTexUnit(0)->bind(mAlphaRampImagep); mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); - m2DAlphaRampImagep = gImageList.getImageFromFile("alpha_gradient_2d.j2c", - TRUE, TRUE, GL_ALPHA8, GL_ALPHA, + m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c", + TRUE, TRUE, + LLViewerTexture::FETCHED_TEXTURE, + GL_ALPHA8, GL_ALPHA, LLUUID("38b86f85-2575-52a9-a531-23108d8da837")); - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); - mTexturep->setBoostLevel(LLViewerImage::BOOST_TERRAIN); + mTexturep->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -170,7 +174,7 @@ void LLDrawPoolTerrain::render(S32 pass) LLVLComposition *compp = regionp->getComposition(); for (S32 i = 0; i < 4; i++) { - compp->mDetailTextures[i]->setBoostLevel(LLViewerImage::BOOST_TERRAIN); + compp->mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area } @@ -289,10 +293,10 @@ void LLDrawPoolTerrain::renderFullShader() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - LLViewerImage *detail_texture0p = compp->mDetailTextures[0]; - LLViewerImage *detail_texture1p = compp->mDetailTextures[1]; - LLViewerImage *detail_texture2p = compp->mDetailTextures[2]; - LLViewerImage *detail_texture3p = compp->mDetailTextures[3]; + LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; + LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; + LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; + LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; @@ -363,7 +367,7 @@ void LLDrawPoolTerrain::renderFullShader() // Alpha Ramp // S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); - gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep); // GL_BLEND disabled by default drawLoop(); @@ -429,10 +433,10 @@ void LLDrawPoolTerrain::renderFull4TU() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - LLViewerImage *detail_texture0p = compp->mDetailTextures[0]; - LLViewerImage *detail_texture1p = compp->mDetailTextures[1]; - LLViewerImage *detail_texture2p = compp->mDetailTextures[2]; - LLViewerImage *detail_texture3p = compp->mDetailTextures[3]; + LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; + LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; + LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; + LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; @@ -527,7 +531,7 @@ void LLDrawPoolTerrain::renderFull4TU() // // Stage 1: Generate alpha ramp for detail2/detail3 transition // - gGL.getTexUnit(1)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(1)->bind(m2DAlphaRampImagep); gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(1)->activate(); @@ -559,7 +563,7 @@ void LLDrawPoolTerrain::renderFull4TU() // // Stage 3: Generate alpha ramp for detail1/detail2 transition // - gGL.getTexUnit(3)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(3)->bind(m2DAlphaRampImagep); gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(3)->activate(); @@ -630,10 +634,10 @@ void LLDrawPoolTerrain::renderFull2TU() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - LLViewerImage *detail_texture0p = compp->mDetailTextures[0]; - LLViewerImage *detail_texture1p = compp->mDetailTextures[1]; - LLViewerImage *detail_texture2p = compp->mDetailTextures[2]; - LLViewerImage *detail_texture3p = compp->mDetailTextures[3]; + LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; + LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; + LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; + LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; @@ -671,7 +675,7 @@ void LLDrawPoolTerrain::renderFull2TU() // // Stage 0: Generate alpha ramp for detail0/detail1 transition // - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); @@ -709,7 +713,7 @@ void LLDrawPoolTerrain::renderFull2TU() // // Stage 0: Generate alpha ramp for detail1/detail2 transition // - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); // Set the texture matrix glMatrixMode(GL_TEXTURE); @@ -749,7 +753,7 @@ void LLDrawPoolTerrain::renderFull2TU() // Stage 0: Generate alpha ramp for detail2/detail3 transition // gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); // Set the texture matrix glMatrixMode(GL_TEXTURE); glLoadIdentity(); @@ -822,7 +826,7 @@ void LLDrawPoolTerrain::renderSimple() gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->bind(mTexturep.get()); + gGL.getTexUnit(0)->bind(mTexturep); LLVector3 origin_agent = mDrawFace[0]->getDrawable()->getVObj()->getRegion()->getOriginAgent(); F32 tscale = 1.f/256.f; @@ -872,7 +876,7 @@ void LLDrawPoolTerrain::renderOwnership() LLSurface *surfacep = surface_patchp->getSurface(); LLViewerRegion *regionp = surfacep->getRegion(); LLViewerParcelOverlay *overlayp = regionp->getParcelOverlay(); - LLImageGL *texturep = overlayp->getTexture(); + LLViewerTexture *texturep = overlayp->getTexture(); gGL.getTexUnit(0)->bind(texturep); @@ -920,9 +924,10 @@ void LLDrawPoolTerrain::renderForSelect() } } -void LLDrawPoolTerrain::dirtyTextures(const std::set& textures) +void LLDrawPoolTerrain::dirtyTextures(const std::set& textures) { - if (textures.find(mTexturep) != textures.end()) + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(mTexturep) ; + if (tex && textures.find(tex) != textures.end()) { for (std::vector::iterator iter = mReferences.begin(); iter != mReferences.end(); iter++) @@ -933,12 +938,12 @@ void LLDrawPoolTerrain::dirtyTextures(const std::set& textures) } } -LLViewerImage *LLDrawPoolTerrain::getTexture() +LLViewerTexture *LLDrawPoolTerrain::getTexture() { return mTexturep; } -LLViewerImage *LLDrawPoolTerrain::getDebugTexture() +LLViewerTexture *LLDrawPoolTerrain::getDebugTexture() { return mTexturep; } diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 19d09e2feb..2e2a36d533 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -37,7 +37,7 @@ class LLDrawPoolTerrain : public LLFacePool { - LLPointer mTexturep; + LLPointer mTexturep; public: enum { @@ -53,7 +53,7 @@ public: virtual U32 getVertexDataMask(); static S32 getDetailMode(); - LLDrawPoolTerrain(LLViewerImage *texturep); + LLDrawPoolTerrain(LLViewerTexture *texturep); virtual ~LLDrawPoolTerrain(); /*virtual*/ LLDrawPool *instancePool(); @@ -73,14 +73,14 @@ public: /*virtual*/ void beginRenderPass( S32 pass ); /*virtual*/ void endRenderPass( S32 pass ); /*virtual*/ void renderForSelect(); - /*virtual*/ void dirtyTextures(const std::set& textures); - /*virtual*/ LLViewerImage *getTexture(); - /*virtual*/ LLViewerImage *getDebugTexture(); + /*virtual*/ void dirtyTextures(const std::set& textures); + /*virtual*/ LLViewerTexture *getTexture(); + /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display - LLPointer mAlphaRampImagep; - LLPointer m2DAlphaRampImagep; - LLPointer mAlphaNoiseImagep; + LLPointer mAlphaRampImagep; + LLPointer m2DAlphaRampImagep; + LLPointer mAlphaNoiseImagep; static S32 sDetailMode; static F32 sDetailScale; // meters per texture diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 22634d96b0..f572e2cb44 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -47,11 +47,11 @@ S32 LLDrawPoolTree::sDiffTex = 0; static LLGLSLShader* shader = NULL; -LLDrawPoolTree::LLDrawPoolTree(LLViewerImage *texturep) : +LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) : LLFacePool(POOL_TREE), mTexturep(texturep) { - gGL.getTexUnit(0)->bind(mTexturep.get()); + gGL.getTexUnit(0)->bind(mTexturep); mTexturep->setAddressMode(LLTexUnit::TAM_WRAP); } @@ -246,7 +246,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting) LLGLState normalize(GL_NORMALIZE, TRUE); // Bind the texture for this tree. - gGL.getTexUnit(sDiffTex)->bind(mTexturep.get()); + gGL.getTexUnit(sDiffTex)->bind(mTexturep); U32 indices_drawn = 0; @@ -376,12 +376,12 @@ BOOL LLDrawPoolTree::verify() const return TRUE; } -LLViewerImage *LLDrawPoolTree::getTexture() +LLViewerTexture *LLDrawPoolTree::getTexture() { return mTexturep; } -LLViewerImage *LLDrawPoolTree::getDebugTexture() +LLViewerTexture *LLDrawPoolTree::getDebugTexture() { return mTexturep; } diff --git a/indra/newview/lldrawpooltree.h b/indra/newview/lldrawpooltree.h index 80c4fdfffe..bc7711d4e8 100644 --- a/indra/newview/lldrawpooltree.h +++ b/indra/newview/lldrawpooltree.h @@ -37,7 +37,7 @@ class LLDrawPoolTree : public LLFacePool { - LLPointer mTexturep; + LLPointer mTexturep; public: enum { @@ -48,7 +48,7 @@ public: virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } - LLDrawPoolTree(LLViewerImage *texturep); + LLDrawPoolTree(LLViewerTexture *texturep); /*virtual*/ LLDrawPool *instancePool(); @@ -70,8 +70,8 @@ public: /*virtual*/ S32 getNumPasses() { return 1; } /*virtual*/ void renderForSelect(); /*virtual*/ BOOL verify() const; - /*virtual*/ LLViewerImage *getTexture(); - /*virtual*/ LLViewerImage *getDebugTexture(); + /*virtual*/ LLViewerTexture *getTexture(); + /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display static S32 sDiffTex; diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 4a593ac4f8..16623ca2b6 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -45,7 +45,7 @@ #include "lldrawable.h" #include "llface.h" #include "llsky.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "llvosky.h" #include "llvowater.h" @@ -69,17 +69,17 @@ LLVector3 LLDrawPoolWater::sLightDir; LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER) { - mHBTex[0] = gImageList.getImage(gSunTextureID, TRUE, TRUE); - gGL.getTexUnit(0)->bind(mHBTex[0].get()); + mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, TRUE); + gGL.getTexUnit(0)->bind(mHBTex[0]) ; mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP); - mHBTex[1] = gImageList.getImage(gMoonTextureID, TRUE, TRUE); - gGL.getTexUnit(0)->bind(mHBTex[1].get()); + mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, TRUE); + gGL.getTexUnit(0)->bind(mHBTex[1]); mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP); - mWaterImagep = gImageList.getImage(WATER_TEST); + mWaterImagep = LLViewerTextureManager::getFetchedTexture(WATER_TEST); mWaterImagep->setNoDelete() ; - mWaterNormp = gImageList.getImage(DEFAULT_WATER_NORMAL); + mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL); mWaterNormp->setNoDelete() ; restoreGL(); @@ -184,7 +184,7 @@ void LLDrawPoolWater::render(S32 pass) mWaterImagep->addTextureStats(1024.f*1024.f); gGL.getTexUnit(1)->activate(); gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->bind(mWaterImagep.get()); + gGL.getTexUnit(1)->bind(mWaterImagep) ; LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); F32 up_dot = camera_up * LLVector3::z_axis; @@ -329,7 +329,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face) LLGLSNoFog noFog; - gGL.getTexUnit(0)->bind(mHBTex[dr].get()); + gGL.getTexUnit(0)->bind(mHBTex[dr]); LLOverrideFaceColor override(this, face->getFaceColor().mV); face->renderIndexed(); @@ -419,11 +419,11 @@ void LLDrawPoolWater::shade() // change mWaterNormp if needed if (mWaterNormp->getID() != param_mgr->getNormalMapID()) { - mWaterNormp = gImageList.getImage(param_mgr->getNormalMapID()); + mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID()); } mWaterNormp->addTextureStats(1024.f*1024.f); - gGL.getTexUnit(bumpTex)->bind(mWaterNormp.get()); + gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ; if (gSavedSettings.getBOOL("RenderWaterMipNormal")) { mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); @@ -587,20 +587,9 @@ void LLDrawPoolWater::renderForSelect() return; } - -void LLDrawPoolWater::renderFaceSelected(LLFace *facep, - LLImageGL *image, - const LLColor4 &color, - const S32 index_offset, const S32 index_count) +LLViewerTexture *LLDrawPoolWater::getDebugTexture() { - // Can't select water - return; -} - - -LLViewerImage *LLDrawPoolWater::getDebugTexture() -{ - return LLViewerImage::sSmokeImagep; + return LLViewerFetchedTexture::sSmokeImagep; } LLColor3 LLDrawPoolWater::getDebugColor() const diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index 6351041140..e28ac1cfab 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -43,9 +43,9 @@ class LLWaterSurface; class LLDrawPoolWater: public LLFacePool { protected: - LLPointer mHBTex[2]; - LLPointer mWaterImagep; - LLPointer mWaterNormp; + LLPointer mHBTex[2]; + LLPointer mWaterImagep; + LLPointer mWaterNormp; const LLWaterSurface *mWaterSurface; public: @@ -78,12 +78,10 @@ public: /*virtual*/ S32 getNumPasses(); /*virtual*/ void render(S32 pass = 0); - /*virtual*/ void renderFaceSelected(LLFace *facep, LLImageGL *image, const LLColor4 &color, - const S32 index_offset = 0, const S32 index_count = 0); /*virtual*/ void prerender(); /*virtual*/ void renderForSelect(); - /*virtual*/ LLViewerImage *getDebugTexture(); + /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display void renderReflection(LLFace* face); diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 6ff65c7ed0..917b6fafbc 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -47,7 +47,7 @@ #include "llface.h" #include "llrender.h" -LLPointer LLDrawPoolWLSky::sCloudNoiseTexture = NULL; +LLPointer LLDrawPoolWLSky::sCloudNoiseTexture = NULL; LLPointer LLDrawPoolWLSky::sCloudNoiseRawImage = NULL; @@ -71,7 +71,7 @@ LLDrawPoolWLSky::LLDrawPoolWLSky(void) : cloudNoiseFile->decode(sCloudNoiseRawImage, 0.0f); - LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE); + sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE); LLWLParamManager::instance()->propagateParameters(); } @@ -83,7 +83,7 @@ LLDrawPoolWLSky::~LLDrawPoolWLSky() sCloudNoiseRawImage = NULL; } -LLViewerImage *LLDrawPoolWLSky::getDebugTexture() +LLViewerTexture *LLDrawPoolWLSky::getDebugTexture() { return NULL; } @@ -224,7 +224,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN]; if (gSky.mVOSkyp->getSun().getDraw() && face->getGeomCount()) { - LLImageGL * tex = face->getTexture(); + LLViewerTexture * tex = face->getTexture(); gGL.getTexUnit(0)->bind(tex); LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor()); LLFacePool::LLOverrideFaceColor color_override(this, color); @@ -239,8 +239,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() // *NOTE: even though we already bound this texture above for the // stars register combiners, we bind again here for defensive reasons, // since LLImageGL::bind detects that it's a noop, and optimizes it out. - LLImageGL * tex = face->getTexture(); - gGL.getTexUnit(0)->bind(tex); + gGL.getTexUnit(0)->bind(face->getTexture()); LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor()); F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2]; if (a > 0.f) @@ -280,9 +279,8 @@ void LLDrawPoolWLSky::render(S32 pass) // *NOTE: have to bind a texture here since register combiners blending in // renderStars() requires something to be bound and we might as well only - // bind the moon's texture once. - LLImageGL * tex = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture(); - gGL.getTexUnit(0)->bind(tex); + // bind the moon's texture once. + gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture()); renderHeavenlyBodies(); @@ -306,7 +304,7 @@ LLDrawPoolWLSky *LLDrawPoolWLSky::instancePool() return new LLDrawPoolWLSky(); } -LLViewerImage* LLDrawPoolWLSky::getTexture() +LLViewerTexture* LLDrawPoolWLSky::getTexture() { return NULL; } @@ -324,5 +322,5 @@ void LLDrawPoolWLSky::cleanupGL() //static void LLDrawPoolWLSky::restoreGL() { - LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE); + sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE); } diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h index c7a1f3fe27..7ff760ac39 100644 --- a/indra/newview/lldrawpoolwlsky.h +++ b/indra/newview/lldrawpoolwlsky.h @@ -55,7 +55,7 @@ public: /*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } - /*virtual*/ LLViewerImage *getDebugTexture(); + /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ void beginRenderPass( S32 pass ); /*virtual*/ void endRenderPass( S32 pass ); /*virtual*/ S32 getNumPasses() { return 1; } @@ -65,11 +65,11 @@ public: /*virtual*/ BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct! /*virtual*/ S32 getVertexShaderLevel() const { return mVertexShaderLevel; } - //static LLDrawPool* createPool(const U32 type, LLViewerImage *tex0 = NULL); + //static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL); // Create an empty new instance of the pool. /*virtual*/ LLDrawPoolWLSky *instancePool(); ///< covariant override - /*virtual*/ LLViewerImage* getTexture(); + /*virtual*/ LLViewerTexture* getTexture(); /*virtual*/ BOOL isFacePool() { return FALSE; } /*virtual*/ void resetDrawOrders(); @@ -83,7 +83,7 @@ private: void renderHeavenlyBodies(); private: - static LLPointer sCloudNoiseTexture; + static LLPointer sCloudNoiseTexture; static LLPointer sCloudNoiseRawImage; }; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 1953c29068..0bb5edf3f9 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -1,6 +1,6 @@ /** * @file lldynamictexture.cpp - * @brief Implementation of LLDynamicTexture class + * @brief Implementation of LLViewerDynamicTexture class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -42,24 +42,20 @@ #include "llviewerwindow.h" #include "llviewercamera.h" #include "llviewercontrol.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llvertexbuffer.h" #include "llviewerdisplay.h" #include "llrender.h" // static -LLDynamicTexture::instance_list_t LLDynamicTexture::sInstances[ LLDynamicTexture::ORDER_COUNT ]; -S32 LLDynamicTexture::sNumRenders = 0; +LLViewerDynamicTexture::instance_list_t LLViewerDynamicTexture::sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; +S32 LLViewerDynamicTexture::sNumRenders = 0; //----------------------------------------------------------------------------- -// LLDynamicTexture() +// LLViewerDynamicTexture() //----------------------------------------------------------------------------- -LLDynamicTexture::LLDynamicTexture(S32 width, S32 height, S32 components, EOrder order, BOOL clamp) : - mWidth(width), - mHeight(height), - mComponents(components), - mTexture(NULL), - mLastBindTime(0), +LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 components, EOrder order, BOOL clamp) : + LLViewerTexture(width, height, components, FALSE), mClamp(clamp) { llassert((1 <= components) && (components <= 4)); @@ -67,64 +63,56 @@ LLDynamicTexture::LLDynamicTexture(S32 width, S32 height, S32 components, EOrder generateGLTexture(); llassert( 0 <= order && order < ORDER_COUNT ); - LLDynamicTexture::sInstances[ order ].insert(this); + LLViewerDynamicTexture::sInstances[ order ].insert(this); } //----------------------------------------------------------------------------- -// LLDynamicTexture() +// LLViewerDynamicTexture() //----------------------------------------------------------------------------- -LLDynamicTexture::~LLDynamicTexture() +LLViewerDynamicTexture::~LLViewerDynamicTexture() { - releaseGLTexture(); for( S32 order = 0; order < ORDER_COUNT; order++ ) { - LLDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. + LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. } } -//----------------------------------------------------------------------------- -// releaseGLTexture() -//----------------------------------------------------------------------------- -void LLDynamicTexture::releaseGLTexture() +//virtual +S8 LLViewerDynamicTexture::getType() const { - if (mTexture.notNull()) - { -// llinfos << "RELEASING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl; - mTexture = NULL; - } + return LLViewerTexture::DYNAMIC_TEXTURE ; } //----------------------------------------------------------------------------- // generateGLTexture() //----------------------------------------------------------------------------- -void LLDynamicTexture::generateGLTexture() +void LLViewerDynamicTexture::generateGLTexture() { + LLViewerTexture::generateGLTexture() ; generateGLTexture(-1, 0, 0, FALSE); } -void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) +void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) { if (mComponents < 1 || mComponents > 4) { llerrs << "Bad number of components in dynamic texture: " << mComponents << llendl; } - releaseGLTexture(); - LLPointer raw_image = new LLImageRaw(mWidth, mHeight, mComponents); - mTexture = new LLViewerImage(mWidth, mHeight, mComponents, FALSE); + + LLPointer raw_image = new LLImageRaw(mFullWidth, mFullHeight, mComponents); if (internal_format >= 0) { - mTexture->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes); + setExplicitFormat(internal_format, primary_format, type_format, swap_bytes); } -// llinfos << "ALLOCATING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl; - mTexture->createGLTexture(0, raw_image); - mTexture->setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP); - mTexture->setGLTextureCreated(false); + createGLTexture(0, raw_image); + setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP); + mGLTexturep->setGLTextureCreated(false); } //----------------------------------------------------------------------------- // render() //----------------------------------------------------------------------------- -BOOL LLDynamicTexture::render() +BOOL LLViewerDynamicTexture::render() { return FALSE; } @@ -132,13 +120,13 @@ BOOL LLDynamicTexture::render() //----------------------------------------------------------------------------- // preRender() //----------------------------------------------------------------------------- -void LLDynamicTexture::preRender(BOOL clear_depth) +void LLViewerDynamicTexture::preRender(BOOL clear_depth) { { // force rendering to on-screen portion of frame buffer LLCoordScreen window_pos; gViewerWindow->getWindow()->getPosition( &window_pos ); - mOrigin.set(0, gViewerWindow->getWindowDisplayHeight() - mHeight); // top left corner + mOrigin.set(0, gViewerWindow->getWindowDisplayHeight() - mFullHeight); // top left corner if (window_pos.mX < 0) { @@ -159,7 +147,7 @@ void LLDynamicTexture::preRender(BOOL clear_depth) mCamera.setView(LLViewerCamera::getInstance()->getView()); mCamera.setNear(LLViewerCamera::getInstance()->getNear()); - glViewport(mOrigin.mX, mOrigin.mY, mWidth, mHeight); + glViewport(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); if (clear_depth) { glClear(GL_DEPTH_BUFFER_BIT); @@ -169,12 +157,16 @@ void LLDynamicTexture::preRender(BOOL clear_depth) //----------------------------------------------------------------------------- // postRender() //----------------------------------------------------------------------------- -void LLDynamicTexture::postRender(BOOL success) +void LLViewerDynamicTexture::postRender(BOOL success) { { if (success) { - success = mTexture->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mWidth, mHeight); + if(mGLTexturep.isNull()) + { + generateGLTexture() ; + } + success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); } } @@ -194,7 +186,7 @@ void LLDynamicTexture::postRender(BOOL success) // updateDynamicTextures() // Calls update on each dynamic texture. Calls each group in order: "first," then "middle," then "last." //----------------------------------------------------------------------------- -BOOL LLDynamicTexture::updateAllInstances() +BOOL LLViewerDynamicTexture::updateAllInstances() { sNumRenders = 0; if (gGLManager.mIsDisabled) @@ -206,10 +198,10 @@ BOOL LLDynamicTexture::updateAllInstances() BOOL ret = FALSE ; for( S32 order = 0; order < ORDER_COUNT; order++ ) { - for (instance_list_t::iterator iter = LLDynamicTexture::sInstances[order].begin(); - iter != LLDynamicTexture::sInstances[order].end(); ++iter) + for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); + iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) { - LLDynamicTexture *dynamicTexture = *iter; + LLViewerDynamicTexture *dynamicTexture = *iter; if (dynamicTexture->needsRender()) { glClear(GL_DEPTH_BUFFER_BIT); @@ -236,30 +228,18 @@ BOOL LLDynamicTexture::updateAllInstances() return ret; } -//virtual -void LLDynamicTexture::restoreGLTexture() -{ - generateGLTexture() ; -} - -//virtual -void LLDynamicTexture::destroyGLTexture() -{ - releaseGLTexture() ; -} - //----------------------------------------------------------------------------- // static // destroyGL() //----------------------------------------------------------------------------- -void LLDynamicTexture::destroyGL() +void LLViewerDynamicTexture::destroyGL() { for( S32 order = 0; order < ORDER_COUNT; order++ ) { - for (instance_list_t::iterator iter = LLDynamicTexture::sInstances[order].begin(); - iter != LLDynamicTexture::sInstances[order].end(); ++iter) + for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); + iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) { - LLDynamicTexture *dynamicTexture = *iter; + LLViewerDynamicTexture *dynamicTexture = *iter; dynamicTexture->destroyGLTexture() ; } } @@ -269,7 +249,7 @@ void LLDynamicTexture::destroyGL() // static // restoreGL() //----------------------------------------------------------------------------- -void LLDynamicTexture::restoreGL() +void LLViewerDynamicTexture::restoreGL() { if (gGLManager.mIsDisabled) { @@ -278,10 +258,10 @@ void LLDynamicTexture::restoreGL() for( S32 order = 0; order < ORDER_COUNT; order++ ) { - for (instance_list_t::iterator iter = LLDynamicTexture::sInstances[order].begin(); - iter != LLDynamicTexture::sInstances[order].end(); ++iter) + for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); + iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) { - LLDynamicTexture *dynamicTexture = *iter; + LLViewerDynamicTexture *dynamicTexture = *iter; dynamicTexture->restoreGLTexture() ; } } diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index 22e5a4819d..2a944eaada 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -1,6 +1,6 @@ /** * @file lldynamictexture.h - * @brief Implementation of LLDynamicTexture class + * @brief Implementation of LLViewerDynamicTexture class * * $LicenseInfo:firstyear=2002&license=viewergpl$ * @@ -36,59 +36,52 @@ #include "llcamera.h" #include "llgl.h" #include "llcoord.h" -#include "llimagegl.h" +#include "llviewertexture.h" +#include "llcamera.h" -class LLDynamicTexture +class LLViewerDynamicTexture : public LLViewerTexture { +protected: + /*virtual*/ ~LLViewerDynamicTexture(); + public: enum EOrder { ORDER_FIRST = 0, ORDER_MIDDLE = 1, ORDER_LAST = 2, ORDER_RESET = 3, ORDER_COUNT = 4 }; - LLDynamicTexture(S32 width, + LLViewerDynamicTexture(S32 width, S32 height, S32 components, // = 4, EOrder order, // = ORDER_MIDDLE, BOOL clamp); - virtual ~LLDynamicTexture(); + + /*virtual*/ S8 getType() const ; S32 getOriginX() { return mOrigin.mX; } S32 getOriginY() { return mOrigin.mY; } - S32 getWidth() { return mWidth; } - S32 getHeight() { return mHeight; } - S32 getComponents() { return mComponents; } - S32 getSize() { return mWidth * mHeight * mComponents; } + + S32 getSize() { return mFullWidth * mFullHeight * mComponents; } virtual BOOL needsRender() { return TRUE; } virtual void preRender(BOOL clear_depth = TRUE); virtual BOOL render(); virtual void postRender(BOOL success); - virtual void restoreGLTexture() ; - virtual void destroyGLTexture() ; - - LLImageGL* getTexture(void) const { return mTexture; } + virtual void restoreGLTexture() {} + virtual void destroyGLTexture() {} static BOOL updateAllInstances(); - - static void destroyGL(); - static void restoreGL(); - + static void destroyGL() ; + static void restoreGL() ; protected: - void releaseGLTexture(); void generateGLTexture(); void generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes = FALSE); protected: - S32 mWidth; - S32 mHeight; - S32 mComponents; - LLPointer mTexture; - F32 mLastBindTime; BOOL mClamp; LLCoordGL mOrigin; - LLCamera mCamera; - typedef std::set instance_list_t; - static instance_list_t sInstances[ LLDynamicTexture::ORDER_COUNT ]; + + typedef std::set instance_list_t; + static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; static S32 sNumRenders; }; diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp index e54d78de2e..80d4d21166 100644 --- a/indra/newview/lleventnotifier.cpp +++ b/indra/newview/lleventnotifier.cpp @@ -190,9 +190,12 @@ bool LLEventNotification::handleResponse(const LLSD& notification, const LLSD& r switch (option) { case 0: - gAgent.teleportViaLocation(getEventPosGlobal()); - LLFloaterWorldMap::getInstance()->trackLocation(getEventPosGlobal()); - break; + { + gAgent.teleportViaLocation(getEventPosGlobal()); + LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance(); + if(floater_world_map) floater_world_map->trackLocation(getEventPosGlobal()); + break; + } case 1: gDisplayEventHack = TRUE; LLFloaterReg::showInstance("search", LLSD().insert("panel", "event").insert("id", S32(getEventID()))); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 69edccacf0..bef9e40c49 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -47,7 +47,7 @@ #include "lllightconstants.h" #include "llsky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llvosky.h" #include "llvovolume.h" #include "pipeline.h" @@ -179,6 +179,10 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) void LLFace::destroy() { + if(mTexture.notNull()) + { + mTexture->removeFace(this) ; + } if (mDrawPoolp) { mDrawPoolp->removeFace(this); @@ -217,7 +221,7 @@ void LLFace::setWorldMatrix(const LLMatrix4 &mat) llerrs << "Faces on this drawable are not independently modifiable\n" << llendl; } -void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep) +void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep) { LLMemType mt1(LLMemType::MTYPE_DRAWABLE); @@ -247,9 +251,28 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep) } mDrawPoolp = new_pool; } - mTexture = texturep; + setTexture(texturep) ; } +void LLFace::setTexture(LLViewerTexture* tex) +{ + if(mTexture == tex) + { + return ; + } + + if(mTexture.notNull()) + { + mTexture->removeFace(this) ; + } + + mTexture = tex ; + + if(mTexture.notNull()) + { + mTexture->addFace(this) ; + } +} void LLFace::setTEOffset(const S32 te_offset) { @@ -422,7 +445,7 @@ void LLFace::renderForSelect(U32 data_mask) } } -void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) +void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) { if(mDrawablep.isNull() || mVertexBuffer.isNull() || mDrawablep->getSpatialGroup() == NULL || mDrawablep->getSpatialGroup()->isState(LLSpatialGroup::GEOM_DIRTY)) @@ -463,8 +486,8 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) /* removed in lieu of raycast uv detection void LLFace::renderSelectedUV() { - LLViewerImage* red_blue_imagep = gImageList.getImageFromFile("uv_test1.j2c", TRUE, TRUE); - LLViewerImage* green_imagep = gImageList.getImageFromFile("uv_test2.tga", TRUE, TRUE); + LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, TRUE); + LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, TRUE); LLGLSUVSelect object_select; @@ -998,7 +1021,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, break; case BE_BRIGHTNESS: case BE_DARKNESS: - if( mTexture.notNull() && mTexture->getHasGLTexture()) + if( mTexture.notNull() && mTexture->hasValidGLTexture()) { // Offset by approximately one texel S32 cur_discard = mTexture->getDiscardLevel(); diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 8332eec19c..e0728fe15e 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -45,15 +45,15 @@ #include "xform.h" #include "lldarrayptr.h" #include "llvertexbuffer.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "lldrawable.h" class LLFacePool; class LLVolume; -class LLViewerImage; +class LLViewerTexture; class LLTextureEntry; class LLVertexProgram; -class LLViewerImage; +class LLViewerTexture; class LLGeometryManager; const F32 MIN_ALPHA_SIZE = 1024.f; @@ -86,8 +86,8 @@ public: U16 getGeomCount() const { return mGeomCount; } // vertex count for this face U16 getGeomIndex() const { return mGeomIndex; } // index into draw pool U16 getGeomStart() const { return mGeomIndex; } // index into draw pool - LLViewerImage* getTexture() const { return mTexture; } - void setTexture(LLViewerImage* tex) { mTexture = tex; } + LLViewerTexture* getTexture() const { return mTexture; } + void setTexture(LLViewerTexture* tex) ; LLXformMatrix* getXform() const { return mXform; } BOOL hasGeometry() const { return mGeomCount > 0; } LLVector3 getPositionAgent() const; @@ -119,10 +119,10 @@ public: LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; } void setPoolType(U32 type) { mPoolType = type; } S32 getTEOffset() { return mTEOffset; } - LLViewerImage* getTexture() { return mTexture; } + LLViewerTexture* getTexture() { return mTexture; } void setViewerObject(LLViewerObject* object); - void setPool(LLFacePool *pool, LLViewerImage *texturep); + void setPool(LLFacePool *pool, LLViewerTexture *texturep); void setDrawable(LLDrawable *drawable); void setTEOffset(const S32 te_offset); @@ -171,7 +171,7 @@ public: void renderSelectedUV(); void renderForSelect(U32 data_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); - void renderSelected(LLImageGL *image, const LLColor4 &color); + void renderSelected(LLViewerTexture *image, const LLColor4 &color); F32 getKey() const { return mDistance; } @@ -222,7 +222,7 @@ protected: U32 mLastIndicesIndex; LLXformMatrix* mXform; - LLPointer mTexture; + LLPointer mTexture; LLPointer mDrawablep; LLPointer mVObjp; S32 mTEOffset; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index bae3d57300..f383e5301c 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -44,7 +44,7 @@ #include "llsdserialize.h" #include "llappviewer.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llui.h" #include "llviewercontrol.h" #include "llstat.h" @@ -80,7 +80,7 @@ static timer_tree_iterator_t end_timer_tree() } LLFastTimerView::LLFastTimerView(const LLRect& rect) -: LLFloater(), +: LLFloater(LLSD()), mHoverTimer(NULL) { setRect(rect); diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 0e5b943dd3..3964fbfa74 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -43,11 +43,13 @@ #include "llagent.h" #include "llinventorybridge.h" #include "llinventorymodel.h" +#include "llsidetray.h" +#include "lltoggleablemenu.h" #include "llviewerinventory.h" #include "llviewermenu.h" #include "llviewermenu.h" -static LLDefaultWidgetRegistry::Register r("favorites_bar"); +static LLDefaultChildRegistry::Register r("favorites_bar"); // updateButtons's helper struct LLFavoritesSort @@ -69,41 +71,6 @@ struct LLFavoritesSort } }; -class LLVisibilityTrackingMenuGL : public LLMenuGL -{ -protected: - LLVisibilityTrackingMenuGL(const LLMenuGL::Params&); - friend class LLUICtrlFactory; -public: - virtual void onVisibilityChange (BOOL curVisibilityIn); - void setChevronRect(const LLRect& rect) { mChevronRect = rect; } - - bool getClosedByChevronClick() { return mClosedByChevronClick; } - void resetClosedByChevronClick() { mClosedByChevronClick = false; } - -protected: - bool mClosedByChevronClick; - LLRect mChevronRect; -}; - -LLVisibilityTrackingMenuGL::LLVisibilityTrackingMenuGL(const LLMenuGL::Params& p) -: LLMenuGL(p), - mClosedByChevronClick(false) -{ -} - -//virtual -void LLVisibilityTrackingMenuGL::onVisibilityChange (BOOL curVisibilityIn) -{ - S32 x,y; - LLUI::getCursorPositionLocal(LLUI::getRootView(), &x, &y); - - if (!curVisibilityIn && mChevronRect.pointInRect(x, y)) - { - mClosedByChevronClick = true; - } -} - LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p) : LLUICtrl(p), mFont(p.font.isProvided() ? p.font() : LLFontGL::getFontSansSerifSmall()), @@ -213,7 +180,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) const S32 buttonHPad = LLUI::sSettingGroups["config"]->getS32("ButtonHPad"); const S32 buttonHGap = 2; const S32 buttonVGap = 2; - static LLButton::Params default_button_params(LLUICtrlFactory::getDefaultParams()); + static LLButton::Params default_button_params(LLUICtrlFactory::getDefaultParams()); std::string flat_icon = "transparent.j2c"; std::string hover_icon = default_button_params.image_unselected.name; std::string hover_icon_selected = default_button_params.image_selected.name; @@ -249,6 +216,8 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) } } + bool recreate_buttons = true; + // If inventory items are not changed up to mFirstDropDownItem, no need to recreate them if (mFirstDropDownItem == first_drop_down_item && (mItemNamesCache.size() == count || mItemNamesCache.size() == mFirstDropDownItem)) { @@ -262,114 +231,125 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) } if (i == mFirstDropDownItem) { - // Chevron button should stay right aligned - LLView *chevron_button = getChildView(std::string(">>"), FALSE, FALSE); - if (chevron_button) - { - LLRect rect; - rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap); - chevron_button->setRect(rect); - - S32 chevron_root_x, chevron_root_y; - localPointToOtherView(rect.mLeft, rect.mBottom, &chevron_root_x, &chevron_root_y, LLUI::getRootView()); - mChevronRect.setOriginAndSize(chevron_root_x, chevron_root_y, rect.getWidth(), rect.getHeight()); - } - return; + recreate_buttons = false; } } - mFirstDropDownItem = first_drop_down_item; - - mItemNamesCache.clear(); - for (S32 i = 0; i < mFirstDropDownItem; i++) + if (recreate_buttons) { - mItemNamesCache.put(items.get(i)->getName()); - } + mFirstDropDownItem = first_drop_down_item; - // Rebuild the buttons only - // child_list_t is a linked list, so safe to erase from the middle if we pre-incrament the iterator - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ) - { - child_list_const_iter_t cur_it = child_it++; - LLView* viewp = *cur_it; - LLButton* button = dynamic_cast(viewp); - if (button) - { - removeChild(button); - delete button; - } - } + mItemNamesCache.clear(); + for (S32 i = 0; i < mFirstDropDownItem; i++) + { + mItemNamesCache.put(items.get(i)->getName()); + } - // Adding buttons - for(S32 i = 0; i < mFirstDropDownItem; i++) - { - - LLInventoryItem* item = items.get(i); + // Rebuild the buttons only + // child_list_t is a linked list, so safe to erase from the middle if we pre-incrament the iterator + for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ) + { + child_list_const_iter_t cur_it = child_it++; + LLView* viewp = *cur_it; + LLButton* button = dynamic_cast(viewp); + if (button) + { + removeChild(button); + delete button; + } + } - S32 buttonWidth = mFont->getWidth(item->getName()) + buttonHPad * 2; + // Adding buttons + for(S32 i = mFirstDropDownItem -1; i >= 0; i--) + { - LLRect rect; - rect.setOriginAndSize(curr_x, buttonVGap, buttonWidth, getRect().getHeight()-buttonVGap); + LLInventoryItem* item = items.get(i); - LLButton::Params bparams; - bparams.image_unselected.name(flat_icon); - bparams.image_disabled.name(flat_icon); - bparams.image_selected.name(hover_icon_selected); - bparams.image_hover_selected.name(hover_icon_selected); - bparams.image_disabled_selected.name(hover_icon_selected); - bparams.image_hover_unselected.name(hover_icon); - bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM); - bparams.rect (rect); - bparams.tab_stop(false); - bparams.font(mFont); - bparams.name(item->getName()); - bparams.tool_tip(item->getName()); - bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); - bparams.rightclick_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID())); + S32 buttonWidth = mFont->getWidth(item->getName()) + buttonHPad * 2; - addChildInBack(LLUICtrlFactory::create (bparams)); + LLRect rect; + rect.setOriginAndSize(curr_x, buttonVGap, buttonWidth, getRect().getHeight()-buttonVGap); - curr_x += buttonWidth + buttonHGap; + LLButton::Params bparams; + bparams.image_unselected.name(flat_icon); + bparams.image_disabled.name(flat_icon); + bparams.image_selected.name(hover_icon_selected); + bparams.image_hover_selected.name(hover_icon_selected); + bparams.image_disabled_selected.name(hover_icon_selected); + bparams.image_hover_unselected.name(hover_icon); + bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM); + bparams.rect (rect); + bparams.tab_stop(false); + bparams.font(mFont); + bparams.name(item->getName()); + bparams.tool_tip(item->getName()); + bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); + bparams.rightclick_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID())); + + addChildInBack(LLUICtrlFactory::create (bparams)); + + curr_x += buttonWidth + buttonHGap; + } } // Chevron button if (mFirstDropDownItem != count) { - LLButton::Params bparams; + // Chevron button should stay right aligned + LLView *chevron_button = getChildView(std::string(">>"), FALSE, FALSE); + if (chevron_button) + { + LLRect rect; + rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap); + chevron_button->setRect(rect); + chevron_button->setVisible(TRUE); + mChevronRect = rect; + } + else + { + LLButton::Params bparams; - LLRect rect; - rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap); + LLRect rect; + rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap); - bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM); - bparams.image_unselected.name(flat_icon); - bparams.image_disabled.name(flat_icon); - bparams.image_selected.name(hover_icon_selected); - bparams.image_hover_selected.name(hover_icon_selected); - bparams.image_disabled_selected.name(hover_icon_selected); - bparams.image_hover_unselected.name(hover_icon); - bparams.rect (rect); - bparams.tab_stop(false); - bparams.font(mFont); - bparams.name(">>"); - bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this)); + bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM); + bparams.image_unselected.name(flat_icon); + bparams.image_disabled.name(flat_icon); + bparams.image_selected.name(hover_icon_selected); + bparams.image_hover_selected.name(hover_icon_selected); + bparams.image_disabled_selected.name(hover_icon_selected); + bparams.image_hover_unselected.name(hover_icon); + bparams.rect (rect); + bparams.tab_stop(false); + bparams.font(mFont); + bparams.name(">>"); + bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this)); - addChildInBack(LLUICtrlFactory::create (bparams)); + addChildInBack(LLUICtrlFactory::create (bparams)); - S32 chevron_root_x, chevron_root_y; - localPointToOtherView(rect.mLeft, rect.mBottom, &chevron_root_x, &chevron_root_y, LLUI::getRootView()); - mChevronRect.setOriginAndSize(chevron_root_x, chevron_root_y, rect.getWidth(), rect.getHeight()); + mChevronRect = rect; + } + } + else + { + // Hide chevron button if all items are visible on bar + LLView *chevron_button = getChildView(std::string(">>"), FALSE, FALSE); + if (chevron_button) + { + chevron_button->setVisible(FALSE); + } } } BOOL LLFavoritesBarCtrl::postBuild() { // make the popup menu available - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_favorites.xml", gMenuHolder); + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_favorites.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if (!menu) { menu = LLUICtrlFactory::getDefaultWidget("inventory_menu"); } - menu->setBackgroundColor(gSavedSkinSettings.getColor("MenuPopupBgColor")); + menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor")); mInventoryItemsPopupMenuHandle = menu->getHandle(); return TRUE; @@ -394,31 +374,31 @@ void LLFavoritesBarCtrl::showDropDownMenu() { if (mPopupMenuHandle.isDead()) { - LLMenuGL::Params menu_p; + LLToggleableMenu::Params menu_p; menu_p.name("favorites menu"); menu_p.can_tear_off(false); menu_p.visible(false); menu_p.scrollable(true); - LLVisibilityTrackingMenuGL* menu = LLUICtrlFactory::create(menu_p); + LLToggleableMenu* menu = LLUICtrlFactory::create(menu_p); mPopupMenuHandle = menu->getHandle(); } - LLVisibilityTrackingMenuGL* menu = (LLVisibilityTrackingMenuGL*)mPopupMenuHandle.get(); + LLToggleableMenu* menu = (LLToggleableMenu*)mPopupMenuHandle.get(); if(menu) { - if (menu->getClosedByChevronClick()) + if (menu->getClosedByButtonClick()) { - menu->resetClosedByChevronClick(); + menu->resetClosedByButtonClick(); return; } if (menu->getVisible()) { menu->setVisible(FALSE); - menu->resetClosedByChevronClick(); + menu->resetClosedByButtonClick(); return; } @@ -449,7 +429,7 @@ void LLFavoritesBarCtrl::showDropDownMenu() menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); - menu->setChevronRect(mChevronRect); + menu->setButtonRect(mChevronRect, this); LLMenuGL::showPopup(this, menu, getRect().getWidth() - menu->getRect().getWidth(), 0); return; @@ -482,6 +462,7 @@ void LLFavoritesBarCtrl::showDropDownMenu() item_params.label(item_name); item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); + item_params.rightclick_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID())); LLMenuItemCallGL *menu_item = LLUICtrlFactory::create(item_params); @@ -514,7 +495,7 @@ void LLFavoritesBarCtrl::showDropDownMenu() menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); - menu->setChevronRect(mChevronRect); + menu->setButtonRect(mChevronRect, this); LLMenuGL::showPopup(this, menu, getRect().getWidth() - max_width, 0); } @@ -565,7 +546,11 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata) } else if (action == "about") { - LLFloaterReg::showInstance("preview_landmark", LLSD(mSelectedItemID), TAKE_FOCUS_YES); + LLSD key; + key["type"] = "landmark"; + key["id"] = mSelectedItemID; + + LLSideTray::getInstance()->showPanel("panel_places", key); } else if (action == "rename") { diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 646e98cabb..a559692331 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -34,7 +34,7 @@ #define LL_LLFAVORITESBARCTRL_H #include "lluictrl.h" -#include "lliconctrl.h" + #include "llinventorymodel.h" class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index e863be40e1..fb724f30e0 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -48,7 +48,7 @@ #include "llviewercontrol.h" #include "llworld.h" #include "lldrawpoolterrain.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llwindow.h" #include "llui.h" #include "llcontrol.h" @@ -430,7 +430,6 @@ void LLFeatureManager::applyRecommendedSettings() setGraphicsLevel(level, false); gSavedSettings.setU32("RenderQualityPerformance", level); - gSavedSettings.setBOOL("RenderCustomSettings", FALSE); // now apply the tweaks to draw distance // these are double negatives, because feature masks only work by diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp index 352ca3c863..de079b7123 100644 --- a/indra/newview/llfirstuse.cpp +++ b/indra/newview/llfirstuse.cpp @@ -145,7 +145,7 @@ void LLFirstUse::useBuild() LLNotifications::instance().add("FirstBuild"); } } - +/* // static void LLFirstUse::useLeftClickNoHit() { @@ -156,7 +156,7 @@ void LLFirstUse::useLeftClickNoHit() LLNotifications::instance().add("FirstLeftClickNoHit"); } } - +*/ // static void LLFirstUse::useTeleport() { diff --git a/indra/newview/llfirstuse.h b/indra/newview/llfirstuse.h index bb64cdd2c6..7b4f9f516f 100644 --- a/indra/newview/llfirstuse.h +++ b/indra/newview/llfirstuse.h @@ -95,7 +95,7 @@ public: static void useMap(); static void useGoTo(); static void useBuild(); - static void useLeftClickNoHit(); +// static void useLeftClickNoHit(); static void useTeleport(); static void useOverrideKeys(); static void useAttach(); diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 8f2c6d538b..bafb69a835 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -39,11 +39,10 @@ #include "llglheaders.h" #include "llrendersphere.h" #include "llviewerobject.h" -#include "llimagegl.h" #include "llagent.h" #include "llsky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 61a031d502..2cdb149f9a 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -77,7 +77,7 @@ static std::string get_viewer_release_notes_url(); // Default constructor LLFloaterAbout::LLFloaterAbout(const LLSD& key) -: LLFloater() +: LLFloater(key) { //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about.xml"); @@ -105,7 +105,7 @@ BOOL LLFloaterAbout::postBuild() viewer_link_style->setVisible(true); viewer_link_style->setFontName(LLStringUtil::null); viewer_link_style->setLinkHREF(get_viewer_release_notes_url()); - viewer_link_style->setColor(gSavedSkinSettings.getColor4("HTMLLinkColor")); + viewer_link_style->setColor(LLUIColorTable::instance().getColor("HTMLLinkColor")); // Version string std::string version = LLTrans::getString("SECOND_LIFE_VIEWER") @@ -113,7 +113,7 @@ BOOL LLFloaterAbout::postBuild() LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VIEWER_BUILD, __DATE__, __TIME__, gSavedSettings.getString("VersionChannelName").c_str()); - support_widget->appendColoredText(version, FALSE, FALSE, LLUI::sSettingGroups["color"]->getColor("TextFgReadOnlyColor")); + support_widget->appendColoredText(version, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor")); support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, viewer_link_style); std::string support; @@ -135,7 +135,7 @@ BOOL LLFloaterAbout::postBuild() server_link_style->setVisible(true); server_link_style->setFontName(LLStringUtil::null); server_link_style->setLinkHREF(region->getCapability("ServerReleaseNotes")); - server_link_style->setColor(gSavedSkinSettings.getColor4("HTMLLinkColor")); + server_link_style->setColor(LLUIColorTable::instance().getColor("HTMLLinkColor")); const LLVector3d &pos = gAgent.getPositionGlobal(); LLUIString pos_text = getString("you_are_at"); @@ -157,7 +157,7 @@ BOOL LLFloaterAbout::postBuild() support.append(gLastVersionChannel); support.append("\n"); - support_widget->appendColoredText(support, FALSE, FALSE, LLUI::sSettingGroups["color"]->getColor("TextFgReadOnlyColor")); + support_widget->appendColoredText(support, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor")); support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, server_link_style); support = "\n\n"; @@ -245,7 +245,7 @@ BOOL LLFloaterAbout::postBuild() support.append(getString ("PacketsLost", args) + "\n"); } - support_widget->appendColoredText(support, FALSE, FALSE, LLUI::sSettingGroups["color"]->getColor("TextFgReadOnlyColor")); + support_widget->appendColoredText(support, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor")); // Fix views support_widget->setCursorPos(0); diff --git a/indra/newview/llfloaterabout.h b/indra/newview/llfloaterabout.h index 1b0f3cddd3..c15a20d549 100644 --- a/indra/newview/llfloaterabout.h +++ b/indra/newview/llfloaterabout.h @@ -36,12 +36,11 @@ #include "llfloater.h" class LLFloaterAbout - : public LLFloater, public LLFloaterSingleton + : public LLFloater { - friend class LLUISingleton >; -public: + friend class LLFloaterReg; +private: LLFloaterAbout(const LLSD& key); -protected: virtual ~LLFloaterAbout(); public: diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index 12c4932293..dec27db74b 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -37,6 +37,7 @@ #include "llbvhloader.h" #include "lldatapacker.h" #include "lldir.h" +#include "lleconomy.h" #include "llvfile.h" #include "llapr.h" #include "llstring.h" @@ -69,8 +70,6 @@ #include "lluictrlfactory.h" #include "lltrans.h" -S32 LLFloaterAnimPreview::sUploadAmount = 10; - const S32 PREVIEW_BORDER_WIDTH = 2; const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH; const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE; @@ -197,7 +196,6 @@ BOOL LLFloaterAnimPreview::postBuild() childSetCommitCallback("name_form", onCommitName, this); - childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount)); childSetAction("ok_btn", onBtnOK, this); setDefaultBtn(); @@ -307,8 +305,9 @@ BOOL LLFloaterAnimPreview::postBuild() motionp->setName(childGetValue("name_form").asString()); mAnimPreview->getDummyAvatar()->startMotion(mMotionID); - childSetMinValue("playback_slider", 0.0); - childSetMaxValue("playback_slider", 1.0); + + getChild("playback_slider")->setMinValue(0.0); + getChild("playback_slider")->setMaxValue(1.0); childSetValue("loop_check", LLSD(motionp->getLoop())); childSetValue("loop_in_point", LLSD(motionp->getLoopIn() / motionp->getDuration() * 100.f)); @@ -325,7 +324,6 @@ BOOL LLFloaterAnimPreview::postBuild() } else { - delete mAnimPreview; mAnimPreview = NULL; mMotionID.setNull(); childSetValue("bad_animation_text", getString("failed_to_initialize")); @@ -367,7 +365,6 @@ BOOL LLFloaterAnimPreview::postBuild() //----------------------------------------------------------------------------- LLFloaterAnimPreview::~LLFloaterAnimPreview() { - delete mAnimPreview; mAnimPreview = NULL; setEnabled(FALSE); @@ -387,7 +384,7 @@ void LLFloaterAnimPreview::draw() { gGL.color3f(1.f, 1.f, 1.f); - gGL.getTexUnit(0)->bind(mAnimPreview->getTexture()); + gGL.getTexUnit(0)->bind(mAnimPreview); gGL.begin( LLRender::QUADS ); { @@ -734,7 +731,7 @@ void LLFloaterAnimPreview::onCommitName(LLUICtrl* ctrl, void* data) motionp->setName(previewp->childGetValue("name_form").asString()); } - LLFloaterNameDesc::doCommit(ctrl, data); + previewp->doCommit(); } //----------------------------------------------------------------------------- @@ -985,7 +982,7 @@ void LLFloaterAnimPreview::onBtnOK(void* userdata) std::string name = floaterp->childGetValue("name_form").asString(); std::string desc = floaterp->childGetValue("description_form").asString(); LLAssetStorage::LLStoreAssetCallback callback = NULL; - S32 expected_upload_cost = sUploadAmount; + S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); void *userdata = NULL; upload_new_resource(floaterp->mTransactionID, // tid LLAssetType::AT_ANIMATION, @@ -1017,7 +1014,7 @@ void LLFloaterAnimPreview::onBtnOK(void* userdata) //----------------------------------------------------------------------------- // LLPreviewAnimation //----------------------------------------------------------------------------- -LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) +LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) { mNeedsUpdate = TRUE; mCameraDistance = PREVIEW_CAMERA_DISTANCE; @@ -1063,7 +1060,7 @@ BOOL LLPreviewAnimation::render() glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); glLoadIdentity(); - glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); + glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); gGL.pushMatrix(); @@ -1073,7 +1070,7 @@ BOOL LLPreviewAnimation::render() gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); - gl_rect_2d_simple( mWidth, mHeight ); + gl_rect_2d_simple( mFullWidth, mFullHeight ); glMatrixMode(GL_PROJECTION); gGL.popMatrix(); @@ -1095,7 +1092,7 @@ BOOL LLPreviewAnimation::render() target_pos + (mCameraOffset * av_rot) ); // point of interest LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); - LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); mCameraRelPos = LLViewerCamera::getInstance()->getOrigin() - avatarp->mHeadp->getWorldPosition(); diff --git a/indra/newview/llfloateranimpreview.h b/indra/newview/llfloateranimpreview.h index 2f228c3ecd..f1c4a6b0d0 100644 --- a/indra/newview/llfloateranimpreview.h +++ b/indra/newview/llfloateranimpreview.h @@ -41,12 +41,14 @@ class LLVOAvatar; class LLViewerJointMesh; -class LLPreviewAnimation : public LLDynamicTexture +class LLPreviewAnimation : public LLViewerDynamicTexture { -public: - LLPreviewAnimation(S32 width, S32 height); +protected: virtual ~LLPreviewAnimation(); +public: + LLPreviewAnimation(S32 width, S32 height); + BOOL render(); void requestUpdate(); void rotate(F32 yaw_radians, F32 pitch_radians); @@ -86,7 +88,6 @@ public: static void onBtnPlay(void*); static void onBtnStop(void*); - static void setUploadAmount(S32 amount) { sUploadAmount = amount; } static void onSliderMove(LLUICtrl*, void*); static void onCommitBaseAnim(LLUICtrl*, void*); static void onCommitLoop(LLUICtrl*, void*); @@ -114,7 +115,7 @@ protected: void draw(); void resetMotion(); - LLPreviewAnimation* mAnimPreview; + LLPointer< LLPreviewAnimation > mAnimPreview; S32 mLastMouseX; S32 mLastMouseY; LLButton* mPlayButton; @@ -127,8 +128,6 @@ protected: LLAnimPauseRequest mPauseRequest; std::map mIDList; - - static S32 sUploadAmount; }; #endif // LL_LLFLOATERANIMPREVIEW_H diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp index 8ad5a19d02..da2a4d9d93 100644 --- a/indra/newview/llfloaterauction.cpp +++ b/indra/newview/llfloaterauction.cpp @@ -47,7 +47,7 @@ #include "llcombobox.h" #include "llnotify.h" #include "llsavedsettingsglue.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "lluictrlfactory.h" @@ -72,7 +72,7 @@ void auction_tga_upload_done(const LLUUID& asset_id, // Default constructor LLFloaterAuction::LLFloaterAuction(const LLSD& key) - : LLFloater(), + : LLFloater(key), mParcelID(-1) { // LLUICtrlFactory::getInstance()->buildFloater(this, "floater_auction.xml"); @@ -186,7 +186,7 @@ void LLFloaterAuction::onClickSnapshot(void* data) tga->encode(raw); LLVFile::writeFile(tga->getData(), tga->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_IMAGE_TGA); - raw->biasedScaleToPowerOfTwo(LLViewerImage::MAX_IMAGE_SIZE_DEFAULT); + raw->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT); llinfos << "Writing J2C..." << llendl; @@ -194,7 +194,7 @@ void LLFloaterAuction::onClickSnapshot(void* data) j2c->encode(raw, 0.0f); LLVFile::writeFile(j2c->getData(), j2c->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_TEXTURE); - self->mImage = new LLImageGL((LLImageRaw*)raw, FALSE); + self->mImage = LLViewerTextureManager::getLocalTexture((LLImageRaw*)raw, FALSE); gGL.getTexUnit(0)->bind(self->mImage); self->mImage->setAddressMode(LLTexUnit::TAM_CLAMP); } diff --git a/indra/newview/llfloaterauction.h b/indra/newview/llfloaterauction.h index b018316c64..1acc08057c 100644 --- a/indra/newview/llfloaterauction.h +++ b/indra/newview/llfloaterauction.h @@ -37,7 +37,7 @@ #include "llfloater.h" #include "lluuid.h" #include "llpointer.h" -#include "llviewerimage.h" +#include "llviewertexture.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFloaterAuction @@ -46,18 +46,19 @@ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLParcelSelection; -class LLFloaterAuction : public LLFloater, public LLFloaterSingleton +class LLFloaterAuction : public LLFloater { - friend class LLUISingleton >; + friend class LLFloaterReg; public: // LLFloater interface - /*virtual*/ void onClose(bool app_quitting) { setVisible(FALSE); } /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ void draw(); + +private: LLFloaterAuction(const LLSD& key); ~LLFloaterAuction(); -private: + void initialize(); static void onClickSnapshot(void* data); @@ -67,7 +68,7 @@ private: private: LLTransactionID mTransactionID; LLAssetID mImageID; - LLPointer mImage; + LLPointer mImage; LLSafeHandle mParcelp; S32 mParcelID; LLHost mParcelHost; diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 2c2dcda633..91b9bcfe72 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -33,66 +33,54 @@ #include "llfloateravatarpicker.h" -#include "message.h" - +// Viewer includes #include "llagent.h" -#include "llbutton.h" #include "llfocusmgr.h" -#include "llinventoryview.h" +#include "llfloaterreg.h" +#include "llfloaterinventory.h" +#include "llfoldervieweventlistener.h" #include "llinventorymodel.h" +#include "llviewercontrol.h" +#include "llworld.h" + +// Linden libraries +#include "llbutton.h" #include "lllineeditor.h" #include "llscrolllistctrl.h" #include "llscrolllistitem.h" #include "llscrolllistcell.h" +#include "lltabcontainer.h" #include "lltextbox.h" #include "lluictrlfactory.h" -#include "llviewercontrol.h" -#include "llworld.h" -#include "lltabcontainer.h" - -// static -LLFloaterAvatarPicker* LLFloaterAvatarPicker::sInstance = NULL; - +#include "message.h" LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(callback_t callback, void* userdata, BOOL allow_multiple, BOOL closeOnSelect) { - // TODO: This class should not be a singleton as it's used in multiple places - // and therefore can't be used simultaneously. -MG - if (!sInstance) - { - sInstance = new LLFloaterAvatarPicker(); - sInstance->mCallback = callback; - sInstance->mCallbackUserdata = userdata; - sInstance->mCloseOnSelect = FALSE; - - sInstance->openFloater(); - sInstance->center(); - sInstance->setAllowMultiple(allow_multiple); - } - else - { - sInstance->openFloater(); - sInstance->mCallback = callback; - sInstance->mCallbackUserdata = userdata; - sInstance->setAllowMultiple(allow_multiple); - } + // *TODO: Use a key to allow this not to be an effective singleton + LLFloaterAvatarPicker* floater = LLFloaterReg::showTypedInstance("avatar_picker"); - sInstance->mNearMeListComplete = FALSE; - sInstance->mCloseOnSelect = closeOnSelect; - return sInstance; + floater->mCallback = callback; + floater->mCallbackUserdata = userdata; + floater->setAllowMultiple(allow_multiple); + floater->mNearMeListComplete = FALSE; + floater->mCloseOnSelect = closeOnSelect; + + return floater; } // Default constructor -LLFloaterAvatarPicker::LLFloaterAvatarPicker() - : LLFloater(), +LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key) + : LLFloater(key), mResultsReturned(FALSE), mCallback(NULL), - mCallbackUserdata(NULL) + mCallbackUserdata(NULL), + mNearMeListComplete(FALSE), + mCloseOnSelect(FALSE) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_picker.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_picker.xml"); } BOOL LLFloaterAvatarPicker::postBuild() @@ -140,7 +128,9 @@ BOOL LLFloaterAvatarPicker::postBuild() boost::bind(&LLFloaterAvatarPicker::onTabChanged, this)); setAllowMultiple(FALSE); - + + center(); + return TRUE; } @@ -153,8 +143,6 @@ void LLFloaterAvatarPicker::onTabChanged() LLFloaterAvatarPicker::~LLFloaterAvatarPicker() { gFocusMgr.releaseFocusIfNeeded( this ); - - sInstance = NULL; } void LLFloaterAvatarPicker::onBtnFind(void* userdata) @@ -405,23 +393,21 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* // Not for us if (agent_id != gAgent.getID()) return; - - // Dialog already closed - LLFloaterAvatarPicker *self = sInstance; - if (!self) return; + + LLFloaterAvatarPicker* floater = LLFloaterReg::findTypedInstance("avatar_picker"); // these are not results from our last request - if (query_id != self->mQueryID) + if (query_id != floater->mQueryID) { return; } - LLScrollListCtrl* search_results = self->getChild("SearchResults"); + LLScrollListCtrl* search_results = floater->getChild("SearchResults"); // clear "Searching" label on first results search_results->deleteAllItems(); - self->mResultsReturned = TRUE; + floater->mResultsReturned = TRUE; BOOL found_one = FALSE; S32 num_new_rows = msg->getNumberOfBlocks("Data"); @@ -435,10 +421,10 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* if (avatar_id.isNull()) { LLStringUtil::format_map_t map; - map["[TEXT]"] = self->childGetText("Edit"); - avatar_name = self->getString("not_found", map); + map["[TEXT]"] = floater->childGetText("Edit"); + avatar_name = floater->getString("not_found", map); search_results->setEnabled(FALSE); - self->childDisable("Select"); + floater->childDisable("Select"); } else { @@ -454,9 +440,9 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* if (found_one) { - self->childEnable("Select"); + floater->childEnable("Select"); search_results->selectFirstItem(); - self->onList(search_results, self); + floater->onList(search_results, floater); search_results->setFocus(TRUE); } } diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index 0f47401f23..63896bef9f 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -48,6 +48,10 @@ public: void* userdata, BOOL allow_multiple = FALSE, BOOL closeOnSelect = FALSE); + + LLFloaterAvatarPicker(const LLSD& key); + virtual ~LLFloaterAvatarPicker(); + virtual BOOL postBuild(); static void processAvatarPickerReply(class LLMessageSystem* msg, void**); @@ -84,12 +88,6 @@ private: void (*mCallback)(const std::vector& name, const std::vector& id, void* userdata); void* mCallbackUserdata; - - static LLFloaterAvatarPicker* sInstance; - - // do not call these directly - LLFloaterAvatarPicker(); - virtual ~LLFloaterAvatarPicker(); }; #endif diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp index e2f13088eb..3976e25ba4 100644 --- a/indra/newview/llfloateravatartextures.cpp +++ b/indra/newview/llfloateravatartextures.cpp @@ -42,29 +42,15 @@ using namespace LLVOAvatarDefines; -LLFloaterAvatarTextures* LLFloaterAvatarTextures::sInstance = NULL; -LLFloaterAvatarTextures::LLFloaterAvatarTextures(const LLUUID& id) - : LLFloater(), - mID(id) +LLFloaterAvatarTextures::LLFloaterAvatarTextures(const LLSD& id) + : LLFloater(id), + mID(id.asUUID()) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_textures.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_textures.xml"); } LLFloaterAvatarTextures::~LLFloaterAvatarTextures() { - sInstance = NULL; -} - -LLFloaterAvatarTextures* LLFloaterAvatarTextures::show(const LLUUID &id) -{ - if (!sInstance) - { - sInstance = new LLFloaterAvatarTextures(id); - gFloaterView->addChild(sInstance); - gFloaterView->adjustToFitScreen(sInstance, FALSE); - } - sInstance->openFloater(); - return sInstance; } BOOL LLFloaterAvatarTextures::postBuild() diff --git a/indra/newview/llfloateravatartextures.h b/indra/newview/llfloateravatartextures.h index 3ec0e7cb03..e27484d26f 100644 --- a/indra/newview/llfloateravatartextures.h +++ b/indra/newview/llfloateravatartextures.h @@ -43,7 +43,7 @@ class LLTextureCtrl; class LLFloaterAvatarTextures : public LLFloater { public: - LLFloaterAvatarTextures(const LLUUID& id); + LLFloaterAvatarTextures(const LLSD& id); virtual ~LLFloaterAvatarTextures(); /*virtual*/ BOOL postBuild(); @@ -51,8 +51,6 @@ public: void refresh(); - static LLFloaterAvatarTextures* show(const LLUUID& id); - private: static void onClickDump(void*); @@ -60,7 +58,6 @@ private: LLUUID mID; std::string mTitle; LLTextureCtrl* mTextures[LLVOAvatarDefines::TEX_NUM_INDICES]; - static LLFloaterAvatarTextures* sInstance; }; #endif diff --git a/indra/newview/llfloaterbeacons.cpp b/indra/newview/llfloaterbeacons.cpp index 052f334285..13a7888f60 100644 --- a/indra/newview/llfloaterbeacons.cpp +++ b/indra/newview/llfloaterbeacons.cpp @@ -40,9 +40,9 @@ LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed) -: LLFloater() +: LLFloater(seed) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_beacons.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_beacons.xml"); // Initialize pipeline states from saved settings. // OK to do at floater constructor time because beacons do not display unless the floater is open @@ -56,43 +56,21 @@ LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed) LLPipeline::setRenderParticleBeacons( gSavedSettings.getBOOL("particlesbeacon")); LLPipeline::setRenderHighlights( gSavedSettings.getBOOL("renderhighlights")); LLPipeline::setRenderBeacons( gSavedSettings.getBOOL("renderbeacons")); + mCommitCallbackRegistrar.add("Beacons.UICheck", boost::bind(&LLFloaterBeacons::onClickUICheck, this,_1)); } BOOL LLFloaterBeacons::postBuild() { - childSetCommitCallback("touch_only", onClickUICheck, this); - childSetCommitCallback("scripted", onClickUICheck, this); - childSetCommitCallback("physical", onClickUICheck, this); - childSetCommitCallback("sounds", onClickUICheck, this); - childSetCommitCallback("particles", onClickUICheck, this); - childSetCommitCallback("highlights", onClickUICheck, this); - childSetCommitCallback("beacons", onClickUICheck, this); return TRUE; } -// Needed to make the floater visibility toggle the beacons. -// Too bad we can't just add control_name="BeaconAlwaysOn" to the XML. -void LLFloaterBeacons::onOpen(const LLSD& key) -{ - gSavedSettings.setBOOL( "BeaconAlwaysOn", TRUE); -} -void LLFloaterBeacons::onClose(bool app_quitting) -{ - destroy(); - if(!app_quitting) - { - gSavedSettings.setBOOL( "BeaconAlwaysOn", FALSE); - } -} - // Callback attached to each check box control to both affect their main purpose // and to implement the couple screwy interdependency rules that some have. -//static -void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data) + +void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl) { LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; std::string name = check->getName(); - LLFloaterBeacons* view = (LLFloaterBeacons*)data; if( name == "touch_only") { LLPipeline::toggleRenderScriptedTouchBeacons(NULL); @@ -102,8 +80,8 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data) LLPipeline::getRenderScriptedBeacons(NULL) ) { LLPipeline::setRenderScriptedBeacons(FALSE); - view->getChild("scripted")->setControlValue(LLSD(FALSE)); - view->getChild("touch_only")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline + getChild("scripted")->setControlValue(LLSD(FALSE)); + getChild("touch_only")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline } } else if(name == "scripted") @@ -115,8 +93,8 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data) LLPipeline::getRenderScriptedBeacons(NULL) ) { LLPipeline::setRenderScriptedTouchBeacons(FALSE); - view->getChild("touch_only")->setControlValue(LLSD(FALSE)); - view->getChild("scripted")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline + getChild("touch_only")->setControlValue(LLSD(FALSE)); + getChild("scripted")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline } } else if(name == "physical") LLPipeline::setRenderPhysicalBeacons(check->get()); @@ -131,8 +109,8 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data) !LLPipeline::getRenderHighlights(NULL) ) { LLPipeline::setRenderBeacons(TRUE); - view->getChild("beacons")->setControlValue(LLSD(TRUE)); - view->getChild("highlights")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline + getChild("beacons")->setControlValue(LLSD(TRUE)); + getChild("highlights")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline } } else if(name == "beacons") @@ -144,8 +122,8 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data) !LLPipeline::getRenderHighlights(NULL) ) { LLPipeline::setRenderHighlights(TRUE); - view->getChild("highlights")->setControlValue(LLSD(TRUE)); - view->getChild("beacons")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline + getChild("highlights")->setControlValue(LLSD(TRUE)); + getChild("beacons")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline } } } diff --git a/indra/newview/llfloaterbeacons.h b/indra/newview/llfloaterbeacons.h index 8156e82ac3..c175cb3ef4 100644 --- a/indra/newview/llfloaterbeacons.h +++ b/indra/newview/llfloaterbeacons.h @@ -36,22 +36,20 @@ #include "llfloater.h" -class LLFloaterBeacons : public LLFloater, public LLFloaterSingleton +class LLFloaterBeacons : public LLFloater { - friend class LLUISingleton >; + friend class LLFloaterReg; public: + /*virtual*/ BOOL postBuild(); // Needed to make the floater visibility toggle the beacons. // Too bad we can't just add control_name="BeaconAlwaysOn" to the XML. - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); + void onClickUICheck(LLUICtrl *ctrl); private: LLFloaterBeacons(const LLSD& seed); - - static void onClickUICheck(LLUICtrl *ctrl, void* data); }; #endif diff --git a/indra/newview/llfloaterbuildoptions.cpp b/indra/newview/llfloaterbuildoptions.cpp index 9dbd1db38e..30e9428df9 100644 --- a/indra/newview/llfloaterbuildoptions.cpp +++ b/indra/newview/llfloaterbuildoptions.cpp @@ -44,7 +44,7 @@ // Methods // LLFloaterBuildOptions::LLFloaterBuildOptions(const LLSD& key) - : LLFloater() + : LLFloater(key) { //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_build_options.xml"); } diff --git a/indra/newview/llfloaterbuildoptions.h b/indra/newview/llfloaterbuildoptions.h index 61db303ba2..43cbb201c2 100644 --- a/indra/newview/llfloaterbuildoptions.h +++ b/indra/newview/llfloaterbuildoptions.h @@ -42,10 +42,10 @@ class LLFloaterBuildOptions - : public LLFloater, public LLFloaterSingleton + : public LLFloater { - friend class LLUISingleton >; -public: + friend class LLFloaterReg; +private: LLFloaterBuildOptions(const LLSD& key); ~LLFloaterBuildOptions(); }; diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp index 65dc3cd9f0..a73ebf4e06 100644 --- a/indra/newview/llfloaterbulkpermission.cpp +++ b/indra/newview/llfloaterbulkpermission.cpp @@ -58,22 +58,22 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed) -: LLFloater(), +: LLFloater(seed), mDone(FALSE) { mID.generate(); - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml"); + mCommitCallbackRegistrar.add("BulkPermission.Apply", boost::bind(&LLFloaterBulkPermission::onApplyBtn, this)); + mCommitCallbackRegistrar.add("BulkPermission.Close", boost::bind(&LLFloaterBulkPermission::onCloseBtn, this)); + mCommitCallbackRegistrar.add("BulkPermission.CheckAll", boost::bind(&LLFloaterBulkPermission::onCheckAll, this)); + mCommitCallbackRegistrar.add("BulkPermission.UncheckAll", boost::bind(&LLFloaterBulkPermission::onUncheckAll, this)); + mCommitCallbackRegistrar.add("BulkPermission.CommitCopy", boost::bind(&LLFloaterBulkPermission::onCommitCopy, this)); } BOOL LLFloaterBulkPermission::postBuild() { - childSetEnabled("next_owner_transfer", gSavedSettings.getBOOL("BulkChangeNextOwnerCopy")); - childSetAction("help", onHelpBtn, this); - childSetAction("apply", onApplyBtn, this); - childSetAction("close", onCloseBtn, this); - childSetAction("check_all", onCheckAll, this); - childSetAction("check_none", onUncheckAll, this); - childSetCommitCallback("next_owner_copy", &onCommitCopy, this); +// childSetAction("help", onHelpBtn, this); // this is not in use + return TRUE; } @@ -152,34 +152,32 @@ void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object, } } -void LLFloaterBulkPermission::onApplyBtn(void* user_data) +void LLFloaterBulkPermission::onApplyBtn() { - LLFloaterBulkPermission* self = static_cast(user_data); - self->doApply(); + doApply(); } -void LLFloaterBulkPermission::onHelpBtn(void* user_data) -{ - LLNotifications::instance().add("HelpBulkPermission"); -} +// angela -- this is not in use +//void LLFloaterBulkPermission::onHelpBtn(void* user_data) +//{ +// LLNotifications::instance().add("HelpBulkPermission"); +//} -void LLFloaterBulkPermission::onCloseBtn(void* user_data) +void LLFloaterBulkPermission::onCloseBtn() { - LLFloaterBulkPermission* self = static_cast(user_data); - self->onClose(false); + closeFloater(); } //static -void LLFloaterBulkPermission::onCommitCopy(LLUICtrl* ctrl, void* data) +void LLFloaterBulkPermission::onCommitCopy() { - LLFloaterBulkPermission* self = static_cast(data); // Implements fair use BOOL copyable = gSavedSettings.getBOOL("BulkChangeNextOwnerCopy"); if(!copyable) { gSavedSettings.setBOOL("BulkChangeNextOwnerTransfer", TRUE); } - LLCheckBoxCtrl* xfer = self->getChild("next_owner_transfer"); + LLCheckBoxCtrl* xfer =getChild("next_owner_transfer"); xfer->setEnabled(copyable); } @@ -252,7 +250,6 @@ void LLFloaterBulkPermission::doCheckUncheckAll(BOOL check) gSavedSettings.setBOOL("BulkChangeIncludeBodyParts" , check); gSavedSettings.setBOOL("BulkChangeIncludeClothing" , check); gSavedSettings.setBOOL("BulkChangeIncludeGestures" , check); - gSavedSettings.setBOOL("BulkChangeIncludeLandmarks" , check); gSavedSettings.setBOOL("BulkChangeIncludeNotecards" , check); gSavedSettings.setBOOL("BulkChangeIncludeObjects" , check); gSavedSettings.setBOOL("BulkChangeIncludeScripts" , check); @@ -275,7 +272,6 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, Invent ( asstype == LLAssetType::AT_BODYPART && gSavedSettings.getBOOL("BulkChangeIncludeBodyParts" )) || ( asstype == LLAssetType::AT_CLOTHING && gSavedSettings.getBOOL("BulkChangeIncludeClothing" )) || ( asstype == LLAssetType::AT_GESTURE && gSavedSettings.getBOOL("BulkChangeIncludeGestures" )) || - ( asstype == LLAssetType::AT_LANDMARK && gSavedSettings.getBOOL("BulkChangeIncludeLandmarks" )) || ( asstype == LLAssetType::AT_FAVORITE && gSavedSettings.getBOOL("BulkChangeIncludeFavourite" )) || ( asstype == LLAssetType::AT_NOTECARD && gSavedSettings.getBOOL("BulkChangeIncludeNotecards" )) || ( asstype == LLAssetType::AT_OBJECT && gSavedSettings.getBOOL("BulkChangeIncludeObjects" )) || diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h index 2ea12fbe69..c34e4413cc 100644 --- a/indra/newview/llfloaterbulkpermission.h +++ b/indra/newview/llfloaterbulkpermission.h @@ -46,14 +46,16 @@ #include "llviewerinventory.h" -class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener, public LLFloaterSingleton +class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener { + friend class LLFloaterReg; public: - LLFloaterBulkPermission(const LLSD& seed); BOOL postBuild(); private: + + LLFloaterBulkPermission(const LLSD& seed); virtual ~LLFloaterBulkPermission() {} BOOL start(); // returns TRUE if the queue has started, otherwise FALSE. @@ -77,12 +79,12 @@ private: U8 key, bool is_new); - static void onHelpBtn(void* user_data); - static void onCloseBtn(void* user_data); - static void onApplyBtn(void* user_data); - static void onCommitCopy(LLUICtrl* ctrl, void* data); - static void onCheckAll( void* user_data) { ((LLFloaterBulkPermission*)user_data)->doCheckUncheckAll(TRUE); } - static void onUncheckAll(void* user_data) { ((LLFloaterBulkPermission*)user_data)->doCheckUncheckAll(FALSE); } +// static void onHelpBtn(void* user_data); + void onCloseBtn(); + void onApplyBtn(); + void onCommitCopy(); + void onCheckAll() { doCheckUncheckAll(TRUE); } + void onUncheckAll() { doCheckUncheckAll(FALSE); } // returns true if this is done BOOL isDone() const { return (mCurrentObjectID.isNull() || (mObjectIDs.count() == 0)); } diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp index e4e1c7efa2..8b64f913e0 100644 --- a/indra/newview/llfloaterbump.cpp +++ b/indra/newview/llfloaterbump.cpp @@ -45,11 +45,13 @@ ///---------------------------------------------------------------------------- /// Class LLFloaterBump ///---------------------------------------------------------------------------- +extern BOOL gNoRender; // Default constructor LLFloaterBump::LLFloaterBump(const LLSD& key) -: LLFloater() +: LLFloater(key) { + if(gNoRender) return; //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_bumps.xml"); } diff --git a/indra/newview/llfloaterbump.h b/indra/newview/llfloaterbump.h index b56817436c..1f2cb6d6ab 100644 --- a/indra/newview/llfloaterbump.h +++ b/indra/newview/llfloaterbump.h @@ -40,14 +40,17 @@ class LLMeanCollisionData; class LLScrollListCtrl; class LLFloaterBump -: public LLFloater, public LLFloaterSingleton +: public LLFloater { - friend class LLUISingleton >; + friend class LLFloaterReg; protected: void add(LLScrollListCtrl* list, LLMeanCollisionData *mcd); public: /*virtual*/ void onOpen(const LLSD& key); + +private: + LLFloaterBump(const LLSD& key); virtual ~LLFloaterBump(); }; diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index 9c523522fd..a7aaf71ef6 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -43,7 +43,8 @@ #include "llagent.h" // for agent id #include "llalertdialog.h" #include "llinventorymodel.h" // for gInventory -#include "llinventoryview.h" // for get_item_icon +#include "llfloaterreg.h" +#include "llfloaterinventory.h" // for get_item_icon #include "llselectmgr.h" #include "llscrolllistctrl.h" #include "llviewerobject.h" @@ -51,13 +52,10 @@ #include "llviewerwindow.h" #include "lltrans.h" -LLFloaterBuy* LLFloaterBuy::sInstance = NULL; - -LLFloaterBuy::LLFloaterBuy() -: LLFloater() +LLFloaterBuy::LLFloaterBuy(const LLSD& key) +: LLFloater(key) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_object.xml"); - +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_object.xml"); } BOOL LLFloaterBuy::postBuild() @@ -65,16 +63,23 @@ BOOL LLFloaterBuy::postBuild() childDisable("object_list"); childDisable("item_list"); - childSetAction("cancel_btn", onClickCancel, this); - childSetAction("buy_btn", onClickBuy, this); + getChild("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuy::onClickCancel, this)); + getChild("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuy::onClickBuy, this)); setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130) + + // Always center the dialog. User can change the size, + // but purchases are important and should be center screen. + // This also avoids problems where the user resizes the application window + // mid-session and the saved rect is off-center. + center(); + return TRUE; } LLFloaterBuy::~LLFloaterBuy() { - sInstance = NULL; + mObjectSelection = NULL; } void LLFloaterBuy::reset() @@ -96,47 +101,34 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) LLNotifications::instance().add("BuyOneObjectOnly"); return; } - - // Create a new instance only if one doesn't exist - if (sInstance) - { - // Clean up the lists... - sInstance->reset(); - } - else - { - sInstance = new LLFloaterBuy(); - } - sInstance->openFloater(); - sInstance->setFocus(TRUE); - sInstance->mSaleInfo = sale_info; - sInstance->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); - - // Always center the dialog. User can change the size, - // but purchases are important and should be center screen. - // This also avoids problems where the user resizes the application window - // mid-session and the saved rect is off-center. - sInstance->center(); - + LLFloaterBuy* floater = LLFloaterReg::showTypedInstance("buy_object"); + if (!floater) + return; + + // Clean up the lists... + floater->reset(); + floater->mSaleInfo = sale_info; + floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); + LLSelectNode* node = selection->getFirstRootNode(); if (!node) return; - + // Set title based on sale type LLUIString title; switch (sale_info.getSaleType()) { case LLSaleInfo::FS_ORIGINAL: - title = sInstance->getString("title_buy_text"); + title = floater->getString("title_buy_text"); break; case LLSaleInfo::FS_COPY: default: - title = sInstance->getString("title_buy_copy_text"); + title = floater->getString("title_buy_copy_text"); break; } title.setArg("[NAME]", node->mName); - sInstance->setTitle(title); + floater->setTitle(title); LLUUID owner_id; std::string owner_name; @@ -147,7 +139,7 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) return; } - LLCtrlListInterface *object_list = sInstance->childGetListInterface("object_list"); + LLCtrlListInterface *object_list = floater->childGetListInterface("object_list"); if (!object_list) { return; @@ -172,15 +164,15 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) std::string text = node->mName; if (!(next_owner_mask & PERM_COPY)) { - text.append(sInstance->getString("no_copy_text")); + text.append(floater->getString("no_copy_text")); } if (!(next_owner_mask & PERM_MODIFY)) { - text.append(sInstance->getString("no_modify_text")); + text.append(floater->getString("no_modify_text")); } if (!(next_owner_mask & PERM_TRANSFER)) { - text.append(sInstance->getString("no_transfer_text")); + text.append(floater->getString("no_transfer_text")); } row["columns"][1]["column"] = "text"; @@ -190,15 +182,15 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) // Add after columns added so appropriate heights are correct. object_list->addElement(row); - sInstance->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice())); - sInstance->childSetTextArg("buy_text", "[NAME]", owner_name); + floater->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice())); + floater->childSetTextArg("buy_text", "[NAME]", owner_name); // Must do this after the floater is created, because // sometimes the inventory is already there and // the callback is called immediately. LLViewerObject* obj = selection->getFirstRootObject(); - sInstance->registerVOInventoryListener(obj,NULL); - sInstance->requestVOInventory(); + floater->registerVOInventoryListener(obj,NULL); + floater->requestVOInventory(); } void LLFloaterBuy::inventoryChanged(LLViewerObject* obj, @@ -276,7 +268,7 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj, std::string text = obj->getName(); if (!(next_owner_mask & PERM_COPY)) { - text.append(getString("no_copy")); + text.append(LLTrans::getString("no_copy")); } if (!(next_owner_mask & PERM_MODIFY)) { @@ -296,15 +288,8 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj, removeVOInventoryListener(); } -// static -void LLFloaterBuy::onClickBuy(void*) +void LLFloaterBuy::onClickBuy() { - if (!sInstance) - { - llinfos << "LLFloaterBuy::onClickBuy no sInstance!" << llendl; - return; - } - // Put the items where we put new folders. LLUUID category_id; category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT); @@ -312,24 +297,13 @@ void LLFloaterBuy::onClickBuy(void*) // *NOTE: doesn't work for multiple object buy, which UI does not // currently support sale info is used for verification only, if // it doesn't match region info then sale is canceled. - LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, sInstance->mSaleInfo ); + LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, mSaleInfo ); - sInstance->closeFloater(); + closeFloater(); } -// static -void LLFloaterBuy::onClickCancel(void*) +void LLFloaterBuy::onClickCancel() { - if (sInstance) - { - sInstance->closeFloater(); - } -} - -void LLFloaterBuy::onClose(bool app_quitting) -{ - // drop reference to current selection so selection goes away - mObjectSelection = NULL; - destroy(); + closeFloater(); } diff --git a/indra/newview/llfloaterbuy.h b/indra/newview/llfloaterbuy.h index ffd3fa30c8..ee54303267 100644 --- a/indra/newview/llfloaterbuy.h +++ b/indra/newview/llfloaterbuy.h @@ -52,13 +52,14 @@ class LLFloaterBuy : public LLFloater, public LLVOInventoryListener { public: + LLFloaterBuy(const LLSD& key); + ~LLFloaterBuy(); + + /*virtual*/ BOOL postBuild(); + static void show(const LLSaleInfo& sale_info); protected: - LLFloaterBuy(); - ~LLFloaterBuy(); - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onClose(bool app_quitting); void reset(); void requestObjectInventories(); @@ -67,12 +68,10 @@ protected: S32 serial_num, void* data); - static void onClickBuy(void*); - static void onClickCancel(void*); + void onClickBuy(); + void onClickCancel(); private: - static LLFloaterBuy* sInstance; - LLSafeHandle mObjectSelection; LLSaleInfo mSaleInfo; }; diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index 7a90275201..3a4171c6be 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -46,7 +46,8 @@ #include "llalertdialog.h" #include "llcheckboxctrl.h" #include "llinventorymodel.h" // for gInventory -#include "llinventoryview.h" // for get_item_icon +#include "llfloaterreg.h" +#include "llfloaterinventory.h" // for get_item_icon #include "llselectmgr.h" #include "llscrolllistctrl.h" #include "llviewerobject.h" @@ -54,31 +55,35 @@ #include "lluictrlfactory.h" #include "llviewerwindow.h" -LLFloaterBuyContents* LLFloaterBuyContents::sInstance = NULL; - -LLFloaterBuyContents::LLFloaterBuyContents() -: LLFloater() +LLFloaterBuyContents::LLFloaterBuyContents(const LLSD& key) +: LLFloater(key) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_contents.xml"); - +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_contents.xml"); } + BOOL LLFloaterBuyContents::postBuild() { - childSetAction("cancel_btn", onClickCancel, this); - childSetAction("buy_btn", onClickBuy, this); + getChild("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyContents::onClickCancel, this)); + getChild("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyContents::onClickBuy, this)); childDisable("item_list"); childDisable("buy_btn"); childDisable("wear_check"); setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130) + + // Always center the dialog. User can change the size, + // but purchases are important and should be center screen. + // This also avoids problems where the user resizes the application window + // mid-session and the saved rect is off-center. + center(); + return TRUE; } LLFloaterBuyContents::~LLFloaterBuyContents() { - sInstance = NULL; } @@ -92,27 +97,16 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info) LLNotifications::instance().add("BuyContentsOneOnly"); return; } + + LLFloaterBuyContents* floater = LLFloaterReg::showTypedInstance("buy_object_contents"); + if (!floater) + return; + + LLScrollListCtrl* list = floater->getChild("item_list"); + if (list) + list->deleteAllItems(); - // Create a new instance only if needed - if (sInstance) - { - LLScrollListCtrl* list = sInstance->getChild("item_list"); - if (list) list->deleteAllItems(); - } - else - { - sInstance = new LLFloaterBuyContents(); - } - - sInstance->openFloater(); - sInstance->setFocus(TRUE); - sInstance->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); - - // Always center the dialog. User can change the size, - // but purchases are important and should be center screen. - // This also avoids problems where the user resizes the application window - // mid-session and the saved rect is off-center. - sInstance->center(); + floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); LLUUID owner_id; std::string owner_name; @@ -123,7 +117,7 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info) return; } - sInstance->mSaleInfo = sale_info; + floater->mSaleInfo = sale_info; // Update the display LLSelectNode* node = selection->getFirstRootNode(); @@ -133,16 +127,16 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info) gCacheName->getGroupName(owner_id, owner_name); } - sInstance->childSetTextArg("contains_text", "[NAME]", node->mName); - sInstance->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice())); - sInstance->childSetTextArg("buy_text", "[NAME]", owner_name); + floater->childSetTextArg("contains_text", "[NAME]", node->mName); + floater->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice())); + floater->childSetTextArg("buy_text", "[NAME]", owner_name); // Must do this after the floater is created, because // sometimes the inventory is already there and // the callback is called immediately. LLViewerObject* obj = selection->getFirstRootObject(); - sInstance->registerVOInventoryListener(obj,NULL); - sInstance->requestVOInventory(); + floater->registerVOInventoryListener(obj,NULL); + floater->requestVOInventory(); } @@ -272,22 +266,21 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj, } -// static -void LLFloaterBuyContents::onClickBuy(void*) +void LLFloaterBuyContents::onClickBuy() { // Make sure this wasn't selected through other mechanisms // (ie, being the default button and pressing enter. - if(!sInstance->childIsEnabled("buy_btn")) + if(!childIsEnabled("buy_btn")) { // We shouldn't be enabled. Just close. - sInstance->closeFloater(); + closeFloater(); return; } // We may want to wear this item - if (sInstance->childGetValue("wear_check")) + if (childGetValue("wear_check")) { - LLInventoryView::sWearNewClothing = TRUE; + LLFloaterInventory::sWearNewClothing = TRUE; } // Put the items where we put new folders. @@ -297,14 +290,12 @@ void LLFloaterBuyContents::onClickBuy(void*) // *NOTE: doesn't work for multiple object buy, which UI does not // currently support sale info is used for verification only, if // it doesn't match region info then sale is canceled. - LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, sInstance->mSaleInfo); + LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, mSaleInfo); - sInstance->closeFloater(); + closeFloater(); } - -// static -void LLFloaterBuyContents::onClickCancel(void*) +void LLFloaterBuyContents::onClickCancel() { - sInstance->closeFloater(); + closeFloater(); } diff --git a/indra/newview/llfloaterbuycontents.h b/indra/newview/llfloaterbuycontents.h index 52114811bf..8045a46c9f 100644 --- a/indra/newview/llfloaterbuycontents.h +++ b/indra/newview/llfloaterbuycontents.h @@ -52,22 +52,21 @@ class LLFloaterBuyContents public: static void show(const LLSaleInfo& sale_info); -protected: - LLFloaterBuyContents(); + LLFloaterBuyContents(const LLSD& key); ~LLFloaterBuyContents(); /*virtual*/ BOOL postBuild(); + +protected: void requestObjectInventories(); /*virtual*/ void inventoryChanged(LLViewerObject* obj, InventoryObjectList* inv, S32 serial_num, void* data); - - static void onClickBuy(void*); - static void onClickCancel(void*); + + void onClickBuy(); + void onClickCancel(); protected: - static LLFloaterBuyContents* sInstance; - LLSafeHandle mObjectSelection; LLSaleInfo mSaleInfo; }; diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp index 4274650f2c..0107cb6fe2 100644 --- a/indra/newview/llfloaterbuycurrency.cpp +++ b/indra/newview/llfloaterbuycurrency.cpp @@ -37,6 +37,7 @@ // viewer includes #include "llcurrencyuimanager.h" #include "llfloater.h" +#include "llfloaterreg.h" #include "llstatusbar.h" #include "lltextbox.h" #include "llviewchildren.h" @@ -53,12 +54,7 @@ class LLFloaterBuyCurrencyUI : public LLFloater { public: - static LLFloaterBuyCurrencyUI* soleInstance(bool createIfNeeded); - -private: - static LLFloaterBuyCurrencyUI* sInstance; - - LLFloaterBuyCurrencyUI(); + LLFloaterBuyCurrencyUI(const LLSD& key); virtual ~LLFloaterBuyCurrencyUI(); @@ -81,30 +77,17 @@ public: virtual void draw(); virtual BOOL canClose(); - static void onClickBuy(void* data); - static void onClickCancel(void* data); - static void onClickErrorWeb(void* data); + void onClickBuy(); + void onClickCancel(); + void onClickErrorWeb(); }; - -// static -LLFloaterBuyCurrencyUI* LLFloaterBuyCurrencyUI::sInstance = NULL; - -// static -LLFloaterBuyCurrencyUI* LLFloaterBuyCurrencyUI::soleInstance(bool createIfNeeded) +LLFloater* LLFloaterBuyCurrency::buildFloater(const LLSD& key) { - if (!sInstance && createIfNeeded) - { - sInstance = new LLFloaterBuyCurrencyUI(); - - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_buy_currency.xml"); - sInstance->center(); - } - - return sInstance; + LLFloaterBuyCurrencyUI* floater = new LLFloaterBuyCurrencyUI(key); + return floater; } - #if LL_WINDOWS // passing 'this' during construction generates a warning. The callee // only uses the pointer to hold a reference to 'this' which is @@ -112,8 +95,8 @@ LLFloaterBuyCurrencyUI* LLFloaterBuyCurrencyUI::soleInstance(bool createIfNeeded // warning so that we can compile without generating a warning. #pragma warning(disable : 4355) #endif -LLFloaterBuyCurrencyUI::LLFloaterBuyCurrencyUI() -: LLFloater(), +LLFloaterBuyCurrencyUI::LLFloaterBuyCurrencyUI(const LLSD& key) +: LLFloater(key), mChildren(*this), mManager(*this) { @@ -121,10 +104,6 @@ LLFloaterBuyCurrencyUI::LLFloaterBuyCurrencyUI() LLFloaterBuyCurrencyUI::~LLFloaterBuyCurrencyUI() { - if (sInstance == this) - { - sInstance = NULL; - } } @@ -156,11 +135,14 @@ BOOL LLFloaterBuyCurrencyUI::postBuild() { mManager.prepare(); - childSetAction("buy_btn", onClickBuy, this); - childSetAction("cancel_btn", onClickCancel, this); - childSetAction("error_web", onClickErrorWeb, this); - + getChild("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickBuy, this)); + getChild("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickCancel, this)); + getChild("error_web")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickErrorWeb, this)); + + center(); + updateUI(); + return TRUE; } @@ -312,57 +294,41 @@ void LLFloaterBuyCurrencyUI::updateUI() } } -// static -void LLFloaterBuyCurrencyUI::onClickBuy(void* data) +void LLFloaterBuyCurrencyUI::onClickBuy() { - LLFloaterBuyCurrencyUI* self = LLFloaterBuyCurrencyUI::soleInstance(false); - if (self) - { - self->mManager.buy(self->getString("buy_currency")); - self->updateUI(); - // JC: updateUI() doesn't get called again until progress is made - // with transaction processing, so the "Purchase" button would be - // left enabled for some time. Pre-emptively disable. - self->childSetEnabled("buy_btn", false); - } + mManager.buy(getString("buy_currency")); + updateUI(); + // JC: updateUI() doesn't get called again until progress is made + // with transaction processing, so the "Purchase" button would be + // left enabled for some time. Pre-emptively disable. + childSetEnabled("buy_btn", false); } -// static -void LLFloaterBuyCurrencyUI::onClickCancel(void* data) +void LLFloaterBuyCurrencyUI::onClickCancel() { - LLFloaterBuyCurrencyUI* self = LLFloaterBuyCurrencyUI::soleInstance(false); - if (self) - { - self->closeFloater(); - } + closeFloater(); } -// static -void LLFloaterBuyCurrencyUI::onClickErrorWeb(void* data) +void LLFloaterBuyCurrencyUI::onClickErrorWeb() { - LLFloaterBuyCurrencyUI* self = LLFloaterBuyCurrencyUI::soleInstance(false); - if (self) - { - LLWeb::loadURLExternal(self->mManager.errorURI()); - self->closeFloater(); - } + LLWeb::loadURLExternal(mManager.errorURI()); + closeFloater(); } // static void LLFloaterBuyCurrency::buyCurrency() { - LLFloaterBuyCurrencyUI* ui = LLFloaterBuyCurrencyUI::soleInstance(true); + LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance("buy_currency"); ui->noTarget(); ui->updateUI(); - ui->openFloater(); } +// static void LLFloaterBuyCurrency::buyCurrency(const std::string& name, S32 price) { - LLFloaterBuyCurrencyUI* ui = LLFloaterBuyCurrencyUI::soleInstance(true); + LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance("buy_currency"); ui->target(name, price); ui->updateUI(); - ui->openFloater(); } diff --git a/indra/newview/llfloaterbuycurrency.h b/indra/newview/llfloaterbuycurrency.h index 756acd2f0c..9b3f9b43d0 100644 --- a/indra/newview/llfloaterbuycurrency.h +++ b/indra/newview/llfloaterbuycurrency.h @@ -35,6 +35,8 @@ #include "stdtypes.h" +class LLFloater; + class LLFloaterBuyCurrency { public: @@ -46,6 +48,8 @@ public: "Uploading costs" a space and the price will be appended */ + + static LLFloater* buildFloater(const LLSD& key); }; diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 3fbee83c7b..3d1b7965a1 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -43,6 +43,7 @@ #include "llconfirmationmanager.h" #include "llcurrencyuimanager.h" #include "llfloater.h" +#include "llfloaterreg.h" #include "llfloatertools.h" #include "llframetimer.h" #include "lliconctrl.h" @@ -75,10 +76,22 @@ const F64 CURRENCY_ESTIMATE_FREQUENCY = 0.5; class LLFloaterBuyLandUI : public LLFloater { -private: - LLFloaterBuyLandUI(); +public: + LLFloaterBuyLandUI(const LLSD& key); virtual ~LLFloaterBuyLandUI(); - + +private: + class SelectionObserver : public LLParcelObserver + { + public: + SelectionObserver(LLFloaterBuyLandUI* floater) : mFloater(floater) {} + virtual void changed(); + private: + LLFloaterBuyLandUI* mFloater; + }; + +private: + SelectionObserver mParcelSelectionObserver; LLViewerRegion* mRegion; LLParcelSelectionHandle mParcel; bool mIsClaim; @@ -144,11 +157,7 @@ private: LLViewerParcelMgr::ParcelBuyInfo* mParcelBuyInfo; - static LLFloaterBuyLandUI* sInstance; - public: - static LLFloaterBuyLandUI* soleInstance(bool createIfNeeded); - void setForGroup(bool is_for_group); void setParcel(LLViewerRegion* region, LLParcelSelectionHandle parcel); @@ -156,10 +165,10 @@ public: void updateParcelInfo(); void updateCovenantInfo(); static void onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data); - void updateCovenantText(const std::string& string, const LLUUID &asset_id); - void updateEstateName(const std::string& name); - void updateLastModified(const std::string& text); - void updateEstateOwnerName(const std::string& name); + void updateFloaterCovenantText(const std::string& string, const LLUUID &asset_id); + void updateFloaterEstateName(const std::string& name); + void updateFloaterLastModified(const std::string& text); + void updateFloaterEstateOwnerName(const std::string& name); void updateWebSiteInfo(); void finishWebSiteInfo(); @@ -171,7 +180,7 @@ public: void refreshUI(); - void startTransaction(TransactionType type, LLXMLRPCValue params); + void startTransaction(TransactionType type, const LLXMLRPCValue& params); bool checkTransaction(); void tellUserError(const std::string& message, const std::string& uri); @@ -181,26 +190,21 @@ public: void startBuyPreConfirm(); void startBuyPostConfirm(const std::string& password); - static void onClickBuy(void* data); - static void onClickCancel(void* data); - static void onClickErrorWeb(void* data); + void onClickBuy(); + void onClickCancel(); + void onClickErrorWeb(); virtual void draw(); virtual BOOL canClose(); - /*virtual*/ void setMinimized(BOOL b); + + void onVisibilityChange ( const LLSD& new_visibility ); -private: - class SelectionObserver : public LLParcelObserver - { - public: - virtual void changed(); - }; }; static void cacheNameUpdateRefreshesBuyLand(const LLUUID&, const std::string&, const std::string&, BOOL) { - LLFloaterBuyLandUI* ui = LLFloaterBuyLandUI::soleInstance(false); + LLFloaterBuyLandUI* ui = LLFloaterReg::findTypedInstance("buy_land"); if (ui) { ui->updateNames(); @@ -217,101 +221,64 @@ void LLFloaterBuyLand::buyLand( return; } - LLFloaterBuyLandUI* ui = LLFloaterBuyLandUI::soleInstance(true); - ui->setForGroup(is_for_group); - ui->setParcel(region, parcel); - ui->openFloater(); + LLFloaterBuyLandUI* ui = LLFloaterReg::showTypedInstance("buy_land"); + if (ui) + { + ui->setForGroup(is_for_group); + ui->setParcel(region, parcel); + } } // static void LLFloaterBuyLand::updateCovenantText(const std::string& string, const LLUUID &asset_id) { - LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE); + LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance("buy_land"); if (floater) { - floater->updateCovenantText(string, asset_id); + floater->updateFloaterCovenantText(string, asset_id); } } // static void LLFloaterBuyLand::updateEstateName(const std::string& name) { - LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE); + LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance("buy_land"); if (floater) { - floater->updateEstateName(name); + floater->updateFloaterEstateName(name); } } // static void LLFloaterBuyLand::updateLastModified(const std::string& text) { - LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE); + LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance("buy_land"); if (floater) { - floater->updateLastModified(text); + floater->updateFloaterLastModified(text); } } // static void LLFloaterBuyLand::updateEstateOwnerName(const std::string& name) { - LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE); + LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance("buy_land"); if (floater) { - floater->updateEstateOwnerName(name); + floater->updateFloaterEstateOwnerName(name); } } // static -BOOL LLFloaterBuyLand::isOpen() +LLFloater* LLFloaterBuyLand::buildFloater(const LLSD& key) { - LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE); - if (floater) - { - return floater->getVisible(); - } - return FALSE; -} - -// static -LLFloaterBuyLandUI* LLFloaterBuyLandUI::sInstance = NULL; - -// static -LLFloaterBuyLandUI* LLFloaterBuyLandUI::soleInstance(bool createIfNeeded) -{ -#if !LL_RELEASE_FOR_DOWNLOAD - if (createIfNeeded) - { - delete sInstance; - sInstance = NULL; - } -#endif - if (!sInstance && createIfNeeded) - { - sInstance = new LLFloaterBuyLandUI(); - - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_buy_land.xml"); - sInstance->center(); - - static bool observingCacheName = false; - if (!observingCacheName) - { - gCacheName->addObserver(&cacheNameUpdateRefreshesBuyLand); - observingCacheName = true; - } - - static SelectionObserver* parcelSelectionObserver = NULL; - if (!parcelSelectionObserver) - { - parcelSelectionObserver = new SelectionObserver; - LLViewerParcelMgr::getInstance()->addObserver(parcelSelectionObserver); - } - } - - return sInstance; + LLFloaterBuyLandUI* floater = new LLFloaterBuyLandUI(key); + return floater; } +//---------------------------------------------------------------------------- +// LLFloaterBuyLandUI +//---------------------------------------------------------------------------- #if LL_WINDOWS // passing 'this' during construction generates a warning. The callee @@ -320,42 +287,45 @@ LLFloaterBuyLandUI* LLFloaterBuyLandUI::soleInstance(bool createIfNeeded) // warning so that we can compile without generating a warning. #pragma warning(disable : 4355) #endif -LLFloaterBuyLandUI::LLFloaterBuyLandUI() -: LLFloater(), +LLFloaterBuyLandUI::LLFloaterBuyLandUI(const LLSD& key) +: LLFloater(LLSD()), + mParcelSelectionObserver(this), mParcel(0), mBought(false), mParcelValid(false), mSiteValid(false), mChildren(*this), mCurrency(*this), mTransaction(0), mParcelBuyInfo(0) { + static bool observingCacheName = false; + if (!observingCacheName) + { + gCacheName->addObserver(&cacheNameUpdateRefreshesBuyLand); + observingCacheName = true; + } + + LLViewerParcelMgr::getInstance()->addObserver(&mParcelSelectionObserver); + +// LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_buy_land.xml"); } LLFloaterBuyLandUI::~LLFloaterBuyLandUI() { - delete mTransaction; - + LLViewerParcelMgr::getInstance()->removeObserver(&mParcelSelectionObserver); LLViewerParcelMgr::getInstance()->deleteParcelBuy(mParcelBuyInfo); - if (sInstance == this) - { - sInstance = NULL; - } + delete mTransaction; } void LLFloaterBuyLandUI::SelectionObserver::changed() { - LLFloaterBuyLandUI* ui = LLFloaterBuyLandUI::soleInstance(false); - if (ui) + if (LLViewerParcelMgr::getInstance()->selectionEmpty()) { - if (LLViewerParcelMgr::getInstance()->selectionEmpty()) - { - ui->closeFloater(); - } - else { - ui->setParcel( - LLViewerParcelMgr::getInstance()->getSelectionRegion(), - LLViewerParcelMgr::getInstance()->getParcelSelection()); - } + mFloater->closeFloater(); + } + else + { + mFloater->setParcel(LLViewerParcelMgr::getInstance()->getSelectionRegion(), + LLViewerParcelMgr::getInstance()->getParcelSelection()); } } @@ -593,7 +563,7 @@ void LLFloaterBuyLandUI::onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data) } } -void LLFloaterBuyLandUI::updateCovenantText(const std::string &string, const LLUUID& asset_id) +void LLFloaterBuyLandUI::updateFloaterCovenantText(const std::string &string, const LLUUID& asset_id) { LLViewerTextEditor* editor = getChild("covenant_editor"); if (editor) @@ -625,19 +595,19 @@ void LLFloaterBuyLandUI::updateCovenantText(const std::string &string, const LLU } } -void LLFloaterBuyLandUI::updateEstateName(const std::string& name) +void LLFloaterBuyLandUI::updateFloaterEstateName(const std::string& name) { LLTextBox* box = getChild("estate_name_text"); if (box) box->setText(name); } -void LLFloaterBuyLandUI::updateLastModified(const std::string& text) +void LLFloaterBuyLandUI::updateFloaterLastModified(const std::string& text) { LLTextBox* editor = getChild("covenant_timestamp_text"); if (editor) editor->setText(text); } -void LLFloaterBuyLandUI::updateEstateOwnerName(const std::string& name) +void LLFloaterBuyLandUI::updateFloaterEstateOwnerName(const std::string& name) { LLTextBox* box = getChild("estate_owner_text"); if (box) box->setText(name); @@ -834,8 +804,7 @@ void LLFloaterBuyLandUI::updateNames() } -void LLFloaterBuyLandUI::startTransaction(TransactionType type, - LLXMLRPCValue params) +void LLFloaterBuyLandUI::startTransaction(TransactionType type, const LLXMLRPCValue& params) { delete mTransaction; mTransaction = NULL; @@ -916,11 +885,15 @@ void LLFloaterBuyLandUI::tellUserError( // virtual BOOL LLFloaterBuyLandUI::postBuild() { + mVisibleSignal.connect(boost::bind(&LLFloaterBuyLandUI::onVisibilityChange, this, _2)); + mCurrency.prepare(); - childSetAction("buy_btn", onClickBuy, this); - childSetAction("cancel_btn", onClickCancel, this); - childSetAction("error_web", onClickErrorWeb, this); + getChild("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyLandUI::onClickBuy, this)); + getChild("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyLandUI::onClickCancel, this)); + getChild("error_web")->setCommitCallback( boost::bind(&LLFloaterBuyLandUI::onClickErrorWeb, this)); + + center(); return TRUE; } @@ -986,12 +959,9 @@ BOOL LLFloaterBuyLandUI::canClose() return can_close; } -// virtual -void LLFloaterBuyLandUI::setMinimized(BOOL minimize) +void LLFloaterBuyLandUI::onVisibilityChange ( const LLSD& new_visibility ) { - bool restored = (isMinimized() && !minimize); - LLFloater::setMinimized(minimize); - if (restored) + if (new_visibility.asBoolean()) { refreshUI(); } @@ -1346,26 +1316,20 @@ void LLFloaterBuyLandUI::startBuyPostConfirm(const std::string& password) } -// static -void LLFloaterBuyLandUI::onClickBuy(void* data) +void LLFloaterBuyLandUI::onClickBuy() { - LLFloaterBuyLandUI* self = (LLFloaterBuyLandUI*)data; - self->startBuyPreConfirm(); + startBuyPreConfirm(); } -// static -void LLFloaterBuyLandUI::onClickCancel(void* data) +void LLFloaterBuyLandUI::onClickCancel() { - LLFloaterBuyLandUI* self = (LLFloaterBuyLandUI*)data; - self->closeFloater(); + closeFloater(); } -// static -void LLFloaterBuyLandUI::onClickErrorWeb(void* data) +void LLFloaterBuyLandUI::onClickErrorWeb() { - LLFloaterBuyLandUI* self = (LLFloaterBuyLandUI*)data; - LLWeb::loadURLExternal(self->mCannotBuyURI); - self->closeFloater(); + LLWeb::loadURLExternal(mCannotBuyURI); + closeFloater(); } diff --git a/indra/newview/llfloaterbuyland.h b/indra/newview/llfloaterbuyland.h index 82e59a0bcc..7df07f752d 100644 --- a/indra/newview/llfloaterbuyland.h +++ b/indra/newview/llfloaterbuyland.h @@ -33,6 +33,7 @@ #ifndef LL_LLFLOATERBUYLAND_H #define LL_LLFLOATERBUYLAND_H +class LLFloater; class LLViewerRegion; class LLViewerTextEditor; class LLParcelSelection; @@ -47,7 +48,8 @@ public: static void updateEstateName(const std::string& name); static void updateLastModified(const std::string& text); static void updateEstateOwnerName(const std::string& name); - static BOOL isOpen(); + + static LLFloater* buildFloater(const LLSD& key); }; #endif diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index e79142513b..81f1beb40d 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -35,24 +35,143 @@ #include "llfloatercamera.h" // Library includes -#include "lluictrlfactory.h" +#include "llfloaterreg.h" // Viewer includes #include "lljoystickbutton.h" +#include "llfirsttimetipmanager.h" #include "llviewercontrol.h" +#include "llbottomtray.h" +#include "llagent.h" +#include "lltoolmgr.h" +#include "lltoolfocus.h" // Constants const F32 CAMERA_BUTTON_DELAY = 0.0f; +#define ORBIT "cam_rotate_stick" +#define PAN "cam_track_stick" +#define CONTROLS "controls" + // // Member functions // -LLFloaterCamera::LLFloaterCamera(const LLSD& val) -: LLFloater() + +/*static*/ bool LLFloaterCamera::inFreeCameraMode() +{ + LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance(); + if (floater_camera && floater_camera->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA) + { + return true; + } + return false; +} + +bool LLFloaterCamera::inAvatarViewMode() +{ + return mCurrMode == CAMERA_CTRL_MODE_AVATAR_VIEW; +} + +void LLFloaterCamera::resetFreeCameraMode() +{ + if (mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA) + { + /* Camera Tool can be deselected when we are mouse wheel scrolling into Mouse Look + In such case we are unable to determine that we will be into Mouse Look view */ + if (mPrevMode == CAMERA_CTRL_MODE_AVATAR_VIEW) + { + setMode(CAMERA_CTRL_MODE_ORBIT); + } + else + { + setMode(mPrevMode); + } + } +} + +void LLFloaterCamera::update() +{ + ECameraControlMode mode = determineMode(); + if (mode != mCurrMode) setMode(mode); + LLFirstTimeTipsManager::showTipsFor(mMode2TipType[mode], this); +} + + +/*static*/ void LLFloaterCamera::updateIfNotInAvatarViewMode() +{ + LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance(); + if (floater_camera && !floater_camera->inAvatarViewMode()) + { + floater_camera->update(); + } +} + + +void LLFloaterCamera::toPrevMode() +{ + switchMode(mPrevMode); +} + +/*static*/ void LLFloaterCamera::toPrevModeIfInAvatarViewMode() +{ + LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance(); + if (floater_camera && floater_camera->inAvatarViewMode()) + { + floater_camera->toPrevMode(); + } +} + +LLFloaterCamera* LLFloaterCamera::findInstance() +{ + return LLFloaterReg::findTypedInstance("camera"); +} + +/*static*/ +void LLFloaterCamera::onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param) +{ + std::string name = param.asString(); + + if ("rear_view" == name) + { + LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_REAR, ctrl); + gAgent.resetView(TRUE, TRUE); + } + else if ("3/4_view" == name) + { + LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_GROUP); + //*TODO implement 3/4 view + } + else if ("front_view" == name) + { + LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_FRONT); + //*TODO implement front view + } + +} + +void LLFloaterCamera::onOpen(const LLSD& key) +{ + updatePosition(); +} + +void LLFloaterCamera::updatePosition() +{ + LLBottomTray* tray = LLBottomTray::getInstance(); + if (!tray) return; + + LLButton* camera_button = tray->getChild("camera_btn", TRUE, FALSE); + if (!camera_button) return; + + //align centers of a button and a floater + S32 x = camera_button->calcScreenRect().getCenterX() - getRect().getWidth()/2; + setOrigin(x, 0); +} + +LLFloaterCamera::LLFloaterCamera(const LLSD& val) +: LLFloater(val), + mCurrMode(CAMERA_CTRL_MODE_ORBIT), + mPrevMode(CAMERA_CTRL_MODE_ORBIT) { - // For now, only used for size and tooltip strings - const BOOL DONT_OPEN = FALSE; - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_camera.xml", DONT_OPEN); } // virtual @@ -60,27 +179,163 @@ BOOL LLFloaterCamera::postBuild() { setIsChrome(TRUE); - mRotate = getChild("cam_rotate_stick"); + mRotate = getChild(ORBIT); mZoom = getChild("zoom"); - mTrack = getChild("cam_track_stick"); + mTrack = getChild(PAN); + + initMode2TipTypeMap(); + + assignButton2Mode(CAMERA_CTRL_MODE_ORBIT, "orbit_btn"); + assignButton2Mode(CAMERA_CTRL_MODE_PAN, "pan_btn"); + assignButton2Mode(CAMERA_CTRL_MODE_FREE_CAMERA, "freecamera_btn"); + assignButton2Mode(CAMERA_CTRL_MODE_AVATAR_VIEW, "avatarview_btn"); + + update(); return TRUE; } -// virtual -void LLFloaterCamera::onOpen(const LLSD& key) +ECameraControlMode LLFloaterCamera::determineMode() { - gSavedSettings.setBOOL("ShowCameraControls", TRUE); + LLTool* curr_tool = LLToolMgr::getInstance()->getCurrentTool(); + if (curr_tool == LLToolCamera::getInstance()) + { + return CAMERA_CTRL_MODE_FREE_CAMERA; + } + + if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK) + { + return CAMERA_CTRL_MODE_AVATAR_VIEW; + } + + return CAMERA_CTRL_MODE_ORBIT; } -// virtual -void LLFloaterCamera::onClose(bool app_quitting) + +void clear_camera_tool() { - destroy(); - - if (!app_quitting) + LLToolMgr* tool_mgr = LLToolMgr::getInstance(); + if (tool_mgr->usingTransientTool() && + tool_mgr->getCurrentTool() == LLToolCamera::getInstance()) { - gSavedSettings.setBOOL("ShowCameraControls", FALSE); + tool_mgr->clearTransientTool(); + } +} + + +void LLFloaterCamera::setMode(ECameraControlMode mode) +{ + if (mode != mCurrMode) + { + mPrevMode = mCurrMode; + mCurrMode = mode; + } + + updateState(); +} + +void LLFloaterCamera::switchMode(ECameraControlMode mode) +{ + setMode(mode); + + switch (mode) + { + case CAMERA_CTRL_MODE_ORBIT: + clear_camera_tool(); + break; + + case CAMERA_CTRL_MODE_PAN: + clear_camera_tool(); + break; + + case CAMERA_CTRL_MODE_FREE_CAMERA: + LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance()); + break; + + case CAMERA_CTRL_MODE_AVATAR_VIEW: + gAgent.changeCameraToMouselook(); + break; + + default: + //normally we won't occur here + llassert_always(FALSE); + } +} + + +void LLFloaterCamera::onClickBtn(ECameraControlMode mode) +{ + // check for a click on active button + if (mCurrMode == mode) mMode2Button[mode]->setToggleState(TRUE); + + switchMode(mode); + + LLFirstTimeTipsManager::showTipsFor(mMode2TipType[mode], mMode2Button[mode]); +} + +void LLFloaterCamera::assignButton2Mode(ECameraControlMode mode, const std::string& button_name) +{ + LLButton* button = getChild(button_name, TRUE, FALSE); + llassert_always(button); + + if (button) + { + button->setClickedCallback(boost::bind(&LLFloaterCamera::onClickBtn, this, mode)); + mMode2Button[mode] = button; + } +} + +void LLFloaterCamera::initMode2TipTypeMap() +{ + mMode2TipType[CAMERA_CTRL_MODE_ORBIT] = LLFirstTimeTipsManager::FTT_CAMERA_ORBIT_MODE; + mMode2TipType[CAMERA_CTRL_MODE_PAN] = LLFirstTimeTipsManager::FTT_CAMERA_PAN_MODE; + mMode2TipType[CAMERA_CTRL_MODE_FREE_CAMERA] = LLFirstTimeTipsManager::FTT_CAMERA_FREE_MODE; + mMode2TipType[CAMERA_CTRL_MODE_AVATAR_VIEW] = LLFirstTimeTipsManager::FTT_AVATAR_FREE_MODE; +} + + +void LLFloaterCamera::updateState() +{ + //updating buttons + std::map::const_iterator iter = mMode2Button.begin(); + for (; iter != mMode2Button.end(); ++iter) + { + iter->second->setToggleState(iter->first == mCurrMode); + } + + //updating controls + bool isOrbitMode = CAMERA_CTRL_MODE_ORBIT == mCurrMode; + bool isPanMode = CAMERA_CTRL_MODE_PAN == mCurrMode; + + childSetVisible(ORBIT, isOrbitMode); + childSetVisible(PAN, isPanMode); + + //hiding or showing the panel with controls by reshaping the floater + bool showControls = isOrbitMode || isPanMode; + if (showControls == childIsVisible(CONTROLS)) return; + + childSetVisible(CONTROLS, showControls); + + LLRect rect = getRect(); + LLRect controls_rect; + if (childGetRect(CONTROLS, controls_rect)) + { + static S32 height = controls_rect.getHeight(); + S32 newHeight = rect.getHeight(); + + if (showControls) + { + newHeight += height; + } + else + { + newHeight -= height; + } + + rect.setOriginAndSize(rect.mLeft, rect.mBottom, rect.getWidth(), newHeight); + reshape(rect.getWidth(), rect.getHeight()); + setRect(rect); + } } diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index f954e329eb..04554c6493 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -35,27 +35,94 @@ #include "llfloater.h" +#include "llfirsttimetipmanager.h" + class LLJoystickCameraRotate; class LLJoystickCameraZoom; class LLJoystickCameraTrack; +class LLFloaterReg; + +enum ECameraControlMode +{ + CAMERA_CTRL_MODE_ORBIT, + CAMERA_CTRL_MODE_PAN, + CAMERA_CTRL_MODE_FREE_CAMERA, + CAMERA_CTRL_MODE_AVATAR_VIEW +}; class LLFloaterCamera - : public LLFloater, - public LLFloaterSingleton + : public LLFloater { - friend class LLUISingleton >; + friend class LLFloaterReg; -private: - LLFloaterCamera(const LLSD& val); - ~LLFloaterCamera() {}; - - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); - /*virtual*/ BOOL postBuild(); public: + + /* whether in free camera mode */ + static bool inFreeCameraMode(); + + static void toPrevModeIfInAvatarViewMode(); + + /* resets free camera mode to the previous mode */ + //*TODO remove, if it won't be used by LLToolCamera::handleDeselect() + void resetFreeCameraMode(); + + /* determines actual mode and updates ui */ + void update(); + + static void updateIfNotInAvatarViewMode(); + + static void onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param); + + virtual void onOpen(const LLSD& key); + + // *HACK: due to hard enough to have this control aligned with "Camera" button while resizing + // let update its position in each frame + /*virtual*/ void draw(){updatePosition(); LLFloater::draw();} + LLJoystickCameraRotate* mRotate; LLJoystickCameraZoom* mZoom; LLJoystickCameraTrack* mTrack; + +private: + + LLFloaterCamera(const LLSD& val); + ~LLFloaterCamera() {}; + + /* return instance if it exists - created by LLFloaterReg */ + static LLFloaterCamera* findInstance(); + + /*virtual*/ BOOL postBuild(); + + ECameraControlMode determineMode(); + + /* whether in avatar view (first person) mode */ + bool inAvatarViewMode(); + + /* resets to the previous mode */ + void toPrevMode(); + + /* sets a new mode and performs related actions */ + void switchMode(ECameraControlMode mode); + + /* sets a new mode preserving previous one and updates ui*/ + void setMode(ECameraControlMode mode); + + /* updates the state (UI) according to the current mode */ + void updateState(); + + void onClickBtn(ECameraControlMode mode); + void assignButton2Mode(ECameraControlMode mode, const std::string& button_name); + void initMode2TipTypeMap(); + + /*Updates position of the floater to be center aligned with "Camera" button.*/ + void updatePosition(); + + + ECameraControlMode mPrevMode; + ECameraControlMode mCurrMode; + std::map mMode2Button; + std::map mMode2TipType; + }; #endif diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index 61ef3abda6..8fcb7b985f 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -63,7 +63,6 @@ #include "llviewerwindow.h" #include "llviewercontrol.h" #include "lluictrlfactory.h" -#include "llchatbar.h" #include "lllogchat.h" #include "lltexteditor.h" #include "lltextparser.h" @@ -87,6 +86,7 @@ const F32 INSTANT_MSG_SIZE = 8.0f; const F32 CHAT_MSG_SIZE = 8.0f; + // // Global statics // @@ -96,7 +96,7 @@ LLColor4 get_text_color(const LLChat& chat); // Member Functions // LLFloaterChat::LLFloaterChat(const LLSD& seed) - : LLFloater(), + : LLFloater(seed), mPanel(NULL) { mFactoryMap["chat_panel"] = LLCallbackMap(createChatPanel, NULL); @@ -110,11 +110,6 @@ LLFloaterChat::~LLFloaterChat() // Children all cleaned up by default view destructor. } -void LLFloaterChat::setVisible(BOOL visible) -{ - LLFloater::setVisible( visible ); -} - void LLFloaterChat::draw() { // enable say and shout only when text available @@ -133,14 +128,11 @@ void LLFloaterChat::draw() BOOL LLFloaterChat::postBuild() { + // Hide the chat overlay when our history is visible. + mVisibleSignal.connect(boost::bind(&LLFloaterChat::updateConsoleVisibility, this)); + mPanel = (LLPanelActiveSpeakers*)getChild("active_speakers_panel"); - LLChatBar* chat_barp = findChild("chat_panel", TRUE); - if (chat_barp) - { - chat_barp->setGestureCombo(getChild( "Gesture")); - } - childSetCommitCallback("show mutes",onClickToggleShowMute,this); //show mutes childSetVisible("Chat History Editor with mute",FALSE); childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this); @@ -148,34 +140,6 @@ BOOL LLFloaterChat::postBuild() return TRUE; } -// public virtual -void LLFloaterChat::onClose(bool app_quitting) -{ - if (getHost()) - { - getHost()->setVisible(FALSE); - } - else - { - setVisible(FALSE); - } -} - -void LLFloaterChat::onVisibilityChange(BOOL new_visibility) -{ - // Hide the chat overlay when our history is visible. - updateConsoleVisibility(); - - LLFloater::onVisibilityChange(new_visibility); -} - -void LLFloaterChat::setMinimized(BOOL minimized) -{ - LLFloater::setMinimized(minimized); - updateConsoleVisibility(); -} - - void LLFloaterChat::updateConsoleVisibility() { // determine whether we should show console due to not being visible @@ -218,7 +182,7 @@ void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& void log_chat_text(const LLChat& chat) { std::string histstr; - if (gSavedPerAccountSettings.getBOOL("LogChatTimestamp")) + if (gSavedPerAccountSettings.getBOOL("LogTimestamp")) histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + chat.mText; else histstr = chat.mText; @@ -228,7 +192,7 @@ void log_chat_text(const LLChat& chat) // static void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file) { - if ( gSavedPerAccountSettings.getBOOL("LogChat") && log_to_file) + if ( (gSavedPerAccountSettings.getS32("IMLogOptions")!=LOG_IM) && log_to_file) { log_chat_text(chat); } @@ -368,11 +332,11 @@ void LLFloaterChat::addChat(const LLChat& chat, F32 size = CHAT_MSG_SIZE; if (chat.mSourceType == CHAT_SOURCE_SYSTEM) { - text_color = gSavedSkinSettings.getColor("SystemChatColor"); + text_color = LLUIColorTable::instance().getColor("SystemChatColor"); } else if(from_instant_message) { - text_color = gSavedSkinSettings.getColor("IMChatColor"); + text_color = LLUIColorTable::instance().getColor("IMChatColor"); size = INSTANT_MSG_SIZE; } // We display anything if it's not an IM. If it's an IM, check pref... @@ -382,7 +346,7 @@ void LLFloaterChat::addChat(const LLChat& chat, } } - if(from_instant_message && gSavedPerAccountSettings.getBOOL("LogChatIM")) + if(from_instant_message && (gSavedPerAccountSettings.getS32("IMLogOptions")== LOG_BOTH_TOGETHER)) log_chat_text(chat); if(from_instant_message && gSavedSettings.getBOOL("IMInChatHistory")) @@ -453,37 +417,37 @@ LLColor4 get_text_color(const LLChat& chat) switch(chat.mSourceType) { case CHAT_SOURCE_SYSTEM: - text_color = gSavedSkinSettings.getColor4("SystemChatColor"); + text_color = LLUIColorTable::instance().getColor("SystemChatColor"); break; case CHAT_SOURCE_AGENT: if (chat.mFromID.isNull()) { - text_color = gSavedSkinSettings.getColor4("SystemChatColor"); + text_color = LLUIColorTable::instance().getColor("SystemChatColor"); } else { if(gAgent.getID() == chat.mFromID) { - text_color = gSavedSkinSettings.getColor4("UserChatColor"); + text_color = LLUIColorTable::instance().getColor("UserChatColor"); } else { - text_color = gSavedSkinSettings.getColor4("AgentChatColor"); + text_color = LLUIColorTable::instance().getColor("AgentChatColor"); } } break; case CHAT_SOURCE_OBJECT: if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) { - text_color = gSavedSkinSettings.getColor4("ScriptErrorColor"); + text_color = LLUIColorTable::instance().getColor("ScriptErrorColor"); } else if ( chat.mChatType == CHAT_TYPE_OWNER ) { - text_color = gSavedSkinSettings.getColor4("llOwnerSayChatColor"); + text_color = LLUIColorTable::instance().getColor("llOwnerSayChatColor"); } else { - text_color = gSavedSkinSettings.getColor4("ObjectChatColor"); + text_color = LLUIColorTable::instance().getColor("ObjectChatColor"); } break; default: @@ -558,6 +522,6 @@ void LLFloaterChat::onClickToggleActiveSpeakers(void* userdata) //static LLFloaterChat* LLFloaterChat::getInstance() { - LLFloater* inst = LLFloaterReg::getInstance("chat", LLSD()) ; - return dynamic_cast(inst); + return LLFloaterReg::getTypedInstance("chat", LLSD()) ; + } diff --git a/indra/newview/llfloaterchat.h b/indra/newview/llfloaterchat.h index 2bae4ea0c2..e8af48d095 100644 --- a/indra/newview/llfloaterchat.h +++ b/indra/newview/llfloaterchat.h @@ -51,18 +51,23 @@ class LLLogChat; class LLVector3d; class LLWindow; +enum ELogOptions +{ + LOG_CHAT = 0, + LOG_IM = 1, + LOG_BOTH_TOGETHER = 2, + LOG_BOTH_SEPARATE = 3 +}; + class LLFloaterChat : public LLFloater { public: LLFloaterChat(const LLSD& seed); ~LLFloaterChat(); - virtual void setVisible( BOOL b ); virtual void draw(); virtual BOOL postBuild(); - virtual void onClose(bool app_quitting); - virtual void onVisibilityChange(BOOL cur_visibility); - virtual void setMinimized(BOOL); + void updateConsoleVisibility(); static void setHistoryCursorAndScrollToEnd(); diff --git a/indra/newview/llfloaterchatterbox.cpp b/indra/newview/llfloaterchatterbox.cpp index a283b445f5..05ea800d0e 100644 --- a/indra/newview/llfloaterchatterbox.cpp +++ b/indra/newview/llfloaterchatterbox.cpp @@ -50,7 +50,7 @@ // LLFloaterMyFriends::LLFloaterMyFriends(const LLSD& seed) - : LLFloater() + : LLFloater(seed) { mFactoryMap["friends_panel"] = LLCallbackMap(LLFloaterMyFriends::createFriendsPanel, NULL); mFactoryMap["groups_panel"] = LLCallbackMap(LLFloaterMyFriends::createGroupsPanel, NULL); @@ -78,11 +78,6 @@ void LLFloaterMyFriends::onOpen(const LLSD& key) } } -void LLFloaterMyFriends::onClose(bool app_quitting) -{ - setVisible(FALSE); -} - //static void* LLFloaterMyFriends::createFriendsPanel(void* data) { @@ -98,16 +93,15 @@ void* LLFloaterMyFriends::createGroupsPanel(void* data) //static LLFloaterMyFriends* LLFloaterMyFriends::getInstance() { - LLFloater* inst = LLFloaterReg::getInstance("contacts", "friends") ; - return dynamic_cast(inst); + return LLFloaterReg::getTypedInstance("contacts", "friends") ; } // // LLFloaterChatterBox // LLFloaterChatterBox::LLFloaterChatterBox(const LLSD& seed) - : LLMultiFloater(), - mActiveVoiceFloater(NULL) +: LLMultiFloater(seed), + mActiveVoiceFloater(NULL) { mAutoResize = FALSE; @@ -120,14 +114,19 @@ LLFloaterChatterBox::~LLFloaterChatterBox() BOOL LLFloaterChatterBox::postBuild() { + mVisibleSignal.connect(boost::bind(&LLFloaterChatterBox::onVisibilityChange, this, _2)); + if (gSavedSettings.getBOOL("ContactsTornOff")) { LLFloaterMyFriends* floater_contacts = LLFloaterMyFriends::getInstance(); - // add then remove to set up relationship for re-attach - addFloater(floater_contacts, FALSE); - removeFloater(floater_contacts); - // reparent to floater view - gFloaterView->addChild(floater_contacts); + if(floater_contacts) + { + // add then remove to set up relationship for re-attach + addFloater(floater_contacts, FALSE); + removeFloater(floater_contacts); + // reparent to floater view + gFloaterView->addChild(floater_contacts); + } } else { @@ -137,11 +136,14 @@ BOOL LLFloaterChatterBox::postBuild() if (gSavedSettings.getBOOL("ChatHistoryTornOff")) { LLFloaterChat* floater_chat = LLFloaterChat::getInstance(); - // add then remove to set up relationship for re-attach - addFloater(floater_chat, FALSE); - removeFloater(floater_chat); - // reparent to floater view - gFloaterView->addChild(floater_chat); + if(floater_chat) + { + // add then remove to set up relationship for re-attach + addFloater(floater_chat, FALSE); + removeFloater(floater_chat); + // reparent to floater view + gFloaterView->addChild(floater_chat); + } } else { @@ -240,20 +242,20 @@ void LLFloaterChatterBox::onOpen(const LLSD& key) } } -void LLFloaterChatterBox::onClose(bool app_quitting) +void LLFloaterChatterBox::onVisibilityChange ( const LLSD& new_visibility ) { - setVisible(FALSE); -} - -void LLFloaterChatterBox::setMinimized(BOOL minimized) -{ - LLFloater::setMinimized(minimized); // HACK: potentially need to toggle console - LLFloaterChat::getInstance()->updateConsoleVisibility(); + LLFloaterChat* instance = LLFloaterChat::getInstance(); + if(instance) + { + instance->updateConsoleVisibility(); + } } void LLFloaterChatterBox::removeFloater(LLFloater* floaterp) { + if(!floaterp) return; + if (floaterp->getName() == "chat floater") { // only my friends floater now locked @@ -275,6 +277,8 @@ void LLFloaterChatterBox::addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point) { + if(!floaterp) return; + S32 num_locked_tabs = mTabContainer->getNumLockedTabs(); // already here @@ -319,7 +323,7 @@ void LLFloaterChatterBox::addFloater(LLFloater* floaterp, else { LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point); - openFloater(floaterp->getKey()); + // openFloater(floaterp->getKey()); } // make sure active voice icon shows up for new tab @@ -332,8 +336,7 @@ void LLFloaterChatterBox::addFloater(LLFloater* floaterp, //static LLFloaterChatterBox* LLFloaterChatterBox::getInstance() { - LLFloater* inst = LLFloaterReg::getInstance("communicate", LLSD()) ; - return dynamic_cast(inst); + return LLFloaterReg::getTypedInstance("communicate", LLSD()) ; } //static @@ -351,6 +354,7 @@ LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater() else { LLFloaterChatterBox* floater = LLFloaterChatterBox::getInstance(); + if(!floater) return NULL; // iterator over all IM tabs (skip friends and near me) for (S32 i = 0; i < floater->getFloaterCount(); i++) { diff --git a/indra/newview/llfloaterchatterbox.h b/indra/newview/llfloaterchatterbox.h index e6a2e30ba6..3929e6e36c 100644 --- a/indra/newview/llfloaterchatterbox.h +++ b/indra/newview/llfloaterchatterbox.h @@ -52,8 +52,6 @@ public: /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); /*virtual*/ void draw(); /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); - /*virtual*/ void setMinimized(BOOL minimized); /*virtual*/ void removeFloater(LLFloater* floaterp); /*virtual*/ void addFloater(LLFloater* floaterp, @@ -64,6 +62,8 @@ public: static LLFloater* getCurrentVoiceFloater(); protected: + void onVisibilityChange ( const LLSD& new_visibility ); + LLFloater* mActiveVoiceFloater; }; @@ -76,7 +76,6 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); static LLFloaterMyFriends* getInstance(); // *TODO:Skinning Deprecate diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index 4964f04556..8e385fca78 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -56,7 +56,6 @@ #include "llpointer.h" #include "llimage.h" #include "llmousehandler.h" -#include "llimagegl.h" #include "llglheaders.h" #include "llcheckboxctrl.h" #include "lltextbox.h" @@ -80,7 +79,7 @@ const F32 CONTEXT_FADE_TIME = 0.08f; ////////////////////////////////////////////////////////////////////////////// LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate ) - : LLFloater(), + : LLFloater(LLSD()), mComponents ( 3 ), mMouseDownInLumRegion ( FALSE ), mMouseDownInHueRegion ( FALSE ), @@ -114,6 +113,9 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show mCanApplyImmediately ( show_apply_immediate ), mContextConeOpacity ( 0.f ) { + // build the majority of the gui using the factory builder + LLUICtrlFactory::getInstance()->buildFloater ( this, "floater_color_picker.xml", NULL ); + // create user interface for this picker createUI (); @@ -134,10 +136,6 @@ LLFloaterColorPicker::~LLFloaterColorPicker() // void LLFloaterColorPicker::createUI () { - // build the majority of the gui using the factory builder - LLUICtrlFactory::getInstance()->buildFloater ( this, "floater_color_picker.xml" ); - setVisible ( FALSE ); - // create RGB type area (not really RGB but it's got R,G & B in it.,.. LLPointer raw = new LLImageRaw ( mRGBViewerImageWidth, mRGBViewerImageHeight, mComponents ); @@ -161,7 +159,7 @@ void LLFloaterColorPicker::createUI () * ( bits + x + y * linesize + 2 ) = ( U8 )( bVal * 255.0f ); } } - mRGBImage = new LLImageGL ( (LLImageRaw*)raw, FALSE ); + mRGBImage = LLViewerTextureManager::getLocalTexture( (LLImageRaw*)raw, FALSE ); gGL.getTexUnit(0)->bind(mRGBImage); mRGBImage->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -173,7 +171,7 @@ void LLFloaterColorPicker::createUI () // argh! const std::string s ( codec.str () ); - mPalette.push_back ( new LLColor4 ( gSavedSkinSettings.getColor4 ( s ) ) ); + mPalette.push_back ( new LLColor4 ( LLUIColorTable::instance().getColor ( s ) ) ); } } @@ -1017,7 +1015,7 @@ BOOL LLFloaterColorPicker::handleMouseUp ( S32 x, S32 y, MASK mask ) std::ostringstream codec; codec << "ColorPaletteEntry" << std::setfill ( '0' ) << std::setw ( 2 ) << curEntry + 1; const std::string s ( codec.str () ); - gSavedSkinSettings.setColor4( s, *mPalette [ curEntry ] ); + LLUIColorTable::instance().setColor(s, *mPalette [ curEntry ] ); } } diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h index 16f456b5bf..a16cde7f10 100644 --- a/indra/newview/llfloatercolorpicker.h +++ b/indra/newview/llfloatercolorpicker.h @@ -175,7 +175,7 @@ class LLFloaterColorPicker const S32 mPaletteRegionHeight; // image used to compose color grid - LLPointer mRGBImage; + LLPointer mRGBImage; // current swatch in use LLColorSwatchCtrl* mSwatch; diff --git a/indra/newview/llfloaterdaycycle.cpp b/indra/newview/llfloaterdaycycle.cpp index a448df792e..7f3b988dfe 100644 --- a/indra/newview/llfloaterdaycycle.cpp +++ b/indra/newview/llfloaterdaycycle.cpp @@ -59,14 +59,13 @@ #include "llfloaterwindlight.h" -LLFloaterDayCycle* LLFloaterDayCycle::sDayCycle = NULL; std::map LLFloaterDayCycle::sSliderToKey; const F32 LLFloaterDayCycle::sHoursPerDay = 24.0f; -LLFloaterDayCycle::LLFloaterDayCycle() - : LLFloater() +LLFloaterDayCycle::LLFloaterDayCycle(const LLSD& key) +: LLFloater(key) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_day_cycle_options.xml"); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_day_cycle_options.xml"); } BOOL LLFloaterDayCycle::postBuild() @@ -95,6 +94,10 @@ BOOL LLFloaterDayCycle::postBuild() // load it up initCallbacks(); + + syncMenu(); + syncSliderTrack(); + return TRUE; } @@ -102,17 +105,14 @@ LLFloaterDayCycle::~LLFloaterDayCycle() { } -void LLFloaterDayCycle::onClickHelp(void* data) +void LLFloaterDayCycle::onClickHelp(std::string xml_alert) { - LLFloaterDayCycle* self = LLFloaterDayCycle::instance(); - - std::string xml_alert = *(std::string *) data; - LLNotifications::instance().add(self->contextualNotification(xml_alert)); + LLNotifications::instance().add(contextualNotification(xml_alert)); } void LLFloaterDayCycle::initHelpBtn(const std::string& name, const std::string& xml_alert) { - childSetAction(name, onClickHelp, new std::string(xml_alert)); + getChild(name)->setClickedCallback(boost::bind(&LLFloaterDayCycle::onClickHelp, this, xml_alert)); } void LLFloaterDayCycle::initCallbacks(void) @@ -120,24 +120,24 @@ void LLFloaterDayCycle::initCallbacks(void) initHelpBtn("WLDayCycleHelp", "HelpDayCycle"); // WL Day Cycle - childSetCommitCallback("WLTimeSlider", onTimeSliderMoved, NULL); - childSetCommitCallback("WLDayCycleKeys", onKeyTimeMoved, NULL); - childSetCommitCallback("WLCurKeyHour", onKeyTimeChanged, NULL); - childSetCommitCallback("WLCurKeyMin", onKeyTimeChanged, NULL); - childSetCommitCallback("WLKeyPresets", onKeyPresetChanged, NULL); + getChild("WLTimeSlider")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onTimeSliderMoved, this, _1)); + getChild("WLDayCycleKeys")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onKeyTimeMoved, this, _1)); + getChild("WLCurKeyHour")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onKeyTimeChanged, this, _1)); + getChild("WLCurKeyMin")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onKeyTimeChanged, this, _1)); + getChild("WLKeyPresets")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onKeyPresetChanged, this, _1)); - childSetCommitCallback("WLLengthOfDayHour", onTimeRateChanged, NULL); - childSetCommitCallback("WLLengthOfDayMin", onTimeRateChanged, NULL); - childSetCommitCallback("WLLengthOfDaySec", onTimeRateChanged, NULL); - childSetAction("WLUseLindenTime", onUseLindenTime, NULL); - childSetAction("WLAnimSky", onRunAnimSky, NULL); - childSetAction("WLStopAnimSky", onStopAnimSky, NULL); + getChild("WLLengthOfDayHour")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onTimeRateChanged, this, _1)); + getChild("WLLengthOfDayMin")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onTimeRateChanged, this, _1)); + getChild("WLLengthOfDaySec")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onTimeRateChanged, this, _1)); + getChild("WLUseLindenTime")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onUseLindenTime, this, _1)); + getChild("WLAnimSky")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onRunAnimSky, this, _1)); + getChild("WLStopAnimSky")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onStopAnimSky, this, _1)); - childSetAction("WLLoadDayCycle", onLoadDayCycle, NULL); - childSetAction("WLSaveDayCycle", onSaveDayCycle, NULL); + getChild("WLLoadDayCycle")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onLoadDayCycle, this, _1)); + getChild("WLSaveDayCycle")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onSaveDayCycle, this, _1)); - childSetAction("WLAddKey", onAddKey, NULL); - childSetAction("WLDeleteKey", onDeleteKey, NULL); + getChild("WLAddKey")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onAddKey, this, _1)); + getChild("WLDeleteKey")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onDeleteKey, this, _1)); } void LLFloaterDayCycle::syncMenu() @@ -145,12 +145,12 @@ void LLFloaterDayCycle::syncMenu() // std::map & currentParams = LLWLParamManager::instance()->mCurParams.mParamValues; // set time - LLMultiSliderCtrl* sldr = LLFloaterDayCycle::sDayCycle->getChild("WLTimeSlider"); + LLMultiSliderCtrl* sldr = getChild("WLTimeSlider"); sldr->setCurSliderValue((F32)LLWLParamManager::instance()->mAnimator.getDayTime() * sHoursPerDay); - LLSpinCtrl* secSpin = sDayCycle->getChild("WLLengthOfDaySec"); - LLSpinCtrl* minSpin = sDayCycle->getChild("WLLengthOfDayMin"); - LLSpinCtrl* hourSpin = sDayCycle->getChild("WLLengthOfDayHour"); + LLSpinCtrl* secSpin = getChild("WLLengthOfDaySec"); + LLSpinCtrl* minSpin = getChild("WLLengthOfDayMin"); + LLSpinCtrl* hourSpin = getChild("WLLengthOfDayHour"); F32 curRate; F32 hours, min, sec; @@ -170,18 +170,18 @@ void LLFloaterDayCycle::syncMenu() // turn off Use Estate Time button if it's already being used if( LLWLParamManager::instance()->mAnimator.mUseLindenTime == true) { - LLFloaterDayCycle::sDayCycle->childDisable("WLUseLindenTime"); + childDisable("WLUseLindenTime"); } else { - LLFloaterDayCycle::sDayCycle->childEnable("WLUseLindenTime"); + childEnable("WLUseLindenTime"); } } void LLFloaterDayCycle::syncSliderTrack() { // clear the slider - LLMultiSliderCtrl* kSldr = sDayCycle->getChild("WLDayCycleKeys"); + LLMultiSliderCtrl* kSldr = getChild("WLDayCycleKeys"); kSldr->clear(); sSliderToKey.clear(); @@ -204,12 +204,12 @@ void LLFloaterDayCycle::syncTrack() } LLMultiSliderCtrl* sldr; - sldr = sDayCycle->getChild( + sldr = getChild( "WLDayCycleKeys"); llassert_always(sSliderToKey.size() == sldr->getValue().size()); LLMultiSliderCtrl* tSldr; - tSldr = sDayCycle->getChild( + tSldr = getChild( "WLTimeSlider"); // create a new animation track @@ -231,50 +231,7 @@ void LLFloaterDayCycle::syncTrack() LLWLParamManager::instance()->mCurParams); } -// static -LLFloaterDayCycle* LLFloaterDayCycle::instance() -{ - if (!sDayCycle) - { - sDayCycle = new LLFloaterDayCycle(); - sDayCycle->openFloater(); - sDayCycle->setFocus(TRUE); - } - return sDayCycle; -} - -bool LLFloaterDayCycle::isOpen() -{ - if (sDayCycle != NULL) - { - return true; - } - return false; -} - -void LLFloaterDayCycle::show() -{ - LLFloaterDayCycle* dayCycle = instance(); - dayCycle->syncMenu(); - syncSliderTrack(); - - // comment in if you want the menu to rebuild each time - //LLUICtrlFactory::getInstance()->buildFloater(dayCycle, "floater_day_cycle_options.xml"); - //dayCycle->initCallbacks(); - - dayCycle->openFloater(); -} - -// virtual -void LLFloaterDayCycle::onClose(bool app_quitting) -{ - if (sDayCycle) - { - sDayCycle->setVisible(FALSE); - } -} - -void LLFloaterDayCycle::onRunAnimSky(void* userData) +void LLFloaterDayCycle::onRunAnimSky(LLUICtrl* ctrl) { // if no keys, do nothing if(sSliderToKey.size() == 0) @@ -283,11 +240,11 @@ void LLFloaterDayCycle::onRunAnimSky(void* userData) } LLMultiSliderCtrl* sldr; - sldr = sDayCycle->getChild("WLDayCycleKeys"); + sldr = getChild("WLDayCycleKeys"); llassert_always(sSliderToKey.size() == sldr->getValue().size()); LLMultiSliderCtrl* tSldr; - tSldr = sDayCycle->getChild("WLTimeSlider"); + tSldr = getChild("WLTimeSlider"); // turn off linden time LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; @@ -299,7 +256,7 @@ void LLFloaterDayCycle::onRunAnimSky(void* userData) llassert_always(LLWLParamManager::instance()->mAnimator.mTimeTrack.size() == sldr->getValue().size()); } -void LLFloaterDayCycle::onStopAnimSky(void* userData) +void LLFloaterDayCycle::onStopAnimSky(LLUICtrl* ctrl) { // if no keys, do nothing if(sSliderToKey.size() == 0) { @@ -311,17 +268,16 @@ void LLFloaterDayCycle::onStopAnimSky(void* userData) LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; } -void LLFloaterDayCycle::onUseLindenTime(void* userData) +void LLFloaterDayCycle::onUseLindenTime(LLUICtrl* ctrl) { - LLFloaterWindLight* wl = LLFloaterWindLight::instance(); - LLComboBox* box = wl->getChild("WLPresetsCombo"); + LLComboBox* box = getChild("WLPresetsCombo"); box->selectByValue(""); LLWLParamManager::instance()->mAnimator.mIsRunning = true; LLWLParamManager::instance()->mAnimator.mUseLindenTime = true; } -void LLFloaterDayCycle::onLoadDayCycle(void* userData) +void LLFloaterDayCycle::onLoadDayCycle(LLUICtrl* ctrl) { LLWLParamManager::instance()->mDay.loadDayCycle("Default.xml"); @@ -331,7 +287,7 @@ void LLFloaterDayCycle::onLoadDayCycle(void* userData) // set the param manager's track to the new one LLMultiSliderCtrl* tSldr; - tSldr = sDayCycle->getChild( + tSldr = getChild( "WLTimeSlider"); LLWLParamManager::instance()->resetAnimator( tSldr->getCurSliderValue() / sHoursPerDay, false); @@ -341,15 +297,15 @@ void LLFloaterDayCycle::onLoadDayCycle(void* userData) LLWLParamManager::instance()->mCurParams); } -void LLFloaterDayCycle::onSaveDayCycle(void* userData) +void LLFloaterDayCycle::onSaveDayCycle(LLUICtrl* ctrl) { LLWLParamManager::instance()->mDay.saveDayCycle("Default.xml"); } -void LLFloaterDayCycle::onTimeSliderMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterDayCycle::onTimeSliderMoved(LLUICtrl* ctrl) { - LLMultiSliderCtrl* sldr = sDayCycle->getChild( + LLMultiSliderCtrl* sldr = getChild( "WLTimeSlider"); /// get the slider value @@ -365,12 +321,12 @@ void LLFloaterDayCycle::onTimeSliderMoved(LLUICtrl* ctrl, void* userData) LLWLParamManager::instance()->mCurParams); } -void LLFloaterDayCycle::onKeyTimeMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterDayCycle::onKeyTimeMoved(LLUICtrl* ctrl) { - LLComboBox* comboBox = sDayCycle->getChild("WLKeyPresets"); - LLMultiSliderCtrl* sldr = sDayCycle->getChild("WLDayCycleKeys"); - LLSpinCtrl* hourSpin = sDayCycle->getChild("WLCurKeyHour"); - LLSpinCtrl* minSpin = sDayCycle->getChild("WLCurKeyMin"); + LLComboBox* comboBox = getChild("WLKeyPresets"); + LLMultiSliderCtrl* sldr = getChild("WLDayCycleKeys"); + LLSpinCtrl* hourSpin = getChild("WLCurKeyHour"); + LLSpinCtrl* minSpin = getChild("WLCurKeyMin"); if(sldr->getValue().size() == 0) { return; @@ -408,18 +364,18 @@ void LLFloaterDayCycle::onKeyTimeMoved(LLUICtrl* ctrl, void* userData) } -void LLFloaterDayCycle::onKeyTimeChanged(LLUICtrl* ctrl, void* userData) +void LLFloaterDayCycle::onKeyTimeChanged(LLUICtrl* ctrl) { // if no keys, skipped if(sSliderToKey.size() == 0) { return; } - LLMultiSliderCtrl* sldr = sDayCycle->getChild( + LLMultiSliderCtrl* sldr = getChild( "WLDayCycleKeys"); - LLSpinCtrl* hourSpin = sDayCycle->getChild( + LLSpinCtrl* hourSpin = getChild( "WLCurKeyHour"); - LLSpinCtrl* minSpin = sDayCycle->getChild( + LLSpinCtrl* minSpin = getChild( "WLCurKeyMin"); F32 hour = hourSpin->get(); @@ -437,12 +393,12 @@ void LLFloaterDayCycle::onKeyTimeChanged(LLUICtrl* ctrl, void* userData) syncTrack(); } -void LLFloaterDayCycle::onKeyPresetChanged(LLUICtrl* ctrl, void* userData) +void LLFloaterDayCycle::onKeyPresetChanged(LLUICtrl* ctrl) { // get the time - LLComboBox* comboBox = sDayCycle->getChild( + LLComboBox* comboBox = getChild( "WLKeyPresets"); - LLMultiSliderCtrl* sldr = sDayCycle->getChild( + LLMultiSliderCtrl* sldr = getChild( "WLDayCycleKeys"); // do nothing if no sliders @@ -464,16 +420,16 @@ void LLFloaterDayCycle::onKeyPresetChanged(LLUICtrl* ctrl, void* userData) syncTrack(); } -void LLFloaterDayCycle::onTimeRateChanged(LLUICtrl* ctrl, void* userData) +void LLFloaterDayCycle::onTimeRateChanged(LLUICtrl* ctrl) { // get the time - LLSpinCtrl* secSpin = sDayCycle->getChild( + LLSpinCtrl* secSpin = getChild( "WLLengthOfDaySec"); - LLSpinCtrl* minSpin = sDayCycle->getChild( + LLSpinCtrl* minSpin = getChild( "WLLengthOfDayMin"); - LLSpinCtrl* hourSpin = sDayCycle->getChild( + LLSpinCtrl* hourSpin = getChild( "WLLengthOfDayHour"); F32 hour; @@ -492,13 +448,13 @@ void LLFloaterDayCycle::onTimeRateChanged(LLUICtrl* ctrl, void* userData) syncTrack(); } -void LLFloaterDayCycle::onAddKey(void* userData) +void LLFloaterDayCycle::onAddKey(LLUICtrl* ctrl) { - LLComboBox* comboBox = sDayCycle->getChild( + LLComboBox* comboBox = getChild( "WLKeyPresets"); - LLMultiSliderCtrl* kSldr = sDayCycle->getChild( + LLMultiSliderCtrl* kSldr = getChild( "WLDayCycleKeys"); - LLMultiSliderCtrl* tSldr = sDayCycle->getChild( + LLMultiSliderCtrl* tSldr = getChild( "WLTimeSlider"); llassert_always(sSliderToKey.size() == kSldr->getValue().size()); @@ -514,7 +470,7 @@ void LLFloaterDayCycle::onAddKey(void* userData) void LLFloaterDayCycle::addSliderKey(F32 time, const std::string & presetName) { - LLMultiSliderCtrl* kSldr = sDayCycle->getChild( + LLMultiSliderCtrl* kSldr = getChild( "WLDayCycleKeys"); // make a slider @@ -539,7 +495,7 @@ void LLFloaterDayCycle::addSliderKey(F32 time, const std::string & presetName) void LLFloaterDayCycle::deletePreset(std::string& presetName) { - LLMultiSliderCtrl* sldr = sDayCycle->getChild("WLDayCycleKeys"); + LLMultiSliderCtrl* sldr = getChild("WLDayCycleKeys"); /// delete any reference std::map::iterator curr_preset, next_preset; @@ -555,15 +511,15 @@ void LLFloaterDayCycle::deletePreset(std::string& presetName) } } -void LLFloaterDayCycle::onDeleteKey(void* userData) +void LLFloaterDayCycle::onDeleteKey(LLUICtrl* ctrl) { if(sSliderToKey.size() == 0) { return; } - LLComboBox* comboBox = sDayCycle->getChild( + LLComboBox* comboBox = getChild( "WLKeyPresets"); - LLMultiSliderCtrl* sldr = sDayCycle->getChild("WLDayCycleKeys"); + LLMultiSliderCtrl* sldr = getChild("WLDayCycleKeys"); // delete from map const std::string& sldrName = sldr->getCurSlider(); @@ -580,8 +536,8 @@ void LLFloaterDayCycle::onDeleteKey(void* userData) comboBox->selectByValue(sSliderToKey[name].presetName); F32 time = sSliderToKey[name].time; - LLSpinCtrl* hourSpin = sDayCycle->getChild("WLCurKeyHour"); - LLSpinCtrl* minSpin = sDayCycle->getChild("WLCurKeyMin"); + LLSpinCtrl* hourSpin = getChild("WLCurKeyHour"); + LLSpinCtrl* minSpin = getChild("WLCurKeyMin"); // now set the spinners F32 hour = (F32)((S32)time); diff --git a/indra/newview/llfloaterdaycycle.h b/indra/newview/llfloaterdaycycle.h index a03a7f749a..43c347d4f2 100644 --- a/indra/newview/llfloaterdaycycle.h +++ b/indra/newview/llfloaterdaycycle.h @@ -56,87 +56,69 @@ class LLFloaterDayCycle : public LLFloater { public: - LLFloaterDayCycle(); + LLFloaterDayCycle(const LLSD& key); virtual ~LLFloaterDayCycle(); /*virtual*/ BOOL postBuild(); /// help button stuff - static void onClickHelp(void* data); + void onClickHelp(std::string xml_alert); void initHelpBtn(const std::string& name, const std::string& xml_alert); /// initialize all void initCallbacks(void); - /// one and one instance only - static LLFloaterDayCycle* instance(); - /// on time slider moved - static void onTimeSliderMoved(LLUICtrl* ctrl, void* userData); + void onTimeSliderMoved(LLUICtrl* ctrl); /// what happens when you move the key frame - static void onKeyTimeMoved(LLUICtrl* ctrl, void* userData); + void onKeyTimeMoved(LLUICtrl* ctrl); /// what happens when you change the key frame's time - static void onKeyTimeChanged(LLUICtrl* ctrl, void* userData); + void onKeyTimeChanged(LLUICtrl* ctrl); /// if you change the combo box, change the frame - static void onKeyPresetChanged(LLUICtrl* ctrl, void* userData); + void onKeyPresetChanged(LLUICtrl* ctrl); /// run this when user says to run the sky animation - static void onRunAnimSky(void* userData); + void onRunAnimSky(LLUICtrl* ctrl); /// run this when user says to stop the sky animation - static void onStopAnimSky(void* userData); + void onStopAnimSky(LLUICtrl* ctrl); /// if you change the combo box, change the frame - static void onTimeRateChanged(LLUICtrl* ctrl, void* userData); + void onTimeRateChanged(LLUICtrl* ctrl); /// add a new key on slider - static void onAddKey(void* userData); + void onAddKey(LLUICtrl* ctrl); /// delete any and all reference to a preset void deletePreset(std::string& presetName); /// delete a key frame - static void onDeleteKey(void* userData); + void onDeleteKey(LLUICtrl* ctrl); /// button to load day - static void onLoadDayCycle(void* userData); + void onLoadDayCycle(LLUICtrl* ctrl); /// button to save day - static void onSaveDayCycle(void* userData); + void onSaveDayCycle(LLUICtrl* ctrl); /// toggle for Linden time - static void onUseLindenTime(void* userData); - - - //// menu management - - /// show off our menu - static void show(); - - /// return if the menu exists or not - static bool isOpen(); - - /// stuff to do on exit - virtual void onClose(bool app_quitting); + void onUseLindenTime(LLUICtrl* ctrl); /// sync up sliders with day cycle structure - static void syncMenu(); + void syncMenu(); // makes sure key slider has what's in day cycle - static void syncSliderTrack(); + void syncSliderTrack(); /// makes sure day cycle data structure has what's in menu - static void syncTrack(); + void syncTrack(); /// add a slider to the track - static void addSliderKey(F32 time, const std::string& presetName); + void addSliderKey(F32 time, const std::string& presetName); private: - // one instance on the inside - static LLFloaterDayCycle* sDayCycle; - // map of sliders to parameters static std::map sSliderToKey; diff --git a/indra/newview/llfloaterenvsettings.cpp b/indra/newview/llfloaterenvsettings.cpp index cfdf49373e..a520df36de 100644 --- a/indra/newview/llfloaterenvsettings.cpp +++ b/indra/newview/llfloaterenvsettings.cpp @@ -34,6 +34,7 @@ #include "llfloaterenvsettings.h" +#include "llfloaterreg.h" #include "llfloaterwindlight.h" #include "llfloaterwater.h" #include "lluictrlfactory.h" @@ -52,12 +53,10 @@ #include -LLFloaterEnvSettings* LLFloaterEnvSettings::sEnvSettings = NULL; - -LLFloaterEnvSettings::LLFloaterEnvSettings() - : LLFloater() +LLFloaterEnvSettings::LLFloaterEnvSettings(const LLSD& key) + : LLFloater(key) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_env_settings.xml"); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_env_settings.xml"); } // virtual LLFloaterEnvSettings::~LLFloaterEnvSettings() @@ -68,31 +67,29 @@ BOOL LLFloaterEnvSettings::postBuild() { // load it up initCallbacks(); + syncMenu(); return TRUE; } -void LLFloaterEnvSettings::onClickHelp(void* data) +void LLFloaterEnvSettings::onClickHelp() { - LLFloaterEnvSettings* self = (LLFloaterEnvSettings*)data; - LLNotifications::instance().add(self->contextualNotification("EnvSettingsHelpButton")); + LLNotifications::instance().add(contextualNotification("EnvSettingsHelpButton")); } void LLFloaterEnvSettings::initCallbacks(void) { // our three sliders - childSetCommitCallback("EnvTimeSlider", onChangeDayTime, NULL); - childSetCommitCallback("EnvCloudSlider", onChangeCloudCoverage, NULL); - childSetCommitCallback("EnvWaterFogSlider", onChangeWaterFogDensity, - &LLWaterParamManager::instance()->mFogDensity); + getChild("EnvTimeSlider")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeDayTime, this, _1)); + getChild("EnvCloudSlider")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeCloudCoverage, this, _1)); + getChild("EnvWaterFogSlider")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeWaterFogDensity, this, _1, &LLWaterParamManager::instance()->mFogDensity)); // color picker - childSetCommitCallback("EnvWaterColor", onChangeWaterColor, - &LLWaterParamManager::instance()->mFogColor); + getChild("EnvWaterColor")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeWaterColor, this, _1, &LLWaterParamManager::instance()->mFogColor)); // WL Top - childSetAction("EnvAdvancedSkyButton", onOpenAdvancedSky, NULL); - childSetAction("EnvAdvancedWaterButton", onOpenAdvancedWater, NULL); - childSetAction("EnvUseEstateTimeButton", onUseEstateTime, NULL); - childSetAction("EnvSettingsHelpButton", onClickHelp, this); + getChild("EnvAdvancedSkyButton")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onOpenAdvancedSky, this)); + getChild("EnvAdvancedWaterButton")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onOpenAdvancedWater, this)); + getChild("EnvUseEstateTimeButton")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onUseEstateTime, this)); + getChild("EnvSettingsHelpButton")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onClickHelp, this)); } @@ -101,14 +98,14 @@ void LLFloaterEnvSettings::initCallbacks(void) void LLFloaterEnvSettings::syncMenu() { LLSliderCtrl* sldr; - sldr = sEnvSettings->getChild("EnvTimeSlider"); + sldr = getChild("EnvTimeSlider"); // sync the clock F32 val = (F32)LLWLParamManager::instance()->mAnimator.getDayTime(); std::string timeStr = timeToString(val); LLTextBox* textBox; - textBox = sEnvSettings->getChild("EnvTimeText"); + textBox = getChild("EnvTimeText"); textBox->setValue(timeStr); @@ -127,7 +124,7 @@ void LLFloaterEnvSettings::syncMenu() LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); // sync water params LLColor4 col = param_mgr->getFogColor(); - LLColorSwatchCtrl* colCtrl = sEnvSettings->getChild("EnvWaterColor"); + LLColorSwatchCtrl* colCtrl = getChild("EnvWaterColor"); col.mV[3] = 1.0f; colCtrl->set(col); @@ -171,53 +168,9 @@ void LLFloaterEnvSettings::syncMenu() } } - -// static instance of it -LLFloaterEnvSettings* LLFloaterEnvSettings::instance() +void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl) { - if (!sEnvSettings) - { - sEnvSettings = new LLFloaterEnvSettings(); - sEnvSettings->openFloater(); - sEnvSettings->setFocus(TRUE); - } - return sEnvSettings; -} -void LLFloaterEnvSettings::show() -{ - LLFloaterEnvSettings* envSettings = instance(); - envSettings->syncMenu(); - - // comment in if you want the menu to rebuild each time - //LLUICtrlFactory::getInstance()->buildFloater(envSettings, "floater_env_settings.xml"); - //envSettings->initCallbacks(); - - envSettings->openFloater(); -} - -bool LLFloaterEnvSettings::isOpen() -{ - if (sEnvSettings != NULL) - { - return true; - } - return false; -} - -// virtual -void LLFloaterEnvSettings::onClose(bool app_quitting) -{ - if (sEnvSettings) - { - sEnvSettings->setVisible(FALSE); - } -} - - -void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl, void* userData) -{ - LLSliderCtrl* sldr; - sldr = sEnvSettings->getChild("EnvTimeSlider"); + LLSliderCtrl* sldr = static_cast(ctrl); // deactivate animator LLWLParamManager::instance()->mAnimator.mIsRunning = false; @@ -234,10 +187,9 @@ void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl, void* userData) LLWLParamManager::instance()->mCurParams); } -void LLFloaterEnvSettings::onChangeCloudCoverage(LLUICtrl* ctrl, void* userData) +void LLFloaterEnvSettings::onChangeCloudCoverage(LLUICtrl* ctrl) { - LLSliderCtrl* sldr; - sldr = sEnvSettings->getChild("EnvCloudSlider"); + LLSliderCtrl* sldr = static_cast(ctrl); // deactivate animator //LLWLParamManager::instance()->mAnimator.mIsRunning = false; @@ -247,17 +199,10 @@ void LLFloaterEnvSettings::onChangeCloudCoverage(LLUICtrl* ctrl, void* userData) LLWLParamManager::instance()->mCurParams.set("cloud_shadow", val); } -void LLFloaterEnvSettings::onChangeWaterFogDensity(LLUICtrl* ctrl, void* userData) +void LLFloaterEnvSettings::onChangeWaterFogDensity(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl) { LLSliderCtrl* sldr; - sldr = sEnvSettings->getChild("EnvWaterFogSlider"); - - if(NULL == userData) - { - return; - } - - WaterExpFloatControl * expFloatControl = static_cast(userData); + sldr = getChild("EnvWaterFogSlider"); F32 val = sldr->getValueF32(); expFloatControl->mExp = val; @@ -267,10 +212,9 @@ void LLFloaterEnvSettings::onChangeWaterFogDensity(LLUICtrl* ctrl, void* userDat LLWaterParamManager::instance()->propagateParameters(); } -void LLFloaterEnvSettings::onChangeWaterColor(LLUICtrl* ctrl, void* userData) +void LLFloaterEnvSettings::onChangeWaterColor(LLUICtrl* ctrl, WaterColorControl* colorControl) { LLColorSwatchCtrl* swatch = static_cast(ctrl); - WaterColorControl * colorControl = static_cast(userData); *colorControl = swatch->get(); colorControl->update(LLWaterParamManager::instance()->mCurParams); @@ -278,23 +222,22 @@ void LLFloaterEnvSettings::onChangeWaterColor(LLUICtrl* ctrl, void* userData) } -void LLFloaterEnvSettings::onOpenAdvancedSky(void* userData) +void LLFloaterEnvSettings::onOpenAdvancedSky() { - LLFloaterWindLight::show(); + LLFloaterReg::showInstance("env_windlight"); } -void LLFloaterEnvSettings::onOpenAdvancedWater(void* userData) +void LLFloaterEnvSettings::onOpenAdvancedWater() { - LLFloaterWater::show(); + LLFloaterReg::showInstance("env_water"); } -void LLFloaterEnvSettings::onUseEstateTime(void* userData) +void LLFloaterEnvSettings::onUseEstateTime() { - if(LLFloaterWindLight::isOpen()) + LLFloaterWindLight* wl = LLFloaterReg::findTypedInstance("env_windlight"); + if(wl) { - // select the blank value in - LLFloaterWindLight* wl = LLFloaterWindLight::instance(); LLComboBox* box = wl->getChild("WLPresetsCombo"); box->selectByValue(""); } diff --git a/indra/newview/llfloaterenvsettings.h b/indra/newview/llfloaterenvsettings.h index 725fb9ed45..083e3636d1 100644 --- a/indra/newview/llfloaterenvsettings.h +++ b/indra/newview/llfloaterenvsettings.h @@ -39,59 +39,46 @@ #include "llfloater.h" +struct WaterColorControl; +struct WaterExpFloatControl; /// Menuing system for all of windlight's functionality class LLFloaterEnvSettings : public LLFloater { public: - LLFloaterEnvSettings(); + LLFloaterEnvSettings(const LLSD& key); /*virtual*/ ~LLFloaterEnvSettings(); /*virtual*/ BOOL postBuild(); /// initialize all the callbacks for the menu void initCallbacks(void); - /// one and one instance only - static LLFloaterEnvSettings* instance(); - /// callback for the menus help button - static void onClickHelp(void* data); + void onClickHelp(); /// handle if time of day is changed - static void onChangeDayTime(LLUICtrl* ctrl, void* userData); + void onChangeDayTime(LLUICtrl* ctrl); /// handle if cloud coverage is changed - static void onChangeCloudCoverage(LLUICtrl* ctrl, void* userData); + void onChangeCloudCoverage(LLUICtrl* ctrl); /// handle change in water fog density - static void onChangeWaterFogDensity(LLUICtrl* ctrl, void* userData); - - /// handle change in under water fog density - static void onChangeUnderWaterFogMod(LLUICtrl* ctrl, void* userData); + void onChangeWaterFogDensity(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl); /// handle change in water fog color - static void onChangeWaterColor(LLUICtrl* ctrl, void* userData); + void onChangeWaterColor(LLUICtrl* ctrl, WaterColorControl* colorControl); /// open the advanced sky settings menu - static void onOpenAdvancedSky(void* userData); + void onOpenAdvancedSky(); /// open the advanced water settings menu - static void onOpenAdvancedWater(void* userData); + void onOpenAdvancedWater(); /// sync time with the server - static void onUseEstateTime(void* userData); + void onUseEstateTime(); //// menu management - /// show off our menu - static void show(); - - /// return if the menu exists or not - static bool isOpen(); - - /// stuff to do on exit - virtual void onClose(bool app_quitting); - /// sync up sliders with parameters void syncMenu(); @@ -99,8 +86,6 @@ public: std::string timeToString(F32 curTime); private: - // one instance on the inside - static LLFloaterEnvSettings* sEnvSettings; }; diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp deleted file mode 100644 index 6f84807564..0000000000 --- a/indra/newview/llfloaterevent.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file llfloaterevent.cpp - * @brief Event information as shown in a floating window from - * secondlife:// command handler. - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfloaterevent.h" - -// viewer project includes -#include "llcommandhandler.h" -#include "llpanelevent.h" - -// linden library includes -#include "lluuid.h" -#include "lluictrlfactory.h" - -//////////////////////////////////////////////////////////////////////////// -// LLFloaterEventInfo - -//----------------------------------------------------------------------------- -// Globals -//----------------------------------------------------------------------------- - -LLMap< U32, LLFloaterEventInfo* > gEventInfoInstances; - -class LLEventHandler : public LLCommandHandler -{ -public: - // requires trusted browser to trigger - LLEventHandler() : LLCommandHandler("event", true) { } - bool handle(const LLSD& tokens, const LLSD& query_map, - LLWebBrowserCtrl* web) - { - if (tokens.size() < 2) - { - return false; - } - U32 event_id = tokens[0].asInteger(); - if (tokens[1].asString() == "about") - { - LLFloaterEventInfo::show(event_id); - return true; - } - return false; - } -}; -LLEventHandler gEventHandler; - -LLFloaterEventInfo::LLFloaterEventInfo(const U32 event_id) -: LLFloater(), - mEventID( event_id ) -{ - - mFactoryMap["event_details_panel"] = LLCallbackMap(LLFloaterEventInfo::createEventDetail, this); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_event.xml"); - gEventInfoInstances.addData(event_id, this); -} - -LLFloaterEventInfo::~LLFloaterEventInfo() -{ - // child views automatically deleted - gEventInfoInstances.removeData(mEventID); -} - -void LLFloaterEventInfo::displayEventInfo(const U32 event_id) -{ - mPanelEventp->setEventID(event_id); - this->setFrontmost(true); -} - -// static -void* LLFloaterEventInfo::createEventDetail(void* userdata) -{ - LLFloaterEventInfo *self = (LLFloaterEventInfo*)userdata; - self->mPanelEventp = new LLPanelEvent(); - LLUICtrlFactory::getInstance()->buildPanel(self->mPanelEventp, "panel_event.xml"); - - return self->mPanelEventp; -} - -// static -LLFloaterEventInfo* LLFloaterEventInfo::show(const U32 event_id) -{ - LLFloaterEventInfo *floater; - if (gEventInfoInstances.checkData(event_id)) - { - // ...bring that window to front - floater = gEventInfoInstances.getData(event_id); - floater->openFloater(); - floater->setFrontmost(true); - } - else - { - floater = new LLFloaterEventInfo( event_id ); - floater->center(); - floater->openFloater(); - floater->displayEventInfo(event_id); - floater->setFrontmost(true); - } - - return floater; -} diff --git a/indra/newview/llfloaterfonttest.cpp b/indra/newview/llfloaterfonttest.cpp index 02791b711e..413992910e 100644 --- a/indra/newview/llfloaterfonttest.cpp +++ b/indra/newview/llfloaterfonttest.cpp @@ -42,25 +42,11 @@ #include "lluictrlfactory.h" -LLFloaterFontTest* LLFloaterFontTest::sInstance = NULL; - -LLFloaterFontTest::LLFloaterFontTest() +LLFloaterFontTest::LLFloaterFontTest(const LLSD& key) : LLFloater("floater_font_test") { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_font_test.xml"); } LLFloaterFontTest::~LLFloaterFontTest() { - sInstance = NULL; -} - -// static -void LLFloaterFontTest::show(void *unused) -{ - if (!sInstance) - sInstance = new LLFloaterFontTest(); - - sInstance->openFloater(); - sInstance->setFocus(TRUE); } diff --git a/indra/newview/llfloaterfonttest.h b/indra/newview/llfloaterfonttest.h index eb2d410387..4406a9f36a 100644 --- a/indra/newview/llfloaterfonttest.h +++ b/indra/newview/llfloaterfonttest.h @@ -39,14 +39,10 @@ class LLFloaterFontTest: public LLFloater { -public: - static void show(void* unused); - + friend class LLFloaterReg; private: - LLFloaterFontTest(); + LLFloaterFontTest(const LLSD& key); ~LLFloaterFontTest(); - - static LLFloaterFontTest* sInstance; }; #endif diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index 1e8129c7d3..1e8e7bad74 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -46,7 +46,7 @@ #include "llfloateravatarpicker.h" #include "llviewerwindow.h" #include "llbutton.h" -#include "llfriendactions.h" +#include "llavataractions.h" #include "llinventorymodel.h" #include "llnamelistctrl.h" #include "llnotify.h" @@ -62,7 +62,7 @@ #include "lltextbox.h" #include "llvoiceclient.h" -// *TODO: Move more common stuff to LLFriendActions? +// *TODO: Move more common stuff to LLAvatarActions? //Maximum number of people you can select to do an operation on at once. #define MAX_FRIEND_SELECT 20 @@ -546,7 +546,7 @@ void LLPanelFriends::onClickProfile(void* user_data) if(ids.size() > 0) { LLUUID agent_id = ids[0]; - LLFriendActions::showProfile(agent_id); + LLAvatarActions::showProfile(agent_id); } } @@ -560,11 +560,11 @@ void LLPanelFriends::onClickIM(void* user_data) { if(ids.size() == 1) { - LLFriendActions::startIM(ids[0]); + LLAvatarActions::startIM(ids[0]); } else { - LLFriendActions::startConference(ids); + LLAvatarActions::startConference(ids); } } } @@ -576,7 +576,7 @@ void LLPanelFriends::onPickAvatar(const std::vector& names, { if (names.empty()) return; if (ids.empty()) return; - LLFriendActions::requestFriendshipDialog(ids[0], names[0]); + LLAvatarActions::requestFriendshipDialog(ids[0], names[0]); } // static @@ -595,14 +595,14 @@ void LLPanelFriends::onClickAddFriend(void* user_data) void LLPanelFriends::onClickRemove(void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; - LLFriendActions::removeFriendsDialog(panelp->getSelectedIDs()); + LLAvatarActions::removeFriendsDialog(panelp->getSelectedIDs()); } // static void LLPanelFriends::onClickOfferTeleport(void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; - LLFriendActions::offerTeleport(panelp->getSelectedIDs()); + LLAvatarActions::offerTeleport(panelp->getSelectedIDs()); } // static diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index c3448d52c9..431bc09d86 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -44,7 +44,7 @@ #include "llcombobox.h" #include "llgesturemgr.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyboard.h" #include "lllineeditor.h" #include "llpreviewgesture.h" @@ -56,15 +56,11 @@ #include "lltrans.h" #include "lluictrlfactory.h" #include "llviewergesture.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerinventory.h" #include "llvoavatar.h" #include "llviewercontrol.h" -// static -LLFloaterGesture* LLFloaterGesture::sInstance = NULL; -LLFloaterGestureObserver* LLFloaterGesture::sObserver = NULL; - BOOL item_name_precedes( LLInventoryItem* a, LLInventoryItem* b ) { return LLStringUtil::precedesDict( a->getName(), b->getName() ); @@ -73,29 +69,31 @@ BOOL item_name_precedes( LLInventoryItem* a, LLInventoryItem* b ) class LLFloaterGestureObserver : public LLGestureManagerObserver { public: - LLFloaterGestureObserver() {} + LLFloaterGestureObserver(LLFloaterGesture* floater) : mFloater(floater) {} virtual ~LLFloaterGestureObserver() {} - virtual void changed() { LLFloaterGesture::refreshAll(); } + virtual void changed() { mFloater->refreshAll(); } + +private: + LLFloaterGesture* mFloater; }; //--------------------------------------------------------------------------- // LLFloaterGesture //--------------------------------------------------------------------------- -LLFloaterGesture::LLFloaterGesture() -: LLFloater() +LLFloaterGesture::LLFloaterGesture(const LLSD& key) + : LLFloater(key) { - sObserver = new LLFloaterGestureObserver; - gGestureManager.addObserver(sObserver); + mObserver = new LLFloaterGestureObserver(this); + LLGestureManager::instance().addObserver(mObserver); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_gesture.xml"); } // virtual LLFloaterGesture::~LLFloaterGesture() { - gGestureManager.removeObserver(sObserver); - delete sObserver; - sObserver = NULL; - - sInstance = NULL; + LLGestureManager::instance().removeObserver(mObserver); + delete mObserver; + mObserver = NULL; } // virtual @@ -107,45 +105,27 @@ BOOL LLFloaterGesture::postBuild() setTitle(label); - childSetCommitCallback("gesture_list", onCommitList, this); - getChild("gesture_list")->setDoubleClickCallback(onClickPlay, this); + getChild("gesture_list")->setCommitCallback(boost::bind(&LLFloaterGesture::onCommitList, this)); + getChild("gesture_list")->setDoubleClickCallback(boost::bind(&LLFloaterGesture::onClickPlay, this)); - childSetAction("inventory_btn", onClickInventory, this); + getChild("inventory_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickInventory, this)); - childSetAction("edit_btn", onClickEdit, this); + getChild("edit_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickEdit, this)); - childSetAction("play_btn", onClickPlay, this); - childSetAction("stop_btn", onClickPlay, this); + getChild("play_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickPlay, this)); + getChild("stop_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickPlay, this)); - childSetAction("new_gesture_btn", onClickNew, this); + getChild("new_gesture_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickNew, this)); childSetVisible("play_btn", true); childSetVisible("stop_btn", false); setDefaultBtn("play_btn"); + + buildGestureList(); + + childSetFocus("gesture_list"); - return TRUE; -} - - -// static -void LLFloaterGesture::show() -{ - if (sInstance) - { - sInstance->openFloater(); - return; - } - - sInstance = new LLFloaterGesture(); - - // Builds and adds to gFloaterView - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_gesture.xml"); - - sInstance->buildGestureList(); - - sInstance->childSetFocus("gesture_list"); - - LLCtrlListInterface *list = sInstance->childGetListInterface("gesture_list"); + LLCtrlListInterface *list = childGetListInterface("gesture_list"); if (list) { const BOOL ascending = TRUE; @@ -153,51 +133,34 @@ void LLFloaterGesture::show() list->selectFirstItem(); } - sInstance->mSelectedID = LLUUID::null; - // Update button labels - onCommitList(NULL, sInstance); - sInstance->openFloater(); + onCommitList(); + + return TRUE; } -// static -void LLFloaterGesture::toggleVisibility() + +void LLFloaterGesture::refreshAll() { - if(sInstance && sInstance->getVisible()) + buildGestureList(); + + LLCtrlListInterface *list = childGetListInterface("gesture_list"); + if (!list) return; + + if (mSelectedID.isNull()) { - sInstance->closeFloater(); + list->selectFirstItem(); } else { - show(); - } -} - -// static -void LLFloaterGesture::refreshAll() -{ - if (sInstance) - { - sInstance->buildGestureList(); - - LLCtrlListInterface *list = sInstance->childGetListInterface("gesture_list"); - if (!list) return; - - if (sInstance->mSelectedID.isNull()) + if (! list->setCurrentByID(mSelectedID)) { list->selectFirstItem(); } - else - { - if (! list->setCurrentByID(sInstance->mSelectedID)) - { - list->selectFirstItem(); - } - } - - // Update button labels - onCommitList(NULL, sInstance); } + + // Update button labels + onCommitList(); } void LLFloaterGesture::buildGestureList() @@ -214,7 +177,7 @@ void LLFloaterGesture::buildGestureList() list->operateOnAll(LLCtrlListInterface::OP_DELETE); LLGestureManager::item_map_t::iterator it; - for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it) + for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it) { const LLUUID& item_id = (*it).first; LLMultiGesture* gesture = (*it).second; @@ -313,36 +276,30 @@ void LLFloaterGesture::buildGestureList() scroll->setScrollPos(current_scroll_pos); } -// static -void LLFloaterGesture::onClickInventory(void* data) +void LLFloaterGesture::onClickInventory() { - LLFloaterGesture* self = (LLFloaterGesture*)data; - - LLCtrlListInterface *list = self->childGetListInterface("gesture_list"); + LLCtrlListInterface *list = childGetListInterface("gesture_list"); if (!list) return; const LLUUID& item_id = list->getCurrentID(); - LLInventoryView* inv = LLInventoryView::showAgentInventory(); + LLFloaterInventory* inv = LLFloaterInventory::showAgentInventory(); if (!inv) return; inv->getPanel()->setSelection(item_id, TRUE); } -// static -void LLFloaterGesture::onClickPlay(void* data) +void LLFloaterGesture::onClickPlay() { - LLFloaterGesture* self = (LLFloaterGesture*)data; - - LLCtrlListInterface *list = self->childGetListInterface("gesture_list"); + LLCtrlListInterface *list = childGetListInterface("gesture_list"); if (!list) return; const LLUUID& item_id = list->getCurrentID(); - if (gGestureManager.isGesturePlaying(item_id)) + if (LLGestureManager::instance().isGesturePlaying(item_id)) { - gGestureManager.stopGesture(item_id); + LLGestureManager::instance().stopGesture(item_id); } else { - gGestureManager.playGesture(item_id); + LLGestureManager::instance().playGesture(item_id); } } @@ -355,8 +312,7 @@ public: } }; -// static -void LLFloaterGesture::onClickNew(void* data) +void LLFloaterGesture::onClickNew() { LLPointer cb = new GestureShowCallback(); create_inventory_item(gAgent.getID(), gAgent.getSessionID(), @@ -365,12 +321,9 @@ void LLFloaterGesture::onClickNew(void* data) } -// static -void LLFloaterGesture::onClickEdit(void* data) +void LLFloaterGesture::onClickEdit() { - LLFloaterGesture* self = (LLFloaterGesture*)data; - - LLCtrlListInterface *list = self->childGetListInterface("gesture_list"); + LLCtrlListInterface *list = childGetListInterface("gesture_list"); if (!list) return; const LLUUID& item_id = list->getCurrentID(); @@ -380,26 +333,23 @@ void LLFloaterGesture::onClickEdit(void* data) LLPreviewGesture* previewp = LLPreviewGesture::show(item_id, LLUUID::null); if (!previewp->getHost()) { - previewp->setRect(gFloaterView->findNeighboringPosition(self, previewp)); + previewp->setRect(gFloaterView->findNeighboringPosition(this, previewp)); } } -// static -void LLFloaterGesture::onCommitList(LLUICtrl* ctrl, void* data) +void LLFloaterGesture::onCommitList() { - LLFloaterGesture* self = (LLFloaterGesture*)data; + const LLUUID& item_id = childGetValue("gesture_list").asUUID(); - const LLUUID& item_id = self->childGetValue("gesture_list").asUUID(); - - self->mSelectedID = item_id; - if (gGestureManager.isGesturePlaying(item_id)) + mSelectedID = item_id; + if (LLGestureManager::instance().isGesturePlaying(item_id)) { - self->childSetVisible("play_btn", false); - self->childSetVisible("stop_btn", true); + childSetVisible("play_btn", false); + childSetVisible("stop_btn", true); } else { - self->childSetVisible("play_btn", true); - self->childSetVisible("stop_btn", false); + childSetVisible("play_btn", true); + childSetVisible("stop_btn", false); } } diff --git a/indra/newview/llfloatergesture.h b/indra/newview/llfloatergesture.h index f7c4e558ac..9c1ab27cb0 100644 --- a/indra/newview/llfloatergesture.h +++ b/indra/newview/llfloatergesture.h @@ -56,32 +56,28 @@ class LLFloaterGesture : public LLFloater { public: - LLFloaterGesture(); + LLFloaterGesture(const LLSD& key); virtual ~LLFloaterGesture(); virtual BOOL postBuild(); - static void show(); - static void toggleVisibility(); - static void refreshAll(); + void refreshAll(); protected: // Reads from the gesture manager's list of active gestures // and puts them in this list. void buildGestureList(); - static void onClickInventory(void* data); - static void onClickEdit(void* data); - static void onClickPlay(void* data); - static void onClickNew(void* data); - static void onCommitList(LLUICtrl* ctrl, void* data); + void onClickInventory(); + void onClickEdit(); + void onClickPlay(); + void onClickNew(); + void onCommitList(); protected: LLUUID mSelectedID; - static LLFloaterGesture* sInstance; - static LLFloaterGestureObserver* sObserver; - static LLFloaterGestureInventoryObserver* sInventoryObserver; + LLFloaterGestureObserver* mObserver; }; diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp index 58cbe02d6d..886f5ec924 100644 --- a/indra/newview/llfloatergodtools.cpp +++ b/indra/newview/llfloatergodtools.cpp @@ -50,6 +50,7 @@ #include "llcombobox.h" #include "lldraghandle.h" #include "llfloater.h" +#include "llfloaterreg.h" #include "llfocusmgr.h" #include "llfloatertopobjects.h" #include "lllineeditor.h" @@ -105,7 +106,7 @@ void LLFloaterGodTools::onOpen(const LLSD& key) // static void LLFloaterGodTools::refreshAll() { - LLFloaterGodTools* god_tools = getInstance(); + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance("god_tools"); if (god_tools) { if (gAgent.getRegionHost() != god_tools->mCurrentHost) @@ -119,7 +120,7 @@ void LLFloaterGodTools::refreshAll() LLFloaterGodTools::LLFloaterGodTools(const LLSD& key) -: LLFloater(), +: LLFloater(key), mCurrentHost(LLHost::invalid), mUpdateTimer() { @@ -127,13 +128,16 @@ LLFloaterGodTools::LLFloaterGodTools(const LLSD& key) mFactoryMap["region"] = LLCallbackMap(createPanelRegion, this); mFactoryMap["objects"] = LLCallbackMap(createPanelObjects, this); mFactoryMap["request"] = LLCallbackMap(createPanelRequest, this); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_god_tools.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_god_tools.xml"); - sendRegionInfoRequest(); - - childShowTab("GodTools Tabs", "region"); } +BOOL LLFloaterGodTools::postBuild() +{ + sendRegionInfoRequest(); + childShowTab("GodTools Tabs", "region"); + return TRUE; +} // static void* LLFloaterGodTools::createPanelGrid(void *userdata) { @@ -166,10 +170,7 @@ LLFloaterGodTools::~LLFloaterGodTools() { // children automatically deleted } -BOOL LLFloaterGodTools::postBuild() -{ - return TRUE; -} + U32 LLFloaterGodTools::computeRegionFlags() const { @@ -184,15 +185,6 @@ void LLFloaterGodTools::updatePopup(LLCoordGL center, MASK mask) { } -// virtual -void LLFloaterGodTools::onClose(bool app_quitting) -{ - if (getInstance()) - { - getInstance()->setVisible(FALSE); - } -} - // virtual void LLFloaterGodTools::draw() { @@ -271,16 +263,19 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) regionp->setWaterHeight(water_height); regionp->setBillableFactor(billable_factor); } + + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance("god_tools"); + if (!god_tools) return; // push values to god tools, if available if ( gAgent.isGodlike() - && instanceVisible() - && getInstance()->mPanelRegionTools - && getInstance()->mPanelObjectTools + && LLFloaterReg::instanceVisible("god_tools") + && god_tools->mPanelRegionTools + && god_tools->mPanelObjectTools && msg ) { - LLPanelRegionTools* rtool = getInstance()->mPanelRegionTools; - getInstance()->mCurrentHost = host; + LLPanelRegionTools* rtool = god_tools->mPanelRegionTools; + god_tools->mCurrentHost = host; // store locally rtool->setSimName(sim_name); @@ -293,7 +288,7 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) rtool->setRedirectGridY(redirect_grid_y); rtool->enableAllWidgets(); - LLPanelObjectTools *otool = getInstance()->mPanelObjectTools; + LLPanelObjectTools *otool = god_tools->mPanelObjectTools; otool->setCheckFlags(region_flags); otool->enableAllWidgets(); @@ -336,14 +331,17 @@ void LLFloaterGodTools::sendRegionInfoRequest() void LLFloaterGodTools::sendGodUpdateRegionInfo() { + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance("god_tools"); + if (!god_tools) return; + LLViewerRegion *regionp = gAgent.getRegion(); if (gAgent.isGodlike() - && getInstance()->mPanelRegionTools + && god_tools->mPanelRegionTools && regionp && gAgent.getRegionHost() == mCurrentHost) { LLMessageSystem *msg = gMessageSystem; - LLPanelRegionTools *rtool = getInstance()->mPanelRegionTools; + LLPanelRegionTools *rtool = god_tools->mPanelRegionTools; msg->newMessage("GodUpdateRegionInfo"); msg->nextBlockFast(_PREHASH_AgentData); @@ -403,58 +401,31 @@ const F32 PRICE_PER_METER_MAX = 100.f; LLPanelRegionTools::LLPanelRegionTools() : LLPanel() { + mCommitCallbackRegistrar.add("RegionTools.ChangeAnything", boost::bind(&LLPanelRegionTools::onChangeAnything, this)); + mCommitCallbackRegistrar.add("RegionTools.ChangePrelude", boost::bind(&LLPanelRegionTools::onChangePrelude, this)); + mCommitCallbackRegistrar.add("RegionTools.BakeTerrain", boost::bind(&LLPanelRegionTools::onBakeTerrain, this)); + mCommitCallbackRegistrar.add("RegionTools.RevertTerrain", boost::bind(&LLPanelRegionTools::onRevertTerrain, this)); + mCommitCallbackRegistrar.add("RegionTools.SwapTerrain", boost::bind(&LLPanelRegionTools::onSwapTerrain, this)); + mCommitCallbackRegistrar.add("RegionTools.Refresh", boost::bind(&LLPanelRegionTools::onRefresh, this)); + mCommitCallbackRegistrar.add("RegionTools.ApplyChanges", boost::bind(&LLPanelRegionTools::onApplyChanges, this)); + mCommitCallbackRegistrar.add("RegionTools.SelectRegion", boost::bind(&LLPanelRegionTools::onSelectRegion, this)); + mCommitCallbackRegistrar.add("RegionTools.SaveState", boost::bind(&LLPanelRegionTools::onSaveState, this)); } BOOL LLPanelRegionTools::postBuild() { - childSetCommitCallback("region name", onChangeAnything, this); getChild("region name")->setKeystrokeCallback(onChangeSimName, this); childSetPrevalidate("region name", &LLLineEditor::prevalidatePrintableNotPipe); - - childSetCommitCallback("check prelude", onChangePrelude, this); - childSetCommitCallback("check fixed sun", onChangeAnything, this); - childSetCommitCallback("check reset home", onChangeAnything, this); - childSetCommitCallback("check visible", onChangeAnything, this); - childSetCommitCallback("check damage", onChangeAnything, this); - childSetCommitCallback("block dwell", onChangeAnything, this); - childSetCommitCallback("block terraform", onChangeAnything, this); - childSetCommitCallback("allow transfer", onChangeAnything, this); - childSetCommitCallback("is sandbox", onChangeAnything, this); - - childSetAction("Bake Terrain", onBakeTerrain, this); - childSetAction("Revert Terrain", onRevertTerrain, this); - childSetAction("Swap Terrain", onSwapTerrain, this); - - childSetCommitCallback("estate", onChangeAnything, this); childSetPrevalidate("estate", &LLLineEditor::prevalidatePositiveS32); - - childSetCommitCallback("parentestate", onChangeAnything, this); childSetPrevalidate("parentestate", &LLLineEditor::prevalidatePositiveS32); childDisable("parentestate"); - - childSetCommitCallback("gridposx", onChangeAnything, this); childSetPrevalidate("gridposx", &LLLineEditor::prevalidatePositiveS32); childDisable("gridposx"); - - childSetCommitCallback("gridposy", onChangeAnything, this); childSetPrevalidate("gridposy", &LLLineEditor::prevalidatePositiveS32); childDisable("gridposy"); - - childSetCommitCallback("redirectx", onChangeAnything, this); + childSetPrevalidate("redirectx", &LLLineEditor::prevalidatePositiveS32); - - childSetCommitCallback("redirecty", onChangeAnything, this); childSetPrevalidate("redirecty", &LLLineEditor::prevalidatePositiveS32); - - childSetCommitCallback("billable factor", onChangeAnything, this); - - childSetCommitCallback("land cost", onChangeAnything, this); - - childSetAction("Refresh", onRefresh, this); - childSetAction("Apply", onApplyChanges, this); - - childSetAction("Select Region", onSelectRegion, this); - childSetAction("Autosave now", onSaveState, this); return TRUE; } @@ -541,8 +512,6 @@ void LLPanelRegionTools::enableAllWidgets() childEnable("Autosave now"); } - -// static void LLPanelRegionTools::onSaveState(void* userdata) { if (gAgent.isGodlike()) @@ -739,28 +708,25 @@ void LLPanelRegionTools::setPricePerMeter(S32 price) childSetValue("land cost", price); } -// static -void LLPanelRegionTools::onChangeAnything(LLUICtrl* ctrl, void* userdata) +void LLPanelRegionTools::onChangeAnything() { - if (userdata && gAgent.isGodlike()) + if (gAgent.isGodlike()) { - LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata; - region_tools->childEnable("Apply"); + childEnable("Apply"); } } -// static -void LLPanelRegionTools::onChangePrelude(LLUICtrl* ctrl, void* data) +void LLPanelRegionTools::onChangePrelude() { // checking prelude auto-checks fixed sun - LLPanelRegionTools* self = (LLPanelRegionTools*)data; - if (self->childGetValue("check prelude").asBoolean()) + if (childGetValue("check prelude").asBoolean()) { - self->childSetValue("check fixed sun", TRUE); - self->childSetValue("check reset home", TRUE); + childSetValue("check fixed sun", TRUE); + childSetValue("check reset home", TRUE); + onChangeAnything(); } // pass on to default onChange handler - onChangeAnything(ctrl, data); + } // static @@ -773,49 +739,50 @@ void LLPanelRegionTools::onChangeSimName(LLLineEditor* caller, void* userdata ) } } -//static -void LLPanelRegionTools::onRefresh(void* userdata) + +void LLPanelRegionTools::onRefresh() { + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance("god_tools"); + if(!god_tools) return; LLViewerRegion *region = gAgent.getRegion(); if (region && gAgent.isGodlike()) { - LLFloaterGodTools::getInstance()->sendRegionInfoRequest(); + god_tools->sendRegionInfoRequest(); + //LLFloaterGodTools::getInstance()->sendRegionInfoRequest(); + //LLFloaterReg::getTypedInstance("god_tools")->sendRegionInfoRequest(); } } -// static -void LLPanelRegionTools::onApplyChanges(void* userdata) +void LLPanelRegionTools::onApplyChanges() { + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance("god_tools"); + if(!god_tools) return; LLViewerRegion *region = gAgent.getRegion(); - if (region && userdata && gAgent.isGodlike()) + if (region && gAgent.isGodlike()) { - LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata; - - region_tools->childDisable("Apply"); - LLFloaterGodTools::getInstance()->sendGodUpdateRegionInfo(); + childDisable("Apply"); + god_tools->sendGodUpdateRegionInfo(); + //LLFloaterReg::getTypedInstance("god_tools")->sendGodUpdateRegionInfo(); } } -// static -void LLPanelRegionTools::onBakeTerrain(void *userdata) +void LLPanelRegionTools::onBakeTerrain() { LLPanelRequestTools::sendRequest("terrain", "bake", gAgent.getRegionHost()); } -// static -void LLPanelRegionTools::onRevertTerrain(void *userdata) +void LLPanelRegionTools::onRevertTerrain() { LLPanelRequestTools::sendRequest("terrain", "revert", gAgent.getRegionHost()); } -// static -void LLPanelRegionTools::onSwapTerrain(void *userdata) + +void LLPanelRegionTools::onSwapTerrain() { LLPanelRequestTools::sendRequest("terrain", "swap", gAgent.getRegionHost()); } -// static -void LLPanelRegionTools::onSelectRegion(void* userdata) +void LLPanelRegionTools::onSelectRegion() { llinfos << "LLPanelRegionTools::onSelectRegion" << llendl; @@ -860,6 +827,8 @@ const F32 HOURS_TO_RADIANS = (2.f*F_PI)/24.f; LLPanelGridTools::LLPanelGridTools() : LLPanel() { + mCommitCallbackRegistrar.add("GridTools.KickAll", boost::bind(&LLPanelGridTools::onClickKickAll, this)); + mCommitCallbackRegistrar.add("GridTools.FlushMapVisibilityCaches", boost::bind(&LLPanelGridTools::onClickFlushMapVisibilityCaches, this)); } // Destroys the object @@ -869,9 +838,6 @@ LLPanelGridTools::~LLPanelGridTools() BOOL LLPanelGridTools::postBuild() { - childSetAction("Kick all users", onClickKickAll, this); - childSetAction("Flush This Region's Map Visibility Caches", onClickFlushMapVisibilityCaches, this); - return TRUE; } @@ -879,9 +845,7 @@ void LLPanelGridTools::refresh() { } - -// static -void LLPanelGridTools::onClickKickAll(void* userdata) +void LLPanelGridTools::onClickKickAll() { LLNotifications::instance().add("KickAllUsers", LLSD(), LLSD(), LLPanelGridTools::confirmKick); } @@ -921,9 +885,7 @@ bool LLPanelGridTools::finishKick(const LLSD& notification, const LLSD& response return false; } - -// static -void LLPanelGridTools::onClickFlushMapVisibilityCaches(void* data) +void LLPanelGridTools::onClickFlushMapVisibilityCaches() { LLNotifications::instance().add("FlushMapVisibilityCaches", LLSD(), LLSD(), flushMapVisibilityCachesConfirm); } @@ -981,6 +943,15 @@ LLPanelObjectTools::LLPanelObjectTools() : LLPanel(), mTargetAvatar() { + mCommitCallbackRegistrar.add("ObjectTools.ChangeAnything", boost::bind(&LLPanelObjectTools::onChangeAnything, this)); + mCommitCallbackRegistrar.add("ObjectTools.DeletePublicOwnedBy", boost::bind(&LLPanelObjectTools::onClickDeletePublicOwnedBy, this)); + mCommitCallbackRegistrar.add("ObjectTools.DeleteAllScriptedOwnedBy", boost::bind(&LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy, this)); + mCommitCallbackRegistrar.add("ObjectTools.DeleteAllOwnedBy", boost::bind(&LLPanelObjectTools::onClickDeleteAllOwnedBy, this)); + mCommitCallbackRegistrar.add("ObjectTools.ApplyChanges", boost::bind(&LLPanelObjectTools::onApplyChanges, this)); + mCommitCallbackRegistrar.add("ObjectTools.Set", boost::bind(&LLPanelObjectTools::onClickSet, this)); + mCommitCallbackRegistrar.add("ObjectTools.GetTopColliders", boost::bind(&LLPanelObjectTools::onGetTopColliders, this)); + mCommitCallbackRegistrar.add("ObjectTools.GetTopScripts", boost::bind(&LLPanelObjectTools::onGetTopScripts, this)); + mCommitCallbackRegistrar.add("ObjectTools.GetScriptDigest", boost::bind(&LLPanelObjectTools::onGetScriptDigest, this)); } // Destroys the object @@ -991,22 +962,6 @@ LLPanelObjectTools::~LLPanelObjectTools() BOOL LLPanelObjectTools::postBuild() { - childSetCommitCallback("disable scripts", onChangeAnything, this); - childSetCommitCallback("disable collisions", onChangeAnything, this); - childSetCommitCallback("disable physics", onChangeAnything, this); - - childSetAction("Apply", onApplyChanges, this); - - childSetAction("Set Target", onClickSet, this); - - childSetAction("Delete Target's Scripted Objects On Others Land", onClickDeletePublicOwnedBy, this); - childSetAction("Delete Target's Scripted Objects On *Any* Land", onClickDeleteAllScriptedOwnedBy, this); - childSetAction("Delete *ALL* Of Target's Objects", onClickDeleteAllOwnedBy, this); - - childSetAction("Get Top Colliders", onGetTopColliders, this); - childSetAction("Get Top Scripts", onGetTopScripts, this); - childSetAction("Scripts digest", onGetScriptDigest, this); - return TRUE; } @@ -1095,30 +1050,33 @@ void LLPanelObjectTools::enableAllWidgets() } -// static -void LLPanelObjectTools::onGetTopColliders(void* userdata) +void LLPanelObjectTools::onGetTopColliders() { + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); + if(!instance) return; + if (gAgent.isGodlike()) { - LLFloaterTopObjects::show(); + LLFloaterReg::showInstance("top_objects"); LLFloaterTopObjects::setMode(STAT_REPORT_TOP_COLLIDERS); - LLFloaterTopObjects::onRefresh(NULL); + instance->onRefresh(); } } -// static -void LLPanelObjectTools::onGetTopScripts(void* userdata) +void LLPanelObjectTools::onGetTopScripts() { + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); + if(!instance) return; + if (gAgent.isGodlike()) { - LLFloaterTopObjects::show(); + LLFloaterReg::showInstance("top_objects"); LLFloaterTopObjects::setMode(STAT_REPORT_TOP_SCRIPTS); - LLFloaterTopObjects::onRefresh(NULL); + instance->onRefresh(); } } -// static -void LLPanelObjectTools::onGetScriptDigest(void* userdata) +void LLPanelObjectTools::onGetScriptDigest() { if (gAgent.isGodlike()) { @@ -1128,20 +1086,20 @@ void LLPanelObjectTools::onGetScriptDigest(void* userdata) } } -void LLPanelObjectTools::onClickDeletePublicOwnedBy(void* userdata) +void LLPanelObjectTools::onClickDeletePublicOwnedBy() { // Bring up view-modal dialog - LLPanelObjectTools* panelp = (LLPanelObjectTools*)userdata; - if (!panelp->mTargetAvatar.isNull()) + + if (!mTargetAvatar.isNull()) { - panelp->mSimWideDeletesFlags = + mSimWideDeletesFlags = SWD_SCRIPTED_ONLY | SWD_OTHERS_LAND_ONLY; LLSD args; - args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString(); + args["AVATAR_NAME"] = childGetValue("target_avatar_name").asString(); LLSD payload; - payload["avatar_id"] = panelp->mTargetAvatar; - payload["flags"] = (S32)panelp->mSimWideDeletesFlags; + payload["avatar_id"] = mTargetAvatar; + payload["flags"] = (S32)mSimWideDeletesFlags; LLNotifications::instance().add( "GodDeleteAllScriptedPublicObjectsByUser", args, @@ -1150,20 +1108,18 @@ void LLPanelObjectTools::onClickDeletePublicOwnedBy(void* userdata) } } -// static -void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy(void* userdata) +void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy() { // Bring up view-modal dialog - LLPanelObjectTools* panelp = (LLPanelObjectTools*)userdata; - if (!panelp->mTargetAvatar.isNull()) + if (!mTargetAvatar.isNull()) { - panelp->mSimWideDeletesFlags = SWD_SCRIPTED_ONLY; + mSimWideDeletesFlags = SWD_SCRIPTED_ONLY; LLSD args; - args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString(); + args["AVATAR_NAME"] = childGetValue("target_avatar_name").asString(); LLSD payload; - payload["avatar_id"] = panelp->mTargetAvatar; - payload["flags"] = (S32)panelp->mSimWideDeletesFlags; + payload["avatar_id"] = mTargetAvatar; + payload["flags"] = (S32)mSimWideDeletesFlags; LLNotifications::instance().add( "GodDeleteAllScriptedObjectsByUser", args, @@ -1172,20 +1128,18 @@ void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy(void* userdata) } } -// static -void LLPanelObjectTools::onClickDeleteAllOwnedBy(void* userdata) +void LLPanelObjectTools::onClickDeleteAllOwnedBy() { // Bring up view-modal dialog - LLPanelObjectTools* panelp = (LLPanelObjectTools*)userdata; - if (!panelp->mTargetAvatar.isNull()) + if (!mTargetAvatar.isNull()) { - panelp->mSimWideDeletesFlags = 0; + mSimWideDeletesFlags = 0; LLSD args; - args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString(); + args["AVATAR_NAME"] = childGetValue("target_avatar_name").asString(); LLSD payload; - payload["avatar_id"] = panelp->mTargetAvatar; - payload["flags"] = (S32)panelp->mSimWideDeletesFlags; + payload["avatar_id"] = mTargetAvatar; + payload["flags"] = (S32)mSimWideDeletesFlags; LLNotifications::instance().add( "GodDeleteAllObjectsByUser", args, @@ -1209,11 +1163,10 @@ bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const return false; } -void LLPanelObjectTools::onClickSet(void* data) +void LLPanelObjectTools::onClickSet() { - LLPanelObjectTools* panelp = (LLPanelObjectTools*) data; // grandparent is a floater, which can have a dependent - gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarID, data)); + gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarID, this)); } void LLPanelObjectTools::onClickSetBySelection(void* data) @@ -1247,28 +1200,25 @@ void LLPanelObjectTools::callbackAvatarID(const std::vector& names, object_tools->refresh(); } - -// static -void LLPanelObjectTools::onChangeAnything(LLUICtrl* ctrl, void* userdata) +void LLPanelObjectTools::onChangeAnything() { - if (userdata && gAgent.isGodlike()) + if (gAgent.isGodlike()) { - LLPanelObjectTools* object_tools = (LLPanelObjectTools*) userdata; - object_tools->childEnable("Apply"); + childEnable("Apply"); } } -// static -void LLPanelObjectTools::onApplyChanges(void* userdata) +void LLPanelObjectTools::onApplyChanges() { + LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance("god_tools"); + if(!god_tools) return; LLViewerRegion *region = gAgent.getRegion(); if (region && gAgent.isGodlike()) { - LLPanelObjectTools* object_tools = (LLPanelObjectTools*) userdata; // TODO -- implement this - - object_tools->childDisable("Apply"); - LLFloaterGodTools::getInstance()->sendGodUpdateRegionInfo(); + childDisable("Apply"); + god_tools->sendGodUpdateRegionInfo(); + //LLFloaterReg::getTypedInstance("god_tools")->sendGodUpdateRegionInfo(); } } @@ -1283,6 +1233,7 @@ const std::string AGENT_REGION = "Agent Region"; LLPanelRequestTools::LLPanelRequestTools(): LLPanel() { + mCommitCallbackRegistrar.add("GodTools.Request", boost::bind(&LLPanelRequestTools::onClickRequest, this)); } LLPanelRequestTools::~LLPanelRequestTools() @@ -1291,8 +1242,6 @@ LLPanelRequestTools::~LLPanelRequestTools() BOOL LLPanelRequestTools::postBuild() { - childSetAction("Make Request", onClickRequest, this); - refresh(); return TRUE; @@ -1353,21 +1302,19 @@ void LLPanelRequestTools::sendRequest(const std::string& request, msg->sendReliable(host); } -// static -void LLPanelRequestTools::onClickRequest(void* data) +void LLPanelRequestTools::onClickRequest() { - LLPanelRequestTools* self = (LLPanelRequestTools*)data; - const std::string dest = self->childGetValue("destination").asString(); + const std::string dest = childGetValue("destination").asString(); if(dest == SELECTION) { - std::string req = self->childGetValue("request"); + std::string req =childGetValue("request"); req = req.substr(0, req.find_first_of(" ")); - std::string param = self->childGetValue("parameter"); + std::string param = childGetValue("parameter"); LLSelectMgr::getInstance()->sendGodlikeRequest(req, param); } else if(dest == AGENT_REGION) { - self->sendRequest(gAgent.getRegionHost()); + sendRequest(gAgent.getRegionHost()); } else { @@ -1379,7 +1326,7 @@ void LLPanelRequestTools::onClickRequest(void* data) if(dest == regionp->getName()) { // found it - self->sendRequest(regionp->getHost()); + sendRequest(regionp->getHost()); } } } diff --git a/indra/newview/llfloatergodtools.h b/indra/newview/llfloatergodtools.h index 6c4b438808..ebab1fde11 100644 --- a/indra/newview/llfloatergodtools.h +++ b/indra/newview/llfloatergodtools.h @@ -57,9 +57,9 @@ class LLTextBox; class LLMessageSystem; class LLFloaterGodTools - : public LLFloater, public LLFloaterSingleton + : public LLFloater { - friend class LLUISingleton >; + friend class LLFloaterReg; public: enum EGodPanel @@ -81,7 +81,6 @@ public: void showPanel(const std::string& panel_name); virtual void onOpen(const LLSD& key); - virtual void onClose(bool app_quitting); virtual void draw(); @@ -98,12 +97,16 @@ public: // Send possibly changed values to simulator. void sendGodUpdateRegionInfo(); +private: + + LLFloaterGodTools(const LLSD& key); + ~LLFloaterGodTools(); + protected: U32 computeRegionFlags() const; protected: - LLFloaterGodTools(const LLSD& key); - ~LLFloaterGodTools(); + /*virtual*/ BOOL postBuild(); // When the floater is going away, reset any options that need to be // cleared. @@ -133,16 +136,17 @@ public: /*virtual*/ void refresh(); - static void onSaveState(void* data); - static void onChangeAnything(LLUICtrl* ctrl, void* userdata); - static void onChangePrelude(LLUICtrl* ctrl, void* data); + static void onSaveState(void* userdata); static void onChangeSimName(LLLineEditor* caller, void* userdata); - static void onApplyChanges(void* userdata); - static void onBakeTerrain(void *userdata); - static void onRevertTerrain(void *userdata); - static void onSwapTerrain(void *userdata); - static void onSelectRegion(void *userdata); - static void onRefresh(void* userdata); + + void onChangeAnything(); + void onChangePrelude(); + void onApplyChanges(); + void onBakeTerrain(); + void onRevertTerrain(); + void onSwapTerrain(); + void onSelectRegion(); + void onRefresh(); // set internal checkboxes/spinners/combos const std::string getSimName() const; @@ -194,11 +198,11 @@ public: void refresh(); - static void onClickKickAll(void *data); + void onClickKickAll(); static bool confirmKick(const LLSD& notification, const LLSD& response); static bool finishKick(const LLSD& notification, const LLSD& response); static void onDragSunPhase(LLUICtrl *ctrl, void *userdata); - static void onClickFlushMapVisibilityCaches(void* data); + void onClickFlushMapVisibilityCaches(); static bool flushMapVisibilityCachesConfirm(const LLSD& notification, const LLSD& response); protected: @@ -227,17 +231,17 @@ public: void enableAllWidgets(); void setCheckFlags(U32 flags); - static void onChangeAnything(LLUICtrl* ctrl, void* data); - static void onApplyChanges(void* data); - static void onClickSet(void* data); + void onChangeAnything(); + void onApplyChanges(); + void onClickSet(); static void callbackAvatarID(const std::vector& names, const std::vector& ids, void* data); - static void onClickDeletePublicOwnedBy(void* data); - static void onClickDeleteAllScriptedOwnedBy(void* data); - static void onClickDeleteAllOwnedBy(void* data); + void onClickDeletePublicOwnedBy(); + void onClickDeleteAllScriptedOwnedBy(); + void onClickDeleteAllOwnedBy(); static bool callbackSimWideDeletes(const LLSD& notification, const LLSD& response); - static void onGetTopColliders(void* data); - static void onGetTopScripts(void* data); - static void onGetScriptDigest(void* data); + void onGetTopColliders(); + void onGetTopScripts(); + void onGetScriptDigest(); static void onClickSetBySelection(void* data); protected: @@ -267,7 +271,7 @@ public: const LLHost& host); protected: - static void onClickRequest(void *data); + void onClickRequest(); void sendRequest(const LLHost& host); }; diff --git a/indra/newview/llfloatergroupinvite.cpp b/indra/newview/llfloatergroupinvite.cpp index 92db0b0926..3598479305 100644 --- a/indra/newview/llfloatergroupinvite.cpp +++ b/indra/newview/llfloatergroupinvite.cpp @@ -79,7 +79,7 @@ void LLFloaterGroupInvite::impl::closeFloater(void* data) // Implementation //----------------------------------------------------------------------------- LLFloaterGroupInvite::LLFloaterGroupInvite(const LLUUID& group_id) -: LLFloater() +: LLFloater(group_id) { static LLUICachedControl floater_header_size ("UIFloaterHeaderSize", 0); LLRect contents; diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index a967a1833f..7f03d63b3e 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -53,9 +53,6 @@ using namespace LLOldEvents; -// static -std::map LLFloaterGroupPicker::sInstances; - // helper functions void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 powers_mask = GP_ALL_POWERS); @@ -63,36 +60,16 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 pow /// Class LLFloaterGroupPicker ///---------------------------------------------------------------------------- -// static -LLFloaterGroupPicker* LLFloaterGroupPicker::findInstance(const LLSD& seed) -{ - instance_map_t::iterator found_it = sInstances.find(seed.asUUID()); - if (found_it != sInstances.end()) - { - return found_it->second; - } - return NULL; -} - -// static -LLFloaterGroupPicker* LLFloaterGroupPicker::createInstance(const LLSD &seed) -{ - LLFloaterGroupPicker* pickerp = new LLFloaterGroupPicker(seed); - return pickerp; -} - LLFloaterGroupPicker::LLFloaterGroupPicker(const LLSD& seed) -: LLFloater(), - mPowersMask(GP_ALL_POWERS) +: LLFloater(seed), + mPowersMask(GP_ALL_POWERS), + mID(seed.asUUID()) { - mID = seed.asUUID(); - sInstances.insert(std::make_pair(mID, this)); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_choose_group.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_choose_group.xml"); } LLFloaterGroupPicker::~LLFloaterGroupPicker() { - sInstances.erase(mID); } void LLFloaterGroupPicker::setPowersMask(U64 powers_mask) diff --git a/indra/newview/llfloatergroups.h b/indra/newview/llfloatergroups.h index 0425b81294..489238356d 100644 --- a/indra/newview/llfloatergroups.h +++ b/indra/newview/llfloatergroups.h @@ -56,10 +56,10 @@ class LLScrollListCtrl; class LLButton; class LLFloaterGroupPicker; -class LLFloaterGroupPicker : public LLFloater, public LLUIFactory > +class LLFloaterGroupPicker : public LLFloater { - friend class LLUIFactory; public: + LLFloaterGroupPicker(const LLSD& seed); ~LLFloaterGroupPicker(); // Note: Don't return connection; use boost::bind + boost::signals2::trackable to disconnect slots @@ -73,7 +73,6 @@ public: static LLFloaterGroupPicker* createInstance(const LLSD& seed); protected: - LLFloaterGroupPicker(const LLSD& seed); void ok(); static void onBtnOK(void* userdata); static void onBtnCancel(void* userdata); diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 38915ebff9..3c3508b65c 100644 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -38,7 +38,7 @@ #include "llfloaterpreference.h" #include "llviewerwindow.h" #include "llviewercontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llfeaturemanager.h" #include "llstartup.h" #include "pipeline.h" @@ -47,14 +47,12 @@ #include "llradiogroup.h" #include "lluictrlfactory.h" #include "llwindow.h" -#include "llimagegl.h" +#include "llslider.h" -LLFloaterHardwareSettings* LLFloaterHardwareSettings::sHardwareSettings = NULL; - -LLFloaterHardwareSettings::LLFloaterHardwareSettings() - : LLFloater() +LLFloaterHardwareSettings::LLFloaterHardwareSettings(const LLSD& key) + : LLFloater(key) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hardware_settings.xml"); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hardware_settings.xml"); } LLFloaterHardwareSettings::~LLFloaterHardwareSettings() @@ -91,10 +89,10 @@ void LLFloaterHardwareSettings::refresh() void LLFloaterHardwareSettings::refreshEnabledState() { - S32 min_tex_mem = LLViewerImageList::getMinVideoRamSetting(); - S32 max_tex_mem = LLViewerImageList::getMaxVideoRamSetting(); - childSetMinValue("GrapicsCardTextureMemory", min_tex_mem); - childSetMaxValue("GrapicsCardTextureMemory", max_tex_mem); + S32 min_tex_mem = LLViewerTextureList::getMinVideoRamSetting(); + S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(); + getChild("GrapicsCardTextureMemory")->setMinValue(min_tex_mem); + getChild("GrapicsCardTextureMemory")->setMinValue(max_tex_mem); if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || !gGLManager.mHasVertexBufferObject) @@ -109,48 +107,6 @@ void LLFloaterHardwareSettings::refreshEnabledState() } -// static instance of it -LLFloaterHardwareSettings* LLFloaterHardwareSettings::instance() -{ - if (!sHardwareSettings) - { - sHardwareSettings = new LLFloaterHardwareSettings(); - sHardwareSettings->closeFloater(); - } - return sHardwareSettings; -} -void LLFloaterHardwareSettings::show() -{ - LLFloaterHardwareSettings* hardSettings = instance(); - hardSettings->refresh(); - hardSettings->center(); - - // comment in if you want the menu to rebuild each time - //LLUICtrlFactory::getInstance()->buildFloater(hardSettings, "floater_hardware_settings.xml"); - //hardSettings->initCallbacks(); - - hardSettings->openFloater(); -} - -bool LLFloaterHardwareSettings::isOpen() -{ - if (sHardwareSettings != NULL) - { - return true; - } - return false; -} - -// virtual -void LLFloaterHardwareSettings::onClose(bool app_quitting) -{ - if (sHardwareSettings) - { - sHardwareSettings->setVisible(FALSE); - } -} - - //============================================================================ BOOL LLFloaterHardwareSettings::postBuild() @@ -158,6 +114,7 @@ BOOL LLFloaterHardwareSettings::postBuild() childSetAction("OK", onBtnOK, this); refresh(); + center(); // load it up initCallbacks(); @@ -217,3 +174,4 @@ void LLFloaterHardwareSettings::onBtnOK( void* userdata ) fp->closeFloater(false); } + diff --git a/indra/newview/llfloaterhardwaresettings.h b/indra/newview/llfloaterhardwaresettings.h index ec99638740..3f19d89cbb 100644 --- a/indra/newview/llfloaterhardwaresettings.h +++ b/indra/newview/llfloaterhardwaresettings.h @@ -42,7 +42,7 @@ class LLFloaterHardwareSettings : public LLFloater public: - LLFloaterHardwareSettings(); + LLFloaterHardwareSettings(const LLSD& key); /*virtual*/ ~LLFloaterHardwareSettings(); /*virtual*/ BOOL postBuild(); @@ -50,9 +50,6 @@ public: /// initialize all the callbacks for the menu void initCallbacks(void); - /// one and one instance only - static LLFloaterHardwareSettings* instance(); - /// callback for the menus help button static void onClickHelp(void* data); @@ -67,9 +64,6 @@ public: /// return if the menu exists or not static bool isOpen(); - /// stuff to do on exit - virtual void onClose(bool app_quitting); - /// sync up menu with parameters void refresh(); @@ -92,8 +86,6 @@ protected: BOOL mProbeHardwareOnStartup; private: - // one instance on the inside - static LLFloaterHardwareSettings* sHardwareSettings; }; #endif diff --git a/indra/newview/llfloaterhud.cpp b/indra/newview/llfloaterhud.cpp index 4379d25a66..4dcf726c9a 100644 --- a/indra/newview/llfloaterhud.cpp +++ b/indra/newview/llfloaterhud.cpp @@ -42,8 +42,6 @@ // Linden libs #include "lluictrlfactory.h" -// statics -LLFloaterHUD* LLFloaterHUD::sInstance = 0; ///---------------------------------------------------------------------------- /// Class LLFloaterHUD @@ -51,12 +49,18 @@ LLFloaterHUD* LLFloaterHUD::sInstance = 0; #define super LLFloater /* superclass */ // Default constructor -LLFloaterHUD::LLFloaterHUD() -: LLFloater(), +LLFloaterHUD::LLFloaterHUD(const LLSD& key) +: LLFloater(key), mWebBrowser(0) { - // Create floater from its XML definition - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hud.xml"); + // do not build the floater if there the url is empty + if (gSavedSettings.getString("TutorialURL") == "") + { + LLNotifications::instance().add("TutorialNotFound"); + return; + } + + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hud.xml"); // Don't grab the focus as it will impede performing in-world actions // while using the HUD @@ -68,68 +72,32 @@ LLFloaterHUD::LLFloaterHUD() // Opaque background since we never get the focus setBackgroundOpaque(TRUE); +} +BOOL LLFloaterHUD::postBuild() +{ mWebBrowser = getChild("floater_hud_browser" ); if (mWebBrowser) { // Open links in internal browser mWebBrowser->setOpenInExternalBrowser(false); - + // This is a "chrome" floater, so we don't want anything to // take focus (as the user needs to be able to walk with // arrow keys during tutorial). mWebBrowser->setTakeFocusOnClick(false); - + std::string language = LLUI::getLanguage(); std::string base_url = gSavedSettings.getString("TutorialURL"); - + std::string url = base_url + language + "/"; mWebBrowser->navigateTo(url); } -} - -// Get the instance -LLFloaterHUD* LLFloaterHUD::getInstance() -{ - if (!sInstance) - { - sInstance = new LLFloaterHUD(); - } - return sInstance; + + return TRUE; } // Destructor LLFloaterHUD::~LLFloaterHUD() { - // Clear out the one instance if it's ours - if (sInstance == this) - { - sInstance = NULL; - } -} - -// Show the HUD -void LLFloaterHUD::showHUD() -{ - // do not build the floater if there the url is empty - if (gSavedSettings.getString("TutorialURL") == "") - { - LLNotifications::instance().add("TutorialNotFound"); - return; - } - - // Create the instance if necessary - LLFloaterHUD* hud = getInstance(); - hud->openFloater(); - hud->setFrontmost(FALSE); -} - -// Save our visibility state on close in case the user accidentally -// quit the application while the tutorial was visible. -// virtual -void LLFloaterHUD::onClose(bool app_quitting) -{ - bool stay_visible = app_quitting; - gSavedSettings.setBOOL("ShowTutorial", stay_visible); - destroy(); } diff --git a/indra/newview/llfloaterhud.h b/indra/newview/llfloaterhud.h index 2d58685b58..4772735afc 100644 --- a/indra/newview/llfloaterhud.h +++ b/indra/newview/llfloaterhud.h @@ -39,22 +39,18 @@ class LLWebBrowserCtrl; class LLFloaterHUD : public LLFloater { + friend class LLFloaterReg; public: - static LLFloaterHUD* getInstance(); ///< get instance creating if necessary - - static void showHUD(); ///< show the HUD - - // Save our visibility state during close - /*virtual*/ void onClose(bool app_quitting); + BOOL postBuild(); + private: // Handles its own construction and destruction, so private. - LLFloaterHUD(); + LLFloaterHUD(const LLSD& key); /*virtual*/ ~LLFloaterHUD(); private: LLWebBrowserCtrl* mWebBrowser; ///< the actual web browser control - static LLFloaterHUD* sInstance; }; #endif // LL_LLFLOATERHUD_H diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index faa4f0ec99..07dbf98a1e 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -56,12 +56,9 @@ #include "llvoavatar.h" #include "pipeline.h" #include "lluictrlfactory.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llstring.h" -//static -S32 LLFloaterImagePreview::sUploadAmount = 10; - const S32 PREVIEW_BORDER_WIDTH = 2; const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH; const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE; @@ -93,9 +90,7 @@ BOOL LLFloaterImagePreview::postBuild() { return FALSE; } - - childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount)); - + LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo"); if (iface) { @@ -130,7 +125,9 @@ BOOL LLFloaterImagePreview::postBuild() childDisable("clothing_type_combo"); childDisable("ok_btn"); } - + + getChild("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this)); + return TRUE; } @@ -142,9 +139,6 @@ LLFloaterImagePreview::~LLFloaterImagePreview() clearAllPreviewTextures(); mRawImagep = NULL; - delete mAvatarPreview; - delete mSculptedPreview; - mImagep = NULL ; } @@ -252,7 +246,7 @@ void LLFloaterImagePreview::draw() } else { - mImagep = new LLImageGL(mRawImagep, FALSE) ; + mImagep = LLViewerTextureManager::getLocalTexture(mRawImagep.get(), FALSE) ; gGL.getTexUnit(0)->unbind(mImagep->getTarget()) ; gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName()); @@ -294,11 +288,11 @@ void LLFloaterImagePreview::draw() if (selected == 9) { - gGL.getTexUnit(0)->bind(mSculptedPreview->getTexture()); + gGL.getTexUnit(0)->bind(mSculptedPreview); } else { - gGL.getTexUnit(0)->bind(mAvatarPreview->getTexture()); + gGL.getTexUnit(0)->bind(mAvatarPreview); } gGL.begin( LLRender::QUADS ); @@ -606,7 +600,7 @@ void LLFloaterImagePreview::onMouseCaptureLostImagePreview(LLMouseHandler* handl //----------------------------------------------------------------------------- // LLImagePreviewAvatar //----------------------------------------------------------------------------- -LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) +LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) { mNeedsUpdate = TRUE; mTargetJoint = NULL; @@ -697,7 +691,7 @@ BOOL LLImagePreviewAvatar::render() glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); glLoadIdentity(); - glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); + glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); gGL.pushMatrix(); @@ -706,7 +700,7 @@ BOOL LLImagePreviewAvatar::render() LLGLSUIDefault def; gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); - gl_rect_2d_simple( mWidth, mHeight ); + gl_rect_2d_simple( mFullWidth, mFullHeight ); glMatrixMode(GL_PROJECTION); gGL.popMatrix(); @@ -728,9 +722,9 @@ BOOL LLImagePreviewAvatar::render() stop_glerror(); - LLViewerCamera::getInstance()->setAspect((F32)mWidth / mHeight); + LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / mFullHeight); LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); - LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); LLVertexBuffer::unbind(); avatarp->updateLOD(); @@ -788,7 +782,7 @@ void LLImagePreviewAvatar::pan(F32 right, F32 up) // LLImagePreviewSculpted //----------------------------------------------------------------------------- -LLImagePreviewSculpted::LLImagePreviewSculpted(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) +LLImagePreviewSculpted::LLImagePreviewSculpted(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) { mNeedsUpdate = TRUE; mCameraDistance = 0.f; @@ -871,7 +865,7 @@ BOOL LLImagePreviewSculpted::render() glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); glLoadIdentity(); - glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); + glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); gGL.pushMatrix(); @@ -879,7 +873,7 @@ BOOL LLImagePreviewSculpted::render() gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); - gl_rect_2d_simple( mWidth, mHeight ); + gl_rect_2d_simple( mFullWidth, mFullHeight ); glMatrixMode(GL_PROJECTION); gGL.popMatrix(); @@ -902,9 +896,9 @@ BOOL LLImagePreviewSculpted::render() stop_glerror(); - LLViewerCamera::getInstance()->setAspect((F32) mWidth / mHeight); + LLViewerCamera::getInstance()->setAspect((F32) mFullWidth / mFullHeight); LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); - LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); const LLVolumeFace &vf = mVolume->getVolumeFace(0); U32 num_indices = vf.mIndices.size(); diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h index 6a4de3d3cc..f007697e88 100644 --- a/indra/newview/llfloaterimagepreview.h +++ b/indra/newview/llfloaterimagepreview.h @@ -44,12 +44,14 @@ class LLVOAvatar; class LLTextBox; class LLVertexBuffer; -class LLImagePreviewSculpted : public LLDynamicTexture +class LLImagePreviewSculpted : public LLViewerDynamicTexture { - public: - LLImagePreviewSculpted(S32 width, S32 height); +protected: virtual ~LLImagePreviewSculpted(); + public: + LLImagePreviewSculpted(S32 width, S32 height); + void setPreviewTarget(LLImageRaw *imagep, F32 distance); void setTexture(U32 name) { mTextureName = name; } @@ -73,12 +75,14 @@ class LLImagePreviewSculpted : public LLDynamicTexture }; -class LLImagePreviewAvatar : public LLDynamicTexture +class LLImagePreviewAvatar : public LLViewerDynamicTexture { -public: - LLImagePreviewAvatar(S32 width, S32 height); +protected: virtual ~LLImagePreviewAvatar(); +public: + LLImagePreviewAvatar(S32 width, S32 height); + void setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male); void setTexture(U32 name) { mTextureName = name; } void clearPreviewTexture(const std::string& mesh_name); @@ -117,7 +121,6 @@ public: BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); static void onMouseCaptureLostImagePreview(LLMouseHandler*); - static void setUploadAmount(S32 amount) { sUploadAmount = amount; } void clearAllPreviewTextures(); @@ -127,15 +130,14 @@ protected: bool loadImage(const std::string& filename); LLPointer mRawImagep; - LLImagePreviewAvatar* mAvatarPreview; - LLImagePreviewSculpted* mSculptedPreview; + LLPointer mAvatarPreview; + LLPointer mSculptedPreview; S32 mLastMouseX; S32 mLastMouseY; LLRect mPreviewRect; LLRectf mPreviewImageRect; - LLPointer mImagep ; + LLPointer mImagep ; - static S32 sUploadAmount; }; #endif // LL_LLFLOATERIMAGEPREVIEW_H diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 57f4bcf319..e26937e93f 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -35,9 +35,8 @@ #include "llfloaterinspect.h" #include "llfloaterreg.h" -#include "llfloateravatarinfo.h" #include "llfloatertools.h" -#include "llfriendactions.h" +#include "llavataractions.h" #include "llcachename.h" #include "llscrolllistctrl.h" #include "llscrolllistitem.h" @@ -48,13 +47,28 @@ #include "llviewerobject.h" #include "lluictrlfactory.h" -LLFloaterInspect* LLFloaterInspect::sInstance = NULL; +//LLFloaterInspect* LLFloaterInspect::sInstance = NULL; -LLFloaterInspect::LLFloaterInspect(void) - : LLFloater(), +LLFloaterInspect::LLFloaterInspect(const LLSD& key) + : LLFloater(key), mDirty(FALSE) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inspect.xml"); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inspect.xml"); + mCommitCallbackRegistrar.add("Inspect.OwnerProfile", boost::bind(&LLFloaterInspect::onClickOwnerProfile, this)); + mCommitCallbackRegistrar.add("Inspect.CreatorProfile", boost::bind(&LLFloaterInspect::onClickCreatorProfile, this)); + mCommitCallbackRegistrar.add("Inspect.SelectObject", boost::bind(&LLFloaterInspect::onSelectObject, this)); +} + +BOOL LLFloaterInspect::postBuild() +{ + mObjectList = getChild("object_list"); +// childSetAction("button owner",onClickOwnerProfile, this); +// childSetAction("button creator",onClickCreatorProfile, this); +// childSetCommitCallback("object_list", onSelectObject, NULL); + + refresh(); + + return TRUE; } LLFloaterInspect::~LLFloaterInspect(void) @@ -72,14 +86,14 @@ LLFloaterInspect::~LLFloaterInspect(void) { LLFloaterReg::showInstance("build", LLSD(), TRUE); } - sInstance = NULL; + //sInstance = NULL; } - +/* BOOL LLFloaterInspect::isVisible() { return (!!sInstance); -} - +}*/ +/* void LLFloaterInspect::show(void* ignored) { // setForceSelection ensures that the pie menu does not deselect things when it @@ -99,15 +113,22 @@ void LLFloaterInspect::show(void* ignored) sInstance->mObjectSelection = LLSelectMgr::getInstance()->getSelection(); sInstance->refresh(); } - -void LLFloaterInspect::onClickCreatorProfile(void* ctrl) +*/ +void LLFloaterInspect::onOpen(const LLSD& key) { - if(sInstance->mObjectList->getAllSelected().size() == 0) + BOOL forcesel = LLSelectMgr::getInstance()->setForceSelection(TRUE); + LLToolMgr::getInstance()->setTransientTool(LLToolCompInspect::getInstance()); + LLSelectMgr::getInstance()->setForceSelection(forcesel); // restore previouis value + mObjectSelection = LLSelectMgr::getInstance()->getSelection(); + refresh(); +} +void LLFloaterInspect::onClickCreatorProfile() +{ + if(mObjectList->getAllSelected().size() == 0) { return; } - LLScrollListItem* first_selected = - sInstance->mObjectList->getFirstSelected(); + LLScrollListItem* first_selected =mObjectList->getFirstSelected(); if (first_selected) { @@ -120,19 +141,18 @@ void LLFloaterInspect::onClickCreatorProfile(void* ctrl) return (obj_id == node->getObject()->getID()); } } func(first_selected->getUUID()); - LLSelectNode* node = sInstance->mObjectSelection->getFirstNode(&func); + LLSelectNode* node = mObjectSelection->getFirstNode(&func); if(node) { - LLFriendActions::showProfile(node->mPermissions->getCreator()); + LLAvatarActions::showProfile(node->mPermissions->getCreator()); } } } -void LLFloaterInspect::onClickOwnerProfile(void* ctrl) +void LLFloaterInspect::onClickOwnerProfile() { - if(sInstance->mObjectList->getAllSelected().size() == 0) return; - LLScrollListItem* first_selected = - sInstance->mObjectList->getFirstSelected(); + if(mObjectList->getAllSelected().size() == 0) return; + LLScrollListItem* first_selected =mObjectList->getFirstSelected(); if (first_selected) { @@ -146,46 +166,34 @@ void LLFloaterInspect::onClickOwnerProfile(void* ctrl) return (obj_id == node->getObject()->getID()); } } func(selected_id); - LLSelectNode* node = sInstance->mObjectSelection->getFirstNode(&func); + LLSelectNode* node = mObjectSelection->getFirstNode(&func); if(node) { const LLUUID& owner_id = node->mPermissions->getOwner(); - LLFriendActions::showProfile(owner_id); + LLAvatarActions::showProfile(owner_id); } } } -BOOL LLFloaterInspect::postBuild() -{ - mObjectList = getChild("object_list"); - childSetAction("button owner",onClickOwnerProfile, this); - childSetAction("button creator",onClickCreatorProfile, this); - childSetCommitCallback("object_list", onSelectObject, NULL); - return TRUE; -} - -void LLFloaterInspect::onSelectObject(LLUICtrl* ctrl, void* user_data) +void LLFloaterInspect::onSelectObject() { if(LLFloaterInspect::getSelectedUUID() != LLUUID::null) { - sInstance->childSetEnabled("button owner", true); - sInstance->childSetEnabled("button creator", true); + childSetEnabled("button owner", true); + childSetEnabled("button creator", true); } } LLUUID LLFloaterInspect::getSelectedUUID() { - if(sInstance) + if(mObjectList->getAllSelected().size() > 0) { - if(sInstance->mObjectList->getAllSelected().size() > 0) + LLScrollListItem* first_selected =mObjectList->getFirstSelected(); + if (first_selected) { - LLScrollListItem* first_selected = - sInstance->mObjectList->getFirstSelected(); - if (first_selected) - { - return first_selected->getUUID(); - } + return first_selected->getUUID(); } + } return LLUUID::null; } @@ -263,7 +271,7 @@ void LLFloaterInspect::refresh() { mObjectList->selectNthItem(0); } - onSelectObject(this, NULL); + onSelectObject(); mObjectList->setScrollPos(pos); } @@ -275,10 +283,7 @@ void LLFloaterInspect::onFocusReceived() void LLFloaterInspect::dirty() { - if(sInstance) - { - sInstance->setDirty(); - } + setDirty(); } void LLFloaterInspect::draw() diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h index 57bba6864f..ce9485ee74 100644 --- a/indra/newview/llfloaterinspect.h +++ b/indra/newview/llfloaterinspect.h @@ -44,29 +44,33 @@ class LLUICtrl; class LLFloaterInspect : public LLFloater { + friend class LLFloaterReg; public: - virtual ~LLFloaterInspect(void); - static void show(void* ignored = NULL); + +// static void show(void* ignored = NULL); + void onOpen(const LLSD& key); virtual BOOL postBuild(); - static void dirty(); - static LLUUID getSelectedUUID(); + void dirty(); + LLUUID getSelectedUUID(); virtual void draw(); virtual void refresh(); - static BOOL isVisible(); +// static BOOL isVisible(); virtual void onFocusReceived(); - static void onClickCreatorProfile(void* ctrl); - static void onClickOwnerProfile(void* ctrl); - static void onSelectObject(LLUICtrl* ctrl, void* user_data); + void onClickCreatorProfile(); + void onClickOwnerProfile(); + void onSelectObject(); LLScrollListCtrl* mObjectList; protected: // protected members - LLFloaterInspect(); void setDirty() { mDirty = TRUE; } bool mDirty; private: + + LLFloaterInspect(const LLSD& key); + virtual ~LLFloaterInspect(void); // static data - static LLFloaterInspect* sInstance; +// static LLFloaterInspect* sInstance; LLSafeHandle mObjectSelection; }; diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp new file mode 100644 index 0000000000..a486ef565a --- /dev/null +++ b/indra/newview/llfloaterinventory.cpp @@ -0,0 +1,1883 @@ +/** + * @file llfloaterinventory.cpp + * @brief Implementation of the inventory view and associated stuff. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include // for std::pair<> + +#include "llfloaterinventory.h" + +// library includes +#include "llagent.h" +#include "llagentwearables.h" +#include "llcallingcard.h" +#include "llfloaterreg.h" +#include "llsdserialize.h" +#include "llfiltereditor.h" +#include "llspinctrl.h" +#include "llui.h" +#include "message.h" + +// newview includes +#include "llappviewer.h" +#include "llfirstuse.h" +#include "llfloaterchat.h" +#include "llfloatercustomize.h" +#include "llfocusmgr.h" +#include "llfolderview.h" +#include "llgesturemgr.h" +#include "lliconctrl.h" +#include "llimview.h" +#include "llinventorybridge.h" +#include "llinventoryclipboard.h" +#include "llinventorymodel.h" +#include "lllineeditor.h" +#include "llmenugl.h" +#include "llpreviewanim.h" +#include "llpreviewgesture.h" +#include "llpreviewlandmark.h" +#include "llpreviewnotecard.h" +#include "llpreviewscript.h" +#include "llpreviewsound.h" +#include "llpreviewtexture.h" +#include "llresmgr.h" +#include "llscrollbar.h" +#include "llscrollcontainer.h" +#include "llselectmgr.h" +#include "lltabcontainer.h" +#include "lltooldraganddrop.h" +#include "lluictrlfactory.h" +#include "llviewerinventory.h" +#include "llviewermessage.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llviewerwindow.h" +#include "llvoavatarself.h" +#include "llwearablelist.h" + +static LLDefaultChildRegistry::Register r("inventory_panel"); + +//BOOL LLFloaterInventory::sOpenNextNewItem = FALSE; +BOOL LLFloaterInventory::sWearNewClothing = FALSE; +LLUUID LLFloaterInventory::sWearNewClothingTransactionID; + +///---------------------------------------------------------------------------- +/// LLFloaterInventoryFinder +///---------------------------------------------------------------------------- + +LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLFloaterInventory* inventory_view) +: LLFloater(LLSD()), + mFloaterInventory(inventory_view), + mFilter(inventory_view->mActivePanel->getFilter()) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_view_finder.xml", NULL); + updateElementsFromFilter(); +} + + +void LLFloaterInventoryFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data) +{ + LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data; + if (!self) return; + + bool since_logoff= self->childGetValue("check_since_logoff"); + + if (!since_logoff && + !( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) ) + { + self->mSpinSinceHours->set(1.0f); + } +} +BOOL LLFloaterInventoryFinder::postBuild() +{ + const LLRect& viewrect = mFloaterInventory->getRect(); + setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight())); + + childSetAction("All", selectAllTypes, this); + childSetAction("None", selectNoTypes, this); + + mSpinSinceHours = getChild("spin_hours_ago"); + childSetCommitCallback("spin_hours_ago", onTimeAgo, this); + + mSpinSinceDays = getChild("spin_days_ago"); + childSetCommitCallback("spin_days_ago", onTimeAgo, this); + + // mCheckSinceLogoff = getChild("check_since_logoff"); + childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this); + + childSetAction("Close", onCloseBtn, this); + + updateElementsFromFilter(); + return TRUE; +} +void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data) +{ + LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data; + if (!self) return; + + bool since_logoff=true; + if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) + { + since_logoff = false; + } + self->childSetValue("check_since_logoff", since_logoff); +} + +void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter) +{ + mFilter = filter; + updateElementsFromFilter(); +} + +void LLFloaterInventoryFinder::updateElementsFromFilter() +{ + if (!mFilter) + return; + + // Get data needed for filter display + U32 filter_types = mFilter->getFilterTypes(); + std::string filter_string = mFilter->getFilterSubString(); + LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState(); + U32 hours = mFilter->getHoursAgo(); + + // update the ui elements + LLFloater::setTitle(mFilter->getName()); + childSetValue("check_animation", (S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION)); + + childSetValue("check_calling_card", (S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD)); + childSetValue("check_clothing", (S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE)); + childSetValue("check_gesture", (S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE)); + childSetValue("check_landmark", (S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK)); + childSetValue("check_notecard", (S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD)); + childSetValue("check_object", (S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT)); + childSetValue("check_script", (S32) (filter_types & 0x1 << LLInventoryType::IT_LSL)); + childSetValue("check_sound", (S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND)); + childSetValue("check_texture", (S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE)); + childSetValue("check_snapshot", (S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT)); + childSetValue("check_show_empty", show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS); + childSetValue("check_since_logoff", mFilter->isSinceLogoff()); + mSpinSinceHours->set((F32)(hours % 24)); + mSpinSinceDays->set((F32)(hours / 24)); +} + +void LLFloaterInventoryFinder::draw() +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW); + U32 filter = 0xffffffff; + BOOL filtered_by_all_types = TRUE; + + if (!childGetValue("check_animation")) + { + filter &= ~(0x1 << LLInventoryType::IT_ANIMATION); + filtered_by_all_types = FALSE; + } + + + if (!childGetValue("check_calling_card")) + { + filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_clothing")) + { + filter &= ~(0x1 << LLInventoryType::IT_WEARABLE); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_gesture")) + { + filter &= ~(0x1 << LLInventoryType::IT_GESTURE); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_landmark")) + + + { + filter &= ~(0x1 << LLInventoryType::IT_LANDMARK); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_notecard")) + { + filter &= ~(0x1 << LLInventoryType::IT_NOTECARD); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_object")) + { + filter &= ~(0x1 << LLInventoryType::IT_OBJECT); + filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_script")) + { + filter &= ~(0x1 << LLInventoryType::IT_LSL); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_sound")) + { + filter &= ~(0x1 << LLInventoryType::IT_SOUND); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_texture")) + { + filter &= ~(0x1 << LLInventoryType::IT_TEXTURE); + filtered_by_all_types = FALSE; + } + + if (!childGetValue("check_snapshot")) + { + filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT); + filtered_by_all_types = FALSE; + } + + if (!filtered_by_all_types) + { + // don't include folders in filter, unless I've selected everything + filter &= ~(0x1 << LLInventoryType::IT_CATEGORY); + } + + // update the panel, panel will update the filter + mFloaterInventory->mActivePanel->setShowFolderState(getCheckShowEmpty() ? + LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); + mFloaterInventory->mActivePanel->setFilterTypes(filter); + if (getCheckSinceLogoff()) + { + mSpinSinceDays->set(0); + mSpinSinceHours->set(0); + } + U32 days = (U32)mSpinSinceDays->get(); + U32 hours = (U32)mSpinSinceHours->get(); + if (hours > 24) + { + days += hours / 24; + hours = (U32)hours % 24; + mSpinSinceDays->set((F32)days); + mSpinSinceHours->set((F32)hours); + } + hours += days * 24; + mFloaterInventory->mActivePanel->setHoursAgo(hours); + mFloaterInventory->mActivePanel->setSinceLogoff(getCheckSinceLogoff()); + mFloaterInventory->setFilterTextFromFilter(); + + LLFloater::draw(); +} + +BOOL LLFloaterInventoryFinder::getCheckShowEmpty() +{ + return childGetValue("check_show_empty"); +} + +BOOL LLFloaterInventoryFinder::getCheckSinceLogoff() +{ + return childGetValue("check_since_logoff"); +} + +void LLFloaterInventoryFinder::onCloseBtn(void* user_data) +{ + LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data; + finderp->closeFloater(); +} + +// static +void LLFloaterInventoryFinder::selectAllTypes(void* user_data) +{ + LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; + if(!self) return; + + self->childSetValue("check_animation", TRUE); + self->childSetValue("check_calling_card", TRUE); + self->childSetValue("check_clothing", TRUE); + self->childSetValue("check_gesture", TRUE); + self->childSetValue("check_landmark", TRUE); + self->childSetValue("check_notecard", TRUE); + self->childSetValue("check_object", TRUE); + self->childSetValue("check_script", TRUE); + self->childSetValue("check_sound", TRUE); + self->childSetValue("check_texture", TRUE); + self->childSetValue("check_snapshot", TRUE); + +/* + self->mCheckCallingCard->set(TRUE); + self->mCheckClothing->set(TRUE); + self->mCheckGesture->set(TRUE); + self->mCheckLandmark->set(TRUE); + self->mCheckNotecard->set(TRUE); + self->mCheckObject->set(TRUE); + self->mCheckScript->set(TRUE); + self->mCheckSound->set(TRUE); + self->mCheckTexture->set(TRUE); + self->mCheckSnapshot->set(TRUE);*/ +} + +//static +void LLFloaterInventoryFinder::selectNoTypes(void* user_data) +{ + LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; + if(!self) return; + + /* + self->childSetValue("check_animation", FALSE); + self->mCheckCallingCard->set(FALSE); + self->mCheckClothing->set(FALSE); + self->mCheckGesture->set(FALSE); + self->mCheckLandmark->set(FALSE); + self->mCheckNotecard->set(FALSE); + self->mCheckObject->set(FALSE); + self->mCheckScript->set(FALSE); + self->mCheckSound->set(FALSE); + self->mCheckTexture->set(FALSE); + self->mCheckSnapshot->set(FALSE);*/ + + + self->childSetValue("check_animation", FALSE); + self->childSetValue("check_calling_card", FALSE); + self->childSetValue("check_clothing", FALSE); + self->childSetValue("check_gesture", FALSE); + self->childSetValue("check_landmark", FALSE); + self->childSetValue("check_notecard", FALSE); + self->childSetValue("check_object", FALSE); + self->childSetValue("check_script", FALSE); + self->childSetValue("check_sound", FALSE); + self->childSetValue("check_texture", FALSE); + self->childSetValue("check_snapshot", FALSE); +} + + +///---------------------------------------------------------------------------- +/// LLFloaterInventory +///---------------------------------------------------------------------------- +void LLSaveFolderState::setApply(BOOL apply) +{ + mApply = apply; + // before generating new list of open folders, clear the old one + if(!apply) + { + clearOpenFolders(); + } +} + +void LLSaveFolderState::doFolder(LLFolderViewFolder* folder) +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_DO_FOLDER); + if(mApply) + { + // we're applying the open state + LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener(); + if(!bridge) return; + LLUUID id(bridge->getUUID()); + if(mOpenFolders.find(id) != mOpenFolders.end()) + { + folder->setOpen(TRUE); + } + else + { + // keep selected filter in its current state, this is less jarring to user + if (!folder->isSelected()) + { + folder->setOpen(FALSE); + } + } + } + else + { + // we're recording state at this point + if(folder->isOpen()) + { + LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener(); + if(!bridge) return; + mOpenFolders.insert(bridge->getUUID()); + } + } +} + +LLFloaterInventory::LLFloaterInventory(const LLSD& key) + : LLFloater(key) +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_INIT); + // Menu Callbacks (non contex menus) + mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLFloaterInventory::doToSelected, this, _2)); + mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLFloaterInventory::closeAllFolders, this)); + mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH)); + mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND)); + mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLFloaterInventory::doCreate, this, _2)); +// mCommitCallbackRegistrar.add("Inventory.NewWindow", boost::bind(&LLFloaterInventory::newWindow, this)); + mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLFloaterInventory::toggleFindOptions, this)); + mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLFloaterInventory::resetFilters, this)); + mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLFloaterInventory::setSortBy, this, _2)); + + // Controls + // *TODO: Just use persistant settings for each of these + U32 sort_order = gSavedSettings.getU32("InventorySortOrder"); + BOOL sort_by_name = ! ( sort_order & LLInventoryFilter::SO_DATE ); + BOOL sort_folders_by_name = ( sort_order & LLInventoryFilter::SO_FOLDERS_BY_NAME ); + BOOL sort_system_folders_to_top = ( sort_order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP ); + + gSavedSettings.declareBOOL("Inventory.SortByName", sort_by_name, "Declared in code", FALSE); + gSavedSettings.declareBOOL("Inventory.SortByDate", !sort_by_name, "Declared in code", FALSE); + gSavedSettings.declareBOOL("Inventory.FoldersAlwaysByName", sort_folders_by_name, "Declared in code", FALSE); + gSavedSettings.declareBOOL("Inventory.SystemFoldersToTop", sort_system_folders_to_top, "Declared in code", FALSE); + + mSavedFolderState = new LLSaveFolderState(); + mSavedFolderState->setApply(FALSE); + + //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory.xml"); +} + +BOOL LLFloaterInventory::postBuild() +{ + gInventory.addObserver(this); + + mFilterTabs = getChild("inventory filter tabs"); + mFilterTabs->setCommitCallback(boost::bind(&LLFloaterInventory::onFilterSelected, this)); + + //panel->getFilter()->markDefault(); + + // Set up the default inv. panel/filter settings. + mActivePanel = getChild("All Items"); + if (mActivePanel) + { + // "All Items" is the previous only view, so it gets the InventorySortOrder + mActivePanel->setSortOrder(gSavedSettings.getU32("InventorySortOrder")); + mActivePanel->getFilter()->markDefault(); + mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); + mActivePanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mActivePanel, _1, _2)); + } + LLInventoryPanel* recent_items_panel = getChild("Recent Items"); + if (recent_items_panel) + { + recent_items_panel->setSinceLogoff(TRUE); + recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE); + recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); + recent_items_panel->getFilter()->markDefault(); + recent_items_panel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, recent_items_panel, _1, _2)); + } + + // Now load the stored settings from disk, if available. + std::ostringstream filterSaveName; + filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml"); + llinfos << "LLFloaterInventory::init: reading from " << filterSaveName << llendl; + llifstream file(filterSaveName.str()); + LLSD savedFilterState; + if (file.is_open()) + { + LLSDSerialize::fromXML(savedFilterState, file); + file.close(); + + // Load the persistent "Recent Items" settings. + // Note that the "All Items" settings do not persist. + if(recent_items_panel) + { + if(savedFilterState.has(recent_items_panel->getFilter()->getName())) + { + LLSD recent_items = savedFilterState.get( + recent_items_panel->getFilter()->getName()); + recent_items_panel->getFilter()->fromLLSD(recent_items); + } + } + + } + + + mFilterEditor = getChild("inventory search editor"); + if (mFilterEditor) + { + mFilterEditor->setCommitCallback(boost::bind(&LLFloaterInventory::onFilterEdit, this, _2)); + } + + // *TODO:Get the cost info from the server + const std::string upload_cost("10"); + childSetLabelArg("Upload Image", "[COST]", upload_cost); + childSetLabelArg("Upload Sound", "[COST]", upload_cost); + childSetLabelArg("Upload Animation", "[COST]", upload_cost); + childSetLabelArg("Bulk Upload", "[COST]", upload_cost); + + return TRUE; +} + +// Destroys the object +LLFloaterInventory::~LLFloaterInventory( void ) +{ + // Save the filters state. + LLSD filterRoot; + LLInventoryPanel* all_items_panel = getChild("All Items"); + if (all_items_panel) + { + LLInventoryFilter* filter = all_items_panel->getFilter(); + LLSD filterState; + filter->toLLSD(filterState); + filterRoot[filter->getName()] = filterState; + } + + LLInventoryPanel* recent_items_panel = getChild("Recent Items"); + if (recent_items_panel) + { + LLInventoryFilter* filter = recent_items_panel->getFilter(); + LLSD filterState; + filter->toLLSD(filterState); + filterRoot[filter->getName()] = filterState; + } + + std::ostringstream filterSaveName; + filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml"); + llofstream filtersFile(filterSaveName.str()); + if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile)) + { + llwarns << "Could not write to filters save file " << filterSaveName << llendl; + } + else + filtersFile.close(); + + gInventory.removeObserver(this); + delete mSavedFolderState; +} + +void LLFloaterInventory::draw() +{ + if (LLInventoryModel::isEverythingFetched()) + { + LLLocale locale(LLLocale::USER_LOCALE); + std::ostringstream title; + //title << "Inventory"; + title<getIntegerString(item_count_string, gInventory.getItemCount()); + title << " (" << item_count_string << getString("Items")<<")"; + //TODO:: Translate mFilterText + title << mFilterText; + setTitle(title.str()); + } + LLFloater::draw(); +} + +void LLOpenFilteredFolders::doItem(LLFolderViewItem *item) +{ + if (item->getFiltered()) + { + item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } +} + +void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder) +{ + if (folder->getFiltered() && folder->getParentFolder()) + { + folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } + // if this folder didn't pass the filter, and none of its descendants did + else if (!folder->getFiltered() && !folder->hasFilteredDescendants()) + { + folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_NO); + } +} + +void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item) +{ + if (item->getFiltered() && !mItemSelected) + { + item->getRoot()->setSelection(item, FALSE, FALSE); + if (item->getParentFolder()) + { + item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } + item->getRoot()->scrollToShowSelection(); + mItemSelected = TRUE; + } +} + +void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder) +{ + if (folder->getFiltered() && !mItemSelected) + { + folder->getRoot()->setSelection(folder, FALSE, FALSE); + if (folder->getParentFolder()) + { + folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } + folder->getRoot()->scrollToShowSelection(); + mItemSelected = TRUE; + } +} + +void LLOpenFoldersWithSelection::doItem(LLFolderViewItem *item) +{ + if (item->getParentFolder() && item->isSelected()) + { + item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } +} + +void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder) +{ + if (folder->getParentFolder() && folder->isSelected()) + { + folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } +} + +void LLFloaterInventory::startSearch() +{ + // this forces focus to line editor portion of search editor + if (mFilterEditor) + { + mFilterEditor->focusFirstItem(TRUE); + } +} + +void LLFloaterInventory::onOpen(const LLSD& key) +{ + LLFirstUse::useInventory(); +} + +BOOL LLFloaterInventory::handleKeyHere(KEY key, MASK mask) +{ + LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL; + if (root_folder) + { + // first check for user accepting current search results + if (mFilterEditor + && mFilterEditor->hasFocus() + && (key == KEY_RETURN + || key == KEY_DOWN) + && mask == MASK_NONE) + { + // move focus to inventory proper + mActivePanel->setFocus(TRUE); + root_folder->scrollToShowSelection(); + return TRUE; + } + + if (mActivePanel->hasFocus() && key == KEY_UP) + { + startSearch(); + } + } + + return LLFloater::handleKeyHere(key, mask); + +} + +void LLFloaterInventory::changed(U32 mask) +{ + std::ostringstream title; + //title << "Inventory"; + title<getIntegerString(item_count_string, gInventory.getItemCount()); + title << " ( "<< getString("Fetched") << item_count_string << getString("Items")<<")"; + } + //TODO:: Translate mFilterText + title << mFilterText; + setTitle(title.str()); + +} + +//---------------------------------------------------------------------------- +// menu callbacks + +void LLFloaterInventory::doToSelected(const LLSD& userdata) +{ + getPanel()->getRootFolder()->doToSelected(&gInventory, userdata); +} + +void LLFloaterInventory::closeAllFolders() +{ + getPanel()->getRootFolder()->closeAllFolders(); +} + +void LLFloaterInventory::doCreate(const LLSD& userdata) +{ + menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata); +} + +void LLFloaterInventory::resetFilters() +{ + LLFloaterInventoryFinder *finder = getFinder(); + getActivePanel()->getFilter()->resetDefault(); + if (finder) + { + finder->updateElementsFromFilter(); + } + + setFilterTextFromFilter(); +} + +void LLFloaterInventory::setSortBy(const LLSD& userdata) +{ + std::string sort_field = userdata.asString(); + if (sort_field == "name") + { + U32 order = getActivePanel()->getSortOrder(); + getActivePanel()->setSortOrder( order & ~LLInventoryFilter::SO_DATE ); + + gSavedSettings.setBOOL("Inventory.SortByName", TRUE ); + gSavedSettings.setBOOL("Inventory.SortByDate", FALSE ); + } + else if (sort_field == "date") + { + U32 order = getActivePanel()->getSortOrder(); + getActivePanel()->setSortOrder( order | LLInventoryFilter::SO_DATE ); + + gSavedSettings.setBOOL("Inventory.SortByName", FALSE ); + gSavedSettings.setBOOL("Inventory.SortByDate", TRUE ); + } + else if (sort_field == "foldersalwaysbyname") + { + U32 order = getActivePanel()->getSortOrder(); + if ( order & LLInventoryFilter::SO_FOLDERS_BY_NAME ) + { + order &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME; + + gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", FALSE ); + } + else + { + order |= LLInventoryFilter::SO_FOLDERS_BY_NAME; + + gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", TRUE ); + } + getActivePanel()->setSortOrder( order ); + } + else if (sort_field == "systemfolderstotop") + { + U32 order = getActivePanel()->getSortOrder(); + if ( order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP ) + { + order &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; + + gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", FALSE ); + } + else + { + order |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; + + gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", TRUE ); + } + getActivePanel()->setSortOrder( order ); + } +} + +//---------------------------------------------------------------------------- + +// static +LLFloaterInventory* LLFloaterInventory::showAgentInventory() +{ + LLFloaterInventory* iv = NULL; + if (!gAgent.cameraMouselook()) + { + iv = LLFloaterReg::showTypedInstance("inventory", LLSD()); + } + return iv; +} + +// static +LLFloaterInventory* LLFloaterInventory::getActiveInventory() +{ + LLFloaterInventory* res = NULL; + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + S32 z_min = S32_MAX; + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) + { + LLFloaterInventory* iv = dynamic_cast(*iter); + if (iv) + { + S32 z_order = gFloaterView->getZOrder(iv); + if (z_order < z_min) + { + res = iv; + z_min = z_order; + } + } + } + return res; +} + +// static +void LLFloaterInventory::cleanup() +{ + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end();) + { + LLFloaterInventory* iv = dynamic_cast(*iter++); + if (iv) + { + iv->destroy(); + } + } +} + +void LLFloaterInventory::toggleFindOptions() +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE); + LLFloater *floater = getFinder(); + if (!floater) + { + LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this); + mFinderHandle = finder->getHandle(); + finder->openFloater(); + addDependentFloater(mFinderHandle); + + // start background fetch of folders + gInventory.startBackgroundFetch(); + } + else + { + floater->closeFloater(); + } +} + +// static +BOOL LLFloaterInventory::filtersVisible(void* user_data) +{ + LLFloaterInventory* self = (LLFloaterInventory*)user_data; + if(!self) return FALSE; + + return self->getFinder() != NULL; +} + +void LLFloaterInventory::onClearSearch() +{ + LLFloater *finder = getFinder(); + if (mActivePanel) + { + mActivePanel->setFilterSubString(LLStringUtil::null); + mActivePanel->setFilterTypes(0xffffffff); + } + + if (finder) + { + LLFloaterInventoryFinder::selectAllTypes(finder); + } + + // re-open folders that were initially open + if (mActivePanel) + { + mSavedFolderState->setApply(TRUE); + mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); + LLOpenFoldersWithSelection opener; + mActivePanel->getRootFolder()->applyFunctorRecursively(opener); + mActivePanel->getRootFolder()->scrollToShowSelection(); + } +} + +void LLFloaterInventory::onFilterEdit(const std::string& search_string ) +{ + if (search_string == "") + { + onClearSearch(); + } + if (!mActivePanel) + { + return; + } + + gInventory.startBackgroundFetch(); + + std::string uppercase_search_string = search_string; + LLStringUtil::toUpper(uppercase_search_string); + if (mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty()) + { + // current filter and new filter empty, do nothing + return; + } + + // save current folder open state if no filter currently applied + if (!mActivePanel->getRootFolder()->isFilterModified()) + { + mSavedFolderState->setApply(FALSE); + mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); + } + + // set new filter string + mActivePanel->setFilterSubString(uppercase_search_string); +} + + + //static + BOOL LLFloaterInventory::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward) + { + LLFloaterInventory* active_view = NULL; + + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) + { + LLFloaterInventory* iv = dynamic_cast(*iter); + if (iv) + { + if (gFocusMgr.childHasKeyboardFocus(iv)) + { + active_view = iv; + break; + } + } + } + + if (!active_view) + { + return FALSE; + } + + std::string search_string(find_text); + + if (search_string.empty()) + { + return FALSE; + } + + if (active_view->mActivePanel && + active_view->mActivePanel->getRootFolder()->search(first_item, search_string, backward)) + { + return TRUE; + } + + return FALSE; + } + +void LLFloaterInventory::onFilterSelected() +{ + // Find my index + mActivePanel = (LLInventoryPanel*)childGetVisibleTab("inventory filter tabs"); + + if (!mActivePanel) + { + return; + } + LLInventoryFilter* filter = mActivePanel->getFilter(); + LLFloaterInventoryFinder *finder = getFinder(); + if (finder) + { + finder->changeFilter(filter); + } + if (filter->isActive()) + { + // If our filter is active we may be the first thing requiring a fetch so we better start it here. + gInventory.startBackgroundFetch(); + } + setFilterTextFromFilter(); +} + +BOOL LLFloaterInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + // Check to see if we are auto scrolling from the last frame + LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel(); + BOOL needsToScroll = panel->getScrollableContainer()->needsToScroll(x, y, LLScrollContainer::VERTICAL); + if(mFilterTabs) + { + if(needsToScroll) + { + mFilterTabs->startDragAndDropDelayTimer(); + } + } + + BOOL handled = LLFloater::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + + return handled; +} +const std::string& get_item_icon_name(LLAssetType::EType asset_type, + LLInventoryType::EType inventory_type, + U32 attachment_point, + BOOL item_is_multi ) +{ + EInventoryIcon idx = OBJECT_ICON_NAME; + if ( item_is_multi ) + { + idx = OBJECT_MULTI_ICON_NAME; + } + + switch(asset_type) + { + case LLAssetType::AT_TEXTURE: + if(LLInventoryType::IT_SNAPSHOT == inventory_type) + { + idx = SNAPSHOT_ICON_NAME; + } + else + { + idx = TEXTURE_ICON_NAME; + } + break; + + case LLAssetType::AT_SOUND: + idx = SOUND_ICON_NAME; + break; + case LLAssetType::AT_CALLINGCARD: + if(attachment_point!= 0) + { + idx = CALLINGCARD_ONLINE_ICON_NAME; + } + else + { + idx = CALLINGCARD_OFFLINE_ICON_NAME; + } + break; + case LLAssetType::AT_LANDMARK: + if(attachment_point!= 0) + { + idx = LANDMARK_VISITED_ICON_NAME; + } + else + { + idx = LANDMARK_ICON_NAME; + } + break; + case LLAssetType::AT_SCRIPT: + case LLAssetType::AT_LSL_TEXT: + case LLAssetType::AT_LSL_BYTECODE: + idx = SCRIPT_ICON_NAME; + break; + case LLAssetType::AT_CLOTHING: + idx = CLOTHING_ICON_NAME; + case LLAssetType::AT_BODYPART : + if(LLAssetType::AT_BODYPART == asset_type) + { + idx = BODYPART_ICON_NAME; + } + switch(LLInventoryItem::II_FLAGS_WEARABLES_MASK & attachment_point) + { + case WT_SHAPE: + idx = BODYPART_SHAPE_ICON_NAME; + break; + case WT_SKIN: + idx = BODYPART_SKIN_ICON_NAME; + break; + case WT_HAIR: + idx = BODYPART_HAIR_ICON_NAME; + break; + case WT_EYES: + idx = BODYPART_EYES_ICON_NAME; + break; + case WT_SHIRT: + idx = CLOTHING_SHIRT_ICON_NAME; + break; + case WT_PANTS: + idx = CLOTHING_PANTS_ICON_NAME; + break; + case WT_SHOES: + idx = CLOTHING_SHOES_ICON_NAME; + break; + case WT_SOCKS: + idx = CLOTHING_SOCKS_ICON_NAME; + break; + case WT_JACKET: + idx = CLOTHING_JACKET_ICON_NAME; + break; + case WT_GLOVES: + idx = CLOTHING_GLOVES_ICON_NAME; + break; + case WT_UNDERSHIRT: + idx = CLOTHING_UNDERSHIRT_ICON_NAME; + break; + case WT_UNDERPANTS: + idx = CLOTHING_UNDERPANTS_ICON_NAME; + break; + case WT_SKIRT: + idx = CLOTHING_SKIRT_ICON_NAME; + break; + case WT_ALPHA: + idx = CLOTHING_ALPHA_ICON_NAME; + break; + case WT_TATTOO: + idx = CLOTHING_TATTOO_ICON_NAME; + break; + default: + // no-op, go with choice above + break; + } + break; + case LLAssetType::AT_NOTECARD: + idx = NOTECARD_ICON_NAME; + break; + case LLAssetType::AT_ANIMATION: + idx = ANIMATION_ICON_NAME; + break; + case LLAssetType::AT_GESTURE: + idx = GESTURE_ICON_NAME; + break; + case LLAssetType::AT_FAVORITE: + //TODO - need bette idx + idx = LANDMARK_ICON_NAME; + break; + case LLAssetType::AT_LINK: + idx = BODYPART_ICON_NAME; // Seraph replace this with broken item link icon + break; + case LLAssetType::AT_LINK_FOLDER: + idx = BODYPART_ICON_NAME; // Seraph replace this with broken folder link icon + break; + default: + break; + } + + return ICON_NAME[idx]; +} + +LLUIImagePtr get_item_icon(LLAssetType::EType asset_type, + LLInventoryType::EType inventory_type, + U32 attachment_point, + BOOL item_is_multi) +{ + const std::string& icon_name = get_item_icon_name(asset_type, inventory_type, attachment_point, item_is_multi ); + return LLUI::getUIImage(icon_name); +} + +const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder"); +const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder"); +const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string(""); + +LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) +: LLPanel(p), + mInventoryObserver(NULL), + mFolders(NULL), + mScroller(NULL), + mSortOrderSetting(p.sort_order_setting), + mInventory(p.inventory), + mAllowMultiSelect(p.allow_multi_select) +{ + // contex menu callbacks + mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2)); + mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH)); + mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND)); + mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLInventoryPanel::doCreate, this, _2)); + mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2)); + mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this)); + + setBackgroundColor(LLUIColorTable::instance().getColor("InventoryBackgroundColor")); + setBackgroundVisible(TRUE); + setBackgroundOpaque(TRUE); +} + +BOOL LLInventoryPanel::postBuild() +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD); + + mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves + + // create root folder + { + LLRect folder_rect(0, + 0, + getRect().getWidth(), + 0); + LLFolderView::Params p; + p.name = getName(); + p.rect = folder_rect; + p.parent_panel = this; + mFolders = LLUICtrlFactory::create(p); + mFolders->setAllowMultiSelect(mAllowMultiSelect); + } + + mCommitCallbackRegistrar.popScope(); + + mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar); + + // scroller + { + LLRect scroller_view_rect = getRect(); + scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); + LLScrollContainer::Params p; + p.name("Inventory Scroller"); + p.rect(scroller_view_rect); + p.follows.flags(FOLLOWS_ALL); + p.reserve_scroll_corner(true); + p.tab_stop(true); + mScroller = LLUICtrlFactory::create(p); + } + addChild(mScroller); + mScroller->addChild(mFolders); + + mFolders->setScrollContainer(mScroller); + + // set up the callbacks from the inventory we're viewing, and then + // build everything. + mInventoryObserver = new LLInventoryPanelObserver(this); + mInventory->addObserver(mInventoryObserver); + rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD); + + // bit of a hack to make sure the inventory is open. + mFolders->openFolder(std::string("My Inventory")); + + if (mSortOrderSetting != INHERIT_SORT_ORDER) + { + setSortOrder(gSavedSettings.getU32(mSortOrderSetting)); + } + else + { + setSortOrder(gSavedSettings.getU32(DEFAULT_SORT_ORDER)); + } + mFolders->setSortOrder(mFolders->getFilter()->getSortOrder()); + + return TRUE; +} + +LLInventoryPanel::~LLInventoryPanel() +{ + // should this be a global setting? + if (mFolders) + { + U32 sort_order = mFolders->getSortOrder(); + if (mSortOrderSetting != INHERIT_SORT_ORDER) + { + gSavedSettings.setU32(mSortOrderSetting, sort_order); + } + } + + // LLView destructor will take care of the sub-views. + mInventory->removeObserver(mInventoryObserver); + delete mInventoryObserver; + mScroller = NULL; +} + + LLMemType mt(LLMemType::MTYPE_INVENTORY_FROM_XML); +void LLInventoryPanel::draw() +{ + // select the desired item (in case it wasn't loaded when the selection was requested) + mFolders->updateSelection(); + LLPanel::draw(); +} + +void LLInventoryPanel::setFilterTypes(U32 filter_types) +{ + mFolders->getFilter()->setFilterTypes(filter_types); +} + +void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask) +{ + mFolders->getFilter()->setFilterPermissions(filter_perm_mask); +} + +void LLInventoryPanel::setFilterSubString(const std::string& string) +{ + mFolders->getFilter()->setFilterSubString(string); +} + +void LLInventoryPanel::setSortOrder(U32 order) +{ + mFolders->getFilter()->setSortOrder(order); + if (mFolders->getFilter()->isModified()) + { + mFolders->setSortOrder(order); + // try to keep selection onscreen, even if it wasn't to start with + mFolders->scrollToShowSelection(); + } +} + +void LLInventoryPanel::setSinceLogoff(BOOL sl) +{ + mFolders->getFilter()->setDateRangeLastLogoff(sl); +} + +void LLInventoryPanel::setHoursAgo(U32 hours) +{ + mFolders->getFilter()->setHoursAgo(hours); +} + +void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show) +{ + mFolders->getFilter()->setShowFolderState(show); +} + +LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState() +{ + return mFolders->getFilter()->getShowFolderState(); +} + +void LLInventoryPanel::modelChanged(U32 mask) +{ + LLFastTimer t2(LLFastTimer::FTM_REFRESH); + + bool handled = false; + if(mask & LLInventoryObserver::LABEL) + { + handled = true; + // label change - empty out the display name for each object + // in this change set. + const std::set& changed_items = gInventory.getChangedIDs(); + std::set::const_iterator id_it = changed_items.begin(); + std::set::const_iterator id_end = changed_items.end(); + LLFolderViewItem* view = NULL; + LLInvFVBridge* bridge = NULL; + for (;id_it != id_end; ++id_it) + { + view = mFolders->getItemByID(*id_it); + if(view) + { + // request refresh on this item (also flags for filtering) + bridge = (LLInvFVBridge*)view->getListener(); + if(bridge) + { // Clear the display name first, so it gets properly re-built during refresh() + bridge->clearDisplayName(); + } + view->refresh(); + } + } + } + if((mask & (LLInventoryObserver::STRUCTURE + | LLInventoryObserver::ADD + | LLInventoryObserver::REMOVE)) != 0) + { + handled = true; + // Record which folders are open by uuid. + LLInventoryModel* model = getModel(); + if (model) + { + const std::set& changed_items = gInventory.getChangedIDs(); + + std::set::const_iterator id_it = changed_items.begin(); + std::set::const_iterator id_end = changed_items.end(); + for (;id_it != id_end; ++id_it) + { + // sync view with model + LLInventoryObject* model_item = model->getObject(*id_it); + LLFolderViewItem* view_item = mFolders->getItemByID(*id_it); + + if (model_item) + { + if (!view_item) + { + // this object was just created, need to build a view for it + if ((mask & LLInventoryObserver::ADD) != LLInventoryObserver::ADD) + { + llwarns << *id_it << " is in model but not in view, but ADD flag not set" << llendl; + } + buildNewViews(*id_it); + + // select any newly created object + // that has the auto rename at top of folder + // root set + if(mFolders->getRoot()->needsAutoRename()) + { + setSelection(*id_it, FALSE); + } + } + else + { + // this object was probably moved, check its parent + if ((mask & LLInventoryObserver::STRUCTURE) != LLInventoryObserver::STRUCTURE) + { + llwarns << *id_it << " is in model and in view, but STRUCTURE flag not set" << llendl; + } + + LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolders->getItemByID(model_item->getParentUUID()); + if (view_item->getParentFolder() != new_parent) + { + view_item->getParentFolder()->extractItem(view_item); + view_item->addToFolder(new_parent, mFolders); + } + } + } + else + { + if (view_item) + { + if ((mask & LLInventoryObserver::REMOVE) != LLInventoryObserver::REMOVE) + { + llwarns << *id_it << " is not in model but in view, but REMOVE flag not set" << llendl; + } + // item in view but not model, need to delete view + view_item->destroyView(); + } + else + { + llwarns << *id_it << "Item does not exist in either view or model, but notification triggered" << llendl; + } + } + } + } + } + + if (!handled) + { + // it's a small change that only requires a refresh. + // *TODO: figure out a more efficient way to do the refresh + // since it is expensive on large inventories + mFolders->refresh(); + } +} + +void LLInventoryPanel::rebuildViewsFor(const LLUUID& id, U32 mask) +{ + LLFolderViewItem* old_view = NULL; + + // get old LLFolderViewItem + old_view = mFolders->getItemByID(id); + if (old_view && id.notNull()) + { + old_view->destroyView(); + } + + buildNewViews(id); +} + +void LLInventoryPanel::buildNewViews(const LLUUID& id) +{ + LLMemType mt(LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS); + LLFolderViewItem* itemp = NULL; + LLInventoryObject* objectp = gInventory.getObject(id); + + if (objectp) + { + if (objectp->getType() <= LLAssetType::AT_NONE || + objectp->getType() >= LLAssetType::AT_COUNT) + { + llwarns << "LLInventoryPanel::buildNewViews called with objectp->mType == " + << ((S32) objectp->getType()) + << " (shouldn't happen)" << llendl; + } + else if (objectp->getType() == LLAssetType::AT_CATEGORY && + objectp->getActualType() != LLAssetType::AT_LINK_FOLDER) + { + LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(objectp->getType(), + objectp->getType(), + LLInventoryType::IT_CATEGORY, + this, + objectp->getUUID()); + + if (new_listener) + { + LLFolderViewFolder::Params p; + p.name = new_listener->getDisplayName(); + p.icon = new_listener->getIcon(); + p.root = mFolders; + p.listener = new_listener; + LLFolderViewFolder* folderp = LLUICtrlFactory::create(p); + + folderp->setItemSortOrder(mFolders->getSortOrder()); + itemp = folderp; + } + } + else + { + // Build new view for item + LLInventoryItem* item = (LLInventoryItem*)objectp; + LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(item->getType(), + item->getActualType(), + item->getInventoryType(), + this, + item->getUUID(), + item->getFlags()); + + if (new_listener) + { + LLFolderViewItem::Params params; + params.name(new_listener->getDisplayName()); + params.icon(new_listener->getIcon()); + params.creation_date(new_listener->getCreationDate()); + params.root(mFolders); + params.listener(new_listener); + params.rect(LLRect (0, 0, 0, 0)); + itemp = LLUICtrlFactory::create (params); + } + } + + LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(objectp->getParentUUID()); + + if (itemp) + { + if (parent_folder) + { + itemp->addToFolder(parent_folder, mFolders); + } + else + { + llwarns << "Couldn't find parent folder for child " << itemp->getLabel() << llendl; + delete itemp; + } + } + } + if ((id.isNull() || + (objectp && objectp->getType() == LLAssetType::AT_CATEGORY))) + { + LLViewerInventoryCategory::cat_array_t* categories; + LLViewerInventoryItem::item_array_t* items; + + mInventory->lockDirectDescendentArrays(id, categories, items); + if(categories) + { + S32 count = categories->count(); + for(S32 i = 0; i < count; ++i) + { + LLInventoryCategory* cat = categories->get(i); + buildNewViews(cat->getUUID()); + } + } + if(items) + { + S32 count = items->count(); + for(S32 i = 0; i < count; ++i) + { + LLInventoryItem* item = items->get(i); + buildNewViews(item->getUUID()); + } + } + mInventory->unlockDirectDescendentArrays(id); + } +} + +struct LLConfirmPurgeData +{ + LLUUID mID; + LLInventoryModel* mModel; +}; + +class LLIsNotWorn : public LLInventoryCollectFunctor +{ +public: + LLIsNotWorn() {} + virtual ~LLIsNotWorn() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item) + { + return !gAgentWearables.isWearingItem(item->getUUID()); + } +}; + +class LLOpenFolderByID : public LLFolderViewFunctor +{ +public: + LLOpenFolderByID(const LLUUID& id) : mID(id) {} + virtual ~LLOpenFolderByID() {} + virtual void doFolder(LLFolderViewFolder* folder) + { + if (folder->getListener() && folder->getListener()->getUUID() == mID) folder->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); + } + virtual void doItem(LLFolderViewItem* item) {} +protected: + const LLUUID& mID; +}; + + +void LLInventoryPanel::openSelected() +{ + LLFolderViewItem* folder_item = mFolders->getCurSelectedItem(); + if(!folder_item) return; + LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener(); + if(!bridge) return; + bridge->openItem(); +} + +BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask) +{ + BOOL handled = LLView::handleHover(x, y, mask); + if(handled) + { + ECursorType cursor = getWindow()->getCursor(); + if (LLInventoryModel::backgroundFetchActive() && cursor == UI_CURSOR_ARROW) + { + // replace arrow cursor with arrow and hourglass cursor + getWindow()->setCursor(UI_CURSOR_WORKING); + } + } + else + { + getWindow()->setCursor(UI_CURSOR_ARROW); + } + return TRUE; +} + +BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + + BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + + if (handled) + { + mFolders->setDragAndDropThisFrame(); + } + + return handled; +} + +void LLInventoryPanel::onFocusLost() +{ + // inventory no longer handles cut/copy/paste/delete + if (LLEditMenuHandler::gEditMenuHandler == mFolders) + { + LLEditMenuHandler::gEditMenuHandler = NULL; + } + + LLPanel::onFocusLost(); +} + +void LLInventoryPanel::onFocusReceived() +{ + // inventory now handles cut/copy/paste/delete + LLEditMenuHandler::gEditMenuHandler = mFolders; + + LLPanel::onFocusReceived(); +} + + +void LLInventoryPanel::openAllFolders() +{ + mFolders->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN); + mFolders->arrangeAll(); +} + +void LLInventoryPanel::openDefaultFolderForType(LLAssetType::EType type) +{ + LLUUID category_id = mInventory->findCategoryUUIDForType(type); + LLOpenFolderByID opener(category_id); + mFolders->applyFunctorRecursively(opener); +} + +void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus) +{ + mFolders->setSelectionByID(obj_id, take_keyboard_focus); +} + +void LLInventoryPanel::clearSelection() +{ + mFolders->clearSelection(); +} + +void LLInventoryPanel::onSelectionChange(const std::deque& items, BOOL user_action) +{ + LLFolderView* fv = getRootFolder(); + if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename + { + fv->setNeedsAutoRename(FALSE); + if (items.size()) // new asset is visible and selected + { + fv->startRenamingSelectedItem(); + } + } +} + +//---------------------------------------------------------------------------- + +void LLInventoryPanel::doToSelected(const LLSD& userdata) +{ + mFolders->doToSelected(&gInventory, userdata); +} + +void LLInventoryPanel::doCreate(const LLSD& userdata) +{ + menu_create_inventory_item(mFolders, LLFolderBridge::sSelf, userdata); +} + +bool LLInventoryPanel::beginIMSession() +{ + std::set selected_items; + mFolders->getSelectionList(selected_items); + + std::string name; + static int session_num = 1; + + LLDynamicArray members; + EInstantMessage type = IM_SESSION_CONFERENCE_START; + + std::set::const_iterator iter; + for (iter = selected_items.begin(); iter != selected_items.end(); iter++) + { + + LLUUID item = *iter; + LLFolderViewItem* folder_item = mFolders->getItemByID(item); + + if(folder_item) + { + LLFolderViewEventListener* fve_listener = folder_item->getListener(); + if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY)) + { + + LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getListener(); + if(!bridge) return true; + LLViewerInventoryCategory* cat = bridge->getCategory(); + if(!cat) return true; + name = cat->getName(); + LLUniqueBuddyCollector is_buddy; + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + gInventory.collectDescendentsIf(bridge->getUUID(), + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + is_buddy); + S32 count = item_array.count(); + if(count > 0) + { + LLFloaterReg::showInstance("communicate"); + // create the session + LLAvatarTracker& at = LLAvatarTracker::instance(); + LLUUID id; + for(S32 i = 0; i < count; ++i) + { + id = item_array.get(i)->getCreatorUUID(); + if(at.isBuddyOnline(id)) + { + members.put(id); + } + } + } + } + else + { + LLFolderViewItem* folder_item = mFolders->getItemByID(item); + if(!folder_item) return true; + LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getListener(); + + if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD) + { + LLInventoryItem* inv_item = gInventory.getItem(listenerp->getUUID()); + + if (inv_item) + { + LLAvatarTracker& at = LLAvatarTracker::instance(); + LLUUID id = inv_item->getCreatorUUID(); + + if(at.isBuddyOnline(id)) + { + members.put(id); + } + } + } //if IT_CALLINGCARD + } //if !IT_CATEGORY + } + } //for selected_items + + // the session_id is randomly generated UUID which will be replaced later + // with a server side generated number + + if (name.empty()) + { + name = llformat("Session %d", session_num++); + } + + gIMMgr->addSession(name, type, members[0], members); + + return true; +} + +bool LLInventoryPanel::attachObject(const LLSD& userdata) +{ + std::set selected_items; + mFolders->getSelectionList(selected_items); + LLUUID id = *selected_items.begin(); + + std::string joint_name = userdata.asString(); + LLVOAvatar *avatarp = static_cast(gAgent.getAvatarObject()); + LLViewerJointAttachment* attachmentp = NULL; + for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); + iter != avatarp->mAttachmentPoints.end(); ) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if (attachment->getName() == joint_name) + { + attachmentp = attachment; + break; + } + } + if (attachmentp == NULL) + { + return true; + } + LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(id); + + if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID())) + { + rez_attachment(item, attachmentp); + } + else if(item && item->isComplete()) + { + // must be in library. copy it to our inventory and put it on. + LLPointer cb = new RezAttachmentCallback(attachmentp); + copy_inventory_item(gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + LLUUID::null, + std::string(), + cb); + } + gFocusMgr.setKeyboardFocus(NULL); + + return true; +} + + +//---------------------------------------------------------------------------- + +// static DEBUG ONLY: +void LLInventoryPanel::dumpSelectionInformation(void* user_data) +{ + LLInventoryPanel* iv = (LLInventoryPanel*)user_data; + iv->mFolders->dumpSelectionInformation(); +} + +BOOL LLInventoryPanel::getSinceLogoff() +{ + return mFolders->getFilter()->isSinceLogoff(); +} + +void example_param_block_usage() +{ + LLInventoryPanel::Params param_block; + param_block.name(std::string("inventory")); + + param_block.sort_order_setting(LLInventoryPanel::RECENTITEMS_SORT_ORDER); + param_block.allow_multi_select(true); + param_block.filter(LLInventoryPanel::Filter() + .sort_order(1) + .types(0xffff0000)); + param_block.inventory(&gInventory); + param_block.has_border(true); + + LLUICtrlFactory::create(param_block); + + param_block = LLInventoryPanel::Params(); + param_block.name(std::string("inventory")); + + //LLSD param_block_sd; + //param_block_sd["sort_order_setting"] = LLInventoryPanel::RECENTITEMS_SORT_ORDER; + //param_block_sd["allow_multi_select"] = true; + //param_block_sd["filter"]["sort_order"] = 1; + //param_block_sd["filter"]["types"] = (S32)0xffff0000; + //param_block_sd["has_border"] = true; + + //LLInitParam::LLSDParser(param_block_sd).parse(param_block); + + LLUICtrlFactory::create(param_block); +} diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h new file mode 100644 index 0000000000..734ab5032e --- /dev/null +++ b/indra/newview/llfloaterinventory.h @@ -0,0 +1,362 @@ +/** + * @file llfloaterinventory.h + * @brief LLFloaterInventory, LLInventoryFolder, and LLInventoryItem + * class definition + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLINVENTORYVIEW_H +#define LL_LLINVENTORYVIEW_H + +#include "llassetstorage.h" +#include "lldarray.h" +#include "llfloater.h" +#include "llinventory.h" +#include "llinventoryfilter.h" +#include "llfolderview.h" +#include "llinventorymodel.h" +#include "lluictrlfactory.h" +#include + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFloaterInventory +// +// This is the agent inventory _floater_. +// It deals with the buttons and views used to navigate as +// well as controls the behavior of the overall object. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLFolderViewItem; +class LLInventoryFilter; +class LLInventoryModel; +class LLInvFVBridge; +class LLMenuBarGL; +class LLCheckBoxCtrl; +class LLSpinCtrl; +class LLScrollContainer; +class LLTextBox; +class LLIconCtrl; +class LLSaveFolderState; +class LLFilterEditor; +class LLTabContainer; + +class LLInventoryPanel : public LLPanel +{ +public: + static const std::string DEFAULT_SORT_ORDER; + static const std::string RECENTITEMS_SORT_ORDER; + static const std::string INHERIT_SORT_ORDER; + + struct Filter : public LLInitParam::Block + { + Optional sort_order; + Optional types; + Optional search_string; + + Filter() + : sort_order("sort_order"), + types("types", 0xffffffff), + search_string("search_string") + {} + }; + + struct Params + : public LLInitParam::Block + { + Optional sort_order_setting; + Optional inventory; + Optional allow_multi_select; + Optional filter; + + Params() + : sort_order_setting("sort_order_setting"), + inventory("", &gInventory), + allow_multi_select("allow_multi_select", true), + filter("filter") + {} + }; + +protected: + LLInventoryPanel(const Params&); + friend class LLUICtrlFactory; + +public: + ~LLInventoryPanel(); + + LLInventoryModel* getModel() { return mInventory; } + + BOOL postBuild(); + + // LLView methods + void draw(); + BOOL handleHover(S32 x, S32 y, MASK mask); + BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + // LLUICtrl methods + /*virtual*/ void onFocusLost(); + /*virtual*/ void onFocusReceived(); + + // Call this method to set the selection. + void openAllFolders(); + void openDefaultFolderForType(LLAssetType::EType); + void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus); + void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); } + void clearSelection(); + LLInventoryFilter* getFilter() { return mFolders->getFilter(); } + void setFilterTypes(U32 filter); + U32 getFilterTypes() const { return mFolders->getFilterTypes(); } + void setFilterPermMask(PermissionMask filter_perm_mask); + U32 getFilterPermMask() const { return mFolders->getFilterPermissions(); } + void setFilterSubString(const std::string& string); + const std::string getFilterSubString() { return mFolders->getFilterSubString(); } + void setSortOrder(U32 order); + U32 getSortOrder() { return mFolders->getSortOrder(); } + void setSinceLogoff(BOOL sl); + void setHoursAgo(U32 hours); + BOOL getSinceLogoff(); + + void setShowFolderState(LLInventoryFilter::EFolderShow show); + LLInventoryFilter::EFolderShow getShowFolderState(); + void setAllowMultiSelect(BOOL allow) { mFolders->setAllowMultiSelect(allow); } + // This method is called when something has changed about the inventory. + void modelChanged(U32 mask); + LLFolderView* getRootFolder() { return mFolders; } + LLScrollContainer* getScrollableContainer() { return mScroller; } + + void onSelectionChange(const std::deque &items, BOOL user_action); + + // Callbacks + void doToSelected(const LLSD& userdata); + void doCreate(const LLSD& userdata); + bool beginIMSession(); + bool attachObject(const LLSD& userdata); + + // DEBUG ONLY: + static void dumpSelectionInformation(void* user_data); + + void openSelected(); + void unSelectAll() { mFolders->setSelection(NULL, FALSE, FALSE); } + +protected: + // Given the id and the parent, build all of the folder views. + void rebuildViewsFor(const LLUUID& id, U32 mask); + void buildNewViews(const LLUUID& id); + +protected: + LLInventoryModel* mInventory; + LLInventoryObserver* mInventoryObserver; + LLFolderView* mFolders; + LLScrollContainer* mScroller; + BOOL mAllowMultiSelect; + std::string mSortOrderSetting; +}; + +class LLFloaterInventory; + +class LLFloaterInventoryFinder : public LLFloater +{ +public: + LLFloaterInventoryFinder( LLFloaterInventory* inventory_view); + virtual void draw(); + /*virtual*/ BOOL postBuild(); + void changeFilter(LLInventoryFilter* filter); + void updateElementsFromFilter(); + BOOL getCheckShowEmpty(); + BOOL getCheckSinceLogoff(); + + static void onTimeAgo(LLUICtrl*, void *); + static void onCheckSinceLogoff(LLUICtrl*, void *); + static void onCloseBtn(void* user_data); + static void selectAllTypes(void* user_data); + static void selectNoTypes(void* user_data); + +protected: + LLFloaterInventory* mFloaterInventory; + LLSpinCtrl* mSpinSinceDays; + LLSpinCtrl* mSpinSinceHours; + LLInventoryFilter* mFilter; +}; + +class LLFloaterInventory : public LLFloater, LLInventoryObserver +{ +friend class LLFloaterInventoryFinder; + +public: + LLFloaterInventory(const LLSD& key); + ~LLFloaterInventory(); + + /*virtual*/ void changed(U32 mask); + + BOOL postBuild(); + + // + // Misc functions + // + void setFilterTextFromFilter() { mFilterText = mActivePanel->getFilter()->getFilterText(); } + void startSearch(); + + // This method makes sure that an inventory view exists, is + // visible, and has focus. The view chosen is returned. + static LLFloaterInventory* showAgentInventory(); + + // Return the active inventory view if there is one. Active is + // defined as the inventory that is the closest to the front, and + // is visible. + static LLFloaterInventory* getActiveInventory(); + + // This method calls showAgentInventory() if no views are visible, + // or hides/destroyes them all if any are visible. + static void toggleVisibility(); + static void toggleVisibility(void*) { toggleVisibility(); } + + // Final cleanup, destroy all open inventory views. + static void cleanup(); + + // LLView & LLFloater functionality + virtual void onOpen(const LLSD& key); + virtual void draw(); + virtual BOOL handleKeyHere(KEY key, MASK mask); + + BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + + + LLInventoryPanel* getPanel() { return mActivePanel; } + LLInventoryPanel* getActivePanel() { return mActivePanel; } + + static BOOL filtersVisible(void* user_data); + void onClearSearch(); + static void onFoldersByName(void *user_data); + static BOOL checkFoldersByName(void *user_data); + void onFilterEdit(const std::string& search_string ); + static BOOL incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward); + void onFilterSelected(); + + const std::string getFilterSubString() { return mActivePanel->getFilterSubString(); } + void setFilterSubString(const std::string& string) { mActivePanel->setFilterSubString(string); } + + // menu callbacks + void doToSelected(const LLSD& userdata); + void closeAllFolders(); + void doCreate(const LLSD& userdata); + void resetFilters(); + void setSortBy(const LLSD& userdata); + + // HACK: Until we can route this info through the instant message hierarchy + static BOOL sWearNewClothing; + static LLUUID sWearNewClothingTransactionID; // wear all clothing in this transaction + + void toggleFindOptions(); + + LLFloaterInventoryFinder* getFinder() { return (LLFloaterInventoryFinder*)mFinderHandle.get(); } + +protected: + LLFilterEditor* mFilterEditor; + LLTabContainer* mFilterTabs; + LLHandle mFinderHandle; + LLInventoryPanel* mActivePanel; + LLSaveFolderState* mSavedFolderState; + + std::string mFilterText; +}; + +class LLSelectFirstFilteredItem : public LLFolderViewFunctor +{ +public: + LLSelectFirstFilteredItem() : mItemSelected(FALSE) {} + virtual ~LLSelectFirstFilteredItem() {} + virtual void doFolder(LLFolderViewFolder* folder); + virtual void doItem(LLFolderViewItem* item); + BOOL wasItemSelected() { return mItemSelected; } +protected: + BOOL mItemSelected; +}; + +class LLOpenFilteredFolders : public LLFolderViewFunctor +{ +public: + LLOpenFilteredFolders() {} + virtual ~LLOpenFilteredFolders() {} + virtual void doFolder(LLFolderViewFolder* folder); + virtual void doItem(LLFolderViewItem* item); +}; + +class LLSaveFolderState : public LLFolderViewFunctor +{ +public: + LLSaveFolderState() : mApply(FALSE) {} + virtual ~LLSaveFolderState() {} + virtual void doFolder(LLFolderViewFolder* folder); + virtual void doItem(LLFolderViewItem* item) {} + void setApply(BOOL apply); + void clearOpenFolders() { mOpenFolders.clear(); } +protected: + std::set mOpenFolders; + BOOL mApply; +}; + +class LLOpenFoldersWithSelection : public LLFolderViewFunctor +{ +public: + LLOpenFoldersWithSelection() {} + virtual ~LLOpenFoldersWithSelection() {} + virtual void doFolder(LLFolderViewFolder* folder); + virtual void doItem(LLFolderViewItem* item); +}; + +///---------------------------------------------------------------------------- +/// Function declarations, constants, enums, and typedefs +///---------------------------------------------------------------------------- + +// useful functions with the inventory view + +class LLInventoryCategory; +class LLInventoryItem; + +const std::string& get_item_icon_name(LLAssetType::EType asset_type, + LLInventoryType::EType inventory_type, + U32 attachment_point, + BOOL item_is_multi ); + +LLUIImagePtr get_item_icon(LLAssetType::EType asset_type, + LLInventoryType::EType inventory_type, + U32 attachment_point, + BOOL item_is_multi ); + +#endif // LL_LLINVENTORYVIEW_H + + + diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index c73218cd0f..06fe2a84c8 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -48,7 +48,7 @@ #include "llcheckboxctrl.h" LLFloaterJoystick::LLFloaterJoystick(const LLSD& data) - : LLFloater() + : LLFloater(data) { //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_joystick.xml"); diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h index 9c66b3a895..f3559c28e9 100644 --- a/indra/newview/llfloaterjoystick.h +++ b/indra/newview/llfloaterjoystick.h @@ -38,11 +38,11 @@ class LLCheckBoxCtrl; -class LLFloaterJoystick : public LLFloater, public LLFloaterSingleton +class LLFloaterJoystick : public LLFloater { + friend class LLFloaterReg; + public: - LLFloaterJoystick(const LLSD& data); - virtual ~LLFloaterJoystick(); virtual BOOL postBuild(); virtual void refresh(); @@ -52,6 +52,10 @@ public: static void setSNDefaults(); private: + + LLFloaterJoystick(const LLSD& data); + virtual ~LLFloaterJoystick(); + static void onCommitJoystickEnabled(LLUICtrl*, void*); static void onClickRestoreSNDefaults(void*); static void onClickCancel(void*); diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp index 82deaef4a9..da6dceb149 100644 --- a/indra/newview/llfloaterlagmeter.cpp +++ b/indra/newview/llfloaterlagmeter.cpp @@ -36,7 +36,7 @@ #include "lluictrlfactory.h" #include "llviewerstats.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llviewercontrol.h" #include "llappviewer.h" @@ -51,7 +51,7 @@ const std::string LAG_WARNING_IMAGE_NAME = "lag_status_warning.tga"; const std::string LAG_GOOD_IMAGE_NAME = "lag_status_good.tga"; LLFloaterLagMeter::LLFloaterLagMeter(const LLSD& key) - : LLFloater() + : LLFloater(key) { // LLUICtrlFactory::getInstance()->buildFloater(this, "floater_lagmeter.xml"); mCommitCallbackRegistrar.add("LagMeter.ClickShrink", boost::bind(&LLFloaterLagMeter::onClickShrink, this)); @@ -185,7 +185,7 @@ void LLFloaterLagMeter::determineClient() { mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) ); } - else if((BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes)) > LLViewerImage::sMaxBoundTextureMemInMegaBytes) + else if((BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes)) > LLViewerTexture::sMaxBoundTextureMemInMegaBytes) { mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) ); } diff --git a/indra/newview/llfloaterlagmeter.h b/indra/newview/llfloaterlagmeter.h index 6d2086839e..592630636a 100644 --- a/indra/newview/llfloaterlagmeter.h +++ b/indra/newview/llfloaterlagmeter.h @@ -37,18 +37,17 @@ class LLTextBox; -class LLFloaterLagMeter : public LLFloater, public LLFloaterSingleton +class LLFloaterLagMeter : public LLFloater { - friend class LLUISingleton >; + friend class LLFloaterReg; public: - LLFloaterLagMeter(const LLSD& key); - /*virtual*/ ~LLFloaterLagMeter(); - /*virtual*/ void draw(); /*virtual*/ BOOL postBuild(); private: - + + LLFloaterLagMeter(const LLSD& key); + /*virtual*/ ~LLFloaterLagMeter(); void determineClient(); void determineNetwork(); void determineServer(); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index f3275913e4..63ac44da4f 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -52,7 +52,7 @@ #include "llfloaterauction.h" #include "llfloatergroups.h" #include "llfloatergroupinfo.h" -#include "llfriendactions.h" +#include "llavataractions.h" #include "lllineeditor.h" #include "llnamelistctrl.h" #include "llnotify.h" @@ -68,7 +68,7 @@ #include "lltexturectrl.h" #include "lluiconstants.h" #include "lluictrlfactory.h" -#include "llviewerimagelist.h" // LLUIImageList +#include "llviewertexturelist.h" // LLUIImageList #include "llviewermessage.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" @@ -149,23 +149,50 @@ void send_parcel_select_objects(S32 parcel_local_id, S32 return_type, //static LLPanelLandObjects* LLFloaterLand::getCurrentPanelLandObjects() { - return LLFloaterLand::getInstance()->mPanelObjects; + LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance("about_land"); + if(land_instance) + { + return land_instance->mPanelObjects; + } + else + { + return NULL; + } } //static LLPanelLandCovenant* LLFloaterLand::getCurrentPanelLandCovenant() { - return LLFloaterLand::getInstance()->mPanelCovenant; + LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance("about_land"); + if(land_instance) + { + return land_instance->mPanelCovenant; + } + else + { + return NULL; + } } // static void LLFloaterLand::refreshAll() { - LLFloaterLand::getInstance()->refresh(); + LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance("about_land"); + if(land_instance) + { + land_instance->refresh(); + } } void LLFloaterLand::onOpen(const LLSD& key) { + // moved from triggering show instance in llviwermenu.cpp + + if (LLViewerParcelMgr::getInstance()->selectionEmpty()) + { + LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal()); + } + // Done automatically when the selected parcel's properties arrive // (and hence we have the local id). // LLViewerParcelMgr::getInstance()->sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_RENTER); @@ -177,26 +204,21 @@ void LLFloaterLand::onOpen(const LLSD& key) refresh(); } - -// virtual -void LLFloaterLand::onClose(bool app_quitting) +void LLFloaterLand::onVisibilityChange(const LLSD& visible) { - LLViewerParcelMgr::getInstance()->removeObserver( sObserver ); - delete sObserver; - sObserver = NULL; + if (!visible.asBoolean()) + { + // Might have been showing owned objects + LLSelectMgr::getInstance()->unhighlightAll(); - // Might have been showing owned objects - LLSelectMgr::getInstance()->unhighlightAll(); - - // Save which panel we had open - sLastTab = mTabLand->getCurrentPanelIndex(); - - destroy(); + // Save which panel we had open + sLastTab = mTabLand->getCurrentPanelIndex(); + } } LLFloaterLand::LLFloaterLand(const LLSD& seed) -: LLFloater() +: LLFloater(seed) { mFactoryMap["land_general_panel"] = LLCallbackMap(createPanelLandGeneral, this); mFactoryMap["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this); @@ -205,14 +227,16 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed) mFactoryMap["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this); mFactoryMap["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about_land.xml", false); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about_land.xml", false); sObserver = new LLParcelSelectionObserver(); LLViewerParcelMgr::getInstance()->addObserver( sObserver ); } BOOL LLFloaterLand::postBuild() -{ +{ + mVisibleSignal.connect(boost::bind(&LLFloaterLand::onVisibilityChange, this, _2)); + LLTabContainer* tab = getChild("landtab"); mTabLand = (LLTabContainer*) tab; @@ -229,6 +253,9 @@ BOOL LLFloaterLand::postBuild() // virtual LLFloaterLand::~LLFloaterLand() { + LLViewerParcelMgr::getInstance()->removeObserver( sObserver ); + delete sObserver; + sObserver = NULL; } // public @@ -754,18 +781,18 @@ void LLPanelLandGeneral::draw() void LLPanelLandGeneral::onClickSetGroup() { - LLFloaterGroupPicker* fg; - LLFloater* parent_floater = gFloaterView->getParentFloater(this); - fg = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); - fg->setSelectGroupCallback( boost::bind(&LLPanelLandGeneral::setGroup, this, _1 )); - - if (parent_floater) + LLFloaterGroupPicker* fg = LLFloaterReg::showTypedInstance("group_picker", LLSD(gAgent.getID())); + if (fg) { - LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg); - fg->setOrigin(new_rect.mLeft, new_rect.mBottom); - parent_floater->addDependentFloater(fg); + fg->setSelectGroupCallback( boost::bind(&LLPanelLandGeneral::setGroup, this, _1 )); + if (parent_floater) + { + LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg); + fg->setOrigin(new_rect.mLeft, new_rect.mBottom); + parent_floater->addDependentFloater(fg); + } } } @@ -784,7 +811,7 @@ void LLPanelLandGeneral::onClickProfile(void* data) else { const LLUUID& avatar_id = parcel->getOwnerID(); - LLFriendActions::showProfile(avatar_id); + LLAvatarActions::showProfile(avatar_id); } } @@ -1057,7 +1084,7 @@ void LLPanelLandObjects::onDoubleClickOwner(void *userdata) } else { - LLFriendActions::showProfile(owner_id); + LLAvatarActions::showProfile(owner_id); } } } @@ -1463,26 +1490,26 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo if (is_group_owned) { - item_params.cells.add().type("icon").value(self->mIconGroup->getName()).column("type"); - item_params.cells.add().value(OWNER_GROUP).font(FONT).column("online_status"); + item_params.columns.add().type("icon").value(self->mIconGroup->getName()).column("type"); + item_params.columns.add().value(OWNER_GROUP).font(FONT).column("online_status"); } else if (is_online) { - item_params.cells.add().type("icon").value(self->mIconAvatarOnline->getName()).column("type"); - item_params.cells.add().value(OWNER_ONLINE).font(FONT).column("online_status"); + item_params.columns.add().type("icon").value(self->mIconAvatarOnline->getName()).column("type"); + item_params.columns.add().value(OWNER_ONLINE).font(FONT).column("online_status"); } else // offline { - item_params.cells.add().type("icon").value(self->mIconAvatarOffline->getName()).column("type"); - item_params.cells.add().value(OWNER_OFFLINE).font(FONT).column("online_status"); + item_params.columns.add().type("icon").value(self->mIconAvatarOffline->getName()).column("type"); + item_params.columns.add().value(OWNER_OFFLINE).font(FONT).column("online_status"); } // Placeholder for name. - item_params.cells.add().font(FONT).column("name"); + item_params.columns.add().font(FONT).column("name"); object_count_str = llformat("%d", object_count); - item_params.cells.add().value(object_count_str).font(FONT).column("count"); - item_params.cells.add().value(formatted_time((time_t)most_recent_time)).font(FONT).column("mostrecent"); + item_params.columns.add().value(object_count_str).font(FONT).column("count"); + item_params.columns.add().value(formatted_time((time_t)most_recent_time)).font(FONT).column("mostrecent"); self->mOwnerList->addRow(item_params); @@ -1693,7 +1720,6 @@ LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel) mCheckFly(NULL), mCheckGroupScripts(NULL), mCheckOtherScripts(NULL), - mCheckLandmark(NULL), mCheckShowDirectory(NULL), mCategoryCombo(NULL), mLandingTypeCombo(NULL), @@ -1727,10 +1753,6 @@ BOOL LLPanelLandOptions::postBuild() childSetCommitCallback("edit land check", onCommitAny, this); - mCheckLandmark = getChild( "check landmark"); - childSetCommitCallback("check landmark", onCommitAny, this); - - mCheckGroupScripts = getChild( "check group scripts"); childSetCommitCallback("check group scripts", onCommitAny, this); @@ -1856,9 +1878,6 @@ void LLPanelLandOptions::refresh() mCheckFly ->set(FALSE); mCheckFly ->setEnabled(FALSE); - mCheckLandmark ->set(FALSE); - mCheckLandmark ->setEnabled(FALSE); - mCheckGroupScripts ->set(FALSE); mCheckGroupScripts ->setEnabled(FALSE); @@ -1909,9 +1928,6 @@ void LLPanelLandOptions::refresh() mCheckFly ->set( parcel->getAllowFly() ); mCheckFly ->setEnabled( can_change_options ); - mCheckLandmark ->set( parcel->getAllowLandmark() ); - mCheckLandmark ->setEnabled( can_change_options ); - mCheckGroupScripts ->set( parcel->getAllowGroupScripts() || parcel->getAllowOtherScripts()); mCheckGroupScripts ->setEnabled( can_change_options && !parcel->getAllowOtherScripts()); @@ -2126,7 +2142,7 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata) BOOL allow_terraform = self->mCheckEditLand->get(); BOOL allow_damage = !self->mCheckSafe->get(); BOOL allow_fly = self->mCheckFly->get(); - BOOL allow_landmark = self->mCheckLandmark->get(); + BOOL allow_landmark = TRUE; // cannot restrict landmark creation BOOL allow_group_scripts = self->mCheckGroupScripts->get() || self->mCheckOtherScripts->get(); BOOL allow_other_scripts = self->mCheckOtherScripts->get(); BOOL allow_publish = FALSE; diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 74c1205e1f..7fc5ed0c9e 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -39,6 +39,7 @@ #include "llfloater.h" #include "llpointer.h" // LLPointer<> +//#include "llviewertexturelist.h" #include "llsafehandle.h" typedef std::set uuid_list_t; @@ -71,26 +72,27 @@ class LLPanelLandRenters; class LLPanelLandCovenant; class LLFloaterLand -: public LLFloater, public LLFloaterSingleton +: public LLFloater { - friend class LLUISingleton >; + friend class LLFloaterReg; public: static void refreshAll(); static LLPanelLandObjects* getCurrentPanelLandObjects(); static LLPanelLandCovenant* getCurrentPanelLandCovenant(); - // Destroys itself on close. - virtual void onClose(bool app_quitting); virtual void onOpen(const LLSD& key); virtual BOOL postBuild(); -protected: - +private: // Does its own instance management, so clients not allowed // to allocate or destroy. LLFloaterLand(const LLSD& seed); virtual ~LLFloaterLand(); + + void onVisibilityChange(const LLSD& visible); + +protected: /*virtual*/ void refresh(); @@ -328,7 +330,6 @@ private: LLCheckBoxCtrl* mCheckFly; LLCheckBoxCtrl* mCheckGroupScripts; LLCheckBoxCtrl* mCheckOtherScripts; - LLCheckBoxCtrl* mCheckLandmark; LLCheckBoxCtrl* mCheckShowDirectory; LLComboBox* mCategoryCombo; diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index 223cca50b2..de3cd5d4e3 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -56,46 +56,16 @@ #include "llviewermessage.h" #include "lluictrlfactory.h" -// statics -LLFloaterLandHoldings* LLFloaterLandHoldings::sInstance = NULL; - - -// static -void LLFloaterLandHoldings::show(void*) -{ - LLFloaterLandHoldings* floater = new LLFloaterLandHoldings(); - LLUICtrlFactory::getInstance()->buildFloater(floater, "floater_land_holdings.xml"); - floater->center(); - - // query_id null is known to be us - const LLUUID& query_id = LLUUID::null; - - // look only for parcels we own - U32 query_flags = DFQ_AGENT_OWNED; - - send_places_query(query_id, - LLUUID::null, - "", - query_flags, - LLParcel::C_ANY, - ""); - - // TODO: request updated L$ balance? - floater->openFloater(); -} - - // protected -LLFloaterLandHoldings::LLFloaterLandHoldings() -: LLFloater(), +LLFloaterLandHoldings::LLFloaterLandHoldings(const LLSD& key) +: LLFloater(key), mActualArea(0), mBillableArea(0), mFirstPacketReceived(FALSE), mSortColumn(""), mSortAscending(TRUE) { - // Instance management. - sInstance = this; +// LLUICtrlFactory::getInstance()->buildFloater(floater, "floater_land_holdings.xml"); } BOOL LLFloaterLandHoldings::postBuild() @@ -128,7 +98,9 @@ BOOL LLFloaterLandHoldings::postBuild() list->addElement(element, ADD_SORTED); } - + + center(); + return TRUE; } @@ -136,9 +108,23 @@ BOOL LLFloaterLandHoldings::postBuild() // protected LLFloaterLandHoldings::~LLFloaterLandHoldings() { - sInstance = NULL; } +void LLFloaterLandHoldings::onOpen(const LLSD& key) +{ + // query_id null is known to be us + const LLUUID& query_id = LLUUID::null; + + // look only for parcels we own + U32 query_flags = DFQ_AGENT_OWNED; + + send_places_query(query_id, + LLUUID::null, + "", + query_flags, + LLParcel::C_ANY, + ""); +} void LLFloaterLandHoldings::draw() { @@ -168,7 +154,7 @@ void LLFloaterLandHoldings::refresh() // static void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**) { - LLFloaterLandHoldings* self = sInstance; + LLFloaterLandHoldings* self = LLFloaterReg::findTypedInstance("land_holdings"); // Is this packet from an old, closed window? if (!self) @@ -224,50 +210,53 @@ void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**) land_type = LLTrans::getString("land_type_unknown"); } - self->mActualArea += actual_area; - self->mBillableArea += billable_area; - - S32 region_x = llround(global_x) % REGION_WIDTH_UNITS; - S32 region_y = llround(global_y) % REGION_WIDTH_UNITS; - - std::string location; - location = llformat("%s (%d, %d)", sim_name.c_str(), region_x, region_y); - - std::string area; - if(billable_area == actual_area) + if(owner_id.notNull()) { - area = llformat("%d", billable_area); - } - else - { - area = llformat("%d / %d", billable_area, actual_area); - } - - std::string hidden; - hidden = llformat("%f %f", global_x, global_y); + self->mActualArea += actual_area; + self->mBillableArea += billable_area; - LLSD element; - element["columns"][0]["column"] = "name"; - element["columns"][0]["value"] = name; - element["columns"][0]["font"] = "SANSSERIF"; - - element["columns"][1]["column"] = "location"; - element["columns"][1]["value"] = location; - element["columns"][1]["font"] = "SANSSERIF"; - - element["columns"][2]["column"] = "area"; - element["columns"][2]["value"] = area; - element["columns"][2]["font"] = "SANSSERIF"; - - element["columns"][3]["column"] = "type"; - element["columns"][3]["value"] = land_type; - element["columns"][3]["font"] = "SANSSERIF"; - - // hidden is always last column - element["columns"][4]["column"] = "hidden"; - element["columns"][4]["value"] = hidden; + S32 region_x = llround(global_x) % REGION_WIDTH_UNITS; + S32 region_y = llround(global_y) % REGION_WIDTH_UNITS; - list->addElement(element); + std::string location; + location = llformat("%s (%d, %d)", sim_name.c_str(), region_x, region_y); + + std::string area; + if(billable_area == actual_area) + { + area = llformat("%d", billable_area); + } + else + { + area = llformat("%d / %d", billable_area, actual_area); + } + + std::string hidden; + hidden = llformat("%f %f", global_x, global_y); + + LLSD element; + element["columns"][0]["column"] = "name"; + element["columns"][0]["value"] = name; + element["columns"][0]["font"] = "SANSSERIF"; + + element["columns"][1]["column"] = "location"; + element["columns"][1]["value"] = location; + element["columns"][1]["font"] = "SANSSERIF"; + + element["columns"][2]["column"] = "area"; + element["columns"][2]["value"] = area; + element["columns"][2]["font"] = "SANSSERIF"; + + element["columns"][3]["column"] = "type"; + element["columns"][3]["value"] = land_type; + element["columns"][3]["font"] = "SANSSERIF"; + + // hidden is always last column + element["columns"][4]["column"] = "hidden"; + element["columns"][4]["value"] = hidden; + + list->addElement(element); + } } self->refreshAggregates(); @@ -292,15 +281,16 @@ void LLFloaterLandHoldings::buttonCore(S32 which) F64 global_z = gAgent.getPositionGlobal().mdV[VZ]; LLVector3d pos_global(global_x, global_y, global_z); + LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance(); switch(which) { case 0: gAgent.teleportViaLocation(pos_global); - LLFloaterWorldMap::getInstance()->trackLocation(pos_global); + if(floater_world_map) floater_world_map->trackLocation(pos_global); break; case 1: - LLFloaterWorldMap::getInstance()->trackLocation(pos_global); + if(floater_world_map) floater_world_map->trackLocation(pos_global); LLFloaterReg::showInstance("world_map", "center"); break; default: diff --git a/indra/newview/llfloaterlandholdings.h b/indra/newview/llfloaterlandholdings.h index def77cf2a8..471ddf7f44 100644 --- a/indra/newview/llfloaterlandholdings.h +++ b/indra/newview/llfloaterlandholdings.h @@ -44,10 +44,11 @@ class LLFloaterLandHoldings : public LLFloater { public: - BOOL postBuild(); - - static void show(void*); - + LLFloaterLandHoldings(const LLSD& key); + virtual ~LLFloaterLandHoldings(); + + virtual BOOL postBuild(); + virtual void onOpen(const LLSD& key); virtual void draw(); void refresh(); @@ -63,14 +64,9 @@ public: static void onGrantList(void* data); protected: - LLFloaterLandHoldings(); - virtual ~LLFloaterLandHoldings(); - void refreshAggregates(); protected: - static LLFloaterLandHoldings* sInstance; - // Sum up as packets arrive the total holdings S32 mActualArea; S32 mBillableArea; diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index 6660650c56..f9fc467c05 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -94,7 +94,7 @@ BOOL LLFloaterMap::postBuild() registrar.add("Minimap.Zoom", boost::bind(&LLFloaterMap::handleZoom, this, _2)); registrar.add("Minimap.Tracker", boost::bind(&LLFloaterMap::handleStopTracking, this, _2)); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_minimap.xml", gMenuHolder); + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_minimap.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if (mPopupMenu && !LLTracker::isTracking(0)) { mPopupMenu->setItemEnabled ("Stop Tracking", false); diff --git a/indra/newview/llfloatermemleak.cpp b/indra/newview/llfloatermemleak.cpp index 3f2fcc26db..529bd68e03 100644 --- a/indra/newview/llfloatermemleak.cpp +++ b/indra/newview/llfloatermemleak.cpp @@ -42,26 +42,56 @@ #include "llmath.h" #include "llviewerwindow.h" -LLFloaterMemLeak* LLFloaterMemLeak::sInstance = NULL; U32 LLFloaterMemLeak::sMemLeakingSpeed = 0 ; //bytes leaked per frame U32 LLFloaterMemLeak::sMaxLeakedMem = 0 ; //maximum allowed leaked memory U32 LLFloaterMemLeak::sTotalLeaked = 0 ; S32 LLFloaterMemLeak::sStatus = LLFloaterMemLeak::STOP ; BOOL LLFloaterMemLeak::sbAllocationFailed = FALSE ; -LLFloaterMemLeak::LLFloaterMemLeak() - : LLFloater() +LLFloaterMemLeak::LLFloaterMemLeak(const LLSD& key) + : LLFloater(key) { setTitle("Memory Leaking Simulation Floater"); + mCommitCallbackRegistrar.add("MemLeak.ChangeLeakingSpeed", boost::bind(&LLFloaterMemLeak::onChangeLeakingSpeed, this)); + mCommitCallbackRegistrar.add("MemLeak.ChangeMaxMemLeaking", boost::bind(&LLFloaterMemLeak::onChangeMaxMemLeaking, this)); + mCommitCallbackRegistrar.add("MemLeak.Start", boost::bind(&LLFloaterMemLeak::onClickStart, this)); + mCommitCallbackRegistrar.add("MemLeak.Stop", boost::bind(&LLFloaterMemLeak::onClickStop, this)); + mCommitCallbackRegistrar.add("MemLeak.Release", boost::bind(&LLFloaterMemLeak::onClickRelease, this)); + mCommitCallbackRegistrar.add("MemLeak.Close", boost::bind(&LLFloaterMemLeak::onClickClose, this)); } +//---------------------------------------------- +BOOL LLFloaterMemLeak::postBuild(void) +{ + F32 a, b ; + a = childGetValue("leak_speed").asReal(); + if(a > (F32)(0xFFFFFFFF)) + { + sMemLeakingSpeed = 0xFFFFFFFF ; + } + else + { + sMemLeakingSpeed = (U32)a ; + } + b = childGetValue("max_leak").asReal(); + if(b > (F32)0xFFF) + { + sMaxLeakedMem = 0xFFFFFFFF ; + } + else + { + sMaxLeakedMem = ((U32)b) << 20 ; + } + + sbAllocationFailed = FALSE ; + return TRUE ; +} LLFloaterMemLeak::~LLFloaterMemLeak() { release() ; sMemLeakingSpeed = 0 ; //bytes leaked per frame sMaxLeakedMem = 0 ; //maximum allowed leaked memory - sInstance = NULL ; } void LLFloaterMemLeak::release() @@ -117,79 +147,56 @@ void LLFloaterMemLeak::idle() } //---------------------- -void LLFloaterMemLeak::onChangeLeakingSpeed(LLUICtrl* ctrl, void* userData) +void LLFloaterMemLeak::onChangeLeakingSpeed() { - LLFloaterMemLeak *mem_leak = (LLFloaterMemLeak *)userData; - if (mem_leak) - { - F32 tmp ; - tmp = mem_leak->childGetValue("leak_speed").asReal(); + F32 tmp ; + tmp =childGetValue("leak_speed").asReal(); - if(tmp > (F32)0xFFFFFFFF) - { - sMemLeakingSpeed = 0xFFFFFFFF ; - } - else - { - sMemLeakingSpeed = (U32)tmp ; - } + if(tmp > (F32)0xFFFFFFFF) + { + sMemLeakingSpeed = 0xFFFFFFFF ; } + else + { + sMemLeakingSpeed = (U32)tmp ; + } + } -void LLFloaterMemLeak::onChangeMaxMemLeaking(LLUICtrl* ctrl, void* userData) +void LLFloaterMemLeak::onChangeMaxMemLeaking() { - LLFloaterMemLeak *mem_leak = (LLFloaterMemLeak *)userData; - if (mem_leak) + + F32 tmp ; + tmp =childGetValue("max_leak").asReal(); + if(tmp > (F32)0xFFF) { - F32 tmp ; - tmp = mem_leak->childGetValue("max_leak").asReal(); - if(tmp > (F32)0xFFF) - { - sMaxLeakedMem = 0xFFFFFFFF ; - } - else - { - sMaxLeakedMem = ((U32)tmp) << 20 ; - } + sMaxLeakedMem = 0xFFFFFFFF ; } + else + { + sMaxLeakedMem = ((U32)tmp) << 20 ; + } + } -void LLFloaterMemLeak::onClickStart(void* userData) +void LLFloaterMemLeak::onClickStart() { sStatus = START ; } -void LLFloaterMemLeak::onClickStop(void* userData) +void LLFloaterMemLeak::onClickStop() { sStatus = STOP ; } -void LLFloaterMemLeak::onClickRelease(void* userData) +void LLFloaterMemLeak::onClickRelease() { sStatus = RELEASE ; } -void LLFloaterMemLeak::onClickClose(void* userData) +void LLFloaterMemLeak::onClickClose() { - if (sInstance) - { - sInstance->setVisible(FALSE); - } -} - -//---------------------------------------------- - -BOOL LLFloaterMemLeak::postBuild(void) -{ - childSetCommitCallback("leak_speed", onChangeLeakingSpeed, this); - childSetCommitCallback("max_leak", onChangeMaxMemLeaking, this); - - childSetAction("start_btn", onClickStart, this); - childSetAction("stop_btn", onClickStop, this); - childSetAction("release_btn", onClickRelease, this); - childSetAction("close_btn", onClickClose, this); - - return TRUE ; + setVisible(FALSE); } void LLFloaterMemLeak::draw() @@ -219,50 +226,3 @@ void LLFloaterMemLeak::draw() LLFloater::draw(); } - -// static instance of it -LLFloaterMemLeak* LLFloaterMemLeak::instance() -{ - if (!sInstance) - { - sInstance = new LLFloaterMemLeak(); - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_mem_leaking.xml", FALSE); - - if(sInstance) - { - F32 a, b ; - a = sInstance->childGetValue("leak_speed").asReal(); - if(a > (F32)(0xFFFFFFFF)) - { - sMemLeakingSpeed = 0xFFFFFFFF ; - } - else - { - sMemLeakingSpeed = (U32)a ; - } - b = sInstance->childGetValue("max_leak").asReal(); - if(b > (F32)0xFFF) - { - sMaxLeakedMem = 0xFFFFFFFF ; - } - else - { - sMaxLeakedMem = ((U32)b) << 20 ; - } - - sbAllocationFailed = FALSE ; - } - } - return sInstance ; -} - -void LLFloaterMemLeak::show(void*) -{ - instance()->openFloater(); -} - -LLFloaterMemLeak* LLFloaterMemLeak::getInstance() -{ - return sInstance ; -} - diff --git a/indra/newview/llfloatermemleak.h b/indra/newview/llfloatermemleak.h index 7d9d5f9c5f..763af943ba 100644 --- a/indra/newview/llfloatermemleak.h +++ b/indra/newview/llfloatermemleak.h @@ -37,34 +37,28 @@ class LLFloaterMemLeak : public LLFloater { + friend class LLFloaterReg; public: - LLFloaterMemLeak(); - virtual ~LLFloaterMemLeak(); - /// initialize all the callbacks for the menu - //void initCallbacks(void); + virtual BOOL postBuild() ; virtual void draw() ; - - /// one and one instance only - static LLFloaterMemLeak* instance(); - static void onChangeLeakingSpeed(LLUICtrl* ctrl, void* userData); - static void onChangeMaxMemLeaking(LLUICtrl* ctrl, void* userData); - static void onClickStart(void* userData); - static void onClickStop(void* userData); - static void onClickRelease(void* userData); - static void onClickClose(void* userData); - - /// show off our menu - static void show(void*); + void onChangeLeakingSpeed(); + void onChangeMaxMemLeaking(); + void onClickStart(); + void onClickStop(); + void onClickRelease(); + void onClickClose(); public: - static LLFloaterMemLeak* getInstance() ; void idle() ; void stop() ; private: + + LLFloaterMemLeak(const LLSD& key); + virtual ~LLFloaterMemLeak(); void release() ; private: @@ -75,9 +69,6 @@ private: START } ; - // one instance on the inside - static LLFloaterMemLeak* sInstance; - static U32 sMemLeakingSpeed ; //bytes leaked per frame static U32 sMaxLeakedMem ; //maximum allowed leaked memory static U32 sTotalLeaked ; diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp index 6ef72d4c1a..ed7d2c71ea 100644 --- a/indra/newview/llfloaternamedesc.cpp +++ b/indra/newview/llfloaternamedesc.cpp @@ -69,15 +69,12 @@ const S32 PREF_BUTTON_HEIGHT = 16; //----------------------------------------------------------------------------- // LLFloaterNameDesc() //----------------------------------------------------------------------------- -LLFloaterNameDesc::LLFloaterNameDesc(const std::string& filename ) - : LLFloater() +LLFloaterNameDesc::LLFloaterNameDesc(const LLSD& filename ) + : LLFloater(filename), + mIsAudio(FALSE) { - setTitle("Name/Description Floater"); - mFilenameAndPath = filename; - mFilename = gDirUtilp->getBaseFileName(filename, false); - // SL-5521 Maintain capitalization of filename when making the inventory item. JC - //LLStringUtil::toLower(mFilename); - mIsAudio = FALSE; + mFilenameAndPath = filename.asString(); + mFilename = gDirUtilp->getBaseFileName(mFilenameAndPath, false); } //----------------------------------------------------------------------------- @@ -93,11 +90,6 @@ BOOL LLFloaterNameDesc::postBuild() LLStringUtil::stripNonprintable(asset_name); LLStringUtil::trim(asset_name); - std::string exten = gDirUtilp->getExtension(asset_name); - if (exten == "wav") - { - mIsAudio = TRUE; - } asset_name = gDirUtilp->getBaseFileName(asset_name, true); // no extsntion setTitle(mFilename); @@ -112,7 +104,7 @@ BOOL LLFloaterNameDesc::postBuild() r.setLeftTopAndSize( PREVIEW_HPAD, y, line_width, PREVIEW_LINE_HEIGHT ); - childSetCommitCallback("name_form", doCommit, this); + getChild("name_form")->setCommitCallback(boost::bind(&LLFloaterNameDesc::doCommit, this)); childSetValue("name_form", LLSD(asset_name)); LLLineEditor *NameEditor = getChild("name_form"); @@ -126,7 +118,7 @@ BOOL LLFloaterNameDesc::postBuild() y -= PREVIEW_LINE_HEIGHT; r.setLeftTopAndSize( PREVIEW_HPAD, y, line_width, PREVIEW_LINE_HEIGHT ); - childSetCommitCallback("description_form", doCommit, this); + getChild("description_form")->setCommitCallback(boost::bind(&LLFloaterNameDesc::doCommit, this)); LLLineEditor *DescEditor = getChild("description_form"); if (DescEditor) { @@ -137,12 +129,12 @@ BOOL LLFloaterNameDesc::postBuild() y -= llfloor(PREVIEW_LINE_HEIGHT * 1.2f); // Cancel button - childSetAction("cancel_btn", onBtnCancel, this); + getChild("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnCancel, this)); - // OK button - childSetAction("ok_btn", onBtnOK, this); + childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload() )); + setDefaultBtn("ok_btn"); - + return TRUE; } @@ -162,45 +154,59 @@ void LLFloaterNameDesc::onCommit() { } -// static //----------------------------------------------------------------------------- // onCommit() //----------------------------------------------------------------------------- -void LLFloaterNameDesc::doCommit( class LLUICtrl *, void* userdata ) +void LLFloaterNameDesc::doCommit() { - LLFloaterNameDesc* self = (LLFloaterNameDesc*) userdata; - self->onCommit(); + onCommit(); } -// static //----------------------------------------------------------------------------- // onBtnOK() //----------------------------------------------------------------------------- -void LLFloaterNameDesc::onBtnOK( void* userdata ) +void LLFloaterNameDesc::onBtnOK( ) { - LLFloaterNameDesc *fp =(LLFloaterNameDesc *)userdata; - - fp->childDisable("ok_btn"); // don't allow inadvertent extra uploads + childDisable("ok_btn"); // don't allow inadvertent extra uploads LLAssetStorage::LLStoreAssetCallback callback = NULL; S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). void *nruserdata = NULL; std::string display_name = LLStringUtil::null; - upload_new_resource(fp->mFilenameAndPath, // file - fp->childGetValue("name_form").asString(), - fp->childGetValue("description_form").asString(), + upload_new_resource(mFilenameAndPath, // file + childGetValue("name_form").asString(), + childGetValue("description_form").asString(), 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE, LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(), display_name, callback, expected_upload_cost, nruserdata); - fp->closeFloater(false); + closeFloater(false); } -// static //----------------------------------------------------------------------------- // onBtnCancel() //----------------------------------------------------------------------------- -void LLFloaterNameDesc::onBtnCancel( void* userdata ) +void LLFloaterNameDesc::onBtnCancel() { - LLFloaterNameDesc *fp =(LLFloaterNameDesc *)userdata; - fp->closeFloater(false); + closeFloater(false); +} + + +//----------------------------------------------------------------------------- +// LLFloaterSoundPreview() +//----------------------------------------------------------------------------- + +LLFloaterSoundPreview::LLFloaterSoundPreview(const LLSD& filename ) + : LLFloaterNameDesc(filename) +{ + mIsAudio = TRUE; +} + +BOOL LLFloaterSoundPreview::postBuild() +{ + if (!LLFloaterNameDesc::postBuild()) + { + return FALSE; + } + getChild("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this)); + return TRUE; } diff --git a/indra/newview/llfloaternamedesc.h b/indra/newview/llfloaternamedesc.h index 6aa19eba40..2cc7f1101d 100644 --- a/indra/newview/llfloaternamedesc.h +++ b/indra/newview/llfloaternamedesc.h @@ -44,11 +44,14 @@ class LLRadioGroup; class LLFloaterNameDesc : public LLFloater { public: - LLFloaterNameDesc(const std::string& filename); + LLFloaterNameDesc(const LLSD& filename); virtual ~LLFloaterNameDesc(); virtual BOOL postBuild(); - - static void doCommit(class LLUICtrl *, void* userdata); + + void onBtnOK(); + void onBtnCancel(); + void doCommit(); + protected: virtual void onCommit(); @@ -57,9 +60,13 @@ protected: std::string mFilenameAndPath; std::string mFilename; - - static void onBtnOK(void*); - static void onBtnCancel(void*); }; +class LLFloaterSoundPreview : public LLFloaterNameDesc +{ +public: + LLFloaterSoundPreview(const LLSD& filename ); + virtual BOOL postBuild(); +}; + #endif // LL_LLFLOATERNAMEDESC_H diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index 3d5d2b733f..7042882084 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -161,20 +161,13 @@ bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter) // LLFloaterNotificationConsole // LLFloaterNotificationConsole::LLFloaterNotificationConsole(const LLSD& key) -: LLFloater() +: LLFloater(key) { mCommitCallbackRegistrar.add("ClickAdd", boost::bind(&LLFloaterNotificationConsole::onClickAdd, this)); //LLUICtrlFactory::instance().buildFloater(this, "floater_notifications_console.xml"); } -void LLFloaterNotificationConsole::onClose(bool app_quitting) -{ - setVisible(FALSE); - //destroy(); -} - - BOOL LLFloaterNotificationConsole::postBuild() { // these are in the order of processing @@ -251,10 +244,10 @@ void LLFloaterNotificationConsole::onClickAdd() //=============== LLFloaterNotification ================ LLFloaterNotification::LLFloaterNotification(LLNotification* note) -: LLFloater(), +: LLFloater(LLSD()), mNote(note) { - LLUICtrlFactory::instance().buildFloater(this, "floater_notification.xml"); + LLUICtrlFactory::instance().buildFloater(this, "floater_notification.xml", NULL); } BOOL LLFloaterNotification::postBuild() diff --git a/indra/newview/llfloaternotificationsconsole.h b/indra/newview/llfloaternotificationsconsole.h index b85437c3c5..7349ff1d8f 100644 --- a/indra/newview/llfloaternotificationsconsole.h +++ b/indra/newview/llfloaternotificationsconsole.h @@ -38,15 +38,14 @@ #include "llnotifications.h" class LLFloaterNotificationConsole : - public LLFloater, - public LLFloaterSingleton + public LLFloater { + friend class LLFloaterReg; + public: - LLFloaterNotificationConsole(const LLSD& key); // LLPanel BOOL postBuild(); - void onClose(bool app_quitting); void addChannel(const std::string& type, bool open = false); void updateResizeLimits(LLLayoutStack &stack); @@ -55,6 +54,7 @@ public: void updateResizeLimits(); private: + LLFloaterNotificationConsole(const LLSD& key); void onClickAdd(); }; @@ -70,7 +70,6 @@ public: // LLPanel BOOL postBuild(); void respond(); - void onClose(bool app_quitting) { setVisible(FALSE); } private: static void onCommitResponse(LLUICtrl* ctrl, void* data) { ((LLFloaterNotification*)data)->respond(); } diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index 4d782a1814..ba23a58b37 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -46,9 +46,10 @@ #include "llagent.h" // for agent id #include "llalertdialog.h" #include "llinventorybridge.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llinventorymodel.h" #include "llpanelinventory.h" +#include "llfloaterreg.h" #include "llselectmgr.h" #include "lluiconstants.h" #include "llviewerobject.h" @@ -56,29 +57,44 @@ #include "llviewerwindow.h" -LLFloaterOpenObject* LLFloaterOpenObject::sInstance = NULL; - -LLFloaterOpenObject::LLFloaterOpenObject() -: LLFloater(), +LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key) +: LLFloater(key), mPanelInventory(NULL), mDirty(TRUE) { - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_openobject.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(this,"floater_openobject.xml"); + mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this)); + mCommitCallbackRegistrar.add("OpenObject.MoveAndWear", boost::bind(&LLFloaterOpenObject::onClickMoveAndWear, this)); } LLFloaterOpenObject::~LLFloaterOpenObject() { - sInstance = NULL; +// sInstance = NULL; } // virtual BOOL LLFloaterOpenObject::postBuild() { - childSetAction("copy_to_inventory_button", onClickMoveToInventory, this); - childSetAction("copy_and_wear_button", onClickMoveAndWear, this); childSetTextArg("object_name", "[DESC]", std::string("Object") ); // *Note: probably do not want to translate this mPanelInventory = getChild("object_contents"); return TRUE; } + +void LLFloaterOpenObject::onOpen(const LLSD& key) +{ + LLObjectSelectionHandle object_selection = LLSelectMgr::getInstance()->getSelection(); + if (object_selection->getRootObjectCount() != 1) + { + LLNotifications::instance().add("UnableToViewContentsMoreThanOne"); + closeFloater(); + return; + } + if(!(object_selection->getPrimaryObject())) + { + closeFloater(); + return; + } + mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); +} void LLFloaterOpenObject::refresh() { mPanelInventory->refresh(); @@ -99,7 +115,6 @@ void LLFloaterOpenObject::refresh() } childSetTextArg("object_name", "[DESC]", name); - childSetEnabled("copy_to_inventory_button", enabled); childSetEnabled("copy_and_wear_button", enabled); @@ -115,34 +130,11 @@ void LLFloaterOpenObject::draw() LLFloater::draw(); } -// static void LLFloaterOpenObject::dirty() { - if (sInstance) sInstance->mDirty = TRUE; + mDirty = TRUE; } -// static -void LLFloaterOpenObject::show() -{ - LLObjectSelectionHandle object_selection = LLSelectMgr::getInstance()->getSelection(); - if (object_selection->getRootObjectCount() != 1) - { - LLNotifications::instance().add("UnableToViewContentsMoreThanOne"); - return; - } - - // Create a new instance only if needed - if (!sInstance) - { - sInstance = new LLFloaterOpenObject(); - sInstance->center(); - } - - sInstance->openFloater(); - sInstance->setFocus(TRUE); - - sInstance->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); -} void LLFloaterOpenObject::moveToInventory(bool wear) @@ -170,7 +162,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear) } else { - parent_category_id = gAgent.getInventoryRootID(); + parent_category_id = gInventory.getRootFolderID(); } LLUUID category_id = gInventory.createNewCategory(parent_category_id, LLAssetType::AT_NONE, @@ -201,8 +193,8 @@ void LLFloaterOpenObject::callbackMoveInventory(S32 result, void* data) if (result == 0) { - LLInventoryView::showAgentInventory(); - LLInventoryView* view = LLInventoryView::getActiveInventory(); + LLFloaterInventory::showAgentInventory(); + LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); if (view) { view->getPanel()->setSelection(cat->mCatID, TAKE_FOCUS_NO); @@ -212,20 +204,15 @@ void LLFloaterOpenObject::callbackMoveInventory(S32 result, void* data) delete cat; } - -// static -void LLFloaterOpenObject::onClickMoveToInventory(void* data) +void LLFloaterOpenObject::onClickMoveToInventory() { - LLFloaterOpenObject* self = (LLFloaterOpenObject*)data; - self->moveToInventory(false); - self->closeFloater(); + moveToInventory(false); + closeFloater(); } -// static -void LLFloaterOpenObject::onClickMoveAndWear(void* data) +void LLFloaterOpenObject::onClickMoveAndWear() { - LLFloaterOpenObject* self = (LLFloaterOpenObject*)data; - self->moveToInventory(true); - self->closeFloater(); + moveToInventory(true); + closeFloater(); } diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h index 0097a85690..0df3780ac4 100644 --- a/indra/newview/llfloateropenobject.h +++ b/indra/newview/llfloateropenobject.h @@ -46,9 +46,10 @@ class LLPanelInventory; class LLFloaterOpenObject : public LLFloater { + friend class LLFloaterReg; public: - static void show(); - static void dirty(); + + void dirty(); struct LLCatAndWear { @@ -57,20 +58,25 @@ public: }; protected: - LLFloaterOpenObject(); - ~LLFloaterOpenObject(); + /*virtual*/ BOOL postBuild(); void refresh(); void draw(); + virtual void onOpen(const LLSD& key); +// virtual void onClose(); void moveToInventory(bool wear); - static void onClickMoveToInventory(void* data); - static void onClickMoveAndWear(void* data); + void onClickMoveToInventory(); + void onClickMoveAndWear(); static void callbackMoveInventory(S32 result, void* data); +private: + + LLFloaterOpenObject(const LLSD& key); + ~LLFloaterOpenObject(); + protected: - static LLFloaterOpenObject* sInstance; LLPanelInventory* mPanelInventory; LLSafeHandle mObjectSelection; diff --git a/indra/newview/llfloaterparcel.cpp b/indra/newview/llfloaterparcel.cpp index fa7403874e..af42ce4f4a 100644 --- a/indra/newview/llfloaterparcel.cpp +++ b/indra/newview/llfloaterparcel.cpp @@ -35,6 +35,8 @@ #include "llfloaterparcel.h" +#include "llfloaterreg.h" + // viewer project includes #include "llcommandhandler.h" #include "llpanelplace.h" @@ -47,8 +49,6 @@ // Globals //----------------------------------------------------------------------------- -LLMap< const LLUUID, LLFloaterParcelInfo* > gPlaceInfoInstances; - class LLParcelHandler : public LLCommandHandler { public: @@ -68,8 +68,11 @@ public: } if (params[1].asString() == "about") { - LLFloaterParcelInfo::show(parcel_id); - return true; + if (parcel_id.notNull()) + { + LLFloaterReg::showInstance("parcel_info", LLSD(parcel_id)); + return true; + } } return false; } @@ -82,7 +85,7 @@ LLParcelHandler gParcelHandler; //---------------------------------------------------------------------------- -void* LLFloaterParcelInfo::createPanelPlace(void* data) +void* LLFloaterParcelInfo::createPanelPlace(void* data) { LLFloaterParcelInfo* self = (LLFloaterParcelInfo*)data; self->mPanelParcelp = new LLPanelPlace(); // allow edit self @@ -93,54 +96,29 @@ void* LLFloaterParcelInfo::createPanelPlace(void* data) //---------------------------------------------------------------------------- -LLFloaterParcelInfo::LLFloaterParcelInfo(const LLUUID &parcel_id) -: LLFloater(), - mParcelID( parcel_id ) +LLFloaterParcelInfo::LLFloaterParcelInfo(const LLSD& parcel_id) +: LLFloater(parcel_id), + mParcelID( parcel_id.asUUID() ), + mPanelParcelp(NULL) { mFactoryMap["place_details_panel"] = LLCallbackMap(LLFloaterParcelInfo::createPanelPlace, this); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_url.xml"); - gPlaceInfoInstances.addData(parcel_id, this); +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_url.xml"); } // virtual LLFloaterParcelInfo::~LLFloaterParcelInfo() { - // child views automatically deleted - gPlaceInfoInstances.removeData(mParcelID); } -void LLFloaterParcelInfo::displayParcelInfo(const LLUUID& parcel_id) +BOOL LLFloaterParcelInfo::postBuild() { - mPanelParcelp->setParcelID(parcel_id); -} - -// static -LLFloaterParcelInfo* LLFloaterParcelInfo::show(const LLUUID &parcel_id) -{ - if (parcel_id.isNull()) + if (mPanelParcelp) { - return NULL; + mPanelParcelp->setParcelID(mParcelID); } - - LLFloaterParcelInfo *floater; - if (gPlaceInfoInstances.checkData(parcel_id)) - { - // ...bring that window to front - floater = gPlaceInfoInstances.getData(parcel_id); - floater->openFloater(); - floater->setFrontmost(true); - } - else - { - floater = new LLFloaterParcelInfo( parcel_id ); - floater->center(); - floater->openFloater(); - floater->displayParcelInfo(parcel_id); - floater->setFrontmost(true); - } - - return floater; + center(); + return LLFloater::postBuild(); } diff --git a/indra/newview/llfloaterparcel.h b/indra/newview/llfloaterparcel.h index c2d5987d8e..386acb3fd5 100644 --- a/indra/newview/llfloaterparcel.h +++ b/indra/newview/llfloaterparcel.h @@ -43,13 +43,13 @@ class LLFloaterParcelInfo public: static void* createPanelPlace(void* data); - LLFloaterParcelInfo( const LLUUID &parcel_id ); + LLFloaterParcelInfo( const LLSD& parcel_id ); /*virtual*/ ~LLFloaterParcelInfo(); - + + /*virtual*/ BOOL postBuild(); + void displayParcelInfo(const LLUUID& parcel_id); - static LLFloaterParcelInfo* show(const LLUUID& parcel_id); - private: LLUUID mParcelID; // for which parcel is this window? LLPanelPlace* mPanelParcelp; diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp index 1ef71a9d53..17bb8221ad 100644 --- a/indra/newview/llfloaterperms.cpp +++ b/indra/newview/llfloaterperms.cpp @@ -42,51 +42,45 @@ LLFloaterPerms::LLFloaterPerms(const LLSD& seed) -: LLFloater() +: LLFloater(seed) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); + mCommitCallbackRegistrar.add("Perms.Copy", boost::bind(&LLFloaterPerms::onCommitCopy, this)); + mCommitCallbackRegistrar.add("Perms.OK", boost::bind(&LLFloaterPerms::onClickOK, this)); + mCommitCallbackRegistrar.add("Perms.Cancel", boost::bind(&LLFloaterPerms::onClickCancel, this)); + } BOOL LLFloaterPerms::postBuild() { - childSetEnabled("next_owner_transfer", gSavedSettings.getBOOL("NextOwnerCopy")); - childSetAction("help", onClickHelp, this); - childSetAction("ok", onClickOK, this); - childSetAction("cancel", onClickCancel, this); - childSetCommitCallback("next_owner_copy", &onCommitCopy, this); - + mCloseSignal.connect(boost::bind(&LLFloaterPerms::cancel, this)); + refresh(); return TRUE; } -//static -void LLFloaterPerms::onClickOK(void* data) +void LLFloaterPerms::onClickOK() { - LLFloaterPerms* self = static_cast(data); - self->ok(); - self->closeFloater(); + ok(); + closeFloater(); } -//static -void LLFloaterPerms::onClickCancel(void* data) +void LLFloaterPerms::onClickCancel() { - LLFloaterPerms* self = static_cast(data); - self->cancel(); - self->closeFloater(); + cancel(); + closeFloater(); } -//static -void LLFloaterPerms::onCommitCopy(LLUICtrl* ctrl, void* data) +void LLFloaterPerms::onCommitCopy() { - LLFloaterPerms* self = static_cast(data); // Implements fair use BOOL copyable = gSavedSettings.getBOOL("NextOwnerCopy"); if(!copyable) { gSavedSettings.setBOOL("NextOwnerTransfer", TRUE); } - LLCheckBoxCtrl* xfer = self->getChild("next_owner_transfer"); + LLCheckBoxCtrl* xfer = getChild("next_owner_transfer"); xfer->setEnabled(copyable); } @@ -113,14 +107,6 @@ void LLFloaterPerms::refresh() mNextOwnerTransfer = gSavedSettings.getBOOL("NextOwnerTransfer"); } -void LLFloaterPerms::onClose(bool app_quitting) -{ - // Cancel any unsaved changes before closing. - // Note: when closed due to the OK button this amounts to a no-op. - cancel(); - destroy(); -} - //static U32 LLFloaterPerms::getGroupPerms(std::string prefix) { @@ -152,9 +138,3 @@ U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix) return flags; } - -//static -void LLFloaterPerms::onClickHelp(void* data) -{ - LLNotifications::instance().add("ClickUploadHelpPermissions"); -} diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h index 805039efe4..2426f43ca7 100644 --- a/indra/newview/llfloaterperms.h +++ b/indra/newview/llfloaterperms.h @@ -36,18 +36,17 @@ #include "llfloater.h" -class LLFloaterPerms : public LLFloater, public LLFloaterSingleton +class LLFloaterPerms : public LLFloater { - friend class LLUISingleton >; + friend class LLFloaterReg; public: - /*virtual*/ void onClose(bool app_quitting = false); /*virtual*/ BOOL postBuild(); void ok(); void cancel(); - static void onClickOK(void*); - static void onClickCancel(void*); - static void onCommitCopy(LLUICtrl* ctrl, void* data); + void onClickOK(); + void onClickCancel(); + void onCommitCopy(); // Convenience methods to get current permission preference bitfields from saved settings: static U32 getEveryonePerms(std::string prefix=""); // prefix + "EveryoneCopy" static U32 getGroupPerms(std::string prefix=""); // prefix + "ShareWithGroup" @@ -57,9 +56,6 @@ private: LLFloaterPerms(const LLSD& seed); void refresh(); - /// callback for the menus help button - static void onClickHelp(void* data); - BOOL // cached values only for implementing cancel. mShareWithGroup, mEveryoneCopy, diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index 4a68e3092e..aa68a1b229 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -45,6 +45,7 @@ #include "lllineeditor.h" #include "llviewertexteditor.h" #include "llbutton.h" +#include "llfloaterreg.h" #include "llviewercontrol.h" #include "llviewernetwork.h" #include "lluictrlfactory.h" @@ -61,7 +62,7 @@ #include "llimagej2c.h" #include "llvfile.h" #include "llvfs.h" - +#include "llviewertexture.h" #include "llassetuploadresponders.h" #include //boost.regex lib @@ -70,40 +71,30 @@ /// Local function declarations, constants, enums, and typedefs ///---------------------------------------------------------------------------- -//static -LLFloaterPostcard::instance_list_t LLFloaterPostcard::sInstances; - ///---------------------------------------------------------------------------- /// Class LLFloaterPostcard ///---------------------------------------------------------------------------- -LLFloaterPostcard::LLFloaterPostcard(LLImageJPEG* jpeg, LLImageGL *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global) -: LLFloater(), - mJPEGImage(jpeg), - mViewerImage(img), - mImageScale(img_scale), - mPosTakenGlobal(pos_taken_global), +LLFloaterPostcard::LLFloaterPostcard(const LLSD& key) +: LLFloater(key), + mJPEGImage(NULL), + mViewerImage(NULL), mHasFirstMsgFocus(false) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_postcard.xml"); - - sInstances.insert(this); - - // pick up the user's up-to-date email address - gAgent.sendAgentUserInfoRequest(); - - openFloater(); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_postcard.xml"); } // Destroys the object LLFloaterPostcard::~LLFloaterPostcard() { - sInstances.erase(this); mJPEGImage = NULL; // deletes image } BOOL LLFloaterPostcard::postBuild() { + // pick up the user's up-to-date email address + gAgent.sendAgentUserInfoRequest(); + childSetAction("cancel_btn", onClickCancel, this); childSetAction("send_btn", onClickSend, this); @@ -127,15 +118,18 @@ BOOL LLFloaterPostcard::postBuild() return TRUE; } - - // static -LLFloaterPostcard* LLFloaterPostcard::showFromSnapshot(LLImageJPEG *jpeg, LLImageGL *img, const LLVector2 &image_scale, const LLVector3d& pos_taken_global) +LLFloaterPostcard* LLFloaterPostcard::showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2 &image_scale, const LLVector3d& pos_taken_global) { // Take the images from the caller // It's now our job to clean them up - LLFloaterPostcard *instance = new LLFloaterPostcard(jpeg, img, image_scale, pos_taken_global); - + LLFloaterPostcard* instance = LLFloaterReg::showTypedInstance("postcard", LLSD(img->getID())); + + instance->mJPEGImage = jpeg; + instance->mViewerImage = img; + instance->mImageScale = image_scale; + instance->mPosTakenGlobal = pos_taken_global; + return instance; } @@ -181,7 +175,7 @@ void LLFloaterPostcard::draw() rect.mBottom, rect.getWidth(), rect.getHeight(), - mViewerImage, + mViewerImage.get(), LLColor4::white); } glMatrixMode(GL_TEXTURE); @@ -302,10 +296,11 @@ void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data, // static void LLFloaterPostcard::updateUserInfo(const std::string& email) { - for (instance_list_t::iterator iter = sInstances.begin(); - iter != sInstances.end(); ++iter) + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); + iter != inst_list.end(); ++iter) { - LLFloaterPostcard *instance = *iter; + LLFloater* instance = *iter; const std::string& text = instance->childGetValue("from_form").asString(); if (text.empty()) { diff --git a/indra/newview/llfloaterpostcard.h b/indra/newview/llfloaterpostcard.h index 5abb97e15f..49cce53106 100644 --- a/indra/newview/llfloaterpostcard.h +++ b/indra/newview/llfloaterpostcard.h @@ -41,20 +41,20 @@ class LLTextEditor; class LLLineEditor; class LLButton; -class LLImageGL; +class LLViewerTexture; class LLImageJPEG; class LLFloaterPostcard : public LLFloater { public: - LLFloaterPostcard(LLImageJPEG* jpeg, LLImageGL *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global); + LLFloaterPostcard(const LLSD& key); virtual ~LLFloaterPostcard(); virtual BOOL postBuild(); virtual void draw(); - static LLFloaterPostcard* showFromSnapshot(LLImageJPEG *jpeg, LLImageGL *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global); + static LLFloaterPostcard* showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global); static void onClickCancel(void* data); static void onClickSend(void* data); @@ -73,15 +73,12 @@ public: protected: LLPointer mJPEGImage; - LLPointer mViewerImage; + LLPointer mViewerImage; LLTransactionID mTransactionID; LLAssetID mAssetID; LLVector2 mImageScale; LLVector3d mPosTakenGlobal; boolean mHasFirstMsgFocus; - - typedef std::set instance_list_t; - static instance_list_t sInstances; }; diff --git a/indra/newview/llfloaterpostprocess.cpp b/indra/newview/llfloaterpostprocess.cpp index a1015918d4..2ab54d6e46 100644 --- a/indra/newview/llfloaterpostprocess.cpp +++ b/indra/newview/llfloaterpostprocess.cpp @@ -36,6 +36,7 @@ #include "llsliderctrl.h" #include "llcheckboxctrl.h" +#include "llcombobox.h" #include "lluictrlfactory.h" #include "llviewerdisplay.h" #include "llpostprocess.h" @@ -44,14 +45,10 @@ #include "llviewerwindow.h" -LLFloaterPostProcess* LLFloaterPostProcess::sPostProcess = NULL; - - -LLFloaterPostProcess::LLFloaterPostProcess() - : LLFloater() +LLFloaterPostProcess::LLFloaterPostProcess(const LLSD& key) + : LLFloater(key) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_post_process.xml"); - + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_post_process.xml"); } LLFloaterPostProcess::~LLFloaterPostProcess() @@ -87,28 +84,16 @@ BOOL LLFloaterPostProcess::postBuild() // Effect loading and saving. LLComboBox* comboBox = getChild("PPEffectsCombo"); - childSetAction("PPLoadEffect", &LLFloaterPostProcess::onLoadEffect, comboBox); + getChild("PPLoadEffect")->setCommitCallback(boost::bind(&LLFloaterPostProcess::onLoadEffect, this, comboBox)); comboBox->setCommitCallback(boost::bind(&LLFloaterPostProcess::onChangeEffectName, this, _1)); LLLineEditor* editBox = getChild("PPEffectNameEditor"); - childSetAction("PPSaveEffect", &LLFloaterPostProcess::onSaveEffect, editBox); + getChild("PPSaveEffect")->setCommitCallback(boost::bind(&LLFloaterPostProcess::onSaveEffect, this, editBox)); syncMenu(); return TRUE; } -LLFloaterPostProcess* LLFloaterPostProcess::instance() -{ - // if we don't have our singleton instance, create it - if (!sPostProcess) - { - sPostProcess = new LLFloaterPostProcess(); - sPostProcess->openFloater(); - sPostProcess->setFocus(TRUE); - } - return sPostProcess; -} - // Bool Toggle void LLFloaterPostProcess::onBoolToggle(LLUICtrl* ctrl, void* userData) { @@ -159,33 +144,29 @@ void LLFloaterPostProcess::onColorControlIMoved(LLUICtrl* ctrl, void* userData) gPostProcess->tweaks[floatVariableName][3] = sldrCtrl->getValue(); } -void LLFloaterPostProcess::onLoadEffect(void* userData) +void LLFloaterPostProcess::onLoadEffect(LLComboBox* comboBox) { - LLComboBox* comboBox = static_cast(userData); - LLSD::String effectName(comboBox->getSelectedValue().asString()); gPostProcess->setSelectedEffect(effectName); - sPostProcess->syncMenu(); + syncMenu(); } -void LLFloaterPostProcess::onSaveEffect(void* userData) +void LLFloaterPostProcess::onSaveEffect(LLLineEditor* editBox) { - LLLineEditor* editBox = static_cast(userData); - std::string effectName(editBox->getValue().asString()); if (gPostProcess->mAllEffects.has(effectName)) { LLSD payload; payload["effect_name"] = effectName; - LLNotifications::instance().add("PPSaveEffectAlert", LLSD(), payload, &LLFloaterPostProcess::saveAlertCallback); + LLNotifications::instance().add("PPSaveEffectAlert", LLSD(), payload, boost::bind(&LLFloaterPostProcess::saveAlertCallback, this, _1, _2)); } else { gPostProcess->saveEffect(effectName); - sPostProcess->syncMenu(); + syncMenu(); } } @@ -207,30 +188,11 @@ bool LLFloaterPostProcess::saveAlertCallback(const LLSD& notification, const LLS { gPostProcess->saveEffect(notification["payload"]["effect_name"].asString()); - sPostProcess->syncMenu(); + syncMenu(); } return false; } -void LLFloaterPostProcess::show() -{ - // get the instance, make sure the values are synced - // and open the menu - LLFloaterPostProcess* postProcess = instance(); - postProcess->syncMenu(); - postProcess->openFloater(); -} - -// virtual -void LLFloaterPostProcess::onClose(bool app_quitting) -{ - // just set visibility to false, don't get fancy yet - if (sPostProcess) - { - sPostProcess->setVisible(FALSE); - } -} - void LLFloaterPostProcess::syncMenu() { // add the combo boxe contents diff --git a/indra/newview/llfloaterpostprocess.h b/indra/newview/llfloaterpostprocess.h index 68e6d1e244..c789adee00 100644 --- a/indra/newview/llfloaterpostprocess.h +++ b/indra/newview/llfloaterpostprocess.h @@ -36,6 +36,8 @@ #include "llfloater.h" class LLButton; +class LLComboBox; +class LLLineEditor; class LLSliderCtrl; class LLTabContainer; class LLPanelPermissions; @@ -51,11 +53,9 @@ class LLFloaterPostProcess : public LLFloater { public: - LLFloaterPostProcess(); + LLFloaterPostProcess(const LLSD& key); virtual ~LLFloaterPostProcess(); /*virtual*/ BOOL postBuild(); - /// one and one instance only - static LLFloaterPostProcess* instance(); /// post process callbacks static void onBoolToggle(LLUICtrl* ctrl, void* userData); @@ -64,18 +64,12 @@ public: static void onColorControlGMoved(LLUICtrl* ctrl, void* userData); static void onColorControlBMoved(LLUICtrl* ctrl, void* userData); static void onColorControlIMoved(LLUICtrl* ctrl, void* userData); - static void onLoadEffect(void* userData); - static void onSaveEffect(void* userData); + void onLoadEffect(LLComboBox* comboBox); + void onSaveEffect(LLLineEditor* editBox); void onChangeEffectName(LLUICtrl* ctrl); /// prompts a user when overwriting an effect - static bool saveAlertCallback(const LLSD& notification, const LLSD& response); - - /// show off our menu - static void show(); - - /// stuff to do on exit - virtual void onClose(bool app_quitting); + bool saveAlertCallback(const LLSD& notification, const LLSD& response); /// sync up sliders void syncMenu(); @@ -84,8 +78,6 @@ public: void refresh(); */ public: - - static LLFloaterPostProcess* sPostProcess; }; #endif diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 15d57ebbcc..8a7b2d84c0 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -45,6 +45,7 @@ #include "llagent.h" #include "llavatarconstants.h" #include "llcheckboxctrl.h" +#include "llcolorswatch.h" #include "llcombobox.h" #include "llcommandhandler.h" #include "lldirpicker.h" @@ -57,6 +58,7 @@ #include "llfloatervoicedevicesettings.h" #include "llkeyboard.h" #include "llmodaldialog.h" +#include "llnavigationbar.h" #include "llpanellogin.h" #include "llradiogroup.h" #include "llsky.h" @@ -90,13 +92,8 @@ #include "llspinctrl.h" #include "llstartup.h" #include "lltextbox.h" - #include "llui.h" - -#include "llviewerimage.h" -#include "llviewerimagelist.h" #include "llviewerobjectlist.h" - #include "llvoavatar.h" #include "llvovolume.h" #include "llwindow.h" @@ -127,9 +124,9 @@ class LLVoiceSetKeyDialog : public LLModalDialog }; LLVoiceSetKeyDialog::LLVoiceSetKeyDialog(LLFloaterPreference* parent) -: LLModalDialog(LLStringUtil::null, 240, 100), mParent(parent) +: LLModalDialog(LLSD(), 240, 100), mParent(parent) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_select_key.xml"); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_select_key.xml", NULL); childSetAction("Cancel", onCancel, this); childSetFocus("Cancel"); @@ -173,6 +170,7 @@ void LLVoiceSetKeyDialog::onCancel(void* user_data) void free_web_media(LLMediaBase *media_source); void handleHTMLLinkColorChanged(const LLSD& newvalue); +void handleNameTagOptionChanged(const LLSD& newvalue); LLMediaBase *get_web_media(); bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response); @@ -224,11 +222,20 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response S32 option = LLNotification::getSelectedOption(notification, response); if ( option == 0 ) // YES { + // clean web LLMediaBase *media_source = get_web_media(); if (media_source) media_source->clearCache(); free_web_media(media_source); + + // clean nav bar history + LLNavigationBar::getInstance()->clearHistoryCache(); + + // flag client texture cache for clearing next time the client runs + gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE); + LLNotifications::instance().add("CacheWillClear"); } + return false; } @@ -238,6 +245,18 @@ void handleHTMLLinkColorChanged(const LLSD& newvalue) LLStyleMap::instance().update(); } +void handleNameTagOptionChanged(const LLSD& newvalue) +{ + S32 name_tag_option = S32(newvalue); + if(name_tag_option==2) + { + gSavedSettings.setBOOL("SmallAvatarNames", TRUE); + } + else + { + gSavedSettings.setBOOL("SmallAvatarNames", FALSE); + } +} bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater) { @@ -318,8 +337,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreference::onBtnCancel, this)); mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreference::onBtnOK, this)); - mCommitCallbackRegistrar.add("Pref.ClearCache", boost::bind(&LLFloaterPreference::onClickClearCache, (void*)NULL)); - mCommitCallbackRegistrar.add("Pref.WebClearCache", boost::bind(&LLFloaterPreference::onClickBrowserClearCache, (void*)NULL)); +// mCommitCallbackRegistrar.add("Pref.ClearCache", boost::bind(&LLFloaterPreference::onClickClearCache, this)); + mCommitCallbackRegistrar.add("Pref.WebClearCache", boost::bind(&LLFloaterPreference::onClickBrowserClearCache, this)); mCommitCallbackRegistrar.add("Pref.SetCache", boost::bind(&LLFloaterPreference::onClickSetCache, this)); mCommitCallbackRegistrar.add("Pref.ResetCache", boost::bind(&LLFloaterPreference::onClickResetCache, this)); mCommitCallbackRegistrar.add("Pref.ClickSkin", boost::bind(&LLFloaterPreference::onClickSkin, this,_1, _2)); @@ -329,10 +348,10 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.ClickSkipDialogs", boost::bind(&LLFloaterPreference::onClickSkipDialogs, this)); mCommitCallbackRegistrar.add("Pref.ClickResetDialogs", boost::bind(&LLFloaterPreference::onClickResetDialogs, this)); mCommitCallbackRegistrar.add("Pref.ClickEnablePopup", boost::bind(&LLFloaterPreference::onClickEnablePopup, this)); + mCommitCallbackRegistrar.add("Pref.ClickDisablePopup", boost::bind(&LLFloaterPreference::onClickDisablePopup, this)); mCommitCallbackRegistrar.add("Pref.LogPath", boost::bind(&LLFloaterPreference::onClickLogPath, this)); mCommitCallbackRegistrar.add("Pref.Logging", boost::bind(&LLFloaterPreference::onCommitLogging, this)); mCommitCallbackRegistrar.add("Pref.OpenHelp", boost::bind(&LLFloaterPreference::onOpenHelp, this)); - mCommitCallbackRegistrar.add("Pref.ChangeCustom", boost::bind(&LLFloaterPreference::onChangeCustom, this)); mCommitCallbackRegistrar.add("Pref.UpdateMeterText", boost::bind(&LLFloaterPreference::updateMeterText, this, _1)); mCommitCallbackRegistrar.add("Pref.HardwareSettings", boost::bind(&LLFloaterPreference::onOpenHardwareSettings, this)); mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this)); @@ -342,16 +361,19 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.AutoDetectAspect", boost::bind(&LLFloaterPreference::onCommitAutoDetectAspect, this)); mCommitCallbackRegistrar.add("Pref.onSelectAspectRatio", boost::bind(&LLFloaterPreference::onKeystrokeAspectRatio, this)); mCommitCallbackRegistrar.add("Pref.QualityPerformance", boost::bind(&LLFloaterPreference::onChangeQuality, this, _2)); - - gSavedSkinSettings.getControl("HTMLLinkColor")->getCommitSignal()->connect(boost::bind(&handleHTMLLinkColorChanged, _2)); + gSavedSettings.getControl("AvatarNameTagMode")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2)); } BOOL LLFloaterPreference::postBuild() { + mCloseSignal.connect(boost::bind(&LLFloaterPreference::onClose, this)); + LLTabContainer* tabcontainer = getChild("pref core"); if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab"))) tabcontainer->selectFirstTab(); + S32 show_avatar_nametag_options = gSavedSettings.getS32("AvatarNameTagMode"); + handleNameTagOptionChanged(LLSD(show_avatar_nametag_options)); return TRUE; } @@ -373,6 +395,10 @@ void LLFloaterPreference::draw() { BOOL has_first_selected = (getChildRef("disabled_popups").getFirstSelected()!=NULL); gSavedSettings.setBOOL("FirstSelectedDisabledPopups", has_first_selected); + + has_first_selected = (getChildRef("enabled_popups").getFirstSelected()!=NULL); + gSavedSettings.setBOOL("FirstSelectedEnabledPopups", has_first_selected); + LLFloater::draw(); } @@ -394,7 +420,11 @@ void LLFloaterPreference::apply() panel->apply(); } // hardware menu apply - LLFloaterHardwareSettings::instance()->apply(); + LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::findTypedInstance("prefs_hardware_settings"); + if (hardware_settings) + { + hardware_settings->apply(); + } LLFloaterVoiceDeviceSettings* voice_device_settings = LLFloaterReg::findTypedInstance("pref_voicedevicesettings"); if(voice_device_settings) @@ -459,7 +489,7 @@ void LLFloaterPreference::apply() applyResolution(); // Only set window size if we're not in fullscreen mode - if(gSavedSettings.getBOOL("NotFullScreen")) + if(!gSavedSettings.getBOOL("WindowFullScreen")) { applyWindowSize(); } @@ -482,7 +512,11 @@ void LLFloaterPreference::cancel() LLFloaterReg::hideInstance("pref_joystick"); // cancel hardware menu - LLFloaterHardwareSettings::instance()->cancel(); // TODO: angela change the build of the floater to floater reg + LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::findTypedInstance("prefs_hardware_settings"); + if (hardware_settings) + { + hardware_settings->cancel(); + } // reverts any changes to current skin gSavedSettings.setString("SkinCurrent", sSkin); @@ -515,16 +549,17 @@ void LLFloaterPreference::setHardwareDefaults() LLFeatureManager::getInstance()->applyRecommendedSettings(); refreshEnabledGraphics(); } -void LLFloaterPreference::onClose(bool app_quitting) + +void LLFloaterPreference::onClose() { gSavedSettings.setS32("LastPrefTab", getChild("pref core")->getCurrentPanelIndex()); LLPanelLogin::setAlwaysRefresh(false); cancel(); // will be a no-op if OK or apply was performed just prior. - destroy(); } + void LLFloaterPreference::onOpenHardwareSettings() { - LLFloaterHardwareSettings::show(); + LLFloaterReg::showInstance("prefs_hardware_settings"); } // static void LLFloaterPreference::onBtnOK() @@ -544,7 +579,7 @@ void LLFloaterPreference::onBtnOK() apply(); closeFloater(false); gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); - gSavedSkinSettings.saveToFile(gSavedSettings.getString("SkinningSettingsFile") , TRUE ); + LLUIColorTable::instance().saveUserSettings(); std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE); // save all settings, even if equals defaults gCrashSettings.saveToFile(crash_settings_filename, FALSE); @@ -605,27 +640,18 @@ void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_ } -void LLFloaterPreference::onChangeCustom() -{ - // if custom is turned off, reset everything to defaults - if (this && getChild("CustomSettings")->getValue()) - { - U32 set = (U32)getChild("QualityPerformanceSelection")->getValueF32(); - LLFeatureManager::getInstance()->setGraphicsLevel(set, true); - updateMeterText(getChild("DrawDistance")); - } - - refreshEnabledGraphics(); -} - void LLFloaterPreference::refreshEnabledGraphics() { LLFloaterPreference* instance = LLFloaterReg::findTypedInstance("preferences"); if(instance) { - LLFloaterHardwareSettings::instance()->refreshEnabledState(); instance->refreshEnabledState(); } + LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::findTypedInstance("prefs_hardware_settings"); + if (hardware_settings) + { + hardware_settings->refreshEnabledState(); + } } void LLFloaterPreference::updateMeterText(LLUICtrl* ctrl) @@ -642,17 +668,16 @@ void LLFloaterPreference::updateMeterText(LLUICtrl* ctrl) m1->setVisible(two_digits); m2->setVisible(!two_digits); } - -// static -void LLFloaterPreference::onClickClearCache(void*) +/* +void LLFloaterPreference::onClickClearCache() { // flag client cache for clearing next time the client runs gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE); LLNotifications::instance().add("CacheWillClear"); } +*/ -// static -void LLFloaterPreference::onClickBrowserClearCache(void*) +void LLFloaterPreference::onClickBrowserClearCache() { LLNotifications::instance().add("ConfirmClearBrowserCache", LLSD(), LLSD(), callback_clear_browser_cache); } @@ -660,6 +685,8 @@ void LLFloaterPreference::onClickBrowserClearCache(void*) void LLFloaterPreference::onClickSetCache() { std::string cur_name(gSavedSettings.getString("CacheLocation")); +// std::string cur_top_folder(gDirUtilp->getBaseFileName(cur_name)); + std::string proposed_name(cur_name); LLDirPicker& picker = LLDirPicker::instance(); @@ -671,14 +698,17 @@ void LLFloaterPreference::onClickSetCache() std::string dir_name = picker.getDirName(); if (!dir_name.empty() && dir_name != cur_name) { - childSetText("cache_location", dir_name); + std::string new_top_folder(gDirUtilp->getBaseFileName(dir_name)); LLNotifications::instance().add("CacheWillBeMoved"); gSavedSettings.setString("NewCacheLocation", dir_name); + gSavedSettings.setString("NewCacheLocationTopFolder", new_top_folder); } else { std::string cache_location = gDirUtilp->getCacheDir(); - childSetText("cache_location", cache_location); + gSavedSettings.setString("CacheLocation", cache_location); + std::string top_folder(gDirUtilp->getBaseFileName(cache_location)); + gSavedSettings.setString("CacheLocationTopFolder", top_folder); } } @@ -687,10 +717,13 @@ void LLFloaterPreference::onClickResetCache() if (!gSavedSettings.getString("CacheLocation").empty()) { gSavedSettings.setString("NewCacheLocation", ""); + gSavedSettings.setString("NewCacheLocationTopFolder", ""); LLNotifications::instance().add("CacheWillBeMoved"); } std::string cache_location = gDirUtilp->getCacheDir(true); - childSetText("cache_location", cache_location); + gSavedSettings.setString("CacheLocation", cache_location); + std::string top_folder(gDirUtilp->getBaseFileName(cache_location)); + gSavedSettings.setString("CacheLocationTopFolder", top_folder); } void LLFloaterPreference::onClickSkin(LLUICtrl* ctrl, const LLSD& userdata) @@ -781,12 +814,6 @@ void LLFloaterPreference::buildLists(void* data) void LLFloaterPreference::refreshEnabledState() { - // disable graphics settings and exit if it's not set to custom - if(!gSavedSettings.getBOOL("RenderCustomSettings")) - { - return; - } - LLCheckBoxCtrl* ctrl_reflections = getChild("Reflections"); LLRadioGroup* radio_reflection_detail = getChild("ReflectionDetailRadio"); @@ -1034,6 +1061,22 @@ void LLFloaterPreference::onClickEnablePopup() buildLists(this); } +void LLFloaterPreference::onClickDisablePopup() +{ + LLScrollListCtrl& enabled_popups = getChildRef("enabled_popups"); + + std::vector items = enabled_popups.getAllSelected(); + std::vector::iterator itor; + for (itor = items.begin(); itor != items.end(); ++itor) + { + LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata())); + //gSavedSettings.setWarning(templatep->mName, TRUE); + std::string notification_name = templatep->mName; + LLUI::sSettingGroups["ignores"]->setBOOL(notification_name, FALSE); + } + + buildLists(this); +} void LLFloaterPreference::resetAllIgnored() { for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin(); @@ -1062,15 +1105,17 @@ void LLFloaterPreference::setAllIgnored() void LLFloaterPreference::onClickLogPath() { - std::string proposed_name(childGetText("log_path_string")); + std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath")); LLDirPicker& picker = LLDirPicker::instance(); if (!picker.getDir(&proposed_name ) ) { return; //Canceled! } - - childSetText("log_path_string", picker.getDirName()); + std::string chat_log_dir = picker.getDirName(); + std::string chat_log_top_folder= gDirUtilp->getBaseFileName(chat_log_dir); + gSavedPerAccountSettings.setString("InstantMessageLogPath",chat_log_dir); + gSavedPerAccountSettings.setString("InstantMessageLogFolder",chat_log_top_folder); } void LLFloaterPreference::onCommitLogging() @@ -1080,15 +1125,17 @@ void LLFloaterPreference::onCommitLogging() void LLFloaterPreference::enableHistory() { - if (childGetValue("log_instant_messages").asBoolean() || childGetValue("log_chat").asBoolean()) + if (childGetValue("log_instant_messages").asBoolean()) { - childEnable("log_show_history"); + childEnable("ChatIMLogs"); childEnable("log_path_button"); + childEnable("show_timestamps_check_im"); } else { - childDisable("log_show_history"); + childDisable("ChatIMLogs"); childDisable("log_path_button"); + childDisable("show_timestamps_check_im"); } } @@ -1122,10 +1169,10 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im childEnable("send_im_to_email"); childSetValue("send_im_to_email", im_via_email); childEnable("log_instant_messages"); - childEnable("log_chat"); +// childEnable("log_chat"); childEnable("busy_response"); - childEnable("log_instant_messages_timestamp"); - childEnable("log_chat_timestamp"); +// childEnable("log_instant_messages_timestamp"); +// childEnable("log_chat_timestamp"); childEnable("log_chat_IM"); childEnable("log_date_timestamp"); @@ -1245,11 +1292,16 @@ void LLFloaterPreference::applyResolution() S32 num_resolutions; LLWindow::LLWindowResolution* supported_resolutions = gViewerWindow->getWindow()->getSupportedResolutions(num_resolutions); - U32 resIndex = getChild("fullscreen combo")->getCurrentIndex(); + S32 resIndex = getChild("fullscreen combo")->getCurrentIndex(); + if (resIndex == -1) + { + // use highest resolution if nothing selected + resIndex = num_resolutions - 1; + } gSavedSettings.setS32("FullScreenWidth", supported_resolutions[resIndex].mWidth); gSavedSettings.setS32("FullScreenHeight", supported_resolutions[resIndex].mHeight); - gViewerWindow->requestResolutionUpdate(!gSavedSettings.getBOOL("NotFullScreen")); + gViewerWindow->requestResolutionUpdate(gSavedSettings.getBOOL("WindowFullScreen")); send_agent_update(TRUE); @@ -1298,6 +1350,12 @@ LLPanelPreference::LLPanelPreference() // mCommitCallbackRegistrar.add("setControlFalse", boost::bind(&LLPanelPreference::setControlFalse,this, _2)); } + +static void applyUIColor(const std::string& color_name, LLUICtrl* ctrl, const LLSD& param) +{ + LLUIColorTable::instance().setColor(color_name, LLColor4(param)); +} + //virtual BOOL LLPanelPreference::postBuild() { @@ -1460,6 +1518,55 @@ BOOL LLPanelPreference::postBuild() refresh(); } + + if(hasChild("user") && hasChild("agent") && hasChild("im") + && hasChild("system") && hasChild("script_error") && hasChild("objects") + && hasChild("owner") && hasChild("background") && hasChild("links")) + { + LLColorSwatchCtrl* color_swatch = getChild("user"); + color_swatch->setCommitCallback(boost::bind(&applyUIColor, "UserChatColor", _1, _2)); + color_swatch->setOriginal(LLUIColorTable::instance().getColor("UserChatColor")); + + color_swatch = getChild("agent"); + color_swatch->setCommitCallback(boost::bind(&applyUIColor, "AgentChatColor", _1, _2)); + color_swatch->setOriginal(LLUIColorTable::instance().getColor("AgentChatColor")); + + color_swatch = getChild("im"); + color_swatch->setCommitCallback(boost::bind(&applyUIColor, "IMChatColor", _1, _2)); + color_swatch->setOriginal(LLUIColorTable::instance().getColor("IMChatColor")); + + color_swatch = getChild("system"); + color_swatch->setCommitCallback(boost::bind(&applyUIColor, "SystemChatColor", _1, _2)); + color_swatch->setOriginal(LLUIColorTable::instance().getColor("SystemChatColor")); + + color_swatch = getChild("script_error"); + color_swatch->setCommitCallback(boost::bind(&applyUIColor, "ScriptErrorColor", _1, _2)); + color_swatch->setOriginal(LLUIColorTable::instance().getColor("ScriptErrorColor")); + + color_swatch = getChild("objects"); + color_swatch->setCommitCallback(boost::bind(&applyUIColor, "ObjectChatColor", _1, _2)); + color_swatch->setOriginal(LLUIColorTable::instance().getColor("ObjectChatColor")); + + color_swatch = getChild("owner"); + color_swatch->setCommitCallback(boost::bind(&applyUIColor, "llOwnerSayChatColor", _1, _2)); + color_swatch->setOriginal(LLUIColorTable::instance().getColor("llOwnerSayChatColor")); + + color_swatch = getChild("background"); + color_swatch->setCommitCallback(boost::bind(&applyUIColor, "BackgroundChatColor", _1, _2)); + color_swatch->setOriginal(LLUIColorTable::instance().getColor("BackgroundChatColor")); + + color_swatch = getChild("links"); + color_swatch->setCommitCallback(boost::bind(&applyUIColor, "HTMLLinkColor", _1, _2)); + color_swatch->setOriginal(LLUIColorTable::instance().getColor("HTMLLinkColor")); + } + + if(hasChild("effect_color_swatch")) + { + LLColorSwatchCtrl* color_swatch = getChild("effect_color_swatch"); + color_swatch->setCommitCallback(boost::bind(&applyUIColor, "EffectColor", _1, _2)); + color_swatch->setOriginal(LLUIColorTable::instance().getColor("EffectColor")); + } + apply(); return true; } @@ -1475,16 +1582,25 @@ void LLPanelPreference::apply() // Process view on top of the stack LLView* curview = view_stack.front(); view_stack.pop_front(); - LLUICtrl* ctrl = dynamic_cast(curview); - if (ctrl) + + LLColorSwatchCtrl* color_swatch = dynamic_cast(curview); + if (color_swatch) { - LLControlVariable* control = ctrl->getControlVariable(); - if (control) + mSavedColors[color_swatch->getName()] = color_swatch->get(); + } + else + { + LLUICtrl* ctrl = dynamic_cast(curview); + if (ctrl) { - mSavedValues[control] = control->getValue(); + LLControlVariable* control = ctrl->getControlVariable(); + if (control) + { + mSavedValues[control] = control->getValue(); + } } } - + // Push children onto the end of the work stack for (child_list_t::const_iterator iter = curview->getChildList()->begin(); iter != curview->getChildList()->end(); ++iter) @@ -1504,6 +1620,17 @@ void LLPanelPreference::cancel() LLSD ctrl_value = iter->second; control->set(ctrl_value); } + + for (string_color_map_t::iterator iter = mSavedColors.begin(); + iter != mSavedColors.end(); ++iter) + { + LLColorSwatchCtrl* color_swatch = findChild(iter->first); + if(color_swatch) + { + color_swatch->set(iter->second); + color_swatch->onCommit(); + } + } } void LLPanelPreference::setControlFalse(const LLSD& user_data) diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index afff610c69..ce31abcd9e 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -72,7 +72,6 @@ public: /*virtual*/ void draw(); virtual BOOL postBuild(); virtual void onOpen(const LLSD& key); - virtual void onClose(bool app_quitting); // static data update, called from message handler static void updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email); @@ -82,13 +81,15 @@ public: protected: + void onClose(); + void onBtnOK(); void onBtnCancel(); void onBtnApply(); void onOpenHelp(); - static void onClickClearCache(void*); - static void onClickBrowserClearCache(void*); +// void onClickClearCache(); + void onClickBrowserClearCache(); // if the custom settings box is clicked void onChangeCustom(); @@ -112,6 +113,7 @@ public: void onClickSkipDialogs(); void onClickResetDialogs(); void onClickEnablePopup(); + void onClickDisablePopup(); void resetAllIgnored(); void setAllIgnored(); void onClickLogPath(); @@ -163,6 +165,9 @@ public: private: typedef std::map control_values_map_t; control_values_map_t mSavedValues; + + typedef std::map string_color_map_t; + string_color_map_t mSavedColors; }; #endif // LL_LLPREFERENCEFLOATER_H diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp index dc72b66949..7312808bd6 100644 --- a/indra/newview/llfloaterproperties.cpp +++ b/indra/newview/llfloaterproperties.cpp @@ -44,7 +44,7 @@ #include "llbutton.h" #include "llcheckboxctrl.h" #include "llfloatergroupinfo.h" -#include "llfriendactions.h" +#include "llavataractions.h" #include "llinventorymodel.h" #include "lllineeditor.h" #include "llradiogroup.h" @@ -76,7 +76,8 @@ class LLPropertiesObserver : public LLInventoryObserver { public: - LLPropertiesObserver() + LLPropertiesObserver(LLFloaterProperties* floater) + : mFloater(floater) { gInventory.addObserver(this); } @@ -85,6 +86,8 @@ public: gInventory.removeObserver(this); } virtual void changed(U32 mask); +private: + LLFloaterProperties* mFloater; }; void LLPropertiesObserver::changed(U32 mask) @@ -92,7 +95,7 @@ void LLPropertiesObserver::changed(U32 mask) // if there's a change we're interested in. if((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0) { - LLFloaterProperties::dirtyAll(); + mFloater->dirty(); } } @@ -102,135 +105,65 @@ void LLPropertiesObserver::changed(U32 mask) /// Class LLFloaterProperties ///---------------------------------------------------------------------------- -// static -LLFloaterProperties::instance_map LLFloaterProperties::sInstances; -LLPropertiesObserver* LLFloaterProperties::sPropertiesObserver = NULL; -S32 LLFloaterProperties::sPropertiesObserverCount = 0; - -// static -LLFloaterProperties* LLFloaterProperties::find(const LLUUID& item_id, - const LLUUID& object_id) -{ - // for simplicity's sake, we key the properties window with a - // single uuid. However, the items are keyed by item and object - // (obj == null -> agent inventory). So, we xor the two ids, and - // use that as a lookup key - instance_map::iterator it = sInstances.find(item_id ^ object_id); - if(it != sInstances.end()) - { - return (*it).second; - } - return NULL; -} - -// static -LLFloaterProperties* LLFloaterProperties::show(const LLUUID& item_id, - const LLUUID& object_id) -{ - LLFloaterProperties* instance = find(item_id, object_id); - if(instance) - { - if (LLFloater::getFloaterHost() && LLFloater::getFloaterHost() != instance->getHost()) - { - // this properties window is being opened in a new context - // needs to be rehosted - LLFloater::getFloaterHost()->addFloater(instance, TRUE); - } - - instance->refresh(); - instance->openFloater(); - } - else - { - LLFloaterProperties* floater = new LLFloaterProperties(item_id, object_id); - // keep onscreen - gFloaterView->adjustToFitScreen(floater, FALSE); - } - return instance; -} - -void LLFloaterProperties::dirtyAll() -{ - // ...this is more clear. Possibly more correct, because the - // refresh method may delete the object. - for(instance_map::iterator it = sInstances.begin(); it!=sInstances.end(); ) - { - (*it++).second->dirty(); - } -} - // Default constructor -LLFloaterProperties::LLFloaterProperties(const LLUUID& item_id, const LLUUID& object_id) - : LLFloater(), +LLFloaterProperties::LLFloaterProperties(const LLUUID& item_id) + : LLFloater(mItemID), mItemID(item_id), - mObjectID(object_id), mDirty(TRUE) { - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_inventory_item_properties.xml"); + mPropertiesObserver = new LLPropertiesObserver(this); - if (!sPropertiesObserver) - { - sPropertiesObserver = new LLPropertiesObserver; - } - sPropertiesObserverCount++; - - // add the object to the static structure - LLUUID key = mItemID ^ mObjectID; - sInstances.insert(instance_map::value_type(key, this)); - + //LLUICtrlFactory::getInstance()->buildFloater(this,"floater_inventory_item_properties.xml"); } // Destroys the object LLFloaterProperties::~LLFloaterProperties() { - // clean up the static data. - instance_map::iterator it = sInstances.find(mItemID ^ mObjectID); - if(it != sInstances.end()) - { - sInstances.erase(it); - } - sPropertiesObserverCount--; - if (!sPropertiesObserverCount) - { - delete sPropertiesObserver; - sPropertiesObserver = NULL; - } + delete mPropertiesObserver; + mPropertiesObserver = NULL; } + // virtual BOOL LLFloaterProperties::postBuild() { // build the UI // item name & description childSetPrevalidate("LabelItemName",&LLLineEditor::prevalidatePrintableNotPipe); - childSetCommitCallback("LabelItemName",onCommitName,this); + getChild("LabelItemName")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitName,this)); childSetPrevalidate("LabelItemDesc",&LLLineEditor::prevalidatePrintableNotPipe); - childSetCommitCallback("LabelItemDesc", onCommitDescription, this); + getChild("LabelItemDesc")->setCommitCallback(boost::bind(&LLFloaterProperties:: onCommitDescription, this)); // Creator information - childSetAction("BtnCreator",onClickCreator,this); + getChild("BtnCreator")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickCreator,this)); // owner information - childSetAction("BtnOwner",onClickOwner,this); + getChild("BtnOwner")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickOwner,this)); // acquired date // owner permissions // Permissions debug text // group permissions - childSetCommitCallback("CheckShareWithGroup",&onCommitPermissions, this); + getChild("CheckShareWithGroup")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); // everyone permissions - childSetCommitCallback("CheckEveryoneCopy",&onCommitPermissions, this); + getChild("CheckEveryoneCopy")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); // next owner permissions - childSetCommitCallback("CheckNextOwnerModify",&onCommitPermissions, this); - childSetCommitCallback("CheckNextOwnerCopy",&onCommitPermissions, this); - childSetCommitCallback("CheckNextOwnerTransfer",&onCommitPermissions, this); + getChild("CheckNextOwnerModify")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); + getChild("CheckNextOwnerCopy")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); + getChild("CheckNextOwnerTransfer")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); // Mark for sale or not, and sale info - childSetCommitCallback("CheckPurchase",&onCommitSaleInfo, this); - childSetCommitCallback("RadioSaleType",&onCommitSaleType, this); + getChild("CheckPurchase")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this)); + getChild("RadioSaleType")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleType, this)); // "Price" label for edit - childSetCommitCallback("EditPrice",&onCommitSaleInfo, this); + getChild("EditPrice")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this)); // The UI has been built, now fill in all the values refresh(); return TRUE; } +// virtual +void LLFloaterProperties::onOpen(const LLSD& key) +{ + refresh(); +} + void LLFloaterProperties::refresh() { LLInventoryItem* item = findItem(); @@ -303,12 +236,14 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) // do not enable the UI for incomplete items. LLViewerInventoryItem* i = (LLViewerInventoryItem*)item; BOOL is_complete = i->isComplete(); - + const BOOL cannot_restrict_permissions = LLInventoryType::cannotRestrictPermissions(i->getInventoryType()); + const BOOL is_calling_card = (i->getInventoryType() == LLInventoryType::IT_CALLINGCARD); const LLPermissions& perm = item->getPermissions(); const BOOL can_agent_manipulate = gAgent.allowOperation(PERM_OWNER, perm, GP_OBJECT_MANIPULATE); const BOOL can_agent_sell = gAgent.allowOperation(PERM_OWNER, perm, - GP_OBJECT_SET_SALE); + GP_OBJECT_SET_SALE) && + !cannot_restrict_permissions; const BOOL is_link = LLAssetType::lookupIsLinkType(i->getActualType()); // You need permission to modify the object to modify an inventory @@ -325,11 +260,11 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) // ITEM NAME & DESC // ////////////////////// BOOL is_modifiable = gAgent.allowOperation(PERM_MODIFY, perm, - GP_OBJECT_MANIPULATE) - && is_obj_modify && is_complete; + GP_OBJECT_MANIPULATE) + && is_obj_modify && is_complete; childSetEnabled("LabelItemNameTitle",TRUE); - childSetEnabled("LabelItemName",is_modifiable); + childSetEnabled("LabelItemName",is_modifiable && !is_calling_card); // for now, don't allow rename of calling cards childSetText("LabelItemName",item->getName()); childSetEnabled("LabelItemDescTitle",TRUE); childSetEnabled("LabelItemDesc",is_modifiable); @@ -492,7 +427,7 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) ///////////// // Check for ability to change values. - if (is_link) + if (is_link || cannot_restrict_permissions) { childSetEnabled("CheckShareWithGroup",FALSE); childSetEnabled("CheckEveryoneCopy",FALSE); @@ -558,9 +493,9 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) childSetEnabled("CheckPurchase",is_complete); childSetEnabled("NextOwnerLabel",TRUE); - childSetEnabled("CheckNextOwnerModify",base_mask & PERM_MODIFY); - childSetEnabled("CheckNextOwnerCopy",base_mask & PERM_COPY); - childSetEnabled("CheckNextOwnerTransfer",next_owner_mask & PERM_COPY); + childSetEnabled("CheckNextOwnerModify",(base_mask & PERM_MODIFY) && !cannot_restrict_permissions); + childSetEnabled("CheckNextOwnerCopy",(base_mask & PERM_COPY) && !cannot_restrict_permissions); + childSetEnabled("CheckNextOwnerTransfer",(next_owner_mask & PERM_COPY) && !cannot_restrict_permissions); childSetEnabled("RadioSaleType",is_complete && is_for_sale); childSetEnabled("TextPrice",is_complete && is_for_sale); @@ -602,25 +537,20 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) } } -// static -void LLFloaterProperties::onClickCreator(void* data) +void LLFloaterProperties::onClickCreator() { - LLFloaterProperties* self = (LLFloaterProperties*)data; - if(!self) return; - LLInventoryItem* item = self->findItem(); + LLInventoryItem* item = findItem(); if(!item) return; if(!item->getCreatorUUID().isNull()) { - LLFriendActions::showProfile(item->getCreatorUUID()); + LLAvatarActions::showProfile(item->getCreatorUUID()); } } // static -void LLFloaterProperties::onClickOwner(void* data) +void LLFloaterProperties::onClickOwner() { - LLFloaterProperties* self = (LLFloaterProperties*)data; - if(!self) return; - LLInventoryItem* item = self->findItem(); + LLInventoryItem* item = findItem(); if(!item) return; if(item->getPermissions().isGroupOwned()) { @@ -628,25 +558,20 @@ void LLFloaterProperties::onClickOwner(void* data) } else { - LLFriendActions::showProfile(item->getPermissions().getOwner()); + LLAvatarActions::showProfile(item->getPermissions().getOwner()); } } // static -void LLFloaterProperties::onCommitName(LLUICtrl* ctrl, void* data) +void LLFloaterProperties::onCommitName() { //llinfos << "LLFloaterProperties::onCommitName()" << llendl; - LLFloaterProperties* self = (LLFloaterProperties*)data; - if(!self) - { - return; - } - LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->findItem(); + LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem(); if(!item) { return; } - LLLineEditor* labelItemName = self->getChild("LabelItemName"); + LLLineEditor* labelItemName = getChild("LabelItemName"); if(labelItemName&& (item->getName() != labelItemName->getText()) && @@ -654,15 +579,16 @@ void LLFloaterProperties::onCommitName(LLUICtrl* ctrl, void* data) { LLPointer new_item = new LLViewerInventoryItem(item); new_item->rename(labelItemName->getText()); - if(self->mObjectID.isNull()) + if(mObjectID.isNull()) { new_item->updateServer(FALSE); gInventory.updateItem(new_item); + gInventory.updateLinkedObjects(new_item->getUUID()); gInventory.notifyObservers(); } else { - LLViewerObject* object = gObjectList.findObject(self->mObjectID); + LLViewerObject* object = gObjectList.findObject(mObjectID); if(object) { object->updateInventory( @@ -674,16 +600,13 @@ void LLFloaterProperties::onCommitName(LLUICtrl* ctrl, void* data) } } -// static -void LLFloaterProperties::onCommitDescription(LLUICtrl* ctrl, void* data) +void LLFloaterProperties::onCommitDescription() { //llinfos << "LLFloaterProperties::onCommitDescription()" << llendl; - LLFloaterProperties* self = (LLFloaterProperties*)data; - if(!self) return; - LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->findItem(); + LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem(); if(!item) return; - LLLineEditor* labelItemDesc = self->getChild("LabelItemDesc"); + LLLineEditor* labelItemDesc = getChild("LabelItemDesc"); if(!labelItemDesc) { return; @@ -694,7 +617,7 @@ void LLFloaterProperties::onCommitDescription(LLUICtrl* ctrl, void* data) LLPointer new_item = new LLViewerInventoryItem(item); new_item->setDescription(labelItemDesc->getText()); - if(self->mObjectID.isNull()) + if(mObjectID.isNull()) { new_item->updateServer(FALSE); gInventory.updateItem(new_item); @@ -702,7 +625,7 @@ void LLFloaterProperties::onCommitDescription(LLUICtrl* ctrl, void* data) } else { - LLViewerObject* object = gObjectList.findObject(self->mObjectID); + LLViewerObject* object = gObjectList.findObject(mObjectID); if(object) { object->updateInventory( @@ -715,17 +638,15 @@ void LLFloaterProperties::onCommitDescription(LLUICtrl* ctrl, void* data) } // static -void LLFloaterProperties::onCommitPermissions(LLUICtrl* ctrl, void* data) +void LLFloaterProperties::onCommitPermissions() { //llinfos << "LLFloaterProperties::onCommitPermissions()" << llendl; - LLFloaterProperties* self = (LLFloaterProperties*)data; - if(!self) return; - LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->findItem(); + LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem(); if(!item) return; LLPermissions perm(item->getPermissions()); - LLCheckBoxCtrl* CheckShareWithGroup = self->getChild("CheckShareWithGroup"); + LLCheckBoxCtrl* CheckShareWithGroup = getChild("CheckShareWithGroup"); if(CheckShareWithGroup) { @@ -733,26 +654,26 @@ void LLFloaterProperties::onCommitPermissions(LLUICtrl* ctrl, void* data) CheckShareWithGroup->get(), PERM_MODIFY | PERM_MOVE | PERM_COPY); } - LLCheckBoxCtrl* CheckEveryoneCopy = self->getChild("CheckEveryoneCopy"); + LLCheckBoxCtrl* CheckEveryoneCopy = getChild("CheckEveryoneCopy"); if(CheckEveryoneCopy) { perm.setEveryoneBits(gAgent.getID(), gAgent.getGroupID(), CheckEveryoneCopy->get(), PERM_COPY); } - LLCheckBoxCtrl* CheckNextOwnerModify = self->getChild("CheckNextOwnerModify"); + LLCheckBoxCtrl* CheckNextOwnerModify = getChild("CheckNextOwnerModify"); if(CheckNextOwnerModify) { perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(), CheckNextOwnerModify->get(), PERM_MODIFY); } - LLCheckBoxCtrl* CheckNextOwnerCopy = self->getChild("CheckNextOwnerCopy"); + LLCheckBoxCtrl* CheckNextOwnerCopy = getChild("CheckNextOwnerCopy"); if(CheckNextOwnerCopy) { perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(), CheckNextOwnerCopy->get(), PERM_COPY); } - LLCheckBoxCtrl* CheckNextOwnerTransfer = self->getChild("CheckNextOwnerTransfer"); + LLCheckBoxCtrl* CheckNextOwnerTransfer = getChild("CheckNextOwnerTransfer"); if(CheckNextOwnerTransfer) { perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(), @@ -788,7 +709,7 @@ void LLFloaterProperties::onCommitPermissions(LLUICtrl* ctrl, void* data) flags |= LLInventoryItem::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP; } new_item->setFlags(flags); - if(self->mObjectID.isNull()) + if(mObjectID.isNull()) { new_item->updateServer(FALSE); gInventory.updateItem(new_item); @@ -796,7 +717,7 @@ void LLFloaterProperties::onCommitPermissions(LLUICtrl* ctrl, void* data) } else { - LLViewerObject* object = gObjectList.findObject(self->mObjectID); + LLViewerObject* object = gObjectList.findObject(mObjectID); if(object) { object->updateInventory( @@ -809,26 +730,22 @@ void LLFloaterProperties::onCommitPermissions(LLUICtrl* ctrl, void* data) else { // need to make sure we don't just follow the click - self->refresh(); + refresh(); } } // static -void LLFloaterProperties::onCommitSaleInfo(LLUICtrl* ctrl, void* data) +void LLFloaterProperties::onCommitSaleInfo() { //llinfos << "LLFloaterProperties::onCommitSaleInfo()" << llendl; - LLFloaterProperties* self = (LLFloaterProperties*)data; - if(!self) return; - self->updateSaleInfo(); + updateSaleInfo(); } // static -void LLFloaterProperties::onCommitSaleType(LLUICtrl* ctrl, void* data) +void LLFloaterProperties::onCommitSaleType() { //llinfos << "LLFloaterProperties::onCommitSaleType()" << llendl; - LLFloaterProperties* self = (LLFloaterProperties*)data; - if(!self) return; - self->updateSaleInfo(); + updateSaleInfo(); } void LLFloaterProperties::updateSaleInfo() @@ -954,13 +871,15 @@ LLInventoryItem* LLFloaterProperties::findItem() const return item; } -void LLFloaterProperties::closeByID(const LLUUID& item_id, const LLUUID &object_id) +//static +void LLFloaterProperties::dirtyAll() { - LLFloaterProperties* floaterp = find(item_id, object_id); - - if (floaterp) + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("properties"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); + iter != inst_list.end(); ++iter) { - floaterp->closeFloater(); + LLFloaterProperties* floater = dynamic_cast(*iter); + floater->dirty(); } } @@ -969,7 +888,7 @@ void LLFloaterProperties::closeByID(const LLUUID& item_id, const LLUUID &object_ ///---------------------------------------------------------------------------- LLMultiProperties::LLMultiProperties() - : LLMultiFloater() + : LLMultiFloater(LLSD()) { // *TODO: There should be a .xml file for this const LLRect& nextrect = LLFloaterReg::getFloaterRect("properties"); // place where the next properties should show up diff --git a/indra/newview/llfloaterproperties.h b/indra/newview/llfloaterproperties.h index d0e5abefb8..586719a4dc 100644 --- a/indra/newview/llfloaterproperties.h +++ b/indra/newview/llfloaterproperties.h @@ -53,30 +53,27 @@ class LLPropertiesObserver; class LLFloaterProperties : public LLFloater { public: - static LLFloaterProperties* find(const LLUUID& item_id, - const LLUUID& object_id = LLUUID::null); - static LLFloaterProperties* show(const LLUUID& item_id, - const LLUUID& object_id = LLUUID::null); - static void dirtyAll(); - - static void closeByID(const LLUUID& item_id, const LLUUID& object_id); - - LLFloaterProperties(const LLUUID& item_id, const LLUUID& object_id); - virtual ~LLFloaterProperties(); + LLFloaterProperties(const LLUUID& item_id); + /*virtual*/ ~LLFloaterProperties(); + /*virtual*/ BOOL postBuild(); - // do everything necessary + /*virtual*/ void onOpen(const LLSD& key); + void setObjectID(const LLUUID& object_id) { mObjectID = object_id; } + void dirty() { mDirty = TRUE; } void refresh(); - + + static void dirtyAll(); + protected: // ui callbacks - static void onClickCreator(void* data); - static void onClickOwner(void* data); - static void onCommitName(LLUICtrl* ctrl, void* data); - static void onCommitDescription(LLUICtrl* ctrl, void* data); - static void onCommitPermissions(LLUICtrl* ctrl, void* data); - static void onCommitSaleInfo(LLUICtrl* ctrl, void* data); - static void onCommitSaleType(LLUICtrl* ctrl, void* data); + void onClickCreator(); + void onClickOwner(); + void onCommitName(); + void onCommitDescription(); + void onCommitPermissions(); + void onCommitSaleInfo(); + void onCommitSaleType(); void updateSaleInfo(); LLInventoryItem* findItem() const; @@ -93,12 +90,9 @@ protected: // inventory. LLUUID mObjectID; - BOOL mDirty; + BOOL mDirty; - typedef std::map instance_map; - static instance_map sInstances; - static LLPropertiesObserver* sPropertiesObserver; - static S32 sPropertiesObserverCount; + LLPropertiesObserver* mPropertiesObserver; }; class LLMultiProperties : public LLMultiFloater diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 57a3bf9445..94d25aa0c8 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -58,6 +58,7 @@ #include "llfloatergodtools.h" // for send_sim_wide_deletes() #include "llfloatertopobjects.h" // added to fix SL-32336 #include "llfloatergroups.h" +#include "llfloaterreg.h" #include "llfloatertelehub.h" #include "llfloaterwindlight.h" #include "llinventorymodel.h" @@ -75,8 +76,8 @@ #include "llviewercontrol.h" #include "lluictrlfactory.h" #include "llviewerinventory.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "llviewerstats.h" #include "llviewertexteditor.h" @@ -164,9 +165,9 @@ bool estate_dispatch_initialized = false; LLUUID LLFloaterRegionInfo::sRequestInvoice; LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed) - : LLFloater() + : LLFloater(seed) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_info.xml", FALSE); + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_info.xml", FALSE); } BOOL LLFloaterRegionInfo::postBuild() @@ -247,7 +248,8 @@ void LLFloaterRegionInfo::requestRegionInfo() void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) { static LLDispatcher dispatch; - if(!findInstance()) + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if(!floater) { return; } @@ -257,7 +259,7 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) LLPanelEstateInfo::initDispatch(dispatch); } - LLTabContainer* tab = findInstance()->getChild("region_panels"); + LLTabContainer* tab = floater->getChild("region_panels"); LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild("Estate"); // unpack the message @@ -283,14 +285,14 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) { LLPanel* panel; - + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); llinfos << "LLFloaterRegionInfo::processRegionInfo" << llendl; - if(!findInstance()) + if(!floater) { return; } - LLTabContainer* tab = findInstance()->getChild("region_panels"); + LLTabContainer* tab = floater->getChild("region_panels"); LLViewerRegion* region = gAgent.getRegion(); BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); @@ -377,13 +379,13 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) panel->childSetEnabled("sun_hour_slider", allow_modify && !use_estate_sun); panel->setCtrlsEnabled(allow_modify); - getInstance()->refreshFromRegion( gAgent.getRegion() ); + floater->refreshFromRegion( gAgent.getRegion() ); } // static LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() { - LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); if (!floater) return NULL; LLTabContainer* tab = floater->getChild("region_panels"); LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild("Estate"); @@ -393,7 +395,7 @@ LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() // static LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() { - LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); if (!floater) return NULL; LLTabContainer* tab = floater->getChild("region_panels"); LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)tab->getChild("Covenant"); @@ -611,7 +613,8 @@ BOOL LLPanelRegionGeneralInfo::postBuild() childSetAction("kick_btn", onClickKick, this); childSetAction("kick_all_btn", onClickKickAll, this); childSetAction("im_btn", onClickMessage, this); - childSetAction("manage_telehub_btn", onClickManageTelehub, this); +// childSetAction("manage_telehub_btn", onClickManageTelehub, this); + mCommitCallbackRegistrar.add("RegionInfo.Cancel", boost::bind(&LLPanelRegionGeneralInfo::onClickManageTelehub, this)); return LLPanelRegionInfo::postBuild(); } @@ -719,12 +722,10 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L return false; } -// static -void LLPanelRegionGeneralInfo::onClickManageTelehub(void* data) +void LLPanelRegionGeneralInfo::onClickManageTelehub() { - LLFloaterRegionInfo::getInstance()->closeFloater(); - - LLFloaterTelehub::show(); + LLFloaterReg::hideInstance("region_info"); + LLFloaterReg::showInstance("telehubs"); } // setregioninfo @@ -958,8 +959,10 @@ void LLPanelRegionDebugInfo::onClickTopColliders(void* data) strings_t strings; strings.push_back("1"); // one physics step LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - LLFloaterTopObjects::show(); - LLFloaterTopObjects::clearList(); + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); + if(!instance) return; + LLFloaterReg::showInstance("top_objects"); + instance->clearList(); self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings); } @@ -970,8 +973,10 @@ void LLPanelRegionDebugInfo::onClickTopScripts(void* data) strings_t strings; strings.push_back("6"); // top 5 scripts LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - LLFloaterTopObjects::show(); - LLFloaterTopObjects::clearList(); + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); + if(!instance) return; + LLFloaterReg::showInstance("top_objects"); + instance->clearList(); self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings); } @@ -1139,11 +1144,11 @@ BOOL LLPanelRegionTextureInfo::validateTextureSizes() if (!texture_ctrl) continue; LLUUID image_asset_id = texture_ctrl->getImageAssetID(); - LLViewerImage* img = gImageList.getImage(image_asset_id); + LLViewerTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id); S32 components = img->getComponents(); // Must ask for highest resolution version's width. JC - S32 width = img->getWidth(0); - S32 height = img->getHeight(0); + S32 width = img->getFullWidth(); + S32 height = img->getFullHeight(); //llinfos << "texture detail " << i << " is " << width << "x" << height << "x" << components << llendl; @@ -1254,7 +1259,7 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() // Grab estate information in case the user decided to set the // region back to estate time. JC - LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); if (!floater) return true; LLTabContainer* tab = floater->getChild("region_panels"); @@ -1450,12 +1455,12 @@ void LLPanelEstateInfo::onChangeFixedSun(LLUICtrl* ctrl, void* user_data) //--------------------------------------------------------------------------- void LLPanelEstateInfo::onClickEditSky(void* user_data) { - LLFloaterWindLight::show(); + LLFloaterReg::showInstance("env_windlight"); } void LLPanelEstateInfo::onClickEditDayCycle(void* user_data) { - LLFloaterDayCycle::show(); + LLFloaterReg::showInstance("env_day_cycle"); } // static @@ -1513,8 +1518,7 @@ bool LLPanelEstateInfo::addAllowedGroup(const LLSD& notification, const LLSD& re LLFloater* parent_floater = gFloaterView->getParentFloater(this); - LLFloaterGroupPicker* widget; - widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); + LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance("group_picker", LLSD(gAgent.getID())); if (widget) { widget->setSelectGroupCallback(boost::bind(&LLPanelEstateInfo::addAllowedGroup2, this, _1)); diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index b3a1fcb7ca..be4becf7e7 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -59,11 +59,11 @@ class LLPanelRegionTerrainInfo; class LLPanelEstateInfo; class LLPanelEstateCovenant; -class LLFloaterRegionInfo : public LLFloater, public LLFloaterSingleton +class LLFloaterRegionInfo : public LLFloater { - friend class LLUISingleton >; + friend class LLFloaterReg; public: - ~LLFloaterRegionInfo(); + /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ BOOL postBuild(); @@ -86,8 +86,12 @@ public: void requestRegionInfo(); -protected: +private: + LLFloaterRegionInfo(const LLSD& seed); + ~LLFloaterRegionInfo(); + +protected: void refreshFromRegion(LLViewerRegion* region); // member data @@ -166,7 +170,7 @@ protected: bool onKickAllCommit(const LLSD& notification, const LLSD& response); static void onClickMessage(void* userdata); bool onMessageCommit(const LLSD& notification, const LLSD& response); - static void onClickManageTelehub(void* data); + void onClickManageTelehub(); }; ///////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 4b175cdc27..00cbc2f0c8 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -53,7 +53,8 @@ #include "llagent.h" #include "llbutton.h" #include "llcheckboxctrl.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" +#include "llfloaterreg.h" #include "lllineeditor.h" #include "lltexturectrl.h" #include "llscrolllistctrl.h" @@ -73,7 +74,7 @@ #include "lltoolmgr.h" #include "llresourcedata.h" // for LLResourceData #include "llviewerwindow.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llworldmap.h" #include "llfilepicker.h" #include "llfloateravatarpicker.h" @@ -91,24 +92,14 @@ const U32 INCLUDE_SCREENSHOT = 0x01 << 0; // Globals //----------------------------------------------------------------------------- -// this map keeps track of current reporter instances -// there can only be one instance of each reporter type -LLMap< EReportType, LLFloaterReporter* > gReporterInstances; - -// keeps track of where email is going to - global to avoid a pile -// of static/non-static access outside my control -namespace { - static BOOL gEmailToEstateOwner = FALSE; - static BOOL gDialogVisible = FALSE; -} - //----------------------------------------------------------------------------- // Member functions //----------------------------------------------------------------------------- -LLFloaterReporter::LLFloaterReporter(EReportType report_type) -: LLFloater(), - mReportType(report_type), +LLFloaterReporter::LLFloaterReporter(const LLSD& key) +: LLFloater(key), + mReportType(COMPLAINT_REPORT), + mEmailToEstateOwner(FALSE), mObjectID(), mScreenID(), mAbuserID(), @@ -118,10 +109,34 @@ LLFloaterReporter::LLFloaterReporter(EReportType report_type) mCopyrightWarningSeen( FALSE ), mResourceDatap(new LLResourceData()) { + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_report_abuse.xml"); +} - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_report_abuse.xml"); +// static +void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg) +{ + U32 region_flags; + msg->getU32("RegionInfo", "RegionFlags", region_flags); + if ( LLFloaterReg::instanceVisible("reporter") ) + { + LLFloaterReporter *f = LLFloaterReg::findTypedInstance("reporter"); + BOOL email_to_estate_owner = ( region_flags & REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER ); + f->mEmailToEstateOwner = email_to_estate_owner; + if ( email_to_estate_owner ) + { + LLNotifications::instance().add("HelpReportAbuseEmailEO"); + } + else + { + LLNotifications::instance().add("HelpReportAbuseEmailLL"); + } + }; +} +// virtual +BOOL LLFloaterReporter::postBuild() +{ childSetText("abuse_location_edit", gAgent.getSLURL() ); enableControls(TRUE); @@ -135,8 +150,6 @@ LLFloaterReporter::LLFloaterReporter(EReportType report_type) } setPosBox(pos); - gReporterInstances.addData(report_type, this); - // Take a screenshot, but don't draw this floater. setVisible(FALSE); takeScreenshot(); @@ -150,9 +163,6 @@ LLFloaterReporter::LLFloaterReporter(EReportType report_type) mDefaultSummary = childGetText("details_edit"); - gDialogVisible = TRUE; - - // send a message and ask for information about this region - // result comes back in processRegionInfo(..) LLMessageSystem* msg = gMessageSystem; @@ -161,29 +171,8 @@ LLFloaterReporter::LLFloaterReporter(EReportType report_type) msg->addUUID("AgentID", gAgent.getID()); msg->addUUID("SessionID", gAgent.getSessionID()); gAgent.sendReliableMessage(); - -} - -// static -void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg) -{ - U32 region_flags; - msg->getU32("RegionInfo", "RegionFlags", region_flags); - gEmailToEstateOwner = ( region_flags & REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER ); - - if ( gDialogVisible ) - { - if ( gEmailToEstateOwner ) - { - LLNotifications::instance().add("HelpReportAbuseEmailEO"); - } - else - LLNotifications::instance().add("HelpReportAbuseEmailLL"); - }; -} -// virtual -BOOL LLFloaterReporter::postBuild() -{ + + // abuser name is selected from a list LLLineEditor* le = getChild("abuser_name_edit"); le->setEnabled( FALSE ); @@ -198,12 +187,19 @@ BOOL LLFloaterReporter::postBuild() childSetAction("send_btn", onClickSend, this); childSetAction("cancel_btn", onClickCancel, this); + + // grab the user's name + std::string fullname; + gAgent.buildFullname(fullname); + childSetText("reporter_field", fullname); + + center(); + return TRUE; } // virtual LLFloaterReporter::~LLFloaterReporter() { - gReporterInstances.removeData(mReportType); // child views automatically deleted mObjectID = LLUUID::null; @@ -218,7 +214,6 @@ LLFloaterReporter::~LLFloaterReporter() mMCDList.clear(); delete mResourceDatap; - gDialogVisible = FALSE; } // virtual @@ -227,7 +222,7 @@ void LLFloaterReporter::draw() // this is set by a static callback sometime after the dialog is created. // Only disable screenshot for abuse reports to estate owners - bug reports always // allow screenshots to be taken. - if ( gEmailToEstateOwner ) + if ( mEmailToEstateOwner ) { childSetValue("screen_check", FALSE ); childSetEnabled("screen_check", FALSE ); @@ -474,27 +469,16 @@ void LLFloaterReporter::closePickTool(void *userdata) // static void LLFloaterReporter::showFromMenu(EReportType report_type) { - if (gReporterInstances.checkData(report_type)) + if (COMPLAINT_REPORT != report_type) { - // ...bring that window to front - LLFloaterReporter *f = gReporterInstances.getData(report_type); - f->openFloater(); + llwarns << "Unknown LLViewerReporter type : " << report_type << llendl; + return; } - else + + LLFloaterReporter* f = LLFloaterReg::showTypedInstance("reporter", LLSD()); + if (f) { - LLFloaterReporter *f; - - if (COMPLAINT_REPORT == report_type) - { - f = LLFloaterReporter::createNewAbuseReporter(); - } - else - { - llwarns << "Unknown LLViewerReporter type : " << report_type << llendl; - return; - } - - f->center(); + f->setReportType(report_type); if (report_type == BUG_REPORT) { @@ -504,11 +488,6 @@ void LLFloaterReporter::showFromMenu(EReportType report_type) { // popup for abuse reports is triggered elsewhere } - - // grab the user's name - std::string fullname; - gAgent.buildFullname(fullname); - f->childSetText("reporter_field", fullname); } } @@ -516,9 +495,7 @@ void LLFloaterReporter::showFromMenu(EReportType report_type) // static void LLFloaterReporter::showFromObject(const LLUUID& object_id) { - LLFloaterReporter* f = createNewAbuseReporter(); - f->center(); - f->setFocus(TRUE); + LLFloaterReporter* f = LLFloaterReg::showTypedInstance("reporter"); // grab the user's name std::string fullname; @@ -535,24 +512,6 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id) } -// static -LLFloaterReporter* LLFloaterReporter::getReporter(EReportType report_type) -{ - LLFloaterReporter *self = NULL; - if (gReporterInstances.checkData(report_type)) - { - // ...bring that window to front - self = gReporterInstances.getData(report_type); - } - return self; -} - -LLFloaterReporter* LLFloaterReporter::createNewAbuseReporter() -{ - return new LLFloaterReporter(COMPLAINT_REPORT); -} - - void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id) { childSetText("object_name", object_name); @@ -710,7 +669,7 @@ LLSD LLFloaterReporter::gatherReport() if (childGetValue("screen_check")) { - if ( gEmailToEstateOwner == FALSE ) + if ( mEmailToEstateOwner == FALSE ) { screenshot_id = childGetValue("screenshot"); } @@ -825,7 +784,7 @@ void LLFloaterReporter::takeScreenshot() llwarns << "Unable to take screenshot" << llendl; return; } - LLPointer upload_data = LLViewerImageList::convertToUploadFile(raw); + LLPointer upload_data = LLViewerTextureList::convertToUploadFile(raw); // create a resource data mResourceDatap->mInventoryType = LLInventoryType::IT_NONE; @@ -855,10 +814,10 @@ void LLFloaterReporter::takeScreenshot() mResourceDatap->mAssetInfo.mType); // store in the image list so it doesn't try to fetch from the server - LLPointer image_in_list = new LLViewerImage(mResourceDatap->mAssetInfo.mUuid, TRUE); + LLPointer image_in_list = + LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid, TRUE, FALSE, LLViewerTexture::FETCHED_TEXTURE); image_in_list->createGLTexture(0, raw); - gImageList.addImage(image_in_list); - + // the texture picker then uses that texture LLTexturePicker* texture = getChild("screenshot"); if (texture) @@ -914,7 +873,7 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data, llwarns << "Unknown report type : " << data->mPreferredLocation << llendl; } - LLFloaterReporter *self = getReporter(report_type); + LLFloaterReporter *self = LLFloaterReg::findTypedInstance("reporter"); if (self) { self->mScreenID = uuid; @@ -935,35 +894,35 @@ void LLFloaterReporter::setPosBox(const LLVector3d &pos) childSetText("pos_field", pos_string); } -void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd) -{ - LLFloaterReporter *self = gReporterInstances[COMPLAINT_REPORT]; - if (self) - { - self->childSetText("details_edit", description); +// void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd) +// { +// LLFloaterReporter *self = LLFloaterReg::findTypedInstance("reporter"); +// if (self) +// { +// self->childSetText("details_edit", description); - for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer()); - self->mMCDList.clear(); - if (mcd) - { - self->mMCDList.push_back(new LLMeanCollisionData(mcd)); - } - } -} +// for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer()); +// self->mMCDList.clear(); +// if (mcd) +// { +// self->mMCDList.push_back(new LLMeanCollisionData(mcd)); +// } +// } +// } -void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd) -{ - LLFloaterReporter *self = gReporterInstances[COMPLAINT_REPORT]; - if (self) - { - LLTextEditor* text = self->getChild("details_edit"); - if (text) - { - text->insertText(description); - } - if (mcd) - { - self->mMCDList.push_back(new LLMeanCollisionData(mcd)); - } - } -} +// void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd) +// { +// LLFloaterReporter *self = LLFloaterReg::findTypedInstance("reporter"); +// if (self) +// { +// LLTextEditor* text = self->getChild("details_edit"); +// if (text) +// { +// text->insertText(description); +// } +// if (mcd) +// { +// self->mMCDList.push_back(new LLMeanCollisionData(mcd)); +// } +// } +// } diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index da1dda9c78..f363b9531e 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -39,7 +39,7 @@ #include "v3math.h" class LLMessageSystem; -class LLViewerImage; +class LLViewerTexture; class LLInventoryItem; class LLViewerObject; class LLAgent; @@ -82,11 +82,13 @@ class LLFloaterReporter : public LLFloater { public: - LLFloaterReporter(EReportType = UNKNOWN_REPORT); + LLFloaterReporter(const LLSD& key); /*virtual*/ ~LLFloaterReporter(); /*virtual*/ BOOL postBuild(); virtual void draw(); - + + void setReportType(EReportType type) { mReportType = type; } + // Enables all buttons static void showFromMenu(EReportType report_type); @@ -101,10 +103,6 @@ public: static void addDescription(const std::string& description, LLMeanCollisionData *mcd = NULL); static void setDescription(const std::string& description, LLMeanCollisionData *mcd = NULL); - // returns a pointer to reporter of report_type - static LLFloaterReporter* getReporter(EReportType report_type); - static LLFloaterReporter* createNewAbuseReporter(); - // static static void processRegionInfo(LLMessageSystem* msg); @@ -126,6 +124,7 @@ private: private: EReportType mReportType; + BOOL mEmailToEstateOwner; LLUUID mObjectID; LLUUID mScreenID; LLUUID mAbuserID; diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp index b2bb343681..c8690de68c 100644 --- a/indra/newview/llfloaterscriptdebug.cpp +++ b/indra/newview/llfloaterscriptdebug.cpp @@ -32,9 +32,10 @@ #include "llviewerprecompiledheaders.h" -#include "lluictrlfactory.h" #include "llfloaterscriptdebug.h" +#include "llfloaterreg.h" +#include "lluictrlfactory.h" #include "llfontgl.h" #include "llrect.h" #include "llerror.h" @@ -45,24 +46,20 @@ #include "llviewertexteditor.h" #include "llviewercontrol.h" #include "llviewerobjectlist.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" // // Statics // -LLFloaterScriptDebug* LLFloaterScriptDebug::sInstance = NULL; - -void* getOutputWindow(void* data); // // Member Functions // -LLFloaterScriptDebug::LLFloaterScriptDebug(const std::string& filename) - : LLMultiFloater() +LLFloaterScriptDebug::LLFloaterScriptDebug(const LLSD& key) + : LLMultiFloater(key) { - mFactoryMap["all_scripts"] = LLCallbackMap(getOutputWindow, NULL); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_script_debug.xml"); - +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_script_debug.xml"); + // avoid resizing of the window to match // the initial size of the tabbed-childs, whenever a tab is opened or closed mAutoResize = FALSE; @@ -70,20 +67,11 @@ LLFloaterScriptDebug::LLFloaterScriptDebug(const std::string& filename) LLFloaterScriptDebug::~LLFloaterScriptDebug() { - sInstance = NULL; } void LLFloaterScriptDebug::show(const LLUUID& object_id) { - LLFloater* floaterp = addOutputWindow(object_id); - if (sInstance) - { - sInstance->openFloater(object_id); - if (object_id.notNull()) - sInstance->showFloater(floaterp, LLTabContainer::END); -// else // Jump to [All scripts], but keep it on the left -// sInstance->showFloater(floaterp, LLTabContainer::START); - } + addOutputWindow(object_id); } BOOL LLFloaterScriptDebug::postBuild() @@ -101,26 +89,16 @@ BOOL LLFloaterScriptDebug::postBuild() return FALSE; } -void* getOutputWindow(void* data) -{ - return new LLFloaterScriptDebugOutput(LLUUID::null); -} - LLFloater* LLFloaterScriptDebug::addOutputWindow(const LLUUID &object_id) { - if (!sInstance) - { - sInstance = new LLFloaterScriptDebug("floater_script_debug.xml"); - sInstance->setVisible(FALSE); - } + LLMultiFloater* host = LLFloaterReg::showTypedInstance("script_debug", LLSD()); + if (!host) + return NULL; - LLFloater::setFloaterHost(sInstance); - LLFloater* floaterp = LLFloaterScriptDebugOutput::show(object_id); + LLFloater::setFloaterHost(host); + LLFloater* floaterp = LLFloaterReg::showInstance("script_debug_output", object_id); LLFloater::setFloaterHost(NULL); - // Tabs sometimes overlap resize handle - sInstance->moveResizeHandlesToFront(); - return floaterp; } @@ -131,7 +109,7 @@ void LLFloaterScriptDebug::addScriptLine(const std::string &utf8mesg, const std: if (objectp) { - objectp->setIcon(gImageList.getImageFromFile("script_error.j2c", TRUE, TRUE)); + objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", TRUE, TRUE)); floater_label = llformat("%s(%.2f, %.2f)", user_name.c_str(), objectp->getPositionRegion().mV[VX], objectp->getPositionRegion().mV[VY]); } else @@ -143,26 +121,29 @@ void LLFloaterScriptDebug::addScriptLine(const std::string &utf8mesg, const std: addOutputWindow(source_id); // add to "All" floater - LLFloaterScriptDebugOutput* floaterp = LLFloaterScriptDebugOutput::getFloaterByID(LLUUID::null); - floaterp->addLine(utf8mesg, user_name, color); - + LLFloaterScriptDebugOutput* floaterp = LLFloaterReg::getTypedInstance("script_debug_output", LLUUID::null); + if (floaterp) + { + floaterp->addLine(utf8mesg, user_name, color); + } + // add to specific script instance floater - floaterp = LLFloaterScriptDebugOutput::getFloaterByID(source_id); - floaterp->addLine(utf8mesg, floater_label, color); + floaterp = LLFloaterReg::getTypedInstance("script_debug_output", source_id); + if (floaterp) + { + floaterp->addLine(utf8mesg, floater_label, color); + } } // // LLFloaterScriptDebugOutput // -std::map LLFloaterScriptDebugOutput::sInstanceMap; - -LLFloaterScriptDebugOutput::LLFloaterScriptDebugOutput(const LLUUID& object_id) - : LLFloater(), - mObjectID(object_id) +LLFloaterScriptDebugOutput::LLFloaterScriptDebugOutput(const LLSD& object_id) + : LLFloater(LLSD(object_id)), + mObjectID(object_id.asUUID()) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_script_debug_panel.xml"); - sInstanceMap[object_id] = this; + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_script_debug_panel.xml"); } BOOL LLFloaterScriptDebugOutput::postBuild() @@ -174,7 +155,6 @@ BOOL LLFloaterScriptDebugOutput::postBuild() LLFloaterScriptDebugOutput::~LLFloaterScriptDebugOutput() { - sInstanceMap.erase(mObjectID); } void LLFloaterScriptDebugOutput::addLine(const std::string &utf8mesg, const std::string &user_name, const LLColor4& color) @@ -193,33 +173,3 @@ void LLFloaterScriptDebugOutput::addLine(const std::string &utf8mesg, const std: mHistoryEditor->appendColoredText(utf8mesg, false, true, color); } -//static -LLFloaterScriptDebugOutput* LLFloaterScriptDebugOutput::show(const LLUUID& object_id) -{ - LLFloaterScriptDebugOutput* floaterp = NULL; - instance_map_t::iterator found_it = sInstanceMap.find(object_id); - if (found_it == sInstanceMap.end()) - { - floaterp = new LLFloaterScriptDebugOutput(object_id); - floaterp->openFloater(); - } - else - { - floaterp = found_it->second; - } - - return floaterp; -} - -//static -LLFloaterScriptDebugOutput* LLFloaterScriptDebugOutput::getFloaterByID(const LLUUID& object_id) -{ - LLFloaterScriptDebugOutput* floaterp = NULL; - instance_map_t::iterator found_it = sInstanceMap.find(object_id); - if (found_it != sInstanceMap.end()) - { - floaterp = found_it->second; - } - - return floaterp; -} diff --git a/indra/newview/llfloaterscriptdebug.h b/indra/newview/llfloaterscriptdebug.h index 5f2cf48125..ffc60e5554 100644 --- a/indra/newview/llfloaterscriptdebug.h +++ b/indra/newview/llfloaterscriptdebug.h @@ -41,15 +41,13 @@ class LLUUID; class LLFloaterScriptDebug : public LLMultiFloater { public: + LLFloaterScriptDebug(const LLSD& key); virtual ~LLFloaterScriptDebug(); - virtual void onClose(bool app_quitting) { setVisible(FALSE); } virtual BOOL postBuild(); static void show(const LLUUID& object_id); static void addScriptLine(const std::string &utf8mesg, const std::string &user_name, const LLColor4& color, const LLUUID& source_id); protected: - LLFloaterScriptDebug(const std::string& filename); - static LLFloater* addOutputWindow(const LLUUID& object_id); protected: @@ -59,24 +57,17 @@ protected: class LLFloaterScriptDebugOutput : public LLFloater { public: - LLFloaterScriptDebugOutput(); - LLFloaterScriptDebugOutput(const LLUUID& object_id); + LLFloaterScriptDebugOutput(const LLSD& object_id); ~LLFloaterScriptDebugOutput(); void addLine(const std::string &utf8mesg, const std::string &user_name, const LLColor4& color); virtual BOOL postBuild(); - static LLFloaterScriptDebugOutput* show(const LLUUID& object_id); - static LLFloaterScriptDebugOutput* getFloaterByID(const LLUUID& id); - protected: - LLTextEditor* mHistoryEditor; + LLTextEditor* mHistoryEditor; - typedef std::map instance_map_t; - static instance_map_t sInstanceMap; - - LLUUID mObjectID; + LLUUID mObjectID; }; #endif // LL_LLFLOATERSCRIPTDEBUG_H diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp index 6775e218cb..a6aa01e83b 100644 --- a/indra/newview/llfloatersellland.cpp +++ b/indra/newview/llfloatersellland.cpp @@ -34,7 +34,7 @@ #include "llfloatersellland.h" #include "llfloateravatarpicker.h" -#include "llfloater.h" +#include "llfloaterreg.h" #include "llfloaterland.h" #include "lllineeditor.h" #include "llnotify.h" @@ -55,10 +55,21 @@ enum Badge { BADGE_OK, BADGE_NOTE, BADGE_WARN, BADGE_ERROR }; class LLFloaterSellLandUI : public LLFloater { -private: - LLFloaterSellLandUI(); +public: + LLFloaterSellLandUI(const LLSD& key); virtual ~LLFloaterSellLandUI(); - + +private: + class SelectionObserver : public LLParcelObserver + { + public: + SelectionObserver(LLFloaterSellLandUI* floater) : mFloater(floater) {} + virtual void changed(); + private: + LLFloaterSellLandUI* mFloater; + }; + +private: LLViewerRegion* mRegion; LLParcelSelectionHandle mParcelSelection; bool mParcelIsForSale; @@ -69,13 +80,12 @@ private: LLUUID mParcelSnapshot; LLUUID mAuthorizedBuyer; bool mParcelSoldWithObjects; + SelectionObserver mParcelSelectionObserver; void updateParcelInfo(); void refreshUI(); void setBadge(const char* id, Badge badge); - static LLFloaterSellLandUI* sInstance; - static void onChangeValue(LLUICtrl *ctrl, void *userdata); static void doSelectAgent(void *userdata); static void doCancel(void *userdata); @@ -89,82 +99,55 @@ private: public: virtual BOOL postBuild(); - static LLFloaterSellLandUI* soleInstance(bool createIfNeeded); - bool setParcel(LLViewerRegion* region, LLParcelSelectionHandle parcel); - -private: - class SelectionObserver : public LLParcelObserver - { - public: - virtual void changed(); - }; }; // static void LLFloaterSellLand::sellLand( LLViewerRegion* region, LLParcelSelectionHandle parcel) { - LLFloaterSellLandUI* ui = LLFloaterSellLandUI::soleInstance(true); - if (ui->setParcel(region, parcel)) - { - ui->openFloater(); - } + LLFloaterSellLandUI* ui = LLFloaterReg::showTypedInstance("sell_land"); + ui->setParcel(region, parcel); } // static -LLFloaterSellLandUI* LLFloaterSellLandUI::sInstance = NULL; - -// static -LLFloaterSellLandUI* LLFloaterSellLandUI::soleInstance(bool createIfNeeded) +LLFloater* LLFloaterSellLand::buildFloater(const LLSD& key) { - if (!sInstance && createIfNeeded) - { - sInstance = new LLFloaterSellLandUI(); - - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_sell_land.xml"); - sInstance->center(); - } - - - static SelectionObserver* parcelSelectionObserver = NULL; - if (!parcelSelectionObserver) - { - parcelSelectionObserver = new SelectionObserver; - LLViewerParcelMgr::getInstance()->addObserver(parcelSelectionObserver); - } - - return sInstance; + LLFloaterSellLandUI* floater = new LLFloaterSellLandUI(key); + return floater; } -LLFloaterSellLandUI::LLFloaterSellLandUI() -: LLFloater(), +#if LL_WINDOWS +// passing 'this' during construction generates a warning. The callee +// only uses the pointer to hold a reference to 'this' which is +// already valid, so this call does the correct thing. Disable the +// warning so that we can compile without generating a warning. +#pragma warning(disable : 4355) +#endif +LLFloaterSellLandUI::LLFloaterSellLandUI(const LLSD& key) +: LLFloater(key), + mParcelSelectionObserver(this), mRegion(0) { + LLViewerParcelMgr::getInstance()->addObserver(&mParcelSelectionObserver); +// LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_sell_land.xml"); } LLFloaterSellLandUI::~LLFloaterSellLandUI() { - if (sInstance == this) - { - sInstance = NULL; - } + LLViewerParcelMgr::getInstance()->removeObserver(&mParcelSelectionObserver); } void LLFloaterSellLandUI::SelectionObserver::changed() { - LLFloaterSellLandUI* ui = LLFloaterSellLandUI::soleInstance(false); - if (ui) + if (LLViewerParcelMgr::getInstance()->selectionEmpty()) { - if (LLViewerParcelMgr::getInstance()->selectionEmpty()) - { - ui->closeFloater(); - } - else { - ui->setParcel( - LLViewerParcelMgr::getInstance()->getSelectionRegion(), - LLViewerParcelMgr::getInstance()->getParcelSelection()); - } + mFloater->closeFloater(); + } + else + { + mFloater->setParcel(LLViewerParcelMgr::getInstance()->getSelectionRegion(), + LLViewerParcelMgr::getInstance()->getParcelSelection()); } } @@ -178,6 +161,7 @@ BOOL LLFloaterSellLandUI::postBuild() childSetAction("cancel_btn", doCancel, this); childSetAction("sell_btn", doSellLand, this); childSetAction("show_objects", doShowObjects, this); + center(); return TRUE; } diff --git a/indra/newview/llfloatersellland.h b/indra/newview/llfloatersellland.h index 12b0ecbcef..1adf08052b 100644 --- a/indra/newview/llfloatersellland.h +++ b/indra/newview/llfloatersellland.h @@ -34,6 +34,7 @@ #include "llsafehandle.h" +class LLFloater; class LLParcel; class LLViewerRegion; class LLParcelSelection; @@ -43,6 +44,8 @@ class LLFloaterSellLand public: static void sellLand(LLViewerRegion* region, LLSafeHandle parcel); + + static LLFloater* buildFloater(const LLSD& key); }; #endif // LL_LLFLOATERSELLLAND_H diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index 8b6102c67f..53b40f8b7a 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -80,10 +80,6 @@ BOOL LLFloaterSettingsDebug::postBuild() { gSavedPerAccountSettings.applyToAll(&func); } - if (key == "all" || key == "skin") - { - gSavedSkinSettings.applyToAll(&func); - } settings_combo->sortByName(); settings_combo->updateSelection(); diff --git a/indra/newview/llfloatersettingsdebug.h b/indra/newview/llfloatersettingsdebug.h index 87833793af..e7dda3a5f4 100644 --- a/indra/newview/llfloatersettingsdebug.h +++ b/indra/newview/llfloatersettingsdebug.h @@ -38,14 +38,11 @@ #include "lltexteditor.h" class LLFloaterSettingsDebug -: public LLFloater, - public LLFloaterSingleton +: public LLFloater { + friend class LLFloaterReg; + public: - // key - selects which settings to show, one of: - // "all", "base", "account", "skin" - LLFloaterSettingsDebug(const LLSD& key); - virtual ~LLFloaterSettingsDebug(); virtual BOOL postBuild(); virtual void draw(); @@ -56,6 +53,12 @@ public: void onCommitSettings(); void onClickDefault(); +private: + // key - selects which settings to show, one of: + // "all", "base", "account", "skin" + LLFloaterSettingsDebug(const LLSD& key); + virtual ~LLFloaterSettingsDebug(); + protected: LLTextEditor* mComment; }; diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index cb4f2a6711..371dfa50cd 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -140,12 +140,12 @@ public: LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; } BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; } BOOL isSnapshotActive() { return mSnapshotActive; } - LLImageGL* getThumbnailImage() const { return mThumbnailImage ; } + LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; } S32 getThumbnailWidth() const { return mThumbnailWidth ; } S32 getThumbnailHeight() const { return mThumbnailHeight ; } BOOL getThumbnailLock() const { return mThumbnailUpdateLock ; } BOOL getThumbnailUpToDate() const { return mThumbnailUpToDate ;} - LLImageGL* getCurrentImage(); + LLViewerTexture* getCurrentImage(); F32 getImageAspect(); F32 getAspect() ; LLRect getImageRect(); @@ -170,7 +170,7 @@ public: private: LLColor4 mColor; - LLPointer mViewerImage[2]; //used to represent the scene when the frame is frozen. + LLPointer mViewerImage[2]; //used to represent the scene when the frame is frozen. LLRect mImageRect[2]; S32 mWidth[2]; S32 mHeight[2]; @@ -178,7 +178,7 @@ private: S32 mMaxImageSize ; //thumbnail image - LLPointer mThumbnailImage ; + LLPointer mThumbnailImage ; S32 mThumbnailWidth ; S32 mThumbnailHeight ; LLRect mPreviewRect ; @@ -278,7 +278,7 @@ void LLSnapshotLivePreview::setMaxImageSize(S32 size) } } -LLImageGL* LLSnapshotLivePreview::getCurrentImage() +LLViewerTexture* LLSnapshotLivePreview::getCurrentImage() { return mViewerImage[mCurImageIndex]; } @@ -723,7 +723,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) if(raw) { - mThumbnailImage = new LLImageGL(raw, FALSE); + mThumbnailImage = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); mThumbnailUpToDate = TRUE ; } @@ -871,8 +871,8 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) scaled->expandToPowerOfTwo(1024, FALSE); } - previewp->mViewerImage[previewp->mCurImageIndex] = new LLImageGL(scaled, FALSE); - LLPointer curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex]; + previewp->mViewerImage[previewp->mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE); + LLPointer curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex]; gGL.getTexUnit(0)->bind(curr_preview_image); if (previewp->getSnapshotType() != SNAPSHOT_TEXTURE) { @@ -1297,7 +1297,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) floater->childSetColor("file_size_label", shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD && got_bytes - && previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLColor4::red : LLUI::sSettingGroups["color"]->getColor( "LabelTextColor" )); + && previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" )); switch(shot_type) { @@ -2094,14 +2094,6 @@ void LLFloaterSnapshot::onOpen(const LLSD& key) gSnapshotFloaterView->adjustToFitScreen(this, FALSE); } -void LLFloaterSnapshot::onClose(bool app_quitting) -{ - gSnapshotFloaterView->setEnabled(FALSE); - // Set invisible so it doesn't eat tooltips. JC - gSnapshotFloaterView->setVisible(FALSE); - destroy(); -} - //static void LLFloaterSnapshot::update() { diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index 1333497bd2..bd01f6c573 100644 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -52,7 +52,6 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void draw(); /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); static void update(); diff --git a/indra/newview/llfloatertelehub.cpp b/indra/newview/llfloatertelehub.cpp index 1d2d3b98f2..9841cd2796 100644 --- a/indra/newview/llfloatertelehub.cpp +++ b/indra/newview/llfloatertelehub.cpp @@ -39,6 +39,7 @@ #include "llfontgl.h" #include "llagent.h" +#include "llfloaterreg.h" #include "llfloatertools.h" #include "llscrolllistctrl.h" #include "llselectmgr.h" @@ -48,61 +49,25 @@ #include "llviewerobjectlist.h" #include "lluictrlfactory.h" -LLFloaterTelehub* LLFloaterTelehub::sInstance = NULL; - - -// static -void LLFloaterTelehub::show() -{ - if (sInstance) - { - sInstance->setVisibleAndFrontmost(); - return; - } - - sInstance = new LLFloaterTelehub(); - - // Show tools floater by selecting translate (select) tool - LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); - LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompTranslate::getInstance() ); - - // Find tools floater, glue to bottom - if (gFloaterTools) - { - LLRect tools_rect = gFloaterTools->getRect(); - S32 our_width = sInstance->getRect().getWidth(); - S32 our_height = sInstance->getRect().getHeight(); - LLRect our_rect; - our_rect.setLeftTopAndSize(tools_rect.mLeft, tools_rect.mBottom, our_width, our_height); - sInstance->setRect(our_rect); - } - - sInstance->sendTelehubInfoRequest(); -} - -LLFloaterTelehub::LLFloaterTelehub() -: LLFloater(), +LLFloaterTelehub::LLFloaterTelehub(const LLSD& key) +: LLFloater(key), mTelehubObjectID(), mTelehubObjectName(), mTelehubPos(), mTelehubRot(), mNumSpawn(0) { - sInstance = this; - - gMessageSystem->setHandlerFunc("TelehubInfo", processTelehubInfo); - - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_telehub.xml"); - - mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); + //LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_telehub.xml"); } + BOOL LLFloaterTelehub::postBuild() { + gMessageSystem->setHandlerFunc("TelehubInfo", processTelehubInfo); - childSetAction("connect_btn", onClickConnect, this); - childSetAction("disconnect_btn", onClickDisconnect, this); - childSetAction("add_spawn_point_btn", onClickAddSpawnPoint, this); - childSetAction("remove_spawn_point_btn", onClickRemoveSpawnPoint, this); + getChild("connect_btn")->setCommitCallback(boost::bind(&LLFloaterTelehub::onClickConnect, this)); + getChild("disconnect_btn")->setCommitCallback(boost::bind(&LLFloaterTelehub::onClickDisconnect, this)); + getChild("add_spawn_point_btn")->setCommitCallback(boost::bind(&LLFloaterTelehub::onClickAddSpawnPoint, this)); + getChild("remove_spawn_point_btn")->setCommitCallback(boost::bind(&LLFloaterTelehub::onClickRemoveSpawnPoint, this)); LLScrollListCtrl* list = getChild("spawn_points_list"); if (list) @@ -113,10 +78,30 @@ BOOL LLFloaterTelehub::postBuild() return TRUE; } +void LLFloaterTelehub::onOpen(const LLSD& key) +{ + // Show tools floater by selecting translate (select) tool + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompTranslate::getInstance() ); + + // Find tools floater, glue to bottom + if (gFloaterTools) + { + LLRect tools_rect = gFloaterTools->getRect(); + S32 our_width = getRect().getWidth(); + S32 our_height = getRect().getHeight(); + LLRect our_rect; + our_rect.setLeftTopAndSize(tools_rect.mLeft, tools_rect.mBottom, our_width, our_height); + setRect(our_rect); + } + + sendTelehubInfoRequest(); + + mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); +} + LLFloaterTelehub::~LLFloaterTelehub() { - sInstance = NULL; - // no longer interested in this message gMessageSystem->setHandlerFunc("TelehubInfo", NULL); } @@ -158,19 +143,22 @@ void LLFloaterTelehub::refresh() BOOL LLFloaterTelehub::renderBeacons() { // only render if we've got a telehub - return sInstance && sInstance->mTelehubObjectID.notNull(); + LLFloaterTelehub* floater = LLFloaterReg::findTypedInstance("telehubs"); + return floater && floater->mTelehubObjectID.notNull(); } // static void LLFloaterTelehub::addBeacons() { - if (!sInstance) return; - + LLFloaterTelehub* floater = LLFloaterReg::findTypedInstance("telehubs"); + if (!floater) + return; + // Find the telehub position, either our cached old position, or // an updated one based on the actual object position. - LLVector3 hub_pos_region = sInstance->mTelehubPos; - LLQuaternion hub_rot = sInstance->mTelehubRot; - LLViewerObject* obj = gObjectList.findObject(sInstance->mTelehubObjectID); + LLVector3 hub_pos_region = floater->mTelehubPos; + LLQuaternion hub_rot = floater->mTelehubRot; + LLViewerObject* obj = gObjectList.findObject(floater->mTelehubObjectID); if (obj) { hub_pos_region = obj->getPositionRegion(); @@ -179,13 +167,13 @@ void LLFloaterTelehub::addBeacons() // Draw nice thick 3-pixel lines. gObjectList.addDebugBeacon(hub_pos_region, "", LLColor4::yellow, LLColor4::white, 4); - LLScrollListCtrl* list = sInstance->getChild("spawn_points_list"); + LLScrollListCtrl* list = floater->getChild("spawn_points_list"); if (list) { S32 spawn_index = list->getFirstSelectedIndex(); if (spawn_index >= 0) { - LLVector3 spawn_pos = hub_pos_region + (sInstance->mSpawnPointPos[spawn_index] * hub_rot); + LLVector3 spawn_pos = hub_pos_region + (floater->mSpawnPointPos[spawn_index] * hub_rot); gObjectList.addDebugBeacon(spawn_pos, "", LLColor4::orange, LLColor4::white, 4); } } @@ -196,32 +184,27 @@ void LLFloaterTelehub::sendTelehubInfoRequest() LLSelectMgr::getInstance()->sendGodlikeRequest("telehub", "info ui"); } -// static -void LLFloaterTelehub::onClickConnect(void* data) +void LLFloaterTelehub::onClickConnect() { LLSelectMgr::getInstance()->sendGodlikeRequest("telehub", "connect"); } -// static -void LLFloaterTelehub::onClickDisconnect(void* data) +void LLFloaterTelehub::onClickDisconnect() { LLSelectMgr::getInstance()->sendGodlikeRequest("telehub", "delete"); } -// static -void LLFloaterTelehub::onClickAddSpawnPoint(void* data) +void LLFloaterTelehub::onClickAddSpawnPoint() { LLSelectMgr::getInstance()->sendGodlikeRequest("telehub", "spawnpoint add"); LLSelectMgr::getInstance()->deselectAll(); } -// static -void LLFloaterTelehub::onClickRemoveSpawnPoint(void* data) +void LLFloaterTelehub::onClickRemoveSpawnPoint() { - if (!sInstance) return; - - LLScrollListCtrl* list = sInstance->getChild("spawn_points_list"); - if (!list) return; + LLScrollListCtrl* list = getChild("spawn_points_list"); + if (!list) + return; S32 spawn_index = list->getFirstSelectedIndex(); if (spawn_index < 0) return; // nothing selected @@ -259,9 +242,10 @@ void LLFloaterTelehub::onClickRemoveSpawnPoint(void* data) // static void LLFloaterTelehub::processTelehubInfo(LLMessageSystem* msg, void**) { - if (sInstance) + LLFloaterTelehub* floater = LLFloaterReg::findTypedInstance("telehubs"); + if (floater) { - sInstance->unpackTelehubInfo(msg); + floater->unpackTelehubInfo(msg); } } diff --git a/indra/newview/llfloatertelehub.h b/indra/newview/llfloatertelehub.h index b639338dfc..5b654585f1 100644 --- a/indra/newview/llfloatertelehub.h +++ b/indra/newview/llfloatertelehub.h @@ -44,25 +44,24 @@ const S32 MAX_SPAWNPOINTS_PER_TELEHUB = 16; class LLFloaterTelehub : public LLFloater { public: - // Opens the floater on screen. - static void show(); + LLFloaterTelehub(const LLSD& key); + ~LLFloaterTelehub(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); - virtual void draw(); - /*virtual*/ BOOL postBuild(); + /*virtual*/ void draw(); + static BOOL renderBeacons(); static void addBeacons(); -private: - LLFloaterTelehub(); - ~LLFloaterTelehub(); - void refresh(); void sendTelehubInfoRequest(); - static void onClickConnect(void* data); - static void onClickDisconnect(void* data); - static void onClickAddSpawnPoint(void* data); - static void onClickRemoveSpawnPoint(void* data); + void onClickConnect(); + void onClickDisconnect(); + void onClickAddSpawnPoint(); + void onClickRemoveSpawnPoint(); static void processTelehubInfo(LLMessageSystem* msg, void**); void unpackTelehubInfo(LLMessageSystem* msg); diff --git a/indra/newview/llfloatertestlistview.cpp b/indra/newview/llfloatertestlistview.cpp new file mode 100644 index 0000000000..5c942d0ed9 --- /dev/null +++ b/indra/newview/llfloatertestlistview.cpp @@ -0,0 +1,77 @@ +/** +* @file llfloatertestlistview.cpp +* @brief Tests of programmatic manipulation of LLListView widgets +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#include "llviewerprecompiledheaders.h" + +#include "llfloatertestlistview.h" + +// Viewer includes +#include "lllistview.h" + +// Linden library includes +//#include "lluictrlfactory.h" + +LLFloaterTestListView::LLFloaterTestListView(const LLSD& seed) +: LLFloater(seed), + mListView(NULL) +{ + // set up named callback functions for test buttons + mCommitCallbackRegistrar.add("TestListView.Test1", + boost::bind(&LLFloaterTestListView::onClickTest1, this)); + mCommitCallbackRegistrar.add("TestListView.Test2", + boost::bind(&LLFloaterTestListView::onClickTest2, this)); +} + +LLFloaterTestListView::~LLFloaterTestListView() +{} + +BOOL LLFloaterTestListView::postBuild() +{ + mListView = getChild("test_list_view"); + // just set a random property + mListView->setString("set programmatically"); + return LLFloater::postBuild(); +} + +void LLFloaterTestListView::onListViewChanged() +{ + llinfos << "list view changed" << llendl; +} + +void LLFloaterTestListView::onClickTest1() +{ + llinfos << "test 1" << llendl; +} + +void LLFloaterTestListView::onClickTest2() +{ + llinfos << "test 2" << llendl; +} diff --git a/indra/newview/llfloatertestlistview.h b/indra/newview/llfloatertestlistview.h new file mode 100644 index 0000000000..053da95def --- /dev/null +++ b/indra/newview/llfloatertestlistview.h @@ -0,0 +1,64 @@ +/** +* @file llfloatertestlistview.h +* @brief Tests of programmatic manipulation of LLListView widgets +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#ifndef LLFLOATERTESTLISTVIEW_H +#define LLFLOATERTESTLISTVIEW_H + +#include "llfloater.h" + +class LLListView; +class LLSD; + +class LLFloaterTestListView : public LLFloater +{ + friend class LLFloaterReg; +public: + // nothing yet + +private: + // Construction handled by LLFloaterReg + LLFloaterTestListView(const LLSD& seed); + ~LLFloaterTestListView(); + + /*virtual*/ BOOL postBuild(); + + // Perform some debug action when the list-view sends change notification + void onListViewChanged(); + + // Debug function hookups for buttons + void onClickTest1(); + void onClickTest2(); + +private: + LLListView* mListView; +}; + +#endif diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 4bcf470317..bbcab00ab2 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -198,6 +198,7 @@ LLPCode toolData[]={ BOOL LLFloaterTools::postBuild() { + mCloseSignal.connect(boost::bind(&LLFloaterTools::onClose, this)); // Hide until tool selected setVisible(FALSE); @@ -445,7 +446,8 @@ void LLFloaterTools::draw() void LLFloaterTools::dirty() { mDirty = TRUE; - LLFloaterOpenObject::dirty(); + LLFloaterOpenObject* instance = LLFloaterReg::getTypedInstance("openobject"); + if (instance) instance->dirty(); } // Clean up any tool state that should not persist when the @@ -726,11 +728,8 @@ void LLFloaterTools::onOpen(const LLSD& key) gMenuBarView->setItemVisible("BuildTools", TRUE); } -// virtual -void LLFloaterTools::onClose(bool app_quitting) +void LLFloaterTools::onClose() { - setMinimized(FALSE); - setVisible(FALSE); mTab->setVisible(FALSE); LLViewerJoystick::getInstance()->moveAvatar(false); diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index 7bb072232a..1b9f1d31ec 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -73,7 +73,6 @@ public: virtual ~LLFloaterTools(); /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); /*virtual*/ BOOL canClose(); /*virtual*/ void draw(); /*virtual*/ void onFocusReceived(); @@ -103,10 +102,10 @@ public: static void setEditTool(void* data); void saveLastTool(); private: - static void setObjectType( LLPCode pcode ); - + void onClose(); void refresh(); + static void setObjectType( LLPCode pcode ); static void onClickGridOptions(void* data); public: diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 29ac0c66f8..bf5a1141a6 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -40,6 +40,7 @@ #include "llagent.h" #include "llbutton.h" #include "llfloatergodtools.h" +#include "llfloaterreg.h" #include "llparcel.h" #include "llscrolllistctrl.h" #include "llscrolllistitem.h" @@ -53,11 +54,11 @@ #include "lluictrlfactory.h" #include "llviewerwindow.h" -LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL; +//LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL; // Globals // const U32 TIME_STR_LENGTH = 30; - +/* // static void LLFloaterTopObjects::show() { @@ -68,21 +69,28 @@ void LLFloaterTopObjects::show() } sInstance = new LLFloaterTopObjects(); - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_top_objects.xml"); +// LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_top_objects.xml"); sInstance->center(); } - -LLFloaterTopObjects::LLFloaterTopObjects() -: LLFloater(), +*/ +LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key) +: LLFloater(key), mInitialized(FALSE), mtotalScore(0.f) { - sInstance = this; + mCommitCallbackRegistrar.add("TopObjects.ShowBeacon", boost::bind(&LLFloaterTopObjects::onClickShowBeacon, this)); + mCommitCallbackRegistrar.add("TopObjects.ReturnSelected", boost::bind(&LLFloaterTopObjects::onReturnSelected, this)); + mCommitCallbackRegistrar.add("TopObjects.ReturnAll", boost::bind(&LLFloaterTopObjects::onReturnAll, this)); + mCommitCallbackRegistrar.add("TopObjects.DisableSelected", boost::bind(&LLFloaterTopObjects::onDisableSelected, this)); + mCommitCallbackRegistrar.add("TopObjects.DisableAll", boost::bind(&LLFloaterTopObjects::onDisableAll, this)); + mCommitCallbackRegistrar.add("TopObjects.Refresh", boost::bind(&LLFloaterTopObjects::onRefresh, this)); + mCommitCallbackRegistrar.add("TopObjects.GetByObjectName", boost::bind(&LLFloaterTopObjects::onGetByObjectName, this)); + mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this)); + mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this)); } LLFloaterTopObjects::~LLFloaterTopObjects() { - sInstance = NULL; } // virtual @@ -90,24 +98,11 @@ BOOL LLFloaterTopObjects::postBuild() { LLScrollListCtrl *objects_list = getChild("objects_list"); childSetFocus("objects_list"); - childSetCommitCallback("objects_list", onCommitObjectsList, this); objects_list->setDoubleClickCallback(onDoubleClickObjectsList, this); objects_list->setCommitOnSelectionChange(TRUE); - childSetAction("show_beacon_btn", onClickShowBeacon, this); setDefaultBtn("show_beacon_btn"); - childSetAction("return_selected_btn", onReturnSelected, this); - childSetAction("return_all_btn", onReturnAll, this); - childSetAction("disable_selected_btn", onDisableSelected, this); - childSetAction("disable_all_btn", onDisableAll, this); - childSetAction("refresh_btn", onRefresh, this); - - - childSetAction("filter_object_btn", onGetByObjectNameClicked, this); - childSetAction("filter_owner_btn", onGetByOwnerNameClicked, this); - - /* LLLineEditor* line_editor = getChild("owner_name_editor"); if (line_editor) @@ -129,19 +124,29 @@ BOOL LLFloaterTopObjects::postBuild() return TRUE; } +// static +void LLFloaterTopObjects::setMode(U32 mode) +{ + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); + if(!instance) return; + instance->mCurrentMode = mode; +} +// static void LLFloaterTopObjects::handle_land_reply(LLMessageSystem* msg, void** data) { + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); + if(!instance) return; // Make sure dialog is on screen - show(); - sInstance->handleReply(msg, data); + LLFloaterReg::showInstance("top_objects"); + instance->handleReply(msg, data); //HACK: for some reason sometimes top scripts originally comes back //with no results even though they're there - if (!sInstance->mObjectListIDs.size() && !sInstance->mInitialized) + if (!instance->mObjectListIDs.size() && !instance->mInitialized) { - sInstance->onRefresh(NULL); - sInstance->mInitialized = TRUE; + instance->onRefresh(); + instance->mInitialized = TRUE; } } @@ -260,12 +265,9 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) } } -// static -void LLFloaterTopObjects::onCommitObjectsList(LLUICtrl* ctrl, void* data) +void LLFloaterTopObjects::onCommitObjectsList() { - LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; - - self->updateSelectionInfo(); + updateSelectionInfo(); } void LLFloaterTopObjects::updateSelectionInfo() @@ -292,11 +294,9 @@ void LLFloaterTopObjects::onDoubleClickObjectsList(void* data) } // static -void LLFloaterTopObjects::onClickShowBeacon(void* data) +void LLFloaterTopObjects::onClickShowBeacon() { - LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; - if (!self) return; - self->showBeacon(); + showBeacon(); } void LLFloaterTopObjects::doToObjects(int action, bool all) @@ -360,22 +360,24 @@ void LLFloaterTopObjects::doToObjects(int action, bool all) bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); + if(!instance) return false; if (option == 0) { - sInstance->doToObjects(ACTION_RETURN, true); + instance->doToObjects(ACTION_RETURN, true); } return false; } -void LLFloaterTopObjects::onReturnAll(void* data) +void LLFloaterTopObjects::onReturnAll() { LLNotifications::instance().add("ReturnAllTopObjects", LLSD(), LLSD(), &callbackReturnAll); } -void LLFloaterTopObjects::onReturnSelected(void* data) +void LLFloaterTopObjects::onReturnSelected() { - sInstance->doToObjects(ACTION_RETURN, false); + doToObjects(ACTION_RETURN, false); } @@ -383,52 +385,52 @@ void LLFloaterTopObjects::onReturnSelected(void* data) bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); + if(!instance) return false; if (option == 0) { - sInstance->doToObjects(ACTION_DISABLE, true); + instance->doToObjects(ACTION_DISABLE, true); } return false; } -void LLFloaterTopObjects::onDisableAll(void* data) +void LLFloaterTopObjects::onDisableAll() { LLNotifications::instance().add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll); } -void LLFloaterTopObjects::onDisableSelected(void* data) +void LLFloaterTopObjects::onDisableSelected() { - sInstance->doToObjects(ACTION_DISABLE, false); + doToObjects(ACTION_DISABLE, false); } -//static + void LLFloaterTopObjects::clearList() { - LLCtrlListInterface *list = sInstance->childGetListInterface("objects_list"); + LLCtrlListInterface *list = childGetListInterface("objects_list"); if (list) { list->operateOnAll(LLCtrlListInterface::OP_DELETE); } - sInstance->mObjectListData.clear(); - sInstance->mObjectListIDs.clear(); - sInstance->mtotalScore = 0.f; + mObjectListData.clear(); + mObjectListIDs.clear(); + mtotalScore = 0.f; } -//static -void LLFloaterTopObjects::onRefresh(void* data) + +void LLFloaterTopObjects::onRefresh() { U32 mode = STAT_REPORT_TOP_SCRIPTS; U32 flags = 0; std::string filter = ""; - if (sInstance) - { - mode = sInstance->mCurrentMode; - flags = sInstance->mFlags; - filter = sInstance->mFilter; - sInstance->clearList(); - } + mode = mCurrentMode; + flags = mFlags; + filter = mFilter; + clearList(); + LLMessageSystem *msg = gMessageSystem; msg->newMessageFast(_PREHASH_LandStatRequest); @@ -443,31 +445,22 @@ void LLFloaterTopObjects::onRefresh(void* data) msg->sendReliable(gAgent.getRegionHost()); - if (sInstance) - { - sInstance->mFilter.clear(); - sInstance->mFlags = 0; - } + mFilter.clear(); + mFlags = 0; } -void LLFloaterTopObjects::onGetByObjectName(LLUICtrl* ctrl, void* data) +void LLFloaterTopObjects::onGetByObjectName() { - if (sInstance) - { - sInstance->mFlags = STAT_FILTER_BY_OBJECT; - sInstance->mFilter = sInstance->childGetText("object_name_editor"); - onRefresh(NULL); - } + mFlags = STAT_FILTER_BY_OBJECT; + mFilter = childGetText("object_name_editor"); + onRefresh(); } -void LLFloaterTopObjects::onGetByOwnerName(LLUICtrl* ctrl, void* data) +void LLFloaterTopObjects::onGetByOwnerName() { - if (sInstance) - { - sInstance->mFlags = STAT_FILTER_BY_OWNER; - sInstance->mFilter = sInstance->childGetText("owner_name_editor"); - onRefresh(NULL); - } + mFlags = STAT_FILTER_BY_OWNER; + mFilter = childGetText("owner_name_editor"); + onRefresh(); } void LLFloaterTopObjects::showBeacon() diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h index 58cbf5d2ce..ee3c5d3cce 100644 --- a/indra/newview/llfloatertopobjects.h +++ b/indra/newview/llfloatertopobjects.h @@ -39,48 +39,49 @@ class LLUICtrl; class LLFloaterTopObjects : public LLFloater { + friend class LLFloaterReg; public: // Opens the floater on screen. - static void show(); +// static void show(); // Opens the floater if it's not on-screen. // Juggles the UI based on method = "scripts" or "colliders" static void handle_land_reply(LLMessageSystem* msg, void** data); void handleReply(LLMessageSystem* msg, void** data); - static void clearList(); + void clearList(); void updateSelectionInfo(); virtual BOOL postBuild(); - static void onRefresh(void* data); + void onRefresh(); - static void setMode(U32 mode) { if (sInstance) sInstance->mCurrentMode = mode; } + static void setMode(U32 mode); private: - LLFloaterTopObjects(); + LLFloaterTopObjects(const LLSD& key); ~LLFloaterTopObjects(); void initColumns(LLCtrlListInterface *list); - static void onCommitObjectsList(LLUICtrl* ctrl, void* data); + void onCommitObjectsList(); static void onDoubleClickObjectsList(void* data); - static void onClickShowBeacon(void* data); + void onClickShowBeacon(); void doToObjects(int action, bool all); - static void onReturnAll(void* data); - static void onReturnSelected(void* data); - static void onDisableAll(void* data); - static void onDisableSelected(void* data); + void onReturnAll(); + void onReturnSelected(); + void onDisableAll(); + void onDisableSelected(); static bool callbackReturnAll(const LLSD& notification, const LLSD& response); static bool callbackDisableAll(const LLSD& notification, const LLSD& response); - static void onGetByOwnerName(LLUICtrl* ctrl, void* data); - static void onGetByObjectName(LLUICtrl* ctrl, void* data); + void onGetByOwnerName(); + void onGetByObjectName(); - static void onGetByOwnerNameClicked(void* data) { onGetByOwnerName(NULL, data); }; - static void onGetByObjectNameClicked(void* data) { onGetByObjectName(NULL, data); }; +// static void onGetByOwnerNameClicked(void* data) { onGetByOwnerName(NULL, data); }; +// static void onGetByObjectNameClicked(void* data) { onGetByObjectName(NULL, data); }; void showBeacon(); diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index d75640ccb4..9859d34284 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -52,43 +52,12 @@ #include "message.h" -// static -LLFloaterTOS* LLFloaterTOS::sInstance = NULL; - -// static -LLFloaterTOS* LLFloaterTOS::show(ETOSType type, - const std::string & message, - const YesNoCallback& callback) -{ - if( !LLFloaterTOS::sInstance ) - { - LLFloaterTOS::sInstance = new LLFloaterTOS(type, message, callback); - } - - if (type == TOS_TOS) - { - LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_tos.xml"); - } - else - { - LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_critical.xml"); - } - - sInstance->startModal(); - - return LLFloaterTOS::sInstance; -} - - -LLFloaterTOS::LLFloaterTOS(ETOSType type, - const std::string & message, - const YesNoCallback& callback) -: LLModalDialog( std::string(" "), 100, 100 ), - mType(type), - mMessage(message), +LLFloaterTOS::LLFloaterTOS(const LLSD& message) +: LLModalDialog( message, 100, 100 ), + mMessage(message.asString()), mWebBrowserWindowId( 0 ), mLoadCompleteCount( 0 ), - mCallback(callback) + mCallback() { } @@ -144,8 +113,8 @@ BOOL LLFloaterTOS::postBuild() childSetAction("Continue", onContinue, this); childSetAction("Cancel", onCancel, this); childSetCommitCallback("agree_chk", updateAgree, this); - - if ( mType != TOS_TOS ) + + if (hasChild("tos_text")) { // this displays the critical message LLTextEditor *editor = getChild("tos_text"); @@ -182,17 +151,14 @@ BOOL LLFloaterTOS::postBuild() void LLFloaterTOS::setSiteIsAlive( bool alive ) { // only do this for TOS pages - if ( mType == TOS_TOS ) + if (hasChild("tos_html")) { LLWebBrowserCtrl* web_browser = getChild("tos_html"); // if the contents of the site was retrieved if ( alive ) { - if ( web_browser ) - { - // navigate to the "real" page - web_browser->navigateTo( getString( "real_url" ) ); - }; + // navigate to the "real" page + web_browser->navigateTo( getString( "real_url" ) ); } else { @@ -200,8 +166,8 @@ void LLFloaterTOS::setSiteIsAlive( bool alive ) // but if the page is unavailable, we need to do this now LLCheckBoxCtrl* tos_agreement = getChild("agree_chk"); tos_agreement->setEnabled( true ); - }; - }; + } + } } LLFloaterTOS::~LLFloaterTOS() @@ -216,8 +182,6 @@ LLFloaterTOS::~LLFloaterTOS() // tell the responder we're not here anymore if ( gResponsePtr ) gResponsePtr->setParent( 0 ); - - LLFloaterTOS::sInstance = NULL; } // virtual @@ -276,3 +240,8 @@ void LLFloaterTOS::onNavigateComplete( const EventType& eventIn ) tos_agreement->setEnabled( true ); }; } + +void LLFloaterTOS::setTOSCallback(LLFloaterTOS::YesNoCallback const & callback) +{ + mCallback = callback; +} diff --git a/indra/newview/llfloatertos.h b/indra/newview/llfloatertos.h index 67d2f0ceec..0b15c24bc8 100644 --- a/indra/newview/llfloatertos.h +++ b/indra/newview/llfloatertos.h @@ -49,22 +49,11 @@ class LLFloaterTOS : public LLWebBrowserCtrlObserver { public: + LLFloaterTOS(const LLSD& message); virtual ~LLFloaterTOS(); - // Types of dialog. - enum ETOSType - { - TOS_TOS = 0, - TOS_CRITICAL_MESSAGE = 1 - }; - typedef boost::function YesNoCallback; - // Asset_id is overwritten with LLUUID::null when agree is clicked. - static LLFloaterTOS* show(ETOSType type, - const std::string & message, - const YesNoCallback& callback); - BOOL postBuild(); virtual void draw(); @@ -77,20 +66,14 @@ public: virtual void onNavigateComplete( const EventType& eventIn ); -private: - // Asset_id is overwritten with LLUUID::null when agree is clicked. - LLFloaterTOS(ETOSType type, - const std::string & message, - const YesNoCallback& callback); + // *TODO - consider getting rid of this in favor of using an event pump. -brad + void setTOSCallback(YesNoCallback const & callback); private: - ETOSType mType; std::string mMessage; int mWebBrowserWindowId; int mLoadCompleteCount; YesNoCallback mCallback; - - static LLFloaterTOS* sInstance; }; #endif // LL_LLFLOATERTOS_H diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 34db895b52..e5b4657742 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -57,6 +57,7 @@ #include "lldraghandle.h" #include "lllayoutstack.h" #include "llviewermenu.h" +#include "llrngwriter.h" // Boost (for linux/unix command-line execv) #include @@ -70,25 +71,85 @@ #endif // Static initialization -LLFloaterUIPreview* LLFloaterUIPreview::sInstance = NULL; // initialization of static instance pointer to NULL -std::string LLFloaterUIPreview::mSavedEditorPath = std::string(""); -std::string LLFloaterUIPreview::mSavedEditorArgs = std::string(""); -std::string LLFloaterUIPreview::mSavedDiffPath = std::string(""); static const S32 PRIMARY_FLOATER = 1; static const S32 SECONDARY_FLOATER = 2; +static LLDefaultChildRegistry::Register register_overlap_panel("overlap_panel"); + static std::string get_xui_dir() { std::string delim = gDirUtilp->getDirDelimiter(); - return gDirUtilp->getAppRODataDir() + delim + std::string("skins") + delim + "default" + delim + "xui" + delim; + return gDirUtilp->getSkinBaseDir() + delim + "default" + delim + "xui" + delim; } +//---------------------------------------------------------------------------- +// Local class declarations +// Reset object to ensure that when we change the current language setting for preview purposes, +// it automatically is reset. Constructed on the stack at the start of the method; the reset +// occurs as it falls out of scope at the end of the method. See llfloateruipreview.cpp for usage. +class LLLocalizationResetForcer +{ +public: + LLLocalizationResetForcer(LLFloaterUIPreview* floater, S32 ID); + virtual ~LLLocalizationResetForcer(); + +private: + std::string mSavedLocalization; // the localization before we change it +}; + +// Implementation of live file +// When a floater is being previewed, any saved changes to its corresponding +// file cause the previewed floater to be reloaded +class LLGUIPreviewLiveFile : public LLLiveFile +{ +public: + LLGUIPreviewLiveFile(std::string path, std::string name, LLFloaterUIPreview* parent); + virtual ~LLGUIPreviewLiveFile(); + LLFloaterUIPreview* mParent; + LLFadeEventTimer* mFadeTimer; // timer for fade-to-yellow-and-back effect to warn that file has been reloaded + BOOL mFirstFade; // setting this avoids showing the fade reload warning on first load + std::string mFileName; +protected: + bool loadFile(); +}; + +// Implementation of graphical fade in/out (on timer) for when XUI files are updated +class LLFadeEventTimer : public LLEventTimer +{ +public: + LLFadeEventTimer(F32 refresh, LLGUIPreviewLiveFile* parent); + BOOL tick(); + LLGUIPreviewLiveFile* mParent; +private: + BOOL mFadingOut; // fades in then out; this is toggled in between + LLColor4 mOriginalColor; // original color; color is reset to this after fade is coimplete +}; + +// Implementation of previewed floater +// Used to override draw and mouse handler +class LLPreviewedFloater : public LLFloater +{ +public: + LLPreviewedFloater(LLFloaterUIPreview* floater) + : LLFloater(LLSD()), + mFloaterUIPreview(floater) + { + } + virtual void draw(); + BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + BOOL selectElement(LLView* parent, int x, int y, int depth); // select element to display its overlappers + + LLFloaterUIPreview* mFloaterUIPreview; +}; + +//---------------------------------------------------------------------------- + // Localization reset forcer -- ensures that when localization is temporarily changed for previewed floater, it is reset // Changes are made here -LLLocalizationResetForcer::LLLocalizationResetForcer(S32 ID) +LLLocalizationResetForcer::LLLocalizationResetForcer(LLFloaterUIPreview* floater, S32 ID) { mSavedLocalization = LLUI::sSettingGroups["config"]->getString("Language"); // save current localization setting - LLUI::sSettingGroups["config"]->setString("Language", LLFloaterUIPreview::getLocStr(ID));// hack language to be the one we want to preview floaters in + LLUI::sSettingGroups["config"]->setString("Language", floater->getLocStr(ID));// hack language to be the one we want to preview floaters in LLUI::setupPaths(); // forcibly reset XUI paths with this new language } @@ -186,11 +247,6 @@ BOOL LLFadeEventTimer::tick() return FALSE; } -void* create_overlap_panel(void* data) -{ - return new LLOverlapPanel(); -} - // Constructor LLFloaterUIPreview::LLFloaterUIPreview(const LLSD& key) : LLFloater(key), @@ -203,8 +259,6 @@ LLFloaterUIPreview::LLFloaterUIPreview(const LLSD& key) mLastDisplayedY(0) { - sInstance = this; - mFactoryMap["overlap_panel"] = LLCallbackMap(create_overlap_panel, NULL); // called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_ui_preview.xml"); } @@ -214,27 +268,27 @@ LLFloaterUIPreview::~LLFloaterUIPreview() // spawned floaters are deleted automatically, so we don't need to delete them here // save contents of textfields so it can be restored later if the floater is created again this session - LLFloaterUIPreview::mSavedEditorPath = mEditorPathTextBox->getText(); - LLFloaterUIPreview::mSavedEditorArgs = mEditorArgsTextBox->getText(); - LLFloaterUIPreview::mSavedDiffPath = mDiffPathTextBox->getText(); + mSavedEditorPath = mEditorPathTextBox->getText(); + mSavedEditorArgs = mEditorArgsTextBox->getText(); + mSavedDiffPath = mDiffPathTextBox->getText(); // delete live file if it exists - if(sInstance->mLiveFile) + if(mLiveFile) { - delete sInstance->mLiveFile; - sInstance->mLiveFile = NULL; + delete mLiveFile; + mLiveFile = NULL; } - - sInstance = NULL; // clear static pointer } // Perform post-build setup (defined in superclass) BOOL LLFloaterUIPreview::postBuild() { + mCloseSignal.connect(boost::bind(&LLFloaterUIPreview::onClose, this, _2)); + LLPanel* main_panel_tmp = getChild("main_panel"); // get a pointer to the main panel in order to... mFileList = main_panel_tmp->getChild("name_list"); // save pointer to file list // Double-click opens the floater, for convenience - mFileList->setDoubleClickCallback(onClickDisplayFloater, (void*)&PRIMARY_FLOATER); + mFileList->setDoubleClickCallback(boost::bind(&LLFloaterUIPreview::onClickDisplayFloater, this, PRIMARY_FLOATER)); // get pointers to buttons and link to callbacks mLanguageSelection = main_panel_tmp->getChild("language_select_combo"); @@ -243,26 +297,28 @@ BOOL LLFloaterUIPreview::postBuild() mLanguageSelection_2->setSelectionCallback(boost::bind(&LLFloaterUIPreview::onLanguageComboSelect, this, mLanguageSelection)); LLPanel* editor_panel_tmp = main_panel_tmp->getChild("editor_panel"); mDisplayFloaterBtn = main_panel_tmp->getChild("display_floater"); - mDisplayFloaterBtn->setClickedCallback(onClickDisplayFloater, (void*)&PRIMARY_FLOATER); + mDisplayFloaterBtn->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickDisplayFloater, this, PRIMARY_FLOATER)); mDisplayFloaterBtn_2 = main_panel_tmp->getChild("display_floater_2"); - mDisplayFloaterBtn_2->setClickedCallback(onClickDisplayFloater, (void*)&SECONDARY_FLOATER); + mDisplayFloaterBtn_2->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickDisplayFloater, this, SECONDARY_FLOATER)); mToggleOverlapButton = main_panel_tmp->getChild("toggle_overlap_panel"); - mToggleOverlapButton->setClickedCallback(onClickToggleOverlapping, this); + mToggleOverlapButton->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickToggleOverlapping, this)); mCloseOtherButton = main_panel_tmp->getChild("close_displayed_floater"); - mCloseOtherButton->setClickedCallback(onClickCloseDisplayedFloater, (void*)&PRIMARY_FLOATER); + mCloseOtherButton->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickCloseDisplayedFloater, this, PRIMARY_FLOATER)); mCloseOtherButton_2 = main_panel_tmp->getChild("close_displayed_floater_2"); - mCloseOtherButton_2->setClickedCallback(onClickCloseDisplayedFloater, (void*)&SECONDARY_FLOATER); + mCloseOtherButton_2->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickCloseDisplayedFloater, this, SECONDARY_FLOATER)); mEditFloaterBtn = main_panel_tmp->getChild("edit_floater"); - mEditFloaterBtn->setClickedCallback(onClickEditFloater, this); + mEditFloaterBtn->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickEditFloater, this)); mExecutableBrowseButton = editor_panel_tmp->getChild("browse_for_executable"); LLPanel* vlt_panel_tmp = main_panel_tmp->getChild("vlt_panel"); - mExecutableBrowseButton->setClickedCallback(onClickBrowseForEditor, this); + mExecutableBrowseButton->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickBrowseForEditor, this)); mDiffBrowseButton = vlt_panel_tmp->getChild("browse_for_vlt_diffs"); - mDiffBrowseButton->setClickedCallback(onClickBrowseForDiffs, NULL); + mDiffBrowseButton->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickBrowseForDiffs, this)); mToggleHighlightButton = vlt_panel_tmp->getChild("toggle_vlt_diff_highlight"); - mToggleHighlightButton->setClickedCallback(onClickToggleDiffHighlighting, NULL); - main_panel_tmp->getChild("save_floater")->setClickedCallback(onClickSaveFloater, (void*)&PRIMARY_FLOATER); - main_panel_tmp->getChild("save_all_floaters")->setClickedCallback(onClickSaveAll, (void*)&PRIMARY_FLOATER); + mToggleHighlightButton->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickToggleDiffHighlighting, this)); + main_panel_tmp->getChild("save_floater")->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickSaveFloater, this, PRIMARY_FLOATER)); + main_panel_tmp->getChild("save_all_floaters")->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickSaveAll, this, PRIMARY_FLOATER)); + + getChild("export_schema")->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickExportSchema, this)); // get pointers to text fields mEditorPathTextBox = editor_panel_tmp->getChild("executable_path_field"); @@ -270,14 +326,14 @@ BOOL LLFloaterUIPreview::postBuild() mDiffPathTextBox = vlt_panel_tmp->getChild("vlt_diff_path_field"); // *HACK: restored saved editor path and args to textfields - mEditorPathTextBox->setText(LLFloaterUIPreview::mSavedEditorPath); - mEditorArgsTextBox->setText(LLFloaterUIPreview::mSavedEditorArgs); - mDiffPathTextBox->setText(LLFloaterUIPreview::mSavedDiffPath); + mEditorPathTextBox->setText(mSavedEditorPath); + mEditorArgsTextBox->setText(mSavedEditorArgs); + mDiffPathTextBox->setText(mSavedDiffPath); // Set up overlap panel mOverlapPanel = getChild("overlap_panel"); - sInstance->childSetVisible("overlap_scroll", mHighlightingOverlaps); + childSetVisible("overlap_scroll", mHighlightingOverlaps); mDelim = gDirUtilp->getDirDelimiter(); // initialize delimiter to dir sep slash @@ -339,7 +395,7 @@ void LLFloaterUIPreview::onLanguageComboSelect(LLUICtrl* ctrl) { if(mDisplayedFloater) { - onClickCloseDisplayedFloater((void*)&PRIMARY_FLOATER); + onClickCloseDisplayedFloater(PRIMARY_FLOATER); displayFloater(TRUE,1); } } @@ -347,24 +403,56 @@ void LLFloaterUIPreview::onLanguageComboSelect(LLUICtrl* ctrl) { if(mDisplayedFloater_2) { - onClickCloseDisplayedFloater((void*)&PRIMARY_FLOATER); + onClickCloseDisplayedFloater(PRIMARY_FLOATER); displayFloater(TRUE,2); // *TODO: make take an arg } } } -// Close click handler -- delete my displayed floater if it exists -void LLFloaterUIPreview::onClose(bool app_quitting) +void LLFloaterUIPreview::onClickExportSchema() { - if(!app_quitting && sInstance && sInstance->mDisplayedFloater) + gViewerWindow->setCursor(UI_CURSOR_WAIT); + std::string template_path = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "xui", "schema"); + + typedef LLWidgetTypeRegistry::Registrar::registry_map_t::const_iterator registry_it; + registry_it end_it = LLWidgetTypeRegistry::defaultRegistrar().endItems(); + for(registry_it it = LLWidgetTypeRegistry::defaultRegistrar().beginItems(); + it != end_it; + ++it) { - onClickCloseDisplayedFloater((void*)&PRIMARY_FLOATER); - onClickCloseDisplayedFloater((void*)&SECONDARY_FLOATER); - delete sInstance->mDisplayedFloater; - sInstance->mDisplayedFloater = NULL; + std::string widget_name = it->first; + const LLInitParam::BaseBlock& block = + (*LLDefaultParamBlockRegistry::instance().getValue(*LLWidgetTypeRegistry::instance().getValue(widget_name)))(); + LLXMLNodePtr root_nodep = new LLXMLNode(); + LLRNGWriter().writeRNG(widget_name, root_nodep, block, "http://www.lindenlab.com/xui"); + + std::string file_name(template_path + gDirUtilp->getDirDelimiter() + widget_name + ".rng"); + + LLFILE* rng_file = LLFile::fopen(file_name.c_str(), "w"); + { + LLXMLNode::writeHeaderToFile(rng_file); + const bool use_type_decorations = false; + root_nodep->writeToFile(rng_file, std::string(), use_type_decorations); + } + fclose(rng_file); + } + gViewerWindow->setCursor(UI_CURSOR_ARROW); +} + + +// Close click handler -- delete my displayed floater if it exists +void LLFloaterUIPreview::onClose(const LLSD& app_quitting) +{ + if(!app_quitting.asBoolean() && mDisplayedFloater) + { + onClickCloseDisplayedFloater(PRIMARY_FLOATER); + onClickCloseDisplayedFloater(SECONDARY_FLOATER); + delete mDisplayedFloater; + mDisplayedFloater = NULL; + delete mDisplayedFloater_2; + mDisplayedFloater_2 = NULL; } - destroy(); } // Error handling (to avoid code repetition) @@ -382,18 +470,18 @@ std::string LLFloaterUIPreview::getLocStr(S32 ID) { if(ID == 1) { - return sInstance->mLanguageSelection->getSelectedItemLabel(0); + return mLanguageSelection->getSelectedItemLabel(0); } else { - return sInstance->mLanguageSelection_2->getSelectedItemLabel(0); + return mLanguageSelection_2->getSelectedItemLabel(0); } } // Get localized directory (build path from data directory to XUI files, substituting localization string in for language) std::string LLFloaterUIPreview::getLocalizedDirectory() { - return get_xui_dir() + (sInstance ? getLocStr(1) : "en") + mDelim; // e.g. "C:/Code/guipreview/indra/newview/skins/xui/en/"; + return get_xui_dir() + (getLocStr(1)) + mDelim; // e.g. "C:/Code/guipreview/indra/newview/skins/xui/en/"; } // Refresh the list of floaters by doing a directory traverse for XML XUI floater files @@ -505,36 +593,33 @@ void LLFloaterUIPreview::addFloaterEntry(const std::string& path) } // Respond to button click to display/refresh currently-selected floater -void LLFloaterUIPreview::onClickDisplayFloater(void* data) +void LLFloaterUIPreview::onClickDisplayFloater(S32 caller_id) { - S32 caller_id = *((S32*)data); displayFloater(TRUE, caller_id); - if(caller_id == 1) + if(caller_id == PRIMARY_FLOATER) { - sInstance->mDisplayedFloater->center(); // move displayed floater to the center of the screen + mDisplayedFloater->center(); // move displayed floater to the center of the screen } } // Saves the current floater/panel -void LLFloaterUIPreview::onClickSaveFloater(void* data) +void LLFloaterUIPreview::onClickSaveFloater(S32 caller_id) { - S32 caller_id = *((S32*)data); displayFloater(TRUE, caller_id, true); - if(caller_id == 1) + if(caller_id == PRIMARY_FLOATER) { - sInstance->mDisplayedFloater->center(); // move displayed floater to the center of the screen + mDisplayedFloater->center(); // move displayed floater to the center of the screen } } // Saves all floater/panels -void LLFloaterUIPreview::onClickSaveAll(void* data) +void LLFloaterUIPreview::onClickSaveAll(S32 caller_id) { - S32 caller_id = *((S32*)data); - int listSize = sInstance->mFileList->getItemCount(); + int listSize = mFileList->getItemCount(); for (int index = 0; index < listSize; index++) { - sInstance->mFileList->selectNthItem(index); + mFileList->selectNthItem(index); displayFloater(TRUE, caller_id, true); } } @@ -556,56 +641,58 @@ static std::string append_new_to_xml_filename(const std::string& path) void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) { // Convince UI that we're in a different language (the one selected on the drop-down menu) - LLLocalizationResetForcer reset_forcer(ID); // save old language in reset forcer object (to be reset upon destruction when it falls out of scope) + LLLocalizationResetForcer reset_forcer(this, ID); // save old language in reset forcer object (to be reset upon destruction when it falls out of scope) - LLPreviewedFloater** floaterp = (ID == 1 ? &(sInstance->mDisplayedFloater) : &(sInstance->mDisplayedFloater_2)); + LLPreviewedFloater** floaterp = (ID == 1 ? &(mDisplayedFloater) : &(mDisplayedFloater_2)); if(ID == 1) { - BOOL floater_already_open = sInstance->mDisplayedFloater != NULL; + BOOL floater_already_open = mDisplayedFloater != NULL; if(floater_already_open) // if we are already displaying a floater { - sInstance->mLastDisplayedX = sInstance->mDisplayedFloater->calcScreenRect().mLeft; // save floater's last known position to put the new one there - sInstance->mLastDisplayedY = sInstance->mDisplayedFloater->calcScreenRect().mBottom; - delete sInstance->mDisplayedFloater; // delete it (this closes it too) - sInstance->mDisplayedFloater = NULL; // and reset the pointer + mLastDisplayedX = mDisplayedFloater->calcScreenRect().mLeft; // save floater's last known position to put the new one there + mLastDisplayedY = mDisplayedFloater->calcScreenRect().mBottom; + delete mDisplayedFloater; // delete it (this closes it too) + mDisplayedFloater = NULL; // and reset the pointer } } else { - if(sInstance->mDisplayedFloater_2 != NULL) + if(mDisplayedFloater_2 != NULL) { - delete sInstance->mDisplayedFloater_2; - sInstance->mDisplayedFloater_2 = NULL; + delete mDisplayedFloater_2; + mDisplayedFloater_2 = NULL; } } - std::string path = sInstance->mFileList->getSelectedItemLabel(1); // get the path of the currently-selected floater + std::string path = mFileList->getSelectedItemLabel(1); // get the path of the currently-selected floater if(std::string("") == path) // if no item is selected { return; // ignore click (this can only happen with empty list; otherwise an item is always selected) } - *floaterp = new LLPreviewedFloater(); + *floaterp = new LLPreviewedFloater(this); if(!strncmp(path.c_str(),"floater_",8)) // if it's a floater { if (save) { LLXMLNodePtr floater_write = new LLXMLNode(); - LLUICtrlFactory::getInstance()->buildFloater(*floaterp, path, FALSE, floater_write); // just build it + LLUICtrlFactory::getInstance()->buildFloater(*floaterp, path, floater_write); // just build it if (!floater_write->isNull()) { std::string full_filename = append_new_to_xml_filename(path); LLFILE* floater_temp = LLFile::fopen(full_filename.c_str(), "w"); LLXMLNode::writeHeaderToFile(floater_temp); - floater_write->writeToFile(floater_temp); + const bool use_type_decorations = false; + floater_write->writeToFile(floater_temp, std::string(), use_type_decorations); fclose(floater_temp); } } else { - LLUICtrlFactory::getInstance()->buildFloater(*floaterp, path, TRUE); // just build it + LLUICtrlFactory::getInstance()->buildFloater(*floaterp, path, NULL); // just build it + (*floaterp)->openFloater((*floaterp)->getKey()); } } @@ -614,14 +701,15 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) if (save) { LLXMLNodePtr menu_write = new LLXMLNode(); - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile(path, gMenuHolder, menu_write); + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile(path, gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance(), menu_write); if (!menu_write->isNull()) { std::string full_filename = append_new_to_xml_filename(path); LLFILE* menu_temp = LLFile::fopen(full_filename.c_str(), "w"); LLXMLNode::writeHeaderToFile(menu_temp); - menu_write->writeToFile(menu_temp); + const bool use_type_decorations = false; + menu_write->writeToFile(menu_temp, std::string(), use_type_decorations); fclose(menu_temp); } @@ -645,7 +733,8 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) std::string full_filename = append_new_to_xml_filename(path); LLFILE* panel_temp = LLFile::fopen(full_filename.c_str(), "w"); LLXMLNode::writeHeaderToFile(panel_temp); - panel_write->writeToFile(panel_temp); + const bool use_type_decorations = false; + panel_write->writeToFile(panel_temp, std::string(), use_type_decorations); fclose(panel_temp); } } @@ -669,7 +758,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) if(ID == 1) { - (*floaterp)->setOrigin(sInstance->mLastDisplayedX, sInstance->mLastDisplayedY); + (*floaterp)->setOrigin(mLastDisplayedX, mLastDisplayedY); } // *HACK: Remove ability to close it; if you close it, its destructor gets called, but we don't know it's null and try to delete it again, @@ -678,22 +767,22 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) if(ID == 1) { - sInstance->mCloseOtherButton->setEnabled(TRUE); // enable my floater's close button + mCloseOtherButton->setEnabled(TRUE); // enable my floater's close button } else { - sInstance->mCloseOtherButton_2->setEnabled(TRUE); + mCloseOtherButton_2->setEnabled(TRUE); } // *TODO: Make the secondary floater pop up next to the primary one. Doesn't seem to always work if secondary was up first... - if((sInstance->mDisplayedFloater && ID == 2) || (sInstance->mDisplayedFloater_2 && ID == 1)) + if((mDisplayedFloater && ID == 2) || (mDisplayedFloater_2 && ID == 1)) { - sInstance->mDisplayedFloater_2->setSnapTarget(sInstance->mDisplayedFloater->getHandle()); - sInstance->mDisplayedFloater->addDependentFloater(sInstance->mDisplayedFloater_2); + mDisplayedFloater_2->setSnapTarget(mDisplayedFloater->getHandle()); + mDisplayedFloater->addDependentFloater(mDisplayedFloater_2); } // Add localization to title so user knows whether it's localized or defaulted to en - std::string full_path = sInstance->getLocalizedDirectory() + path; + std::string full_path = getLocalizedDirectory() + path; std::string floater_lang = "EN"; llstat dummy; if(!LLFile::stat(full_path.c_str(), &dummy)) // if the file does not exist @@ -707,37 +796,37 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) if(click && ID == 1 && !save) { // set up live file to track it - if(sInstance->mLiveFile) + if(mLiveFile) { - delete sInstance->mLiveFile; - sInstance->mLiveFile = NULL; + delete mLiveFile; + mLiveFile = NULL; } - sInstance->mLiveFile = new LLGUIPreviewLiveFile(std::string(full_path.c_str()),std::string(path.c_str()),sInstance); - sInstance->mLiveFile->checkAndReload(); - sInstance->mLiveFile->addToEventTimer(); + mLiveFile = new LLGUIPreviewLiveFile(std::string(full_path.c_str()),std::string(path.c_str()),this); + mLiveFile->checkAndReload(); + mLiveFile->addToEventTimer(); } if(ID == 1) { - sInstance->mToggleOverlapButton->setEnabled(TRUE); + mToggleOverlapButton->setEnabled(TRUE); } if(LLView::sHighlightingDiffs && click && ID == 1) { - sInstance->highlightChangedElements(); + highlightChangedElements(); } if(ID == 1) { - sInstance->mOverlapMap.clear(); + mOverlapPanel->mOverlapMap.clear(); LLView::sPreviewClickedElement = NULL; // stop overlapping elements from drawing - sInstance->mOverlapPanel->mLastClickedElement = NULL; - sInstance->findOverlapsInChildren((LLView*)sInstance->mDisplayedFloater); + mOverlapPanel->mLastClickedElement = NULL; + findOverlapsInChildren((LLView*)mDisplayedFloater); // highlight and enable them - if(sInstance->mHighlightingOverlaps) + if(mHighlightingOverlaps) { - for(OverlapMap::iterator iter = sInstance->mOverlapMap.begin(); iter != sInstance->mOverlapMap.end(); ++iter) + for(LLOverlapPanel::OverlapMap::iterator iter = mOverlapPanel->mOverlapMap.begin(); iter != mOverlapPanel->mOverlapMap.end(); ++iter) { LLView* viewp = iter->first; LLView::sPreviewHighlightedElements.insert(viewp); @@ -745,7 +834,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) } else if(LLView::sHighlightingDiffs) { - sInstance->highlightChangedElements(); + highlightChangedElements(); } } @@ -753,14 +842,14 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) } // Respond to button click to edit currently-selected floater -void LLFloaterUIPreview::onClickEditFloater(void*) +void LLFloaterUIPreview::onClickEditFloater() { - std::string file_name = sInstance->mFileList->getSelectedItemLabel(1); // get the file name of the currently-selected floater + std::string file_name = mFileList->getSelectedItemLabel(1); // get the file name of the currently-selected floater if(std::string("") == file_name) // if no item is selected { return; // ignore click } - std::string path = sInstance->getLocalizedDirectory() + file_name; + std::string path = getLocalizedDirectory() + file_name; // stat file to see if it exists (some localized versions may not have it there are no diffs, and then we try to open an nonexistent file) llstat dummy; @@ -769,16 +858,20 @@ void LLFloaterUIPreview::onClickEditFloater(void*) std::string warning = "No file for this floater exists in the selected localization. Opening the EN version instead."; popupAndPrintWarning(warning); - path = get_xui_dir() + sInstance->mDelim + "en" + sInstance->mDelim + file_name; // open the en version instead, by default + path = get_xui_dir() + mDelim + "en" + mDelim + file_name; // open the en version instead, by default } // get executable path const char* exe_path_char; - std::string path_in_textfield = sInstance->mEditorPathTextBox->getText(); + std::string path_in_textfield = mEditorPathTextBox->getText(); if(std::string("") != path_in_textfield) // if the text field is not emtpy, use its path { exe_path_char = path_in_textfield.c_str(); } + else if (!LLUI::sSettingGroups["config"]->getString("XUIEditor").empty()) + { + exe_path_char = LLUI::sSettingGroups["config"]->getString("XUIEditor").c_str(); + } else // otherwise use the path specified by the environment variable { exe_path_char = getenv("LL_XUI_EDITOR"); @@ -805,7 +898,7 @@ void LLFloaterUIPreview::onClickEditFloater(void*) { // build paths and arguments std::string args; - std::string custom_args = sInstance->mEditorArgsTextBox->getText(); + std::string custom_args = mEditorArgsTextBox->getText(); int position_of_file = custom_args.find(std::string("%FILE%"), 0); // prepare to replace %FILE% with actual file path std::string first_part_of_args = ""; std::string second_part_of_args = ""; @@ -822,7 +915,7 @@ void LLFloaterUIPreview::onClickEditFloater(void*) } // find directory in which executable resides by taking everything after last slash - int last_slash_position = exe_path.find_last_of(sInstance->mDelim); + int last_slash_position = exe_path.find_last_of(mDelim); if(-1 == last_slash_position) { std::string warning = std::string("Unable to find a valid path to the specified executable for XUI XML editing: ") + exe_path; @@ -936,7 +1029,7 @@ void LLFloaterUIPreview::onClickEditFloater(void*) } // Respond to button click to browse for an executable with which to edit XML files -void LLFloaterUIPreview::onClickBrowseForEditor(void*) +void LLFloaterUIPreview::onClickBrowseForEditor() { // create load dialog box LLFilePicker::ELoadFilter type = (LLFilePicker::ELoadFilter)((intptr_t)((void*)LLFilePicker::FFLOAD_ALL)); // nothing for *.exe so just use all @@ -988,11 +1081,11 @@ void LLFloaterUIPreview::onClickBrowseForEditor(void*) } #endif - sInstance->mEditorPathTextBox->setText(std::string(executable_path)); // copy the path to the executable to the textfield for display and later fetching + mEditorPathTextBox->setText(std::string(executable_path)); // copy the path to the executable to the textfield for display and later fetching } // Respond to button click to browse for a VLT-generated diffs file -void LLFloaterUIPreview::onClickBrowseForDiffs(void*) +void LLFloaterUIPreview::onClickBrowseForDiffs() { // create load dialog box LLFilePicker::ELoadFilter type = (LLFilePicker::ELoadFilter)((intptr_t)((void*)LLFilePicker::FFLOAD_XML)); // nothing for *.exe so just use all @@ -1004,35 +1097,35 @@ void LLFloaterUIPreview::onClickBrowseForDiffs(void*) // put the selected path into text field const std::string chosen_path = picker.getFirstFile(); - sInstance->mDiffPathTextBox->setText(std::string(chosen_path)); // copy the path to the executable to the textfield for display and later fetching + mDiffPathTextBox->setText(std::string(chosen_path)); // copy the path to the executable to the textfield for display and later fetching if(LLView::sHighlightingDiffs) // if we're already highlighting, toggle off and then on so we get the data from the new file { - onClickToggleDiffHighlighting(NULL); - onClickToggleDiffHighlighting(NULL); + onClickToggleDiffHighlighting(); + onClickToggleDiffHighlighting(); } } -void LLFloaterUIPreview::onClickToggleDiffHighlighting(void*) +void LLFloaterUIPreview::onClickToggleDiffHighlighting() { - if(sInstance->mHighlightingOverlaps) + if(mHighlightingOverlaps) { - onClickToggleOverlapping(NULL); - sInstance->mToggleOverlapButton->toggleState(); + onClickToggleOverlapping(); + mToggleOverlapButton->toggleState(); } LLView::sPreviewHighlightedElements.clear(); // clear lists first - sInstance->mDiffsMap.clear(); - sInstance->mFileList->clearHighlightedItems(); + mDiffsMap.clear(); + mFileList->clearHighlightedItems(); if(LLView::sHighlightingDiffs) // Turning highlighting off { - LLView::sHighlightingDiffs = !sInstance->sHighlightingDiffs; + LLView::sHighlightingDiffs = !sHighlightingDiffs; return; } else // Turning highlighting on { // Get the file and make sure it exists - std::string path_in_textfield = sInstance->mDiffPathTextBox->getText(); // get file path + std::string path_in_textfield = mDiffPathTextBox->getText(); // get file path BOOL error = FALSE; if(std::string("") == path_in_textfield) // check for blank file @@ -1066,18 +1159,18 @@ void LLFloaterUIPreview::onClickToggleDiffHighlighting(void*) { if(!strncmp("file",child->getName().c_str(),5)) { - sInstance->scanDiffFile(child); + scanDiffFile(child); } else if(!strncmp("error",child->getName().c_str(),6)) { std::string error_file, error_message; child->getAttributeString("filename",error_file); child->getAttributeString("message",error_message); - if(sInstance->mDiffsMap.find(error_file) != sInstance->mDiffsMap.end()) + if(mDiffsMap.find(error_file) != mDiffsMap.end()) { - sInstance->mDiffsMap.insert(std::make_pair(error_file,std::make_pair(StringListPtr(new StringList), StringListPtr(new StringList)))); + mDiffsMap.insert(std::make_pair(error_file,std::make_pair(StringListPtr(new StringList), StringListPtr(new StringList)))); } - sInstance->mDiffsMap[error_file].second->push_back(error_message); + mDiffsMap[error_file].second->push_back(error_message); } else { @@ -1104,13 +1197,13 @@ void LLFloaterUIPreview::onClickToggleDiffHighlighting(void*) if(error) // if we encountered an error, reset the button to off { - sInstance->mToggleHighlightButton->setToggleState(FALSE); + mToggleHighlightButton->setToggleState(FALSE); } else // only toggle if we didn't encounter an error { - LLView::sHighlightingDiffs = !sInstance->sHighlightingDiffs; - sInstance->highlightChangedElements(); // *TODO: this is extraneous, right? - sInstance->highlightChangedFiles(); // *TODO: this is extraneous, right? + LLView::sHighlightingDiffs = !sHighlightingDiffs; + highlightChangedElements(); // *TODO: this is extraneous, right? + highlightChangedFiles(); // *TODO: this is extraneous, right? } } } @@ -1167,7 +1260,7 @@ void LLFloaterUIPreview::highlightChangedElements() for(std::list::iterator iter = changed_element_paths->begin(); iter != changed_element_paths->end(); ++iter) // for every changed element path { - LLView* element = sInstance->mDisplayedFloater; + LLView* element = mDisplayedFloater; if(!strncmp(iter->c_str(),".",1)) // if it's the root floater itself { continue; @@ -1230,42 +1323,41 @@ void LLFloaterUIPreview::highlightChangedFiles() } // Respond to button click to browse for an executable with which to edit XML files -void LLFloaterUIPreview::onClickCloseDisplayedFloater(void* data) +void LLFloaterUIPreview::onClickCloseDisplayedFloater(S32 caller_id) { - S32 caller_id = *((S32*)data); - if(caller_id == 1) + if(caller_id == PRIMARY_FLOATER) { - sInstance->mCloseOtherButton->setEnabled(FALSE); - sInstance->mToggleOverlapButton->setEnabled(FALSE); + mCloseOtherButton->setEnabled(FALSE); + mToggleOverlapButton->setEnabled(FALSE); - if(sInstance->mDisplayedFloater) + if(mDisplayedFloater) { - sInstance->mLastDisplayedX = sInstance->mDisplayedFloater->calcScreenRect().mLeft; - sInstance->mLastDisplayedY = sInstance->mDisplayedFloater->calcScreenRect().mBottom; - delete sInstance->mDisplayedFloater; - sInstance->mDisplayedFloater = NULL; + mLastDisplayedX = mDisplayedFloater->calcScreenRect().mLeft; + mLastDisplayedY = mDisplayedFloater->calcScreenRect().mBottom; + delete mDisplayedFloater; + mDisplayedFloater = NULL; } - if(sInstance->mLiveFile) + if(mLiveFile) { - delete sInstance->mLiveFile; - sInstance->mLiveFile = NULL; + delete mLiveFile; + mLiveFile = NULL; } - if(sInstance->mToggleOverlapButton->getToggleState()) + if(mToggleOverlapButton->getToggleState()) { - sInstance->mToggleOverlapButton->toggleState(); - onClickToggleOverlapping(NULL); + mToggleOverlapButton->toggleState(); + onClickToggleOverlapping(); } LLView::sPreviewClickedElement = NULL; // stop overlapping elements panel from drawing - sInstance->mOverlapPanel->mLastClickedElement = NULL; + mOverlapPanel->mLastClickedElement = NULL; } else { - sInstance->mCloseOtherButton_2->setEnabled(FALSE); - delete sInstance->mDisplayedFloater_2; - sInstance->mDisplayedFloater_2 = NULL; + mCloseOtherButton_2->setEnabled(FALSE); + delete mDisplayedFloater_2; + mDisplayedFloater_2 = NULL; } } @@ -1321,47 +1413,47 @@ BOOL LLPreviewedFloater::selectElement(LLView* parent, int x, int y, int depth) void LLPreviewedFloater::draw() { - if(NULL != LLFloaterUIPreview::sInstance) + if(NULL != mFloaterUIPreview) { // Set and unset sDrawPreviewHighlights flag so as to avoid using two flags - if(LLFloaterUIPreview::sInstance->mHighlightingOverlaps) + if(mFloaterUIPreview->mHighlightingOverlaps) { LLView::sDrawPreviewHighlights = TRUE; } LLFloater::draw(); - if(LLFloaterUIPreview::sInstance->mHighlightingOverlaps) + if(mFloaterUIPreview->mHighlightingOverlaps) { LLView::sDrawPreviewHighlights = FALSE; } } } -void LLFloaterUIPreview::onClickToggleOverlapping(void*) +void LLFloaterUIPreview::onClickToggleOverlapping() { if(LLView::sHighlightingDiffs) { - onClickToggleDiffHighlighting(NULL); - sInstance->mToggleHighlightButton->toggleState(); + onClickToggleDiffHighlighting(); + mToggleHighlightButton->toggleState(); } LLView::sPreviewHighlightedElements.clear(); // clear lists first S32 width, height; - sInstance->getResizeLimits(&width, &height); // illegal call of non-static member function - if(sInstance->mHighlightingOverlaps) + getResizeLimits(&width, &height); // illegal call of non-static member function + if(mHighlightingOverlaps) { - sInstance->mHighlightingOverlaps = !sInstance->mHighlightingOverlaps; + mHighlightingOverlaps = !mHighlightingOverlaps; // reset list of preview highlighted elements - sInstance->setRect(LLRect(sInstance->getRect().mLeft,sInstance->getRect().mTop,sInstance->getRect().mRight - sInstance->mOverlapPanel->getRect().getWidth(),sInstance->getRect().mBottom)); - sInstance->setResizeLimits(width - sInstance->mOverlapPanel->getRect().getWidth(), height); + setRect(LLRect(getRect().mLeft,getRect().mTop,getRect().mRight - mOverlapPanel->getRect().getWidth(),getRect().mBottom)); + setResizeLimits(width - mOverlapPanel->getRect().getWidth(), height); } else { - sInstance->mHighlightingOverlaps = !sInstance->mHighlightingOverlaps; + mHighlightingOverlaps = !mHighlightingOverlaps; displayFloater(FALSE,1); - sInstance->setRect(LLRect(sInstance->getRect().mLeft,sInstance->getRect().mTop,sInstance->getRect().mRight + sInstance->mOverlapPanel->getRect().getWidth(),sInstance->getRect().mBottom)); - sInstance->setResizeLimits(width + sInstance->mOverlapPanel->getRect().getWidth(), height); + setRect(LLRect(getRect().mLeft,getRect().mTop,getRect().mRight + mOverlapPanel->getRect().getWidth(),getRect().mBottom)); + setResizeLimits(width + mOverlapPanel->getRect().getWidth(), height); } - sInstance->childSetVisible("overlap_scroll", sInstance->mHighlightingOverlaps); + childSetVisible("overlap_scroll", mHighlightingOverlaps); } void LLFloaterUIPreview::findOverlapsInChildren(LLView* parent) @@ -1392,7 +1484,7 @@ void LLFloaterUIPreview::findOverlapsInChildren(LLView* parent) // if they overlap... (we don't care if they're visible or enabled -- we want to check those anyway, i.e. hidden tabs that can be later shown) if(sibling != child && elementOverlap(child, sibling)) { - mOverlapMap[child].push_back(sibling); // add to the map + mOverlapPanel->mOverlapMap[child].push_back(sibling); // add to the map } } findOverlapsInChildren(child); // recur @@ -1444,13 +1536,13 @@ void LLOverlapPanel::draw() } else { - LLFloaterUIPreview::OverlapMap::iterator iterExists = LLFloaterUIPreview::sInstance->mOverlapMap.find(LLView::sPreviewClickedElement); - if(iterExists == LLFloaterUIPreview::sInstance->mOverlapMap.end()) + OverlapMap::iterator iterExists = mOverlapMap.find(LLView::sPreviewClickedElement); + if(iterExists == mOverlapMap.end()) { return; } - std::list overlappers = LLFloaterUIPreview::sInstance->mOverlapMap[LLView::sPreviewClickedElement]; + std::list overlappers = mOverlapMap[LLView::sPreviewClickedElement]; if(overlappers.size() == 0) { LLUI::translate(5,getRect().getHeight()-20); // translate to top-5,left-5 @@ -1481,15 +1573,15 @@ void LLOverlapPanel::draw() if(need_to_recalculate_bounds || LLView::sPreviewClickedElement->getName() != mLastClickedElement->getName()) { // reset panel's rectangle to its default width and height (300x600) - LLRect panel_rect = LLFloaterUIPreview::sInstance->mOverlapPanel->getRect(); - LLFloaterUIPreview::sInstance->mOverlapPanel->setRect(LLRect(panel_rect.mLeft,panel_rect.mTop,panel_rect.mLeft+LLFloaterUIPreview::sInstance->mOverlapPanel->getRect().getWidth(),panel_rect.mTop-LLFloaterUIPreview::sInstance->mOverlapPanel->getRect().getHeight())); + LLRect panel_rect = getRect(); + setRect(LLRect(panel_rect.mLeft,panel_rect.mTop,panel_rect.mLeft+getRect().getWidth(),panel_rect.mTop-getRect().getHeight())); LLRect rect; // change bounds for selected element int height_sum = mLastClickedElement->getRect().getHeight() + mSpacing + 80; - rect = LLFloaterUIPreview::sInstance->mOverlapPanel->getRect(); - LLFloaterUIPreview::sInstance->mOverlapPanel->setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() > mLastClickedElement->getRect().getWidth() + 5 ? rect.mRight : rect.mLeft + mLastClickedElement->getRect().getWidth() + 5, rect.mBottom)); + rect = getRect(); + setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() > mLastClickedElement->getRect().getWidth() + 5 ? rect.mRight : rect.mLeft + mLastClickedElement->getRect().getWidth() + 5, rect.mBottom)); // and widen to accomodate text if that's wider std::string display_text = current_selection_text + LLView::sPreviewClickedElement->getName(); @@ -1497,15 +1589,15 @@ void LLOverlapPanel::draw() rect = getRect(); setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() < text_width ? rect.mLeft + text_width : rect.mRight,rect.mTop)); - std::list overlappers = LLFloaterUIPreview::sInstance->mOverlapMap[LLView::sPreviewClickedElement]; + std::list overlappers = mOverlapMap[LLView::sPreviewClickedElement]; for(std::list::iterator overlap_it = overlappers.begin(); overlap_it != overlappers.end(); ++overlap_it) { LLView* viewp = *overlap_it; height_sum += viewp->getRect().getHeight() + mSpacing*3; // widen panel's rectangle to accommodate widest overlapping element of this floater - rect = LLFloaterUIPreview::sInstance->mOverlapPanel->getRect(); - LLFloaterUIPreview::sInstance->mOverlapPanel->setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() > viewp->getRect().getWidth() + 5 ? rect.mRight : rect.mLeft + viewp->getRect().getWidth() + 5, rect.mBottom)); + rect = getRect(); + setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() > viewp->getRect().getWidth() + 5 ? rect.mRight : rect.mLeft + viewp->getRect().getWidth() + 5, rect.mBottom)); // and widen to accomodate text if that's wider std::string display_text = overlapper_text + viewp->getName(); @@ -1514,8 +1606,8 @@ void LLOverlapPanel::draw() setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() < text_width ? rect.mLeft + text_width : rect.mRight,rect.mTop)); } // change panel's height to accommodate all element heights plus spacing between them - rect = LLFloaterUIPreview::sInstance->mOverlapPanel->getRect(); - LLFloaterUIPreview::sInstance->mOverlapPanel->setRect(LLRect(rect.mLeft,rect.mTop,rect.mRight,rect.mTop-height_sum)); + rect = getRect(); + setRect(LLRect(rect.mLeft,rect.mTop,rect.mRight,rect.mTop-height_sum)); } LLUI::translate(5,getRect().getHeight()-10); // translate to top left diff --git a/indra/newview/llfloateruipreview.h b/indra/newview/llfloateruipreview.h index b0af841e11..b8c378e2e9 100644 --- a/indra/newview/llfloateruipreview.h +++ b/indra/newview/llfloateruipreview.h @@ -49,61 +49,15 @@ class LLColor; class LLScrollListCtrl; class LLComboBox; class LLButton; +class LLLineEditor; class LLXmlTreeNode; class LLFloaterUIPreview; class LLFadeEventTimer; -// Reset object to ensure that when we change the current language setting for preview purposes, -// it automatically is reset. Constructed on the stack at the start of the method; the reset -// occurs as it falls out of scope at the end of the method. See llfloateruipreview.cpp for usage. -class LLLocalizationResetForcer -{ -public: - LLLocalizationResetForcer(S32 ID); - virtual ~LLLocalizationResetForcer(); - -private: - std::string mSavedLocalization; // the localization before we change it -}; - -// Implementation of live file -// When a floater is being previewed, any saved changes to its corresponding -// file cause the previewed floater to be reloaded -class LLGUIPreviewLiveFile : public LLLiveFile -{ -public: - LLGUIPreviewLiveFile(std::string path, std::string name, LLFloaterUIPreview* parent); - virtual ~LLGUIPreviewLiveFile(); - LLFloaterUIPreview* mParent; - LLFadeEventTimer* mFadeTimer; // timer for fade-to-yellow-and-back effect to warn that file has been reloaded - BOOL mFirstFade; // setting this avoids showing the fade reload warning on first load - std::string mFileName; -protected: - bool loadFile(); -}; - -// Implementation of graphical fade in/out (on timer) for when XUI files are updated -class LLFadeEventTimer : public LLEventTimer -{ -public: - LLFadeEventTimer(F32 refresh, LLGUIPreviewLiveFile* parent); - BOOL tick(); - LLGUIPreviewLiveFile* mParent; -private: - BOOL mFadingOut; // fades in then out; this is toggled in between - LLColor4 mOriginalColor; // original color; color is reset to this after fade is coimplete -}; - -// Implementation of previewed floater -// Used to override draw and mouse handler -class LLPreviewedFloater : public LLFloater -{ -public: - LLPreviewedFloater() : LLFloater() {} - virtual void draw(); - BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - BOOL selectElement(LLView* parent, int x, int y, int depth); // select element to display its overlappers -}; +class LLLocalizationResetForcer; +class LLGUIPreviewLiveFile; +class LLFadeEventTimer; +class LLPreviewedFloater; // Implementation of custom overlapping element display panel class LLOverlapPanel : public LLPanel @@ -122,11 +76,16 @@ public: mOriginalHeight = getRect().getHeight(); } virtual void draw(); + + typedef std::map > OverlapMap; + OverlapMap mOverlapMap; // map, of XUI element to a list of XUI elements it overlaps + // LLView *mClickedElement; LLView *mLastClickedElement; int mOriginalWidth, mOriginalHeight, mSpacing; }; + class LLFloaterUIPreview : public LLFloater { public: @@ -134,15 +93,16 @@ public: LLFloaterUIPreview(const LLSD& key); virtual ~LLFloaterUIPreview(); - static std::string getLocStr(S32 ID); // fetches the localization string based on what is selected in the drop-down menu - static void displayFloater(BOOL click, S32 ID, bool save = false); // needs to be public so live file can call it when it finds an update - static BOOL containerType(LLView* viewp); // check if the element is a container type and tree traverses need to look at its children - static LLFloaterUIPreview* sInstance; // static instance of this (for references in handlers) + std::string getLocStr(S32 ID); // fetches the localization string based on what is selected in the drop-down menu + void displayFloater(BOOL click, S32 ID, bool save = false); // needs to be public so live file can call it when it finds an update BOOL postBuild(); // post-build setup (called by superclass' constructor) void refreshList(); // refresh list (empty it out and fill it up from scratch) void addFloaterEntry(const std::string& path); // add a single file's entry to the list of floaters - + + static BOOL containerType(LLView* viewp); // check if the element is a container type and tree traverses need to look at its children + +public: LLPreviewedFloater* mDisplayedFloater; // the floater which is currently being displayed LLPreviewedFloater* mDisplayedFloater_2; // the floater which is currently being displayed LLGUIPreviewLiveFile* mLiveFile; // live file for checking for updates to the currently-displayed XML file @@ -150,9 +110,6 @@ public: // BOOL mHighlightingDiffs; // bool for whether localization diffs are being highlighted or not BOOL mHighlightingOverlaps; // bool for whether overlapping elements are being highlighted - typedef std::map > OverlapMap; - OverlapMap mOverlapMap; // map, of XUI element to a list of XUI elements it overlaps - // typedef std::map,std::list > > DiffMap; // this version copies the lists etc., and thus is bad memory-wise typedef std::list StringList; typedef boost::shared_ptr StringListPtr; @@ -160,7 +117,7 @@ public: DiffMap mDiffsMap; // map, of filename to pair of list of changed element paths and list of errors protected: - virtual void onClose(bool app_quitting); + void onClose(const LLSD& app_quitting); private: // XUI elements for this floater @@ -173,19 +130,19 @@ private: LLButton* mEditFloaterBtn; // button to edit floater LLButton* mExecutableBrowseButton; // button to browse for executable LLButton* mCloseOtherButton; // button to close primary displayed floater - LLButton* mCloseOtherButton_2; // button to close secondary displayed floater + LLButton* mCloseOtherButton_2; // button to close secondary displayed floater LLButton* mDiffBrowseButton; // button to browse for diff file LLButton* mToggleHighlightButton; // button to toggle highlight of files/elements with diffs LLButton* mToggleOverlapButton; // button to togle overlap panel/highlighting LLComboBox* mLanguageSelection; // combo box for primary language selection LLComboBox* mLanguageSelection_2; // combo box for secondary language selection - LLScrollContainer* mOverlapScrollView; // overlapping elements scroll container + LLScrollContainer* mOverlapScrollView; // overlapping elements scroll container S32 mLastDisplayedX, mLastDisplayedY; // stored position of last floater so the new one opens up in the same place - std::string mDelim; // the OS-specific delimiter character (/ or \) (*TODO: this shouldn't be needed, right?) + std::string mDelim; // the OS-specific delimiter character (/ or \) (*TODO: this shouldn't be needed, right?) - static std::string mSavedEditorPath; // stored editor path so closing this floater doesn't reset it - static std::string mSavedEditorArgs; // stored editor args so closing this floater doesn't reset it - static std::string mSavedDiffPath; // stored diff file path so closing this floater doesn't reset it + std::string mSavedEditorPath; // stored editor path so closing this floater doesn't reset it + std::string mSavedEditorArgs; // stored editor args so closing this floater doesn't reset it + std::string mSavedDiffPath; // stored diff file path so closing this floater doesn't reset it // Internal functionality static void popupAndPrintWarning(std::string& warning); // pop up a warning @@ -201,16 +158,17 @@ private: BOOL elementOverlap(LLView* view1, LLView* view2); // Button/drop-down action listeners (self explanatory) - static void onClickDisplayFloater(void*); - static void onClickSaveFloater(void*); - static void onClickSaveAll(void*); - static void onClickEditFloater(void*); - static void onClickBrowseForEditor(void*); - static void onClickBrowseForDiffs(void*); - static void onClickToggleDiffHighlighting(void*); - static void onClickToggleOverlapping(void*); - static void onClickCloseDisplayedFloater(void*); + void onClickDisplayFloater(S32 id); + void onClickSaveFloater(S32 id); + void onClickSaveAll(S32 id); + void onClickEditFloater(); + void onClickBrowseForEditor(); + void onClickBrowseForDiffs(); + void onClickToggleDiffHighlighting(); + void onClickToggleOverlapping(); + void onClickCloseDisplayedFloater(S32 id); void onLanguageComboSelect(LLUICtrl* ctrl); + void onClickExportSchema(); }; #endif // LL_LLUIPREVIEW_H diff --git a/indra/newview/llfloaterurldisplay.cpp b/indra/newview/llfloaterurldisplay.cpp index 7f7d05e1d2..3b9321a876 100644 --- a/indra/newview/llfloaterurldisplay.cpp +++ b/indra/newview/llfloaterurldisplay.cpp @@ -45,11 +45,10 @@ LLFloaterURLDisplay::LLFloaterURLDisplay(const LLSD& sd) - : LLFloater() + : LLFloater(sd) { mFactoryMap["place_details_panel"] = LLCallbackMap(LLFloaterURLDisplay::createPlaceDetail, this); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_url.xml"); - this->setVisible(false); +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_url.xml"); // If positioned at 0,0 the teleport button is behind the toolbar. LLRect r = getRect(); diff --git a/indra/newview/llfloaterurldisplay.h b/indra/newview/llfloaterurldisplay.h index 91c544ae86..22f5a95ad0 100644 --- a/indra/newview/llfloaterurldisplay.h +++ b/indra/newview/llfloaterurldisplay.h @@ -40,11 +40,10 @@ class LLPanelPlace; class LLSD; class LLUUID; -class LLFloaterURLDisplay : public LLFloater, public LLFloaterSingleton +class LLFloaterURLDisplay : public LLFloater { + friend class LLFloaterReg; public: - LLFloaterURLDisplay(const LLSD& sd); - virtual ~LLFloaterURLDisplay(); void displayParcelInfo(U64 region_handle, const LLVector3& pos); void setSnapshotDisplay(const LLUUID& snapshot_id); @@ -54,6 +53,9 @@ public: static void* createPlaceDetail(void* userdata); private: + LLFloaterURLDisplay(const LLSD& sd); + virtual ~LLFloaterURLDisplay(); + LLVector3 mRegionPosition; U64 mRegionHandle; LLPanelPlace* mPlacePanel; diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp index 1f59812029..2ad41291f3 100644 --- a/indra/newview/llfloaterurlentry.cpp +++ b/indra/newview/llfloaterurlentry.cpp @@ -86,10 +86,10 @@ public: // LLFloaterURLEntry() //----------------------------------------------------------------------------- LLFloaterURLEntry::LLFloaterURLEntry(LLHandle parent) - : LLFloater(), + : LLFloater(LLSD()), mPanelLandMediaHandle(parent) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_url_entry.xml"); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_url_entry.xml", NULL); } //----------------------------------------------------------------------------- diff --git a/indra/newview/llfloatervoicedevicesettings.cpp b/indra/newview/llfloatervoicedevicesettings.cpp index 12d12f37f2..fa76bb728d 100644 --- a/indra/newview/llfloatervoicedevicesettings.cpp +++ b/indra/newview/llfloatervoicedevicesettings.cpp @@ -113,7 +113,7 @@ void LLPanelVoiceDeviceSettings::draw() { if (power_bar_idx < discrete_power) { - LLColor4 color = (power_bar_idx >= 3) ? gSavedSkinSettings.getColor4("OverdrivenColor") : gSavedSkinSettings.getColor4("SpeakingColor"); + LLColor4 color = (power_bar_idx >= 3) ? LLUIColorTable::instance().getColor("OverdrivenColor") : LLUIColorTable::instance().getColor("SpeakingColor"); gl_rect_2d(bar_view->getRect(), color, TRUE); } gl_rect_2d(bar_view->getRect(), LLColor4::grey, FALSE); @@ -284,7 +284,7 @@ void LLPanelVoiceDeviceSettings::onCommitOutputDevice(LLUICtrl* ctrl, void* user // LLFloaterVoiceDeviceSettings::LLFloaterVoiceDeviceSettings(const LLSD& seed) - : LLFloater(), + : LLFloater(seed), mDevicePanel(NULL) { mFactoryMap["device_settings"] = LLCallbackMap(createPanelVoiceDeviceSettings, this); @@ -294,6 +294,8 @@ LLFloaterVoiceDeviceSettings::LLFloaterVoiceDeviceSettings(const LLSD& seed) } BOOL LLFloaterVoiceDeviceSettings::postBuild() { + mCloseSignal.connect(boost::bind(&LLFloaterVoiceDeviceSettings::onClose, this)); + center(); return TRUE; } @@ -305,14 +307,12 @@ void LLFloaterVoiceDeviceSettings::onOpen(const LLSD& key) } } -void LLFloaterVoiceDeviceSettings::onClose(bool app_quitting) +void LLFloaterVoiceDeviceSettings::onClose() { if(mDevicePanel) { mDevicePanel->cleanup(); } - - setVisible(FALSE); } void LLFloaterVoiceDeviceSettings::apply() diff --git a/indra/newview/llfloatervoicedevicesettings.h b/indra/newview/llfloatervoicedevicesettings.h index 47f41d6d7e..2565bfad2b 100644 --- a/indra/newview/llfloatervoicedevicesettings.h +++ b/indra/newview/llfloatervoicedevicesettings.h @@ -62,20 +62,26 @@ protected: BOOL mDevicesUpdated; }; -class LLFloaterVoiceDeviceSettings : public LLFloater, public LLFloaterSingleton +class LLFloaterVoiceDeviceSettings : public LLFloater { + friend class LLFloaterReg; + public: - LLFloaterVoiceDeviceSettings(const LLSD& seed); + virtual BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void draw(); void apply(); void cancel(); - +private: + LLFloaterVoiceDeviceSettings(const LLSD& seed); + protected: static void* createPanelVoiceDeviceSettings(void* user_data); - + + void onClose(); + +protected: LLPanelVoiceDeviceSettings* mDevicePanel; }; diff --git a/indra/newview/llfloaterwater.cpp b/indra/newview/llfloaterwater.cpp index 5b551af836..72c82c178b 100644 --- a/indra/newview/llfloaterwater.cpp +++ b/indra/newview/llfloaterwater.cpp @@ -37,6 +37,7 @@ #include "pipeline.h" #include "llsky.h" +#include "llfloaterreg.h" #include "llsliderctrl.h" #include "llspinctrl.h" #include "llcolorswatch.h" @@ -62,15 +63,19 @@ #undef max -LLFloaterWater* LLFloaterWater::sWaterMenu = NULL; - std::set LLFloaterWater::sDefaultPresets; -LLFloaterWater::LLFloaterWater() - : LLFloater() +LLFloaterWater::LLFloaterWater(const LLSD& key) + : LLFloater(key) +{ + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_water.xml"); +} + +LLFloaterWater::~LLFloaterWater() +{ +} +BOOL LLFloaterWater::postBuild() { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_water.xml"); - std::string def_water = getString("WLDefaultWaterNames"); @@ -82,15 +87,7 @@ LLFloaterWater::LLFloaterWater() std::string tok(*token_iter); sDefaultPresets.insert(tok); } - - -} - -LLFloaterWater::~LLFloaterWater() -{ -} -BOOL LLFloaterWater::postBuild() -{ + // add the combo boxes LLComboBox* comboBox = getChild("WaterPresetsCombo"); @@ -108,6 +105,7 @@ BOOL LLFloaterWater::postBuild() } // load it up initCallbacks(); + syncMenu(); return TRUE; } void LLFloaterWater::initCallbacks(void) { @@ -131,63 +129,58 @@ void LLFloaterWater::initCallbacks(void) { LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); - childSetCommitCallback("WaterFogColor", onWaterFogColorMoved, ¶m_mgr->mFogColor); + getChild("WaterFogColor")->setCommitCallback(boost::bind(&LLFloaterWater::onWaterFogColorMoved, this, _1, ¶m_mgr->mFogColor)); // - childSetCommitCallback("WaterGlow", onColorControlAMoved, ¶m_mgr->mFogColor); + getChild("WaterGlow")->setCommitCallback(boost::bind(&LLFloaterWater::onColorControlAMoved, this, _1, ¶m_mgr->mFogColor)); // fog density - childSetCommitCallback("WaterFogDensity", onExpFloatControlMoved, ¶m_mgr->mFogDensity); - childSetCommitCallback("WaterUnderWaterFogMod", onFloatControlMoved, ¶m_mgr->mUnderWaterFogMod); + getChild("WaterFogDensity")->setCommitCallback(boost::bind(&LLFloaterWater::onExpFloatControlMoved, this, _1, ¶m_mgr->mFogDensity)); + getChild("WaterUnderWaterFogMod")->setCommitCallback(boost::bind(&LLFloaterWater::onFloatControlMoved, this, _1, ¶m_mgr->mUnderWaterFogMod)); // blue density - childSetCommitCallback("WaterNormalScaleX", onVector3ControlXMoved, ¶m_mgr->mNormalScale); - childSetCommitCallback("WaterNormalScaleY", onVector3ControlYMoved, ¶m_mgr->mNormalScale); - childSetCommitCallback("WaterNormalScaleZ", onVector3ControlZMoved, ¶m_mgr->mNormalScale); + getChild("WaterNormalScaleX")->setCommitCallback(boost::bind(&LLFloaterWater::onVector3ControlXMoved, this, _1, ¶m_mgr->mNormalScale)); + getChild("WaterNormalScaleY")->setCommitCallback(boost::bind(&LLFloaterWater::onVector3ControlYMoved, this, _1, ¶m_mgr->mNormalScale)); + getChild("WaterNormalScaleZ")->setCommitCallback(boost::bind(&LLFloaterWater::onVector3ControlZMoved, this, _1, ¶m_mgr->mNormalScale)); // fresnel - childSetCommitCallback("WaterFresnelScale", onFloatControlMoved, ¶m_mgr->mFresnelScale); - childSetCommitCallback("WaterFresnelOffset", onFloatControlMoved, ¶m_mgr->mFresnelOffset); + getChild("WaterFresnelScale")->setCommitCallback(boost::bind(&LLFloaterWater::onFloatControlMoved, this, _1, ¶m_mgr->mFresnelScale)); + getChild("WaterFresnelOffset")->setCommitCallback(boost::bind(&LLFloaterWater::onFloatControlMoved, this, _1, ¶m_mgr->mFresnelOffset)); // scale above/below - childSetCommitCallback("WaterScaleAbove", onFloatControlMoved, ¶m_mgr->mScaleAbove); - childSetCommitCallback("WaterScaleBelow", onFloatControlMoved, ¶m_mgr->mScaleBelow); + getChild("WaterScaleAbove")->setCommitCallback(boost::bind(&LLFloaterWater::onFloatControlMoved, this, _1, ¶m_mgr->mScaleAbove)); + getChild("WaterScaleBelow")->setCommitCallback(boost::bind(&LLFloaterWater::onFloatControlMoved, this, _1, ¶m_mgr->mScaleBelow)); // blur mult - childSetCommitCallback("WaterBlurMult", onFloatControlMoved, ¶m_mgr->mBlurMultiplier); + getChild("WaterBlurMult")->setCommitCallback(boost::bind(&LLFloaterWater::onFloatControlMoved, this, _1, ¶m_mgr->mBlurMultiplier)); // Load/save - LLComboBox* comboBox = getChild("WaterPresetsCombo"); - - //childSetAction("WaterLoadPreset", onLoadPreset, comboBox); - childSetAction("WaterNewPreset", onNewPreset, comboBox); - childSetAction("WaterSavePreset", onSavePreset, comboBox); - childSetAction("WaterDeletePreset", onDeletePreset, comboBox); +// getChild("WaterLoadPreset")->setCommitCallback(boost::bind(&LLFloaterWater::onLoadPreset, this)); + getChild("WaterNewPreset")->setCommitCallback(boost::bind(&LLFloaterWater::onNewPreset, this)); + getChild("WaterSavePreset")->setCommitCallback(boost::bind(&LLFloaterWater::onSavePreset, this)); + getChild("WaterDeletePreset")->setCommitCallback(boost::bind(&LLFloaterWater::onDeletePreset, this)); // wave direction - childSetCommitCallback("WaterWave1DirX", onVector2ControlXMoved, ¶m_mgr->mWave1Dir); - childSetCommitCallback("WaterWave1DirY", onVector2ControlYMoved, ¶m_mgr->mWave1Dir); - childSetCommitCallback("WaterWave2DirX", onVector2ControlXMoved, ¶m_mgr->mWave2Dir); - childSetCommitCallback("WaterWave2DirY", onVector2ControlYMoved, ¶m_mgr->mWave2Dir); + getChild("WaterWave1DirX")->setCommitCallback(boost::bind(&LLFloaterWater::onVector2ControlXMoved, this, _1, ¶m_mgr->mWave1Dir)); + getChild("WaterWave1DirY")->setCommitCallback(boost::bind(&LLFloaterWater::onVector2ControlYMoved, this, _1, ¶m_mgr->mWave1Dir)); + getChild("WaterWave2DirX")->setCommitCallback(boost::bind(&LLFloaterWater::onVector2ControlXMoved, this, _1, ¶m_mgr->mWave2Dir)); + getChild("WaterWave2DirY")->setCommitCallback(boost::bind(&LLFloaterWater::onVector2ControlYMoved, this, _1, ¶m_mgr->mWave2Dir)); - comboBox->setCommitCallback(boost::bind(&LLFloaterWater::onChangePresetName, this, _1)); + getChild("WaterPresetsCombo")->setCommitCallback(boost::bind(&LLFloaterWater::onChangePresetName, this, _1)); LLTextureCtrl* textCtrl = getChild("WaterNormalMap"); textCtrl->setDefaultImageAssetID(DEFAULT_WATER_NORMAL); - childSetCommitCallback("WaterNormalMap", onNormalMapPicked, NULL); + getChild("WaterNormalMap")->setCommitCallback(boost::bind(&LLFloaterWater::onNormalMapPicked, this, _1)); } -void LLFloaterWater::onClickHelp(void* data) +void LLFloaterWater::onClickHelp(std::string xml_alert) { - LLFloaterWater* self = LLFloaterWater::instance(); - - const std::string* xml_alert = (std::string*)data; - LLNotifications::instance().add(self->contextualNotification(*xml_alert)); + LLNotifications::instance().add(contextualNotification(xml_alert)); } void LLFloaterWater::initHelpBtn(const std::string& name, const std::string& xml_alert) { - childSetAction(name, onClickHelp, new std::string(xml_alert)); + getChild(name)->setClickedCallback(boost::bind(&LLFloaterWater::onClickHelp, this, xml_alert)); } bool LLFloaterWater::newPromptCallback(const LLSD& notification, const LLSD& response) @@ -201,7 +194,7 @@ bool LLFloaterWater::newPromptCallback(const LLSD& notification, const LLSD& res } if(option == 0) { - LLComboBox* comboBox = sWaterMenu->getChild( "WaterPresetsCombo"); + LLComboBox* comboBox = getChild( "WaterPresetsCombo"); LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); @@ -245,7 +238,7 @@ void LLFloaterWater::syncMenu() LLColor4 col = param_mgr->getFogColor(); childSetValue("WaterGlow", col.mV[3]); col.mV[3] = 1.0f; - LLColorSwatchCtrl* colCtrl = sWaterMenu->getChild("WaterFogColor"); + LLColorSwatchCtrl* colCtrl = getChild("WaterFogColor"); colCtrl->set(col); @@ -290,56 +283,15 @@ void LLFloaterWater::syncMenu() childSetValue("WaterWave2DirX", param_mgr->mWave2Dir.mX); childSetValue("WaterWave2DirY", param_mgr->mWave2Dir.mY); - LLTextureCtrl* textCtrl = sWaterMenu->getChild("WaterNormalMap"); + LLTextureCtrl* textCtrl = getChild("WaterNormalMap"); textCtrl->setImageAssetID(param_mgr->getNormalMapID()); } -// static -LLFloaterWater* LLFloaterWater::instance() -{ - if (!sWaterMenu) - { - sWaterMenu = new LLFloaterWater(); - sWaterMenu->openFloater(); - sWaterMenu->setFocus(TRUE); - } - return sWaterMenu; -} -void LLFloaterWater::show() -{ - LLFloaterWater* water = instance(); - water->syncMenu(); - - // comment in if you want the menu to rebuild each time - //LLUICtrlFactory::getInstance()->buildFloater(water, "floater_water.xml"); - //water->initCallbacks(); - - water->openFloater(); -} - -bool LLFloaterWater::isOpen() -{ - if (sWaterMenu != NULL) { - return true; - } - return false; -} - -// virtual -void LLFloaterWater::onClose(bool app_quitting) -{ - if (sWaterMenu) - { - sWaterMenu->setVisible(FALSE); - } -} - // vector control callbacks -void LLFloaterWater::onVector3ControlXMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onVector3ControlXMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WaterVector3Control * vectorControl = static_cast(userData); vectorControl->mX = sldrCtrl->getValueF32(); @@ -349,10 +301,9 @@ void LLFloaterWater::onVector3ControlXMoved(LLUICtrl* ctrl, void* userData) } // vector control callbacks -void LLFloaterWater::onVector3ControlYMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onVector3ControlYMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WaterVector3Control * vectorControl = static_cast(userData); vectorControl->mY = sldrCtrl->getValueF32(); @@ -362,10 +313,9 @@ void LLFloaterWater::onVector3ControlYMoved(LLUICtrl* ctrl, void* userData) } // vector control callbacks -void LLFloaterWater::onVector3ControlZMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onVector3ControlZMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WaterVector3Control * vectorControl = static_cast(userData); vectorControl->mZ = sldrCtrl->getValueF32(); @@ -376,10 +326,9 @@ void LLFloaterWater::onVector3ControlZMoved(LLUICtrl* ctrl, void* userData) // vector control callbacks -void LLFloaterWater::onVector2ControlXMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onVector2ControlXMoved(LLUICtrl* ctrl, WaterVector2Control* vectorControl) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WaterVector2Control * vectorControl = static_cast(userData); vectorControl->mX = sldrCtrl->getValueF32(); @@ -389,10 +338,9 @@ void LLFloaterWater::onVector2ControlXMoved(LLUICtrl* ctrl, void* userData) } // vector control callbacks -void LLFloaterWater::onVector2ControlYMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onVector2ControlYMoved(LLUICtrl* ctrl, WaterVector2Control* vectorControl) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WaterVector2Control * vectorControl = static_cast(userData); vectorControl->mY = sldrCtrl->getValueF32(); @@ -402,10 +350,9 @@ void LLFloaterWater::onVector2ControlYMoved(LLUICtrl* ctrl, void* userData) } // color control callbacks -void LLFloaterWater::onColorControlRMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onColorControlRMoved(LLUICtrl* ctrl, WaterColorControl* colorControl) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WaterColorControl * colorControl = static_cast(userData); colorControl->mR = sldrCtrl->getValueF32(); @@ -418,7 +365,7 @@ void LLFloaterWater::onColorControlRMoved(LLUICtrl* ctrl, void* userData) std::string name = colorControl->mSliderName; name.append("I"); - sWaterMenu->childSetValue(name, colorControl->mR); + childSetValue(name, colorControl->mR); } colorControl->update(LLWaterParamManager::instance()->mCurParams); @@ -426,10 +373,9 @@ void LLFloaterWater::onColorControlRMoved(LLUICtrl* ctrl, void* userData) LLWaterParamManager::instance()->propagateParameters(); } -void LLFloaterWater::onColorControlGMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onColorControlGMoved(LLUICtrl* ctrl, WaterColorControl* colorControl) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WaterColorControl * colorControl = static_cast(userData); colorControl->mG = sldrCtrl->getValueF32(); @@ -442,7 +388,7 @@ void LLFloaterWater::onColorControlGMoved(LLUICtrl* ctrl, void* userData) std::string name = colorControl->mSliderName; name.append("I"); - sWaterMenu->childSetValue(name, colorControl->mG); + childSetValue(name, colorControl->mG); } @@ -451,10 +397,9 @@ void LLFloaterWater::onColorControlGMoved(LLUICtrl* ctrl, void* userData) LLWaterParamManager::instance()->propagateParameters(); } -void LLFloaterWater::onColorControlBMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onColorControlBMoved(LLUICtrl* ctrl, WaterColorControl* colorControl) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WaterColorControl * colorControl = static_cast(userData); colorControl->mB = sldrCtrl->getValueF32(); @@ -467,7 +412,7 @@ void LLFloaterWater::onColorControlBMoved(LLUICtrl* ctrl, void* userData) std::string name = colorControl->mSliderName; name.append("I"); - sWaterMenu->childSetValue(name, colorControl->mB); + childSetValue(name, colorControl->mB); } colorControl->update(LLWaterParamManager::instance()->mCurParams); @@ -475,10 +420,9 @@ void LLFloaterWater::onColorControlBMoved(LLUICtrl* ctrl, void* userData) LLWaterParamManager::instance()->propagateParameters(); } -void LLFloaterWater::onColorControlAMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onColorControlAMoved(LLUICtrl* ctrl, WaterColorControl* colorControl) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WaterColorControl * colorControl = static_cast(userData); colorControl->mA = sldrCtrl->getValueF32(); @@ -488,10 +432,9 @@ void LLFloaterWater::onColorControlAMoved(LLUICtrl* ctrl, void* userData) } -void LLFloaterWater::onColorControlIMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onColorControlIMoved(LLUICtrl* ctrl, WaterColorControl* colorControl) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WaterColorControl * colorControl = static_cast(userData); colorControl->mI = sldrCtrl->getValueF32(); @@ -538,9 +481,9 @@ void LLFloaterWater::onColorControlIMoved(LLUICtrl* ctrl, void* userData) } // set the sliders to the new vals - sWaterMenu->childSetValue(rName, colorControl->mR); - sWaterMenu->childSetValue(gName, colorControl->mG); - sWaterMenu->childSetValue(bName, colorControl->mB); + childSetValue(rName, colorControl->mR); + childSetValue(gName, colorControl->mG); + childSetValue(bName, colorControl->mB); } // now update the current parameters and send them to shaders @@ -548,10 +491,9 @@ void LLFloaterWater::onColorControlIMoved(LLUICtrl* ctrl, void* userData) LLWaterParamManager::instance()->propagateParameters(); } -void LLFloaterWater::onExpFloatControlMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onExpFloatControlMoved(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WaterExpFloatControl * expFloatControl = static_cast(userData); F32 val = sldrCtrl->getValueF32(); expFloatControl->mExp = val; @@ -561,50 +503,40 @@ void LLFloaterWater::onExpFloatControlMoved(LLUICtrl* ctrl, void* userData) LLWaterParamManager::instance()->propagateParameters(); } -void LLFloaterWater::onFloatControlMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onFloatControlMoved(LLUICtrl* ctrl, WaterFloatControl* floatControl) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WaterFloatControl * floatControl = static_cast(userData); floatControl->mX = sldrCtrl->getValueF32() / floatControl->mMult; floatControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } -void LLFloaterWater::onWaterFogColorMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onWaterFogColorMoved(LLUICtrl* ctrl, WaterColorControl* colorControl) { LLColorSwatchCtrl* swatch = static_cast(ctrl); - WaterColorControl * colorControl = static_cast(userData); *colorControl = swatch->get(); colorControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } -void LLFloaterWater::onBoolToggle(LLUICtrl* ctrl, void* userData) -{ - LLCheckBoxCtrl* cbCtrl = static_cast(ctrl); - - bool value = cbCtrl->get(); - (*(static_cast(userData))) = value; -} - -void LLFloaterWater::onNormalMapPicked(LLUICtrl* ctrl, void* userData) +void LLFloaterWater::onNormalMapPicked(LLUICtrl* ctrl) { LLTextureCtrl* textCtrl = static_cast(ctrl); LLUUID textID = textCtrl->getImageAssetID(); LLWaterParamManager::instance()->setNormalMapID(textID); } -void LLFloaterWater::onNewPreset(void* userData) +void LLFloaterWater::onNewPreset() { - LLNotifications::instance().add("NewWaterPreset", LLSD(), LLSD(), newPromptCallback); + LLNotifications::instance().add("NewWaterPreset", LLSD(), LLSD(), boost::bind(&LLFloaterWater::newPromptCallback, this, _1, _2)); } -void LLFloaterWater::onSavePreset(void* userData) +void LLFloaterWater::onSavePreset() { // get the name - LLComboBox* comboBox = sWaterMenu->getChild("WaterPresetsCombo"); + LLComboBox* comboBox = getChild("WaterPresetsCombo"); // don't save the empty name if(comboBox->getSelectedItemLabel() == "") @@ -624,7 +556,7 @@ void LLFloaterWater::onSavePreset(void* userData) return; } - LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback); + LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterWater::saveAlertCallback, this, _1, _2)); } bool LLFloaterWater::saveAlertCallback(const LLSD& notification, const LLSD& response) @@ -645,9 +577,9 @@ bool LLFloaterWater::saveAlertCallback(const LLSD& notification, const LLSD& res return false; } -void LLFloaterWater::onDeletePreset(void* userData) +void LLFloaterWater::onDeletePreset() { - LLComboBox* combo_box = sWaterMenu->getChild("WaterPresetsCombo"); + LLComboBox* combo_box = getChild("WaterPresetsCombo"); if(combo_box->getSelectedValue().asString() == "") { @@ -656,7 +588,7 @@ void LLFloaterWater::onDeletePreset(void* userData) LLSD args; args["SKY"] = combo_box->getSelectedValue().asString(); - LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(), deleteAlertCallback); + LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(), boost::bind(&LLFloaterWater::deleteAlertCallback, this, _1, _2)); } bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& response) @@ -665,14 +597,13 @@ bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& r // if they choose delete, do it. Otherwise, don't do anything if(option == 0) { - LLComboBox* combo_box = sWaterMenu->getChild("WaterPresetsCombo"); - LLFloaterDayCycle* day_cycle = NULL; + LLComboBox* combo_box = getChild("WaterPresetsCombo"); + LLFloaterDayCycle* day_cycle = LLFloaterReg::findTypedInstance("env_day_cycle"); LLComboBox* key_combo = NULL; LLMultiSliderCtrl* mult_sldr = NULL; - if(LLFloaterDayCycle::isOpen()) + if (day_cycle) { - day_cycle = LLFloaterDayCycle::instance(); key_combo = day_cycle->getChild("WaterKeyPresets"); mult_sldr = day_cycle->getChild("WaterDayCycleKeys"); } @@ -723,7 +654,7 @@ void LLFloaterWater::onChangePresetName(LLUICtrl* ctrl) if(!data.empty()) { LLWaterParamManager::instance()->loadPreset(data); - sWaterMenu->syncMenu(); + syncMenu(); } } diff --git a/indra/newview/llfloaterwater.h b/indra/newview/llfloaterwater.h index 50fd7dd450..08c630c69e 100644 --- a/indra/newview/llfloaterwater.h +++ b/indra/newview/llfloaterwater.h @@ -42,91 +42,74 @@ #include #include "llwlparamset.h" +struct WaterVector2Control; +struct WaterVector3Control; struct WaterColorControl; -struct WaterloatControl; - +struct WaterFloatControl; +struct WaterExpFloatControl; /// Menuing system for all of windlight's functionality class LLFloaterWater : public LLFloater { public: - LLFloaterWater(); + LLFloaterWater(const LLSD& key); virtual ~LLFloaterWater(); /*virtual*/ BOOL postBuild(); /// initialize all void initCallbacks(void); - /// one and one instance only - static LLFloaterWater* instance(); - // help button stuff - static void onClickHelp(void* data); + void onClickHelp(std::string xml_alert); void initHelpBtn(const std::string& name, const std::string& xml_alert); - static bool newPromptCallback(const LLSD& notification, const LLSD& response); + bool newPromptCallback(const LLSD& notification, const LLSD& response); /// general purpose callbacks for dealing with color controllers - static void onColorControlRMoved(LLUICtrl* ctrl, void* userData); - static void onColorControlGMoved(LLUICtrl* ctrl, void* userData); - static void onColorControlBMoved(LLUICtrl* ctrl, void* userData); - static void onColorControlAMoved(LLUICtrl* ctrl, void* userData); - static void onColorControlIMoved(LLUICtrl* ctrl, void* userData); + void onColorControlRMoved(LLUICtrl* ctrl, WaterColorControl* colorControl); + void onColorControlGMoved(LLUICtrl* ctrl, WaterColorControl* colorControl); + void onColorControlBMoved(LLUICtrl* ctrl, WaterColorControl* colorControl); + void onColorControlAMoved(LLUICtrl* ctrl, WaterColorControl* colorControl); + void onColorControlIMoved(LLUICtrl* ctrl, WaterColorControl* colorControl); - static void onVector3ControlXMoved(LLUICtrl* ctrl, void* userData); - static void onVector3ControlYMoved(LLUICtrl* ctrl, void* userData); - static void onVector3ControlZMoved(LLUICtrl* ctrl, void* userData); + void onVector3ControlXMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl); + void onVector3ControlYMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl); + void onVector3ControlZMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl); - static void onVector2ControlXMoved(LLUICtrl* ctrl, void* userData); - static void onVector2ControlYMoved(LLUICtrl* ctrl, void* userData); + void onVector2ControlXMoved(LLUICtrl* ctrl, WaterVector2Control* vectorControl); + void onVector2ControlYMoved(LLUICtrl* ctrl, WaterVector2Control* vectorControl); + + void onFloatControlMoved(LLUICtrl* ctrl, WaterFloatControl* floatControl); - static void onFloatControlMoved(LLUICtrl* ctrl, void* userData); + void onExpFloatControlMoved(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl); - static void onExpFloatControlMoved(LLUICtrl* ctrl, void* userData); - - static void onWaterFogColorMoved(LLUICtrl* ctrl, void* userData); - - static void onBoolToggle(LLUICtrl* ctrl, void* userData); + void onWaterFogColorMoved(LLUICtrl* ctrl, WaterColorControl* colorControl); /// handle if they choose a new normal map - static void onNormalMapPicked(LLUICtrl* ctrl, void* userData); + void onNormalMapPicked(LLUICtrl* ctrl); /// when user hits the load preset button - static void onNewPreset(void* userData); + void onNewPreset(); /// when user hits the save preset button - static void onSavePreset(void* userData); + void onSavePreset(); /// prompts a user when overwriting a preset - static bool saveAlertCallback(const LLSD& notification, const LLSD& response); + bool saveAlertCallback(const LLSD& notification, const LLSD& response); /// when user hits the save preset button - static void onDeletePreset(void* userData); + void onDeletePreset(); /// prompts a user when overwriting a preset - static bool deleteAlertCallback(const LLSD& notification, const LLSD& response); + bool deleteAlertCallback(const LLSD& notification, const LLSD& response); /// what to do when you change the preset name void onChangePresetName(LLUICtrl* ctrl); - //// menu management - - /// show off our menu - static void show(); - - /// return if the menu exists or not - static bool isOpen(); - - /// stuff to do on exit - virtual void onClose(bool app_quitting); - /// sync up sliders with parameters void syncMenu(); private: - // one instance on the inside - static LLFloaterWater* sWaterMenu; - static std::set sDefaultPresets; }; diff --git a/indra/newview/llfloaterwindlight.cpp b/indra/newview/llfloaterwindlight.cpp index 2ba4002d94..18745284cb 100644 --- a/indra/newview/llfloaterwindlight.cpp +++ b/indra/newview/llfloaterwindlight.cpp @@ -37,6 +37,7 @@ #include "pipeline.h" #include "llsky.h" +#include "llfloaterreg.h" #include "llsliderctrl.h" #include "llmultislider.h" #include "llmultisliderctrl.h" @@ -61,19 +62,22 @@ #undef max -LLFloaterWindLight* LLFloaterWindLight::sWindLight = NULL; - std::set LLFloaterWindLight::sDefaultPresets; static const F32 WL_SUN_AMBIENT_SLIDER_SCALE = 3.0f; -LLFloaterWindLight::LLFloaterWindLight() - : LLFloater() +LLFloaterWindLight::LLFloaterWindLight(const LLSD& key) + : LLFloater(key) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_windlight_options.xml"); - + //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_windlight_options.xml"); +} +LLFloaterWindLight::~LLFloaterWindLight() +{ +} +BOOL LLFloaterWindLight::postBuild() +{ // add the list of presets std::string def_days = getString("WLDefaultSkyNames"); @@ -85,13 +89,7 @@ LLFloaterWindLight::LLFloaterWindLight() std::string tok(*token_iter); sDefaultPresets.insert(tok); } -} -LLFloaterWindLight::~LLFloaterWindLight() -{ -} -BOOL LLFloaterWindLight::postBuild() -{ // add the combo boxes LLComboBox* comboBox = getChild("WLPresetsCombo"); @@ -112,6 +110,9 @@ BOOL LLFloaterWindLight::postBuild() } // load it up initCallbacks(); + + syncMenu(); + return TRUE; } void LLFloaterWindLight::initCallbacks(void) { @@ -149,102 +150,99 @@ void LLFloaterWindLight::initCallbacks(void) { LLWLParamManager * param_mgr = LLWLParamManager::instance(); // blue horizon - childSetCommitCallback("WLBlueHorizonR", onColorControlRMoved, ¶m_mgr->mBlueHorizon); - childSetCommitCallback("WLBlueHorizonG", onColorControlGMoved, ¶m_mgr->mBlueHorizon); - childSetCommitCallback("WLBlueHorizonB", onColorControlBMoved, ¶m_mgr->mBlueHorizon); - childSetCommitCallback("WLBlueHorizonI", onColorControlIMoved, ¶m_mgr->mBlueHorizon); + getChild("WLBlueHorizonR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mBlueHorizon)); + getChild("WLBlueHorizonG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mBlueHorizon)); + getChild("WLBlueHorizonB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mBlueHorizon)); + getChild("WLBlueHorizonI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, ¶m_mgr->mBlueHorizon)); // haze density, horizon, mult, and altitude - childSetCommitCallback("WLHazeDensity", onColorControlRMoved, ¶m_mgr->mHazeDensity); - childSetCommitCallback("WLHazeHorizon", onColorControlRMoved, ¶m_mgr->mHazeHorizon); - childSetCommitCallback("WLDensityMult", onFloatControlMoved, ¶m_mgr->mDensityMult); - childSetCommitCallback("WLMaxAltitude", onFloatControlMoved, ¶m_mgr->mMaxAlt); + getChild("WLHazeDensity")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mHazeDensity)); + getChild("WLHazeHorizon")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mHazeHorizon)); + getChild("WLDensityMult")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, ¶m_mgr->mDensityMult)); + getChild("WLMaxAltitude")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, ¶m_mgr->mMaxAlt)); // blue density - childSetCommitCallback("WLBlueDensityR", onColorControlRMoved, ¶m_mgr->mBlueDensity); - childSetCommitCallback("WLBlueDensityG", onColorControlGMoved, ¶m_mgr->mBlueDensity); - childSetCommitCallback("WLBlueDensityB", onColorControlBMoved, ¶m_mgr->mBlueDensity); - childSetCommitCallback("WLBlueDensityI", onColorControlIMoved, ¶m_mgr->mBlueDensity); + getChild("WLBlueDensityR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mBlueDensity)); + getChild("WLBlueDensityG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mBlueDensity)); + getChild("WLBlueDensityB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mBlueDensity)); + getChild("WLBlueDensityI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, ¶m_mgr->mBlueDensity)); // Lighting // sunlight - childSetCommitCallback("WLSunlightR", onColorControlRMoved, ¶m_mgr->mSunlight); - childSetCommitCallback("WLSunlightG", onColorControlGMoved, ¶m_mgr->mSunlight); - childSetCommitCallback("WLSunlightB", onColorControlBMoved, ¶m_mgr->mSunlight); - childSetCommitCallback("WLSunlightI", onColorControlIMoved, ¶m_mgr->mSunlight); + getChild("WLSunlightR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mSunlight)); + getChild("WLSunlightG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mSunlight)); + getChild("WLSunlightB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mSunlight)); + getChild("WLSunlightI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, ¶m_mgr->mSunlight)); // glow - childSetCommitCallback("WLGlowR", onGlowRMoved, ¶m_mgr->mGlow); - childSetCommitCallback("WLGlowB", onGlowBMoved, ¶m_mgr->mGlow); + getChild("WLGlowR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onGlowRMoved, this, _1, ¶m_mgr->mGlow)); + getChild("WLGlowB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onGlowBMoved, this, _1, ¶m_mgr->mGlow)); // ambient - childSetCommitCallback("WLAmbientR", onColorControlRMoved, ¶m_mgr->mAmbient); - childSetCommitCallback("WLAmbientG", onColorControlGMoved, ¶m_mgr->mAmbient); - childSetCommitCallback("WLAmbientB", onColorControlBMoved, ¶m_mgr->mAmbient); - childSetCommitCallback("WLAmbientI", onColorControlIMoved, ¶m_mgr->mAmbient); + getChild("WLAmbientR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mAmbient)); + getChild("WLAmbientG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mAmbient)); + getChild("WLAmbientB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mAmbient)); + getChild("WLAmbientI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, ¶m_mgr->mAmbient)); // time of day - childSetCommitCallback("WLSunAngle", onSunMoved, ¶m_mgr->mLightnorm); - childSetCommitCallback("WLEastAngle", onSunMoved, ¶m_mgr->mLightnorm); + getChild("WLSunAngle")->setCommitCallback(boost::bind(&LLFloaterWindLight::onSunMoved, this, _1, ¶m_mgr->mLightnorm)); + getChild("WLEastAngle")->setCommitCallback(boost::bind(&LLFloaterWindLight::onSunMoved, this, _1, ¶m_mgr->mLightnorm)); // Clouds // Cloud Color - childSetCommitCallback("WLCloudColorR", onColorControlRMoved, ¶m_mgr->mCloudColor); - childSetCommitCallback("WLCloudColorG", onColorControlGMoved, ¶m_mgr->mCloudColor); - childSetCommitCallback("WLCloudColorB", onColorControlBMoved, ¶m_mgr->mCloudColor); - childSetCommitCallback("WLCloudColorI", onColorControlIMoved, ¶m_mgr->mCloudColor); + getChild("WLCloudColorR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mCloudColor)); + getChild("WLCloudColorG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mCloudColor)); + getChild("WLCloudColorB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mCloudColor)); + getChild("WLCloudColorI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, ¶m_mgr->mCloudColor)); // Cloud - childSetCommitCallback("WLCloudX", onColorControlRMoved, ¶m_mgr->mCloudMain); - childSetCommitCallback("WLCloudY", onColorControlGMoved, ¶m_mgr->mCloudMain); - childSetCommitCallback("WLCloudDensity", onColorControlBMoved, ¶m_mgr->mCloudMain); + getChild("WLCloudX")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mCloudMain)); + getChild("WLCloudY")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mCloudMain)); + getChild("WLCloudDensity")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mCloudMain)); // Cloud Detail - childSetCommitCallback("WLCloudDetailX", onColorControlRMoved, ¶m_mgr->mCloudDetail); - childSetCommitCallback("WLCloudDetailY", onColorControlGMoved, ¶m_mgr->mCloudDetail); - childSetCommitCallback("WLCloudDetailDensity", onColorControlBMoved, ¶m_mgr->mCloudDetail); + getChild("WLCloudDetailX")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, ¶m_mgr->mCloudDetail)); + getChild("WLCloudDetailY")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, ¶m_mgr->mCloudDetail)); + getChild("WLCloudDetailDensity")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, ¶m_mgr->mCloudDetail)); // Cloud extras - childSetCommitCallback("WLCloudCoverage", onFloatControlMoved, ¶m_mgr->mCloudCoverage); - childSetCommitCallback("WLCloudScale", onFloatControlMoved, ¶m_mgr->mCloudScale); - childSetCommitCallback("WLCloudLockX", onCloudScrollXToggled, NULL); - childSetCommitCallback("WLCloudLockY", onCloudScrollYToggled, NULL); - childSetCommitCallback("WLCloudScrollX", onCloudScrollXMoved, NULL); - childSetCommitCallback("WLCloudScrollY", onCloudScrollYMoved, NULL); - childSetCommitCallback("WLDistanceMult", onFloatControlMoved, ¶m_mgr->mDistanceMult); + getChild("WLCloudCoverage")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, ¶m_mgr->mCloudCoverage)); + getChild("WLCloudScale")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, ¶m_mgr->mCloudScale)); + getChild("WLCloudLockX")->setCommitCallback(boost::bind(&LLFloaterWindLight::onCloudScrollXToggled, this, _1)); + getChild("WLCloudLockY")->setCommitCallback(boost::bind(&LLFloaterWindLight::onCloudScrollYToggled, this, _1)); + getChild("WLCloudScrollX")->setCommitCallback(boost::bind(&LLFloaterWindLight::onCloudScrollXMoved, this, _1)); + getChild("WLCloudScrollY")->setCommitCallback(boost::bind(&LLFloaterWindLight::onCloudScrollYMoved, this, _1)); + getChild("WLDistanceMult")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, ¶m_mgr->mDistanceMult)); getChild("DrawClassicClouds")->setCommitCallback(boost::bind(LLSavedSettingsGlue::setBOOL, _1, "SkyUseClassicClouds")); // WL Top - childSetAction("WLDayCycleMenuButton", onOpenDayCycle, NULL); + getChild("WLDayCycleMenuButton")->setCommitCallback(boost::bind(&LLFloaterWindLight::onOpenDayCycle, this)); // Load/save LLComboBox* comboBox = getChild("WLPresetsCombo"); //childSetAction("WLLoadPreset", onLoadPreset, comboBox); - childSetAction("WLNewPreset", onNewPreset, comboBox); - childSetAction("WLSavePreset", onSavePreset, comboBox); - childSetAction("WLDeletePreset", onDeletePreset, comboBox); + getChild("WLNewPreset")->setCommitCallback(boost::bind(&LLFloaterWindLight::onNewPreset, this)); + getChild("WLSavePreset")->setCommitCallback(boost::bind(&LLFloaterWindLight::onSavePreset, this)); + getChild("WLDeletePreset")->setCommitCallback(boost::bind(&LLFloaterWindLight::onDeletePreset, this)); comboBox->setCommitCallback(boost::bind(&LLFloaterWindLight::onChangePresetName, this, _1)); // Dome - childSetCommitCallback("WLGamma", onFloatControlMoved, ¶m_mgr->mWLGamma); - childSetCommitCallback("WLStarAlpha", onStarAlphaMoved, NULL); + getChild("WLGamma")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, ¶m_mgr->mWLGamma)); + getChild("WLStarAlpha")->setCommitCallback(boost::bind(&LLFloaterWindLight::onStarAlphaMoved, this, _1)); } -void LLFloaterWindLight::onClickHelp(void* data) +void LLFloaterWindLight::onClickHelp(std::string xml_alert) { - LLFloaterWindLight* self = LLFloaterWindLight::instance(); - - const std::string xml_alert = *(std::string*)data; - LLNotifications::instance().add(self->contextualNotification(xml_alert)); + LLNotifications::instance().add(contextualNotification(xml_alert)); } void LLFloaterWindLight::initHelpBtn(const std::string& name, const std::string& xml_alert) { - childSetAction(name, onClickHelp, new std::string(xml_alert)); + getChild(name)->setClickedCallback(boost::bind(&LLFloaterWindLight::onClickHelp, this, xml_alert)); } bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD& response) @@ -258,16 +256,13 @@ bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD& } if(option == 0) { - LLComboBox* comboBox = sWindLight->getChild( - "WLPresetsCombo"); + LLComboBox* comboBox = getChild("WLPresetsCombo"); - LLFloaterDayCycle* sDayCycle = NULL; + LLFloaterDayCycle* day_cycle = LLFloaterReg::findTypedInstance("env_day_cycle"); LLComboBox* keyCombo = NULL; - if(LLFloaterDayCycle::isOpen()) + if(day_cycle) { - sDayCycle = LLFloaterDayCycle::instance(); - keyCombo = sDayCycle->getChild( - "WLKeyPresets"); + keyCombo = day_cycle->getChild("WLKeyPresets"); } // add the current parameters to the list @@ -292,7 +287,7 @@ bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD& comboBox->add(LLStringUtil::null); comboBox->setSelectedByValue(text, true); - if(LLFloaterDayCycle::isOpen()) + if(keyCombo) { keyCombo->add(text); keyCombo->sortByName(); @@ -442,53 +437,12 @@ void LLFloaterWindLight::syncMenu() } -// static -LLFloaterWindLight* LLFloaterWindLight::instance() -{ - if (!sWindLight) - { - sWindLight = new LLFloaterWindLight(); - sWindLight->openFloater(); - sWindLight->setFocus(TRUE); - } - return sWindLight; -} -void LLFloaterWindLight::show() -{ - LLFloaterWindLight* windLight = instance(); - windLight->syncMenu(); - - // comment in if you want the menu to rebuild each time - //LLUICtrlFactory::getInstance()->buildFloater(windLight, "floater_windlight_options.xml"); - //windLight->initCallbacks(); - - windLight->openFloater(); -} - -bool LLFloaterWindLight::isOpen() -{ - if (sWindLight != NULL) { - return true; - } - return false; -} - -// virtual -void LLFloaterWindLight::onClose(bool app_quitting) -{ - if (sWindLight) - { - sWindLight->setVisible(FALSE); - } -} - // color control callbacks -void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, WLColorControl* colorControl) { deactivateAnimator(); LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WLColorControl * colorControl = static_cast(userData); colorControl->r = sldrCtrl->getValueF32(); if(colorControl->isSunOrAmbientColor) { @@ -506,11 +460,11 @@ void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, void* userData) name.append("I"); if(colorControl->isSunOrAmbientColor) { - sWindLight->childSetValue(name, colorControl->r / 3); + childSetValue(name, colorControl->r / 3); } else if(colorControl->isBlueHorizonOrDensity) { - sWindLight->childSetValue(name, colorControl->r / 2); + childSetValue(name, colorControl->r / 2); } else { - sWindLight->childSetValue(name, colorControl->r); + childSetValue(name, colorControl->r); } } @@ -519,12 +473,11 @@ void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, void* userData) LLWLParamManager::instance()->propagateParameters(); } -void LLFloaterWindLight::onColorControlGMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onColorControlGMoved(LLUICtrl* ctrl, WLColorControl* colorControl) { deactivateAnimator(); LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WLColorControl * colorControl = static_cast(userData); colorControl->g = sldrCtrl->getValueF32(); if(colorControl->isSunOrAmbientColor) { @@ -542,11 +495,11 @@ void LLFloaterWindLight::onColorControlGMoved(LLUICtrl* ctrl, void* userData) name.append("I"); if(colorControl->isSunOrAmbientColor) { - sWindLight->childSetValue(name, colorControl->g / 3); + childSetValue(name, colorControl->g / 3); } else if(colorControl->isBlueHorizonOrDensity) { - sWindLight->childSetValue(name, colorControl->g / 2); + childSetValue(name, colorControl->g / 2); } else { - sWindLight->childSetValue(name, colorControl->g); + childSetValue(name, colorControl->g); } } @@ -555,12 +508,11 @@ void LLFloaterWindLight::onColorControlGMoved(LLUICtrl* ctrl, void* userData) LLWLParamManager::instance()->propagateParameters(); } -void LLFloaterWindLight::onColorControlBMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onColorControlBMoved(LLUICtrl* ctrl, WLColorControl* colorControl) { deactivateAnimator(); LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WLColorControl * colorControl = static_cast(userData); colorControl->b = sldrCtrl->getValueF32(); if(colorControl->isSunOrAmbientColor) { @@ -578,11 +530,11 @@ void LLFloaterWindLight::onColorControlBMoved(LLUICtrl* ctrl, void* userData) name.append("I"); if(colorControl->isSunOrAmbientColor) { - sWindLight->childSetValue(name, colorControl->b / 3); + childSetValue(name, colorControl->b / 3); } else if(colorControl->isBlueHorizonOrDensity) { - sWindLight->childSetValue(name, colorControl->b / 2); + childSetValue(name, colorControl->b / 2); } else { - sWindLight->childSetValue(name, colorControl->b); + childSetValue(name, colorControl->b); } } @@ -591,12 +543,11 @@ void LLFloaterWindLight::onColorControlBMoved(LLUICtrl* ctrl, void* userData) LLWLParamManager::instance()->propagateParameters(); } -void LLFloaterWindLight::onColorControlIMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onColorControlIMoved(LLUICtrl* ctrl, WLColorControl* colorControl) { deactivateAnimator(); LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WLColorControl * colorControl = static_cast(userData); colorControl->i = sldrCtrl->getValueF32(); @@ -653,24 +604,24 @@ void LLFloaterWindLight::onColorControlIMoved(LLUICtrl* ctrl, void* userData) // divide sun color vals by three if(colorControl->isSunOrAmbientColor) { - sWindLight->childSetValue(rName, colorControl->r/3); - sWindLight->childSetValue(gName, colorControl->g/3); - sWindLight->childSetValue(bName, colorControl->b/3); + childSetValue(rName, colorControl->r/3); + childSetValue(gName, colorControl->g/3); + childSetValue(bName, colorControl->b/3); } else if(colorControl->isBlueHorizonOrDensity) { - sWindLight->childSetValue(rName, colorControl->r/2); - sWindLight->childSetValue(gName, colorControl->g/2); - sWindLight->childSetValue(bName, colorControl->b/2); + childSetValue(rName, colorControl->r/2); + childSetValue(gName, colorControl->g/2); + childSetValue(bName, colorControl->b/2); } else { // set the sliders to the new vals - sWindLight->childSetValue(rName, colorControl->r); - sWindLight->childSetValue(gName, colorControl->g); - sWindLight->childSetValue(bName, colorControl->b); + childSetValue(rName, colorControl->r); + childSetValue(gName, colorControl->g); + childSetValue(bName, colorControl->b); } } @@ -680,12 +631,11 @@ void LLFloaterWindLight::onColorControlIMoved(LLUICtrl* ctrl, void* userData) } /// GLOW SPECIFIC CODE -void LLFloaterWindLight::onGlowRMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onGlowRMoved(LLUICtrl* ctrl, WLColorControl* colorControl) { deactivateAnimator(); LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WLColorControl * colorControl = static_cast(userData); // scaled by 20 colorControl->r = (2 - sldrCtrl->getValueF32()) * 20; @@ -695,12 +645,11 @@ void LLFloaterWindLight::onGlowRMoved(LLUICtrl* ctrl, void* userData) } /// \NOTE that we want NEGATIVE (-) B -void LLFloaterWindLight::onGlowBMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onGlowBMoved(LLUICtrl* ctrl, WLColorControl* colorControl) { deactivateAnimator(); LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WLColorControl * colorControl = static_cast(userData); /// \NOTE that we want NEGATIVE (-) B and NOT by 20 as 20 is too big colorControl->b = -sldrCtrl->getValueF32() * 5; @@ -709,12 +658,11 @@ void LLFloaterWindLight::onGlowBMoved(LLUICtrl* ctrl, void* userData) LLWLParamManager::instance()->propagateParameters(); } -void LLFloaterWindLight::onFloatControlMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onFloatControlMoved(LLUICtrl* ctrl, WLFloatControl* floatControl) { deactivateAnimator(); LLSliderCtrl* sldrCtrl = static_cast(ctrl); - WLFloatControl * floatControl = static_cast(userData); floatControl->x = sldrCtrl->getValueF32() / floatControl->mult; @@ -722,29 +670,16 @@ void LLFloaterWindLight::onFloatControlMoved(LLUICtrl* ctrl, void* userData) LLWLParamManager::instance()->propagateParameters(); } -void LLFloaterWindLight::onBoolToggle(LLUICtrl* ctrl, void* userData) -{ - deactivateAnimator(); - - LLCheckBoxCtrl* cbCtrl = static_cast(ctrl); - - bool value = cbCtrl->get(); - (*(static_cast(userData))) = value; -} - - // Lighting callbacks // time of day -void LLFloaterWindLight::onSunMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onSunMoved(LLUICtrl* ctrl, WLColorControl* colorControl) { deactivateAnimator(); - LLSliderCtrl* sunSldr = sWindLight->getChild("WLSunAngle"); - LLSliderCtrl* eastSldr = sWindLight->getChild("WLEastAngle"); + LLSliderCtrl* sunSldr = getChild("WLSunAngle"); + LLSliderCtrl* eastSldr = getChild("WLEastAngle"); - WLColorControl * colorControl = static_cast(userData); - // get the two angles LLWLParamManager * param_mgr = LLWLParamManager::instance(); @@ -763,18 +698,7 @@ void LLFloaterWindLight::onSunMoved(LLUICtrl* ctrl, void* userData) param_mgr->propagateParameters(); } -void LLFloaterWindLight::onFloatTweakMoved(LLUICtrl* ctrl, void* userData) -{ - deactivateAnimator(); - - LLSliderCtrl* sldrCtrl = static_cast(ctrl); - F32 * tweak = static_cast(userData); - - (*tweak) = sldrCtrl->getValueF32(); - LLWLParamManager::instance()->propagateParameters(); -} - -void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl) { deactivateAnimator(); @@ -783,15 +707,15 @@ void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl, void* userData) LLWLParamManager::instance()->mCurParams.setStarBrightness(sldrCtrl->getValueF32()); } -void LLFloaterWindLight::onNewPreset(void* userData) +void LLFloaterWindLight::onNewPreset() { - LLNotifications::instance().add("NewSkyPreset", LLSD(), LLSD(), newPromptCallback); + LLNotifications::instance().add("NewSkyPreset", LLSD(), LLSD(), boost::bind(&LLFloaterWindLight::newPromptCallback, this, _1, _2)); } -void LLFloaterWindLight::onSavePreset(void* userData) +void LLFloaterWindLight::onSavePreset() { // get the name - LLComboBox* comboBox = sWindLight->getChild( + LLComboBox* comboBox = getChild( "WLPresetsCombo"); // don't save the empty name @@ -812,7 +736,7 @@ void LLFloaterWindLight::onSavePreset(void* userData) LLWLParamManager::instance()->mCurParams.mName = comboBox->getSelectedItemLabel(); - LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback); + LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterWindLight::saveAlertCallback, this, _1, _2)); } bool LLFloaterWindLight::saveAlertCallback(const LLSD& notification, const LLSD& response) @@ -831,9 +755,9 @@ bool LLFloaterWindLight::saveAlertCallback(const LLSD& notification, const LLSD& return false; } -void LLFloaterWindLight::onDeletePreset(void* userData) +void LLFloaterWindLight::onDeletePreset() { - LLComboBox* combo_box = sWindLight->getChild( + LLComboBox* combo_box = getChild( "WLPresetsCombo"); if(combo_box->getSelectedValue().asString() == "") @@ -844,7 +768,7 @@ void LLFloaterWindLight::onDeletePreset(void* userData) LLSD args; args["SKY"] = combo_box->getSelectedValue().asString(); LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(), - boost::bind(&LLFloaterWindLight::deleteAlertCallback, sWindLight, _1, _2)); + boost::bind(&LLFloaterWindLight::deleteAlertCallback, this, _1, _2)); } bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLSD& response) @@ -854,17 +778,14 @@ bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLS // if they choose delete, do it. Otherwise, don't do anything if(option == 0) { - LLComboBox* combo_box = getChild( - "WLPresetsCombo"); - LLFloaterDayCycle* day_cycle = NULL; + LLComboBox* combo_box = getChild("WLPresetsCombo"); + LLFloaterDayCycle* day_cycle = LLFloaterReg::findTypedInstance("env_day_cycle"); LLComboBox* key_combo = NULL; LLMultiSliderCtrl* mult_sldr = NULL; - if(LLFloaterDayCycle::isOpen()) + if (day_cycle) { - day_cycle = LLFloaterDayCycle::instance(); - key_combo = day_cycle->getChild( - "WLKeyPresets"); + key_combo = day_cycle->getChild("WLKeyPresets"); mult_sldr = day_cycle->getChild("WLDayCycleKeys"); } @@ -915,17 +836,17 @@ void LLFloaterWindLight::onChangePresetName(LLUICtrl* ctrl) if(!data.empty()) { LLWLParamManager::instance()->loadPreset( data); - sWindLight->syncMenu(); + syncMenu(); } } -void LLFloaterWindLight::onOpenDayCycle(void* userData) +void LLFloaterWindLight::onOpenDayCycle() { - LLFloaterDayCycle::show(); + LLFloaterReg::showInstance("env_day_cycle"); } // Clouds -void LLFloaterWindLight::onCloudScrollXMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onCloudScrollXMoved(LLUICtrl* ctrl) { deactivateAnimator(); @@ -934,7 +855,7 @@ void LLFloaterWindLight::onCloudScrollXMoved(LLUICtrl* ctrl, void* userData) LLWLParamManager::instance()->mCurParams.setCloudScrollX(sldrCtrl->getValueF32() + 10.0f); } -void LLFloaterWindLight::onCloudScrollYMoved(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onCloudScrollYMoved(LLUICtrl* ctrl) { deactivateAnimator(); @@ -944,7 +865,7 @@ void LLFloaterWindLight::onCloudScrollYMoved(LLUICtrl* ctrl, void* userData) LLWLParamManager::instance()->mCurParams.setCloudScrollY(sldrCtrl->getValueF32() + 10.0f); } -void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl) { deactivateAnimator(); @@ -953,7 +874,7 @@ void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl, void* userData) bool lock = cbCtrl->get(); LLWLParamManager::instance()->mCurParams.setEnableCloudScrollX(!lock); - LLSliderCtrl* sldr = sWindLight->getChild( + LLSliderCtrl* sldr = getChild( "WLCloudScrollX"); if(cbCtrl->get()) @@ -967,7 +888,7 @@ void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl, void* userData) } -void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl, void* userData) +void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl) { deactivateAnimator(); @@ -975,7 +896,7 @@ void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl, void* userData) bool lock = cbCtrl->get(); LLWLParamManager::instance()->mCurParams.setEnableCloudScrollY(!lock); - LLSliderCtrl* sldr = sWindLight->getChild( + LLSliderCtrl* sldr = getChild( "WLCloudScrollY"); if(cbCtrl->get()) diff --git a/indra/newview/llfloaterwindlight.h b/indra/newview/llfloaterwindlight.h index e527a5637c..56c2c6623b 100644 --- a/indra/newview/llfloaterwindlight.h +++ b/indra/newview/llfloaterwindlight.h @@ -51,54 +51,47 @@ class LLFloaterWindLight : public LLFloater { public: - LLFloaterWindLight(); + LLFloaterWindLight(const LLSD& key); virtual ~LLFloaterWindLight(); /*virtual*/ BOOL postBuild(); /// initialize all void initCallbacks(void); - /// one and one instance only - static LLFloaterWindLight* instance(); - // help button stuff - static void onClickHelp(void* data); + void onClickHelp(std::string alert); void initHelpBtn(const std::string& name, const std::string& xml_alert); - static bool newPromptCallback(const LLSD& notification, const LLSD& response); + bool newPromptCallback(const LLSD& notification, const LLSD& response); /// general purpose callbacks for dealing with color controllers - static void onColorControlRMoved(LLUICtrl* ctrl, void* userData); - static void onColorControlGMoved(LLUICtrl* ctrl, void* userData); - static void onColorControlBMoved(LLUICtrl* ctrl, void* userData); - static void onColorControlIMoved(LLUICtrl* ctrl, void* userData); - static void onFloatControlMoved(LLUICtrl* ctrl, void* userData); - static void onBoolToggle(LLUICtrl* ctrl, void* userData); + void onColorControlRMoved(LLUICtrl* ctrl, WLColorControl* userData); + void onColorControlGMoved(LLUICtrl* ctrl, WLColorControl* userData); + void onColorControlBMoved(LLUICtrl* ctrl, WLColorControl* userData); + void onColorControlIMoved(LLUICtrl* ctrl, WLColorControl* userData); + void onFloatControlMoved(LLUICtrl* ctrl, WLFloatControl* userData); /// lighting callbacks for glow - static void onGlowRMoved(LLUICtrl* ctrl, void* userData); + void onGlowRMoved(LLUICtrl* ctrl, WLColorControl* userData); //static void onGlowGMoved(LLUICtrl* ctrl, void* userData); - static void onGlowBMoved(LLUICtrl* ctrl, void* userData); + void onGlowBMoved(LLUICtrl* ctrl, WLColorControl* userData); /// lighting callbacks for sun - static void onSunMoved(LLUICtrl* ctrl, void* userData); - - /// handle if float is changed - static void onFloatTweakMoved(LLUICtrl* ctrl, void* userData); + void onSunMoved(LLUICtrl* ctrl, WLColorControl* userData); /// for handling when the star slider is moved to adjust the alpha - static void onStarAlphaMoved(LLUICtrl* ctrl, void* userData); + void onStarAlphaMoved(LLUICtrl* ctrl); /// when user hits the load preset button - static void onNewPreset(void* userData); + void onNewPreset(); /// when user hits the save preset button - static void onSavePreset(void* userData); + void onSavePreset(); /// prompts a user when overwriting a preset - static bool saveAlertCallback(const LLSD& notification, const LLSD& response); + bool saveAlertCallback(const LLSD& notification, const LLSD& response); /// when user hits the save preset button - static void onDeletePreset(void* userData); + void onDeletePreset(); /// prompts a user when overwriting a preset bool deleteAlertCallback(const LLSD& notification, const LLSD& response); @@ -107,24 +100,13 @@ public: void onChangePresetName(LLUICtrl* ctrl); /// when user hits the save preset button - static void onOpenDayCycle(void* userData); + void onOpenDayCycle(); /// handle cloud scrolling - static void onCloudScrollXMoved(LLUICtrl* ctrl, void* userData); - static void onCloudScrollYMoved(LLUICtrl* ctrl, void* userData); - static void onCloudScrollXToggled(LLUICtrl* ctrl, void* userData); - static void onCloudScrollYToggled(LLUICtrl* ctrl, void* userData); - - //// menu management - - /// show off our menu - static void show(); - - /// return if the menu exists or not - static bool isOpen(); - - /// stuff to do on exit - virtual void onClose(bool app_quitting); + void onCloudScrollXMoved(LLUICtrl* ctrl); + void onCloudScrollYMoved(LLUICtrl* ctrl); + void onCloudScrollXToggled(LLUICtrl* ctrl); + void onCloudScrollYToggled(LLUICtrl* ctrl); /// sync up sliders with parameters void syncMenu(); @@ -133,9 +115,6 @@ public: static void deactivateAnimator(); private: - // one instance on the inside - static LLFloaterWindLight* sWindLight; - static std::set sDefaultPresets; }; diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 2fe817625a..57acbb147d 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -67,6 +67,7 @@ #include "llappviewer.h" #include "llmapimagetype.h" #include "llweb.h" +#include "llslider.h" #include "llglheaders.h" #include "llwindow.h" // copyTextToClipboard() @@ -161,6 +162,16 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key) mFactoryMap["terrain_mapview"] = LLCallbackMap(createWorldMapView, NULL); //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_world_map.xml", FALSE); + mCommitCallbackRegistrar.add("WMap.Location", boost::bind(&LLFloaterWorldMap::onLocationCommit, this)); + mCommitCallbackRegistrar.add("WMap.AvatarCombo", boost::bind(&LLFloaterWorldMap::onAvatarComboCommit, this)); + mCommitCallbackRegistrar.add("WMap.SearchResult", boost::bind(&LLFloaterWorldMap::onCommitSearchResult, this)); + mCommitCallbackRegistrar.add("WMap.CommitLocation", boost::bind(&LLFloaterWorldMap::onCommitLocation, this)); + mCommitCallbackRegistrar.add("WMap.GoHome", boost::bind(&LLFloaterWorldMap::onGoHome, this)); + mCommitCallbackRegistrar.add("WMap.Teleport", boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this)); + mCommitCallbackRegistrar.add("WMap.ShowTarget", boost::bind(&LLFloaterWorldMap::onShowTargetBtn, this)); + mCommitCallbackRegistrar.add("WMap.ShowAgent", boost::bind(&LLFloaterWorldMap::onShowAgentBtn, this)); + mCommitCallbackRegistrar.add("WMap.Clear", boost::bind(&LLFloaterWorldMap::onClearBtn, this)); + mCommitCallbackRegistrar.add("WMap.CopySLURL", boost::bind(&LLFloaterWorldMap::onCopySLURL, this)); } // static @@ -171,6 +182,8 @@ void* LLFloaterWorldMap::createWorldMapView(void* data) BOOL LLFloaterWorldMap::postBuild() { + mCloseSignal.connect(boost::bind(&LLFloaterWorldMap::onClose, this)); + mTabs = getChild("maptab"); if (!mTabs) return FALSE; @@ -183,8 +196,6 @@ BOOL LLFloaterWorldMap::postBuild() // //onCommitBackground(); - childSetCommitCallback("friend combo", onAvatarComboCommit, this); - LLComboBox *avatar_combo = getChild("friend combo"); if (avatar_combo) { @@ -193,8 +204,6 @@ BOOL LLFloaterWorldMap::postBuild() avatar_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); } - childSetAction("DoSearch", onLocationCommit, this); - getChild("location")->setFocusChangedCallback(boost::bind(&LLFloaterWorldMap::onLocationFocusChanged, this, _1)); LLLineEditor *location_editor = getChild("location"); @@ -203,13 +212,7 @@ BOOL LLFloaterWorldMap::postBuild() location_editor->setKeystrokeCallback( boost::bind(&LLFloaterWorldMap::onSearchTextEntry, this, _1), NULL ); } - childSetCommitCallback("search_results", onCommitSearchResult, this); - getChild("search_results")->setDoubleClickCallback(onClickTeleportBtn, this); - childSetCommitCallback("spin x", onCommitLocation, this); - childSetCommitCallback("spin y", onCommitLocation, this); - childSetCommitCallback("spin z", onCommitLocation, this); - - childSetCommitCallback("landmark combo", onLandmarkComboCommit, this); + getChild("search_results")->setDoubleClickCallback( boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this)); LLComboBox *landmark_combo = getChild( "landmark combo"); if (landmark_combo) @@ -219,15 +222,6 @@ BOOL LLFloaterWorldMap::postBuild() landmark_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); } - childSetAction("Go Home", onGoHome, this); - - childSetAction("Teleport", onClickTeleportBtn, this); - - childSetAction("Show Destination", onShowTargetBtn, this); - childSetAction("Show My Location", onShowAgentBtn, this); - childSetAction("Clear", onClearBtn, this); - childSetAction("copy_slurl", onCopySLURL, this); - mCurZoomVal = log(gMapScale)/log(2.f); childSetValue("zoom slider", gMapScale); @@ -260,21 +254,10 @@ LLFloaterWorldMap* LLFloaterWorldMap::getInstance() return LLFloaterReg::getTypedInstance("world_map"); } -// virtual -void LLFloaterWorldMap::onClose(bool app_quitting) +void LLFloaterWorldMap::onClose() { // While we're not visible, discard the overlay images we're using LLWorldMap::getInstance()->clearImageRefs(); - -#if RELEASE_FOR_DOWNLOAD - setVisible(FALSE); -#else - // Don't call destroy(), we need to delete this immediately - delete this; // sets gFloaterWorldMap = NULL; - // need to reconstruct gFloaterWorldMap so that code that assumes it exists doesn't crash - LLFloaterReg::getInstance("world_map"); // constructs a LLFloaterWorldMap and sets gFloaterWorldMap - gFloaterWorldMap->setVisible(FALSE); // hide it -#endif } // virtual @@ -387,8 +370,8 @@ void LLFloaterWorldMap::reshape( S32 width, S32 height, BOOL called_from_parent // virtual void LLFloaterWorldMap::draw() { - static LLCachedControl map_track_color(gSavedSkinSettings, "MapTrackColor", LLColor4::white); - static LLCachedControl map_track_disabled_color(gSavedSkinSettings, "MapTrackDisabledColor", LLColor4::white); + static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white); + static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white); // Hide/Show Mature Events controls childSetVisible("events_mature_icon", gAgent.canAccessMature()); @@ -863,7 +846,7 @@ void LLFloaterWorldMap::buildLandmarkIDLists() LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLIsType is_landmark(LLAssetType::AT_LANDMARK); - gInventory.collectDescendentsIf(gAgent.getInventoryRootID(), + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, @@ -989,7 +972,8 @@ void LLFloaterWorldMap::adjustZoomSliderBounds() pixels_per_region = llclamp(pixels_per_region, 1.f, ZOOM_MAX); F32 min_power = log(pixels_per_region/256.f)/log(2.f); - childSetMinValue("zoom slider", min_power); + + getChild("zoom slider")->setMinValue(min_power); } @@ -997,34 +981,10 @@ void LLFloaterWorldMap::adjustZoomSliderBounds() // User interface widget callbacks //------------------------------------------------------------------------- -// static -void LLFloaterWorldMap::onPanBtn( void* userdata ) -{ - if( !gFloaterWorldMap ) return; - - EPanDirection direction = (EPanDirection)(intptr_t)userdata; - - S32 pan_x = 0; - S32 pan_y = 0; - switch( direction ) - { - case PAN_UP: pan_y = -1; break; - case PAN_DOWN: pan_y = 1; break; - case PAN_LEFT: pan_x = 1; break; - case PAN_RIGHT: pan_x = -1; break; - default: llassert(0); return; - } - - LLWorldMapView* map_panel; - map_panel = (LLWorldMapView*)gFloaterWorldMap->mTabs->getCurrentPanel(); - map_panel->translatePan( pan_x, pan_y ); -} - -// static -void LLFloaterWorldMap::onGoHome(void*) +void LLFloaterWorldMap::onGoHome() { gAgent.teleportHome(); - gFloaterWorldMap->closeFloater(); + closeFloater(); } @@ -1040,7 +1000,7 @@ void LLFloaterWorldMap::onLandmarkComboPrearrange( ) LLUUID current_choice = list->getCurrentID(); - gFloaterWorldMap->buildLandmarkIDLists(); + buildLandmarkIDLists(); if( current_choice.isNull() || !list->setCurrentByID( current_choice ) ) { @@ -1063,17 +1023,15 @@ void LLFloaterWorldMap::onSearchTextEntry( LLLineEditor* ctrl ) updateSearchEnabled(); } -// static -void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata ) -{ - LLFloaterWorldMap* self = gFloaterWorldMap; - if( !self || self->mIsClosing ) +void LLFloaterWorldMap::onLandmarkComboCommit() +{ + if( mIsClosing ) { return; } - LLCtrlListInterface *list = gFloaterWorldMap->childGetListInterface("landmark combo"); + LLCtrlListInterface *list = childGetListInterface("landmark combo"); if (!list) return; LLUUID asset_id; @@ -1105,11 +1063,11 @@ void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata ) } } - self->trackLandmark( item_id); - onShowTargetBtn(self); + trackLandmark( item_id); + onShowTargetBtn(); // Reset to user postion if nothing is tracked - self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); + mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); } // static @@ -1138,31 +1096,28 @@ void LLFloaterWorldMap::onAvatarComboPrearrange( ) } } - -// static -void LLFloaterWorldMap::onAvatarComboCommit( LLUICtrl* ctrl, void* userdata ) +void LLFloaterWorldMap::onAvatarComboCommit() { - LLFloaterWorldMap* self = gFloaterWorldMap; - if( !self || self->mIsClosing ) + if( mIsClosing ) { return; } - LLCtrlListInterface *list = gFloaterWorldMap->childGetListInterface("friend combo"); + LLCtrlListInterface *list = childGetListInterface("friend combo"); if (!list) return; const LLUUID& new_avatar_id = list->getCurrentID(); if (new_avatar_id.notNull()) { std::string name; - LLComboBox* combo = gFloaterWorldMap->getChild("friend combo"); + LLComboBox* combo = getChild("friend combo"); if (combo) name = combo->getSimple(); - self->trackAvatar(new_avatar_id, name); - onShowTargetBtn(self); + trackAvatar(new_avatar_id, name); + onShowTargetBtn(); } else { // Reset to user postion if nothing is tracked - self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); + mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); } } @@ -1184,33 +1139,31 @@ void LLFloaterWorldMap::updateSearchEnabled() } } -// static -void LLFloaterWorldMap::onLocationCommit( void* userdata ) +void LLFloaterWorldMap::onLocationCommit() { - LLFloaterWorldMap *self = gFloaterWorldMap; - if( !self || self->mIsClosing ) + if( mIsClosing ) { return; } - self->clearLocationSelection(FALSE); - self->mCompletingRegionName = ""; - self->mLastRegionName = ""; + clearLocationSelection(FALSE); + mCompletingRegionName = ""; + mLastRegionName = ""; - std::string str = self->childGetValue("location").asString(); + std::string str = childGetValue("location").asString(); // Trim any leading and trailing spaces in the search target std::string saved_str = str; LLStringUtil::trim( str ); if ( str != saved_str ) { // Set the value in the UI if any spaces were removed - self->childSetValue("location", str); + childSetValue("location", str); } LLStringUtil::toLower(str); - gFloaterWorldMap->mCompletingRegionName = str; + mCompletingRegionName = str; LLWorldMap::getInstance()->mIsTrackingCommit = TRUE; - self->mExactMatch = FALSE; + mExactMatch = FALSE; if (str.length() >= 3) { LLWorldMap::getInstance()->sendNamedRegionRequest(str); @@ -1222,67 +1175,42 @@ void LLFloaterWorldMap::onLocationCommit( void* userdata ) } } - -// static -void LLFloaterWorldMap::onClearBtn(void* data) +void LLFloaterWorldMap::onClearBtn() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->mTrackedStatus = LLTracker::TRACKING_NOTHING; + mTrackedStatus = LLTracker::TRACKING_NOTHING; LLTracker::stopTracking((void *)(intptr_t)TRUE); LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE; - self->mSLURL = ""; // Clear the SLURL since it's invalid - self->mSetToUserPosition = TRUE; // Revert back to the current user position + mSLURL = ""; // Clear the SLURL since it's invalid + mSetToUserPosition = TRUE; // Revert back to the current user position } -// static -void LLFloaterWorldMap::onFlyBtn(void* data) +void LLFloaterWorldMap::onShowTargetBtn() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->fly(); + centerOnTarget(TRUE); } -void LLFloaterWorldMap::onShowTargetBtn(void* data) -{ - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->centerOnTarget(TRUE); -} - -void LLFloaterWorldMap::onShowAgentBtn(void* data) +void LLFloaterWorldMap::onShowAgentBtn() { LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate - // Set flag so user's location will be displayed if not tracking anything else - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->mSetToUserPosition = TRUE; + mSetToUserPosition = TRUE; } -// static -void LLFloaterWorldMap::onClickTeleportBtn(void* data) +void LLFloaterWorldMap::onClickTeleportBtn() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->teleport(); + teleport(); } -// static -void LLFloaterWorldMap::onCopySLURL(void* data) +void LLFloaterWorldMap::onCopySLURL() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->getWindow()->copyTextToClipboard(utf8str_to_wstring(self->mSLURL)); + getWindow()->copyTextToClipboard(utf8str_to_wstring(mSLURL)); LLSD args; - args["SLURL"] = self->mSLURL; + args["SLURL"] = mSLURL; LLNotifications::instance().add("CopySLURL", args); } -void LLFloaterWorldMap::onCheckEvents(LLUICtrl*, void* data) -{ - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - if(!self) return; - self->childSetEnabled("event_mature_chk", self->childGetValue("event_chk")); - self->childSetEnabled("event_adult_chk", self->childGetValue("event_chk")); -} - // protected void LLFloaterWorldMap::centerOnTarget(BOOL animate) { @@ -1402,24 +1330,6 @@ void LLFloaterWorldMap::teleport() } } -// static -void LLFloaterWorldMap::onGoToLandmarkDialog( S32 option, void* userdata ) -{ - LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata; - switch( option ) - { - case 0: - self->teleportToLandmark(); - break; - case 1: - self->flyToLandmark(); - break; - default: - // nothing - break; - } -} - void LLFloaterWorldMap::flyToLandmark() { LLVector3d destination_pos_global; @@ -1553,13 +1463,13 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) { mExactMatch = TRUE; childSetFocus("search_results"); - onCommitSearchResult(NULL, this); + onCommitSearchResult(); } else if (!mExactMatch && num_results > 0) { list->selectFirstItem(); // select first item by default childSetFocus("search_results"); - onCommitSearchResult(NULL, this); + onCommitSearchResult(); } else if (num_results == 0) { @@ -1568,30 +1478,25 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) } } -// static -void LLFloaterWorldMap::onCommitLocation(LLUICtrl* ctrl, void* userdata) +void LLFloaterWorldMap::onCommitLocation() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata; LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); if ( LLTracker::TRACKING_LOCATION == tracking_status) { LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); - F64 local_x = self->childGetValue("spin x"); - F64 local_y = self->childGetValue("spin y"); - F64 local_z = self->childGetValue("spin z"); + F64 local_x = childGetValue("spin x"); + F64 local_y = childGetValue("spin y"); + F64 local_z = childGetValue("spin z"); pos_global.mdV[VX] += -fmod(pos_global.mdV[VX], 256.0) + local_x; pos_global.mdV[VY] += -fmod(pos_global.mdV[VY], 256.0) + local_y; pos_global.mdV[VZ] = local_z; - self->trackLocation(pos_global); + trackLocation(pos_global); } } -// static -void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata) +void LLFloaterWorldMap::onCommitSearchResult() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata; - - LLCtrlListInterface *list = self->childGetListInterface("search_results"); + LLCtrlListInterface *list = childGetListInterface("search_results"); if (!list) return; LLSD selected_value = list->getSelectedValue(); @@ -1612,19 +1517,19 @@ void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata) if (sim_name == info_sim_name) { LLVector3d pos_global = from_region_handle( info->mHandle ); - F64 local_x = self->childGetValue("spin x"); - F64 local_y = self->childGetValue("spin y"); - F64 local_z = self->childGetValue("spin z"); + F64 local_x = childGetValue("spin x"); + F64 local_y = childGetValue("spin y"); + F64 local_z = childGetValue("spin z"); pos_global.mdV[VX] += local_x; pos_global.mdV[VY] += local_y; pos_global.mdV[VZ] = local_z; - self->childSetValue("location", sim_name); - self->trackLocation(pos_global); - self->setDefaultBtn("Teleport"); + childSetValue("location", sim_name); + trackLocation(pos_global); + setDefaultBtn("Teleport"); break; } } - onShowTargetBtn(self); + onShowTargetBtn(); } diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index a7d7051b40..f117ea05af 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -49,6 +49,7 @@ class LLFriendObserver; class LLInventoryModel; class LLInventoryObserver; class LLItemInfo; +class LLLineEditor; class LLTabContainer; class LLFloaterWorldMap : public LLFloater @@ -64,7 +65,6 @@ public: BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); static void reloadIcons(void*); @@ -112,29 +112,26 @@ public: void teleport(); protected: - static void onPanBtn( void* userdata ); + void onClose(); + + void onGoHome(); - static void onGoHome(void* data); + void onLandmarkComboPrearrange(); + void onLandmarkComboCommit(); - void onLandmarkComboPrearrange( ); - static void onLandmarkComboCommit( LLUICtrl* ctrl, void* data ); - - void onAvatarComboPrearrange( ); - static void onAvatarComboCommit( LLUICtrl* ctrl, void* data ); + void onAvatarComboPrearrange(); + void onAvatarComboCommit(); void onCommitBackground(); void onComboTextEntry( ); void onSearchTextEntry( LLLineEditor* ctrl ); - static void onClearBtn(void*); - static void onFlyBtn(void*); - static void onClickTeleportBtn(void*); - static void onShowTargetBtn(void*); - static void onShowAgentBtn(void*); - static void onCopySLURL(void*); - - static void onCheckEvents(LLUICtrl* ctrl, void*); + void onClearBtn(); + void onClickTeleportBtn(); + void onShowTargetBtn(); + void onShowAgentBtn(); + void onCopySLURL(); void centerOnTarget(BOOL animate); void updateLocation(); @@ -143,7 +140,6 @@ protected: void fly(); void buildLandmarkIDLists(); - static void onGoToLandmarkDialog(S32 option,void* userdata); void flyToLandmark(); void teleportToLandmark(); void setLandmarkVisited(); @@ -152,11 +148,11 @@ protected: void flyToAvatar(); void teleportToAvatar(); - void updateSearchEnabled( ); + void updateSearchEnabled(); void onLocationFocusChanged( LLFocusableElement* ctrl ); - static void onLocationCommit( void* userdata ); - static void onCommitLocation( LLUICtrl* ctrl, void* userdata ); - static void onCommitSearchResult( LLUICtrl* ctrl, void* userdata ); + void onLocationCommit(); + void onCommitLocation(); + void onCommitSearchResult(); void cacheLandmarkPosition(); @@ -169,7 +165,6 @@ protected: LLDynamicArray mLandmarkAssetIDList; LLDynamicArray mLandmarkItemIDList; - BOOL mHasLandmarkPosition; static const LLUUID sHomeID; diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index fd8c22b8e5..c54eafb67a 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -34,20 +34,13 @@ #include "llfolderview.h" -#include - -#include "llviewercontrol.h" -#include "lldbstrings.h" -#include "llfocusmgr.h" -#include "llfontgl.h" -#include "llgl.h" -#include "llrender.h" -#include "llinventory.h" - +#include "llagent.h" #include "llcallbacklist.h" #include "llinventorybridge.h" #include "llinventoryclipboard.h" // *TODO: remove this once hack below gone. -#include "llinventoryview.h"// hacked in for the bonus context menu items. +#include "llinventoryfilter.h" +#include "llfoldertype.h" +#include "llfloaterinventory.h"// hacked in for the bonus context menu items. #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" @@ -56,39 +49,40 @@ #include "lltooldraganddrop.h" #include "lltrans.h" #include "llui.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewerjointattachment.h" #include "llviewermenu.h" #include "lluictrlfactory.h" +#include "llviewercontrol.h" #include "llviewerwindow.h" #include "llvoavatar.h" #include "llfloaterproperties.h" -// RN: HACK -// We need these because some of the code below relies on things like -// gAgent root folder. Remove them once the abstraction leak is fixed. -#include "llagent.h" -#include "llappviewer.h" +// Linden library includes +#include "lldbstrings.h" +#include "llfocusmgr.h" +#include "llfontgl.h" +#include "llgl.h" +#include "llrender.h" +#include "llinventory.h" + +// Third-party library includes +#include ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs ///---------------------------------------------------------------------------- -const S32 LEFT_PAD = 5; -const S32 LEFT_INDENTATION = 13; -const S32 ICON_PAD = 2; -const S32 ICON_WIDTH = 16; -const S32 TEXT_PAD = 1; -const S32 ARROW_SIZE = 12; const S32 RENAME_WIDTH_PAD = 4; const S32 RENAME_HEIGHT_PAD = 2; const S32 AUTO_OPEN_STACK_DEPTH = 16; -const S32 MIN_ITEM_WIDTH_VISIBLE = ICON_WIDTH + ICON_PAD + ARROW_SIZE + TEXT_PAD + /*first few characters*/ 40; +const S32 MIN_ITEM_WIDTH_VISIBLE = LLFolderViewItem::ICON_WIDTH + + LLFolderViewItem::ICON_PAD + + LLFolderViewItem::ARROW_SIZE + + LLFolderViewItem::TEXT_PAD + + /*first few characters*/ 40; const S32 MINIMUM_RENAMER_WIDTH = 80; -const F32 FOLDER_CLOSE_TIME_CONSTANT = 0.02f; -const F32 FOLDER_OPEN_TIME_CONSTANT = 0.03f; -const S32 MAX_FOLDER_ITEM_OVERLAP = 2; enum { SIGNAL_NO_KEYBOARD_FOCUS = 1, @@ -104,2332 +98,6 @@ void properties_selected_items(void* user_data); void paste_items(void* user_data); void renamer_focus_lost( LLFocusableElement* handler, void* user_data ); -///---------------------------------------------------------------------------- -/// Class LLFolderViewItem -///---------------------------------------------------------------------------- - -// statics -const LLFontGL* LLFolderViewItem::sFont = NULL; -const LLFontGL* LLFolderViewItem::sSmallFont = NULL; -LLUIImagePtr LLFolderViewItem::sArrowImage; -LLUIImagePtr LLFolderViewItem::sBoxImage; - -const LLColor4U DEFAULT_WHITE(255, 255, 255); - -//static -void LLFolderViewItem::initClass() -{ - sFont = LLFontGL::getFontSansSerifSmall(); - sSmallFont = LLFontGL::getFontMonospace(); - sArrowImage = LLUI::getUIImage("folder_arrow.tga"); - sBoxImage = LLUI::getUIImage("rounded_square.tga"); -} - -//static -void LLFolderViewItem::cleanupClass() -{ - sArrowImage = NULL; - sBoxImage = NULL; -} - -// NOTE: Optimize this, we call it a *lot* when opening a large inventory - -// Default constructor -LLFolderViewItem::LLFolderViewItem(LLFolderViewItem::Params p) -: LLView(p), - mLabelWidth(0), - mLabelWidthDirty(false), - mParentFolder( NULL ), - mIsSelected( FALSE ), - mIsCurSelection( FALSE ), - mSelectPending(FALSE), - mLabelStyle( LLFontGL::NORMAL ), - mHasVisibleChildren(FALSE), - mIndentation(0), - mNumDescendantsSelected(0), - mFiltered(FALSE), - mLastFilterGeneration(-1), - mStringMatchOffset(std::string::npos), - mControlLabelRotation(0.f), - mDragAndDropTarget(FALSE), - mIsLoading(FALSE), - mLabel(p.name), - mRoot(p.root), - mCreationDate(p.creation_date), - mListener(p.listener), - mArrowImage(p.folder_arrow_image), - mBoxImage(p.selection_image) -{ - refresh(); -} - -// Destroys the object -LLFolderViewItem::~LLFolderViewItem( void ) -{ - delete mListener; - mListener = NULL; -} - -LLFolderView* LLFolderViewItem::getRoot() -{ - return mRoot; -} - -// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor. -BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor ) -{ - LLFolderViewItem* root = this; - while( root->mParentFolder ) - { - if( root->mParentFolder == potential_ancestor ) - { - return TRUE; - } - root = root->mParentFolder; - } - return FALSE; -} - -LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children) -{ - if (!mParentFolder) - { - return NULL; - } - - LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children ); - while(itemp && !itemp->getVisible()) - { - LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children ); - if (itemp == next_itemp) - { - // hit last item - return itemp->getVisible() ? itemp : this; - } - itemp = next_itemp; - } - - return itemp; -} - -LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children) -{ - if (!mParentFolder) - { - return NULL; - } - - LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children ); - while(itemp && !itemp->getVisible()) - { - LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children ); - if (itemp == next_itemp) - { - // hit first item - return itemp->getVisible() ? itemp : this; - } - itemp = next_itemp; - } - - return itemp; -} - -// is this item something we think we should be showing? -// for example, if we haven't gotten around to filtering it yet, then the answer is yes -// until we find out otherwise -BOOL LLFolderViewItem::potentiallyVisible() -{ - // we haven't been checked against min required filter - // or we have and we passed - return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered(); -} - -BOOL LLFolderViewItem::getFiltered() -{ - return mFiltered && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration(); -} - -BOOL LLFolderViewItem::getFiltered(S32 filter_generation) -{ - return mFiltered && mLastFilterGeneration >= filter_generation; -} - -void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation) -{ - mFiltered = filtered; - mLastFilterGeneration = filter_generation; -} - -void LLFolderViewItem::setIcon(LLUIImagePtr icon) -{ - mIcon = icon; -} - -// refresh information from the listener -void LLFolderViewItem::refreshFromListener() -{ - if(mListener) - { - mLabel = mListener->getDisplayName(); - LLAssetType::EType preferred_type = mListener->getPreferredType(); - - // *TODO: to be removed when database supports multi language. This is a - // temporary attempt to display the inventory folder in the user locale. - if (preferred_type != LLAssetType::AT_NONE) - { - mLabel = LLTrans::getString("InvFolder " + mLabel); - }; - - setIcon(mListener->getIcon()); - time_t creation_date = mListener->getCreationDate(); - if (mCreationDate != creation_date) - { - mCreationDate = mListener->getCreationDate(); - dirtyFilter(); - } - mLabelStyle = mListener->getLabelStyle(); - mLabelSuffix = mListener->getLabelSuffix(); - } -} - -void LLFolderViewItem::refresh() -{ - refreshFromListener(); - - std::string searchable_label(mLabel); - searchable_label.append(mLabelSuffix); - LLStringUtil::toUpper(searchable_label); - - if (mSearchableLabel.compare(searchable_label)) - { - mSearchableLabel.assign(searchable_label); - dirtyFilter(); - // some part of label has changed, so overall width has potentially changed, and sort order too - if (mParentFolder) - { - mParentFolder->requestSort(); - mParentFolder->requestArrange(); - } - } - - mLabelWidthDirty = true; -} - -void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor) -{ - functor(mListener); -} - -// This function is called when items are added or view filters change. It's -// implemented here but called by derived classes when folding the -// views. -void LLFolderViewItem::filterFromRoot( void ) -{ - LLFolderViewItem* root = getRoot(); - - root->filter(*((LLFolderView*)root)->getFilter()); -} - -// This function is called when the folder view is dirty. It's -// implemented here but called by derived classes when folding the -// views. -void LLFolderViewItem::arrangeFromRoot() -{ - LLFolderViewItem* root = getRoot(); - - S32 height = 0; - S32 width = 0; - root->arrange( &width, &height, 0 ); -} - -// This function clears the currently selected item, and records the -// specified selected item appropriately for display and use in the -// UI. If open is TRUE, then folders are opened up along the way to -// the selection. -void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection, - BOOL openitem, - BOOL take_keyboard_focus) -{ - getRoot()->setSelection(selection, openitem, take_keyboard_focus); -} - -// helper function to change the selection from the root. -void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected) -{ - getRoot()->changeSelection(selection, selected); -} - -void LLFolderViewItem::extendSelectionFromRoot(LLFolderViewItem* selection) -{ - LLDynamicArray selected_items; - - getRoot()->extendSelection(selection, NULL, selected_items); -} - -EInventorySortGroup LLFolderViewItem::getSortGroup() const -{ - return SG_ITEM; -} - -// addToFolder() returns TRUE if it succeeds. FALSE otherwise -BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) -{ - if (!folder) - { - return FALSE; - } - mParentFolder = folder; - root->addItemID(getListener()->getUUID(), this); - return folder->addItem(this); -} - - -// Finds width and height of this object and it's children. Also -// makes sure that this view and it's children are the right size. -S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation) -{ - mIndentation = mParentFolder ? mParentFolder->getIndentation() + LEFT_INDENTATION : 0; - if (mLabelWidthDirty) - { - mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + sFont->getWidth(mSearchableLabel); - mLabelWidthDirty = false; - } - - *width = llmax(*width, mLabelWidth + mIndentation); - *height = getItemHeight(); - return *height; -} - -S32 LLFolderViewItem::getItemHeight() -{ - S32 icon_height = mIcon->getHeight(); - S32 label_height = llround(sFont->getLineHeight()); - return llmax( icon_height, label_height ) + ICON_PAD; -} - -void LLFolderViewItem::filter( LLInventoryFilter& filter) -{ - BOOL filtered = mListener && filter.check(this); - - // if our visibility will change as a result of this filter, then - // we need to be rearranged in our parent folder - if (getVisible() != filtered) - { - if (mParentFolder) - { - mParentFolder->requestArrange(); - } - } - - setFiltered(filtered, filter.getCurrentGeneration()); - mStringMatchOffset = filter.getStringMatchOffset(); - filter.decrementFilterCount(); - - if (getRoot()->getDebugFilters()) - { - mStatusText = llformat("%d", mLastFilterGeneration); - } -} - -void LLFolderViewItem::dirtyFilter() -{ - mLastFilterGeneration = -1; - // bubble up dirty flag all the way to root - if (getParentFolder()) - { - getParentFolder()->setCompletedFilterGeneration(-1, TRUE); - } -} - -// *TODO: This can be optimized a lot by simply recording that it is -// selected in the appropriate places, and assuming that set selection -// means 'deselect' for a leaf item. Do this optimization after -// multiple selection is implemented to make sure it all plays nice -// together. -BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus) -{ - if( selection == this ) - { - mIsSelected = TRUE; - if(mListener) - { - mListener->selectItem(); - } - } - else - { - mIsSelected = FALSE; - } - return mIsSelected; -} - -BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected) -{ - if(selection == this && mIsSelected != selected) - { - mIsSelected = selected; - if(mListener) - { - mListener->selectItem(); - } - return TRUE; - } - return FALSE; -} - -void LLFolderViewItem::recursiveDeselect(BOOL deselect_self) -{ - if (mIsSelected && deselect_self) - { - mIsSelected = FALSE; - - // update ancestors' count of selected descendents - LLFolderViewFolder* parent_folder = getParentFolder(); - while(parent_folder) - { - parent_folder->mNumDescendantsSelected--; - parent_folder = parent_folder->getParentFolder(); - } - } -} - - -BOOL LLFolderViewItem::isMovable() -{ - if( mListener ) - { - return mListener->isItemMovable(); - } - else - { - return TRUE; - } -} - -BOOL LLFolderViewItem::isRemovable() -{ - if( mListener ) - { - return mListener->isItemRemovable(); - } - else - { - return TRUE; - } -} - -void LLFolderViewItem::destroyView() -{ - if (mParentFolder) - { - // removeView deletes me - mParentFolder->removeView(this); - } -} - -// Call through to the viewed object and return true if it can be -// removed. -//BOOL LLFolderViewItem::removeRecursively(BOOL single_item) -BOOL LLFolderViewItem::remove() -{ - if(!isRemovable()) - { - return FALSE; - } - if(mListener) - { - return mListener->removeItem(); - } - return TRUE; -} - -// Build an appropriate context menu for the item. -void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags) -{ - if(mListener) - { - mListener->buildContextMenu(menu, flags); - } -} - -void LLFolderViewItem::openItem( void ) -{ - if( mListener ) - { - mListener->openItem(); - } -} - -void LLFolderViewItem::preview( void ) -{ - if (mListener) - { - mListener->previewItem(); - } -} - -void LLFolderViewItem::rename(const std::string& new_name) -{ - if( !new_name.empty() ) - { - if( mListener ) - { - mListener->renameItem(new_name); - - if(mParentFolder) - { - mParentFolder->requestSort(); - } - } - } -} - -const std::string& LLFolderViewItem::getSearchableLabel() const -{ - return mSearchableLabel; -} - -const std::string& LLFolderViewItem::getName( void ) const -{ - if(mListener) - { - return mListener->getName(); - } - return mLabel; -} - -// LLView functionality -BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask ) -{ - if(!mIsSelected) - { - setSelectionFromRoot(this, FALSE); - } - make_ui_sound("UISndClick"); - return TRUE; -} - -BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - // No handler needed for focus lost since this class has no - // state that depends on it. - gFocusMgr.setMouseCapture( this ); - - if (!mIsSelected) - { - if(mask & MASK_CONTROL) - { - changeSelectionFromRoot(this, !mIsSelected); - } - else if (mask & MASK_SHIFT) - { - extendSelectionFromRoot(this); - } - else - { - setSelectionFromRoot(this, FALSE); - } - make_ui_sound("UISndClick"); - } - else - { - mSelectPending = TRUE; - } - - if( isMovable() ) - { - S32 screen_x; - S32 screen_y; - localPointToScreen(x, y, &screen_x, &screen_y ); - LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y ); - } - return TRUE; -} - -BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask ) -{ - if( hasMouseCapture() && isMovable() ) - { - S32 screen_x; - S32 screen_y; - localPointToScreen(x, y, &screen_x, &screen_y ); - BOOL can_drag = TRUE; - if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) ) - { - LLFolderView* root = getRoot(); - - if(root->getCurSelectedItem()) - { - LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_WORLD; - - // *TODO: push this into listener and remove - // dependency on llagent - if(mListener && gInventory.isObjectDescendentOf(mListener->getUUID(), gAgent.getInventoryRootID())) - { - src = LLToolDragAndDrop::SOURCE_AGENT; - } - else if (mListener && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventoryLibraryRoot)) - { - src = LLToolDragAndDrop::SOURCE_LIBRARY; - } - - can_drag = root->startDrag(src); - if (can_drag) - { - // if (mListener) mListener->startDrag(); - // RN: when starting drag and drop, clear out last auto-open - root->autoOpenTest(NULL); - root->setShowSelectionContext(TRUE); - - // Release keyboard focus, so that if stuff is dropped into the - // world, pressing the delete key won't blow away the inventory - // item. - gFocusMgr.setKeyboardFocus(NULL); - - return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask ); - } - } - } - - if (can_drag) - { - gViewerWindow->setCursor(UI_CURSOR_ARROW); - } - else - { - gViewerWindow->setCursor(UI_CURSOR_NOLOCKED); - } - return TRUE; - } - else - { - getRoot()->setShowSelectionContext(FALSE); - gViewerWindow->setCursor(UI_CURSOR_ARROW); - // let parent handle this then... - return FALSE; - } -} - - -BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask ) -{ - preview(); - return TRUE; -} - -BOOL LLFolderViewItem::handleScrollWheel(S32 x, S32 y, S32 clicks) -{ - if (getParent()) - { - return getParent()->handleScrollWheel(x, y, clicks); - } - return FALSE; -} - -BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask ) -{ - // if mouse hasn't moved since mouse down... - if ( pointInView(x, y) && mSelectPending ) - { - //...then select - if(mask & MASK_CONTROL) - { - changeSelectionFromRoot(this, !mIsSelected); - } - else if (mask & MASK_SHIFT) - { - extendSelectionFromRoot(this); - } - else - { - setSelectionFromRoot(this, FALSE); - } - } - - mSelectPending = FALSE; - - if( hasMouseCapture() ) - { - getRoot()->setShowSelectionContext(FALSE); - gFocusMgr.setMouseCapture( NULL ); - } - return TRUE; -} - -BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - BOOL accepted = FALSE; - BOOL handled = FALSE; - if(mListener) - { - accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data); - handled = accepted; - if (accepted) - { - mDragAndDropTarget = TRUE; - *accept = ACCEPT_YES_MULTI; - } - else - { - *accept = ACCEPT_NO; - } - } - if(mParentFolder && !handled) - { - handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); - } - if (handled) - { - lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl; - } - - return handled; -} - - -void LLFolderViewItem::draw() -{ - static LLCachedControl sFgColor(gSavedSkinSettings, "MenuItemEnabledColor", DEFAULT_WHITE); - static LLCachedControl sHighlightBgColor(gSavedSkinSettings, "MenuItemHighlightBgColor", DEFAULT_WHITE); - static LLCachedControl sHighlightFgColor(gSavedSkinSettings, "MenuItemHighlightFgColor", DEFAULT_WHITE); - static LLCachedControl sFilterBGColor(gSavedSkinSettings, "FilterBackgroundColor", DEFAULT_WHITE); - static LLCachedControl sFilterTextColor(gSavedSkinSettings, "FilterTextColor", DEFAULT_WHITE); - static LLCachedControl sSuffixColor(gSavedSkinSettings, "InventoryItemSuffixColor", DEFAULT_WHITE); - static LLCachedControl sSearchStatusColor(gSavedSkinSettings, "InventorySearchStatusColor", DEFAULT_WHITE); - - bool possibly_has_children = false; - bool up_to_date = mListener && mListener->isUpToDate(); - if((up_to_date && hasVisibleChildren() ) || // we fetched our children and some of them have passed the filter... - (!up_to_date && mListener && mListener->hasChildren())) // ...or we know we have children but haven't fetched them (doesn't obey filter) - { - possibly_has_children = true; - } - if(/*mControlLabel[0] != '\0' && */possibly_has_children) - { - if (sArrowImage) - { - gl_draw_scaled_rotated_image(mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD, - ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, sArrowImage->getImage(), sFgColor); - } - } - - F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation); - - // If we have keyboard focus, draw selection filled - BOOL show_context = getRoot()->getShowSelectionContext(); - BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus()); - - // always render "current" item, only render other selected items if - // mShowSingleSelection is FALSE - if( mIsSelected ) - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLColor4 bg_color = sHighlightBgColor; - //const S32 TRAILING_PAD = 5; // It just looks better with this. - if (!mIsCurSelection) - { - // do time-based fade of extra objects - F32 fade_time = getRoot()->getSelectionFadeElapsedTime(); - if (getRoot()->getShowSingleSelection()) - { - // fading out - bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f); - } - else - { - // fading in - bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]); - } - } - - gl_rect_2d( - 0, - getRect().getHeight(), - getRect().getWidth() - 2, - llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), - bg_color, filled); - if (mIsCurSelection) - { - gl_rect_2d( - 0, - getRect().getHeight(), - getRect().getWidth() - 2, - llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), - sHighlightFgColor, FALSE); - } - if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) - { - gl_rect_2d( - 0, - llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, - getRect().getWidth() - 2, - 2, - sHighlightFgColor, FALSE); - if (show_context) - { - gl_rect_2d( - 0, - llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, - getRect().getWidth() - 2, - 2, - sHighlightBgColor, TRUE); - } - } - } - if (mDragAndDropTarget) - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gl_rect_2d( - 0, - getRect().getHeight(), - getRect().getWidth() - 2, - llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), - sHighlightBgColor, FALSE); - - if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) - { - gl_rect_2d( - 0, - llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, - getRect().getWidth() - 2, - 2, - sHighlightBgColor, FALSE); - } - mDragAndDropTarget = FALSE; - } - - - if(mIcon) - { - mIcon->draw(mIndentation + ARROW_SIZE + TEXT_PAD, getRect().getHeight() - mIcon->getHeight()); - } - - if (!mLabel.empty()) - { - // highlight filtered text - BOOL debug_filters = getRoot()->getDebugFilters(); - LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor ); - F32 right_x; - F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; - - if (debug_filters) - { - if (!getFiltered() && !possibly_has_children) - { - color.mV[VALPHA] *= 0.5f; - } - - LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? LLColor4(0.5f, 0.8f, 0.5f, 1.f) : LLColor4(0.8f, 0.5f, 0.5f, 1.f); - sSmallFont->renderUTF8(mStatusText, 0, text_left, y, filter_color, - LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, &right_x, FALSE ); - text_left = right_x; - } - - - if ( mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime") ) - { - sFont->renderUTF8(LLTrans::getString("LoadingData"), 0, text_left, y, sSearchStatusColor, - LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &right_x, FALSE); - text_left = right_x; - } - - sFont->renderUTF8( mLabel, 0, text_left, y, color, - LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, &right_x, FALSE ); - if (!mLabelSuffix.empty()) - { - sFont->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor, - LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, &right_x, FALSE ); - } - - if (sBoxImage.notNull() && mStringMatchOffset != std::string::npos) - { - // don't draw backgrounds for zero-length strings - S32 filter_string_length = getRoot()->getFilterSubString().size(); - if (filter_string_length > 0) - { - std::string combined_string = mLabel + mLabelSuffix; - S32 left = llround(text_left) + sFont->getWidth(combined_string, 0, mStringMatchOffset) - 1; - S32 right = left + sFont->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2; - S32 bottom = llfloor(getRect().getHeight() - sFont->getLineHeight() - 3); - S32 top = getRect().getHeight(); - - LLRect box_rect(left, top, right, bottom); - sBoxImage->draw(box_rect, sFilterBGColor); - F32 match_string_left = text_left + sFont->getWidthF32(combined_string, 0, mStringMatchOffset); - F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; - sFont->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y, - sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, - filter_string_length, S32_MAX, &right_x, FALSE ); - } - } - } - - if( sDebugRects ) - { - drawDebugRect(); - } - - //// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview) - //std::set::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this); - //if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights)) - //{ - // drawDebugRect(); - //} -} - - -///---------------------------------------------------------------------------- -/// Class LLFolderViewFolder -///---------------------------------------------------------------------------- - -LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): - LLFolderViewItem( p ), // 0 = no create time - mIsOpen(FALSE), - mExpanderHighlighted(FALSE), - mCurHeight(0.f), - mTargetHeight(0.f), - mAutoOpenCountdown(0.f), - mSubtreeCreationDate(0), - mAmTrash(LLFolderViewFolder::UNKNOWN), - mLastArrangeGeneration( -1 ), - mLastCalculatedWidth(0), - mCompletedFilterGeneration(-1), - mMostFilteredDescendantGeneration(-1), - mNeedsSort(false) -{} - -// Destroys the object -LLFolderViewFolder::~LLFolderViewFolder( void ) -{ - // The LLView base class takes care of object destruction. make sure that we - // don't have mouse or keyboard focus - gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() -} - -// addToFolder() returns TRUE if it succeeds. FALSE otherwise -BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) -{ - if (!folder) - { - return FALSE; - } - mParentFolder = folder; - root->addItemID(getListener()->getUUID(), this); - return folder->addFolder(this); -} - -// Finds width and height of this object and it's children. Also -// makes sure that this view and it's children are the right size. -S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation) -{ - // sort before laying out contents - if (mNeedsSort) - { - mFolders.sort(mSortFunction); - mItems.sort(mSortFunction); - mNeedsSort = false; - } - - mHasVisibleChildren = hasFilteredDescendants(filter_generation); - - LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getShowFolderState(); - - // calculate height as a single item (without any children), and reshapes rectangle to match - LLFolderViewItem::arrange( width, height, filter_generation ); - - // clamp existing animated height so as to never get smaller than a single item - mCurHeight = llmax((F32)*height, mCurHeight); - - // initialize running height value as height of single item in case we have no children - *height = getItemHeight(); - F32 running_height = (F32)*height; - F32 target_height = (F32)*height; - - // are my children visible? - if (needsArrange()) - { - // set last arrange generation first, in case children are animating - // and need to be arranged again - mLastArrangeGeneration = getRoot()->getArrangeGeneration(); - if (mIsOpen) - { - // Add sizes of children - S32 parent_item_height = getRect().getHeight(); - - for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit) - { - LLFolderViewFolder* folderp = (*fit); - if (getRoot()->getDebugFilters()) - { - folderp->setVisible(TRUE); - } - else - { - folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders? - (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter - } - - if (folderp->getVisible()) - { - S32 child_width = *width; - S32 child_height = 0; - S32 child_top = parent_item_height - llround(running_height); - - target_height += folderp->arrange( &child_width, &child_height, filter_generation ); - - running_height += (F32)child_height; - *width = llmax(*width, child_width); - folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() ); - } - } - for(items_t::iterator iit = mItems.begin(); - iit != mItems.end(); ++iit) - { - LLFolderViewItem* itemp = (*iit); - if (getRoot()->getDebugFilters()) - { - itemp->setVisible(TRUE); - } - else - { - itemp->setVisible(itemp->getFiltered(filter_generation)); - } - - if (itemp->getVisible()) - { - S32 child_width = *width; - S32 child_height = 0; - S32 child_top = parent_item_height - llround(running_height); - - target_height += itemp->arrange( &child_width, &child_height, filter_generation ); - // don't change width, as this item is as wide as its parent folder by construction - itemp->reshape( itemp->getRect().getWidth(), child_height); - - running_height += (F32)child_height; - *width = llmax(*width, child_width); - itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() ); - } - } - } - - mTargetHeight = target_height; - // cache this width so next time we can just return it - mLastCalculatedWidth = *width; - } - else - { - // just use existing width - *width = mLastCalculatedWidth; - } - - // animate current height towards target height - if (llabs(mCurHeight - mTargetHeight) > 1.f) - { - mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT)); - - requestArrange(); - - // hide child elements that fall out of current animated height - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - // number of pixels that bottom of folder label is from top of parent folder - if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight() - > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP) - { - // hide if beyond current folder height - (*fit)->setVisible(FALSE); - } - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - // number of pixels that bottom of item label is from top of parent folder - if (getRect().getHeight() - (*iit)->getRect().mBottom - > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP) - { - (*iit)->setVisible(FALSE); - } - } - } - else - { - mCurHeight = mTargetHeight; - } - - // don't change width as this item is already as wide as its parent folder - reshape(getRect().getWidth(),llround(mCurHeight)); - - // pass current height value back to parent - *height = llround(mCurHeight); - - return llround(mTargetHeight); -} - -BOOL LLFolderViewFolder::needsArrange() -{ - return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); -} - -void LLFolderViewFolder::requestSort() -{ - mNeedsSort = true; - // whenever item order changes, we need to lay things out again - requestArrange(); -} - -void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up) -{ - mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation); - mCompletedFilterGeneration = generation; - // only aggregate up if we are a lower (older) value - if (recurse_up && mParentFolder && generation < mParentFolder->getCompletedFilterGeneration()) - { - mParentFolder->setCompletedFilterGeneration(generation, TRUE); - } -} - -void LLFolderViewFolder::filter( LLInventoryFilter& filter) -{ - S32 filter_generation = filter.getCurrentGeneration(); - // if failed to pass filter newer than must_pass_generation - // you will automatically fail this time, so we only - // check against items that have passed the filter - S32 must_pass_generation = filter.getMustPassGeneration(); - - // if we have already been filtered against this generation, skip out - if (getCompletedFilterGeneration() >= filter_generation) - { - return; - } - - // filter folder itself - if (getLastFilterGeneration() < filter_generation) - { - if (getLastFilterGeneration() >= must_pass_generation && // folder has been compared to a valid precursor filter - !mFiltered) // and did not pass the filter - { - // go ahead and flag this folder as done - mLastFilterGeneration = filter_generation; - } - else - { - // filter self only on first pass through - LLFolderViewItem::filter( filter ); - } - } - - if (getRoot()->getDebugFilters()) - { - mStatusText = llformat("%d", mLastFilterGeneration); - mStatusText += llformat("(%d)", mCompletedFilterGeneration); - mStatusText += llformat("+%d", mMostFilteredDescendantGeneration); - } - - // all descendants have been filtered later than must pass generation - // but none passed - if(getCompletedFilterGeneration() >= must_pass_generation && !hasFilteredDescendants(must_pass_generation)) - { - // don't traverse children if we've already filtered them since must_pass_generation - // and came back with nothing - return; - } - - // we entered here with at least one filter iteration left - // check to see if we have any more before continuing on to children - if (filter.getFilterCount() < 0) - { - return; - } - - // when applying a filter, matching folders get their contents downloaded first - if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID()))) - { - gInventory.startBackgroundFetch(mListener->getUUID()); - } - - // now query children - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - // have we run out of iterations this frame? - if (filter.getFilterCount() < 0) - { - break; - } - - // mMostFilteredDescendantGeneration might have been reset - // in which case we need to update it even for folders that - // don't need to be filtered anymore - if ((*fit)->getCompletedFilterGeneration() >= filter_generation) - { - // track latest generation to pass any child items - if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter.getMinRequiredGeneration())) - { - mMostFilteredDescendantGeneration = filter_generation; - if (getRoot()->needsAutoSelect()) - { - (*fit)->setOpenArrangeRecursively(TRUE); - } - } - // just skip it, it has already been filtered - continue; - } - - // update this folders filter status (and children) - (*fit)->filter( filter ); - - // track latest generation to pass any child items - if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter_generation)) - { - mMostFilteredDescendantGeneration = filter_generation; - if (getRoot()->needsAutoSelect()) - { - (*fit)->setOpenArrangeRecursively(TRUE); - } - } - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if (filter.getFilterCount() < 0) - { - break; - } - if ((*iit)->getLastFilterGeneration() >= filter_generation) - { - if ((*iit)->getFiltered()) - { - mMostFilteredDescendantGeneration = filter_generation; - } - continue; - } - - if ((*iit)->getLastFilterGeneration() >= must_pass_generation && - !(*iit)->getFiltered(must_pass_generation)) - { - // failed to pass an earlier filter that was a subset of the current one - // go ahead and flag this item as done - (*iit)->setFiltered(FALSE, filter_generation); - continue; - } - - (*iit)->filter( filter ); - - if ((*iit)->getFiltered(filter.getMinRequiredGeneration())) - { - mMostFilteredDescendantGeneration = filter_generation; - } - } - - // if we didn't use all filter iterations - // that means we filtered all of our descendants - // instead of exhausting the filter count for this frame - if (filter.getFilterCount() > 0) - { - // flag this folder as having completed filter pass for all descendants - setCompletedFilterGeneration(filter_generation, FALSE/*dont recurse up to root*/); - } -} - -void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation) -{ - // if this folder is now filtered, but wasn't before - // (it just passed) - if (filtered && !mFiltered) - { - // reset current height, because last time we drew it - // it might have had more visible items than now - mCurHeight = 0.f; - } - - LLFolderViewItem::setFiltered(filtered, filter_generation); -} - -void LLFolderViewFolder::dirtyFilter() -{ - // we're a folder, so invalidate our completed generation - setCompletedFilterGeneration(-1, FALSE); - LLFolderViewItem::dirtyFilter(); -} - -BOOL LLFolderViewFolder::hasFilteredDescendants() -{ - return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration(); -} - -// Passes selection information on to children and record selection -// information if necessary. -BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus) -{ - BOOL rv = FALSE; - if( selection == this ) - { - mIsSelected = TRUE; - if(mListener) - { - mListener->selectItem(); - } - rv = TRUE; - } - else - { - mIsSelected = FALSE; - rv = FALSE; - } - BOOL child_selected = FALSE; - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - if((*fit)->setSelection(selection, openitem, take_keyboard_focus)) - { - rv = TRUE; - child_selected = TRUE; - mNumDescendantsSelected++; - } - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if((*iit)->setSelection(selection, openitem, take_keyboard_focus)) - { - rv = TRUE; - child_selected = TRUE; - mNumDescendantsSelected++; - } - } - if(openitem && child_selected) - { - setOpenArrangeRecursively(TRUE); - } - return rv; -} - -// This method is used to change the selection of an item. If -// selection is 'this', then note selection as true. Returns TRUE -// if this or a child is now selected. -BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, - BOOL selected) -{ - BOOL rv = FALSE; - if(selection == this) - { - mIsSelected = selected; - if(mListener && selected) - { - mListener->selectItem(); - } - rv = TRUE; - } - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - if((*fit)->changeSelection(selection, selected)) - { - if (selected) - { - mNumDescendantsSelected++; - } - else - { - mNumDescendantsSelected--; - } - rv = TRUE; - } - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if((*iit)->changeSelection(selection, selected)) - { - if (selected) - { - mNumDescendantsSelected++; - } - else - { - mNumDescendantsSelected--; - } - rv = TRUE; - } - } - return rv; -} - -S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray& selected_items) -{ - S32 num_selected = 0; - - // pass on to child folders first - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - num_selected += (*fit)->extendSelection(selection, last_selected, selected_items); - mNumDescendantsSelected += num_selected; - } - - // handle selection of our immediate children... - BOOL reverse_select = FALSE; - BOOL found_last_selected = FALSE; - BOOL found_selection = FALSE; - LLDynamicArray items_to_select; - LLFolderViewItem* item; - - //...folders first... - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - item = (*fit); - if(item == selection) - { - found_selection = TRUE; - } - else if (item == last_selected) - { - found_last_selected = TRUE; - if (found_selection) - { - reverse_select = TRUE; - } - } - - if (found_selection || found_last_selected) - { - // deselect currently selected items so they can be pushed back on queue - if (item->isSelected()) - { - item->changeSelection(item, FALSE); - } - items_to_select.put(item); - } - - if (found_selection && found_last_selected) - { - break; - } - } - - if (!(found_selection && found_last_selected)) - { - //,,,then items - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - item = (*iit); - if(item == selection) - { - found_selection = TRUE; - } - else if (item == last_selected) - { - found_last_selected = TRUE; - if (found_selection) - { - reverse_select = TRUE; - } - } - - if (found_selection || found_last_selected) - { - // deselect currently selected items so they can be pushed back on queue - if (item->isSelected()) - { - item->changeSelection(item, FALSE); - } - items_to_select.put(item); - } - - if (found_selection && found_last_selected) - { - break; - } - } - } - - if (found_last_selected && found_selection) - { - // we have a complete selection inside this folder - for (S32 index = reverse_select ? items_to_select.getLength() - 1 : 0; - reverse_select ? index >= 0 : index < items_to_select.getLength(); reverse_select ? index-- : index++) - { - LLFolderViewItem* item = items_to_select[index]; - if (item->changeSelection(item, TRUE)) - { - selected_items.put(item); - mNumDescendantsSelected++; - num_selected++; - } - } - } - else if (found_selection) - { - // last selection was not in this folder....go ahead and select just the new item - if (selection->changeSelection(selection, TRUE)) - { - selected_items.put(selection); - mNumDescendantsSelected++; - num_selected++; - } - } - - return num_selected; -} - -void LLFolderViewFolder::recursiveDeselect(BOOL deselect_self) -{ - // make sure we don't have negative values - llassert(mNumDescendantsSelected >= 0); - - if (mIsSelected && deselect_self) - { - mIsSelected = FALSE; - - // update ancestors' count of selected descendents - LLFolderViewFolder* parent_folder = getParentFolder(); - while(parent_folder) - { - parent_folder->mNumDescendantsSelected--; - parent_folder = parent_folder->getParentFolder(); - } - } - - if (0 == mNumDescendantsSelected) - { - return; - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - LLFolderViewItem* item = (*iit); - item->recursiveDeselect(TRUE); - } - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - LLFolderViewFolder* folder = (*fit); - folder->recursiveDeselect(TRUE); - } - -} - -void LLFolderViewFolder::destroyView() -{ - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - LLFolderViewItem* item = (*iit); - getRoot()->removeItemID(item->getListener()->getUUID()); - } - - std::for_each(mItems.begin(), mItems.end(), DeletePointer()); - mItems.clear(); - - while (!mFolders.empty()) - { - LLFolderViewFolder *folderp = mFolders.back(); - folderp->destroyView(); // removes entry from mFolders - } - - deleteAllChildren(); - - if (mParentFolder) - { - mParentFolder->removeView(this); - } -} - -// remove the specified item (and any children) if possible. Return -// TRUE if the item was deleted. -BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item) -{ - if(item->remove()) - { - //RN: this seem unneccessary as remove() moves to trash - //removeView(item); - return TRUE; - } - return FALSE; -} - -// simply remove the view (and any children) Don't bother telling the -// listeners. -void LLFolderViewFolder::removeView(LLFolderViewItem* item) -{ - if (!item || item->getParentFolder() != this) - { - return; - } - // deselect without traversing hierarchy - item->recursiveDeselect(TRUE); - getRoot()->removeFromSelectionList(item); - extractItem(item); - delete item; -} - -// extractItem() removes the specified item from the folder, but -// doesn't delete it. -void LLFolderViewFolder::extractItem( LLFolderViewItem* item ) -{ - items_t::iterator it = std::find(mItems.begin(), mItems.end(), item); - if(it == mItems.end()) - { - // This is an evil downcast. However, it's only doing - // pointer comparison to find if (which it should be ) the - // item is in the container, so it's pretty safe. - LLFolderViewFolder* f = reinterpret_cast(item); - folders_t::iterator ft; - ft = std::find(mFolders.begin(), mFolders.end(), f); - if(ft != mFolders.end()) - { - mFolders.erase(ft); - } - } - else - { - mItems.erase(it); - } - //item has been removed, need to update filter - dirtyFilter(); - //because an item is going away regardless of filter status, force rearrange - requestArrange(); - getRoot()->removeItemID(item->getListener()->getUUID()); - removeChild(item); -} - -bool LLFolderViewFolder::isTrash() const -{ - if (mAmTrash == LLFolderViewFolder::UNKNOWN) - { - mAmTrash = mListener->getUUID() == gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH, false) ? LLFolderViewFolder::TRASH : LLFolderViewFolder::NOT_TRASH; - } - return mAmTrash == LLFolderViewFolder::TRASH; -} - -void LLFolderViewFolder::sortBy(U32 order) -{ - if (!mSortFunction.updateSort(order)) - { - // No changes. - return; - } - - // Propegate this change to sub folders - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->sortBy(order); - } - - mFolders.sort(mSortFunction); - mItems.sort(mSortFunction); - - if (order & LLInventoryFilter::SO_DATE) - { - time_t latest = 0; - - if (!mItems.empty()) - { - LLFolderViewItem* item = *(mItems.begin()); - latest = item->getCreationDate(); - } - - if (!mFolders.empty()) - { - LLFolderViewFolder* folder = *(mFolders.begin()); - if (folder->getCreationDate() > latest) - { - latest = folder->getCreationDate(); - } - } - mSubtreeCreationDate = latest; - } -} - -void LLFolderViewFolder::setItemSortOrder(U32 ordering) -{ - if (mSortFunction.updateSort(ordering)) - { - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->setItemSortOrder(ordering); - } - - mFolders.sort(mSortFunction); - mItems.sort(mSortFunction); - } -} - -EInventorySortGroup LLFolderViewFolder::getSortGroup() const -{ - if (isTrash()) - { - return SG_TRASH_FOLDER; - } - - // Folders that can't be moved are 'system' folders. - if( mListener ) - { - if( !(mListener->isItemMovable()) ) - { - return SG_SYSTEM_FOLDER; - } - } - - return SG_NORMAL_FOLDER; -} - -BOOL LLFolderViewFolder::isMovable() -{ - if( mListener ) - { - if( !(mListener->isItemMovable()) ) - { - return FALSE; - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if(!(*iit)->isMovable()) - { - return FALSE; - } - } - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - if(!(*fit)->isMovable()) - { - return FALSE; - } - } - } - return TRUE; -} - - -BOOL LLFolderViewFolder::isRemovable() -{ - if( mListener ) - { - if( !(mListener->isItemRemovable()) ) - { - return FALSE; - } - - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - if(!(*iit)->isRemovable()) - { - return FALSE; - } - } - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - if(!(*fit)->isRemovable()) - { - return FALSE; - } - } - } - return TRUE; -} - -// this is an internal method used for adding items to folders. -BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) -{ - mItems.push_back(item); - item->setRect(LLRect(0, 0, getRect().getWidth(), 0)); - item->setVisible(FALSE); - addChild( item ); - item->dirtyFilter(); - requestArrange(); - requestSort(); - return TRUE; -} - -// this is an internal method used for adding items to folders. -BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder) -{ - mFolders.push_back(folder); - folder->setOrigin(0, 0); - folder->reshape(getRect().getWidth(), 0); - folder->setVisible(FALSE); - addChild( folder ); - folder->dirtyFilter(); - // rearrange all descendants too, as our indentation level might have changed - folder->requestArrange(TRUE); - requestSort(); - return TRUE; -} - -void LLFolderViewFolder::requestArrange(BOOL include_descendants) -{ - mLastArrangeGeneration = -1; - // flag all items up to root - if (mParentFolder) - { - mParentFolder->requestArrange(); - } - - if (include_descendants) - { - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end(); - ++iter) - { - (*iter)->requestArrange(TRUE); - } - } -} - -void LLFolderViewFolder::toggleOpen() -{ - setOpen(!mIsOpen); -} - -// Force a folder open or closed -void LLFolderViewFolder::setOpen(BOOL openitem) -{ - setOpenArrangeRecursively(openitem); -} - -void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse) -{ - BOOL was_open = mIsOpen; - mIsOpen = openitem; - if(!was_open && openitem) - { - if(mListener) - { - mListener->openItem(); - } - } - - if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN) - { - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN); /* Flawfinder: ignore */ - } - } - if (mParentFolder && (recurse == RECURSE_UP || recurse == RECURSE_UP_DOWN)) - { - mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP); - } - - if (was_open != mIsOpen) - { - requestArrange(); - } -} - -BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask, - BOOL drop, - EDragAndDropType c_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data); - if (accepted) - { - mDragAndDropTarget = TRUE; - *accept = ACCEPT_YES_MULTI; - } - else - { - *accept = ACCEPT_NO; - } - - // drag and drop to child item, so clear pending auto-opens - getRoot()->autoOpenTest(NULL); - - return TRUE; -} - -void LLFolderViewFolder::openItem( void ) -{ - toggleOpen(); -} - -void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor) -{ - functor.doFolder(this); - - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->applyFunctorRecursively(functor); - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - functor.doItem((*iit)); - } -} - -void LLFolderViewFolder::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor) -{ - functor(mListener); - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) - { - folders_t::iterator fit = iter++; - (*fit)->applyListenerFunctorRecursively(functor); - } - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) - { - items_t::iterator iit = iter++; - (*iit)->applyListenerFunctorRecursively(functor); - } -} - -// LLView functionality -BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask, - BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - LLFolderView* root_view = getRoot(); - - BOOL handled = FALSE; - if(mIsOpen) - { - handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, - cargo_data, accept, tooltip_msg) != NULL; - } - - if (!handled) - { - BOOL accepted = mListener && mListener->dragOrDrop(mask, drop,cargo_type,cargo_data); - - if (accepted) - { - mDragAndDropTarget = TRUE; - *accept = ACCEPT_YES_MULTI; - } - else - { - *accept = ACCEPT_NO; - } - - if (!drop && accepted) - { - root_view->autoOpenTest(this); - } - - lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl; - } - - return TRUE; -} - - -BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - // fetch contents of this folder, as context menu can depend on contents - // still, user would have to open context menu again to see the changes - gInventory.fetchDescendentsOf(mListener->getUUID()); - - if( mIsOpen ) - { - handled = childrenHandleRightMouseDown( x, y, mask ) != NULL; - } - if (!handled) - { - handled = LLFolderViewItem::handleRightMouseDown( x, y, mask ); - } - return handled; -} - - -BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask) -{ - BOOL handled = LLView::handleHover(x, y, mask); - - if (!handled) - { - // this doesn't do child processing - handled = LLFolderViewItem::handleHover(x, y, mask); - } - - //if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD && y > getRect().getHeight() - ) - //{ - // gViewerWindow->setCursor(UI_CURSOR_ARROW); - // mExpanderHighlighted = TRUE; - // handled = TRUE; - //} - return handled; -} - -BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - if( mIsOpen ) - { - handled = childrenHandleMouseDown(x,y,mask) != NULL; - } - if( !handled ) - { - if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD) - { - toggleOpen(); - handled = TRUE; - } - else - { - // do normal selection logic - handled = LLFolderViewItem::handleMouseDown(x, y, mask); - } - } - - return handled; -} - -BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - if( mIsOpen ) - { - handled = childrenHandleDoubleClick( x, y, mask ) != NULL; - } - if( !handled ) - { - if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD) - { - // don't select when user double-clicks plus sign - // so as not to contradict single-click behavior - toggleOpen(); - } - else - { - setSelectionFromRoot(this, FALSE); - toggleOpen(); - } - handled = TRUE; - } - return handled; -} - -void LLFolderViewFolder::draw() -{ - if (mAutoOpenCountdown != 0.f) - { - mControlLabelRotation = mAutoOpenCountdown * -90.f; - } - else if (mIsOpen) - { - mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f)); - } - else - { - mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f)); - } - - bool possibly_has_children = false; - bool up_to_date = mListener && mListener->isUpToDate(); - if(!up_to_date && mListener && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter) - { - possibly_has_children = true; - } - - - BOOL loading = ( mIsOpen && possibly_has_children && !up_to_date ); - - if ( loading && !mIsLoading ) - { - // Measure how long we've been in the loading state - mTimeSinceRequestStart.reset(); - } - - mIsLoading = loading; - - LLFolderViewItem::draw(); - - // draw children if root folder, or any other folder that is open or animating to closed state - if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight )) - { - LLView::draw(); - } - - mExpanderHighlighted = FALSE; -} - -time_t LLFolderViewFolder::getCreationDate() const -{ - return llmax(mCreationDate, mSubtreeCreationDate); -} - - -BOOL LLFolderViewFolder::potentiallyVisible() -{ - // folder should be visible by it's own filter status - return LLFolderViewItem::potentiallyVisible() - // or one or more of its descendants have passed the minimum filter requirement - || hasFilteredDescendants(getRoot()->getFilter()->getMinRequiredGeneration()) - // or not all of its descendants have been checked against minimum filter requirement - || getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration(); -} - -// this does prefix traversal, as folders are listed above their contents -LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children ) -{ - BOOL found_item = FALSE; - - LLFolderViewItem* result = NULL; - // when not starting from a given item, start at beginning - if(item == NULL) - { - found_item = TRUE; - } - - // find current item among children - folders_t::iterator fit = mFolders.begin(); - folders_t::iterator fend = mFolders.end(); - - items_t::iterator iit = mItems.begin(); - items_t::iterator iend = mItems.end(); - - // if not trivially starting at the beginning, we have to find the current item - if (!found_item) - { - // first, look among folders, since they are always above items - for(; fit != fend; ++fit) - { - if(item == (*fit)) - { - found_item = TRUE; - // if we are on downwards traversal - if (include_children && (*fit)->isOpen()) - { - // look for first descendant - return (*fit)->getNextFromChild(NULL, TRUE); - } - // otherwise advance to next folder - ++fit; - include_children = TRUE; - break; - } - } - - // didn't find in folders? Check items... - if (!found_item) - { - for(; iit != iend; ++iit) - { - if(item == (*iit)) - { - found_item = TRUE; - // point to next item - ++iit; - break; - } - } - } - } - - if (!found_item) - { - // you should never call this method with an item that isn't a child - // so we should always find something - llassert(FALSE); - return NULL; - } - - // at this point, either iit or fit point to a candidate "next" item - // if both are out of range, we need to punt up to our parent - - // now, starting from found folder, continue through folders - // searching for next visible folder - while(fit != fend && !(*fit)->getVisible()) - { - // turn on downwards traversal for next folder - ++fit; - } - - if (fit != fend) - { - result = (*fit); - } - else - { - // otherwise, scan for next visible item - while(iit != iend && !(*iit)->getVisible()) - { - ++iit; - } - - // check to see if we have a valid item - if (iit != iend) - { - result = (*iit); - } - } - - if( !result && mParentFolder ) - { - // If there are no siblings or children to go to, recurse up one level in the tree - // and skip children for this folder, as we've already discounted them - result = mParentFolder->getNextFromChild(this, FALSE); - } - - return result; -} - -// this does postfix traversal, as folders are listed above their contents -LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children ) -{ - BOOL found_item = FALSE; - - LLFolderViewItem* result = NULL; - // when not starting from a given item, start at end - if(item == NULL) - { - found_item = TRUE; - } - - // find current item among children - folders_t::reverse_iterator fit = mFolders.rbegin(); - folders_t::reverse_iterator fend = mFolders.rend(); - - items_t::reverse_iterator iit = mItems.rbegin(); - items_t::reverse_iterator iend = mItems.rend(); - - // if not trivially starting at the end, we have to find the current item - if (!found_item) - { - // first, look among items, since they are always below the folders - for(; iit != iend; ++iit) - { - if(item == (*iit)) - { - found_item = TRUE; - // point to next item - ++iit; - break; - } - } - - // didn't find in items? Check folders... - if (!found_item) - { - for(; fit != fend; ++fit) - { - if(item == (*fit)) - { - found_item = TRUE; - // point to next folder - ++fit; - break; - } - } - } - } - - if (!found_item) - { - // you should never call this method with an item that isn't a child - // so we should always find something - llassert(FALSE); - return NULL; - } - - // at this point, either iit or fit point to a candidate "next" item - // if both are out of range, we need to punt up to our parent - - // now, starting from found item, continue through items - // searching for next visible item - while(iit != iend && !(*iit)->getVisible()) - { - ++iit; - } - - if (iit != iend) - { - // we found an appropriate item - result = (*iit); - } - else - { - // otherwise, scan for next visible folder - while(fit != fend && !(*fit)->getVisible()) - { - ++fit; - } - - // check to see if we have a valid folder - if (fit != fend) - { - // try selecting child element of this folder - if ((*fit)->isOpen()) - { - result = (*fit)->getPreviousFromChild(NULL); - } - else - { - result = (*fit); - } - } - } - - if( !result ) - { - // If there are no siblings or children to go to, recurse up one level in the tree - // which gets back to this folder, which will only be visited if it is a valid, visible item - result = this; - } - - return result; -} - //--------------------------------------------------------------------------- @@ -2514,7 +182,7 @@ LLFolderView::LLFolderView(const Params& p) mNeedsAutoRename(FALSE), mDebugFilters(FALSE), mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME), // This gets overridden by a pref immediately - mFilter(p.name), + mFilter( new LLInventoryFilter(p.name) ), mShowSelectionContext(FALSE), mShowSingleSelection(FALSE), mArrangeGeneration(0), @@ -2557,12 +225,12 @@ LLFolderView::LLFolderView(const Params& p) addChild(mRenamer); // make the popup menu available - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory.xml", gMenuHolder); + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if (!menu) { menu = LLUICtrlFactory::getDefaultWidget("inventory_menu"); } - menu->setBackgroundColor(gSavedSkinSettings.getColor("MenuPopupBgColor")); + menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor")); mPopupMenuHandle = menu->getHandle(); } @@ -2600,6 +268,9 @@ LLFolderView::~LLFolderView( void ) mFolders.clear(); mItemMap.clear(); + + delete mFilter; + mFilter = NULL; } BOOL LLFolderView::canFocusChildren() const @@ -2646,7 +317,7 @@ U32 LLFolderView::getSortOrder() const BOOL LLFolderView::addFolder( LLFolderViewFolder* folder) { // enforce sort order of My Inventory followed by Library - if (folder->getListener()->getUUID() == gInventoryLibraryRoot) + if (folder->getListener()->getUUID() == gInventory.getLibraryRootFolderID()) { mFolders.push_back(folder); } @@ -2693,14 +364,15 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen { LLFastTimer t2(LLFastTimer::FTM_ARRANGE); - filter_generation = mFilter.getMinRequiredGeneration(); + filter_generation = mFilter->getMinRequiredGeneration(); mMinWidth = 0; mHasVisibleChildren = hasFilteredDescendants(filter_generation); // arrange always finishes, so optimistically set the arrange generation to the most current mLastArrangeGeneration = getRoot()->getArrangeGeneration(); - LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getShowFolderState(); + LLInventoryFilter::EFolderShow show_folder_state = + getRoot()->getFilter()->getShowFolderState(); S32 total_width = LEFT_PAD; S32 running_height = mDebugFilters ? llceil(sSmallFont->getLineHeight()) : 0; @@ -2781,7 +453,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen const std::string LLFolderView::getFilterSubString(BOOL trim) { - return mFilter.getFilterSubString(trim); + return mFilter->getFilterSubString(trim); } void LLFolderView::filter( LLInventoryFilter& filter ) @@ -2904,7 +576,7 @@ void LLFolderView::setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_foc LLFolderViewItem* itemp = getItemByID(obj_id); if(itemp && itemp->getListener()) { - itemp->getListener()->arrangeAndSet(itemp, TRUE, take_keyboard_focus); + itemp->arrangeAndSet(TRUE, take_keyboard_focus); mSelectThisID.setNull(); return; } @@ -2997,7 +669,7 @@ void LLFolderView::sanitizeSelection() LLFolderViewItem* original_selected_item = getCurSelectedItem(); // Cache "Show all folders" filter setting - BOOL show_all_folders = (getRoot()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS); + BOOL show_all_folders = (getRoot()->getFilter()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS); std::vector items_to_remove; selected_items_t::iterator item_iter; @@ -3087,7 +759,7 @@ void LLFolderView::sanitizeSelection() else { // nothing selected to start with, so pick "My Inventory" as best guess - new_selection = getItemByID(gAgent.getInventoryRootID()); + new_selection = getItemByID(gInventory.getRootFolderID()); } if (new_selection) @@ -3148,11 +820,11 @@ void LLFolderView::commitRename( const LLSD& data ) void LLFolderView::draw() { - static LLCachedControl sSearchStatusColor(gSavedSkinSettings, "InventorySearchStatusColor", DEFAULT_WHITE); + static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", LLColor4::white); if (mDebugFilters) { std::string current_filter_string = llformat("Current Filter: %d, Least Filter: %d, Auto-accept Filter: %d", - mFilter.getCurrentGeneration(), mFilter.getMinRequiredGeneration(), mFilter.getMustPassGeneration()); + mFilter->getCurrentGeneration(), mFilter->getMinRequiredGeneration(), mFilter->getMustPassGeneration()); sSmallFont->renderUTF8(current_filter_string, 0, 2, getRect().getHeight() - sSmallFont->getLineHeight(), LLColor4(0.5f, 0.5f, 0.8f, 1.f), LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE ); @@ -3189,13 +861,14 @@ void LLFolderView::draw() mSearchString.clear(); } - if (hasVisibleChildren() || getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) + if (hasVisibleChildren() + || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) { mStatusText.clear(); } else { - if (gInventory.backgroundFetchActive() || mCompletedFilterGeneration < mFilter.getMinRequiredGeneration()) + if (gInventory.backgroundFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration()) { mStatusText = LLTrans::getString("Searching"); sFont->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE ); @@ -3423,6 +1096,35 @@ void LLFolderView::propertiesSelectedItems( void ) } } +void LLFolderView::changeType(LLInventoryModel *model, LLAssetType::EType new_folder_type) +{ + LLFolderBridge *folder_bridge = LLFolderBridge::sSelf; + + if (!folder_bridge) return; + LLViewerInventoryCategory *cat = folder_bridge->getCategory(); + if (!cat) return; + + const LLUUID &folder_id = cat->getUUID(); + const LLUUID &parent_id = cat->getParentUUID(); + const std::string &name = cat->getName(); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_UpdateInventoryFolder); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_FolderData); + msg->addUUIDFast(_PREHASH_FolderID, folder_id); + msg->addUUIDFast(_PREHASH_ParentID, parent_id); + msg->addS8Fast(_PREHASH_Type, new_folder_type); + msg->addStringFast(_PREHASH_Name, name); + gAgent.sendReliableMessage(); + + cat->setPreferredType(new_folder_type); + gInventory.addChangedMask(LLInventoryObserver::LABEL, folder_id); + gInventory.updateLinkedObjects(folder_id); +} + void LLFolderView::autoOpenItem( LLFolderViewFolder* item ) { if (mAutoOpenItems.check() == item || mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH) @@ -4233,6 +1935,16 @@ bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata) LLInventoryClipboard::instance().reset(); } + static const std::string change_folder_string = "change_folder_type_"; + if (action.length() > change_folder_string.length() && + (action.compare(0,change_folder_string.length(),"change_folder_type_") == 0)) + { + LLAssetType::EType new_folder_type = LLFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length())); + changeType(model, new_folder_type); + return true; + } + + std::set selected_items; getSelectionList(selected_items); @@ -4292,9 +2004,9 @@ void LLFolderView::doIdle() arrangeAll(); } - mFilter.clearModified(); - BOOL filter_modified_and_active = mCompletedFilterGeneration < mFilter.getCurrentGeneration() && - mFilter.isNotDefault(); + mFilter->clearModified(); + BOOL filter_modified_and_active = mCompletedFilterGeneration < mFilter->getCurrentGeneration() && + mFilter->isNotDefault(); mNeedsAutoSelect = filter_modified_and_active && !(gFocusMgr.childHasKeyboardFocus(this) || gFocusMgr.getMouseCapture()); @@ -4335,7 +2047,7 @@ void LLFolderView::doIdle() { scrollToShowItem(mSelectedItems.back()); // continue scrolling until animated layout change is done - if (getCompletedFilterGeneration() >= mFilter.getMinRequiredGeneration() && + if (getCompletedFilterGeneration() >= mFilter->getMinRequiredGeneration() && (!needsArrange() || !is_visible)) { mNeedsScroll = FALSE; @@ -4402,73 +2114,6 @@ void LLFolderView::updateRenamerPosition() ///---------------------------------------------------------------------------- /// Local function definitions ///---------------------------------------------------------------------------- -bool LLInventorySort::updateSort(U32 order) -{ - if (order != mSortOrder) - { - mSortOrder = order; - mByDate = (order & LLInventoryFilter::SO_DATE); - mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP); - mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME); - return true; - } - return false; -} - -bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b) -{ - // We sort by name if we aren't sorting by date - // OR if these are folders and we are sorting folders by name. - bool by_name = (!mByDate - || (mFoldersByName - && (a->getSortGroup() != SG_ITEM))); - - if (a->getSortGroup() != b->getSortGroup()) - { - if (mSystemToTop) - { - // Group order is System Folders, Trash, Normal Folders, Items - return (a->getSortGroup() < b->getSortGroup()); - } - else if (mByDate) - { - // Trash needs to go to the bottom if we are sorting by date - if ( (a->getSortGroup() == SG_TRASH_FOLDER) - || (b->getSortGroup() == SG_TRASH_FOLDER)) - { - return (b->getSortGroup() == SG_TRASH_FOLDER); - } - } - } - - if (by_name) - { - S32 compare = LLStringUtil::compareDict(a->getLabel(), b->getLabel()); - if (0 == compare) - { - return (a->getCreationDate() > b->getCreationDate()); - } - else - { - return (compare < 0); - } - } - else - { - // BUG: This is very very slow. The getCreationDate() is log n in number - // of inventory items. - time_t first_create = a->getCreationDate(); - time_t second_create = b->getCreationDate(); - if (first_create == second_create) - { - return (LLStringUtil::compareDict(a->getLabel(), b->getLabel()) < 0); - } - else - { - return (first_create > second_create); - } - } -} //static void LLFolderView::onRenamerLost( LLFocusableElement* renamer, void* user_data) @@ -4480,6 +2125,42 @@ void LLFolderView::onRenamerLost( LLFocusableElement* renamer, void* user_data) } } +LLInventoryFilter* LLFolderView::getFilter() +{ + return mFilter; +} + +void LLFolderView::setFilterPermMask( PermissionMask filter_perm_mask ) +{ + mFilter->setFilterPermissions(filter_perm_mask); +} + +U32 LLFolderView::getFilterTypes() const +{ + return mFilter->getFilterTypes(); +} + +PermissionMask LLFolderView::getFilterPermissions() const +{ + return mFilter->getFilterPermissions(); +} + +// JAMESDEBUG +//LLInventoryFilter::EFolderShow LLFolderView::getShowFolderState() +//{ +// return mFilter->getShowFolderState(); +//} + +BOOL LLFolderView::isFilterModified() +{ + return mFilter->isNotDefault(); +} + +BOOL LLFolderView::getAllowMultiSelect() +{ + return mAllowMultiSelect; +} + void delete_selected_item(void* user_data) { if(user_data) @@ -4524,610 +2205,3 @@ void properties_selected_items(void* user_data) fv->propertiesSelectedItems(); } } - -///---------------------------------------------------------------------------- -/// Class LLFolderViewEventListener -///---------------------------------------------------------------------------- - -void LLFolderViewEventListener::arrangeAndSet(LLFolderViewItem* focus, - BOOL set_selection, - BOOL take_keyboard_focus) -{ - if(!focus) return; - LLFolderView* root = focus->getRoot(); - focus->getParentFolder()->requestArrange(); - if(set_selection) - { - focus->setSelectionFromRoot(focus, TRUE, take_keyboard_focus); - if(root) - { - root->scrollToShowSelection(); - } - } -} - - -///---------------------------------------------------------------------------- -/// Class LLInventoryFilter -///---------------------------------------------------------------------------- -LLInventoryFilter::LLInventoryFilter(const std::string& name) : - mName(name), - mModified(FALSE), - mNeedTextRebuild(TRUE) -{ - mFilterOps.mFilterTypes = 0xffffffff; - mFilterOps.mMinDate = time_min(); - mFilterOps.mMaxDate = time_max(); - mFilterOps.mHoursAgo = 0; - mFilterOps.mShowFolderState = SHOW_NON_EMPTY_FOLDERS; - mFilterOps.mPermissions = PERM_NONE; - - mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately - - mSubStringMatchOffset = 0; - mFilterSubString.clear(); - mFilterGeneration = 0; - mMustPassGeneration = S32_MAX; - mMinRequiredGeneration = 0; - mFilterCount = 0; - mNextFilterGeneration = mFilterGeneration + 1; - - mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff"); - mFilterBehavior = FILTER_NONE; - - // copy mFilterOps into mDefaultFilterOps - markDefault(); -} - -LLInventoryFilter::~LLInventoryFilter() -{ -} - -BOOL LLInventoryFilter::check(LLFolderViewItem* item) -{ - time_t earliest; - - earliest = time_corrected() - mFilterOps.mHoursAgo * 3600; - if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest) - { - earliest = mFilterOps.mMinDate; - } - else if (!mFilterOps.mHoursAgo) - { - earliest = 0; - } - LLFolderViewEventListener* listener = item->getListener(); - mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos; - BOOL passed = (0x1 << listener->getInventoryType() & mFilterOps.mFilterTypes || listener->getInventoryType() == LLInventoryType::IT_NONE) - && (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos) - && ((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions) - && (listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate); - return passed; -} - -const std::string LLInventoryFilter::getFilterSubString(BOOL trim) -{ - return mFilterSubString; -} - -std::string::size_type LLInventoryFilter::getStringMatchOffset() const -{ - return mSubStringMatchOffset; -} - -// has user modified default filter params? -BOOL LLInventoryFilter::isNotDefault() -{ - return mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes - || mFilterSubString.size() - || mFilterOps.mPermissions != mDefaultFilterOps.mPermissions - || mFilterOps.mMinDate != mDefaultFilterOps.mMinDate - || mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate - || mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo; -} - -BOOL LLInventoryFilter::isActive() -{ - return mFilterOps.mFilterTypes != 0xffffffff - || mFilterSubString.size() - || mFilterOps.mPermissions != PERM_NONE - || mFilterOps.mMinDate != time_min() - || mFilterOps.mMaxDate != time_max() - || mFilterOps.mHoursAgo != 0; -} - -BOOL LLInventoryFilter::isModified() -{ - return mModified; -} - -BOOL LLInventoryFilter::isModifiedAndClear() -{ - BOOL ret = mModified; - mModified = FALSE; - return ret; -} - -void LLInventoryFilter::setFilterTypes(U32 types) -{ - if (mFilterOps.mFilterTypes != types) - { - // keep current items only if no type bits getting turned off - BOOL fewer_bits_set = (mFilterOps.mFilterTypes & ~types); - BOOL more_bits_set = (~mFilterOps.mFilterTypes & types); - - mFilterOps.mFilterTypes = types; - if (more_bits_set && fewer_bits_set) - { - // neither less or more restrive, both simultaneously - // so we need to filter from scratch - setModified(FILTER_RESTART); - } - else if (more_bits_set) - { - // target is only one of all requested types so more type bits == less restrictive - setModified(FILTER_LESS_RESTRICTIVE); - } - else if (fewer_bits_set) - { - setModified(FILTER_MORE_RESTRICTIVE); - } - - } -} - -void LLInventoryFilter::setFilterSubString(const std::string& string) -{ - if (mFilterSubString != string) - { - // hitting BACKSPACE, for example - BOOL less_restrictive = mFilterSubString.size() >= string.size() && !mFilterSubString.substr(0, string.size()).compare(string); - // appending new characters - BOOL more_restrictive = mFilterSubString.size() < string.size() && !string.substr(0, mFilterSubString.size()).compare(mFilterSubString); - mFilterSubString = string; - LLStringUtil::toUpper(mFilterSubString); - LLStringUtil::trimHead(mFilterSubString); - - if (less_restrictive) - { - setModified(FILTER_LESS_RESTRICTIVE); - } - else if (more_restrictive) - { - setModified(FILTER_MORE_RESTRICTIVE); - } - else - { - setModified(FILTER_RESTART); - } - } -} - -void LLInventoryFilter::setFilterPermissions(PermissionMask perms) -{ - if (mFilterOps.mPermissions != perms) - { - // keep current items only if no perm bits getting turned off - BOOL fewer_bits_set = (mFilterOps.mPermissions & ~perms); - BOOL more_bits_set = (~mFilterOps.mPermissions & perms); - mFilterOps.mPermissions = perms; - - if (more_bits_set && fewer_bits_set) - { - setModified(FILTER_RESTART); - } - else if (more_bits_set) - { - // target must have all requested permission bits, so more bits == more restrictive - setModified(FILTER_MORE_RESTRICTIVE); - } - else if (fewer_bits_set) - { - setModified(FILTER_LESS_RESTRICTIVE); - } - } -} - -void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date) -{ - mFilterOps.mHoursAgo = 0; - if (mFilterOps.mMinDate != min_date) - { - mFilterOps.mMinDate = min_date; - setModified(); - } - if (mFilterOps.mMaxDate != llmax(mFilterOps.mMinDate, max_date)) - { - mFilterOps.mMaxDate = llmax(mFilterOps.mMinDate, max_date); - setModified(); - } -} - -void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl) -{ - if (sl && !isSinceLogoff()) - { - setDateRange(mLastLogoff, time_max()); - setModified(); - } - if (!sl && isSinceLogoff()) - { - setDateRange(0, time_max()); - setModified(); - } -} - -BOOL LLInventoryFilter::isSinceLogoff() -{ - return (mFilterOps.mMinDate == (time_t)mLastLogoff) && - (mFilterOps.mMaxDate == time_max()); -} - -void LLInventoryFilter::setHoursAgo(U32 hours) -{ - if (mFilterOps.mHoursAgo != hours) - { - // *NOTE: need to cache last filter time, in case filter goes stale - BOOL less_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours > mFilterOps.mHoursAgo); - BOOL more_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours <= mFilterOps.mHoursAgo); - mFilterOps.mHoursAgo = hours; - mFilterOps.mMinDate = time_min(); - mFilterOps.mMaxDate = time_max(); - if (less_restrictive) - { - setModified(FILTER_LESS_RESTRICTIVE); - } - else if (more_restrictive) - { - setModified(FILTER_MORE_RESTRICTIVE); - } - else - { - setModified(FILTER_RESTART); - } - } -} -void LLInventoryFilter::setShowFolderState(EFolderShow state) -{ - if (mFilterOps.mShowFolderState != state) - { - mFilterOps.mShowFolderState = state; - if (state == SHOW_NON_EMPTY_FOLDERS) - { - // showing fewer folders than before - setModified(FILTER_MORE_RESTRICTIVE); - } - else if (state == SHOW_ALL_FOLDERS) - { - // showing same folders as before and then some - setModified(FILTER_LESS_RESTRICTIVE); - } - else - { - setModified(); - } - } -} - -void LLInventoryFilter::setSortOrder(U32 order) -{ - if (mOrder != order) - { - mOrder = order; - setModified(); - } -} - -void LLInventoryFilter::markDefault() -{ - mDefaultFilterOps = mFilterOps; -} - -void LLInventoryFilter::resetDefault() -{ - mFilterOps = mDefaultFilterOps; - setModified(); -} - -void LLInventoryFilter::setModified(EFilterBehavior behavior) -{ - mModified = TRUE; - mNeedTextRebuild = TRUE; - mFilterGeneration = mNextFilterGeneration++; - - if (mFilterBehavior == FILTER_NONE) - { - mFilterBehavior = behavior; - } - else if (mFilterBehavior != behavior) - { - // trying to do both less restrictive and more restrictive filter - // basically means restart from scratch - mFilterBehavior = FILTER_RESTART; - } - - if (isNotDefault()) - { - // if not keeping current filter results, update last valid as well - switch(mFilterBehavior) - { - case FILTER_RESTART: - mMustPassGeneration = mFilterGeneration; - mMinRequiredGeneration = mFilterGeneration; - break; - case FILTER_LESS_RESTRICTIVE: - mMustPassGeneration = mFilterGeneration; - break; - case FILTER_MORE_RESTRICTIVE: - mMinRequiredGeneration = mFilterGeneration; - // must have passed either current filter generation (meaningless, as it hasn't been run yet) - // or some older generation, so keep the value - mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration); - break; - default: - llerrs << "Bad filter behavior specified" << llendl; - } - } - else - { - // shortcut disabled filters to show everything immediately - mMinRequiredGeneration = 0; - mMustPassGeneration = S32_MAX; - } -} - -BOOL LLInventoryFilter::isFilterWith(LLInventoryType::EType t) -{ - return mFilterOps.mFilterTypes & (0x01 << t); -} - -std::string LLInventoryFilter::getFilterText() -{ - if (!mNeedTextRebuild) - { - return mFilterText; - } - - mNeedTextRebuild = FALSE; - std::string filtered_types; - std::string not_filtered_types; - BOOL filtered_by_type = FALSE; - BOOL filtered_by_all_types = TRUE; - S32 num_filter_types = 0; - mFilterText.clear(); - - if (isFilterWith(LLInventoryType::IT_ANIMATION)) - { - //filtered_types += " Animations,"; - filtered_types += LLTrans::getString("Animations"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Animations,"; - not_filtered_types += LLTrans::getString("Animations"); - - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_CALLINGCARD)) - { - //filtered_types += " Calling Cards,"; - filtered_types += LLTrans::getString("Calling Cards"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Calling Cards,"; - not_filtered_types += LLTrans::getString("Calling Cards"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_WEARABLE)) - { - //filtered_types += " Clothing,"; - filtered_types += LLTrans::getString("Clothing"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Clothing,"; - not_filtered_types += LLTrans::getString("Clothing"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_GESTURE)) - { - //filtered_types += " Gestures,"; - filtered_types += LLTrans::getString("Gestures"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Gestures,"; - not_filtered_types += LLTrans::getString("Gestures"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_LANDMARK)) - { - //filtered_types += " Landmarks,"; - filtered_types += LLTrans::getString("Landmarks"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Landmarks,"; - not_filtered_types += LLTrans::getString("Landmarks"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_NOTECARD)) - { - //filtered_types += " Notecards,"; - filtered_types += LLTrans::getString("Notecards"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Notecards,"; - not_filtered_types += LLTrans::getString("Notecards"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_OBJECT) && isFilterWith(LLInventoryType::IT_ATTACHMENT)) - { - //filtered_types += " Objects,"; - filtered_types += LLTrans::getString("Objects"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Objects,"; - not_filtered_types += LLTrans::getString("Objects"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_LSL)) - { - //filtered_types += " Scripts,"; - filtered_types += LLTrans::getString("Scripts"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Scripts,"; - not_filtered_types += LLTrans::getString("Scripts"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_SOUND)) - { - //filtered_types += " Sounds,"; - filtered_types += LLTrans::getString("Sounds"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Sounds,"; - not_filtered_types += LLTrans::getString("Sounds"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_TEXTURE)) - { - //filtered_types += " Textures,"; - filtered_types += LLTrans::getString("Textures"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Textures,"; - not_filtered_types += LLTrans::getString("Textures"); - filtered_by_all_types = FALSE; - } - - if (isFilterWith(LLInventoryType::IT_SNAPSHOT)) - { - //filtered_types += " Snapshots,"; - filtered_types += LLTrans::getString("Snapshots"); - filtered_by_type = TRUE; - num_filter_types++; - } - else - { - //not_filtered_types += " Snapshots,"; - not_filtered_types += LLTrans::getString("Snapshots"); - filtered_by_all_types = FALSE; - } - - if (!gInventory.backgroundFetchActive() && filtered_by_type && !filtered_by_all_types) - { - mFilterText += " - "; - if (num_filter_types < 5) - { - mFilterText += filtered_types; - } - else - { - //mFilterText += "No "; - mFilterText += LLTrans::getString("No Filters"); - mFilterText += not_filtered_types; - } - // remove the ',' at the end - mFilterText.erase(mFilterText.size() - 1, 1); - } - - if (isSinceLogoff()) - { - //mFilterText += " - Since Logoff"; - mFilterText += LLTrans::getString("Since Logoff"); - } - return mFilterText; -} - -void LLInventoryFilter::toLLSD(LLSD& data) -{ - data["filter_types"] = (LLSD::Integer)getFilterTypes(); - data["min_date"] = (LLSD::Integer)getMinDate(); - data["max_date"] = (LLSD::Integer)getMaxDate(); - data["hours_ago"] = (LLSD::Integer)getHoursAgo(); - data["show_folder_state"] = (LLSD::Integer)getShowFolderState(); - data["permissions"] = (LLSD::Integer)getFilterPermissions(); - data["substring"] = (LLSD::String)getFilterSubString(); - data["sort_order"] = (LLSD::Integer)getSortOrder(); - data["since_logoff"] = (LLSD::Boolean)isSinceLogoff(); -} - -void LLInventoryFilter::fromLLSD(LLSD& data) -{ - if(data.has("filter_types")) - { - setFilterTypes((U32)data["filter_types"].asInteger()); - } - - if(data.has("min_date") && data.has("max_date")) - { - setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger()); - } - - if(data.has("hours_ago")) - { - setHoursAgo((U32)data["hours_ago"].asInteger()); - } - - if(data.has("show_folder_state")) - { - setShowFolderState((EFolderShow)data["show_folder_state"].asInteger()); - } - - if(data.has("permissions")) - { - setFilterPermissions((PermissionMask)data["permissions"].asInteger()); - } - - if(data.has("substring")) - { - setFilterSubString(std::string(data["substring"].asString())); - } - - if(data.has("sort_order")) - { - setSortOrder((U32)data["sort_order"].asInteger()); - } - - if(data.has("since_logoff")) - { - setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean()); - } -} diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 3386a7fb0e..8d9d52cd17 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -41,6 +41,7 @@ #ifndef LL_LLFOLDERVIEW_H #define LL_LLFOLDERVIEW_H +// JAMESDEBUG - trim this list #include #include #include @@ -54,99 +55,11 @@ #include "stdenums.h" #include "llfontgl.h" #include "lleditmenuhandler.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "lldepthstack.h" #include "lltooldraganddrop.h" - -class LLMenuGL; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewEventListener -// -// This is an abstract base class that users of the folderview classes -// would use to catch the useful events emitted from the folder -// views. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - -class LLFolderViewItem; -class LLFolderView; -class LLInventoryModel; -class LLScrollContainer; - -class LLFolderViewEventListener -{ -public: - virtual ~LLFolderViewEventListener( void ) {} - virtual const std::string& getName() const = 0; - virtual const std::string& getDisplayName() const = 0; - virtual const LLUUID& getUUID() const = 0; - virtual time_t getCreationDate() const = 0; // UTC seconds - virtual PermissionMask getPermissionMask() const = 0; - virtual LLAssetType::EType getPreferredType() const {return LLAssetType::AT_NONE;}; - virtual LLUIImagePtr getIcon() const = 0; - virtual LLFontGL::StyleFlags getLabelStyle() const = 0; - virtual std::string getLabelSuffix() const = 0; - virtual void openItem( void ) = 0; - virtual void previewItem( void ) = 0; - virtual void selectItem(void) = 0; - virtual void showProperties(void) = 0; - virtual BOOL isItemRenameable() const = 0; - virtual BOOL renameItem(const std::string& new_name) = 0; - virtual BOOL isItemMovable( void ) = 0; // Can be moved to another folder - virtual BOOL isItemRemovable( void ) = 0; // Can be destroyed - virtual BOOL removeItem() = 0; - virtual void removeBatch(LLDynamicArray& batch) = 0; - virtual void move( LLFolderViewEventListener* parent_listener ) = 0; - virtual BOOL isItemCopyable() const = 0; - virtual BOOL copyToClipboard() const = 0; - virtual void cutToClipboard() = 0; - virtual BOOL isClipboardPasteable() const = 0; - virtual void pasteFromClipboard() = 0; - virtual void pasteLinkFromClipboard() = 0; - virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0; - virtual BOOL isUpToDate() const = 0; - virtual BOOL hasChildren() const = 0; - virtual LLInventoryType::EType getInventoryType() const = 0; - virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) {} - - // This method should be called when a drag begins. returns TRUE - // if the drag can begin, otherwise FALSE. - virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0; - - // This method will be called to determine if a drop can be - // performed, and will set drop to TRUE if a drop is - // requested. Returns TRUE if a drop is possible/happened, - // otherwise FALSE. - virtual BOOL dragOrDrop(MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data) = 0; - - // This method is called when the object being referenced by the - // bridge is actually dropped. This allows for cleanup of the old - // view, reference counting, etc. -// virtual void dropped() = 0; - - // this method accesses the parent and arranges and sets it as - // specified. - void arrangeAndSet(LLFolderViewItem* focus, BOOL set_selection, - BOOL take_keyboard_focus = TRUE); -}; - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewListenerFunctor -// -// This simple abstract base class can be used to applied to all -// listeners in a hierarchy. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLFolderViewListenerFunctor -{ -public: - virtual ~LLFolderViewListenerFunctor() {} - virtual void operator()(LLFolderViewEventListener* listener) = 0; -}; +// JAMESDEBUG - move this up +#include "llfolderviewitem.h" // because LLFolderView is-a LLFolderViewFolder //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFolderViewFunctor @@ -168,571 +81,6 @@ public: virtual void doItem(LLFolderViewItem* item) = 0; }; -class LLInventoryFilter -{ -public: - typedef enum e_folder_show - { - SHOW_ALL_FOLDERS, - SHOW_NON_EMPTY_FOLDERS, - SHOW_NO_FOLDERS - } EFolderShow; - - typedef enum e_filter_behavior - { - FILTER_NONE, // nothing to do, already filtered - FILTER_RESTART, // restart filtering from scratch - FILTER_LESS_RESTRICTIVE, // existing filtered items will certainly pass this filter - FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one - } EFilterBehavior; - - static const U32 SO_DATE = 1; - static const U32 SO_FOLDERS_BY_NAME = 2; - static const U32 SO_SYSTEM_FOLDERS_TO_TOP = 4; - - LLInventoryFilter(const std::string& name); - virtual ~LLInventoryFilter(); - - void setFilterTypes(U32 types); - U32 getFilterTypes() const { return mFilterOps.mFilterTypes; } - - void setFilterSubString(const std::string& string); - const std::string getFilterSubString(BOOL trim = FALSE); - - void setFilterPermissions(PermissionMask perms); - PermissionMask getFilterPermissions() const { return mFilterOps.mPermissions; } - - void setDateRange(time_t min_date, time_t max_date); - void setDateRangeLastLogoff(BOOL sl); - time_t getMinDate() const { return mFilterOps.mMinDate; } - time_t getMaxDate() const { return mFilterOps.mMaxDate; } - - void setHoursAgo(U32 hours); - U32 getHoursAgo() const { return mFilterOps.mHoursAgo; } - - void setShowFolderState( EFolderShow state); - EFolderShow getShowFolderState() { return mFilterOps.mShowFolderState; } - - void setSortOrder(U32 order); - U32 getSortOrder() { return mOrder; } - - BOOL check(LLFolderViewItem* item); - std::string::size_type getStringMatchOffset() const; - BOOL isActive(); - BOOL isNotDefault(); - BOOL isModified(); - BOOL isModifiedAndClear(); - BOOL isSinceLogoff(); - void clearModified() { mModified = FALSE; mFilterBehavior = FILTER_NONE; } - const std::string getName() const { return mName; } - std::string getFilterText(); - - void setFilterCount(S32 count) { mFilterCount = count; } - S32 getFilterCount() { return mFilterCount; } - void decrementFilterCount() { mFilterCount--; } - - void markDefault(); - void resetDefault(); - - BOOL isFilterWith(LLInventoryType::EType t); - - S32 getCurrentGeneration() const { return mFilterGeneration; } - S32 getMinRequiredGeneration() const { return mMinRequiredGeneration; } - S32 getMustPassGeneration() const { return mMustPassGeneration; } - - //RN: this is public to allow system to externally force a global refilter - void setModified(EFilterBehavior behavior = FILTER_RESTART); - - void toLLSD(LLSD& data); - void fromLLSD(LLSD& data); - -protected: - struct filter_ops - { - U32 mFilterTypes; - time_t mMinDate; - time_t mMaxDate; - U32 mHoursAgo; - EFolderShow mShowFolderState; - PermissionMask mPermissions; - }; - filter_ops mFilterOps; - filter_ops mDefaultFilterOps; - std::string::size_type mSubStringMatchOffset; - std::string mFilterSubString; - U32 mOrder; - const std::string mName; - S32 mFilterGeneration; - S32 mMustPassGeneration; - S32 mMinRequiredGeneration; - S32 mFilterCount; - S32 mNextFilterGeneration; - EFilterBehavior mFilterBehavior; - -private: - U32 mLastLogoff; - BOOL mModified; - BOOL mNeedTextRebuild; - std::string mFilterText; -}; - -// These are grouping of inventory types. -// Order matters when sorting system folders to the top. -enum EInventorySortGroup -{ - SG_SYSTEM_FOLDER, - SG_TRASH_FOLDER, - SG_NORMAL_FOLDER, - SG_ITEM -}; - -class LLInventorySort -{ -public: - LLInventorySort() - : mSortOrder(0), - mByDate(false), - mSystemToTop(false), - mFoldersByName(false) { } - - // Returns true if order has changed - bool updateSort(U32 order); - U32 getSort() { return mSortOrder; } - - bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b); -private: - U32 mSortOrder; - bool mByDate; - bool mSystemToTop; - bool mFoldersByName; -}; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewItem -// -// An instance of this class represents a single item in a folder view -// such as an inventory item or a file. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLFontGL; -class LLFolderViewFolder; -class LLFolderView; - -class LLFolderViewItem : public LLView -{ -public: - static void initClass(); - static void cleanupClass(); - struct Params : public LLInitParam::Block - { - Optional icon; - Optional root; - Optional listener; - - Optional folder_arrow_image; - Optional selection_image; - - Optional creation_date; //UTC seconds - Params() - : folder_arrow_image("", LLUI::getUIImage("folder_arrow.tga")), - selection_image("", LLUI::getUIImage("rounded_square.tga")) - { - mouse_opaque(true); - follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP|FOLLOWS_RIGHT); - tab_stop(false); - } - }; - -protected: - friend class LLUICtrlFactory; - friend class LLFolderViewEventListener; - - LLFolderViewItem(Params = LLFolderViewItem::Params()); - - static const LLFontGL* sFont; - static const LLFontGL* sSmallFont; - static LLUIImagePtr sArrowImage; - static LLUIImagePtr sBoxImage; - std::string mLabel; - std::string mSearchableLabel; - S32 mLabelWidth; - bool mLabelWidthDirty; - time_t mCreationDate; - LLFolderViewFolder* mParentFolder; - LLFolderViewEventListener* mListener; - BOOL mIsSelected; - BOOL mIsCurSelection; - BOOL mSelectPending; - LLFontGL::StyleFlags mLabelStyle; - std::string mLabelSuffix; - LLUIImagePtr mIcon; - std::string mStatusText; - BOOL mHasVisibleChildren; - S32 mIndentation; - S32 mNumDescendantsSelected; - BOOL mFiltered; - S32 mLastFilterGeneration; - std::string::size_type mStringMatchOffset; - F32 mControlLabelRotation; - LLFolderView* mRoot; - BOOL mDragAndDropTarget; - LLUIImagePtr mArrowImage; - LLUIImagePtr mBoxImage; - BOOL mIsLoading; - LLTimer mTimeSinceRequestStart; - - // This function clears the currently selected item, and records - // the specified selected item appropriately for display and use - // in the UI. If open is TRUE, then folders are opened up along - // the way to the selection. - void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus = TRUE); - - // helper function to change the selection from the root. - void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected); - - // helper function to change the selection from the root. - void extendSelectionFromRoot(LLFolderViewItem* selection); - - // this is an internal method used for adding items to folders. A - // no-op at this leve, but reimplemented in derived classes. - virtual BOOL addItem(LLFolderViewItem*) { return FALSE; } - virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; } - -public: - // This function is called when the folder view is dirty. It's - // implemented here but called by derived classes when folding the - // views. - void arrangeFromRoot(); - void filterFromRoot( void ); - - virtual ~LLFolderViewItem( void ); - - // addToFolder() returns TRUE if it succeeds. FALSE otherwise - enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE }; - virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); - - virtual EInventorySortGroup getSortGroup() const; - - // Finds width and height of this object and it's children. Also - // makes sure that this view and it's children are the right size. - virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); - virtual S32 getItemHeight(); - - // applies filters to control visibility of inventory items - virtual void filter( LLInventoryFilter& filter); - - // updates filter serial number and optionally propagated value up to root - S32 getLastFilterGeneration() { return mLastFilterGeneration; } - - virtual void dirtyFilter(); - - // If the selection is 'this' then note that otherwise - // ignore. Returns TRUE if this object was affected. If open is - // TRUE, then folders are opened up along the way to the - // selection. - virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus); - - // This method is used to toggle the selection of an item. If - // selection is 'this', then note selection, and return TRUE. - virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); - - // this method is used to group select items - virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray& items){ return FALSE; } - - // this method is used to group select items - virtual void recursiveDeselect(BOOL deselect_self); - - // gets multiple-element selection - virtual BOOL getSelectionList(std::set &selection){return TRUE;} - - // Returns true is this object and all of its children can be removed (deleted by user) - virtual BOOL isRemovable(); - - // Returns true is this object and all of its children can be moved - virtual BOOL isMovable(); - - // destroys this item recursively - virtual void destroyView(); - - S32 getNumSelectedDescendants() { return mNumDescendantsSelected; } - - BOOL isSelected() { return mIsSelected; } - - void setIsCurSelection(BOOL select) { mIsCurSelection = select; } - - BOOL getIsCurSelection() { return mIsCurSelection; } - - BOOL hasVisibleChildren() { return mHasVisibleChildren; } - - // Call through to the viewed object and return true if it can be - // removed. Returns true if it's removed. - //virtual BOOL removeRecursively(BOOL single_item); - BOOL remove(); - - // Build an appropriate context menu for the item. Flags unused. - void buildContextMenu(LLMenuGL& menu, U32 flags); - - // This method returns the actual name of the thing being - // viewed. This method will ask the viewed object itself. - const std::string& getName( void ) const; - - const std::string& getSearchableLabel( void ) const; - - // This method returns the label displayed on the view. This - // method was primarily added to allow sorting on the folder - // contents possible before the entire view has been constructed. - const std::string& getLabel() const { return mLabel; } - - // Used for sorting, like getLabel() above. - virtual time_t getCreationDate() const { return mCreationDate; } - - LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; } - const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; } - - LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE ); - LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE ); - - const LLFolderViewEventListener* getListener( void ) const { return mListener; } - LLFolderViewEventListener* getListener( void ) { return mListener; } - - // just rename the object. - void rename(const std::string& new_name); - - // open - virtual void openItem( void ); - virtual void preview(void); - - // Show children (unfortunate that this is called "open") - virtual void setOpen(BOOL open = TRUE) {}; - - virtual BOOL isOpen() { return FALSE; } - - virtual LLFolderView* getRoot(); - BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor ); - S32 getIndentation() { return mIndentation; } - - virtual BOOL potentiallyVisible(); // do we know for a fact that this item has been filtered out? - - virtual BOOL getFiltered(); - virtual BOOL getFiltered(S32 filter_generation); - virtual void setFiltered(BOOL filtered, S32 filter_generation); - - // change the icon - void setIcon(LLUIImagePtr icon); - - // refresh information from the object being viewed. - void refreshFromListener(); - virtual void refresh(); - - virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor); - - // LLView functionality - virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleHover( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); - virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); - virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); - - // virtual void handleDropped(); - virtual void draw(); - virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg); -}; - - -// function used for sorting. -typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b); - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewFolder -// -// An instance of an LLFolderViewFolder represents a collection of -// more folders and items. This is used to build the hierarchy of -// items found in the folder view. :) -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLFolderViewFolder : public LLFolderViewItem -{ -protected: - LLFolderViewFolder( const LLFolderViewItem::Params& ); - friend class LLUICtrlFactory; - -public: - typedef enum e_trash - { - UNKNOWN, TRASH, NOT_TRASH - } ETrash; - -protected: - typedef std::list items_t; - typedef std::list folders_t; - items_t mItems; - folders_t mFolders; - LLInventorySort mSortFunction; - - BOOL mIsOpen; - BOOL mExpanderHighlighted; - F32 mCurHeight; - F32 mTargetHeight; - F32 mAutoOpenCountdown; - time_t mSubtreeCreationDate; - mutable ETrash mAmTrash; - S32 mLastArrangeGeneration; - S32 mLastCalculatedWidth; - S32 mCompletedFilterGeneration; - S32 mMostFilteredDescendantGeneration; - bool mNeedsSort; -public: - typedef enum e_recurse_type - { - RECURSE_NO, - RECURSE_UP, - RECURSE_DOWN, - RECURSE_UP_DOWN - } ERecurseType; - - - virtual ~LLFolderViewFolder( void ); - - virtual BOOL potentiallyVisible(); - - LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE ); - LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE ); - - // addToFolder() returns TRUE if it succeeds. FALSE otherwise - virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); - - // Finds width and height of this object and it's children. Also - // makes sure that this view and it's children are the right size. - virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); - - BOOL needsArrange(); - void requestSort(); - - // Returns the sort group (system, trash, folder) for this folder. - virtual EInventorySortGroup getSortGroup() const; - - virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up); - virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; } - - BOOL hasFilteredDescendants(S32 filter_generation) { return mMostFilteredDescendantGeneration >= filter_generation; } - BOOL hasFilteredDescendants(); - - // applies filters to control visibility of inventory items - virtual void filter( LLInventoryFilter& filter); - virtual void setFiltered(BOOL filtered, S32 filter_generation); - virtual void dirtyFilter(); - - // Passes selection information on to children and record - // selection information if necessary. Returns TRUE if this object - // (or a child) was affected. - virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus); - - // This method is used to change the selection of an item. If - // selection is 'this', then note selection as true. Returns TRUE - // if this or a child is now selected. - virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); - - // this method is used to group select items - virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray& items); - - virtual void recursiveDeselect(BOOL deselect_self); - - // Returns true is this object and all of its children can be removed. - virtual BOOL isRemovable(); - - // Returns true is this object and all of its children can be moved - virtual BOOL isMovable(); - - // destroys this folder, and all children - virtual void destroyView(); - - // If this folder can be removed, remove all children that can be - // removed, return TRUE if this is empty after the operation and - // it's viewed folder object can be removed. - //virtual BOOL removeRecursively(BOOL single_item); - //virtual BOOL remove(); - - // remove the specified item (and any children) if - // possible. Return TRUE if the item was deleted. - BOOL removeItem(LLFolderViewItem* item); - - // simply remove the view (and any children) Don't bother telling - // the listeners. - void removeView(LLFolderViewItem* item); - - // extractItem() removes the specified item from the folder, but - // doesn't delete it. - void extractItem( LLFolderViewItem* item ); - - // This function is called by a child that needs to be resorted. - void resort(LLFolderViewItem* item); - - void setItemSortOrder(U32 ordering); - void sortBy(U32); - //BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b)); - - void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; } - - // folders can be opened. This will usually be called by internal - // methods. - virtual void toggleOpen(); - - // Force a folder open or closed - virtual void setOpen(BOOL openitem = TRUE); - - // Called when a child is refreshed. - // don't rearrange child folder contents unless explicitly requested - virtual void requestArrange(BOOL include_descendants = FALSE); - - // internal method which doesn't update the entire view. This - // method was written because the list iterators destroy the state - // of other iterations, thus, we can't arrange while iterating - // through the children (such as when setting which is selected. - virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO); - - // Get the current state of the folder. - virtual BOOL isOpen() { return mIsOpen; } - - // special case if an object is dropped on the child. - BOOL handleDragAndDropFromChild(MASK mask, - BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg); - - void applyFunctorRecursively(LLFolderViewFunctor& functor); - virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor); - - virtual void openItem( void ); - virtual BOOL addItem(LLFolderViewItem* item); - virtual BOOL addFolder( LLFolderViewFolder* folder); - - // LLView functionality - virtual BOOL handleHover(S32 x, S32 y, MASK mask); - virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); - virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg); - virtual void draw(); - - time_t getCreationDate() const; - bool isTrash() const; -}; - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFolderView @@ -741,8 +89,12 @@ public: // manages the screen region of the folder view. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLUICtrl; +class LLFolderViewEventListener; +class LLInventoryModel; class LLLineEditor; +class LLMenuGL; +class LLScrollContainer; +class LLUICtrl; class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler { @@ -765,21 +117,23 @@ public: // and resort the items if necessary. void setSortOrder(U32 order); void checkTreeResortForModelChanged(); - void setFilterPermMask(PermissionMask filter_perm_mask) { mFilter.setFilterPermissions(filter_perm_mask); } + void setFilterPermMask(PermissionMask filter_perm_mask); void setAllowMultiSelect(BOOL allow) { mAllowMultiSelect = allow; } typedef boost::signals2::signal& items, BOOL user_action)> signal_t; void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); } void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); } - LLInventoryFilter* getFilter() { return &mFilter; } + // filter is never null + LLInventoryFilter* getFilter(); const std::string getFilterSubString(BOOL trim = FALSE); - U32 getFilterTypes() const { return mFilter.getFilterTypes(); } - PermissionMask getFilterPermissions() const { return mFilter.getFilterPermissions(); } - LLInventoryFilter::EFolderShow getShowFolderState() { return mFilter.getShowFolderState(); } + U32 getFilterTypes() const; + PermissionMask getFilterPermissions() const; + // JAMESDEBUG use getFilter()->getShowFolderState(); + //LLInventoryFilter::EFolderShow getShowFolderState(); U32 getSortOrder() const; - BOOL isFilterModified() { return mFilter.isNotDefault(); } - BOOL getAllowMultiSelect() { return mAllowMultiSelect; } + BOOL isFilterModified(); + BOOL getAllowMultiSelect(); // Close all folders in the view void closeAllFolders(); @@ -836,6 +190,9 @@ public: void openSelectedItems( void ); void propertiesSelectedItems( void ); + // change the folder type + void changeType(LLInventoryModel *model, LLAssetType::EType new_folder_type); + void autoOpenItem(LLFolderViewFolder* item); void closeAutoOpenedFolders(); BOOL autoOpenTest(LLFolderViewFolder* item); @@ -914,7 +271,7 @@ public: LLPanel* getParentPanel() { return mParentPanel; } // DEBUG only void dumpSelectionInformation(); - + private: void updateRenamerPosition(); @@ -955,7 +312,7 @@ protected: LLFrameTimer mAutoOpenTimer; LLFrameTimer mSearchTimer; std::string mSearchString; - LLInventoryFilter mFilter; + LLInventoryFilter* mFilter; BOOL mShowSelectionContext; BOOL mShowSingleSelection; LLFrameTimer mMultiSelectionFadeTimer; diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h new file mode 100644 index 0000000000..eb06123b46 --- /dev/null +++ b/indra/newview/llfoldervieweventlistener.h @@ -0,0 +1,100 @@ +/** + * @file llfoldervieweventlistener.h + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#ifndef LLFOLDERVIEWEVENTLISTENER_H +#define LLFOLDERVIEWEVENTLISTENER_H + +#include "lldarray.h" // JAMESDEBUG convert to std::vector +#include "llfontgl.h" // just for StyleFlags enum +#include "llpointer.h" + + +class LLFolderViewItem; +class LLFolderView; +class LLFontGL; +class LLInventoryModel; +class LLMenuGL; +class LLScrollContainer; +class LLUIImage; +class LLUUID; + +// This is an abstract base class that users of the folderview classes +// would use to catch the useful events emitted from the folder +// views. +class LLFolderViewEventListener +{ +public: + virtual ~LLFolderViewEventListener( void ) {} + virtual const std::string& getName() const = 0; + virtual const std::string& getDisplayName() const = 0; + virtual const LLUUID& getUUID() const = 0; + virtual time_t getCreationDate() const = 0; // UTC seconds + virtual PermissionMask getPermissionMask() const = 0; + virtual LLAssetType::EType getPreferredType() const = 0; + virtual LLPointer getIcon() const = 0; + virtual LLFontGL::StyleFlags getLabelStyle() const = 0; + virtual std::string getLabelSuffix() const = 0; + virtual void openItem( void ) = 0; + virtual void previewItem( void ) = 0; + virtual void selectItem(void) = 0; + virtual void showProperties(void) = 0; + virtual BOOL isItemRenameable() const = 0; + virtual BOOL renameItem(const std::string& new_name) = 0; + virtual BOOL isItemMovable( void ) = 0; // Can be moved to another folder + virtual BOOL isItemRemovable( void ) = 0; // Can be destroyed + virtual BOOL removeItem() = 0; + virtual void removeBatch(LLDynamicArray& batch) = 0; + virtual void move( LLFolderViewEventListener* parent_listener ) = 0; + virtual BOOL isItemCopyable() const = 0; + virtual BOOL copyToClipboard() const = 0; + virtual void cutToClipboard() = 0; + virtual BOOL isClipboardPasteable() const = 0; + virtual void pasteFromClipboard() = 0; + virtual void pasteLinkFromClipboard() = 0; + virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0; + virtual BOOL isUpToDate() const = 0; + virtual BOOL hasChildren() const = 0; + virtual LLInventoryType::EType getInventoryType() const = 0; + virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) = 0; + + // This method should be called when a drag begins. returns TRUE + // if the drag can begin, otherwise FALSE. + virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0; + + // This method will be called to determine if a drop can be + // performed, and will set drop to TRUE if a drop is + // requested. Returns TRUE if a drop is possible/happened, + // otherwise FALSE. + virtual BOOL dragOrDrop(MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data) = 0; +}; + +#endif diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp new file mode 100644 index 0000000000..a6a8da2a76 --- /dev/null +++ b/indra/newview/llfolderviewitem.cpp @@ -0,0 +1,2475 @@ +/** +* @file llfolderviewitem.cpp +* @brief Items and folders that can appear in a hierarchical folder view +* +* $LicenseInfo:firstyear=2001&license=viewergpl$ +* +* Copyright (c) 2001-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#include "llviewerprecompiledheaders.h" + +#include "llfolderviewitem.h" + +// viewer includes +#include "llfolderview.h" // Items depend extensively on LLFolderViews +#include "llfoldervieweventlistener.h" +#include "llinventoryfilter.h" +#include "llinventorymodel.h" // *TODO: make it take a pointer to an inventory-model interface +#include "llviewercontrol.h" // gSavedSettings +#include "llviewerwindow.h" // Argh, only for setCursor() + +// linden library includes +#include "llfocusmgr.h" // gFocusMgr +#include "llpanel.h" // panel->hasFocus() +#include "lltrans.h" + +///---------------------------------------------------------------------------- +/// Class LLFolderViewItem +///---------------------------------------------------------------------------- + +// statics +const LLFontGL* LLFolderViewItem::sFont = NULL; +const LLFontGL* LLFolderViewItem::sSmallFont = NULL; +LLUIImagePtr LLFolderViewItem::sArrowImage; +LLUIImagePtr LLFolderViewItem::sBoxImage; + +// only integers can be initialized in header +const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f; +const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f; + +const LLColor4U DEFAULT_WHITE(255, 255, 255); + +//static +void LLFolderViewItem::initClass() +{ + sFont = LLFontGL::getFontSansSerifSmall(); + sSmallFont = LLFontGL::getFontMonospace(); + sArrowImage = LLUI::getUIImage("folder_arrow.tga"); + sBoxImage = LLUI::getUIImage("rounded_square.tga"); +} + +//static +void LLFolderViewItem::cleanupClass() +{ + sArrowImage = NULL; + sBoxImage = NULL; +} + + +// NOTE: Optimize this, we call it a *lot* when opening a large inventory +LLFolderViewItem::Params::Params() +: icon("icon"), + folder_arrow_image("folder_arrow_image", LLUI::getUIImage("folder_arrow.tga")), + selection_image("selection_image", LLUI::getUIImage("rounded_square.tga")) +{ + mouse_opaque(true); + follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP|FOLLOWS_RIGHT); + // JAMESDEBUG tab_stop(false); +} + +// Default constructor +LLFolderViewItem::LLFolderViewItem(LLFolderViewItem::Params p) +: LLView(p), + mLabelWidth(0), + mLabelWidthDirty(false), + mParentFolder( NULL ), + mIsSelected( FALSE ), + mIsCurSelection( FALSE ), + mSelectPending(FALSE), + mLabelStyle( LLFontGL::NORMAL ), + mHasVisibleChildren(FALSE), + mIndentation(0), + mNumDescendantsSelected(0), + mFiltered(FALSE), + mLastFilterGeneration(-1), + mStringMatchOffset(std::string::npos), + mControlLabelRotation(0.f), + mDragAndDropTarget(FALSE), + mIsLoading(FALSE), + mLabel(p.name), + mRoot(p.root), + mCreationDate(p.creation_date), + mListener(p.listener), + mArrowImage(p.folder_arrow_image), + mBoxImage(p.selection_image) +{ + refresh(); +} + +// Destroys the object +LLFolderViewItem::~LLFolderViewItem( void ) +{ + delete mListener; + mListener = NULL; +} + +LLFolderView* LLFolderViewItem::getRoot() +{ + return mRoot; +} + +// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor. +BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor ) +{ + LLFolderViewItem* root = this; + while( root->mParentFolder ) + { + if( root->mParentFolder == potential_ancestor ) + { + return TRUE; + } + root = root->mParentFolder; + } + return FALSE; +} + +LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children) +{ + if (!mParentFolder) + { + return NULL; + } + + LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children ); + while(itemp && !itemp->getVisible()) + { + LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children ); + if (itemp == next_itemp) + { + // hit last item + return itemp->getVisible() ? itemp : this; + } + itemp = next_itemp; + } + + return itemp; +} + +LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children) +{ + if (!mParentFolder) + { + return NULL; + } + + LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children ); + while(itemp && !itemp->getVisible()) + { + LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children ); + if (itemp == next_itemp) + { + // hit first item + return itemp->getVisible() ? itemp : this; + } + itemp = next_itemp; + } + + return itemp; +} + +// is this item something we think we should be showing? +// for example, if we haven't gotten around to filtering it yet, then the answer is yes +// until we find out otherwise +BOOL LLFolderViewItem::potentiallyVisible() +{ + // we haven't been checked against min required filter + // or we have and we passed + return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered(); +} + +BOOL LLFolderViewItem::getFiltered() +{ + return mFiltered && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration(); +} + +BOOL LLFolderViewItem::getFiltered(S32 filter_generation) +{ + return mFiltered && mLastFilterGeneration >= filter_generation; +} + +void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation) +{ + mFiltered = filtered; + mLastFilterGeneration = filter_generation; +} + +void LLFolderViewItem::setIcon(LLUIImagePtr icon) +{ + mIcon = icon; +} + +// refresh information from the listener +void LLFolderViewItem::refreshFromListener() +{ + if(mListener) + { + mLabel = mListener->getDisplayName(); + LLAssetType::EType preferred_type = mListener->getPreferredType(); + + // *TODO: to be removed when database supports multi language. This is a + // temporary attempt to display the inventory folder in the user locale. + if (LLAssetType::lookupIsProtectedCategoryType(preferred_type)) + { + mLabel = LLTrans::getString("InvFolder " + mLabel); + }; + + setIcon(mListener->getIcon()); + time_t creation_date = mListener->getCreationDate(); + if (mCreationDate != creation_date) + { + mCreationDate = mListener->getCreationDate(); + dirtyFilter(); + } + mLabelStyle = mListener->getLabelStyle(); + mLabelSuffix = mListener->getLabelSuffix(); + } +} + +void LLFolderViewItem::refresh() +{ + refreshFromListener(); + + std::string searchable_label(mLabel); + searchable_label.append(mLabelSuffix); + LLStringUtil::toUpper(searchable_label); + + if (mSearchableLabel.compare(searchable_label)) + { + mSearchableLabel.assign(searchable_label); + dirtyFilter(); + // some part of label has changed, so overall width has potentially changed, and sort order too + if (mParentFolder) + { + mParentFolder->requestSort(); + mParentFolder->requestArrange(); + } + } + + mLabelWidthDirty = true; +} + +void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor) +{ + functor(mListener); +} + +// This function is called when items are added or view filters change. It's +// implemented here but called by derived classes when folding the +// views. +void LLFolderViewItem::filterFromRoot( void ) +{ + LLFolderViewItem* root = getRoot(); + + root->filter(*((LLFolderView*)root)->getFilter()); +} + +// This function is called when the folder view is dirty. It's +// implemented here but called by derived classes when folding the +// views. +void LLFolderViewItem::arrangeFromRoot() +{ + LLFolderViewItem* root = getRoot(); + + S32 height = 0; + S32 width = 0; + root->arrange( &width, &height, 0 ); +} + +// Utility function for LLFolderView +void LLFolderViewItem::arrangeAndSet(BOOL set_selection, + BOOL take_keyboard_focus) +{ + LLFolderView* root = getRoot(); + getParentFolder()->requestArrange(); + if(set_selection) + { + setSelectionFromRoot(this, TRUE, take_keyboard_focus); + if(root) + { + root->scrollToShowSelection(); + } + } +} + +// This function clears the currently selected item, and records the +// specified selected item appropriately for display and use in the +// UI. If open is TRUE, then folders are opened up along the way to +// the selection. +void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection, + BOOL openitem, + BOOL take_keyboard_focus) +{ + getRoot()->setSelection(selection, openitem, take_keyboard_focus); +} + +// helper function to change the selection from the root. +void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected) +{ + getRoot()->changeSelection(selection, selected); +} + +void LLFolderViewItem::extendSelectionFromRoot(LLFolderViewItem* selection) +{ + LLDynamicArray selected_items; + + getRoot()->extendSelection(selection, NULL, selected_items); +} + +EInventorySortGroup LLFolderViewItem::getSortGroup() const +{ + return SG_ITEM; +} + +// addToFolder() returns TRUE if it succeeds. FALSE otherwise +BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) +{ + if (!folder) + { + return FALSE; + } + mParentFolder = folder; + root->addItemID(getListener()->getUUID(), this); + return folder->addItem(this); +} + + +// Finds width and height of this object and it's children. Also +// makes sure that this view and it's children are the right size. +S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation) +{ + mIndentation = mParentFolder ? mParentFolder->getIndentation() + LEFT_INDENTATION : 0; + if (mLabelWidthDirty) + { + mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + sFont->getWidth(mSearchableLabel); + mLabelWidthDirty = false; + } + + *width = llmax(*width, mLabelWidth + mIndentation); + *height = getItemHeight(); + return *height; +} + +S32 LLFolderViewItem::getItemHeight() +{ + S32 icon_height = mIcon->getHeight(); + S32 label_height = llround(sFont->getLineHeight()); + return llmax( icon_height, label_height ) + ICON_PAD; +} + +void LLFolderViewItem::filter( LLInventoryFilter& filter) +{ + BOOL filtered = mListener && filter.check(this); + + // if our visibility will change as a result of this filter, then + // we need to be rearranged in our parent folder + if (getVisible() != filtered) + { + if (mParentFolder) + { + mParentFolder->requestArrange(); + } + } + + setFiltered(filtered, filter.getCurrentGeneration()); + mStringMatchOffset = filter.getStringMatchOffset(); + filter.decrementFilterCount(); + + if (getRoot()->getDebugFilters()) + { + mStatusText = llformat("%d", mLastFilterGeneration); + } +} + +void LLFolderViewItem::dirtyFilter() +{ + mLastFilterGeneration = -1; + // bubble up dirty flag all the way to root + if (getParentFolder()) + { + getParentFolder()->setCompletedFilterGeneration(-1, TRUE); + } +} + +// *TODO: This can be optimized a lot by simply recording that it is +// selected in the appropriate places, and assuming that set selection +// means 'deselect' for a leaf item. Do this optimization after +// multiple selection is implemented to make sure it all plays nice +// together. +BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus) +{ + if( selection == this ) + { + mIsSelected = TRUE; + if(mListener) + { + mListener->selectItem(); + } + } + else + { + mIsSelected = FALSE; + } + return mIsSelected; +} + +BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected) +{ + if(selection == this && mIsSelected != selected) + { + mIsSelected = selected; + if(mListener) + { + mListener->selectItem(); + } + return TRUE; + } + return FALSE; +} + +void LLFolderViewItem::recursiveDeselect(BOOL deselect_self) +{ + if (mIsSelected && deselect_self) + { + mIsSelected = FALSE; + + // update ancestors' count of selected descendents + LLFolderViewFolder* parent_folder = getParentFolder(); + while(parent_folder) + { + parent_folder->mNumDescendantsSelected--; + parent_folder = parent_folder->getParentFolder(); + } + } +} + + +BOOL LLFolderViewItem::isMovable() +{ + if( mListener ) + { + return mListener->isItemMovable(); + } + else + { + return TRUE; + } +} + +BOOL LLFolderViewItem::isRemovable() +{ + if( mListener ) + { + return mListener->isItemRemovable(); + } + else + { + return TRUE; + } +} + +void LLFolderViewItem::destroyView() +{ + if (mParentFolder) + { + // removeView deletes me + mParentFolder->removeView(this); + } +} + +// Call through to the viewed object and return true if it can be +// removed. +//BOOL LLFolderViewItem::removeRecursively(BOOL single_item) +BOOL LLFolderViewItem::remove() +{ + if(!isRemovable()) + { + return FALSE; + } + if(mListener) + { + return mListener->removeItem(); + } + return TRUE; +} + +// Build an appropriate context menu for the item. +void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + if(mListener) + { + mListener->buildContextMenu(menu, flags); + } +} + +void LLFolderViewItem::openItem( void ) +{ + if( mListener ) + { + mListener->openItem(); + } +} + +void LLFolderViewItem::preview( void ) +{ + if (mListener) + { + mListener->previewItem(); + } +} + +void LLFolderViewItem::rename(const std::string& new_name) +{ + if( !new_name.empty() ) + { + if( mListener ) + { + mListener->renameItem(new_name); + + if(mParentFolder) + { + mParentFolder->requestSort(); + } + } + } +} + +const std::string& LLFolderViewItem::getSearchableLabel() const +{ + return mSearchableLabel; +} + +const std::string& LLFolderViewItem::getName( void ) const +{ + if(mListener) + { + return mListener->getName(); + } + return mLabel; +} + +// LLView functionality +BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask ) +{ + if(!mIsSelected) + { + setSelectionFromRoot(this, FALSE); + } + make_ui_sound("UISndClick"); + return TRUE; +} + +BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask ) +{ + // No handler needed for focus lost since this class has no + // state that depends on it. + gFocusMgr.setMouseCapture( this ); + + if (!mIsSelected) + { + if(mask & MASK_CONTROL) + { + changeSelectionFromRoot(this, !mIsSelected); + } + else if (mask & MASK_SHIFT) + { + extendSelectionFromRoot(this); + } + else + { + setSelectionFromRoot(this, FALSE); + } + make_ui_sound("UISndClick"); + } + else + { + mSelectPending = TRUE; + } + + if( isMovable() ) + { + S32 screen_x; + S32 screen_y; + localPointToScreen(x, y, &screen_x, &screen_y ); + LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y ); + } + return TRUE; +} + +BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask ) +{ + if( hasMouseCapture() && isMovable() ) + { + S32 screen_x; + S32 screen_y; + localPointToScreen(x, y, &screen_x, &screen_y ); + BOOL can_drag = TRUE; + if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) ) + { + LLFolderView* root = getRoot(); + + if(root->getCurSelectedItem()) + { + LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_WORLD; + + // *TODO: push this into listener and remove + // dependency on llagent + if (mListener + && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getRootFolderID())) + { + src = LLToolDragAndDrop::SOURCE_AGENT; + } + else if (mListener + && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getLibraryRootFolderID())) + { + src = LLToolDragAndDrop::SOURCE_LIBRARY; + } + + can_drag = root->startDrag(src); + if (can_drag) + { + // if (mListener) mListener->startDrag(); + // RN: when starting drag and drop, clear out last auto-open + root->autoOpenTest(NULL); + root->setShowSelectionContext(TRUE); + + // Release keyboard focus, so that if stuff is dropped into the + // world, pressing the delete key won't blow away the inventory + // item. + gFocusMgr.setKeyboardFocus(NULL); + + return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask ); + } + } + } + + if (can_drag) + { + gViewerWindow->setCursor(UI_CURSOR_ARROW); + } + else + { + gViewerWindow->setCursor(UI_CURSOR_NOLOCKED); + } + return TRUE; + } + else + { + getRoot()->setShowSelectionContext(FALSE); + gViewerWindow->setCursor(UI_CURSOR_ARROW); + // let parent handle this then... + return FALSE; + } +} + + +BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask ) +{ + preview(); + return TRUE; +} + +BOOL LLFolderViewItem::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ + if (getParent()) + { + return getParent()->handleScrollWheel(x, y, clicks); + } + return FALSE; +} + +BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask ) +{ + // if mouse hasn't moved since mouse down... + if ( pointInView(x, y) && mSelectPending ) + { + //...then select + if(mask & MASK_CONTROL) + { + changeSelectionFromRoot(this, !mIsSelected); + } + else if (mask & MASK_SHIFT) + { + extendSelectionFromRoot(this); + } + else + { + setSelectionFromRoot(this, FALSE); + } + } + + mSelectPending = FALSE; + + if( hasMouseCapture() ) + { + getRoot()->setShowSelectionContext(FALSE); + gFocusMgr.setMouseCapture( NULL ); + } + return TRUE; +} + +BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + BOOL accepted = FALSE; + BOOL handled = FALSE; + if(mListener) + { + accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data); + handled = accepted; + if (accepted) + { + mDragAndDropTarget = TRUE; + *accept = ACCEPT_YES_MULTI; + } + else + { + *accept = ACCEPT_NO; + } + } + if(mParentFolder && !handled) + { + handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); + } + if (handled) + { + lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl; + } + + return handled; +} + + +void LLFolderViewItem::draw() +{ + static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE); + static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE); + static LLUIColor sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE); + static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE); + static LLUIColor sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemSuffixColor", DEFAULT_WHITE); + static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE); + + bool possibly_has_children = false; + bool up_to_date = mListener && mListener->isUpToDate(); + if((up_to_date && hasVisibleChildren() ) || // we fetched our children and some of them have passed the filter... + (!up_to_date && mListener && mListener->hasChildren())) // ...or we know we have children but haven't fetched them (doesn't obey filter) + { + possibly_has_children = true; + } + if(/*mControlLabel[0] != '\0' && */possibly_has_children) + { + if (sArrowImage) + { + gl_draw_scaled_rotated_image(mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD, + ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, sArrowImage->getImage(), sFgColor); + } + } + + F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation); + + // If we have keyboard focus, draw selection filled + BOOL show_context = getRoot()->getShowSelectionContext(); + BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus()); + + // always render "current" item, only render other selected items if + // mShowSingleSelection is FALSE + if( mIsSelected ) + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLColor4 bg_color = sHighlightBgColor; + //const S32 TRAILING_PAD = 5; // It just looks better with this. + if (!mIsCurSelection) + { + // do time-based fade of extra objects + F32 fade_time = getRoot()->getSelectionFadeElapsedTime(); + if (getRoot()->getShowSingleSelection()) + { + // fading out + bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f); + } + else + { + // fading in + bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]); + } + } + + gl_rect_2d( + 0, + getRect().getHeight(), + getRect().getWidth() - 2, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), + bg_color, filled); + if (mIsCurSelection) + { + gl_rect_2d( + 0, + getRect().getHeight(), + getRect().getWidth() - 2, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), + sHighlightFgColor, FALSE); + } + if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) + { + gl_rect_2d( + 0, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, + getRect().getWidth() - 2, + 2, + sHighlightFgColor, FALSE); + if (show_context) + { + gl_rect_2d( + 0, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, + getRect().getWidth() - 2, + 2, + sHighlightBgColor, TRUE); + } + } + } + if (mDragAndDropTarget) + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gl_rect_2d( + 0, + getRect().getHeight(), + getRect().getWidth() - 2, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), + sHighlightBgColor, FALSE); + + if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) + { + gl_rect_2d( + 0, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, + getRect().getWidth() - 2, + 2, + sHighlightBgColor, FALSE); + } + mDragAndDropTarget = FALSE; + } + + + if(mIcon) + { + mIcon->draw(mIndentation + ARROW_SIZE + TEXT_PAD, getRect().getHeight() - mIcon->getHeight()); + } + + if (!mLabel.empty()) + { + // highlight filtered text + BOOL debug_filters = getRoot()->getDebugFilters(); + LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor ); + F32 right_x; + F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; + + if (debug_filters) + { + if (!getFiltered() && !possibly_has_children) + { + color.mV[VALPHA] *= 0.5f; + } + + LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? LLColor4(0.5f, 0.8f, 0.5f, 1.f) : LLColor4(0.8f, 0.5f, 0.5f, 1.f); + sSmallFont->renderUTF8(mStatusText, 0, text_left, y, filter_color, + LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, + S32_MAX, S32_MAX, &right_x, FALSE ); + text_left = right_x; + } + + + if ( mIsLoading + && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime") ) + { + sFont->renderUTF8(LLTrans::getString("LoadingData"), 0, text_left, y, sSearchStatusColor, + LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &right_x, FALSE); + text_left = right_x; + } + + sFont->renderUTF8( mLabel, 0, text_left, y, color, + LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, + S32_MAX, S32_MAX, &right_x, FALSE ); + if (!mLabelSuffix.empty()) + { + sFont->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor, + LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, + S32_MAX, S32_MAX, &right_x, FALSE ); + } + + if (sBoxImage.notNull() && mStringMatchOffset != std::string::npos) + { + // don't draw backgrounds for zero-length strings + S32 filter_string_length = getRoot()->getFilterSubString().size(); + if (filter_string_length > 0) + { + std::string combined_string = mLabel + mLabelSuffix; + S32 left = llround(text_left) + sFont->getWidth(combined_string, 0, mStringMatchOffset) - 1; + S32 right = left + sFont->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2; + S32 bottom = llfloor(getRect().getHeight() - sFont->getLineHeight() - 3); + S32 top = getRect().getHeight(); + + LLRect box_rect(left, top, right, bottom); + sBoxImage->draw(box_rect, sFilterBGColor); + F32 match_string_left = text_left + sFont->getWidthF32(combined_string, 0, mStringMatchOffset); + F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; + sFont->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y, + sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, + filter_string_length, S32_MAX, &right_x, FALSE ); + } + } + } + + if( sDebugRects ) + { + drawDebugRect(); + } + + //// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview) + //std::set::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this); + //if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights)) + //{ + // drawDebugRect(); + //} +} + + +///---------------------------------------------------------------------------- +/// Class LLFolderViewFolder +///---------------------------------------------------------------------------- + +LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): +LLFolderViewItem( p ), // 0 = no create time +mIsOpen(FALSE), +mExpanderHighlighted(FALSE), +mCurHeight(0.f), +mTargetHeight(0.f), +mAutoOpenCountdown(0.f), +mSubtreeCreationDate(0), +mAmTrash(LLFolderViewFolder::UNKNOWN), +mLastArrangeGeneration( -1 ), +mLastCalculatedWidth(0), +mCompletedFilterGeneration(-1), +mMostFilteredDescendantGeneration(-1), +mNeedsSort(false) +{} + +// Destroys the object +LLFolderViewFolder::~LLFolderViewFolder( void ) +{ + // The LLView base class takes care of object destruction. make sure that we + // don't have mouse or keyboard focus + gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() +} + +// addToFolder() returns TRUE if it succeeds. FALSE otherwise +BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) +{ + if (!folder) + { + return FALSE; + } + mParentFolder = folder; + root->addItemID(getListener()->getUUID(), this); + return folder->addFolder(this); +} + +// Finds width and height of this object and it's children. Also +// makes sure that this view and it's children are the right size. +S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation) +{ + // sort before laying out contents + if (mNeedsSort) + { + mFolders.sort(mSortFunction); + mItems.sort(mSortFunction); + mNeedsSort = false; + } + + mHasVisibleChildren = hasFilteredDescendants(filter_generation); + + LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getFilter()->getShowFolderState(); + + // calculate height as a single item (without any children), and reshapes rectangle to match + LLFolderViewItem::arrange( width, height, filter_generation ); + + // clamp existing animated height so as to never get smaller than a single item + mCurHeight = llmax((F32)*height, mCurHeight); + + // initialize running height value as height of single item in case we have no children + *height = getItemHeight(); + F32 running_height = (F32)*height; + F32 target_height = (F32)*height; + + // are my children visible? + if (needsArrange()) + { + // set last arrange generation first, in case children are animating + // and need to be arranged again + mLastArrangeGeneration = getRoot()->getArrangeGeneration(); + if (mIsOpen) + { + // Add sizes of children + S32 parent_item_height = getRect().getHeight(); + + for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit) + { + LLFolderViewFolder* folderp = (*fit); + if (getRoot()->getDebugFilters()) + { + folderp->setVisible(TRUE); + } + else + { + folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders? + (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter + } + + if (folderp->getVisible()) + { + S32 child_width = *width; + S32 child_height = 0; + S32 child_top = parent_item_height - llround(running_height); + + target_height += folderp->arrange( &child_width, &child_height, filter_generation ); + + running_height += (F32)child_height; + *width = llmax(*width, child_width); + folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() ); + } + } + for(items_t::iterator iit = mItems.begin(); + iit != mItems.end(); ++iit) + { + LLFolderViewItem* itemp = (*iit); + if (getRoot()->getDebugFilters()) + { + itemp->setVisible(TRUE); + } + else + { + itemp->setVisible(itemp->getFiltered(filter_generation)); + } + + if (itemp->getVisible()) + { + S32 child_width = *width; + S32 child_height = 0; + S32 child_top = parent_item_height - llround(running_height); + + target_height += itemp->arrange( &child_width, &child_height, filter_generation ); + // don't change width, as this item is as wide as its parent folder by construction + itemp->reshape( itemp->getRect().getWidth(), child_height); + + running_height += (F32)child_height; + *width = llmax(*width, child_width); + itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() ); + } + } + } + + mTargetHeight = target_height; + // cache this width so next time we can just return it + mLastCalculatedWidth = *width; + } + else + { + // just use existing width + *width = mLastCalculatedWidth; + } + + // animate current height towards target height + if (llabs(mCurHeight - mTargetHeight) > 1.f) + { + mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT)); + + requestArrange(); + + // hide child elements that fall out of current animated height + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + // number of pixels that bottom of folder label is from top of parent folder + if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight() + > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP) + { + // hide if beyond current folder height + (*fit)->setVisible(FALSE); + } + } + + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + // number of pixels that bottom of item label is from top of parent folder + if (getRect().getHeight() - (*iit)->getRect().mBottom + > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP) + { + (*iit)->setVisible(FALSE); + } + } + } + else + { + mCurHeight = mTargetHeight; + } + + // don't change width as this item is already as wide as its parent folder + reshape(getRect().getWidth(),llround(mCurHeight)); + + // pass current height value back to parent + *height = llround(mCurHeight); + + return llround(mTargetHeight); +} + +BOOL LLFolderViewFolder::needsArrange() +{ + return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); +} + +void LLFolderViewFolder::requestSort() +{ + mNeedsSort = true; + // whenever item order changes, we need to lay things out again + requestArrange(); +} + +void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up) +{ + mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation); + mCompletedFilterGeneration = generation; + // only aggregate up if we are a lower (older) value + if (recurse_up && mParentFolder && generation < mParentFolder->getCompletedFilterGeneration()) + { + mParentFolder->setCompletedFilterGeneration(generation, TRUE); + } +} + +void LLFolderViewFolder::filter( LLInventoryFilter& filter) +{ + S32 filter_generation = filter.getCurrentGeneration(); + // if failed to pass filter newer than must_pass_generation + // you will automatically fail this time, so we only + // check against items that have passed the filter + S32 must_pass_generation = filter.getMustPassGeneration(); + + // if we have already been filtered against this generation, skip out + if (getCompletedFilterGeneration() >= filter_generation) + { + return; + } + + // filter folder itself + if (getLastFilterGeneration() < filter_generation) + { + if (getLastFilterGeneration() >= must_pass_generation && // folder has been compared to a valid precursor filter + !mFiltered) // and did not pass the filter + { + // go ahead and flag this folder as done + mLastFilterGeneration = filter_generation; + } + else + { + // filter self only on first pass through + LLFolderViewItem::filter( filter ); + } + } + + if (getRoot()->getDebugFilters()) + { + mStatusText = llformat("%d", mLastFilterGeneration); + mStatusText += llformat("(%d)", mCompletedFilterGeneration); + mStatusText += llformat("+%d", mMostFilteredDescendantGeneration); + } + + // all descendants have been filtered later than must pass generation + // but none passed + if(getCompletedFilterGeneration() >= must_pass_generation && !hasFilteredDescendants(must_pass_generation)) + { + // don't traverse children if we've already filtered them since must_pass_generation + // and came back with nothing + return; + } + + // we entered here with at least one filter iteration left + // check to see if we have any more before continuing on to children + if (filter.getFilterCount() < 0) + { + return; + } + + // when applying a filter, matching folders get their contents downloaded first + if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID()))) + { + gInventory.startBackgroundFetch(mListener->getUUID()); + } + + // now query children + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + // have we run out of iterations this frame? + if (filter.getFilterCount() < 0) + { + break; + } + + // mMostFilteredDescendantGeneration might have been reset + // in which case we need to update it even for folders that + // don't need to be filtered anymore + if ((*fit)->getCompletedFilterGeneration() >= filter_generation) + { + // track latest generation to pass any child items + if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter.getMinRequiredGeneration())) + { + mMostFilteredDescendantGeneration = filter_generation; + if (getRoot()->needsAutoSelect()) + { + (*fit)->setOpenArrangeRecursively(TRUE); + } + } + // just skip it, it has already been filtered + continue; + } + + // update this folders filter status (and children) + (*fit)->filter( filter ); + + // track latest generation to pass any child items + if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter_generation)) + { + mMostFilteredDescendantGeneration = filter_generation; + if (getRoot()->needsAutoSelect()) + { + (*fit)->setOpenArrangeRecursively(TRUE); + } + } + } + + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + if (filter.getFilterCount() < 0) + { + break; + } + if ((*iit)->getLastFilterGeneration() >= filter_generation) + { + if ((*iit)->getFiltered()) + { + mMostFilteredDescendantGeneration = filter_generation; + } + continue; + } + + if ((*iit)->getLastFilterGeneration() >= must_pass_generation && + !(*iit)->getFiltered(must_pass_generation)) + { + // failed to pass an earlier filter that was a subset of the current one + // go ahead and flag this item as done + (*iit)->setFiltered(FALSE, filter_generation); + continue; + } + + (*iit)->filter( filter ); + + if ((*iit)->getFiltered(filter.getMinRequiredGeneration())) + { + mMostFilteredDescendantGeneration = filter_generation; + } + } + + // if we didn't use all filter iterations + // that means we filtered all of our descendants + // instead of exhausting the filter count for this frame + if (filter.getFilterCount() > 0) + { + // flag this folder as having completed filter pass for all descendants + setCompletedFilterGeneration(filter_generation, FALSE/*dont recurse up to root*/); + } +} + +void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation) +{ + // if this folder is now filtered, but wasn't before + // (it just passed) + if (filtered && !mFiltered) + { + // reset current height, because last time we drew it + // it might have had more visible items than now + mCurHeight = 0.f; + } + + LLFolderViewItem::setFiltered(filtered, filter_generation); +} + +void LLFolderViewFolder::dirtyFilter() +{ + // we're a folder, so invalidate our completed generation + setCompletedFilterGeneration(-1, FALSE); + LLFolderViewItem::dirtyFilter(); +} + +BOOL LLFolderViewFolder::hasFilteredDescendants() +{ + return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration(); +} + +// Passes selection information on to children and record selection +// information if necessary. +BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem, + BOOL take_keyboard_focus) +{ + BOOL rv = FALSE; + if( selection == this ) + { + mIsSelected = TRUE; + if(mListener) + { + mListener->selectItem(); + } + rv = TRUE; + } + else + { + mIsSelected = FALSE; + rv = FALSE; + } + BOOL child_selected = FALSE; + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + if((*fit)->setSelection(selection, openitem, take_keyboard_focus)) + { + rv = TRUE; + child_selected = TRUE; + mNumDescendantsSelected++; + } + } + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + if((*iit)->setSelection(selection, openitem, take_keyboard_focus)) + { + rv = TRUE; + child_selected = TRUE; + mNumDescendantsSelected++; + } + } + if(openitem && child_selected) + { + setOpenArrangeRecursively(TRUE); + } + return rv; +} + +// This method is used to change the selection of an item. If +// selection is 'this', then note selection as true. Returns TRUE +// if this or a child is now selected. +BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, + BOOL selected) +{ + BOOL rv = FALSE; + if(selection == this) + { + mIsSelected = selected; + if(mListener && selected) + { + mListener->selectItem(); + } + rv = TRUE; + } + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + if((*fit)->changeSelection(selection, selected)) + { + if (selected) + { + mNumDescendantsSelected++; + } + else + { + mNumDescendantsSelected--; + } + rv = TRUE; + } + } + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + if((*iit)->changeSelection(selection, selected)) + { + if (selected) + { + mNumDescendantsSelected++; + } + else + { + mNumDescendantsSelected--; + } + rv = TRUE; + } + } + return rv; +} + +S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray& selected_items) +{ + S32 num_selected = 0; + + // pass on to child folders first + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + num_selected += (*fit)->extendSelection(selection, last_selected, selected_items); + mNumDescendantsSelected += num_selected; + } + + // handle selection of our immediate children... + BOOL reverse_select = FALSE; + BOOL found_last_selected = FALSE; + BOOL found_selection = FALSE; + LLDynamicArray items_to_select; + LLFolderViewItem* item; + + //...folders first... + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + item = (*fit); + if(item == selection) + { + found_selection = TRUE; + } + else if (item == last_selected) + { + found_last_selected = TRUE; + if (found_selection) + { + reverse_select = TRUE; + } + } + + if (found_selection || found_last_selected) + { + // deselect currently selected items so they can be pushed back on queue + if (item->isSelected()) + { + item->changeSelection(item, FALSE); + } + items_to_select.put(item); + } + + if (found_selection && found_last_selected) + { + break; + } + } + + if (!(found_selection && found_last_selected)) + { + //,,,then items + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + item = (*iit); + if(item == selection) + { + found_selection = TRUE; + } + else if (item == last_selected) + { + found_last_selected = TRUE; + if (found_selection) + { + reverse_select = TRUE; + } + } + + if (found_selection || found_last_selected) + { + // deselect currently selected items so they can be pushed back on queue + if (item->isSelected()) + { + item->changeSelection(item, FALSE); + } + items_to_select.put(item); + } + + if (found_selection && found_last_selected) + { + break; + } + } + } + + if (found_last_selected && found_selection) + { + // we have a complete selection inside this folder + for (S32 index = reverse_select ? items_to_select.getLength() - 1 : 0; + reverse_select ? index >= 0 : index < items_to_select.getLength(); reverse_select ? index-- : index++) + { + LLFolderViewItem* item = items_to_select[index]; + if (item->changeSelection(item, TRUE)) + { + selected_items.put(item); + mNumDescendantsSelected++; + num_selected++; + } + } + } + else if (found_selection) + { + // last selection was not in this folder....go ahead and select just the new item + if (selection->changeSelection(selection, TRUE)) + { + selected_items.put(selection); + mNumDescendantsSelected++; + num_selected++; + } + } + + return num_selected; +} + +void LLFolderViewFolder::recursiveDeselect(BOOL deselect_self) +{ + // make sure we don't have negative values + llassert(mNumDescendantsSelected >= 0); + + if (mIsSelected && deselect_self) + { + mIsSelected = FALSE; + + // update ancestors' count of selected descendents + LLFolderViewFolder* parent_folder = getParentFolder(); + while(parent_folder) + { + parent_folder->mNumDescendantsSelected--; + parent_folder = parent_folder->getParentFolder(); + } + } + + if (0 == mNumDescendantsSelected) + { + return; + } + + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + LLFolderViewItem* item = (*iit); + item->recursiveDeselect(TRUE); + } + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + LLFolderViewFolder* folder = (*fit); + folder->recursiveDeselect(TRUE); + } + +} + +void LLFolderViewFolder::destroyView() +{ + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + LLFolderViewItem* item = (*iit); + getRoot()->removeItemID(item->getListener()->getUUID()); + } + + std::for_each(mItems.begin(), mItems.end(), DeletePointer()); + mItems.clear(); + + while (!mFolders.empty()) + { + LLFolderViewFolder *folderp = mFolders.back(); + folderp->destroyView(); // removes entry from mFolders + } + + deleteAllChildren(); + + if (mParentFolder) + { + mParentFolder->removeView(this); + } +} + +// remove the specified item (and any children) if possible. Return +// TRUE if the item was deleted. +BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item) +{ + if(item->remove()) + { + //RN: this seem unneccessary as remove() moves to trash + //removeView(item); + return TRUE; + } + return FALSE; +} + +// simply remove the view (and any children) Don't bother telling the +// listeners. +void LLFolderViewFolder::removeView(LLFolderViewItem* item) +{ + if (!item || item->getParentFolder() != this) + { + return; + } + // deselect without traversing hierarchy + item->recursiveDeselect(TRUE); + getRoot()->removeFromSelectionList(item); + extractItem(item); + delete item; +} + +// extractItem() removes the specified item from the folder, but +// doesn't delete it. +void LLFolderViewFolder::extractItem( LLFolderViewItem* item ) +{ + items_t::iterator it = std::find(mItems.begin(), mItems.end(), item); + if(it == mItems.end()) + { + // This is an evil downcast. However, it's only doing + // pointer comparison to find if (which it should be ) the + // item is in the container, so it's pretty safe. + LLFolderViewFolder* f = reinterpret_cast(item); + folders_t::iterator ft; + ft = std::find(mFolders.begin(), mFolders.end(), f); + if(ft != mFolders.end()) + { + mFolders.erase(ft); + } + } + else + { + mItems.erase(it); + } + //item has been removed, need to update filter + dirtyFilter(); + //because an item is going away regardless of filter status, force rearrange + requestArrange(); + getRoot()->removeItemID(item->getListener()->getUUID()); + removeChild(item); +} + +bool LLFolderViewFolder::isTrash() const +{ + if (mAmTrash == LLFolderViewFolder::UNKNOWN) + { + mAmTrash = mListener->getUUID() == gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH, false) ? LLFolderViewFolder::TRASH : LLFolderViewFolder::NOT_TRASH; + } + return mAmTrash == LLFolderViewFolder::TRASH; +} + +void LLFolderViewFolder::sortBy(U32 order) +{ + if (!mSortFunction.updateSort(order)) + { + // No changes. + return; + } + + // Propegate this change to sub folders + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->sortBy(order); + } + + mFolders.sort(mSortFunction); + mItems.sort(mSortFunction); + + if (order & LLInventoryFilter::SO_DATE) + { + time_t latest = 0; + + if (!mItems.empty()) + { + LLFolderViewItem* item = *(mItems.begin()); + latest = item->getCreationDate(); + } + + if (!mFolders.empty()) + { + LLFolderViewFolder* folder = *(mFolders.begin()); + if (folder->getCreationDate() > latest) + { + latest = folder->getCreationDate(); + } + } + mSubtreeCreationDate = latest; + } +} + +void LLFolderViewFolder::setItemSortOrder(U32 ordering) +{ + if (mSortFunction.updateSort(ordering)) + { + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->setItemSortOrder(ordering); + } + + mFolders.sort(mSortFunction); + mItems.sort(mSortFunction); + } +} + +EInventorySortGroup LLFolderViewFolder::getSortGroup() const +{ + if (isTrash()) + { + return SG_TRASH_FOLDER; + } + + // Folders that can't be moved are 'system' folders. + if( mListener ) + { + if( !(mListener->isItemMovable()) ) + { + return SG_SYSTEM_FOLDER; + } + } + + return SG_NORMAL_FOLDER; +} + +BOOL LLFolderViewFolder::isMovable() +{ + if( mListener ) + { + if( !(mListener->isItemMovable()) ) + { + return FALSE; + } + + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + if(!(*iit)->isMovable()) + { + return FALSE; + } + } + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + if(!(*fit)->isMovable()) + { + return FALSE; + } + } + } + return TRUE; +} + + +BOOL LLFolderViewFolder::isRemovable() +{ + if( mListener ) + { + if( !(mListener->isItemRemovable()) ) + { + return FALSE; + } + + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + if(!(*iit)->isRemovable()) + { + return FALSE; + } + } + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + if(!(*fit)->isRemovable()) + { + return FALSE; + } + } + } + return TRUE; +} + +// this is an internal method used for adding items to folders. +BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) +{ + mItems.push_back(item); + item->setRect(LLRect(0, 0, getRect().getWidth(), 0)); + item->setVisible(FALSE); + addChild( item ); + item->dirtyFilter(); + requestArrange(); + requestSort(); + return TRUE; +} + +// this is an internal method used for adding items to folders. +BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder) +{ + mFolders.push_back(folder); + folder->setOrigin(0, 0); + folder->reshape(getRect().getWidth(), 0); + folder->setVisible(FALSE); + addChild( folder ); + folder->dirtyFilter(); + // rearrange all descendants too, as our indentation level might have changed + folder->requestArrange(TRUE); + requestSort(); + return TRUE; +} + +void LLFolderViewFolder::requestArrange(BOOL include_descendants) +{ + mLastArrangeGeneration = -1; + // flag all items up to root + if (mParentFolder) + { + mParentFolder->requestArrange(); + } + + if (include_descendants) + { + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end(); + ++iter) + { + (*iter)->requestArrange(TRUE); + } + } +} + +void LLFolderViewFolder::toggleOpen() +{ + setOpen(!mIsOpen); +} + +// Force a folder open or closed +void LLFolderViewFolder::setOpen(BOOL openitem) +{ + setOpenArrangeRecursively(openitem); +} + +void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse) +{ + BOOL was_open = mIsOpen; + mIsOpen = openitem; + if(!was_open && openitem) + { + if(mListener) + { + mListener->openItem(); + } + } + + if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN) + { + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN); /* Flawfinder: ignore */ + } + } + if (mParentFolder && (recurse == RECURSE_UP || recurse == RECURSE_UP_DOWN)) + { + mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP); + } + + if (was_open != mIsOpen) + { + requestArrange(); + } +} + +BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask, + BOOL drop, + EDragAndDropType c_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data); + if (accepted) + { + mDragAndDropTarget = TRUE; + *accept = ACCEPT_YES_MULTI; + } + else + { + *accept = ACCEPT_NO; + } + + // drag and drop to child item, so clear pending auto-opens + getRoot()->autoOpenTest(NULL); + + return TRUE; +} + +void LLFolderViewFolder::openItem( void ) +{ + toggleOpen(); +} + +void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor) +{ + functor.doFolder(this); + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->applyFunctorRecursively(functor); + } + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + functor.doItem((*iit)); + } +} + +void LLFolderViewFolder::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor) +{ + functor(mListener); + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->applyListenerFunctorRecursively(functor); + } + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + (*iit)->applyListenerFunctorRecursively(functor); + } +} + +// LLView functionality +BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask, + BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + LLFolderView* root_view = getRoot(); + + BOOL handled = FALSE; + if(mIsOpen) + { + handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, + cargo_data, accept, tooltip_msg) != NULL; + } + + if (!handled) + { + BOOL accepted = mListener && mListener->dragOrDrop(mask, drop,cargo_type,cargo_data); + + if (accepted) + { + mDragAndDropTarget = TRUE; + *accept = ACCEPT_YES_MULTI; + } + else + { + *accept = ACCEPT_NO; + } + + if (!drop && accepted) + { + root_view->autoOpenTest(this); + } + + lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl; + } + + return TRUE; +} + + +BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask ) +{ + BOOL handled = FALSE; + // fetch contents of this folder, as context menu can depend on contents + // still, user would have to open context menu again to see the changes + gInventory.fetchDescendentsOf(mListener->getUUID()); + + if( mIsOpen ) + { + handled = childrenHandleRightMouseDown( x, y, mask ) != NULL; + } + if (!handled) + { + handled = LLFolderViewItem::handleRightMouseDown( x, y, mask ); + } + return handled; +} + + +BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask) +{ + BOOL handled = LLView::handleHover(x, y, mask); + + if (!handled) + { + // this doesn't do child processing + handled = LLFolderViewItem::handleHover(x, y, mask); + } + + //if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD && y > getRect().getHeight() - ) + //{ + // gViewerWindow->setCursor(UI_CURSOR_ARROW); + // mExpanderHighlighted = TRUE; + // handled = TRUE; + //} + return handled; +} + +BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask ) +{ + BOOL handled = FALSE; + if( mIsOpen ) + { + handled = childrenHandleMouseDown(x,y,mask) != NULL; + } + if( !handled ) + { + if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD) + { + toggleOpen(); + handled = TRUE; + } + else + { + // do normal selection logic + handled = LLFolderViewItem::handleMouseDown(x, y, mask); + } + } + + return handled; +} + +BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask ) +{ + BOOL handled = FALSE; + if( mIsOpen ) + { + handled = childrenHandleDoubleClick( x, y, mask ) != NULL; + } + if( !handled ) + { + if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD) + { + // don't select when user double-clicks plus sign + // so as not to contradict single-click behavior + toggleOpen(); + } + else + { + setSelectionFromRoot(this, FALSE); + toggleOpen(); + } + handled = TRUE; + } + return handled; +} + +void LLFolderViewFolder::draw() +{ + if (mAutoOpenCountdown != 0.f) + { + mControlLabelRotation = mAutoOpenCountdown * -90.f; + } + else if (mIsOpen) + { + mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f)); + } + else + { + mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f)); + } + + bool possibly_has_children = false; + bool up_to_date = mListener && mListener->isUpToDate(); + if(!up_to_date && mListener && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter) + { + possibly_has_children = true; + } + + + BOOL loading = ( mIsOpen && possibly_has_children && !up_to_date ); + + if ( loading && !mIsLoading ) + { + // Measure how long we've been in the loading state + mTimeSinceRequestStart.reset(); + } + + mIsLoading = loading; + + LLFolderViewItem::draw(); + + // draw children if root folder, or any other folder that is open or animating to closed state + if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight )) + { + LLView::draw(); + } + + mExpanderHighlighted = FALSE; +} + +time_t LLFolderViewFolder::getCreationDate() const +{ + return llmax(mCreationDate, mSubtreeCreationDate); +} + + +BOOL LLFolderViewFolder::potentiallyVisible() +{ + // folder should be visible by it's own filter status + return LLFolderViewItem::potentiallyVisible() + // or one or more of its descendants have passed the minimum filter requirement + || hasFilteredDescendants(getRoot()->getFilter()->getMinRequiredGeneration()) + // or not all of its descendants have been checked against minimum filter requirement + || getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration(); +} + +// this does prefix traversal, as folders are listed above their contents +LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children ) +{ + BOOL found_item = FALSE; + + LLFolderViewItem* result = NULL; + // when not starting from a given item, start at beginning + if(item == NULL) + { + found_item = TRUE; + } + + // find current item among children + folders_t::iterator fit = mFolders.begin(); + folders_t::iterator fend = mFolders.end(); + + items_t::iterator iit = mItems.begin(); + items_t::iterator iend = mItems.end(); + + // if not trivially starting at the beginning, we have to find the current item + if (!found_item) + { + // first, look among folders, since they are always above items + for(; fit != fend; ++fit) + { + if(item == (*fit)) + { + found_item = TRUE; + // if we are on downwards traversal + if (include_children && (*fit)->isOpen()) + { + // look for first descendant + return (*fit)->getNextFromChild(NULL, TRUE); + } + // otherwise advance to next folder + ++fit; + include_children = TRUE; + break; + } + } + + // didn't find in folders? Check items... + if (!found_item) + { + for(; iit != iend; ++iit) + { + if(item == (*iit)) + { + found_item = TRUE; + // point to next item + ++iit; + break; + } + } + } + } + + if (!found_item) + { + // you should never call this method with an item that isn't a child + // so we should always find something + llassert(FALSE); + return NULL; + } + + // at this point, either iit or fit point to a candidate "next" item + // if both are out of range, we need to punt up to our parent + + // now, starting from found folder, continue through folders + // searching for next visible folder + while(fit != fend && !(*fit)->getVisible()) + { + // turn on downwards traversal for next folder + ++fit; + } + + if (fit != fend) + { + result = (*fit); + } + else + { + // otherwise, scan for next visible item + while(iit != iend && !(*iit)->getVisible()) + { + ++iit; + } + + // check to see if we have a valid item + if (iit != iend) + { + result = (*iit); + } + } + + if( !result && mParentFolder ) + { + // If there are no siblings or children to go to, recurse up one level in the tree + // and skip children for this folder, as we've already discounted them + result = mParentFolder->getNextFromChild(this, FALSE); + } + + return result; +} + +// this does postfix traversal, as folders are listed above their contents +LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children ) +{ + BOOL found_item = FALSE; + + LLFolderViewItem* result = NULL; + // when not starting from a given item, start at end + if(item == NULL) + { + found_item = TRUE; + } + + // find current item among children + folders_t::reverse_iterator fit = mFolders.rbegin(); + folders_t::reverse_iterator fend = mFolders.rend(); + + items_t::reverse_iterator iit = mItems.rbegin(); + items_t::reverse_iterator iend = mItems.rend(); + + // if not trivially starting at the end, we have to find the current item + if (!found_item) + { + // first, look among items, since they are always below the folders + for(; iit != iend; ++iit) + { + if(item == (*iit)) + { + found_item = TRUE; + // point to next item + ++iit; + break; + } + } + + // didn't find in items? Check folders... + if (!found_item) + { + for(; fit != fend; ++fit) + { + if(item == (*fit)) + { + found_item = TRUE; + // point to next folder + ++fit; + break; + } + } + } + } + + if (!found_item) + { + // you should never call this method with an item that isn't a child + // so we should always find something + llassert(FALSE); + return NULL; + } + + // at this point, either iit or fit point to a candidate "next" item + // if both are out of range, we need to punt up to our parent + + // now, starting from found item, continue through items + // searching for next visible item + while(iit != iend && !(*iit)->getVisible()) + { + ++iit; + } + + if (iit != iend) + { + // we found an appropriate item + result = (*iit); + } + else + { + // otherwise, scan for next visible folder + while(fit != fend && !(*fit)->getVisible()) + { + ++fit; + } + + // check to see if we have a valid folder + if (fit != fend) + { + // try selecting child element of this folder + if ((*fit)->isOpen()) + { + result = (*fit)->getPreviousFromChild(NULL); + } + else + { + result = (*fit); + } + } + } + + if( !result ) + { + // If there are no siblings or children to go to, recurse up one level in the tree + // which gets back to this folder, which will only be visited if it is a valid, visible item + result = this; + } + + return result; +} + + +bool LLInventorySort::updateSort(U32 order) +{ + if (order != mSortOrder) + { + mSortOrder = order; + mByDate = (order & LLInventoryFilter::SO_DATE); + mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP); + mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME); + return true; + } + return false; +} + +bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b) +{ + // We sort by name if we aren't sorting by date + // OR if these are folders and we are sorting folders by name. + bool by_name = (!mByDate + || (mFoldersByName + && (a->getSortGroup() != SG_ITEM))); + + if (a->getSortGroup() != b->getSortGroup()) + { + if (mSystemToTop) + { + // Group order is System Folders, Trash, Normal Folders, Items + return (a->getSortGroup() < b->getSortGroup()); + } + else if (mByDate) + { + // Trash needs to go to the bottom if we are sorting by date + if ( (a->getSortGroup() == SG_TRASH_FOLDER) + || (b->getSortGroup() == SG_TRASH_FOLDER)) + { + return (b->getSortGroup() == SG_TRASH_FOLDER); + } + } + } + + if (by_name) + { + S32 compare = LLStringUtil::compareDict(a->getLabel(), b->getLabel()); + if (0 == compare) + { + return (a->getCreationDate() > b->getCreationDate()); + } + else + { + return (compare < 0); + } + } + else + { + // BUG: This is very very slow. The getCreationDate() is log n in number + // of inventory items. + time_t first_create = a->getCreationDate(); + time_t second_create = b->getCreationDate(); + if (first_create == second_create) + { + return (LLStringUtil::compareDict(a->getLabel(), b->getLabel()) < 0); + } + else + { + return (first_create > second_create); + } + } +} diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h new file mode 100644 index 0000000000..31866c83c8 --- /dev/null +++ b/indra/newview/llfolderviewitem.h @@ -0,0 +1,528 @@ +/** +* @file llfolderviewitem.h +* @brief Items and folders that can appear in a hierarchical folder view +* +* $LicenseInfo:firstyear=2001&license=viewergpl$ +* +* Copyright (c) 2001-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#ifndef LLFOLDERVIEWITEM_H +#define LLFOLDERVIEWITEM_H + +#include "llview.h" + +class LLFontGL; +class LLFolderView; +class LLFolderViewEventListener; +class LLFolderViewFolder; +class LLFolderViewFunctor; +class LLFolderViewItem; +class LLFolderViewListenerFunctor; +class LLInventoryFilter; +class LLMenuGL; +class LLUIImage; + +// These are grouping of inventory types. +// Order matters when sorting system folders to the top. +enum EInventorySortGroup +{ + SG_SYSTEM_FOLDER, + SG_TRASH_FOLDER, + SG_NORMAL_FOLDER, + SG_ITEM +}; + +// JAMESDEBUG *TODO: do we really need one sort object per folder? +// can we just have one of these per LLFolderView ? +class LLInventorySort +{ +public: + LLInventorySort() + : mSortOrder(0), + mByDate(false), + mSystemToTop(false), + mFoldersByName(false) { } + + // Returns true if order has changed + bool updateSort(U32 order); + U32 getSort() { return mSortOrder; } + + bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b); +private: + U32 mSortOrder; + bool mByDate; + bool mSystemToTop; + bool mFoldersByName; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFolderViewItem +// +// An instance of this class represents a single item in a folder view +// such as an inventory item or a file. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLFolderViewItem : public LLView +{ +public: + static void initClass(); + static void cleanupClass(); + + // jamesdebug was LLUICtrl::Params + struct Params : public LLInitParam::Block + { + Optional icon; + Optional root; + Optional listener; + + Optional folder_arrow_image; + Optional selection_image; + + Optional creation_date; //UTC seconds + + Params(); + }; + + // layout constants + static const S32 LEFT_PAD = 5; + static const S32 LEFT_INDENTATION = 13; + static const S32 ICON_PAD = 2; + static const S32 ICON_WIDTH = 16; + static const S32 TEXT_PAD = 1; + static const S32 ARROW_SIZE = 12; + static const S32 MAX_FOLDER_ITEM_OVERLAP = 2; + // animation parameters + static const F32 FOLDER_CLOSE_TIME_CONSTANT; + static const F32 FOLDER_OPEN_TIME_CONSTANT; + +protected: + friend class LLUICtrlFactory; + friend class LLFolderViewEventListener; + + LLFolderViewItem(Params p = LLFolderViewItem::Params()); + + static const LLFontGL* sFont; + static const LLFontGL* sSmallFont; + static LLUIImagePtr sArrowImage; + static LLUIImagePtr sBoxImage; + + std::string mLabel; + std::string mSearchableLabel; + S32 mLabelWidth; + bool mLabelWidthDirty; + time_t mCreationDate; + LLFolderViewFolder* mParentFolder; + LLFolderViewEventListener* mListener; + BOOL mIsSelected; + BOOL mIsCurSelection; + BOOL mSelectPending; + LLFontGL::StyleFlags mLabelStyle; + std::string mLabelSuffix; + LLUIImagePtr mIcon; + std::string mStatusText; + BOOL mHasVisibleChildren; + S32 mIndentation; + S32 mNumDescendantsSelected; + BOOL mFiltered; + S32 mLastFilterGeneration; + std::string::size_type mStringMatchOffset; + F32 mControlLabelRotation; + LLFolderView* mRoot; + BOOL mDragAndDropTarget; + LLUIImagePtr mArrowImage; + LLUIImagePtr mBoxImage; + BOOL mIsLoading; + LLTimer mTimeSinceRequestStart; + + // helper function to change the selection from the root. + void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected); + + // helper function to change the selection from the root. + void extendSelectionFromRoot(LLFolderViewItem* selection); + + // this is an internal method used for adding items to folders. A + // no-op at this leve, but reimplemented in derived classes. + virtual BOOL addItem(LLFolderViewItem*) { return FALSE; } + virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; } + +public: + // This function clears the currently selected item, and records + // the specified selected item appropriately for display and use + // in the UI. If open is TRUE, then folders are opened up along + // the way to the selection. + void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem, + BOOL take_keyboard_focus = TRUE); + + // This function is called when the folder view is dirty. It's + // implemented here but called by derived classes when folding the + // views. + void arrangeFromRoot(); + void filterFromRoot( void ); + + void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus); + + virtual ~LLFolderViewItem( void ); + + // addToFolder() returns TRUE if it succeeds. FALSE otherwise + enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE }; + virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); + + virtual EInventorySortGroup getSortGroup() const; + + // Finds width and height of this object and it's children. Also + // makes sure that this view and it's children are the right size. + virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); + virtual S32 getItemHeight(); + + // applies filters to control visibility of inventory items + virtual void filter( LLInventoryFilter& filter); + + // updates filter serial number and optionally propagated value up to root + S32 getLastFilterGeneration() { return mLastFilterGeneration; } + + virtual void dirtyFilter(); + + // If the selection is 'this' then note that otherwise + // ignore. Returns TRUE if this object was affected. If open is + // TRUE, then folders are opened up along the way to the + // selection. + virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, + BOOL take_keyboard_focus); + + // This method is used to toggle the selection of an item. If + // selection is 'this', then note selection, and return TRUE. + virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); + + // this method is used to group select items + virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray& items){ return FALSE; } + + // this method is used to group select items + virtual void recursiveDeselect(BOOL deselect_self); + + // gets multiple-element selection + virtual BOOL getSelectionList(std::set &selection){return TRUE;} + + // Returns true is this object and all of its children can be removed (deleted by user) + virtual BOOL isRemovable(); + + // Returns true is this object and all of its children can be moved + virtual BOOL isMovable(); + + // destroys this item recursively + virtual void destroyView(); + + S32 getNumSelectedDescendants() { return mNumDescendantsSelected; } + + BOOL isSelected() { return mIsSelected; } + + void setIsCurSelection(BOOL select) { mIsCurSelection = select; } + + BOOL getIsCurSelection() { return mIsCurSelection; } + + BOOL hasVisibleChildren() { return mHasVisibleChildren; } + + // Call through to the viewed object and return true if it can be + // removed. Returns true if it's removed. + //virtual BOOL removeRecursively(BOOL single_item); + BOOL remove(); + + // Build an appropriate context menu for the item. Flags unused. + void buildContextMenu(LLMenuGL& menu, U32 flags); + + // This method returns the actual name of the thing being + // viewed. This method will ask the viewed object itself. + const std::string& getName( void ) const; + + const std::string& getSearchableLabel( void ) const; + + // This method returns the label displayed on the view. This + // method was primarily added to allow sorting on the folder + // contents possible before the entire view has been constructed. + const std::string& getLabel() const { return mLabel; } + + // Used for sorting, like getLabel() above. + virtual time_t getCreationDate() const { return mCreationDate; } + + LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; } + const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; } + + LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE ); + LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE ); + + const LLFolderViewEventListener* getListener( void ) const { return mListener; } + LLFolderViewEventListener* getListener( void ) { return mListener; } + + // just rename the object. + void rename(const std::string& new_name); + + // open + virtual void openItem( void ); + virtual void preview(void); + + // Show children (unfortunate that this is called "open") + virtual void setOpen(BOOL open = TRUE) {}; + + virtual BOOL isOpen() { return FALSE; } + + virtual LLFolderView* getRoot(); + BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor ); + S32 getIndentation() { return mIndentation; } + + virtual BOOL potentiallyVisible(); // do we know for a fact that this item has been filtered out? + + virtual BOOL getFiltered(); + virtual BOOL getFiltered(S32 filter_generation); + virtual void setFiltered(BOOL filtered, S32 filter_generation); + + // change the icon + void setIcon(LLUIImagePtr icon); + + // refresh information from the object being viewed. + void refreshFromListener(); + virtual void refresh(); + + virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor); + + // LLView functionality + virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); + virtual BOOL handleHover( S32 x, S32 y, MASK mask ); + virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); + virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); + virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + + // virtual void handleDropped(); + virtual void draw(); + virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); +}; + + +// function used for sorting. +typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b); + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFolderViewFolder +// +// An instance of an LLFolderViewFolder represents a collection of +// more folders and items. This is used to build the hierarchy of +// items found in the folder view. :) +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLFolderViewFolder : public LLFolderViewItem +{ +protected: + LLFolderViewFolder( const LLFolderViewItem::Params& ); + friend class LLUICtrlFactory; + +public: + typedef enum e_trash + { + UNKNOWN, TRASH, NOT_TRASH + } ETrash; + +protected: + typedef std::list items_t; + typedef std::list folders_t; + items_t mItems; + folders_t mFolders; + LLInventorySort mSortFunction; + + BOOL mIsOpen; + BOOL mExpanderHighlighted; + F32 mCurHeight; + F32 mTargetHeight; + F32 mAutoOpenCountdown; + time_t mSubtreeCreationDate; + mutable ETrash mAmTrash; + S32 mLastArrangeGeneration; + S32 mLastCalculatedWidth; + S32 mCompletedFilterGeneration; + S32 mMostFilteredDescendantGeneration; + bool mNeedsSort; +public: + typedef enum e_recurse_type + { + RECURSE_NO, + RECURSE_UP, + RECURSE_DOWN, + RECURSE_UP_DOWN + } ERecurseType; + + + virtual ~LLFolderViewFolder( void ); + + virtual BOOL potentiallyVisible(); + + LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE ); + LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE ); + + // addToFolder() returns TRUE if it succeeds. FALSE otherwise + virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); + + // Finds width and height of this object and it's children. Also + // makes sure that this view and it's children are the right size. + virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); + + BOOL needsArrange(); + void requestSort(); + + // Returns the sort group (system, trash, folder) for this folder. + virtual EInventorySortGroup getSortGroup() const; + + virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up); + virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; } + + BOOL hasFilteredDescendants(S32 filter_generation) { return mMostFilteredDescendantGeneration >= filter_generation; } + BOOL hasFilteredDescendants(); + + // applies filters to control visibility of inventory items + virtual void filter( LLInventoryFilter& filter); + virtual void setFiltered(BOOL filtered, S32 filter_generation); + virtual void dirtyFilter(); + + // Passes selection information on to children and record + // selection information if necessary. Returns TRUE if this object + // (or a child) was affected. + virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, + BOOL take_keyboard_focus); + + // This method is used to change the selection of an item. If + // selection is 'this', then note selection as true. Returns TRUE + // if this or a child is now selected. + virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); + + // this method is used to group select items + virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray& items); + + virtual void recursiveDeselect(BOOL deselect_self); + + // Returns true is this object and all of its children can be removed. + virtual BOOL isRemovable(); + + // Returns true is this object and all of its children can be moved + virtual BOOL isMovable(); + + // destroys this folder, and all children + virtual void destroyView(); + + // If this folder can be removed, remove all children that can be + // removed, return TRUE if this is empty after the operation and + // it's viewed folder object can be removed. + //virtual BOOL removeRecursively(BOOL single_item); + //virtual BOOL remove(); + + // remove the specified item (and any children) if + // possible. Return TRUE if the item was deleted. + BOOL removeItem(LLFolderViewItem* item); + + // simply remove the view (and any children) Don't bother telling + // the listeners. + void removeView(LLFolderViewItem* item); + + // extractItem() removes the specified item from the folder, but + // doesn't delete it. + void extractItem( LLFolderViewItem* item ); + + // This function is called by a child that needs to be resorted. + void resort(LLFolderViewItem* item); + + void setItemSortOrder(U32 ordering); + void sortBy(U32); + //BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b)); + + void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; } + + // folders can be opened. This will usually be called by internal + // methods. + virtual void toggleOpen(); + + // Force a folder open or closed + virtual void setOpen(BOOL openitem = TRUE); + + // Called when a child is refreshed. + // don't rearrange child folder contents unless explicitly requested + virtual void requestArrange(BOOL include_descendants = FALSE); + + // internal method which doesn't update the entire view. This + // method was written because the list iterators destroy the state + // of other iterations, thus, we can't arrange while iterating + // through the children (such as when setting which is selected. + virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO); + + // Get the current state of the folder. + virtual BOOL isOpen() { return mIsOpen; } + + // special case if an object is dropped on the child. + BOOL handleDragAndDropFromChild(MASK mask, + BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + + void applyFunctorRecursively(LLFolderViewFunctor& functor); + virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor); + + virtual void openItem( void ); + virtual BOOL addItem(LLFolderViewItem* item); + virtual BOOL addFolder( LLFolderViewFolder* folder); + + // LLView functionality + virtual BOOL handleHover(S32 x, S32 y, MASK mask); + virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); + virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); + virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + virtual void draw(); + + time_t getCreationDate() const; + bool isTrash() const; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFolderViewListenerFunctor +// +// This simple abstract base class can be used to applied to all +// listeners in a hierarchy. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLFolderViewListenerFunctor +{ +public: + virtual ~LLFolderViewListenerFunctor() {} + virtual void operator()(LLFolderViewEventListener* listener) = 0; +}; + +#endif // LLFOLDERVIEWITEM_H diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 0f2951d9df..69498d3099 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -50,16 +50,13 @@ // newview #include "llagent.h" -#include "llchatbar.h" #include "lldelayedgestureerror.h" #include "llinventorymodel.h" #include "llnotify.h" #include "llviewermessage.h" #include "llvoavatarself.h" #include "llviewerstats.h" -#include "llbottomtray.h" - -LLGestureManager gGestureManager; +#include "llnearbychatbar.h" // Longest time, in seconds, to wait for all animations to stop playing const F32 MAX_WAIT_ANIM_SECS = 30.f; @@ -72,7 +69,9 @@ LLGestureManager::LLGestureManager() mPlaying(), mActive(), mLoadingCount(0) -{ } +{ + gInventory.addObserver(this); +} // We own the data for gestures, so clean them up. @@ -86,6 +85,7 @@ LLGestureManager::~LLGestureManager() delete gesture; gesture = NULL; } + gInventory.removeObserver(this); } @@ -443,7 +443,7 @@ void LLGestureManager::replaceGesture(const LLUUID& item_id, LLMultiGesture* new void LLGestureManager::replaceGesture(const LLUUID& item_id, const LLUUID& new_asset_id) { - item_map_t::iterator it = gGestureManager.mActive.find(item_id); + item_map_t::iterator it = LLGestureManager::instance().mActive.find(item_id); if (it == mActive.end()) { llwarns << "replaceGesture for inactive gesture " << item_id << llendl; @@ -452,7 +452,7 @@ void LLGestureManager::replaceGesture(const LLUUID& item_id, const LLUUID& new_a // mActive owns this gesture pointer, so clean up memory. LLMultiGesture* gesture = (*it).second; - gGestureManager.replaceGesture(item_id, gesture, new_asset_id); + LLGestureManager::instance().replaceGesture(item_id, gesture, new_asset_id); } void LLGestureManager::playGesture(LLMultiGesture* gesture) @@ -872,7 +872,7 @@ void LLGestureManager::runStep(LLMultiGesture* gesture, LLGestureStep* step) const BOOL animate = FALSE; - LLBottomTray::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate); + LLNearbyChatBar::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate); gesture->mCurrentStep++; break; @@ -922,7 +922,7 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs, delete info; info = NULL; - gGestureManager.mLoadingCount--; + LLGestureManager::instance().mLoadingCount--; if (0 == status) { @@ -944,22 +944,34 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs, { if (deactivate_similar) { - gGestureManager.deactivateSimilarGestures(gesture, item_id); + LLGestureManager::instance().deactivateSimilarGestures(gesture, item_id); // Display deactivation message if this was the last of the bunch. - if (gGestureManager.mLoadingCount == 0 - && gGestureManager.mDeactivateSimilarNames.length() > 0) + if (LLGestureManager::instance().mLoadingCount == 0 + && LLGestureManager::instance().mDeactivateSimilarNames.length() > 0) { // we're done with this set of deactivations LLSD args; - args["NAMES"] = gGestureManager.mDeactivateSimilarNames; + args["NAMES"] = LLGestureManager::instance().mDeactivateSimilarNames; LLNotifications::instance().add("DeactivatedGesturesTrigger", args); } } + LLViewerInventoryItem* item = gInventory.getItem(item_id); + if(item) + { + gesture->mName = item->getName(); + } + else + { + // Watch this item and set gesture name when item exists in inventory + LLGestureManager::instance().watchItem(item_id); + } + LLGestureManager::instance().mActive[item_id] = gesture; + // Everything has been successful. Add to the active list. - gGestureManager.mActive[item_id] = gesture; gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); + if (inform_server) { // Inform the database of this change @@ -978,13 +990,13 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs, gAgent.sendReliableMessage(); } - gGestureManager.notifyObservers(); + LLGestureManager::instance().notifyObservers(); } else { llwarns << "Unable to load gesture" << llendl; - gGestureManager.mActive.erase(item_id); + LLGestureManager::instance().mActive.erase(item_id); delete gesture; gesture = NULL; @@ -1006,7 +1018,7 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs, llwarns << "Problem loading gesture: " << status << llendl; - gGestureManager.mActive.erase(item_id); + LLGestureManager::instance().mActive.erase(item_id); } } @@ -1134,3 +1146,19 @@ void LLGestureManager::getItemIDs(std::vector* ids) ids->push_back(it->first); } } + +void LLGestureManager::done() +{ + for(item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it) + { + if(it->second->mName.empty()) + { + LLViewerInventoryItem* item = gInventory.getItem(it->first); + if(item) + { + it->second->mName = item->getName(); + } + } + } + notifyObservers(); +} diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index f564c17486..947773d66d 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -38,6 +38,8 @@ #include #include "llassetstorage.h" // LLAssetType +#include "llinventorymodel.h" +#include "llsingleton.h" #include "llviewerinventory.h" class LLMultiGesture; @@ -52,7 +54,7 @@ public: virtual void changed() = 0; }; -class LLGestureManager +class LLGestureManager : public LLSingleton, public LLInventoryCompletionObserver { public: LLGestureManager(); @@ -133,6 +135,9 @@ protected: // Do a single step in a gesture void runStep(LLMultiGesture* gesture, LLGestureStep* step); + // LLInventoryCompletionObserver trigger + void done(); + // Used by loadGesture static void onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, @@ -158,6 +163,4 @@ public: std::vector mObservers; }; -extern LLGestureManager gGestureManager; - #endif diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index cda30d8900..30f4447283 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -39,6 +39,127 @@ #include "llfloatergroupinfo.h" #include "llfloaterreg.h" #include "llimview.h" // for gIMMgr +#include "llgroupmgr.h" +#include "llavataractions.h" +#include "llviewercontrol.h" + +// LLGroupActions::teleport helper +// +// Method is offerTeleport should be called. +// First it checks, whether LLGroupMgr contains LLGroupMgrGroupData for this group already. +// If it's there, processMembersList can be called, which builds vector of ID's for online members and +// calls LLAvatarActions::offerTeleport. +// If LLGroupMgr doesn't contain LLGroupMgrGroupData, then ID of group should be saved in +// mID or queue, if mID is not empty. After that processQueue uses ID from mID or queue, +// registers LLGroupTeleporter as observer at LLGroupMgr and sends request for group members. +// LLGroupMgr notifies about response on this request by calling method 'changed'. +// It calls processMembersList, sets mID to null, to indicate that current group is processed, +// and calls processQueue to process remaining groups. +// The reason of calling of LLGroupMgr::addObserver and LLGroupMgr::removeObserver in +// processQueue and 'changed' methods is that LLGroupMgr notifies observers of only particular group, +// so, for each group mID should be updated and addObserver/removeObserver is called. + +class LLGroupTeleporter : public LLGroupMgrObserver +{ +public: + LLGroupTeleporter() : LLGroupMgrObserver(LLUUID()) {} + + void offerTeleport(const LLUUID& group_id); + + // LLGroupMgrObserver trigger + virtual void changed(LLGroupChange gc); +private: + void processQueue(); + void processMembersList(LLGroupMgrGroupData* gdatap); + + std::queue mGroupsQueue; +}; + +void LLGroupTeleporter::offerTeleport(const LLUUID& group_id) +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id); + + if (!gdatap || !gdatap->isMemberDataComplete()) + { + if (mID.isNull()) + mID = group_id; + else + // Not null mID means that user requested next group teleport before + // previous group is processed, so this group goes to queue + mGroupsQueue.push(group_id); + + processQueue(); + } + else + { + processMembersList(gdatap); + } +} + +// Sends request for group in mID or one group in queue +void LLGroupTeleporter::processQueue() +{ + // Get group from queue, if mID is empty + if (mID.isNull() && !mGroupsQueue.empty()) + { + mID = mGroupsQueue.front(); + mGroupsQueue.pop(); + } + + if (mID.notNull()) + { + LLGroupMgr::getInstance()->addObserver(this); + LLGroupMgr::getInstance()->sendGroupMembersRequest(mID); + } +} + +// Collects all online members of group and offers teleport to them +void LLGroupTeleporter::processMembersList(LLGroupMgrGroupData* gdatap) +{ + U32 limit = gSavedSettings.getU32("GroupTeleportMembersLimit"); + + LLDynamicArray ids; + for (LLGroupMgrGroupData::member_list_t::iterator iter = gdatap->mMembers.begin(); iter != gdatap->mMembers.end(); iter++) + { + LLGroupMemberData* member = iter->second; + if (!member) + continue; + + if (member->getID() == gAgent.getID()) + // No need to teleport own avatar + continue; + + if (member->getOnlineStatus() == "Online") + ids.push_back(member->getID()); + + if ((U32)ids.size() >= limit) + break; + } + + LLAvatarActions::offerTeleport(ids); +} + +// LLGroupMgrObserver trigger +void LLGroupTeleporter::changed(LLGroupChange gc) +{ + if (gc == GC_MEMBER_DATA) + { + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); + + if (gdatap && gdatap->isMemberDataComplete()) + processMembersList(gdatap); + + LLGroupMgr::getInstance()->removeObserver(this); + + // group in mID is processed + mID.setNull(); + + // process other groups in queue, if any + processQueue(); + } +} + +static LLGroupTeleporter sGroupTeleporter; // static void LLGroupActions::search() @@ -119,6 +240,12 @@ void LLGroupActions::startChat(const LLUUID& group_id) } } +// static +void LLGroupActions::offerTeleport(const LLUUID& group_id) +{ + sGroupTeleporter.offerTeleport(group_id); +} + //-- Private methods ---------------------------------------------------------- // static diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h index 1e6caea17c..b6ddb4511a 100644 --- a/indra/newview/llgroupactions.h +++ b/indra/newview/llgroupactions.h @@ -71,6 +71,11 @@ public: * Start group instant messaging session. */ static void startChat(const LLUUID& group_id); + + /** + * Offers teleport for online members of group + */ + static void offerTeleport(const LLUUID& group_id); private: static bool onLeaveGroup(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index 5d0bcab07a..278fd5b9f6 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -34,17 +34,32 @@ #include "llgrouplist.h" +// libs +#include "lltrans.h" + // newview #include "llagent.h" -static LLDefaultWidgetRegistry::Register r("group_list"); +static LLDefaultChildRegistry::Register r("group_list"); + +LLGroupList::Params::Params() +{ + // Prevent the active group from being always first in the list. + online_go_first = false; +} LLGroupList::LLGroupList(const Params& p) : LLAvatarList(p) { } -BOOL LLGroupList::updateList() +static bool findInsensitive(std::string haystack, const std::string& needle_upper) +{ + LLStringUtil::toUpper(haystack); + return haystack.find(needle_upper) != std::string::npos; +} + +BOOL LLGroupList::update(const std::string& name_filter) { LLCtrlListInterface *group_list = getListInterface(); const LLUUID& highlight_id = gAgent.getGroupID(); @@ -58,12 +73,17 @@ BOOL LLGroupList::updateList() // *TODO: check powers mask? id = gAgent.mGroups.get(i).mID; const LLGroupData& group_data = gAgent.mGroups.get(i); + if (name_filter != LLStringUtil::null && !findInsensitive(group_data.mName, name_filter)) + continue; addItem(id, group_data.mName, highlight_id == id, ADD_BOTTOM); } // add "none" to list at top - //name = LLTrans::getString("GroupsNone") - addItem(LLUUID::null, std::string("none"), highlight_id.isNull(), ADD_TOP); // *TODO: localize + { + std::string loc_none = LLTrans::getString("GroupsNone"); + if (name_filter == LLStringUtil::null || findInsensitive(loc_none, name_filter)) + addItem(LLUUID::null, loc_none, highlight_id.isNull(), ADD_TOP); + } group_list->selectByValue(highlight_id); return TRUE; diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h index ce26977fdb..e893313f4b 100644 --- a/indra/newview/llgrouplist.h +++ b/indra/newview/llgrouplist.h @@ -44,10 +44,11 @@ class LLGroupList: public LLAvatarList public: struct Params : public LLInitParam::Block { + Params(); }; LLGroupList(const Params&); - BOOL updateList(); + BOOL update(const std::string& name_filter = LLStringUtil::null); }; #endif // LL_LLGROUPLIST_H diff --git a/indra/newview/llhomelocationresponder.cpp b/indra/newview/llhomelocationresponder.cpp index 3ef58e7561..df478a0a04 100644 --- a/indra/newview/llhomelocationresponder.cpp +++ b/indra/newview/llhomelocationresponder.cpp @@ -103,7 +103,7 @@ void LLHomeLocationResponder::result( const LLSD& content ) } } -void LLHomeLocationResponder::error( const LLSD& content ) +void LLHomeLocationResponder::error( U32 status, const std::string& reason ) { - llinfos << "received error(" << ll_pretty_print_sd( content ) << ")" << llendl; + llinfos << "received error(" << reason << ")" << llendl; } diff --git a/indra/newview/llhomelocationresponder.h b/indra/newview/llhomelocationresponder.h index 1e222cd5b2..3a1d8ebfed 100644 --- a/indra/newview/llhomelocationresponder.h +++ b/indra/newview/llhomelocationresponder.h @@ -42,7 +42,7 @@ class LLHomeLocationResponder : public LLHTTPClient::Responder { virtual void result( const LLSD& content ); - virtual void error( const LLSD& content ); + virtual void error( U32 status, const std::string& reason ); }; #endif diff --git a/indra/newview/llhudeffect.cpp b/indra/newview/llhudeffect.cpp index c1d46f98d4..bfd62805a1 100644 --- a/indra/newview/llhudeffect.cpp +++ b/indra/newview/llhudeffect.cpp @@ -38,7 +38,6 @@ #include "llgl.h" #include "llagent.h" #include "llrendersphere.h" -#include "llimagegl.h" #include "llviewerobjectlist.h" #include "lldrawable.h" diff --git a/indra/newview/llhudeffectbeam.cpp b/indra/newview/llhudeffectbeam.cpp index 6cb3bef751..43a8dd1d81 100644 --- a/indra/newview/llhudeffectbeam.cpp +++ b/indra/newview/llhudeffectbeam.cpp @@ -43,7 +43,6 @@ #include "llgl.h" #include "llglheaders.h" #include "llhudrender.h" -#include "llimagegl.h" #include "llrendersphere.h" #include "llviewercamera.h" #include "llvoavatar.h" diff --git a/indra/newview/llhudeffecttrail.cpp b/indra/newview/llhudeffecttrail.cpp index 0ade6810ba..786491211d 100644 --- a/indra/newview/llhudeffecttrail.cpp +++ b/indra/newview/llhudeffecttrail.cpp @@ -35,14 +35,13 @@ #include "llhudeffecttrail.h" #include "llviewercontrol.h" -#include "llimagegl.h" #include "message.h" #include "llagent.h" #include "llbox.h" #include "lldrawable.h" #include "llhudrender.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewerpartsim.h" #include "llviewerpartsource.h" diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index 3535fe185c..eda1d3fc55 100644 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -40,7 +40,7 @@ #include "llviewerobject.h" #include "lldrawable.h" #include "llviewercamera.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llviewerwindow.h" //----------------------------------------------------------------------------- @@ -144,7 +144,7 @@ void LLHUDIcon::renderIcon(BOOL for_select) alpha_factor *= clamp_rescale(time_elapsed, MAX_VISIBLE_TIME - FADE_OUT_TIME, MAX_VISIBLE_TIME, 1.f, 0.f); } - F32 image_aspect = (F32)mImagep->mFullWidth / (F32)mImagep->mFullHeight; + F32 image_aspect = (F32)mImagep->getFullWidth() / (F32)mImagep->getFullHeight() ; LLVector3 x_scale = image_aspect * (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * x_pixel_vec; LLVector3 y_scale = (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * y_pixel_vec; @@ -164,7 +164,7 @@ void LLHUDIcon::renderIcon(BOOL for_select) LLColor4 icon_color = LLColor4::white; icon_color.mV[VALPHA] = alpha_factor; gGL.color4fv(icon_color.mV); - gGL.getTexUnit(0)->bind(mImagep.get()); + gGL.getTexUnit(0)->bind(mImagep); } gGL.begin(LLRender::QUADS); @@ -181,7 +181,7 @@ void LLHUDIcon::renderIcon(BOOL for_select) gGL.end(); } -void LLHUDIcon::setImage(LLViewerImage* imagep) +void LLHUDIcon::setImage(LLViewerTexture* imagep) { mImagep = imagep; mImagep->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -260,7 +260,7 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en return FALSE; } - F32 image_aspect = (F32)mImagep->mFullWidth / (F32)mImagep->mFullHeight; + F32 image_aspect = (F32)mImagep->getFullWidth() / (F32)mImagep->getFullHeight() ; LLVector3 x_scale = image_aspect * (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * x_pixel_vec; LLVector3 y_scale = (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * y_pixel_vec; diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h index 2c1c549521..770e3bbcd0 100644 --- a/indra/newview/llhudicon.h +++ b/indra/newview/llhudicon.h @@ -61,7 +61,7 @@ public: /*virtual*/ void markDead(); /*virtual*/ F32 getDistance() const { return mDistance; } - void setImage(LLViewerImage* imagep); + void setImage(LLViewerTexture* imagep); void setScale(F32 fraction_of_fov); void restartLifeTimer() { mLifeTimer.reset(); } @@ -88,7 +88,7 @@ protected: void renderIcon(BOOL for_select); // common render code private: - LLPointer mImagep; + LLPointer mImagep; LLFrameTimer mAnimTimer; LLFrameTimer mLifeTimer; F32 mDistance; diff --git a/indra/newview/llhudmanager.cpp b/indra/newview/llhudmanager.cpp index e1e9d9c51e..8588de0fa0 100644 --- a/indra/newview/llhudmanager.cpp +++ b/indra/newview/llhudmanager.cpp @@ -40,6 +40,7 @@ #include "llagent.h" #include "llhudeffect.h" #include "pipeline.h" +#include "llui.h" #include "llviewercontrol.h" #include "llviewerobjectlist.h" @@ -52,9 +53,9 @@ LLColor4 LLHUDManager::sChildColor; LLHUDManager::LLHUDManager() { - LLHUDManager::sParentColor = gSavedSkinSettings.getColor("FocusColor"); + LLHUDManager::sParentColor = LLUIColorTable::instance().getColor("FocusColor"); // rdw commented out since it's not used. Also removed from colors_base.xml - //LLHUDManager::sChildColor =gSavedSkinSettings.getColor("FocusSecondaryColor"); + //LLHUDManager::sChildColor =LLUIColorTable::instance().getColor("FocusSecondaryColor"); } LLHUDManager::~LLHUDManager() diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp index fe65a12c47..886fe3da07 100644 --- a/indra/newview/llhudrender.cpp +++ b/indra/newview/llhudrender.cpp @@ -40,9 +40,9 @@ #include "v3math.h" #include "llquaternion.h" #include "llfontgl.h" -#include "llimagegl.h" #include "llglheaders.h" #include "llviewerwindow.h" +#include "llui.h" void hud_render_utf8text(const std::string &str, const LLVector3 &pos_agent, const LLFontGL &font, diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index efeac9c197..c71262c311 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -39,16 +39,14 @@ #include "llagent.h" #include "llviewercontrol.h" -#include "llchatbar.h" #include "llcriticaldamp.h" #include "lldrawable.h" #include "llfontgl.h" #include "llglheaders.h" #include "llhudrender.h" -#include "llimagegl.h" #include "llui.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobject.h" #include "llvovolume.h" #include "llviewerwindow.h" @@ -292,7 +290,7 @@ void LLHUDText::renderText(BOOL for_select) LLUIImagePtr imagep = LLUI::getUIImage("rounded_square.tga"); // *TODO: make this a per-text setting - LLColor4 bg_color = gSavedSkinSettings.getColor4("BackgroundChatColor"); + LLColor4 bg_color = LLUIColorTable::instance().getColor("BackgroundChatColor"); bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); const S32 border_height = 16; @@ -804,10 +802,6 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset) LLRect world_rect = gViewerWindow->getVirtualWorldViewRect(); S32 bottom = world_rect.mBottom + STATUS_BAR_HEIGHT; - if (gChatBar && gChatBar->getVisible()) - { - bottom += CHAT_BAR_HEIGHT; - } LLVector2 screen_center; screen_center.mV[VX] = llclamp((F32)screen_pos_vec.mV[VX], (F32)world_rect.mLeft + mWidth * 0.5f, (F32)world_rect.mRight - mWidth * 0.5f); diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 6acd174fc3..4ae188977e 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -35,6 +35,7 @@ #include "llimpanel.h" #include "indra_constants.h" +#include "llfloaterreg.h" #include "llfocusmgr.h" #include "llfontgl.h" #include "llrect.h" @@ -45,22 +46,26 @@ #include "llagent.h" #include "llbutton.h" +#include "llbottomtray.h" #include "llcallingcard.h" #include "llchat.h" +#include "llchiclet.h" #include "llconsole.h" #include "llfloater.h" #include "llfloatercall.h" #include "llfloatergroupinfo.h" -#include "llfriendactions.h" +#include "llavataractions.h" #include "llimview.h" #include "llinventory.h" #include "llinventorymodel.h" -#include "llinventoryview.h" -#include "llfloateractivespeakers.h" +#include "llfloaterinventory.h" #include "llfloaterchat.h" +#include "lliconctrl.h" +#include "llimview.h" // for LLIMModel to get other avatar id in chat #include "llkeyboard.h" #include "lllineeditor.h" #include "llnotify.h" +#include "llpanelimcontrolpanel.h" #include "llrecentpeople.h" #include "llresmgr.h" #include "lltrans.h" @@ -101,190 +106,7 @@ LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL; BOOL LLVoiceChannel::sSuspended = FALSE; -void session_starter_helper( - const LLUUID& temp_session_id, - const LLUUID& other_participant_id, - EInstantMessage im_type) -{ - LLMessageSystem *msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ImprovedInstantMessage); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - - msg->nextBlockFast(_PREHASH_MessageBlock); - msg->addBOOLFast(_PREHASH_FromGroup, FALSE); - msg->addUUIDFast(_PREHASH_ToAgentID, other_participant_id); - msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); - msg->addU8Fast(_PREHASH_Dialog, im_type); - msg->addUUIDFast(_PREHASH_ID, temp_session_id); - msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary - - std::string name; - gAgent.buildFullname(name); - - msg->addStringFast(_PREHASH_FromAgentName, name); - msg->addStringFast(_PREHASH_Message, LLStringUtil::null); - msg->addU32Fast(_PREHASH_ParentEstateID, 0); - msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null); - msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); -} - -void start_deprecated_conference_chat( - const LLUUID& temp_session_id, - const LLUUID& creator_id, - const LLUUID& other_participant_id, - const LLSD& agents_to_invite) -{ - U8* bucket; - U8* pos; - S32 count; - S32 bucket_size; - - // *FIX: this could suffer from endian issues - count = agents_to_invite.size(); - bucket_size = UUID_BYTES * count; - bucket = new U8[bucket_size]; - pos = bucket; - - for(S32 i = 0; i < count; ++i) - { - LLUUID agent_id = agents_to_invite[i].asUUID(); - - memcpy(pos, &agent_id, UUID_BYTES); - pos += UUID_BYTES; - } - - session_starter_helper( - temp_session_id, - other_participant_id, - IM_SESSION_CONFERENCE_START); - - gMessageSystem->addBinaryDataFast( - _PREHASH_BinaryBucket, - bucket, - bucket_size); - - gAgent.sendReliableMessage(); - - delete[] bucket; -} - -class LLStartConferenceChatResponder : public LLHTTPClient::Responder -{ -public: - LLStartConferenceChatResponder( - const LLUUID& temp_session_id, - const LLUUID& creator_id, - const LLUUID& other_participant_id, - const LLSD& agents_to_invite) - { - mTempSessionID = temp_session_id; - mCreatorID = creator_id; - mOtherParticipantID = other_participant_id; - mAgents = agents_to_invite; - } - - virtual void error(U32 statusNum, const std::string& reason) - { - //try an "old school" way. - if ( statusNum == 400 ) - { - start_deprecated_conference_chat( - mTempSessionID, - mCreatorID, - mOtherParticipantID, - mAgents); - } - - //else throw an error back to the client? - //in theory we should have just have these error strings - //etc. set up in this file as opposed to the IMMgr, - //but the error string were unneeded here previously - //and it is not worth the effort switching over all - //the possible different language translations - } - -private: - LLUUID mTempSessionID; - LLUUID mCreatorID; - LLUUID mOtherParticipantID; - - LLSD mAgents; -}; - -// Returns true if any messages were sent, false otherwise. -// Is sort of equivalent to "does the server need to do anything?" -bool send_start_session_messages( - const LLUUID& temp_session_id, - const LLUUID& other_participant_id, - const std::vector& ids, - EInstantMessage dialog) -{ - if ( dialog == IM_SESSION_GROUP_START ) - { - session_starter_helper( - temp_session_id, - other_participant_id, - dialog); - - switch(dialog) - { - case IM_SESSION_GROUP_START: - gMessageSystem->addBinaryDataFast( - _PREHASH_BinaryBucket, - EMPTY_BINARY_BUCKET, - EMPTY_BINARY_BUCKET_SIZE); - break; - default: - break; - } - gAgent.sendReliableMessage(); - - return true; - } - else if ( dialog == IM_SESSION_CONFERENCE_START ) - { - LLSD agents; - for (int i = 0; i < (S32) ids.size(); i++) - { - agents.append(ids[i]); - } - - //we have a new way of starting conference calls now - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - std::string url = region->getCapability( - "ChatSessionRequest"); - LLSD data; - data["method"] = "start conference"; - data["session-id"] = temp_session_id; - - data["params"] = agents; - - LLHTTPClient::post( - url, - data, - new LLStartConferenceChatResponder( - temp_session_id, - gAgent.getID(), - other_participant_id, - data["params"])); - } - else - { - start_deprecated_conference_chat( - temp_session_id, - gAgent.getID(), - other_participant_id, - agents); - } - } - - return false; -} class LLVoiceCallCapResponder : public LLHTTPClient::Responder { @@ -627,13 +449,17 @@ void LLVoiceChannel::setState(EState state) void LLVoiceChannel::toggleCallWindowIfNeeded(EState state) { if (state == STATE_CONNECTED) - LLFloaterCall::openInstance(mSessionID); + { + LLFloaterReg::showInstance("voice_call", mSessionID); + } // By checking that current state is CONNECTED we make sure that the call window // has been shown, hence there's something to hide. This helps when user presses // the "End call" button right after initiating the call. // *TODO: move this check to LLFloaterCall? else if (state == STATE_HUNG_UP && mState == STATE_CONNECTED) - LLFloaterCall::closeInstance(mSessionID); + { + LLFloaterReg::hideInstance("voice_call", mSessionID); + } } //static @@ -1184,7 +1010,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label, // All participants will be added to the list of people we've recently interacted with. mSpeakers->addListener(&LLRecentPeople::instance(), "add"); - LLUICtrlFactory::getInstance()->buildFloater(this, xml_filename, FALSE); + LLUICtrlFactory::getInstance()->buildFloater(this, xml_filename, NULL); setTitle(mSessionLabel); mInputEditor->setMaxTextLength(1023); @@ -1200,7 +1026,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label, if ( !mSessionInitialized ) { - if ( !send_start_session_messages( + if ( !LLIMModel::instance().sendStartSession( mSessionUUID, mOtherParticipantUUID, mSessionInitialTargetIDs, @@ -1222,7 +1048,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label, addHistoryLine( session_start, - gSavedSkinSettings.getColor4("SystemChatColor"), + LLUIColorTable::instance().getColor("SystemChatColor"), false); } } @@ -1267,6 +1093,10 @@ LLFloaterIMPanel::~LLFloaterIMPanel() BOOL LLFloaterIMPanel::postBuild() { + mCloseSignal.connect(boost::bind(&LLFloaterIMPanel::onClose, this)); + + mVisibleSignal.connect(boost::bind(&LLFloaterIMPanel::onVisibilityChange, this, _2)); + requires("chat_editor"); requires("im_history"); @@ -1542,34 +1372,42 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 prepend_newline = false; } + std::string separator_string(": "); + // 'name' is a sender name that we want to hotlink so that clicking on it opens a profile. if (!name.empty()) // If name exists, then add it to the front of the message. { // Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text. if (name == SYSTEM_FROM) { - mHistoryEditor->appendColoredText(name,false,prepend_newline,color); + mHistoryEditor->appendColoredText(name + separator_string, false, prepend_newline, color); } else { // Convert the name to a hotlink and add to message. const LLStyleSP &source_style = LLStyleMap::instance().lookupAgent(source); - mHistoryEditor->appendStyledText(name,false,prepend_newline,source_style); + mHistoryEditor->appendStyledText(name + separator_string, false, prepend_newline, source_style); } prepend_newline = false; } mHistoryEditor->appendColoredText(utf8msg, false, prepend_newline, color); - - if (log_to_file - && gSavedPerAccountSettings.getBOOL("LogInstantMessages") ) + S32 im_log_option = gSavedPerAccountSettings.getS32("IMLogOptions"); + if (log_to_file && (im_log_option!=LOG_CHAT)) { std::string histstr; - if (gSavedPerAccountSettings.getBOOL("IMLogTimestamp")) - histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + name + utf8msg; + if (gSavedPerAccountSettings.getBOOL("LogTimestamp")) + histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + name + separator_string + utf8msg; else - histstr = name + utf8msg; + histstr = name + separator_string + utf8msg; - LLLogChat::saveHistory(getTitle(),histstr); + if(im_log_option==LOG_BOTH_TOGETHER) + { + LLLogChat::saveHistory(std::string("chat"),histstr); + } + else + { + LLLogChat::saveHistory(getTitle(),histstr); + } } if (!isInVisibleChain()) @@ -1585,24 +1423,6 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 } -void LLFloaterIMPanel::setVisible(BOOL b) -{ - LLPanel::setVisible(b); - - LLMultiFloater* hostp = getHost(); - if( b && hostp ) - { - hostp->setFloaterFlashing(this, FALSE); - - /* Don't change containing floater title - leave it "Instant Message" JC - LLUIString title = sTitleString; - title.setArg("[NAME]", mSessionLabel); - hostp->setTitle( title ); - */ - } -} - - void LLFloaterIMPanel::setInputFocus( BOOL b ) { mInputEditor->setFocus( b ); @@ -1620,7 +1440,6 @@ void LLFloaterIMPanel::selectNone() mInputEditor->deselect(); } - BOOL LLFloaterIMPanel::handleKeyHere( KEY key, MASK mask ) { BOOL handled = FALSE; @@ -1752,7 +1571,7 @@ void LLFloaterIMPanel::onClickProfile( void* userdata ) if (self->getOtherParticipantID().notNull()) { - LLFriendActions::showProfile(self->getOtherParticipantID()); + LLAvatarActions::showProfile(self->getOtherParticipantID()); } } @@ -1843,118 +1662,29 @@ void LLFloaterIMPanel::onInputEditorKeystroke(LLLineEditor* caller, void* userda } } -void LLFloaterIMPanel::onClose(bool app_quitting) +void LLFloaterIMPanel::onClose() { setTyping(FALSE); - if(mSessionUUID.notNull()) - { - std::string name; - gAgent.buildFullname(name); - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - mOtherParticipantUUID, - name, - LLStringUtil::null, - IM_ONLINE, - IM_SESSION_LEAVE, - mSessionUUID); - gAgent.sendReliableMessage(); - } + LLIMModel::instance().sendLeaveSession(mSessionUUID, mOtherParticipantUUID); + gIMMgr->removeSession(mSessionUUID); // *HACK hide the voice floater - LLFloaterCall::toggleInstanceVisibility(FALSE, mSessionUUID); - - destroy(); + LLFloaterReg::hideInstance("voice_call", mSessionUUID); } -void LLFloaterIMPanel::onVisibilityChange(BOOL new_visibility) +void LLFloaterIMPanel::onVisibilityChange(const LLSD& new_visibility) { - if (new_visibility) + if (new_visibility.asBoolean()) { mNumUnreadMessages = 0; } - - LLFloaterCall::toggleInstanceVisibility( - new_visibility && mVoiceChannel->getState() == LLVoiceChannel::STATE_CONNECTED, - mSessionUUID); -} - -void deliver_message(const std::string& utf8_text, - const LLUUID& im_session_id, - const LLUUID& other_participant_id, - EInstantMessage dialog) -{ - std::string name; - bool sent = false; - gAgent.buildFullname(name); - - const LLRelationship* info = NULL; - info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id); - U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE; - - if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id))) - { - // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice. - sent = gVoiceClient->sendTextMessage(other_participant_id, utf8_text); - } - - if(!sent) - { - // Send message normally. - - // default to IM_SESSION_SEND unless it's nothing special - in - // which case it's probably an IM to everyone. - U8 new_dialog = dialog; - - if ( dialog != IM_NOTHING_SPECIAL ) - { - new_dialog = IM_SESSION_SEND; - } - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - other_participant_id, - name.c_str(), - utf8_text.c_str(), - offline, - (EInstantMessage)new_dialog, - im_session_id); - gAgent.sendReliableMessage(); - } - - // If there is a mute list and this is not a group chat... - if ( LLMuteList::getInstance() ) - { - // ... the target should not be in our mute list for some message types. - // Auto-remove them if present. - switch( dialog ) - { - case IM_NOTHING_SPECIAL: - case IM_GROUP_INVITATION: - case IM_INVENTORY_OFFERED: - case IM_SESSION_INVITE: - case IM_SESSION_P2P_INVITE: - case IM_SESSION_CONFERENCE_START: - case IM_SESSION_SEND: // This one is marginal - erring on the side of hearing. - case IM_LURE_USER: - case IM_GODLIKE_LURE_USER: - case IM_FRIENDSHIP_OFFERED: - LLMuteList::getInstance()->autoRemove(other_participant_id, LLMuteList::AR_IM); - break; - default: ; // do nothing - } - } - - // Add the recipient to the recent people list. - LLRecentPeople::instance().add(other_participant_id); + if (new_visibility.asBoolean() && mVoiceChannel->getState() == LLVoiceChannel::STATE_CONNECTED) + LLFloaterReg::showInstance("voice_call", mSessionUUID); + else + LLFloaterReg::hideInstance("voice_call", mSessionUUID); } void LLFloaterIMPanel::sendMsg() @@ -1978,7 +1708,7 @@ void LLFloaterIMPanel::sendMsg() if ( mSessionInitialized ) { - deliver_message(utf8_text, + LLIMModel::sendMessage(utf8_text, mSessionUUID, mOtherParticipantUUID, mDialog); @@ -2004,7 +1734,7 @@ void LLFloaterIMPanel::sendMsg() BOOL other_was_typing = mOtherTyping; - addHistoryLine(history_echo, gSavedSkinSettings.getColor("IMChatColor"), true, gAgent.getID()); + addHistoryLine(history_echo, LLUIColorTable::instance().getColor("IMChatColor"), true, gAgent.getID()); if (other_was_typing) { @@ -2084,7 +1814,7 @@ void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id) iter != mQueuedMsgsForInit.endArray(); ++iter) { - deliver_message( + LLIMModel::sendMessage( iter->asString(), mSessionUUID, mOtherParticipantUUID, @@ -2135,23 +1865,10 @@ void LLFloaterIMPanel::sendTypingState(BOOL typing) // much network traffic. Only send in person-to-person IMs. if (mDialog != IM_NOTHING_SPECIAL) return; - std::string name; - gAgent.buildFullname(name); - - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - mOtherParticipantUUID, - name, - std::string("typing"), - IM_ONLINE, - (typing ? IM_TYPING_START : IM_TYPING_STOP), - mSessionUUID); - gAgent.sendReliableMessage(); + LLIMModel::instance().sendTypingState(mSessionUUID, mOtherParticipantUUID, typing); } + void LLFloaterIMPanel::processIMTyping(const LLIMInfo* im_info, BOOL typing) { if (typing) @@ -2175,7 +1892,7 @@ void LLFloaterIMPanel::addTypingIndicator(const std::string &name) mTypingLineStartIndex = mHistoryEditor->getWText().length(); LLUIString typing_start = sTypingStartString; typing_start.setArg("[NAME]", name); - addHistoryLine(typing_start, gSavedSkinSettings.getColor4("SystemChatColor"), false); + addHistoryLine(typing_start, LLUIColorTable::instance().getColor("SystemChatColor"), false); mOtherTypingName = name; mOtherTyping = TRUE; } @@ -2206,19 +1923,19 @@ void LLFloaterIMPanel::chatFromLogFile(LLLogChat::ELogLineType type, std::string { LLFloaterIMPanel* self = (LLFloaterIMPanel*)userdata; std::string message = line; - + S32 im_log_option = gSavedPerAccountSettings.getS32("IMLogOptions"); switch (type) { case LLLogChat::LOG_EMPTY: // add warning log enabled message - if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")) + if (im_log_option!=LOG_CHAT) { message = LLTrans::getString("IM_logging_string"); } break; case LLLogChat::LOG_END: // add log end message - if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")) + if (im_log_option!=LOG_CHAT) { message = LLTrans::getString("IM_logging_string"); } @@ -2232,7 +1949,7 @@ void LLFloaterIMPanel::chatFromLogFile(LLLogChat::ELogLineType type, std::string } //self->addHistoryLine(line, LLColor4::grey, FALSE); - self->mHistoryEditor->appendColoredText(message, false, true, gSavedSkinSettings.getColor4("ChatHistoryTextColor")); + self->mHistoryEditor->appendColoredText(message, false, true, LLUIColorTable::instance().getColor("ChatHistoryTextColor")); } void LLFloaterIMPanel::showSessionStartError( @@ -2318,5 +2035,261 @@ bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const } return false; } + + +LLIMFloater::LLIMFloater(const LLUUID& session_id) + : LLFloater(session_id), + mSessionID(session_id), + mLastMessageIndex(-1), + mDialog(IM_NOTHING_SPECIAL), + mHistoryEditor(NULL), + mInputEditor(NULL), + mPositioned(false) +{ +// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml"); +} + +/* static */ +void LLIMFloater::newIMCallback(const LLSD& data){ + + if (data["num_unread"].asInteger() > 0) + { + LLUUID session_id = data["session_id"].asUUID(); + + LLIMFloater* floater = LLFloaterReg::findTypedInstance("impanel", session_id); + if (floater == NULL) + { + llwarns << "new_im_callback for non-existent session_id " << session_id << llendl; + return; + } + + // update if visible, otherwise will be updated when opened + if (floater->getVisible()) + { + floater->updateMessages(); + } + } +} + +void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata ) +{ + LLIMFloater* self = (LLIMFloater*) userdata; + self->sendMsg(); +} + +void LLIMFloater::sendMsg() +{ + if (!gAgent.isGodlike() + && (mDialog == IM_NOTHING_SPECIAL) + && mOtherParticipantUUID.isNull()) + { + llinfos << "Cannot send IM to everyone unless you're a god." << llendl; + return; + } + + if (mInputEditor) + { + LLWString text = mInputEditor->getConvertedText(); + if(!text.empty()) + { + // Truncate and convert to UTF8 for transport + std::string utf8_text = wstring_to_utf8str(text); + utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); + + LLIMModel::sendMessage(utf8_text, + mSessionID, + mOtherParticipantUUID, + mDialog); + + mInputEditor->setText(LLStringUtil::null); + + updateMessages(); + } + } +} + +LLIMFloater::~LLIMFloater() +{ +} + +//virtual +BOOL LLIMFloater::postBuild() +{ + LLPanelIMControlPanel* im_control_panel = getChild("panel_im_control_panel"); + + LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL); + if(session) + { + mOtherParticipantUUID = session->mOtherParticipantID; + im_control_panel->setAvatarId(session->mOtherParticipantID); + mDialog = session->mType; + } + + LLButton* slide_left = getChild("slide_left_btn"); + slide_left->setVisible(im_control_panel->getVisible()); + slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); + + LLButton* slide_right = getChild("slide_right_btn"); + slide_right->setVisible(!im_control_panel->getVisible()); + slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); + + mInputEditor = getChild("chat_editor"); + mInputEditor->setMaxTextLength(1023); + // enable line history support for instant message bar + mInputEditor->setEnableLineHistory(TRUE); + + mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this ); + mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this ); + mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this ); + mInputEditor->setCommitOnFocusLost( FALSE ); + mInputEditor->setRevertOnEsc( FALSE ); + mInputEditor->setReplaceNewlinesWithSpaces( FALSE ); + + childSetCommitCallback("chat_editor", onSendMsg, this); + + mHistoryEditor = getChild("im_text", true, false); + + setTitle(LLIMModel::instance().getName(mSessionID)); + setDocked(true); + + mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png"); + + return TRUE; +} + +const U32 UNDOCK_LEAP_HEIGHT = 12; +const U32 DOCK_ICON_HEIGHT = 6; + +//virtual +void LLIMFloater::onFocusLost() +{ + // spec says close if docked to bottom tray and user has clicked away + // (hence we are no longer focused) + if (isDocked()) + { + // app not quitting + closeFloater(false); + } +} + + +//virtual +void LLIMFloater::setDocked(bool docked, bool pop_on_undock) +{ + LLFloater::setDocked(docked); + + if (!docked && pop_on_undock) + { + // visually pop up a little bit to emphasize the undocking + translate(0, UNDOCK_LEAP_HEIGHT); + } +} + +void LLIMFloater::onSlide() +{ + LLPanel* im_control_panel = getChild("panel_im_control_panel"); + im_control_panel->setVisible(!im_control_panel->getVisible()); + + getChild("slide_left_btn")->setVisible(im_control_panel->getVisible()); + getChild("slide_right_btn")->setVisible(!im_control_panel->getVisible()); +} + +//static +LLIMFloater* LLIMFloater::show(const LLUUID& session_id) +{ + //hide all + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); + iter != inst_list.end(); ++iter) + { + LLIMFloater* floater = dynamic_cast(*iter); + if (floater) + { + floater->setVisible(false); + } + } + + LLIMFloater* floater = LLFloaterReg::showTypedInstance("impanel", session_id); + + floater->updateMessages(); + floater->mInputEditor->setFocus(TRUE); + return floater; +} + +void LLIMFloater::updateMessages() +{ + + std::list messages = LLIMModel::instance().getMessages(mSessionID, mLastMessageIndex+1); + + if (messages.size()) + { + std::ostringstream message; + std::list::const_reverse_iterator iter = messages.rbegin(); + std::list::const_reverse_iterator iter_end = messages.rend(); + for (; iter != iter_end; ++iter) + { + LLSD msg = *iter; + + message << msg["from"].asString() << " : " << msg["time"].asString() << "\n " << msg["message"].asString() << "\n"; + + mLastMessageIndex = msg["index"].asInteger(); + } + + mHistoryEditor->appendText(message.str(), false, false); + mHistoryEditor->setCursorAndScrollToEnd(); + } + +} +// static +void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ) +{ + LLIMFloater* self= (LLIMFloater*) userdata; + self->mHistoryEditor->setCursorAndScrollToEnd(); +} + +// static +void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) +{ + LLIMFloater* self = (LLIMFloater*) userdata; + self->setTyping(FALSE); +} + +// static +void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata) +{ + LLIMFloater* self = (LLIMFloater*)userdata; + std::string text = self->mInputEditor->getText(); + if (!text.empty()) + { + self->setTyping(TRUE); + } + else + { + // Deleting all text counts as stopping typing. + self->setTyping(FALSE); + } +} + + +//just a stub for now +void LLIMFloater::setTyping(BOOL typing) +{ +} + + +void LLIMFloater::draw() +{ + //if we are docked, make sure we've been positioned by the chiclet + if (!isDocked() || mPositioned) + { + LLFloater::draw(); + + if (isDocked()) + { + mDockTongue->draw( (getRect().getWidth()/2) - mDockTongue->getWidth()/2, -mDockTongue->getHeight()); + } + } +} + diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index 7cd19d4872..dcb0f2416f 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -195,8 +195,9 @@ public: // Check typing timeout timer. /*virtual*/ void draw(); - /*virtual*/ void onClose(bool app_quitting = FALSE); - /*virtual*/ void onVisibilityChange(BOOL new_visibility); + + void onClose(); + void onVisibilityChange(const LLSD& new_visibility); // add target ids to the session. // Return TRUE if successful, otherwise FALSE. @@ -212,7 +213,6 @@ public: void selectAll(); void selectNone(); - void setVisible(BOOL b); S32 getNumUnreadMessages() { return mNumUnreadMessages; } @@ -250,6 +250,7 @@ public: void setSpeakers(const LLSD& speaker_list); LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; } EInstantMessage getDialogType() const { return mDialog; } + void setDialogType(EInstantMessage dialog) { mDialog = dialog; } void requestAutoConnect(); @@ -356,10 +357,68 @@ private: LLFrameTimer mLastKeystrokeTimer; void disableWhileSessionStarting(); - - typedef std::map styleMap; - static styleMap mStyleMap; }; +// Individual IM window that appears at the bottom of the screen, +// optionally "docked" to the bottom tray. +class LLIMFloater : public LLFloater +{ +public: + LLIMFloater(const LLUUID& session_id); + + virtual ~LLIMFloater(); + + // LLView overrides + /*virtual*/ BOOL postBuild(); + + // LLView overrides for drawing dock tongue + /*virtual*/ + void draw(); + + // Floater should close when user clicks away to other UI area, + // hence causing focus loss. + /*virtual*/ void onFocusLost(); + + // LLFloater overrides + /*virtual*/ void setDocked(bool docked, bool pop_on_undock = true); + + static LLIMFloater* show(const LLUUID& session_id); + + // get new messages from LLIMModel + void updateMessages(); + static void onSendMsg( LLUICtrl*, void*); + void sendMsg(); + + // callback for LLIMModel on new messages + // route to specific floater if it is visible + static void newIMCallback(const LLSD& data); + + // called when docked floater's position has been set by chiclet + void setPositioned(bool b) { mPositioned = b; }; + + + +private: + + static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ); + static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata); + static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata); + void setTyping(BOOL typing); + + void onSlide(); + + LLUUID mSessionID; + S32 mLastMessageIndex; + EInstantMessage mDialog; + LLUUID mOtherParticipantUUID; + LLViewerTextEditor* mHistoryEditor; + LLLineEditor* mInputEditor; + bool mPositioned; + LLUIImagePtr mDockTongue; +}; + + + + #endif // LL_IMPANEL_H diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index cb67fd34e5..66165090ef 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -51,6 +51,7 @@ #include "llresmgr.h" #include "llfloaterchat.h" #include "llfloaterchatterbox.h" +#include "llavataractions.h" #include "llhttpnode.h" #include "llimpanel.h" #include "llresizebar.h" @@ -91,16 +92,496 @@ std::map LLFloaterIM::sEventStringsMap; std::map LLFloaterIM::sErrorStringsMap; std::map LLFloaterIM::sForceCloseSessionMap; +std::map LLIMModel::sSessionsMap; + + + +void toast_callback(const LLSD& msg){ + + //we send notifications to reset counter also + if (msg["num_unread"].asInteger()) + { + LLSD args; + args["MESSAGE"] = msg["message"]; + args["TIME"] = msg["time"]; + args["FROM"] = msg["from"]; + + LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLFloaterChatterBox::onOpen, LLFloaterChatterBox::getInstance(), msg["session_id"].asUUID())); + } +} + +LLIMModel::LLIMModel() +{ + addChangedCallback(toast_callback); + addChangedCallback(LLIMFloater::newIMCallback); +} + + +void LLIMModel::testMessages() +{ + LLUUID bot1_id("d0426ec6-6535-4c11-a5d9-526bb0c654d9"); + LLUUID bot1_session_id; + std::string from = "IM Tester"; + + bot1_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot1_id); + newSession(bot1_session_id, from, IM_NOTHING_SPECIAL, bot1_id); + addMessage(bot1_session_id, from, "Test Message: Hi from testerbot land!"); + + LLUUID bot2_id; + std::string firstname[] = {"Roflcopter", "Joe"}; + std::string lastname[] = {"Linden", "Tester", "Resident", "Schmoe"}; + + S32 rand1 = ll_rand(sizeof firstname)/(sizeof firstname[0]); + S32 rand2 = ll_rand(sizeof lastname)/(sizeof lastname[0]); + + from = firstname[rand1] + " " + lastname[rand2]; + bot2_id.generate(from); + LLUUID bot2_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot2_id); + newSession(bot2_session_id, from, IM_NOTHING_SPECIAL, bot2_id); + addMessage(bot2_session_id, from, "Test Message: Can I haz bear? "); + addMessage(bot2_session_id, from, "Test Message: OMGWTFBBQ."); +} + + +bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id) +{ + if (is_in_map(sSessionsMap, session_id)) + { + llwarns << "IM Session " << session_id << " already exists" << llendl; + return false; + } + + LLIMSession* session = new LLIMSession(name, type, other_participant_id); + sSessionsMap[session_id] = session; + + LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, name, other_participant_id); + + return true; + +} + +std::list LLIMModel::getMessages(LLUUID session_id, int start_index) +{ + std::list return_list; + + LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL); + + if (!session) + { + llwarns << "session " << session_id << "does not exist " << llendl; + return return_list; + } + + int i = session->mMsgs.size() - start_index; + + for (std::list::iterator iter = session->mMsgs.begin(); + iter != session->mMsgs.end() && i > 0; + iter++) + { + LLSD msg; + msg = *iter; + return_list.push_back(*iter); + i--; + } + + session->mNumUnread = 0; + + LLSD arg; + arg["session_id"] = session_id; + arg["num_unread"] = 0; + mChangedSignal(arg); + + // TODO: in the future is there a more efficient way to return these + return return_list; + +} + +bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string utf8_text) { + + LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL); + + if (!session) + { + llwarns << "session " << session_id << "does not exist " << llendl; + return false; + } + + LLSD message; + message["from"] = from; + message["message"] = utf8_text; + message["time"] = LLLogChat::timestamp(false); //might want to add date separately + message["index"] = (LLSD::Integer)session->mMsgs.size(); + + session->mMsgs.push_front(message); + + return true; + +} + + +bool LLIMModel::addMessage(LLUUID session_id, std::string from, std::string utf8_text) { + + LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL); + + if (!session) + { + llwarns << "session " << session_id << "does not exist " << llendl; + return false; + } + + addToHistory(session_id, from, utf8_text); + + std::string agent_name; + gAgent.buildFullname(agent_name); + + session->mNumUnread++; + + // notify listeners + LLSD arg; + arg["session_id"] = session_id; + arg["num_unread"] = session->mNumUnread; + arg["message"] = utf8_text; + mChangedSignal(arg); + + return true; +} + + +const std::string& LLIMModel::getName(LLUUID session_id) +{ + LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL); + + if (!session) + { + llwarns << "session " << session_id << "does not exist " << llendl; + return LLStringUtil::null; + } + + return session->mName; +} + + +// TODO get rid of other participant ID +void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing) +{ + std::string name; + gAgent.buildFullname(name); + + pack_instant_message( + gMessageSystem, + gAgent.getID(), + FALSE, + gAgent.getSessionID(), + other_participant_id, + name, + std::string("typing"), + IM_ONLINE, + (typing ? IM_TYPING_START : IM_TYPING_STOP), + session_id); + gAgent.sendReliableMessage(); +} + +void LLIMModel::sendLeaveSession(LLUUID session_id, LLUUID other_participant_id) +{ + if(session_id.notNull()) + { + std::string name; + gAgent.buildFullname(name); + pack_instant_message( + gMessageSystem, + gAgent.getID(), + FALSE, + gAgent.getSessionID(), + other_participant_id, + name, + LLStringUtil::null, + IM_ONLINE, + IM_SESSION_LEAVE, + session_id); + gAgent.sendReliableMessage(); + } +} + + + +void LLIMModel::sendMessage(const std::string& utf8_text, + const LLUUID& im_session_id, + const LLUUID& other_participant_id, + EInstantMessage dialog) +{ + std::string name; + bool sent = false; + gAgent.buildFullname(name); + + const LLRelationship* info = NULL; + info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id); + + U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE; + + if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id))) + { + // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice. + sent = gVoiceClient->sendTextMessage(other_participant_id, utf8_text); + } + + if(!sent) + { + // Send message normally. + + // default to IM_SESSION_SEND unless it's nothing special - in + // which case it's probably an IM to everyone. + U8 new_dialog = dialog; + + if ( dialog != IM_NOTHING_SPECIAL ) + { + new_dialog = IM_SESSION_SEND; + } + pack_instant_message( + gMessageSystem, + gAgent.getID(), + FALSE, + gAgent.getSessionID(), + other_participant_id, + name.c_str(), + utf8_text.c_str(), + offline, + (EInstantMessage)new_dialog, + im_session_id); + gAgent.sendReliableMessage(); + } + + // If there is a mute list and this is not a group chat... + if ( LLMuteList::getInstance() ) + { + // ... the target should not be in our mute list for some message types. + // Auto-remove them if present. + switch( dialog ) + { + case IM_NOTHING_SPECIAL: + case IM_GROUP_INVITATION: + case IM_INVENTORY_OFFERED: + case IM_SESSION_INVITE: + case IM_SESSION_P2P_INVITE: + case IM_SESSION_CONFERENCE_START: + case IM_SESSION_SEND: // This one is marginal - erring on the side of hearing. + case IM_LURE_USER: + case IM_GODLIKE_LURE_USER: + case IM_FRIENDSHIP_OFFERED: + LLMuteList::getInstance()->autoRemove(other_participant_id, LLMuteList::AR_IM); + break; + default: ; // do nothing + } + } + + if((dialog == IM_NOTHING_SPECIAL) && + (other_participant_id.notNull())) + { + // Do we have to replace the /me's here? + std::string from; + gAgent.buildFullname(from); + LLIMModel::instance().addToHistory(im_session_id, from, utf8_text); + } + + // Add the recipient to the recent people list. + LLRecentPeople::instance().add(other_participant_id); +} + +boost::signals2::connection LLIMModel::addChangedCallback( boost::function cb ) +{ + return mChangedSignal.connect(cb); +} + +void session_starter_helper( + const LLUUID& temp_session_id, + const LLUUID& other_participant_id, + EInstantMessage im_type) +{ + LLMessageSystem *msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_ImprovedInstantMessage); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + + msg->nextBlockFast(_PREHASH_MessageBlock); + msg->addBOOLFast(_PREHASH_FromGroup, FALSE); + msg->addUUIDFast(_PREHASH_ToAgentID, other_participant_id); + msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); + msg->addU8Fast(_PREHASH_Dialog, im_type); + msg->addUUIDFast(_PREHASH_ID, temp_session_id); + msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary + + std::string name; + gAgent.buildFullname(name); + + msg->addStringFast(_PREHASH_FromAgentName, name); + msg->addStringFast(_PREHASH_Message, LLStringUtil::null); + msg->addU32Fast(_PREHASH_ParentEstateID, 0); + msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null); + msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); +} + +void start_deprecated_conference_chat( + const LLUUID& temp_session_id, + const LLUUID& creator_id, + const LLUUID& other_participant_id, + const LLSD& agents_to_invite) +{ + U8* bucket; + U8* pos; + S32 count; + S32 bucket_size; + + // *FIX: this could suffer from endian issues + count = agents_to_invite.size(); + bucket_size = UUID_BYTES * count; + bucket = new U8[bucket_size]; + pos = bucket; + + for(S32 i = 0; i < count; ++i) + { + LLUUID agent_id = agents_to_invite[i].asUUID(); + + memcpy(pos, &agent_id, UUID_BYTES); + pos += UUID_BYTES; + } + + session_starter_helper( + temp_session_id, + other_participant_id, + IM_SESSION_CONFERENCE_START); + + gMessageSystem->addBinaryDataFast( + _PREHASH_BinaryBucket, + bucket, + bucket_size); + + gAgent.sendReliableMessage(); + + delete[] bucket; +} + +class LLStartConferenceChatResponder : public LLHTTPClient::Responder +{ +public: + LLStartConferenceChatResponder( + const LLUUID& temp_session_id, + const LLUUID& creator_id, + const LLUUID& other_participant_id, + const LLSD& agents_to_invite) + { + mTempSessionID = temp_session_id; + mCreatorID = creator_id; + mOtherParticipantID = other_participant_id; + mAgents = agents_to_invite; + } + + virtual void error(U32 statusNum, const std::string& reason) + { + //try an "old school" way. + if ( statusNum == 400 ) + { + start_deprecated_conference_chat( + mTempSessionID, + mCreatorID, + mOtherParticipantID, + mAgents); + } + + //else throw an error back to the client? + //in theory we should have just have these error strings + //etc. set up in this file as opposed to the IMMgr, + //but the error string were unneeded here previously + //and it is not worth the effort switching over all + //the possible different language translations + } + +private: + LLUUID mTempSessionID; + LLUUID mCreatorID; + LLUUID mOtherParticipantID; + + LLSD mAgents; +}; + +// Returns true if any messages were sent, false otherwise. +// Is sort of equivalent to "does the server need to do anything?" +bool LLIMModel::sendStartSession( + const LLUUID& temp_session_id, + const LLUUID& other_participant_id, + const std::vector& ids, + EInstantMessage dialog) +{ + if ( dialog == IM_SESSION_GROUP_START ) + { + session_starter_helper( + temp_session_id, + other_participant_id, + dialog); + + switch(dialog) + { + case IM_SESSION_GROUP_START: + gMessageSystem->addBinaryDataFast( + _PREHASH_BinaryBucket, + EMPTY_BINARY_BUCKET, + EMPTY_BINARY_BUCKET_SIZE); + break; + default: + break; + } + gAgent.sendReliableMessage(); + + return true; + } + else if ( dialog == IM_SESSION_CONFERENCE_START ) + { + LLSD agents; + for (int i = 0; i < (S32) ids.size(); i++) + { + agents.append(ids[i]); + } + + //we have a new way of starting conference calls now + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + std::string url = region->getCapability( + "ChatSessionRequest"); + LLSD data; + data["method"] = "start conference"; + data["session-id"] = temp_session_id; + + data["params"] = agents; + + LLHTTPClient::post( + url, + data, + new LLStartConferenceChatResponder( + temp_session_id, + gAgent.getID(), + other_participant_id, + data["params"])); + } + else + { + start_deprecated_conference_chat( + temp_session_id, + gAgent.getID(), + other_participant_id, + agents); + } + } + + return false; +} + + + // // Helper Functions // -// returns true if a should appear before b -//static BOOL group_dictionary_sort( LLGroupData* a, LLGroupData* b ) -//{ -// return (LLStringUtil::compareDict( a->mName, b->mName ) < 0); -//} - class LLViewerChatterBoxInvitationAcceptResponder : public LLHTTPClient::Responder { @@ -238,14 +719,14 @@ LLUUID LLIMMgr::computeSessionID( //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LLFloaterIM::LLFloaterIM() - : LLMultiFloater() + : LLMultiFloater(LLSD()) { // autoresize=false is necessary to avoid resizing of the IM window whenever // a session is opened or closed (it would otherwise resize the window to match // the size of the im-sesssion when they were created. This happens in // LLMultiFloater::resizeToContents() when called through LLMultiFloater::addFloater()) - this->mAutoResize = FALSE; - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im.xml"); + mAutoResize = FALSE; + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im.xml", NULL); } BOOL LLFloaterIM::postBuild() @@ -332,10 +813,10 @@ BOOL LLFloaterIM::postBuild() // Class LLIncomingCallDialog //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) : - LLModalDialog(LLStringUtil::null, 240, 200), + LLModalDialog(payload, 240, 200), mPayload(payload) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_incoming_call.xml"); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_incoming_call.xml", NULL); } BOOL LLIncomingCallDialog::postBuild() @@ -613,26 +1094,6 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response) return false; } -// -// Public Static Member Functions -// - -// This is a helper function to determine what kind of im session -// should be used for the given agent. -// static -EInstantMessage LLIMMgr::defaultIMTypeForAgent(const LLUUID& agent_id) -{ - EInstantMessage type = IM_NOTHING_SPECIAL; - if(is_agent_friend(agent_id)) - { - if(LLAvatarTracker::instance().isBuddyOnline(agent_id)) - { - type = IM_SESSION_CONFERENCE_START; - } - } - return type; -} - // // Member Functions // @@ -725,8 +1186,6 @@ void LLIMMgr::addMessage( dialog, FALSE); - notifyObserverSessionAdded(floater->getSessionID(), name, other_participant_id); - // When we get a new IM, and if you are a god, display a bit // of information about the source. This is to help liaisons // when answering questions. @@ -745,7 +1204,8 @@ void LLIMMgr::addMessage( //<< "*** region_id: " << region_id << std::endl //<< "*** position: " << position << std::endl; - floater->addHistoryLine(bonus_info.str(), gSavedSkinSettings.getColor4("SystemChatColor")); + floater->addHistoryLine(bonus_info.str(), LLUIColorTable::instance().getColor("SystemChatColor")); + LLIMModel::instance().addMessage(new_session_id, from, bonus_info.str()); } make_ui_sound("UISndNewIncomingIMSession"); @@ -754,8 +1214,8 @@ void LLIMMgr::addMessage( // now add message to floater bool is_from_system = target_id.isNull() || (from == SYSTEM_FROM); const LLColor4& color = ( is_from_system ? - gSavedSkinSettings.getColor4("SystemChatColor") : - gSavedSkinSettings.getColor("IMChatColor")); + LLUIColorTable::instance().getColor("SystemChatColor") : + LLUIColorTable::instance().getColor("IMChatColor")); if ( !link_name ) { floater->addHistoryLine(msg,color); // No name to prepend, so just add the message normally @@ -765,6 +1225,8 @@ void LLIMMgr::addMessage( floater->addHistoryLine(msg, color, true, other_participant_id, from); // Insert linked name to front of message } + LLIMModel::instance().addMessage(new_session_id, from, msg); + if( !LLFloaterReg::instanceVisible("communicate") && !floater->getVisible()) { LLFloaterChatterBox* chat_floater = LLFloaterChatterBox::getInstance(); @@ -885,7 +1347,10 @@ LLUUID LLIMMgr::addSession( TRUE); noteOfflineUsers(floater, ids); - LLFloaterReg::showInstance("communicate", session_id); + //LLFloaterReg::showInstance("communicate", session_id); + // *NOTE: Is this right? Or should we only do it for + // dialog == IM_NOTHING_SPECIAL and some group types? + LLIMFloater::show(session_id); // Only warn for regular IMs - not group IMs if( dialog == IM_NOTHING_SPECIAL ) @@ -895,6 +1360,8 @@ LLUUID LLIMMgr::addSession( } else { + // *TODO: Remove this? Otherwise old communicate window opens on + // second initiation of IM session from People panel? floater->openFloater(); } //mTabContainer->selectTabPanel(panel); @@ -936,7 +1403,8 @@ LLUUID LLIMMgr::addSession( if ( !floater ) return LLUUID::null; noteOfflineUsers(floater, ids); - LLFloaterReg::showInstance("communicate", session_id); + // *BUG: Is this correct? What do we want to spawn for group IMs? + // LLFloaterReg::showInstance("communicate", session_id); // Only warn for regular IMs - not group IMs if( dialog == IM_NOTHING_SPECIAL ) @@ -1296,6 +1764,7 @@ LLFloaterIMPanel* LLIMMgr::createFloater( LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END; LLFloaterChatterBox::getInstance()->addFloater(floater, FALSE, i_pt); mFloaters.insert(floater->getHandle()); + LLIMModel::instance().newSession(session_id, session_label, dialog, other_participant_id); return floater; } @@ -1322,6 +1791,7 @@ LLFloaterIMPanel* LLIMMgr::createFloater( LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END; LLFloaterChatterBox::getInstance()->addFloater(floater, FALSE, i_pt); mFloaters.insert(floater->getHandle()); + LLIMModel::instance().newSession(session_id, session_label, dialog, other_participant_id); return floater; } @@ -1332,7 +1802,7 @@ void LLIMMgr::noteOfflineUsers( S32 count = ids.count(); if(count == 0) { - floater->addHistoryLine(sOnlyUserMessage, gSavedSkinSettings.getColor4("SystemChatColor")); + floater->addHistoryLine(sOnlyUserMessage, LLUIColorTable::instance().getColor("SystemChatColor")); } else { @@ -1348,7 +1818,7 @@ void LLIMMgr::noteOfflineUsers( LLUIString offline = sOfflineMessage; offline.setArg("[FIRST]", first); offline.setArg("[LAST]", last); - floater->addHistoryLine(offline, gSavedSkinSettings.getColor4("SystemChatColor")); + floater->addHistoryLine(offline, LLUIColorTable::instance().getColor("SystemChatColor")); } } } @@ -1652,7 +2122,7 @@ public: { saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str()); } - std::string buffer = separator_string + saved + message.substr(message_offset); + std::string buffer = saved + message.substr(message_offset); BOOL is_this_agent = FALSE; if(from_id == gAgentID) diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 37dcd1593f..b3b821f2ac 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -38,6 +38,7 @@ #include "llinstantmessage.h" #include "lluuid.h" #include "llmultifloater.h" +#include "llrecentpeople.h" class LLFloaterChatterBox; class LLUUID; @@ -45,6 +46,47 @@ class LLFloaterIMPanel; class LLFriendObserver; class LLFloaterIM; +class LLIMModel : public LLSingleton +{ +public: + + struct LLIMSession + { + LLIMSession(std::string name, EInstantMessage type, LLUUID other_participant_id) + :mName(name), mType(type), mNumUnread(0), mOtherParticipantID(other_participant_id) {} + + std::string mName; + EInstantMessage mType; + LLUUID mOtherParticipantID; + S32 mNumUnread; + std::list mMsgs; + }; + + + LLIMModel(); + + static std::map sSessionsMap; //mapping session_id to session + boost::signals2::signal mChangedSignal; + boost::signals2::connection addChangedCallback( boost::function cb ); + + bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id); + std::list getMessages(LLUUID session_id, int start_index = 0); + bool addMessage(LLUUID session_id, std::string from, std::string utf8_text); + bool addToHistory(LLUUID session_id, std::string from, std::string utf8_text); + //used to get the name of the session, for use as the title + //currently just the other avatar name + const std::string& getName(LLUUID session_id); + + static void sendLeaveSession(LLUUID session_id, LLUUID other_participant_id); + static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id, + const std::vector& ids, EInstantMessage dialog); + static void sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing); + static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id, + const LLUUID& other_participant_id, EInstantMessage dialog); + + void testMessages(); +}; + class LLIMSessionObserver { public: @@ -53,8 +95,11 @@ public: virtual void sessionRemoved(const LLUUID& session_id) = 0; }; + class LLIMMgr : public LLSingleton { + friend class LLIMModel; + public: enum EInvitationType { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index af653238d3..5877a0b19c 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -34,7 +34,7 @@ #include // for std::pair<> -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llinventorybridge.h" #include "message.h" @@ -51,13 +51,14 @@ #include "llviewercontrol.h" #include "llfirstuse.h" +#include "llfoldertype.h" #include "llfloaterchat.h" #include "llfloatercustomize.h" #include "llfloaterproperties.h" #include "llfloaterworldmap.h" #include "llfocusmgr.h" #include "llfolderview.h" -#include "llfriendactions.h" +#include "llavataractions.h" #include "llgesturemgr.h" #include "lliconctrl.h" #include "llinventorymodel.h" @@ -75,7 +76,7 @@ #include "llscrollcontainer.h" #include "llimview.h" #include "lltooldraganddrop.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerinventory.h" #include "llviewerobjectlist.h" #include "llviewerwindow.h" @@ -88,6 +89,7 @@ #include "lltabcontainer.h" #include "lluictrlfactory.h" #include "llselectmgr.h" +#include "llsidetray.h" #include "llfloateropenobject.h" #include "lltrans.h" @@ -184,6 +186,13 @@ PermissionMask LLInvFVBridge::getPermissionMask() const return PERM_ALL; } +// virtual +LLAssetType::EType LLInvFVBridge::getPreferredType() const +{ + return LLAssetType::AT_NONE; +} + + // Folders don't have creation dates. time_t LLInvFVBridge::getCreationDate() const { @@ -195,7 +204,7 @@ BOOL LLInvFVBridge::isItemRemovable() { LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; - if(model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID())) + if(model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID())) { return TRUE; } @@ -243,7 +252,7 @@ BOOL LLInvFVBridge::isItemMovable() // *TODO: make sure this does the right thing void LLInvFVBridge::showProperties() { - LLFloaterProperties::show(mUUID); + LLFloaterReg::showInstance("properties", mUUID); } void LLInvFVBridge::removeBatch(LLDynamicArray& batch) @@ -266,7 +275,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray& batc { if(LLAssetType::AT_GESTURE == item->getType()) { - gGestureManager.deactivateGesture(item->getUUID()); + LLGestureManager::instance().deactivateGesture(item->getUUID()); } } } @@ -282,7 +291,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray& batc { if(LLAssetType::AT_GESTURE == descendent_items[j]->getType()) { - gGestureManager.deactivateGesture(descendent_items[j]->getUUID()); + LLGestureManager::instance().deactivateGesture(descendent_items[j]->getUUID()); } } } @@ -596,7 +605,7 @@ BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const if(obj) { - *type = LLAssetType::lookupDragAndDropType(obj->getType()); + *type = LLAssetType::lookupDragAndDropType(obj->getActualType()); if(*type == DAD_NONE) { return FALSE; @@ -645,11 +654,11 @@ BOOL LLInvFVBridge::isLinkedObjectInTrash() const { if (isInTrash()) return TRUE; - LLInventoryModel* model = getInventoryModel(); - if(!model) return FALSE; - LLInventoryObject *obj = model->getObject(mUUID); + LLInventoryObject *obj = getInventoryObject(); if (obj && LLAssetType::lookupIsLinkType(obj->getActualType())) { + LLInventoryModel* model = getInventoryModel(); + if(!model) return FALSE; const LLUUID& trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); return model->isObjectDescendentOf(obj->getLinkedUUID(), trash_id); } @@ -660,8 +669,8 @@ BOOL LLInvFVBridge::isAgentInventory() const { LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; - if(gAgent.getInventoryRootID() == mUUID) return TRUE; - return model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID()); + if(gInventory.getRootFolderID() == mUUID) return TRUE; + return model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()); } BOOL LLInvFVBridge::isItemPermissive() const @@ -727,6 +736,7 @@ const std::string safe_inv_type_lookup(LLInventoryType::EType inv_type) } LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, + LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, const LLUUID& uuid, @@ -825,12 +835,22 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, break; case LLAssetType::AT_CATEGORY: case LLAssetType::AT_ROOT_CATEGORY: + if (actual_asset_type == LLAssetType::AT_LINK_FOLDER) + { + // Create a link folder handler instead. + new_listener = new LLLinkFolderBridge(inventory, uuid); + break; + } new_listener = new LLFolderBridge(inventory, uuid); break; case LLAssetType::AT_LINK: // Only should happen for broken links. new_listener = new LLLinkItemBridge(inventory, uuid); break; + case LLAssetType::AT_LINK_FOLDER: + // Only should happen for broken links. + new_listener = new LLLinkItemBridge(inventory, uuid); + break; default: llinfos << "Unhandled asset type (llassetstorage.h): " << (S32)asset_type << llendl; @@ -867,6 +887,10 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid) void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) { + if ("goto" == action) + { + gotoItem(folder); + } if ("open" == action) { openItem(); @@ -997,6 +1021,19 @@ void LLItemBridge::restoreToWorld() } } +void LLItemBridge::gotoItem(LLFolderView *folder) +{ + LLInventoryObject *obj = getInventoryObject(); + if (obj && LLAssetType::lookupIsLinkType(obj->getActualType())) + { + LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel(); + if (active_panel) + { + active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO); + } + } +} + LLUIImagePtr LLItemBridge::getIcon() const { return LLUI::getUIImage(ICON_NAME[OBJECT_ICON_NAME]); @@ -1020,7 +1057,7 @@ PermissionMask LLItemBridge::getPermissionMask() const } return perm_mask; } - + const std::string& LLItemBridge::getDisplayName() const { if(mDisplayName.empty()) @@ -1062,11 +1099,13 @@ LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const std::string LLItemBridge::getLabelSuffix() const { - // assume that this won't be called before string table is loaded - static const char* NO_COPY =LLTrans::getString("NO_COPY").c_str(); - static const char* NO_MOD = LLTrans::getString("NO_MOD").c_str(); - static const char* NO_XFER = LLTrans::getString("NO_XFER").c_str(); - + // String table is loaded before login screen and inventory items are + // loaded after login, so LLTrans should be ready. + static std::string NO_COPY =LLTrans::getString("no_copy"); + static std::string NO_MOD = LLTrans::getString("no_modify"); + static std::string NO_XFER = LLTrans::getString("no_transfer"); + static std::string LINK = LLTrans::getString("link"); + static std::string BROKEN_LINK = LLTrans::getString("broken_link"); std::string suffix; LLInventoryItem* item = getItem(); if(item) @@ -1075,26 +1114,28 @@ std::string LLItemBridge::getLabelSuffix() const if(LLAssetType::AT_CALLINGCARD != item->getType() && item->getPermissions().getOwner() == gAgent.getID()) { - BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); - BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); - BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, - gAgent.getID()); - BOOL link = (item->getActualType() == LLAssetType::AT_LINK); + BOOL broken_link = LLAssetType::lookupIsLinkType(item->getType()); + if (broken_link) return BROKEN_LINK; - const char* EMPTY = ""; - const char* LINK = " (link)"; // *TODO: Seraph translate + BOOL link = LLAssetType::lookupIsLinkType(item->getActualType()); if (link) return LINK; - const char* scopy; - if(copy) scopy = EMPTY; - else scopy = NO_COPY; - const char* smod; - if(mod) smod = EMPTY; - else smod = NO_MOD; - const char* sxfer; - if(xfer) sxfer = EMPTY; - else sxfer = NO_XFER; - suffix = llformat("%s%s%s",scopy,smod,sxfer); + BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); + if (!copy) + { + suffix += NO_COPY; + } + BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); + if (!mod) + { + suffix += NO_MOD; + } + BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, + gAgent.getID()); + if (!xfer) + { + suffix += NO_XFER; + } } } return suffix; @@ -1116,6 +1157,12 @@ BOOL LLItemBridge::isItemRenameable() const LLViewerInventoryItem* item = getItem(); if(item) { + // (For now) Don't allow calling card rename since that may confuse users as to + // what the calling card points to. + if (item->getInventoryType() == LLInventoryType::IT_CALLINGCARD) + { + return FALSE; + } return (item->getPermissions().allowModifyBy(gAgent.getID())); } return FALSE; @@ -1137,7 +1184,7 @@ BOOL LLItemBridge::renameItem(const std::string& new_name) buildDisplayName(new_item, mDisplayName); new_item->updateServer(FALSE); model->updateItem(new_item); - renameLinkedItems(item->getUUID(),new_name); + model->updateLinkedObjects(item->getUUID()); model->notifyObservers(); } @@ -1195,7 +1242,7 @@ BOOL LLItemBridge::isItemCopyable() const // All items can be copied, not all can be pasted. // The only time an item can't be copied is if it's a link // return (item->getPermissions().allowCopyBy(gAgent.getID())); - if (item->getActualType() == LLAssetType::AT_LINK) + if (LLAssetType::lookupIsLinkType(item->getActualType())) { return FALSE; } @@ -1250,7 +1297,7 @@ BOOL LLFolderBridge::isItemMovable() LLInventoryObject* obj = getInventoryObject(); if(obj) { - return (LLAssetType::AT_NONE == ((LLInventoryCategory*)obj)->getPreferredType()); + return (!LLAssetType::lookupIsProtectedCategoryType(((LLInventoryCategory*)obj)->getPreferredType())); } return FALSE; } @@ -1269,7 +1316,7 @@ BOOL LLFolderBridge::isItemRemovable() return FALSE; } - if(!model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID())) + if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID())) { return FALSE; } @@ -1286,7 +1333,7 @@ BOOL LLFolderBridge::isItemRemovable() return FALSE; } - if( LLAssetType::AT_NONE != category->getPreferredType() ) + if(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType())) { return FALSE; } @@ -1299,7 +1346,7 @@ BOOL LLFolderBridge::isItemRemovable() for( i = 0; i < descendent_categories.count(); i++ ) { LLInventoryCategory* category = descendent_categories[i]; - if( LLAssetType::AT_NONE != category->getPreferredType() ) + if(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType())) { return FALSE; } @@ -1394,7 +1441,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); - BOOL is_movable = (LLAssetType::AT_NONE == inv_cat->getPreferredType()); + BOOL is_movable = (!LLAssetType::lookupIsProtectedCategoryType(inv_cat->getPreferredType())); if( is_movable ) { gInventory.collectDescendents( cat_id, descendent_categories, descendent_items, FALSE ); @@ -1402,7 +1449,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, for( i = 0; i < descendent_categories.count(); i++ ) { LLInventoryCategory* category = descendent_categories[i]; - if( LLAssetType::AT_NONE != category->getPreferredType() ) + if(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType())) { // ...can't move "special folders" like Textures is_movable = FALSE; @@ -1454,9 +1501,9 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, { LLInventoryItem* item = descendent_items[i]; if (item->getType() == LLAssetType::AT_GESTURE - && gGestureManager.isGestureActive(item->getUUID())) + && LLGestureManager::instance().isGestureActive(item->getUUID())) { - gGestureManager.deactivateGesture(item->getUUID()); + LLGestureManager::instance().deactivateGesture(item->getUUID()); } } } @@ -1859,7 +1906,7 @@ void LLFolderBridge::openItem() BOOL LLFolderBridge::isItemRenameable() const { LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)getCategory(); - if(cat && (cat->getPreferredType() == LLAssetType::AT_NONE) + if(cat && !LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType()) && (cat->getOwnerID() == gAgent.getID())) { return TRUE; @@ -1895,13 +1942,26 @@ LLAssetType::EType LLFolderBridge::getPreferredType() const // Icons for folders are based on the preferred type LLUIImagePtr LLFolderBridge::getIcon() const { - const char* control = NULL; LLAssetType::EType preferred_type = LLAssetType::AT_NONE; LLViewerInventoryCategory* cat = getCategory(); if(cat) { preferred_type = cat->getPreferredType(); } + return getIcon(preferred_type); +} + +LLUIImagePtr LLFolderBridge::getIcon(LLAssetType::EType preferred_type) +{ + if (preferred_type >= LLAssetType::AT_FOLDER_ENSEMBLE_START && + preferred_type <= LLAssetType::AT_FOLDER_ENSEMBLE_END) + { + LLUIImage* icon = LLUI::getUIImage(LLFolderType::lookupIconName(preferred_type)); + if (icon) + return icon; + } + + const char* control = NULL; switch(preferred_type) { case LLAssetType::AT_TEXTURE: @@ -1975,7 +2035,7 @@ BOOL LLFolderBridge::renameItem(const std::string& new_name) new_cat->rename(new_name); new_cat->updateServer(FALSE); model->updateCategory(new_cat); - renameLinkedItems(cat->getUUID(),new_name); + model->updateLinkedObjects(cat->getUUID()); model->notifyObservers(); } @@ -2008,9 +2068,9 @@ BOOL LLFolderBridge::removeItem() { LLInventoryItem* item = descendent_items[i]; if (item->getType() == LLAssetType::AT_GESTURE - && gGestureManager.isGestureActive(item->getUUID())) + && LLGestureManager::instance().isGestureActive(item->getUUID())) { - gGestureManager.deactivateGesture(item->getUUID()); + LLGestureManager::instance().deactivateGesture(item->getUUID()); } } @@ -2057,15 +2117,24 @@ void LLFolderBridge::pasteLinkFromClipboard() LLInventoryModel* model = getInventoryModel(); if(model) { - LLInventoryItem* item = NULL; LLDynamicArray objects; LLInventoryClipboard::instance().retrieve(objects); S32 count = objects.count(); LLUUID parent_id(mUUID); for(S32 i = 0; i < count; i++) { - item = model->getItem(objects.get(i)); - if (item) + const LLUUID &object_id = objects.get(i); + if (LLInventoryCategory *cat = model->getCategory(object_id)) + { + link_inventory_item( + gAgent.getID(), + cat->getUUID(), + parent_id, + cat->getName(), + LLAssetType::AT_LINK_FOLDER, + LLPointer(NULL)); + } + else if (LLInventoryItem *item = model->getItem(object_id)) { link_inventory_item( gAgent.getID(), @@ -2094,7 +2163,7 @@ void LLFolderBridge::folderOptionsMenu() const LLInventoryCategory* category = model->getCategory(mUUID); bool is_default_folder = category && - (LLAssetType::AT_NONE != category->getPreferredType()); + (LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType())); // calling card related functionality for folders. @@ -2190,7 +2259,14 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) mItems.push_back(std::string("New Gesture")); mItems.push_back(std::string("New Clothes")); mItems.push_back(std::string("New Body Parts")); + mItems.push_back(std::string("Change Type")); + LLViewerInventoryCategory *cat = getCategory(); + if (cat && LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())) + { + mDisabledItems.push_back(std::string("Change Type")); + } + getClipboardEntries(false, mItems, mDisabledItems, flags); //Added by spatters to force inventory pull on right-click to display folder options correctly. 07-17-06 @@ -2259,26 +2335,27 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, BOOL accept = FALSE; switch(cargo_type) { - case DAD_TEXTURE: - case DAD_SOUND: - case DAD_CALLINGCARD: - case DAD_LANDMARK: - case DAD_SCRIPT: - case DAD_OBJECT: - case DAD_NOTECARD: - case DAD_CLOTHING: - case DAD_BODYPART: - case DAD_ANIMATION: - case DAD_GESTURE: - accept = dragItemIntoFolder((LLInventoryItem*)cargo_data, - drop); - break; - case DAD_CATEGORY: - accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, + case DAD_TEXTURE: + case DAD_SOUND: + case DAD_CALLINGCARD: + case DAD_LANDMARK: + case DAD_SCRIPT: + case DAD_OBJECT: + case DAD_NOTECARD: + case DAD_CLOTHING: + case DAD_BODYPART: + case DAD_ANIMATION: + case DAD_GESTURE: + case DAD_LINK: + accept = dragItemIntoFolder((LLInventoryItem*)cargo_data, drop); - break; - default: - break; + break; + case DAD_CATEGORY: + accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, + drop); + break; + default: + break; } return accept; } @@ -2481,14 +2558,14 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { BOOL is_movable = TRUE; - switch( inv_item->getType() ) + switch( inv_item->getActualType() ) { case LLAssetType::AT_ROOT_CATEGORY: is_movable = FALSE; break; case LLAssetType::AT_CATEGORY: - is_movable = ( LLAssetType::AT_NONE == ((LLInventoryCategory*)inv_item)->getPreferredType() ); + is_movable = !LLAssetType::lookupIsProtectedCategoryType(((LLInventoryCategory*)inv_item)->getPreferredType()); break; default: break; @@ -2502,11 +2579,11 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { case LLAssetType::AT_CLOTHING: case LLAssetType::AT_BODYPART: - is_movable = !gAgentWearables.isWearingItem(inv_item->getUUID()); + is_movable = !gAgentWearables.isWearingItem(inv_item->getUUID(), TRUE); break; case LLAssetType::AT_OBJECT: - is_movable = !avatar->isWearingAttachment(inv_item->getUUID()); + is_movable = !avatar->isWearingAttachment(inv_item->getUUID(), TRUE); break; default: break; @@ -2517,17 +2594,17 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, if(accept && drop) { if (inv_item->getType() == LLAssetType::AT_GESTURE - && gGestureManager.isGestureActive(inv_item->getUUID()) && move_is_into_trash) + && LLGestureManager::instance().isGestureActive(inv_item->getUUID()) && move_is_into_trash) { - gGestureManager.deactivateGesture(inv_item->getUUID()); + LLGestureManager::instance().deactivateGesture(inv_item->getUUID()); } // If an item is being dragged between windows, unselect // everything in the active window so that we don't follow // the selection to its new location (which is very // annoying). - if (LLInventoryView::getActiveInventory()) + if (LLFloaterInventory::getActiveInventory()) { - LLInventoryPanel* active_panel = LLInventoryView::getActiveInventory()->getPanel(); + LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel(); LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); if (active_panel && (panel != active_panel)) { @@ -2817,7 +2894,15 @@ void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* mod LLViewerInventoryItem* item = getItem(); if(item) { - LLFloaterReg::showInstance("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES); + LLSD key; + key["type"] = "landmark"; + key["id"] = item->getUUID(); + + LLSideTray::getInstance()->showPanel("panel_places", key); + + // Floater preview_landmark disabled, + // its functionality moved to Side Tray Places Panel + //LLFloaterReg::showInstance("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES); } } else @@ -2908,7 +2993,9 @@ void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel* if (item && (item->getCreatorUUID() != gAgent.getID()) && (!item->getCreatorUUID().isNull())) { - gIMMgr->addSession(item->getName(), IM_NOTHING_SPECIAL, item->getCreatorUUID()); + std::string callingcard_name; + gCacheName->getFullName(item->getCreatorUUID(), callingcard_name); + gIMMgr->addSession(callingcard_name, IM_NOTHING_SPECIAL, item->getCreatorUUID()); } } else if ("lure" == action) @@ -2917,7 +3004,7 @@ void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel* if (item && (item->getCreatorUUID() != gAgent.getID()) && (!item->getCreatorUUID().isNull())) { - LLFriendActions::offerTeleport(item->getCreatorUUID()); + LLAvatarActions::offerTeleport(item->getCreatorUUID()); } } else LLItemBridge::performAction(folder, model, action); @@ -2959,7 +3046,7 @@ void LLCallingCardBridge::openItem() LLViewerInventoryItem* item = getItem(); if(item && !item->getCreatorUUID().isNull()) { - LLFriendActions::showProfile(item->getCreatorUUID()); + LLAvatarActions::showProfile(item->getCreatorUUID()); } */ } @@ -3121,7 +3208,7 @@ LLUIImagePtr LLGestureBridge::getIcon() const LLFontGL::StyleFlags LLGestureBridge::getLabelStyle() const { - if( gGestureManager.isGestureActive(mUUID) ) + if( LLGestureManager::instance().isGestureActive(mUUID) ) { return LLFontGL::BOLD; } @@ -3133,7 +3220,7 @@ LLFontGL::StyleFlags LLGestureBridge::getLabelStyle() const std::string LLGestureBridge::getLabelSuffix() const { - if( gGestureManager.isGestureActive(mUUID) ) + if( LLGestureManager::instance().isGestureActive(mUUID) ) { return LLItemBridge::getLabelSuffix() + " (active)"; } @@ -3148,7 +3235,7 @@ void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* mode { if ("activate" == action) { - gGestureManager.activateGesture(mUUID); + LLGestureManager::instance().activateGesture(mUUID); LLViewerInventoryItem* item = gInventory.getItem(mUUID); if (!item) return; @@ -3160,7 +3247,7 @@ void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* mode } else if ("deactivate" == action) { - gGestureManager.deactivateGesture(mUUID); + LLGestureManager::instance().deactivateGesture(mUUID); LLViewerInventoryItem* item = gInventory.getItem(mUUID); if (!item) return; @@ -3194,7 +3281,7 @@ void LLGestureBridge::openItem() BOOL LLGestureBridge::removeItem() { // Force close the preview window, if it exists - gGestureManager.deactivateGesture(mUUID); + LLGestureManager::instance().deactivateGesture(mUUID); return LLItemBridge::removeItem(); } @@ -3348,7 +3435,7 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model LLUUID object_id = mUUID; LLViewerInventoryItem* item; item = (LLViewerInventoryItem*)gInventory.getItem(object_id); - if(item && gInventory.isObjectDescendentOf(object_id, gAgent.getInventoryRootID())) + if(item && gInventory.isObjectDescendentOf(object_id, gInventory.getRootFolderID())) { rez_attachment(item, NULL); } @@ -3403,7 +3490,7 @@ void LLObjectBridge::openItem() } /* - LLFloaterProperties::show(mUUID); + LLFloaterReg::showInstance("properties", mUUID); */ } @@ -3418,7 +3505,7 @@ LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const } LLInventoryItem* item = getItem(); - if (item->getActualType() == LLAssetType::AT_LINK) + if (LLAssetType::lookupIsLinkType(item->getActualType())) { font |= LLFontGL::ITALIC; } @@ -3516,13 +3603,18 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else { + LLInventoryItem* item = getItem(); + if (item && LLAssetType::lookupIsLinkType(item->getActualType())) + { + items.push_back(std::string("Goto Link")); + } + items.push_back(std::string("Properties")); getClipboardEntries(true, items, disabled_items, flags); LLObjectBridge::sContextMenuItemID = mUUID; - LLInventoryItem* item = getItem(); if(item) { LLVOAvatarSelf* avatarp = gAgent.getAvatarObject(); @@ -3602,7 +3694,7 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name) buildDisplayName(new_item, mDisplayName); new_item->updateServer(FALSE); model->updateItem(new_item); - renameLinkedItems(item->getUUID(),new_name); + model->updateLinkedObjects(item->getUUID()); model->notifyObservers(); @@ -3815,7 +3907,7 @@ void LLOutfitObserver::done() } if(pid.isNull()) { - pid = gAgent.getInventoryRootID(); + pid = gInventory.getRootFolderID(); } LLUUID cat_id = gInventory.createNewCategory( @@ -3922,7 +4014,7 @@ void wear_outfit_by_name(const std::string& name) LLInventoryModel::cat_array_t cat_array; LLInventoryModel::item_array_t item_array; LLNameCategoryCollector has_name(name); - gInventory.collectDescendentsIf(gAgent.getInventoryRootID(), + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH, @@ -4064,7 +4156,7 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOO { llinfos << "Activating " << gest_count << " gestures" << llendl; - gGestureManager.activateGestures(gest_item_array); + LLGestureManager::instance().activateGestures(gest_item_array); // Update the inventory item labels to reflect the fact // they are active. @@ -4184,7 +4276,7 @@ void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void* data) iter != holder->mFoundList.end(); ++iter) { LLFoundData* data = *iter; - if(wearable->getID() == data->mAssetID) + if(wearable->getAssetID() == data->mAssetID) { data->mWearable = wearable; break; @@ -4217,7 +4309,7 @@ void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, B { LLViewerInventoryItem* item; item = (LLViewerInventoryItem*)gInventory.getItem(data->mItemID); - if( item && (item->getAssetUUID() == wearable->getID()) ) + if( item && (item->getAssetUUID() == wearable->getAssetID()) ) { items.put(item); wearables.put(wearable); @@ -4341,9 +4433,9 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_ { for(i = 0; i < gest_count; ++i) { - if ( gGestureManager.isGestureActive( gest_item_array.get(i)->getUUID()) ) + if ( LLGestureManager::instance().isGestureActive( gest_item_array.get(i)->getUUID()) ) { - gGestureManager.deactivateGesture( gest_item_array.get(i)->getUUID() ); + LLGestureManager::instance().deactivateGesture( gest_item_array.get(i)->getUUID() ); gInventory.updateItem( gest_item_array.get(i) ); gInventory.notifyObservers(); } @@ -4496,6 +4588,11 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Open")); } + if (item && LLAssetType::lookupIsLinkType(item->getActualType())) + { + items.push_back(std::string("Goto Link")); + } + items.push_back(std::string("Properties")); getClipboardEntries(true, items, disabled_items, flags); @@ -4621,9 +4718,9 @@ void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userda item = (LLViewerInventoryItem*)gInventory.getItem(*item_id); if(item) { - if(item->getAssetUUID() == wearable->getID()) + if(item->getAssetUUID() == wearable->getAssetID()) { - gAgentWearables.setWearable(item, wearable); + gAgentWearables.setWearableItem(item, wearable); gInventory.notifyObservers(); //self->getFolderItem()->refreshFromRoot(); } @@ -4646,10 +4743,10 @@ void LLWearableBridge::onWearAddOnAvatarArrived( LLWearable* wearable, void* use item = (LLViewerInventoryItem*)gInventory.getItem(*item_id); if(item) { - if(item->getAssetUUID() == wearable->getID()) + if(item->getAssetUUID() == wearable->getAssetID()) { bool do_append = true; - gAgentWearables.setWearable(item, wearable, do_append); + gAgentWearables.setWearableItem(item, wearable, do_append); gInventory.notifyObservers(); //self->getFolderItem()->refreshFromRoot(); } @@ -4683,7 +4780,7 @@ void LLWearableBridge::onEditOnAvatar(void* user_data) void LLWearableBridge::editOnAvatar() { - LLWearable* wearable = gAgentWearables.getWearableFromWearableItem(mUUID); + const LLWearable* wearable = gAgentWearables.getWearableFromWearableItem(mUUID); if( wearable ) { // Set the tab to the right wearable. @@ -4883,7 +4980,7 @@ void LLCallingCardBridgeAction::doIt() LLViewerInventoryItem* item = getItem(); if(item && item->getCreatorUUID().notNull()) { - LLFriendActions::showProfile(item->getCreatorUUID()); + LLAvatarActions::showProfile(item->getCreatorUUID()); } LLInvFVBridgeAction::doIt(); @@ -4931,7 +5028,7 @@ void LLAnimationBridgeAction::doIt() //virtual void LLObjectBridgeAction::doIt() { - LLFloaterProperties::show(mUUID); + LLFloaterReg::showInstance("properties", mUUID); LLInvFVBridgeAction::doIt(); } @@ -4960,8 +5057,8 @@ BOOL LLWearableBridgeAction::isInTrash() const BOOL LLWearableBridgeAction::isAgentInventory() const { if(!mModel) return FALSE; - if(gAgent.getInventoryRootID() == mUUID) return TRUE; - return mModel->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID()); + if(gInventory.getRootFolderID() == mUUID) return TRUE; + return mModel->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()); } void LLWearableBridgeAction::wearOnAvatar() @@ -5076,3 +5173,94 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } hideContextEntries(menu, items, disabled_items); } + + +// +=================================================+ +// | LLLinkBridge | +// +=================================================+ +// For broken links. + +std::string LLLinkFolderBridge::sPrefix("Link: "); + + +LLUIImagePtr LLLinkFolderBridge::getIcon() const +{ + LLAssetType::EType preferred_type = LLAssetType::AT_NONE; + if (LLViewerInventoryItem *item = getItem()) + { + if (const LLViewerInventoryCategory* cat = item->getLinkedCategory()) + { + preferred_type = cat->getPreferredType(); + } + } + return LLFolderBridge::getIcon(preferred_type); +} + +void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + // *TODO: Translate + lldebugs << "LLLink::buildContextMenu()" << llendl; + std::vector items; + std::vector disabled_items; + + if(isInTrash()) + { + items.push_back(std::string("Purge Item")); + if (!isItemRemovable()) + { + disabled_items.push_back(std::string("Purge Item")); + } + + items.push_back(std::string("Restore Item")); + } + else + { + items.push_back(std::string("Goto Link")); + items.push_back(std::string("Delete")); + if (!isItemRemovable()) + { + disabled_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 = getInventoryModel()) + { + model->fetchDescendentsOf(cat_uuid); + } + base_folder->setOpen(TRUE); + folder->setSelectionFromRoot(base_folder,TRUE); + } + } +} + +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; +} diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 016eb701d6..915dfec629 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -38,7 +38,8 @@ #include "llviewercontrol.h" #include "llcallingcard.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" +#include "llfoldervieweventlistener.h" enum EInventoryIcon { @@ -132,6 +133,7 @@ public: // This method is a convenience function which creates the correct // type of bridge based on some basic information static LLInvFVBridge* createBridge(LLAssetType::EType asset_type, + LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, const LLUUID& uuid, @@ -147,6 +149,7 @@ public: virtual const std::string& getName() const; virtual const std::string& getDisplayName() const; virtual PermissionMask getPermissionMask() const; + virtual LLAssetType::EType getPreferredType() const; virtual time_t getCreationDate() const; virtual LLFontGL::StyleFlags getLabelStyle() const { @@ -154,6 +157,7 @@ public: } virtual std::string getLabelSuffix() const { return LLStringUtil::null; } virtual void openItem() {} + virtual void gotoItem(LLFolderView *folder) {} // for links virtual void previewItem() {openItem();} virtual void showProperties(); virtual BOOL isItemRenameable() const { return TRUE; } @@ -229,6 +233,7 @@ public: virtual void selectItem(); virtual void restoreItem(); virtual void restoreToWorld(); + virtual void gotoItem(LLFolderView *folder); virtual LLUIImagePtr getIcon() const; virtual const std::string& getDisplayName() const; @@ -272,6 +277,8 @@ public: virtual LLAssetType::EType getPreferredType() const; virtual LLUIImagePtr getIcon() const; + static LLUIImagePtr getIcon(LLAssetType::EType asset_type); + virtual BOOL renameItem(const std::string& new_name); virtual BOOL removeItem(); virtual void pasteFromClipboard(); @@ -589,6 +596,27 @@ protected: static std::string sPrefix; }; + +class LLLinkFolderBridge : public LLItemBridge +{ + friend class LLInvFVBridge; +public: + virtual const std::string& getPrefix() { return sPrefix; } + + virtual LLUIImagePtr getIcon() const; + virtual void buildContextMenu(LLMenuGL& menu, U32 flags); + virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action); + virtual void gotoItem(LLFolderView *folder); + +protected: + LLLinkFolderBridge(LLInventoryPanel* inventory, const LLUUID& uuid) : + LLItemBridge(inventory, uuid) {} + const LLUUID &getFolderID() const; + +protected: + static std::string sPrefix; +}; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLInvFVBridgeAction (& its derived classes) // diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp new file mode 100644 index 0000000000..9cbe11f5c9 --- /dev/null +++ b/indra/newview/llinventoryfilter.cpp @@ -0,0 +1,631 @@ +/** +* @file llinventoryfilter.cpp +* @brief Support for filtering your inventory to only display a subset of the +* available items. +* +* $LicenseInfo:firstyear=2005&license=viewergpl$ +* +* Copyright (c) 2005-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#include "llviewerprecompiledheaders.h" + +#include "llinventoryfilter.h" + +// viewer includes +#include "llfoldervieweventlistener.h" +#include "llfolderviewitem.h" +#include "llinventorymodel.h" // gInventory.backgroundFetchActive() +#include "llviewercontrol.h" + +// linden library includes +#include "lltrans.h" + +///---------------------------------------------------------------------------- +/// Class LLInventoryFilter +///---------------------------------------------------------------------------- +LLInventoryFilter::LLInventoryFilter(const std::string& name) +: mName(name), + mModified(FALSE), + mNeedTextRebuild(TRUE) +{ + mFilterOps.mFilterTypes = 0xffffffff; + mFilterOps.mMinDate = time_min(); + mFilterOps.mMaxDate = time_max(); + mFilterOps.mHoursAgo = 0; + mFilterOps.mShowFolderState = SHOW_NON_EMPTY_FOLDERS; + mFilterOps.mPermissions = PERM_NONE; + + mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately + + mSubStringMatchOffset = 0; + mFilterSubString.clear(); + mFilterGeneration = 0; + mMustPassGeneration = S32_MAX; + mMinRequiredGeneration = 0; + mFilterCount = 0; + mNextFilterGeneration = mFilterGeneration + 1; + + mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff"); + mFilterBehavior = FILTER_NONE; + + // copy mFilterOps into mDefaultFilterOps + markDefault(); +} + +LLInventoryFilter::~LLInventoryFilter() +{ +} + +BOOL LLInventoryFilter::check(LLFolderViewItem* item) +{ + time_t earliest; + + earliest = time_corrected() - mFilterOps.mHoursAgo * 3600; + if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest) + { + earliest = mFilterOps.mMinDate; + } + else if (!mFilterOps.mHoursAgo) + { + earliest = 0; + } + LLFolderViewEventListener* listener = item->getListener(); + mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos; + BOOL passed = (0x1 << listener->getInventoryType() & mFilterOps.mFilterTypes || listener->getInventoryType() == LLInventoryType::IT_NONE) + && (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos) + && ((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions) + && (listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate); + return passed; +} + +const std::string LLInventoryFilter::getFilterSubString(BOOL trim) +{ + return mFilterSubString; +} + +std::string::size_type LLInventoryFilter::getStringMatchOffset() const +{ + return mSubStringMatchOffset; +} + +// has user modified default filter params? +BOOL LLInventoryFilter::isNotDefault() +{ + return mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes + || mFilterSubString.size() + || mFilterOps.mPermissions != mDefaultFilterOps.mPermissions + || mFilterOps.mMinDate != mDefaultFilterOps.mMinDate + || mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate + || mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo; +} + +BOOL LLInventoryFilter::isActive() +{ + return mFilterOps.mFilterTypes != 0xffffffff + || mFilterSubString.size() + || mFilterOps.mPermissions != PERM_NONE + || mFilterOps.mMinDate != time_min() + || mFilterOps.mMaxDate != time_max() + || mFilterOps.mHoursAgo != 0; +} + +BOOL LLInventoryFilter::isModified() +{ + return mModified; +} + +BOOL LLInventoryFilter::isModifiedAndClear() +{ + BOOL ret = mModified; + mModified = FALSE; + return ret; +} + +void LLInventoryFilter::setFilterTypes(U32 types) +{ + if (mFilterOps.mFilterTypes != types) + { + // keep current items only if no type bits getting turned off + BOOL fewer_bits_set = (mFilterOps.mFilterTypes & ~types); + BOOL more_bits_set = (~mFilterOps.mFilterTypes & types); + + mFilterOps.mFilterTypes = types; + if (more_bits_set && fewer_bits_set) + { + // neither less or more restrive, both simultaneously + // so we need to filter from scratch + setModified(FILTER_RESTART); + } + else if (more_bits_set) + { + // target is only one of all requested types so more type bits == less restrictive + setModified(FILTER_LESS_RESTRICTIVE); + } + else if (fewer_bits_set) + { + setModified(FILTER_MORE_RESTRICTIVE); + } + + } +} + +void LLInventoryFilter::setFilterSubString(const std::string& string) +{ + if (mFilterSubString != string) + { + // hitting BACKSPACE, for example + BOOL less_restrictive = mFilterSubString.size() >= string.size() && !mFilterSubString.substr(0, string.size()).compare(string); + // appending new characters + BOOL more_restrictive = mFilterSubString.size() < string.size() && !string.substr(0, mFilterSubString.size()).compare(mFilterSubString); + mFilterSubString = string; + LLStringUtil::toUpper(mFilterSubString); + LLStringUtil::trimHead(mFilterSubString); + + if (less_restrictive) + { + setModified(FILTER_LESS_RESTRICTIVE); + } + else if (more_restrictive) + { + setModified(FILTER_MORE_RESTRICTIVE); + } + else + { + setModified(FILTER_RESTART); + } + } +} + +void LLInventoryFilter::setFilterPermissions(PermissionMask perms) +{ + if (mFilterOps.mPermissions != perms) + { + // keep current items only if no perm bits getting turned off + BOOL fewer_bits_set = (mFilterOps.mPermissions & ~perms); + BOOL more_bits_set = (~mFilterOps.mPermissions & perms); + mFilterOps.mPermissions = perms; + + if (more_bits_set && fewer_bits_set) + { + setModified(FILTER_RESTART); + } + else if (more_bits_set) + { + // target must have all requested permission bits, so more bits == more restrictive + setModified(FILTER_MORE_RESTRICTIVE); + } + else if (fewer_bits_set) + { + setModified(FILTER_LESS_RESTRICTIVE); + } + } +} + +void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date) +{ + mFilterOps.mHoursAgo = 0; + if (mFilterOps.mMinDate != min_date) + { + mFilterOps.mMinDate = min_date; + setModified(); + } + if (mFilterOps.mMaxDate != llmax(mFilterOps.mMinDate, max_date)) + { + mFilterOps.mMaxDate = llmax(mFilterOps.mMinDate, max_date); + setModified(); + } +} + +void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl) +{ + if (sl && !isSinceLogoff()) + { + setDateRange(mLastLogoff, time_max()); + setModified(); + } + if (!sl && isSinceLogoff()) + { + setDateRange(0, time_max()); + setModified(); + } +} + +BOOL LLInventoryFilter::isSinceLogoff() +{ + return (mFilterOps.mMinDate == (time_t)mLastLogoff) && + (mFilterOps.mMaxDate == time_max()); +} + +void LLInventoryFilter::setHoursAgo(U32 hours) +{ + if (mFilterOps.mHoursAgo != hours) + { + // *NOTE: need to cache last filter time, in case filter goes stale + BOOL less_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours > mFilterOps.mHoursAgo); + BOOL more_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours <= mFilterOps.mHoursAgo); + mFilterOps.mHoursAgo = hours; + mFilterOps.mMinDate = time_min(); + mFilterOps.mMaxDate = time_max(); + if (less_restrictive) + { + setModified(FILTER_LESS_RESTRICTIVE); + } + else if (more_restrictive) + { + setModified(FILTER_MORE_RESTRICTIVE); + } + else + { + setModified(FILTER_RESTART); + } + } +} +void LLInventoryFilter::setShowFolderState(EFolderShow state) +{ + if (mFilterOps.mShowFolderState != state) + { + mFilterOps.mShowFolderState = state; + if (state == SHOW_NON_EMPTY_FOLDERS) + { + // showing fewer folders than before + setModified(FILTER_MORE_RESTRICTIVE); + } + else if (state == SHOW_ALL_FOLDERS) + { + // showing same folders as before and then some + setModified(FILTER_LESS_RESTRICTIVE); + } + else + { + setModified(); + } + } +} + +void LLInventoryFilter::setSortOrder(U32 order) +{ + if (mOrder != order) + { + mOrder = order; + setModified(); + } +} + +void LLInventoryFilter::markDefault() +{ + mDefaultFilterOps = mFilterOps; +} + +void LLInventoryFilter::resetDefault() +{ + mFilterOps = mDefaultFilterOps; + setModified(); +} + +void LLInventoryFilter::setModified(EFilterBehavior behavior) +{ + mModified = TRUE; + mNeedTextRebuild = TRUE; + mFilterGeneration = mNextFilterGeneration++; + + if (mFilterBehavior == FILTER_NONE) + { + mFilterBehavior = behavior; + } + else if (mFilterBehavior != behavior) + { + // trying to do both less restrictive and more restrictive filter + // basically means restart from scratch + mFilterBehavior = FILTER_RESTART; + } + + if (isNotDefault()) + { + // if not keeping current filter results, update last valid as well + switch(mFilterBehavior) + { + case FILTER_RESTART: + mMustPassGeneration = mFilterGeneration; + mMinRequiredGeneration = mFilterGeneration; + break; + case FILTER_LESS_RESTRICTIVE: + mMustPassGeneration = mFilterGeneration; + break; + case FILTER_MORE_RESTRICTIVE: + mMinRequiredGeneration = mFilterGeneration; + // must have passed either current filter generation (meaningless, as it hasn't been run yet) + // or some older generation, so keep the value + mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration); + break; + default: + llerrs << "Bad filter behavior specified" << llendl; + } + } + else + { + // shortcut disabled filters to show everything immediately + mMinRequiredGeneration = 0; + mMustPassGeneration = S32_MAX; + } +} + +BOOL LLInventoryFilter::isFilterWith(LLInventoryType::EType t) +{ + return mFilterOps.mFilterTypes & (0x01 << t); +} + +std::string LLInventoryFilter::getFilterText() +{ + if (!mNeedTextRebuild) + { + return mFilterText; + } + + mNeedTextRebuild = FALSE; + std::string filtered_types; + std::string not_filtered_types; + BOOL filtered_by_type = FALSE; + BOOL filtered_by_all_types = TRUE; + S32 num_filter_types = 0; + mFilterText.clear(); + + if (isFilterWith(LLInventoryType::IT_ANIMATION)) + { + //filtered_types += " Animations,"; + filtered_types += LLTrans::getString("Animations"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Animations,"; + not_filtered_types += LLTrans::getString("Animations"); + + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_CALLINGCARD)) + { + //filtered_types += " Calling Cards,"; + filtered_types += LLTrans::getString("Calling Cards"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Calling Cards,"; + not_filtered_types += LLTrans::getString("Calling Cards"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_WEARABLE)) + { + //filtered_types += " Clothing,"; + filtered_types += LLTrans::getString("Clothing"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Clothing,"; + not_filtered_types += LLTrans::getString("Clothing"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_GESTURE)) + { + //filtered_types += " Gestures,"; + filtered_types += LLTrans::getString("Gestures"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Gestures,"; + not_filtered_types += LLTrans::getString("Gestures"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_LANDMARK)) + { + //filtered_types += " Landmarks,"; + filtered_types += LLTrans::getString("Landmarks"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Landmarks,"; + not_filtered_types += LLTrans::getString("Landmarks"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_NOTECARD)) + { + //filtered_types += " Notecards,"; + filtered_types += LLTrans::getString("Notecards"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Notecards,"; + not_filtered_types += LLTrans::getString("Notecards"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_OBJECT) && isFilterWith(LLInventoryType::IT_ATTACHMENT)) + { + //filtered_types += " Objects,"; + filtered_types += LLTrans::getString("Objects"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Objects,"; + not_filtered_types += LLTrans::getString("Objects"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_LSL)) + { + //filtered_types += " Scripts,"; + filtered_types += LLTrans::getString("Scripts"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Scripts,"; + not_filtered_types += LLTrans::getString("Scripts"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_SOUND)) + { + //filtered_types += " Sounds,"; + filtered_types += LLTrans::getString("Sounds"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Sounds,"; + not_filtered_types += LLTrans::getString("Sounds"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_TEXTURE)) + { + //filtered_types += " Textures,"; + filtered_types += LLTrans::getString("Textures"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Textures,"; + not_filtered_types += LLTrans::getString("Textures"); + filtered_by_all_types = FALSE; + } + + if (isFilterWith(LLInventoryType::IT_SNAPSHOT)) + { + //filtered_types += " Snapshots,"; + filtered_types += LLTrans::getString("Snapshots"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + //not_filtered_types += " Snapshots,"; + not_filtered_types += LLTrans::getString("Snapshots"); + filtered_by_all_types = FALSE; + } + + if (!gInventory.backgroundFetchActive() + && filtered_by_type + && !filtered_by_all_types) + { + mFilterText += " - "; + if (num_filter_types < 5) + { + mFilterText += filtered_types; + } + else + { + //mFilterText += "No "; + mFilterText += LLTrans::getString("No Filters"); + mFilterText += not_filtered_types; + } + // remove the ',' at the end + mFilterText.erase(mFilterText.size() - 1, 1); + } + + if (isSinceLogoff()) + { + //mFilterText += " - Since Logoff"; + mFilterText += LLTrans::getString("Since Logoff"); + } + return mFilterText; +} + +void LLInventoryFilter::toLLSD(LLSD& data) +{ + data["filter_types"] = (LLSD::Integer)getFilterTypes(); + data["min_date"] = (LLSD::Integer)getMinDate(); + data["max_date"] = (LLSD::Integer)getMaxDate(); + data["hours_ago"] = (LLSD::Integer)getHoursAgo(); + data["show_folder_state"] = (LLSD::Integer)getShowFolderState(); + data["permissions"] = (LLSD::Integer)getFilterPermissions(); + data["substring"] = (LLSD::String)getFilterSubString(); + data["sort_order"] = (LLSD::Integer)getSortOrder(); + data["since_logoff"] = (LLSD::Boolean)isSinceLogoff(); +} + +void LLInventoryFilter::fromLLSD(LLSD& data) +{ + if(data.has("filter_types")) + { + setFilterTypes((U32)data["filter_types"].asInteger()); + } + + if(data.has("min_date") && data.has("max_date")) + { + setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger()); + } + + if(data.has("hours_ago")) + { + setHoursAgo((U32)data["hours_ago"].asInteger()); + } + + if(data.has("show_folder_state")) + { + setShowFolderState((EFolderShow)data["show_folder_state"].asInteger()); + } + + if(data.has("permissions")) + { + setFilterPermissions((PermissionMask)data["permissions"].asInteger()); + } + + if(data.has("substring")) + { + setFilterSubString(std::string(data["substring"].asString())); + } + + if(data.has("sort_order")) + { + setSortOrder((U32)data["sort_order"].asInteger()); + } + + if(data.has("since_logoff")) + { + setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean()); + } +} diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h new file mode 100644 index 0000000000..7c5f6681cf --- /dev/null +++ b/indra/newview/llinventoryfilter.h @@ -0,0 +1,150 @@ +/** +* @file llinventoryfilter.h +* @brief Support for filtering your inventory to only display a subset of the +* available items. +* +* $LicenseInfo:firstyear=2005&license=viewergpl$ +* +* Copyright (c) 2005-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#ifndef LLINVENTORYFILTER_H +#define LLINVENTORYFILTER_H + +// lots of includes here +#include "llinventorytype.h" +#include "llpermissionsflags.h" // PermissionsMask + +class LLFolderViewItem; + +class LLInventoryFilter +{ +public: + typedef enum e_folder_show + { + SHOW_ALL_FOLDERS, + SHOW_NON_EMPTY_FOLDERS, + SHOW_NO_FOLDERS + } EFolderShow; + + typedef enum e_filter_behavior + { + FILTER_NONE, // nothing to do, already filtered + FILTER_RESTART, // restart filtering from scratch + FILTER_LESS_RESTRICTIVE, // existing filtered items will certainly pass this filter + FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one + } EFilterBehavior; + + static const U32 SO_DATE = 1; + static const U32 SO_FOLDERS_BY_NAME = 2; + static const U32 SO_SYSTEM_FOLDERS_TO_TOP = 4; + + LLInventoryFilter(const std::string& name); + virtual ~LLInventoryFilter(); + + void setFilterTypes(U32 types); + U32 getFilterTypes() const { return mFilterOps.mFilterTypes; } + + void setFilterSubString(const std::string& string); + const std::string getFilterSubString(BOOL trim = FALSE); + + void setFilterPermissions(PermissionMask perms); + PermissionMask getFilterPermissions() const { return mFilterOps.mPermissions; } + + void setDateRange(time_t min_date, time_t max_date); + void setDateRangeLastLogoff(BOOL sl); + time_t getMinDate() const { return mFilterOps.mMinDate; } + time_t getMaxDate() const { return mFilterOps.mMaxDate; } + + void setHoursAgo(U32 hours); + U32 getHoursAgo() const { return mFilterOps.mHoursAgo; } + + void setShowFolderState( EFolderShow state); + EFolderShow getShowFolderState() { return mFilterOps.mShowFolderState; } + + void setSortOrder(U32 order); + U32 getSortOrder() { return mOrder; } + + BOOL check(LLFolderViewItem* item); + std::string::size_type getStringMatchOffset() const; + BOOL isActive(); + BOOL isNotDefault(); + BOOL isModified(); + BOOL isModifiedAndClear(); + BOOL isSinceLogoff(); + void clearModified() { mModified = FALSE; mFilterBehavior = FILTER_NONE; } + const std::string getName() const { return mName; } + std::string getFilterText(); + + void setFilterCount(S32 count) { mFilterCount = count; } + S32 getFilterCount() { return mFilterCount; } + void decrementFilterCount() { mFilterCount--; } + + void markDefault(); + void resetDefault(); + + BOOL isFilterWith(LLInventoryType::EType t); + + S32 getCurrentGeneration() const { return mFilterGeneration; } + S32 getMinRequiredGeneration() const { return mMinRequiredGeneration; } + S32 getMustPassGeneration() const { return mMustPassGeneration; } + + //RN: this is public to allow system to externally force a global refilter + void setModified(EFilterBehavior behavior = FILTER_RESTART); + + void toLLSD(LLSD& data); + void fromLLSD(LLSD& data); + +protected: + struct filter_ops + { + U32 mFilterTypes; + time_t mMinDate; + time_t mMaxDate; + U32 mHoursAgo; + EFolderShow mShowFolderState; + PermissionMask mPermissions; + }; + filter_ops mFilterOps; + filter_ops mDefaultFilterOps; + std::string::size_type mSubStringMatchOffset; + std::string mFilterSubString; + U32 mOrder; + const std::string mName; + S32 mFilterGeneration; + S32 mMustPassGeneration; + S32 mMinRequiredGeneration; + S32 mFilterCount; + S32 mNextFilterGeneration; + EFilterBehavior mFilterBehavior; + +private: + U32 mLastLogoff; + BOOL mModified; + BOOL mNeedTextRebuild; + std::string mFilterText; +}; + +#endif diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 665ad5b1a2..9d3d383d1c 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -46,7 +46,7 @@ #include "llfloater.h" #include "llfocusmgr.h" #include "llinventorybridge.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llviewerinventory.h" #include "llviewermessage.h" #include "llviewerwindow.h" @@ -155,9 +155,20 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item) LLInventoryModel gInventory; // Default constructor -LLInventoryModel::LLInventoryModel() : - mModifyMask(LLInventoryObserver::ALL), +LLInventoryModel::LLInventoryModel() +: mModifyMask(LLInventoryObserver::ALL), + mChangedItemIDs(), + mCategoryMap(), + mItemMap(), + mCategoryLock(), + mItemLock(), mLastItem(NULL), + mParentChildCategoryTree(), + mParentChildItemTree(), + mObservers(), + mRootFolderID(), + mLibraryRootFolderID(), + mLibraryOwnerID(), mIsAgentInvUsable(false) { } @@ -299,7 +310,7 @@ LLUUID LLInventoryModel::findCategoryUUIDForType(LLAssetType::EType t, bool crea LLUUID rv = findCatUUID(t); if(rv.isNull() && isInventoryUsable() && create_folder) { - LLUUID root_id = gAgent.getInventoryRootID(); + LLUUID root_id = gInventory.getRootFolderID(); if(root_id.notNull()) { rv = createNewCategory(root_id, t, LLStringUtil::null); @@ -312,7 +323,7 @@ LLUUID LLInventoryModel::findCategoryUUIDForType(LLAssetType::EType t, bool crea // preferred type. Returns LLUUID::null if not found. LLUUID LLInventoryModel::findCatUUID(LLAssetType::EType preferred_type) { - LLUUID root_id = gAgent.getInventoryRootID(); + LLUUID root_id = gInventory.getRootFolderID(); if(LLAssetType::AT_CATEGORY == preferred_type) { return root_id; @@ -464,12 +475,41 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, } } +void LLInventoryModel::updateLinkedObjects(const LLUUID& object_id) +{ + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + LLLinkedItemIDMatches is_linked_item_match(object_id); + collectDescendentsIf(gInventory.getRootFolderID(), + cat_array, + item_array, + LLInventoryModel::INCLUDE_TRASH, + is_linked_item_match); + + for (LLInventoryModel::cat_array_t::iterator cat_iter = cat_array.begin(); + cat_iter != cat_array.end(); + cat_iter++) + { + LLViewerInventoryCategory *linked_cat = (*cat_iter); + addChangedMask(LLInventoryObserver::LABEL, linked_cat->getUUID()); + }; + + for (LLInventoryModel::item_array_t::iterator iter = item_array.begin(); + iter != item_array.end(); + iter++) + { + LLViewerInventoryItem *linked_item = (*iter); + addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); + }; + notifyObservers(); +} + void LLInventoryModel::collectLinkedItems(const LLUUID& id, item_array_t& items) { LLInventoryModel::cat_array_t cat_array; LLLinkedItemIDMatches is_linked_item_match(id); - collectDescendentsIf(gAgent.getInventoryRootID(), + collectDescendentsIf(gInventory.getRootFolderID(), cat_array, items, LLInventoryModel::INCLUDE_TRASH, @@ -500,7 +540,7 @@ void LLInventoryModel::appendPath(const LLUUID& id, std::string& path) bool LLInventoryModel::isInventoryUsable() { bool result = false; - if(gAgent.getInventoryRootID().notNull() && mIsAgentInvUsable) + if(gInventory.getRootFolderID().notNull() && mIsAgentInvUsable) { result = true; } @@ -814,10 +854,10 @@ void LLInventoryModel::purgeObject(const LLUUID &id) void LLInventoryModel::purgeLinkedObjects(const LLUUID &id) { - LLInventoryItem* itemp = getItem(id); - if (!itemp) return; + LLInventoryObject* objectp = getObject(id); + if (!objectp) return; - if (LLAssetType::lookupIsLinkType(itemp->getActualType())) + if (LLAssetType::lookupIsLinkType(objectp->getActualType())) { return; } @@ -1478,8 +1518,8 @@ void LLInventoryModel::startBackgroundFetch(const LLUUID& cat_id) if (!sFullFetchStarted) { sFullFetchStarted = TRUE; - sFetchQueue.push_back(gInventoryLibraryRoot); - sFetchQueue.push_back(gAgent.getInventoryRootID()); + sFetchQueue.push_back(gInventory.getLibraryRootFolderID()); + sFetchQueue.push_back(gInventory.getRootFolderID()); gIdleCallbacks.addFunction(&LLInventoryModel::backgroundFetch, NULL); } } @@ -2263,7 +2303,7 @@ void LLInventoryModel::buildParentChildMap() else { // it's a protected folder. - cat->setParent(gAgent.getInventoryRootID()); + cat->setParent(gInventory.getRootFolderID()); } cat->updateServer(TRUE); catsp = getUnlockedCatArray(cat->getParentUUID()); @@ -2363,7 +2403,7 @@ void LLInventoryModel::buildParentChildMap() } } - const LLUUID& agent_inv_root_id = gAgent.getInventoryRootID(); + LLUUID agent_inv_root_id = gInventory.getRootFolderID(); if (agent_inv_root_id.notNull()) { cat_array_t* catsp = get_ptr_in_map(mParentChildCategoryTree, agent_inv_root_id); @@ -2813,7 +2853,7 @@ void LLInventoryModel::processUpdateInventoryFolder(LLMessageSystem* msg, gInventory.notifyObservers(); // *HACK: Do the 'show' logic for a new item in the inventory. - LLInventoryView* view = LLInventoryView::getActiveInventory(); + LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); if(view) { view->getPanel()->setSelection(lastfolder->getUUID(), TAKE_FOCUS_NO); @@ -3022,13 +3062,13 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) // The incoming inventory could span more than one BulkInventoryUpdate packet, // so record the transaction ID for this purchase, then wear all clothing // that comes in as part of that transaction ID. JC - if (LLInventoryView::sWearNewClothing) + if (LLFloaterInventory::sWearNewClothing) { - LLInventoryView::sWearNewClothingTransactionID = tid; - LLInventoryView::sWearNewClothing = FALSE; + LLFloaterInventory::sWearNewClothingTransactionID = tid; + LLFloaterInventory::sWearNewClothing = FALSE; } - if (tid == LLInventoryView::sWearNewClothingTransactionID) + if (tid == LLFloaterInventory::sWearNewClothingTransactionID) { count = wearable_ids.size(); for (i = 0; i < count; ++i) @@ -3046,7 +3086,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) gInventoryCallbacks.fire(cbinfo.mCallback, cbinfo.mInvID); } // Don't show the inventory. We used to call showAgentInventory here. - //LLInventoryView* view = LLInventoryView::getActiveInventory(); + //LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); //if(view) //{ // const BOOL take_keyboard_focus = FALSE; @@ -3056,10 +3096,10 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) // // HACK to open inventory offers that are accepted. This information // // really needs to flow through the instant messages and inventory // // transfer/update messages. - // if (LLInventoryView::sOpenNextNewItem) + // if (LLFloaterInventory::sOpenNextNewItem) // { // view->openSelected(); - // LLInventoryView::sOpenNextNewItem = FALSE; + // LLFloaterInventory::sOpenNextNewItem = FALSE; // } // // // restore keyboard focus @@ -3224,6 +3264,36 @@ void LLInventoryModel::removeItem(const LLUUID& item_id) } } +LLUUID LLInventoryModel::getRootFolderID() const +{ + return mRootFolderID; +} + +void LLInventoryModel::setRootFolderID(const LLUUID& val) +{ + mRootFolderID = val; +} + +LLUUID LLInventoryModel::getLibraryRootFolderID() const +{ + return mLibraryRootFolderID; +} + +void LLInventoryModel::setLibraryRootFolderID(const LLUUID& val) +{ + mLibraryRootFolderID = val; +} + +LLUUID LLInventoryModel::getLibraryOwnerID() const +{ + return mLibraryOwnerID; +} + +void LLInventoryModel::setLibraryOwnerID(const LLUUID& val) +{ + mLibraryOwnerID = val; +} + //---------------------------------------------------------------------------- // *NOTE: DEBUG functionality diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 8dc3c1605f..da10528c9d 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -118,6 +118,7 @@ public: public: fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {}; void result(const LLSD& content); + void error(U32 status, const std::string& reason); public: @@ -180,7 +181,6 @@ public: cat_array_t& categories, item_array_t& items, BOOL include_trash); - void collectDescendentsIf(const LLUUID& id, cat_array_t& categories, item_array_t& items, @@ -191,8 +191,9 @@ public: // Assumes item_id is itself not a linked item. void collectLinkedItems(const LLUUID& item_id, item_array_t& items); - - // This method will return false if this inventory model is in an usabel state. + // Updates all linked objects pointing to this id. + void updateLinkedObjects(const LLUUID& object_id); + // The inventory model usage is sensitive to the initial construction of the // model. bool isInventoryUsable(); @@ -204,7 +205,7 @@ public: // Calling this method with an inventory item will either change // an existing item with a matching item_id, or will add the item // to the current inventory. Returns the change mask generated by - // the update. No notifcation will be sent to observers. This + // the update. No notification will be sent to observers. This // method will only generate network traffic if the item had to be // reparented. // *NOTE: In usage, you will want to perform cache accounting @@ -231,7 +232,7 @@ public: // delete a particular inventory object by ID. This will purge one // object from the internal data structures maintaining a - // cosistent internal state. No cache accounting, observer + // consistent internal state. No cache accounting, observer // notification, or server update is performed. Purges linked items. void deleteObject(const LLUUID& id); @@ -240,12 +241,12 @@ public: void purgeObject(const LLUUID& id); void purgeLinkedObjects(const LLUUID& id); - // This is a method which collects the descendents of the id + // This is a method which collects the descendants of the id // provided. If the category is not found, no action is // taken. This method goes through the long winded process of // removing server representation of folders and items while doing // cache accounting in a fairly efficient manner. This method does - // not notify observers (though maybe it shouldd...) + // not notify observers (though maybe it should...) void purgeDescendentsOf(const LLUUID& id); // This method optimally removes the referenced categories and @@ -392,6 +393,22 @@ public: static bool isEverythingFetched(); static void backgroundFetch(void*); // background fetch idle function static void incrBulkFetch(S16 fetching) { sBulkFetchCount+=fetching; if (sBulkFetchCount<0) sBulkFetchCount=0; } + + + // Data about the agent's root folder and root library folder + // are stored here, rather than in LLAgent where it used to be, because + // gInventory is a singleton and represents the agent's inventory. + // The "library" is actually the inventory of a special agent, + // usually Alexandria Linden. + LLUUID getRootFolderID() const; + LLUUID getLibraryOwnerID() const; + LLUUID getLibraryRootFolderID() const; + + // These are set during login with data from the server + void setRootFolderID(const LLUUID& id); + void setLibraryOwnerID(const LLUUID& id); + void setLibraryRootFolderID(const LLUUID& id); + protected: // Internal methods which add inventory and make sure that all of @@ -444,7 +461,7 @@ protected: item_array_t* getUnlockedItemArray(const LLUUID& id); protected: - // Varaibles used to track what has changed since the last notify. + // Variables used to track what has changed since the last notify. U32 mModifyMask; typedef std::set changed_items_t; changed_items_t mChangedItemIDs; @@ -475,6 +492,11 @@ protected: typedef std::set observer_list_t; observer_list_t mObservers; + // Agent inventory folder information. + LLUUID mRootFolderID; + LLUUID mLibraryRootFolderID; + LLUUID mLibraryOwnerID; + // completing the fetch once per session should be sufficient static BOOL sBackgroundFetchActive; static BOOL sTimelyFetchPending; diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp index 8e6889a379..efc03b3d88 100644 --- a/indra/newview/lljoystickbutton.cpp +++ b/indra/newview/lljoystickbutton.cpp @@ -42,18 +42,18 @@ // Project includes #include "llui.h" #include "llagent.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llmoveview.h" #include "llglheaders.h" -static LLDefaultWidgetRegistry::Register r1("joystick_slide"); -static LLDefaultWidgetRegistry::Register r2("joystick_turn"); -static LLDefaultWidgetRegistry::Register r3("joystick_rotate"); -static LLDefaultWidgetRegistry::Register r4("joystick_zoom"); -static LLDefaultWidgetRegistry::Register r5("joystick_track"); +static LLDefaultChildRegistry::Register r1("joystick_slide"); +static LLDefaultChildRegistry::Register r2("joystick_turn"); +static LLDefaultChildRegistry::Register r3("joystick_rotate"); +static LLDefaultChildRegistry::Register r4("joystick_zoom"); +static LLDefaultChildRegistry::Register r5("joystick_track"); @@ -552,7 +552,7 @@ void LLJoystickCameraRotate::draw() } // Draws image rotated by multiples of 90 degrees -void LLJoystickCameraRotate::drawRotatedImage( LLImageGL* image, S32 rotations ) +void LLJoystickCameraRotate::drawRotatedImage( LLTexture* image, S32 rotations ) { S32 width = image->getWidth(); S32 height = image->getHeight(); diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h index 954a8c481d..8caef30fa4 100644 --- a/indra/newview/lljoystickbutton.h +++ b/indra/newview/lljoystickbutton.h @@ -35,7 +35,7 @@ #include "llbutton.h" #include "llcoord.h" -#include "llviewerimage.h" +#include "llviewertexture.h" typedef enum e_joystick_quadrant { @@ -63,7 +63,7 @@ public: Params() : quadrant("quadrant", JQ_ORIGIN) { - label(""); + label = ""; } }; LLJoystick(const Params&); @@ -150,7 +150,7 @@ public: protected: F32 getOrbitRate(); virtual void updateSlop(); - void drawRotatedImage( LLImageGL* image, S32 rotations ); + void drawRotatedImage( LLTexture* image, S32 rotations ); protected: BOOL mInLeft; diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp new file mode 100644 index 0000000000..b51064f226 --- /dev/null +++ b/indra/newview/lllandmarkactions.cpp @@ -0,0 +1,141 @@ +/** +* @file lllandmarkactions.cpp +* @brief LLLandmarkActions class implementation +* +* $LicenseInfo:firstyear=2001&license=viewergpl$ +* +* Copyright (c) 2001-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "lllandmarkactions.h" + +#include "llagent.h" +#include "llinventory.h" +#include "llinventorymodel.h" +#include "lllandmark.h" +#include "lllandmarklist.h" +#include "llnotifications.h" +#include "llparcel.h" +#include "llviewerinventory.h" +#include "llviewerparcelmgr.h" +#include "roles_constants.h" + +// Returns true if the given inventory item is a landmark pointing to the current parcel. +// Used to filter inventory items. +class LLIsAgentParcelLandmark : public LLInventoryCollectFunctor +{ +public: + /*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) + { + if (!item || item->getType() != LLAssetType::AT_LANDMARK) + return false; + + LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID()); + if (!landmark) // the landmark not been loaded yet + return false; + + LLVector3d landmark_global_pos; + if (!landmark->getGlobalPos(landmark_global_pos)) + return false; + + return LLViewerParcelMgr::getInstance()->inAgentParcel(landmark_global_pos); + } +}; + +bool LLLandmarkActions::landmarkAlreadyExists() +{ + // Determine whether there are landmarks pointing to the current parcel. + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLIsAgentParcelLandmark is_current_parcel_landmark; + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + is_current_parcel_landmark); + + return !items.empty(); +} + +bool LLLandmarkActions::canCreateLandmarkHere() +{ + LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if(!agent_parcel) + { + llwarns << "No agent region" << llendl; + return false; + } + if (agent_parcel->getAllowLandmark() + || LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK)) + { + return true; + } + + return false; +} + +void LLLandmarkActions::createLandmarkHere( + const std::string& name, + const std::string& desc, + const LLUUID& folder_id) +{ + if(!gAgent.getRegion()) + { + llwarns << "No agent region" << llendl; + return; + } + LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (!agent_parcel) + { + llwarns << "No agent parcel" << llendl; + return; + } + if (!canCreateLandmarkHere()) + { + LLNotifications::instance().add("CannotCreateLandmarkNotOwner"); + return; + } + + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + folder_id, LLTransactionID::tnull, + name, desc, + LLAssetType::AT_LANDMARK, + LLInventoryType::IT_LANDMARK, + NOT_WEARABLE, PERM_ALL, + NULL); +} + +void LLLandmarkActions::createLandmarkHere() +{ + std::string landmark_name, landmark_desc; + + gAgent.buildLocationString(landmark_name, LLAgent::LOCATION_FORMAT_LANDMARK); + gAgent.buildLocationString(landmark_desc, LLAgent::LOCATION_FORMAT_FULL); + LLUUID folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); + + createLandmarkHere(landmark_name, landmark_desc, folder_id); +} diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h new file mode 100644 index 0000000000..e1e94edb75 --- /dev/null +++ b/indra/newview/lllandmarkactions.h @@ -0,0 +1,68 @@ +/** +* @file lllandmarkactions.h +* @brief LLLandmark class declaration +* +* $LicenseInfo:firstyear=2000&license=viewergpl$ +* +* Copyright (c) 2000-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#ifndef LL_LLLANDMARKACTIONS_H +#define LL_LLLANDMARKACTIONS_H + +/** +* @brief Provides helper functions to manage landmarks +*/ +class LLLandmarkActions +{ +public: + + /** + * @brief Checks whether landmark exists for current parcel. + */ + static bool landmarkAlreadyExists(); + + /** + * @brief Checks whether agent has rights to create landmark for current parcel. + */ + static bool canCreateLandmarkHere(); + + /** + * @brief Creates landmark for current parcel. + */ + static void createLandmarkHere(); + + /** + * @brief Creates landmark for current parcel. + */ + static void createLandmarkHere( + const std::string& name, + const std::string& desc, + const LLUUID& folder_id); + +}; + +#endif //LL_LLLANDMARKACTIONS_H diff --git a/indra/newview/lllistbrowser.cpp b/indra/newview/lllistbrowser.cpp new file mode 100644 index 0000000000..edd8e9818f --- /dev/null +++ b/indra/newview/lllistbrowser.cpp @@ -0,0 +1,37 @@ +/** + * @file lllistbrowser.cpp + * @brief UI widget showing a search filter, list view, icon action buttons, + * and verb action buttons, as usually embedded in the side tray. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "lllistbrowser.h" + +// TODO diff --git a/indra/newview/lllistbrowser.h b/indra/newview/lllistbrowser.h new file mode 100644 index 0000000000..bc9498c514 --- /dev/null +++ b/indra/newview/lllistbrowser.h @@ -0,0 +1,36 @@ +/** + * @file lllistbrowser.h + * @brief UI widget showing a search filter, list view, icon action buttons, + * and verb action buttons, as usually embedded in the side tray. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#ifndef LLLISTBROWSER_H +#define LLLISTBROWSER_H + +#endif // LLLISTBROWSER_H diff --git a/indra/newview/lllistview.cpp b/indra/newview/lllistview.cpp new file mode 100644 index 0000000000..3019d5d3d5 --- /dev/null +++ b/indra/newview/lllistview.cpp @@ -0,0 +1,73 @@ +/** + * @file lllistview.cpp + * @brief UI widget containing a scrollable, possibly hierarchical list of + * folders (LLListViewFolder) and items (LLListViewItem). + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "lllistview.h" + +#include "lltextbox.h" +#include "lluictrlfactory.h" // LLDefaultChildRegistry + +// linker optimizes this out on Windows until there is a real reference +// to this file +static LLDefaultChildRegistry::Register r("list_view"); + +LLListView::Params::Params() +: bg_color("bg_color"), + fg_selected_color("fg_selected_color"), + bg_selected_color("bg_selected_color") +{} + +LLListView::LLListView(const Params& p) +: LLUICtrl(p), + mLabel(NULL), + mBgColor(p.bg_color()), + mFgSelectedColor(p.fg_selected_color()), + mBgSelectedColor(p.bg_selected_color()) +{ + LLRect label_rect(0, 20, 300, 0); + LLTextBox::Params text_box_params; + text_box_params.rect(label_rect); + text_box_params.text("This is a list-view"); + mLabel = LLUICtrlFactory::create(text_box_params); + addChild(mLabel); +} + +LLListView::~LLListView() +{} + + +// placeholder for setting a property +void LLListView::setString(const std::string& s) +{ + mLabel->setValue( LLSD(s) ); +} diff --git a/indra/newview/lllistview.h b/indra/newview/lllistview.h new file mode 100644 index 0000000000..501c0c9e1f --- /dev/null +++ b/indra/newview/lllistview.h @@ -0,0 +1,66 @@ +/** + * @file lllistview.h + * @brief UI widget containing a scrollable, possibly hierarchical list of + * folders (LLListViewFolder) and items (LLListViewItem). + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#ifndef LLLISTVIEW_H +#define LLLISTVIEW_H + +#include "llui.h" // for LLUIColor, *TODO: use more specific header +#include "lluictrl.h" + +class LLTextBox; + +class LLListView +: public LLUICtrl +{ +public: + struct Params : public LLInitParam::Block + { + Optional bg_color, + fg_selected_color, + bg_selected_color; + Params(); + }; + LLListView(const Params& p); + virtual ~LLListView(); + + // placeholder for setting a property + void setString(const std::string& s); + +private: + // TODO: scroll container? + LLTextBox* mLabel; // just for testing + LLUIColor mBgColor; + LLUIColor mFgSelectedColor; + LLUIColor mBgSelectedColor; +}; + +#endif // LLLISTVIEW_H diff --git a/indra/newview/lllocaltextureobject.cpp b/indra/newview/lllocaltextureobject.cpp new file mode 100644 index 0000000000..e4a20aea68 --- /dev/null +++ b/indra/newview/lllocaltextureobject.cpp @@ -0,0 +1,149 @@ +/** + * @file lllocaltextureobject.cpp + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lllocaltextureobject.h" + +#include "lltexlayer.h" +#include "llviewertexture.h" +#include "lltextureentry.h" +#include "lluuid.h" + + +LLLocalTextureObject::LLLocalTextureObject() : + mIsBakedReady(FALSE), + mDiscard(MAX_DISCARD_LEVEL+1) +{ + mImage = NULL; +} + +LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture *image, LLTextureEntry *entry, LLTexLayer *layer, LLUUID id) +{ + if (entry) + { + LLTextureEntry * te = new LLTextureEntry(*entry); + mTexEntry = boost::shared_ptr(te); + } + + if (layer) + { + LLTexLayer *texLayer = new LLTexLayer(*layer); + mTexLayer = boost::shared_ptr(texLayer); + } + mImage = image; + mID = id; +} + +LLLocalTextureObject::LLLocalTextureObject(const LLLocalTextureObject <o) : +mImage(lto.mImage), +mTexEntry(lto.mTexEntry), +mTexLayer(lto.mTexLayer), +mID(lto.mID), +mIsBakedReady(lto.mIsBakedReady), +mDiscard(lto.mDiscard) +{ +} + +LLLocalTextureObject::~LLLocalTextureObject() +{ +} + +LLViewerFetchedTexture* LLLocalTextureObject::getImage() const +{ + return mImage; +} + +LLTextureEntry* LLLocalTextureObject::getTexEntry() const +{ + return mTexEntry.get(); +} + +LLTexLayer* LLLocalTextureObject::getTexLayer() const +{ + return mTexLayer.get(); +} + +LLUUID LLLocalTextureObject::getID() const +{ + return mID; +} + +S32 LLLocalTextureObject::getDiscard() const +{ + return mDiscard; +} + +BOOL LLLocalTextureObject::getBakedReady() const +{ + return mIsBakedReady; +} + +void LLLocalTextureObject::setImage(LLViewerFetchedTexture* new_image) +{ + mImage = new_image; +} + +void LLLocalTextureObject::setTexEntry(LLTextureEntry *new_te) +{ + LLTextureEntry *ptr = NULL; + if (new_te) + { + ptr = new LLTextureEntry(*new_te); + } + mTexEntry = boost::shared_ptr(ptr); +} + +void LLLocalTextureObject::setTexLayer(LLTexLayer *new_tex_layer) +{ + LLTexLayer *ptr = NULL; + if (new_tex_layer) + { + ptr = new LLTexLayer(*new_tex_layer); + } + mTexLayer = boost::shared_ptr(ptr); +} + +void LLLocalTextureObject::setID(LLUUID new_id) +{ + mID = new_id; +} + +void LLLocalTextureObject::setDiscard(S32 new_discard) +{ + mDiscard = new_discard; +} + +void LLLocalTextureObject::setBakedReady(BOOL ready) +{ + mIsBakedReady = ready; +} + diff --git a/indra/newview/lllocaltextureobject.h b/indra/newview/lllocaltextureobject.h new file mode 100644 index 0000000000..79e1562dce --- /dev/null +++ b/indra/newview/lllocaltextureobject.h @@ -0,0 +1,85 @@ +/** + * @file lllocaltextureobject.h + * @brief LLLocalTextureObject class header file + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LOCALTEXTUREOBJECT_H +#define LL_LOCALTEXTUREOBJECT_H + +#include + +class LLViewerFetchedTexture; +class LLUUID; +class LLTexLayer; +class LLTextureEntry; + +// Stores all relevant information for a single texture +// assumed to have ownership of all objects referred to - +// will delete objects when being replaced or if object is destroyed. +class LLLocalTextureObject +{ +public: + LLLocalTextureObject(); + LLLocalTextureObject(LLViewerFetchedTexture *image, LLTextureEntry *entry, LLTexLayer *layer, LLUUID id); + LLLocalTextureObject(const LLLocalTextureObject <o); + ~LLLocalTextureObject(); + + LLViewerFetchedTexture* getImage() const; + LLTextureEntry* getTexEntry() const; + LLTexLayer* getTexLayer() const; + LLUUID getID() const; + S32 getDiscard() const; + BOOL getBakedReady() const; + + void setImage(LLViewerFetchedTexture* new_image); + void setTexEntry(LLTextureEntry *new_te); + void setTexLayer(LLTexLayer *new_tex_layer); + void setID(LLUUID new_id); + void setDiscard(S32 new_discard); + void setBakedReady(BOOL ready); + +protected: + +private: + + LLPointer mImage; + // NOTE: LLLocalTextureObject should be the exclusive owner of mTexEntry and mTexLayer + // using shared pointers here only for smart assignment & cleanup + // do NOT create new shared pointers to these objects, or keep pointers to them around + boost::shared_ptr mTexEntry; + boost::shared_ptr mTexLayer; + LLUUID mID; + + BOOL mIsBakedReady; + S32 mDiscard; +}; + + #endif // LL_LOCALTEXTUREOBJECT_H + diff --git a/indra/newview/lllocationhistory.cpp b/indra/newview/lllocationhistory.cpp index 179eca2532..68143fd1e3 100644 --- a/indra/newview/lllocationhistory.cpp +++ b/indra/newview/lllocationhistory.cpp @@ -39,8 +39,7 @@ #include "llui.h" LLLocationHistory::LLLocationHistory() : - mFilename("typed_locations.txt"), - mLoadedCallback(NULL) + mFilename("typed_locations.txt") { } @@ -48,6 +47,12 @@ void LLLocationHistory::addItem(std::string item) { static LLUICachedControl max_items("LocationHistoryMaxSize", 100); + std::vector::iterator item_iter = std::find(mItems.begin(), mItems.end(), item); + + if (item_iter != mItems.end()) { + mItems.erase(item_iter); + } + mItems.push_back(item); // If the vector size exceeds the maximum, purge the oldest items. @@ -55,6 +60,11 @@ void LLLocationHistory::addItem(std::string item) mItems.erase(mItems.begin(), mItems.end()-max_items); } +void LLLocationHistory::removeItems() +{ + mItems.clear(); +} + bool LLLocationHistory::getMatchingItems(std::string substring, location_list_t& result) const { @@ -129,6 +139,5 @@ void LLLocationHistory::load() file.close(); - if (mLoadedCallback) - mLoadedCallback(); + mLoadedSignal(); } diff --git a/indra/newview/lllocationhistory.h b/indra/newview/lllocationhistory.h index d2a959ae62..19032686c1 100644 --- a/indra/newview/lllocationhistory.h +++ b/indra/newview/lllocationhistory.h @@ -46,14 +46,16 @@ class LLLocationHistory: public LLSingleton public: typedef std::vector location_list_t; typedef boost::function loaded_callback_t; + typedef boost::signals2::signal loaded_signal_t; LLLocationHistory(); void addItem(std::string item); + void removeItems(); size_t getItemCount() const { return mItems.size(); } const location_list_t& getItems() const { return mItems; } bool getMatchingItems(std::string substring, location_list_t& result) const; - void setLoadedCallback(loaded_callback_t cb) { mLoadedCallback = cb; } + boost::signals2::connection setLoadedCallback(loaded_callback_t cb) { return mLoadedSignal.connect(cb); } void save() const; void load(); @@ -62,7 +64,7 @@ public: private: std::vector mItems; std::string mFilename; /// File to store the history to. - loaded_callback_t mLoadedCallback; + loaded_signal_t mLoadedSignal; }; #endif diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index fac0de0f33..3880ea91eb 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -48,12 +48,13 @@ #include "llagent.h" #include "llfloaterland.h" #include "llinventorymodel.h" +#include "lllandmarkactions.h" #include "lllandmarklist.h" #include "lllocationhistory.h" -#include "llpanelplaces.h" #include "llsidetray.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" +#include "llviewercontrol.h" //============================================================================ /* @@ -84,28 +85,6 @@ * and choose the appropriate image for the "Add landmark" button. */ -// Returns true if the given inventory item is a landmark pointing to the current parcel. -// Used to filter inventory items. -class LLIsAgentParcelLandmark : public LLInventoryCollectFunctor -{ -public: - /*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) - { - if (!item || item->getType() != LLAssetType::AT_LANDMARK) - return false; - - LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID()); - if (!landmark) // the landmark not been loaded yet - return false; - - LLVector3d landmark_global_pos; - if (!landmark->getGlobalPos(landmark_global_pos)) - return false; - - return LLViewerParcelMgr::getInstance()->inAgentParcel(landmark_global_pos); - } -}; - /** * Initiates loading the landmarks that have been just added. * @@ -167,15 +146,14 @@ private: //============================================================================ -static LLDefaultWidgetRegistry::Register r("location_input"); +static LLDefaultChildRegistry::Register r("location_input"); LLLocationInputCtrl::Params::Params() : add_landmark_image_enabled("add_landmark_image_enabled"), add_landmark_image_disabled("add_landmark_image_disabled"), add_landmark_button("add_landmark_button"), add_landmark_hpad("add_landmark_hpad", 0), - info_button("info_button"), - background("background") + info_button("info_button") { } @@ -185,11 +163,6 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) mInfoBtn(NULL), mAddLandmarkBtn(NULL) { - // Background image. - LLButton::Params bg_params = p.background; - mBackground = LLUICtrlFactory::create(bg_params); - addChildInBack(mBackground); - // "Place information" button. LLButton::Params info_params = p.info_button; mInfoBtn = LLUICtrlFactory::create(info_params); @@ -213,8 +186,6 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) enableAddLandmarkButton(true); addChild(mAddLandmarkBtn); - setFocusReceivedCallback(boost::bind(&LLLocationInputCtrl::onFocusReceived, this)); - setFocusLostCallback(boost::bind(&LLLocationInputCtrl::onFocusLost, this)); setPrearrangeCallback(boost::bind(&LLLocationInputCtrl::onLocationPrearrange, this, _2)); updateWidgetlayout(); @@ -222,10 +193,10 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) // - Make the "Add landmark" button updated when either current parcel gets changed // or a landmark gets created or removed from the inventory. // - Update the location string on parcel change. - LLViewerParcelMgr::getInstance()->setAgentParcelChangedCallback( + mParcelMgrConnection = LLViewerParcelMgr::getInstance()->setAgentParcelChangedCallback( boost::bind(&LLLocationInputCtrl::onAgentParcelChange, this)); - LLLocationHistory::getInstance()->setLoadedCallback( + mLocationHistoryConnection = LLLocationHistory::getInstance()->setLoadedCallback( boost::bind(&LLLocationInputCtrl::onLocationHistoryLoaded, this)); mRemoveLandmarkObserver = new LLRemoveLandmarkObserver(this); @@ -240,6 +211,9 @@ LLLocationInputCtrl::~LLLocationInputCtrl() gInventory.removeObserver(mAddLandmarkObserver); delete mRemoveLandmarkObserver; delete mAddLandmarkObserver; + + mParcelMgrConnection.disconnect(); + mLocationHistoryConnection.disconnect(); } void LLLocationInputCtrl::setEnabled(BOOL enabled) @@ -354,20 +328,28 @@ void LLLocationInputCtrl::onFocusReceived() void LLLocationInputCtrl::onFocusLost() { + LLUICtrl::onFocusLost(); refreshLocation(); } +void LLLocationInputCtrl::draw(){ + + if(!hasFocus()){ + refreshLocation(); + } + LLComboBox::draw(); +} void LLLocationInputCtrl::onInfoButtonClicked() { - LLSD key; - key["type"] = LLPanelPlaces::AGENT; - - LLSideTray::getInstance()->showPanel("panel_places", key); + LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "agent")); } void LLLocationInputCtrl::onAddLandmarkButtonClicked() { - LLFloaterReg::showInstance("add_landmark"); + LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); + + // Floater "Add Landmark" functionality moved to Side Tray + //LLFloaterReg::showInstance("add_landmark"); } void LLLocationInputCtrl::onAgentParcelChange() @@ -412,8 +394,10 @@ void LLLocationInputCtrl::refreshLocation() // Update location field. std::string location_name; + LLAgent::ELocationFormat format = (gSavedSettings.getBOOL("ShowCoordinatesOption") ? + LLAgent::LOCATION_FORMAT_FULL: LLAgent::LOCATION_FORMAT_NORMAL); - if (!gAgent.buildLocationString(location_name, LLAgent::LOCATION_FORMAT_NORMAL)) + if (!gAgent.buildLocationString(location_name,format)) location_name = "Unknown"; setText(location_name); @@ -461,41 +445,21 @@ void LLLocationInputCtrl::enableAddLandmarkButton(bool val) // depending on whether current parcel has been landmarked. void LLLocationInputCtrl::updateAddLandmarkButton() { - bool cur_parcel_landmarked = false; - - // Determine whether there are landmarks pointing to the current parcel. - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - LLIsAgentParcelLandmark is_current_parcel_landmark; - gInventory.collectDescendentsIf(gAgent.getInventoryRootID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - is_current_parcel_landmark); - cur_parcel_landmarked = !items.empty(); - - enableAddLandmarkButton(!cur_parcel_landmarked); + enableAddLandmarkButton(!LLLandmarkActions::landmarkAlreadyExists()); } void LLLocationInputCtrl::updateWidgetlayout() { const LLRect& rect = getLocalRect(); const LLRect& hist_btn_rect = mButton->getRect(); - LLRect info_btn_rect = mButton->getRect(); + LLRect info_btn_rect = mInfoBtn->getRect(); // info button info_btn_rect.setOriginAndSize( - 0, (rect.getHeight() - info_btn_rect.getHeight()) / 2, + 2, (rect.getHeight() - info_btn_rect.getHeight()) / 2, info_btn_rect.getWidth(), info_btn_rect.getHeight()); mInfoBtn->setRect(info_btn_rect); - // background - mBackground->setRect(LLRect(info_btn_rect.getWidth(), rect.mTop, - rect.mRight - hist_btn_rect.getWidth(), rect.mBottom)); - - // history button - mButton->setRightHPad(0); - // "Add Landmark" button { LLRect al_btn_rect = mAddLandmarkBtn->getRect(); @@ -504,14 +468,4 @@ void LLLocationInputCtrl::updateWidgetlayout() (rect.getHeight() - al_btn_rect.getHeight()) / 2); mAddLandmarkBtn->setRect(al_btn_rect); } - - // text entry - if (mTextEntry) - { - LLRect text_entry_rect(rect); - text_entry_rect.mLeft = info_btn_rect.getWidth(); - text_entry_rect.mRight = mAddLandmarkBtn->getRect().mLeft; - text_entry_rect.stretch(0, -1); // make space for border - mTextEntry->setRect(text_entry_rect); - } } diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index 1732853263..bda67fd313 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -61,8 +61,7 @@ public: add_landmark_image_disabled; Optional add_landmark_hpad; Optional add_landmark_button, - info_button, - background; + info_button; Params(); }; @@ -70,6 +69,9 @@ public: /*virtual*/ void setEnabled(BOOL enabled); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); + /*virtual*/ void onFocusReceived(); + /*virtual*/ void onFocusLost(); + /*virtual*/ void draw(); //======================================================================== // LLUICtrl interface @@ -98,8 +100,6 @@ private: void updateAddLandmarkButton(); void updateWidgetlayout(); - void onFocusReceived(); - void onFocusLost(); void onInfoButtonClicked(); void onLocationHistoryLoaded(); void onLocationPrearrange(const LLSD& data); @@ -107,13 +107,15 @@ private: void onAddLandmarkButtonClicked(); void onAgentParcelChange(); - LLButton* mBackground; LLButton* mAddLandmarkBtn; LLButton* mInfoBtn; S32 mAddLandmarkHPad; LLAddLandmarkObserver* mAddLandmarkObserver; LLRemoveLandmarkObserver* mRemoveLandmarkObserver; + + boost::signals2::connection mParcelMgrConnection; + boost::signals2::connection mLocationHistoryConnection; }; #endif diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 16192079a2..3c59cb83cd 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -49,6 +49,7 @@ #include "llviewernetwork.h" #include "llviewercontrol.h" #include "llurlsimstring.h" +#include "llfloaterreg.h" #include "llfloatertos.h" #include "llwindow.h" #if LL_LINUX || LL_SOLARIS @@ -221,18 +222,19 @@ bool LLLoginInstance::handleLoginFailure(const LLSD& event) // to reconnect or to end the attempt in failure. if(reason_response == "tos") { - LLFloaterTOS::show(LLFloaterTOS::TOS_TOS, - message_response, - boost::bind(&LLLoginInstance::handleTOSResponse, + LLFloaterTOS * tos = + LLFloaterReg::showTypedInstance("message_tos", LLSD(message_response)); + + tos->setTOSCallback(boost::bind(&LLLoginInstance::handleTOSResponse, this, _1, "agree_to_tos")); } else if(reason_response == "critical") { - LLFloaterTOS::show(LLFloaterTOS::TOS_CRITICAL_MESSAGE, - message_response, - boost::bind(&LLLoginInstance::handleTOSResponse, - this, _1, "read_critical") - ); + LLFloaterTOS * tos = + LLFloaterReg::showTypedInstance("message_critical",LLSD(message_response)); + + tos->setTOSCallback(boost::bind(&LLLoginInstance::handleTOSResponse, + this, _1, "read_critical")); } else if(reason_response == "update" || gSavedSettings.getBOOL("ForceMandatoryUpdate")) { @@ -296,7 +298,7 @@ void LLLoginInstance::updateApp(bool mandatory, const std::string& auth_msg) { // store off config state, as we might quit soon gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); - gSavedSkinSettings.saveToFile(gSavedSettings.getString("SkinningSettingsFile"), TRUE); + LLUIColorTable::instance().saveUserSettings(); std::ostringstream message; std::string msg; diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 7039776585..3d1d6cad74 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -40,7 +40,7 @@ #include "llrender.h" #include "llprimitive.h" #include "llview.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llagent.h" #include "llviewercontrol.h" @@ -581,9 +581,9 @@ void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string LLColor4 LLManip::setupSnapGuideRenderPass(S32 pass) { - static LLColor4 grid_color_fg = gSavedSkinSettings.getColor("GridlineColor"); - static LLColor4 grid_color_bg = gSavedSkinSettings.getColor("GridlineBGColor"); - static LLColor4 grid_color_shadow = gSavedSkinSettings.getColor("GridlineShadowColor"); + static LLColor4 grid_color_fg = LLUIColorTable::instance().getColor("GridlineColor"); + static LLColor4 grid_color_bg = LLUIColorTable::instance().getColor("GridlineBGColor"); + static LLColor4 grid_color_shadow = LLUIColorTable::instance().getColor("GridlineShadowColor"); LLColor4 line_color; F32 line_alpha = gSavedSettings.getF32("GridOpacity"); diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index f228ea624b..d1d112c4bf 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -1107,8 +1107,8 @@ BOOL LLManipRotate::updateVisiblity() mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag; mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm; - mCenterScreen.set((S32)((0.5f - mRotationCenter.mdV[VY]) / gAgent.mHUDCurZoom * gViewerWindow->getWindowWidth()), - (S32)((mRotationCenter.mdV[VZ] + 0.5f) / gAgent.mHUDCurZoom * gViewerWindow->getWindowHeight())); + mCenterScreen.set((S32)((0.5f - mRotationCenter.mdV[VY]) / gAgent.mHUDCurZoom * gViewerWindow->getWorldViewWidth()), + (S32)((mRotationCenter.mdV[VZ] + 0.5f) / gAgent.mHUDCurZoom * gViewerWindow->getWorldViewHeight())); visible = TRUE; } else @@ -1624,8 +1624,8 @@ void LLManipRotate::mouseToRay( S32 x, S32 y, LLVector3* ray_pt, LLVector3* ray_ { if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD) { - F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidth()) - 0.5f) / gAgent.mHUDCurZoom; - F32 mouse_y = ((((F32)y) / gViewerWindow->getWindowHeight()) - 0.5f) / gAgent.mHUDCurZoom; + F32 mouse_x = (((F32)x / gViewerWindow->getWorldViewWidth()) - 0.5f) / gAgent.mHUDCurZoom; + F32 mouse_y = ((((F32)y) / gViewerWindow->getWorldViewHeight()) - 0.5f) / gAgent.mHUDCurZoom; *ray_pt = LLVector3(-1.f, -mouse_x, mouse_y); *ray_dir = LLVector3(1.f, 0.f, 0.f); @@ -1699,7 +1699,7 @@ void LLManipRotate::highlightManipulators( S32 x, S32 y ) F32 dist_y = mouse_dir_y.normVec(); F32 dist_z = mouse_dir_z.normVec(); - F32 distance_threshold = (MAX_MANIP_SELECT_DISTANCE * mRadiusMeters) / gViewerWindow->getWindowHeight(); + F32 distance_threshold = (MAX_MANIP_SELECT_DISTANCE * mRadiusMeters) / gViewerWindow->getWorldViewHeight(); if (llabs(dist_x - mRadiusMeters) * llmax(0.05f, proj_rot_x_axis) < distance_threshold) { diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index 5261c130ea..72596e850a 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -493,8 +493,8 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) mProjectedManipulators.insert(projManipulator); } - F32 half_width = (F32)gViewerWindow->getWindowWidth() / 2.f; - F32 half_height = (F32)gViewerWindow->getWindowHeight() / 2.f; + F32 half_width = (F32)gViewerWindow->getWorldViewWidth() / 2.f; + F32 half_height = (F32)gViewerWindow->getWorldViewHeight() / 2.f; LLVector2 manip2d; LLVector2 mousePos((F32)x - half_width, (F32)y - half_height); LLVector2 delta; @@ -1368,7 +1368,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) else { F32 object_distance = dist_vec(mScaleCenter, LLViewerCamera::getInstance()->getOrigin()); - mSnapRegimeOffset = (SNAP_GUIDE_SCREEN_OFFSET * gViewerWindow->getWindowWidth() * object_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio(); + mSnapRegimeOffset = (SNAP_GUIDE_SCREEN_OFFSET * gViewerWindow->getWorldViewWidth() * object_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio(); } LLVector3 cam_at_axis; F32 snap_guide_length; @@ -1381,7 +1381,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) { cam_at_axis = LLViewerCamera::getInstance()->getAtAxis(); F32 manipulator_distance = dist_vec(box_corner_agent, LLViewerCamera::getInstance()->getOrigin()); - snap_guide_length = (SNAP_GUIDE_SCREEN_LENGTH * gViewerWindow->getWindowWidth() * manipulator_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio(); + snap_guide_length = (SNAP_GUIDE_SCREEN_LENGTH * gViewerWindow->getWorldViewWidth() * manipulator_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio(); } mSnapGuideLength = snap_guide_length / llmax(0.1f, (llmin(mSnapGuideDir1 * cam_at_axis, mSnapGuideDir2 * cam_at_axis))); diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index b8c2a3d64b..cc2531d139 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -78,7 +78,7 @@ const F32 PLANE_TICK_SIZE = 0.4f; const F32 MANIPULATOR_SCALE_HALF_LIFE = 0.07f; const F32 SNAP_ARROW_SCALE = 0.7f; -static LLPointer sGridTex = NULL ; +static LLPointer sGridTex = NULL ; const LLManip::EManipPart MANIPULATOR_IDS[9] = { @@ -154,7 +154,7 @@ void LLManipTranslate::restoreGL() U32 mip = 0; destroyGL() ; - sGridTex = new LLImageGL() ; + sGridTex = LLViewerTextureManager::getLocalTexture() ; if(!sGridTex->createGLTexture()) { sGridTex = NULL ; @@ -414,7 +414,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) // Handle auto-rotation if necessary. const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD; - const S32 ROTATE_H_MARGIN = gViewerWindow->getWindowWidth() / 20; + const S32 ROTATE_H_MARGIN = gViewerWindow->getWorldViewWidth() / 20; const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped; BOOL rotated = FALSE; @@ -426,7 +426,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) gAgent.cameraOrbitAround(rotate_angle); rotated = TRUE; } - else if (x > gViewerWindow->getWindowWidth() - ROTATE_H_MARGIN) + else if (x > gViewerWindow->getWorldViewWidth() - ROTATE_H_MARGIN) { gAgent.cameraOrbitAround(-rotate_angle); rotated = TRUE; @@ -960,8 +960,8 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) LLVector2 manip_start_2d; LLVector2 manip_end_2d; LLVector2 manip_dir; - F32 half_width = gViewerWindow->getWindowWidth() / 2.f; - F32 half_height = gViewerWindow->getWindowHeight() / 2.f; + F32 half_width = gViewerWindow->getWorldViewWidth() / 2.f; + F32 half_height = gViewerWindow->getWorldViewHeight() / 2.f; LLVector2 mousePos((F32)x - half_width, (F32)y - half_height); LLVector2 mouse_delta; @@ -1225,7 +1225,7 @@ void LLManipTranslate::renderSnapGuides() { LLVector3 cam_to_selection = getPivotPoint() - LLViewerCamera::getInstance()->getOrigin(); F32 current_range = cam_to_selection.normVec(); - guide_size_meters = SNAP_GUIDE_SCREEN_SIZE * gViewerWindow->getWindowHeight() * current_range / LLViewerCamera::getInstance()->getPixelMeterRatio(); + guide_size_meters = SNAP_GUIDE_SCREEN_SIZE * gViewerWindow->getWorldViewHeight() * current_range / LLViewerCamera::getInstance()->getPixelMeterRatio(); F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians @@ -1522,7 +1522,7 @@ void LLManipTranslate::renderSnapGuides() float a = line_alpha; - LLColor4 col = gSavedSkinSettings.getColor("SilhouetteChildColor"); + LLColor4 col = LLUIColorTable::instance().getColor("SilhouetteChildColor"); { //draw grid behind objects LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); @@ -1800,7 +1800,7 @@ void LLManipTranslate::renderTranslationHandles() // Drag handles if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { - mArrowLengthMeters = mAxisArrowLength / gViewerWindow->getWindowHeight(); + mArrowLengthMeters = mAxisArrowLength / gViewerWindow->getWorldViewHeight(); mArrowLengthMeters /= gAgent.mHUDCurZoom; } else diff --git a/indra/newview/llmemoryview.cpp b/indra/newview/llmemoryview.cpp index ab5db93027..3c7716e9c2 100644 --- a/indra/newview/llmemoryview.cpp +++ b/indra/newview/llmemoryview.cpp @@ -119,7 +119,7 @@ void LLMemoryView::draw() const S32 UPDATE_INTERVAL = 60; const S32 MARGIN_AMT = 10; static S32 curUpdate = UPDATE_INTERVAL; - static LLCachedControl s_console_color(gSavedSkinSettings, "ConsoleBackground", LLColor4U::black); + static LLUIColor s_console_color = LLUIColorTable::instance().getColor("ConsoleBackground", LLColor4U::black); // setup update interval if (curUpdate >= UPDATE_INTERVAL) diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index d76ddbf4d4..2433b6fac6 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -44,14 +44,14 @@ #include "llagent.h" #include "llcallingcard.h" -#include "llchatbar.h" #include "llviewercontrol.h" #include "llfirstuse.h" #include "llfloaterchat.h" #include "llfloaterdirectory.h" #include "llfloaterworldmap.h" #include "llgivemoney.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" +#include "lllineeditor.h" #include "llnotify.h" #include "llstatusbar.h" #include "llimview.h" @@ -67,7 +67,7 @@ #include "llworld.h" #include "llworldmap.h" #include "llfocusmgr.h" -#include "llbottomtray.h" +#include "llnearbychatbar.h" void handle_pay_by_id(const LLUUID& agent_id) { const BOOL is_group = FALSE; @@ -83,20 +83,20 @@ void handle_mouselook(void*) void handle_chat(void*) { // give focus to chatbar if it's open but not focused - if (gSavedSettings.getBOOL("ChatVisible") && gFocusMgr.childHasKeyboardFocus( - LLBottomTray::getInstance()->getChatBox())) + if (gSavedSettings.getBOOL("ChatVisible") && + gFocusMgr.childHasKeyboardFocus(LLNearbyChatBar::getInstance()->getChatBox())) { - LLChatBar::stopChat(); + LLNearbyChatBar::stopChat(); } else { - LLChatBar::startChat(NULL); + LLNearbyChatBar::startChat(NULL); } } void handle_slash_key(void*) { - // LLChatBar::startChat("/"); + // LLBottomTray::startChat("/"); // // Don't do this, it results in a double-slash in the input field. // Another "/" will be automatically typed for us, because the WM_KEYDOWN event @@ -106,5 +106,5 @@ void handle_slash_key(void*) // menu accelerators that put input focus into a field. And Mac works // the same way. JC - LLChatBar::startChat(NULL); + LLNearbyChatBar::startChat(NULL); } diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 36ec2c779a..124a2def7f 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -38,12 +38,19 @@ #include "indra_constants.h" // Viewer includes + #include "llagent.h" -#include "llviewercontrol.h" +#include "llvoavatarself.h" // to check gAgent.getAvatarObject()->isSitting() +#include "llbottomtray.h" #include "llbutton.h" -#include "llviewerwindow.h" +#include "llfirsttimetipmanager.h" +#include "llfloaterreg.h" +#include "llfloaterfirsttimetip.h" #include "lljoystickbutton.h" #include "lluictrlfactory.h" +#include "llviewerwindow.h" +#include "llviewercontrol.h" +#include "llselectmgr.h" // // Constants @@ -53,75 +60,87 @@ const F32 MOVE_BUTTON_DELAY = 0.0f; const F32 YAW_NUDGE_RATE = 0.05f; // fraction of normal speed const F32 NUDGE_TIME = 0.25f; // in seconds +const std::string BOTTOM_TRAY_BUTTON_NAME = "movement_btn"; + // // Member functions // // protected LLFloaterMove::LLFloaterMove(const LLSD& key) -: LLFloater() +: LLFloater(key), + mForwardButton(NULL), + mBackwardButton(NULL), + mTurnLeftButton(NULL), + mTurnRightButton(NULL), + mMoveUpButton(NULL), + mMoveDownButton(NULL), + mStopFlyingButton(NULL), + mModeActionsPanel(NULL) { - setIsChrome(TRUE); - - const BOOL DONT_OPEN = FALSE; - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_moveview.xml", DONT_OPEN); - } -// virtual -void LLFloaterMove::onClose(bool app_quitting) -{ - destroy(); - - if (!app_quitting) - { - gSavedSettings.setBOOL("ShowMovementControls", FALSE); - } -} // virtual BOOL LLFloaterMove::postBuild() { + setIsChrome(TRUE); + + mForwardButton = getChild("forward btn"); mForwardButton->setHeldDownDelay(MOVE_BUTTON_DELAY); mBackwardButton = getChild("backward btn"); mBackwardButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - mSlideLeftButton = getChild("slide left btn"); - mSlideLeftButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - - mSlideRightButton = getChild("slide right btn"); - mSlideRightButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - mTurnLeftButton = getChild("turn left btn"); mTurnLeftButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - mTurnLeftButton->setHeldDownCallback( turnLeft, NULL ); - + mTurnLeftButton->setHeldDownCallback(boost::bind(&LLFloaterMove::turnLeft, this)); mTurnRightButton = getChild("turn right btn"); mTurnRightButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - mTurnRightButton->setHeldDownCallback( turnRight, NULL ); + mTurnRightButton->setHeldDownCallback(boost::bind(&LLFloaterMove::turnRight, this)); mMoveUpButton = getChild("move up btn"); - childSetAction("move up btn",moveUp,NULL); mMoveUpButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - mMoveUpButton->setHeldDownCallback( moveUp, NULL ); + mMoveUpButton->setHeldDownCallback(boost::bind(&LLFloaterMove::moveUp, this)); mMoveDownButton = getChild("move down btn"); - childSetAction("move down btn",moveDown,NULL); mMoveDownButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - mMoveDownButton->setHeldDownCallback( moveDown, NULL ); + mMoveDownButton->setHeldDownCallback(boost::bind(&LLFloaterMove::moveDown, this)); + + + mStopFlyingButton = getChild("stop_fly_btn"); + + mModeActionsPanel = getChild("panel_modes"); + + LLButton* btn; + btn = getChild("mode_walk_btn"); + btn->setCommitCallback(boost::bind(&LLFloaterMove::onWalkButtonClick, this)); + + btn = getChild("mode_run_btn"); + btn->setCommitCallback(boost::bind(&LLFloaterMove::onRunButtonClick, this)); + + btn = getChild("mode_fly_btn"); + btn->setCommitCallback(boost::bind(&LLFloaterMove::onFlyButtonClick, this)); + + btn = getChild("stop_fly_btn"); + btn->setCommitCallback(boost::bind(&LLFloaterMove::onStopFlyingButtonClick, this)); + + + + showFlyControls(false); + + initModeTooltips(); + + updatePosition(); + + initModeButtonMap(); + + initMovementMode(); + return TRUE; } -// -// Static member functions -// -void LLFloaterMove::onOpen(const LLSD& key) -{ - gSavedSettings.setBOOL("ShowMovementControls", TRUE); -} - -// protected static +// static F32 LLFloaterMove::getYawRate( F32 time ) { if( time < NUDGE_TIME ) @@ -135,32 +154,431 @@ F32 LLFloaterMove::getYawRate( F32 time ) } } -// protected static -void LLFloaterMove::turnLeft(void *) + +// static +void LLFloaterMove::setFlyingMode(BOOL fly) { - F32 time = getInstance()->mTurnLeftButton->getHeldDownTime(); + LLFloaterMove* instance = LLFloaterReg::findTypedInstance("moveview"); + if (instance) + { + instance->setFlyingModeImpl(fly); + instance->showModeButtons(!fly); + } + if (fly) + { + LLPanelStandStopFlying::setStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STOP_FLYING); + } + else + { + LLPanelStandStopFlying::clearStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STOP_FLYING); + } +} +//static +void LLFloaterMove::setAlwaysRunMode(bool run) +{ + LLFloaterMove* instance = LLFloaterReg::findTypedInstance("moveview"); + if (instance) + { + instance->setAlwaysRunModeImpl(run); + } +} + +void LLFloaterMove::setFlyingModeImpl(BOOL fly) +{ + updateButtonsWithMovementMode(fly ? MM_FLY : (gAgent.getAlwaysRun() ? MM_RUN : MM_WALK)); +} + +void LLFloaterMove::setAlwaysRunModeImpl(bool run) +{ + if (!gAgent.getFlying()) + { + updateButtonsWithMovementMode(run ? MM_RUN : MM_WALK); + } +} + +//static +void LLFloaterMove::setSittingMode(BOOL bSitting) +{ + if (bSitting) + { + LLPanelStandStopFlying::setStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STAND); + } + else + { + LLPanelStandStopFlying::clearStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STAND); + } + enableInstance(!bSitting); +} + +// protected +void LLFloaterMove::turnLeft() +{ + F32 time = mTurnLeftButton->getHeldDownTime(); gAgent.moveYaw( getYawRate( time ) ); } -// protected static -void LLFloaterMove::turnRight(void *) +// protected +void LLFloaterMove::turnRight() { - F32 time = getInstance()->mTurnRightButton->getHeldDownTime(); + F32 time = mTurnRightButton->getHeldDownTime(); gAgent.moveYaw( -getYawRate( time ) ); } -// protected static -void LLFloaterMove::moveUp(void *) +// protected +void LLFloaterMove::moveUp() { // Jumps or flys up, depending on fly state gAgent.moveUp(1); } -// protected static -void LLFloaterMove::moveDown(void *) +// protected +void LLFloaterMove::moveDown() { // Crouches or flys down, depending on fly state gAgent.moveUp(-1); } +////////////////////////////////////////////////////////////////////////// +// Private Section: +////////////////////////////////////////////////////////////////////////// + +void LLFloaterMove::onWalkButtonClick() +{ + setMovementMode(MM_WALK); +} +void LLFloaterMove::onRunButtonClick() +{ + setMovementMode(MM_RUN); +} +void LLFloaterMove::onFlyButtonClick() +{ + setMovementMode(MM_FLY); +} +void LLFloaterMove::onStopFlyingButtonClick() +{ + setMovementMode(gAgent.getAlwaysRun() ? MM_RUN : MM_WALK); +} + +void LLFloaterMove::setMovementMode(const EMovementMode mode) +{ + gAgent.setFlying(MM_FLY == mode); + + switch (mode) + { + case MM_RUN: + gAgent.setAlwaysRun(); + gAgent.setRunning(); + break; + case MM_WALK: + gAgent.clearAlwaysRun(); + gAgent.clearRunning(); + break; + default: + //do nothing for other modes (MM_FLY) + break; + } + // tell the simulator. + gAgent.sendWalkRun(gAgent.getAlwaysRun()); + + updateButtonsWithMovementMode(mode); + + bool bHideModeButtons = MM_FLY == mode + || (gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting()); + + showModeButtons(!bHideModeButtons); + + showQuickTips(mode); +} + +void LLFloaterMove::updateButtonsWithMovementMode(const EMovementMode newMode) +{ + showFlyControls(MM_FLY == newMode); + setModeTooltip(newMode); + setModeButtonToggleState(newMode); +} + +void LLFloaterMove::showFlyControls(bool bShow) +{ + mMoveUpButton->setVisible(bShow); + mMoveDownButton->setVisible(bShow); + + // *TODO: mantipov: mStopFlyingButton from the FloaterMove is not used now. + // It was not completly removed until functionality is reviewed by LL + mStopFlyingButton->setVisible(FALSE); +} + +void LLFloaterMove::initModeTooltips() +{ + control_tooltip_map_t walkTipMap; + walkTipMap.insert(std::make_pair(mForwardButton, getString("walk_forward_tooltip"))); + walkTipMap.insert(std::make_pair(mBackwardButton, getString("walk_back_tooltip"))); + mModeControlTooltipsMap[MM_WALK] = walkTipMap; + + control_tooltip_map_t runTipMap; + runTipMap.insert(std::make_pair(mForwardButton, getString("run_forward_tooltip"))); + runTipMap.insert(std::make_pair(mBackwardButton, getString("run_back_tooltip"))); + mModeControlTooltipsMap[MM_RUN] = runTipMap; + + control_tooltip_map_t flyTipMap; + flyTipMap.insert(std::make_pair(mForwardButton, getString("fly_forward_tooltip"))); + flyTipMap.insert(std::make_pair(mBackwardButton, getString("fly_back_tooltip"))); + mModeControlTooltipsMap[MM_FLY] = flyTipMap; + + setModeTooltip(MM_WALK); +} + +void LLFloaterMove::initModeButtonMap() +{ + mModeControlButtonMap[MM_WALK] = getChild("mode_walk_btn"); + mModeControlButtonMap[MM_RUN] = getChild("mode_run_btn"); + mModeControlButtonMap[MM_FLY] = getChild("mode_fly_btn"); +} + +void LLFloaterMove::initMovementMode() +{ + EMovementMode initMovementMode = gAgent.getAlwaysRun() ? MM_RUN : MM_WALK; + if (gAgent.getFlying()) + { + initMovementMode = MM_FLY; + } + setMovementMode(initMovementMode); + + if (gAgent.getAvatarObject()) + { + setEnabled(!gAgent.getAvatarObject()->isSitting()); + } +} + +void LLFloaterMove::setModeTooltip(const EMovementMode mode) +{ + llassert_always(mModeControlTooltipsMap.end() != mModeControlTooltipsMap.find(mode)); + control_tooltip_map_t controlsTipMap = mModeControlTooltipsMap[mode]; + control_tooltip_map_t::const_iterator it = controlsTipMap.begin(); + for (; it != controlsTipMap.end(); ++it) + { + LLView* ctrl = it->first; + std::string tooltip = it->second; + ctrl->setToolTip(tooltip); + } +} + +/** + * Updates position of the floater to be center aligned with Move button. + * + * Because Tip floater created as dependent floater this method + * must be called before "showQuickTips()" to get Tip floater be positioned at the right side of the floater + */ +void LLFloaterMove::updatePosition() +{ + LLBottomTray* tray = LLBottomTray::getInstance(); + if (!tray) return; + + LLButton* movement_btn = tray->getChild(BOTTOM_TRAY_BUTTON_NAME, TRUE, FALSE); + if (!movement_btn) return; + + //align centers of a button and a floater + S32 x = movement_btn->calcScreenRect().getCenterX() - getRect().getWidth()/2; + + S32 y = 0; + if (!mModeActionsPanel->getVisible()) + { + y = mModeActionsPanel->getRect().getHeight(); + } + setOrigin(x, y); +} +void LLFloaterMove::showModeButtons(BOOL bShow) +{ + if (mModeActionsPanel->getVisible() == bShow) + return; + mModeActionsPanel->setVisible(bShow); + + LLRect rect = getRect(); + + static S32 height = mModeActionsPanel->getRect().getHeight(); + S32 newHeight = getRect().getHeight(); + if (!bShow) + { + newHeight -= height; + } + else + { + newHeight += height; + } + rect.setLeftTopAndSize(rect.mLeft, rect.mTop, rect.getWidth(), newHeight); + reshape(rect.getWidth(), rect.getHeight()); + setRect(rect); +} +//static +void LLFloaterMove::enableInstance(BOOL bEnable) +{ + LLFloaterMove* instance = LLFloaterReg::findTypedInstance("moveview"); + if (instance) + { + instance->setEnabled(bEnable); + instance->showModeButtons(bEnable); + } +} + +void LLFloaterMove::onOpen(const LLSD& key) +{ + updatePosition(); +} + +void LLFloaterMove::showQuickTips(const EMovementMode mode) +{ + LLFirstTimeTipsManager::EFirstTimeTipType tipType = LLFirstTimeTipsManager::FTT_MOVE_WALK; + switch (mode) + { + case MM_FLY: tipType = LLFirstTimeTipsManager::FTT_MOVE_FLY; break; + case MM_RUN: tipType = LLFirstTimeTipsManager::FTT_MOVE_RUN; break; + case MM_WALK: tipType = LLFirstTimeTipsManager::FTT_MOVE_WALK; break; + default: llwarns << "Quick Tip type was not detected, FTT_MOVE_WALK will be used" << llendl; + } + + LLFirstTimeTipsManager::showTipsFor(tipType, this); +} + +void LLFloaterMove::setModeButtonToggleState(const EMovementMode mode) +{ + llassert_always(mModeControlButtonMap.end() != mModeControlButtonMap.find(mode)); + + mode_control_button_map_t::const_iterator it = mModeControlButtonMap.begin(); + for (; it != mModeControlButtonMap.end(); ++it) + { + it->second->setToggleState(FALSE); + } + + mModeControlButtonMap[mode]->setToggleState(TRUE); +} + + + +/************************************************************************/ +/* LLPanelStandStopFlying */ +/************************************************************************/ +LLPanelStandStopFlying::LLPanelStandStopFlying() : + mStandButton(NULL), + mStopFlyingButton(NULL) +{ + // make sure we have the only instance of this class + static bool b = true; + llassert_always(b); + b=false; +} + +// static +inline LLPanelStandStopFlying* LLPanelStandStopFlying::getInstance() +{ + static LLPanelStandStopFlying* panel = getStandStopFlyingPanel(); + return panel; +} + +//static +void LLPanelStandStopFlying::setStandStopFlyingMode(EStandStopFlyingMode mode) +{ + LLPanelStandStopFlying* panel = getInstance(); + panel->setVisible(TRUE); + + BOOL standVisible = SSFM_STAND == mode; + panel->mStandButton->setVisible(standVisible); + panel->mStopFlyingButton->setVisible(!standVisible); +} + +//static +void LLPanelStandStopFlying::clearStandStopFlyingMode(EStandStopFlyingMode mode) +{ + LLPanelStandStopFlying* panel = getInstance(); + switch(mode) { + case SSFM_STAND: + panel->mStandButton->setVisible(FALSE); + break; + case SSFM_STOP_FLYING: + panel->mStopFlyingButton->setVisible(FALSE); + break; + default: + llerrs << "Unexpected EStandStopFlyingMode is passed: " << mode << llendl; + } + +} + +BOOL LLPanelStandStopFlying::postBuild() +{ + mStandButton = getChild("stand_btn"); + mStandButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStandButtonClick, this)); + mStandButton->setCommitCallback(boost::bind(&LLFloaterMove::enableInstance, TRUE)); + + mStopFlyingButton = getChild("stop_fly_btn"); + mStopFlyingButton->setCommitCallback(boost::bind(&LLFloaterMove::setFlyingMode, FALSE)); + mStopFlyingButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStopFlyingButtonClick, this)); + + + return TRUE; +} + +//virtual +void LLPanelStandStopFlying::setVisible(BOOL visible) +{ + if (visible) + { + updatePosition(); + } + + LLPanel::setVisible(visible); +} + +////////////////////////////////////////////////////////////////////////// +// Private Section +////////////////////////////////////////////////////////////////////////// + +//static +LLPanelStandStopFlying* LLPanelStandStopFlying::getStandStopFlyingPanel() +{ + LLPanelStandStopFlying* panel = new LLPanelStandStopFlying(); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_stand_stop_flying.xml"); + + panel->setVisible(FALSE); + LLUI::getRootView()->addChild(panel); + + llinfos << "Build LLPanelStandStopFlying panel" << llendl; + + panel->updatePosition(); + return panel; +} + +void LLPanelStandStopFlying::onStandButtonClick() +{ + LLSelectMgr::getInstance()->deselectAllForStandingUp(); + gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + + setVisible(FALSE); +} + +void LLPanelStandStopFlying::onStopFlyingButtonClick() +{ + gAgent.setFlying(FALSE); + + setVisible(FALSE); +} + +/** + * Updates position of the Stand & Stop Flying panel to be center aligned with Move button. + */ +void LLPanelStandStopFlying::updatePosition() +{ + + LLBottomTray* tray = LLBottomTray::getInstance(); + if (!tray) return; + + LLButton* movement_btn = tray->getChild(BOTTOM_TRAY_BUTTON_NAME, TRUE, FALSE); + if (!movement_btn) return; + + //align centers of a button and a floater + S32 x = movement_btn->calcScreenRect().getCenterX() - getRect().getWidth()/2; + + S32 y = tray->getRect().getHeight(); + + setOrigin(x, y); +} + + // EOF diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h index 8d7cdc881d..fd9cf9f4c1 100644 --- a/indra/newview/llmoveview.h +++ b/indra/newview/llmoveview.h @@ -44,40 +44,117 @@ class LLJoystickAgentSlide; // Classes // class LLFloaterMove -: public LLFloater, - public LLFloaterSingleton +: public LLFloater { - friend class LLUISingleton >; - -protected: + friend class LLFloaterReg; + +private: LLFloaterMove(const LLSD& key); ~LLFloaterMove() {} - public: - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); + /*virtual*/ BOOL postBuild(); static F32 getYawRate(F32 time); + static void setFlyingMode(BOOL fly); + void setFlyingModeImpl(BOOL fly); + static void setAlwaysRunMode(bool run); + void setAlwaysRunModeImpl(bool run); + static void setSittingMode(BOOL bSitting); + static void enableInstance(BOOL bEnable); + /*virtual*/ void onOpen(const LLSD& key); + + // *HACK: due to hard enough to have this control aligned with "Move" button while resizing + // let update its position in each frame + /*virtual*/ void draw(){updatePosition(); LLFloater::draw();} + protected: - static void turnLeftNudge(void* userdata); - static void turnLeft(void* userdata); - - static void turnRightNudge(void* userdata); - static void turnRight(void* userdata); + void turnLeft(); + void turnRight(); - static void moveUp(void* userdata); - static void moveDown(void* userdata); + void moveUp(); + void moveDown(); + +private: + typedef enum movement_mode_t + { + MM_WALK, + MM_RUN, + MM_FLY + } EMovementMode; + void onWalkButtonClick(); + void onRunButtonClick(); + void onFlyButtonClick(); + void onStopFlyingButtonClick(); + void initMovementMode(); + void setMovementMode(const EMovementMode mode); + void showFlyControls(bool bShow); + void initModeTooltips(); + void setModeTooltip(const EMovementMode mode); + void showQuickTips(const EMovementMode mode); + void initModeButtonMap(); + void setModeButtonToggleState(const EMovementMode mode); + void updateButtonsWithMovementMode(const EMovementMode newMode); + void updatePosition(); + void showModeButtons(BOOL bShow); public: + LLJoystickAgentTurn* mForwardButton; LLJoystickAgentTurn* mBackwardButton; - LLJoystickAgentSlide* mSlideLeftButton; - LLJoystickAgentSlide* mSlideRightButton; LLButton* mTurnLeftButton; LLButton* mTurnRightButton; LLButton* mMoveUpButton; LLButton* mMoveDownButton; +private: + LLButton* mStopFlyingButton; + LLPanel* mModeActionsPanel; + + typedef std::map control_tooltip_map_t; + typedef std::map mode_control_tooltip_map_t; + mode_control_tooltip_map_t mModeControlTooltipsMap; + + typedef std::map mode_control_button_map_t; + mode_control_button_map_t mModeControlButtonMap; + +}; + + +/** + * This class contains Stand Up and Stop Flying buttons displayed above Move button in bottom tray + */ +class LLPanelStandStopFlying : public LLPanel +{ +public: + typedef enum stand_stop_flying_mode_t + { + SSFM_STAND, + SSFM_STOP_FLYING + } EStandStopFlyingMode; + + static LLPanelStandStopFlying* getInstance(); + static void setStandStopFlyingMode(EStandStopFlyingMode mode); + static void clearStandStopFlyingMode(EStandStopFlyingMode mode); + /*virtual*/ BOOL postBuild(); + /*virtual*/ void setVisible(BOOL visible); + + // *HACK: due to hard enough to have this control aligned with "Move" button while resizing + // let update its position in each frame + /*virtual*/ void draw(){updatePosition(); LLPanel::draw();} + + +protected: + LLPanelStandStopFlying(); + + +private: + static LLPanelStandStopFlying* getStandStopFlyingPanel(); + void onStandButtonClick(); + void onStopFlyingButtonClick(); + void updatePosition(); + + LLButton* mStandButton; + LLButton* mStopFlyingButton; }; diff --git a/indra/newview/llnamebox.cpp b/indra/newview/llnamebox.cpp index b85c1c759d..56648d3218 100644 --- a/indra/newview/llnamebox.cpp +++ b/indra/newview/llnamebox.cpp @@ -46,7 +46,7 @@ // statics std::set LLNameBox::sInstances; -static LLDefaultWidgetRegistry::Register r("name_box"); +static LLDefaultChildRegistry::Register r("name_box"); LLNameBox::LLNameBox(const Params& p) diff --git a/indra/newview/llnameeditor.cpp b/indra/newview/llnameeditor.cpp index 7f9ba8ba5a..ccb33c770a 100644 --- a/indra/newview/llnameeditor.cpp +++ b/indra/newview/llnameeditor.cpp @@ -43,7 +43,7 @@ #include "llstring.h" #include "llui.h" -static LLDefaultWidgetRegistry::Register r("name_editor"); +static LLDefaultChildRegistry::Register r("name_editor"); // statics std::set LLNameEditor::sInstances; diff --git a/indra/newview/llnameeditor.h b/indra/newview/llnameeditor.h index f9cabb5831..99e03a1166 100644 --- a/indra/newview/llnameeditor.h +++ b/indra/newview/llnameeditor.h @@ -50,6 +50,11 @@ public: { Optional is_group; Optional name_id; + + Params() + : is_group("is_group"), + name_id("name_id") + {} }; protected: diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 722113928b..087fdda14a 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -44,7 +44,7 @@ #include "llscrolllistcolumn.h" #include "llsdparam.h" -static LLDefaultWidgetRegistry::Register r("name_list"); +static LLDefaultChildRegistry::Register r("name_list"); void LLNameListCtrl::NameTypeNames::declareValues() { @@ -138,20 +138,20 @@ void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos, item.enabled = enabled; item.target = GROUP; - addRow(item, pos); + addNameItemRow(item, pos); } // public void LLNameListCtrl::addGroupNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos) { item.target = GROUP; - addRow(item, pos); + addNameItemRow(item, pos); } void LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos) { item.target = INDIVIDUAL; - addRow(item, pos); + addNameItemRow(item, pos); } LLScrollListItem* LLNameListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata) @@ -159,17 +159,17 @@ LLScrollListItem* LLNameListCtrl::addElement(const LLSD& element, EAddPosition p LLNameListCtrl::NameItem item_params; LLParamSDParser::instance().readSD(element, item_params); item_params.userdata = userdata; - return addRow(item_params, pos); + return addNameItemRow(item_params, pos); } -LLScrollListItem* LLNameListCtrl::addRow(const LLNameListCtrl::NameItem& name_item, EAddPosition pos) +LLScrollListItem* LLNameListCtrl::addNameItemRow(const LLNameListCtrl::NameItem& name_item, EAddPosition pos) { LLScrollListItem* item = LLScrollListCtrl::addRow(name_item, pos); if (!item) return NULL; // use supplied name by default - std::string fullname = name_item.display_name; + std::string fullname = name_item.name; switch(name_item.target) { case GROUP: diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 6f64aa68ad..070b6c4f4f 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -57,11 +57,11 @@ public: struct NameItem : public LLInitParam::Block { - Optional display_name; + Optional name; Optional target; NameItem() - : display_name("name"), + : name("name"), target("target", INDIVIDUAL) {} }; @@ -94,7 +94,7 @@ public: void addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM); /*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); - LLScrollListItem* addRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM); + LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM); // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index cf1d9a5d86..06cab9afb0 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -42,15 +42,20 @@ #include "llagent.h" #include "llfloaterhtmlhelp.h" +#include "lllandmarkactions.h" #include "lllocationhistory.h" #include "lllocationinputctrl.h" #include "llteleporthistory.h" +#include "llsearcheditor.h" +#include "llsidetray.h" #include "llslurl.h" #include "llurlsimstring.h" #include "llviewerinventory.h" #include "llviewermenu.h" #include "llviewerparcelmgr.h" #include "llworldmap.h" +#include "llappviewer.h" +#include "llviewercontrol.h" //-- LLTeleportHistoryMenuItem ----------------------------------------------- @@ -174,9 +179,9 @@ LLNavigationBar::LLNavigationBar() mBtnBack(NULL), mBtnForward(NULL), mBtnHome(NULL), - mBtnHelp(NULL), mCmbLocation(NULL), - mLeSearch(NULL) + mLeSearch(NULL), + mPurgeTPHistoryItems(false) { setIsChrome(TRUE); @@ -188,6 +193,9 @@ LLNavigationBar::LLNavigationBar() // navigation bar can never get a tab setFocusRoot(FALSE); + + // set a listener function for LoginComplete event + LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLNavigationBar::handleLoginComplete, this)); } LLNavigationBar::~LLNavigationBar() @@ -200,15 +208,12 @@ BOOL LLNavigationBar::postBuild() mBtnBack = getChild("back_btn"); mBtnForward = getChild("forward_btn"); mBtnHome = getChild("home_btn"); - mBtnHelp = getChild("help_btn"); mCmbLocation= getChild("location_combo"); - mLeSearch = getChild("search_input"); - - LLButton* search_btn = getChild("search_btn"); + mLeSearch = getChild("search_input"); - if (!mBtnBack || !mBtnForward || !mBtnHome || !mBtnHelp || - !mCmbLocation || !mLeSearch || !search_btn) + if (!mBtnBack || !mBtnForward || !mBtnHome || + !mCmbLocation || !mLeSearch) { llwarns << "Malformed navigation bar" << llendl; return FALSE; @@ -223,15 +228,13 @@ BOOL LLNavigationBar::postBuild() mBtnForward->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _2)); mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this)); - mBtnHelp->setClickedCallback(boost::bind(&LLNavigationBar::onHelpButtonClicked, this)); mCmbLocation->setSelectionCallback(boost::bind(&LLNavigationBar::onLocationSelection, this)); mLeSearch->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this)); - search_btn->setClickedCallback(boost::bind(&LLNavigationBar::onSearchCommit, this)); // Load the location field context menu - mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_navbar.xml", gMenuHolder); + mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if (!mLocationContextMenu) { llwarns << "Error loading navigation bar context menu" << llendl; @@ -247,10 +250,16 @@ BOOL LLNavigationBar::postBuild() void LLNavigationBar::draw() { + if(mPurgeTPHistoryItems) + { + LLTeleportHistory::getInstance()->purgeItems(); + onTeleportHistoryChanged(); + mPurgeTPHistoryItems = false; + } LLPanel::draw(); } -BOOL LLNavigationBar::handleRightMouseDown(S32 x, S32 y, MASK mask) +BOOL LLNavigationBar::handleRightMouseUp(S32 x, S32 y, MASK mask) { // *HACK. We should use mCmbLocation's right click callback instead. @@ -268,7 +277,7 @@ BOOL LLNavigationBar::handleRightMouseDown(S32 x, S32 y, MASK mask) } return TRUE; } - return LLPanel:: handleRightMouseDown(x, y, mask); + return LLPanel:: handleRightMouseUp(x, y, mask); } void LLNavigationBar::onBackButtonClicked() @@ -292,14 +301,9 @@ void LLNavigationBar::onHomeButtonClicked() gAgent.teleportHome(); } -void LLNavigationBar::onHelpButtonClicked() -{ - gViewerHtmlHelp.show(); -} - void LLNavigationBar::onSearchCommit() { - invokeSearch(mLeSearch->getText()); + invokeSearch(mLeSearch->getValue().asString()); } void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata) @@ -412,21 +416,26 @@ void LLNavigationBar::onRegionNameResponse( } // Location is valid. Add it to the typed locations history. + // If user has typed text this variable will contain -1. S32 selected_item = mCmbLocation->getCurrentIndex(); - if (selected_item == -1) // user has typed text - { - LLLocationHistory* lh = LLLocationHistory::getInstance(); - mCmbLocation->add(typed_location); - lh->addItem(typed_location); - lh->save(); - } + + /* + LLLocationHistory* lh = LLLocationHistory::getInstance(); + lh->addItem(selected_item == -1 ? typed_location : mCmbLocation->getSelectedItemLabel()); + lh->save(); + */ // Teleport to the location. LLVector3d region_pos = from_region_handle(region_handle); LLVector3d global_pos = region_pos + (LLVector3d) local_coords; + llinfos << "Teleporting to: " << global_pos << llendl; gAgent.teleportViaLocation(global_pos); + + LLLocationHistory* lh = LLLocationHistory::getInstance(); + lh->addItem(selected_item == -1 ? typed_location : mCmbLocation->getSelectedItemLabel()); + lh->save(); } void LLNavigationBar::showTeleportHistoryMenu() @@ -458,18 +467,16 @@ void LLNavigationBar::onLocationContextMenuItemClicked(const LLSD& userdata) std::string item = userdata.asString(); LLLineEditor* location_entry = mCmbLocation->getTextEntry(); - if (item == std::string("copy_url")) + if (item == std::string("show_coordinates")) { - std::string sl_url = gAgent.getSLURL(); - LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(sl_url)); - - LLSD args; - args["SLURL"] = sl_url; - LLNotifications::instance().add("CopySLURL", args); + gSavedSettings.setBOOL("ShowCoordinatesOption",!gSavedSettings.getBOOL("ShowCoordinatesOption")); } else if (item == std::string("landmark")) { - LLFloaterReg::showInstance("add_landmark"); + LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); + + // Floater "Add Landmark" functionality moved to Side Tray + //LLFloaterReg::showInstance("add_landmark"); } else if (item == std::string("cut")) { @@ -518,6 +525,13 @@ bool LLNavigationBar::onLocationContextMenuItemEnabled(const LLSD& userdata) { return location_entry->canSelectAll(); } + else if(item == std::string("can_landmark")) + { + return !LLLandmarkActions::landmarkAlreadyExists(); + }else if(item == std::string("show_coordinates")){ + + return gSavedSettings.getBOOL("ShowCoordinatesOption"); + } return false; } @@ -531,3 +545,12 @@ void LLNavigationBar::invokeSearch(std::string search_text) { LLFloaterReg::showInstance("search", LLSD().insert("panel", "all").insert("id", LLSD(search_text))); } + +void LLNavigationBar::clearHistoryCache() +{ + mCmbLocation->removeall(); + LLLocationHistory* lh = LLLocationHistory::getInstance(); + lh->removeItems(); + lh->save(); + mPurgeTPHistoryItems= true; +} diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index 4c8375839e..17a1438912 100644 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -40,7 +40,7 @@ extern S32 NAVIGATION_BAR_HEIGHT; class LLButton; class LLLocationInputCtrl; class LLMenuGL; -class LLLineEditor; +class LLSearchEditor; /** * Web browser-like navigation bar. @@ -56,17 +56,18 @@ public: /*virtual*/ void draw(); /*virtual*/ BOOL postBuild(); - /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); void handleLoginComplete(); - + void clearHistoryCache(); + private: LLNavigationBar(); void rebuildTeleportHistoryMenu(); void showTeleportHistoryMenu(); void invokeSearch(std::string search_text); - + // callbacks bool onLocationContextMenuItemEnabled(const LLSD& userdata); void onLocationContextMenuItemClicked(const LLSD& userdata); @@ -79,7 +80,6 @@ private: void onHelpButtonClicked(); void onLocationSelection(); void onLocationPrearrange(const LLSD& data); - void onLocationHistoryLoaded(); void onSearchCommit(); void onRegionNameResponse( std::string typed_location, @@ -95,9 +95,9 @@ private: LLButton* mBtnBack; LLButton* mBtnForward; LLButton* mBtnHome; - LLButton* mBtnHelp; - LLLineEditor* mLeSearch; + LLSearchEditor* mLeSearch; LLLocationInputCtrl* mCmbLocation; + bool mPurgeTPHistoryItems; }; #endif diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp new file mode 100644 index 0000000000..1fa1e2a09d --- /dev/null +++ b/indra/newview/llnearbychat.cpp @@ -0,0 +1,524 @@ +/** + * @file LLNearbyChat.cpp + * @brief Nearby chat history scrolling panel implementation + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llnearbychat.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "llrootview.h" +//#include "llchatitemscontainerctrl.h" +#include "lliconctrl.h" +#include "llsidetray.h" +#include "llfocusmgr.h" +#include "llresizebar.h" +#include "llresizehandle.h" +#include "llmenugl.h" +#include "llviewermenu.h"//for gMenuHolder + +#include "llnearbychathandler.h" +#include "llchannelmanager.h" + +static const S32 RESIZE_BAR_THICKNESS = 3; + +LLNearbyChat::LLNearbyChat(const LLSD& key) : + LLFloater(key), + mEChatTearofState(CHAT_PINNED) +{ +} + +LLNearbyChat::~LLNearbyChat() +{ +} + +BOOL LLNearbyChat::postBuild() +{ + //resize bars + setCanResize(true); + + mResizeBar[LLResizeBar::BOTTOM]->setVisible(false); + mResizeBar[LLResizeBar::LEFT]->setVisible(false); + mResizeBar[LLResizeBar::RIGHT]->setVisible(false); + + mResizeBar[LLResizeBar::BOTTOM]->setResizeLimits(120,500); + mResizeBar[LLResizeBar::TOP]->setResizeLimits(120,500); + mResizeBar[LLResizeBar::LEFT]->setResizeLimits(220,600); + mResizeBar[LLResizeBar::RIGHT]->setResizeLimits(220,600); + + mResizeHandle[0]->setVisible(false); + mResizeHandle[1]->setVisible(false); + mResizeHandle[2]->setVisible(false); + mResizeHandle[3]->setVisible(false); + + //menu + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + + enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2)); + registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2)); + + + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + + if(menu) + mPopupMenuHandle = menu->getHandle(); + + gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true); + + /* + LLChatItemsContainerCtrl* panel = getChild("chat_history",false,false); + if(panel) + { + panel->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names")); + } + */ + + reshape(getRect().getWidth(), getRect().getHeight(), FALSE); + + return LLFloater::postBuild(); +} + +#include "llagent.h" // gAgent +#include "llfloaterscriptdebug.h" +#include "llviewertexteditor.h" +#include "llstylemap.h" + +LLColor4 nearbychat_get_text_color(const LLChat& chat) +{ + LLColor4 text_color; + + if(chat.mMuted) + { + text_color.setVec(0.8f, 0.8f, 0.8f, 1.f); + } + else + { + switch(chat.mSourceType) + { + case CHAT_SOURCE_SYSTEM: + text_color = LLUIColorTable::instance().getColor("SystemChatColor"); + break; + case CHAT_SOURCE_AGENT: + if (chat.mFromID.isNull()) + { + text_color = LLUIColorTable::instance().getColor("SystemChatColor"); + } + else + { + if(gAgentID == chat.mFromID) + { + text_color = LLUIColorTable::instance().getColor("UserChatColor"); + } + else + { + text_color = LLUIColorTable::instance().getColor("AgentChatColor"); + } + } + break; + case CHAT_SOURCE_OBJECT: + if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) + { + text_color = LLUIColorTable::instance().getColor("ScriptErrorColor"); + } + else if ( chat.mChatType == CHAT_TYPE_OWNER ) + { + text_color = LLUIColorTable::instance().getColor("llOwnerSayChatColor"); + } + else + { + text_color = LLUIColorTable::instance().getColor("ObjectChatColor"); + } + break; + default: + text_color.setToWhite(); + } + + if (!chat.mPosAgent.isExactlyZero()) + { + LLVector3 pos_agent = gAgent.getPositionAgent(); + F32 distance = dist_vec(pos_agent, chat.mPosAgent); + if (distance > gAgent.getNearChatRadius()) + { + // diminish far-off chat + text_color.mV[VALPHA] = 0.8f; + } + } + } + + return text_color; +} + +void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color) +{ + std::string line = chat.mFromName; + line +=": "; + line +=chat.mText; + + bool prepend_newline = true; + if (gSavedSettings.getBOOL("ChatShowTimestamps")) + { + edit->appendTime(prepend_newline); + prepend_newline = false; + } + + // If the msg is from an agent (not yourself though), + // extract out the sender name and replace it with the hotlinked name. + if (chat.mSourceType == CHAT_SOURCE_AGENT && + chat.mFromID != LLUUID::null) + { + chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str()); + } + + // If the chat line has an associated url, link it up to the name. + if (!chat.mURL.empty() + && (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0)) + { + std::string start_line = line.substr(0, chat.mFromName.length() + 1); + line = line.substr(chat.mFromName.length() + 1); + const LLStyleSP &sourceStyle = LLStyleMap::instance().lookup(chat.mFromID,chat.mURL); + edit->appendStyledText(start_line, false, prepend_newline, sourceStyle); + prepend_newline = false; + } + edit->appendColoredText(line, false, prepend_newline, color); +} + + + +void LLNearbyChat::addMessage(const LLChat& chat) +{ + /* + LLChatItemsContainerCtrl* panel = getChild("chat_history",false,false); + if(!panel) + return; + panel->addMessage(message); + */ + + //"Chat History Editor" !!!!! + + LLColor4 color = nearbychat_get_text_color(chat); + + + if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) + { + LLFloaterScriptDebug::addScriptLine(chat.mText, + chat.mFromName, + color, + chat.mFromID); + if (!gSavedSettings.getBOOL("ScriptErrorsAsChat")) + { + return; + } + } + + // could flash the chat button in the status bar here. JC + + LLViewerTextEditor* history_editor = getChild("Chat History Editor"); + + history_editor->setParseHTML(TRUE); + history_editor->setParseHighlights(TRUE); + + if (!chat.mMuted) + nearbychat_add_timestamped_line(history_editor, chat, color); +} + +void LLNearbyChat::onNearbySpeakers() +{ + LLSD param; + param["people_panel_tab_name"] = "nearby_panel"; + LLSideTray::getInstance()->showPanel("panel_people",param); +} + +void LLNearbyChat::onTearOff() +{ + if(mEChatTearofState == CHAT_PINNED) + float_panel(); + else + pinn_panel(); +} + +void LLNearbyChat::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + + LLFloater::reshape(width, height, called_from_parent); + + LLPanel* caption = getChild("chat_caption",false,false); + + LLRect resize_rect; + resize_rect.setLeftTopAndSize( 0, height, width, RESIZE_BAR_THICKNESS); + if (mResizeBar[LLResizeBar::TOP]) + { + mResizeBar[LLResizeBar::TOP]->reshape(width,RESIZE_BAR_THICKNESS); + mResizeBar[LLResizeBar::TOP]->setRect(resize_rect); + } + + resize_rect.setLeftTopAndSize( 0, RESIZE_BAR_THICKNESS, width, RESIZE_BAR_THICKNESS); + if (mResizeBar[LLResizeBar::BOTTOM]) + { + mResizeBar[LLResizeBar::BOTTOM]->reshape(width,RESIZE_BAR_THICKNESS); + mResizeBar[LLResizeBar::BOTTOM]->setRect(resize_rect); + } + + resize_rect.setLeftTopAndSize( 0, height, RESIZE_BAR_THICKNESS, height); + if (mResizeBar[LLResizeBar::LEFT]) + { + mResizeBar[LLResizeBar::LEFT]->reshape(RESIZE_BAR_THICKNESS,height); + mResizeBar[LLResizeBar::LEFT]->setRect(resize_rect); + } + + resize_rect.setLeftTopAndSize( width - RESIZE_BAR_THICKNESS, height, RESIZE_BAR_THICKNESS, height); + if (mResizeBar[LLResizeBar::RIGHT]) + { + mResizeBar[LLResizeBar::RIGHT]->reshape(RESIZE_BAR_THICKNESS,height); + mResizeBar[LLResizeBar::RIGHT]->setRect(resize_rect); + } + + + LLRect caption_rect; + if (caption) + { + caption_rect = caption->getRect(); + caption_rect.setLeftTopAndSize( 2, height - RESIZE_BAR_THICKNESS, width - 4, caption_rect.getHeight()); + caption->reshape( width - 4, caption_rect.getHeight(), 1); + caption->setRect(caption_rect); + } + + //LLPanel* scroll_panel = getChild("chat_history",false,false); + LLViewerTextEditor* scroll_panel = getChild("Chat History Editor"); + + if (scroll_panel) + { + LLRect scroll_rect = scroll_panel->getRect(); + scroll_rect.setLeftTopAndSize( 2, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS, width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2); + scroll_panel->reshape( width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2, 1); + scroll_panel->setRect(scroll_rect); + } + + // + if(mEChatTearofState == CHAT_PINNED) + { + const LLRect& parent_rect = gViewerWindow->getRootView()->getRect(); + + LLRect panel_rect; + panel_rect.setLeftTopAndSize( parent_rect.mLeft+2, parent_rect.mBottom+height+4, width, height); + setRect(panel_rect); + } + else + { + LLRect panel_rect; + panel_rect.setLeftTopAndSize( getRect().mLeft, getRect().mTop, width, height); + setRect(panel_rect); + } + +} + +BOOL LLNearbyChat::handleMouseDown (S32 x, S32 y, MASK mask) +{ + LLPanel* caption = getChild("chat_caption",false,false); + if(caption) + { + LLUICtrl* nearby_speakers_btn = caption->getChild("nearby_speakers_btn"); + LLUICtrl* tearoff_btn = caption->getChild("tearoff_btn"); + LLUICtrl* close_btn = caption->getChild("close_btn"); + + S32 caption_local_x = x - caption->getRect().mLeft; + S32 caption_local_y = y - caption->getRect().mBottom; + + if(nearby_speakers_btn && tearoff_btn) + { + S32 local_x = caption_local_x - nearby_speakers_btn->getRect().mLeft; + S32 local_y = caption_local_y - nearby_speakers_btn->getRect().mBottom; + if(nearby_speakers_btn->pointInView(local_x, local_y)) + { + onNearbySpeakers(); + bringToFront( x, y ); + return true; + } + local_x = caption_local_x - tearoff_btn->getRect().mLeft; + local_y = caption_local_y- tearoff_btn->getRect().mBottom; + if(tearoff_btn->pointInView(local_x, local_y)) + { + onTearOff(); + bringToFront( x, y ); + return true; + } + + if(close_btn) + { + local_x = caption_local_x - close_btn->getRect().mLeft; + local_y = caption_local_y - close_btn->getRect().mBottom; + if(close_btn->pointInView(local_x, local_y)) + { + setVisible(false); + bringToFront( x, y ); + return true; + } + } + } + + if(mEChatTearofState == CHAT_UNPINNED && caption->pointInView(caption_local_x, caption_local_y) ) + { + //start draggind + gFocusMgr.setMouseCapture(this); + mStart_Y = y; + mStart_X = x; + bringToFront( x, y ); + return true; + } + } + + return LLFloater::handleMouseDown(x,y,mask); +} + +BOOL LLNearbyChat::handleMouseUp(S32 x, S32 y, MASK mask) +{ + if( hasMouseCapture() ) + { + // Release the mouse + gFocusMgr.setMouseCapture( NULL ); + mStart_X = 0; + mStart_Y = 0; + return true; + } + + return LLFloater::handleMouseUp(x,y,mask); +} + +BOOL LLNearbyChat::handleHover(S32 x, S32 y, MASK mask) +{ + if( hasMouseCapture() ) + { + translate(x-mStart_X,y-mStart_Y); + return true; + } + return LLFloater::handleHover(x,y,mask); +} + +void LLNearbyChat::pinn_panel() +{ + mEChatTearofState = CHAT_PINNED; + LLPanel* caption = getChild("chat_caption",false,false); + LLIconCtrl* tearoff_btn = caption->getChild("tearoff_btn",false,false); + + tearoff_btn->setValue("inv_item_landmark_visited.tga"); + + const LLRect& parent_rect = gViewerWindow->getRootView()->getRect(); + + LLRect panel_rect; + panel_rect.setLeftTopAndSize( parent_rect.mLeft+2, parent_rect.mBottom+getRect().getHeight()+4, getRect().getWidth(), getRect().getHeight()); + setRect(panel_rect); + + mResizeBar[LLResizeBar::BOTTOM]->setVisible(false); + mResizeBar[LLResizeBar::LEFT]->setVisible(false); + mResizeBar[LLResizeBar::RIGHT]->setVisible(false); + +} + +void LLNearbyChat::float_panel() +{ + mEChatTearofState = CHAT_UNPINNED; + LLPanel* caption = getChild("chat_caption",false,false); + LLIconCtrl* tearoff_btn = caption->getChild("tearoff_btn",false,false); + + tearoff_btn->setValue("inv_item_landmark.tga"); + mResizeBar[LLResizeBar::BOTTOM]->setVisible(true); + mResizeBar[LLResizeBar::LEFT]->setVisible(true); + mResizeBar[LLResizeBar::RIGHT]->setVisible(true); + + translate(4,4); +} + +void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata) +{ + /* + LLChatItemsContainerCtrl* panel = getChild("chat_history",false,false); + if(!panel) + return; + + std::string str = userdata.asString(); + if(str == "show_buddy_icons") + panel->setHeaderVisibility(CHATITEMHEADER_SHOW_ONLY_ICON); + else if(str == "show_names") + panel->setHeaderVisibility(CHATITEMHEADER_SHOW_ONLY_NAME); + else if(str == "show_icons_and_names") + panel->setHeaderVisibility(CHATITEMHEADER_SHOW_BOTH); + + gSavedSettings.setS32("nearbychat_showicons_and_names", (S32)panel->getHeaderVisibility()); + */ +} +bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata) +{ + std::string str = userdata.asString(); + if(str == "nearby_people") + onNearbySpeakers(); + /* + LLChatItemsContainerCtrl* panel = getChild("chat_history",false,false); + if(!panel) + return false; + + if(str == "show_buddy_icons") + return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_ONLY_ICON; + else if(str == "show_names") + return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_ONLY_NAME; + else if(str == "show_icons_and_names") + return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_BOTH; + else if(str == "nearby_people") + onNearbySpeakers(); + */ + return false; +} + +BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + LLPanel* caption = getChild("chat_caption",false,false); + if(caption && caption->pointInView(x - caption->getRect().mLeft, y - caption->getRect().mBottom) ) + { + LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); + + if(menu) + { + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(this, menu, x, y); + } + return true; + } + return LLFloater::handleRightMouseDown(x, y, mask); +} + +void LLNearbyChat::onOpen(const LLSD& key ) +{ + LLNotificationsUI::LLScreenChannel* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->getChannelByID(LLUUID(NEARBY_CHAT_ID)); + if(chat_channel) + { + chat_channel->removeToastsFromChannel(); + } +} diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h new file mode 100644 index 0000000000..670a394c95 --- /dev/null +++ b/indra/newview/llnearbychat.h @@ -0,0 +1,94 @@ +/** + * @file llnearbychat.h + * @brief nearby chat history scrolling panel implementation + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLNEARBYCHAT_H_ +#define LL_LLNEARBYCHAT_H_ + +#include "llfloater.h" +#include "llscrollbar.h" +#include "llchat.h" + +class LLResizeBar; + +class LLNearbyChat: public LLFloater +{ +public: + // enumerations used by the chat system + typedef enum e_chat_tearof_state + { + CHAT_PINNED = 0, + CHAT_UNPINNED = 1, + } EChatTearofState; + + enum { RESIZE_BAR_COUNT=4 }; + + LLNearbyChat(const LLSD& key); + ~LLNearbyChat(); + + BOOL postBuild (); + void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE); + + BOOL handleMouseDown (S32 x, S32 y, MASK mask); + BOOL handleMouseUp (S32 x, S32 y, MASK mask); + BOOL handleHover (S32 x, S32 y, MASK mask); + + BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + + void addMessage (const LLChat& message); + + void onNearbySpeakers (); + void onTearOff(); + + void onNearbyChatContextMenuItemClicked(const LLSD& userdata); + bool onNearbyChatCheckContextMenuItem(const LLSD& userdata); + + virtual void onClose (bool app_quitting) { if(app_quitting) destroy(); else setVisible(false); } + + virtual void onOpen (const LLSD& key); + +private: + + void pinn_panel(); + void float_panel(); + +private: + EChatTearofState mEChatTearofState; + S32 mStart_X; + S32 mStart_Y; + + //LLResizeBar* mResizeBar[RESIZE_BAR_COUNT]; + LLHandle mPopupMenuHandle; +}; + +#endif + + diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp new file mode 100644 index 0000000000..83f8d14b5f --- /dev/null +++ b/indra/newview/llnearbychatbar.cpp @@ -0,0 +1,622 @@ +/** + * @file llnearbychatbar.cpp + * @brief LLNearbyChatBar class implementation + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llnearbychatbar.h" +#include "llbottomtray.h" +#include "llagent.h" +#include "llgesturemgr.h" +#include "llmultigesture.h" +#include "llkeyboard.h" +#include "llanimationstates.h" +#include "llviewerstats.h" +#include "llcommandhandler.h" +#include "llviewercontrol.h" + +S32 LLNearbyChatBar::sLastSpecialChatChannel = 0; + +// legacy calllback glue +void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); + +static LLDefaultChildRegistry::Register r("gesture_combo_box"); + +struct LLChatTypeTrigger { + std::string name; + EChatType type; +}; + +static LLChatTypeTrigger sChatTypeTriggers[] = { + { "/whisper" , CHAT_TYPE_WHISPER}, + { "/shout" , CHAT_TYPE_SHOUT} +}; + +LLGestureComboBox::LLGestureComboBox(const LLGestureComboBox::Params& p) + : LLComboBox(p) + , mGestureLabelTimer() + , mLabel(p.label) +{ + setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this, _1)); + + // now register us as observer since we have a place to put the results + LLGestureManager::instance().addObserver(this); + + // refresh list from current active gestures + refreshGestures(); +} + +LLGestureComboBox::~LLGestureComboBox() +{ + LLGestureManager::instance().removeObserver(this); +} + +void LLGestureComboBox::refreshGestures() +{ + //store current selection so we can maintain it + std::string cur_gesture = getValue().asString(); + selectFirstItem(); + // clear + clearRows(); + + // collect list of unique gestures + std::map unique; + LLGestureManager::item_map_t::iterator it; + for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it) + { + LLMultiGesture* gesture = (*it).second; + if (gesture) + { + if (!gesture->mTrigger.empty()) + { + unique[gesture->mTrigger] = TRUE; + } + } + } + + // add unique gestures + std::map ::iterator it2; + for (it2 = unique.begin(); it2 != unique.end(); ++it2) + { + addSimpleElement((*it2).first); + } + + sortByName(); + // Insert label after sorting, at top, with separator below it + addSeparator(ADD_TOP); + addSimpleElement(mLabel, ADD_TOP); + + if (!cur_gesture.empty()) + { + selectByValue(LLSD(cur_gesture)); + } + else + { + selectFirstItem(); + } +} + +void LLGestureComboBox::onCommitGesture(LLUICtrl* ctrl) +{ + LLCtrlListInterface* gestures = getListInterface(); + if (gestures) + { + S32 index = gestures->getFirstSelectedIndex(); + if (index == 0) + { + return; + } + const std::string& trigger = gestures->getSelectedValue().asString(); + + // pretend the user chatted the trigger string, to invoke + // substitution and logging. + std::string text(trigger); + std::string revised_text; + LLGestureManager::instance().triggerAndReviseString(text, &revised_text); + + revised_text = utf8str_trim(revised_text); + if (!revised_text.empty()) + { + // Don't play nodding animation + LLNearbyChatBar::sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE); + } + } + + mGestureLabelTimer.start(); + // free focus back to chat bar + setFocus(FALSE); +} + +//virtual +void LLGestureComboBox::draw() +{ + // HACK: Leave the name of the gesture in place for a few seconds. + const F32 SHOW_GESTURE_NAME_TIME = 2.f; + if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME) + { + LLCtrlListInterface* gestures = getListInterface(); + if (gestures) gestures->selectFirstItem(); + mGestureLabelTimer.stop(); + } + + LLComboBox::draw(); +} + +LLNearbyChatBar::LLNearbyChatBar() + : LLPanel() + , mChatBox(NULL) +{ +} + +//virtual +BOOL LLNearbyChatBar::postBuild() +{ + mChatBox = getChild("chat_box",TRUE,FALSE); + + if (mChatBox) + { + mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this)); + mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this); + mChatBox->setFocusLostCallback(&onChatBoxFocusLost, this); + + mChatBox->setIgnoreArrowKeys(TRUE); + mChatBox->setCommitOnFocusLost( FALSE ); + mChatBox->setRevertOnEsc( FALSE ); + mChatBox->setIgnoreTab(TRUE); + mChatBox->setPassDelete(TRUE); + mChatBox->setReplaceNewlinesWithSpaces(FALSE); + mChatBox->setMaxTextLength(1023); + mChatBox->setEnableLineHistory(TRUE); + } + + mTalkBtn = getChild("talk",TRUE,FALSE); + + return TRUE; +} + +//static +LLNearbyChatBar* LLNearbyChatBar::getInstance() +{ + return LLBottomTray::getInstance() ? LLBottomTray::getInstance()->getNearbyChatBar() : NULL; +} + +std::string LLNearbyChatBar::getCurrentChat() +{ + return mChatBox ? mChatBox->getText() : LLStringUtil::null; +} + +// virtual +BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask ) +{ + BOOL handled = FALSE; + + // ALT-RETURN is reserved for windowed/fullscreen toggle + if( KEY_RETURN == key && mask == MASK_CONTROL) + { + // shout + sendChat(CHAT_TYPE_SHOUT); + handled = TRUE; + } + + return handled; +} + +BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::string* out_str) +{ + U32 in_len = in_str.length(); + S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); + + for (S32 n = 0; n < cnt; n++) + { + if (in_len > sChatTypeTriggers[n].name.length()) + continue; + + std::string trigger_trunc = sChatTypeTriggers[n].name; + LLStringUtil::truncate(trigger_trunc, in_len); + + if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc)) + { + *out_str = sChatTypeTriggers[n].name; + return TRUE; + } + } + + return FALSE; +} + +void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata) +{ + + LLNearbyChatBar* self = (LLNearbyChatBar *)userdata; + + if (!self->mChatBox) + return; + + LLWString raw_text = self->mChatBox->getWText(); + + // Can't trim the end, because that will cause autocompletion + // to eat trailing spaces that might be part of a gesture. + LLWStringUtil::trimHead(raw_text); + + S32 length = raw_text.length(); + + if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences + { + gAgent.startTyping(); + } + else + { + gAgent.stopTyping(); + } + + /* Doesn't work -- can't tell the difference between a backspace + that killed the selection vs. backspace at the end of line. + if (length > 1 + && text[0] == '/' + && key == KEY_BACKSPACE) + { + // the selection will already be deleted, but we need to trim + // off the character before + std::string new_text = raw_text.substr(0, length-1); + self->mInputEditor->setText( new_text ); + self->mInputEditor->setCursorToEnd(); + length = length - 1; + } + */ + + KEY key = gKeyboard->currentKey(); + + // Ignore "special" keys, like backspace, arrows, etc. + if (length > 1 + && raw_text[0] == '/' + && key < KEY_SPECIAL) + { + // we're starting a gesture, attempt to autocomplete + + std::string utf8_trigger = wstring_to_utf8str(raw_text); + std::string utf8_out_str(utf8_trigger); + + if (LLGestureManager::instance().matchPrefix(utf8_trigger, &utf8_out_str)) + { + std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); + self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part + S32 outlength = self->mChatBox->getLength(); // in characters + + // Select to end of line, starting from the character + // after the last one the user typed. + self->mChatBox->setSelection(length, outlength); + } + else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str)) + { + std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); + self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part + self->mChatBox->setCursorToEnd(); + } + + //llinfos << "GESTUREDEBUG " << trigger + // << " len " << length + // << " outlen " << out_str.getLength() + // << llendl; + } +} + +// static +void LLNearbyChatBar::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata) +{ + // stop typing animation + gAgent.stopTyping(); +} + +EChatType LLNearbyChatBar::processChatTypeTriggers(EChatType type, std::string &str) +{ + U32 length = str.length(); + S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); + + for (S32 n = 0; n < cnt; n++) + { + if (length >= sChatTypeTriggers[n].name.length()) + { + std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length()); + + if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name)) + { + U32 trigger_length = sChatTypeTriggers[n].name.length(); + + // It's to remove space after trigger name + if (length > trigger_length && str[trigger_length] == ' ') + trigger_length++; + + str = str.substr(trigger_length, length); + + if (CHAT_TYPE_NORMAL == type) + return sChatTypeTriggers[n].type; + else + break; + } + } + } + + return type; +} + +void LLNearbyChatBar::sendChat( EChatType type ) +{ + if (mChatBox) + { + LLWString text = mChatBox->getConvertedText(); + if (!text.empty()) + { + // store sent line in history, duplicates will get filtered + mChatBox->updateHistory(); + // Check if this is destined for another channel + S32 channel = 0; + stripChannelNumber(text, &channel); + + std::string utf8text = wstring_to_utf8str(text); + // Try to trigger a gesture, if not chat to a script. + std::string utf8_revised_text; + if (0 == channel) + { + // discard returned "found" boolean + LLGestureManager::instance().triggerAndReviseString(utf8text, &utf8_revised_text); + } + else + { + utf8_revised_text = utf8text; + } + + utf8_revised_text = utf8str_trim(utf8_revised_text); + + type = processChatTypeTriggers(type, utf8_revised_text); + + if (!utf8_revised_text.empty()) + { + // Chat with animation + sendChatFromViewer(utf8_revised_text, type, TRUE); + } + } + + mChatBox->setText(LLStringExplicit("")); + } + + gAgent.stopTyping(); + + // If the user wants to stop chatting on hitting return, lose focus + // and go out of chat mode. + if (gSavedSettings.getBOOL("CloseChatOnReturn")) + { + stopChat(); + } +} + +void LLNearbyChatBar::onChatBoxCommit() +{ + if (mChatBox && mChatBox->getText().length() > 0) + { + sendChat(CHAT_TYPE_NORMAL); + } + + gAgent.stopTyping(); +} + +void LLNearbyChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate) +{ + sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate); +} + +void LLNearbyChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate) +{ + // Look for "/20 foo" channel chats. + S32 channel = 0; + LLWString out_text = stripChannelNumber(wtext, &channel); + std::string utf8_out_text = wstring_to_utf8str(out_text); + std::string utf8_text = wstring_to_utf8str(wtext); + + utf8_text = utf8str_trim(utf8_text); + if (!utf8_text.empty()) + { + utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); + } + + // Don't animate for chats people can't hear (chat to scripts) + if (animate && (channel == 0)) + { + if (type == CHAT_TYPE_WHISPER) + { + lldebugs << "You whisper " << utf8_text << llendl; + gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START); + } + else if (type == CHAT_TYPE_NORMAL) + { + lldebugs << "You say " << utf8_text << llendl; + gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START); + } + else if (type == CHAT_TYPE_SHOUT) + { + lldebugs << "You shout " << utf8_text << llendl; + gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START); + } + else + { + llinfos << "send_chat_from_viewer() - invalid volume" << llendl; + return; + } + } + else + { + if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) + { + lldebugs << "Channel chat: " << utf8_text << llendl; + } + } + + send_chat_from_viewer(utf8_out_text, type, channel); +} + +// static +void LLNearbyChatBar::startChat(const char* line) +{ + LLBottomTray *bt = LLBottomTray::getInstance(); + + if (!bt) + return; + + LLNearbyChatBar* cb = bt->getNearbyChatBar(); + + if (!cb || !cb->mChatBox) + return; + + bt->setVisible(TRUE); + cb->mChatBox->setFocus(TRUE); + + if (line) + { + std::string line_string(line); + cb->mChatBox->setText(line_string); + } + + cb->mChatBox->setCursorToEnd(); +} + +// Exit "chat mode" and do the appropriate focus changes +// static +void LLNearbyChatBar::stopChat() +{ + LLBottomTray *bt = LLBottomTray::getInstance(); + + if (!bt) + return; + + LLNearbyChatBar* cb = bt->getNearbyChatBar(); + + if (!cb || !cb->mChatBox) + return; + + cb->mChatBox->setFocus(FALSE); + + // stop typing animation + gAgent.stopTyping(); +} + +// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20. +// Otherwise returns input and channel 0. +LLWString LLNearbyChatBar::stripChannelNumber(const LLWString &mesg, S32* channel) +{ + if (mesg[0] == '/' + && mesg[1] == '/') + { + // This is a "repeat channel send" + *channel = sLastSpecialChatChannel; + return mesg.substr(2, mesg.length() - 2); + } + else if (mesg[0] == '/' + && mesg[1] + && LLStringOps::isDigit(mesg[1])) + { + // This a special "/20" speak on a channel + S32 pos = 0; + + // Copy the channel number into a string + LLWString channel_string; + llwchar c; + do + { + c = mesg[pos+1]; + channel_string.push_back(c); + pos++; + } + while(c && pos < 64 && LLStringOps::isDigit(c)); + + // Move the pointer forward to the first non-whitespace char + // Check isspace before looping, so we can handle "/33foo" + // as well as "/33 foo" + while(c && iswspace(c)) + { + c = mesg[pos+1]; + pos++; + } + + sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10); + *channel = sLastSpecialChatChannel; + return mesg.substr(pos, mesg.length() - pos); + } + else + { + // This is normal chat. + *channel = 0; + return mesg; + } +} + +void LLNearbyChatBar::setPTTState(bool state) +{ + mTalkBtn->setSpeakBtnToggleState(state); +} + +void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) +{ + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ChatFromViewer); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ChatData); + msg->addStringFast(_PREHASH_Message, utf8_out_text); + msg->addU8Fast(_PREHASH_Type, type); + msg->addS32("Channel", channel); + + gAgent.sendReliableMessage(); + + LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); +} + +class LLChatHandler : public LLCommandHandler +{ +public: + // not allowed from outside the app + LLChatHandler() : LLCommandHandler("chat", true) { } + + // Your code here + bool handle(const LLSD& tokens, const LLSD& query_map, + LLWebBrowserCtrl* web) + { + if (tokens.size() < 2) return false; + S32 channel = tokens[0].asInteger(); + std::string mesg = tokens[1].asString(); + send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel); + return true; + } +}; + +// Creating the object registers with the dispatcher. +LLChatHandler gChatHandler; + + diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h new file mode 100644 index 0000000000..b640aedf7a --- /dev/null +++ b/indra/newview/llnearbychatbar.h @@ -0,0 +1,108 @@ +/** + * @file llnearbychatbar.h + * @brief LLNearbyChatBar class definition + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLNEARBYCHATBAR_H +#define LL_LLNEARBYCHATBAR_H + +#include "llpanel.h" +#include "llcombobox.h" +#include "llgesturemgr.h" +#include "llchat.h" +#include "llchiclet.h" + +class LLGestureComboBox + : public LLComboBox + , public LLGestureManagerObserver +{ +public: + struct Params : public LLInitParam::Block { }; +protected: + LLGestureComboBox(const Params&); + friend class LLUICtrlFactory; +public: + ~LLGestureComboBox(); + + void refreshGestures(); + void onCommitGesture(LLUICtrl* ctrl); + virtual void draw(); + + // LLGestureManagerObserver trigger + virtual void changed() { refreshGestures(); } + +protected: + LLFrameTimer mGestureLabelTimer; + std::string mLabel; +}; + +class LLNearbyChatBar +: public LLPanel +{ +public: + // constructor for inline chat-bars (e.g. hosted in chat history window) + LLNearbyChatBar(); + ~LLNearbyChatBar() {} + + virtual BOOL postBuild(); + + static LLNearbyChatBar* getInstance(); + + LLLineEditor* getChatBox() { return mChatBox; } + + std::string getCurrentChat(); + virtual BOOL handleKeyHere( KEY key, MASK mask ); + + void setPTTState(bool state); + static void startChat(const char* line); + static void stopChat(); + + static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate); + static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); + +protected: + static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str); + static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata); + static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata); + + void sendChat( EChatType type ); + void onChatBoxCommit(); + + static LLWString stripChannelNumber(const LLWString &mesg, S32* channel); + EChatType processChatTypeTriggers(EChatType type, std::string &str); + + // Which non-zero channel did we last chat on? + static S32 sLastSpecialChatChannel; + + LLLineEditor* mChatBox; + LLTalkButton* mTalkBtn; +}; + +#endif diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp new file mode 100644 index 0000000000..cb1b65a604 --- /dev/null +++ b/indra/newview/llnearbychathandler.cpp @@ -0,0 +1,124 @@ +/** + * @file LLNearbyChatHandler.cpp + * @brief Nearby chat notification managment + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llnearbychathandler.h" + +#include "llchatitemscontainerctrl.h" +#include "llnearbychat.h" +#include "llrecentpeople.h" + +#include "llviewercontrol.h" + +#include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance + +//add LLNearbyChatHandler to LLNotificationsUI namespace +namespace LLNotificationsUI{ + + +LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id) +{ + mType = type; + LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); + ///////////////////////////////////////////////////// + LLChannelManager::Params p; //TODO: check and correct + p.id = LLUUID(NEARBY_CHAT_ID); + p.channel_right_bound = nearby_chat->getRect().mRight; + p.channel_width = nearby_chat->getRect().mRight - 16; //HACK: 16 - ? + ///////////////////////////////////////////////////// + + + // Getting a Channel for our notifications + mChannel = LLChannelManager::getInstance()->createChannel(p); + mChannel->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_TOP); + mChannel->setOverflowFormatString("You have %d unread nearby chat messages"); + mChannel->setStoreToasts(false); +} +LLNearbyChatHandler::~LLNearbyChatHandler() +{ +} +void LLNearbyChatHandler::processChat(const LLChat& chat_msg) +{ + if(chat_msg.mSourceType == CHAT_SOURCE_AGENT && chat_msg.mFromID.notNull()) + LLRecentPeople::instance().add(chat_msg.mFromID); + + if(chat_msg.mText.empty()) + return;//don't process empty messages + + LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); + nearby_chat->addMessage(chat_msg); + if(nearby_chat->getVisible()) + return;//no need in toast if chat is visible + + LLUUID id; + id.generate(); + + LLChatItemCtrl* item = LLChatItemCtrl::createInstance(); + + item->setMessage(chat_msg); + //static S32 chat_item_width = nearby_chat->getRect().getWidth() - 16; + static S32 chat_item_width = 304; + item->setWidth(chat_item_width); + item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names")); + + item->setVisible(true); + + + LLToast* toast = mChannel->addToast(id, item); + + toast->setOnMouseEnterCallback(boost::bind(&LLNearbyChatHandler::onToastDestroy, this, toast)); + toast->setAndStartTimer(gSavedSettings.getS32("NotificationToastTime")); +} + +void LLNearbyChatHandler::onToastDestroy(LLToast* toast) +{ + //TODO: what should be done to toasts here? may be htey are to be destroyed? + //toast->hide(); + if(mChannel) + mChannel->removeToastsFromChannel(); + else if(toast) + toast->hide(); + + LLFloaterReg::showTypedInstance("nearby_chat", LLSD()); +} + +void LLNearbyChatHandler::onChicletClick(void) +{ +} +void LLNearbyChatHandler::onChicletClose(void) +{ + +} + +} + diff --git a/indra/newview/llnearbychathandler.h b/indra/newview/llnearbychathandler.h new file mode 100644 index 0000000000..89ac08b9f0 --- /dev/null +++ b/indra/newview/llnearbychathandler.h @@ -0,0 +1,60 @@ +/** + * @file llnearbychathandler.h + * @brief nearby chat notify + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLNEARBYCHATHANDLER_H +#define LL_LLNEARBYCHATHANDLER_H + +#include "llnotificationhandler.h" + +#define NEARBY_CHAT_ID "E1158BD6-661C-4981-9DAD-4DCBFF062502" + +//add LLNearbyChatHandler to LLNotificationsUI namespace +namespace LLNotificationsUI{ + +class LLNearbyChatHandler : public LLChatHandler +{ +public: + LLNearbyChatHandler(e_notification_type type,const LLSD& id); + virtual ~LLNearbyChatHandler(); + + + virtual void processChat(const LLChat& chat_msg); + virtual void onToastDestroy(LLToast* toast); + virtual void onChicletClick(void); + virtual void onChicletClose(void); + +protected: +}; + +} + +#endif /* LL_LLNEARBYCHATHANDLER_H */ diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index b40af37f7e..7b0b0c2fb7 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -51,12 +51,15 @@ #include "llsurface.h" #include "llviewercamera.h" #include "llviewercontrol.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" +#include "llviewermenu.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llworld.h" #include "llworldmapview.h" // shared draw code -static LLDefaultWidgetRegistry::Register r1("net_map"); +static LLDefaultChildRegistry::Register r1("net_map"); const F32 MAP_SCALE_MIN = 64; const F32 MAP_SCALE_MID = 172; @@ -112,12 +115,12 @@ void LLNetMap::translatePan( F32 delta_x, F32 delta_y ) void LLNetMap::draw() { static LLFrameTimer map_timer; - static LLCachedControl map_avatar_color(gSavedSkinSettings, "MapAvatarColor", LLColor4::white); - static LLCachedControl map_avatar_friend_color(gSavedSkinSettings, "MapAvatarFriendColor", LLColor4::white); - static LLCachedControl map_track_color(gSavedSkinSettings, "MapTrackColor", LLColor4::white); - static LLCachedControl map_track_disabled_color(gSavedSkinSettings, "MapTrackDisabledColor", LLColor4::white); - static LLCachedControl map_frustum_color(gSavedSkinSettings, "MapFrustumColor", LLColor4::white); - static LLCachedControl map_frustum_rotating_color(gSavedSkinSettings, "MapFrustumRotatingColor", LLColor4::white); + static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white); + static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white); + static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white); + static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white); + static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white); + static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white); if (mObjectImagep.isNull()) { @@ -664,7 +667,7 @@ void LLNetMap::createObjectImage() mObjectRawImagep = new LLImageRaw(img_size, img_size, 4); U8* data = mObjectRawImagep->getData(); memset( data, 0, img_size * img_size * 4 ); - mObjectImagep = new LLImageGL( mObjectRawImagep, FALSE); + mObjectImagep = LLViewerTextureManager::getLocalTexture( mObjectRawImagep.get(), FALSE); setScale(mScale); } mUpdateNow = TRUE; diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index cebc4af165..a673ea3f57 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -39,11 +39,11 @@ #include "v3dmath.h" #include "v4color.h" #include "llimage.h" -#include "llimagegl.h" class LLColor4U; class LLCoordGL; class LLTextBox; +class LLViewerTexture ; class LLNetMap : public LLUICtrl { @@ -106,7 +106,7 @@ private: BOOL mUpdateNow; LLVector3d mObjectImageCenterGlobal; LLPointer mObjectRawImagep; - LLPointer mObjectImagep; + LLPointer mObjectImagep; LLUUID mClosestAgentToCursor; LLUUID mClosestAgentAtLastRightClick; diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp new file mode 100644 index 0000000000..06826998bf --- /dev/null +++ b/indra/newview/llnotificationalerthandler.cpp @@ -0,0 +1,116 @@ +/** + * @file llnotificationalerthandler.cpp + * @brief Notification Handler Class for Alert Notifications + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "llnotificationhandler.h" +#include "lltoastnotifypanel.h" +#include "llbottomtray.h" +#include "llviewercontrol.h" + +#include "lltoastalertpanel.h" + +using namespace LLNotificationsUI; + +//-------------------------------------------------------------------------- +LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsModal(false) +{ + mType = type; + + LLBottomTray* tray = LLBottomTray::getInstance(); + LLChannelManager::Params p; + p.id = LLUUID(ALERT_CHANNEL_ID); + p.channel_right_bound = tray->getRect().getWidth() / 2; + p.channel_width = 0; + p.align = NA_CENTRE; + + // Getting a Channel for our notifications + mChannel = LLChannelManager::getInstance()->createChannel(p); + mChannel->setFollows(FOLLOWS_BOTTOM | FOLLOWS_TOP); +} + +//-------------------------------------------------------------------------- +LLAlertHandler::~LLAlertHandler() +{ +} + +//-------------------------------------------------------------------------- +void LLAlertHandler::processNotification(const LLSD& notify) +{ + LLToast* toast = NULL; + + LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); + + if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load") + { + LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal); + + toast = mChannel->addToast(notification->getID(), (LLToastPanel*)alert_dialog); + if(!toast) + return; + toast->setHideButtonEnabled(false); + toast->setOnToastDestroyCallback((boost::bind(&LLAlertHandler::onToastDestroy, this, toast))); + toast->setCanFade(false); + toast->setModal(mIsModal); + } + else if (notify["sigtype"].asString() == "change") + { + LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal); + mChannel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog); + } + else + { + mChannel->killToastByNotificationID(notification->getID()); + } +} + +//-------------------------------------------------------------------------- + +void LLAlertHandler::onToastDestroy(LLToast* toast) +{ + toast->close(); +} + +//-------------------------------------------------------------------------- +void LLAlertHandler::onChicletClick(void) +{ +} + +//-------------------------------------------------------------------------- +void LLAlertHandler::onChicletClose(void) +{ +} + +//-------------------------------------------------------------------------- + + diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp new file mode 100644 index 0000000000..ad09f43c10 --- /dev/null +++ b/indra/newview/llnotificationgrouphandler.cpp @@ -0,0 +1,117 @@ +/** + * @file llnotificationgrouphandler.cpp + * @brief Notification Handler Class for Group Notifications + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "llnotificationhandler.h" +#include "lltoastgroupnotifypanel.h" +#include "llagent.h" +#include "llbottomtray.h" +#include "llviewercontrol.h" + +using namespace LLNotificationsUI; + +//-------------------------------------------------------------------------- +LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id) +{ + mType = type; + + // getting a Chiclet and creating params for a channel + LLBottomTray* tray = LLBottomTray::getInstance(); + mChiclet = tray->getSysWell(); + LLChannelManager::Params p; + p.chiclet = mChiclet; + p.channel_right_bound = tray->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); + p.channel_width = gSavedSettings.getS32("NotifyBoxWidth"); + + // Getting a Channel for our notifications + mChannel = LLChannelManager::getInstance()->createChannel(p); +} + +//-------------------------------------------------------------------------- +LLGroupHandler::~LLGroupHandler() +{ +} + +//-------------------------------------------------------------------------- +void LLGroupHandler::processNotification(const LLSD& notify) +{ + LLToast* toast = NULL; + + LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); + if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") + { + LLPanel* notify_box = new LLToastGroupNotifyPanel(notification); + toast = mChannel->addToast(notification->getID(), notify_box); + if(!toast) + return; + toast->setAndStartTimer(gSavedSettings.getS32("NotificationToastTime")); + toast->setOnToastDestroyCallback((boost::bind(&LLGroupHandler::onToastDestroy, this, toast))); + mChiclet->setCounter(mChiclet->getCounter() + 1); + } + else if (notify["sigtype"].asString() == "delete") + { + mChannel->killToastByNotificationID(notification->getID()); + } +} + +//-------------------------------------------------------------------------- +void LLGroupHandler::onToastDestroy(LLToast* toast) +{ + mChiclet->setCounter(mChiclet->getCounter() - 1); + toast->close(); +} + +//-------------------------------------------------------------------------- +void LLGroupHandler::onChicletClick(void) +{ +} + +//-------------------------------------------------------------------------- +void LLGroupHandler::onChicletClose(void) +{ +} + +//-------------------------------------------------------------------------- + + +//-------------------------------------------------------------------------- + + +//-------------------------------------------------------------------------- + + +//-------------------------------------------------------------------------- + + +//-------------------------------------------------------------------------- + diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h new file mode 100644 index 0000000000..9037fc82ab --- /dev/null +++ b/indra/newview/llnotificationhandler.h @@ -0,0 +1,180 @@ +/** + * @file llnotificationhandler.h + * @brief Here are implemented Notification Handling Classes. + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLNOTIFICATIONHANDLER_H +#define LL_LLNOTIFICATIONHANDLER_H + + +#include "llwindow.h" + +#include "llnotifications.h" +#include "llchannelmanager.h" +#include "llchat.h" + +namespace LLNotificationsUI +{ +// ID for channel that displays Alert Notifications +#define ALERT_CHANNEL_ID "F3E07BC8-A973-476D-8C7F-F3B7293975D1" + +// ENotificationType enumerates all possible types of notifications that could be met +// +typedef enum e_notification_type +{ + NT_NOTIFY, + NT_NOTIFYTIP, + NT_GROUPNOTIFY, + NT_IMCHAT, + NT_GROUPCHAT, + NT_NEARBYCHAT, + NT_ALERT, + NT_ALERTMODAL +} ENotificationType; + +/** + * Handler of notification events. + * This handler manages events related to toasts and chicklets. This is base class + * for chat and system notification handlers. + */ + +// LLEventHandler is a base class that specifies a common interface for all +// notification handlers. It states, that every handler must react on the follofing +// events: +// - destroying of a toast; +// - clicking on a correspondet chiclet; +// - closing of a correspondent chiclet. +// Also every handler must have the following attributes: +// - type of the notification that this handler is responsible to; +// - pointer to a correspondent chiclet; +// - pointer to a correspondent screen channel, in which all toasts of the handled notification's +// type should be displayed +// +class LLEventHandler +{ +public: + virtual ~LLEventHandler() {}; + + virtual void onToastDestroy(LLToast* toast)=0; + virtual void onChicletClick(void)=0; + virtual void onChicletClose(void)=0; + + LLScreenChannel* mChannel; + LLChiclet* mChiclet; + e_notification_type mType; +}; + +// LLSysHandler and LLChatHandler are more specific base classes +// that divide all notification handlers on to groups: +// - handlers for different system notifications (script dialogs, tips, group notices and alerts); +// - handlers for different messaging notifications (nearby chat, IM chat, group chat etc.) +/** + * Handler for system notifications. + */ +class LLSysHandler : public LLEventHandler +{ +public: + virtual ~LLSysHandler() {}; + + virtual void processNotification(const LLSD& notify)=0; +}; + +/** + * Handler for chat message notifications. + */ +class LLChatHandler : public LLEventHandler +{ +public: + virtual ~LLChatHandler() {}; + + virtual void processChat(const LLChat& chat_msg)=0; +}; + +/** + * Handler for system informational notices. + * It manages life time of tip and script notices. + */ +class LLInfoHandler : public LLSysHandler +{ +public: + LLInfoHandler(e_notification_type type, const LLSD& id); + virtual ~LLInfoHandler(); + + + virtual void processNotification(const LLSD& notify); + virtual void onToastDestroy(LLToast* toast); + virtual void onChicletClick(void); + virtual void onChicletClose(void); + +protected: +}; + + +/** + * Handler for group system notices. + */ +class LLGroupHandler : public LLSysHandler +{ +public: + LLGroupHandler(e_notification_type type, const LLSD& id); + virtual ~LLGroupHandler(); + + + virtual void processNotification(const LLSD& notify); + virtual void onToastDestroy(LLToast* toast); + virtual void onChicletClick(void); + virtual void onChicletClose(void); + +protected: +}; + +/** + * Handler for alert system notices. + */ +class LLAlertHandler : public LLSysHandler +{ +public: + LLAlertHandler(e_notification_type type, const LLSD& id); + virtual ~LLAlertHandler(); + + void setAlertMode(bool is_modal) { mIsModal = is_modal; } + + virtual void processNotification(const LLSD& notify); + virtual void onToastDestroy(LLToast* toast); + virtual void onChicletClick(void); + virtual void onChicletClose(void); + +protected: + bool mIsModal; +}; + +} +#endif + diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp new file mode 100644 index 0000000000..3eda0d0d14 --- /dev/null +++ b/indra/newview/llnotificationmanager.cpp @@ -0,0 +1,127 @@ +/** + * @file llnotificationmanager.cpp + * @brief Class implements a brige between the old and a new notification sistems + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + + +#include "llviewerprecompiledheaders.h" // must be first include + + +#include "llnotificationmanager.h" +#include "llnearbychathandler.h" + +#include "boost/bind.hpp" + +using namespace LLNotificationsUI; + +//-------------------------------------------------------------------------- +LLNotificationManager::LLNotificationManager() +{ + mNotifyHandlers.clear(); + init(); +} + +//-------------------------------------------------------------------------- +LLNotificationManager::~LLNotificationManager() +{ +} + +//-------------------------------------------------------------------------- +void LLNotificationManager::init() +{ + LLNotificationChannel::buildChannel("Notifications", "Visible", LLNotificationFilters::filterBy(&LLNotification::getType, "notify")); + LLNotificationChannel::buildChannel("NotificationTips", "Visible", LLNotificationFilters::filterBy(&LLNotification::getType, "notifytip")); + LLNotificationChannel::buildChannel("Group Notifications", "Visible", LLNotificationFilters::filterBy(&LLNotification::getType, "groupnotify")); + LLNotificationChannel::buildChannel("Alerts", "Visible", LLNotificationFilters::filterBy(&LLNotification::getType, "alert")); + LLNotificationChannel::buildChannel("AlertModal", "Visible", LLNotificationFilters::filterBy(&LLNotification::getType, "alertmodal")); + + LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); + LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); + LLNotifications::instance().getChannel("Group Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); + LLNotifications::instance().getChannel("Alerts")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); + LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); + + mNotifyHandlers["notify"] = boost::shared_ptr(new LLInfoHandler(NT_NOTIFY, LLSD())); + mNotifyHandlers["notifytip"] = mNotifyHandlers["notify"]; + mNotifyHandlers["groupnotify"] = boost::shared_ptr(new LLGroupHandler(NT_GROUPNOTIFY, LLSD())); + mNotifyHandlers["alert"] = boost::shared_ptr(new LLAlertHandler(NT_ALERT, LLSD())); + mNotifyHandlers["alertmodal"] = mNotifyHandlers["alert"]; + + mNotifyHandlers["nearbychat"] = boost::shared_ptr(new LLNearbyChatHandler(NT_NEARBYCHAT, LLSD())); +} + +//-------------------------------------------------------------------------- +bool LLNotificationManager::onNotification(const LLSD& notify) +{ + LLSysHandler* handle = NULL; + + LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); + + if (!notification) + return false; + + std::string notification_type = notification->getType(); + handle = dynamic_cast(mNotifyHandlers[notification_type].get()); + + if(!handle) + return false; + + if( notification_type == "alertmodal" ) + dynamic_cast(handle)->setAlertMode(true); + + handle->processNotification(notify); + + return true; +} + +//-------------------------------------------------------------------------- +void LLNotificationManager::onChat(const LLChat& msg,ENotificationType type) +{ + switch(type) + { + case NT_NEARBYCHAT: + { + LLNearbyChatHandler* handle = dynamic_cast(mNotifyHandlers["nearbychat"].get()); + + if(handle) + handle->processChat(msg); + } + break; + default: //no need to handle all enum types + break; + } +} + +//-------------------------------------------------------------------------- + + + + diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h new file mode 100644 index 0000000000..838a00ee11 --- /dev/null +++ b/indra/newview/llnotificationmanager.h @@ -0,0 +1,79 @@ +// Notification Manager Class +/** + * @file llnotificationmanager.h + * @brief Class implements a brige between the old and a new notification sistems + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLNOTIFICATIONMANAGER_H +#define LL_LLNOTIFICATIONMANAGER_H + +#include "lluictrl.h" +#include "llnotificationhandler.h" + + +#include +#include + +#include + +namespace LLNotificationsUI { + +class LLToast; + +/** + * Responsible for registering notification handlers. + */ +class LLNotificationManager : public LLUICtrl, public LLSingleton +{ + typedef std::pair eventhandlers; +public: + LLNotificationManager(); + virtual ~LLNotificationManager(); + + //TODO: make private + // this method initialize handlers' map for different types of notifications + void init(void); + //TODO: combine processing and storage (*) + + // this method reacts on system notifications and calls an appropriate handler + bool onNotification(const LLSD& notification); + + // this method reacts on chat notifications and calls an appropriate handler + void onChat(const LLChat& msg,ENotificationType type); + +private: + //TODO (*) + std::map > mNotifyHandlers; + std::map mChatHandlers; +}; + +} +#endif + diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index ff26707a56..d088c45710 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -39,41 +39,64 @@ // viewer includes #include "llvoiceclient.h" -static LLDefaultWidgetRegistry::Register r("output_monitor"); +// default options set in output_monitor.xml +static LLDefaultChildRegistry::Register r("output_monitor"); // The defaults will be initialized in the constructor. -LLColor4 LLOutputMonitorCtrl::sColorMuted; -LLColor4 LLOutputMonitorCtrl::sColorOverdriven; -LLColor4 LLOutputMonitorCtrl::sColorNormal; +//LLColor4 LLOutputMonitorCtrl::sColorMuted; +//LLColor4 LLOutputMonitorCtrl::sColorOverdriven; +//LLColor4 LLOutputMonitorCtrl::sColorNormal; LLColor4 LLOutputMonitorCtrl::sColorBound; -S32 LLOutputMonitorCtrl::sRectsNumber = 0; -F32 LLOutputMonitorCtrl::sRectWidthRatio = 0.f; -F32 LLOutputMonitorCtrl::sRectHeightRatio = 0.f; +//S32 LLOutputMonitorCtrl::sRectsNumber = 0; +//F32 LLOutputMonitorCtrl::sRectWidthRatio = 0.f; +//F32 LLOutputMonitorCtrl::sRectHeightRatio = 0.f; + +LLOutputMonitorCtrl::Params::Params() +: draw_border("draw_border"), + image_mute("image_mute"), + image_off("image_off"), + image_on("image_on"), + image_level_1("image_level_1"), + image_level_2("image_level_2"), + image_level_3("image_level_3") +{ + draw_border = true; + name = "output_monitor"; + follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP); + mouse_opaque = false; +}; LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p) : LLView(p), mPower(0), - mIsMuted(true) + mIsMuted(true), + mIsTalking(false), + mImageMute(p.image_mute), + mImageOff(p.image_off), + mImageOn(p.image_on), + mImageLevel1(p.image_level_1), + mImageLevel2(p.image_level_2), + mImageLevel3(p.image_level_3) { - static LLUICachedControl output_monitor_muted_color("OutputMonitorMutedColor", LLColor4::orange); - static LLUICachedControl output_monitor_overdriven_color("OutputMonitorOverdrivenColor", LLColor4::red); - static LLUICachedControl output_monitor_normal_color("OutputMonitorNotmalColor", LLColor4::green); - static LLUICachedControl output_monitor_bound_color("OutputMonitorBoundColor", LLColor4::white); - static LLUICachedControl output_monitor_rects_number("OutputMonitorRectanglesNumber", 20); - static LLUICachedControl output_monitor_rect_width_ratio("OutputMonitorRectangleWidthRatio", 0.5f); - static LLUICachedControl output_monitor_rect_height_ratio("OutputMonitorRectangleHeightRatio", 0.8f); + //static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange); + //static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red); + //static LLUIColor output_monitor_normal_color = LLUIColorTable::instance().getColor("OutputMonitorNotmalColor", LLColor4::green); + static LLUIColor output_monitor_bound_color = LLUIColorTable::instance().getColor("OutputMonitorBoundColor", LLColor4::white); + //static LLUICachedControl output_monitor_rects_number("OutputMonitorRectanglesNumber", 20); + //static LLUICachedControl output_monitor_rect_width_ratio("OutputMonitorRectangleWidthRatio", 0.5f); + //static LLUICachedControl output_monitor_rect_height_ratio("OutputMonitorRectangleHeightRatio", 0.8f); // IAN BUG compare to existing pattern where these are members - some will change per-widget and need to be anyway // sent feedback to PE // *TODO: it looks suboptimal to load the defaults every time an output monitor is constructed. - sColorMuted = output_monitor_muted_color; - sColorOverdriven = output_monitor_overdriven_color; - sColorNormal = output_monitor_normal_color; + //sColorMuted = output_monitor_muted_color; + //sColorOverdriven = output_monitor_overdriven_color; + //sColorNormal = output_monitor_normal_color; sColorBound = output_monitor_bound_color; - sRectsNumber = output_monitor_rects_number; - sRectWidthRatio = output_monitor_rect_width_ratio; - sRectHeightRatio = output_monitor_rect_height_ratio; + //sRectsNumber = output_monitor_rects_number; + //sRectWidthRatio = output_monitor_rect_width_ratio; + //sRectHeightRatio = output_monitor_rect_height_ratio; mBorder = p.draw_border; } @@ -89,6 +112,49 @@ void LLOutputMonitorCtrl::setPower(F32 val) void LLOutputMonitorCtrl::draw() { + // Copied from llmediaremotectrl.cpp + // *TODO: Give the LLOutputMonitorCtrl an agent-id to monitor, then + // call directly into gVoiceClient to ask if that agent-id is muted, is + // speaking, and what power. This avoids duplicating data, which can get + // out of sync. + const F32 LEVEL_0 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL / 3.f; + const F32 LEVEL_1 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL * 2.f / 3.f; + const F32 LEVEL_2 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL; + + LLPointer icon; + if (mIsMuted) + { + icon = mImageMute; + } + else if (mPower == 0.f && !mIsTalking) + { + // only show off if PTT is not engaged + icon = mImageOff; + } + else if (mPower < LEVEL_0) + { + // PTT is on, possibly with quiet background noise + icon = mImageOn; + } + else if (mPower < LEVEL_1) + { + icon = mImageLevel1; + } + else if (mPower < LEVEL_2) + { + icon = mImageLevel2; + } + else + { + // overdriven + icon = mImageLevel3; + } + + if (icon) + { + icon->draw(0, 0); + } + // // Fill the monitor with a bunch of small rectangles. // The rectangles will be filled with gradient color, @@ -98,41 +164,41 @@ void LLOutputMonitorCtrl::draw() // const int monh = getRect().getHeight(); const int monw = getRect().getWidth(); - int maxrects = sRectsNumber; - const int period = llmax(1, monw / maxrects, 0, 0); // "1" - min value for the period - const int rectw = llmax(1, llfloor(period * sRectWidthRatio), 0, 0); // "1" - min value for the rect's width - const int recth = llfloor(monh * sRectHeightRatio); + //int maxrects = sRectsNumber; + //const int period = llmax(1, monw / maxrects, 0, 0); // "1" - min value for the period + //const int rectw = llmax(1, llfloor(period * sRectWidthRatio), 0, 0); // "1" - min value for the rect's width + //const int recth = llfloor(monh * sRectHeightRatio); - if(period == 1 && rectw == 1) //if we have so small control, then "maxrects = monitor's_width - 2*monitor_border's_width - maxrects = monw-2; + //if(period == 1 && rectw == 1) //if we have so small control, then "maxrects = monitor's_width - 2*monitor_border's_width + // maxrects = monw-2; - const int nrects = mIsMuted ? maxrects : llfloor(mPower * maxrects); // how many rects to draw? - const int rectbtm = (monh - recth) / 2; - const int recttop = rectbtm + recth; - - LLColor4 rect_color; - - for (int i=1, xpos = 0; i <= nrects; i++) - { - // Calculate color to use for the current rectangle. - if (mIsMuted) - { - rect_color = sColorMuted; - } - else - { - F32 frac = (mPower * i/nrects) / LLVoiceClient::OVERDRIVEN_POWER_LEVEL; - // Use overdriven color if the power exceeds overdriven level. - if (frac > 1.0f) - frac = 1.0f; - rect_color = lerp(sColorNormal, sColorOverdriven, frac); - } + //const int nrects = mIsMuted ? maxrects : llfloor(mPower * maxrects); // how many rects to draw? + //const int rectbtm = (monh - recth) / 2; + //const int recttop = rectbtm + recth; + // + //LLColor4 rect_color; + // + //for (int i=1, xpos = 0; i <= nrects; i++) + //{ + // // Calculate color to use for the current rectangle. + // if (mIsMuted) + // { + // rect_color = sColorMuted; + // } + // else + // { + // F32 frac = (mPower * i/nrects) / LLVoiceClient::OVERDRIVEN_POWER_LEVEL; + // // Use overdriven color if the power exceeds overdriven level. + // if (frac > 1.0f) + // frac = 1.0f; + // rect_color = lerp(sColorNormal, sColorOverdriven, frac); + // } + + // // Draw rectangle filled with the color. + // gl_rect_2d(xpos, recttop, xpos+rectw, rectbtm, rect_color, TRUE); + // xpos += period; + //} - // Draw rectangle filled with the color. - gl_rect_2d(xpos, recttop, xpos+rectw, rectbtm, rect_color, TRUE); - xpos += period; - } - // // Draw bounding box. // diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h index 881ad0f010..98b2fe9dc6 100644 --- a/indra/newview/lloutputmonitorctrl.h +++ b/indra/newview/lloutputmonitorctrl.h @@ -50,14 +50,14 @@ public: struct Params : public LLInitParam::Block { Optional draw_border; + Mandatory image_mute, + image_off, + image_on, + image_level_1, + image_level_2, + image_level_3; - Params() - { - draw_border = true; - name = "output_monitor"; - follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP); - mouse_opaque = false; - }; + Params(); }; protected: bool mBorder; @@ -76,17 +76,28 @@ public: bool getIsMuted() const { return mIsMuted; } void setIsMuted(bool val) { mIsMuted = val; } + // For the current user, need to know the PTT state to show + // correct button image. + void setIsTalking(bool val) { mIsTalking = val; } + private: - static LLColor4 sColorMuted; - static LLColor4 sColorNormal; - static LLColor4 sColorOverdriven; + //static LLColor4 sColorMuted; + //static LLColor4 sColorNormal; + //static LLColor4 sColorOverdriven; static LLColor4 sColorBound; - static S32 sRectsNumber; - static F32 sRectWidthRatio; - static F32 sRectHeightRatio; + //static S32 sRectsNumber; + //static F32 sRectWidthRatio; + //static F32 sRectHeightRatio; F32 mPower; bool mIsMuted; + bool mIsTalking; + LLPointer mImageMute; + LLPointer mImageOff; + LLPointer mImageOn; + LLPointer mImageLevel1; + LLPointer mImageLevel2; + LLPointer mImageLevel3; }; #endif diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index 2ccd729e0a..0eb96f992a 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -41,7 +41,6 @@ #include "llrender.h" #include "llagent.h" #include "llbutton.h" -#include "llchatbar.h" #include "llfocusmgr.h" #include "llimview.h" #include "llmediaremotectrl.h" @@ -49,7 +48,7 @@ #include "lltextbox.h" #include "llui.h" #include "llviewercontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerjoystick.h" #include "llviewermedia.h" #include "llviewermenu.h" // handle_reset_view() @@ -92,12 +91,6 @@ void* LLOverlayBar::createVoiceRemote(void* userdata) return self->mVoiceRemote; } -void* LLOverlayBar::createChatBar(void* userdata) -{ - gChatBar = new LLChatBar(); - return gChatBar; -} - LLOverlayBar::LLOverlayBar() : LLPanel(), mMediaRemote(NULL), @@ -111,7 +104,6 @@ LLOverlayBar::LLOverlayBar() mFactoryMap["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this); mFactoryMap["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this); - mFactoryMap["chat_bar"] = LLCallbackMap(LLOverlayBar::createChatBar, this); LLUICtrlFactory::getInstance()->buildPanel(this, "panel_overlaybar.xml"); } @@ -239,7 +231,7 @@ void LLOverlayBar::refresh() BOOL sitting = FALSE; if (gAgent.getAvatarObject()) { - sitting = gAgent.getAvatarObject()->mIsSitting; + sitting = gAgent.getAvatarObject()->isSitting(); } button = getChild("Stand Up"); diff --git a/indra/newview/lloverlaybar.h b/indra/newview/lloverlaybar.h index f0cf480458..ffdbd96f60 100644 --- a/indra/newview/lloverlaybar.h +++ b/indra/newview/lloverlaybar.h @@ -85,7 +85,6 @@ public: protected: static void* createMediaRemote(void* userdata); static void* createVoiceRemote(void* userdata); - static void* createChatBar(void* userdata); void enableMediaButtons(); diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index d7929cc5c2..91156ae542 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -38,13 +38,13 @@ #include "llavatarconstants.h" #include "llcallingcard.h" #include "llcombobox.h" -#include "llfriendactions.h" +#include "llavataractions.h" #include "llimview.h" #include "lltexteditor.h" #include "lltexturectrl.h" #include "lltooldraganddrop.h" -#include "llviewermenu.h" // *FIX: for is_agent_friend() #include "llscrollcontainer.h" +#include "llweb.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLDropTarget @@ -61,6 +61,7 @@ public: { Optional agent_id; Params() + : agent_id("agent_id") { mouse_opaque(false); follows.flags(FOLLOWS_ALL); @@ -114,7 +115,7 @@ BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, return FALSE; } -static LLDefaultWidgetRegistry::Register r("drop_target"); +static LLDefaultChildRegistry::Register r("drop_target"); ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- @@ -139,7 +140,6 @@ LLPanelProfileTab::LLPanelProfileTab(const Params& params ) LLPanelProfileTab::~LLPanelProfileTab() { - // *TODO Vadim: use notNull() instead. (there are several similar cases below) if(mAvatarId.notNull()) { LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); @@ -165,9 +165,15 @@ void LLPanelProfileTab::setProfileType() mProfileType = (gAgentID == mAvatarId) ? PT_OWN : PT_OTHER; } +void LLPanelProfileTab::onOpen(const LLSD& key) +{ + onActivate(key); +} + void LLPanelProfileTab::onActivate(const LLUUID& id) { setAvatarId(id); + scrollToTop(); updateData(); } @@ -177,7 +183,7 @@ void LLPanelProfileTab::onAddFriend() { std::string name; gCacheName->getFullName(getAvatarId(),name); - LLFriendActions::requestFriendshipDialog(getAvatarId(), name); + LLAvatarActions::requestFriendshipDialog(getAvatarId(), name); } } @@ -195,7 +201,16 @@ void LLPanelProfileTab::onTeleport() { if(getAvatarId().notNull()) { - LLFriendActions::offerTeleport(getAvatarId()); + LLAvatarActions::offerTeleport(getAvatarId()); + } +} + +void LLPanelProfileTab::scrollToTop() +{ + LLScrollContainer* scrollContainer = getChild("profile_scroll", FALSE, FALSE); + if (NULL != scrollContainer) + { + scrollContainer->goToTop(); } } @@ -254,29 +269,35 @@ void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType ty childSetValue("sl_description_edit", avatar_data->about_text); childSetValue("fl_description_edit",avatar_data->fl_about_text); childSetValue("2nd_life_pic", avatar_data->image_id); - childSetValue("1st_life_pic", avatar_data->fl_image_id); + childSetValue("real_world_pic", avatar_data->fl_image_id); childSetValue("homepage_edit", avatar_data->profile_url); if (!isEditMode()) { setCaptionText(avatar_data); - } - childSetValue("show_in_search_checkbox", (BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); - - if (avatar_data->partner_id.notNull()) - { - std::string first, last; - BOOL found = gCacheName->getName(avatar_data->partner_id, first, last); - if (found) + if (avatar_data->partner_id.notNull()) { - childSetTextArg("partner_text", "[FIRST]", first); - childSetTextArg("partner_text", "[LAST]", last); + std::string first, last; + BOOL found = gCacheName->getName(avatar_data->partner_id, first, last); + if (found) + { + childSetTextArg("partner_text", "[FIRST]", first); + childSetTextArg("partner_text", "[LAST]", last); + } + } + else + { + childSetTextArg("partner_text", "[FIRST]", getString("no_partner_text")); } } - //http://secondlife.com/partner + else + { + childSetValue("show_in_search_checkbox", (BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); + } + bool online = avatar_data->flags & AVATAR_ONLINE; - if(is_agent_friend(avatar_data->avatar_id)) + if(LLAvatarActions::isFriend(avatar_data->avatar_id)) { // Online status NO could be because they are hidden // If they are a friend, we may know the truth! @@ -306,6 +327,12 @@ void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType ty } mStatusCombobox->setValue(status); } + if (isOwnProfile()) + { + std::string full_name; + gCacheName->getFullName(mAvatarId, full_name); + childSetValue("user_name", full_name); + } } else if(APT_GROUPS == type) { @@ -313,12 +340,17 @@ void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType ty if(avatar_groups) { std::string groups; - LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); - for(; avatar_groups->group_list.end() != it; ++it) - { + if (!avatar_groups->group_list.empty()) { + LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); LLAvatarGroups::LLGroupData group_data = *it; - groups += group_data.group_name; - groups += ", "; + groups+= group_data.group_name; + while (++it != avatar_groups->group_list.end()) + { + group_data = *it; + groups += ", "; + groups += group_data.group_name; + + } } childSetValue("sl_groups",groups); } @@ -333,7 +365,7 @@ void LLPanelAvatarProfile::clear() void LLPanelAvatarProfile::clearControls() { childSetValue("2nd_life_pic",LLUUID::null); - childSetValue("1st_life_pic",LLUUID::null); + childSetValue("real_world_pic",LLUUID::null); childSetValue("online_status",LLStringUtil::null); childSetValue("status_message",LLStringUtil::null); childSetValue("sl_description_edit",LLStringUtil::null); @@ -438,6 +470,14 @@ void LLPanelAvatarProfile::onShareButtonClick() mStatusMessage->setCommitCallback(boost::bind(&LLPanelAvatarProfile::onStatusMessageChanged, this)); } + if (!isEditMode()) + { + childSetActionTextbox("homepage_edit", boost::bind(&LLPanelAvatarProfile::onHomepageTextboxClicked, this)); + childSetActionTextbox("payment_update_link", boost::bind(&LLPanelAvatarProfile::onUpdateAccountTextboxClicked, this)); + childSetActionTextbox("my_account_link", boost::bind(&LLPanelAvatarProfile::onMyAccountTextboxClicked, this)); + childSetActionTextbox("partner_edit_link", boost::bind(&LLPanelAvatarProfile::onPartnerEditTextboxClicked, this)); + } + childSetCommitCallback("add_friend",(boost::bind(&LLPanelAvatarProfile::onAddFriendButtonClick,this)),NULL); childSetCommitCallback("im",(boost::bind(&LLPanelAvatarProfile::onIMButtonClick,this)),NULL); childSetCommitCallback("call",(boost::bind(&LLPanelAvatarProfile::onCallButtonClick,this)),NULL); @@ -449,7 +489,7 @@ void LLPanelAvatarProfile::onShareButtonClick() { pic->setFallbackImageName("default_land_picture.j2c"); } - pic = getChild("1st_life_pic",TRUE,FALSE); + pic = getChild("real_world_pic",TRUE,FALSE); if(pic) { pic->setFallbackImageName("default_land_picture.j2c"); @@ -460,55 +500,52 @@ void LLPanelAvatarProfile::onShareButtonClick() return TRUE; } + void LLPanelAvatarProfile::onOpen(const LLSD& key) { - setAvatarId(key); - scrollToTop(); + onActivate(key); updateChildrenList(); - updateData(); } -void LLPanelAvatarProfile::scrollToTop() -{ - LLScrollContainer* scrollContainer = getChild("profile_scroll", FALSE, FALSE); - if (NULL != scrollContainer) - { - scrollContainer->goToTop(); - } -} void LLPanelAvatarProfile::updateChildrenList() { - if (mUpdated || isEditMode()) - { - return; - } switch (mProfileType) { case PT_OWN: - childSetVisible("status_panel",FALSE); - childSetVisible("profile_buttons_panel",FALSE); - childSetVisible("title_groups_text",FALSE); - childSetVisible("sl_groups",FALSE); + if (mUpdated || isEditMode()) + { + return; + } + childSetVisible("user_name", true); + childSetVisible("status_panel", false); + childSetVisible("profile_buttons_panel", false); + childSetVisible("title_groups_text", false); + childSetVisible("sl_groups", false); mUpdated = true; - childSetVisible("status_me_panel",TRUE); - childSetVisible("profile_me_buttons_panel",TRUE); + childSetVisible("status_me_panel", true); + childSetVisible("profile_me_buttons_panel", true); break; case PT_OTHER: - childSetVisible("status_me_panel",FALSE); - childSetVisible("profile_me_buttons_panel",FALSE); + childSetVisible("user_name", false); + childSetVisible("status_me_panel", false); + childSetVisible("profile_me_buttons_panel", false); - childSetVisible("status_panel",TRUE); - childSetVisible("profile_buttons_panel",TRUE); - childSetVisible("title_groups_text",TRUE); - childSetVisible("sl_groups",TRUE); + childSetVisible("status_panel", true); + childSetVisible("profile_buttons_panel", true); + childSetVisible("title_groups_text", true); + childSetVisible("sl_groups", true); // account actions - childSetVisible("account_actions_panel", FALSE); - childSetVisible("partner_edit_link", FALSE); + childSetVisible("account_actions_panel", false); + childSetVisible("partner_edit_link", false); - mUpdated = true; + //hide for friends + childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId())); + + //need to update profile view on every activate + mUpdated = false; break; case PT_UNKNOWN: break;//do nothing default: @@ -546,6 +583,31 @@ void LLPanelAvatarProfile::onStatusMessageChanged() updateData(); } +//static +void LLPanelAvatarProfile::onUrlTextboxClicked(std::string url) +{ + LLWeb::loadURL(url); +} + +void LLPanelAvatarProfile::onHomepageTextboxClicked() +{ + onUrlTextboxClicked(childGetValue("homepage_edit").asString()); +} + +void LLPanelAvatarProfile::onUpdateAccountTextboxClicked() +{ + onUrlTextboxClicked(getString("payment_update_link_url")); +} + +void LLPanelAvatarProfile::onMyAccountTextboxClicked() +{ + onUrlTextboxClicked(getString("my_account_link_url")); +} + +void LLPanelAvatarProfile::onPartnerEditTextboxClicked() +{ + onUrlTextboxClicked(getString("partner_edit_link_url")); +} //----------------------------------------------------------------------------- // LLPanelAvatarNotes() @@ -664,3 +726,15 @@ void LLPanelAvatarNotes::processProperties(void* data, EAvatarProcessorType type } } } + +void LLPanelAvatarNotes::onActivate(const LLUUID& id) +{ + LLPanelProfileTab::onActivate(id); + updateChildrenList(); +} + +void LLPanelAvatarNotes::updateChildrenList() +{ + //hide for friends + childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId())); +} diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index f72eb1990d..2b0fbaf193 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -34,37 +34,10 @@ #define LL_LLPANELAVATAR_H #include "llpanel.h" -#include "v3dmath.h" -#include "lluuid.h" -#include "llwebbrowserctrl.h" - #include "llavatarpropertiesprocessor.h" -class LLButton; -class LLCheckBoxCtrl; class LLComboBox; -class LLDropTarget; -class LLInventoryItem; class LLLineEditor; -class LLNameEditor; -class LLPanelAvatar; -class LLScrollListCtrl; -class LLTabContainer; -class LLTextBox; -class LLTextEditor; -class LLTextureCtrl; -class LLUICtrl; -class LLViewerImage; -class LLViewerObject; -class LLMessageSystem; -class LLIconCtrl; -class LLWebBrowserCtrl; -class LLVector3d; -class LLFloaterReg; - -class LLPanelMeProfile; -class LLPanelPick; -class LLAgent; enum EOnlineStatus { @@ -87,7 +60,9 @@ public: const LLUUID& getAvatarId(){return mAvatarId;} virtual void updateData() = 0; - + + virtual void onOpen(const LLSD& key); + virtual void onActivate(const LLUUID& id); typedef enum e_profile_type @@ -109,6 +84,9 @@ protected: virtual ~LLPanelProfileTab(); void setProfileType(); +private: + void scrollToTop(); + protected: e_profile_type mProfileType; LLUUID mAvatarId; @@ -133,17 +111,7 @@ public: virtual void clearControls(); /*virtual*/ BOOL postBuild(void); - void onOpen(const LLSD& key); - - void onAddFriendButtonClick(); - - void onIMButtonClick(); - - void onCallButtonClick(); - - void onTeleportButtonClick(); - - void onShareButtonClick(); + /*virtual*/ void onOpen(const LLSD& key); private: bool isOwnProfile(){return PT_OWN == mProfileType;} @@ -152,7 +120,18 @@ private: void onStatusChanged(); void onStatusMessageChanged(); void setCaptionText(const LLAvatarData* avatar_data); - void scrollToTop(); + + static void onUrlTextboxClicked(std::string url); + void onHomepageTextboxClicked(); + void onUpdateAccountTextboxClicked(); + void onMyAccountTextboxClicked(); + void onPartnerEditTextboxClicked(); + + void onAddFriendButtonClick(); + void onIMButtonClick(); + void onCallButtonClick(); + void onTeleportButtonClick(); + void onShareButtonClick(); protected: @@ -175,6 +154,8 @@ public: static void* create(void* data); + void onActivate(const LLUUID& id); + BOOL postBuild(void); void onCommitRights(); @@ -188,6 +169,8 @@ public: void updateData(); protected: + + void updateChildrenList(); }; diff --git a/indra/newview/llpanelavatartag.cpp b/indra/newview/llpanelavatartag.cpp new file mode 100644 index 0000000000..e66c36287b --- /dev/null +++ b/indra/newview/llpanelavatartag.cpp @@ -0,0 +1,129 @@ +/** + * @file llpanelavatartag.cpp + * @brief Avatar tag panel + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelavatartag.h" + +#include "lluictrlfactory.h" +#include "llavatariconctrl.h" +#include "lltextbox.h" + +LLPanelAvatarTag::LLPanelAvatarTag(const LLUUID& key, const std::string im_time) + : LLPanel() + , mAvatarId(LLUUID::null) +// , mFadeTimer() +{ + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_tag.xml"); + setLeftButtonClickCallback(boost::bind(&LLPanelAvatarTag::onClick, this)); + setAvatarId(key); + setTime(im_time); +} + +LLPanelAvatarTag::~LLPanelAvatarTag() +{ + // Name callbacks will be automatically disconnected since LLPanel is trackable +} + +BOOL LLPanelAvatarTag::postBuild() +{ + mIcon = getChild("avatar_tag_icon"); + mName = getChild("sender_tag_name"); + mTime = getChild("tag_time"); + return TRUE; +} + +void LLPanelAvatarTag::draw() +{ + + ///TODO: ANGELA do something similar to fade the panel out +/* // HACK: assuming tooltip background is in ToolTipBGColor, perform fade out + LLColor4 bg_color = LLUIColorTable::instance().getColor( "ToolTipBgColor" ); + if (tooltip_vis) + { + mToolTipFadeTimer.stop(); + mToolTip->setBackgroundColor(bg_color); + } + else + { + if (!mToolTipFadeTimer.getStarted()) + { + mToolTipFadeTimer.start(); + } + F32 tool_tip_fade_time = gSavedSettings.getF32("ToolTipFadeTime"); + bg_color.mV[VALPHA] = clamp_rescale(mToolTipFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time, bg_color.mV[VALPHA], 0.f); + mToolTip->setBackgroundColor(bg_color); + } + + // above interpolation of bg_color alpha is guaranteed to reach 0.f exactly + mToolTip->setVisible( bg_color.mV[VALPHA] != 0.f ); + */ +} +void LLPanelAvatarTag::setName(const std::string& name) +{ + if (mName) + mName->setText(name); +} + +void LLPanelAvatarTag::setTime(const std::string& time) +{ + if (mTime) + mTime->setText(time); +} + + +void LLPanelAvatarTag::setAvatarId(const LLUUID& avatar_id) +{ + mAvatarId = avatar_id; + if (mIcon) + { + mIcon->setValue(avatar_id); + } + setName(std::string(mIcon->getFirstName()+ " "+ mIcon->getLastName())); +} + +boost::signals2::connection LLPanelAvatarTag::setLeftButtonClickCallback( + const commit_callback_t& cb) +{ + return mCommitSignal.connect(cb); +} + +BOOL LLPanelAvatarTag::handleMouseDown(S32 x, S32 y, MASK mask) +{ + onCommit(); + return TRUE; +} + +void LLPanelAvatarTag::onClick() +{ + // Do the on click stuff. +} diff --git a/indra/newview/llpanelavatartag.h b/indra/newview/llpanelavatartag.h new file mode 100644 index 0000000000..d68b0d7299 --- /dev/null +++ b/indra/newview/llpanelavatartag.h @@ -0,0 +1,93 @@ +/** + * @file llpanelavatartag.h + * @brief Avatar row panel + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELAVATARTAG_H +#define LL_LLPANELAVATARTAG_H + +#include "llpanel.h" +#include "llavatarpropertiesprocessor.h" + +class LLAvatarIconCtrl; +class LLTextBox; + +/** + * Avatar Tag panel. + * + * Test. + * + * Contains avatar name + * Provide methods for setting avatar id, state, muted status and speech power. + */ +class LLPanelAvatarTag : public LLPanel +{ +public: + LLPanelAvatarTag(const LLUUID& key, const std::string im_time); + virtual ~LLPanelAvatarTag(); + + /** + * Set avatar ID. + * + * After the ID is set, it is possible to track the avatar status and get its name. + */ + void setAvatarId(const LLUUID& avatar_id); + void setTime (const std::string& time); + + const LLUUID& getAvatarId() const { return mAvatarId; } + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void draw(); + + virtual boost::signals2::connection setLeftButtonClickCallback( + const commit_callback_t& cb); + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + + void onClick(); +private: + void setName(const std::string& name); + + /** + * Called by LLCacheName when the avatar name gets updated. + */ + void nameUpdatedCallback( + const LLUUID& id, + const std::string& first, + const std::string& last, + BOOL is_group); + + LLAvatarIconCtrl* mIcon; /// status tracking avatar icon + LLTextBox* mName; /// displays avatar name + LLTextBox* mTime; /// displays time + LLUUID mAvatarId; +// LLFrameTimer mFadeTimer; +}; + +#endif diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index c328bcb7f9..42522942f3 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -42,10 +42,12 @@ #include "lldispatcher.h" #include "llfloaterreg.h" #include "llparcel.h" +#include "lltabcontainer.h" #include "message.h" #include "llagent.h" #include "llalertdialog.h" +#include "llavataractions.h" #include "llbutton.h" #include "llcheckboxctrl.h" #include "llclassifiedflags.h" @@ -53,8 +55,6 @@ #include "llcommandhandler.h" // for classified HTML detail page click tracking #include "llviewercontrol.h" #include "lllineeditor.h" -#include "llfloateravatarinfo.h" -#include "llfloaterclassified.h" #include "lltextbox.h" #include "llcombobox.h" #include "llviewertexteditor.h" @@ -931,12 +931,12 @@ bool LLPanelClassified::confirmPublish(const LLSD& notification, const LLSD& res void LLPanelClassified::onClickTeleport(void* data) { LLPanelClassified* self = (LLPanelClassified*)data; - - if (!self->mPosGlobal.isExactlyZero()) + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + + if (!self->mPosGlobal.isExactlyZero()&&worldmap_instance) { - gAgent.teleportViaLocation(self->mPosGlobal); - LLFloaterWorldMap::getInstance()->trackLocation(self->mPosGlobal); - + gAgent.teleportViaLocation(self->mPosGlobal); + worldmap_instance->trackLocation(self->mPosGlobal); self->sendClassifiedClickMessage("teleport"); } } @@ -946,9 +946,12 @@ void LLPanelClassified::onClickTeleport(void* data) void LLPanelClassified::onClickMap(void* data) { LLPanelClassified* self = (LLPanelClassified*)data; - LLFloaterWorldMap::getInstance()->trackLocation(self->mPosGlobal); - LLFloaterReg::showInstance("world_map", "center"); - + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if(worldmap_instance) + { + worldmap_instance->trackLocation(self->mPosGlobal); + LLFloaterReg::showInstance("world_map", "center"); + } self->sendClassifiedClickMessage("map"); } @@ -956,7 +959,7 @@ void LLPanelClassified::onClickMap(void* data) void LLPanelClassified::onClickProfile(void* data) { LLPanelClassified* self = (LLPanelClassified*)data; - LLFloaterAvatarInfo::showFromDirectory(self->mCreatorID); + LLAvatarActions::showProfile(self->mCreatorID); self->sendClassifiedClickMessage("profile"); } @@ -1059,7 +1062,7 @@ void LLPanelClassified::sendClassifiedClickMessage(const std::string& type) //////////////////////////////////////////////////////////////////////////////////////////// LLFloaterPriceForListing::LLFloaterPriceForListing() -: LLFloater(), +: LLFloater(LLSD()), mCallback(NULL), mUserData(NULL) { } @@ -1095,7 +1098,7 @@ void LLFloaterPriceForListing::show( void (*callback)(S32, std::string, void*), LLFloaterPriceForListing *self = new LLFloaterPriceForListing(); // Builds and adds to gFloaterView - LLUICtrlFactory::getInstance()->buildFloater(self, "floater_price_for_listing.xml"); + LLUICtrlFactory::getInstance()->buildFloater(self, "floater_price_for_listing.xml", NULL); self->center(); self->mCallback = callback; diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index b7ec485872..5da646497b 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -193,5 +193,5 @@ void LLPanelContents::onClickNewScript(void *userdata) void LLPanelContents::onClickPermissions(void *userdata) { LLPanelContents* self = (LLPanelContents*)userdata; - gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterBulkPermission::showInstance()); + gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterReg::showInstance("bulk_perms")); } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 2ff22416ec..e9e71644b1 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -411,7 +411,7 @@ void LLPanelFace::getState() { LLUUID get(LLViewerObject* object, S32 te) { - LLViewerImage* image = object->getTEImage(te); + LLViewerTexture* image = object->getTEImage(te); return image ? image->getID() : LLUUID::null; } } func; diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index d495373cc4..b1b464b4e4 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -44,7 +44,7 @@ #include "llcheckboxctrl.h" #include "llcombobox.h" #include "lldbstrings.h" -#include "llfriendactions.h" +#include "llavataractions.h" #include "lllineeditor.h" #include "llnamebox.h" #include "llnamelistctrl.h" @@ -216,8 +216,7 @@ BOOL LLPanelGroupGeneral::postBuild() } mIncompleteMemberDataStr = getString("incomplete_member_data_str"); - mConfirmGroupCreateStr = getString("confirm_group_create_str"); - + // If the group_id is null, then we are creating a new group if (mGroupID.isNull()) { @@ -375,7 +374,7 @@ void LLPanelGroupGeneral::openProfile(void* data) LLScrollListItem* selected = self->mListVisibleMembers->getFirstSelected(); if (selected) { - LLFriendActions::showProfile(selected->getUUID()); + LLAvatarActions::showProfile(selected->getUUID()); } } } @@ -450,9 +449,7 @@ bool LLPanelGroupGeneral::apply(std::string& mesg) return false; } - LLSD args; - args["MESSAGE"] = mConfirmGroupCreateStr; - LLNotifications::instance().add("GenericAlertYesCancel", args, LLSD(), boost::bind(&LLPanelGroupGeneral::createGroupCallback, this, _1, _2)); + LLNotifications::instance().add("CreateGroupCost", LLSD(), LLSD(), boost::bind(&LLPanelGroupGeneral::createGroupCallback, this, _1, _2)); return false; } diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index 5d673d5219..c04b40819d 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -87,7 +87,6 @@ private: BOOL mChanged; BOOL mFirstUse; std::string mIncompleteMemberDataStr; - std::string mConfirmGroupCreateStr; LLUUID mDefaultIconID; // Group information (include any updates in updateChanged) diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index ea092645e7..39a9f231b2 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -247,9 +247,12 @@ void LLPanelGroupLandMoney::impl::onMapButton() F64 global_z = gAgent.getPositionGlobal().mdV[VZ]; LLVector3d pos_global(global_x, global_y, global_z); - LLFloaterWorldMap::getInstance()->trackLocation(pos_global); - - LLFloaterReg::showInstance("world_map", "center"); + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if(worldmap_instance) + { + worldmap_instance->trackLocation(pos_global); + LLFloaterReg::showInstance("world_map", "center"); + } } bool LLPanelGroupLandMoney::impl::applyContribution() diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 201cf5a023..15ae374447 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -39,7 +39,7 @@ #include "llinventory.h" #include "llviewerinventory.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llagent.h" #include "lltooldraganddrop.h" @@ -105,7 +105,7 @@ protected: LLUUID mGroupID; }; -static LLDefaultWidgetRegistry::Register r("group_drop_target"); +static LLDefaultChildRegistry::Register r("group_drop_target"); LLGroupDropTarget::LLGroupDropTarget(const LLGroupDropTarget::Params& p) : LLView(p), @@ -152,6 +152,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, case DAD_BODYPART: case DAD_ANIMATION: case DAD_GESTURE: + case DAD_CALLINGCARD: { LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; if(gInventory.getItem(inv_item->getUUID()) @@ -175,7 +176,6 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, break; } case DAD_CATEGORY: - case DAD_CALLINGCARD: default: *accept = ACCEPT_NO; break; diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 9e537be425..50e1f84cad 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -37,7 +37,7 @@ #include "llagent.h" #include "llbutton.h" #include "llfloatergroupinvite.h" -#include "llfriendactions.h" +#include "llavataractions.h" #include "lliconctrl.h" #include "lllineeditor.h" #include "llnamelistctrl.h" @@ -49,7 +49,7 @@ #include "lltabcontainer.h" #include "lltextbox.h" #include "lltexteditor.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llfocusmgr.h" @@ -144,17 +144,22 @@ BOOL LLPanelGroupRoles::postBuild() if (!mSubTabContainer) return FALSE; // Hook up each sub-tabs callback and widgets. - S32 i; - for (i = 0; i < mSubTabContainer->getTabCount(); ++i) + for (S32 i = 0; i < mSubTabContainer->getTabCount(); ++i) { - LLPanelGroupSubTab* subtabp = (LLPanelGroupSubTab*) mSubTabContainer->getPanelByIndex(i); - + LLPanel* panel = mSubTabContainer->getPanelByIndex(i); + LLPanelGroupSubTab* subtabp = dynamic_cast(panel); + if (!subtabp) + { + llwarns << "Invalid subtab panel: " << panel->getName() << llendl; + return FALSE; + } // Add click callbacks to all the tabs. mSubTabContainer->setCommitCallback(boost::bind(&LLPanelGroupRoles::handleClickSubTab, this)); // Hand the subtab a pointer to this LLPanelGroupRoles, so that it can // look around for the widgets it is interested in. - if (!subtabp->postBuildSubTab(this)) return FALSE; + if (!subtabp->postBuildSubTab(this)) + return FALSE; subtabp->addObserver(this); } @@ -1289,7 +1294,7 @@ void LLPanelGroupMembersSubTab::handleMemberDoubleClick() LLScrollListItem* selected = mMembersList->getFirstSelected(); if (selected) { - LLFriendActions::showProfile(selected->getUUID()); + LLAvatarActions::showProfile(selected->getUUID()); } } @@ -1711,7 +1716,18 @@ void* LLPanelGroupRolesSubTab::createTab(void* data) } LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab(const LLUUID& group_id) -: LLPanelGroupSubTab(group_id), mHasRoleChange(FALSE) + : LLPanelGroupSubTab(group_id), + mRolesList(NULL), + mAssignedMembersList(NULL), + mAllowedActionsList(NULL), + mRoleName(NULL), + mRoleTitle(NULL), + mRoleDescription(NULL), + mMemberVisibleCheck(NULL), + mDeleteRoleButton(NULL), + mCreateRoleButton(NULL), + + mHasRoleChange(FALSE) { } diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp new file mode 100644 index 0000000000..45fe625a13 --- /dev/null +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -0,0 +1,87 @@ +/** + * @file llpanelavatar.cpp + * @brief LLPanelAvatar and related class implementations + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelimcontrolpanel.h" + +#include "llavataractions.h" +#include "llavatariconctrl.h" +#include "llbutton.h" + +static LLRegisterPanelClassWrapper t_im_control_panel("panel_im_control_panel"); + +LLPanelIMControlPanel::LLPanelIMControlPanel() +: LLPanel() +{ +} + +LLPanelIMControlPanel::~LLPanelIMControlPanel() +{ +} + +BOOL LLPanelIMControlPanel::postBuild() +{ + childSetAction("view_profile_btn", boost::bind(&LLPanelIMControlPanel::onViewProfileButtonClicked, this)); + childSetAction("add_friend_btn", boost::bind(&LLPanelIMControlPanel::onAddFriendButtonClicked, this)); + childSetAction("call_btn", boost::bind(&LLPanelIMControlPanel::onCallButtonClicked, this)); + childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this)); + + return TRUE; +} + +void LLPanelIMControlPanel::onViewProfileButtonClicked() +{ + LLAvatarActions::showProfile(getChild("avatar_icon")->getAvatarId()); +} + +void LLPanelIMControlPanel::onAddFriendButtonClicked() +{ + LLAvatarIconCtrl* avatar_icon = getChild("avatar_icon"); + std::string full_name = avatar_icon->getFirstName() + " " + avatar_icon->getLastName(); + LLAvatarActions::requestFriendshipDialog(avatar_icon->getAvatarId(), full_name); +} + +void LLPanelIMControlPanel::onCallButtonClicked() +{ + // *TODO: Implement +} + +void LLPanelIMControlPanel::onShareButtonClicked() +{ + // *TODO: Implement +} + +void LLPanelIMControlPanel::setAvatarId(const LLUUID& avatar_id) +{ + getChild("avatar_icon")->setValue(avatar_id); +} diff --git a/indra/newview/llfloaterevent.h b/indra/newview/llpanelimcontrolpanel.h similarity index 61% rename from indra/newview/llfloaterevent.h rename to indra/newview/llpanelimcontrolpanel.h index 563ecc49da..be3b2d3130 100644 --- a/indra/newview/llfloaterevent.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -1,12 +1,10 @@ /** - * @file llfloaterevent.h - * @brief Event information as shown in a floating window from - * secondlife:// command handler. - * Just a wrapper for LLPanelEvent. + * @file llpanelimcontrolpanel.h + * @brief LLPanelIMControlPanel and related class definitions * - * $LicenseInfo:firstyear=2007&license=viewergpl$ + * $LicenseInfo:firstyear=2004&license=viewergpl$ * - * Copyright (c) 2007-2009, Linden Research, Inc. + * Copyright (c) 2004-2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -32,29 +30,26 @@ * $/LicenseInfo$ */ -#ifndef LL_LLFLOATEREVENT_H -#define LL_LLFLOATEREVENT_H +#ifndef LL_LLPANELIMCONTROLPANEL_H +#define LL_LLPANELIMCONTROLPANEL_H -#include "llfloater.h" +#include "llpanel.h" -class LLPanelEvent; - -class LLFloaterEventInfo : public LLFloater +class LLPanelIMControlPanel : public LLPanel { public: - LLFloaterEventInfo( const U32 event_id ); - /*virtual*/ ~LLFloaterEventInfo(); + LLPanelIMControlPanel(); + ~LLPanelIMControlPanel(); - void displayEventInfo(const U32 event_id); + BOOL postBuild(); - static LLFloaterEventInfo* show(const U32 event_id); - - static void* createEventDetail(void* userdata); + void setAvatarId(const LLUUID& avatar_id); private: - U32 mEventID; // for which event is this window? - LLPanelEvent* mPanelEventp; - + void onViewProfileButtonClicked(); + void onAddFriendButtonClicked(); + void onCallButtonClicked(); + void onShareButtonClicked(); }; -#endif // LL_LLFLOATEREVENT_H +#endif // LL_LLPANELIMCONTROLPANEL_H diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp index 92fe082ef2..bce5525a40 100644 --- a/indra/newview/llpanelland.cpp +++ b/indra/newview/llpanelland.cpp @@ -40,6 +40,7 @@ #include "llbutton.h" #include "llcheckboxctrl.h" #include "llfloaterland.h" +#include "llfloaterreg.h" #include "lltextbox.h" #include "llviewercontrol.h" #include "llviewerparcelmgr.h" @@ -262,7 +263,7 @@ void LLPanelLandInfo::onClickAbout(void*) LLViewerParcelMgr::getInstance()->selectParcelInRectangle(); } - LLFloaterLand::showInstance(); + LLFloaterReg::showInstance("about_land"); } void LLPanelLandInfo::onShowOwnersHelp(void* user_data) diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 24b4082630..7bf7ceb6d2 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -31,12 +31,15 @@ #include "llviewerprecompiledheaders.h" +#include "llpanellandmarks.h" + +#include "llbutton.h" #include "llfloaterreg.h" #include "lllandmark.h" #include "llfloaterworldmap.h" +#include "llfoldervieweventlistener.h" #include "lllandmarklist.h" -#include "llpanellandmarks.h" #include "llsidetray.h" #include "lltabcontainer.h" #include "llworldmap.h" @@ -138,9 +141,10 @@ void LLLandmarksPanel::onShowOnMap() if (!landmark->getGlobalPos(landmark_global_pos)) return; - if (!landmark_global_pos.isExactlyZero()) + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if (!landmark_global_pos.isExactlyZero() && worldmap_instance) { - LLFloaterWorldMap::getInstance()->trackLocation(landmark_global_pos); + worldmap_instance->trackLocation(landmark_global_pos); LLFloaterReg::showInstance("world_map", "center"); } } @@ -157,8 +161,6 @@ void LLLandmarksPanel::onTeleport() { listenerp->openItem(); } - - togglePanelPlacesButtons(TRUE); } /* @@ -195,6 +197,28 @@ void LLLandmarksPanel::onCopySLURL() } */ +// virtual +void LLLandmarksPanel::updateVerbs() +{ + if (!isTabVisible()) + return; + + BOOL enabled = FALSE; + + LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem(); + if (current_item) + { + LLFolderViewEventListener* listenerp = current_item->getListener(); + if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) + { + enabled = TRUE; + } + } + + mTeleportBtn->setEnabled(enabled); + mShowOnMapBtn->setEnabled(enabled); +} + void LLLandmarksPanel::onSelectionChange(const std::deque &items, BOOL user_action) { LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem(); @@ -224,16 +248,14 @@ void LLLandmarksPanel::onSelectionChange(const std::deque &it if (!mActionBtn->getVisible()) mActionBtn->setVisible(TRUE); - - togglePanelPlacesButtons(TRUE); } else { if (mActionBtn->getVisible()) mActionBtn->setVisible(FALSE); - - togglePanelPlacesButtons(FALSE); } + + updateVerbs(); } void LLLandmarksPanel::onSelectorButtonClicked() @@ -244,9 +266,14 @@ void LLLandmarksPanel::onSelectorButtonClicked() if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) { LLSD key; - key["type"] = LLPanelPlaces::LANDMARK; + key["type"] = "landmark"; key["id"] = listenerp->getUUID(); LLSideTray::getInstance()->showPanel("panel_places", key); } } + +void LLLandmarksPanel::setSelectedItem(const LLUUID& obj_id) +{ + mInventoryPanel->setSelection(obj_id, FALSE); +} diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 0f400a722e..0b11270fb5 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -33,7 +33,7 @@ #ifndef LL_LLPANELLANDMARKS_H #define LL_LLPANELLANDMARKS_H -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llinventorymodel.h" #include "llpanelplacestab.h" @@ -48,9 +48,11 @@ public: /*virtual*/ void onShowOnMap(); /*virtual*/ void onTeleport(); ///*virtual*/ void onCopySLURL(); + /*virtual*/ void updateVerbs(); void onSelectionChange(const std::deque &items, BOOL user_action); void onSelectorButtonClicked(); + void setSelectedItem(const LLUUID& obj_id); private: LLInventoryPanel* mInventoryPanel; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 7af1cbf51f..7007bfc9d5 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -57,7 +57,7 @@ #include "lluiconstants.h" #include "llurlsimstring.h" #include "llviewerbuild.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewermenu.h" // for handle_preferences() #include "llviewernetwork.h" #include "llviewerwindow.h" // to link into child list @@ -362,7 +362,7 @@ LLPanelLogin::~LLPanelLogin() gResponsePtr->setParent( 0 ); //// We know we're done with the image, so be rid of it. - //gImageList.deleteImage( mLogoImage ); + //gTextureList.deleteImage( mLogoImage ); } // virtual @@ -431,8 +431,14 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask) # if !LL_RELEASE_FOR_DOWNLOAD if ( KEY_F2 == key ) { - llinfos << "Spawning floater TOS window" << llendl; - LLFloaterTOS::show(LLFloaterTOS::TOS_TOS,"", NULL); + llinfos << "Spawning floater TOS window (TOS)" << llendl; + LLFloaterReg::showInstance("message_tos",LLSD("")); + return TRUE; + } + if ( KEY_F3 == key ) + { + llinfos << "Spawning floater TOS window (critical message)" << llendl; + LLFloaterReg::showInstance("message_critical",LLSD("")); return TRUE; } #endif @@ -635,7 +641,12 @@ void LLPanelLogin::refreshLocation( bool force_visible ) BOOL show_start = TRUE; if ( ! force_visible ) - show_start = gSavedSettings.getBOOL("ShowStartLocation"); + { + // Don't show on first run after install + // Otherwise ShowStartLocation defaults to true. + show_start = gSavedSettings.getBOOL("ShowStartLocation") + && !gSavedSettings.getBOOL("FirstRunThisInstall"); + } sInstance->childSetVisible("start_location_combo", show_start); sInstance->childSetVisible("start_location_text", show_start); @@ -792,7 +803,8 @@ void LLPanelLogin::loadLoginPage() { oStr << "&auto_login=TRUE"; } - if (gSavedSettings.getBOOL("ShowStartLocation")) + if (gSavedSettings.getBOOL("ShowStartLocation") + && !gSavedSettings.getBOOL("FirstRunThisInstall")) { oStr << "&show_start_location=TRUE"; } diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 540f938053..83a31eecda 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -37,6 +37,7 @@ #include "llpointer.h" // LLPointer<> #include "llwebbrowserctrl.h" // LLWebBrowserCtrlObserver +class LLLineEditor; class LLUIImage; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 1d7a2748cc..9be2fb12d2 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -35,7 +35,7 @@ // libs #include "llfloaterreg.h" #include "llmenugl.h" -#include "llsearcheditor.h" +#include "llfiltereditor.h" #include "lltabcontainer.h" #include "lluictrlfactory.h" @@ -47,7 +47,7 @@ #include "llcallingcard.h" // for LLAvatarTracker #include "llfloateravatarpicker.h" #include "llfloaterminiinspector.h" -#include "llfriendactions.h" +#include "llavataractions.h" #include "llgroupactions.h" #include "llgrouplist.h" #include "llrecentpeople.h" @@ -62,10 +62,18 @@ using namespace LLOldEvents; #define NEARBY_LIST_UPDATE_INTERVAL 1 #define RECENT_LIST_UPDATE_DELAY 1 +static const std::string NEARBY_TAB_NAME = "nearby_panel"; +static const std::string FRIENDS_TAB_NAME = "friends_panel"; +static const std::string GROUP_TAB_NAME = "groups_panel"; +static const std::string RECENT_TAB_NAME = "recent_panel"; + static LLRegisterPanelClassWrapper t_people("panel_people"); //============================================================================= +/** + * Updates given list either on regular basis or on external events (up to implementation). + */ class LLPanelPeople::Updater { public: @@ -74,15 +82,31 @@ public: : mCallback(cb) { } + virtual ~Updater() { } + + /** + * Force the list updates. + * + * This may start repeated updates until all names are complete. + */ + virtual void forceUpdate() {} + + /** + * Activate/deactivate updater. + * + * This may start/stop regular updates. + */ virtual void setActive(bool) {} + protected: bool updateList(U32 mask = 0) { return mCallback(mask); } + callback_t mCallback; }; @@ -99,10 +123,13 @@ public: /** * Updates the friends list. + * + * Updates the list on external events which trigger the changed() method. */ class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver { LOG_CLASS(LLFriendListUpdater); + public: LLFriendListUpdater(callback_t cb) : LLAvatarListUpdater(cb, FRIEND_LIST_UPDATE_TIMEOUT) @@ -111,20 +138,20 @@ public: // For notification when SIP online status changes. LLVoiceClient::getInstance()->addObserver(this); } + ~LLFriendListUpdater() { LLVoiceClient::getInstance()->removeObserver(this); LLAvatarTracker::instance().removeObserver(this); } - /*virtual*/ void setActive(bool val) - { - if (!val) - return; + /*virtual*/ void forceUpdate() + { // Perform updates until all names are loaded. if (!updateList(LLFriendObserver::ADD)) changed(LLFriendObserver::ADD); } + /*virtual*/ void changed(U32 mask) { // events can arrive quickly in bulk - we need not process EVERY one of them - @@ -134,6 +161,7 @@ public: // save-up all the mask-bits which have come-in mMask |= mask; } + /*virtual*/ BOOL tick() { if (updateList(mMask)) @@ -145,33 +173,33 @@ public: return FALSE; } + private: U32 mMask; }; /** * Periodically updates the nearby people list while the Nearby tab is active. + * + * The period is defined by NEARBY_LIST_UPDATE_INTERVAL constant. */ class LLNearbyListUpdater : public LLAvatarListUpdater { LOG_CLASS(LLNearbyListUpdater); + public: LLNearbyListUpdater(callback_t cb) : LLAvatarListUpdater(cb, NEARBY_LIST_UPDATE_INTERVAL) { setActive(false); } - /*virtual*/ BOOL tick() - { - updateList(); - return FALSE; - } + /*virtual*/ void setActive(bool val) { if (val) { // update immediately and start regular updates - tick(); + updateList(); mEventTimer.start(); } else @@ -180,6 +208,17 @@ public: mEventTimer.stop(); } } + + /*virtual*/ void forceUpdate() + { + updateList(); + } + + /*virtual*/ BOOL tick() + { + updateList(); + return FALSE; + } private: }; @@ -189,13 +228,20 @@ private: class LLRecentListUpdater : public LLAvatarListUpdater { LOG_CLASS(LLRecentListUpdater); + public: LLRecentListUpdater(callback_t cb) : LLAvatarListUpdater(cb, RECENT_LIST_UPDATE_DELAY) { LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::onRecentPeopleChanged, this)); } + private: + /*virtual*/ void forceUpdate() + { + onRecentPeopleChanged(); + } + /*virtual*/ BOOL tick() { // Update the list until we get all the names. @@ -207,6 +253,7 @@ private: return FALSE; } + void onRecentPeopleChanged() { if (!updateList()) @@ -223,16 +270,24 @@ private: class LLGroupListUpdater : public LLPanelPeople::Updater, public LLSimpleListener { LOG_CLASS(LLGroupListUpdater); + public: LLGroupListUpdater(callback_t cb) : LLPanelPeople::Updater(cb) { gAgent.addListener(this, "new group"); } + ~LLGroupListUpdater() { gAgent.removeListener(this); } + + /*virtual*/ void forceUpdate() + { + updateList(); + } + /*virtual*/ bool handleEvent(LLPointer event, const LLSD& userdata) { // Why is "new group" sufficient? @@ -251,7 +306,7 @@ public: LLPanelPeople::LLPanelPeople() : LLPanel(), mFilterSubString(LLStringUtil::null), - mSearchEditor(NULL), + mFilterEditor(NULL), mTabContainer(NULL), mFriendList(NULL), mNearbyList(NULL), @@ -271,28 +326,30 @@ LLPanelPeople::~LLPanelPeople() delete mGroupListUpdater; LLView::deleteViewByHandle(mGroupPlusMenuHandle); - LLView::deleteViewByHandle(mGroupMinusMenuHandle); } BOOL LLPanelPeople::postBuild() { - mSearchEditor = getChild("filter_input"); + mVisibleSignal.connect(boost::bind(&LLPanelPeople::onVisibilityChange, this, _2)); + + mFilterEditor = getChild("filter_input"); + mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); mTabContainer = getChild("tabs"); mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2)); - mTabContainer->selectTabByName("friends_panel"); // must go after setting commit callback + mTabContainer->selectTabByName(FRIENDS_TAB_NAME); // must go after setting commit callback - mFriendList = getChild("friends_panel")->getChild("avatar_list"); - mNearbyList = getChild("nearby_panel")->getChild("avatar_list"); - mRecentList = getChild("recent_panel")->getChild("avatar_list"); + mFriendList = getChild(FRIENDS_TAB_NAME)->getChild("avatar_list"); + mNearbyList = getChild(NEARBY_TAB_NAME)->getChild("avatar_list"); + mRecentList = getChild(RECENT_TAB_NAME)->getChild("avatar_list"); mGroupList = getChild("group_list"); - LLPanel* groups_panel = getChild("groups_panel"); + LLPanel* groups_panel = getChild(GROUP_TAB_NAME); groups_panel->childSetAction("activate_btn", boost::bind(&LLPanelPeople::onActivateButtonClicked, this)); groups_panel->childSetAction("plus_btn", boost::bind(&LLPanelPeople::onGroupPlusButtonClicked, this)); groups_panel->childSetAction("minus_btn", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked, this)); - LLPanel* friends_panel = getChild("friends_panel"); + LLPanel* friends_panel = getChild(FRIENDS_TAB_NAME); friends_panel->childSetAction("add_btn", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this)); friends_panel->childSetAction("del_btn", boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked, this)); @@ -319,89 +376,95 @@ BOOL LLPanelPeople::postBuild() // Create menus. LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("People.Group.Plus.Action", boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked, this, _2)); - LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile("menu_group_plus.xml", gMenuHolder); + LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile("menu_group_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mGroupPlusMenuHandle = plus_menu->getHandle(); - registrar.add("People.Group.Minus.Action", boost::bind(&LLPanelPeople::onGroupMinusMenuItemClicked, this, _2)); - LLMenuGL* minus_menu = LLUICtrlFactory::getInstance()->createFromFile("menu_group_minus.xml", gMenuHolder); - mGroupMinusMenuHandle = minus_menu->getHandle(); // Perform initial update. - mFriendListUpdater->setActive(true); + mFriendListUpdater->forceUpdate(); updateGroupList(); updateRecentList(); return TRUE; } -bool LLPanelPeople::refreshFriendNames(U32 changed_mask) +bool LLPanelPeople::updateFriendList(U32 changed_mask) { - // get all buddies we know about - LLAvatarTracker::buddy_map_t all_buddies; - LLAvatarTracker::instance().copyBuddyList(all_buddies); - - bool have_names = true; - + // Refresh names. if (changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE)) { + // get all buddies we know about + LLAvatarTracker::buddy_map_t all_buddies; + LLAvatarTracker::instance().copyBuddyList(all_buddies); + // *TODO: it's suboptimal to rebuild the whole list on online status change. // convert the buddy map to vector - std::vector avatar_ids; + mFriendVec.clear(); LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin(); for (; buddy_it != all_buddies.end(); ++buddy_it) - avatar_ids.push_back(buddy_it->first); + mFriendVec.push_back(buddy_it->first); - // do refresh the friend list - if (avatar_ids.size() > 0) - have_names = mFriendList->updateList(avatar_ids); - else - mFriendList->setCommentText(getString("no_friends")); + return filterFriendList(); } - return have_names; -} - -bool LLPanelPeople::updateFriendList(U32 changed_mask) -{ - // Refresh names. - if (changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE)) - { - return refreshFriendNames(changed_mask); - } - return true; } bool LLPanelPeople::updateNearbyList() { - std::vector avatar_ids; - - LLWorld::getInstance()->getAvatars(&avatar_ids, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange")); - - mNearbyList->updateList(avatar_ids); - - if (avatar_ids.size() == 0) - mNearbyList->setCommentText(getString("no_one_near")); + LLWorld::getInstance()->getAvatars(&mNearbyVec, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange")); + filterNearbyList(); return true; } bool LLPanelPeople::updateRecentList() { - std::vector avatar_ids; + LLRecentPeople::instance().get(mRecentVec); + filterRecentList(); - LLRecentPeople::instance().get(avatar_ids); - - if (avatar_ids.size() > 0) - return mRecentList->updateList(avatar_ids); - - mRecentList->setCommentText(getString("no_people")); return true; } bool LLPanelPeople::updateGroupList() { - return mGroupList->updateList(); + bool have_names = mGroupList->update(mFilterSubString); + + if (mGroupList->isEmpty()) + mGroupList->setCommentText(getString("no_groups")); + + return have_names; +} + +bool LLPanelPeople::filterFriendList() +{ + // We must always update Friends list to clear the latest removed friend. + bool have_names = mFriendList->update(mFriendVec, mFilterSubString); + + if (mFriendVec.size() == 0) + mFriendList->setCommentText(getString("no_friends")); + + return have_names; +} + +bool LLPanelPeople::filterNearbyList() +{ + bool have_names = mNearbyList->update(mNearbyVec, mFilterSubString); + + if (mNearbyVec.size() == 0) + mNearbyList->setCommentText(getString("no_one_near")); + + return have_names; +} + +bool LLPanelPeople::filterRecentList() +{ + if (mRecentVec.size() > 0) + return mRecentList->update(mRecentVec, mFilterSubString); + + mRecentList->setCommentText(getString("no_people")); + + return true; } void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible) @@ -433,10 +496,10 @@ void LLPanelPeople::buttonSetAction(const std::string& btn_name, const commit_si void LLPanelPeople::updateButtons() { std::string cur_tab = mTabContainer->getCurrentPanel()->getName(); - bool nearby_tab_active = (cur_tab == "nearby_panel"); - bool friends_tab_active = (cur_tab == "friends_panel"); - bool group_tab_active = (cur_tab == "groups_panel"); - bool recent_tab_active = (cur_tab == "recent_panel"); + bool nearby_tab_active = (cur_tab == NEARBY_TAB_NAME); + bool friends_tab_active = (cur_tab == FRIENDS_TAB_NAME); + bool group_tab_active = (cur_tab == GROUP_TAB_NAME); + bool recent_tab_active = (cur_tab == RECENT_TAB_NAME); LLUUID selected_id; buttonSetVisible("group_info_btn", group_tab_active); @@ -449,17 +512,19 @@ void LLPanelPeople::updateButtons() if (group_tab_active) { + bool item_selected = mGroupList->getFirstSelected() != NULL; bool cur_group_active = true; - selected_id = mGroupList->getCurrentID(); - if (selected_id.notNull()) + if (item_selected) + { + selected_id = mGroupList->getCurrentID(); cur_group_active = (gAgent.getGroupID() == selected_id); - - bool item_selected = selected_id.notNull(); + } + LLPanel* groups_panel = mTabContainer->getCurrentPanel(); - groups_panel->childSetEnabled("activate_btn", !item_selected || !cur_group_active); // "none" or a non-active group selected + groups_panel->childSetEnabled("activate_btn", item_selected && !cur_group_active); // "none" or a non-active group selected groups_panel->childSetEnabled("plus_btn", item_selected); - groups_panel->childSetEnabled("minus_btn", item_selected); + groups_panel->childSetEnabled("minus_btn", item_selected && selected_id.notNull()); } else { @@ -476,7 +541,7 @@ void LLPanelPeople::updateButtons() } bool item_selected = selected_id.notNull(); - buttonSetEnabled("teleport_btn", friends_tab_active && item_selected); + buttonSetEnabled("teleport_btn", (friends_tab_active || group_tab_active) && item_selected); buttonSetEnabled("view_profile_btn", item_selected); buttonSetEnabled("im_btn", item_selected); buttonSetEnabled("call_btn", item_selected && false); // not implemented yet @@ -489,11 +554,11 @@ LLAvatarList* LLPanelPeople::getActiveAvatarList() const { std::string cur_tab = mTabContainer->getCurrentPanel()->getName(); - if (cur_tab == "friends_panel") + if (cur_tab == FRIENDS_TAB_NAME) return mFriendList; - if (cur_tab == "nearby_panel") + if (cur_tab == NEARBY_TAB_NAME) return mNearbyList; - if (cur_tab == "recent_panel") + if (cur_tab == RECENT_TAB_NAME) return mRecentList; return NULL; @@ -526,39 +591,52 @@ void LLPanelPeople::showGroupMenu(LLMenuGL* menu) LLMenuGL::showPopup(parent_panel, menu, menu_x, menu_y); } -void LLPanelPeople::onVisibilityChange(BOOL new_visibility) +void LLPanelPeople::onVisibilityChange(const LLSD& new_visibility) { - if (new_visibility == FALSE) + if (new_visibility.asBoolean() == FALSE) { // Don't update anything while we're invisible. mNearbyListUpdater->setActive(FALSE); } else { - // Make the tab-container re-select current tab - // for onTabSelected() callback to get called. - // (currently this is needed to reactivate nearby list updates - // when we get visible) - mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex()); + reSelectedCurrentTab(); } } -void LLPanelPeople::onSearchEdit(const std::string& search_string) +// Make the tab-container re-select current tab +// for onTabSelected() callback to get called. +// (currently this is needed to reactivate nearby list updates +// when we get visible) +void LLPanelPeople::reSelectedCurrentTab() +{ + mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex()); +} + +void LLPanelPeople::onFilterEdit(const std::string& search_string) { if (mFilterSubString == search_string) return; mFilterSubString = search_string; + // Searches are case-insensitive LLStringUtil::toUpper(mFilterSubString); LLStringUtil::trimHead(mFilterSubString); - mSearchEditor->setText(mFilterSubString); + + // Apply new filter to all tabs. + filterNearbyList(); + filterFriendList(); + filterRecentList(); + updateGroupList(); + + updateButtons(); } void LLPanelPeople::onTabSelected(const LLSD& param) { std::string tab_name = getChild(param.asString())->getName(); - mNearbyListUpdater->setActive(tab_name == "nearby_panel"); + mNearbyListUpdater->setActive(tab_name == NEARBY_TAB_NAME); updateButtons(); } @@ -583,7 +661,7 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list) void LLPanelPeople::onViewProfileButtonClicked() { LLUUID id = getCurrentItemID(); - LLFriendActions::showProfile(id); + LLAvatarActions::showProfile(id); } void LLPanelPeople::onAddFriendButtonClicked() @@ -593,7 +671,7 @@ void LLPanelPeople::onAddFriendButtonClicked() { std::string name; gCacheName->getFullName(id, name); - LLFriendActions::requestFriendshipDialog(id, name); + LLAvatarActions::requestFriendshipDialog(id, name); } } @@ -610,7 +688,7 @@ void LLPanelPeople::onAddFriendWizButtonClicked() void LLPanelPeople::onDeleteFriendButtonClicked() { - LLFriendActions::removeFriendDialog(getCurrentItemID()); + LLAvatarActions::removeFriendDialog(getCurrentItemID()); } void LLPanelPeople::onGroupInfoButtonClicked() @@ -632,7 +710,7 @@ void LLPanelPeople::onImButtonClicked() LLUUID id = getCurrentItemID(); if (id.notNull()) { - LLFriendActions::startIM(id); + LLAvatarActions::startIM(id); } } @@ -648,7 +726,7 @@ void LLPanelPeople::onAvatarPicked( void*) { if (!names.empty() && !ids.empty()) - LLFriendActions::requestFriendshipDialog(ids[0], names[0]); + LLAvatarActions::requestFriendshipDialog(ids[0], names[0]); } bool LLPanelPeople::onFriendListUpdate(U32 changed_mask) @@ -673,11 +751,9 @@ void LLPanelPeople::onGroupPlusButtonClicked() void LLPanelPeople::onGroupMinusButtonClicked() { - LLMenuGL* minus_menu = (LLMenuGL*)mGroupMinusMenuHandle.get(); - if (!minus_menu) - return; - - showGroupMenu(minus_menu); + LLUUID group_id = getCurrentItemID(); + if (group_id.notNull()) + LLGroupActions::leave(group_id); } void LLPanelPeople::onGroupPlusMenuItemClicked(const LLSD& userdata) @@ -690,19 +766,6 @@ void LLPanelPeople::onGroupPlusMenuItemClicked(const LLSD& userdata) LLGroupActions::create(); } -void LLPanelPeople::onGroupMinusMenuItemClicked(const LLSD& userdata) -{ - std::string chosen_item = userdata.asString(); - - LLUUID group_id = getCurrentItemID(); - if (chosen_item == "leave_group") - LLGroupActions::leave(group_id); - /* - else if (chosen_item == "delete_group") - ; // *TODO: how to delete a group? - */ -} - void LLPanelPeople::onCallButtonClicked() { // *TODO: not implemented yet @@ -710,7 +773,16 @@ void LLPanelPeople::onCallButtonClicked() void LLPanelPeople::onTeleportButtonClicked() { - LLFriendActions::offerTeleport(getCurrentItemID()); + std::string cur_tab = mTabContainer->getCurrentPanel()->getName(); + + if (cur_tab == FRIENDS_TAB_NAME) + { + LLAvatarActions::offerTeleport(getCurrentItemID()); + } + else if (cur_tab == GROUP_TAB_NAME) + { + LLGroupActions::offerTeleport(getCurrentItemID()); + } } void LLPanelPeople::onShareButtonClicked() @@ -725,5 +797,10 @@ void LLPanelPeople::onMoreButtonClicked() void LLPanelPeople::onOpen(const LLSD& key) { - mTabContainer->selectTab(key.asInteger()); + std::string tab_name = key["people_panel_tab_name"]; + if (!tab_name.empty()) + mTabContainer->selectTabByName(tab_name); + else + reSelectedCurrentTab(); } + diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 4d535f287c..58ed77f0f2 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -37,7 +37,7 @@ #include "llcallingcard.h" // for avatar tracker -class LLSearchEditor; +class LLFilterEditor; class LLTabContainer; class LLAvatarList; class LLGroupList; @@ -61,8 +61,10 @@ private: bool updateNearbyList(); bool updateRecentList(); bool updateGroupList(); + bool filterFriendList(); + bool filterNearbyList(); + bool filterRecentList(); void updateButtons(); - bool refreshFriendNames(U32 changed_mask); LLAvatarList* getActiveAvatarList() const; LLUUID getCurrentItemID() const; void buttonSetVisible(std::string btn_name, BOOL visible); @@ -70,10 +72,12 @@ private: void buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb); void showGroupMenu(LLMenuGL* menu); - /*virtual*/ void onVisibilityChange(BOOL new_visibility); + void onVisibilityChange( const LLSD& new_visibility); + + void reSelectedCurrentTab(); // UI callbacks - void onSearchEdit(const std::string& search_string); + void onFilterEdit(const std::string& search_string); void onTabSelected(const LLSD& param); void onViewProfileButtonClicked(); void onAddFriendButtonClicked(); @@ -92,7 +96,6 @@ private: void onGroupPlusButtonClicked(); void onGroupMinusButtonClicked(); void onGroupPlusMenuItemClicked(const LLSD& userdata); - void onGroupMinusMenuItemClicked(const LLSD& userdata); // misc callbacks bool onFriendListUpdate(U32 changed_mask); @@ -101,7 +104,7 @@ private: const std::vector& ids, void*); - LLSearchEditor* mSearchEditor; + LLFilterEditor* mFilterEditor; LLTabContainer* mTabContainer; LLAvatarList* mFriendList; LLAvatarList* mNearbyList; @@ -109,7 +112,6 @@ private: LLGroupList* mGroupList; LLHandle mGroupPlusMenuHandle; - LLHandle mGroupMinusMenuHandle; Updater* mFriendListUpdater; Updater* mNearbyListUpdater; @@ -117,6 +119,17 @@ private: Updater* mGroupListUpdater; std::string mFilterSubString; + + // The vectors below contain up-to date avatar lists + // for the corresponding tabs. + // When the user enters a filter, it gets applied + // to all the vectors and the result is shown in the tabs. + // We don't need to have such a vector for the groups tab + // since re-fetching the groups list is always fast. + typedef std::vector uuid_vector_t; + uuid_vector_t mNearbyVec; + uuid_vector_t mFriendVec; + uuid_vector_t mRecentVec; }; #endif //LL_LLPANELPEOPLE_H diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 9fdde9e757..19aef93d7e 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -53,16 +53,17 @@ #include "llagent.h" #include "llstatusbar.h" // for getBalance() #include "lllineeditor.h" -#include "llradiogroup.h" #include "llcombobox.h" #include "lluiconstants.h" #include "lldbstrings.h" #include "llfloatergroupinfo.h" #include "llfloatergroups.h" -#include "llfriendactions.h" +#include "llfloaterreg.h" +#include "llavataractions.h" #include "llnamebox.h" #include "llviewercontrol.h" #include "lluictrlfactory.h" +#include "llspinctrl.h" #include "roles_constants.h" ///---------------------------------------------------------------------------- @@ -100,6 +101,8 @@ BOOL LLPanelPermissions::postBuild() childSetCommitCallback("checkbox for sale",LLPanelPermissions::onCommitSaleInfo,this); childSetCommitCallback("sale type",LLPanelPermissions::onCommitSaleType,this); + + childSetCommitCallback("Edit Cost", LLPanelPermissions::onCommitSaleInfo, this); childSetCommitCallback("checkbox next owner can modify",LLPanelPermissions::onCommitNextOwnerModify,this); childSetCommitCallback("checkbox next owner can copy",LLPanelPermissions::onCommitNextOwnerCopy,this); @@ -208,12 +211,9 @@ void LLPanelPermissions::refresh() childSetValue("search_check", FALSE); childSetEnabled("search_check", false); - LLRadioGroup* RadioSaleType = getChild("sale type"); - if(RadioSaleType) - { - RadioSaleType->setSelectedIndex(-1); - RadioSaleType->setEnabled(FALSE); - } + LLComboBox* combo_sale_type = getChild("sale type"); + combo_sale_type->setValue(LLSaleInfo::FS_COPY); + combo_sale_type->setEnabled(FALSE); childSetEnabled("Cost",false); childSetText("Cost",getString("Cost Default")); @@ -417,22 +417,22 @@ void LLPanelPermissions::refresh() childSetText("Cost",getString("Cost Default")); } - LLLineEditor *editPrice = getChild("Edit Cost"); - if(keyboard_focus_view != editPrice) + LLSpinCtrl *edit_price = getChild("Edit Cost"); + if(!edit_price->hasFocus()) { // If the sale price is mixed then set the cost to MIXED, otherwise // set to the actual cost. if (num_for_sale > 0 && is_for_sale_mixed) { - childSetText("Edit Cost",getString("Sale Mixed")); + edit_price->setTentative(TRUE); } else if (num_for_sale > 0 && is_sale_price_mixed) { - childSetText("Edit Cost",getString("Cost Mixed")); + edit_price->setTentative(TRUE); } else { - childSetText("Edit Cost",llformat("%d",individual_sale_price)); + edit_price->setValue(individual_sale_price); } } // The edit fields are only enabled if you can sell this object @@ -742,20 +742,17 @@ void LLPanelPermissions::refresh() BOOL valid_sale_info = LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info); LLSaleInfo::EForSale sale_type = sale_info.getSaleType(); - LLRadioGroup* RadioSaleType = getChild("sale type"); - if(RadioSaleType) + LLComboBox* combo_sale_type = getChild("sale type"); + if (valid_sale_info) { - if (valid_sale_info) - { - RadioSaleType->setSelectedIndex((S32)sale_type - 1); - RadioSaleType->setTentative(FALSE); // unfortunately this doesn't do anything at the moment. - } - else - { - // default option is sell copy, determined to be safest - RadioSaleType->setSelectedIndex((S32)LLSaleInfo::FS_COPY - 1); - RadioSaleType->setTentative(TRUE); // unfortunately this doesn't do anything at the moment. - } + combo_sale_type->setValue(sale_type == LLSaleInfo::FS_NOT ? LLSaleInfo::FS_COPY : sale_type); + combo_sale_type->setTentative(FALSE); // unfortunately this doesn't do anything at the moment. + } + else + { + // default option is sell copy, determined to be safest + combo_sale_type->setValue(LLSaleInfo::FS_COPY); + combo_sale_type->setTentative(TRUE); // unfortunately this doesn't do anything at the moment. } childSetValue("checkbox for sale", num_for_sale != 0); @@ -811,7 +808,7 @@ void LLPanelPermissions::onClickCreator(void *data) { LLPanelPermissions *self = (LLPanelPermissions *)data; - LLFriendActions::showProfile(self->mCreatorID); + LLAvatarActions::showProfile(self->mCreatorID); } // static @@ -827,7 +824,7 @@ void LLPanelPermissions::onClickOwner(void *data) } else { - LLFriendActions::showProfile(self->mOwnerID); + LLAvatarActions::showProfile(self->mOwnerID); } } @@ -840,15 +837,17 @@ void LLPanelPermissions::onClickGroup() if(owners_identical && (owner_id == gAgent.getID())) { - LLFloaterGroupPicker* fg; - fg = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); - fg->setSelectGroupCallback( boost::bind(&LLPanelPermissions::cbGroupID, this, _1) ); - - if (parent_floater) + LLFloaterGroupPicker* fg = LLFloaterReg::showTypedInstance("group_picker", LLSD(gAgent.getID())); + if (fg) { - LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg); - fg->setOrigin(new_rect.mLeft, new_rect.mBottom); - parent_floater->addDependentFloater(fg); + fg->setSelectGroupCallback( boost::bind(&LLPanelPermissions::cbGroupID, this, _1) ); + + if (parent_floater) + { + LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg); + fg->setOrigin(new_rect.mLeft, new_rect.mBottom); + parent_floater->addDependentFloater(fg); + } } } } @@ -991,44 +990,14 @@ void LLPanelPermissions::setAllSaleInfo() // Set the sale type if the object(s) are for sale. if(checkPurchase && checkPurchase->get()) { - LLRadioGroup* RadioSaleType = getChild("sale type"); - if(RadioSaleType) - { - switch(RadioSaleType->getSelectedIndex()) - { - case 0: - sale_type = LLSaleInfo::FS_ORIGINAL; - break; - case 1: - sale_type = LLSaleInfo::FS_COPY; - break; - case 2: - sale_type = LLSaleInfo::FS_CONTENTS; - break; - default: - sale_type = LLSaleInfo::FS_COPY; - break; - } - } + sale_type = static_cast(getChild("sale type")->getValue().asInteger()); } S32 price = -1; - LLLineEditor *editPrice = getChild("Edit Cost"); - if (editPrice) - { - // Don't extract the price if it's labeled as MIXED or is empty. - const std::string& editPriceString = editPrice->getText(); - if (editPriceString != getString("Cost Mixed") && editPriceString != getString("Sale Mixed") && - !editPriceString.empty()) - { - price = atoi(editPriceString.c_str()); - } - else - { - price = DEFAULT_PRICE; - } - } + LLSpinCtrl *edit_price = getChild("Edit Cost"); + price = (edit_price->getTentative()) ? DEFAULT_PRICE : edit_price->getValue().asInteger(); + // If somehow an invalid price, turn the sale off. if (price < 0) sale_type = LLSaleInfo::FS_NOT; diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index 65be4718ef..cda1a9e7e7 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -38,13 +38,16 @@ #include "llpanel.h" #include "message.h" #include "llagent.h" +#include "llbutton.h" #include "llparcel.h" #include "llviewerparcelmgr.h" #include "lltexturectrl.h" #include "lluiconstants.h" +#include "llworldmap.h" +#include "llfloaterworldmap.h" +#include "llfloaterreg.h" #include "llavatarpropertiesprocessor.h" #include "llpanelpick.h" -#include "llpanelmeprofile.h" #define XML_PANEL_EDIT_PICK "panel_edit_pick.xml" @@ -55,6 +58,12 @@ #define XML_SNAPSHOT "pick_snapshot" #define XML_LOCATION "pick_location" +#define XML_BTN_SAVE "save_changes_btn" + +#define SAVE_BTN_LABEL "[WHAT]" +#define LABEL_PICK = "Pick" +#define LABEL_CHANGES = "Changes" + LLPanelPick::LLPanelPick(BOOL edit_mode/* = FALSE */) : LLPanel(), LLAvatarPropertiesObserver(), @@ -78,15 +87,27 @@ LLPanelPick::LLPanelPick(BOOL edit_mode/* = FALSE */) LLPanelPick::~LLPanelPick() { - if (!mCreatorId.isNull()) LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorId, this); + if (mCreatorId.notNull()) LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorId, this); } void LLPanelPick::reset() { + setEditMode(FALSE); + mPickId.setNull(); mCreatorId.setNull(); mParcelId.setNull(); + setPickName(""); + setPickDesc(""); + setPickLocation(""); + mSnapshotCtrl->setImageAssetID(LLUUID::null); + + //*HACK just setting asset id to NULL not enough to clear + //the texture controls, w/o setValid(FALSE) it continues to + //draw the previously set image + mSnapshotCtrl->setValid(FALSE); + mDataReceived = FALSE; mPosGlobal.clearVec(); @@ -98,17 +119,24 @@ BOOL LLPanelPick::postBuild() if (mEditMode) { - childSetAction("cancel_btn", onClickCancel, this); - childSetAction("set_to_curr_location_btn", onClickSet, this); - childSetAction("save_changes_btn", onClickSave, this); + childSetAction("cancel_btn", boost::bind(&LLPanelPick::onClickCancel, this)); + childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPick::onClickSet, this)); + childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPick::onClickSave, this)); + + mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPick::childSetVisible, this, "edit_icon", true)); + mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPick::childSetVisible, this, "edit_icon", false)); } else { - childSetAction("edit_btn", onClickEdit, this); - childSetAction("teleport_btn", onClickTeleport, this); - childSetAction("show_on_map_btn", onClickMap, this); - childSetAction("back_btn", onClickBack, this); - //*TODO set on menu + childSetAction("edit_btn", boost::bind(&LLPanelPick::onClickEdit, this)); + childSetAction("teleport_btn", boost::bind(&LLPanelPick::onClickTeleport, this)); + childSetAction("show_on_map_btn", boost::bind(&LLPanelPick::onClickMap, this)); + + if (!mBackCb.empty()) + { + LLButton* button = findChild("back_btn"); + if (button) button->setClickedCallback(mBackCb); + } } return TRUE; @@ -119,21 +147,15 @@ void LLPanelPick::init(LLUUID creator_id, LLUUID pick_id) mCreatorId = creator_id; mPickId = pick_id; - // on Pick Info panel (for non-Agent picks) edit_btn should be invisible - if (!mEditMode) - { - if (mCreatorId != gAgentID) - { - childSetEnabled("edit_btn", FALSE); - childSetVisible("edit_btn", FALSE); - } - else - { - childSetEnabled("edit_btn", TRUE); - childSetVisible("edit_btn", TRUE); - } - } + //*TODO consider removing this, already called by setEditMode() + updateButtons(); + requestData(); +} + +void LLPanelPick::requestData() +{ + mDataReceived = FALSE; LLAvatarPropertiesProcessor::instance().addObserver(mCreatorId, this); LLAvatarPropertiesProcessor::instance().sendDataRequest(mCreatorId, APT_PICK_INFO, &mPickId); } @@ -143,11 +165,14 @@ void LLPanelPick::init(LLPickData *pick_data) mPickId = pick_data->pick_id; mCreatorId = pick_data->creator_id; - setName(pick_data->name); - setDesc(pick_data->desc); - setLocation(pick_data->location_text); + setPickName(pick_data->name); + setPickDesc(pick_data->desc); + setPickLocation(pick_data->location_text); mSnapshotCtrl->setImageAssetID(pick_data->snapshot_id); + //*HACK see reset() where the texture control was set to FALSE + mSnapshotCtrl->setValid(TRUE); + mPosGlobal = pick_data->pos_global; mSimName = pick_data->sim_name; mParcelId = pick_data->parcel_id; @@ -164,12 +189,14 @@ void LLPanelPick::createNewPick() LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (parcel) { - setName(parcel->getName()); - setDesc(parcel->getDesc()); + setPickName(parcel->getName()); + setPickDesc(parcel->getDesc()); mSnapshotCtrl->setImageAssetID(parcel->getSnapshotID()); } sendUpdate(); + + childSetLabelArg(XML_BTN_SAVE, SAVE_BTN_LABEL, std::string("Pick")); } /*virtual*/ void LLPanelPick::processProperties(void* data, EAvatarProcessorType type) @@ -183,7 +210,7 @@ void LLPanelPick::createNewPick() init(pick_data); mDataReceived = TRUE; - LLAvatarPropertiesProcessor::instance().removeObserver(gAgentID, this); + LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorId, this); } @@ -192,47 +219,36 @@ void LLPanelPick::setEditMode( BOOL edit_mode ) if (mEditMode == edit_mode) return; mEditMode = edit_mode; + // preserve data before killing controls + LLUUID snapshot_id = mSnapshotCtrl->getImageAssetID(); + LLRect old_rect = getRect(); + + deleteAllChildren(); + if (edit_mode) { - // preserve data before killing controls - std::string name = getName(); - std::string desc = getDesc(); - std::string location = getLocation(); - LLUUID snapshot_id = mSnapshotCtrl->getImageAssetID(); - LLRect old_rect = getRect(); - - deleteAllChildren(); - LLUICtrlFactory::getInstance()->buildPanel(this, XML_PANEL_EDIT_PICK); - - //*NOTE this code is from LLPanelMeProfile.togglePanel()... doubt this is a right way to do things - reshape(old_rect.getWidth(), old_rect.getHeight()); - old_rect.setLeftTopAndSize(0, old_rect.getHeight(), old_rect.getWidth(), old_rect.getHeight()); - setRect(old_rect); - - // time to restore data - setName(name); - setDesc(desc); - setLocation(location); - mSnapshotCtrl->setImageAssetID(snapshot_id); } else { - // returning to VIEW mode - need to perform cleanup - // this is the case when that panel is reused between viewing/editing different picks - deleteAllChildren(); - reset(); LLUICtrlFactory::getInstance()->buildPanel(this, XML_PANEL_PICK_INFO); } + + //*NOTE this code is from LLPanelMeProfile.togglePanel()... doubt this is a right way to do things + reshape(old_rect.getWidth(), old_rect.getHeight()); + old_rect.setLeftTopAndSize(0, old_rect.getHeight(), old_rect.getWidth(), old_rect.getHeight()); + setRect(old_rect); + + // time to restore data + setPickName(mName); + setPickDesc(mDesc); + setPickLocation(mLocation); + mSnapshotCtrl->setImageAssetID(snapshot_id); + + updateButtons(); } -//*HACK need to be redone - control panel toggling from parent (Me Panel/Avatar Profile Panel) -void LLPanelPick::setPanelMeProfile(LLPanelMeProfile* meProfilePanel) -{ - mMeProfilePanel = meProfilePanel; -} - -void LLPanelPick::setName(std::string name) +void LLPanelPick::setPickName(std::string name) { if (mEditMode) { @@ -242,9 +258,12 @@ void LLPanelPick::setName(std::string name) { childSetWrappedText(XML_NAME, name); } + + //preserving non-wrapped text for info/edit modes switching + mName = name; } -void LLPanelPick::setDesc(std::string desc) +void LLPanelPick::setPickDesc(std::string desc) { if (mEditMode) { @@ -254,24 +273,30 @@ void LLPanelPick::setDesc(std::string desc) { childSetWrappedText(XML_DESC, desc); } + + //preserving non-wrapped text for info/edit modes switching + mDesc = desc; } -void LLPanelPick::setLocation(std::string location) +void LLPanelPick::setPickLocation(std::string location) { childSetWrappedText(XML_LOCATION, location); + + //preserving non-wrapped text for info/edit modes switching + mLocation = location; } -std::string LLPanelPick::getName() +std::string LLPanelPick::getPickName() { return childGetValue(XML_NAME).asString(); } -std::string LLPanelPick::getDesc() +std::string LLPanelPick::getPickDesc() { return childGetValue(XML_DESC).asString(); } -std::string LLPanelPick::getLocation() +std::string LLPanelPick::getPickLocation() { return childGetValue(XML_LOCATION).asString(); } @@ -292,13 +317,16 @@ void LLPanelPick::sendUpdate() //legacy var need to be deleted pick_data.top_pick = FALSE; pick_data.parcel_id = mParcelId; - pick_data.name = getName(); - pick_data.desc = getDesc(); + pick_data.name = getPickName(); + pick_data.desc = getPickDesc(); pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID(); pick_data.pos_global = mPosGlobal; pick_data.sort_order = 0; pick_data.enabled = TRUE; + mDataReceived = FALSE; + LLAvatarPropertiesProcessor::instance().addObserver(gAgentID, this); + LLAvatarPropertiesProcessor::instance().sendDataUpdate(&pick_data, APT_PICK_INFO); } @@ -308,85 +336,117 @@ void LLPanelPick::sendUpdate() //----------------------------------------- //static -void LLPanelPick::onClickEdit(void* data) +void LLPanelPick::onClickEdit() { - LLPanelPick* self = (LLPanelPick*)data; - if (!self) return; - if (self->mEditMode) return; - if (!self->mDataReceived) return; - - self->setEditMode(TRUE); + if (mEditMode) return; + if (!mDataReceived) return; + setEditMode(TRUE); } //static -void LLPanelPick::onClickTeleport(void* data) +void LLPanelPick::onClickTeleport() { - //LLPanelPick* self = (LLPanelPick*)data; - //*TODO implement + teleport(mPosGlobal); } //static -void LLPanelPick::onClickMap(void* data) +void LLPanelPick::onClickMap() { - //LLPanelPick* self = (LLPanelPick*)data; - //*TODO implement + showOnMap(mPosGlobal); } -//*HACK need to move panel toggling to parent panels -//static -void LLPanelPick::onClickBack(void* data) -{ - LLPanelPick* self = (LLPanelPick*)data; - if (!self) return; - self->mMeProfilePanel->togglePanel(self); -} - - //----------------------------------------- // "EDIT PICK" (EDIT MODE) BUTTON HANDLERS //----------------------------------------- //static -void LLPanelPick::onClickCancel(void* data) +void LLPanelPick::onClickCancel() { - LLPanelPick* self = (LLPanelPick*) data; - if (!self) return; - if (!self->mEditMode) return; - self->mMeProfilePanel->togglePanel(self); + if (!mEditMode) return; + + LLUUID pick_id = mPickId; + LLUUID creator_id = mCreatorId; + reset(); + init(creator_id, pick_id); } // static -void LLPanelPick::onClickSet(void* data) +void LLPanelPick::onClickSet() { - //TODO check whether pick data was received before - - LLPanelPick* self = (LLPanelPick*) data; - if (!self) return; - if (!self->mEditMode) return; + if (!mEditMode) return; + if (!mDataReceived) return; // Save location for later. - self->mPosGlobal = gAgent.getPositionGlobal(); + mPosGlobal = gAgent.getPositionGlobal(); - S32 region_x = llround((F32)self->mPosGlobal.mdV[VX]) % REGION_WIDTH_UNITS; - S32 region_y = llround((F32)self->mPosGlobal.mdV[VY]) % REGION_WIDTH_UNITS; - S32 region_z = llround((F32)self->mPosGlobal.mdV[VZ]); + S32 region_x = llround((F32)mPosGlobal.mdV[VX]) % REGION_WIDTH_UNITS; + S32 region_y = llround((F32)mPosGlobal.mdV[VY]) % REGION_WIDTH_UNITS; + S32 region_z = llround((F32)mPosGlobal.mdV[VZ]); std::string location_text = "(will update after save), "; - location_text.append(self->mSimName); + location_text.append(mSimName); location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z)); - self->setLocation(location_text); + setPickLocation(location_text); } // static -void LLPanelPick::onClickSave(void* data) +void LLPanelPick::onClickSave() { - LLPanelPick* self = (LLPanelPick*)data; - if (!self->mEditMode) return; - if (!self->mDataReceived) return; + if (!mEditMode) return; + if (!mDataReceived) return; - //*TODO check if data was received before - self->sendUpdate(); - self->mMeProfilePanel->togglePanel(self); + sendUpdate(); + setEditMode(FALSE); +} + +void LLPanelPick::updateButtons() +{ + + // on Pick Info panel (for non-Agent picks) edit_btn should be invisible + if (mEditMode) + { + childSetLabelArg(XML_BTN_SAVE, SAVE_BTN_LABEL, std::string("Changes")); + } + else + { + if (mCreatorId != gAgentID) + { + childSetEnabled("edit_btn", FALSE); + childSetVisible("edit_btn", FALSE); + } + else + { + childSetEnabled("edit_btn", TRUE); + childSetVisible("edit_btn", TRUE); + } + } +} + +void LLPanelPick::setExitCallback(commit_callback_t cb) +{ + mBackCb = cb; + if (!mEditMode) + { + LLButton* button = findChild("back_btn"); + if (button) button->setClickedCallback(mBackCb); + } +} + +//static +void LLPanelPick::teleport(const LLVector3d& position) +{ + if (!position.isExactlyZero()) + { + gAgent.teleportViaLocation(position); + LLFloaterWorldMap::getInstance()->trackLocation(position); + } +} + +//static +void LLPanelPick::showOnMap(const LLVector3d& position) +{ + LLFloaterWorldMap::getInstance()->trackLocation(position); + LLFloaterReg::showInstance("world_map", "center"); } diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h index 8ada1a39fb..15b0d6c541 100644 --- a/indra/newview/llpanelpick.h +++ b/indra/newview/llpanelpick.h @@ -41,7 +41,6 @@ class LLTextureCtrl; class LLMessageSystem; -class LLPanelMeProfile; class LLAvatarPropertiesObserver; class LLPanelPick : public LLPanel, public LLAvatarPropertiesObserver @@ -51,6 +50,7 @@ public: LLPanelPick(BOOL edit_mode = FALSE); /*virtual*/ ~LLPanelPick(); + // switches the panel to the VIEW mode and resets controls void reset(); /*virtual*/ BOOL postBuild(); @@ -59,47 +59,61 @@ public: // initial position, etc. void createNewPick(); + //initializes the panel with data of the pick with id = pick_id + //owned by the avatar with id = creator_id void init(LLUUID creator_id, LLUUID pick_id); /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); + // switches the panel to either View or Edit mode void setEditMode(BOOL edit_mode); - //TODO redo panel toggling - void setPanelMeProfile(LLPanelMeProfile* meProfilePanel); + // because this panel works in two modes (edit/view) we are + // free from managing two panel for editing and viewing picks and so + // are free from controlling switching between them in the parent panel (e.g. Me Profile) + // but that causes such a complication that we cannot set a callback for a "Back" button + // from the parent panel only once, so we have to preserve that callback + // in the pick panel and set it for the back button everytime postBuild() is called. + void setExitCallback(commit_callback_t cb); + + static void teleport(const LLVector3d& position); + static void showOnMap(const LLVector3d& position); + protected: - void setName(std::string name); - void setDesc(std::string desc); - void setLocation(std::string location); + void setPickName(std::string name); + void setPickDesc(std::string desc); + void setPickLocation(std::string location); - std::string getName(); - std::string getDesc(); - std::string getLocation(); + std::string getPickName(); + std::string getPickDesc(); + std::string getPickLocation(); void sendUpdate(); + void requestData(); + void init(LLPickData *pick_data); + void updateButtons(); + //----------------------------------------- // "PICK INFO" (VIEW MODE) BUTTON HANDLERS //----------------------------------------- - static void onClickEdit(void* data); - static void onClickTeleport(void* data); - static void onClickMap(void* data); - static void onClickBack(void* data); + void onClickEdit(); + void onClickTeleport(); + void onClickMap(); //----------------------------------------- // "EDIT PICK" (EDIT MODE) BUTTON HANDLERS //----------------------------------------- - static void onClickSet(void* data); - static void onClickSave(void* data); - static void onClickCancel(void* data); + void onClickSet(); + void onClickSave(); + void onClickCancel(); protected: BOOL mEditMode; LLTextureCtrl* mSnapshotCtrl; - BOOL mDataRequested; BOOL mDataReceived; LLUUID mPickId; @@ -108,8 +122,12 @@ protected: LLUUID mParcelId; std::string mSimName; - //TODO redo panel toggling - LLPanelMeProfile* mMeProfilePanel; + //These strings are used to keep non-wrapped text + std::string mName; + std::string mDesc; + std::string mLocation; + + commit_callback_t mBackCb; }; #endif // LL_LLPANELPICK_H diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index 1a3aa8a33a..e8d6ff9ec9 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -36,37 +36,43 @@ #include "llavatarconstants.h" #include "lltexturectrl.h" #include "llviewergenericmessage.h" // send_generic_message -#include "llworldmap.h" -#include "llfloaterworldmap.h" -#include "llpanelmeprofile.h" -#include "llfloaterreg.h" +#include "llmenugl.h" +#include "llviewermenu.h" +#include "llregistry.h" + #include "llpanelpicks.h" #include "llavatarpropertiesprocessor.h" +#include "llpanelavatar.h" +#include "llpanelprofile.h" #include "llpanelpick.h" +#include "llscrollcontainer.h" -#define XML_BTN_NEW "new_btn" -#define XML_BTN_DELETE "trash_btn" -#define XML_BTN_INFO "info_btn" +static const std::string XML_BTN_NEW = "new_btn"; +static const std::string XML_BTN_DELETE = "trash_btn"; +static const std::string XML_BTN_INFO = "info_btn"; +static const std::string XML_BTN_TELEPORT = "teleport_btn"; +static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn"; + +static const std::string XML_PICKS_LIST = "back_panel"; + +#define PICK_ITEMS_BETWEEN 5 //----------------------------------------------------------------------------- // LLPanelPicks //----------------------------------------------------------------------------- -LLPanelPicks::LLPanelPicks(const LLUUID& avatar_id /* = LLUUID::null */) -:LLPanelProfileTab(avatar_id), mMeProfilePanel(NULL) +LLPanelPicks::LLPanelPicks() +: LLPanelProfileTab(LLUUID::null), + mPopupMenu(NULL), + mSelectedPickItem(NULL), + mProfilePanel(NULL), + mPickPanel(NULL) { - updateData(); -} - -LLPanelPicks::LLPanelPicks(const Params& params) -:LLPanelProfileTab(params), mMeProfilePanel(NULL) -{ - } LLPanelPicks::~LLPanelPicks() { - if(!getAvatarId().isNull()) + if(getAvatarId().notNull()) { LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); } @@ -74,12 +80,6 @@ LLPanelPicks::~LLPanelPicks() void* LLPanelPicks::create(void* data /* = NULL */) { - LLSD* id = NULL; - if(data) - { - id = static_cast(data); - return new LLPanelPicks(LLUUID(id->asUUID())); - } return new LLPanelPicks(); } @@ -99,8 +99,13 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type) gCacheName->getName(getAvatarId(),name,second_name); childSetTextArg("pick_title", "[NAME]",name); - LLView* picks_list = getChild("back_panel",TRUE,FALSE); + LLView* picks_list = getPicksList(); if(!picks_list) return; + + // to restore selection of the same item later + LLUUID pick_id_selected(LLUUID::null); + if (mSelectedPickItem) pick_id_selected = mSelectedPickItem->getPickId(); + clear(); //*TODO move it somewhere else? @@ -108,13 +113,9 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type) childSetEnabled(XML_BTN_NEW, false); childSetEnabled(XML_BTN_DELETE, false); childSetEnabled(XML_BTN_INFO, false); + childSetEnabled(XML_BTN_TELEPORT,!avatar_picks->picks_list.empty()); + childSetEnabled(XML_BTN_SHOW_ON_MAP,!avatar_picks->picks_list.empty()); - S32 height = avatar_picks->picks_list.size() * 85; - LLRect rc = picks_list->getRect(); - rc.setLeftTopAndSize(rc.mLeft,rc.mTop,rc.getWidth(),height); - picks_list->setRect(rc); - picks_list->reshape(rc.getWidth(),rc.getHeight()); - LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin(); for(; avatar_picks->picks_list.end() != it; ++it) { @@ -122,32 +123,26 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type) std::string pick_name = it->second; LLPickItem* picture = LLPickItem::create(); + picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this)); + picks_list->addChild(picture); - picture->setPictureName(pick_name); - picture->setPictureId(pick_id); + picture->setPickName(pick_name); + picture->setPickId(pick_id); picture->setCreatorId(getAvatarId()); - S32 last_bottom = picks_list->getRect().getHeight(); - if(mPickItemList.size() > 0) - { - last_bottom = mPickItemList[mPickItemList.size()-1]->getRect().mBottom; - last_bottom -= 5; - } - LLRect rc = picture->getRect(); - rc.mBottom = last_bottom - rc.getHeight(); - rc.mTop = last_bottom; - picture->reshape(rc.getWidth(),rc.getHeight()); - picture->setRect(rc); - - LLAvatarPropertiesProcessor::instance().addObserver(mAvatarId, picture); picture->update(); mPickItemList.push_back(picture); + if (pick_id_selected != LLUUID::null && + pick_id == pick_id_selected) setSelectedPickItem(picture); } + + reshapePicksList(); LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); updateButtons(); + if (!mSelectedPickItem && mPickItemList.size()) setSelectedPickItem(mPickItemList.back()); picks_list->setEnabled(TRUE); } @@ -156,7 +151,7 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type) void LLPanelPicks::clear() { - LLView* scroll = getChild("back_panel",TRUE,FALSE); + LLView* scroll = getPicksList(); if(scroll) { picture_list_t::const_iterator it = mPickItemList.begin(); @@ -167,27 +162,110 @@ void LLPanelPicks::clear() } } mPickItemList.clear(); + mSelectedPickItem = NULL; } -BOOL LLPanelPicks::postBuild(void) -{ - childSetAction(XML_BTN_INFO, onClickInfo, this); - childSetAction(XML_BTN_NEW, onClickNew, this); - childSetAction(XML_BTN_DELETE, onClickDelete, this); - childSetAction("teleport_btn", onClickTeleport, this); - childSetAction("show_on_map_btn", onClickMap, this); +LLPickItem* LLPanelPicks::getSelectedPickItem() +{ + return mSelectedPickItem; +} + + +void LLPanelPicks::removePickItem( LLPickItem* pick_item ) +{ + LLView* scroll = getPicksList(); + scroll->removeChild(pick_item); + mPickItemList.remove(pick_item); + if (mPickItemList.size() == 0) + { + mSelectedPickItem = NULL; + } + else + { + setSelectedPickItem(mPickItemList.back()); + } + + reshapePicksList(); +} + +void LLPanelPicks::reshapePicksList() +{ + if (!mPickItemList.size()) return; + LLView* pickList = getPicksList(); + + S32 last_bottom = pickList->getRect().getHeight(); + child_list_const_iter_t child_it, child_first_it = pickList->getChildList()->begin(); + for ( child_it = child_first_it; child_it != pickList->getChildList()->end(); ++child_it) + { + LLView* const childp = *child_it; + if(child_it != child_first_it) + { + last_bottom -= childp->getRect().getHeight(); + last_bottom -= PICK_ITEMS_BETWEEN; + } + reshapePickItem(childp, last_bottom,pickList->getRect().getWidth()); + } + + S32 height = pickList->getChildCount() * ((*child_first_it)->getRect().getHeight() + PICK_ITEMS_BETWEEN); + LLRect rc = pickList->getRect(); + rc.setLeftTopAndSize(rc.mLeft, rc.mTop, rc.getWidth(), height); + pickList->reshape(rc.getWidth(), rc.getHeight()); + pickList->setRect(rc); +} + +void LLPanelPicks::reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth) +{ + LLRect rc = pick_item->getRect(); + rc.mBottom = last_bottom - rc.getHeight(); + rc.mTop = last_bottom; + pick_item->setRect(rc); + pick_item->reshape(newWidth, rc.getHeight()); +} + +LLView* LLPanelPicks::getPicksList() const +{ + return getChild(XML_PICKS_LIST, TRUE, FALSE); +} + +BOOL LLPanelPicks::postBuild() +{ + childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this)); + + childSetAction("teleport_btn", boost::bind(&LLPanelPicks::onClickTeleport, this)); + childSetAction("show_on_map_btn", boost::bind(&LLPanelPicks::onClickMap, this)); + + childSetAction("info_btn", boost::bind(&LLPanelPicks::onClickInfo, this)); + childSetAction("new_btn", boost::bind(&LLPanelPicks::onClickNew, this)); + + CommitCallbackRegistry::ScopedRegistrar registar; + registar.add("Pick.Info", boost::bind(&LLPanelPicks::onClickInfo, this)); + registar.add("Pick.Edit", boost::bind(&LLPanelPicks::onClickMenuEdit, this)); + registar.add("Pick.Teleport", boost::bind(&LLPanelPicks::onClickTeleport, this)); + registar.add("Pick.Map", boost::bind(&LLPanelPicks::onClickMap, this)); + registar.add("Pick.Delete", boost::bind(&LLPanelPicks::onClickDelete, this)); + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + return TRUE; } -void LLPanelPicks::onActivate(const LLUUID& id) +void LLPanelPicks::onOpen(const LLSD& key) { + const LLUUID id(key.asUUID()); BOOL self = (gAgent.getID() == id); // only agent can edit her picks childSetEnabled("edit_panel", self); childSetVisible("edit_panel", self); + // Disable buttons when viewing profile for first time + if(getAvatarId() != id) + { + childSetEnabled(XML_BTN_INFO,FALSE); + childSetEnabled(XML_BTN_TELEPORT,FALSE); + childSetEnabled(XML_BTN_SHOW_ON_MAP,FALSE); + } + // and see a special title - set as invisible by default in xml file if (self) { @@ -195,144 +273,99 @@ void LLPanelPicks::onActivate(const LLUUID& id) childSetVisible("pick_title_agent", self); } - LLPanelProfileTab::onActivate(id); -} - - -//static -void LLPanelPicks::onClickInfo(void *data) -{ - LLPanelPicks* self = (LLPanelPicks*) data; - if (self) - { - LLPanelPick* panel_pick_info = new LLPanelPick(); - - //*TODO redo, use the selected pick from List View, but not the first (last) one - LLView* scroll = self->getChild("back_panel", TRUE, FALSE); - LLPickItem* pick = static_cast(scroll->getFirstChild()); - if (!pick) return; - - panel_pick_info->init(pick->getCreatorId(), pick->getPickId()); - - //*HACK redo toggling of panels (should work on both "profiles") - if (self->mMeProfilePanel) - { - panel_pick_info->setPanelMeProfile(self->mMeProfilePanel); - //self->mMeProfilePanel->addChildInBack(panel_pick_info); - self->mMeProfilePanel->togglePanel(panel_pick_info); - } - } + LLPanelProfileTab::onOpen(key); } //static -void LLPanelPicks::onClickNew(void *data) +void LLPanelPicks::onClickDelete() { - LLPanelPicks* self = (LLPanelPicks*) data; - if(self && self->mMeProfilePanel) - { - if (self->mPickItemList.size() >= MAX_AVATAR_PICKS) - { - //*TODO show warning message - return; - } - - //in edit mode - LLPanelPick* panel_edit_pick = new LLPanelPick(TRUE); - panel_edit_pick->createNewPick(); - - //*HACK redo toggling of panels - panel_edit_pick->setPanelMeProfile(self->mMeProfilePanel); - self->mMeProfilePanel->togglePanel(panel_edit_pick); - } -} - -//static -void LLPanelPicks::onClickDelete(void *data) -{ - LLPanelPicks* self = (LLPanelPicks*) data; - if(self && self->mMeProfilePanel) - { - //*TODO redo, use the selected pick from List View, but not the first (last) one - LLView* scroll = self->getChild("back_panel", TRUE, FALSE); - LLPickItem* first_pick = static_cast(scroll->getFirstChild()); - if (!first_pick) return; + LLPickItem* pick_item = getSelectedPickItem(); + if (!pick_item) return; LLSD args; - args["PICK"] = first_pick->getPickName(); - LLNotifications::instance().add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDelete, self, _1, _2)); - } + args["PICK"] = pick_item->getPickName(); + LLNotifications::instance().add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDelete, this, _1, _2)); } bool LLPanelPicks::callbackDelete(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); - //*TODO redo, use the selected pick from List View, but not the first (last) one - LLView* scroll = getChild("back_panel",TRUE,FALSE); - LLPickItem* first_pick = static_cast(scroll->getFirstChild()); - if (!first_pick) return false; + LLPickItem* pick_item = getSelectedPickItem(); if (0 == option) { - LLAvatarPropertiesProcessor::instance().sendPickDelete(first_pick->getPickId()); - - scroll->removeChild(first_pick); - mPickItemList.pop_back(); - first_pick = NULL; + LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_item->getPickId()); + removePickItem(pick_item); } updateButtons(); return false; } -void LLPanelPicks::setPanelMeProfile(LLPanelMeProfile* meProfilePanel) +bool LLPanelPicks::callbackTeleport( const LLSD& notification, const LLSD& response ) { - mMeProfilePanel = meProfilePanel; -} + S32 option = LLNotification::getSelectedOption(notification, response); -//static -void LLPanelPicks::teleport(const LLVector3d& position) -{ - if (!position.isExactlyZero()) + if (0 == option) { - gAgent.teleportViaLocation(position); - LLFloaterWorldMap::getInstance()->trackLocation(position); + onClickTeleport(); } + return false; } //static -void LLPanelPicks::onClickTeleport(void* data) +void LLPanelPicks::onClickTeleport() { - LLPanelPicks* self = (LLPanelPicks*)data; - - if (!self->mPickItemList.size()) return; - - //*TODO use the selected Pick instead of the last one in the list of Picks - LLPickItem* last_pick = self->mPickItemList.back(); - if (!last_pick) return; - - teleport(last_pick->getPosGlobal()); + LLPickItem* pick_item = getSelectedPickItem(); + if (!pick_item) return; + LLPanelPick::teleport(pick_item->getPosGlobal()); } //static -void LLPanelPicks::onClickMap(void* data) +void LLPanelPicks::onClickMap() { - LLPanelPicks* self = (LLPanelPicks*)data; - - if (!self->mPickItemList.size()) return; - - //*TODO use the selected Pick instead of the last one in the list of Picks - LLPickItem* last_pick = self->mPickItemList.back(); - if (!last_pick) return; - - showOnMap(last_pick->getPosGlobal()); - + LLPickItem* pick_item = getSelectedPickItem(); + if (!pick_item) return; + LLPanelPick::showOnMap(pick_item->getPosGlobal()); } -//static -void LLPanelPicks::showOnMap(const LLVector3d& position) + +BOOL LLPanelPicks::handleRightMouseDown(S32 x, S32 y, MASK mask) { - LLFloaterWorldMap::getInstance()->trackLocation(position); - LLFloaterReg::showInstance("world_map", "center"); + if (isMouseInPick(x, y)) + { + if (mPopupMenu) + { + mPopupMenu->buildDrawLabels(); + mPopupMenu->updateParent(LLMenuGL::sMenuContainer); + ((LLContextMenu*)mPopupMenu)->show(x, y); + LLMenuGL::showPopup(this, mPopupMenu, x, y); + } + return TRUE; + } + return LLPanel::handleRightMouseDown(x, y, mask); +} + +BOOL LLPanelPicks::handleMouseDown( S32 x, S32 y, MASK mask ) +{ + isMouseInPick(x, y); + return LLPanel::handleMouseDown(x, y, mask); +} + +BOOL LLPanelPicks::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + if (isMouseInPick(x, y)) + { + LLPickItem* pick_item = getSelectedPickItem(); + if (pick_item) + { + LLSD args; + args["PICK"] = pick_item->getPickName(); + LLNotifications::instance().add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2)); + } + return TRUE; + } + return LLPanel::handleDoubleClick(x, y, mask); } void LLPanelPicks::updateButtons() @@ -344,27 +377,127 @@ void LLPanelPicks::updateButtons() { childSetEnabled(XML_BTN_NEW, picks_num < MAX_AVATAR_PICKS); childSetEnabled(XML_BTN_DELETE, picks_num > 0); + + //*TODO move somewhere this calls + // we'd better set them up earlier when a panel was being constructed + mPopupMenu->setItemVisible("pick_delete", TRUE); + mPopupMenu->setItemVisible("pick_edit", TRUE); + mPopupMenu->setItemVisible("pick_separator", TRUE); + } + + //*TODO update buttons like Show on Map, Teleport etc. + +} + +void LLPanelPicks::setSelectedPickItem(LLPickItem* item) +{ + if (!item) return; + if (mSelectedPickItem == item) return; + if (mSelectedPickItem && mSelectedPickItem->isBackgroundVisible()) + { + mSelectedPickItem->setBackgroundVisible(FALSE); + } + item->setBackgroundVisible(TRUE); + mSelectedPickItem = item; +} + +BOOL LLPanelPicks::isMouseInPick( S32 x, S32 y ) +{ + LLScrollContainer* scroll = getChild("profile_scroll"); + if (!scroll->parentPointInView(x, y)) return FALSE; + + S32 x_l = x; + S32 y_l = y; + + picture_list_t::const_iterator it = mPickItemList.begin(); + for(; mPickItemList.end() != it; ++it) + { + localPointToOtherView(x, y, &x_l, &y_l, (*it)); + if ((*it)->pointInView(x_l, y_l)) + { + setSelectedPickItem(*it); + return TRUE; + } + } + return FALSE; +} + + +void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel) +{ + mProfilePanel = profile_panel; +} + + +void LLPanelPicks::buildPickPanel() +{ + if (mPickPanel == NULL) + { + mPickPanel = new LLPanelPick(); + mPickPanel->setExitCallback(boost::bind(&LLPanelPicks::onClickBack, this)); } } +void LLPanelPicks::onClickNew() +{ + buildPickPanel(); + mPickPanel->setEditMode(TRUE); + mPickPanel->createNewPick(); + getProfilePanel()->togglePanel(mPickPanel); +} + +void LLPanelPicks::onClickInfo() +{ + LLPickItem* pick = getSelectedPickItem(); + if (!pick) return; + + buildPickPanel(); + mPickPanel->reset(); + mPickPanel->init(pick->getCreatorId(), pick->getPickId()); + getProfilePanel()->togglePanel(mPickPanel); +} + +void LLPanelPicks::onClickBack() +{ + getProfilePanel()->togglePanel(mPickPanel); +} + +void LLPanelPicks::onClickMenuEdit() +{ + //*TODO, refactor - most of that is similar to onClickInfo + LLPickItem* pick = getSelectedPickItem(); + if (!pick) return; + + buildPickPanel(); + mPickPanel->reset(); + mPickPanel->init(pick->getCreatorId(), pick->getPickId()); + mPickPanel->setEditMode(TRUE); + getProfilePanel()->togglePanel(mPickPanel); +} + +inline LLPanelProfile* LLPanelPicks::getProfilePanel() +{ + llassert_always(NULL != mProfilePanel); + return mProfilePanel; +} //----------------------------------------------------------------------------- // LLPanelPicks //----------------------------------------------------------------------------- LLPickItem::LLPickItem() : LLPanel() -, mPicID(LLUUID::null) +, mPickID(LLUUID::null) , mCreatorID(LLUUID::null) , mParcelID(LLUUID::null) , mSnapshotID(LLUUID::null) , mNeedData(true) { - LLUICtrlFactory::getInstance()->buildPanel(this,"panel_pic_list_item.xml"); + LLUICtrlFactory::getInstance()->buildPanel(this,"panel_pick_list_item.xml"); } LLPickItem::~LLPickItem() { - if (!mCreatorID.isNull()) + if (mCreatorID.notNull()) { LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this); } @@ -378,7 +511,7 @@ LLPickItem* LLPickItem::create() void LLPickItem::init(LLPickData* pick_data) { - setPictureDescription(pick_data->desc); + setPickDesc(pick_data->desc); setSnapshotId(pick_data->snapshot_id); mPosGlobal = pick_data->pos_global; mLocation = pick_data->location_text; @@ -390,12 +523,7 @@ void LLPickItem::init(LLPickData* pick_data) } } -void LLPickItem::setPicture() -{ - -} - -void LLPickItem::setPictureName(const std::string& name) +void LLPickItem::setPickName(const std::string& name) { mPickName = name; childSetValue("picture_name",name); @@ -417,19 +545,19 @@ const LLUUID& LLPickItem::getSnapshotId() return mSnapshotID; } -void LLPickItem::setPictureDescription(const std::string& descr) +void LLPickItem::setPickDesc(const std::string& descr) { childSetValue("picture_descr",descr); } -void LLPickItem::setPictureId(const LLUUID& id) +void LLPickItem::setPickId(const LLUUID& id) { - mPicID = id; + mPickID = id; } const LLUUID& LLPickItem::getPickId() { - return mPicID; + return mPickID; } const LLVector3d& LLPickItem::getPosGlobal() @@ -450,7 +578,7 @@ const std::string LLPickItem::getDescription() void LLPickItem::update() { mNeedData = true; - LLAvatarPropertiesProcessor::instance().sendDataRequest(mCreatorID, APT_PICK_INFO, &mPicID); + LLAvatarPropertiesProcessor::instance().sendDataRequest(mCreatorID, APT_PICK_INFO, &mPickID); mNeedData = false; } @@ -461,9 +589,9 @@ void LLPickItem::processProperties(void *data, EAvatarProcessorType type) LLPickData* pick_data = static_cast(data); if (!pick_data) return; - if (mPicID != pick_data->pick_id) return; + if (mPickID != pick_data->pick_id) return; init(pick_data); - LLAvatarPropertiesProcessor::instance().removeObserver(pick_data->agent_id, this); + LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this); } diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h index bb1ee06780..e0e7f69532 100644 --- a/indra/newview/llpanelpicks.h +++ b/indra/newview/llpanelpicks.h @@ -37,13 +37,16 @@ #include "v3dmath.h" #include "lluuid.h" #include "llavatarpropertiesprocessor.h" +#include "llpanelavatar.h" +#include "llregistry.h" +class LLPanelProfile; class LLMessageSystem; class LLVector3d; class LLPanelProfileTab; -class LLPanelMeProfile; class LLPanelPick; class LLAgent; +class LLMenuGL; class LLPickItem; @@ -51,46 +54,72 @@ class LLPanelPicks : public LLPanelProfileTab { public: - LLPanelPicks(const LLUUID& avatar_id = LLUUID::null); - LLPanelPicks(const Params& params ); + LLPanelPicks(); ~LLPanelPicks(); static void* create(void* data); - static void teleport(const LLVector3d& position); - - static void showOnMap(const LLVector3d& position); - /*virtual*/ BOOL postBuild(void); - /*virtual*/ void onActivate(const LLUUID& id); + /*virtual*/ void onOpen(const LLSD& key); void processProperties(void* data, EAvatarProcessorType type); void updateData(); - void setPanelMeProfile(LLPanelMeProfile*); - void clear(); - //*TODO implement - //LLPickItem& getSelectedPick(); + // returns the selected pick item + LLPickItem* getSelectedPickItem(); + + // removes the specified pick item + void removePickItem(LLPickItem* pick_item); + + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + + //*NOTE top down approch when panel toggling is done only by + // parent panels failed to work (picks related code was in me profile panel) + void setProfilePanel(LLPanelProfile* profile_panel); private: - static void onClickInfo(void* data); - static void onClickNew(void* data); - static void onClickDelete(void* data); - static void onClickTeleport(void* data); - static void onClickMap(void* data); + void onClickDelete(); + void onClickTeleport(); + void onClickMap(); + + //------------------------------------------------ + // Callbacks which require panel toggling + //------------------------------------------------ + void onClickNew(); + void onClickInfo(); + void onClickBack(); + void onClickMenuEdit(); + + void buildPickPanel(); bool callbackDelete(const LLSD& notification, const LLSD& response); + bool callbackTeleport(const LLSD& notification, const LLSD& response); + void reshapePicksList(); + void reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth); + LLView* getPicksList() const; void updateButtons(); - typedef std::vector picture_list_t; - picture_list_t mPickItemList; - LLPanelMeProfile* mMeProfilePanel; + void setSelectedPickItem(LLPickItem* item); + BOOL isMouseInPick(S32 x, S32 y); + + LLPanelProfile* getProfilePanel(); + + + typedef std::list picture_list_t; + picture_list_t mPickItemList; + + LLMenuGL* mPopupMenu; + LLPickItem* mSelectedPickItem; + LLPanelProfile* mProfilePanel; + LLPanelPick* mPickPanel; }; class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver @@ -103,13 +132,11 @@ public: void init(LLPickData* pick_data); - void setPictureName(const std::string& name); + void setPickName(const std::string& name); - void setPictureDescription(const std::string& descr); + void setPickDesc(const std::string& descr); - void setPicture(); - - void setPictureId(const LLUUID& id); + void setPickId(const LLUUID& id); void setCreatorId(const LLUUID& id) {mCreatorID = id;}; @@ -139,7 +166,7 @@ public: protected: - LLUUID mPicID; + LLUUID mPickID; LLUUID mCreatorID; LLUUID mParcelID; LLUUID mSnapshotID; diff --git a/indra/newview/llpanelplace.cpp b/indra/newview/llpanelplace.cpp index ad385d8bdf..83702c08ab 100644 --- a/indra/newview/llpanelplace.cpp +++ b/indra/newview/llpanelplace.cpp @@ -356,16 +356,17 @@ void LLPanelPlace::onClickTeleport(void* data) } // LLFloater* parent_floaterp = (LLFloater*)self->getParent(); parent_viewp->setVisible(false); - if(self->mLandmarkAssetID.notNull()) + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if(self->mLandmarkAssetID.notNull() && worldmap_instance) { gAgent.teleportViaLandmark(self->mLandmarkAssetID); - LLFloaterWorldMap::getInstance()->trackLandmark(self->mLandmarkAssetID); + worldmap_instance->trackLandmark(self->mLandmarkAssetID); } - else if (!self->mPosGlobal.isExactlyZero()) + else if (!self->mPosGlobal.isExactlyZero() && worldmap_instance) { gAgent.teleportViaLocation(self->mPosGlobal); - LLFloaterWorldMap::getInstance()->trackLocation(self->mPosGlobal); + worldmap_instance->trackLocation(self->mPosGlobal); } } @@ -373,9 +374,11 @@ void LLPanelPlace::onClickTeleport(void* data) void LLPanelPlace::onClickMap(void* data) { LLPanelPlace* self = (LLPanelPlace*)data; - if (!self->mPosGlobal.isExactlyZero()) + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + + if (!self->mPosGlobal.isExactlyZero() && worldmap_instance) { - LLFloaterWorldMap::getInstance()->trackLocation(self->mPosGlobal); + worldmap_instance->trackLocation(self->mPosGlobal); LLFloaterReg::showInstance("world_map", "center"); } } diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index 951c223668..31d76ca4e2 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -34,43 +34,41 @@ #include "llpanelplaceinfo.h" -// *TODO: reorder includes to match the coding standard -#include "llinventory.h" -#include "llviewercontrol.h" -#include "llqueryflags.h" -#include "llui.h" +#include "roles_constants.h" +#include "llsdutil.h" #include "llsecondlifeurls.h" -#include "llfloater.h" -#include "llfloaterreg.h" + +#include "llinventory.h" +#include "llparcel.h" + +#include "llqueryflags.h" + +#include "llbutton.h" +#include "lllineeditor.h" +#include "llscrollcontainer.h" +#include "lltextbox.h" #include "llagent.h" -#include "llviewerwindow.h" -#include "llviewerinventory.h" -#include "llbutton.h" #include "llfloaterworldmap.h" -#include "lllineeditor.h" #include "llinventorymodel.h" -#include "lluiconstants.h" -#include "roles_constants.h" -#include "lltextbox.h" -#include "llviewertexteditor.h" +#include "lllandmarkactions.h" #include "lltexturectrl.h" -#include "lltrans.h" -#include "llworldmap.h" +#include "llviewerinventory.h" +#include "llviewerparcelmgr.h" #include "llviewerregion.h" -#include "lluictrlfactory.h" -#include "llweb.h" -#include "llsdutil.h" +#include "llviewertexteditor.h" +#include "llworldmap.h" #include "llsdutil_math.h" -static LLRegisterPanelClassWrapper t_places("panel_landmark_info"); +static LLRegisterPanelClassWrapper t_place_info("panel_place_info"); LLPanelPlaceInfo::LLPanelPlaceInfo() : LLPanel(), mParcelID(), mRequestedID(), mPosRegion(), - mLandmarkID() + mLandmarkID(), + mMinHeight(0) {} LLPanelPlaceInfo::~LLPanelPlaceInfo() @@ -83,6 +81,9 @@ LLPanelPlaceInfo::~LLPanelPlaceInfo() BOOL LLPanelPlaceInfo::postBuild() { + mTitle = getChild("panel_title"); + mCurrentTitle = mTitle->getText(); + // Since this is only used in the directory browser, always // disable the snapshot control. Otherwise clicking on it will // open a texture picker. @@ -105,7 +106,14 @@ BOOL LLPanelPlaceInfo::postBuild() mNotesEditor->setCommitCallback(boost::bind(&LLPanelPlaceInfo::onCommitTitleOrNote, this, NOTE)); mNotesEditor->setCommitOnFocusLost(true); - mInfoPanel = getChild("info_panel"); + LLScrollContainer* scroll_container = getChild("scroll_container"); + scroll_container->setBorderVisible(FALSE); + mMinHeight = scroll_container->getScrolledViewRect().getHeight(); + + mScrollingPanel = getChild("scrolling_panel"); + + mInfoPanel = getChild("info_panel", TRUE, FALSE); + mMediaPanel = getChild("media_panel", TRUE, FALSE); return TRUE; } @@ -217,6 +225,8 @@ void LLPanelPlaceInfo::resetLocation() mCreated->setText(not_available); mTitleEditor->setText(LLStringUtil::null); mNotesEditor->setText(LLStringUtil::null); + mSnapshotCtrl->setImageAssetID(LLUUID::null); + mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c"); } //virtual @@ -226,6 +236,70 @@ void LLPanelPlaceInfo::setParcelID(const LLUUID& parcel_id) sendParcelInfoRequest(); } +void LLPanelPlaceInfo::setInfoType(INFO_TYPE type) +{ + if (!mInfoPanel) + return; + + switch(type) + { + case CREATE_LANDMARK: + mCurrentTitle = getString("title_create_landmark"); + + toggleMediaPanel(FALSE); + break; + + case PLACE: + mCurrentTitle = getString("title_place"); + + if (!isMediaPanelVisible()) + { + mTitle->setText(mCurrentTitle); + } + break; + + // Hide Media Panel if showing information about + // a landmark or a teleport history item + case LANDMARK: + mCurrentTitle = getString("title_landmark"); + + toggleMediaPanel(FALSE); + break; + + case TELEPORT_HISTORY: + mCurrentTitle = getString("title_place"); + + toggleMediaPanel(FALSE); + break; + } +} + +BOOL LLPanelPlaceInfo::isMediaPanelVisible() +{ + if (!mMediaPanel) + return FALSE; + + return mMediaPanel->getVisible(); +} + +void LLPanelPlaceInfo::toggleMediaPanel(BOOL visible) +{ + if (!(mMediaPanel && mInfoPanel)) + return; + + if (visible) + { + mTitle->setText(getString("title_media")); + } + else + { + mTitle->setText(mCurrentTitle); + } + + mInfoPanel->setVisible(!visible); + mMediaPanel->setVisible(visible); +} + void LLPanelPlaceInfo::sendParcelInfoRequest() { if (mParcelID != mRequestedID) @@ -300,21 +374,33 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data) region_z = llround(parcel_data.global_z); } + std::string name; if (!parcel_data.sim_name.empty()) { - std::string name = llformat("%s (%d, %d, %d)", - parcel_data.sim_name.c_str(), region_x, region_y, region_z); + name = llformat("%s (%d, %d, %d)", + parcel_data.sim_name.c_str(), region_x, region_y, region_z); mRegionName->setText(name); } + + if (mCurrentTitle != getString("title_landmark")) + { + mTitleEditor->setText(parcel_data.name + "; " + name); + mNotesEditor->setText(LLStringUtil::null); + } } void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region, const LLUUID& region_id, const LLVector3d& pos_global) { - LLSD body; mPosRegion = pos_region; - std::string url = gAgent.getRegion()->getCapability("RemoteParcelRequest"); + + LLViewerRegion* region = gAgent.getRegion(); + if (!region) + return; + + LLSD body; + std::string url = region->getCapability("RemoteParcelRequest"); if (!url.empty()) { body["location"] = ll_sd_from_vector3(pos_region); @@ -333,8 +419,29 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region, { mDescEditor->setText(getString("server_update_text")); } - mSnapshotCtrl->setImageAssetID(LLUUID::null); - mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c"); +} + +void LLPanelPlaceInfo::displayAgentParcelInfo() +{ + mPosRegion = gAgent.getPositionAgent(); + + LLViewerRegion* region = gAgent.getRegion(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (!region || !parcel) + return; + + LLParcelData parcel_data; + parcel_data.desc = parcel->getDesc(); + parcel_data.flags = parcel->getParcelFlags(); + parcel_data.name = parcel->getName(); + parcel_data.sim_name = gAgent.getRegion()->getName(); + parcel_data.snapshot_id = parcel->getSnapshotID(); + LLVector3d global_pos = gAgent.getPositionGlobal(); + parcel_data.global_x = global_pos.mdV[0]; + parcel_data.global_y = global_pos.mdV[1]; + parcel_data.global_z = global_pos.mdV[2]; + + processParcelInfo(parcel_data); } void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type) @@ -381,3 +488,33 @@ void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type) gInventory.notifyObservers(); } } + +void LLPanelPlaceInfo::createLandmark(const LLUUID& folder_id) +{ + std::string name = mTitleEditor->getText(); + std::string desc = mNotesEditor->getText(); + + LLStringUtil::trim(name); + LLStringUtil::trim(desc); + + // If typed name is empty use the parcel name instead. + if (name.empty()) + { + name = mParcelName->getText() + "; " + mRegionName->getText(); + } + + LLStringUtil::replaceChar(desc, '\n', ' '); + // If no folder chosen use the "Landmarks" folder. + LLLandmarkActions::createLandmarkHere(name, desc, + folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK)); +} + +void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + if (mMinHeight > 0) + { + mScrollingPanel->reshape(mScrollingPanel->getRect().getWidth(), mMinHeight); + } + + LLView::reshape(width, height, called_from_parent); +} diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index f88e29bc91..e7b81dc3e6 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -1,5 +1,5 @@ /** - * @file llpanelplace.h + * @file llpanelplaceinfo.h * @brief Displays place information in Side Tray. * * $LicenseInfo:firstyear=2009&license=viewergpl$ @@ -40,50 +40,79 @@ #include "lliconctrl.h" +#include "llpanelmedia.h" #include "llremoteparcelrequest.h" class LLButton; -class LLTextBox; +class LLInventoryItem; class LLLineEditor; +class LLTextBox; class LLTextEditor; class LLTextureCtrl; -class LLInventoryItem; class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver { public: + enum INFO_TYPE + { + CREATE_LANDMARK, + PLACE, + LANDMARK, + TELEPORT_HISTORY + }; + LLPanelPlaceInfo(); /*virtual*/ ~LLPanelPlaceInfo(); /*virtual*/ BOOL postBuild(); + // Ignore all old location information, useful if you are + // recycling an existing dialog and need to clear it. void resetLocation(); - // Ignore all old location information, useful if you are - // recycling an existing dialog and need to clear it. + // Sends a request for data about the given parcel, which will + // only update the location if there is none already available. /*virtual*/ void setParcelID(const LLUUID& parcel_id); - // Sends a request for data about the given parcel, which will - // only update the location if there is none already available. + // Depending on how the panel was triggered + // (from landmark or current location, or other) + // sets a corresponding title and contents. + void setInfoType(INFO_TYPE type); + + // Create a landmark for the current location + // in a folder specified by folder_id + void createLandmark(const LLUUID& folder_id); + + BOOL isMediaPanelVisible(); + void toggleMediaPanel(BOOL visible); void displayItemInfo(const LLInventoryItem* pItem); /*virtual*/ void setErrorStatus(U32 status, const std::string& reason); void sendParcelInfoRequest(); + + // Displays information about a remote parcel. + // Sends a request to the server. void displayParcelInfo(const LLVector3& pos_region, const LLUUID& region_id, const LLVector3d& pos_global); + + // Displays information about the parcel the agent is currently on + // without sending a request to the server. + void displayAgentParcelInfo(); + void nameUpdatedCallback(LLTextBox* text, const std::string& first, const std::string& last); /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); private: enum LANDMARK_INFO_TYPE - { - TITLE, - NOTE - }; + { + TITLE, + NOTE + }; void onCommitTitleOrNote(LANDMARK_INFO_TYPE type); @@ -91,7 +120,10 @@ private: LLUUID mRequestedID; LLUUID mLandmarkID; LLVector3 mPosRegion; + std::string mCurrentTitle; + S32 mMinHeight; + LLTextBox* mTitle; LLTextureCtrl* mSnapshotCtrl; LLTextBox* mRegionName; LLTextBox* mParcelName; @@ -102,8 +134,10 @@ private: LLTextBox* mCreated; LLLineEditor* mTitleEditor; LLTextEditor* mNotesEditor; - LLTextBox* mLocationEditor; + LLTextBox* mLocationEditor; + LLPanel* mScrollingPanel; LLPanel* mInfoPanel; + LLMediaPanel* mMediaPanel; }; #endif // LL_LLPANELPLACEINFO_H diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index d18cac9f42..31b2d01dcf 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -31,32 +31,51 @@ #include "llviewerprecompiledheaders.h" -#include "llfloaterreg.h" -#include "llsearcheditor.h" -#include "lltabcontainer.h" -#include "lluictrlfactory.h" +#include "llassettype.h" #include "lllandmark.h" +#include "llfloaterreg.h" +#include "llnotifications.h" +#include "llfiltereditor.h" +#include "lltabcontainer.h" +#include "lltrans.h" +#include "lluictrlfactory.h" + #include "llagent.h" #include "lllandmarklist.h" #include "llfloaterworldmap.h" #include "llpanelplaces.h" #include "llpanellandmarks.h" #include "llpanelteleporthistory.h" +#include "llsidetray.h" +#include "lltoggleablemenu.h" +#include "llviewerparcelmgr.h" #include "llviewerregion.h" +// Helper functions +static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right); +static std::string getFullFolderName(const LLViewerInventoryCategory* cat); +static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats); +static const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global); + static LLRegisterPanelClassWrapper t_places("panel_places"); LLPanelPlaces::LLPanelPlaces() : LLPanel(), mFilterSubString(LLStringUtil::null), mActivePanel(NULL), - mSearchEditor(NULL), - mPlaceInfo(NULL) + mFilterEditor(NULL), + mPlaceInfo(NULL), + mItem(NULL), + mLandmarkFoldersMenuHandle(), + mPosGlobal() { gInventory.addObserver(this); + LLViewerParcelMgr::getInstance()->setAgentParcelChangedCallback( + boost::bind(&LLPanelPlaces::onAgentParcelChange, this)); + //LLUICtrlFactory::getInstance()->buildPanel(this, "panel_places.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() } @@ -64,23 +83,42 @@ LLPanelPlaces::~LLPanelPlaces() { if (gInventory.containsObserver(this)) gInventory.removeObserver(this); + + LLView::deleteViewByHandle(mLandmarkFoldersMenuHandle); } BOOL LLPanelPlaces::postBuild() { + mCreateLandmarkBtn = getChild("create_landmark_btn"); + mCreateLandmarkBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onCreateLandmarkButtonClicked, this, LLUUID())); + + mFolderMenuBtn = getChild("folder_menu_btn"); + mFolderMenuBtn->setClickedCallback(boost::bind(&LLPanelPlaces::showLandmarkFoldersMenu, this)); + + mTeleportBtn = getChild("teleport_btn"); + mTeleportBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this)); + + mShowOnMapBtn = getChild("map_btn"); + mShowOnMapBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this)); + + mShareBtn = getChild("share_btn"); + //mShareBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShareButtonClicked, this)); + + mOverflowBtn = getChild("overflow_btn"); + mTabContainer = getChild("Places Tabs"); if (mTabContainer) { mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this)); } - mSearchEditor = getChild("Filter"); - if (mSearchEditor) + mFilterEditor = getChild("Filter"); + if (mFilterEditor) { - mSearchEditor->setSearchCallback(boost::bind(&LLPanelPlaces::onSearchEdit, this, _1)); + mFilterEditor->setCommitCallback(boost::bind(&LLPanelPlaces::onFilterEdit, this, _2)); } - mPlaceInfo = dynamic_cast(getChild("panel_landmark_info")); + mPlaceInfo = getChild("panel_place_info", TRUE, FALSE); if (mPlaceInfo) { LLButton* back_btn = mPlaceInfo->getChild("back_btn"); @@ -88,60 +126,64 @@ BOOL LLPanelPlaces::postBuild() { back_btn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); } + + // *TODO: Assign the action to an appropriate event. + mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::toggleMediaPanel, this)); } - //childSetAction("share_btn", boost::bind(&LLPanelPlaces::onShareButtonClicked, this), this); - childSetAction("teleport_btn", boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this), this); - childSetAction("map_btn", boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this), this); - return TRUE; } -void LLPanelPlaces::draw() -{ - LLPanel::draw(); -} - void LLPanelPlaces::onOpen(const LLSD& key) { if(key.size() == 0) return; + mPlaceInfoType = key["type"].asString(); + mPosGlobal.setZero(); togglePlaceInfoPanel(TRUE); - - mPlaceInfoType = key["type"].asInteger(); + updateVerbs(); - if (mPlaceInfoType == AGENT) + if (mPlaceInfoType == "agent") { - // We don't need to teleport to the current location so disable the button - getChild("teleport_btn")->setEnabled(FALSE); - - mPlaceInfo->displayParcelInfo(gAgent.getPositionAgent(), - gAgent.getRegion()->getRegionID(), - gAgent.getPositionGlobal()); + mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE); + mPlaceInfo->displayAgentParcelInfo(); + + mPosGlobal = gAgent.getPositionGlobal(); } - else if (mPlaceInfoType == LANDMARK) + else if (mPlaceInfoType == "create_landmark") { - LLInventoryItem* item = gInventory.getItem(key["id"].asUUID()); + mPlaceInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK); + mPlaceInfo->displayAgentParcelInfo(); + + mPosGlobal = gAgent.getPositionGlobal(); + } + else if (mPlaceInfoType == "landmark") + { + LLUUID item_uuid = key["id"].asUUID(); + LLInventoryItem* item = gInventory.getItem(item_uuid); if (!item) return; - - mPlaceInfo->displayItemInfo(item); - - LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID()); - if (!landmark) - return; - - LLUUID region_id; - landmark->getRegionID(region_id); - LLVector3d pos_global; - landmark->getGlobalPos(pos_global); - mPlaceInfo->displayParcelInfo(landmark->getRegionPos(), - region_id, - pos_global); - + + setItem(item); } - else if (mPlaceInfoType == TELEPORT_HISTORY) + else if (mPlaceInfoType == "remote_place") + { + if (mPlaceInfo->isMediaPanelVisible()) + { + toggleMediaPanel(); + } + + mPosGlobal = LLVector3d(key["x"].asReal(), + key["y"].asReal(), + key["z"].asReal()); + + mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE); + mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal), + LLUUID(), + mPosGlobal); + } + else if (mPlaceInfoType == "teleport_history") { S32 index = key["id"].asInteger(); @@ -150,52 +192,77 @@ void LLPanelPlaces::onOpen(const LLSD& key) LLVector3d pos_global = hist_items[index].mGlobalPos; - F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS ); - F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); - - LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]); - - mPlaceInfo->displayParcelInfo(pos_local, + mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY); + mPlaceInfo->displayParcelInfo(get_pos_local_from_global(pos_global), hist_items[index].mRegionID, pos_global); } } -void LLPanelPlaces::onSearchEdit(const std::string& search_string) +void LLPanelPlaces::setItem(LLInventoryItem* item) +{ + mItem = item; + + // If the item is a link get a linked item + if (mItem->getType() == LLAssetType::AT_LINK) + { + mItem = gInventory.getItem(mItem->getAssetUUID()); + if (mItem.isNull()) + return; + } + + mPlaceInfo->setInfoType(LLPanelPlaceInfo::LANDMARK); + mPlaceInfo->displayItemInfo(mItem); + + LLLandmark* lm = gLandmarkList.getAsset(mItem->getAssetUUID(), + boost::bind(&LLPanelPlaces::onLandmarkLoaded, this, _1)); + if (lm) + { + onLandmarkLoaded(lm); + } +} + +void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark) +{ + LLUUID region_id; + landmark->getRegionID(region_id); + LLVector3d pos_global; + landmark->getGlobalPos(pos_global); + mPlaceInfo->displayParcelInfo(landmark->getRegionPos(), + region_id, + pos_global); +} + +void LLPanelPlaces::onFilterEdit(const std::string& search_string) { if (mFilterSubString != search_string) { mFilterSubString = search_string; + // Searches are case-insensitive LLStringUtil::toUpper(mFilterSubString); LLStringUtil::trimHead(mFilterSubString); - mSearchEditor->setText(mFilterSubString); - mActivePanel->onSearchEdit(mFilterSubString); } } void LLPanelPlaces::onTabSelected() { + mActivePanel = dynamic_cast(mTabContainer->getCurrentPanel()); if (!mActivePanel) return; - mActivePanel = dynamic_cast(mTabContainer->getCurrentPanel()); - - if (mActivePanel) - { - mActivePanel->onSearchEdit(mFilterSubString); - mActivePanel->onTabSelected(); - } + onFilterEdit(mFilterSubString); + mActivePanel->updateVerbs(); } +/* void LLPanelPlaces::onShareButtonClicked() { // TODO: Launch the "Things" Share wizard } -/* void LLPanelPlaces::onAddLandmarkButtonClicked() { LLFloaterReg::showInstance("add_landmark"); @@ -209,19 +276,64 @@ void LLPanelPlaces::onCopySLURLButtonClicked() void LLPanelPlaces::onTeleportButtonClicked() { - mActivePanel->onTeleport(); + if (mPlaceInfo->getVisible()) + { + if (mPlaceInfoType == "landmark") + { + LLSD payload; + payload["asset_id"] = mItem->getAssetUUID(); + LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload); + } + else if (mPlaceInfoType == "remote_place") + { + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if (!mPosGlobal.isExactlyZero() && worldmap_instance) + { + gAgent.teleportViaLocation(mPosGlobal); + worldmap_instance->trackLocation(mPosGlobal); + } + } + } + else + { + mActivePanel->onTeleport(); + } } void LLPanelPlaces::onShowOnMapButtonClicked() { - if (!mPlaceInfoType) + if (mPlaceInfo->getVisible()) { - LLVector3d global_pos = gAgent.getPositionGlobal(); - if (!global_pos.isExactlyZero()) + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if(!worldmap_instance) + return; + + if (mPlaceInfoType == "agent" || + mPlaceInfoType == "create_landmark" || + mPlaceInfoType == "remote_place") + { + if (!mPosGlobal.isExactlyZero()) { - LLFloaterWorldMap::getInstance()->trackLocation(global_pos); + worldmap_instance->trackLocation(mPosGlobal); LLFloaterReg::showInstance("world_map", "center"); } + } + else if (mPlaceInfoType == "landmark") + { + LLLandmark* landmark = gLandmarkList.getAsset(mItem->getAssetUUID()); + if (!landmark) + return; + + LLVector3d landmark_global_pos; + if (!landmark->getGlobalPos(landmark_global_pos)) + return; + + if (!landmark_global_pos.isExactlyZero()) + { + worldmap_instance->trackLocation(landmark_global_pos); + LLFloaterReg::showInstance("world_map", "center"); + } + } } else { @@ -229,9 +341,33 @@ void LLPanelPlaces::onShowOnMapButtonClicked() } } +void LLPanelPlaces::onCreateLandmarkButtonClicked(const LLUUID& folder_id) +{ + if (!mPlaceInfo) + return; + + mPlaceInfo->createLandmark(folder_id); + + onBackButtonClicked(); + LLSideTray::getInstance()->collapseSideBar(); +} + void LLPanelPlaces::onBackButtonClicked() { togglePlaceInfoPanel(FALSE); + + // Resetting mPlaceInfoType when Place Info panel is closed. + mPlaceInfoType = LLStringUtil::null; + + updateVerbs(); +} + +void LLPanelPlaces::toggleMediaPanel() +{ + if (!mPlaceInfo) + return; + + mPlaceInfo->toggleMediaPanel(!mPlaceInfo->isMediaPanelVisible()); } void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) @@ -240,7 +376,7 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) return; mPlaceInfo->setVisible(visible); - mSearchEditor->setVisible(!visible); + mFilterEditor->setVisible(!visible); mTabContainer->setVisible(!visible); if (visible) @@ -249,7 +385,7 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) LLRect rect = getRect(); LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom); - mPlaceInfo->reshape(new_rect.getWidth(),new_rect.getHeight()); + mPlaceInfo->reshape(new_rect.getWidth(),new_rect.getHeight()); } } @@ -267,7 +403,7 @@ void LLPanelPlaces::changed(U32 mask) mTabContainer->addTabPanel( LLTabContainer::TabPanelParams(). panel(landmarks_panel). - label("Landmarks"). + label(getString("landmarks_tab_title")). insert_at(LLTabContainer::END)); } @@ -279,7 +415,7 @@ void LLPanelPlaces::changed(U32 mask) mTabContainer->addTabPanel( LLTabContainer::TabPanelParams(). panel(teleport_history_panel). - label("Teleport History"). + label(getString("teleport_history_tab_title")). insert_at(LLTabContainer::END)); } @@ -291,3 +427,258 @@ void LLPanelPlaces::changed(U32 mask) // so remove the observer gInventory.removeObserver(this); } + +void LLPanelPlaces::onAgentParcelChange() +{ + if (mPlaceInfo->getVisible() && (mPlaceInfoType == "agent" || mPlaceInfoType == "create_landmark")) + { + onOpen(LLSD().insert("type", mPlaceInfoType)); + } + else + { + updateVerbs(); + } +} + +void LLPanelPlaces::updateVerbs() +{ + bool is_place_info_visible = mPlaceInfo->getVisible(); + bool is_agent_place_info_visible = mPlaceInfoType == "agent"; + bool is_create_landmark_visible = mPlaceInfoType == "create_landmark"; + + mTeleportBtn->setVisible(!is_create_landmark_visible); + mShareBtn->setVisible(!is_create_landmark_visible); + mCreateLandmarkBtn->setVisible(is_create_landmark_visible); + mFolderMenuBtn->setVisible(is_create_landmark_visible); + + // Enable overflow button only when showing the information + // about agent's current location. + mOverflowBtn->setEnabled(is_agent_place_info_visible); + + if (is_place_info_visible) + { + if (is_agent_place_info_visible) + { + // We don't need to teleport to the current location so disable the button + mTeleportBtn->setEnabled(FALSE); + } + else if (mPlaceInfoType == "landmark" || mPlaceInfoType == "remote_place") + { + mTeleportBtn->setEnabled(TRUE); + } + + mShowOnMapBtn->setEnabled(TRUE); + } + else + { + mActivePanel->updateVerbs(); + } +} + +void LLPanelPlaces::showLandmarkFoldersMenu() +{ + if (mLandmarkFoldersMenuHandle.isDead()) + { + LLToggleableMenu::Params menu_p; + menu_p.name("landmarks_folders_menu"); + menu_p.can_tear_off(false); + menu_p.visible(false); + menu_p.scrollable(true); + + LLToggleableMenu* menu = LLUICtrlFactory::create(menu_p); + + mLandmarkFoldersMenuHandle = menu->getHandle(); + } + + LLToggleableMenu* menu = (LLToggleableMenu*)mLandmarkFoldersMenuHandle.get(); + if(!menu) + return; + + if (menu->getClosedByButtonClick()) + { + menu->resetClosedByButtonClick(); + return; + } + + if (menu->getVisible()) + { + menu->setVisible(FALSE); + menu->resetClosedByButtonClick(); + return; + } + + // Collect all folders that can contain landmarks. + LLInventoryModel::cat_array_t cats; + collectLandmarkFolders(cats); + + // Sort the folders by their full name. + folder_vec_t folders; + S32 count = cats.count(); + for (S32 i = 0; i < count; i++) + { + const LLViewerInventoryCategory* cat = cats.get(i); + std::string cat_full_name = getFullFolderName(cat); + folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name)); + } + sort(folders.begin(), folders.end(), cmp_folders); + + LLRect btn_rect = mFolderMenuBtn->getRect(); + + LLRect root_rect = getRootView()->getRect(); + + // Check it there are changed items or viewer dimensions + // have changed since last call + if (mLandmarkFoldersCache.size() == count && + mRootViewWidth == root_rect.getWidth() && + mRootViewHeight == root_rect.getHeight()) + { + S32 i; + for (i = 0; i < count; i++) + { + if (mLandmarkFoldersCache[i].second != folders[i].second) + { + break; + } + } + + // Check passed, just show the menu + if (i == count) + { + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); + + menu->setButtonRect(btn_rect, this); + LLMenuGL::showPopup(this, menu, btn_rect.mRight, btn_rect.mTop); + return; + } + } + + // If there are changes, store the new viewer dimensions + // and a list of folders + mRootViewWidth = root_rect.getWidth(); + mRootViewHeight = root_rect.getHeight(); + mLandmarkFoldersCache = folders; + + menu->empty(); + U32 max_width = 0; + + // Menu width must not exceed the root view limits, + // so we assume the space between the left edge of + // the root view and + LLRect screen_btn_rect; + localRectToScreen(btn_rect, &screen_btn_rect); + S32 free_space = screen_btn_rect.mRight; + + for(folder_vec_t::const_iterator it = mLandmarkFoldersCache.begin(); it != mLandmarkFoldersCache.end(); it++) + { + const std::string& item_name = it->second; + + LLMenuItemCallGL::Params item_params; + item_params.name(item_name); + item_params.label(item_name); + + item_params.on_click.function(boost::bind(&LLPanelPlaces::onCreateLandmarkButtonClicked, this, it->first)); + + LLMenuItemCallGL *menu_item = LLUICtrlFactory::create(item_params); + + // Check whether item name wider than menu + if ((S32) menu_item->getNominalWidth() > free_space) + { + S32 chars_total = item_name.length(); + S32 chars_fitted = 1; + menu_item->setLabel(LLStringExplicit("")); + S32 label_space = free_space - menu_item->getFont()->getWidth("...") - + menu_item->getNominalWidth(); // This returns width of menu item with empty label (pad pixels) + + while (chars_fitted < chars_total && menu_item->getFont()->getWidth(item_name, 0, chars_fitted) < label_space) + { + chars_fitted++; + } + chars_fitted--; // Rolling back one char, that doesn't fit + + menu_item->setLabel(item_name.substr(0, chars_fitted) + "..."); + } + + max_width = llmax(max_width, menu_item->getNominalWidth()); + + menu->addChild(menu_item); + } + + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); + menu->setButtonRect(btn_rect, this); + LLMenuGL::showPopup(this, menu, btn_rect.mRight, btn_rect.mTop); +} + +static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right) +{ + return left.second < right.second; +} + +static std::string getFullFolderName(const LLViewerInventoryCategory* cat) +{ + std::string name = cat->getName(); + LLUUID parent_id; + + // translate category name, if it's right below the root + // FIXME: it can throw notification about non existent string in strings.xml + if (cat->getParentUUID().notNull() && cat->getParentUUID() == gInventory.getRootFolderID()) + { + name = LLTrans::getString("InvFolder " + name); + } + + // we don't want "My Inventory" to appear in the name + while ((parent_id = cat->getParentUUID()).notNull() && parent_id != gInventory.getRootFolderID()) + { + cat = gInventory.getCategory(parent_id); + name = cat->getName() + "/" + name; + } + + return name; +} + +static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats) +{ + // Add the "Landmarks" category itself. + LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); + LLViewerInventoryCategory* landmarks_cat = gInventory.getCategory(landmarks_id); + if (!landmarks_cat) + { + llwarns << "Cannot find the landmarks folder" << llendl; + } + else + { + cats.put(landmarks_cat); + } + + // Add descendent folders of the "Landmarks" category. + LLInventoryModel::item_array_t items; // unused + LLIsType is_category(LLAssetType::AT_CATEGORY); + gInventory.collectDescendentsIf( + landmarks_id, + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + is_category); + + // Add the "My Favorites" category. + LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE); + LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id); + if (!favorites_cat) + { + llwarns << "Cannot find the favorites folder" << llendl; + } + else + { + cats.put(favorites_cat); + } +} + +const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global) +{ + F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS ); + F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); + + LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]); + return pos_local; +} diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 533fb8dd82..695c78cfba 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -32,6 +32,8 @@ #ifndef LL_LLPANELPLACES_H #define LL_LLPANELPLACES_H +#include "lltimer.h" + #include "llpanel.h" #include "llinventory.h" @@ -39,47 +41,86 @@ #include "llinventorymodel.h" #include "llpanelplaceinfo.h" +class LLInventoryItem; +class LLLandmark; class LLPanelPlacesTab; -class LLSearchEditor; +class LLFilterEditor; class LLTabContainer; +typedef std::pair folder_pair_t; + class LLPanelPlaces : public LLPanel, LLInventoryObserver { public: - enum PLACE_INFO_TYPE - { - AGENT, - LANDMARK, - TELEPORT_HISTORY - }; - LLPanelPlaces(); virtual ~LLPanelPlaces(); /*virtual*/ BOOL postBuild(); - /*virtual*/ void draw(); /*virtual*/ void changed(U32 mask); /*virtual*/ void onOpen(const LLSD& key); - void onSearchEdit(const std::string& search_string); - void onTabSelected(); - //void onAddLandmarkButtonClicked(); - //void onCopySLURLButtonClicked(); - void onShareButtonClicked(); - void onTeleportButtonClicked(); - void onShowOnMapButtonClicked(); - void onBackButtonClicked(); - void togglePlaceInfoPanel(BOOL visible); + void setItem(LLInventoryItem* item); private: - LLSearchEditor* mSearchEditor; - LLPanelPlacesTab* mActivePanel; - LLTabContainer* mTabContainer; - LLPanelPlaceInfo* mPlaceInfo; - std::string mFilterSubString; + void onLandmarkLoaded(LLLandmark* landmark); + void onFilterEdit(const std::string& search_string); + void onTabSelected(); - // Place information type currently shown in Information panel - S32 mPlaceInfoType; + //void onAddLandmarkButtonClicked(); + //void onCopySLURLButtonClicked(); + //void onShareButtonClicked(); + void onTeleportButtonClicked(); + void onShowOnMapButtonClicked(); + void onCreateLandmarkButtonClicked(const LLUUID& folder_id); + void onBackButtonClicked(); + + void toggleMediaPanel(); + void togglePlaceInfoPanel(BOOL visible); + + void onAgentParcelChange(); + void updateVerbs(); + + void showLandmarkFoldersMenu(); + + LLFilterEditor* mFilterEditor; + LLPanelPlacesTab* mActivePanel; + LLTabContainer* mTabContainer; + LLPanelPlaceInfo* mPlaceInfo; + + LLButton* mCreateLandmarkBtn; + LLButton* mFolderMenuBtn; + LLButton* mTeleportBtn; + LLButton* mShowOnMapBtn; + LLButton* mShareBtn; + LLButton* mOverflowBtn; + + // Pointer to a landmark item or to a linked landmark + LLPointer mItem; + + // Absolute position of the location for teleport, may not + // be available (hence zero) + LLVector3d mPosGlobal; + + // Search string for filtering landmarks and teleport + // history locations + std::string mFilterSubString; + + // Information type currently shown in Place Information panel + std::string mPlaceInfoType; + + // Menu handle for pop-up menu to chose a landmark saving + // folder when creating a new landmark + LLHandle mLandmarkFoldersMenuHandle; + + typedef std::vector folder_vec_t; + + // List of folders to choose from when creating a landmark + folder_vec_t mLandmarkFoldersCache; + + // If root view width or height is changed + // the pop-up menu must be updated + S32 mRootViewWidth; + S32 mRootViewHeight; }; #endif //LL_LLPANELPLACES_H diff --git a/indra/newview/llpanelplacestab.cpp b/indra/newview/llpanelplacestab.cpp index 2b38aa0890..7c0a7b0cc4 100644 --- a/indra/newview/llpanelplacestab.cpp +++ b/indra/newview/llpanelplacestab.cpp @@ -31,14 +31,24 @@ #include "llviewerprecompiledheaders.h" +#include "llpanelplacestab.h" + #include "llwindow.h" #include "llnotifications.h" +#include "llbutton.h" #include "llslurl.h" -#include "llpanelplacestab.h" #include "llworldmap.h" +bool LLPanelPlacesTab::isTabVisible() +{ + LLUICtrl* parent = getParentUICtrl(); + if (!parent) return false; + if (!parent->getVisible()) return false; + return true; +} + void LLPanelPlacesTab::setPanelPlacesButtons(LLPanelPlaces* panel) { //mShareBtn = panel->getChild("share_btn"); @@ -75,24 +85,3 @@ void LLPanelPlacesTab::onRegionResponse(const LLVector3d& landmark_global_pos, LLNotifications::instance().add("CopySLURL", args); } - -void LLPanelPlacesTab::onTabSelected() -{ - togglePanelPlacesButtons(TRUE); -} - -void LLPanelPlacesTab::togglePanelPlacesButtons(BOOL enabled) -{ - if (enabled) - { - //mShareBtn->setEnabled(TRUE); - mTeleportBtn->setEnabled(TRUE); - mShowOnMapBtn->setEnabled(TRUE); - } - else - { - //mShareBtn->setEnabled(FALSE); - mTeleportBtn->setEnabled(FALSE); - mShowOnMapBtn->setEnabled(FALSE); - } -} diff --git a/indra/newview/llpanelplacestab.h b/indra/newview/llpanelplacestab.h index 5d6b7d1090..1c70869414 100644 --- a/indra/newview/llpanelplacestab.h +++ b/indra/newview/llpanelplacestab.h @@ -43,23 +43,21 @@ public: virtual ~LLPanelPlacesTab() {} virtual void onSearchEdit(const std::string& string) = 0; + virtual void updateVerbs() = 0; // Updates buttons at the bottom of Places panel //virtual void onShare() = 0; virtual void onShowOnMap() = 0; virtual void onTeleport() = 0; //virtual void onCopySLURL() = 0; + bool isTabVisible(); // Check if parent TabContainer is visible. + void setPanelPlacesButtons(LLPanelPlaces* panel); void onRegionResponse(const LLVector3d& landmark_global_pos, U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport); - void onTabSelected(); - protected: - void togglePanelPlacesButtons(BOOL enabled); - -private: //LLButton* mShareBtn; LLButton* mTeleportBtn; LLButton* mShowOnMapBtn; diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp new file mode 100644 index 0000000000..f97105caa8 --- /dev/null +++ b/indra/newview/llpanelprofile.cpp @@ -0,0 +1,156 @@ +/** +* @file llpanelprofile.cpp +* @brief Profile panel implementation +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llpanelprofile.h" +#include "lltabcontainer.h" +#include "llpanelpicks.h" +#include "llagent.h" +#include "llcommandhandler.h" +#include "llavataractions.h" + +static const std::string PANEL_PICKS = "panel_picks"; +static const std::string PANEL_NOTES = "panel_notes"; +static const std::string PANEL_PROFILE = "panel_profile"; + +static LLRegisterPanelClassWrapper t_panel_profile(PANEL_PROFILE); +static LLRegisterPanelClassWrapper t_panel_picks(PANEL_PICKS); + + +class LLAgentHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLAgentHandler() : LLCommandHandler("agent", true) { } + + bool handle(const LLSD& params, const LLSD& query_map, + LLWebBrowserCtrl* web) + { + if (params.size() < 2) return false; + LLUUID agent_id; + if (!agent_id.set(params[0], FALSE)) + { + return false; + } + + if (params[1].asString() == "about") + { + LLAvatarActions::showProfile(agent_id); + return true; + } + return false; + } +}; +LLAgentHandler gAgentHandler; + + +LLPanelProfile::LLPanelProfile() +: LLPanel(), + mTabContainer(NULL) +{ +} + +LLPanelProfile::~LLPanelProfile() +{ +} + +BOOL LLPanelProfile::postBuild() +{ + mTabContainer = getChild("tabs"); + mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabSelected, this, _2)); + + LLPanelPicks* panel_picks = getChild(PANEL_PICKS); + panel_picks->setProfilePanel(this); + mTabs[PANEL_PICKS] = panel_picks; + + mTabs[PANEL_PROFILE] = getChild(PANEL_PROFILE); + + return TRUE; +} + +//*TODO redo panel toggling +void LLPanelProfile::togglePanel(LLPanel* panel) +{ + // TRUE - we need to open/expand "panel" + BOOL expand = this->getChildList()->back() != panel; // mTabContainer->getVisible(); + + if (expand) + { + //*NOTE on view profile panel along with tabcontainer there is + // a backbutton that will be shown when there will be a panel over it even + //if that panel has visible backgroud + setAllChildrenVisible(FALSE); + + panel->setVisible(TRUE); + if (panel->getParent() != this) + { + addChildInBack(panel); + } + else + { + sendChildToBack(panel); + } + + LLRect new_rect = getRect(); + panel->reshape(new_rect.getWidth(), new_rect.getHeight()); + new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight()); + panel->setRect(new_rect); + } + else + { + this->setAllChildrenVisible(TRUE); + if (panel->getParent() == this) removeChild(panel); + sendChildToBack(mTabContainer); + mTabContainer->getCurrentPanel()->onOpen(mAvatarId); + } +} + + +void LLPanelProfile::onTabSelected(const LLSD& param) +{ + std::string tab_name = param.asString(); + if (NULL != mTabs[tab_name]) + { + mTabs[tab_name]->onOpen(mAvatarId); + } +} + +void LLPanelProfile::setAllChildrenVisible(BOOL visible) +{ + const child_list_t* child_list = getChildList(); + for (child_list_const_iter_t child_it = child_list->begin(); child_it != child_list->end(); ++child_it) + { + LLView* viewp = *child_it; + viewp->setVisible(visible); + } +} + diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h new file mode 100644 index 0000000000..2f6d53a859 --- /dev/null +++ b/indra/newview/llpanelprofile.h @@ -0,0 +1,72 @@ +/** +* @file llpanelprofile.h +* @brief Profile panel +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#ifndef LL_LLPANELPROFILE_H +#define LL_LLPANELPROFILE_H + +#include "llviewerprecompiledheaders.h" +#include "llpanel.h" +#include "llpanelavatar.h" + +class LLTabContainer; + +class LLPanelProfile : public LLPanel +{ + LOG_CLASS(LLPanelProfile); + +public: + virtual BOOL postBuild(); + + virtual void onOpen(const LLSD& key) {}; + + virtual void togglePanel(LLPanel*); + +protected: + LLPanelProfile(); + ~LLPanelProfile(); + + void onTabSelected(const LLSD& param); + + void setAllChildrenVisible(BOOL visible); + + + LLTabContainer* mTabContainer; + + typedef std::map profile_tabs_t; + profile_tabs_t mTabs; + + LLUUID mAvatarId; +}; + + + +#endif //LL_LLPANELPROFILE_H diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp index 0d25272f88..00254ee8ee 100644 --- a/indra/newview/llpanelprofileview.cpp +++ b/indra/newview/llpanelprofileview.cpp @@ -32,11 +32,11 @@ #include "llviewerprecompiledheaders.h" #include "llpanelprofileview.h" -#include -#include -#include + #include "llpanelavatar.h" #include "llpanelpicks.h" +#include "llsidetraypanelcontainer.h" +#include "llpanelprofile.h" static LLRegisterPanelClassWrapper t_panel_target_profile("panel_profile_view"); static LLRegisterPanelClassWrapper t_panel_notes("panel_notes"); @@ -46,7 +46,7 @@ static std::string PANEL_PICKS = "panel_picks"; static std::string PANEL_NOTES = "panel_notes"; LLPanelProfileView::LLPanelProfileView() -: LLPanel() +: LLPanelProfile() { } @@ -57,37 +57,31 @@ LLPanelProfileView::~LLPanelProfileView(void) /*virtual*/ void LLPanelProfileView::onOpen(const LLSD& key) { - if (!getVisible()) - setVisible(TRUE); + LLUUID id = key["id"]; + if (key.has("open_tab_name")) + mTabContainer->selectTabByName(key["open_tab_name"]); - LLUUID id(key.asUUID()); - if(id.notNull() && mProfileId.notNull() && mProfileId != id) + if(id.notNull() && mAvatarId != id) { + mAvatarId = id; + mTabs[PANEL_PROFILE]->clear(); mTabs[PANEL_PICKS]->clear(); mTabs[PANEL_NOTES]->clear(); } - mProfileId = id; - mTabs[PANEL_PROFILE]->onOpen(mProfileId); - mTabs[PANEL_PICKS]->setAvatarId(mProfileId); - mTabs[PANEL_PICKS]->updateData(); - mTabs[PANEL_NOTES]->setAvatarId(mProfileId); - mTabs[PANEL_NOTES]->updateData(); + mTabContainer->getCurrentPanel()->onOpen(mAvatarId); std::string full_name; - gCacheName->getFullName(key,full_name); + gCacheName->getFullName(mAvatarId,full_name); childSetValue("user_name",full_name); } BOOL LLPanelProfileView::postBuild() { - mTabContainer = getChild("profile_tabs"); - mTabContainer->setCommitCallback(boost::bind(&LLPanelProfileView::onTabSelected, this, _2)); + LLPanelProfile::postBuild(); - mTabs[PANEL_PROFILE] = (getChild(PANEL_PROFILE)); - mTabs[PANEL_PICKS] = (getChild(PANEL_PICKS)); mTabs[PANEL_NOTES] = (getChild(PANEL_NOTES)); childSetCommitCallback("back",boost::bind(&LLPanelProfileView::onBackBtnClick,this),NULL); @@ -98,15 +92,11 @@ BOOL LLPanelProfileView::postBuild() //private -void LLPanelProfileView::initTabs(const LLSD& key) -{ -} - -void LLPanelProfileView::onTabSelected(const LLSD& param) -{ -} - void LLPanelProfileView::onBackBtnClick() { - setVisible(FALSE); + LLSideTrayPanelContainer* parent = dynamic_cast(getParent()); + if(parent) + { + parent->openPreviousPanel(); + } } diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h index 2d89f15fe4..6c5fc77951 100644 --- a/indra/newview/llpanelprofileview.h +++ b/indra/newview/llpanelprofileview.h @@ -33,12 +33,13 @@ #ifndef LL_LLPANELPROFILEVIEW_H #define LL_LLPANELPROFILEVIEW_H -#include +#include "llpanel.h" +#include "llpanelprofile.h" +class LLPanelProfile; class LLPanelProfileTab; -class LLTabContainer; -class LLPanelProfileView : public LLPanel +class LLPanelProfileView : public LLPanelProfile { LOG_CLASS(LLPanelProfileView); friend class LLUICtrlFactory; @@ -48,22 +49,10 @@ public: ~LLPanelProfileView(void); - void onTabSelected(const LLSD& param); - void onOpen(const LLSD& key); BOOL postBuild(); - - void initTabs(const LLSD& key); - void onBackBtnClick(); - -private: - LLTabContainer* mTabContainer; - - typedef std::map profile_tabs_t; - profile_tabs_t mTabs; - LLUUID mProfileId; }; #endif //LL_LLPANELPROFILEVIEW_H diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index eb35834dc0..51cd05376a 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -92,8 +92,15 @@ void LLTeleportHistoryPanel::onShowOnMap() S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger(); - // teleport to existing item in history, so we don't add it again - mTeleportHistory->goToItem(index); + const LLTeleportHistory::slurl_list_t& hist_items = mTeleportHistory->getItems(); + + LLVector3d global_pos = hist_items[index].mGlobalPos; + + if (!global_pos.isExactlyZero()) + { + LLFloaterWorldMap::getInstance()->trackLocation(global_pos); + LLFloaterReg::showInstance("world_map", "center"); + } } // virtual @@ -104,7 +111,8 @@ void LLTeleportHistoryPanel::onTeleport() return; S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger(); - + + // teleport to existing item in history, so we don't add it again mTeleportHistory->goToItem(index); } @@ -132,6 +140,26 @@ void LLTeleportHistoryPanel::onCopySLURL() } */ +// virtual +void LLTeleportHistoryPanel::updateVerbs() +{ + if (!isTabVisible()) + return; + + S32 index = 0; + S32 cur_item = 0; + + LLScrollListItem* itemp = mHistoryItems->getFirstSelected(); + if (itemp) + { + index = itemp->getColumn(LIST_INDEX)->getValue().asInteger(); + cur_item = mTeleportHistory->getCurrentItemIndex(); + } + + mTeleportBtn->setEnabled(index != cur_item); + mShowOnMapBtn->setEnabled(itemp != NULL); +} + void LLTeleportHistoryPanel::showTeleportHistory() { const LLTeleportHistory::slurl_list_t& hist_items = mTeleportHistory->getItems(); @@ -181,17 +209,12 @@ void LLTeleportHistoryPanel::showTeleportHistory() } } - togglePanelPlacesButtons(mHistoryItems->getFirstSelected() != NULL); + updateVerbs(); } void LLTeleportHistoryPanel::handleItemSelect(const LLSD& data) { - LLScrollListItem* itemp = mHistoryItems->getFirstSelected(); - - if (!itemp) - return; - - togglePanelPlacesButtons(TRUE); + updateVerbs(); } //static @@ -204,7 +227,7 @@ void LLTeleportHistoryPanel::onDoubleClickItem(void* user_data) return; LLSD key; - key["type"] = LLPanelPlaces::TELEPORT_HISTORY; + key["type"] = "teleport_history"; key["id"] = itemp->getColumn(LIST_INDEX)->getValue().asInteger(); LLSideTray::getInstance()->showPanel("panel_places", key); diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index 6f41c97eec..553385b37e 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -50,7 +50,8 @@ public: /*virtual*/ void onShowOnMap(); /*virtual*/ void onTeleport(); ///*virtual*/ void onCopySLURL(); - + /*virtual*/ void updateVerbs(); + void showTeleportHistory(); void handleItemSelect(const LLSD& data); diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index 676943ff87..7faabbb28b 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -51,7 +51,7 @@ #include "llagent.h" #include "llvoavatarself.h" #include "llselectmgr.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llviewerinventory.h" #include "llviewerwindow.h" #include "lltrans.h" @@ -442,7 +442,7 @@ void LLPreview::handleReshape(const LLRect& new_rect, bool by_user) // LLMultiPreview::LLMultiPreview() - : LLMultiFloater() + : LLMultiFloater(LLSD()) { // *TODO: There should be a .xml file for this const LLRect& nextrect = LLFloaterReg::getFloaterRect("preview"); // place where the next preview should show up diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index 6857d14fff..6fe23e8aeb 100644 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -36,7 +36,7 @@ #include "llbutton.h" #include "llresmgr.h" #include "llinventory.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llvoavatarself.h" #include "llagent.h" // gAgent #include "llkeyframemotion.h" @@ -69,6 +69,8 @@ void LLPreviewAnim::endAnimCallback( void *userdata ) // virtual BOOL LLPreviewAnim::postBuild() { + mCloseSignal.connect(boost::bind(&LLPreviewAnim::onClose, this)); + const LLInventoryItem* item = getItem(); if(item) { @@ -180,7 +182,7 @@ void LLPreviewAnim::auditionAnim( void *userdata ) } } -void LLPreviewAnim::onClose(bool app_quitting) +void LLPreviewAnim::onClose() { const LLInventoryItem *item = getItem(); @@ -198,5 +200,4 @@ void LLPreviewAnim::onClose(bool app_quitting) motion->setDeactivateCallback(NULL, (void *)NULL); } } - destroy(); } diff --git a/indra/newview/llpreviewanim.h b/indra/newview/llpreviewanim.h index ca42b7e731..d24e624c32 100644 --- a/indra/newview/llpreviewanim.h +++ b/indra/newview/llpreviewanim.h @@ -49,7 +49,7 @@ public: void activate(e_activation_type type); protected: - virtual void onClose(bool app_quitting); + void onClose(); LLAnimPauseRequest mPauseRequest; LLUUID mItemID; diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index dc6ee44936..04827e3a78 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -260,11 +260,9 @@ BOOL LLPreviewGesture::canClose() } } -// virtual -void LLPreviewGesture::onClose(bool app_quitting) +void LLPreviewGesture::onClose() { - gGestureManager.stopGesture(mPreviewGesture); - LLPreview::onClose(app_quitting); + LLGestureManager::instance().stopGesture(mPreviewGesture); } // virtual @@ -273,18 +271,11 @@ void LLPreviewGesture::onUpdateSucceeded() refresh(); } -// virtual -void LLPreviewGesture::setMinimized(BOOL minimize) +void LLPreviewGesture::onVisibilityChange ( const LLSD& new_visibility ) { - if (minimize != isMinimized()) + if (new_visibility.asBoolean()) { - LLFloater::setMinimized(minimize); - - // We're being restored - if (!minimize) - { - refresh(); - } + refresh(); } } @@ -295,13 +286,13 @@ bool LLPreviewGesture::handleSaveChangesDialog(const LLSD& notification, const L switch(option) { case 0: // "Yes" - gGestureManager.stopGesture(mPreviewGesture); + LLGestureManager::instance().stopGesture(mPreviewGesture); mCloseAfterSave = TRUE; onClickSave(this); break; case 1: // "No" - gGestureManager.stopGesture(mPreviewGesture); + LLGestureManager::instance().stopGesture(mPreviewGesture); mDirty = FALSE; // Force the dirty flag because user has clicked NO on confirm save dialog... closeFloater(); break; @@ -363,6 +354,9 @@ LLPreviewGesture::~LLPreviewGesture() BOOL LLPreviewGesture::postBuild() { + mCloseSignal.connect(boost::bind(&LLPreviewGesture::onClose, this)); + mVisibleSignal.connect(boost::bind(&LLPreviewGesture::onVisibilityChange, this, _2)); + LLLineEditor* edit; LLComboBox* combo; LLButton* btn; @@ -559,7 +553,7 @@ void LLPreviewGesture::addAnimations() PERM_ITEM_UNRESTRICTED, gAgent.getID(), gAgent.getGroupID()); - gInventory.collectDescendentsIf(gAgent.getInventoryRootID(), + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, @@ -604,7 +598,7 @@ void LLPreviewGesture::addSounds() PERM_ITEM_UNRESTRICTED, gAgent.getID(), gAgent.getGroupID()); - gInventory.collectDescendentsIf(gAgent.getInventoryRootID(), + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, @@ -778,7 +772,7 @@ void LLPreviewGesture::refresh() mOptionsText->setText(optionstext); - BOOL active = gGestureManager.isGestureActive(mItemUUID); + BOOL active = LLGestureManager::instance().isGestureActive(mItemUUID); mActiveCheck->set(active); // Can only preview if there are steps @@ -1130,10 +1124,10 @@ void LLPreviewGesture::saveIfNeeded() // If this gesture is active, then we need to update the in-memory // active map with the new pointer. - if (!delayedUpload && gGestureManager.isGestureActive(mItemUUID)) + if (!delayedUpload && LLGestureManager::instance().isGestureActive(mItemUUID)) { // gesture manager now owns the pointer - gGestureManager.replaceGesture(mItemUUID, gesture, asset_id); + LLGestureManager::instance().replaceGesture(mItemUUID, gesture, asset_id); // replaceGesture may deactivate other gestures so let the // inventory know. @@ -1694,13 +1688,13 @@ void LLPreviewGesture::onClickDelete(void* data) void LLPreviewGesture::onCommitActive(LLUICtrl* ctrl, void* data) { LLPreviewGesture* self = (LLPreviewGesture*)data; - if (!gGestureManager.isGestureActive(self->mItemUUID)) + if (!LLGestureManager::instance().isGestureActive(self->mItemUUID)) { - gGestureManager.activateGesture(self->mItemUUID); + LLGestureManager::instance().activateGesture(self->mItemUUID); } else { - gGestureManager.deactivateGesture(self->mItemUUID); + LLGestureManager::instance().deactivateGesture(self->mItemUUID); } // Make sure the (active) label in the inventory gets updated. @@ -1739,14 +1733,14 @@ void LLPreviewGesture::onClickPreview(void* data) self->mPreviewBtn->setLabel(self->getString("stop_txt")); // play it, and delete when done - gGestureManager.playGesture(self->mPreviewGesture); + LLGestureManager::instance().playGesture(self->mPreviewGesture); self->refresh(); } else { // Will call onDonePreview() below - gGestureManager.stopGesture(self->mPreviewGesture); + LLGestureManager::instance().stopGesture(self->mPreviewGesture); self->refresh(); } diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h index d3e9c77789..16ac935775 100644 --- a/indra/newview/llpreviewgesture.h +++ b/indra/newview/llpreviewgesture.h @@ -70,8 +70,6 @@ public: // LLFloater /*virtual*/ BOOL canClose(); - /*virtual*/ void setMinimized(BOOL minimize); - /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void onUpdateSucceeded(); /*virtual*/ void refresh(); @@ -109,7 +107,10 @@ protected: // Add a step. Pass the name of the step, like "Animation", // "Sound", "Chat", or "Wait" LLScrollListItem* addStep(const enum EStepType step_type); - + + void onClose(); + void onVisibilityChange ( const LLSD& new_visibility ); + static std::string getLabel(std::vector labels); static void updateLabel(LLScrollListItem* item); diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 7c50bc5977..ad978cc5b3 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -156,10 +156,10 @@ private: LLFloaterScriptSearch* LLFloaterScriptSearch::sInstance = NULL; LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core) -: LLFloater(), +: LLFloater(LLSD()), mEditorCore(editor_core) { - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_search.xml"); + LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_search.xml", NULL); sInstance = this; @@ -640,8 +640,8 @@ void LLScriptEdCore::onBtnDynamicHelp() return; } - live_help_floater = new LLFloater(); - LLUICtrlFactory::getInstance()->buildFloater(live_help_floater, "floater_lsl_guide.xml"); + live_help_floater = new LLFloater(LLSD()); + LLUICtrlFactory::getInstance()->buildFloater(live_help_floater, "floater_lsl_guide.xml", NULL); LLFloater* parent = dynamic_cast(getParent()); parent->addDependentFloater(live_help_floater, TRUE); live_help_floater->childSetCommitCallback("lock_check", onCheckLock, this); @@ -973,7 +973,7 @@ void LLPreviewLSL::loadAsset() const LLInventoryItem* item = gInventory.getItem(mItemUUID); BOOL is_library = item && !gInventory.isObjectDescendentOf(mItemUUID, - gAgent.getInventoryRootID()); + gInventory.getRootFolderID()); if(!item) { // do the more generic search. diff --git a/indra/newview/llpreviewsound.cpp b/indra/newview/llpreviewsound.cpp index 7e7be5b2c6..84f7562297 100644 --- a/indra/newview/llpreviewsound.cpp +++ b/indra/newview/llpreviewsound.cpp @@ -36,7 +36,7 @@ #include "llagent.h" // gAgent #include "llbutton.h" #include "llinventory.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "lllineeditor.h" #include "llpreviewsound.h" #include "llresmgr.h" diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 3204006e43..9122e49a06 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -39,15 +39,15 @@ #include "llfilepicker.h" #include "llfloaterreg.h" #include "llimagetga.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llinventory.h" #include "llresmgr.h" #include "lltrans.h" #include "lltextbox.h" #include "lltextureview.h" #include "llui.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" #include "lllineeditor.h" @@ -205,7 +205,7 @@ void LLPreviewTexture::draw() LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); - F32 data_progress = mImage->mDownloadProgress; + F32 data_progress = mImage->getDownloadProgress() ; // Draw the progress bar. const S32 BAR_HEIGHT = 12; @@ -295,7 +295,7 @@ void LLPreviewTexture::onFocusReceived() // static void LLPreviewTexture::onFileLoadedForSave(BOOL success, - LLViewerImage *src_vi, + LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, @@ -357,8 +357,8 @@ void LLPreviewTexture::updateDimensions() mUpdateDimensions = FALSE; - S32 image_height = llmax(1, mImage->getHeight(0)); - S32 image_width = llmax(1, mImage->getWidth(0)); + S32 image_height = llmax(1, mImage->getFullHeight()); + S32 image_width = llmax(1, mImage->getFullWidth()); // Attempt to make the image 1:1 on screen. // If that fails, cut width by half. S32 client_width = image_width; @@ -379,8 +379,8 @@ void LLPreviewTexture::updateDimensions() S32 view_height = client_height + vert_pad; // set text on dimensions display (should be moved out of here and into a callback of some sort) - childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->mFullWidth)); - childSetTextArg("dimensions", "[HEIGHT]", llformat("%d", mImage->mFullHeight)); + childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->getFullWidth())); + childSetTextArg("dimensions", "[HEIGHT]", llformat("%d", mImage->getFullHeight())); // add space for dimensions S32 info_height = 0; @@ -464,15 +464,15 @@ void LLPreviewTexture::updateDimensions() void LLPreviewTexture::loadAsset() { - mImage = gImageList.getImage(mImageID, MIPMAP_TRUE, FALSE); - mImage->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + mImage = LLViewerTextureManager::getFetchedTexture(mImageID, MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); + mImage->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); mAssetStatus = PREVIEW_ASSET_LOADING; updateDimensions(); } LLPreview::EAssetStatus LLPreviewTexture::getAssetStatus() { - if (mImage.notNull() && (mImage->mFullWidth * mImage->mFullHeight > 0)) + if (mImage.notNull() && (mImage->getFullWidth() * mImage->getFullHeight() > 0)) { mAssetStatus = PREVIEW_ASSET_LOADED; } diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h index 45b173e7bf..9ace304fa6 100644 --- a/indra/newview/llpreviewtexture.h +++ b/indra/newview/llpreviewtexture.h @@ -36,7 +36,7 @@ #include "llpreview.h" #include "llbutton.h" #include "llframetimer.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLImageRaw; @@ -60,7 +60,7 @@ public: static void saveToFile(void* userdata); static void onFileLoadedForSave( BOOL success, - LLViewerImage *src_vi, + LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, @@ -75,7 +75,7 @@ protected: private: void updateDimensions(); LLUUID mImageID; - LLPointer mImage; + LLPointer mImage; BOOL mLoadingFullImage; std::string mSaveFileName; LLFrameTimer mSavedFileTimer; diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 38d617e468..f70cfc59ec 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -40,7 +40,6 @@ #include "llrender.h" #include "llui.h" #include "llfontgl.h" -#include "llimagegl.h" #include "lltimer.h" #include "lltextbox.h" #include "llglheaders.h" @@ -51,7 +50,7 @@ #include "llprogressbar.h" #include "llstartup.h" #include "llviewercontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llappviewer.h" #include "llweb.h" @@ -147,10 +146,10 @@ void LLProgressView::draw() // Paint bitmap if we've got one glPushMatrix(); - if (gStartImageGL) + if (gStartTexture) { LLGLSUIDefault gls_ui; - gGL.getTexUnit(0)->bind(gStartImageGL); + gGL.getTexUnit(0)->bind(gStartTexture.get()); gGL.color4f(1.f, 1.f, 1.f, mFadeTimer.getStarted() ? clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, FADE_IN_TIME, 1.f, 0.f) : 1.f); F32 image_aspect = (F32)gStartImageWidth / (F32)gStartImageHeight; S32 width = getRect().getWidth(); @@ -186,7 +185,7 @@ void LLProgressView::draw() { gFocusMgr.removeTopCtrlWithoutCallback(this); LLPanel::setVisible(FALSE); - gStartImageGL = NULL; + gStartTexture = NULL; } return; } diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp index fe4e8b5d0c..1ac0175b83 100644 --- a/indra/newview/llremoteparcelrequest.cpp +++ b/indra/newview/llremoteparcelrequest.cpp @@ -57,7 +57,13 @@ void LLRemoteParcelRequestResponder::result(const LLSD& content) { LLUUID parcel_id = content["parcel_id"]; - mObserverHandle.get()->setParcelID(parcel_id); + // Panel inspecting the information may be closed and destroyed + // before this response is received. + LLRemoteParcelInfoObserver* observer = mObserverHandle.get(); + if (observer) + { + observer->setParcelID(parcel_id); + } } //If we get back an error (not found, etc...), handle it here @@ -67,7 +73,13 @@ void LLRemoteParcelRequestResponder::error(U32 status, const std::string& reason llinfos << "LLRemoteParcelRequest::error(" << status << ": " << reason << ")" << llendl; - mObserverHandle.get()->setErrorStatus(status, reason); + // Panel inspecting the information may be closed and destroyed + // before this response is received. + LLRemoteParcelInfoObserver* observer = mObserverHandle.get(); + if (observer) + { + observer->setErrorStatus(status, reason); + } } void LLRemoteParcelInfoProcessor::addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer) diff --git a/indra/newview/llrootview.h b/indra/newview/llrootview.h index af9517f922..f704fecddd 100644 --- a/indra/newview/llrootview.h +++ b/indra/newview/llrootview.h @@ -36,20 +36,16 @@ #include "llview.h" #include "lluictrlfactory.h" -class LLRootViewRegistry : public LLWidgetRegistry +class LLRootViewRegistry : public LLChildRegistry {}; class LLRootView : public LLView { public: + typedef LLRootViewRegistry child_registry_t; + LLRootView(const Params& p) : LLView(p) {} - - const widget_registry_t& getChildRegistry() const - { - // use default widget registry - return LLRootViewRegistry::instance(); - } }; #endif //LL_LLROOTVIEW_H diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp new file mode 100644 index 0000000000..5ae79f6c63 --- /dev/null +++ b/indra/newview/llscreenchannel.cpp @@ -0,0 +1,409 @@ +/** + * @file llscreenchannel.cpp + * @brief Class implements a channel on a screen in which appropriate toasts may appear. + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "lliconctrl.h" +#include "lltextbox.h" +#include "llscreenchannel.h" + +#include "llviewercontrol.h" + +#include + +using namespace LLNotificationsUI; + +bool LLScreenChannel::mWasStartUpToastShown = false; + +//-------------------------------------------------------------------------- +LLScreenChannel::LLScreenChannel(): mUnreadToastsPanel(NULL), + mToastAlignment(NA_BOTTOM), + mStoreToasts(true), + mHiddenToastsNum(0), + mOverflowToastHidden(false), + mIsHovering(false), + mControlHovering(false) +{ + setFollows(FOLLOWS_RIGHT | FOLLOWS_BOTTOM | FOLLOWS_TOP); + + //TODO: load as a resource string + mOverflowFormatString = "You have %d more notification"; + + mToastList.clear(); + setMouseOpaque( false ); +} + +void LLScreenChannel::init(S32 channel_left, S32 channel_right) +{ + S32 channel_top = getRootView()->getRect().getHeight() - gSavedSettings.getS32("NavBarMargin"); + S32 channel_bottom = getRootView()->getRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin"); + setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom)); + +} + +//-------------------------------------------------------------------------- +LLScreenChannel::~LLScreenChannel() +{ +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLUICtrl::reshape(width, height, called_from_parent); + if(mToastAlignment != NA_CENTRE) + showToasts(); +} + +//-------------------------------------------------------------------------- +LLToast* LLScreenChannel::addToast(LLUUID id, LLPanel* panel, bool is_not_tip) +{ + ToastElem new_toast_elem(id, panel); + + mOverflowToastHidden = false; + + mToastList.push_back(new_toast_elem); + getRootView()->addChild(new_toast_elem.toast); + new_toast_elem.toast->setOnFadeCallback(boost::bind(&LLScreenChannel::onToastFade, this, new_toast_elem.toast)); + if(mControlHovering) + { + new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2)); + } + + // don't show toasts until StartUp toast will fade, but show alerts + if(!mWasStartUpToastShown && mToastAlignment != NA_CENTRE) + { + new_toast_elem.toast->stopTimer(); + // Count and store only non tip notifications + if(is_not_tip) + { + mHiddenToastsNum++; + storeToast(new_toast_elem); + } + else + { + // destroy tip toasts at once + new_toast_elem.toast->close(); + } + // remove toast from channel + mToastList.pop_back(); + } + else + { + showToasts(); + } + + return new_toast_elem.toast; +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::onToastFade(LLToast* toast) +{ + std::vector::iterator it = find(mToastList.begin(), mToastList.end(), static_cast(toast)); + + bool destroy_toast = toast->isViewed() || !mStoreToasts || !toast->getCanBeStored(); + if(destroy_toast) + { + mToastList.erase(it); + toast->mOnToastDestroy(toast, LLSD()); + } + else + { + storeToast((*it)); + mToastList.erase(it); + } + + showToasts(); +} + +//-------------------------------------------------------------------------- + +void LLScreenChannel::storeToast(ToastElem& toast_elem) +{ + mStoredToastList.push_back(toast_elem); +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::loadStoredToastsToChannel() +{ + std::vector::iterator it; + + if(mStoredToastList.size() == 0) + return; + + mOverflowToastHidden = false; + + for(it = mStoredToastList.begin(); it != mStoredToastList.end(); ++it) + { + (*it).toast->resetTimer(); + mToastList.push_back((*it)); + } + + mStoredToastList.clear(); + showToasts(); +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::killToastByNotificationID(LLUUID id) +{ + std::vector::iterator it = find(mToastList.begin(), mToastList.end(), id); + + if( it != mToastList.end()) + { + LLToast* toast = (*it).toast; + mToastList.erase(it); + toast->mOnToastDestroy(toast, LLSD()); + showToasts(); + } +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel) +{ + std::vector::iterator it = find(mToastList.begin(), mToastList.end(), id); + + if( it != mToastList.end() && panel) + { + LLToast* toast = (*it).toast; + LLPanel* old_panel = toast->getPanel(); + toast->removeChild(old_panel); + delete old_panel; + toast->arrange(panel); + toast->resetTimer(); + showToasts(); + } +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::showToasts() +{ + if(mToastList.size() == 0 || mIsHovering) + return; + + hideToastsFromScreen(); + + switch(mToastAlignment) + { + case NA_TOP : + showToastsTop(); + break; + + case NA_CENTRE : + showToastsCentre(); + break; + + case NA_BOTTOM : + showToastsBottom(); + } +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::showToastsBottom() +{ + LLRect toast_rect; + S32 bottom = getRect().mBottom; + std::vector::reverse_iterator it; + + for(it = mToastList.rbegin(); it != mToastList.rend(); ++it) + { + if(it != mToastList.rbegin()) + { + bottom = (*(it-1)).toast->getRect().mTop; + } + + toast_rect = (*it).toast->getRect(); + toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight()); + (*it).toast->setRect(toast_rect); + + bool stop_showing_toasts = (*it).toast->getRect().mTop > getRect().getHeight(); + + if(!stop_showing_toasts) + { + if( it != mToastList.rend()-1) + { + stop_showing_toasts = ((*it).toast->getRect().mTop + gSavedSettings.getS32("OverflowToastHeight") + gSavedSettings.getS32("ToastMargin")) > getRect().getHeight(); + } + } + + if(stop_showing_toasts) + break; + + (*it).toast->setVisible(TRUE); + } + + if(it != mToastList.rend() && !mOverflowToastHidden) + { + mHiddenToastsNum = 0; + for(; it != mToastList.rend(); it++) + { + mHiddenToastsNum++; + } + createOverflowToast(bottom, gSavedSettings.getS32("NotificationToastTime")); + } +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::showToastsCentre() +{ + LLRect toast_rect; + S32 bottom = (getRect().mTop - getRect().mBottom)/2 + mToastList[0].toast->getRect().getHeight()/2; + std::vector::reverse_iterator it; + + for(it = mToastList.rbegin(); it != mToastList.rend(); ++it) + { + toast_rect = (*it).toast->getRect(); + toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight()); + (*it).toast->setRect(toast_rect); + + (*it).toast->setVisible(TRUE); + } +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::showToastsTop() +{ +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer) +{ + LLRect toast_rect; + mUnreadToastsPanel = new LLToast(NULL); + + if(!mUnreadToastsPanel) + return; + + mUnreadToastsPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onOverflowToastHide, this)); + + LLTextBox* text_box = mUnreadToastsPanel->getChild("toast_text"); + LLIconCtrl* icon = mUnreadToastsPanel->getChild("icon"); + std::string text = llformat(mOverflowFormatString.c_str(),mHiddenToastsNum); + if(mHiddenToastsNum == 1) + { + text += "."; + } + else + { + text += "s."; + } + + toast_rect = mUnreadToastsPanel->getRect(); + mUnreadToastsPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true); + toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), getRect().getWidth(), toast_rect.getHeight()); + mUnreadToastsPanel->setRect(toast_rect); + mUnreadToastsPanel->setAndStartTimer(timer); + getRootView()->addChild(mUnreadToastsPanel); + + text_box->setValue(text); + text_box->setVisible(TRUE); + icon->setVisible(TRUE); + + mUnreadToastsPanel->setVisible(TRUE); +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::onOverflowToastHide() +{ + mOverflowToastHidden = true; + onCommit(); +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::closeUnreadToastsPanel() +{ + if(mUnreadToastsPanel != NULL) + { + mUnreadToastsPanel->close(); + mUnreadToastsPanel = NULL; + } +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::hideToastsFromScreen() +{ + closeUnreadToastsPanel(); + for(std::vector::iterator it = mToastList.begin(); it != mToastList.end(); it++) + (*it).toast->setVisible(FALSE); +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::removeToastsFromChannel() +{ + hideToastsFromScreen(); + for(std::vector::iterator it = mToastList.begin(); it != mToastList.end(); it++) + { + (*it).toast->close(); + //toast->mOnToastDestroy(toast, LLSD()); //TODO: check OnToastDestroy handler for chat + } + mToastList.clear(); +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::onToastHover(LLToast* toast, bool mouse_enter) +{ + // because of LLViewerWindow::updateUI() that ALWAYS calls onMouseEnter BEFORE onMouseLeave + // we must check this to prevent incorrect setting for hovering in a channel + std::map::iterator it_first, it_second; + S32 stack_size = mToastEventStack.size(); + mIsHovering = mouse_enter; + + switch(stack_size) + { + case 0: + mToastEventStack.insert(std::pair(toast, mouse_enter)); + break; + case 1: + it_first = mToastEventStack.begin(); + if((*it_first).second && !mouse_enter && ((*it_first).first != toast) ) + { + mToastEventStack.clear(); + mIsHovering = true; + } + else + { + mToastEventStack.clear(); + mToastEventStack.insert(std::pair(toast, mouse_enter)); + } + break; + default: + LL_ERRS ("LLScreenChannel::onToastHover: stack size error " ) << stack_size << llendl; + } + + if(!mIsHovering) + showToasts(); +} + +//-------------------------------------------------------------------------- + + + + diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h new file mode 100644 index 0000000000..a205b913ab --- /dev/null +++ b/indra/newview/llscreenchannel.h @@ -0,0 +1,148 @@ +/** + * @file llscreenchannel.h + * @brief Class implements a channel on a screen in which appropriate toasts may appear. + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSCREENCHANNEL_H +#define LL_LLSCREENCHANNEL_H + +#include "lltoast.h" + +#include +#include + +namespace LLNotificationsUI +{ + +typedef enum e_notification_toast_alignment +{ + NA_TOP, + NA_CENTRE, + NA_BOTTOM, +} EToastAlignment; + + +/** + * Screen channel manages toasts visibility and positioning on the screen. + */ +class LLScreenChannel : public LLUICtrl +{ + friend class LLChannelManager; +public: + LLScreenChannel(); + virtual ~LLScreenChannel(); + + void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + + LLToast* addToast(LLUUID id, LLPanel* panel, bool is_not_tip = true); + void init(S32 channel_left, S32 channel_right); + + void killToastByNotificationID(LLUUID id); + void modifyToastByNotificationID(LLUUID id, LLPanel* panel); + + void setToastAlignment(e_notification_toast_alignment align) {mToastAlignment = align;} + + void setControlHovering(bool control) { mControlHovering = control; } + void setHovering(bool hovering) { mIsHovering = hovering; } + + void removeToastsFromChannel(); + void closeUnreadToastsPanel(); + void hideToastsFromScreen(); + + void setStoreToasts(bool store) { mStoreToasts = store; } + void loadStoredToastsToChannel(); + + void showToasts(); + + S32 getNumberOfHiddenToasts() { return mHiddenToastsNum;} + void setNumberOfHiddenToasts(S32 num) { mHiddenToastsNum = num;} + + static void setStartUpToastShown() { mWasStartUpToastShown = true; } + + e_notification_toast_alignment getToastAlignment() {return mToastAlignment;} + + void setOverflowFormatString ( std::string str) { mOverflowFormatString = str; } + +private: + struct ToastElem + { + LLUUID id; + LLToast* toast; + ToastElem(LLUUID lluuid, LLPanel* panel) : id(lluuid) + { + toast = new LLToast(panel); + } + + ToastElem(const ToastElem& toast_elem) + { + id = toast_elem.id; + toast = toast_elem.toast; + } + + bool operator == (const LLUUID &id_op) const + { + return (id == id_op); + } + + bool operator == (LLPanel* panel_op) const + { + return (toast == panel_op); + } + }; + + void onToastHover(LLToast* toast, bool mouse_enter); + + void onToastFade(LLToast* toast); + void storeToast(ToastElem& toast_elem); + + void showToastsBottom(); + void showToastsCentre(); + void showToastsTop(); + + void createOverflowToast(S32 bottom, F32 timer); + void onOverflowToastHide(); + + static bool mWasStartUpToastShown; + bool mControlHovering; + bool mIsHovering; + bool mStoreToasts; + bool mOverflowToastHidden; + S32 mHiddenToastsNum; + LLToast* mUnreadToastsPanel; + std::vector mToastList; + std::vector mStoredToastList; + e_notification_toast_alignment mToastAlignment; + std::map mToastEventStack; + + std::string mOverflowFormatString; +}; + +} +#endif diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index ed7c7dce12..5984af5df4 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -57,6 +57,7 @@ #include "llfloaterinspect.h" #include "llfloaterproperties.h" #include "llfloaterreporter.h" +#include "llfloaterreg.h" #include "llfloatertools.h" #include "llframetimer.h" #include "llhudeffecttrail.h" @@ -73,7 +74,7 @@ #include "llui.h" #include "llviewercamera.h" #include "llviewercontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewermenu.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -187,12 +188,12 @@ LLSelectMgr::LLSelectMgr() sHighlightUAnim = gSavedSettings.getF32("SelectionHighlightUAnim"); sHighlightVAnim = gSavedSettings.getF32("SelectionHighlightVAnim"); - sSilhouetteParentColor =gSavedSkinSettings.getColor("SilhouetteParentColor"); - sSilhouetteChildColor = gSavedSkinSettings.getColor("SilhouetteChildColor"); - sHighlightParentColor = gSavedSkinSettings.getColor("HighlightParentColor"); - sHighlightChildColor = gSavedSkinSettings.getColor("HighlightChildColor"); - sHighlightInspectColor = gSavedSkinSettings.getColor("HighlightInspectColor"); - sContextSilhouetteColor = gSavedSkinSettings.getColor("ContextSilhouetteColor")*0.5f; + sSilhouetteParentColor =LLUIColorTable::instance().getColor("SilhouetteParentColor"); + sSilhouetteChildColor = LLUIColorTable::instance().getColor("SilhouetteChildColor"); + sHighlightParentColor = LLUIColorTable::instance().getColor("HighlightParentColor"); + sHighlightChildColor = LLUIColorTable::instance().getColor("HighlightChildColor"); + sHighlightInspectColor = LLUIColorTable::instance().getColor("HighlightInspectColor"); + sContextSilhouetteColor = LLUIColorTable::instance().getColor("ContextSilhouetteColor")*0.5f; sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius"); @@ -1424,7 +1425,7 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid) // Texture picker defaults aren't inventory items // * Don't need to worry about permissions for them // * Can just apply the texture and be done with it. - objectp->setTEImage(te, gImageList.getImage(mImageID, TRUE, FALSE)); + objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE)); } return true; } @@ -1580,7 +1581,7 @@ BOOL LLSelectMgr::selectionRevertTextures() } else { - object->setTEImage(te, gImageList.getImage(id)); + object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE)); } } } @@ -4451,8 +4452,7 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use // the reporter widget askes the server for info about picked objects if (request_flags & COMPLAINT_REPORT_REQUEST ) { - EReportType report_type = COMPLAINT_REPORT ; - LLFloaterReporter *reporterp = LLFloaterReporter::getReporter(report_type); + LLFloaterReporter *reporterp = LLFloaterReg::findTypedInstance("reporter"); if (reporterp) { std::string fullname; @@ -4543,7 +4543,7 @@ void LLSelectMgr::updateSilhouettes() if (!mSilhouetteImagep) { - mSilhouetteImagep = gImageList.getImageFromFile("silhouette.j2c", TRUE, TRUE); + mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", TRUE, TRUE); } mHighlightedObjects->cleanupNodes(); @@ -4813,7 +4813,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) return; } - gGL.getTexUnit(0)->bind(mSilhouetteImagep.get()); + gGL.getTexUnit(0)->bind(mSilhouetteImagep); LLGLSPipelineSelection gls_select; gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); LLGLEnable blend(GL_BLEND); @@ -4842,8 +4842,12 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) } if (mSelectedObjects->getNumNodes()) { - LLUUID inspect_item_id = LLFloaterInspect::getSelectedUUID(); - + LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance("inspect"); + LLUUID inspect_item_id= LLUUID::null; + if(inspect_instance) + { + inspect_item_id = inspect_instance->getSelectedUUID(); + } for (S32 pass = 0; pass < 2; pass++) { for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); @@ -5400,7 +5404,12 @@ void dialog_refresh_all() } LLFloaterProperties::dirtyAll(); - LLFloaterInspect::dirty(); + + LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance("inspect"); + if(inspect_instance) + { + inspect_instance->dirty(); + } } S32 get_family_count(LLViewerObject *parent) diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 992cc1e906..cfc2b702fc 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -54,7 +54,7 @@ #include "boost/iterator/filter_iterator.hpp" class LLMessageSystem; -class LLViewerImage; +class LLViewerTexture; class LLViewerObject; class LLColor4; class LLVector3; @@ -690,7 +690,7 @@ private: static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle); private: - LLPointer mSilhouetteImagep; + LLPointer mSilhouetteImagep; LLObjectSelectionHandle mSelectedObjects; LLObjectSelectionHandle mHoverObjects; LLObjectSelectionHandle mHighlightedObjects; diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index e7008abe60..5f0fbe6ee5 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -36,23 +36,23 @@ #include "llsidetray.h" #include "llviewerwindow.h" -#include "llaccordionpanel.h" +#include "llaccordionctrl.h" #include "llfocusmgr.h" #include "llrootview.h" -#include "llcollapsiblectrl.h" +#include "llaccordionctrltab.h" #include "llfloater.h" //for gFloaterView #include "lliconctrl.h"//for Home tab icon +#include "llsidetraypanelcontainer.h" #include "llwindow.h"//for SetCursor -#include "llbottomtray.h"//for reshape //#include "llscrollcontainer.h" using namespace std; static LLRootViewRegistry::Register t1("side_tray"); -static LLDefaultWidgetRegistry::Register t2("sidetray_tab"); +static LLDefaultChildRegistry::Register t2("sidetray_tab"); static const std::string COLLAPSED_NAME = "<<"; static const std::string EXPANDED_NAME = ">>"; @@ -64,24 +64,11 @@ LLSideTray* LLSideTray::sInstance = 0; class LLSideTrayInfoPanel: public LLPanel { -protected: - LLSideTrayInfoPanel(){} + public: - static LLSideTrayInfoPanel* createInstance(const string& image, const string& name,const string& description) + LLSideTrayInfoPanel():LLPanel() { - LLSideTrayInfoPanel* panel = new LLSideTrayInfoPanel(); - LLUICtrlFactory::getInstance()->buildPanel(panel,"panel_sidetray_tab_info.xml"); - if(panel) - panel->setData(image, name,description); - panel->setBorderVisible(true); - return panel; - - } - void setData(const string& image, const string& name,const string& description) - { - getChild("tab_name",false,false)->setValue(name); - getChild("tab_description",false,false)->setValue(description); - getChild("tab_icon",false,false)->setValue(image); + setBorderVisible(true); } BOOL handleHover(S32 x, S32 y, MASK mask) @@ -92,18 +79,25 @@ public: BOOL handleMouseUp(S32 x, S32 y, MASK mask) { + std::string name = getName(); onCommit(); + LLSideTray::getInstance()->selectTabByName(name); return LLPanel::handleMouseUp(x,y,mask); } + void reshape (S32 width, S32 height, BOOL called_from_parent ) + { + return LLPanel::reshape(width, height, called_from_parent); + } }; +static LLRegisterPanelClassWrapper t_people("panel_sidetray_home_info"); LLSideTray* LLSideTray::getInstance() { if (!sInstance) { - sInstance = LLUICtrlFactory::createFromFile("panel_side_tray.xml",gViewerWindow->getRootView()); + sInstance = LLUICtrlFactory::createFromFile("panel_side_tray.xml",gViewerWindow->getRootView(), LLRootView::child_registry_t::instance()); } return sInstance; @@ -114,41 +108,23 @@ bool LLSideTray::instanceCreated () return sInstance!=0; } -LLSideTrayTab::LLSideTrayTab(const Params& params):mAccordionPanel(0) +LLSideTrayTab::LLSideTrayTab(const Params& params):mMainPanel(0) { mImagePath = params.image_path; mTabTitle = params.tab_title; - mDescription = params.tab_description; + mDescription = params.description; } LLSideTrayTab::~LLSideTrayTab() { } -void LLSideTrayTab::addPanel(LLPanel* panel) -{ - //addChild(panel,false); -} - bool LLSideTrayTab::addChild(LLView* view, S32 tab_group) { - if(mAccordionPanel == 0) - { - mAccordionPanel = new LLAccordionPanel(); - mAccordionPanel->setVisible(TRUE); - LLPanel::addChild(mAccordionPanel,tab_group); - } - - - bool res = true; - if(TAB_PANEL_CAPTION_NAME != view->getName())//skip our caption panel - { - mAccordionPanel->addCollapsibleCtrl(view); - } - else - res = LLPanel::addChild(view,tab_group); - - return res; + if(mMainPanel == 0 && TAB_PANEL_CAPTION_NAME != view->getName())//skip our caption panel + mMainPanel = view; + return LLPanel::addChild(view,tab_group); + //return res; } @@ -156,14 +132,14 @@ bool LLSideTrayTab::addChild(LLView* view, S32 tab_group) //virtual BOOL LLSideTrayTab::postBuild() { - LLPanel* title_panel = LLUICtrlFactory::getInstance()->createFromFile("panel_side_tray_tab_caption.xml",this); + LLPanel* title_panel = LLUICtrlFactory::getInstance()->createFromFile("panel_side_tray_tab_caption.xml",this, child_registry_t::instance()); string name = title_panel->getName(); LLPanel::addChild(title_panel); title_panel->getChild(TAB_PANEL_CAPTION_TITLE_BOX)->setValue(mTabTitle); - static LLUICachedControl default_background_color ("FloaterDefaultBackgroundColor", *(new LLColor4)); - static LLUICachedControl focus_background_color ("FloaterFocusBackgroundColor", *(new LLColor4)); + static LLUIColor default_background_color = LLUIColorTable::instance().getColor("FloaterDefaultBackgroundColor"); + static LLUIColor focus_background_color = LLUIColorTable::instance().getColor("FloaterFocusBackgroundColor"); setTransparentColor(default_background_color); setBackgroundColor(focus_background_color); @@ -171,11 +147,6 @@ BOOL LLSideTrayTab::postBuild() return true; } -S32 LLSideTrayTab::getMaxSideBarTabWidth() -{ - return (mAccordionPanel)?mAccordionPanel->getMaxPanelWidth():0; -} - static const S32 splitter_margin = 1; //virtual @@ -191,17 +162,18 @@ void LLSideTrayTab::arrange(S32 width, S32 height ) offset = title_panel->getRect().getHeight(); } - LLRect sRect = mAccordionPanel->getRect(); + LLRect sRect = mMainPanel->getRect(); sRect.setLeftTopAndSize( splitter_margin, height - offset - splitter_margin, width - 2*splitter_margin, height - offset - 2*splitter_margin); - mAccordionPanel->setRect(sRect); + mMainPanel->reshape(sRect.getWidth(),sRect.getHeight()); + mMainPanel->setRect(sRect); + + - mAccordionPanel->setMaxWidth(sRect.getWidth()); - mAccordionPanel->arrange(); } void LLSideTrayTab::reshape (S32 width, S32 height, BOOL called_from_parent ) { - if(!mAccordionPanel) + if(!mMainPanel) return; S32 offset = 0; @@ -216,12 +188,12 @@ void LLSideTrayTab::reshape (S32 width, S32 height, BOOL called_from_parent ) - LLRect sRect = mAccordionPanel->getRect(); + LLRect sRect = mMainPanel->getRect(); sRect.setLeftTopAndSize( splitter_margin, height - offset - splitter_margin, width - 2*splitter_margin, height - offset - 2*splitter_margin); - mAccordionPanel->setMaxWidth(sRect.getWidth()); - mAccordionPanel->reshape(sRect.getWidth(), sRect.getHeight()); + //mMainPanel->setMaxWidth(sRect.getWidth()); + mMainPanel->reshape(sRect.getWidth(), sRect.getHeight()); - mAccordionPanel->setRect(sRect); + mMainPanel->setRect(sRect); } @@ -237,7 +209,9 @@ void LLSideTrayTab::draw() void LLSideTrayTab::onOpen (const LLSD& key) { - mAccordionPanel->onOpen(key); + LLPanel* panel = dynamic_cast(mMainPanel); + if(panel) + panel->onOpen(key); } LLSideTrayTab* LLSideTrayTab::createInstance () @@ -252,11 +226,11 @@ LLSideTrayTab* LLSideTrayTab::createInstance () //virtual LLSideTray::LLSideTray(Params& params) - :mActiveTab(0) + : LLPanel(params) + ,mActiveTab(0) ,mCollapsed(false) ,mCollapseButton(0) - ,mMaxBarWidth(0) - ,mHomeTab(0) + ,mMaxBarWidth(params.rect.width) { mCollapsed=params.collapsed; } @@ -264,14 +238,10 @@ LLSideTray::LLSideTray(Params& params) BOOL LLSideTray::postBuild() { - calcMaxSideBarWidth(); - createButtons(); - createHomeTab(); - arrange(); - selectTabByName("home_tab"); + selectTabByName("sidebar_home"); if(mCollapsed) collapseSideBar(); @@ -340,8 +310,6 @@ bool LLSideTray::selectTabByIndex(size_t index) bool LLSideTray::selectTabByName (const std::string& name) { LLSideTrayTab* side_bar = getTab(name); - if(side_bar == 0 && name == "home_tab") - side_bar = mHomeTab; if(side_bar == NULL || side_bar == mActiveTab) return false; @@ -374,7 +342,7 @@ bool LLSideTray::selectTabByName (const std::string& name) LLButton* LLSideTray::createButton (const std::string& name,const std::string& image,LLUICtrl::commit_callback_t callback) { - static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams()); + static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams()); LLButton::Params bparams; @@ -423,9 +391,10 @@ void LLSideTray::createButtons () mCollapseButton = createButton(EXPANDED_NAME,"",boost::bind(&LLSideTray::onToggleCollapse, this)); //create buttons for tabs - child_vector_const_iter_t child_it; + child_vector_const_iter_t child_it = mTabs.begin(); + ++child_it; - for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it) + for ( ; child_it != mTabs.end(); ++child_it) { LLSideTrayTab* sidebar_tab = dynamic_cast(*child_it); if(sidebar_tab == NULL) @@ -452,7 +421,7 @@ void LLSideTray::onToggleCollapse() if(mCollapsed) { expandSideBar(); - selectTabByName("home_tab"); + selectTabByName("sidebar_home"); } else collapseSideBar(); @@ -475,11 +444,7 @@ void LLSideTray::reflectCollapseChange() void LLSideTray::arrange () { - static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams()); - - calcMaxSideBarWidth(); - - + static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams()); setPanelRect(); @@ -528,10 +493,6 @@ void LLSideTray::arrange () sidebar_tab->setRect(ctrl_rect); sidebar_tab->arrange(mMaxBarWidth,getRect().getHeight()); } - - mHomeTab->setRect(ctrl_rect); - mHomeTab->arrange(mMaxBarWidth,getRect().getHeight()); - } void LLSideTray::collapseSideBar () @@ -553,25 +514,6 @@ void LLSideTray::expandSideBar () } -void LLSideTray::calcMaxSideBarWidth() -{ - - S32 max_bar_width = 0; - - - child_vector_const_iter_t child_it; - for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it) - { - LLSideTrayTab* sidebar_tab = dynamic_cast(*child_it); - if(sidebar_tab == NULL) - continue; - max_bar_width = llmax(max_bar_width,sidebar_tab->getMaxSideBarTabWidth()); - } - - if(max_bar_width > 0) - mMaxBarWidth = max_bar_width; - -} void LLSideTray::highlightFocused() { if(!mActiveTab) @@ -600,7 +542,7 @@ void LLSideTray::reshape (S32 width, S32 height, BOOL called_from_parent) if(!mActiveTab) return; - static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams()); + static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams()); setPanelRect(); @@ -649,19 +591,16 @@ void LLSideTray::reshape (S32 width, S32 height, BOOL called_from_parent) sidebar_tab->setRect(ctrl_rect); } - - mHomeTab->reshape(mMaxBarWidth,getRect().getHeight()); - ctrl_rect.setLeftTopAndSize(sidetray_params.default_button_width,getRect().getHeight(),mMaxBarWidth,getRect().getHeight()); - mHomeTab->setRect(ctrl_rect); - - } /** * Activate tab with "panel_name" panel - * if no such tab - return false, otherwise true + * if no such tab - return false, otherwise true. + * TODO* In some cases a pointer to a panel of + * a specific class may be needed so this method + * would need to use templates. */ -bool LLSideTray::showPanel (const std::string& panel_name, const LLSD& params) +LLPanel* LLSideTray::showPanel (const std::string& panel_name, const LLSD& params) { //arrange tabs child_vector_const_iter_t child_it; @@ -671,59 +610,34 @@ bool LLSideTray::showPanel (const std::string& panel_name, const LLSD& params) if(view) { onTabButtonClick((*child_it)->getName()); + + LLSideTrayPanelContainer* container = dynamic_cast(view->getParent()); + if(container) + { + LLSD new_params = params; + new_params[LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME] = panel_name; + container->onOpen(new_params); + + return container->getCurrentPanel(); + } + LLPanel* panel = dynamic_cast(view); if(panel) + { panel->onOpen(params); - return true; + } + return panel; } } - return false; + return NULL; } -void LLSideTray::createHomeTab() -{ - mHomeTab = LLSideTrayTab::createInstance(); - child_vector_iter_t child_it; - for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it) - { - LLSideTrayTab* sidebar_tab = dynamic_cast(*child_it); - if(sidebar_tab == NULL) - continue; - - LLPanel* panel = LLSideTrayInfoPanel::createInstance(sidebar_tab->mImagePath,sidebar_tab->getTabTitle(),sidebar_tab->getDescription()); - - panel->setCommitCallback(boost::bind(&LLSideTray::onTabButtonClick, this, sidebar_tab->getName())); - - LLCollapsibleCtrl::Params panel_params; - panel_params.display_children(true); - panel_params.collapsible(false); - panel_params.header_visible(false); - panel_params.can_resize(false); - panel_params.min_height(200); - panel_params.padding_left(10); - panel_params.padding_right(10); - panel_params.padding_top(5); - panel_params.padding_bottom(5); - - LLCollapsibleCtrl* ctrl = LLUICtrlFactory::create(panel_params); - - - ctrl->setPanel(panel); - ctrl->postBuild(); - mHomeTab->addChild(ctrl,0); - } - - mHomeTab->setBackgroundVisible(true); - mHomeTab->postBuild(); - - LLUICtrl::addChild(mHomeTab, 0); -} static const S32 fake_offset = 132; static const S32 fake_top_offset = 78; void LLSideTray::setPanelRect () { - static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams()); + static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams()); const LLRect& parent_rect = gViewerWindow->getRootView()->getRect(); @@ -732,8 +646,6 @@ void LLSideTray::setPanelRect () panel_width+=mMaxBarWidth; S32 panel_height = parent_rect.getHeight()-fake_top_offset; - panel_height -= LLBottomTray::getInstance()->getRect().getHeight(); - LLRect panel_rect; panel_rect.setLeftTopAndSize( parent_rect.mRight-panel_width, parent_rect.mTop-fake_top_offset, panel_width, panel_height); setRect(panel_rect); @@ -741,6 +653,6 @@ void LLSideTray::setPanelRect () S32 LLSideTray::getTrayWidth() { - static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams()); + static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams()); return getRect().getWidth() - (sidetray_params.default_button_width + sidetray_params.default_button_margin); } diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index 7d26925753..1f8b6b402f 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -37,7 +37,7 @@ #include "string" class LLSideTray; -class LLAccordionPanel; +class LLAccordionCtrl; class LLSideTrayTab: public LLPanel { @@ -51,21 +51,20 @@ public: // image name Optional image_path; Optional tab_title; - Optional tab_description; - Params():image_path("image","") - ,tab_title("tab_title","no title") - ,tab_description("description","no description") + Optional description; + Params() + : image_path("image"), + tab_title("tab_title","no title"), + description("description","no description") {}; }; protected: LLSideTrayTab(const Params& params); - S32 getMaxSideBarTabWidth(); public: virtual ~LLSideTrayTab(); - void addPanel (LLPanel* panel); /*virtual*/ BOOL postBuild (); /*virtual*/ bool addChild (LLView* view, S32 tab_group); @@ -87,7 +86,7 @@ private: std::string mImagePath; std::string mDescription; - LLAccordionPanel* mAccordionPanel; + LLView* mMainPanel; }; @@ -110,14 +109,14 @@ public: Optional default_button_height; Optional default_button_margin; - Params(): - collapsed("collapsed",false) - ,tab_btn_image_normal("tab_btn_image","sidebar_tab_left.tga") - ,tab_btn_image_selected("tab_btn_image_selected","button_enabled_selected_32x128.tga") - ,default_button_width("tab_btn_width",32) - ,default_button_height("tab_btn_height",32) - ,default_button_margin("tab_btn_margin",0) - {}; + Params() + : collapsed("collapsed",false), + tab_btn_image_normal("tab_btn_image","sidebar_tab_left.tga"), + tab_btn_image_selected("tab_btn_image_selected","button_enabled_selected_32x128.tga"), + default_button_width("tab_btn_width",32), + default_button_height("tab_btn_height",32), + default_button_margin("tab_btn_margin",0) + {}; }; static LLSideTray* getInstance (); @@ -163,9 +162,10 @@ public: /** * Activate tab with "panel_name" panel - * if no such tab - return false, otherwise true + * if no such tab - return NULL, otherwise a pointer to the panel + * Pass params as array, or they may be overwritten(example - params["name"]="nearby") */ - bool showPanel (const std::string& panel_name, const LLSD& params); + LLPanel* showPanel (const std::string& panel_name, const LLSD& params); /* * collapse SideBar, hiding visible tab and moving tab buttons @@ -209,15 +209,12 @@ protected: void createButtons (); LLButton* createButton (const std::string& name,const std::string& image,LLUICtrl::commit_callback_t callback); - void createHomeTab (); void arrange (); void reflectCollapseChange(); void toggleTabButton (LLSideTrayTab* tab); - void calcMaxSideBarWidth(); - void setPanelRect (); @@ -225,7 +222,6 @@ private: std::map mTabButtons; child_vector_t mTabs; - LLSideTrayTab* mHomeTab; LLSideTrayTab* mActiveTab; LLButton* mCollapseButton; diff --git a/indra/newview/llsidetraypanelcontainer.cpp b/indra/newview/llsidetraypanelcontainer.cpp new file mode 100644 index 0000000000..21061a802a --- /dev/null +++ b/indra/newview/llsidetraypanelcontainer.cpp @@ -0,0 +1,89 @@ +/** +* @file llsidetraypanelcontainer.cpp +* @brief LLSideTrayPanelContainer implementation +* +* $LicenseInfo:firstyear=2001&license=viewergpl$ +* +* Copyright (c) 2001-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llsidetraypanelcontainer.h" + +static LLDefaultChildRegistry::Register r2("panel_container"); + +std::string LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME = "sub_panel_name"; + +LLSideTrayPanelContainer::Params::Params() +{ + // Always hide tabs. + hide_tabs(true); +} + +LLSideTrayPanelContainer::LLSideTrayPanelContainer(const Params& p) + : LLTabContainer(p) +{ +} + +void LLSideTrayPanelContainer::onOpen(const LLSD& key) +{ + // Select specified panel and save navigation history. + if(key.has(PARAM_SUB_PANEL_NAME)) + { + // Save panel navigation history + std::string panel_name = key[PARAM_SUB_PANEL_NAME]; + S32 old_index = getCurrentPanelIndex(); + + selectTabByName(panel_name); + + S32 new_index = getCurrentPanelIndex(); + + // Don't update navigation history if we are opening same panel again. + if(old_index != new_index) + { + mPanelHistory[panel_name] = old_index; + } + } + // Will reopen current panel if no panel name was passed. + getCurrentPanel()->onOpen(key); +} + +void LLSideTrayPanelContainer::openPreviousPanel() +{ + std::string current_panel_name = getCurrentPanel()->getName(); + panel_navigation_history_t::const_iterator it = mPanelHistory.find(current_panel_name); + if(mPanelHistory.end() != it) + { + selectTab(it->second); + } +} + +BOOL LLSideTrayPanelContainer::handleKeyHere(KEY key, MASK mask) +{ + // No key press handling code for Panel Container - this disables + // Tab Container's Alt + Left/Right Button tab switching. + return TRUE; +} diff --git a/indra/newview/llsidetraypanelcontainer.h b/indra/newview/llsidetraypanelcontainer.h new file mode 100644 index 0000000000..3f3cb552f8 --- /dev/null +++ b/indra/newview/llsidetraypanelcontainer.h @@ -0,0 +1,95 @@ +/** +* @file llsidetraypanelcontainer.h +* @brief LLSideTrayPanelContainer class declaration +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#ifndef LL_LLSIDETRAY_PANEL_CONTAINER_H +#define LL_LLSIDETRAY_PANEL_CONTAINER_H + +#include "lltabcontainer.h" + +/** +* LLSideTrayPanelContainer class acts like LLTabContainer with invisible tabs. +* It is designed to make panel switching easier, avoid setVisible(TRUE) setVisible(FALSE) +* calls and related workarounds. +* use onOpen to open sub panel, pass the name of panel to open +* in key[PARAM_SUB_PANEL_NAME]. +* LLSideTrayPanelContainer also implements panel navigation history - it allows to +* open previous or next panel if navigation history is available(after user +* has opened two or more panels). *NOTE - only back navigation is implemented so far. +*/ +class LLSideTrayPanelContainer : public LLTabContainer +{ +public: + + struct Params : public LLInitParam::Block + { + Params(); + }; + + /** + * Opens sub panel + * @param key - params to be passed to panel, use key[PARAM_SUB_PANEL_NAME] + * to specify panel name to be opened. + */ + /*virtual*/ void onOpen(const LLSD& key); + + /** + * Opens previous panel from panel navigation history. + */ + void openPreviousPanel(); + + /** + * Overrides LLTabContainer::handleKeyHere to disable panel switch on + * Alt + Left/Right button press. + */ + BOOL handleKeyHere(KEY key, MASK mask); + + /** + * Name of parameter that stores panel name to open. + */ + static std::string PARAM_SUB_PANEL_NAME; + +protected: + LLSideTrayPanelContainer(const Params& p); + friend class LLUICtrlFactory; + + /** + * std::string - name of panel + * S32 - index of previous panel + * *NOTE - no forward navigation implemented yet + */ + typedef std::map panel_navigation_history_t; + + // Navigation history + panel_navigation_history_t mPanelHistory; +}; + +#endif //LL_LLSIDETRAY_PANEL_CONTAINER_H diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index f8b824732f..c4364ed6ca 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -577,7 +577,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) return; } - if (group->changeLOD()) + if (!LLPipeline::sSkipUpdate && group->changeLOD()) { group->mLastUpdateDistance = group->mDistance; group->mLastUpdateViewAngle = group->mViewAngle; @@ -826,7 +826,7 @@ class LLSpatialSetStateDiff : public LLSpatialSetState public: LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { } - virtual void traverse(const LLSpatialGroup::TreeNode* n) + virtual void traverse(const LLSpatialGroup::OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); @@ -885,7 +885,7 @@ class LLSpatialClearStateDiff : public LLSpatialClearState public: LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { } - virtual void traverse(const LLSpatialGroup::TreeNode* n) + virtual void traverse(const LLSpatialGroup::OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); @@ -1498,7 +1498,7 @@ public: return false; } - virtual void traverse(const LLSpatialGroup::TreeNode* n) + virtual void traverse(const LLSpatialGroup::OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); @@ -2356,7 +2356,7 @@ void renderTexturePriority(LLDrawable* drawable) LLGLDisable blend(GL_BLEND); - //LLViewerImage* imagep = facep->getTexture(); + //LLViewerTexture* imagep = facep->getTexture(); //if (imagep) { @@ -2386,7 +2386,7 @@ void renderTexturePriority(LLDrawable* drawable) /*S32 boost = imagep->getBoostLevel(); if (boost) { - F32 t = (F32) boost / (F32) (LLViewerImage::BOOST_MAX_LEVEL-1); + F32 t = (F32) boost / (F32) (LLViewerTexture::BOOST_MAX_LEVEL-1); LLVector4 col = lerp(boost_cold, boost_hot, t); LLGLEnable blend_on(GL_BLEND); gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); @@ -2896,7 +2896,7 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, con } LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, - LLViewerImage* texture, LLVertexBuffer* buffer, + LLViewerTexture* texture, LLVertexBuffer* buffer, BOOL fullbright, U8 bump, BOOL particle, F32 part_size) : mVertexBuffer(buffer), diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 8aec5c8377..13ab35402c 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -67,12 +67,12 @@ protected: public: LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, - LLViewerImage* image, LLVertexBuffer* buffer, + LLViewerTexture* image, LLVertexBuffer* buffer, BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); LLPointer mVertexBuffer; - LLPointer mTexture; + LLPointer mTexture; LLColor4U mGlowColor; S32 mDebugColor; const LLMatrix4* mTextureMatrix; @@ -164,7 +164,7 @@ public: typedef std::vector > drawmap_elem_t; typedef std::map draw_map_t; typedef std::vector > buffer_list_t; - typedef std::map, buffer_list_t> buffer_texture_map_t; + typedef std::map, buffer_list_t> buffer_texture_map_t; typedef std::map buffer_map_t; typedef LLOctreeListener BaseType; diff --git a/indra/newview/llsplitbutton.cpp b/indra/newview/llsplitbutton.cpp new file mode 100644 index 0000000000..ffd9bc7624 --- /dev/null +++ b/indra/newview/llsplitbutton.cpp @@ -0,0 +1,275 @@ +/** + * @file llsplitbutton.cpp + * @brief LLSplitButton base class + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +// A control that consolidates several buttons as options + +#include "llviewerprecompiledheaders.h" + +#include "llsplitbutton.h" + +#include "llinitparam.h" +#include "llpanel.h" +#include "llfocusmgr.h" +#include "llviewerwindow.h" +#include "llrootview.h" + + +S32 BUTTON_PAD = 2; //pad between buttons on an items panel + + +static LLDefaultChildRegistry::Register split_button("split_button"); + +void LLSplitButton::ArrowPositionValues::declareValues() +{ + declare("left", LEFT); + declare("right", RIGHT); +} + +LLSplitButton::ItemParams::ItemParams() +{ +} + +LLSplitButton::Params::Params() +: arrow_position("arrow_position", LEFT), + items("item"), + arrow_button("arrow_button"), + items_panel("items_panel") +{ +} + + +void LLSplitButton::onFocusLost() +{ + hideButtons(); + LLUICtrl::onFocusLost(); +} + +void LLSplitButton::setFocus(BOOL b) +{ + LLUICtrl::setFocus(b); + + if (b) + { + if (mItemsPanel && mItemsPanel->getVisible()) + { + mItemsPanel->setFocus(TRUE); + } + } +} + +void LLSplitButton::setEnabled(BOOL enabled) +{ + LLView::setEnabled(enabled); + mArrowBtn->setEnabled(enabled); +} + + +void LLSplitButton::onArrowBtnDown() +{ + if (!mItemsPanel->getVisible()) + { + showButtons(); + + setFocus(TRUE); + + if (mArrowBtn->hasMouseCapture() || mShownItem->hasMouseCapture()) + { + gFocusMgr.setMouseCapture(this); + } + } + else + { + hideButtons(); + } +} + +void LLSplitButton::onHeldDownShownButton() +{ + if (!mItemsPanel->getVisible()) onArrowBtnDown(); +} + +void LLSplitButton::onItemSelected(LLUICtrl* ctrl) +{ + if (!ctrl) return; + + hideButtons(); + + // call the callback if it exists + if(!mSelectionCallback.empty()) + { + mSelectionCallback(this, ctrl->getName()); + } + + gFocusMgr.setKeyboardFocus(NULL); +} + +BOOL LLSplitButton::handleMouseUp(S32 x, S32 y, MASK mask) +{ + gFocusMgr.setMouseCapture(NULL); + + if (mShownItem->parentPointInView(x, y)) + { + onItemSelected(mShownItem); + return TRUE; + } + + for (std::list::const_iterator it = mHidenItems.begin(); it != mHidenItems.end(); ++it) + { + LLButton* item = *it; + + S32 panel_x = 0; + S32 panel_y = 0; + localPointToOtherView(x, y, &panel_x, &panel_y, mItemsPanel); + + if (item->parentPointInView(panel_x, panel_y)) + { + onItemSelected(item); + return TRUE; + } + } + return TRUE; +} + +void LLSplitButton::showButtons() +{ + mItemsPanel->setOrigin(0, getRect().getHeight()); + + // register ourselves as a "top" control + // effectively putting us into a special draw layer + gFocusMgr.setTopCtrl(this); + + mItemsPanel->setFocus(TRUE); + + //push arrow button down and show the item buttons + mArrowBtn->setToggleState(TRUE); + mItemsPanel->setVisible(TRUE); + + setUseBoundingRect(TRUE); +} + +void LLSplitButton::hideButtons() +{ + mItemsPanel->setVisible(FALSE); + mArrowBtn->setToggleState(FALSE); + + setUseBoundingRect(FALSE); + if(gFocusMgr.getTopCtrl() == this) + { + gFocusMgr.setTopCtrl(NULL); + } +} + + +// protected/private + +LLSplitButton::LLSplitButton(const LLSplitButton::Params& p) +: LLUICtrl(p), + mArrowBtn(NULL), + mShownItem(NULL), + mItemsPanel(NULL), + mArrowPosition(p.arrow_position) +{ + LLRect rc(p.rect); + + LLButton::Params arrow_params = p.arrow_button; + S32 arrow_width = p.arrow_button.rect.width; + + //Default arrow rect values for LEFT arrow position + S32 arrow_left = 0; + S32 arrow_right = arrow_width; + S32 btn_left = arrow_width; + S32 btn_right = rc.getWidth(); + + if (mArrowPosition == RIGHT) + { + arrow_left = rc.getWidth()- arrow_width; + arrow_right = rc.getWidth(); + btn_left = 0; + btn_right = arrow_left; + } + + arrow_params.rect(LLRect(arrow_left, rc.getHeight(), arrow_right, 0)); + arrow_params.label(""); + arrow_params.mouse_down_callback.function(boost::bind(&LLSplitButton::onArrowBtnDown, this)); + mArrowBtn = LLUICtrlFactory::create(arrow_params); + addChild(mArrowBtn); + + //a panel for hidden item buttons + LLPanel::Params panel_params = p.items_panel; + mItemsPanel= prepareItemsPanel(panel_params, p.items.numValidElements()); + addChild(mItemsPanel); + + + LLInitParam::ParamIterator::const_iterator it = p.items().begin(); + + //processing shown item button + mShownItem = prepareItemButton(*it); + mShownItem->setHeldDownCallback(boost::bind(&LLSplitButton::onHeldDownShownButton, this)); + mShownItem->setMouseUpCallback(boost::bind(&LLSplitButton::onItemSelected, this, _1)); + mShownItem->setRect(LLRect(btn_left, rc.getHeight(), btn_right, 0)); + addChild(mShownItem); + + //processing hidden item buttons + S32 item_top = mItemsPanel->getRect().getHeight(); + for (++it; it != p.items().end(); ++it) + { + LLButton* hidden_button = prepareItemButton(*it); + hidden_button->setRect(LLRect(btn_left, item_top, btn_right, item_top - rc.getHeight())); + hidden_button->setMouseDownCallback(boost::bind(&LLSplitButton::onItemSelected, this, _1)); + mHidenItems.push_back(hidden_button); + mItemsPanel->addChild(hidden_button); + + //calculate next button's top + item_top -= (rc.getHeight() + BUTTON_PAD); + } + + setTopLostCallback(boost::bind(&LLSplitButton::hideButtons, this)); +} + + +LLButton* LLSplitButton::prepareItemButton(LLButton::Params params) +{ + params.label(""); + params.is_toggle(false); + return LLUICtrlFactory::create(params); +} + +LLPanel* LLSplitButton::prepareItemsPanel(LLPanel::Params params, S32 items_count) +{ + S32 num_hiden_btns = items_count - 1; + S32 panel_height = num_hiden_btns * (getRect().getHeight() + BUTTON_PAD); + params.visible(false); + params.rect.width(getRect().getWidth()); + params.rect.height(panel_height); + return LLUICtrlFactory::create(params); +} + diff --git a/indra/newview/llsplitbutton.h b/indra/newview/llsplitbutton.h new file mode 100644 index 0000000000..0fb5f6594e --- /dev/null +++ b/indra/newview/llsplitbutton.h @@ -0,0 +1,112 @@ +/** + * @file llsplitbutton.h + * @brief LLSplitButton base class + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +// A control that displays the name of the chosen item, which when clicked +// shows a scrolling box of choices. + + +#include "llbutton.h" +#include "llpanel.h" +#include "lluictrl.h" + + +#ifndef LL_LLSPLITBUTTON_H +#define LL_LLSPLITBUTTON_H + +class LLSplitButton + : public LLUICtrl +{ +public: + typedef enum e_arrow_position + { + LEFT, + RIGHT + } EArrowPosition; + + struct ArrowPositionValues : public LLInitParam::TypeValuesHelper + { + static void declareValues(); + }; + + struct ItemParams : public LLInitParam::Block + { + ItemParams(); + }; + + struct Params : public LLInitParam::Block + { + Optional arrow_position; + Optional arrow_button; + Optional items_panel; + Multiple items; + + Params(); + }; + + + virtual ~LLSplitButton() {}; + + //Overridden + virtual void onFocusLost(); + virtual void setFocus(BOOL b); + virtual void setEnabled(BOOL enabled); + + //Callbacks + void onArrowBtnDown(); + void onHeldDownShownButton(); + void onItemSelected(LLUICtrl* ctrl); + void setSelectionCallback(commit_callback_t cb) { mSelectionCallback = cb; } + + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + + virtual void showButtons(); + virtual void hideButtons(); + + +protected: + friend class LLUICtrlFactory; + LLSplitButton(const LLSplitButton::Params& p); + + LLButton* prepareItemButton(LLButton::Params params); + LLPanel* prepareItemsPanel(LLPanel::Params params, S32 items_count); + + LLPanel* mItemsPanel; + std::list mHidenItems; + LLButton* mArrowBtn; + LLButton* mShownItem; + EArrowPosition mArrowPosition; + + commit_callback_t mSelectionCallback; +}; + + +#endif diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp index 893ed22297..dce4e9d144 100644 --- a/indra/newview/llsprite.cpp +++ b/indra/newview/llsprite.cpp @@ -48,7 +48,7 @@ #include "lldrawable.h" #include "llface.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" LLVector3 LLSprite::sCameraUp(0.0f,0.0f,1.0f); LLVector3 LLSprite::sCameraRight(1.0f,0.0f,0.0f); diff --git a/indra/newview/llsprite.h b/indra/newview/llsprite.h index 28f4ec5d03..eefe2a2386 100644 --- a/indra/newview/llsprite.h +++ b/indra/newview/llsprite.h @@ -40,7 +40,7 @@ #include "v4color.h" #include "lluuid.h" #include "llgl.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLViewerCamera; @@ -82,7 +82,7 @@ public: public: LLUUID mImageID; - LLPointer mImagep; + LLPointer mImagep; private: F32 mWidth; F32 mHeight; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index eb585f8fe3..a2e879d24d 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -94,9 +94,6 @@ #include "llface.h" #include "llfeaturemanager.h" #include "llfirstuse.h" -#include "llfloateractivespeakers.h" -#include "llfloaterbeacons.h" -#include "llfloatercamera.h" #include "llfloaterchat.h" #include "llfloatergesture.h" #include "llfloaterhud.h" @@ -112,7 +109,7 @@ #include "llimagebmp.h" #include "llinventorybridge.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyboard.h" #include "llloginhandler.h" // gLoginHandler, SLURL support #include "lllogininstance.h" // Host the login module. @@ -153,7 +150,7 @@ #include "llviewerdisplay.h" #include "llviewergenericmessage.h" #include "llviewergesture.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewermedia.h" #include "llviewermenu.h" #include "llviewermessage.h" @@ -207,7 +204,7 @@ bool gAgentMovementCompleted = false; std::string SCREEN_HOME_FILENAME = "screen_home.bmp"; std::string SCREEN_LAST_FILENAME = "screen_last.bmp"; -LLPointer gStartImageGL; +LLPointer gStartTexture; // // Imported globals @@ -300,8 +297,11 @@ public: virtual void done() { // we've downloaded all the items, so repaint the dialog - LLFloaterGesture::refreshAll(); - + LLFloaterGesture* floater = LLFloaterReg::findTypedInstance("gestures"); + if (floater) + { + floater->refreshAll(); + } gInventory.removeObserver(this); delete this; } @@ -312,7 +312,7 @@ void update_texture_fetch() LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread - gImageList.updateImages(0.10f); + gTextureList.updateImages(0.10f); } // Returns false to skip other idle processing. Should only return @@ -369,7 +369,7 @@ bool idle_startup() if (!gNoRender) { // Update images? - gImageList.updateImages(0.01f); + gTextureList.updateImages(0.01f); } if ( STATE_FIRST == LLStartUp::getStartupState() ) @@ -453,13 +453,24 @@ bool idle_startup() #if LL_WINDOWS // On the windows dev builds, unpackaged, the message_template.msg - // file will be located in - // indra/build-vc**/newview//app_settings. + // file will be located in: + // build-vc**/newview//app_settings if (!found_template) { message_template_path = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "app_settings", "message_template.msg"); found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */ } + #elif LL_DARWIN + // On Mac dev builds, message_template.msg lives in: + // indra/build-*/newview//Second Life/Contents/Resources/app_settings + if (!found_template) + { + message_template_path = + gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, + "../Resources/app_settings", + "message_template.msg"); + found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */ + } #endif if (found_template) @@ -722,8 +733,10 @@ bool idle_startup() std::string msg = LLTrans::getString("LoginInitializingBrowser"); set_startup_status(0.03f, msg.c_str(), gAgent.mMOTD.c_str()); display_startup(); +#if !defined(LL_WINDOWS) || !defined(LL_DEBUG) + // This generates an error in debug mode on Windows LLViewerMedia::initBrowser(); - +#endif LLStartUp::setStartupState( STATE_LOGIN_SHOW ); return FALSE; } @@ -836,8 +849,6 @@ bool idle_startup() gDirUtilp->setLindenUserDir(gFirstname, gLastname); LLFile::mkdir(gDirUtilp->getLindenUserDir()); - LLLocationHistory::getInstance()->load(); - // Set PerAccountSettingsFile to the default value. gSavedSettings.setString("PerAccountSettingsFile", gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, @@ -856,10 +867,13 @@ bool idle_startup() } //Default the path if one isn't set. - if (gSavedPerAccountSettings.getString("InstantMessageLogPath").empty()) + if (gSavedPerAccountSettings.getString("InstantMessageLogFolder").empty()) { gDirUtilp->setChatLogsDir(gDirUtilp->getOSUserAppDir()); - gSavedPerAccountSettings.setString("InstantMessageLogPath",gDirUtilp->getChatLogsDir()); + std::string chat_log_dir = gDirUtilp->getChatLogsDir(); + std::string chat_log_top_folder=gDirUtilp->getBaseFileName(chat_log_dir); + gSavedPerAccountSettings.setString("InstantMessageLogPath",chat_log_dir); + gSavedPerAccountSettings.setString("InstantMessageLogFolder",chat_log_top_folder); } else { @@ -897,7 +911,7 @@ bool idle_startup() //For HTML parsing in text boxes. - LLTextEditor::setLinkColor( gSavedSkinSettings.getColor4("HTMLLinkColor") ); + LLTextEditor::setLinkColor( LLUIColorTable::instance().getColor("HTMLLinkColor") ); // Load URL History File LLURLHistory::loadFile("url_history.xml"); @@ -1102,12 +1116,12 @@ bool idle_startup() // Since we connected, save off the settings so the user doesn't have to // type the name/password again if we crash. gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); - gSavedSkinSettings.saveToFile(gSavedSettings.getString("SkinningSettingsFile"), TRUE); + LLUIColorTable::instance().saveUserSettings(); // // Initialize classes w/graphics stuff. // - gImageList.doPrefetchImages(); + gTextureList.doPrefetchImages(); LLSurface::initClasses(); LLFace::initClass(); @@ -1206,27 +1220,6 @@ bool idle_startup() } gLoginMenuBarView->setVisible( FALSE ); gLoginMenuBarView->setEnabled( FALSE ); - - LLFloaterReg::showInitialVisibleInstances(); - - if (gSavedSettings.getBOOL("ShowCameraControls")) - { - LLFloaterCamera::showInstance(); - } - if (gSavedSettings.getBOOL("ShowMovementControls")) - { - LLFloaterMove::showInstance(); - } - - if (gSavedSettings.getBOOL("ShowActiveSpeakers")) - { - LLFloaterActiveSpeakers::showInstance(); - } - - if (gSavedSettings.getBOOL("BeaconAlwaysOn")) - { - LLFloaterBeacons::showInstance(); - } if (!gNoRender) { @@ -1335,7 +1328,7 @@ bool idle_startup() F32 frac = (F32)i / (F32)DECODE_TIME_SEC; set_startup_status(0.45f + frac*0.1f, LLTrans::getString("LoginDecodingImages"), gAgent.mMOTD); display_startup(); - gImageList.decodeAllImages(1.f); + gTextureList.decodeAllImages(1.f); } LLStartUp::setStartupState( STATE_WORLD_WAIT ); @@ -1479,7 +1472,7 @@ bool idle_startup() LLSD id = inv_lib_root[0]["folder_id"]; if(id.isDefined()) { - gInventoryLibraryRoot = id.asUUID(); + gInventory.setLibraryRootFolderID(id.asUUID()); } } @@ -1490,14 +1483,14 @@ bool idle_startup() LLSD id = inv_lib_owner[0]["agent_id"]; if(id.isDefined()) { - gInventoryLibraryOwner = id.asUUID(); + gInventory.setLibraryOwnerID( LLUUID(id.asUUID())); } } LLSD inv_skel_lib = response["inventory-skel-lib"]; - if(inv_skel_lib.isDefined() && gInventoryLibraryOwner.notNull()) + if(inv_skel_lib.isDefined() && gInventory.getLibraryOwnerID().notNull()) { - if(!gInventory.loadSkeleton(inv_skel_lib, gInventoryLibraryOwner)) + if(!gInventory.loadSkeleton(inv_skel_lib, gInventory.getLibraryOwnerID())) { LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL; } @@ -1568,10 +1561,9 @@ bool idle_startup() // Either we want to show tutorial because this is the first login // to a Linden Help Island or the user quit with the tutorial // visible. JC - if (show_hud - || gSavedSettings.getBOOL("ShowTutorial")) + if (show_hud || gSavedSettings.getBOOL("ShowTutorial")) { - LLFloaterHUD::showHUD(); + LLFloaterReg::showInstance("hud", LLSD(), FALSE); } LLSD event_categories = response["event_categories"]; @@ -1671,6 +1663,7 @@ bool idle_startup() // We're successfully logged in. gSavedSettings.setBOOL("FirstLoginThisInstall", FALSE); + LLFloaterReg::showInitialVisibleInstances(); // based on the comments, we've successfully logged in so we can delete the 'forced' // URL that the updater set in settings.ini (in a mostly paranoid fashion) @@ -1682,7 +1675,7 @@ bool idle_startup() // and make sure it's saved gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile") , TRUE ); - gSavedSkinSettings.saveToFile( gSavedSettings.getString("SkinningSettingsFile") , TRUE ); + LLUIColorTable::instance().saveUserSettings(); }; if (!gNoRender) @@ -1713,7 +1706,7 @@ bool idle_startup() // Could schedule and delay these for later. const BOOL no_inform_server = FALSE; const BOOL no_deactivate_similar = FALSE; - gGestureManager.activateGestureWithAsset(item_id, asset_id, + LLGestureManager::instance().activateGestureWithAsset(item_id, asset_id, no_inform_server, no_deactivate_similar); // We need to fetch the inventory items for these gestures @@ -1935,9 +1928,11 @@ bool idle_startup() // Let the map know about the inventory. LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance(); - floater_world_map->observeInventory(&gInventory); - floater_world_map->observeFriends(); - + if(floater_world_map) + { + floater_world_map->observeInventory(&gInventory); + floater_world_map->observeFriends(); + } gViewerWindow->showCursor(); gViewerWindow->getWindow()->resetBusyCount(); gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); @@ -2001,6 +1996,8 @@ bool idle_startup() // reset timers now that we are running "logged in" logic LLFastTimer::reset(); + LLLocationHistory::getInstance()->load(); + return TRUE; } @@ -2059,7 +2056,7 @@ void login_callback(S32 option, void *userdata) { // turn off the setting and write out to disk gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile") , TRUE ); - gSavedSkinSettings.saveToFile( gSavedSettings.getString("SkinningSettingsFile") , TRUE ); + LLUIColorTable::instance().saveUserSettings(); } // Next iteration through main loop should shut down the app cleanly. @@ -2290,8 +2287,8 @@ void use_circuit_callback(void**, S32 result) void register_viewer_callbacks(LLMessageSystem* msg) { msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data ); - msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerImageList::receiveImageHeader ); - msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerImageList::receiveImagePacket ); + msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader ); + msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket ); msg->setHandlerFuncFast(_PREHASH_ObjectUpdate, process_object_update ); msg->setHandlerFunc("ObjectUpdateCompressed", process_compressed_object_update ); msg->setHandlerFunc("ObjectUpdateCached", process_cached_object_update ); @@ -2422,7 +2419,7 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFunc("TeleportFailed", process_teleport_failed, NULL); msg->setHandlerFunc("TeleportLocal", process_teleport_local, NULL); - msg->setHandlerFunc("ImageNotInDatabase", LLViewerImageList::processImageNotInDatabase, NULL); + msg->setHandlerFunc("ImageNotInDatabase", LLViewerTextureList::processImageNotInDatabase, NULL); msg->setHandlerFuncFast(_PREHASH_GroupMembersReply, LLGroupMgr::processGroupMembersReply); @@ -2553,9 +2550,9 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, // Loads a bitmap to display during load void init_start_screen(S32 location_id) { - if (gStartImageGL.notNull()) + if (gStartTexture.notNull()) { - gStartImageGL = NULL; + gStartTexture = NULL; LL_INFOS("AppInit") << "re-initializing start screen" << LL_ENDL; } @@ -2587,7 +2584,6 @@ void init_start_screen(S32 location_id) return; } - gStartImageGL = new LLImageGL(FALSE); gStartImageWidth = start_image_bmp->getWidth(); gStartImageHeight = start_image_bmp->getHeight(); @@ -2595,12 +2591,12 @@ void init_start_screen(S32 location_id) if (!start_image_bmp->decode(raw, 0.0f)) { LL_WARNS("AppInit") << "Bitmap decode failed" << LL_ENDL; - gStartImageGL = NULL; + gStartTexture = NULL; return; } raw->expandToPowerOfTwo(); - gStartImageGL->createGLTexture(0, raw); + gStartTexture = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE) ; } @@ -2608,7 +2604,7 @@ void init_start_screen(S32 location_id) void release_start_screen() { LL_DEBUGS("AppInit") << "Releasing bitmap..." << LL_ENDL; - gStartImageGL = NULL; + gStartTexture = NULL; } @@ -2916,7 +2912,7 @@ bool process_login_success_response() LLUUID inv_root_folder_id = response["inventory-root"][0]["folder_id"]; if(inv_root_folder_id.notNull()) { - gAgent.getInventoryRootID() = inv_root_folder_id; + gInventory.setRootFolderID(inv_root_folder_id); //gInventory.mock(gAgent.getInventoryRootID()); } @@ -3004,7 +3000,7 @@ bool process_login_success_response() && gAgentSessionID.notNull() && gMessageSystem->mOurCircuitCode && gFirstSim.isOk() - && gAgent.getInventoryRootID().notNull()) + && gInventory.getRootFolderID().notNull()) { success = true; } diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 5e89030a01..7f869d014f 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -33,7 +33,7 @@ #ifndef LL_LLSTARTUP_H #define LL_LLSTARTUP_H -#include "llimagegl.h" +class LLViewerTexture ; // functions bool idle_startup(); @@ -70,7 +70,7 @@ typedef enum { // exported symbols extern bool gAgentMovementCompleted; -extern LLPointer gStartImageGL; +extern LLPointer gStartTexture; class LLStartUp { diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 8c2372ee74..bc90fe7adc 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -47,7 +47,7 @@ #include "llfloaterregioninfo.h" #include "llfloaterscriptdebug.h" #include "llhudicon.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" @@ -237,7 +237,7 @@ void LLStatusBar::draw() if (isBackgroundVisible()) { static LLUICachedControl drop_shadow_floater ("DropShadowFloater", 0); - static LLUICachedControl color_drop_shadow ("ColorDropShadow"); + static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow"); gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, color_drop_shadow, drop_shadow_floater ); } diff --git a/indra/newview/llstylemap.cpp b/indra/newview/llstylemap.cpp index a1384c28ba..a422db1cc1 100644 --- a/indra/newview/llstylemap.cpp +++ b/indra/newview/llstylemap.cpp @@ -64,7 +64,7 @@ const LLStyleSP &LLStyleMap::lookupAgent(const LLUUID &source) style->setFontName(LLStringUtil::null); if (source != LLUUID::null && source != gAgent.getID() ) { - style->setColor(gSavedSkinSettings.getColor4("HTMLLinkColor")); + style->setColor(LLUIColorTable::instance().getColor("HTMLLinkColor")); std::string link = llformat("secondlife:///app/agent/%s/about",source.asString().c_str()); style->setLinkHREF(link); } @@ -90,7 +90,7 @@ const LLStyleSP &LLStyleMap::lookup(const LLUUID& id, const std::string& link) style->setFontName(LLStringUtil::null); if (id != LLUUID::null && !link.empty()) { - style->setColor(gSavedSkinSettings.getColor4("HTMLLinkColor")); + style->setColor(LLUIColorTable::instance().getColor("HTMLLinkColor")); style->setLinkHREF(link); } else @@ -115,6 +115,6 @@ void LLStyleMap::update() { LLStyleSP &style = iter->second; // Update the link color in case it has been changed. - style->setColor(gSavedSkinSettings.getColor4("HTMLLinkColor")); + style->setColor(LLUIColorTable::instance().getColor("HTMLLinkColor")); } } diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 27a08e7d7b..de3d80f044 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -36,7 +36,7 @@ #include "llrender.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llpatchvertexarray.h" #include "patch_dct.h" #include "patch_code.h" @@ -47,7 +47,7 @@ #include "llappviewer.h" #include "llworld.h" #include "llviewercontrol.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llsurfacepatch.h" #include "llvosurfacepatch.h" #include "llvowater.h" @@ -137,12 +137,10 @@ LLSurface::~LLSurface() // Don't enable this until we blitz the draw pool for it as well. -- djs if (mSTexturep) { - gImageList.deleteImage(mSTexturep); mSTexturep = NULL; } if (mWaterTexturep) { - gImageList.deleteImage(mWaterTexturep); mWaterTexturep = NULL; } } @@ -214,18 +212,18 @@ void LLSurface::create(const S32 grids_per_edge, createPatchData(); } -LLViewerImage* LLSurface::getSTexture() +LLViewerTexture* LLSurface::getSTexture() { - if (mSTexturep.notNull() && !mSTexturep->getHasGLTexture()) + if (mSTexturep.notNull() && !mSTexturep->hasValidGLTexture()) { createSTexture(); } return mSTexturep; } -LLViewerImage* LLSurface::getWaterTexture() +LLViewerTexture* LLSurface::getWaterTexture() { - if (mWaterTexturep.notNull() && !mWaterTexturep->getHasGLTexture()) + if (mWaterTexturep.notNull() && !mWaterTexturep->hasValidGLTexture()) { createWaterTexture(); } @@ -249,11 +247,10 @@ void LLSurface::createSTexture() } } - mSTexturep = new LLViewerImage(raw, FALSE); + mSTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); mSTexturep->dontDiscard(); - gGL.getTexUnit(0)->bind(mSTexturep.get()); - mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - gImageList.addImage(mSTexturep); + gGL.getTexUnit(0)->bind(mSTexturep); + mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); } } @@ -274,11 +271,10 @@ void LLSurface::createWaterTexture() *(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3]; } } - mWaterTexturep = new LLViewerImage(raw, FALSE); + mWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); mWaterTexturep->dontDiscard(); - gGL.getTexUnit(0)->bind(mWaterTexturep.get()); + gGL.getTexUnit(0)->bind(mWaterTexturep); mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - gImageList.addImage(mWaterTexturep); } } @@ -1193,7 +1189,7 @@ F32 LLSurface::getWaterHeight() const BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y, const F32 width, const F32 height) { - if (!getWaterTexture()) + if (!getWaterTexture() || !mWaterTexturep->hasGLTexture()) { return FALSE; } diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 310ab5d2c3..1f672d2250 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -46,7 +46,7 @@ #include "llvowater.h" #include "llpatchvertexarray.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLTimer; class LLUUID; @@ -133,8 +133,8 @@ public: void setWaterHeight(F32 height); F32 getWaterHeight() const; - LLViewerImage *getSTexture(); - LLViewerImage *getWaterTexture(); + LLViewerTexture *getSTexture(); + LLViewerTexture *getWaterTexture(); BOOL hasZData() const { return mHasZData; } void dirtyAllPatches(); // Use this to dirty all patches when changing terrain parameters @@ -205,8 +205,8 @@ protected: // The textures should never be directly initialized - use the setter methods! - LLPointer mSTexturep; // Texture for surface - LLPointer mWaterTexturep; // Water texture + LLPointer mSTexturep; // Texture for surface + LLPointer mWaterTexturep; // Water texture LLPointer mWaterObjp; diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp index 99389017cb..9754568f56 100644 --- a/indra/newview/llteleporthistory.cpp +++ b/indra/newview/llteleporthistory.cpp @@ -172,6 +172,14 @@ void LLTeleportHistory::onHistoryChanged() mHistoryChangedSignal(); } +void LLTeleportHistory::purgeItems() +{ + mItems.erase(mItems.begin(), mItems.end()-1); + // reset the count + mRequestedItem = -1; + mCurrentItem = 0; +} + // static std::string LLTeleportHistory::getCurrentLocationTitle() { diff --git a/indra/newview/llteleporthistory.h b/indra/newview/llteleporthistory.h index c68aabe9a1..775b21e24c 100644 --- a/indra/newview/llteleporthistory.h +++ b/indra/newview/llteleporthistory.h @@ -106,7 +106,7 @@ public: * @return history items. */ const slurl_list_t& getItems() const { return mItems; } - + void purgeItems(); /** * Is the history empty? * @@ -119,7 +119,6 @@ public: * Get index of the current location in the history. */ int getCurrentItemIndex() const { return mCurrentItem; } - /** * Set a callback to be called upon history changes. * diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 716ab8eef4..5a5f187415 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -72,7 +72,7 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height, BOOL has_bump) : // ORDER_LAST => must render these after the hints are created. - LLDynamicTexture( width, height, 4, LLDynamicTexture::ORDER_LAST, TRUE ), + LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), mNeedsUpdate( TRUE ), mNeedsUpload( FALSE ), mUploadPending( FALSE ), // Not used for any logic here, just to sync sending of updates @@ -91,8 +91,8 @@ LLTexLayerSetBuffer::~LLTexLayerSetBuffer() if( mBumpTex.notNull()) { mBumpTex = NULL ; - LLImageGL::sGlobalTextureMemoryInBytes -= mWidth * mHeight * 4; - LLTexLayerSetBuffer::sGLBumpByteCount -= mWidth * mHeight * 4; + LLImageGL::sGlobalTextureMemoryInBytes -= mFullWidth * mFullHeight * 4; + LLTexLayerSetBuffer::sGLBumpByteCount -= mFullWidth * mFullHeight * 4; } } @@ -100,7 +100,7 @@ LLTexLayerSetBuffer::~LLTexLayerSetBuffer() void LLTexLayerSetBuffer::restoreGLTexture() { createBumpTexture() ; - LLDynamicTexture::restoreGLTexture() ; + LLViewerDynamicTexture::restoreGLTexture() ; } //virtual @@ -109,11 +109,11 @@ void LLTexLayerSetBuffer::destroyGLTexture() if( mBumpTex.notNull() ) { mBumpTex = NULL ; - LLImageGL::sGlobalTextureMemoryInBytes -= mWidth * mHeight * 4; - LLTexLayerSetBuffer::sGLBumpByteCount -= mWidth * mHeight * 4; + LLImageGL::sGlobalTextureMemoryInBytes -= mFullWidth * mFullHeight * 4; + LLTexLayerSetBuffer::sGLBumpByteCount -= mFullWidth * mFullHeight * 4; } - LLDynamicTexture::destroyGLTexture() ; + LLViewerDynamicTexture::destroyGLTexture() ; } void LLTexLayerSetBuffer::createBumpTexture() @@ -121,7 +121,7 @@ void LLTexLayerSetBuffer::createBumpTexture() if( mHasBump ) { LLGLSUIDefault gls_ui; - mBumpTex = new LLImageGL(FALSE) ; + mBumpTex = LLViewerTextureManager::getLocalTexture(FALSE) ; if(!mBumpTex->createGLTexture()) { mBumpTex = NULL ; @@ -135,13 +135,13 @@ void LLTexLayerSetBuffer::createBumpTexture() gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA8, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA8, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, NULL); stop_glerror(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLImageGL::sGlobalTextureMemoryInBytes += mWidth * mHeight * 4; - LLTexLayerSetBuffer::sGLBumpByteCount += mWidth * mHeight * 4; + LLImageGL::sGlobalTextureMemoryInBytes += mFullWidth * mFullHeight * 4; + LLTexLayerSetBuffer::sGLBumpByteCount += mFullWidth * mFullHeight * 4; } } @@ -184,7 +184,7 @@ void LLTexLayerSetBuffer::pushProjection() const glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); glLoadIdentity(); - glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); + glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); gGL.pushMatrix(); @@ -230,14 +230,14 @@ void LLTexLayerSetBuffer::preRender(BOOL clear_depth) pushProjection(); // keep depth buffer, we don't need to clear it - LLDynamicTexture::preRender(FALSE); + LLViewerDynamicTexture::preRender(FALSE); } void LLTexLayerSetBuffer::postRender(BOOL success) { popProjection(); - LLDynamicTexture::postRender(success); + LLViewerDynamicTexture::postRender(success); } BOOL LLTexLayerSetBuffer::render() @@ -256,7 +256,7 @@ BOOL LLTexLayerSetBuffer::render() if( mBumpTex.notNull() ) { // Composite the bump data - success &= mTexLayerSet->renderBump( mOrigin.mX, mOrigin.mY, mWidth, mHeight ); + success &= mTexLayerSet->renderBump( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight ); stop_glerror(); if (success) @@ -267,14 +267,14 @@ BOOL LLTexLayerSetBuffer::render() gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName()); stop_glerror(); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mOrigin.mX, mOrigin.mY, mWidth, mHeight); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); stop_glerror(); // if we need to upload the data, read it back into a buffer if( upload_now ) { - baked_bump_data = new U8[ mWidth * mHeight * 4 ]; - glReadPixels(mOrigin.mX, mOrigin.mY, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_bump_data ); + baked_bump_data = new U8[ mFullWidth * mFullHeight * 4 ]; + glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_bump_data ); stop_glerror(); } } @@ -282,7 +282,7 @@ BOOL LLTexLayerSetBuffer::render() // Composite the color data LLGLSUIDefault gls_ui; - success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mWidth, mHeight ); + success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight ); gGL.flush(); if( upload_now ) @@ -303,7 +303,7 @@ BOOL LLTexLayerSetBuffer::render() gGL.setSceneBlendType(LLRender::BT_ALPHA); // we have valid texture data now - mTexture->setGLTextureCreated(true); + mGLTexturep->setGLTextureCreated(true); mNeedsUpdate = FALSE; delete [] baked_bump_data; @@ -312,7 +312,7 @@ BOOL LLTexLayerSetBuffer::render() bool LLTexLayerSetBuffer::isInitialized(void) const { - return mTexture.notNull() && mTexture->isGLTextureCreated(); + return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated(); } BOOL LLTexLayerSetBuffer::updateImmediate() @@ -333,9 +333,9 @@ BOOL LLTexLayerSetBuffer::updateImmediate() void LLTexLayerSetBuffer::readBackAndUpload(const U8* baked_bump_data) { // pointers for storing data to upload - U8* baked_color_data = new U8[ mWidth * mHeight * 4 ]; + U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ]; - glReadPixels(mOrigin.mX, mOrigin.mY, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data ); + glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data ); stop_glerror(); llinfos << "Baked " << mTexLayerSet->getBodyRegion() << llendl; @@ -350,16 +350,16 @@ void LLTexLayerSetBuffer::readBackAndUpload(const U8* baked_bump_data) LLGLSUIDefault gls_ui; - LLPointer baked_mask_image = new LLImageRaw(mWidth, mHeight, 1 ); + LLPointer baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 ); U8* baked_mask_data = baked_mask_image->getData(); - mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data, mWidth, mHeight); + mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data, mFullWidth, mFullHeight); // writes into baked_color_data const char* comment_text = NULL; S32 baked_image_components = mBumpTex.notNull() ? 5 : 4; // red green blue [bump] clothing - LLPointer baked_image = new LLImageRaw( mWidth, mHeight, baked_image_components ); + LLPointer baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components ); U8* baked_image_data = baked_image->getData(); @@ -368,9 +368,9 @@ void LLTexLayerSetBuffer::readBackAndUpload(const U8* baked_bump_data) comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // 5 channels: rgb, heightfield/alpha, mask S32 i = 0; - for( S32 u = 0; u < mWidth; u++ ) + for( S32 u = 0; u < mFullWidth; u++ ) { - for( S32 v = 0; v < mHeight; v++ ) + for( S32 v = 0; v < mFullHeight; v++ ) { baked_image_data[5*i + 0] = baked_color_data[4*i + 0]; baked_image_data[5*i + 1] = baked_color_data[4*i + 1]; @@ -384,9 +384,9 @@ void LLTexLayerSetBuffer::readBackAndUpload(const U8* baked_bump_data) else { S32 i = 0; - for( S32 u = 0; u < mWidth; u++ ) + for( S32 u = 0; u < mFullWidth; u++ ) { - for( S32 v = 0; v < mHeight; v++ ) + for( S32 v = 0; v < mFullHeight; v++ ) { baked_image_data[4*i + 0] = baked_color_data[4*i + 0]; baked_image_data[4*i + 1] = baked_color_data[4*i + 1]; @@ -555,11 +555,7 @@ void LLTexLayerSetBuffer::bindBumpTexture( U32 stage ) gGL.getTexUnit(stage)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName()); gGL.getTexUnit(0)->activate(); - if( mLastBindTime != LLImageGL::sLastFrameTime ) - { - mLastBindTime = LLImageGL::sLastFrameTime; - LLImageGL::updateBoundTexMem(mWidth * mHeight * 4); - } + mGLTexturep->updateBindStats(mFullWidth * mFullHeight * 4); } else { @@ -673,7 +669,6 @@ LLTexLayerSet::~LLTexLayerSet() deleteCaches(); std::for_each(mLayerList.begin(), mLayerList.end(), DeletePointer()); std::for_each(mMaskLayerList.begin(), mMaskLayerList.end(), DeletePointer()); - delete mComposite; } //----------------------------------------------------------------------------- @@ -886,7 +881,6 @@ void LLTexLayerSet::destroyComposite() { if( mComposite ) { - delete mComposite; mComposite = NULL; } } @@ -960,11 +954,11 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 width, S32 height, bool forceCle LLGLSNoAlphaTest gls_no_alpha_test; gGL.flush(); { - LLImageGL* image_gl = LLTexLayerStaticImageList::getInstance()->getImageGL(info->mStaticAlphaFileName, TRUE); - if( image_gl ) + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE); + if( tex ) { LLGLSUIDefault gls_ui; - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE ); gl_rect_2d_simple_tex( width, height ); } @@ -1243,6 +1237,16 @@ LLTexLayer::LLTexLayer(LLTexLayerSet* layer_set) : { } +LLTexLayer::LLTexLayer(const LLTexLayer &layer) : + mTexLayerSet( layer.mTexLayerSet ) +{ + setInfo(layer.getInfo()); + + + mHasMorph = layer.mHasMorph; + +} + LLTexLayer::~LLTexLayer() { // mParamAlphaList and mParamColorList are LLViewerVisualParam's and get @@ -1409,16 +1413,16 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly ) { { - LLImageGL* image_gl = NULL; - if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) ) + LLViewerTexture* tex = NULL; + if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex ) ) { - if( image_gl ) + if( tex ) { LLGLDisable alpha_test(getInfo()->mWriteAllChannels ? GL_ALPHA_TEST : 0); - LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode(); + LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode(); - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); gl_rect_2d_simple_tex( width, height ); @@ -1437,10 +1441,10 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) if( !getInfo()->mStaticImageFileName.empty() ) { { - LLImageGL* image_gl = LLTexLayerStaticImageList::getInstance()->getImageGL(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); - if( image_gl ) + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + if( tex ) { - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -1548,11 +1552,11 @@ BOOL LLTexLayer::blendAlphaTexture(S32 width, S32 height) if( !getInfo()->mStaticImageFileName.empty() ) { - LLImageGL* image_gl = LLTexLayerStaticImageList::getInstance()->getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask ); - if( image_gl ) + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask ); + if( tex ) { LLGLSNoAlphaTest gls_no_alpha_test; - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -1565,13 +1569,13 @@ BOOL LLTexLayer::blendAlphaTexture(S32 width, S32 height) { if (getInfo()->mLocalTexture >=0 && getInfo()->mLocalTexture < TEX_NUM_INDICES) { - LLImageGL* image_gl = NULL; - if (mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl)) + LLViewerTexture* tex = NULL; + if (mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex)) { - if (image_gl) + if (tex) { LLGLSNoAlphaTest gls_no_alpha_test; - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); success = TRUE; @@ -1623,16 +1627,16 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC // Accumulate the alpha component of the texture if( getInfo()->mLocalTexture != -1 ) { - LLImageGL* image_gl = NULL; - if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) ) + LLViewerTexture* tex = NULL; + if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex ) ) { - if( image_gl && (image_gl->getComponents() == 4) ) + if( tex && (tex->getComponents() == 4) ) { LLGLSNoAlphaTest gls_no_alpha_test; - LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode(); + LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode(); - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); gl_rect_2d_simple_tex( width, height ); @@ -1649,14 +1653,14 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC if( !getInfo()->mStaticImageFileName.empty() ) { - LLImageGL* image_gl = LLTexLayerStaticImageList::getInstance()->getImageGL(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); - if( image_gl ) + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + if( tex ) { - if( (image_gl->getComponents() == 4) || - ( (image_gl->getComponents() == 1) && getInfo()->mStaticImageIsMask ) ) + if( (tex->getComponents() == 4) || + ( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) ) { LLGLSNoAlphaTest gls_no_alpha_test; - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -1856,16 +1860,16 @@ void LLTexLayerStaticImageList::deleteCachedImages() //mStaticImageLists uses LLPointers, clear() will cause deletion mStaticImageListTGA.clear(); - mStaticImageListGL.clear(); + mStaticImageList.clear(); mGLBytes = 0; mTGABytes = 0; } } -// Note: in general, for a given image image we'll call either getImageTga() or getImageGL(). +// Note: in general, for a given image image we'll call either getImageTga() or getTexture(). // We call getImageTga() if the image is used as an alpha gradient. -// Otherwise, we call getImageGL() +// Otherwise, we call getTexture() // Returns an LLImageTGA that contains the encoded data from a tga file named file_name. // Caches the result to speed identical subsequent requests. @@ -1897,19 +1901,19 @@ LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name) // Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name. // Caches the result to speed identical subsequent requests. -LLImageGL* LLTexLayerStaticImageList::getImageGL(const std::string& file_name, BOOL is_mask) +LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask) { - LLPointer image_gl; + LLPointer tex; const char *namekey = mImageNames.addString(file_name); - image_gl_map_t::const_iterator iter = mStaticImageListGL.find(namekey); - if( iter != mStaticImageListGL.end() ) + texture_map_t::const_iterator iter = mStaticImageList.find(namekey); + if( iter != mStaticImageList.end() ) { - image_gl = iter->second; + tex = iter->second; } else { - image_gl = new LLImageGL( FALSE ); + tex = LLViewerTextureManager::getLocalTexture( FALSE ); LLPointer image_raw = new LLImageRaw; if( loadImageRaw( file_name, image_raw ) ) { @@ -1917,23 +1921,23 @@ LLImageGL* LLTexLayerStaticImageList::getImageGL(const std::string& file_name, B { // Note: these are static, unchanging images so it's ok to assume // that once an image is a mask it's always a mask. - image_gl->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); + tex->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); } - image_gl->createGLTexture(0, image_raw); + tex->createGLTexture(0, image_raw); - gGL.getTexUnit(0)->bind(image_gl); - image_gl->setAddressMode(LLTexUnit::TAM_CLAMP); + gGL.getTexUnit(0)->bind(tex); + tex->setAddressMode(LLTexUnit::TAM_CLAMP); - mStaticImageListGL [ namekey ] = image_gl; - mGLBytes += (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); + mStaticImageList [ namekey ] = tex; + mGLBytes += (S32)tex->getWidth() * tex->getHeight() * tex->getComponents(); } else { - image_gl = NULL; + tex = NULL; } } - return image_gl; + return tex; } // Reads a .tga file, decodes it, and puts the decoded data in image_raw. diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h index 5890440108..b0ac13913e 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/newview/lltexlayer.h @@ -40,7 +40,6 @@ class LLVOAvatar; class LLVOAvatarSelf; -class LLImageGL; class LLImageTGA; class LLImageRaw; class LLXmlTreeNode; @@ -54,6 +53,7 @@ class LLTexLayerParamColorInfo; class LLTexLayerParamAlpha; class LLTexLayerParamAlphaInfo; + typedef std::vector param_color_list_t; typedef std::vector param_alpha_list_t; typedef std::vector param_color_info_list_t; @@ -75,6 +75,7 @@ public: }; LLTexLayer(LLTexLayerSet* const layer_set); + LLTexLayer(const LLTexLayer &layer); ~LLTexLayer(); const LLTexLayerInfo* getInfo() const { return mInfo; } @@ -195,7 +196,7 @@ public: LLVOAvatarSelf* getAvatar() const { return mAvatar; } const std::string getBodyRegion() const; - BOOL hasComposite() const { return (mComposite != NULL); } + BOOL hasComposite() const { return (mComposite.notNull()); } void setBump(BOOL b) { mHasBump = b; } BOOL hasBump() const { return mHasBump; } LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; } @@ -208,7 +209,7 @@ private: typedef std::vector layer_list_t; layer_list_t mLayerList; layer_list_t mMaskLayerList; - LLTexLayerSetBuffer* mComposite; + LLPointer mComposite; LLVOAvatarSelf* const mAvatar; // Backlink only; don't make this an LLPointer. BOOL mUpdatesEnabled; BOOL mHasBump; @@ -241,7 +242,7 @@ private: }; // The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one. -class LLTexLayerSetBuffer : public LLDynamicTexture +class LLTexLayerSetBuffer : public LLViewerDynamicTexture { public: LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height, BOOL has_bump); @@ -282,7 +283,7 @@ private: BOOL mNeedsUpload; BOOL mUploadPending; LLUUID mUploadID; // Identifys the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit) - LLPointer mBumpTex; // zero if none + LLPointer mBumpTex; // zero if none static S32 sGLByteCount; static S32 sGLBumpByteCount; @@ -302,7 +303,7 @@ public: LLTexLayerStaticImageList(); ~LLTexLayerStaticImageList(); - LLImageGL* getImageGL(const std::string& file_name, BOOL is_mask); + LLViewerTexture* getTexture(const std::string& file_name, BOOL is_mask); LLImageTGA* getImageTGA(const std::string& file_name); void deleteCachedImages(); @@ -314,8 +315,8 @@ private: private: LLStringTable mImageNames; - typedef std::map< const char*, LLPointer > image_gl_map_t; - image_gl_map_t mStaticImageListGL; + typedef std::map< const char*, LLPointer > texture_map_t; + texture_map_t mStaticImageList; typedef std::map< const char*, LLPointer > image_tga_map_t; image_tga_map_t mStaticImageListTGA; diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp index e00f6aeb04..c9117a84a5 100644 --- a/indra/newview/lltexlayerparams.cpp +++ b/indra/newview/lltexlayerparams.cpp @@ -89,12 +89,12 @@ void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes) iter != sInstances.end(); iter++) { LLTexLayerParamAlpha* instance = *iter; - LLImageGL* image_gl = instance->mCachedProcessedImageGL; - if (image_gl) + LLViewerTexture* tex = instance->mCachedProcessedTexture; + if (tex) { - S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); + S32 bytes = (S32)tex->getWidth() * tex->getHeight() * tex->getComponents(); - if (image_gl->getHasGLTexture()) + if (tex->hasValidGLTexture()) { *gl_bytes += bytes; } @@ -104,7 +104,7 @@ void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes) LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayer* layer) : LLTexLayerParam(layer), - mCachedProcessedImageGL(NULL), + mCachedProcessedTexture(NULL), mNeedsCreateTexture(FALSE), mStaticImageInvalid(FALSE), mAvgDistortionVec(1.f, 1.f, 1.f), @@ -115,7 +115,7 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayer* layer) : LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLVOAvatar* avatar) : LLTexLayerParam(avatar), - mCachedProcessedImageGL(NULL), + mCachedProcessedTexture(NULL), mNeedsCreateTexture(FALSE), mStaticImageInvalid(FALSE), mAvgDistortionVec(1.f, 1.f, 1.f), @@ -134,7 +134,7 @@ LLTexLayerParamAlpha::~LLTexLayerParamAlpha() void LLTexLayerParamAlpha::deleteCaches() { mStaticImageTGA = NULL; // deletes image - mCachedProcessedImageGL = NULL; + mCachedProcessedTexture = NULL; mStaticImageRaw = NULL; mNeedsCreateTexture = FALSE; } @@ -266,22 +266,22 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) const S32 image_tga_width = mStaticImageTGA->getWidth(); const S32 image_tga_height = mStaticImageTGA->getHeight(); - if (!mCachedProcessedImageGL || - (mCachedProcessedImageGL->getWidth() != image_tga_width) || - (mCachedProcessedImageGL->getHeight() != image_tga_height) || + if (!mCachedProcessedTexture || + (mCachedProcessedTexture->getWidth() != image_tga_width) || + (mCachedProcessedTexture->getHeight() != image_tga_height) || (weight_changed)) { // llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl; mCachedEffectiveWeight = effective_weight; - if (!mCachedProcessedImageGL) + if (!mCachedProcessedTexture) { - mCachedProcessedImageGL = new LLImageGL(image_tga_width, image_tga_height, 1, FALSE); + mCachedProcessedTexture = LLViewerTextureManager::getLocalTexture(image_tga_width, image_tga_height, 1, FALSE); // We now have something in one of our caches - LLTexLayerSet::sHasCaches |= mCachedProcessedImageGL ? TRUE : FALSE; + LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE; - mCachedProcessedImageGL->setExplicitFormat(GL_ALPHA8, GL_ALPHA); + mCachedProcessedTexture->setExplicitFormat(GL_ALPHA8, GL_ALPHA); } // Applies domain and effective weight to data as it is decoded. Also resizes the raw image if needed. @@ -291,20 +291,20 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) mNeedsCreateTexture = TRUE; } - if (mCachedProcessedImageGL) + if (mCachedProcessedTexture) { { // Create the GL texture, and then hang onto it for future use. if (mNeedsCreateTexture) { - mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw); + mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw); mNeedsCreateTexture = FALSE; - gGL.getTexUnit(0)->bind(mCachedProcessedImageGL); - mCachedProcessedImageGL->setAddressMode(LLTexUnit::TAM_CLAMP); + gGL.getTexUnit(0)->bind(mCachedProcessedTexture); + mCachedProcessedTexture->setAddressMode(LLTexUnit::TAM_CLAMP); } LLGLSNoAlphaTest gls_no_alpha_test; - gGL.getTexUnit(0)->bind(mCachedProcessedImageGL); + gGL.getTexUnit(0)->bind(mCachedProcessedTexture); gl_rect_2d_simple_tex(width, height); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); stop_glerror(); @@ -315,7 +315,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) // (It's not really a "cache" in that case, but the logic is the same) if (mAvatar->isSelf()) { - mCachedProcessedImageGL = NULL; + mCachedProcessedTexture = NULL; } } else diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h index 8c01738317..49feb01b5e 100644 --- a/indra/newview/lltexlayerparams.h +++ b/indra/newview/lltexlayerparams.h @@ -80,7 +80,7 @@ public: BOOL getMultiplyBlend() const; private: - LLPointer mCachedProcessedImageGL; + LLPointer mCachedProcessedTexture; LLPointer mStaticImageTGA; LLPointer mStaticImageRaw; BOOL mNeedsCreateTexture; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 3c9290acea..3c7a8d757b 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -37,17 +37,18 @@ #include "llrender.h" #include "llagent.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llcheckboxctrl.h" #include "llcombobox.h" #include "llbutton.h" #include "lldraghandle.h" #include "llfocusmgr.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llfolderview.h" +#include "llfoldervieweventlistener.h" #include "llinventory.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "lllineeditor.h" #include "llui.h" #include "llviewerinventory.h" @@ -59,7 +60,7 @@ #include "llscrollcontainer.h" #include "lltoolmgr.h" #include "lltoolpipette.h" -#include "llsearcheditor.h" +#include "llfiltereditor.h" #include "lltool.h" #include "llviewerwindow.h" @@ -109,7 +110,6 @@ public: virtual BOOL handleKeyHere(KEY key, MASK mask); // LLFloater overrides - virtual void onClose(bool app_quitting); virtual BOOL postBuild(); // New functions @@ -129,7 +129,8 @@ public: void updateFilterPermMask(); void commitIfImmediateSet(); - void onSearchEdit(const std::string& search_string ); + void onFilterEdit(const std::string& search_string ); + void onClose(); static void onBtnSetToDefault( void* userdata ); static void onBtnSelect( void* userdata ); @@ -145,7 +146,7 @@ public: void onTextureSelect( const LLTextureEntry& te ); protected: - LLPointer mTexturep; + LLPointer mTexturep; LLTextureCtrl* mOwner; LLUUID mImageAssetID; // Currently selected texture @@ -163,7 +164,7 @@ protected: std::string mPendingName; BOOL mActive; - LLSearchEditor* mSearchEdit; + LLFilterEditor* mFilterEdit; LLInventoryPanel* mInventoryPanel; PermissionMask mImmediateFilterPermMask; PermissionMask mNonImmediateFilterPermMask; @@ -180,7 +181,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( PermissionMask non_immediate_filter_perm_mask, BOOL can_apply_immediately, const std::string& fallback_image_name) -: LLFloater(), +: LLFloater(LLSD()), mOwner( owner ), mImageAssetID( owner->getImageAssetID() ), mFallbackImageName( fallback_image_name ), @@ -190,13 +191,13 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mTentativeLabel(NULL), mResolutionLabel(NULL), mActive( TRUE ), - mSearchEdit(NULL), + mFilterEdit(NULL), mImmediateFilterPermMask(immediate_filter_perm_mask), mNonImmediateFilterPermMask(non_immediate_filter_perm_mask), mContextConeOpacity(0.f) { mCanApplyImmediately = can_apply_immediately; - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml"); + LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml",NULL); setCanMinimize(FALSE); } @@ -262,9 +263,9 @@ void LLFloaterTexturePicker::updateImageStats() if (mTexturep.notNull()) { //RN: have we received header data for this image? - if (mTexturep->getWidth(0) > 0 && mTexturep->getHeight(0) > 0) + if (mTexturep->getFullWidth() > 0 && mTexturep->getFullHeight() > 0) { - std::string formatted_dims = llformat("%d x %d", mTexturep->getWidth(0),mTexturep->getHeight(0)); + std::string formatted_dims = llformat("%d x %d", mTexturep->getFullWidth(),mTexturep->getFullHeight()); mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims); } else @@ -334,15 +335,15 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask) { LLFolderView* root_folder = mInventoryPanel->getRootFolder(); - if (root_folder && mSearchEdit) + if (root_folder && mFilterEdit) { - if (mSearchEdit->hasFocus() + if (mFilterEdit->hasFocus() && (key == KEY_RETURN || key == KEY_DOWN) && mask == MASK_NONE) { if (!root_folder->getCurSelectedItem()) { - LLFolderViewItem* itemp = root_folder->getItemByID(gAgent.getInventoryRootID()); + LLFolderViewItem* itemp = root_folder->getItemByID(gInventory.getRootFolderID()); if (itemp) { root_folder->setSelection(itemp, FALSE, FALSE); @@ -361,27 +362,27 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask) if (mInventoryPanel->hasFocus() && key == KEY_UP) { - mSearchEdit->focusFirstItem(TRUE); + mFilterEdit->focusFirstItem(TRUE); } } return LLFloater::handleKeyHere(key, mask); } -// virtual -void LLFloaterTexturePicker::onClose(bool app_quitting) +void LLFloaterTexturePicker::onClose() { if (mOwner) { mOwner->onFloaterClose(); } stopUsingPipette(); - destroy(); } // virtual BOOL LLFloaterTexturePicker::postBuild() { + mCloseSignal.connect(boost::bind(&LLFloaterTexturePicker::onClose, this)); + LLFloater::postBuild(); if (!mLabel.empty()) @@ -403,8 +404,8 @@ BOOL LLFloaterTexturePicker::postBuild() childSetCommitCallback("show_folders_check", onShowFolders, this); childSetVisible("show_folders_check", FALSE); - mSearchEdit = getChild("inventory search editor"); - mSearchEdit->setSearchCallback(boost::bind(&LLFloaterTexturePicker::onSearchEdit, this, _1)); + mFilterEdit = getChild("inventory search editor"); + mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2)); mInventoryPanel = getChild("inventory panel"); @@ -522,22 +523,19 @@ void LLFloaterTexturePicker::draw() childSetEnabled("Pipette", mActive); childSetValue("Pipette", LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); - //RN: reset search bar to reflect actual search query (all caps, for example) - mSearchEdit->setText(mInventoryPanel->getFilterSubString()); - //BOOL allow_copy = FALSE; if( mOwner ) { mTexturep = NULL; if(mImageAssetID.notNull()) { - mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); - mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); + mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); } else if (!mFallbackImageName.empty()) { - mTexturep = gImageList.getImageFromFile(mFallbackImageName); - mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + mTexturep = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName); + mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); } if (mTentativeLabel) @@ -796,7 +794,7 @@ void LLFloaterTexturePicker::updateFilterPermMask() //mInventoryPanel->setFilterPermMask( getFilterPermMask() ); Commented out due to no-copy texture loss. } -void LLFloaterTexturePicker::onSearchEdit(const std::string& search_string ) +void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string ) { std::string upper_case_search_string = search_string; LLStringUtil::toUpper(upper_case_search_string); @@ -858,7 +856,7 @@ void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) /////////////////////////////////////////////////////////////////////// // LLTextureCtrl -static LLDefaultWidgetRegistry::Register r("texture_picker"); +static LLDefaultChildRegistry::Register r("texture_picker"); LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) : LLUICtrl(p), @@ -1190,14 +1188,14 @@ void LLTextureCtrl::draw() } else if (!mImageAssetID.isNull()) { - mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); - mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); + mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); } else if (!mFallbackImageName.empty()) { // Show fallback image. - mTexturep = gImageList.getImageFromFile(mFallbackImageName); - mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + mTexturep = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName); + mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); } // Border diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index ebe2cd2e5f..0b232da62b 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -45,7 +45,7 @@ class LLButton; class LLFloaterTexturePicker; class LLInventoryItem; -class LLViewerImage; +class LLViewerTexture; // used for setting drag & drop callbacks. typedef boost::function drag_n_drop_callback; @@ -84,7 +84,7 @@ public: Params() : image_id("image"), - default_image_id("default_image"), + default_image_id("default_image_id"), default_image_name("default_image_name"), allow_no_texture("allow_no_texture"), can_apply_immediately("can_apply_immediately"), @@ -189,7 +189,7 @@ private: drag_n_drop_callback mDropCallback; commit_callback_t mOnCancelCallback; commit_callback_t mOnSelectCallback; - LLPointer mTexturep; + LLPointer mTexturep; LLUIColor mBorderColor; LLUUID mImageItemID; LLUUID mImageAssetID; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index be535761fc..63af170fa9 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -44,8 +44,8 @@ #include "llagent.h" #include "lltexturecache.h" -#include "llviewerimagelist.h" -#include "llviewerimage.h" +#include "llviewertexturelist.h" +#include "llviewertexture.h" #include "llviewerregion.h" ////////////////////////////////////////////////////////////////////////////// @@ -469,8 +469,8 @@ void LLTextureFetchWorker::clearPackets() U32 LLTextureFetchWorker::calcWorkPriority() { -// llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerImage::maxDecodePriority()); - F32 priority_scale = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerImage::maxDecodePriority(); +// llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerTexture::maxDecodePriority()); + F32 priority_scale = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerFetchedTexture::maxDecodePriority(); mWorkPriority = (U32)(mImagePriority * priority_scale); return mWorkPriority; } @@ -512,7 +512,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) void LLTextureFetchWorker::setImagePriority(F32 priority) { -// llassert_always(priority >= 0 && priority <= LLViewerImage::maxDecodePriority()); +// llassert_always(priority >= 0 && priority <= LLViewerTexture::maxDecodePriority()); F32 delta = fabs(priority - mImagePriority); if (delta > (mImagePriority * .05f) || mState == DONE) { @@ -542,7 +542,7 @@ void LLTextureFetchWorker::startWork(S32 param) llassert(mFormattedImage.isNull()); } -#include "llviewerimagelist.h" // debug +#include "llviewertexturelist.h" // debug // Called from LLWorkerThread::processRequest() bool LLTextureFetchWorker::doWork(S32 param) @@ -796,7 +796,7 @@ bool LLTextureFetchWorker::doWork(S32 param) mFormattedImage->deleteData(); #endif mRequestedSize -= cur_size; - // F32 priority = mImagePriority / (F32)LLViewerImage::maxDecodePriority(); // 0-1 + // F32 priority = mImagePriority / (F32)LLViewerTexture::maxDecodePriority(); // 0-1 S32 offset = cur_size; mBufferSize = cur_size; // This will get modified by callbackHttpGet() std::string url; diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 282fbb6481..97719a9468 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -38,7 +38,7 @@ #include "lluuid.h" #include "llworkerthread.h" -class LLViewerImage; +class LLViewerTexture; class LLTextureFetchWorker; class LLTextureCache; class LLHost; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 50b73bfbc7..70a8ab9f61 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -49,8 +49,8 @@ #include "lltexturecache.h" #include "lltexturefetch.h" #include "llviewerobject.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llappviewer.h" extern F32 texmem_lower_bound_scale; @@ -58,18 +58,18 @@ extern F32 texmem_lower_bound_scale; LLTextureView *gTextureView = NULL; //static -std::set LLTextureView::sDebugImages; +std::set LLTextureView::sDebugImages; //////////////////////////////////////////////////////////////////////////// -static std::string title_string1a("Tex UUID Area DDis(Req) DecodePri(Fetch) [download] pk/max"); -static std::string title_string1b("Tex UUID Area DDis(Req) Fetch(DecodePri) [download] pk/max"); +static std::string title_string1a("Tex UUID Area DDis(Req) DecodePri(Fetch) [download] pk/max"); +static std::string title_string1b("Tex UUID Area DDis(Req) Fetch(DecodePri) [download] pk/max"); static std::string title_string2("State"); static std::string title_string3("Pkt Bnd"); static std::string title_string4(" W x H (Dis) Mem"); static S32 title_x1 = 0; -static S32 title_x2 = 440; +static S32 title_x2 = 460; static S32 title_x3 = title_x2 + 40; static S32 title_x4 = title_x3 + 50; static S32 texture_bar_height = 8; @@ -79,7 +79,7 @@ static S32 texture_bar_height = 8; class LLTextureBar : public LLView { public: - LLPointer mImagep; + LLPointer mImagep; S32 mHilite; public: @@ -109,8 +109,8 @@ public: { LLTextureBar* bar1p = (LLTextureBar*)i1; LLTextureBar* bar2p = (LLTextureBar*)i2; - LLViewerImage *i1p = bar1p->mImagep; - LLViewerImage *i2p = bar2p->mImagep; + LLViewerFetchedTexture *i1p = bar1p->mImagep; + LLViewerFetchedTexture *i2p = bar2p->mImagep; F32 pri1 = i1p->getDecodePriority(); // i1p->mRequestedDownloadPriority F32 pri2 = i2p->getDecodePriority(); // i2p->mRequestedDownloadPriority if (pri1 > pri2) @@ -128,10 +128,10 @@ public: { LLTextureBar* bar1p = (LLTextureBar*)i1; LLTextureBar* bar2p = (LLTextureBar*)i2; - LLViewerImage *i1p = bar1p->mImagep; - LLViewerImage *i2p = bar2p->mImagep; - U32 pri1 = i1p->mFetchPriority; - U32 pri2 = i2p->mFetchPriority; + LLViewerFetchedTexture *i1p = bar1p->mImagep; + LLViewerFetchedTexture *i2p = bar2p->mImagep; + U32 pri1 = i1p->getFetchPriority() ; + U32 pri2 = i2p->getFetchPriority() ; if (pri1 > pri2) return true; else if (pri2 > pri1) @@ -315,10 +315,10 @@ void LLTextureBar::draw() pip_x += pip_width + pip_space; // we don't want to show bind/resident pips for textures using the default texture - if (mImagep->getHasGLTexture()) + if (mImagep->hasValidGLTexture()) { // Draw the bound pip - last_event = mImagep->sLastFrameTime - mImagep->mLastBindTime; + last_event = mImagep->getTimePassedSinceLastBound(); if (last_event < 1.f) { clr = mImagep->getMissed() ? LLColor4::red : LLColor4::magenta1; @@ -342,7 +342,7 @@ void LLTextureBar::draw() // draw the image size at the end { std::string num_str = llformat("%3dx%3d (%d) %7d", mImagep->getWidth(), mImagep->getHeight(), - mImagep->getDiscardLevel(), mImagep->mTextureMemory); + mImagep->getDiscardLevel(), mImagep->hasGLTexture() ? mImagep->getTextureMemory() : 0); LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, title_x4, getRect().getHeight(), color, LLFontGL::LEFT, LLFontGL::TOP); } @@ -400,13 +400,13 @@ private: void LLGLTexMemBar::draw() { - S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes); - S32 max_bound_mem = LLViewerImage::sMaxBoundTextureMemInMegaBytes; - S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sTotalTextureMemoryInBytes); - S32 max_total_mem = LLViewerImage::sMaxTotalTextureMemInMegaBytes; - F32 discard_bias = LLViewerImage::sDesiredDiscardBias; + S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes); + S32 max_bound_mem = LLViewerTexture::sMaxBoundTextureMemInMegaBytes; + S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sTotalTextureMemoryInBytes); + S32 max_total_mem = LLViewerTexture::sMaxTotalTextureMemInMegaBytes; + F32 discard_bias = LLViewerTexture::sDesiredDiscardBias; S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - + S32 h_offset = (S32)((texture_bar_height + 2.5f) * mTextureView->mNumTextureBars + 2.5f); //---------------------------------------------------------------------------- LLGLSUIDefault gls_ui; F32 text_color[] = {1.f, 1.f, 1.f, 0.75f}; @@ -419,13 +419,13 @@ void LLGLTexMemBar::draw() max_bound_mem, discard_bias); - LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, line_height*3, + LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, h_offset + line_height*3, text_color, LLFontGL::LEFT, LLFontGL::TOP); //---------------------------------------------------------------------------- S32 bar_left = 380; S32 bar_width = 200; - S32 top = line_height*3 - 2; + S32 top = line_height*3 - 2 + h_offset; S32 bottom = top - 6; S32 left = bar_left; S32 right = left + bar_width; @@ -477,49 +477,49 @@ void LLGLTexMemBar::draw() //---------------------------------------------------------------------------- text = llformat("Textures: Count: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d(%d) RAW:%d mRaw:%d mAux:%d CB:%d", - gImageList.getNumImages(), + gTextureList.getNumImages(), LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(), LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount, LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(), LLLFSThread::sLocal->getPending(), LLImageWorker::sCount, LLImageWorker::getWorkerThread()->getNumDeletes(), - LLImageRaw::sRawImageCount, LLViewerImage::sRawCount, LLViewerImage::sAuxCount, - gImageList.mCallbackList.size()); + LLImageRaw::sRawImageCount, LLViewerFetchedTexture::sRawCount, LLViewerFetchedTexture::sAuxCount, + gTextureList.mCallbackList.size()); - LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, line_height*2, + LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, h_offset + line_height*2, text_color, LLFontGL::LEFT, LLFontGL::TOP); S32 dx1 = 0; if (LLAppViewer::getTextureFetch()->mDebugPause) { - LLFontGL::getFontMonospace()->renderUTF8(std::string("!"), 0, title_x1, line_height, + LLFontGL::getFontMonospace()->renderUTF8(std::string("!"), 0, title_x1, h_offset + line_height, text_color, LLFontGL::LEFT, LLFontGL::TOP); dx1 += 8; } if (mTextureView->mFreezeView) { - LLFontGL::getFontMonospace()->renderUTF8(std::string("*"), 0, title_x1, line_height, + LLFontGL::getFontMonospace()->renderUTF8(std::string("*"), 0, title_x1, h_offset + line_height, text_color, LLFontGL::LEFT, LLFontGL::TOP); dx1 += 8; } if (mTextureView->mOrderFetch) { - LLFontGL::getFontMonospace()->renderUTF8(title_string1b, 0, title_x1+dx1, line_height, + LLFontGL::getFontMonospace()->renderUTF8(title_string1b, 0, title_x1+dx1, h_offset + line_height, text_color, LLFontGL::LEFT, LLFontGL::TOP); } else { - LLFontGL::getFontMonospace()->renderUTF8(title_string1a, 0, title_x1+dx1, line_height, + LLFontGL::getFontMonospace()->renderUTF8(title_string1a, 0, title_x1+dx1, h_offset + line_height, text_color, LLFontGL::LEFT, LLFontGL::TOP); } - LLFontGL::getFontMonospace()->renderUTF8(title_string2, 0, title_x2, line_height, + LLFontGL::getFontMonospace()->renderUTF8(title_string2, 0, title_x2, h_offset + line_height, text_color, LLFontGL::LEFT, LLFontGL::TOP); - LLFontGL::getFontMonospace()->renderUTF8(title_string3, 0, title_x3, line_height, + LLFontGL::getFontMonospace()->renderUTF8(title_string3, 0, title_x3, h_offset + line_height, text_color, LLFontGL::LEFT, LLFontGL::TOP); - LLFontGL::getFontMonospace()->renderUTF8(title_string4, 0, title_x4, line_height, + LLFontGL::getFontMonospace()->renderUTF8(title_string4, 0, title_x4, h_offset + line_height, text_color, LLFontGL::LEFT, LLFontGL::TOP); } @@ -557,7 +557,7 @@ LLTextureView::~LLTextureView() mGLTexMemBar = 0; } -typedef std::pair decode_pair_t; +typedef std::pair decode_pair_t; struct compare_decode_pair { bool operator()(const decode_pair_t& a, const decode_pair_t& b) @@ -587,18 +587,19 @@ void LLTextureView::draw() llinfos << "ID\tMEM\tBOOST\tPRI\tWIDTH\tHEIGHT\tDISCARD" << llendl; } - for (LLViewerImageList::image_priority_list_t::iterator iter = gImageList.mImageList.begin(); - iter != gImageList.mImageList.end(); ) + for (LLViewerTextureList::image_priority_list_t::iterator iter = gTextureList.mImageList.begin(); + iter != gTextureList.mImageList.end(); ) { - LLPointer imagep = *iter++; + LLPointer imagep = *iter++; S32 cur_discard = imagep->getDiscardLevel(); S32 desired_discard = imagep->mDesiredDiscardLevel; if (mPrintList) { + S32 tex_mem = imagep->hasGLTexture() ? imagep->getTextureMemory() : 0 ; llinfos << imagep->getID() - << "\t" << imagep->mTextureMemory + << "\t" << tex_mem << "\t" << imagep->getBoostLevel() << "\t" << imagep->getDecodePriority() << "\t" << imagep->getWidth() @@ -643,8 +644,8 @@ void LLTextureView::draw() { struct f : public LLSelectedTEFunctor { - LLViewerImage* mImage; - f(LLViewerImage* image) : mImage(image) {} + LLViewerFetchedTexture* mImage; + f(LLViewerFetchedTexture* image) : mImage(image) {} virtual bool apply(LLViewerObject* object, S32 te) { return (mImage == object->getTEImage(te)); @@ -701,10 +702,11 @@ void LLTextureView::draw() static S32 max_count = 50; S32 count = 0; + mNumTextureBars = 0 ; for (display_list_t::iterator iter = display_image_list.begin(); iter != display_image_list.end(); iter++) { - LLViewerImage* imagep = iter->second; + LLViewerFetchedTexture* imagep = iter->second; S32 hilite = 0; F32 pri = iter->first; if (pri >= 1 * HIGH_PRIORITY) @@ -734,7 +736,7 @@ void LLTextureView::draw() reshape(getRect().getWidth(), getRect().getHeight(), TRUE); /* - count = gImageList.getNumImages(); + count = gTextureList.getNumImages(); std::string info_string; info_string = llformat("Global Info:\nTexture Count: %d", count); mInfoTextp->setText(info_string); @@ -756,7 +758,7 @@ void LLTextureView::draw() } -BOOL LLTextureView::addBar(LLViewerImage *imagep, S32 hilite) +BOOL LLTextureView::addBar(LLViewerFetchedTexture *imagep, S32 hilite) { llassert(imagep); diff --git a/indra/newview/lltextureview.h b/indra/newview/lltextureview.h index 99b6db9662..20be17aef4 100644 --- a/indra/newview/lltextureview.h +++ b/indra/newview/lltextureview.h @@ -35,7 +35,7 @@ #include "llcontainerview.h" -class LLViewerImage; +class LLViewerFetchedTexture; class LLTextureBar; class LLGLTexMemBar; @@ -54,12 +54,12 @@ public: /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); - static void addDebugImage(LLViewerImage* image) { sDebugImages.insert(image); } - static void removeDebugImage(LLViewerImage* image) { sDebugImages.insert(image); } + static void addDebugImage(LLViewerFetchedTexture* image) { sDebugImages.insert(image); } + static void removeDebugImage(LLViewerFetchedTexture* image) { sDebugImages.insert(image); } static void clearDebugImages() { sDebugImages.clear(); } private: - BOOL addBar(LLViewerImage *image, BOOL hilight = FALSE); + BOOL addBar(LLViewerFetchedTexture *image, BOOL hilight = FALSE); void removeAllBars(); private: @@ -75,7 +75,7 @@ private: LLGLTexMemBar* mGLTexMemBar; public: - static std::set sDebugImages; + static std::set sDebugImages; }; extern LLTextureView *gTextureView; diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp new file mode 100644 index 0000000000..8a7c7708b9 --- /dev/null +++ b/indra/newview/lltoast.cpp @@ -0,0 +1,253 @@ +/** + * @file lltoast.cpp + * @brief This class implements a placeholder for any notification panel. + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "lltoast.h" + +#include "llbutton.h" +#include "llfocusmgr.h" +#include "llviewercontrol.h" + +using namespace LLNotificationsUI; + +//-------------------------------------------------------------------------- +LLToast::LLToast(LLPanel* panel) : + LLFloater(LLSD()), + mTimerValue(5), + mIsViewed(false), + mPanel(panel), + mCanFade(true), + mHideBtn(NULL), + mIsModal(false), + mCanBeStored(true), + mHideBtnPressed(false) +{ + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_toast.xml"); + + mHideBtn = getChild("hide_btn"); + if(mHideBtn) + { + mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this)); + } + if(mPanel) + { + arrange(mPanel); + } + + // disable unnecessary Floater's functionality + setTitleVisible(FALSE); + setCanMinimize(FALSE); + setCanClose(FALSE); + setCanTearOff(FALSE); + setCanResize(FALSE); + setCanDrag(FALSE); +} + +//-------------------------------------------------------------------------- +void LLToast::setHideButtonEnabled(bool enabled) +{ + if(mHideBtn) + mHideBtn->setEnabled(enabled); +} + +//-------------------------------------------------------------------------- +LLToast::~LLToast() +{ + if(mIsModal) + { + gFocusMgr.unlockFocus(); + gFocusMgr.releaseFocusIfNeeded( this ); + } +} + +//-------------------------------------------------------------------------- +void LLToast::setAndStartTimer(F32 period) +{ + if(mCanFade) + { + mTimerValue = period; + mTimer.start(); + } +} + +//-------------------------------------------------------------------------- +bool LLToast::timerHasExpired() +{ + if (mTimer.getStarted()) + { + F32 elapsed_time = mTimer.getElapsedTimeF32(); + if (elapsed_time > gSavedSettings.getS32("ToastOpaqueTime")) + { + setBackgroundOpaque(FALSE); + } + if (elapsed_time > mTimerValue) + { + return true; + } + } + return false; +} + +//-------------------------------------------------------------------------- +void LLToast::hide() +{ + setVisible(FALSE); + mIsViewed = false; + mTimer.stop(); + mOnFade(this, LLSD()); +} + +//-------------------------------------------------------------------------- +void LLToast::setCanFade(bool can_fade) +{ + mCanFade = can_fade; + if(!mCanFade) + mTimer.stop(); +} + +//-------------------------------------------------------------------------- +void LLToast::tick() +{ + if(mCanFade) + { + setVisible(FALSE); + mTimer.stop(); + mOnFade(this, LLSD()); + } +} + +//-------------------------------------------------------------------------- +void LLToast::arrange(LLPanel* panel) +{ + LLRect panel_rect, toast_rect; + + panel_rect = panel->getRect(); + reshape(panel_rect.getWidth(), panel_rect.getHeight()); + panel_rect.setLeftTopAndSize(0, panel_rect.getHeight(), panel_rect.getWidth(), panel_rect.getHeight()); + panel->setRect(panel_rect); + addChild(panel); +} + +//-------------------------------------------------------------------------- +void LLToast::draw() +{ + if(timerHasExpired()) + { + tick(); + } + + LLFloater::draw(); +} + +//-------------------------------------------------------------------------- +void LLToast::setModal(bool modal) +{ + mIsModal = modal; + if(mIsModal) + { + gFocusMgr.setMouseCapture( this ); + gFocusMgr.setTopCtrl( this ); + setFocus(TRUE); + } +} + +//-------------------------------------------------------------------------- +void LLToast::setVisible(BOOL show) +{ + if(show) + { + setBackgroundOpaque(TRUE); + } + LLPanel::setVisible(show); + if(mPanel) + { + if(!mPanel->isDead()) + { + mPanel->setVisible(show); + } + } +} + +//-------------------------------------------------------------------------- +void LLToast::onMouseEnter(S32 x, S32 y, MASK mask) +{ + mOnToastHover(this, MOUSE_ENTER); + + setVisibleAndFrontmost(); + setBackgroundOpaque(TRUE); + if(mCanFade && !mIsViewed) + { + mTimer.stop(); + } + + sendChildToFront(mHideBtn); + if(mHideBtn && mHideBtn->getEnabled()) + mHideBtn->setVisible(TRUE); + mOnMousEnter(this, LLSD()); +} + +//-------------------------------------------------------------------------- +void LLToast::onMouseLeave(S32 x, S32 y, MASK mask) +{ + llinfos << "MOUSE LEAVE: x = " << x << "y = " << y << llendl; + mOnToastHover(this, MOUSE_LEAVE); + + if(mCanFade && !mIsViewed) + { + mTimer.start(); + } + if(mHideBtn && mHideBtn->getEnabled()) + { + if( mHideBtnPressed ) + { + mHideBtnPressed = false; + return; + } + mHideBtn->setVisible(FALSE); + } +} + +//-------------------------------------------------------------------------- + +BOOL LLToast::handleMouseDown(S32 x, S32 y, MASK mask) +{ + if(mHideBtn && mHideBtn->getEnabled()) + { + mHideBtnPressed = mHideBtn->getRect().pointInRect(x, y); + } + + return LLFloater::handleMouseDown(x, y, mask); +} + + + diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h new file mode 100644 index 0000000000..f998754585 --- /dev/null +++ b/indra/newview/lltoast.h @@ -0,0 +1,117 @@ +/** + * @file lltoast.h + * @brief This class implements a placeholder for any notification panel. + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLTOAST_H +#define LL_LLTOAST_H + + +#include "llpanel.h" +#include "llfloater.h" +#include "lltimer.h" +#include "lldate.h" + +#define MOUSE_LEAVE false +#define MOUSE_ENTER true + +namespace LLNotificationsUI +{ + +/** + * Represents toast pop-up. + * This is a parent view for all toast panels. + */ +class LLToast : public LLFloater +{ +public: + LLToast(LLPanel* panel); + virtual ~LLToast(); + + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + // + bool isViewed() { return mIsViewed; } + + void setCanFade(bool can_fade); + + void setHideButtonEnabled(bool enabled); + + void setCanBeStored(bool can_be_stored) { mCanBeStored = can_be_stored; } + bool getCanBeStored() { return mCanBeStored; } + // + void setAndStartTimer(F32 period); + // + void resetTimer() { mTimer.start(); } + void stopTimer() { mTimer.stop(); } + void close() { die(); } + virtual void draw(); + virtual void setVisible(BOOL show); + virtual void onMouseEnter(S32 x, S32 y, MASK mask); + virtual void onMouseLeave(S32 x, S32 y, MASK mask); + virtual void hide(); + LLPanel* getPanel() { return mPanel; } + void arrange(LLPanel* panel); + void setModal(bool modal); + + + // Registers callbacks for events + boost::signals2::connection setOnFadeCallback(commit_callback_t cb) { return mOnFade.connect(cb); } + boost::signals2::connection setOnMouseEnterCallback(commit_callback_t cb) { return mOnMousEnter.connect(cb); } + boost::signals2::connection setOnToastDestroyCallback(commit_callback_t cb) { return mOnToastDestroy.connect(cb); } + typedef boost::function toast_hover_check_callback_t; + typedef boost::signals2::signal toast_hover_check_signal_t; + toast_hover_check_signal_t mOnToastHover; + boost::signals2::connection setOnToastHoverCallback(toast_hover_check_callback_t cb) { return mOnToastHover.connect(cb); } + + commit_signal_t mOnFade; + commit_signal_t mOnMousEnter; + commit_signal_t mOnToastDestroy; + +private: + + bool timerHasExpired(); + void tick(); + + LLTimer mTimer; + F32 mTimerValue; + + LLPanel* mPanel; + LLButton* mHideBtn; + + LLColor4 mBgColor; + bool mIsViewed; + bool mCanFade; + bool mIsModal; + bool mCanBeStored; + bool mHideBtnPressed; +}; + +} +#endif diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp new file mode 100644 index 0000000000..5d67015526 --- /dev/null +++ b/indra/newview/lltoastalertpanel.cpp @@ -0,0 +1,470 @@ +/** + * @file lltoastalertpanel.cpp + * @brief Panel for alert toasts. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "linden_common.h" + +#include "llboost.h" + +#include "lltoastalertpanel.h" +#include "llfontgl.h" +#include "lltextbox.h" +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llkeyboard.h" +#include "llfocusmgr.h" +#include "lliconctrl.h" +#include "llui.h" +#include "lllineeditor.h" +#include "lluictrlfactory.h" +#include "llnotifications.h" +#include "llfunctorregistry.h" + +const S32 MAX_ALLOWED_MSG_WIDTH = 400; +const F32 DEFAULT_BUTTON_DELAY = 0.5f; +const S32 MSG_PAD = 8; + +/*static*/ LLControlGroup* LLToastAlertPanel::sSettings = NULL; +/*static*/ LLToastAlertPanel::URLLoader* LLToastAlertPanel::sURLLoader; + +//----------------------------------------------------------------------------- +// Private methods + +static const S32 VPAD = 16; +static const S32 HPAD = 25; +static const S32 BTN_HPAD = 8; + +LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal) + : LLFloater(LLSD()), + LLToastPanel(notification), + mDefaultOption( 0 ), + mCheck(NULL), + mCaution(notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH), + mLabel(notification->getName()), + mLineEditor(NULL) +{ + const LLFontGL* font = LLFontGL::getFontSansSerif(); + const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f); + const S32 EDITOR_HEIGHT = 20; + + LLNotificationFormPtr form = mNotification->getForm(); + std::string edit_text_name; + std::string edit_text_contents; + bool is_password = false; + + LLToastPanel::setBackgroundVisible(FALSE); + LLToastPanel::setBackgroundOpaque(TRUE); + + + typedef std::vector > options_t; + options_t supplied_options; + + // for now, get LLSD to iterator over form elements + LLSD form_sd = form->asLLSD(); + + S32 option_index = 0; + for (LLSD::array_const_iterator it = form_sd.beginArray(); it != form_sd.endArray(); ++it) + { + std::string type = (*it)["type"].asString(); + if (type == "button") + { + if((*it)["default"]) + { + mDefaultOption = option_index; + } + + supplied_options.push_back(std::make_pair((*it)["name"].asString(), (*it)["text"].asString())); + + ButtonData data; + if (option_index == mNotification->getURLOption()) + { + data.mURL = mNotification->getURL(); + data.mURLExternal = mNotification->getURLOpenExternally(); + } + + mButtonData.push_back(data); + option_index++; + } + else if (type == "text") + { + edit_text_contents = (*it)["value"].asString(); + edit_text_name = (*it)["name"].asString(); + } + else if (type == "password") + { + edit_text_contents = (*it)["value"].asString(); + edit_text_name = (*it)["name"].asString(); + is_password = true; + } + } + + // Buttons + options_t options; + if (supplied_options.empty()) + { + options.push_back(std::make_pair(std::string("close"), LLNotifications::instance().getGlobalString("implicitclosebutton"))); + + // add data for ok button. + ButtonData ok_button; + mButtonData.push_back(ok_button); + mDefaultOption = 0; + } + else + { + options = supplied_options; + } + + S32 num_options = options.size(); + + // Calc total width of buttons + S32 button_width = 0; + S32 sp = font->getWidth(std::string("OO")); + for( S32 i = 0; i < num_options; i++ ) + { + S32 w = S32(font->getWidth( options[i].second ) + 0.99f) + sp + 2 * LLBUTTON_H_PAD; + button_width = llmax( w, button_width ); + } + S32 btn_total_width = button_width; + if( num_options > 1 ) + { + btn_total_width = (num_options * button_width) + ((num_options - 1) * BTN_HPAD); + } + + // Message: create text box using raw string, as text has been structure deliberately + // Use size of created text box to generate dialog box size + std::string msg = mNotification->getMessage(); + llwarns << "Alert: " << msg << llendl; + LLTextBox::Params params; + params.name("Alert message"); + params.font(font); + params.tab_stop(false); + params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP); + + LLTextBox * msg_box = LLUICtrlFactory::create (params); + // Compute max allowable height for the dialog text, so we can allocate + // space before wrapping the text to fit. + S32 max_allowed_msg_height = + gFloaterView->getRect().getHeight() + - LINE_HEIGHT // title bar + - 3*VPAD - BTN_HEIGHT; + msg_box->reshape( MAX_ALLOWED_MSG_WIDTH, max_allowed_msg_height ); + msg_box->setWrappedText(msg, (F32)MAX_ALLOWED_MSG_WIDTH); + msg_box->reshapeToFitText(); + + const LLRect& text_rect = msg_box->getRect(); + S32 dialog_width = llmax( btn_total_width, text_rect.getWidth() ) + 2 * HPAD; + S32 dialog_height = text_rect.getHeight() + 3 * VPAD + BTN_HEIGHT; + + if (hasTitleBar()) + { + dialog_height += LINE_HEIGHT; // room for title bar + } + + // it's ok for the edit text body to be empty, but we want the name to exist if we're going to draw it + if (!edit_text_name.empty()) + { + dialog_height += EDITOR_HEIGHT + VPAD; + dialog_width = llmax(dialog_width, (S32)(font->getWidth( edit_text_contents ) + 0.99f)); + } + + if (mCaution) + { + // Make room for the caution icon. + dialog_width += 32 + HPAD; + } + + LLToastPanel::reshape( dialog_width, dialog_height, FALSE ); + + S32 msg_y = LLToastPanel::getRect().getHeight() - VPAD; + S32 msg_x = HPAD; + if (hasTitleBar()) + { + msg_y -= LINE_HEIGHT; // room for title + } + + static LLUIColor alert_caution_text_color = LLUIColorTable::instance().getColor("AlertCautionTextColor"); + static LLUIColor alert_text_color = LLUIColorTable::instance().getColor("AlertTextColor"); + if (mCaution) + { + LLIconCtrl::Params params; + params.name("icon"); + params.rect(LLRect(msg_x, msg_y, msg_x+32, msg_y-32)); + params.mouse_opaque(false); + params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP); + params.tab_stop(false); + LLIconCtrl * icon = LLUICtrlFactory::create (params); + icon->setValue ("notify_caution_icon.tga"); + icon->setMouseOpaque(FALSE); + LLToastPanel::addChild(icon); + msg_x += 32 + HPAD; + msg_box->setColor( alert_caution_text_color ); + } + else + { + msg_box->setColor( alert_text_color ); + } + + LLRect rect; + rect.setLeftTopAndSize( msg_x, msg_y, text_rect.getWidth(), text_rect.getHeight() ); + msg_box->setRect( rect ); + LLToastPanel::addChild(msg_box); + + // Buttons + S32 button_left = (LLToastPanel::getRect().getWidth() - btn_total_width) / 2; + + for( S32 i = 0; i < num_options; i++ ) + { + LLRect button_rect; + button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT ); + + LLButton::Params p; + p.name(options[i].first); + p.rect(button_rect); + p.click_callback.function(boost::bind(&LLToastAlertPanel::onButtonPressed, this, _2, i)); + p.font(font); + p.label(options[i].second); + + LLButton* btn = LLUICtrlFactory::create(p); + mButtonData[i].mButton = btn; + + LLToastPanel::addChild(btn); + + if( i == mDefaultOption ) + { + btn->setFocus(TRUE); + } + + button_left += button_width + BTN_HPAD; + } + + // (Optional) Edit Box + if (!edit_text_name.empty()) + { + S32 y = VPAD + BTN_HEIGHT + VPAD/2; + + LLLineEditor::Params params; + params.name(edit_text_name); + params.rect(LLRect( HPAD, y+EDITOR_HEIGHT, dialog_width-HPAD, y)); + params.default_text(edit_text_contents); + params.max_length_bytes(STD_STRING_STR_LEN); + mLineEditor = LLUICtrlFactory::create (params); + + // make sure all edit keys get handled properly (DEV-22396) + mLineEditor->setHandleEditKeysDirectly(TRUE); + + LLToastPanel::addChild(mLineEditor); + } + + if (mLineEditor) + { + mLineEditor->setDrawAsterixes(is_password); + + setEditTextArgs(notification->getSubstitutions()); + } + + std::string ignore_label; + + if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE) + { + setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label); + } + else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE) + { + setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label); + } + + gFloaterView->adjustToFitScreen(this, FALSE); + LLFloater::setFocus(TRUE); + if (mLineEditor) + { + mLineEditor->setFocus(TRUE); + mLineEditor->selectAll(); + } + if(mDefaultOption >= 0) + { + // delay before enabling default button + mDefaultBtnTimer.start(); + mDefaultBtnTimer.setTimerExpirySec(DEFAULT_BUTTON_DELAY); + } +} + +bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std::string& check_control ) +{ + const LLFontGL* font = LLFontGL::getFontSansSerif(); + const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f); + + // Extend dialog for "check next time" + S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * HPAD; + S32 check_width = S32(font->getWidth(check_title) + 0.99f) + 16; + max_msg_width = llmax(max_msg_width, check_width); + S32 dialog_width = max_msg_width + 2 * HPAD; + + S32 dialog_height = LLToastPanel::getRect().getHeight(); + dialog_height += LINE_HEIGHT; + dialog_height += LINE_HEIGHT / 2; + + LLToastPanel::reshape( dialog_width, dialog_height, FALSE ); + + S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2; + + LLCheckBoxCtrl::Params p; + p.name("check"); + p.rect.left(msg_x).bottom(VPAD+BTN_HEIGHT+LINE_HEIGHT/2).width(max_msg_width).height(LINE_HEIGHT); + p.label(check_title); + p.font(font); + p.commit_callback.function(boost::bind(&LLToastAlertPanel::onClickIgnore, this, _1)); + mCheck = LLUICtrlFactory::create(p); + LLToastPanel::addChild(mCheck); + + return true; +} + +void LLToastAlertPanel::setVisible( BOOL visible ) +{ + LLToastPanel::setVisible( visible ); + + if( visible ) + { + make_ui_sound("UISndAlert"); + } +} + +LLToastAlertPanel::~LLToastAlertPanel() +{ +} + +BOOL LLToastAlertPanel::hasTitleBar() const +{ + return (getCurrentTitle() != "" && getCurrentTitle() != " ") // has title + || isMinimizeable() + || isCloseable(); +} + +BOOL LLToastAlertPanel::handleKeyHere(KEY key, MASK mask ) +{ + if( KEY_RETURN == key && mask == MASK_NONE ) + { + return TRUE; + } + else if (KEY_RIGHT == key) + { + LLToastPanel::focusNextItem(FALSE); + return TRUE; + } + else if (KEY_LEFT == key) + { + LLToastPanel::focusPrevItem(FALSE); + return TRUE; + } + else if (KEY_TAB == key && mask == MASK_NONE) + { + LLToastPanel::focusNextItem(FALSE); + return TRUE; + } + else if (KEY_TAB == key && mask == MASK_SHIFT) + { + LLToastPanel::focusPrevItem(FALSE); + return TRUE; + } + else + { + return TRUE; + } +} + +// virtual +void LLToastAlertPanel::draw() +{ + // if the default button timer has just expired, activate the default button + if(mDefaultBtnTimer.hasExpired() && mDefaultBtnTimer.getStarted()) + { + mDefaultBtnTimer.stop(); // prevent this block from being run more than once + LLToastPanel::setDefaultBtn(mButtonData[mDefaultOption].mButton); + } + + static LLUIColor shadow_color = LLUIColorTable::instance().getColor("ColorDropShadow"); + static LLUICachedControl shadow_lines ("DropShadowFloater"); + + gl_drop_shadow( 0, LLToastPanel::getRect().getHeight(), LLToastPanel::getRect().getWidth(), 0, + shadow_color, shadow_lines); + + LLToastPanel::draw(); +} + +void LLToastAlertPanel::setEditTextArgs(const LLSD& edit_args) +{ + if (mLineEditor) + { + std::string msg = mLineEditor->getText(); + mLineEditor->setText(msg); + } + else + { + llwarns << "LLToastAlertPanel::setEditTextArgs called on dialog with no line editor" << llendl; + } +} + +void LLToastAlertPanel::onButtonPressed( const LLSD& data, S32 button ) +{ + ButtonData* button_data = &mButtonData[button]; + + LLSD response = mNotification->getResponseTemplate(); + if (mLineEditor) + { + response[mLineEditor->getName()] = mLineEditor->getValue(); + } + response[button_data->mButton->getName()] = true; + + // If we declared a URL and chose the URL option, go to the url + if (!button_data->mURL.empty() && sURLLoader != NULL) + { + sURLLoader->load(button_data->mURL, button_data->mURLExternal); + } + + mNotification->respond(response); // new notification reponse + closeFloater(); // deletes self +} + +void LLToastAlertPanel::onClickIgnore(LLUICtrl* ctrl) +{ + // checkbox sometimes means "hide and do the default" and + // other times means "warn me again". Yuck. JC + BOOL check = ctrl->getValue().asBoolean(); + if (mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN) + { + // question was "show again" so invert value to get "ignore" + check = !check; + } + mNotification->setIgnored(check); +} diff --git a/indra/newview/lltoastalertpanel.h b/indra/newview/lltoastalertpanel.h new file mode 100644 index 0000000000..543c14d404 --- /dev/null +++ b/indra/newview/lltoastalertpanel.h @@ -0,0 +1,123 @@ +/** + * @file lltoastalertpanel.h + * @brief Panel for alert toasts. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_TOASTALERTPANEL_H +#define LL_TOASTALERTPANEL_H + +#include "lltoastpanel.h" +#include "llfloater.h" +#include "llui.h" +#include "llnotifications.h" + +class LLButton; +class LLCheckBoxCtrl; +class LLAlertDialogTemplate; +class LLLineEditor; + +/** + * Toast panel for alert notification. + * Alerts notifications doesn't require user interaction. + * + * Replaces class LLAlertDialog. + * https://wiki.lindenlab.com/mediawiki/index.php?title=LLAlertDialog&oldid=81388 + */ + +class LLToastAlertPanel + : public LLToastPanel, + public LLFloater +{ +public: + typedef bool (*display_callback_t)(S32 modal); + + class URLLoader + { + public: + virtual void load(const std::string& url, bool force_open_externally = 0 ) = 0; + virtual ~URLLoader() {} + }; + + static void setURLLoader(URLLoader* loader) + { + sURLLoader = loader; + } + +public: + // User's responsibility to call show() after creating these. + LLToastAlertPanel( LLNotificationPtr notep, bool is_modal ); + + virtual BOOL handleKeyHere(KEY key, MASK mask ); + + virtual void draw(); + virtual void setVisible( BOOL visible ); + + bool setCheckBox( const std::string&, const std::string& ); + void setCaution(BOOL val = TRUE) { mCaution = val; } + // If mUnique==TRUE only one copy of this message should exist + void setUnique(BOOL val = TRUE) { mUnique = val; } + void setEditTextArgs(const LLSD& edit_args); + + void onClickIgnore(LLUICtrl* ctrl); + void onButtonPressed(const LLSD& data, S32 button); + +private: + static std::map sUniqueActiveMap; + + virtual ~LLToastAlertPanel(); + // No you can't kill it. It can only kill itself. + + // Does it have a readable title label, or minimize or close buttons? + BOOL hasTitleBar() const; + +private: + static URLLoader* sURLLoader; + static LLControlGroup* sSettings; + + struct ButtonData + { + LLButton* mButton; + std::string mURL; + U32 mURLExternal; + }; + std::vector mButtonData; + + S32 mDefaultOption; + LLCheckBoxCtrl* mCheck; + BOOL mCaution; + BOOL mUnique; + LLUIString mLabel; + LLFrameTimer mDefaultBtnTimer; + // For Dialogs that take a line as text as input: + LLLineEditor* mLineEditor; + +}; + +#endif // LL_TOASTALERTPANEL_H diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp new file mode 100644 index 0000000000..f5ed7f8710 --- /dev/null +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -0,0 +1,206 @@ +/** + * @file lltoastgroupnotifypanel.cpp + * @brief Panel for group notify toasts. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lltoastgroupnotifypanel.h" + +#include "llfocusmgr.h" + +#include "llbutton.h" +#include "lliconctrl.h" +#include "llnotify.h" +#include "lltextbox.h" +#include "llviewertexteditor.h" +#include "lluiconstants.h" +#include "llui.h" +#include "llviewercontrol.h" +#include "llfloatergroupinfo.h" +#include "lltrans.h" +#include "llinitparam.h" + +#include "llglheaders.h" +#include "llagent.h" +#include "llavatariconctrl.h" +#include "llfloaterinventory.h" +#include "llinventorytype.h" + +LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification) +: LLToastPanel(notification), + mInventoryOffer(NULL) +{ + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_notify.xml"); + const LLSD& payload = notification->getPayload(); + LLGroupData groupData; + if (!gAgent.getGroupData(payload["group_id"].asUUID(),groupData)) + { + llwarns << "Group notice for unkown group: " << payload["group_id"].asUUID() << llendl; + } + + static const LLUIColor textColor = LLUIColorTable::instance().getColor("GroupNotifyTextColor"); + + //group icon + LLIconCtrl* pGroupIcon = getChild("group_icon", TRUE); + pGroupIcon->setValue(groupData.mInsigniaID); + + //header title + const std::string& from_name = payload["sender_name"].asString(); + std::stringstream from; + from << from_name << "/" << groupData.mName; + LLTextBox* pTitleText = this->getChild("title", TRUE, FALSE); + pTitleText->setValue(from.str()); + + //message body + const std::string& subject = payload["subject"].asString(); + const std::string& message = payload["message"].asString(); + + LLTextEditor* pMessageText = getChild< LLTextEditor>("message", TRUE, FALSE); + pMessageText->setValue(""); + pMessageText->setEnabled(FALSE); + pMessageText->setTakesFocus(FALSE); + + static const LLStyleSP headerstyle(new LLStyle(true, textColor, + "SansSerifBig")); + static const LLStyleSP datestyle(new LLStyle(true, textColor, "serif")); + + pMessageText->appendStyledText(subject + "\n",false,false,headerstyle); + + std::string timeStr = "["+LLTrans::getString("UTCTimeWeek")+"],[" + +LLTrans::getString("UTCTimeDay")+"] [" + +LLTrans::getString("UTCTimeMth")+"] [" + +LLTrans::getString("UTCTimeYr")+"] [" + +LLTrans::getString("UTCTimeHr")+"]:[" + +LLTrans::getString("UTCTimeMin")+"]:[" + +LLTrans::getString("UTCTimeSec")+"] [" + +LLTrans::getString("UTCTimeTimezone")+"]"; + const LLDate timeStamp = notification->getDate(); + LLDate notice_date = timeStamp.notNull() ? timeStamp : LLDate::now(); + LLSD substitution; + substitution["datetime"] = (S32) notice_date.secondsSinceEpoch(); + LLStringUtil::format(timeStr, substitution); + pMessageText->appendStyledText(timeStr, false, false, datestyle); + pMessageText->appendColoredText(std::string("\n\n") + message, false, + false, textColor); + + //attachment + BOOL hasInventory = payload["inventory_offer"].isDefined(); + LLTextBox * pAttachLink = getChild("attachment", TRUE, FALSE); + pAttachLink->setVisible(hasInventory); + if (hasInventory) { + pAttachLink->setValue(payload["inventory_name"]); + mInventoryOffer = new LLOfferInfo(payload["inventory_offer"]); + childSetActionTextbox("attachment", boost::bind( + &LLToastGroupNotifyPanel::onClickAttachment, this)); + + //attachment icon + LLIconCtrl* pAttachIcon = getChild("attachment_icon", TRUE); + LLUIImagePtr attachIconImg = get_item_icon(mInventoryOffer->mType, + LLInventoryType::IT_TEXTURE, + 0, FALSE); + pAttachIcon->setValue(attachIconImg->getName()); + } + + //ok button + LLButton* pOkBtn = getChild("btn_ok", TRUE, FALSE); + pOkBtn->setClickedCallback((boost::bind(&LLToastGroupNotifyPanel::onClickOk, this))); + setDefaultBtn(pOkBtn); +} + + +// virtual +LLToastGroupNotifyPanel::~LLToastGroupNotifyPanel() +{ +} + +void LLToastGroupNotifyPanel::close() +{ + // The group notice dialog may be an inventory offer. + // If it has an inventory save button and that button is still enabled + // Then we need to send the inventory declined message + if(mInventoryOffer != NULL) + { + mInventoryOffer->forceResponse(IOR_DECLINE); + mInventoryOffer = NULL; + } + + die(); +} + +void LLToastGroupNotifyPanel::onClickOk() +{ + LLSD response = mNotification->getResponseTemplate(); + mNotification->respond(response); + close(); +} + +void LLToastGroupNotifyPanel::onClickAttachment() +{ + if (mInventoryOffer != NULL) { + mInventoryOffer->forceResponse(IOR_ACCEPT); + + LLTextBox * pAttachLink = getChild ("attachment", TRUE, + FALSE); + static const LLUIColor textColor = LLUIColorTable::instance().getColor( + "GroupNotifyDimmedTextColor"); + pAttachLink->setColor(textColor); + + LLIconCtrl* pAttachIcon = + getChild ("attachment_icon", TRUE); + pAttachIcon->setEnabled(FALSE); + + //if attachment isn't openable - notify about saving + if (!isAttachmentOpenable(mInventoryOffer->mType)) { + LLNotifications::instance().add("AttachmentSaved"); + } + + mInventoryOffer = NULL; + } +} + +//static +bool LLToastGroupNotifyPanel::isAttachmentOpenable(LLAssetType::EType type) +{ + switch(type) + { + case LLAssetType::AT_LANDMARK: + case LLAssetType::AT_FAVORITE: + case LLAssetType::AT_NOTECARD: + case LLAssetType::AT_IMAGE_JPEG: + case LLAssetType::AT_IMAGE_TGA: + case LLAssetType::AT_TEXTURE: + case LLAssetType::AT_TEXTURE_TGA: + return true; + default: + return false; + } +} + diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h new file mode 100644 index 0000000000..ba98531251 --- /dev/null +++ b/indra/newview/lltoastgroupnotifypanel.h @@ -0,0 +1,83 @@ +/** + * @file lltoastgroupnotifypanel.h + * @brief Panel for group notify toasts. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLGROUPNOTIFY_H +#define LL_LLGROUPNOTIFY_H + +#include "llfontgl.h" +#include "lltoastpanel.h" +#include "lldarray.h" +#include "lltimer.h" +#include "llviewermessage.h" +#include "llnotifications.h" + +class LLButton; + +/** + * Toast panel for group notification. + * + * Replaces class LLGroupNotifyBox. + */ +class LLToastGroupNotifyPanel +: public LLToastPanel +{ +public: + void close(); + + static bool onNewNotification(const LLSD& notification); + + + // Non-transient messages. You can specify non-default button + // layouts (like one for script dialogs) by passing various + // numbers in for "layout". + LLToastGroupNotifyPanel(LLNotificationPtr& notification); + + /*virtual*/ ~LLToastGroupNotifyPanel(); +protected: + void onClickOk(); + void onClickAttachment(); +private: + static bool isAttachmentOpenable(LLAssetType::EType); + + LLButton* mSaveInventoryBtn; + + LLUUID mGroupID; + LLOfferInfo* mInventoryOffer; +}; + +// This view contains the stack of notification windows. +//extern LLView* gGroupNotifyBoxView; + +const S32 GROUP_LAYOUT_DEFAULT = 0; +const S32 GROUP_LAYOUT_SCRIPT_DIALOG = 1; + +#endif diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp new file mode 100644 index 0000000000..a7b57802c1 --- /dev/null +++ b/indra/newview/lltoastnotifypanel.cpp @@ -0,0 +1,435 @@ +/** + * @file lltoastnotifypanel.cpp + * @brief Panel for notify toasts. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lltoastnotifypanel.h" +#include "llviewercontrol.h" +#include "lluiconstants.h" +#include "llrect.h" +#include "lliconctrl.h" +#include "lltexteditor.h" +#include "lltextbox.h" +#include "lldbstrings.h" +#include "llchat.h" +#include "llfloaterchat.h" +#include "lltrans.h" +#include "lloverlaybar.h" + + +const S32 BOTTOM_PAD = VPAD * 3; + +//static +const LLFontGL* LLToastNotifyPanel::sFont = NULL; +const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL; + +LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification) : LLToastPanel(notification) { + mIsTip = notification->getType() == "notifytip"; + mNumOptions = 0; + mNumButtons = 0; + mIsScriptDialog = (notification->getName() == "ScriptDialog" + || notification->getName() == "ScriptDialogGroup"); + mAddedDefaultBtn = false; + + // clicking on a button does not steal current focus + setIsChrome(TRUE); + + // class init + if (!sFont) + { + sFont = LLFontGL::getFontSansSerif(); + sFontSmall = LLFontGL::getFontSansSerifSmall(); + } + + // setup paramaters + mMessage = notification->getMessage(); + + // initialize + setFocusRoot(!mIsTip); + + // caution flag can be set explicitly by specifying it in the + // notification payload, or it can be set implicitly if the + // notify xml template specifies that it is a caution + // + // tip-style notification handle 'caution' differently - + // they display the tip in a different color + mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH; + + LLNotificationFormPtr form(notification->getForm()); + + mNumOptions = form->getNumElements(); + + LLRect rect = mIsTip ? getNotifyTipRect(mMessage) + : getNotifyRect(mNumOptions, mIsScriptDialog, mIsCaution); + setRect(rect); + setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT)); + setBackgroundVisible(FALSE); + setBackgroundOpaque(TRUE); + + LLIconCtrl* icon; + LLTextEditor* text; + + const S32 TOP = getRect().getHeight() - (mIsTip ? (S32)sFont->getLineHeight() : 32); + const S32 BOTTOM = (S32)sFont->getLineHeight(); + S32 x = HPAD + HPAD; + S32 y = TOP; + + LLIconCtrl::Params common_params; + common_params.rect(LLRect(x, y, x+32, TOP-32)); + common_params.mouse_opaque(false); + common_params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP); + common_params.tab_stop(false); + + if (mIsTip) + { + // use the tip notification icon + common_params.image(LLUI::getUIImage("notify_tip_icon.tga")); + icon = LLUICtrlFactory::create (common_params); + } + else if (mIsCaution) + { + // use the caution notification icon + common_params.image(LLUI::getUIImage("notify_caution_icon.tga")); + icon = LLUICtrlFactory::create (common_params); + } + else + { + // use the default notification icon + common_params.image(LLUI::getUIImage("notify_box_icon.tga")); + icon = LLUICtrlFactory::create (common_params); + } + + icon->setMouseOpaque(FALSE); + addChild(icon); + + x += HPAD + HPAD + 32; + + // add a caution textbox at the top of a caution notification + LLTextBox* caution_box = NULL; + if (mIsCaution && !mIsTip) + { + S32 caution_height = ((S32)sFont->getLineHeight() * 2) + VPAD; + LLTextBox::Params params; + params.name("caution_box"); + params.rect(LLRect(x, y, getRect().getWidth() - 2, caution_height)); + params.font(sFont); + params.mouse_opaque(false); + params.font.style("BOLD"); + params.text_color(LLUIColorTable::instance().getColor("NotifyCautionWarnColor")); + params.background_color(LLUIColorTable::instance().getColor("NotifyCautionBoxColor")); + params.border_visible(false); + caution_box = LLUICtrlFactory::create (params); + caution_box->setWrappedText(notification->getMessage()); + + addChild(caution_box); + + // adjust the vertical position of the next control so that + // it appears below the caution textbox + y = y - caution_height; + } + else + { + + const S32 BTN_TOP = BOTTOM_PAD + (((mNumOptions-1+2)/3)) * (BTN_HEIGHT+VPAD); + + // Tokenization on \n is handled by LLTextBox + + const S32 MAX_LENGTH = 512 + 20 + + DB_FIRST_NAME_BUF_SIZE + + DB_LAST_NAME_BUF_SIZE + + DB_INV_ITEM_NAME_BUF_SIZE; // For script dialogs: add space for title. + + LLTextEditor::Params params; + params.name("box"); + params.rect(LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16)); + params.max_text_length(MAX_LENGTH); + params.default_text(mMessage); + params.font(sFont); + params.embedded_items(false); + params.word_wrap(true); + params.tab_stop(false); + params.mouse_opaque(false); + params.bg_readonly_color(LLColor4::transparent); + params.text_readonly_color(LLUIColorTable::instance().getColor("NotifyTextColor")); + params.takes_non_scroll_clicks(false); + params.hide_scrollbar(true); + params.enabled(false); + params.hide_border(true); + text = LLUICtrlFactory::create (params); + addChild(text); + } + + if (mIsTip) + { + // TODO: Make a separate archive for these. + LLChat chat(mMessage); + chat.mSourceType = CHAT_SOURCE_SYSTEM; + LLFloaterChat::addChatHistory(chat); + } + else + { + LLButton::Params p; + p.name(std::string("next")); + p.rect(LLRect(getRect().getWidth()-26, BOTTOM_PAD + 20, getRect().getWidth()-2, BOTTOM_PAD)); + p.image_selected.name("notify_next.png"); + p.image_unselected.name("notify_next.png"); + p.font(sFont); + p.scale_image(true); + p.tool_tip(LLTrans::getString("next").c_str()); + + for (S32 i = 0; i < mNumOptions; i++) + { + + LLSD form_element = form->getElement(i); + if (form_element["type"].asString() != "button") + { + continue; + } + + addButton(form_element["name"].asString(), form_element["text"].asString(), TRUE, form_element["default"].asBoolean()); + } + + if (mNumButtons == 0) + { + addButton("OK", LLTrans::getString("ok"), FALSE, TRUE); + mAddedDefaultBtn = true; + } + + + } +} + +LLToastNotifyPanel::~LLToastNotifyPanel() { + std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer()); +} + + +LLRect LLToastNotifyPanel::getNotifyRect(S32 num_options, BOOL mIsScriptDialog, BOOL is_caution) +{ + S32 notify_height = gSavedSettings.getS32("NotifyBoxHeight"); + if (is_caution) + { + // make caution-style dialog taller to accomodate extra text, + // as well as causing the accept/decline buttons to be drawn + // in a different position, to help prevent "quick-click-through" + // of many permissions prompts + notify_height = gSavedSettings.getS32("PermissionsCautionNotifyBoxHeight"); + } + const S32 NOTIFY_WIDTH = gSavedSettings.getS32("NotifyBoxWidth"); + + const S32 TOP = getRect().getHeight(); + const S32 RIGHT =getRect().getWidth(); + const S32 LEFT = RIGHT - NOTIFY_WIDTH; + + if (num_options < 1) + { + num_options = 1; + } + + // Add two "blank" option spaces. + if (mIsScriptDialog) + { + num_options += 2; + } + + S32 additional_lines = (num_options-1) / 3; + + notify_height += additional_lines * (BTN_HEIGHT + VPAD); + + return LLRect(LEFT, TOP, RIGHT, TOP-notify_height); +} + +// static +LLRect LLToastNotifyPanel::getNotifyTipRect(const std::string &utf8message) +{ + S32 line_count = 1; + LLWString message = utf8str_to_wstring(utf8message); + S32 message_len = message.length(); + + const S32 NOTIFY_WIDTH = gSavedSettings.getS32("NotifyBoxWidth"); + // Make room for the icon area. + const S32 text_area_width = NOTIFY_WIDTH - HPAD * 4 - 32; + + const llwchar* wchars = message.c_str(); + const llwchar* start = wchars; + const llwchar* end; + S32 total_drawn = 0; + BOOL done = FALSE; + + do + { + line_count++; + + for (end=start; *end != 0 && *end != '\n'; end++) + ; + + if( *end == 0 ) + { + end = wchars + message_len; + done = TRUE; + } + + S32 remaining = end - start; + while( remaining ) + { + S32 drawn = sFont->maxDrawableChars( start, (F32)text_area_width, remaining, TRUE ); + + if( 0 == drawn ) + { + drawn = 1; // Draw at least one character, even if it doesn't all fit. (avoids an infinite loop) + } + + total_drawn += drawn; + start += drawn; + remaining -= drawn; + + if( total_drawn < message_len ) + { + if( (wchars[ total_drawn ] != '\n') ) + { + // wrap because line was too long + line_count++; + } + } + else + { + done = TRUE; + } + } + + total_drawn++; // for '\n' + end++; + start = end; + } while( !done ); + + const S32 MIN_NOTIFY_HEIGHT = 72; + const S32 MAX_NOTIFY_HEIGHT = 600; + S32 notify_height = llceil((F32) (line_count+1) * sFont->getLineHeight()); + if(gOverlayBar) + { + notify_height += gOverlayBar->getBoundingRect().mTop; + } + else + { + // *FIX: this is derived from the padding caused by the + // rounded rects, shouldn't be a const here. + notify_height += 10; + } + notify_height += VPAD; + notify_height = llclamp(notify_height, MIN_NOTIFY_HEIGHT, MAX_NOTIFY_HEIGHT); + + const S32 RIGHT = getRect().getWidth(); + const S32 LEFT = RIGHT - NOTIFY_WIDTH; + + return LLRect(LEFT, notify_height, RIGHT, 0); +} + + +// static +void LLToastNotifyPanel::onClickButton(void* data) +{ + InstanceAndS32* self_and_button = (InstanceAndS32*)data; + LLToastNotifyPanel* self = self_and_button->mSelf; + std::string button_name = self_and_button->mButtonName; + + LLSD response = self->mNotification->getResponseTemplate(); + if (!self->mAddedDefaultBtn && !button_name.empty()) + { + response[button_name] = true; + } + self->mNotification->respond(response); +} + +// virtual +LLButton* LLToastNotifyPanel::addButton(const std::string& name, const std::string& label, BOOL is_option, BOOL is_default) +{ + // make caution notification buttons slightly narrower + // so that 3 of them can fit without overlapping the "next" button + S32 btn_width = mIsCaution? 84 : 90; + + LLRect btn_rect; + LLButton* btn; + S32 btn_height= BTN_HEIGHT; + const LLFontGL* font = sFont; + S32 ignore_pad = 0; + S32 button_index = mNumButtons; + S32 index = button_index; + S32 x = (HPAD * 4) + 32; + + if (mIsScriptDialog) + { + // Add two "blank" option spaces, before the "Ignore" button + index = button_index + 2; + if (button_index == 0) + { + // Ignore button is smaller, less wide + btn_height = BTN_HEIGHT_SMALL; + font = sFontSmall; + ignore_pad = 10; + } + } + + btn_rect.setOriginAndSize(x + (index % 3) * (btn_width+HPAD+HPAD) + ignore_pad, + BOTTOM_PAD + (index / 3) * (BTN_HEIGHT+VPAD), + btn_width - 2*ignore_pad, + btn_height); + + InstanceAndS32* userdata = new InstanceAndS32; + userdata->mSelf = this; + userdata->mButtonName = is_option ? name : ""; + + mBtnCallbackData.push_back(userdata); + + LLButton::Params p; + p.name(name); + p.label(label); + p.rect(btn_rect); + p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata)); + p.font(font); + if (mIsCaution) + { + p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); + p.image_color_disabled(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); + } + btn = LLUICtrlFactory::create(p); + + + addChild(btn, -1); + + if (is_default) + { + setDefaultBtn(btn); + } + + mNumButtons++; + return btn; +} diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h new file mode 100644 index 0000000000..df58c06f25 --- /dev/null +++ b/indra/newview/lltoastnotifypanel.h @@ -0,0 +1,86 @@ +/** + * @file lltoastnotifypanel.h + * @brief Panel for notify toasts. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLTOASTNOTIFYPANEL_H_ +#define LLTOASTNOTIFYPANEL_H_ + +#include "llpanel.h" +#include "llfontgl.h" +#include "llnotifications.h" +#include "llbutton.h" +#include "lltoastpanel.h" + + +/** + * Toast panel for notification. + * Notification panel should be used for notifications that require a response from the user. + * + * Replaces class LLNotifyBox. + */ +class LLToastNotifyPanel: public LLToastPanel { +public: + LLToastNotifyPanel(LLNotificationPtr&); + virtual ~LLToastNotifyPanel(); + bool isTip() {return mIsTip;} + static LLToastNotifyPanel * buildNotifyPanel(LLNotificationPtr notification); + +protected: + LLButton* addButton(std::string const &name, const std::string& label, BOOL is_option, BOOL is_default); + // Used for callbacks + struct InstanceAndS32 + { + LLToastNotifyPanel* mSelf; + std::string mButtonName; + }; + std::vector mBtnCallbackData; + +private: + + // Returns the rect, relative to gNotifyView, where this + // notify box should be placed. + LLRect getNotifyRect(S32 num_options, BOOL layout_script_dialog, BOOL is_caution); + LLRect getNotifyTipRect(const std::string &message); + // internal handler for button being clicked + static void onClickButton(void* data); + bool mIsTip; + bool mAddedDefaultBtn; + bool mIsScriptDialog; + bool mIsCaution; // is this a caution notification? + std::string mMessage; + S32 mNumOptions; + S32 mNumButtons; + + static const LLFontGL* sFont; + static const LLFontGL* sFontSmall; +}; + +#endif /* LLTOASTNOTIFYPANEL_H_ */ diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp new file mode 100644 index 0000000000..79a7d45bbf --- /dev/null +++ b/indra/newview/lltoastpanel.cpp @@ -0,0 +1,42 @@ +/** + * @file lltoastpanel.cpp + * @brief Creates a panel of a specific kind for a toast + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lltoastpanel.h" + +LLToastPanel::LLToastPanel(LLNotificationPtr& notification) { + mNotification = notification; +} + +LLToastPanel::~LLToastPanel() { +} diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h new file mode 100644 index 0000000000..82e2a74672 --- /dev/null +++ b/indra/newview/lltoastpanel.h @@ -0,0 +1,53 @@ +/** + * @file lltoastpanel.h + * @brief Creates a panel of a specific kind for a toast. + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLTOASTPANEL_H +#define LL_LLTOASTPANEL_H + +#include "llpanel.h" +#include "llnotifications.h" + +/** + * Base class for all panels that can be added to the toast. + * All toast panels should contain necessary logic for representing certain notification + * but shouldn't contain logic related to this panel lifetime control and positioning + * on the parent view. + */ +class LLToastPanel: public LLPanel { +public: + LLToastPanel(LLNotificationPtr&); + virtual ~LLToastPanel() = 0; +protected: + LLNotificationPtr mNotification; +}; + +#endif /* LL_TOASTPANEL_H */ diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index d27958c2ac..5478e0005a 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -52,7 +52,7 @@ #include "lluiconstants.h" #include "llvoavatarself.h" #include "lltooldraganddrop.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llfloaterchatterbox.h" #include "llfloaterfriends.h" #include "llfloatersnapshot.h" @@ -157,7 +157,7 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, LLButton* inventory_btn = getChild("inventory_btn"); if (!inventory_btn) return FALSE; - LLInventoryView* active_inventory = LLInventoryView::getActiveInventory(); + LLFloaterInventory* active_inventory = LLFloaterInventory::getActiveInventory(); LLRect button_screen_rect; inventory_btn->localRectToScreen(inventory_btn->getRect(),&button_screen_rect); @@ -173,7 +173,7 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, if (!(active_inventory && active_inventory->getVisible()) && mInventoryAutoOpenTimer.getElapsedTimeF32() > sInventoryAutoOpenTime) { - LLInventoryView::showAgentInventory(); + LLFloaterInventory::showAgentInventory(); } } else @@ -253,7 +253,7 @@ void LLToolBar::refresh() BOOL sitting = FALSE; if (gAgent.getAvatarObject()) { - sitting = gAgent.getAvatarObject()->mIsSitting; + sitting = gAgent.getAvatarObject()->isSitting(); } if (!gAgent.canFly()) @@ -332,8 +332,11 @@ void LLToolBar::updateCommunicateList() communicate_button->addSeparator(ADD_TOP); communicate_button->add(getString("Redock Windows"), LLSD("redock"), ADD_TOP); communicate_button->addSeparator(ADD_TOP); - communicate_button->add(LLFloaterReg::getTypedInstance("mute")->getShortTitle(), LLSD("mute list"), ADD_TOP); - + LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance("mute"); + if(mute_instance) + { + communicate_button->add(mute_instance->getShortTitle(), LLSD("mute list"), ADD_TOP); + } std::set >::const_iterator floater_handle_it; if (gIMMgr->getIMFloaterHandles().size() > 0) @@ -385,25 +388,29 @@ void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, const LLSD& user_data) } else if (selected_option.asString() == "redock") { - LLFloaterChatterBox::getInstance()->addFloater(LLFloaterMyFriends::getInstance(), FALSE); - LLFloaterChatterBox::getInstance()->addFloater(LLFloaterChat::getInstance(), FALSE); - LLUUID session_to_show; - - std::set >::const_iterator floater_handle_it; - for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it) + LLFloaterChatterBox* chatterbox_instance = LLFloaterChatterBox::getInstance(); + if(chatterbox_instance) { - LLFloater* im_floaterp = floater_handle_it->get(); - if (im_floaterp) + chatterbox_instance->addFloater(LLFloaterMyFriends::getInstance(), FALSE); + chatterbox_instance->addFloater(LLFloaterChat::getInstance(), FALSE); + + LLUUID session_to_show; + + std::set >::const_iterator floater_handle_it; + for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it) { - if (im_floaterp->isFrontmost()) + LLFloater* im_floaterp = floater_handle_it->get(); + if (im_floaterp) { - session_to_show = ((LLFloaterIMPanel*)im_floaterp)->getSessionID(); + if (im_floaterp->isFrontmost()) + { + session_to_show = ((LLFloaterIMPanel*)im_floaterp)->getSessionID(); + } + chatterbox_instance->addFloater(im_floaterp, FALSE); } - LLFloaterChatterBox::getInstance()->addFloater(im_floaterp, FALSE); } + LLFloaterReg::showInstance("communicate", session_to_show); } - - LLFloaterReg::showInstance("communicate", session_to_show); } else if (selected_option.asString() == "mute list") { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 0c0253a76a..70fa2f715b 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -51,7 +51,7 @@ #include "llhudmanager.h" #include "llinventorybridge.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llmutelist.h" #include "llnotify.h" #include "llpreviewnotecard.h" @@ -59,7 +59,7 @@ #include "lltoolmgr.h" #include "lltrans.h" #include "llui.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerinventory.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -387,8 +387,8 @@ LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::sDragAndDrop3d[DAD_COUNT] { &LLToolDragAndDrop::dad3dNULL, // Dest: DT_NONE &LLToolDragAndDrop::dad3dNULL, // Dest: DT_SELF - &LLToolDragAndDrop::dad3dNULL, // Dest: DT_AVATAR - &LLToolDragAndDrop::dad3dNULL, // Dest: DT_OBJECT + &LLToolDragAndDrop::dad3dGiveInventory, // Dest: DT_AVATAR + &LLToolDragAndDrop::dad3dUpdateInventory, // Dest: DT_OBJECT &LLToolDragAndDrop::dad3dNULL, // Dest: DT_LAND }, // Source: DAD_LANDMARK @@ -473,6 +473,14 @@ LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::sDragAndDrop3d[DAD_COUNT] &LLToolDragAndDrop::dad3dUpdateInventory, // Dest: DT_OBJECT &LLToolDragAndDrop::dad3dNULL,//dad3dAssetOnLand, // Dest: DT_LAND }, + // Source: DAD_LINK + { + &LLToolDragAndDrop::dad3dNULL, // Dest: DT_NONE + &LLToolDragAndDrop::dad3dNULL, // Dest: DT_SELF + &LLToolDragAndDrop::dad3dNULL, // Dest: DT_AVATAR + &LLToolDragAndDrop::dad3dNULL, // Dest: DT_OBJECT + &LLToolDragAndDrop::dad3dNULL,//dad3dAssetOnLand, // Dest: DT_LAND + }, }; LLToolDragAndDrop::LLToolDragAndDrop() @@ -1146,7 +1154,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, { return; } - LLViewerImage* image = gImageList.getImage(asset_id); + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); S32 num_faces = hit_obj->getNumTEs(); for( S32 face = 0; face < num_faces; face++ ) @@ -1164,7 +1172,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, void LLToolDragAndDrop::dropTextureOneFaceAvatar(LLVOAvatar* avatar, S32 hit_face, LLInventoryItem* item) { if (hit_face == -1) return; - LLViewerImage* image = gImageList.getImage(item->getAssetUUID()); + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID()); avatar->userSetOptionalTE( hit_face, image); } @@ -1189,7 +1197,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, return; } // update viewer side image in anticipation of update from simulator - LLViewerImage* image = gImageList.getImage(asset_id); + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); hit_obj->setTEImage(hit_face, image); dialog_refresh_all(); @@ -1598,6 +1606,8 @@ void LLToolDragAndDrop::commitGiveInventoryItem(const LLUUID& to_agent, gIMMgr->addSystemMessage(im_session_id, "inventory_item_offered", args); } + // add buddy to recent people list + LLRecentPeople::instance().add(to_agent); } void LLToolDragAndDrop::giveInventoryCategory(const LLUUID& to_agent, @@ -1722,6 +1732,9 @@ void LLToolDragAndDrop::commitGiveInventoryCategory(const LLUUID& to_agent, llinfos << "LLToolDragAndDrop::commitGiveInventoryCategory() - " << cat->getUUID() << llendl; + // add buddy to recent people list + LLRecentPeople::instance().add(to_agent); + // Test out how many items are being given. LLViewerInventoryCategory::cat_array_t cats; LLViewerInventoryItem::item_array_t items; @@ -1840,9 +1853,6 @@ BOOL LLToolDragAndDrop::isInventoryGiveAcceptable(LLInventoryItem* item) BOOL acceptable = TRUE; switch(item->getType()) { - case LLAssetType::AT_CALLINGCARD: - acceptable = FALSE; - break; case LLAssetType::AT_OBJECT: if(my_avatar->isWearingAttachment(item->getUUID())) { @@ -1890,11 +1900,8 @@ BOOL LLToolDragAndDrop::isInventoryGroupGiveAcceptable(LLInventoryItem* item) BOOL acceptable = TRUE; switch(item->getType()) { - case LLAssetType::AT_CALLINGCARD: - acceptable = FALSE; - break; case LLAssetType::AT_OBJECT: - if(my_avatar->isWearingAttachment(item->getUUID())) + if(my_avatar->isWearingAttachment(item->getUUID(), TRUE)) { acceptable = FALSE; } @@ -1995,6 +2002,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ case DAD_BODYPART: case DAD_ANIMATION: case DAD_GESTURE: + case DAD_CALLINGCARD: { LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; if(gInventory.getItem(inv_item->getUUID()) @@ -2039,7 +2047,6 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ } break; } - case DAD_CALLINGCARD: default: *accept = ACCEPT_NO; break; @@ -2456,7 +2463,7 @@ EAcceptance LLToolDragAndDrop::dad3dActivateGesture( } else { - gGestureManager.activateGesture(item->getUUID()); + LLGestureManager::instance().activateGesture(item->getUUID()); gInventory.updateItem(item); gInventory.notifyObservers(); } diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index ca78073575..297cf2c667 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -56,6 +56,8 @@ #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llmorphview.h" +#include "llfloaterreg.h" +#include "llfloatercamera.h" // Globals BOOL gCameraBtnZoom = TRUE; @@ -254,7 +256,11 @@ void LLToolCamera::releaseMouse() gViewerWindow->showCursor(); - LLToolMgr::getInstance()->clearTransientTool(); + //for the situation when left click was performed on the Agent + if (!LLFloaterCamera::inFreeCameraMode()) + { + LLToolMgr::getInstance()->clearTransientTool(); + } mMouseSteering = FALSE; mValidClickPoint = FALSE; @@ -359,7 +365,7 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask) // Orbit tool if (hasMouseCapture()) { - const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWindowWidth(); + const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWorldViewWidth(); if (dx != 0) { @@ -387,7 +393,7 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask) F32 dist = (F32) camera_to_focus.normVec(); // Fudge factor for pan - F32 meters_per_pixel = 3.f * dist / gViewerWindow->getWindowWidth(); + F32 meters_per_pixel = 3.f * dist / gViewerWindow->getWorldViewWidth(); if (dx != 0) { @@ -409,7 +415,7 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask) if (hasMouseCapture()) { - const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWindowWidth(); + const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWorldViewWidth(); if (dx != 0) { diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index 409549a66b..abadd251c1 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -46,7 +46,6 @@ // newview headers #include "llagent.h" -//#include "llfloateravatarinfo.h" #include "lldrawable.h" #include "llfloatertools.h" #include "llhudeffect.h" @@ -511,8 +510,8 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask) const F32 RADIANS_PER_PIXEL_X = 0.01f; const F32 RADIANS_PER_PIXEL_Y = 0.01f; - S32 dx = x - (gViewerWindow->getWindowWidth() / 2); - S32 dy = y - (gViewerWindow->getWindowHeight() / 2); + S32 dx = x - (gViewerWindow->getWorldViewWidth() / 2); + S32 dy = y - (gViewerWindow->getWorldViewHeight() / 2); if (dx != 0 || dy != 0) { @@ -632,10 +631,10 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask) // Handle auto-rotation at screen edge. LLVector3 grab_pos_agent = gAgent.getPosAgentFromGlobal( grab_point_global ); - LLCoordGL grab_center_gl( gViewerWindow->getWindowWidth() / 2, gViewerWindow->getWindowHeight() / 2); + LLCoordGL grab_center_gl( gViewerWindow->getWorldViewWidth() / 2, gViewerWindow->getWorldViewHeight() / 2); LLViewerCamera::getInstance()->projectPosAgentToScreen(grab_pos_agent, grab_center_gl); - const S32 ROTATE_H_MARGIN = gViewerWindow->getWindowWidth() / 20; + const S32 ROTATE_H_MARGIN = gViewerWindow->getWorldViewWidth() / 20; const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD; const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped; // ...build mode moves camera about focus point @@ -650,7 +649,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask) gAgent.cameraOrbitAround(rotate_angle); } } - else if (grab_center_gl.mX > gViewerWindow->getWindowWidth() - ROTATE_H_MARGIN) + else if (grab_center_gl.mX > gViewerWindow->getWorldViewWidth() - ROTATE_H_MARGIN) { if (gAgent.getFocusOnAvatar()) { @@ -663,7 +662,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask) } // Don't move above top of screen or below bottom - if ((grab_center_gl.mY < gViewerWindow->getWindowHeight() - 6) + if ((grab_center_gl.mY < gViewerWindow->getWorldViewHeight() - 6) && (grab_center_gl.mY > 24)) { // Transmit update to simulator @@ -885,7 +884,7 @@ void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask) // Look for cursor against the edge of the screen // Only works in fullscreen - if (!gSavedSettings.getBOOL("NotFullScreen")) + if (gSavedSettings.getBOOL("WindowFullScreen")) { if (gAgent.cameraThirdPerson() ) { @@ -894,7 +893,7 @@ void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask) gAgent.yaw(rotate_angle); //gAgent.setControlFlags(AGENT_CONTROL_YAW_POS); } - else if (x == (gViewerWindow->getWindowWidth() - 1) ) + else if (x == (gViewerWindow->getWorldViewWidth() - 1) ) { gAgent.yaw(-rotate_angle); //gAgent.setControlFlags(AGENT_CONTROL_YAW_NEG); diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp index 72fd8b3bac..b70cff3869 100644 --- a/indra/newview/lltoolgun.cpp +++ b/indra/newview/lltoolgun.cpp @@ -42,7 +42,7 @@ #include "llresmgr.h" #include "llfontgl.h" #include "llui.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewercamera.h" #include "llhudmanager.h" #include "lltoolmgr.h" @@ -137,7 +137,7 @@ void LLToolGun::draw() { LLUIImagePtr crosshair = LLUI::getUIImage("crosshairs.tga"); crosshair->draw( - ( gViewerWindow->getWindowWidth() - crosshair->getWidth() ) / 2, - ( gViewerWindow->getWindowHeight() - crosshair->getHeight() ) / 2); + ( gViewerWindow->getWorldViewWidth() - crosshair->getWidth() ) / 2, + ( gViewerWindow->getWorldViewHeight() - crosshair->getHeight() ) / 2); } } diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp index e3ee209030..cf3d15a12a 100644 --- a/indra/newview/lltoolmgr.cpp +++ b/indra/newview/lltoolmgr.cpp @@ -180,6 +180,8 @@ void LLToolMgr::setCurrentTool( LLTool* tool ) mBaseTool = tool; updateToolStatus(); + + mSavedTool = NULL; } LLTool* LLToolMgr::getCurrentTool() diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index af0d784a3e..ae3f2f55de 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -58,7 +58,7 @@ #include "lltoolmgr.h" #include "llui.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobject.h" #include "llviewerwindow.h" #include "llvoavatarself.h" @@ -81,7 +81,7 @@ LLVisualParamHint::LLVisualParamHint( LLViewerVisualParam *param, F32 param_weight) : - LLDynamicTexture(width, height, 3, LLDynamicTexture::ORDER_MIDDLE, TRUE ), + LLViewerDynamicTexture(width, height, 3, LLViewerDynamicTexture::ORDER_MIDDLE, TRUE ), mNeedsUpdate( TRUE ), mIsVisible( FALSE ), mJointMesh( mesh ), @@ -155,7 +155,7 @@ void LLVisualParamHint::preRender(BOOL clear_depth) avatarp->updateGeometry(avatarp->mDrawable); avatarp->updateLOD(); - LLDynamicTexture::preRender(clear_depth); + LLViewerDynamicTexture::preRender(clear_depth); } //----------------------------------------------------------------------------- @@ -169,7 +169,7 @@ BOOL LLVisualParamHint::render() glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); + glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -177,7 +177,7 @@ BOOL LLVisualParamHint::render() LLGLSUIDefault gls_ui; //LLGLState::verify(TRUE); - mBackgroundp->draw(0, 0, mWidth, mHeight); + mBackgroundp->draw(0, 0, mFullWidth, mFullHeight); glMatrixMode(GL_PROJECTION); glPopMatrix(); @@ -224,13 +224,13 @@ BOOL LLVisualParamHint::render() gGL.flush(); - LLViewerCamera::getInstance()->setAspect((F32)mWidth / (F32)mHeight); + LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / (F32)mFullHeight); LLViewerCamera::getInstance()->setOriginAndLookAt( camera_pos, // camera LLVector3(0.f, 0.f, 1.f), // up target_pos ); // point of interest - LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); if (avatarp->mDrawable.notNull()) { @@ -244,7 +244,7 @@ BOOL LLVisualParamHint::render() } avatarp->setVisualParamWeight(mVisualParam, mLastParamWeight); gGL.color4f(1,1,1,1); - mTexture->setGLTextureCreated(true); + mGLTexturep->setGLTextureCreated(true); return TRUE; } @@ -256,7 +256,7 @@ void LLVisualParamHint::draw() { if (!mIsVisible) return; - gGL.getTexUnit(0)->bind(getTexture()); + gGL.getTexUnit(0)->bind(this); gGL.color4f(1.f, 1.f, 1.f, 1.f); @@ -264,13 +264,13 @@ void LLVisualParamHint::draw() gGL.begin(LLRender::QUADS); { gGL.texCoord2i(0, 1); - gGL.vertex2i(0, mHeight); + gGL.vertex2i(0, mFullHeight); gGL.texCoord2i(0, 0); gGL.vertex2i(0, 0); gGL.texCoord2i(1, 0); - gGL.vertex2i(mWidth, 0); + gGL.vertex2i(mFullWidth, 0); gGL.texCoord2i(1, 1); - gGL.vertex2i(mWidth, mHeight); + gGL.vertex2i(mFullWidth, mFullHeight); } gGL.end(); @@ -280,7 +280,7 @@ void LLVisualParamHint::draw() //----------------------------------------------------------------------------- // LLVisualParamReset() //----------------------------------------------------------------------------- -LLVisualParamReset::LLVisualParamReset() : LLDynamicTexture(1, 1, 1, ORDER_RESET, FALSE) +LLVisualParamReset::LLVisualParamReset() : LLViewerDynamicTexture(1, 1, 1, ORDER_RESET, FALSE) { } diff --git a/indra/newview/lltoolmorph.h b/indra/newview/lltoolmorph.h index 11de8160eb..b7df718ba2 100644 --- a/indra/newview/lltoolmorph.h +++ b/indra/newview/lltoolmorph.h @@ -42,7 +42,7 @@ #include "llstrider.h" #include "llviewervisualparam.h" #include "llframetimer.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLViewerJointMesh; class LLPolyMesh; @@ -51,17 +51,18 @@ class LLViewerObject; //----------------------------------------------------------------------------- // LLVisualParamHint //----------------------------------------------------------------------------- -class LLVisualParamHint -: public LLDynamicTexture +class LLVisualParamHint : public LLViewerDynamicTexture { +protected: + virtual ~LLVisualParamHint(); + public: LLVisualParamHint( S32 pos_x, S32 pos_y, S32 width, S32 height, LLViewerJointMesh *mesh, LLViewerVisualParam *param, - F32 param_weight); - virtual ~LLVisualParamHint(); + F32 param_weight); BOOL needsRender(); void preRender(BOOL clear_depth); @@ -94,13 +95,15 @@ protected: LLUIImagePtr mBackgroundp; - typedef std::set instance_list_t; + typedef std::set< LLVisualParamHint* > instance_list_t; static instance_list_t sInstances; }; // this class resets avatar data at the end of an update cycle -class LLVisualParamReset : public LLDynamicTexture +class LLVisualParamReset : public LLViewerDynamicTexture { +protected: + /*virtual */ ~LLVisualParamReset(){} public: LLVisualParamReset(); /*virtual */ BOOL render(); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index a6dcebc3b5..fab336f17d 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -42,12 +42,13 @@ #include "llagent.h" #include "llviewercontrol.h" #include "llfirstuse.h" -#include "llfloateravatarinfo.h" #include "llfloaterland.h" +#include "llfloaterreg.h" #include "llfloaterscriptdebug.h" #include "llhoverview.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" +#include "llmediamanager.h" #include "llmenugl.h" #include "llmutelist.h" #include "llselectmgr.h" @@ -100,15 +101,19 @@ void LLToolPie::leftMouseCallback(const LLPickInfo& pick_info) LLToolPie::getInstance()->pickLeftMouseDownCallback(); } +// Spawn context menus on right mouse down so you can drag over and select +// an item. BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask) { + // don't pick transparent so users can't "pay" transparent objects + gViewerWindow->pickAsync(x, y, mask, rightMouseCallback, FALSE, TRUE); + // claim not handled so UI focus stays same return FALSE; } BOOL LLToolPie::handleRightMouseUp(S32 x, S32 y, MASK mask) { LLToolMgr::getInstance()->clearTransientTool(); - gViewerWindow->pickAsync(x, y, mask, rightMouseCallback, FALSE, TRUE); return LLTool::handleRightMouseUp(x, y, mask); } @@ -116,7 +121,7 @@ BOOL LLToolPie::handleRightMouseUp(S32 x, S32 y, MASK mask) void LLToolPie::rightMouseCallback(const LLPickInfo& pick_info) { LLToolPie::getInstance()->mPick = pick_info; - LLToolPie::getInstance()->pickRightMouseUpCallback(); + LLToolPie::getInstance()->pickRightMouseDownCallback(); } // True if you selected an object. @@ -141,7 +146,7 @@ BOOL LLToolPie::pickLeftMouseDownCallback() else { // not selling passes, get info - LLFloaterLand::showInstance(); + LLFloaterReg::showInstance("about_land"); } } @@ -184,7 +189,7 @@ BOOL LLToolPie::pickLeftMouseDownCallback() // touch behavior down below... break; case CLICK_ACTION_SIT: - if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->mIsSitting)) // agent not already sitting + if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->isSitting())) // agent not already sitting { handle_sit_or_stand(); return TRUE; @@ -286,9 +291,11 @@ BOOL LLToolPie::pickLeftMouseDownCallback() return TRUE; } - // Could be first left-click on nothing - LLFirstUse::useLeftClickNoHit(); - + ////////// + // // Could be first left-click on nothing + // LLFirstUse::useLeftClickNoHit(); + ///////// + // Eat the event return LLTool::handleMouseDown(x, y, mask); } @@ -354,7 +361,7 @@ ECursorType cursor_from_object(LLViewerObject* object) switch(click_action) { case CLICK_ACTION_SIT: - if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->mIsSitting)) // not already sitting? + if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->isSitting())) // not already sitting? { cursor = UI_CURSOR_TOOLSIT; } @@ -424,7 +431,7 @@ void LLToolPie::selectionPropertiesReceived() handle_give_money_dialog(); break; case CLICK_ACTION_OPEN: - handle_object_open(); + LLFloaterReg::showInstance("openobject"); break; default: break; @@ -727,8 +734,8 @@ static ECursorType cursor_from_parcel_media(U8 click_action) } -// True if you selected an object. -BOOL LLToolPie::pickRightMouseUpCallback() +// True if we handled the event. +BOOL LLToolPie::pickRightMouseDownCallback() { S32 x = mPick.mMousePt.mX; S32 y = mPick.mMousePt.mY; @@ -824,7 +831,7 @@ BOOL LLToolPie::pickRightMouseUpCallback() } } - LLTool::handleRightMouseUp(x, y, mask); + LLTool::handleRightMouseDown(x, y, mask); // We handled the event. return TRUE; } diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index 82de2b363e..d2437e813d 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -75,7 +75,7 @@ public: private: BOOL outsideSlop (S32 x, S32 y, S32 start_x, S32 start_y); BOOL pickLeftMouseDownCallback(); - BOOL pickRightMouseUpCallback(); + BOOL pickRightMouseDownCallback(); BOOL useClickAction (MASK mask, LLViewerObject* object,LLViewerObject* parent); void showVisualContextMenuEffect(); diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index 8e4f637832..5929ecd928 100644 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -112,7 +112,7 @@ void LLTracker::stopTracking(void* userdata) // static virtual void LLTracker::drawHUDArrow() { - static LLCachedControl map_track_color(gSavedSkinSettings, "MapTrackColor", LLColor4::white); + static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white); /* tracking autopilot destination has been disabled -- 2004.01.09, Leviathan @@ -163,7 +163,7 @@ void LLTracker::render3D() return; } - static LLCachedControl map_track_color(gSavedSkinSettings, "MapTrackColor", LLColor4::white); + static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white); // Arbitary location beacon if( instance()->mIsTrackingLocation ) diff --git a/indra/newview/lluploaddialog.cpp b/indra/newview/lluploaddialog.cpp index f5160fd26c..153e3e7382 100644 --- a/indra/newview/lluploaddialog.cpp +++ b/indra/newview/lluploaddialog.cpp @@ -144,7 +144,7 @@ void LLUploadDialog::setMessage( const std::string& msg) msg_rect.setOriginAndSize( msg_x, msg_y, max_msg_width, line_height ); mLabelBox[line_num]->setRect(msg_rect); mLabelBox[line_num]->setText(cur_line); - mLabelBox[line_num]->setColor( gSavedSkinSettings.getColor( "LabelTextColor" ) ); + mLabelBox[line_num]->setColor( LLUIColorTable::instance().getColor( "LabelTextColor" ) ); mLabelBox[line_num]->setVisible(TRUE); msg_y -= line_height; ++line_num; diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 6c8e7e1f69..9fb6d1c874 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -36,12 +36,14 @@ // viewer includes #include "llagent.h" // teleportViaLocation() #include "llcommandhandler.h" -#include "llfloaterurldisplay.h" #include "llfloaterdirectory.h" #include "llfloaterhtml.h" -#include "llfloaterworldmap.h" #include "llfloaterhtmlhelp.h" +#include "llfloaterreg.h" +#include "llfloaterurldisplay.h" +#include "llfloaterworldmap.h" #include "llpanellogin.h" +#include "llsidetray.h" #include "llslurl.h" #include "llstartup.h" // gStartupState #include "llurlsimstring.h" @@ -201,8 +203,9 @@ bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mous S32 z = 0; LLURLSimString::parse(sim_string, ®ion_name, &x, &y, &z); - LLFloaterURLDisplay* url_displayp = LLFloaterURLDisplay::getInstance(LLSD()); - url_displayp->setName(region_name); + // LLFloaterURLDisplay functionality moved to LLPanelPlaces in Side Tray. + //LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance("preview_url",LLSD()); + //if(url_displayp) url_displayp->setName(region_name); // Request a region handle by name LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, @@ -273,28 +276,42 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const std::str local_pos.mV[VY] = (F32)local_y; local_pos.mV[VZ] = (F32)z; - + LLVector3d global_pos = from_region_handle(region_handle); + global_pos += LLVector3d(local_pos); if (teleport) - { - LLVector3d global_pos = from_region_handle(region_handle); - global_pos += LLVector3d(local_pos); + { gAgent.teleportViaLocation(global_pos); - LLFloaterWorldMap::getInstance()->trackLocation(global_pos); + LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance(); + if(instance) + { + instance->trackLocation(global_pos); + } } else { - // display informational floater, allow user to click teleport btn - LLFloaterURLDisplay* url_displayp = LLFloaterURLDisplay::getInstance(LLSD()); + LLSD key; + key["type"] = "remote_place"; + key["x"] = global_pos.mdV[VX]; + key["y"] = global_pos.mdV[VY]; + key["z"] = global_pos.mdV[VZ]; + LLSideTray::getInstance()->showPanel("panel_places", key); - url_displayp->displayParcelInfo(region_handle, local_pos); - if(snapshot_id.notNull()) - { - url_displayp->setSnapshotDisplay(snapshot_id); - } - std::string locationString = llformat("%s %d, %d, %d", region_name.c_str(), x, y, z); - url_displayp->setLocationString(locationString); + // LLFloaterURLDisplay functionality moved to LLPanelPlaces in Side Tray. + +// // display informational floater, allow user to click teleport btn +// LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance("preview_url",LLSD()); +// if(url_displayp) +// { +// url_displayp->displayParcelInfo(region_handle, local_pos); +// if(snapshot_id.notNull()) +// { +// url_displayp->setSnapshotDisplay(snapshot_id); +// } +// std::string locationString = llformat("%s %d, %d, %d", region_name.c_str(), x, y, z); +// url_displayp->setLocationString(locationString); +// } } } diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index 15c11c7025..512b590a1b 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -47,6 +47,7 @@ public: LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, LLVFS *vfs); + using LLAssetStorage::storeAssetData; virtual void storeAssetData( const LLTransactionID& tid, LLAssetType::EType atype, diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 320b950649..30c97cdfa3 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -49,7 +49,7 @@ #include "llsky.h" #include "llvieweraudio.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerthrottle.h" #include "llviewerwindow.h" #include "llvoavatarself.h" @@ -78,7 +78,6 @@ BOOL gHackGodmode = FALSE; LLControlGroup gSavedSettings("Global"); // saved at end of session -LLControlGroup gSavedSkinSettings("Skinning"); // saved at end of session LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session LLControlGroup gCrashSettings("CrashSettings"); // saved at end of session LLControlGroup gWarningSettings("Warnings"); // persists ignored dialogs/warnings @@ -213,7 +212,7 @@ static bool handleMaxPartCountChanged(const LLSD& newvalue) static bool handleVideoMemoryChanged(const LLSD& newvalue) { - gImageList.updateMaxResidentTexMem(newvalue.asInteger()); + gTextureList.updateMaxResidentTexMem(newvalue.asInteger()); return true; } @@ -585,7 +584,6 @@ void settings_setup_listeners() gSavedSettings.getControl("DebugViews")->getSignal()->connect(boost::bind(&handleDebugViewsChanged, _2)); gSavedSettings.getControl("UserLogFile")->getSignal()->connect(boost::bind(&handleLogFileChanged, _2)); gSavedSettings.getControl("RenderHideGroupTitle")->getSignal()->connect(boost::bind(handleHideGroupTitleChanged, _2)); - gSavedSkinSettings.getControl("EffectColor")->getSignal()->connect(boost::bind(handleEffectColorChanged, _2)); gSavedSettings.getControl("HighResSnapshot")->getSignal()->connect(boost::bind(handleHighResSnapshotChanged, _2)); gSavedSettings.getControl("VectorizePerfTest")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _2)); gSavedSettings.getControl("VectorizeEnable")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _2)); @@ -603,7 +601,6 @@ void settings_setup_listeners() gSavedSettings.getControl("VelocityInterpolate")->getSignal()->connect(boost::bind(&handleVelocityInterpolate, _2)); } - #if TEST_CACHED_CONTROL #define DECL_LLCC(T, V) static LLCachedControl mySetting_##T("TestCachedControl"#T, V) diff --git a/indra/newview/llviewercontrol.h b/indra/newview/llviewercontrol.h index 3271e5fe9b..b1f14eca7b 100644 --- a/indra/newview/llviewercontrol.h +++ b/indra/newview/llviewercontrol.h @@ -52,7 +52,6 @@ void create_graphics_group(LLControlGroup& group); // saved at end of session extern LLControlGroup gSavedSettings; -extern LLControlGroup gSavedSkinSettings; extern LLControlGroup gSavedPerAccountSettings; extern LLControlGroup gWarningSettings; diff --git a/indra/newview/llviewercontrollistener.cpp b/indra/newview/llviewercontrollistener.cpp index 57426f2af0..ecba1b8eb0 100644 --- a/indra/newview/llviewercontrollistener.cpp +++ b/indra/newview/llviewercontrollistener.cpp @@ -21,20 +21,17 @@ LLViewerControlListener::LLViewerControlListener() : LLDispatchListener("LLViewerControl", "group") { add("Global", boost::bind(&LLViewerControlListener::set, &gSavedSettings, _1)); - add("Skin", boost::bind(&LLViewerControlListener::set, &gSavedSkinSettings, _1)); add("PerAccount", boost::bind(&LLViewerControlListener::set, &gSavedPerAccountSettings, _1)); add("Warning", boost::bind(&LLViewerControlListener::set, &gWarningSettings, _1)); add("Crash", boost::bind(&LLViewerControlListener::set, &gCrashSettings, _1)); #if 0 add(/*"toggleControl",*/ "Global", boost::bind(&LLViewerControlListener::toggleControl, &gSavedSettings, _1)); - add(/*"toggleControl",*/ "Skin", boost::bind(&LLViewerControlListener::toggleControl, &gSavedSkinSettings, _1)); add(/*"toggleControl",*/ "PerAccount", boost::bind(&LLViewerControlListener::toggleControl, &gSavedPerAccountSettings, _1)); add(/*"toggleControl",*/ "Warning", boost::bind(&LLViewerControlListener::toggleControl, &gWarningSettings, _1)); add(/*"toggleControl",*/ "Crash", boost::bind(&LLViewerControlListener::toggleControl, &gCrashSettings, _1)); add(/*"setDefault",*/ "Global", boost::bind(&LLViewerControlListener::setDefault, &gSavedSettings, _1)); - add(/*"setDefault",*/ "Skin", boost::bind(&LLViewerControlListener::setDefault, &gSavedSkinSettings, _1)); add(/*"setDefault",*/ "PerAccount", boost::bind(&LLViewerControlListener::setDefault, &gSavedPerAccountSettings, _1)); add(/*"setDefault",*/ "Warning", boost::bind(&LLViewerControlListener::setDefault, &gWarningSettings, _1)); add(/*"setDefault",*/ "Crash", boost::bind(&LLViewerControlListener::setDefault, &gCrashSettings, _1)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index a340514e3b..f08c287529 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -48,7 +48,6 @@ #include "llfirstuse.h" #include "llhudmanager.h" #include "llimagebmp.h" -#include "llimagegl.h" #include "llmemory.h" #include "llselectmgr.h" #include "llsky.h" @@ -74,7 +73,7 @@ #include "llviewershadermgr.h" #include "llfasttimer.h" #include "llfloatertools.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llfocusmgr.h" #include "llcubemap.h" #include "llviewerregion.h" @@ -84,9 +83,9 @@ #include "llwaterparammanager.h" #include "llpostprocess.h" -extern LLPointer gStartImageGL; +extern LLPointer gStartTexture; -LLPointer gDisconnectedImagep = NULL; +LLPointer gDisconnectedImagep = NULL; // used to toggle renderer back on after teleport const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain @@ -136,7 +135,7 @@ void display_startup() if (frame_count++ > 1) // make sure we have rendered a frame first { - LLDynamicTexture::updateAllInstances(); + LLViewerDynamicTexture::updateAllInstances(); } LLGLState::checkStates(); @@ -313,8 +312,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLImageGL::updateStats(gFrameTimeSeconds); - LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName"); - LLVOAvatar::sRenderGroupTitles = !gSavedSettings.getBOOL("RenderHideGroupTitleAll"); + LLVOAvatar::sRenderName = gSavedSettings.getS32("AvatarNameTagMode"); + LLVOAvatar::sRenderGroupTitles = (gSavedSettings.getBOOL("RenderShowGroupTitleAll") && gSavedSettings.getS32("AvatarNameTagMode")); gPipeline.mBackfaceCull = TRUE; gFrameCount++; @@ -383,7 +382,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["arriving"]); - gImageList.mForceResetTextureStats = TRUE; + gTextureList.mForceResetTextureStats = TRUE; gAgent.resetView(TRUE, TRUE); break; @@ -506,7 +505,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures"); LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES); - if (LLDynamicTexture::updateAllInstances()) + if (LLViewerDynamicTexture::updateAllInstances()) { gGL.setColorMask(true, true); glClear(GL_DEPTH_BUFFER_BIT); @@ -690,13 +689,13 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLMemType mt_iu(LLMemType::MTYPE_DISPLAY_IMAGE_UPDATE); LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE); - LLViewerImage::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(), + LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(), LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean()); - gBumpImageList.updateImages(); // must be called before gImageList version so that it's textures are thrown out first. + gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first. const F32 max_image_decode_time = llmin(0.005f, 0.005f*10.f*gFrameIntervalSeconds); // 50 ms/second decode time (no more than 5ms/frame) - gImageList.updateImages(max_image_decode_time); + gTextureList.updateImages(max_image_decode_time); stop_glerror(); } llpushcallstacks ; @@ -1279,8 +1278,7 @@ void render_disconnected_background() //llinfos << "Bitmap load failed" << llendl; return; } - - gDisconnectedImagep = new LLImageGL( FALSE ); + LLPointer raw = new LLImageRaw; if (!image_bmp->decode(raw, 0.0f)) { @@ -1306,8 +1304,8 @@ void render_disconnected_background() raw->expandToPowerOfTwo(); - gDisconnectedImagep->createGLTexture(0, raw); - gStartImageGL = gDisconnectedImagep; + gDisconnectedImagep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE ); + gStartTexture = gDisconnectedImagep; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 03c4915e66..9c29131def 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -39,29 +39,78 @@ #include "llcompilequeue.h" #include "llfloaterabout.h" -#include "llfloaterauction.h" +#include "llfloateractivespeakers.h" #include "llfloateraddlandmark.h" -#include "llfloateravatarinfo.h" +#include "llfloateranimpreview.h" +#include "llfloaterauction.h" +#include "llfloateravatarpicker.h" +#include "llfloateravatartextures.h" +#include "llfloaterbeacons.h" #include "llfloaterbuildoptions.h" +#include "llfloaterbuy.h" +#include "llfloaterbuycontents.h" +#include "llfloaterbuycurrency.h" +#include "llfloaterbuyland.h" +#include "llfloaterbulkpermission.h" #include "llfloaterbump.h" +#include "llfloatercall.h" +#include "llfloatercamera.h" #include "llfloaterchat.h" #include "llfloaterchatterbox.h" +#include "llfloaterdaycycle.h" #include "llfloaterdirectory.h" +#include "llfloaterfirsttimetip.h" +#include "llfloaterenvsettings.h" +#include "llfloaterfonttest.h" +#include "llfloatergesture.h" +#include "llfloatergodtools.h" +#include "llfloatergroupinfo.h" +#include "llfloatergroups.h" +#include "llfloaterhardwaresettings.h" +#include "llfloaterhtmlcurrency.h" +#include "llfloaterhtmlhelp.h" +#include "llfloaterhud.h" +#include "llfloaterimagepreview.h" +#include "llimpanel.h" +#include "llfloaterinspect.h" +#include "llfloaterinventory.h" #include "llfloaterjoystick.h" -#include "llfloaternotificationsconsole.h" #include "llfloaterlagmeter.h" +#include "llfloaterland.h" +#include "llfloaterlandholdings.h" #include "llfloatermap.h" #include "llfloatermemleak.h" #include "llfloatermute.h" +#include "llfloaternamedesc.h" +#include "llfloaternotificationsconsole.h" +#include "llfloateropenobject.h" +#include "llgivemoney.h" +#include "llfloaterparcel.h" +#include "llfloaterperms.h" +#include "llfloaterpostcard.h" +#include "llfloaterpostprocess.h" #include "llfloaterpreference.h" -#include "llfloatersnapshot.h" +#include "llfloaterproperties.h" +#include "llfloaterregioninfo.h" +#include "llfloaterreporter.h" +#include "llfloaterscriptdebug.h" +#include "llfloatersellland.h" #include "llfloatersettingsdebug.h" +#include "llfloatersnapshot.h" +#include "llfloatertelehub.h" +#include "llfloatertestlistview.h" #include "llfloatertools.h" +#include "llfloatertos.h" +#include "llfloatertopobjects.h" #include "llfloateruipreview.h" +#include "llfloaterurldisplay.h" #include "llfloatervoicedevicesettings.h" +#include "llfloaterwater.h" +#include "llfloaterwindlight.h" #include "llfloaterworldmap.h" -#include "llinventoryview.h" -#include "llnearbychathistory.h" +#include "llmediaremotectrl.h" +#include "llmoveview.h" +#include "llnearbychat.h" #include "llpreviewanim.h" #include "llpreviewgesture.h" @@ -72,46 +121,86 @@ #include "llpreviewtexture.h" #include "llfloaterminiinspector.h" +//class LLLLFloaterObjectIMInfo; + void LLViewerFloaterReg::registerFloaters() { - LLFloaterReg::add("mini_inspector", "panel_mini_inspector.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("sl_about", "floater_about.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("search", "floater_directory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("build", "floater_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("add_landmark", "floater_add_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("mute", "floater_mute.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + // *NOTE: Please keep these alphabetized for easier merges + LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("active_speakers", "floater_active_speakers.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("add_landmark", "floater_add_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("avatar_textures", "floater_avatar_textures.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("beacons", "floater_beacons.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("bulk_perms", "floater_bulk_perms.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("buy_currency", "floater_buy_currency.xml", &LLFloaterBuyCurrency::buildFloater); + LLFloaterReg::add("buy_land", "floater_buy_land.xml", &LLFloaterBuyLand::buildFloater); + LLFloaterReg::add("buy_object", "floater_buy_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("buy_object_contents", "floater_buy_contents.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("build", "floater_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("build_options", "floater_build_options.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("ui_preview", "floater_ui_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("test_widgets", "floater_test_widgets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("chat", "floater_chat_history.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("communicate", "floater_chatterbox.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("contacts", "floater_my_friends.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("first_time_tip", "floater_first_time_tip.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("env_day_cycle", "floater_day_cycle_options.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("env_post_process", "floater_post_process.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("env_settings", "floater_env_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("env_water", "floater_water.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("env_windlight", "floater_windlight_options.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("font_test", "floater_font_test.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("gestures", "floater_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("group_info", "floater_groupinfo.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("group_picker", "floater_choose_group.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("html_simple", "floater_html_simple.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("media_browser", "floater_media_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("mute", "floater_mute.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("mute_object", "floater_mute_object.xml", &LLFloaterMute::buildFloaterMuteObjectUI); + LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("mini_inspector", "panel_mini_inspector.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("parcel_info", "floater_preview_url.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("pay_resident", "floater_pay.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("pay_object", "floater_pay_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("postcard", "floater_postcard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("prefs_hardware_settings", "floater_hardware_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("preview_url", "floater_preview_url.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("pref_voicedevicesettings", "floater_device_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - - LLFloaterReg::add("communicate", "floater_chatterbox.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("chat", "floater_chat_history.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("contacts", "floater_my_friends.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - - LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("reset_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - - LLFloaterReg::add("preview_avatar", "floater_profile.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("me_profile", "floater_me.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "preview"); LLFloaterReg::add("preview_gesture", "floater_preview_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "preview"); LLFloaterReg::add("preview_landmark", "floater_preview_existing_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "preview"); @@ -120,6 +209,46 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("preview_scriptedit", "floater_live_lsleditor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "preview"); LLFloaterReg::add("preview_sound", "floater_preview_sound.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "preview"); LLFloaterReg::add("preview_texture", "floater_preview_texture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "preview"); + LLFloaterReg::add("properties", "floater_inventory_item_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("telehubs", "floater_telehub.xml",&LLFloaterReg::build); + LLFloaterReg::add("test_list_view", "floater_test_list_view.xml",&LLFloaterReg::build); + LLFloaterReg::add("test_widgets", "floater_test_widgets.xml", &LLFloaterReg::build); + LLFloaterReg::add("top_objects", "floater_top_objects.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("reporter", "floater_report_abuse.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("reset_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("region_info", "floater_region_info.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("script_debug", "floater_script_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("script_debug_output", "floater_script_debug_panel.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("sell_land", "floater_sell_land.xml", &LLFloaterSellLand::buildFloater); + LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("sl_about", "floater_about.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("search", "floater_directory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("ui_preview", "floater_ui_preview.xml", &LLFloaterReg::build); + LLFloaterReg::add("upload_anim", "floater_animation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); + LLFloaterReg::add("upload_image", "floater_image_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); + LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); + + LLFloaterReg::add("voice_call", "floater_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + // *NOTE: Please keep these alphabetized for easier merges + + // debug use only + LLFloaterReg::add("media_remote_ctrl", "floater_media_remote.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + // Untested / dangerous - not for release +#if !LL_RELEASE_FOR_DOWNLOAD + LLFloaterReg::add("buy_currency_html", "floater_html_simple.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); +#endif + + LLFloaterReg::registerControlVariables(); // Make sure visibility and rect controls get preserved when saving } diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp index 2fb56fbcb8..4155a87e14 100644 --- a/indra/newview/llviewergesture.cpp +++ b/indra/newview/llviewergesture.cpp @@ -39,7 +39,6 @@ #include "llviewerinventory.h" #include "sound_ids.h" // for testing -#include "llchatbar.h" #include "llkeyboard.h" // for key shortcuts for testing #include "llinventorymodel.h" #include "llvoavatar.h" @@ -47,7 +46,7 @@ #include "llviewermessage.h" // send_guid_sound_trigger #include "llviewernetwork.h" #include "llagent.h" -#include "llbottomtray.h" +#include "llnearbychatbar.h" // Globals LLViewerGestureList gGestureList; @@ -133,11 +132,11 @@ void LLViewerGesture::doTrigger( BOOL send_chat ) } } - if ( send_chat && !mOutputString.empty()) + if (send_chat && !mOutputString.empty()) { // Don't play nodding animation, since that might not blend // with the gesture animation. - LLBottomTray::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE); + LLNearbyChatBar::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE); } } diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 2c79e67ebc..bb14a619c5 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -45,7 +45,7 @@ #include "llgesturemgr.h" #include "llinventorybridge.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llviewerregion.h" #include "llviewerobjectlist.h" @@ -201,10 +201,19 @@ void LLViewerInventoryItem::fetchFromServer(void) const { std::string url; - if( ALEXANDRIA_LINDEN_ID.getString() == mPermissions.getOwner().getString()) - url = gAgent.getRegion()->getCapability("FetchLib"); - else - url = gAgent.getRegion()->getCapability("FetchInventory"); + LLViewerRegion* region = gAgent.getRegion(); + // we have to check region. It can be null after region was destroyed. See EXT-245 + if (region) + { + if( ALEXANDRIA_LINDEN_ID.getString() == mPermissions.getOwner().getString()) + url = region->getCapability("FetchLib"); + else + url = region->getCapability("FetchInventory"); + } + else + { + llwarns << "Agent Region is absent" << llendl; + } if (!url.empty()) { @@ -403,7 +412,8 @@ void LLViewerInventoryCategory::updateParentOnServer(BOOL restamp) const void LLViewerInventoryCategory::updateServer(BOOL is_new) const { // communicate that change with the server. - if(LLAssetType::AT_NONE != mPreferredType) + + if (LLAssetType::lookupIsProtectedCategoryType(mPreferredType)) { LLNotifications::instance().add("CannotModifyProtectedCategories"); return; @@ -427,7 +437,7 @@ void LLViewerInventoryCategory::removeFromServer( void ) llinfos << "Removing inventory category " << mUUID << " from server." << llendl; // communicate that change with the server. - if(LLAssetType::AT_NONE != mPreferredType) + if(LLAssetType::lookupIsProtectedCategoryType(mPreferredType)) { LLNotifications::instance().add("CannotRemoveProtectedCategories"); return; @@ -664,13 +674,12 @@ void RezAttachmentCallback::fire(const LLUUID& inv_item) } } -extern LLGestureManager gGestureManager; void ActivateGestureCallback::fire(const LLUUID& inv_item) { if (inv_item.isNull()) return; - gGestureManager.activateGesture(inv_item); + LLGestureManager::instance().activateGesture(inv_item); } void CreateGestureCallback::fire(const LLUUID& inv_item) @@ -678,7 +687,7 @@ void CreateGestureCallback::fire(const LLUUID& inv_item) if (inv_item.isNull()) return; - gGestureManager.activateGesture(inv_item); + LLGestureManager::instance().activateGesture(inv_item); LLViewerInventoryItem* item = gInventory.getItem(inv_item); if (!item) return; @@ -870,7 +879,7 @@ void menu_create_inventory_item(LLFolderView* folder, LLFolderBridge *bridge, co } else { - category = gInventory.createNewCategory(gAgent.getInventoryRootID(), LLAssetType::AT_NONE, LLStringUtil::null); + category = gInventory.createNewCategory(gInventory.getRootFolderID(), LLAssetType::AT_NONE, LLStringUtil::null); } gInventory.notifyObservers(); folder->setSelectionByID(category, TRUE); @@ -977,7 +986,10 @@ LLAssetType::EType LLViewerInventoryItem::getType() const { return linked_item->getType(); } - + if (const LLViewerInventoryCategory *linked_category = getLinkedCategory()) + { + return linked_category->getType(); + } return LLInventoryItem::getType(); } @@ -997,6 +1009,10 @@ const std::string& LLViewerInventoryItem::getName() const { return linked_item->getName(); } + if (const LLViewerInventoryCategory *linked_category = getLinkedCategory()) + { + return linked_category->getName(); + } return LLInventoryItem::getName(); } diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 7084c9f37a..5198f5efc7 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -141,7 +141,6 @@ public: }; LLTransactionID getTransactionID() const { return mTransactionID; } -protected: const LLViewerInventoryItem *getLinkedItem() const; const LLViewerInventoryCategory *getLinkedCategory() const; diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index b6f0dafae6..8fbb59bc74 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -52,7 +52,7 @@ #include "lltexlayer.h" #include "llviewercamera.h" #include "llviewercontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerjointmesh.h" #include "llvoavatar.h" #include "llsky.h" @@ -230,7 +230,7 @@ void LLViewerJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha ) //-------------------------------------------------------------------- // LLViewerJointMesh::getTexture() //-------------------------------------------------------------------- -//LLViewerImage *LLViewerJointMesh::getTexture() +//LLViewerTexture *LLViewerJointMesh::getTexture() //{ // return mTexture; //} @@ -238,7 +238,7 @@ void LLViewerJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha ) //-------------------------------------------------------------------- // LLViewerJointMesh::setTexture() //-------------------------------------------------------------------- -void LLViewerJointMesh::setTexture( LLViewerImage *texture ) +void LLViewerJointMesh::setTexture( LLViewerTexture *texture ) { mTexture = texture; @@ -557,7 +557,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { if( mLayerSet->hasComposite() ) { - gGL.getTexUnit(0)->bind(mLayerSet->getComposite()->getTexture()); + gGL.getTexUnit(0)->bind(mLayerSet->getComposite()); } else { @@ -567,19 +567,22 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { llwarns << "Layerset without composite" << llendl; } - gGL.getTexUnit(0)->bind(gImageList.getImage(IMG_DEFAULT)); + gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT)); } } else if ( !is_dummy && mTexture.notNull() ) { - old_mode = mTexture->getAddressMode(); - gGL.getTexUnit(0)->bind(mTexture.get()); + if(mTexture->hasGLTexture()) + { + old_mode = mTexture->getAddressMode(); + } + gGL.getTexUnit(0)->bind(mTexture); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); } else { - gGL.getTexUnit(0)->bind(gImageList.getImage(IMG_DEFAULT_AVATAR)); + gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR)); } if (gRenderForSelect) @@ -633,7 +636,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) if (mTexture.notNull() && !is_dummy) { - gGL.getTexUnit(0)->bind(mTexture.get()); + gGL.getTexUnit(0)->bind(mTexture); gGL.getTexUnit(0)->setTextureAddressMode(old_mode); } diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index 0cae48df93..543679c44b 100644 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -34,7 +34,7 @@ #define LL_LLVIEWERJOINTMESH_H #include "llviewerjoint.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llpolymesh.h" #include "v4color.h" #include "llapr.h" @@ -72,7 +72,7 @@ protected: LLColor4 mColor; // color value // LLColor4 mSpecular; // specular color (always white for now) F32 mShiny; // shiny value - LLPointer mTexture; // ptr to a global texture + LLPointer mTexture; // ptr to a global texture LLTexLayerSet* mLayerSet; // ptr to a layer set owned by the avatar U32 mTestImageName; // handle to a temporary texture for previewing uploads LLPolyMesh* mMesh; // ptr to a global polymesh @@ -110,7 +110,7 @@ public: void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; }; // Sets the shape texture - void setTexture( LLViewerImage *texture ); + void setTexture( LLViewerTexture *texture ); void setTestTexture( U32 name ) { mTestImageName = name; } @@ -148,7 +148,7 @@ public: void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; } - /*virtual*/ BOOL isAnimatable() { return FALSE; } + /*virtual*/ BOOL isAnimatable() const { return FALSE; } static void updateVectorize(); // Update globals when settings variables change diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index ab5cdeba44..6bb302727d 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -36,7 +36,7 @@ #include "llviewerkeyboard.h" #include "llmath.h" #include "llagent.h" -#include "llchatbar.h" +#include "llnearbychatbar.h" #include "llviewercontrol.h" #include "llfocusmgr.h" #include "llmorphview.h" @@ -44,6 +44,7 @@ #include "lltoolfocus.h" #include "llviewerwindow.h" #include "llvoavatarself.h" +#include "llfloatercamera.h" // // Constants @@ -135,14 +136,29 @@ static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDo } } +void camera_move_forward( EKeystate s ); + void agent_push_forward( EKeystate s ) { + //in free camera control mode we need to intercept keyboard events for avatar movements + if (LLFloaterCamera::inFreeCameraMode()) + { + camera_move_forward(s); + return; + } agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD); } +void camera_move_backward( EKeystate s ); void agent_push_backward( EKeystate s ) { + //in free camera control mode we need to intercept keyboard events for avatar movements + if (LLFloaterCamera::inFreeCameraMode()) + { + camera_move_backward(s); + return; + } agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD); } @@ -175,8 +191,17 @@ void agent_slide_right( EKeystate s ) agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT); } +void camera_spin_around_cw( EKeystate s ); + void agent_turn_left( EKeystate s ) { + //in free camera control mode we need to intercept keyboard events for avatar movements + if (LLFloaterCamera::inFreeCameraMode()) + { + camera_spin_around_cw(s); + return; + } + if (LLToolCamera::getInstance()->mouseSteerMode()) { agent_slide_left(s); @@ -189,9 +214,17 @@ void agent_turn_left( EKeystate s ) } } +void camera_spin_around_ccw( EKeystate s ); void agent_turn_right( EKeystate s ) { + //in free camera control mode we need to intercept keyboard events for avatar movements + if (LLFloaterCamera::inFreeCameraMode()) + { + camera_spin_around_ccw(s); + return; + } + if (LLToolCamera::getInstance()->mouseSteerMode()) { agent_slide_right(s); @@ -500,8 +533,7 @@ void stop_moving( EKeystate s ) void start_chat( EKeystate s ) { // start chat - LLChatBar::startChat(NULL); -// gChatBar->startChat(NULL); + LLNearbyChatBar::startChat(NULL); } void start_gesture( EKeystate s ) @@ -509,18 +541,16 @@ void start_gesture( EKeystate s ) if (KEYSTATE_UP == s && !(gFocusMgr.getKeyboardFocus() && gFocusMgr.getKeyboardFocus()->acceptsTextInput())) { - //TODO* remove DUMMY chatbar - LLChatBar::startChat(NULL); -// if (gChatBar->getCurrentChat().empty()) -// { -// // No existing chat in chat editor, insert '/' -// gChatBar->startChat("/"); -// } -// else -// { -// // Don't overwrite existing text in chat editor -// gChatBar->startChat(NULL); -// } + if (LLNearbyChatBar::getInstance()->getCurrentChat().empty()) + { + // No existing chat in chat editor, insert '/' + LLNearbyChatBar::startChat("/"); + } + else + { + // Don't overwrite existing text in chat editor + LLNearbyChatBar::startChat(NULL); + } } } @@ -845,7 +875,7 @@ EKeyboardMode LLViewerKeyboard::getMode() { return MODE_EDIT_AVATAR; } - else if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting) + else if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting()) { return MODE_SITTING; } diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 085d6d47e5..21d686a250 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -34,12 +34,20 @@ #include "llviewermedia.h" +#include "audioengine.h" + +#include "llparcel.h" + #include "llmimetypes.h" #include "llviewercontrol.h" -#include "llviewerimage.h" +#include "llviewertexture.h" +#include "llviewerparcelmedia.h" +#include "llviewerparcelmgr.h" +#include "llviewerparcelmedia.h" +#include "llviewerparcelmgr.h" #include "llviewerwindow.h" #include "llversionviewer.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llevent.h" // LLSimpleListener #include "llmediamanager.h" @@ -53,58 +61,58 @@ class LLViewerMediaImpl : public LLMediaObserver { - public: - LLViewerMediaImpl() - : mMediaSource( NULL ), - mMovieImageID(), - mMovieImageHasMips(false) - { } +public: + LLViewerMediaImpl() + : mMediaSource( NULL ), + mMovieImageID(), + mMovieImageHasMips(false) + { } - void destroyMediaSource(); + void destroyMediaSource(); - void play(const std::string& media_url, - const std::string& mime_type, - const LLUUID& placeholder_texture_id, - S32 media_width, S32 media_height, U8 media_auto_scale, - U8 media_loop); + void play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop); - void stop(); - void pause(); - void start(); - void seek(F32 time); - void setVolume(F32 volume); - LLMediaBase::EStatus getStatus(); + void stop(); + void pause(); + void start(); + void seek(F32 time); + void setVolume(F32 volume); + LLMediaBase::EStatus getStatus(); - /*virtual*/ void onMediaSizeChange(const EventType& event_in); - /*virtual*/ void onMediaContentsChange(const EventType& event_in); + /*virtual*/ void onMediaSizeChange(const EventType& event_in); + /*virtual*/ void onMediaContentsChange(const EventType& event_in); - void updateMovieImage(const LLUUID& image_id, BOOL active); - void updateImagesMediaStreams(); - LLUUID getMediaTextureID(); + void restoreMovieImage(); + void updateImagesMediaStreams(); + LLUUID getMediaTextureID(); - // Internally set our desired browser user agent string, including - // the Second Life version and skin name. Used because we can - // switch skins without restarting the app. - static void updateBrowserUserAgent(); + // Internally set our desired browser user agent string, including + // the Second Life version and skin name. Used because we can + // switch skins without restarting the app. + static void updateBrowserUserAgent(); - // Callback for when the SkinCurrent control is changed to - // switch the user agent string to indicate the new skin. - static bool handleSkinCurrentChanged(const LLSD& newvalue); + // Callback for when the SkinCurrent control is changed to + // switch the user agent string to indicate the new skin. + static bool handleSkinCurrentChanged(const LLSD& newvalue); - public: +public: - // a single media url with some data and an impl. - LLMediaBase* mMediaSource; - LLUUID mMovieImageID; - bool mMovieImageHasMips; - std::string mMediaURL; - std::string mMimeType; - private: - void initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source); + // a single media url with some data and an impl. + LLMediaBase* mMediaSource; + LLUUID mMovieImageID; + bool mMovieImageHasMips; + std::string mMediaURL; + std::string mMimeType; + +private: + void initializePlaceholderImage(LLViewerMediaTexture *placeholder_image, LLMediaBase *media_source); }; static LLViewerMediaImpl sViewerMediaImpl; - ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::destroyMediaSource() @@ -112,12 +120,11 @@ void LLViewerMediaImpl::destroyMediaSource() LLMediaManager* mgr = LLMediaManager::getInstance(); if ( mMediaSource ) { - bool was_playing = LLViewerMedia::isMediaPlaying(); mMediaSource->remObserver(this); mgr->destroySource( mMediaSource ); // Restore the texture - updateMovieImage(LLUUID::null, was_playing); + restoreMovieImage(); } mMediaSource = NULL; @@ -223,49 +230,36 @@ LLMediaBase::EStatus LLViewerMediaImpl::getStatus() } ////////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active) +void LLViewerMediaImpl::restoreMovieImage() { // IF the media image hasn't changed, do nothing - if (mMovieImageID == uuid) + if (mMovieImageID.isNull()) { return; } - // If we have changed media uuid, restore the old one - if (!mMovieImageID.isNull()) + + //restore the movie image to the old one + LLViewerMediaTexture* media = LLViewerTextureManager::findMediaTexture( mMovieImageID ) ; + if (media) { - LLViewerImage* oldImage = LLViewerImage::getImage( mMovieImageID ); - if (oldImage) + if(media->getOldTexture())//set back to the old texture if it exists { - oldImage->reinit(mMovieImageHasMips); - oldImage->mIsMediaTexture = FALSE; - } - mMovieImageID.setNull(); - } - // If the movie is playing, set the new media image - if (active && !uuid.isNull()) - { - LLViewerImage* viewerImage = LLViewerImage::getImage( uuid ); - if( viewerImage ) - { - mMovieImageID = uuid; - // Can't use mipmaps for movies because they don't update the full image - mMovieImageHasMips = viewerImage->getUseMipMaps(); - viewerImage->reinit(FALSE); - viewerImage->mIsMediaTexture = TRUE; + media->switchToTexture(media->getOldTexture()) ; + media->setPlaying(FALSE) ; } + media->reinit(mMovieImageHasMips); } + mMovieImageID.setNull(); } ////////////////////////////////////////////////////////////////////////////////////////// -// static void LLViewerMediaImpl::updateImagesMediaStreams() { LLMediaManager::updateClass(); } -void LLViewerMediaImpl::initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source) +void LLViewerMediaImpl::initializePlaceholderImage(LLViewerMediaTexture *placeholder_image, LLMediaBase *media_source) { int media_width = media_source->getMediaWidth(); int media_height = media_source->getMediaHeight(); @@ -302,19 +296,14 @@ void LLViewerMediaImpl::initializePlaceholderImage(LLViewerImage *placeholder_im // placeholder_image->setExplicitFormat() placeholder_image->setUseMipMaps(FALSE); - - // MEDIAOPT: set this dynamically on play/stop - placeholder_image->mIsMediaTexture = true; } - - // virtual void LLViewerMediaImpl::onMediaContentsChange(const EventType& event_in) { LLMediaBase* media_source = event_in.getSubject(); - LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID ); - if ((placeholder_image) && (placeholder_image->getHasGLTexture())) + LLViewerMediaTexture* placeholder_image = LLViewerTextureManager::getMediaTexture( mMovieImageID ) ; + if (placeholder_image && placeholder_image->hasValidGLTexture()) { if (placeholder_image->getUseMipMaps()) { @@ -339,7 +328,7 @@ void LLViewerMediaImpl::onMediaContentsChange(const EventType& event_in) void LLViewerMediaImpl::onMediaSizeChange(const EventType& event_in) { LLMediaBase* media_source = event_in.getSubject(); - LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID ); + LLViewerMediaTexture* placeholder_image = LLViewerTextureManager::getMediaTexture( mMovieImageID ) ; if (placeholder_image) { initializePlaceholderImage(placeholder_image, media_source); @@ -350,75 +339,6 @@ void LLViewerMediaImpl::onMediaSizeChange(const EventType& event_in) } } - - // Get the image we're using - - /* - // update media stream if required - LLMediaEngine* media_engine = LLMediaEngine::getInstance(); - if (media_engine) - { - if ( media_engine->update() ) - { - LLUUID media_uuid = media_engine->getImageUUID(); - updateMovieImage(media_uuid, TRUE); - if (!media_uuid.isNull()) - { - LLViewerImage* viewerImage = getImage( media_uuid ); - if( viewerImage ) - { - LLMediaBase* renderer = media_engine->getMediaRenderer(); - if ((renderer->getTextureWidth() != viewerImage->getWidth()) || - (renderer->getTextureHeight() != viewerImage->getHeight()) || - (renderer->getTextureDepth() != viewerImage->getComponents()) || - (viewerImage->getHasGLTexture() == FALSE)) - { - // destroy existing GL image - viewerImage->destroyGLTexture(); - - // set new size - viewerImage->setSize( renderer->getTextureWidth(), - renderer->getTextureHeight(), - renderer->getTextureDepth() ); - - LLPointer raw = new LLImageRaw(renderer->getTextureWidth(), - renderer->getTextureHeight(), - renderer->getTextureDepth()); - raw->clear(0x7f,0x7f,0x7f,0xff); - viewerImage->createGLTexture(0, raw); - } - - // Set the explicit format the instance wants - viewerImage->setExplicitFormat(renderer->getTextureFormatInternal(), - renderer->getTextureFormatPrimary(), - renderer->getTextureFormatType(), - renderer->getTextureFormatSwapBytes()); - // This should be redundant, but just in case: - viewerImage->setUseMipMaps(FALSE); - - LLImageRaw* rawImage = media_engine->getImageRaw(); - if ( rawImage ) - { - viewerImage->setSubImage(rawImage, 0, 0, - renderer->getMediaWidth(), - renderer->getMediaHeight()); - } - } - else - { - llwarns << "MediaEngine update unable to get viewer image for GL texture" << llendl; - } - } - } - else - { - LLUUID media_uuid = media_engine->getImageUUID(); - updateMovieImage(media_uuid, FALSE); - } - } - */ - - LLUUID LLViewerMediaImpl::getMediaTextureID() { return mMovieImageID; @@ -461,7 +381,7 @@ bool LLViewerMediaImpl::handleSkinCurrentChanged(const LLSD& /*newvalue*/) // Wrapper class ////////////////////////////////////////////////////////////////////////////////////////// - +S32 LLViewerMedia::mMusicState = LLViewerMedia::STOPPED; ////////////////////////////////////////////////////////////////////////////////////////// // The viewer takes a long time to load the start screen. Part of the problem // is media initialization -- in particular, QuickTime loads many DLLs and @@ -691,6 +611,13 @@ bool LLViewerMedia::isActiveMediaTexture(const LLUUID& id) && isMediaPlaying()); } +////////////////////////////////////////////////////////////////////////////////////////// +//static +bool LLViewerMedia::isMusicPlaying() +{ + return mMusicState == PLAYING; +} + ////////////////////////////////////////////////////////////////////////////////////////// // static std::string LLViewerMedia::getMediaURL() @@ -709,3 +636,58 @@ void LLViewerMedia::setMimeType(std::string mime_type) { sViewerMediaImpl.mMimeType = mime_type; } + +////////////////////////////////////////////////////////////////////////////////////////// +//static +void LLViewerMedia::toggleMusicPlay(void*) +{ + if (mMusicState != PLAYING) + { + mMusicState = PLAYING; // desired state + if (gAudiop) + { + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if ( parcel ) + { + gAudiop->startInternetStream(parcel->getMusicURL()); + } + } + } + else + { + mMusicState = STOPPED; // desired state + if (gAudiop) + { + gAudiop->stopInternetStream(); + } + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +//static +void LLViewerMedia::toggleMediaPlay(void*) +{ + if (LLViewerMedia::isMediaPaused()) + { + LLViewerParcelMedia::start(); + } + else if(LLViewerMedia::isMediaPlaying()) + { + LLViewerParcelMedia::pause(); + } + else + { + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (parcel) + { + LLViewerParcelMedia::play(parcel); + } + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +//static +void LLViewerMedia::mediaStop(void*) +{ + LLViewerParcelMedia::stop(); +} diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 600d7409e2..b3fb2c9031 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -67,6 +67,7 @@ class LLViewerMedia static bool isMediaPaused(); static bool hasMedia(); static bool isActiveMediaTexture(const LLUUID& id); + static bool isMusicPlaying(); static std::string getMediaURL(); static std::string getMimeType(); @@ -74,9 +75,16 @@ class LLViewerMedia static void updateImagesMediaStreams(); + static void toggleMusicPlay(void*); + static void toggleMediaPlay(void*); + static void mediaStop(void*); + private: // Fill in initialization data for LLMediaManager::initClass() static void buildMediaManagerData( LLMediaManagerData* init_data ); + + enum { STOPPED=0, PLAYING=1, PAUSED=2 }; + static S32 mMusicState; }; #endif // LLVIEWERMEDIA_H diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 1ab10b2f27..eb676d3188 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -81,20 +81,19 @@ #include "lldrawpooltree.h" #include "llface.h" #include "llfirstuse.h" +#include "llfirsttimetipmanager.h" #include "llfloater.h" #include "llfloaterabout.h" #include "llfloaterbuycurrency.h" #include "llfloateractivespeakers.h" #include "llfloateranimpreview.h" #include "llfloateravatartextures.h" -#include "llfloaterbeacons.h" #include "llfloaterbuildoptions.h" #include "llfloaterbump.h" #include "llfloaterbuy.h" #include "llfloaterbuycontents.h" #include "llfloaterbuycurrency.h" #include "llfloaterbuyland.h" -#include "llfloatercamera.h" #include "llfloaterchat.h" #include "llfloatercustomize.h" #include "llfloaterdaycycle.h" @@ -133,7 +132,8 @@ #include "llfloaterworldmap.h" #include "llfloatermemleak.h" #include "llfasttimerview.h" -#include "llfriendactions.h" +#include "llavataractions.h" +#include "lllandmarkactions.h" #include "llmemoryview.h" #include "llgivemoney.h" #include "llgroupmgr.h" @@ -146,7 +146,7 @@ #include "llimagetga.h" #include "llinventorybridge.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyboard.h" #include "llpanellogin.h" #include "llmenucommands.h" @@ -161,6 +161,7 @@ #include "llresmgr.h" #include "llrootview.h" #include "llselectmgr.h" +#include "llsidetray.h" #include "llsky.h" #include "llstatusbar.h" #include "llstatview.h" @@ -184,7 +185,7 @@ #include "llviewercamera.h" #include "llviewergenericmessage.h" #include "llviewergesture.h" -#include "llviewerimagelist.h" // gImageList +#include "llviewertexturelist.h" // gTextureList #include "llviewerinventory.h" #include "llviewermenufile.h" // init_menu_file() #include "llviewermessage.h" @@ -500,30 +501,30 @@ void init_menus() /// /// Pie menus /// - gPieSelf = LLUICtrlFactory::getInstance()->createFromFile("menu_pie_self.xml", gMenuHolder); + gPieSelf = LLUICtrlFactory::getInstance()->createFromFile("menu_pie_self.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); // TomY TODO: what shall we do about these? gDetachScreenPieMenu = gMenuHolder->getChild("Object Detach HUD", true); gDetachPieMenu = gMenuHolder->getChild("Object Detach", true); - gPieAvatar = LLUICtrlFactory::getInstance()->createFromFile("menu_pie_avatar.xml", gMenuHolder); + gPieAvatar = LLUICtrlFactory::getInstance()->createFromFile("menu_pie_avatar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - gPieObject = LLUICtrlFactory::getInstance()->createFromFile("menu_pie_object.xml", gMenuHolder); + gPieObject = LLUICtrlFactory::getInstance()->createFromFile("menu_pie_object.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); gAttachScreenPieMenu = gMenuHolder->getChild("Object Attach HUD"); gAttachPieMenu = gMenuHolder->getChild("Object Attach"); gPieRate = gMenuHolder->getChild("Rate Menu"); - gPieAttachment = LLUICtrlFactory::getInstance()->createFromFile("menu_pie_attachment.xml", gMenuHolder); + gPieAttachment = LLUICtrlFactory::getInstance()->createFromFile("menu_pie_attachment.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - gPieLand = LLUICtrlFactory::getInstance()->createFromFile("menu_pie_land.xml", gMenuHolder); + gPieLand = LLUICtrlFactory::getInstance()->createFromFile("menu_pie_land.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); /// /// set up the colors /// LLColor4 color; - LLColor4 context_menu_color = gSavedSkinSettings.getColor("MenuPopupBgColor"); + LLColor4 context_menu_color = LLUIColorTable::instance().getColor("MenuPopupBgColor"); gPieSelf->setBackgroundColor( context_menu_color ); gPieAvatar->setBackgroundColor( context_menu_color ); @@ -532,19 +533,19 @@ void init_menus() gPieLand->setBackgroundColor( context_menu_color ); - color = gSavedSkinSettings.getColor( "MenuPopupBgColor" ); + color = LLUIColorTable::instance().getColor( "MenuPopupBgColor" ); gPopupMenuView->setBackgroundColor( color ); // If we are not in production, use a different color to make it apparent. if (LLViewerLogin::getInstance()->isInProductionGrid()) { - color = gSavedSkinSettings.getColor( "MenuBarBgColor" ); + color = LLUIColorTable::instance().getColor( "MenuBarBgColor" ); } else { - color = gSavedSkinSettings.getColor( "MenuNonProductionBgColor" ); + color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" ); } - gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile("menu_viewer.xml", gMenuHolder); + gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile("menu_viewer.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); gMenuBarView->setRect(LLRect(0, top, 0, top - MENU_BAR_HEIGHT)); gMenuBarView->setBackgroundColor( color ); @@ -575,7 +576,7 @@ void init_menus() // Let land based option enable when parcel changes gMenuParcelObserver = new LLMenuParcelObserver(); - gLoginMenuBarView = LLUICtrlFactory::getInstance()->createFromFile("menu_login.xml", gMenuHolder); + gLoginMenuBarView = LLUICtrlFactory::getInstance()->createFromFile("menu_login.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); gLoginMenuBarView->arrangeAndClear(); LLRect menuBarRect = gLoginMenuBarView->getRect(); gLoginMenuBarView->setRect(LLRect(menuBarRect.mLeft, menuBarRect.mTop, gViewerWindow->getRootView()->getRect().getWidth() - menuBarRect.mLeft, menuBarRect.mBottom)); @@ -612,11 +613,6 @@ class LLAdvancedToggleConsole : public view_listener_t toggle_visibility( (void*)gDebugView->mMemoryView ); } #endif - else if ("notifications" == console_type) - { - //LLFloaterNotificationConsole::showInstance(); - LLFloaterReg::showInstance("notifications_console"); - } return true; } }; @@ -1117,30 +1113,6 @@ class LLAdvancedCheckFrameTest : public view_listener_t }; - // -///////////////////////////// -//// HIDE SELECTED OBJECTS // -///////////////////////////// -// -// -//class LLAdvancedToggleHideSelectedObjects : public view_listener_t -//{ -// bool handleEvent(const LLSD& userdata) -// { -// LLSelectMgr::sHideSelectedObjects = !(LLSelectMgr::sHideSelectedObjects); -// return true; -// } -//}; - // -//class LLAdvancedCheckHideSelectedObjects : public view_listener_t -//{ -// bool handleEvent(const LLSD& userdata) -// { -// bool new_value = gHideSelectedObjects; -// return new_value; -// } -//}; - /////////////////////////// // SELECTED TEXTURE INFO // /////////////////////////// @@ -1185,7 +1157,7 @@ class LLAdvancedToggleDisableTextures : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLViewerImage::sDontLoadVolumeTextures = !LLViewerImage::sDontLoadVolumeTextures; + LLViewerTexture::sDontLoadVolumeTextures = !LLViewerTexture::sDontLoadVolumeTextures; return true; } }; @@ -1194,7 +1166,7 @@ class LLAdvancedCheckDisableTextures : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = LLViewerImage::sDontLoadVolumeTextures; // <-- make this using LLCacheControl + bool new_value = LLViewerTexture::sDontLoadVolumeTextures; // <-- make this using LLCacheControl return new_value; } }; @@ -1506,16 +1478,6 @@ class LLAdvancedCheckDebugWindowProc : public view_listener_t // ------------------------------XUI MENU --------------------------- - -class LLAdvancedShowFontTest : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloaterFontTest::show(NULL); - return true; - } -}; - ////////////////////// // LOAD UI FROM XML // ////////////////////// @@ -1547,6 +1509,15 @@ class LLAdvancedSaveUIToXML : public view_listener_t }; +class LLAdvancedSendTestIms : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLIMModel::instance().testMessages(); + return true; +} +}; + /////////////// // XUI NAMES // @@ -1987,18 +1958,6 @@ class LLAdvancedDumpAvatarLocalTextures : public view_listener_t } }; -//////////////////////////////// -// Memory Leaking Simulation // -//////////////////////////////// -class LLAdvancedMemoryLeakingSimulation : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloaterMemLeak::show(NULL); - return true; - } -}; - #endif ///////////////// @@ -2147,7 +2106,6 @@ class LLAdvancedShowDebugSettings : public view_listener_t { bool handleEvent(const LLSD& userdata) { - // LLFloaterSettingsDebug::showInstance(userdata); LLFloaterReg::showInstance("settings_debug",userdata); return true; } @@ -2414,14 +2372,6 @@ class LLAdminHandleRegionDumpTempAssetData: public view_listener_t } }; //Admin (Top Level) -class LLAdminShowGodTools: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloaterGodTools::showInstance(LLSD()); - return true; - } -}; class LLAdminOnSaveState: public view_listener_t { @@ -2581,7 +2531,7 @@ class LLObjectEnableTouch : public view_listener_t // label.assign("Touch"); // } //} - +/* bool handle_object_open() { LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); @@ -2598,7 +2548,7 @@ class LLObjectOpen : public view_listener_t return handle_object_open(); } }; - +*/ class LLObjectEnableOpen : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -2715,16 +2665,6 @@ class LLObjectEdit : public view_listener_t } }; -class LLObjectInspect : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloaterInspect::show(); - return true; - } -}; - - //--------------------------------------------------------------------------- // Land pie menu //--------------------------------------------------------------------------- @@ -3109,7 +3049,7 @@ class LLAvatarDebug : public view_listener_t strings.push_back(avatar->getID().asString()); LLUUID invoice; send_generic_message("dumptempassetdata", strings, invoice); - LLFloaterAvatarTextures::show( avatar->getID() ); + LLFloaterReg::showInstance( "avatar_tetures", LLSD(avatar->getID()) ); } return true; } @@ -3500,7 +3440,7 @@ class LLSelfStandUp : public view_listener_t { bool handleEvent(const LLSD& userdata) { - gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + gAgent.standUp(); return true; } }; @@ -3509,11 +3449,31 @@ class LLSelfEnableStandUp : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting; + bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting(); return new_value; } }; +class LLSelfFriends : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + // Open "Friends" tab of the "People" panel in side tray. + LLSideTray::getInstance()->showPanel("panel_people", "friends_panel"); + return true; + } +}; + +class LLSelfGroups : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + // Open "Groups" tab of the "People" panel in side tray. + LLSideTray::getInstance()->showPanel("panel_people", "groups_panel"); + return true; + } +}; + BOOL check_admin_override(void*) { return gAgent.getAdminOverride(); @@ -3647,14 +3607,9 @@ bool LLHaveCallingcard::operator()(LLInventoryCategory* cat, } */ -BOOL is_agent_friend(const LLUUID& agent_id) -{ - return (LLAvatarTracker::instance().getBuddyInfo(agent_id) != NULL); -} - BOOL is_agent_mappable(const LLUUID& agent_id) { - return (is_agent_friend(agent_id) && + return (LLAvatarActions::isFriend(agent_id) && LLAvatarTracker::instance().getBuddyInfo(agent_id)->isOnline() && LLAvatarTracker::instance().getBuddyInfo(agent_id)->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION) ); @@ -3667,7 +3622,7 @@ class LLAvatarEnableAddFriend : public view_listener_t bool handleEvent(const LLSD& userdata) { LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); - bool new_value = avatar && !is_agent_friend(avatar->getID()); + bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID()); return new_value; } }; @@ -3691,7 +3646,7 @@ void request_friendship(const LLUUID& dest_id) } if (!fullname.empty()) { - LLFriendActions::requestFriendshipDialog(dest_id, fullname); + LLAvatarActions::requestFriendshipDialog(dest_id, fullname); } else { @@ -3722,7 +3677,7 @@ bool handle_sit_or_stand() if (sitting_on_selection()) { - gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + gAgent.standUp(); return true; } @@ -3768,7 +3723,7 @@ class LLLandSit : public view_listener_t { bool handleEvent(const LLSD& userdata) { - gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + gAgent.standUp(); LLViewerParcelMgr::getInstance()->deselectLand(); LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal; @@ -4382,7 +4337,7 @@ void handle_take() } // check library - if(gInventory.isObjectDescendentOf(category_id, gInventoryLibraryRoot)) + if(gInventory.isObjectDescendentOf(category_id, gInventory.getLibraryRootFolderID())) { category_id.setNull(); } @@ -4676,7 +4631,7 @@ BOOL sitting_on_selection() return FALSE; } - return (avatar->mIsSitting && avatar->getRoot() == root_object); + return (avatar->isSitting() && avatar->getRoot() == root_object); } class LLToolsSaveToInventory : public view_listener_t @@ -5271,6 +5226,9 @@ class LLWorldAlwaysRun : public view_listener_t // tell the simulator. gAgent.sendWalkRun(gAgent.getAlwaysRun()); + // Update Movement Controls according to AlwaysRun mode + LLFloaterMove::setAlwaysRunMode(gAgent.getAlwaysRun()); + return true; } }; @@ -5317,29 +5275,14 @@ class LLWorldSetBusy : public view_listener_t } }; -bool can_create_landmark() -{ - BOOL can = FALSE; - - LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if (agent_parcel) -{ - - if (agent_parcel->getAllowLandmark() - || LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK)) - { - can = TRUE; - } - } - - return can; -} - class LLWorldCreateLandmark : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLFloaterReg::showInstance("add_landmark"); + LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); + + // Floater "Add Landmark" functionality moved to Side Tray + //LLFloaterReg::showInstance("add_landmark"); return true; } }; @@ -5394,8 +5337,7 @@ void invite_to_group(const LLUUID& dest_id) LLViewerObject* dest = gObjectList.findObject(dest_id); if(dest && dest->isAvatar()) { - LLFloaterGroupPicker* widget; - widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); + LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance("group_picker", LLSD(gAgent.getID())); if (widget) { widget->center(); @@ -5423,7 +5365,7 @@ class LLAvatarAddFriend : public view_listener_t bool handleEvent(const LLSD& userdata) { LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); - if(avatar && !is_agent_friend(avatar->getID())) + if(avatar && !LLAvatarActions::isFriend(avatar->getID())) { request_friendship(avatar->getID()); } @@ -5597,11 +5539,7 @@ class LLShowFloater : public view_listener_t bool handleEvent(const LLSD& userdata) { std::string floater_name = userdata.asString(); - if (floater_name == "gestures") - { - LLFloaterGesture::toggleVisibility(); - } - else if (floater_name == "appearance") + if (floater_name == "appearance") { if (gAgentWearables.areWearablesLoaded()) { @@ -5612,35 +5550,6 @@ class LLShowFloater : public view_listener_t { LLToolBar::toggle(NULL); } - else if (floater_name == "mute list") - { - LLFloaterReg::toggleInstance("mute"); - } - else if (floater_name == "camera controls") - { - LLFloaterCamera::toggleInstance(); - } - else if (floater_name == "movement controls") - { - LLFloaterMove::toggleInstance(); - } - else if (floater_name == "my land") - { - LLFloaterLandHoldings::show(NULL); - } - else if (floater_name == "about land") - { - if (LLViewerParcelMgr::getInstance()->selectionEmpty()) - { - LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal()); - } - - LLFloaterLand::showInstance(); - } - else if (floater_name == "about region") - { - LLFloaterRegionInfo::showInstance(); - } else if (floater_name == "buy land") { if (LLViewerParcelMgr::getInstance()->selectionEmpty()) @@ -5650,10 +5559,6 @@ class LLShowFloater : public view_listener_t LLViewerParcelMgr::getInstance()->startBuyLand(); } - else if (floater_name == "grid options") - { - LLFloaterReg::showInstance("build_options"); - } else if (floater_name == "script errors") { LLFloaterScriptDebug::show(LLUUID::null); @@ -5662,48 +5567,16 @@ class LLShowFloater : public view_listener_t { gViewerHtmlHelp.show(); } - else if (floater_name == "help tutorial") - { - LLFloaterHUD::showHUD(); - } else if (floater_name == "complaint reporter") { // Prevent menu from appearing in screen shot. gMenuHolder->hideMenus(); LLFloaterReporter::showFromMenu(COMPLAINT_REPORT); } - else if (floater_name == "mean events") - { - if (!gNoRender) - { - //LLFloaterBump::showInstance(); - LLFloaterReg::showInstance("bumps"); - } - } - else if (floater_name == "lag meter") - { - LLFloaterReg::showInstance("lagmeter"); - } else if (floater_name == "buy currency") { LLFloaterBuyCurrency::buyCurrency(); } - else if (floater_name == "about") - { - LLFloaterReg::showInstance("sl_about"); - } - else if (floater_name == "active speakers") - { - LLFloaterActiveSpeakers::toggleInstance(LLSD()); - } - else if (floater_name == "beacons") - { - LLFloaterBeacons::toggleInstance(LLSD()); - } - else if (floater_name == "perm prefs") - { - LLFloaterPerms::toggleInstance(LLSD()); - } else { LLFloaterReg::toggleInstance(floater_name); @@ -5722,30 +5595,6 @@ class LLFloaterVisible : public view_listener_t { new_value = LLToolBar::visible(NULL); } - else if (floater_name == "mute list") - { - new_value = LLFloaterReg::instanceVisible("mute"); - } - else if (floater_name == "camera controls") - { - new_value = LLFloaterCamera::instanceVisible(); - } - else if (floater_name == "movement controls") - { - new_value = LLFloaterMove::instanceVisible(); - } - else if (floater_name == "stat bar") - { - new_value = gSavedSettings.getBOOL("ShowDebugStats"); - } - else if (floater_name == "active speakers") - { - new_value = LLFloaterActiveSpeakers::instanceVisible(LLSD()); - } - else if (floater_name == "beacons") - { - new_value = LLFloaterBeacons::instanceVisible(LLSD()); - } else { new_value = LLFloaterReg::instanceVisible(floater_name); @@ -5852,7 +5701,7 @@ class LLShowAgentProfile : public view_listener_t LLVOAvatar* avatar = find_avatar_from_object(agent_id); if (avatar) { - LLFriendActions::showProfile(avatar->getID()); + LLAvatarActions::showProfile(avatar->getID()); } return true; } @@ -6440,8 +6289,8 @@ class LLToolsSelectedScriptAction : public view_listener_t msg = "RunningNot"; } LLUUID id; id.generate(); - LLFloater* floater = LLFloaterReg::getInstance(name, LLSD(id)); - LLFloaterScriptQueue* queue = dynamic_cast(floater); + + LLFloaterScriptQueue* queue =LLFloaterReg::getTypedInstance(name, LLSD(id)); if (queue) { queue->setMono(mono); @@ -6450,7 +6299,7 @@ class LLToolsSelectedScriptAction : public view_listener_t else { llwarns << "Failed to generate LLFloaterScriptQueue with action: " << action << llendl; - delete floater; + delete queue; } return true; } @@ -6477,7 +6326,7 @@ void handle_selected_texture_info(void*) { if (!node->isTESelected(i)) continue; - LLViewerImage* img = node->getObject()->getTEImage(i); + LLViewerTexture* img = node->getObject()->getTEImage(i); LLUUID image_id = img->getID(); faces_per_texture[image_id].push_back(i); } @@ -6487,7 +6336,7 @@ void handle_selected_texture_info(void*) { LLUUID image_id = it->first; U8 te = it->second[0]; - LLViewerImage* img = node->getObject()->getTEImage(te); + LLViewerTexture* img = node->getObject()->getTEImage(te); S32 height = img->getHeight(); S32 width = img->getWidth(); S32 components = img->getComponents(); @@ -6807,9 +6656,7 @@ class LLWorldEnableCreateLandmark : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = can_create_landmark(); - - return new_value; + return !LLLandmarkActions::landmarkAlreadyExists(); } }; @@ -6959,7 +6806,7 @@ void handle_debug_avatar_textures(void*) LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (objectp) { - LLFloaterAvatarTextures::show(objectp->getID()); + LLFloaterReg::showInstance( "avatar_tetures", LLSD(objectp->getID()) ); } } @@ -7016,7 +6863,7 @@ void handle_grab_texture(void* data) gInventory.updateItem(item); gInventory.notifyObservers(); - LLInventoryView* view = LLInventoryView::getActiveInventory(); + LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); // Show the preview panel for textures to let // user know that the image is now in inventory. @@ -7026,7 +6873,7 @@ void handle_grab_texture(void* data) view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO); view->getPanel()->openSelected(); - //LLInventoryView::dumpSelectionInformation((void*)view); + //LLFloaterInventory::dumpSelectionInformation((void*)view); // restore keyboard focus gFocusMgr.setKeyboardFocus(focus_ctrl); } @@ -7214,8 +7061,8 @@ void handle_load_from_xml(void*) if (picker.getOpenFile(LLFilePicker::FFLOAD_XML)) { std::string filename = picker.getFirstFile(); - LLFloater* floater = new LLFloater(); - LLUICtrlFactory::getInstance()->buildFloater(floater, filename); + LLFloater* floater = new LLFloater(LLSD()); + LLUICtrlFactory::getInstance()->buildFloater(floater, filename, NULL); } } @@ -7261,10 +7108,7 @@ void handle_buy_currency_test(void*) llinfos << "buy currency url " << url << llendl; - LLFloaterHtmlCurrency* floater = LLFloaterHtmlCurrency::showInstance(url); - // Needed so we can use secondlife:///app/floater/self/close SLURLs - floater->setTrusted(true); - floater->center(); + LLFloaterReg::showInstance("buy_currency_html", LLSD(url)); } void handle_rebake_textures(void*) @@ -7521,47 +7365,47 @@ class LLEditEnableTakeOff : public view_listener_t bool new_value = false; if (clothing == "shirt") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_SHIRT); + new_value = LLAgentWearables::selfHasWearable(WT_SHIRT); } if (clothing == "pants") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_PANTS); + new_value = LLAgentWearables::selfHasWearable(WT_PANTS); } if (clothing == "shoes") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_SHOES); + new_value = LLAgentWearables::selfHasWearable(WT_SHOES); } if (clothing == "socks") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_SOCKS); + new_value = LLAgentWearables::selfHasWearable(WT_SOCKS); } if (clothing == "jacket") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_JACKET); + new_value = LLAgentWearables::selfHasWearable(WT_JACKET); } if (clothing == "gloves") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_GLOVES); + new_value = LLAgentWearables::selfHasWearable(WT_GLOVES); } if (clothing == "undershirt") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_UNDERSHIRT); + new_value = LLAgentWearables::selfHasWearable(WT_UNDERSHIRT); } if (clothing == "underpants") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_UNDERPANTS); + new_value = LLAgentWearables::selfHasWearable(WT_UNDERPANTS); } if (clothing == "skirt") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_SKIRT); + new_value = LLAgentWearables::selfHasWearable(WT_SKIRT); } if (clothing == "alpha") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_ALPHA); + new_value = LLAgentWearables::selfHasWearable(WT_ALPHA); } if (clothing == "tattoo") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_TATTOO); + new_value = LLAgentWearables::selfHasWearable(WT_TATTOO); } return new_value; } @@ -7664,16 +7508,7 @@ class LLWorldEnvSettings : public view_listener_t if (tod == "editor") { // if not there or is hidden, show it - if( !LLFloaterEnvSettings::isOpen() || - !LLFloaterEnvSettings::instance()->getVisible()) { - LLFloaterEnvSettings::show(); - - // otherwise, close it button acts like a toggle - } - else - { - LLFloaterEnvSettings::instance()->closeFloater(); - } + LLFloaterReg::toggleInstance("env_settings"); return true; } @@ -7735,17 +7570,7 @@ class LLWorldWaterSettings : public view_listener_t { bool handleEvent(const LLSD& userdata) { - // if not there or is hidden, show it - if( !LLFloaterWater::isOpen() || - !LLFloaterWater::instance()->getVisible()) { - LLFloaterWater::show(); - - // otherwise, close it button acts like a toggle - } - else - { - LLFloaterWater::instance()->closeFloater(); - } + LLFloaterReg::toggleInstance("env_water"); return true; } }; @@ -7755,7 +7580,7 @@ class LLWorldPostProcess : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLFloaterPostProcess::show(); + LLFloaterReg::showInstance("env_post_process"); return true; } }; @@ -7765,12 +7590,28 @@ class LLWorldDayCycle : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLFloaterDayCycle::show(); + LLFloaterReg::showInstance("env_day_cycle"); return true; } }; +/// Show First Time Tips calbacks +class LLHelpCheckShowFirstTimeTip : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return LLFirstTimeTipsManager::tipsEnabled(); + } +}; +class LLHelpShowFirstTimeTip : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLFirstTimeTipsManager::enabledTip(!userdata.asBoolean()); + return true; + } +}; void initialize_menus() { @@ -7875,6 +7716,9 @@ void initialize_menus() view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess"); view_listener_t::addMenu(new LLWorldDayCycle(), "World.DayCycle"); + view_listener_t::addMenu(new LLHelpCheckShowFirstTimeTip(), "Help.CheckShowFirstTimeTip"); + view_listener_t::addMenu(new LLHelpShowFirstTimeTip(), "Help.ShowQuickTips"); + // Tools menu view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool"); view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects"); @@ -7983,11 +7827,12 @@ void initialize_menus() // Advanced > XUI - view_listener_t::addMenu(new LLAdvancedShowFontTest(), "Advanced.ShowFontTest"); + commit.add("Advanced.ReloadColorSettings", boost::bind(&LLUIColorTable::loadFromSettings, LLUIColorTable::getInstance())); view_listener_t::addMenu(new LLAdvancedLoadUIFromXML(), "Advanced.LoadUIFromXML"); view_listener_t::addMenu(new LLAdvancedSaveUIToXML(), "Advanced.SaveUIToXML"); view_listener_t::addMenu(new LLAdvancedToggleXUINames(), "Advanced.ToggleXUINames"); view_listener_t::addMenu(new LLAdvancedCheckXUINames(), "Advanced.CheckXUINames"); + view_listener_t::addMenu(new LLAdvancedSendTestIms(), "Advanced.SendTestIMs"); // Advanced > Character > Grab Baked Texture view_listener_t::addMenu(new LLAdvancedGrabBakedTexture(), "Advanced.GrabBakedTexture"); @@ -8023,7 +7868,6 @@ void initialize_menus() #ifndef LL_RELEASE_FOR_DOWNLOAD view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures"); view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures"); - view_listener_t::addMenu(new LLAdvancedMemoryLeakingSimulation(), "Advanced.MemoryLeakingSimulation"); #endif // Advanced > Network view_listener_t::addMenu(new LLAdvancedEnableMessageLog(), "Advanced.EnableMessageLog"); @@ -8071,7 +7915,6 @@ void initialize_menus() // Admin >Region view_listener_t::addMenu(new LLAdminHandleRegionDumpTempAssetData(), "Admin.HandleRegionDumpTempAssetData"); // Admin top level - view_listener_t::addMenu(new LLAdminShowGodTools(), "Admin.ShowGodTools"); view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState"); // Self pie menu @@ -8081,6 +7924,10 @@ void initialize_menus() view_listener_t::addMenu(new LLSelfEnableStandUp(), "Self.EnableStandUp"); view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments"); + // we don't use boost::bind directly to delay side tray construction + view_listener_t::addMenu(new LLSelfFriends(), "Self.Friends"); + view_listener_t::addMenu(new LLSelfGroups(), "Self.Groups"); + // Avatar pie menu view_listener_t::addMenu(new LLObjectMute(), "Avatar.Mute"); view_listener_t::addMenu(new LLAvatarAddFriend(), "Avatar.AddFriend"); @@ -8099,7 +7946,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAvatarEnableFreezeEject(), "Avatar.EnableFreezeEject"); // Object pie menu - view_listener_t::addMenu(new LLObjectOpen(), "Object.Open"); view_listener_t::addMenu(new LLObjectBuild(), "Object.Build"); view_listener_t::addMenu(new LLObjectTouch(), "Object.Touch"); view_listener_t::addMenu(new LLObjectSitOrStand(), "Object.SitOrStand"); @@ -8110,7 +7956,6 @@ void initialize_menus() view_listener_t::addMenu(new LLObjectMute(), "Object.Mute"); view_listener_t::addMenu(new LLObjectBuy(), "Object.Buy"); view_listener_t::addMenu(new LLObjectEdit(), "Object.Edit"); - view_listener_t::addMenu(new LLObjectInspect(), "Object.Inspect"); view_listener_t::addMenu(new LLObjectEnableOpen(), "Object.EnableOpen"); view_listener_t::addMenu(new LLObjectEnableTouch(), "Object.EnableTouch"); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 99994bdf5b..e8d350b0b6 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -75,8 +75,6 @@ BOOL enable_deselect(void*); BOOL enable_undo(void*); BOOL enable_redo(void*); -// returns TRUE if we have a friend relationship with agent_id -BOOL is_agent_friend(const LLUUID& agent_id); BOOL is_agent_mappable(const LLUUID& agent_id); void confirm_replace_attachment(S32 option, void* user_data); @@ -101,7 +99,6 @@ void handle_toggle_flycam(); bool handle_sit_or_stand(); bool handle_give_money_dialog(); -bool handle_object_open(); bool handle_go_to(); // Export to XML or Collada diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 6576ea81ed..02e9528f7d 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -37,17 +37,15 @@ // project includes #include "llagent.h" #include "llfilepicker.h" -#include "llfloateranimpreview.h" +#include "llfloaterreg.h" #include "llfloaterbuycurrency.h" -#include "llfloaterimagepreview.h" -#include "llfloaternamedesc.h" #include "llfloatersnapshot.h" #include "llinventorymodel.h" // gInventory #include "llresourcedata.h" #include "llfloaterperms.h" #include "llstatusbar.h" #include "llviewercontrol.h" // gSavedSettings -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "lluictrlfactory.h" #include "llviewerinventory.h" #include "llviewermenu.h" // gMenuHolder @@ -254,8 +252,7 @@ class LLFileUploadImage : public view_listener_t std::string filename = upload_pick((void *)LLFilePicker::FFLOAD_IMAGE); if (!filename.empty()) { - LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename); - LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_image_preview.xml"); + LLFloaterReg::showInstance("upload_image", LLSD(filename)); } return TRUE; } @@ -268,9 +265,7 @@ class LLFileUploadSound : public view_listener_t std::string filename = upload_pick((void*)LLFilePicker::FFLOAD_WAV); if (!filename.empty()) { - LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename); - LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_sound_preview.xml"); - floaterp->childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload() )); + LLFloaterReg::showInstance("upload_sound", LLSD(filename)); } return true; } @@ -283,8 +278,7 @@ class LLFileUploadAnim : public view_listener_t const std::string filename = upload_pick((void*)LLFilePicker::FFLOAD_ANIM); if (!filename.empty()) { - LLFloaterAnimPreview* floaterp = new LLFloaterAnimPreview(filename); - LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_animation_preview.xml"); + LLFloaterReg::showInstance("upload_anim", LLSD(filename)); } return true; } @@ -481,7 +475,7 @@ void handle_compress_image(void*) BOOL success; - success = LLViewerImageList::createUploadFile(infile, outfile, IMG_CODEC_TGA); + success = LLViewerTextureList::createUploadFile(infile, outfile, IMG_CODEC_TGA); if (success) { @@ -537,7 +531,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, else if( exten == "bmp") { asset_type = LLAssetType::AT_TEXTURE; - if (!LLViewerImageList::createUploadFile(src_filename, + if (!LLViewerTextureList::createUploadFile(src_filename, filename, IMG_CODEC_BMP )) { @@ -552,7 +546,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, else if( exten == "tga") { asset_type = LLAssetType::AT_TEXTURE; - if (!LLViewerImageList::createUploadFile(src_filename, + if (!LLViewerTextureList::createUploadFile(src_filename, filename, IMG_CODEC_TGA )) { @@ -567,7 +561,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, else if( exten == "jpg" || exten == "jpeg") { asset_type = LLAssetType::AT_TEXTURE; - if (!LLViewerImageList::createUploadFile(src_filename, + if (!LLViewerTextureList::createUploadFile(src_filename, filename, IMG_CODEC_JPEG )) { @@ -582,7 +576,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, else if( exten == "png") { asset_type = LLAssetType::AT_TEXTURE; - if (!LLViewerImageList::createUploadFile(src_filename, + if (!LLViewerTextureList::createUploadFile(src_filename, filename, IMG_CODEC_PNG )) { diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a05bd30600..f8b6e0f687 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -94,8 +94,9 @@ #include "llhudmanager.h" #include "llimpanel.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llmenugl.h" +#include "llmoveview.h" #include "llmutelist.h" #include "llnotifications.h" #include "llnotify.h" @@ -143,6 +144,9 @@ #include "llwindebug.h" // For the invalid message handler #endif +//#include "llnearbychathistory.h" +#include "llnotificationmanager.h" + // // Constants // @@ -206,6 +210,10 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response) LLUUID fid; LLMessageSystem* msg = gMessageSystem; const LLSD& payload = notification["payload"]; + + // add friend to recent people list + LLRecentPeople::instance().add(payload["from_id"]); + switch(option) { case 0: @@ -912,17 +920,17 @@ void open_offer(const std::vector& items, const std::string& from_name) //highlight item, if it's not in the trash or lost+found // Don't auto-open the inventory floater - LLInventoryView* view = NULL; + LLFloaterInventory* view = NULL; if(gSavedSettings.getBOOL("ShowInInventory") && asset_type != LLAssetType::AT_CALLINGCARD && item->getInventoryType() != LLInventoryType::IT_ATTACHMENT && !from_name.empty()) { - view = LLInventoryView::showAgentInventory(); + view = LLFloaterInventory::showAgentInventory(); } else { - view = LLInventoryView::getActiveInventory(); + view = LLFloaterInventory::getActiveInventory(); } if(!view) { @@ -986,7 +994,8 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id, if (LLMuteList::getInstance()->add(mute)) { LLFloaterReg::showInstance("mute"); - LLFloaterReg::getTypedInstance("mute")->selectMute(blocked_id); + LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance("mute"); + if(mute_instance) mute_instance->selectMute(blocked_id); } // purge the message queue of any previously queued inventory offers from the same source. @@ -1248,6 +1257,12 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& break; } + if(IM_INVENTORY_OFFERED == mIM) + { + // add buddy to recent people list + LLRecentPeople::instance().add(mFromID); + } + if(opener) { gInventory.addObserver(opener); @@ -1454,6 +1469,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat); BOOL is_linden = LLMuteList::getInstance()->isLinden(name); BOOL is_owned_by_me = FALSE; + BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true; + BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly"); chat.mMuted = is_muted && !is_linden; chat.mFromID = from_id; @@ -1527,7 +1544,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // now store incoming IM in chat history - buffer = separator_string + message.substr(message_offset); + buffer = message.substr(message_offset); LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL; @@ -1577,11 +1594,16 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str()); } - buffer = separator_string + saved + message.substr(message_offset); + buffer = saved + message.substr(message_offset); LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL; - if (!is_muted || is_linden) + bool mute_im = is_muted; + if(accept_im_from_only_friend&&!is_friend) + { + mute_im = true; + } + if (!mute_im || is_linden) { gIMMgr->addMessage( session_id, @@ -1715,7 +1737,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) LLSD args; args["SUBJECT"] = subj; args["MESSAGE"] = mes; - LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).timestamp(timestamp)); + LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(timestamp)); } // Also send down the old path for now. @@ -1772,7 +1794,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // Someone has offered us some inventory. { LLOfferInfo* info = new LLOfferInfo; - + bool mute_im = false; if (IM_INVENTORY_OFFERED == dialog) { struct offer_agent_bucket_t @@ -1789,6 +1811,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0]; info->mType = (LLAssetType::EType) bucketp->asset_type; info->mObjectID = bucketp->object_id; + + if(accept_im_from_only_friend&&!is_friend) + { + mute_im = true; + } } else { @@ -1819,7 +1846,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) info->mDesc = message; info->mHost = msg->getSender(); //if (((is_busy && !is_owned_by_me) || is_muted)) - if ( is_muted ) + if ( is_muted || mute_im) { // Same as closing window info->forceResponse(IOR_DECLINE); @@ -1876,7 +1903,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str()); } - buffer = separator_string + saved + message.substr(message_offset); + buffer = saved + message.substr(message_offset); BOOL is_this_agent = FALSE; if(from_id == gAgentID) { @@ -2369,15 +2396,15 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) switch(chat.mChatType) { case CHAT_TYPE_WHISPER: - verb = " " + LLTrans::getString("whisper") + " "; + verb = "(" + LLTrans::getString("whisper") + ")"; break; case CHAT_TYPE_DEBUG_MSG: case CHAT_TYPE_OWNER: case CHAT_TYPE_NORMAL: - verb = ": "; + verb = ""; break; case CHAT_TYPE_SHOUT: - verb = " " + LLTrans::getString("shout") + " "; + verb = "(" + LLTrans::getString("shout") + ")"; break; case CHAT_TYPE_START: case CHAT_TYPE_STOP: @@ -2385,12 +2412,12 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) break; default: LL_WARNS("Messaging") << "Unknown type " << chat.mChatType << " in chat!" << LL_ENDL; - verb = " say, "; + verb = ""; break; } - chat.mText = from_name; + chat.mText = ""; chat.mText += verb; chat.mText += mesg; } @@ -2418,11 +2445,18 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) && (is_linden || !is_busy || is_owned_by_me)) { // show on screen and add to history + LLNotificationsUI::LLNotificationManager::instance().onChat( + chat, LLNotificationsUI::NT_NEARBYCHAT); + + // adding temporarily so that communications window chat bar + // works until the new chat window is ready LLFloaterChat::addChat(chat, FALSE, FALSE); } else { - // just add to chat history + LLNotificationsUI::LLNotificationManager::instance().onChat( + chat, LLNotificationsUI::NT_NEARBYCHAT); + // adding temporarily LLFloaterChat::addChatHistory(chat); } } @@ -3837,7 +3871,7 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data) if (object) { LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation()); - if (!use_autopilot || (avatar && avatar->mIsSitting && avatar->getRoot() == object->getRoot())) + if (!use_autopilot || (avatar && avatar->isSitting() && avatar->getRoot() == object->getRoot())) { //we're already sitting on this object, so don't autopilot } @@ -4509,9 +4543,6 @@ void process_economy_data(LLMessageSystem *msg, void** /*user_data*/) LL_INFOS_ONCE("Messaging") << "EconomyData message arrived; upload cost is L$" << upload_cost << LL_ENDL; - LLFloaterImagePreview::setUploadAmount(upload_cost); - LLFloaterAnimPreview::setUploadAmount(upload_cost); - gMenuHolder->childSetLabelArg("Upload Image", "[COST]", llformat("%d", upload_cost)); gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", llformat("%d", upload_cost)); gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", llformat("%d", upload_cost)); @@ -4793,13 +4824,13 @@ void container_inventory_arrived(LLViewerObject* object, gAgent.changeCameraToDefault(); } - LLInventoryView* view = LLInventoryView::getActiveInventory(); + LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); if (inventory->size() > 2) { // create a new inventory category to put this in LLUUID cat_id; - cat_id = gInventory.createNewCategory(gAgent.getInventoryRootID(), + cat_id = gInventory.createNewCategory(gInventory.getRootFolderID(), LLAssetType::AT_NONE, LLTrans::getString("AcquiredItems")); @@ -5494,10 +5525,14 @@ void process_script_teleport_request(LLMessageSystem* msg, void**) msg->getVector3("Data", "SimPosition", pos); msg->getVector3("Data", "LookAt", look_at); - LLFloaterWorldMap::getInstance()->trackURL( - sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]); - LLFloaterReg::showInstance("world_map", "center"); - + LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance(); + if(instance) + { + instance->trackURL( + sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]); + LLFloaterReg::showInstance("world_map", "center"); + } + // remove above two lines and replace with below line // to re-enable parcel browser for llMapDestination() // LLURLDispatcher::dispatch(LLSLURL::buildSLURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]), FALSE); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index a96ccfd848..ec11e0aee2 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -42,6 +42,7 @@ #include "llviewercontrol.h" #include "lldatapacker.h" #include "llfasttimer.h" +#include "llfloaterreg.h" #include "llfontgl.h" #include "llframetimer.h" #include "llinventory.h" @@ -70,7 +71,7 @@ #include "llrendersphere.h" #include "lltooldraganddrop.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerinventory.h" #include "llviewerobjectlist.h" #include "llviewerparceloverlay.h" @@ -2595,7 +2596,7 @@ void LLViewerObject::doInventoryCallback() void LLViewerObject::removeInventory(const LLUUID& item_id) { // close any associated floater properties - LLFloaterProperties::closeByID(item_id, mID); + LLFloaterReg::hideInstance("properties", item_id); LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_RemoveTaskInventory); @@ -2919,14 +2920,14 @@ void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */) S32 tex_count = getNumTEs(); for (i = 0; i < tex_count; i++) { - getTEImage(i)->setBoostLevel(LLViewerImage::BOOST_SELECTED); + getTEImage(i)->setBoostLevel(LLViewerTexture::BOOST_SELECTED); } if (isSculpted()) { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); LLUUID sculpt_id = sculpt_params->getSculptTexture(); - gImageList.getImage(sculpt_id)->setBoostLevel(LLViewerImage::BOOST_SELECTED); + LLViewerTextureManager::getFetchedTexture(sculpt_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLViewerTexture::BOOST_SELECTED); } if (boost_children) @@ -3554,8 +3555,8 @@ void LLViewerObject::setNumTEs(const U8 num_tes) { if (num_tes) { - LLPointer *new_images; - new_images = new LLPointer[num_tes]; + LLPointer *new_images; + new_images = new LLPointer[num_tes]; for (i = 0; i < num_tes; i++) { if (i < getNumTEs()) @@ -3689,11 +3690,11 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) // if (mDrawable.notNull() && mDrawable->isVisible()) // { const LLUUID& image_id = getTE(te)->getID(); - mTEImages[te] = gImageList.getImage(image_id); + mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); // } } -void LLViewerObject::setTEImage(const U8 te, LLViewerImage *imagep) +void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) { if (mTEImages[te] != imagep) { @@ -3715,7 +3716,7 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos uuid == LLUUID::null) { retval = LLPrimitive::setTETexture(te, uuid); - mTEImages[te] = gImageList.getImageFromHost(uuid, host); + mTEImages[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); setChanged(TEXTURE); if (mDrawable.notNull()) { @@ -3726,6 +3727,18 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos } +void LLViewerObject::changeTEImage(const LLViewerTexture* old_image, LLViewerTexture* new_image) +{ + U32 end = getNumTEs() ; + for (U32 face = 0 ; face < end ; face++) + { + if(old_image == mTEImages[face]) + { + mTEImages[face] = new_image ; + } + } +} + S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid) { // Invalid host == get from the agent's sim @@ -3970,20 +3983,20 @@ S32 LLViewerObject::setTERotation(const U8 te, const F32 r) } -LLViewerImage *LLViewerObject::getTEImage(const U8 face) const +LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const { // llassert(mTEImages); if (face < getNumTEs()) { - LLViewerImage* image = mTEImages[face]; + LLViewerTexture* image = mTEImages[face]; if (image) { return image; } else { - return (LLViewerImage*)((LLImageGL*)LLViewerImage::sDefaultImagep); + return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep); } } @@ -4104,7 +4117,7 @@ void LLViewerObject::setDebugText(const std::string &utf8text) updateText(); } -void LLViewerObject::setIcon(LLViewerImage* icon_image) +void LLViewerObject::setIcon(LLViewerTexture* icon_image) { if (!mIcon) { @@ -4194,14 +4207,14 @@ void LLViewerObject::setParticleSource(const LLPartSysData& particle_parameters, if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) { - LLViewerImage* image; + LLViewerTexture* image; if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) { - image = gImageList.getImageFromFile("pixiesmall.tga"); + image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.tga"); } else { - image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID); + image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID); } mPartSourcep->setImage(image); } @@ -4243,14 +4256,14 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own { if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) { - LLViewerImage* image; + LLViewerTexture* image; if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) { - image = gImageList.getImageFromFile("pixiesmall.j2c"); + image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); } else { - image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID); + image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID); } mPartSourcep->setImage(image); } @@ -4290,14 +4303,14 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_ { if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) { - LLViewerImage* image; + LLViewerTexture* image; if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) { - image = gImageList.getImageFromFile("pixiesmall.j2c"); + image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); } else { - image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID); + image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID); } mPartSourcep->setImage(image); } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 2b2c2d5a95..cda2c5114f 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -68,7 +68,7 @@ class LLPartSysData; class LLPrimitive; class LLPipeline; class LLTextureEntry; -class LLViewerImage; +class LLViewerTexture; class LLViewerInventoryItem; class LLViewerObject; class LLViewerPartSourceScript; @@ -312,8 +312,9 @@ public: /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags ); /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); /*virtual*/ BOOL setMaterial(const U8 material); - virtual void setTEImage(const U8 te, LLViewerImage *imagep); // Not derived from LLPrimitive - LLViewerImage *getTEImage(const U8 te) const; + virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive + void changeTEImage(const LLViewerTexture* old_image, LLViewerTexture* new_image) ; + LLViewerTexture *getTEImage(const U8 te) const; void fitFaceTexture(const U8 face); void sendTEUpdate() const; // Sends packed representation of all texture entry information @@ -354,7 +355,7 @@ public: void setCanSelect(BOOL canSelect); void setDebugText(const std::string &utf8text); - void setIcon(LLViewerImage* icon_image); + void setIcon(LLViewerTexture* icon_image); void clearIcon(); void markForUpdate(BOOL priority); @@ -527,7 +528,7 @@ public: // Last total CRC received from sim, used for caching U32 mTotalCRC; - LLPointer *mTEImages; + LLPointer *mTEImages; // Selection, picking and rendering variables U32 mGLName; // GL "name" used by selection code diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 8e9c798aca..8939faeb91 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -66,7 +66,7 @@ #include "lltoolpie.h" #include "llkeyboard.h" #include "u64.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "lldatapacker.h" #ifdef LL_STANDALONE #include @@ -558,7 +558,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) { num_updates = mObjects.count() - mCurLazyUpdateIndex; max_value = mObjects.count(); - gImageList.setUpdateStats(TRUE); + gTextureList.setUpdateStats(TRUE); } else { @@ -1020,16 +1020,16 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap) { - LLColor4 above_water_color = gSavedSkinSettings.getColor( "NetMapOtherOwnAboveWater" ); - LLColor4 below_water_color = gSavedSkinSettings.getColor( "NetMapOtherOwnBelowWater" ); + LLColor4 above_water_color = LLUIColorTable::instance().getColor( "NetMapOtherOwnAboveWater" ); + LLColor4 below_water_color = LLUIColorTable::instance().getColor( "NetMapOtherOwnBelowWater" ); LLColor4 you_own_above_water_color = - gSavedSkinSettings.getColor( "NetMapYouOwnAboveWater" ); + LLUIColorTable::instance().getColor( "NetMapYouOwnAboveWater" ); LLColor4 you_own_below_water_color = - gSavedSkinSettings.getColor( "NetMapYouOwnBelowWater" ); + LLUIColorTable::instance().getColor( "NetMapYouOwnBelowWater" ); LLColor4 group_own_above_water_color = - gSavedSkinSettings.getColor( "NetMapGroupOwnAboveWater" ); + LLUIColorTable::instance().getColor( "NetMapGroupOwnAboveWater" ); LLColor4 group_own_below_water_color = - gSavedSkinSettings.getColor( "NetMapGroupOwnBelowWater" ); + LLUIColorTable::instance().getColor( "NetMapGroupOwnBelowWater" ); for (S32 i = 0; i < mMapObjects.count(); i++) diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 08e03c97f2..26e21133ac 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -208,7 +208,7 @@ void LLViewerParcelMedia::play(LLParcel* parcel) if (!parcel) return; - if (!gSavedSettings.getBOOL("AudioStreamingVideo")) + if (!gSavedSettings.getBOOL("AudioSteamingMedia") || !gSavedSettings.getBOOL("AudioStreamingVideo")) return; std::string media_url = parcel->getMediaURL(); @@ -389,6 +389,8 @@ bool callback_play_media(const LLSD& notification, const LLSD& response, LLParce if (option == 0) { gSavedSettings.setBOOL("AudioStreamingVideo", TRUE); + if(!gSavedSettings.getBOOL("AudioSteamingMedia")) + gSavedSettings.setBOOL("AudioSteamingMedia", TRUE); LLViewerParcelMedia::play(parcel); } else diff --git a/indra/newview/llviewerparcelmediaautoplay.cpp b/indra/newview/llviewerparcelmediaautoplay.cpp index dbb9c32008..7ba2172c3f 100644 --- a/indra/newview/llviewerparcelmediaautoplay.cpp +++ b/indra/newview/llviewerparcelmediaautoplay.cpp @@ -39,7 +39,7 @@ #include "llviewerparcelmgr.h" #include "lluuid.h" #include "message.h" -#include "llviewerimagelist.h" // for texture stats +#include "llviewertexturelist.h" // for texture stats #include "llagent.h" const F32 AUTOPLAY_TIME = 5; // how many seconds before we autoplay @@ -113,13 +113,13 @@ BOOL LLViewerParcelMediaAutoPlay::tick() { if (this_media_texture_id.notNull()) // and if the media texture is good { - LLViewerImage *image = gImageList.getImage(this_media_texture_id, FALSE); + LLViewerMediaTexture *image = LLViewerTextureManager::getMediaTexture(this_media_texture_id, FALSE) ; F32 image_size = 0; if (image) { - image_size = image->mMaxVirtualSize; + image_size = image->getMaxVirtualSize() ; } if (gAgent.getVelocity().magVec() < AUTOPLAY_SPEED) // and if the agent is stopped (slow enough) diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 1b669dbaf6..ae3b50abe4 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -61,8 +61,8 @@ #include "llsdutil_math.h" #include "llstatusbar.h" #include "llui.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewermenu.h" #include "llviewerparcelmedia.h" #include "llviewerparceloverlay.h" @@ -81,8 +81,8 @@ U8* LLViewerParcelMgr::sPackedOverlay = NULL; LLUUID gCurrentMovieID = LLUUID::null; -LLPointer sBlockedImage; -LLPointer sPassImage; +LLPointer sBlockedImage; +LLPointer sPassImage; // Local functions void optionally_start_music(const std::string& music_url); @@ -144,8 +144,11 @@ LLViewerParcelMgr::LLViewerParcelMgr() mCollisionSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)]; resetSegments(mCollisionSegments); - mBlockedImage = gImageList.getImageFromFile("noentrylines.j2c"); - mPassImage = gImageList.getImageFromFile("noentrypasslines.j2c"); + // JC: Resolved a merge conflict here, eliminated + // mBlockedImage->setAddressMode(LLTexUnit::TAM_WRAP); + // because it is done in llviewertexturelist.cpp + mBlockedImage = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png"); + mPassImage = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png"); S32 overlay_size = mParcelsPerEdge * mParcelsPerEdge / PARCEL_OVERLAY_CHUNKS; sPackedOverlay = new U8[overlay_size]; @@ -763,13 +766,17 @@ BOOL LLViewerParcelMgr::canHearSound(const LLVector3d &pos_global) const BOOL LLViewerParcelMgr::inAgentParcel(const LLVector3d &pos_global) const { LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(pos_global); - if (region != gAgent.getRegion()) + LLViewerRegion* agent_region = gAgent.getRegion(); + if (!region || !agent_region) + return FALSE; + + if (region != agent_region) { // Can't be in the agent parcel if you're not in the same region. return FALSE; } - LLVector3 pos_region = gAgent.getRegion()->getPosRegionFromGlobal(pos_global); + LLVector3 pos_region = agent_region->getPosRegionFromGlobal(pos_global); S32 row = S32(pos_region.mV[VY] / PARCEL_GRID_STEP_METERS); S32 column = S32(pos_region.mV[VX] / PARCEL_GRID_STEP_METERS); @@ -1711,7 +1718,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use void optionally_start_music(const std::string& music_url) { - if (gSavedSettings.getBOOL("AudioStreamingMusic")) + if (gSavedSettings.getBOOL("AudioStreamingMusic") && gSavedSettings.getBOOL("AudioSteamingMedia")) { // Make the user click the start button on the overlay bar. JC // llinfos << "Starting parcel music " << music_url << llendl; @@ -2383,12 +2390,12 @@ void LLViewerParcelMgr::cleanupGlobals() LLParcelSelection::sNullSelection = NULL; } -LLViewerImage* LLViewerParcelMgr::getBlockedImage() const +LLViewerTexture* LLViewerParcelMgr::getBlockedImage() const { return sBlockedImage; } -LLViewerImage* LLViewerParcelMgr::getPassImage() const +LLViewerTexture* LLViewerParcelMgr::getPassImage() const { return sPassImage; } diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index dc6c2a6287..427ed4a6f2 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -46,7 +46,7 @@ class LLUUID; class LLMessageSystem; class LLParcel; -class LLViewerImage; +class LLViewerTexture; class LLViewerRegion; // Constants for sendLandOwner @@ -291,8 +291,8 @@ private: static bool callbackJoinLand(const LLSD& notification, const LLSD& response); //void finishClaim(BOOL user_to_user_sale, U32 join); - LLViewerImage* getBlockedImage() const; - LLViewerImage* getPassImage() const; + LLViewerTexture* getBlockedImage() const; + LLViewerTexture* getPassImage() const; private: BOOL mSelected; @@ -341,8 +341,8 @@ private: BOOL mRenderSelection; S32 mCollisionBanned; LLFrameTimer mCollisionTimer; - LLImageGL* mBlockedImage; - LLImageGL* mPassImage; + LLViewerTexture* mBlockedImage; + LLViewerTexture* mPassImage; // Media S32 mMediaParcelId; diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 5b60ed5a27..1a91240abb 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -43,13 +43,13 @@ #include "v2math.h" // newview includes -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llviewercontrol.h" #include "llsurface.h" #include "llviewerregion.h" #include "llagent.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llselectmgr.h" #include "llfloatertools.h" #include "llglheaders.h" @@ -69,10 +69,9 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_ { // Create a texture to hold color information. // 4 components - // Use mipmaps = FALSE, clamped, NEAREST filter, for sharp edges - mTexture = new LLImageGL(FALSE); + // Use mipmaps = FALSE, clamped, NEAREST filter, for sharp edges mImageRaw = new LLImageRaw(mParcelGridsPerEdge, mParcelGridsPerEdge, OVERLAY_IMG_COMPONENTS); - mTexture->createGLTexture(0, mImageRaw); + mTexture = LLViewerTextureManager::getLocalTexture(mImageRaw.get(), FALSE); gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->bind(mTexture); mTexture->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -206,12 +205,12 @@ void LLViewerParcelOverlay::updateOverlayTexture() { return; } - const LLColor4U avail = gSavedSkinSettings.getColor4("PropertyColorAvail"); - const LLColor4U owned = gSavedSkinSettings.getColor4("PropertyColorOther"); - const LLColor4U group = gSavedSkinSettings.getColor4("PropertyColorGroup"); - const LLColor4U self = gSavedSkinSettings.getColor4("PropertyColorSelf"); - const LLColor4U for_sale = gSavedSkinSettings.getColor4("PropertyColorForSale"); - const LLColor4U auction = gSavedSkinSettings.getColor4("PropertyColorAuction"); + const LLColor4U avail = LLUIColorTable::instance().getColor("PropertyColorAvail").get(); + const LLColor4U owned = LLUIColorTable::instance().getColor("PropertyColorOther").get(); + const LLColor4U group = LLUIColorTable::instance().getColor("PropertyColorGroup").get(); + const LLColor4U self = LLUIColorTable::instance().getColor("PropertyColorSelf").get(); + const LLColor4U for_sale = LLUIColorTable::instance().getColor("PropertyColorForSale").get(); + const LLColor4U auction = LLUIColorTable::instance().getColor("PropertyColorAuction").get(); // Create the base texture. U8 *raw = mImageRaw->getData(); @@ -314,11 +313,11 @@ void LLViewerParcelOverlay::updatePropertyLines() S32 row, col; - const LLColor4U self_coloru = gSavedSkinSettings.getColor4("PropertyColorSelf"); - const LLColor4U other_coloru = gSavedSkinSettings.getColor4("PropertyColorOther"); - const LLColor4U group_coloru = gSavedSkinSettings.getColor4("PropertyColorGroup"); - const LLColor4U for_sale_coloru = gSavedSkinSettings.getColor4("PropertyColorForSale"); - const LLColor4U auction_coloru = gSavedSkinSettings.getColor4("PropertyColorAuction"); + const LLColor4U self_coloru = LLUIColorTable::instance().getColor("PropertyColorSelf").get(); + const LLColor4U other_coloru = LLUIColorTable::instance().getColor("PropertyColorOther").get(); + const LLColor4U group_coloru = LLUIColorTable::instance().getColor("PropertyColorGroup").get(); + const LLColor4U for_sale_coloru = LLUIColorTable::instance().getColor("PropertyColorForSale").get(); + const LLColor4U auction_coloru = LLUIColorTable::instance().getColor("PropertyColorAuction").get(); // Build into dynamic arrays, then copy into static arrays. LLDynamicArray new_vertex_array; diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index 9bed1dde34..e673b811ed 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -39,7 +39,7 @@ #include "lldarray.h" #include "llframetimer.h" #include "lluuid.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLViewerRegion; class LLVector3; @@ -53,7 +53,7 @@ public: ~LLViewerParcelOverlay(); // ACCESS - LLImageGL* getTexture() const { return mTexture; } + LLViewerTexture* getTexture() const { return mTexture; } BOOL isOwned(const LLVector3& pos) const; BOOL isOwnedSelf(const LLVector3& pos) const; @@ -99,7 +99,7 @@ private: S32 mParcelGridsPerEdge; - LLPointer mTexture; + LLPointer mTexture; LLPointer mImageRaw; // Size: mParcelGridsPerEdge * mParcelGridsPerEdge diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index b74f9e9f2c..ec39819bc8 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -98,7 +98,7 @@ LLViewerPart::~LLViewerPart() --LLViewerPartSim::sParticleCount2 ; } -void LLViewerPart::init(LLPointer sourcep, LLViewerImage *imagep, LLVPCallback cb) +void LLViewerPart::init(LLPointer sourcep, LLViewerTexture *imagep, LLVPCallback cb) { LLMemType mt(LLMemType::MTYPE_PARTICLES); mPartID = LLViewerPart::sNextPartID; diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index 208675e7bf..8f1f72518a 100644 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -39,10 +39,10 @@ #include "llpartdata.h" #include "llviewerpartsource.h" -class LLViewerImage; +class LLViewerTexture; class LLViewerPart; class LLViewerRegion; -class LLViewerImage; +class LLViewerTexture; class LLVOPartGroup; typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt); @@ -60,7 +60,7 @@ public: public: LLViewerPart(); - void init(LLPointer sourcep, LLViewerImage *imagep, LLVPCallback cb); + void init(LLPointer sourcep, LLViewerTexture *imagep, LLVPCallback cb); U32 mPartID; // Particle ID used primarily for moving between groups @@ -72,7 +72,7 @@ public: // Current particle state (possibly used for rendering) - LLPointer mImagep; + LLPointer mImagep; LLVector3 mPosAgent; LLVector3 mVelocity; LLVector3 mAccel; diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index 38c75a84d1..a8cbcd86c6 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -39,7 +39,7 @@ #include "llagent.h" #include "lldrawable.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llvoavatar.h" @@ -78,7 +78,7 @@ void LLViewerPartSource::update(const F32 dt) LLUUID LLViewerPartSource::getImageUUID() const { - LLViewerImage* imagep = mImagep; + LLViewerTexture* imagep = mImagep; if(imagep) { return imagep->getID(); @@ -100,8 +100,8 @@ LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp) llassert(source_objp); mSourceObjectp = source_objp; mPosAgent = mSourceObjectp->getPositionAgent(); - mImagep = gImageList.getImageFromFile("pixiesmall.j2c"); - gGL.getTexUnit(0)->bind(mImagep.get()); + mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); + gGL.getTexUnit(0)->bind(mImagep); mImagep->setAddressMode(LLTexUnit::TAM_CLAMP); } @@ -491,7 +491,7 @@ LLPointer LLViewerPartSourceScript::createPSS(LLViewer } -void LLViewerPartSourceScript::setImage(LLViewerImage *imagep) +void LLViewerPartSourceScript::setImage(LLViewerTexture *imagep) { LLMemType mt(LLMemType::MTYPE_PARTICLES); mImagep = imagep; @@ -551,7 +551,7 @@ void LLViewerPartSourceSpiral::update(const F32 dt) LLMemType mt(LLMemType::MTYPE_PARTICLES); if (!mImagep) { - mImagep = gImageList.getImageFromFile("pixiesmall.j2c"); + mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); } const F32 RATE = 0.025f; @@ -720,7 +720,7 @@ void LLViewerPartSourceBeam::update(const F32 dt) if (!mImagep) { - mImagep = gImageList.getImageFromFile("pixiesmall.j2c"); + mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); } LLViewerPart* part = new LLViewerPart(); @@ -806,7 +806,7 @@ void LLViewerPartSourceChat::update(const F32 dt) LLMemType mt(LLMemType::MTYPE_PARTICLES); if (!mImagep) { - mImagep = gImageList.getImageFromFile("pixiesmall.j2c"); + mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); } diff --git a/indra/newview/llviewerpartsource.h b/indra/newview/llviewerpartsource.h index 31e671af3a..540e30eb19 100644 --- a/indra/newview/llviewerpartsource.h +++ b/indra/newview/llviewerpartsource.h @@ -45,7 +45,7 @@ // // -class LLViewerImage; +class LLViewerTexture; class LLViewerObject; class LLViewerPart; @@ -90,7 +90,7 @@ protected: F32 mLastUpdateTime; F32 mLastPartTime; LLUUID mOwnerUUID; - LLPointer mImagep; + LLPointer mImagep; // Particle information U32 mPartFlags; // Flags for the particle @@ -123,8 +123,8 @@ public: static LLPointer unpackPSS(LLViewerObject *source_objp, LLPointer pssp, LLDataPacker &dp); static LLPointer createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters); - LLViewerImage *getImage() const { return mImagep; } - void setImage(LLViewerImage *imagep); + LLViewerTexture *getImage() const { return mImagep; } + void setImage(LLViewerTexture *imagep); LLPartSysData mPartSysData; void setTargetObject(LLViewerObject *objp); diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index c79ded1dce..709fcdcf01 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -45,7 +45,7 @@ #include "pipeline.h" #include "lltexturefetch.h" #include "llviewerobjectlist.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "lltexlayer.h" #include "lltexlayerparams.h" #include "llsurface.h" @@ -424,7 +424,7 @@ void output_statistics(void*) { llinfos << "Number of orphans: " << gObjectList.getOrphanCount() << llendl; llinfos << "Number of dead objects: " << gObjectList.mNumDeadObjects << llendl; - llinfos << "Num images: " << gImageList.getNumImages() << llendl; + llinfos << "Num images: " << gTextureList.getNumImages() << llendl; llinfos << "Texture usage: " << LLImageGL::sGlobalTextureMemoryInBytes << llendl; llinfos << "Texture working set: " << LLImageGL::sBoundTextureMemoryInBytes << llendl; llinfos << "Raw usage: " << LLImageRaw::sGlobalRawMemory << llendl; @@ -567,7 +567,7 @@ void update_statistics(U32 frame_count) { gTotalWorldBytes += gVLManager.getTotalBytes(); gTotalObjectBytes += gObjectBits / 8; - gTotalTextureBytes += gImageList.mTextureBits / 8; + gTotalTextureBytes += gTextureList.mTextureBits / 8; // make sure we have a valid time delta for this frame if (gFrameIntervalSeconds > 0.f) @@ -619,7 +619,7 @@ void update_statistics(U32 frame_count) F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); LLViewerStats::getInstance()->mLayersKBitStat.addValue(layer_bits/1024.f); LLViewerStats::getInstance()->mObjectKBitStat.addValue(gObjectBits/1024.f); - LLViewerStats::getInstance()->mTextureKBitStat.addValue(gImageList.mTextureBits/1024.f); + LLViewerStats::getInstance()->mTextureKBitStat.addValue(gTextureList.mTextureBits/1024.f); LLViewerStats::getInstance()->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); LLViewerStats::getInstance()->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); @@ -633,7 +633,7 @@ void update_statistics(U32 frame_count) gDebugTimers[0].unpause(); } - LLViewerStats::getInstance()->mTexturePacketsStat.addValue(gImageList.mTexturePackets); + LLViewerStats::getInstance()->mTexturePacketsStat.addValue(gTextureList.mTexturePackets); { static F32 visible_avatar_frames = 0.f; @@ -654,8 +654,8 @@ void update_statistics(U32 frame_count) gObjectBits = 0; // gDecodedBits = 0; - gImageList.mTextureBits = 0; - gImageList.mTexturePackets = 0; + gTextureList.mTextureBits = 0; + gTextureList.mTexturePackets = 0; } diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index f4989ec4fe..afee30293a 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -39,32 +39,35 @@ #include "llinventory.h" #include "llinventorybridge.h" #include "llinventorymodel.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llviewertexteditor.h" #include "llfloaterchat.h" #include "llfloaterworldmap.h" #include "llnotify.h" +#include "llpanelplaces.h" #include "llpreview.h" #include "llpreviewtexture.h" #include "llpreviewnotecard.h" #include "llpreviewlandmark.h" #include "llscrollbar.h" +#include "llsidetray.h" #include "lltooldraganddrop.h" #include "lltrans.h" #include "llviewercontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llviewerinventory.h" #include "lluictrlfactory.h" #include "llnotecard.h" #include "llmemorystream.h" #include "llmenugl.h" +#include "llavataractions.h" #include "llappviewer.h" // for gPacificDaylightTime -static LLDefaultWidgetRegistry::Register r("text_editor"); +static LLDefaultChildRegistry::Register r("text_editor"); ///---------------------------------------------------------------------------- /// Class LLEmbeddedNotecardOpener @@ -372,47 +375,61 @@ void LLEmbeddedItems::bindEmbeddedChars( const LLFontGL* font ) const const char* img_name; switch( item->getType() ) { - case LLAssetType::AT_TEXTURE: - if(item->getInventoryType() == LLInventoryType::IT_SNAPSHOT) - { - img_name = "inv_item_snapshot.tga"; - } - else - { - img_name = "inv_item_texture.tga"; - } + case LLAssetType::AT_TEXTURE: + if(item->getInventoryType() == LLInventoryType::IT_SNAPSHOT) + { + img_name = "inv_item_snapshot.tga"; + } + else + { + img_name = "inv_item_texture.tga"; + } - break; - case LLAssetType::AT_SOUND: img_name = "inv_item_sound.tga"; break; - case LLAssetType::AT_LANDMARK: - if (item->getFlags() & LLInventoryItem::II_FLAGS_LANDMARK_VISITED) + break; + case LLAssetType::AT_SOUND: img_name = "inv_item_sound.tga"; break; + case LLAssetType::AT_LANDMARK: + if (item->getFlags() & LLInventoryItem::II_FLAGS_LANDMARK_VISITED) + { + img_name = "inv_item_landmark_visited.tga"; + } + else + { + img_name = "inv_item_landmark.tga"; + } + break; + case LLAssetType::AT_CALLINGCARD: { - img_name = "inv_item_landmark_visited.tga"; + BOOL online; + online = LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID()); + if (online) + { + img_name = "inv_item_callingcard_online.tga"; break; + } + else + { + img_name = "inv_item_callingcard_offline.tga"; break; + } + break; } - else - { - img_name = "inv_item_landmark.tga"; - } - break; - case LLAssetType::AT_CLOTHING: img_name = "inv_item_clothing.tga"; break; - case LLAssetType::AT_OBJECT: - if (item->getFlags() & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS) - { - img_name = "inv_item_object_multi.tga"; - } - else - { - img_name = "inv_item_object.tga"; - } - break; - case LLAssetType::AT_NOTECARD: img_name = "inv_item_notecard.tga"; break; - case LLAssetType::AT_LSL_TEXT: img_name = "inv_item_script.tga"; break; - case LLAssetType::AT_BODYPART: img_name = "inv_item_skin.tga"; break; - case LLAssetType::AT_ANIMATION: img_name = "inv_item_animation.tga";break; - case LLAssetType::AT_GESTURE: img_name = "inv_item_gesture.tga"; break; - //TODO need img_name - case LLAssetType::AT_FAVORITE: img_name = "inv_item_landmark.tga"; break; - default: llassert(0); continue; + case LLAssetType::AT_CLOTHING: img_name = "inv_item_clothing.tga"; break; + case LLAssetType::AT_OBJECT: + if (item->getFlags() & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS) + { + img_name = "inv_item_object_multi.tga"; + } + else + { + img_name = "inv_item_object.tga"; + } + break; + case LLAssetType::AT_NOTECARD: img_name = "inv_item_notecard.tga"; break; + case LLAssetType::AT_LSL_TEXT: img_name = "inv_item_script.tga"; break; + case LLAssetType::AT_BODYPART: img_name = "inv_item_skin.tga"; break; + case LLAssetType::AT_ANIMATION: img_name = "inv_item_animation.tga";break; + case LLAssetType::AT_GESTURE: img_name = "inv_item_gesture.tga"; break; + //TODO need img_name + case LLAssetType::AT_FAVORITE: img_name = "inv_item_landmark.tga"; break; + default: llassert(0); continue; } LLUIImagePtr image = LLUI::getUIImage(img_name); @@ -1019,8 +1036,6 @@ BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) } -// Allow calling cards to be dropped onto text fields. Append the name and -// a carriage return. // virtual BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, @@ -1043,33 +1058,17 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, { switch( cargo_type ) { - case DAD_CALLINGCARD: - if(acceptsCallingCardNames()) - { - if (drop) - { - LLInventoryItem *item = (LLInventoryItem *)cargo_data; - std::string name = item->getName(); - appendText(name, true, true); - } - *accept = ACCEPT_YES_COPY_SINGLE; - } - else - { - *accept = ACCEPT_NO; - } - break; - - case DAD_TEXTURE: - case DAD_SOUND: - case DAD_LANDMARK: - case DAD_SCRIPT: - case DAD_CLOTHING: - case DAD_OBJECT: - case DAD_NOTECARD: - case DAD_BODYPART: - case DAD_ANIMATION: - case DAD_GESTURE: + case DAD_CALLINGCARD: + case DAD_TEXTURE: + case DAD_SOUND: + case DAD_LANDMARK: + case DAD_SCRIPT: + case DAD_CLOTHING: + case DAD_OBJECT: + case DAD_NOTECARD: + case DAD_BODYPART: + case DAD_ANIMATION: + case DAD_GESTURE: { LLInventoryItem *item = (LLInventoryItem *)cargo_data; if( item && allowsEmbeddedItems() ) @@ -1101,8 +1100,8 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, { // *TODO: Translate tooltip_msg.assign("Only items with unrestricted\n" - "'next owner' permissions \n" - "can be attached to notecards."); + "'next owner' permissions \n" + "can be attached to notecards."); } } } @@ -1113,9 +1112,9 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, break; } - default: - *accept = ACCEPT_NO; - break; + default: + *accept = ACCEPT_NO; + break; } } else @@ -1301,32 +1300,36 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, llwchar wc) switch( item->getType() ) { - case LLAssetType::AT_TEXTURE: - openEmbeddedTexture( item, wc ); - return TRUE; + case LLAssetType::AT_TEXTURE: + openEmbeddedTexture( item, wc ); + return TRUE; - case LLAssetType::AT_SOUND: - openEmbeddedSound( item, wc ); - return TRUE; + case LLAssetType::AT_SOUND: + openEmbeddedSound( item, wc ); + return TRUE; - case LLAssetType::AT_NOTECARD: - openEmbeddedNotecard( item, wc ); - return TRUE; + case LLAssetType::AT_NOTECARD: + openEmbeddedNotecard( item, wc ); + return TRUE; - case LLAssetType::AT_LANDMARK: - openEmbeddedLandmark( item, wc ); - return TRUE; + case LLAssetType::AT_LANDMARK: + openEmbeddedLandmark( item, wc ); + return TRUE; - case LLAssetType::AT_LSL_TEXT: - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_OBJECT: - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_ANIMATION: - case LLAssetType::AT_GESTURE: - showCopyToInvDialog( item, wc ); - return TRUE; - default: - return FALSE; + case LLAssetType::AT_CALLINGCARD: + openEmbeddedCallingcard( item, wc ); + return TRUE; + + case LLAssetType::AT_LSL_TEXT: + case LLAssetType::AT_CLOTHING: + case LLAssetType::AT_OBJECT: + case LLAssetType::AT_BODYPART: + case LLAssetType::AT_ANIMATION: + case LLAssetType::AT_GESTURE: + showCopyToInvDialog( item, wc ); + return TRUE; + default: + return FALSE; } } @@ -1364,11 +1367,22 @@ void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item, llwchar wc { if (!item) return; - LLPreviewLandmark* preview = LLFloaterReg::showTypedInstance("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES); - if (preview) + + LLSD key; + key["type"] = "landmark"; + key["id"] = item->getUUID(); + + LLPanelPlaces *panel = dynamic_cast(LLSideTray::getInstance()->showPanel("panel_places", key)); + if (panel) { - preview->setItem( item ); + panel->setItem(item); } + +// LLPreviewLandmark* preview = LLFloaterReg::showTypedInstance("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES); +// if (preview) +// { +// preview->setItem( item ); +// } } void LLViewerTextEditor::openEmbeddedNotecard( LLInventoryItem* item, llwchar wc ) @@ -1376,6 +1390,14 @@ void LLViewerTextEditor::openEmbeddedNotecard( LLInventoryItem* item, llwchar wc copyInventory(item, gInventoryCallbacks.registerCB(mInventoryCallback)); } +void LLViewerTextEditor::openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc ) +{ + if(item && !item->getCreatorUUID().isNull()) + { + LLAvatarActions::showProfile(item->getCreatorUUID()); + } +} + void LLViewerTextEditor::showUnsavedAlertDialog( LLInventoryItem* item ) { LLSD payload; diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h index bc373c858a..1a69c6869d 100644 --- a/indra/newview/llviewertexteditor.h +++ b/indra/newview/llviewertexteditor.h @@ -120,6 +120,7 @@ private: void openEmbeddedSound( LLInventoryItem* item, llwchar wc ); void openEmbeddedLandmark( LLInventoryItem* item, llwchar wc ); void openEmbeddedNotecard( LLInventoryItem* item, llwchar wc); + void openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc); void showCopyToInvDialog( LLInventoryItem* item, llwchar wc ); void showUnsavedAlertDialog( LLInventoryItem* item ); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp new file mode 100644 index 0000000000..6ea1522b47 --- /dev/null +++ b/indra/newview/llviewertexture.cpp @@ -0,0 +1,2386 @@ +/** + * @file llviewertexture.cpp + * @brief Object which handles a received image (and associated texture(s)) + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llviewertexture.h" + +// Library includes +#include "imageids.h" +#include "llmath.h" +#include "llerror.h" +#include "llgl.h" +#include "llglheaders.h" +#include "llhost.h" +#include "llimage.h" +#include "llimagebmp.h" +#include "llimagej2c.h" +#include "llimagetga.h" +#include "llmemtype.h" +#include "llstl.h" +#include "llvfile.h" +#include "llvfs.h" +#include "message.h" +#include "lltimer.h" + +// viewer includes +#include "llimagegl.h" +#include "lldrawpool.h" +#include "lltexturefetch.h" +#include "llviewertexturelist.h" +#include "llviewercontrol.h" +#include "pipeline.h" +#include "llappviewer.h" +/////////////////////////////////////////////////////////////////////////////// + +// statics +LLPointer LLViewerTexture::sNullImagep = NULL; +LLPointer LLViewerFetchedTexture::sMissingAssetImagep = NULL; +LLPointer LLViewerFetchedTexture::sWhiteImagep = NULL; +LLPointer LLViewerFetchedTexture::sDefaultImagep = NULL; +LLPointer LLViewerFetchedTexture::sSmokeImagep = NULL; +LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap ; +LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ; + +S32 LLViewerTexture::sImageCount = 0; +S32 LLViewerTexture::sRawCount = 0; +S32 LLViewerTexture::sAuxCount = 0; +LLTimer LLViewerTexture::sEvaluationTimer; +F32 LLViewerTexture::sDesiredDiscardBias = 0.f; +F32 LLViewerTexture::sDesiredDiscardScale = 1.1f; +S32 LLViewerTexture::sBoundTextureMemoryInBytes = 0; +S32 LLViewerTexture::sTotalTextureMemoryInBytes = 0; +S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0; +S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0; +S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ; +BOOL LLViewerTexture::sDontLoadVolumeTextures = FALSE; + +const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by +const F32 desired_discard_bias_max = 1.5f; // max number of levels to reduce image quality by + +//---------------------------------------------------------------------------------------------- +//namespace: LLViewerTextureAccess +//---------------------------------------------------------------------------------------------- +LLViewerMediaTexture* LLViewerTextureManager::createMediaTexture(const LLUUID &media_id, BOOL usemipmaps, LLImageGL* gl_image) +{ + return new LLViewerMediaTexture(media_id, usemipmaps, gl_image) ; +} + +LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id) +{ + LLViewerTexture* tex ; + //search fetched texture list + tex = gTextureList.findImage(id) ; + + //search media texture list + if(!tex) + { + tex = LLViewerTextureManager::findMediaTexture(id) ; + } + return tex ; +} + +LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id) +{ + LLViewerMediaTexture::media_map_t::iterator iter = LLViewerMediaTexture::sMediaMap.find(media_id); + if(iter == LLViewerMediaTexture::sMediaMap.end()) + return NULL; + + ((LLViewerMediaTexture*)(iter->second))->getLastReferencedTimer()->reset() ; + return iter->second; +} + +LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image) +{ + LLViewerMediaTexture* tex = LLViewerTextureManager::findMediaTexture(id) ; + if(!tex) + { + tex = LLViewerTextureManager::createMediaTexture(id, usemipmaps, gl_image) ; + } + + LLViewerTexture* old_tex = tex->getOldTexture() ; + if(!old_tex) + { + //if there is a fetched texture with the same id, replace it by this media texture + old_tex = gTextureList.findImage(id) ; + if(old_tex) + { + tex->setOldTexture(old_tex) ; + } + } + + if (gSavedSettings.getBOOL("ParcelMediaAutoPlayEnable") && gSavedSettings.getBOOL("AudioStreamingVideo")) + { + if(!tex->isPlaying()) + { + if(old_tex) + { + old_tex->switchToTexture(tex) ; + } + tex->setPlaying(TRUE) ; + } + } + tex->getLastReferencedTimer()->reset() ; + + return tex ; +} + +LLViewerFetchedTexture* LLViewerTextureManager::staticCastToFetchedTexture(LLViewerTexture* tex, BOOL report_error) +{ + if(!tex) + { + return NULL ; + } + + S8 type = tex->getType() ; + if(type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE) + { + return static_cast(tex) ; + } + + if(report_error) + { + llerrs << "not a fetched texture type: " << type << llendl ; + } + + return NULL ; +} + +LLPointer LLViewerTextureManager::getLocalTexture(BOOL usemipmaps, BOOL generate_gl_tex) +{ + LLPointer tex = new LLViewerTexture(usemipmaps) ; + if(generate_gl_tex) + { + tex->generateGLTexture() ; + } + return tex ; +} +LLPointer LLViewerTextureManager::getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex) +{ + LLPointer tex = new LLViewerTexture(id, usemipmaps) ; + if(generate_gl_tex) + { + tex->generateGLTexture() ; + } + return tex ; +} +LLPointer LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) +{ + LLPointer tex = new LLViewerTexture(raw, usemipmaps) ; + return tex ; +} +LLPointer LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex) +{ + LLPointer tex = new LLViewerTexture(width, height, components, usemipmaps) ; + if(generate_gl_tex) + { + tex->generateGLTexture() ; + } + return tex ; +} + +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture( + const LLUUID &image_id, + BOOL usemipmaps, + BOOL level_immediate, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + LLHost request_from_host) +{ + return gTextureList.getImage(image_id, usemipmaps, level_immediate, texture_type, internal_format, primary_format, request_from_host) ; +} + +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile( + const std::string& filename, + BOOL usemipmaps, + BOOL level_immediate, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + const LLUUID& force_id) +{ + return gTextureList.getImageFromFile(filename, usemipmaps, level_immediate, texture_type, internal_format, primary_format, force_id) ; +} + +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, LLHost host) +{ + return gTextureList.getImageFromHost(image_id, host) ; +} + +void LLViewerTextureManager::init() +{ + LLPointer raw = new LLImageRaw(1,1,3); + raw->clear(0x77, 0x77, 0x77, 0xFF); + LLViewerTexture::sNullImagep = LLViewerTextureManager::getLocalTexture(raw.get(), TRUE) ; + +#if 1 + LLPointer imagep = new LLViewerFetchedTexture(IMG_DEFAULT, TRUE); + LLViewerFetchedTexture::sDefaultImagep = imagep; + + const S32 dim = 128; + LLPointer image_raw = new LLImageRaw(dim,dim,3); + U8* data = image_raw->getData(); + for (S32 i = 0; i=(dim-border) || j>=(dim-border)) + { + *data++ = 0xff; + *data++ = 0xff; + *data++ = 0xff; + } + else +#endif + { + *data++ = 0x7f; + *data++ = 0x7f; + *data++ = 0x7f; + } + } + } + imagep->createGLTexture(0, image_raw); + image_raw = NULL; + gTextureList.addImage(imagep); + LLViewerFetchedTexture::sDefaultImagep->dontDiscard(); +#else + LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE); +#endif + + LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, TRUE); + LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ; + + LLViewerTexture::initClass() ; + + if(LLFastTimer::sMetricLog) + { + LLViewerTextureManager::sTesterp = new LLTexturePipelineTester() ; + } +} + +void LLViewerTextureManager::cleanup() +{ + stop_glerror(); + + LLImageGL::sDefaultGLTexture = NULL ; + LLViewerTexture::sNullImagep = NULL; + LLViewerFetchedTexture::sDefaultImagep = NULL; + LLViewerFetchedTexture::sSmokeImagep = NULL; + LLViewerFetchedTexture::sMissingAssetImagep = NULL; + LLViewerFetchedTexture::sWhiteImagep = NULL; + + LLViewerMediaTexture::sMediaMap.clear() ; +} + +//---------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------- +//start of LLViewerTexture +//---------------------------------------------------------------------------------------------- +// static +void LLViewerTexture::initClass() +{ + LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ; +} + +// static +void LLViewerTexture::cleanupClass() +{ +} + +// tuning params +const F32 discard_bias_delta = .05f; +const F32 discard_delta_time = 0.5f; +const S32 min_non_tex_system_mem = (128<<20); // 128 MB +// non-const (used externally +F32 texmem_lower_bound_scale = 0.85f; +F32 texmem_middle_bound_scale = 0.925f; + +//static +void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity) +{ + if(LLViewerTextureManager::sTesterp) + { + LLViewerTextureManager::sTesterp->update() ; + } + LLViewerMediaTexture::updateClass() ; + + sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes + sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes + sMaxBoundTextureMemInMegaBytes = gTextureList.getMaxResidentTexMem();//in MB + sMaxTotalTextureMemInMegaBytes = gTextureList.getMaxTotalTextureMem() ;//in MB + sMaxDesiredTextureMemInBytes = MEGA_BYTES_TO_BYTES(sMaxTotalTextureMemInMegaBytes) ; //in Bytes, by default and when total used texture memory is small. + + if (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) >= sMaxBoundTextureMemInMegaBytes || + BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) >= sMaxTotalTextureMemInMegaBytes) + { + //when texture memory overflows, lower down the threashold to release the textures more aggressively. + sMaxDesiredTextureMemInBytes = llmin((S32)(sMaxDesiredTextureMemInBytes * 0.75f) , MEGA_BYTES_TO_BYTES(MAX_VIDEO_RAM_IN_MEGA_BYTES)) ;//512 MB + + // If we are using more texture memory than we should, + // scale up the desired discard level + if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time) + { + sDesiredDiscardBias += discard_bias_delta; + sEvaluationTimer.reset(); + } + } + else if (sDesiredDiscardBias > 0.0f && + BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < sMaxBoundTextureMemInMegaBytes * texmem_lower_bound_scale && + BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < sMaxTotalTextureMemInMegaBytes * texmem_lower_bound_scale) + { + // If we are using less texture memory than we should, + // scale down the desired discard level + if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time) + { + sDesiredDiscardBias -= discard_bias_delta; + sEvaluationTimer.reset(); + } + } + sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max); +} + +//end of static functions +//------------------------------------------------------------------------------------------- +const U32 LLViewerTexture::sCurrentFileVersion = 1; + +LLViewerTexture::LLViewerTexture(BOOL usemipmaps) +{ + init(true); + mUseMipMaps = usemipmaps ; + + mID.generate(); + sImageCount++; +} + +LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps) + : mID(id) +{ + init(true); + mUseMipMaps = usemipmaps ; + + sImageCount++; +} + +LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) +{ + init(true); + + mFullWidth = width ; + mFullHeight = height ; + mUseMipMaps = usemipmaps ; + mComponents = components ; + + mID.generate(); + sImageCount++; +} + +LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) +{ + init(true); + mUseMipMaps = usemipmaps ; + mGLTexturep = new LLImageGL(raw, usemipmaps) ; + + // Create an empty image of the specified size and width + mID.generate(); + sImageCount++; +} + +LLViewerTexture::~LLViewerTexture() +{ + sImageCount--; +} + +void LLViewerTexture::init(bool firstinit) +{ + mBoostLevel = LLViewerTexture::BOOST_NONE; + + mFullWidth = 0; + mFullHeight = 0; + mUseMipMaps = FALSE ; + mComponents = 0 ; + + mTextureState = NO_DELETE ; + mDontDiscard = FALSE; + mMaxVirtualSize = 0.f; +} + +//virtual +S8 LLViewerTexture::getType() const +{ + return LLViewerTexture::LOCAL_TEXTURE ; +} + +void LLViewerTexture::cleanup() +{ + mFaceList.clear() ; + + if(mGLTexturep) + { + mGLTexturep->cleanup(); + } +} + +// virtual +void LLViewerTexture::dump() +{ + if(mGLTexturep) + { + mGLTexturep->dump(); + } + + llinfos << "LLViewerTexture" + << " mID " << mID + << llendl; +} + +void LLViewerTexture::setBoostLevel(S32 level) +{ + if(mBoostLevel != level) + { + mBoostLevel = level ; + if(mBoostLevel != LLViewerTexture::BOOST_NONE) + { + setNoDelete() ; + } + } +} + + +bool LLViewerTexture::bindDefaultImage(S32 stage) const +{ + if (stage < 0) return false; + + bool res = true; + if (LLViewerFetchedTexture::sDefaultImagep.notNull() && (this != LLViewerFetchedTexture::sDefaultImagep.get())) + { + // use default if we've got it + res = gGL.getTexUnit(stage)->bind(LLViewerFetchedTexture::sDefaultImagep); + } + if (!res && LLViewerTexture::sNullImagep.notNull() && (this != LLViewerTexture::sNullImagep)) + { + res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sNullImagep) ; + } + if (!res) + { + llwarns << "LLViewerTexture::bindDefaultImage failed." << llendl; + } + stop_glerror(); + if(LLViewerTextureManager::sTesterp) + { + LLViewerTextureManager::sTesterp->updateGrayTextureBinding() ; + } + return res; +} + +//virtual +BOOL LLViewerTexture::isMissingAsset()const +{ + return FALSE; +} + +//virtual +void LLViewerTexture::forceImmediateUpdate() +{ +} + +void LLViewerTexture::addTextureStats(F32 virtual_size) const +{ + if (virtual_size > mMaxVirtualSize) + { + mMaxVirtualSize = virtual_size; + } +} + +void LLViewerTexture::resetTextureStats(BOOL zero) +{ + if (zero) + { + mMaxVirtualSize = 0.0f; + } + else + { + mMaxVirtualSize -= mMaxVirtualSize * .10f; // decay by 5%/update + } +} + +void LLViewerTexture::addFace(LLFace* facep) +{ + mFaceList.push_back(facep) ; +} +void LLViewerTexture::removeFace(LLFace* facep) +{ + mFaceList.remove(facep) ; +} + +void LLViewerTexture::switchToTexture(LLViewerTexture* new_texture) +{ + if(this == new_texture) + { + return ; + } + + new_texture->addTextureStats(getMaxVirtualSize()) ; + + for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ) + { + LLFace* facep = *iter++ ; + facep->setTexture(new_texture) ; + facep->getViewerObject()->changeTEImage(this, new_texture) ; + gPipeline.markTextured(facep->getDrawable()); + } +} + +void LLViewerTexture::forceActive() +{ + mTextureState = ACTIVE ; +} + +void LLViewerTexture::setActive() +{ + if(mTextureState != NO_DELETE) + { + mTextureState = ACTIVE ; + } +} + +//set the texture to stay in memory +void LLViewerTexture::setNoDelete() +{ + mTextureState = NO_DELETE ; +} + +void LLViewerTexture::generateGLTexture() +{ + if(mGLTexturep.isNull()) + { + mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ; + } +} + +LLImageGL* LLViewerTexture::getGLTexture() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep ; +} + +BOOL LLViewerTexture::createGLTexture() +{ + if(mGLTexturep.isNull()) + { + generateGLTexture() ; + } + + return mGLTexturep->createGLTexture() ; +} + +BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename) +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->createGLTexture(discard_level, imageraw, usename) ; +} + +void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) +{ + llassert_always(mGLTexturep.notNull()) ; + + mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ; +} +void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode) +{ + llassert_always(mGLTexturep.notNull()) ; + mGLTexturep->setAddressMode(mode) ; +} +void LLViewerTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option) +{ + llassert_always(mGLTexturep.notNull()) ; + mGLTexturep->setFilteringOption(option) ; +} + +//virtual +S32 LLViewerTexture::getWidth(S32 discard_level) const +{ + llassert_always(mGLTexturep.notNull()) ; + return mGLTexturep->getWidth(discard_level) ; +} + +//virtual +S32 LLViewerTexture::getHeight(S32 discard_level) const +{ + llassert_always(mGLTexturep.notNull()) ; + return mGLTexturep->getHeight(discard_level) ; +} + +S32 LLViewerTexture::getMaxDiscardLevel() const +{ + llassert_always(mGLTexturep.notNull()) ; + return mGLTexturep->getMaxDiscardLevel() ; +} +S32 LLViewerTexture::getDiscardLevel() const +{ + llassert_always(mGLTexturep.notNull()) ; + return mGLTexturep->getDiscardLevel() ; +} +S8 LLViewerTexture::getComponents() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getComponents() ; +} + +LLGLuint LLViewerTexture::getTexName() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getTexName() ; +} + +BOOL LLViewerTexture::hasValidGLTexture() const +{ + if(mGLTexturep.notNull()) + { + return mGLTexturep->getHasGLTexture() ; + } + return FALSE ; +} + +BOOL LLViewerTexture::hasGLTexture() const +{ + return mGLTexturep.notNull() ; +} + +BOOL LLViewerTexture::getBoundRecently() const +{ + if(mGLTexturep.notNull()) + { + return mGLTexturep->getBoundRecently() ; + } + return FALSE ; +} + +LLTexUnit::eTextureType LLViewerTexture::getTarget(void) const +{ + llassert_always(mGLTexturep.notNull()) ; + return mGLTexturep->getTarget() ; +} + +BOOL LLViewerTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height) +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ; +} + +BOOL LLViewerTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ; +} + +void LLViewerTexture::setGLTextureCreated (bool initialized) +{ + llassert_always(mGLTexturep.notNull()) ; + + mGLTexturep->setGLTextureCreated (initialized) ; +} + +LLTexUnit::eTextureAddressMode LLViewerTexture::getAddressMode(void) const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getAddressMode() ; +} + +S32 LLViewerTexture::getTextureMemory() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->mTextureMemory ; +} + +LLGLenum LLViewerTexture::getPrimaryFormat() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getPrimaryFormat() ; +} + +BOOL LLViewerTexture::getIsAlphaMask() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getIsAlphaMask() ; +} + +BOOL LLViewerTexture::getMask(const LLVector2 &tc) +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getMask(tc) ; +} + +F32 LLViewerTexture::getTimePassedSinceLastBound() +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getTimePassedSinceLastBound() ; +} +BOOL LLViewerTexture::getMissed() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getMissed() ; +} + +BOOL LLViewerTexture::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->isValidForSculpt(discard_level, image_width, image_height, ncomponents) ; +} + +BOOL LLViewerTexture::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->readBackRaw(discard_level, imageraw, compressed_ok) ; +} + +void LLViewerTexture::destroyGLTexture() +{ + if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture()) + { + mGLTexturep->destroyGLTexture() ; + mTextureState = DELETED ; + } +} + +//virtual +void LLViewerTexture::updateBindStatsForTester() +{ + if(LLViewerTextureManager::sTesterp) + { + LLViewerTextureManager::sTesterp->updateTextureBindingStats(this) ; + } +} +//---------------------------------------------------------------------------------------------- +//end of LLViewerTexture +//---------------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------------- +//start of LLViewerFetchedTexture +//---------------------------------------------------------------------------------------------- + +//static +F32 LLViewerFetchedTexture::maxDecodePriority() +{ + return 2000000.f; +} + +LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, BOOL usemipmaps) + : LLViewerTexture(id, usemipmaps) +{ + init(TRUE) ; + generateGLTexture() ; +} + +LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps) + : LLViewerTexture(raw, usemipmaps) +{ + init(TRUE) ; +} + +LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps) + : LLViewerTexture(id, usemipmaps), + mLocalFileName(full_path) +{ + init(TRUE) ; + generateGLTexture() ; +} + +void LLViewerFetchedTexture::init(bool firstinit) +{ + mOrigWidth = 0; + mOrigHeight = 0; + mNeedsAux = FALSE; + mRequestedDiscardLevel = -1; + mRequestedDownloadPriority = 0.f; + mFullyLoaded = FALSE; + mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1; + mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1; + + mDecodingAux = FALSE; + + mKnownDrawWidth = 0; + mKnownDrawHeight = 0; + + if (firstinit) + { + mDecodePriority = 0.f; + mInImageList = 0; + } + + // Only set mIsMissingAsset true when we know for certain that the database + // does not contain this image. + mIsMissingAsset = FALSE; + + mNeedsCreateTexture = FALSE; + + mIsRawImageValid = FALSE; + mRawDiscardLevel = INVALID_DISCARD_LEVEL; + mMinDiscardLevel = 0; + + mHasFetcher = FALSE; + mIsFetching = FALSE; + mFetchState = 0; + mFetchPriority = 0; + mDownloadProgress = 0.f; + mFetchDeltaTime = 999999.f; + mDecodeFrame = 0; + mVisibleFrame = 0; + mForSculpt = FALSE ; + mIsFetched = FALSE ; +} + +LLViewerFetchedTexture::~LLViewerFetchedTexture() +{ + //*NOTE getTextureFetch can return NULL when Viewer is shutting down. + // This is due to LLWearableList is singleton and is destroyed after + // LLAppViewer::cleanup() was called. (see ticket EXT-177) + if (mHasFetcher && LLAppViewer::getTextureFetch()) + { + LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); + } + cleanup(); +} + +//virtual +S8 LLViewerFetchedTexture::getType() const +{ + return LLViewerTexture::FETCHED_TEXTURE ; +} + +void LLViewerFetchedTexture::cleanup() +{ + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + LLLoadedCallbackEntry *entryp = *iter++; + // We never finished loading the image. Indicate failure. + // Note: this allows mLoadedCallbackUserData to be cleaned up. + entryp->mCallback( FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData ); + delete entryp; + } + mLoadedCallbackList.clear(); + mNeedsAux = FALSE; + + // Clean up image data + destroyRawImage(); +} + +void LLViewerFetchedTexture::setForSculpt() +{ + mForSculpt = TRUE ; +} + +BOOL LLViewerFetchedTexture::isDeleted() +{ + return mTextureState == DELETED ; +} + +BOOL LLViewerFetchedTexture::isInactive() +{ + return mTextureState == INACTIVE ; +} + +BOOL LLViewerFetchedTexture::isDeletionCandidate() +{ + return mTextureState == DELETION_CANDIDATE ; +} + +void LLViewerFetchedTexture::setDeletionCandidate() +{ + if(mGLTexturep.notNull() && mGLTexturep->getTexName() && (mTextureState == INACTIVE)) + { + mTextureState = DELETION_CANDIDATE ; + } +} + +//set the texture inactive +void LLViewerFetchedTexture::setInactive() +{ + if(mTextureState == ACTIVE && mGLTexturep.notNull() && mGLTexturep->getTexName() && !mGLTexturep->getBoundRecently()) + { + mTextureState = INACTIVE ; + } +} + +// virtual +void LLViewerFetchedTexture::dump() +{ + LLViewerTexture::dump(); + + llinfos << "LLViewerFetchedTexture" + << " mIsMissingAsset " << (S32)mIsMissingAsset + << " mFullWidth " << mFullWidth + << " mFullHeight " << mFullHeight + << " mOrigWidth" << mOrigWidth + << " mOrigHeight" << mOrigHeight + << llendl; +} + +/////////////////////////////////////////////////////////////////////////////// +// ONLY called from LLViewerFetchedTextureList +void LLViewerFetchedTexture::destroyTexture() +{ + if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory. + { + return ; + } + if (mNeedsCreateTexture)//return if in the process of generating a new texture. + { + return ; + } + + destroyGLTexture() ; + mFullyLoaded = FALSE ; +} + +// ONLY called from LLViewerTextureList +BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) +{ + if (!mNeedsCreateTexture) + { + destroyRawImage(); + return FALSE; + } + mNeedsCreateTexture = FALSE; + if (mRawImage.isNull()) + { + llerrs << "LLViewerTexture trying to create texture with no Raw Image" << llendl; + } +// llinfos << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", +// mRawDiscardLevel, +// mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize()) +// << mID.getString() << llendl; + BOOL res = TRUE; + if (!gNoRender) + { + // store original size only for locally-sourced images + if (!mLocalFileName.empty()) + { + mOrigWidth = mRawImage->getWidth(); + mOrigHeight = mRawImage->getHeight(); + + // leave black border, do not scale image content + mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE); + + mFullWidth = mRawImage->getWidth(); + mFullHeight = mRawImage->getHeight(); + } + else + { + mOrigWidth = mFullWidth; + mOrigHeight = mFullHeight; + } + + bool size_okay = true; + + U32 raw_width = mRawImage->getWidth() << mRawDiscardLevel; + U32 raw_height = mRawImage->getHeight() << mRawDiscardLevel; + if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE ) + { + llinfos << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << llendl; + size_okay = false; + } + + if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) + { + // A non power-of-two image was uploaded (through a non standard client) + llinfos << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << llendl; + size_okay = false; + } + + if( !size_okay ) + { + // An inappropriately-sized image was uploaded (through a non standard client) + // We treat these images as missing assets which causes them to + // be renderd as 'missing image' and to stop requesting data + setIsMissingAsset(); + destroyRawImage(); + return FALSE; + } + + res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename); + setActive() ; + } + + // + // Iterate through the list of image loading callbacks to see + // what sort of data they need. + // + // *TODO: Fix image callback code + BOOL imageraw_callbacks = FALSE; + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + LLLoadedCallbackEntry *entryp = *iter++; + if (entryp->mNeedsImageRaw) + { + imageraw_callbacks = TRUE; + break; + } + } + + if (!imageraw_callbacks) + { + mNeedsAux = FALSE; + destroyRawImage(); + } + return res; +} + +// Call with 0,0 to turn this feature off. +void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height) +{ + mKnownDrawWidth = width; + mKnownDrawHeight = height; + addTextureStats((F32)(width * height)); +} + +//virtual +void LLViewerFetchedTexture::processTextureStats() +{ + if(mFullyLoaded)//already loaded + { + return ; + } + + if(!mFullWidth || !mFullHeight) + { + mDesiredDiscardLevel = getMaxDiscardLevel() ; + } + else + { + mDesiredDiscardLevel = 0; + if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) + { + mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 + } + + if(getDiscardLevel() >= 0 && (getDiscardLevel() <= mDesiredDiscardLevel)) + { + mFullyLoaded = TRUE ; + } + } +} + +//texture does not have any data, so we don't know the size of the image, treat it like 32 * 32. +F32 LLViewerFetchedTexture::calcDecodePriorityForUnknownTexture(F32 pixel_priority) +{ + static const F64 log_2 = log(2.0); + + F32 desired = (F32)(log(32.0/pixel_priority) / log_2); + S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired + 1; + ddiscard = llclamp(ddiscard, 1, 9); + + return ddiscard*100000.f; +} + +F32 LLViewerFetchedTexture::calcDecodePriority() +{ +#ifndef LL_RELEASE_FOR_DOWNLOAD + if (mID == LLAppViewer::getTextureFetch()->mDebugID) + { + LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints + } +#endif + + if(mFullyLoaded)//already loaded for static texture + { + return -4.0f ; //alreay fetched + } + + if (mNeedsCreateTexture) + { + return mDecodePriority; // no change while waiting to create + } + + F32 priority; + S32 cur_discard = getDiscardLevel(); + bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); + F32 pixel_priority = fsqrtf(mMaxVirtualSize); + const S32 MIN_NOT_VISIBLE_FRAMES = 30; // NOTE: this function is not called every frame + mDecodeFrame++; + if (pixel_priority > 0.f) + { + mVisibleFrame = mDecodeFrame; + } + + if (mIsMissingAsset) + { + priority = 0.0f; + } + else if (mDesiredDiscardLevel > getMaxDiscardLevel()) + { + // Don't decode anything we don't need + priority = -1.0f; + } + else if (mBoostLevel == LLViewerTexture::BOOST_UI && !have_all_data) + { + priority = 1.f; + } + else if (pixel_priority <= 0.f && !have_all_data) + { + // Not on screen but we might want some data + if (mBoostLevel > BOOST_HIGH) + { + // Always want high boosted images + priority = 1.f; + } + else if (mVisibleFrame == 0 || (mDecodeFrame - mVisibleFrame > MIN_NOT_VISIBLE_FRAMES)) + { + // Don't decode anything that isn't visible unless it's important + priority = -2.0f; + } + else + { + // Leave the priority as-is + return mDecodePriority; + } + } + else if (cur_discard < 0) + { + priority = calcDecodePriorityForUnknownTexture(pixel_priority) ; + } + else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel)) + { + // larger mips are corrupted + priority = -3.0f; + } + else if (cur_discard <= mDesiredDiscardLevel) + { + priority = -4.0f; + } + else + { + // priority range = 100000-400000 + S32 ddiscard = cur_discard - mDesiredDiscardLevel; + if (getDontDiscard()) + { + ddiscard+=2; + } + else if (mGLTexturep.notNull() && !mGLTexturep->getBoundRecently() && mBoostLevel == 0) + { + ddiscard-=2; + } + ddiscard = llclamp(ddiscard, 0, 4); + priority = ddiscard*100000.f; + } + if (priority > 0.0f) + { + pixel_priority = llclamp(pixel_priority, 0.0f, priority-1.f); // priority range = 100000-900000 + if ( mBoostLevel > BOOST_HIGH) + { + priority = 1000000.f + pixel_priority + 1000.f * mBoostLevel; + } + else + { + priority += 0.f + pixel_priority + 1000.f * mBoostLevel; + } + } + return priority; +} +//============================================================================ + +void LLViewerFetchedTexture::setDecodePriority(F32 priority) +{ + llassert(!mInImageList); + mDecodePriority = priority; +} + +bool LLViewerFetchedTexture::updateFetch() +{ + mFetchState = 0; + mFetchPriority = 0; + mFetchDeltaTime = 999999.f; + mRequestDeltaTime = 999999.f; + +#ifndef LL_RELEASE_FOR_DOWNLOAD + if (mID == LLAppViewer::getTextureFetch()->mDebugID) + { + LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints + } +#endif + + if (mNeedsCreateTexture) + { + // We may be fetching still (e.g. waiting on write) + // but don't check until we've processed the raw data we have + return false; + } + if (mIsMissingAsset) + { + llassert_always(!mHasFetcher); + return false; // skip + } + if (!mLoadedCallbackList.empty() && mRawImage.notNull()) + { + return false; // process any raw image data in callbacks before replacing + } + + S32 current_discard = getDiscardLevel() ; + S32 desired_discard = getDesiredDiscardLevel(); + F32 decode_priority = getDecodePriority(); + decode_priority = llmax(decode_priority, 0.0f); + + if (mIsFetching) + { + // Sets mRawDiscardLevel, mRawImage, mAuxRawImage + S32 fetch_discard = current_discard; + if (mRawImage.notNull()) sRawCount--; + if (mAuxRawImage.notNull()) sAuxCount--; + bool finished = LLAppViewer::getTextureFetch()->getRequestFinished(getID(), fetch_discard, mRawImage, mAuxRawImage); + if (mRawImage.notNull()) sRawCount++; + if (mAuxRawImage.notNull()) sAuxCount++; + if (finished) + { + mIsFetching = FALSE; + } + else + { + mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, + mFetchPriority, mFetchDeltaTime, mRequestDeltaTime); + } + + // We may have data ready regardless of whether or not we are finished (e.g. waiting on write) + if (mRawImage.notNull()) + { + if(LLViewerTextureManager::sTesterp) + { + mIsFetched = TRUE ; + LLViewerTextureManager::sTesterp->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID)) ; + } + mRawDiscardLevel = fetch_discard; + if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && + (current_discard < 0 || mRawDiscardLevel < current_discard)) + { + if (getComponents() != mRawImage->getComponents()) + { + // We've changed the number of components, so we need to move any + // objects using this pool to a different pool. + mComponents = mRawImage->getComponents(); + mGLTexturep->setComponents(mComponents) ; + + gTextureList.dirtyImage(this); + } + mIsRawImageValid = TRUE; + gTextureList.mCreateTextureList.insert(this); + mNeedsCreateTexture = TRUE; + mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; + mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; + } + else + { + // Data is ready but we don't need it + // (received it already while fetcher was writing to disk) + destroyRawImage(); + return false; // done + } + } + + if (!mIsFetching) + { + if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL)) + { + // We finished but received no data + if (current_discard < 0) + { + setIsMissingAsset(); + desired_discard = -1; + } + else + { + llwarns << mID << ": Setting min discard to " << current_discard << llendl; + mMinDiscardLevel = current_discard; + desired_discard = current_discard; + } + destroyRawImage(); + } + else if (mRawImage.isNull()) + { + // We have data, but our fetch failed to return raw data + // *TODO: FIgure out why this is happening and fix it + destroyRawImage(); + } + } + else + { + LLAppViewer::getTextureFetch()->updateRequestPriority(mID, decode_priority); + } + } + + bool make_request = true; + + if (decode_priority <= 0) + { + make_request = false; + } + else if (mNeedsCreateTexture || mIsMissingAsset) + { + make_request = false; + } + else if (current_discard >= 0 && current_discard <= mMinDiscardLevel) + { + make_request = false; + } + else + { + if (mIsFetching) + { + if (mRequestedDiscardLevel <= desired_discard) + { + make_request = false; + } + } + else + { + if (current_discard >= 0 && current_discard <= desired_discard) + { + make_request = false; + } + } + } + + if (make_request) + { + S32 w=0, h=0, c=0; + if (current_discard >= 0) + { + w = mGLTexturep->getWidth(0); + h = mGLTexturep->getHeight(0); + c = mComponents; + } + if (!mDontDiscard) + { + if (mBoostLevel == 0) + { + desired_discard = llmax(desired_discard, current_discard-1); + } + else + { + desired_discard = llmax(desired_discard, current_discard-2); + } + } + + // bypass texturefetch directly by pulling from LLTextureCache + bool fetch_request_created = false; + if (mLocalFileName.empty()) + { + fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(getID(), getTargetHost(), decode_priority, + w, h, c, desired_discard, + needsAux()); + } + else + { + fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mLocalFileName, getID(),getTargetHost(), decode_priority, + w, h, c, desired_discard, + needsAux()); + } + + if (fetch_request_created) + { + mHasFetcher = TRUE; + mIsFetching = TRUE; + mRequestedDiscardLevel = desired_discard; + mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, + mFetchPriority, mFetchDeltaTime, mRequestDeltaTime); + } + + // if createRequest() failed, we're finishing up a request for this UUID, + // wait for it to complete + } + else if (mHasFetcher && !mIsFetching) + { + // Only delete requests that haven't receeived any network data for a while + const F32 FETCH_IDLE_TIME = 5.f; + if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME) + { +// llinfos << "Deleting request: " << getID() << " Discard: " << current_discard << " <= min:" << mMinDiscardLevel << " or priority == 0: " << decode_priority << llendl; + LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); + mHasFetcher = FALSE; + } + } + + llassert_always(mRawImage.notNull() || (!mNeedsCreateTexture && !mIsRawImageValid)); + + return mIsFetching ? true : false; +} + +void LLViewerFetchedTexture::setIsMissingAsset() +{ + llwarns << mLocalFileName << " " << mID << ": Marking image as missing" << llendl; + if (mHasFetcher) + { + LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); + mHasFetcher = FALSE; + mIsFetching = FALSE; + mFetchState = 0; + mFetchPriority = 0; + } + mIsMissingAsset = TRUE; +} + +void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_callback, + S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata) +{ + // + // Don't do ANYTHING here, just add it to the global callback list + // + if (mLoadedCallbackList.empty()) + { + // Put in list to call this->doLoadedCallbacks() periodically + gTextureList.mCallbackList.insert(this); + } + LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata); + mLoadedCallbackList.push_back(entryp); + mNeedsAux |= needs_aux; + if (mNeedsAux && mAuxRawImage.isNull() && getDiscardLevel() >= 0) + { + // We need aux data, but we've already loaded the image, and it didn't have any + llwarns << "No aux data available for callback for image:" << getID() << llendl; + } +} + +bool LLViewerFetchedTexture::doLoadedCallbacks() +{ + if (mNeedsCreateTexture) + { + return false; + } + + bool res = false; + + if (isMissingAsset()) + { + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + LLLoadedCallbackEntry *entryp = *iter++; + // We never finished loading the image. Indicate failure. + // Note: this allows mLoadedCallbackUserData to be cleaned up. + entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData); + delete entryp; + } + mLoadedCallbackList.clear(); + + // Remove ourself from the global list of textures with callbacks + gTextureList.mCallbackList.erase(this); + } + + S32 gl_discard = getDiscardLevel(); + + // If we don't have a legit GL image, set it to be lower than the worst discard level + if (gl_discard == -1) + { + gl_discard = MAX_DISCARD_LEVEL + 1; + } + + // + // Determine the quality levels of textures that we can provide to callbacks + // and whether we need to do decompression/readback to get it + // + S32 current_raw_discard = MAX_DISCARD_LEVEL + 1; // We can always do a readback to get a raw discard + S32 best_raw_discard = gl_discard; // Current GL quality level + S32 current_aux_discard = MAX_DISCARD_LEVEL + 1; + S32 best_aux_discard = MAX_DISCARD_LEVEL + 1; + + if (mIsRawImageValid) + { + // If we have an existing raw image, we have a baseline for the raw and auxiliary quality levels. + best_raw_discard = llmin(best_raw_discard, mRawDiscardLevel); + best_aux_discard = llmin(best_aux_discard, mRawDiscardLevel); // We always decode the aux when we decode the base raw + current_aux_discard = llmin(current_aux_discard, best_aux_discard); + } + else + { + // We have no data at all, we need to get it + // Do this by forcing the best aux discard to be 0. + best_aux_discard = 0; + } + + + // + // See if any of the callbacks would actually run using the data that we can provide, + // and also determine if we need to perform any readbacks or decodes. + // + bool run_gl_callbacks = false; + bool run_raw_callbacks = false; + bool need_readback = false; + + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + LLLoadedCallbackEntry *entryp = *iter++; + if (entryp->mNeedsImageRaw) + { + if (mNeedsAux) + { + // + // Need raw and auxiliary channels + // + if (entryp->mLastUsedDiscard > current_aux_discard) + { + // We have useful data, run the callbacks + run_raw_callbacks = true; + } + } + else + { + if (entryp->mLastUsedDiscard > current_raw_discard) + { + // We have useful data, just run the callbacks + run_raw_callbacks = true; + } + else if (entryp->mLastUsedDiscard > best_raw_discard) + { + // We can readback data, and then run the callbacks + need_readback = true; + run_raw_callbacks = true; + } + } + } + else + { + // Needs just GL + if (entryp->mLastUsedDiscard > gl_discard) + { + // We have enough data, run this callback requiring GL data + run_gl_callbacks = true; + } + } + } + + // + // Do a readback if required, OR start off a texture decode + // + if (need_readback && (getMaxDiscardLevel() > gl_discard)) + { + // Do a readback to get the GL data into the raw image + // We have GL data. + + destroyRawImage(); + readBackRawImage(gl_discard); + llassert_always(mRawImage.notNull()); + llassert_always(!mNeedsAux || mAuxRawImage.notNull()); + } + + // + // Run raw/auxiliary data callbacks + // + if (run_raw_callbacks && mIsRawImageValid && (mRawDiscardLevel <= getMaxDiscardLevel())) + { + // Do callbacks which require raw image data. + //llinfos << "doLoadedCallbacks raw for " << getID() << llendl; + + // Call each party interested in the raw data. + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + callback_list_t::iterator curiter = iter++; + LLLoadedCallbackEntry *entryp = *curiter; + if (entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > mRawDiscardLevel)) + { + // If we've loaded all the data there is to load or we've loaded enough + // to satisfy the interested party, then this is the last time that + // we're going to call them. + + llassert_always(mRawImage.notNull()); + if(mNeedsAux && mAuxRawImage.isNull()) + { + llwarns << "Raw Image with no Aux Data for callback" << llendl; + } + BOOL final = mRawDiscardLevel <= entryp->mDesiredDiscard ? TRUE : FALSE; + //llinfos << "Running callback for " << getID() << llendl; + //llinfos << mRawImage->getWidth() << "x" << mRawImage->getHeight() << llendl; + if (final) + { + //llinfos << "Final!" << llendl; + } + entryp->mLastUsedDiscard = mRawDiscardLevel; + entryp->mCallback(TRUE, this, mRawImage, mAuxRawImage, mRawDiscardLevel, final, entryp->mUserData); + if (final) + { + iter = mLoadedCallbackList.erase(curiter); + delete entryp; + } + res = true; + } + } + } + + // + // Run GL callbacks + // + if (run_gl_callbacks && (gl_discard <= getMaxDiscardLevel())) + { + //llinfos << "doLoadedCallbacks GL for " << getID() << llendl; + + // Call the callbacks interested in GL data. + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + callback_list_t::iterator curiter = iter++; + LLLoadedCallbackEntry *entryp = *curiter; + if (!entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > gl_discard)) + { + BOOL final = gl_discard <= entryp->mDesiredDiscard ? TRUE : FALSE; + entryp->mLastUsedDiscard = gl_discard; + entryp->mCallback(TRUE, this, NULL, NULL, gl_discard, final, entryp->mUserData); + if (final) + { + iter = mLoadedCallbackList.erase(curiter); + delete entryp; + } + res = true; + } + } + } + + // + // If we have no callbacks, take us off of the image callback list. + // + if (mLoadedCallbackList.empty()) + { + gTextureList.mCallbackList.erase(this); + } + + // Done with any raw image data at this point (will be re-created if we still have callbacks) + destroyRawImage(); + + return res; +} + +//virtual +void LLViewerFetchedTexture::forceImmediateUpdate() +{ + //only immediately update a deleted texture which is now being re-used. + if(!isDeleted()) + { + return ; + } + //if already called forceImmediateUpdate() + if(mInImageList && mDecodePriority == LLViewerFetchedTexture::maxDecodePriority()) + { + return ; + } + + gTextureList.forceImmediateUpdate(this) ; + return ; +} + +// Was in LLImageGL +LLImageRaw* LLViewerFetchedTexture::readBackRawImage(S8 discard_level) +{ + llassert_always(mGLTexturep.notNull()) ; + llassert_always(discard_level >= 0); + llassert_always(mComponents > 0); + if (mRawImage.notNull()) + { + llerrs << "called with existing mRawImage" << llendl; + mRawImage = NULL; + } + mRawImage = new LLImageRaw(mGLTexturep->getWidth(discard_level), mGLTexturep->getHeight(discard_level), mComponents); + sRawCount++; + mRawDiscardLevel = discard_level; + mGLTexturep->readBackRaw(mRawDiscardLevel, mRawImage, false); + mIsRawImageValid = TRUE; + + return mRawImage; +} + +void LLViewerFetchedTexture::destroyRawImage() +{ + if (mRawImage.notNull()) sRawCount--; + if (mAuxRawImage.notNull()) sAuxCount--; + mRawImage = NULL; + mAuxRawImage = NULL; + mIsRawImageValid = FALSE; + mRawDiscardLevel = INVALID_DISCARD_LEVEL; +} +//---------------------------------------------------------------------------------------------- +//end of LLViewerFetchedTexture +//---------------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------------- +//start of LLViewerLODTexture +//---------------------------------------------------------------------------------------------- +LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, BOOL usemipmaps) + : LLViewerFetchedTexture(id, usemipmaps) +{ + init(TRUE) ; +} + +LLViewerLODTexture::LLViewerLODTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps) + : LLViewerFetchedTexture(full_path, id, usemipmaps) +{ + init(TRUE) ; +} + +void LLViewerLODTexture::init(bool firstinit) +{ + mTexelsPerImage = 64.f*64.f; + mDiscardVirtualSize = 0.f; + mCalculatedDiscardLevel = -1.f; +} + +//virtual +S8 LLViewerLODTexture::getType() const +{ + return LLViewerTexture::LOD_TEXTURE ; +} + +// This is gauranteed to get called periodically for every texture +//virtual +void LLViewerLODTexture::processTextureStats() +{ + // Generate the request priority and render priority + if (mDontDiscard || !mUseMipMaps) + { + mDesiredDiscardLevel = 0; + if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) + mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 + } + else if (mBoostLevel < LLViewerTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f) + { + // If the image has not been significantly visible in a while, we don't want it + mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1)); + } + else if (!mFullWidth || !mFullHeight) + { + mDesiredDiscardLevel = getMaxDiscardLevel() ; + } + else + { + //static const F64 log_2 = log(2.0); + static const F64 log_4 = log(4.0); + + S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT); + S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT); + mTexelsPerImage = (F32)fullwidth * fullheight; + + F32 discard_level = 0.f; + + // If we know the output width and height, we can force the discard + // level to the correct value, and thus not decode more texture + // data than we need to. + /*if (mBoostLevel == LLViewerTexture::BOOST_UI || + mBoostLevel == LLViewerTexture::BOOST_PREVIEW || + mBoostLevel == LLViewerTexture::BOOST_AVATAR_SELF) // JAMESDEBUG what about AVATAR_BAKED_SELF? + { + discard_level = 0; // full res + } + else*/ if (mKnownDrawWidth && mKnownDrawHeight) + { + S32 draw_texels = mKnownDrawWidth * mKnownDrawHeight; + + // Use log_4 because we're in square-pixel space, so an image + // with twice the width and twice the height will have mTexelsPerImage + // 4 * draw_size + discard_level = (F32)(log(mTexelsPerImage/draw_texels) / log_4); + } + else + { + if ((mCalculatedDiscardLevel >= 0.f) && + (llabs(mMaxVirtualSize - mDiscardVirtualSize) < mMaxVirtualSize*.20f)) + { + // < 20% change in virtual size = no change in desired discard + discard_level = mCalculatedDiscardLevel; + } + else + { + // Calculate the required scale factor of the image using pixels per texel + discard_level = (F32)(log(mTexelsPerImage/mMaxVirtualSize) / log_4); + mDiscardVirtualSize = mMaxVirtualSize; + mCalculatedDiscardLevel = discard_level; + } + } + if (mBoostLevel < LLViewerTexture::BOOST_HIGH) + { + static const F32 discard_bias = -.5f; // Must be < 1 or highest discard will never load! + discard_level += discard_bias; + discard_level += sDesiredDiscardBias; + discard_level *= sDesiredDiscardScale; // scale + } + discard_level = floorf(discard_level); +// discard_level -= (gTextureList.mVideoMemorySetting>>1); // more video ram = higher detail + + F32 min_discard = 0.f; + if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) + min_discard = 1.f; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 + + discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL); + + // Can't go higher than the max discard level + mDesiredDiscardLevel = llmin(getMaxDiscardLevel() + 1, (S32)discard_level); + // Clamp to min desired discard + mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, mDesiredDiscardLevel); + + // + // At this point we've calculated the quality level that we want, + // if possible. Now we check to see if we have it, and take the + // proper action if we don't. + // + + BOOL increase_discard = FALSE; + S32 current_discard = getDiscardLevel(); + if ((sDesiredDiscardBias > 0.0f) && + (current_discard >= 0 && mDesiredDiscardLevel >= current_discard)) + { + if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) + { + // Limit the amount of GL memory bound each frame + if (mDesiredDiscardLevel > current_discard) + { + increase_discard = TRUE; + } + } + if ( BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) > sMaxTotalTextureMemInMegaBytes*texmem_middle_bound_scale) + { + // Only allow GL to have 2x the video card memory + if (!mGLTexturep->getBoundRecently()) + { + increase_discard = TRUE; + } + } + if (increase_discard) + { + // llinfos << "DISCARDED: " << mID << " Discard: " << current_discard << llendl; + sBoundTextureMemoryInBytes -= mGLTexturep->mTextureMemory; + sTotalTextureMemoryInBytes -= mGLTexturep->mTextureMemory; + // Increase the discard level (reduce the texture res) + S32 new_discard = current_discard+1; + mGLTexturep->setDiscardLevel(new_discard); + sBoundTextureMemoryInBytes += mGLTexturep->mTextureMemory; + sTotalTextureMemoryInBytes += mGLTexturep->mTextureMemory; + if(LLViewerTextureManager::sTesterp) + { + LLViewerTextureManager::sTesterp->setStablizingTime() ; + } + } + } + } +} + +//---------------------------------------------------------------------------------------------- +//end of LLViewerLODTexture +//---------------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------------- +//start of LLViewerMediaTexture +//---------------------------------------------------------------------------------------------- +//static +void LLViewerMediaTexture::updateClass() +{ + static const F32 MAX_INACTIVE_TIME = 30.f ; + + for(media_map_t::iterator iter = sMediaMap.begin() ; iter != sMediaMap.end(); ) + { + LLViewerMediaTexture* mediap = iter->second; + ++iter ; + + if(mediap->getNumRefs() == 1 && mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) //one by sMediaMap + { + sMediaMap.erase(mediap->getID()) ; + } + } +} + +LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image) + : LLViewerTexture(id, usemipmaps) +{ + sMediaMap.insert(std::make_pair(id, this)); + + mGLTexturep = gl_image ; + if(mGLTexturep.isNull()) + { + generateGLTexture() ; + } + mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ; + + mIsPlaying = FALSE ; +} + +void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */) +{ + mGLTexturep = NULL ; + init(false); + mUseMipMaps = usemipmaps ; + mIsPlaying = FALSE ; + getLastReferencedTimer()->reset() ; + + generateGLTexture() ; + mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ; +} + +void LLViewerMediaTexture::setUseMipMaps(BOOL mipmap) +{ + mUseMipMaps = mipmap; + + if(mGLTexturep.notNull()) + { + mGLTexturep->setUseMipMaps(mipmap) ; + } +} + +//virtual +S8 LLViewerMediaTexture::getType() const +{ + return LLViewerTexture::MEDIA_TEXTURE ; +} + +void LLViewerMediaTexture::setOldTexture(LLViewerTexture* tex) +{ + mOldTexturep = tex ; +} + +LLViewerTexture* LLViewerMediaTexture::getOldTexture() const +{ + return mOldTexturep ; +} +//---------------------------------------------------------------------------------------------- +//end of LLViewerMediaTexture +//---------------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------------- +//start of LLTexturePipelineTester +//---------------------------------------------------------------------------------------------- +LLTexturePipelineTester::LLTexturePipelineTester() : + LLMetricPerformanceTester("TextureTester", FALSE) +{ + addMetricString("TotalBytesLoaded") ; + addMetricString("TotalBytesLoadedFromCache") ; + addMetricString("TotalBytesLoadedForLargeImage") ; + addMetricString("TotalBytesLoadedForSculpties") ; + addMetricString("StartFetchingTime") ; + addMetricString("TotalGrayTime") ; + addMetricString("TotalStablizingTime") ; + addMetricString("StartTimeLoadingSculpties") ; + addMetricString("EndTimeLoadingSculpties") ; + + addMetricString("Time") ; + addMetricString("TotalBytesBound") ; + addMetricString("TotalBytesBoundForLargeImage") ; + addMetricString("PercentageBytesBound") ; + + mTotalBytesLoaded = 0 ; + mTotalBytesLoadedFromCache = 0 ; + mTotalBytesLoadedForLargeImage = 0 ; + mTotalBytesLoadedForSculpties = 0 ; + + reset() ; +} + +LLTexturePipelineTester::~LLTexturePipelineTester() +{ + LLViewerTextureManager::sTesterp = NULL ; +} + +void LLTexturePipelineTester::update() +{ + mLastTotalBytesUsed = mTotalBytesUsed ; + mLastTotalBytesUsedForLargeImage = mTotalBytesUsedForLargeImage ; + mTotalBytesUsed = 0 ; + mTotalBytesUsedForLargeImage = 0 ; + + if(LLAppViewer::getTextureFetch()->getNumRequests() > 0) //fetching list is not empty + { + if(mPause) + { + //start a new fetching session + reset() ; + mStartFetchingTime = LLImageGL::sLastFrameTime ; + mPause = FALSE ; + } + + //update total gray time + if(mUsingDefaultTexture) + { + mUsingDefaultTexture = FALSE ; + mTotalGrayTime = LLImageGL::sLastFrameTime - mStartFetchingTime ; + } + + //update the stablizing timer. + updateStablizingTime() ; + + outputTestResults() ; + } + else if(!mPause) + { + //stop the current fetching session + mPause = TRUE ; + outputTestResults() ; + reset() ; + } +} + +void LLTexturePipelineTester::reset() +{ + mPause = TRUE ; + + mUsingDefaultTexture = FALSE ; + mStartStablizingTime = 0.0f ; + mEndStablizingTime = 0.0f ; + + mTotalBytesUsed = 0 ; + mTotalBytesUsedForLargeImage = 0 ; + mLastTotalBytesUsed = 0 ; + mLastTotalBytesUsedForLargeImage = 0 ; + + mStartFetchingTime = 0.0f ; + + mTotalGrayTime = 0.0f ; + mTotalStablizingTime = 0.0f ; + + mStartTimeLoadingSculpties = 1.0f ; + mEndTimeLoadingSculpties = 0.0f ; +} + +//virtual +void LLTexturePipelineTester::outputTestRecord(LLSD *sd) +{ + (*sd)[mCurLabel]["TotalBytesLoaded"] = (LLSD::Integer)mTotalBytesLoaded ; + (*sd)[mCurLabel]["TotalBytesLoadedFromCache"] = (LLSD::Integer)mTotalBytesLoadedFromCache ; + (*sd)[mCurLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage ; + (*sd)[mCurLabel]["TotalBytesLoadedForSculpties"] = (LLSD::Integer)mTotalBytesLoadedForSculpties ; + + (*sd)[mCurLabel]["StartFetchingTime"] = (LLSD::Real)mStartFetchingTime ; + (*sd)[mCurLabel]["TotalGrayTime"] = (LLSD::Real)mTotalGrayTime ; + (*sd)[mCurLabel]["TotalStablizingTime"] = (LLSD::Real)mTotalStablizingTime ; + + (*sd)[mCurLabel]["StartTimeLoadingSculpties"] = (LLSD::Real)mStartTimeLoadingSculpties ; + (*sd)[mCurLabel]["EndTimeLoadingSculpties"] = (LLSD::Real)mEndTimeLoadingSculpties ; + + (*sd)[mCurLabel]["Time"] = LLImageGL::sLastFrameTime ; + (*sd)[mCurLabel]["TotalBytesBound"] = (LLSD::Integer)mLastTotalBytesUsed ; + (*sd)[mCurLabel]["TotalBytesBoundForLargeImage"] = (LLSD::Integer)mLastTotalBytesUsedForLargeImage ; + (*sd)[mCurLabel]["PercentageBytesBound"] = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded) ; +} + +void LLTexturePipelineTester::updateTextureBindingStats(const LLViewerTexture* imagep) +{ + U32 mem_size = (U32)imagep->getTextureMemory() ; + mTotalBytesUsed += mem_size ; + + if(MIN_LARGE_IMAGE_AREA <= (U32)(mem_size / (U32)imagep->getComponents())) + { + mTotalBytesUsedForLargeImage += mem_size ; + } +} + +void LLTexturePipelineTester::updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) +{ + U32 data_size = (U32)raw_imagep->getDataSize() ; + mTotalBytesLoaded += data_size ; + + if(from_cache) + { + mTotalBytesLoadedFromCache += data_size ; + } + + if(MIN_LARGE_IMAGE_AREA <= (U32)(data_size / (U32)raw_imagep->getComponents())) + { + mTotalBytesLoadedForLargeImage += data_size ; + } + + if(imagep->isForSculpt()) + { + mTotalBytesLoadedForSculpties += data_size ; + + if(mStartTimeLoadingSculpties > mEndTimeLoadingSculpties) + { + mStartTimeLoadingSculpties = LLImageGL::sLastFrameTime ; + } + mEndTimeLoadingSculpties = LLImageGL::sLastFrameTime ; + } +} + +void LLTexturePipelineTester::updateGrayTextureBinding() +{ + mUsingDefaultTexture = TRUE ; +} + +void LLTexturePipelineTester::setStablizingTime() +{ + if(mStartStablizingTime <= mStartFetchingTime) + { + mStartStablizingTime = LLImageGL::sLastFrameTime ; + } + mEndStablizingTime = LLImageGL::sLastFrameTime ; +} + +void LLTexturePipelineTester::updateStablizingTime() +{ + if(mStartStablizingTime > mStartFetchingTime) + { + F32 t = mEndStablizingTime - mStartStablizingTime ; + + if(t > 0.0001f && (t - mTotalStablizingTime) < 0.0001f) + { + //already stablized + mTotalStablizingTime = LLImageGL::sLastFrameTime - mStartStablizingTime ; + + //cancel the timer + mStartStablizingTime = 0.f ; + mEndStablizingTime = 0.f ; + } + else + { + mTotalStablizingTime = t ; + } + } + mTotalStablizingTime = 0.f ; +} + +//virtual +void LLTexturePipelineTester::compareTestSessions(std::ofstream* os) +{ + LLTexturePipelineTester::LLTextureTestSession* base_sessionp = dynamic_cast(mBaseSessionp) ; + LLTexturePipelineTester::LLTextureTestSession* current_sessionp = dynamic_cast(mCurrentSessionp) ; + if(!base_sessionp || !current_sessionp) + { + llerrs << "type of test session does not match!" << llendl ; + } + + //compare and output the comparison + *os << llformat("%s\n", mName.c_str()) ; + *os << llformat("AggregateResults\n") ; + + compareTestResults(os, "TotalFetchingTime", base_sessionp->mTotalFetchingTime, current_sessionp->mTotalFetchingTime) ; + compareTestResults(os, "TotalGrayTime", base_sessionp->mTotalGrayTime, current_sessionp->mTotalGrayTime) ; + compareTestResults(os, "TotalStablizingTime", base_sessionp->mTotalStablizingTime, current_sessionp->mTotalStablizingTime); + compareTestResults(os, "StartTimeLoadingSculpties", base_sessionp->mStartTimeLoadingSculpties, current_sessionp->mStartTimeLoadingSculpties) ; + compareTestResults(os, "TotalTimeLoadingSculpties", base_sessionp->mTotalTimeLoadingSculpties, current_sessionp->mTotalTimeLoadingSculpties) ; + + compareTestResults(os, "TotalBytesLoaded", base_sessionp->mTotalBytesLoaded, current_sessionp->mTotalBytesLoaded) ; + compareTestResults(os, "TotalBytesLoadedFromCache", base_sessionp->mTotalBytesLoadedFromCache, current_sessionp->mTotalBytesLoadedFromCache) ; + compareTestResults(os, "TotalBytesLoadedForLargeImage", base_sessionp->mTotalBytesLoadedForLargeImage, current_sessionp->mTotalBytesLoadedForLargeImage) ; + compareTestResults(os, "TotalBytesLoadedForSculpties", base_sessionp->mTotalBytesLoadedForSculpties, current_sessionp->mTotalBytesLoadedForSculpties) ; + + *os << llformat("InstantResults\n") ; + S32 size = llmin(base_sessionp->mInstantPerformanceListCounter, current_sessionp->mInstantPerformanceListCounter) ; + for(S32 i = 0 ; i < size ; i++) + { + *os << llformat("Time(B-T)-%.4f-%.4f\n", base_sessionp->mInstantPerformanceList[i].mTime, current_sessionp->mInstantPerformanceList[i].mTime) ; + + compareTestResults(os, "AverageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond, + current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond) ; + + compareTestResults(os, "AverageBytesUsedForLargeImagePerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond, + current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond) ; + + compareTestResults(os, "AveragePercentageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond, + current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond) ; + } + + if(size < base_sessionp->mInstantPerformanceListCounter) + { + for(S32 i = size ; i < base_sessionp->mInstantPerformanceListCounter ; i++) + { + *os << llformat("Time(B-T)-%.4f- \n", base_sessionp->mInstantPerformanceList[i].mTime) ; + + *os << llformat(", AverageBytesUsedPerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond) ; + *os << llformat(", AverageBytesUsedForLargeImagePerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond) ; + *os << llformat(", AveragePercentageBytesUsedPerSecond, %.4f, N/A \n", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond) ; + } + } + else if(size < current_sessionp->mInstantPerformanceListCounter) + { + for(S32 i = size ; i < current_sessionp->mInstantPerformanceListCounter ; i++) + { + *os << llformat("Time(B-T)- -%.4f\n", current_sessionp->mInstantPerformanceList[i].mTime) ; + + *os << llformat(", AverageBytesUsedPerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond) ; + *os << llformat(", AverageBytesUsedForLargeImagePerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond) ; + *os << llformat(", AveragePercentageBytesUsedPerSecond, N/A, %.4f\n", current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond) ; + } + } +} + +//virtual +LLMetricPerformanceTester::LLTestSession* LLTexturePipelineTester::loadTestSession(LLSD* log) +{ + LLTexturePipelineTester::LLTextureTestSession* sessionp = new LLTexturePipelineTester::LLTextureTestSession() ; + if(!sessionp) + { + return NULL ; + } + + F32 total_fetching_time = 0.f ; + F32 total_gray_time = 0.f ; + F32 total_stablizing_time = 0.f ; + F32 total_loading_sculpties_time = 0.f ; + + F32 start_fetching_time = -1.f ; + F32 start_fetching_sculpties_time = 0.f ; + + F32 last_time = 0.0f ; + S32 frame_count = 0 ; + + sessionp->mInstantPerformanceListCounter = 0 ; + sessionp->mInstantPerformanceList.resize(128) ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0 ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0 ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f ; + + //load a session + BOOL in_log = (*log).has(mCurLabel) ; + while(in_log) + { + LLSD::String label = mCurLabel ; + incLabel() ; + in_log = (*log).has(mCurLabel) ; + + if(sessionp->mInstantPerformanceListCounter >= (S32)sessionp->mInstantPerformanceList.size()) + { + sessionp->mInstantPerformanceList.resize(sessionp->mInstantPerformanceListCounter + 128) ; + } + + //time + F32 start_time = (*log)[label]["StartFetchingTime"].asReal() ; + F32 cur_time = (*log)[label]["Time"].asReal() ; + if(start_time - start_fetching_time > 0.0001f) //fetching has paused for a while + { + sessionp->mTotalFetchingTime += total_fetching_time ; + sessionp->mTotalGrayTime += total_gray_time ; + sessionp->mTotalStablizingTime += total_stablizing_time ; + + sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time ; + sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time ; + + start_fetching_time = start_time ; + total_fetching_time = 0.0f ; + total_gray_time = 0.f ; + total_stablizing_time = 0.f ; + total_loading_sculpties_time = 0.f ; + } + else + { + total_fetching_time = cur_time - start_time ; + total_gray_time = (*log)[label]["TotalGrayTime"].asReal() ; + total_stablizing_time = (*log)[label]["TotalStablizingTime"].asReal() ; + + total_loading_sculpties_time = (*log)[label]["EndTimeLoadingSculpties"].asReal() - (*log)[label]["StartTimeLoadingSculpties"].asReal() ; + if(start_fetching_sculpties_time < 0.f && total_loading_sculpties_time > 0.f) + { + start_fetching_sculpties_time = (*log)[label]["StartTimeLoadingSculpties"].asReal() ; + } + } + + //total loaded bytes + sessionp->mTotalBytesLoaded = (*log)[label]["TotalBytesLoaded"].asInteger() ; + sessionp->mTotalBytesLoadedFromCache = (*log)[label]["TotalBytesLoadedFromCache"].asInteger() ; + sessionp->mTotalBytesLoadedForLargeImage = (*log)[label]["TotalBytesLoadedForLargeImage"].asInteger() ; + sessionp->mTotalBytesLoadedForSculpties = (*log)[label]["TotalBytesLoadedForSculpties"].asInteger() ; + + //instant metrics + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond += + (*log)[label]["TotalBytesBound"].asInteger() ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond += + (*log)[label]["TotalBytesBoundForLargeImage"].asInteger() ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond += + (*log)[label]["PercentageBytesBound"].asReal() ; + frame_count++ ; + if(cur_time - last_time >= 1.0f) + { + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond /= frame_count ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond /= frame_count ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond /= frame_count ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = last_time ; + + frame_count = 0 ; + last_time = cur_time ; + sessionp->mInstantPerformanceListCounter++ ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0 ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0 ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f ; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f ; + } + } + + sessionp->mTotalFetchingTime += total_fetching_time ; + sessionp->mTotalGrayTime += total_gray_time ; + sessionp->mTotalStablizingTime += total_stablizing_time ; + + if(sessionp->mStartTimeLoadingSculpties < 0.f) + { + sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time ; + } + sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time ; + + return sessionp; +} + +LLTexturePipelineTester::LLTextureTestSession::LLTextureTestSession() +{ + reset() ; +} +LLTexturePipelineTester::LLTextureTestSession::~LLTextureTestSession() +{ +} +void LLTexturePipelineTester::LLTextureTestSession::reset() +{ + mTotalFetchingTime = 0.0f ; + + mTotalGrayTime = 0.0f ; + mTotalStablizingTime = 0.0f ; + + mStartTimeLoadingSculpties = 0.0f ; + mTotalTimeLoadingSculpties = 0.0f ; + + mTotalBytesLoaded = 0 ; + mTotalBytesLoadedFromCache = 0 ; + mTotalBytesLoadedForLargeImage = 0 ; + mTotalBytesLoadedForSculpties = 0 ; + + mInstantPerformanceListCounter = 0 ; +} +//---------------------------------------------------------------------------------------------- +//end of LLTexturePipelineTester +//---------------------------------------------------------------------------------------------- + diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h new file mode 100644 index 0000000000..142c212435 --- /dev/null +++ b/indra/newview/llviewertexture.h @@ -0,0 +1,672 @@ +/** + * @file llviewertexture.h + * @brief Object for managing images and their textures + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLVIEWERTEXTURE_H +#define LL_LLVIEWERTEXTURE_H + +#include "lltexture.h" +#include "lltimer.h" +#include "llframetimer.h" +#include "llhost.h" +#include "llgltypes.h" +#include "llrender.h" +#include "llmetricperformancetester.h" + +#include +#include + +#define MIN_VIDEO_RAM_IN_MEGA_BYTES 32 +#define MAX_VIDEO_RAM_IN_MEGA_BYTES 512 // 512MB max for performance reasons. + +class LLFace; +class LLImageGL ; +class LLViewerTexture; +class LLViewerFetchedTexture ; +class LLViewerMediaTexture ; +class LLTexturePipelineTester ; + +typedef void (*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); + +class LLVFile; +class LLMessageSystem; + +class LLLoadedCallbackEntry +{ +public: + LLLoadedCallbackEntry(loaded_callback_func cb, + S32 discard_level, + BOOL need_imageraw, // Needs image raw for the callback + void* userdata ) + : mCallback(cb), + mLastUsedDiscard(MAX_DISCARD_LEVEL+1), + mDesiredDiscard(discard_level), + mNeedsImageRaw(need_imageraw), + mUserData(userdata) + { + } + + loaded_callback_func mCallback; + S32 mLastUsedDiscard; + S32 mDesiredDiscard; + BOOL mNeedsImageRaw; + void* mUserData; +}; + +class LLTextureBar; + +class LLViewerTexture : public LLTexture +{ +public: + enum + { + MAX_IMAGE_SIZE_DEFAULT = 1024, + INVALID_DISCARD_LEVEL = 0x7fff + }; + enum + { + LOCAL_TEXTURE, + MEDIA_TEXTURE, + DYNAMIC_TEXTURE, + FETCHED_TEXTURE, + LOD_TEXTURE, + INVALID_TEXTURE_TYPE + }; + + enum EBoostLevel + { + BOOST_NONE = 0, + BOOST_AVATAR_BAKED = 1, + BOOST_AVATAR = 2, + BOOST_CLOUDS = 3, + BOOST_SCULPTED = 4, + + BOOST_HIGH = 10, + BOOST_TERRAIN = 11, // has to be high priority for minimap / low detail + BOOST_SELECTED = 12, + BOOST_HUD = 13, + BOOST_AVATAR_BAKED_SELF = 14, + BOOST_UI = 15, + BOOST_PREVIEW = 16, + BOOST_MAP = 17, + BOOST_MAP_LAYER = 18, + BOOST_AVATAR_SELF = 19, // needed for baking avatar + BOOST_MAX_LEVEL + }; + +protected: + virtual ~LLViewerTexture(); + LOG_CLASS(LLViewerTexture); + +public: + static void initClass(); + static void cleanupClass(); + static void updateClass(const F32 velocity, const F32 angular_velocity) ; + + LLViewerTexture(BOOL usemipmaps = TRUE); + LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ; + LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) ; + LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ; + + virtual S8 getType() const; + virtual BOOL isMissingAsset()const ; + virtual void dump(); // debug info to llinfos + + /*virtual*/ bool bindDefaultImage(const S32 stage = 0) const ; + /*virtual*/ void forceImmediateUpdate() ; + + const LLUUID& getID() const { return mID; } + + void setBoostLevel(S32 level); + S32 getBoostLevel() { return mBoostLevel; } + + //maxVirtualSize of the texture + void addTextureStats(F32 virtual_size) const ; + void resetTextureStats(BOOL zero = FALSE); + F32 getMaxVirtualSize()const {return mMaxVirtualSize ;} + + LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;} + + S32 getFullWidth() const { return mFullWidth; } + S32 getFullHeight() const { return mFullHeight; } + + void addFace(LLFace* facep) ; + void removeFace(LLFace* facep) ; + + void generateGLTexture() ; + void destroyGLTexture() ; + + //--------------------------------------------------------------------------------------------- + //functions to access LLImageGL + //--------------------------------------------------------------------------------------------- + /*virtual*/S32 getWidth(S32 discard_level = -1) const; + /*virtual*/S32 getHeight(S32 discard_level = -1) const; + + BOOL hasGLTexture() const ; + BOOL hasValidGLTexture() const ; + LLGLuint getTexName() const ; + BOOL createGLTexture() ; + BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0); + + void setFilteringOption(LLTexUnit::eTextureFilterOptions option); + void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); + void setAddressMode(LLTexUnit::eTextureAddressMode mode); + BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height); + BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height); + void setGLTextureCreated (bool initialized); + + LLTexUnit::eTextureAddressMode getAddressMode(void) const ; + S32 getMaxDiscardLevel() const; + S32 getDiscardLevel() const; + S8 getComponents() const ; + BOOL getBoundRecently() const; + S32 getTextureMemory() const ; + LLGLenum getPrimaryFormat() const; + BOOL getIsAlphaMask() const ; + LLTexUnit::eTextureType getTarget(void) const ; + BOOL getMask(const LLVector2 &tc); + F32 getTimePassedSinceLastBound(); + BOOL getMissed() const ; + BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ; + BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const; + //--------------------------------------------------------------------------------------------- + //end of functions to access LLImageGL + //--------------------------------------------------------------------------------------------- + + void switchToTexture(LLViewerTexture* new_texture) ; //make all faces pointing to this texture to point to new_texture. + + //----------------- + /*virtual*/ void setActive() ; + void forceActive() ; + void setNoDelete() ; + void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; } + BOOL getDontDiscard() const { return mDontDiscard; } + //----------------- + + /*virtual*/ void updateBindStatsForTester() ; +protected: + void cleanup() ; + void init(bool firstinit) ; + +private: + //note: do not make this function public. + /*virtual*/ LLImageGL* getGLTexture() const ; + +protected: + LLUUID mID; + S32 mBoostLevel; // enum describing priority level + S32 mFullWidth; + S32 mFullHeight; + BOOL mUseMipMaps ; + S8 mComponents; + mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need? + + LLFrameTimer mLastReferencedTimer; + + typedef std::list ll_face_list_t ; + ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture + + //GL texture + LLPointer mGLTexturep ; + S8 mDontDiscard; // Keep full res version of this image (for UI, etc) + +protected: + typedef enum + { + DELETED = 0, //removed from memory + DELETION_CANDIDATE, //ready to be removed from memory + INACTIVE, //not be used for the last certain period (i.e., 30 seconds). + ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds). + NO_DELETE = 99 //stay in memory, can not be removed. + } LLGLTexureState; + LLGLTexureState mTextureState ; + +public: + static const U32 sCurrentFileVersion; + static S32 sImageCount; + static S32 sRawCount; + static S32 sAuxCount; + static LLTimer sEvaluationTimer; + static F32 sDesiredDiscardBias; + static F32 sDesiredDiscardScale; + static S32 sBoundTextureMemoryInBytes; + static S32 sTotalTextureMemoryInBytes; + static S32 sMaxBoundTextureMemInMegaBytes; + static S32 sMaxTotalTextureMemInMegaBytes; + static S32 sMaxDesiredTextureMemInBytes ; + static BOOL sDontLoadVolumeTextures; + + static LLPointer sNullImagep; // Null texture for non-textured objects. +}; + + +// +//textures are managed in gTextureList. +//raw image data is fetched from remote or local cache +//but the raw image this texture pointing to is fixed. +// +class LLViewerFetchedTexture : public LLViewerTexture +{ + friend class LLTextureBar; // debug info only + friend class LLTextureView; // debug info only + +protected: + /*virtual*/ ~LLViewerFetchedTexture(); +public: + LLViewerFetchedTexture(const LLUUID& id, BOOL usemipmaps = TRUE); + LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps); + LLViewerFetchedTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps = TRUE); + +public: + static F32 maxDecodePriority(); + + struct Compare + { + // lhs < rhs + bool operator()(const LLPointer &lhs, const LLPointer &rhs) const + { + const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs; + const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs; + // greater priority is "less" + const F32 lpriority = lhsp->getDecodePriority(); + const F32 rpriority = rhsp->getDecodePriority(); + if (lpriority > rpriority) // higher priority + return true; + if (lpriority < rpriority) + return false; + return lhsp < rhsp; + } + }; + +public: + /*virtual*/ S8 getType() const ; + /*virtual*/ void forceImmediateUpdate() ; + /*virtual*/ void dump() ; + + // Set callbacks to get called when the image gets updated with higher + // resolution versions. + void setLoadedCallback(loaded_callback_func cb, + S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, + void* userdata); + bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; } + bool doLoadedCallbacks(); + + // ONLY call from LLViewerTextureList + BOOL createTexture(S32 usename = 0); + void destroyTexture() ; + + virtual void processTextureStats() ; + F32 calcDecodePriority() ; + + BOOL needsAux() const { return mNeedsAux; } + + // Host we think might have this image, used for baked av textures. + void setTargetHost(LLHost host) { mTargetHost = host; } + LLHost getTargetHost() const { return mTargetHost; } + + // Set the decode priority for this image... + // DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up + // the priority list, and cause horrible things to happen. + void setDecodePriority(F32 priority = -1.0f); + F32 getDecodePriority() const { return mDecodePriority; }; + + // setDesiredDiscardLevel is only used by LLViewerTextureList + void setDesiredDiscardLevel(S32 discard) { mDesiredDiscardLevel = discard; } + S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; } + void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } + + bool updateFetch(); + + // Override the computation of discard levels if we know the exact output + // size of the image. Used for UI textures to not decode, even if we have + // more data. + void setKnownDrawSize(S32 width, S32 height); + + void setIsMissingAsset(); + /*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; } + + // returns dimensions of original image for local files (before power of two scaling) + // and returns 0 for all asset system images + S32 getOriginalWidth() { return mOrigWidth; } + S32 getOriginalHeight() { return mOrigHeight; } + + BOOL isInImageList() const {return mInImageList ;} + void setInImageList(BOOL flag) {mInImageList = flag ;} + + const std::string& getLocalFileName() const {return mLocalFileName ;} + LLFrameTimer* getLastPacketTimer() {return &mLastPacketTimer;} + + U32 getFetchPriority() const { return mFetchPriority ;} + F32 getDownloadProgress() const {return mDownloadProgress ;} + + LLImageRaw* readBackRawImage(S8 discard_level) ; + void destroyRawImage(); + + //--------------- + BOOL isDeleted() ; + BOOL isInactive() ; + BOOL isDeletionCandidate(); + void setDeletionCandidate() ; + void setInactive() ; + BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } + //--------------- + + void setForSculpt(); + BOOL isForSculpt() const {return mForSculpt;} + +private: + void init(bool firstinit) ; + void cleanup() ; + + F32 calcDecodePriorityForUnknownTexture(F32 pixel_priority) ; + +private: + BOOL mFullyLoaded; + +protected: + S32 mOrigWidth; + S32 mOrigHeight; + + // Override the computation of discard levels if we know the exact output size of the image. + // Used for UI textures to not decode, even if we have more data. + S32 mKnownDrawWidth; + S32 mKnownDrawHeight; + + std::string mLocalFileName; + + S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space + S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have + S32 mMinDiscardLevel; + + S32 mRequestedDiscardLevel; + F32 mRequestedDownloadPriority; + S32 mFetchState; + U32 mFetchPriority; + F32 mDownloadProgress; + F32 mFetchDeltaTime; + F32 mRequestDeltaTime; + S32 mDecodeFrame; + S32 mVisibleFrame; // decode frame where image was last visible + + S8 mNeedsAux; // We need to decode the auxiliary channels + S8 mDecodingAux; // Are we decoding high components + S8 mIsRawImageValid; + S8 mHasFetcher; // We've made a fecth request + S8 mIsFetching; // Fetch request is active + + mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database. + + F32 mDecodePriority; // The priority for decoding this image. + typedef std::list callback_list_t; + callback_list_t mLoadedCallbackList; + + LLPointer mRawImage; + S32 mRawDiscardLevel; + + // Used ONLY for cloth meshes right now. Make SURE you know what you're + // doing if you use it for anything else! - djs + LLPointer mAuxRawImage; + + LLHost mTargetHost; // if LLHost::invalid, just request from agent's simulator + + // Timers + LLFrameTimer mLastPacketTimer; // Time since last packet. + + BOOL mInImageList; // TRUE if image is in list (in which case don't reset priority!) + BOOL mNeedsCreateTexture; + + BOOL mForSculpt ; //a flag if the texture is used as sculpt data. + BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally. + +public: + static LLPointer sMissingAssetImagep; // Texture to show for an image asset that is not in the database + static LLPointer sWhiteImagep; // Texture to show NOTHING (whiteness) + static LLPointer sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local. + static LLPointer sSmokeImagep; // Old "Default" translucent texture +}; + +// +//the image data is fetched from remote or from local cache +//the resolution of the texture is adjustable: depends on the view-dependent parameters. +// +class LLViewerLODTexture : public LLViewerFetchedTexture +{ +protected: + /*virtual*/ ~LLViewerLODTexture(){} + +public: + LLViewerLODTexture(const LLUUID& id, BOOL usemipmaps = TRUE); + LLViewerLODTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps = TRUE); + + /*virtual*/ S8 getType() const; + // Process image stats to determine priority/quality requirements. + /*virtual*/ void processTextureStats(); + +private: + void init(bool firstinit) ; + +private: + + F32 mTexelsPerImage; // Texels per image. + F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard + F32 mCalculatedDiscardLevel; // Last calculated discard level +}; + +// +//the image data is fetched from the media pipeline periodically +//the resolution of the texture is also adjusted by the media pipeline +// +class LLViewerMediaTexture : public LLViewerTexture +{ +protected: + /*virtual*/ ~LLViewerMediaTexture() {} + +public: + LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + + /*virtual*/ S8 getType() const; + + void reinit(BOOL usemipmaps = TRUE); + + BOOL getUseMipMaps() {return mUseMipMaps ; } + void setUseMipMaps(BOOL mipmap) ; + + void setOldTexture(LLViewerTexture* tex) ; + LLViewerTexture* getOldTexture() const ; + + void setPlaying(BOOL playing) {mIsPlaying = playing ;} + BOOL isPlaying() const {return mIsPlaying;} + +private: + LLPointer mOldTexturep ; //the texture this media texture replaces. + BOOL mIsPlaying ; + +public: + static void updateClass() ; + +public: + typedef std::map< LLUUID, LLPointer > media_map_t ; + static media_map_t sMediaMap ; +}; + +//just an interface class, do not create instance from this class. +class LLViewerTextureManager +{ +private: + //make the constructor private to preclude creating instances from this class. + LLViewerTextureManager(){} + +public: + //texture pipeline tester + static LLTexturePipelineTester* sTesterp ; + + //returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture. + static LLViewerFetchedTexture* staticCastToFetchedTexture(LLViewerTexture* tex, BOOL report_error = FALSE) ; + + // + //"find-texture" just check if the texture exists, if yes, return it, otherwise return null. + // + static LLViewerTexture* findTexture(const LLUUID& id) ; + static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ; + + static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + + // + //"get-texture" will create a new texture if the texture does not exist. + // + static LLViewerMediaTexture* getMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + + static LLPointer getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE); + static LLPointer getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; + static LLPointer getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ; + static LLPointer getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; + + static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id, + BOOL usemipmap = TRUE, + BOOL level_immediate = FALSE, // Get the requested level immediately upon creation. + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + LLHost request_from_host = LLHost() + ); + + static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename, + BOOL usemipmap = TRUE, + BOOL level_immediate = FALSE, // Get the requested level immediately upon creation. + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + const LLUUID& force_id = LLUUID::null + ); + + static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, LLHost host) ; + + static void init() ; + static void cleanup() ; +}; +// +//this class is used for test/debug only +//it tracks the activities of the texture pipeline +//records them, and outputs them to log files +// +class LLTexturePipelineTester : public LLMetricPerformanceTester +{ + enum + { + MIN_LARGE_IMAGE_AREA = 262144 //512 * 512 + }; +public: + LLTexturePipelineTester() ; + ~LLTexturePipelineTester() ; + + void update(); + void updateTextureBindingStats(const LLViewerTexture* imagep) ; + void updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) ; + void updateGrayTextureBinding() ; + void setStablizingTime() ; + + /*virtual*/ void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ; + +private: + void reset() ; + void updateStablizingTime() ; + + /*virtual*/ void outputTestRecord(LLSD* sd) ; + +private: + BOOL mPause ; +private: + BOOL mUsingDefaultTexture; //if set, some textures are still gray. + + U32 mTotalBytesUsed ; //total bytes of textures bound/used for the current frame. + U32 mTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the current frame for images larger than 256 * 256. + U32 mLastTotalBytesUsed ; //total bytes of textures bound/used for the previous frame. + U32 mLastTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the previous frame for images larger than 256 * 256. + + // + //data size + // + U32 mTotalBytesLoaded ; //total bytes fetched by texture pipeline + U32 mTotalBytesLoadedFromCache ; //total bytes fetched by texture pipeline from local cache + U32 mTotalBytesLoadedForLargeImage ; //total bytes fetched by texture pipeline for images larger than 256 * 256. + U32 mTotalBytesLoadedForSculpties ; //total bytes fetched by texture pipeline for sculpties + + // + //time + //NOTE: the error tolerances of the following timers is one frame time. + // + F32 mStartFetchingTime ; + F32 mTotalGrayTime ; //total loading time when no gray textures. + F32 mTotalStablizingTime ; //total stablizing time when texture memory overflows + F32 mStartTimeLoadingSculpties ; //the start moment of loading sculpty images. + F32 mEndTimeLoadingSculpties ; //the end moment of loading sculpty images. + F32 mStartStablizingTime ; + F32 mEndStablizingTime ; + +private: + // + //The following members are used for performance analyzing + // + class LLTextureTestSession : public LLTestSession + { + public: + LLTextureTestSession() ; + /*virtual*/ ~LLTextureTestSession() ; + + void reset() ; + + F32 mTotalFetchingTime ; + F32 mTotalGrayTime ; + F32 mTotalStablizingTime ; + F32 mStartTimeLoadingSculpties ; + F32 mTotalTimeLoadingSculpties ; + + S32 mTotalBytesLoaded ; + S32 mTotalBytesLoadedFromCache ; + S32 mTotalBytesLoadedForLargeImage ; + S32 mTotalBytesLoadedForSculpties ; + + typedef struct _texture_instant_preformance_t + { + S32 mAverageBytesUsedPerSecond ; + S32 mAverageBytesUsedForLargeImagePerSecond ; + F32 mAveragePercentageBytesUsedPerSecond ; + F32 mTime ; + }texture_instant_preformance_t ; + std::vector mInstantPerformanceList ; + S32 mInstantPerformanceListCounter ; + }; + + /*virtual*/ LLMetricPerformanceTester::LLTestSession* loadTestSession(LLSD* log) ; + /*virtual*/ void compareTestSessions(std::ofstream* os) ; +}; + +#endif diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp new file mode 100644 index 0000000000..ca9e89723c --- /dev/null +++ b/indra/newview/llviewertexturelist.cpp @@ -0,0 +1,1510 @@ +/** + * @file llviewertexturelist.cpp + * @brief Object for managing the list of images within a region + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llviewertexturelist.h" + +#include "imageids.h" +#include "llgl.h" // fot gathering stats from GL +#include "llimagegl.h" +#include "llimagebmp.h" +#include "llimagej2c.h" +#include "llimagetga.h" +#include "llimagejpeg.h" +#include "llimagepng.h" + +#include "llsdserialize.h" +#include "llsys.h" +#include "llvfs.h" +#include "llvfile.h" +#include "llvfsthread.h" +#include "llxmltree.h" +#include "message.h" + +#include "llagent.h" +#include "lltexturecache.h" +#include "lltexturefetch.h" +#include "llviewercontrol.h" +#include "llviewertexture.h" +#include "llviewermedia.h" +#include "llviewerregion.h" +#include "llviewerstats.h" +#include "pipeline.h" +#include "llappviewer.h" +#include "lluictrlfactory.h" // for LLXUIParser +#include + +//////////////////////////////////////////////////////////////////////////// + +void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL; + +const S32 IMAGES_PER_REQUEST = 42; +const S32 IMAGES_MIN_UPDATES = 4; // Always update the highest N images each frame +const S32 IMAGES_MAX_PACKET_UPDATES = 1; // Only send N packets of IMAGES_PER_REQUEST in a frame +const F32 RESEND_IMAGE_REQUEST_TIME = 15.f; // seconds + +LLViewerTextureList gTextureList; + +/////////////////////////////////////////////////////////////////////////////// + +LLViewerTextureList::LLViewerTextureList() + : mForceResetTextureStats(FALSE), + mUpdateStats(FALSE), + mMaxResidentTexMemInMegaBytes(0), + mMaxTotalTextureMemInMegaBytes(0) +{ +} + +void LLViewerTextureList::init() +{ + mNumImages = 0; + mMaxResidentTexMemInMegaBytes = 0; + mMaxTotalTextureMemInMegaBytes = 0 ; + if (gNoRender) + { + // Don't initialize GL stuff if we're not rendering. + return; + } + + mUpdateStats = TRUE; + + // Update how much texture RAM we're allowed to use. + updateMaxResidentTexMem(0); // 0 = use current + + doPreloadImages(); +} + + +void LLViewerTextureList::doPreloadImages() +{ + LL_DEBUGS("ViewerImages") << "Preloading images..." << LL_ENDL; + + // Set the "missing asset" image + LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", MIPMAP_NO, IMMEDIATE_YES); + + // Set the "white" image + LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", MIPMAP_NO, IMMEDIATE_YES); + + LLUIImageList* image_list = LLUIImageList::getInstance(); + + image_list->initFromFile(); + + // turn off clamping and bilinear filtering for uv picking images + //LLViewerFetchedTexture* uv_test = preloadUIImage("uv_test1.tga", LLUUID::null, FALSE); + //uv_test->setClamp(FALSE, FALSE); + //uv_test->setMipFilterNearest(TRUE, TRUE); + //uv_test = preloadUIImage("uv_test2.tga", LLUUID::null, FALSE); + //uv_test->setClamp(FALSE, FALSE); + //uv_test->setMipFilterNearest(TRUE, TRUE); + + // prefetch specific UUIDs + LLViewerTextureManager::getFetchedTexture(IMG_SHOT, TRUE); + LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF, TRUE); + LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", MIPMAP_YES, IMMEDIATE_YES); + if (image) + { + image->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(image); + } + image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png", MIPMAP_YES, IMMEDIATE_YES); + if (image) + { + image->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(image); + } + image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png", MIPMAP_YES, IMMEDIATE_YES); + if (image) + { + image->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(image); + } + image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, MIPMAP_YES, IMMEDIATE_YES); + if (image) + { + image->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(image); + } + image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", MIPMAP_YES, IMMEDIATE_YES, LLViewerTexture::FETCHED_TEXTURE, + 0,0,LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903")); + if (image) + { + image->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(image); + } + +} + +static std::string get_texture_list_name() +{ + return std::string("texture_list_") + gSavedSettings.getString("LoginLocation") + ".xml"; +} + +void LLViewerTextureList::doPrefetchImages() +{ + if (LLAppViewer::instance()->getPurgeCache()) + { + // cache was purged, no point + return; + } + + // Pre-fetch textures from last logout + LLSD imagelist; + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, get_texture_list_name()); + llifstream file; + file.open(filename); + if (file.is_open()) + { + LLSDSerialize::fromXML(imagelist, file); + } + for (LLSD::array_iterator iter = imagelist.beginArray(); + iter != imagelist.endArray(); ++iter) + { + LLSD imagesd = *iter; + LLUUID uuid = imagesd["uuid"]; + S32 pixel_area = imagesd["area"]; + S32 texture_type = imagesd["type"]; + + if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type) + { + LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, MIPMAP_TRUE, FALSE, texture_type); + if (image) + { + image->addTextureStats((F32)pixel_area); + } + } + } +} + +/////////////////////////////////////////////////////////////////////////////// + +LLViewerTextureList::~LLViewerTextureList() +{ +} + +void LLViewerTextureList::shutdown() +{ + // clear out preloads + mImagePreloads.clear(); + + // Write out list of currently loaded textures for precaching on startup + typedef std::set > image_area_list_t; + image_area_list_t image_area_list; + for (image_priority_list_t::iterator iter = mImageList.begin(); + iter != mImageList.end(); ++iter) + { + LLViewerFetchedTexture* image = *iter; + if (!image->hasGLTexture() || + !image->getUseDiscard() || + image->needsAux() || + image->getTargetHost() != LLHost::invalid) + { + continue; // avoid UI, baked, and other special images + } + S32 desired = image->getDesiredDiscardLevel(); + if (desired >= 0 && desired < MAX_DISCARD_LEVEL) + { + S32 pixel_area = image->getWidth(desired) * image->getHeight(desired); + image_area_list.insert(std::make_pair(pixel_area, image)); + } + } + + LLSD imagelist; + const S32 max_count = 1000; + S32 count = 0; + S32 image_type ; + for (image_area_list_t::reverse_iterator riter = image_area_list.rbegin(); + riter != image_area_list.rend(); ++riter) + { + LLViewerFetchedTexture* image = riter->second; + image_type = (S32)image->getType() ; + imagelist[count]["area"] = riter->first; + imagelist[count]["uuid"] = image->getID(); + imagelist[count]["type"] = image_type; + if (++count >= max_count) + break; + } + + if (count > 0 && !gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "").empty()) + { + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, get_texture_list_name()); + llofstream file; + file.open(filename); + LLSDSerialize::toPrettyXML(imagelist, file); + } + + // + // Clean up "loaded" callbacks. + // + mCallbackList.clear(); + + // Flush all of the references + mLoadingStreamList.clear(); + mCreateTextureList.clear(); + + mUUIDMap.clear(); + + mImageList.clear(); +} + +void LLViewerTextureList::dump() +{ + llinfos << "LLViewerTextureList::dump()" << llendl; + for (image_priority_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it) + { + LLViewerFetchedTexture* image = *it; + + llinfos << "priority " << image->getDecodePriority() + << " boost " << image->getBoostLevel() + << " size " << image->getWidth() << "x" << image->getHeight() + << " discard " << image->getDiscardLevel() + << " desired " << image->getDesiredDiscardLevel() + << " http://asset.siva.lindenlab.com/" << image->getID() << ".texture" + << llendl; + } +} + +void LLViewerTextureList::destroyGL(BOOL save_state) +{ + LLImageGL::destroyGL(save_state); +} + +void LLViewerTextureList::restoreGL() +{ + LLImageGL::restoreGL(); +} + +/* Vertical tab container button image IDs + Seem to not decode when running app in debug. + + const LLUUID BAD_IMG_ONE("1097dcb3-aef9-8152-f471-431d840ea89e"); + const LLUUID BAD_IMG_TWO("bea77041-5835-1661-f298-47e2d32b7a70"); + */ + +/////////////////////////////////////////////////////////////////////////////// + +LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename, + BOOL usemipmaps, + BOOL level_immediate, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + const LLUUID& force_id) +{ + if (gNoRender) + { + // Never mind that this ignores image_set_id; + // getImage() will handle that later. + return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE); + } + + std::string full_path = gDirUtilp->findSkinnedFilename("textures", filename); + if (full_path.empty()) + { + llwarns << "Failed to find local image file: " << filename << llendl; + return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE); + } + + // generate UUID based on hash of filename + LLUUID new_id; + if (force_id.notNull()) + { + new_id = force_id; + } + else + { + new_id.generate(full_path); + } + + LLPointer imagep = findImage(new_id); + + if (imagep.isNull()) + { + switch(texture_type) + { + case LLViewerTexture::FETCHED_TEXTURE: + imagep = new LLViewerFetchedTexture(full_path, new_id, usemipmaps); + break ; + case LLViewerTexture::LOD_TEXTURE: + imagep = new LLViewerLODTexture(full_path, new_id, usemipmaps); + break ; + default: + llerrs << "Invalid texture type " << texture_type << llendl ; + } + + if (internal_format && primary_format) + { + imagep->setExplicitFormat(internal_format, primary_format); + } + + addImage(imagep); + + if (level_immediate) + { + imagep->dontDiscard(); + imagep->setBoostLevel(LLViewerFetchedTexture::BOOST_UI); + } + } + + imagep->setGLTextureCreated(true); + + return imagep; +} + + +LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, + BOOL usemipmaps, + BOOL level_immediate, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + LLHost request_from_host) +{ + // Return the image with ID image_id + // If the image is not found, creates new image and + // enqueues a request for transmission + + if ((&image_id == NULL) || image_id.isNull()) + { + return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE)); + } + + LLPointer imagep = findImage(image_id); + + if (imagep.isNull()) + { + imagep = createImage(image_id, usemipmaps, level_immediate, texture_type, internal_format, primary_format, request_from_host) ; + } + + imagep->setGLTextureCreated(true); + + return imagep; +} + +//when this function is called, there is no such texture in the gTextureList with image_id. +LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, + BOOL usemipmaps, + BOOL level_immediate, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + LLHost request_from_host) +{ + LLPointer imagep ; + switch(texture_type) + { + case LLViewerTexture::FETCHED_TEXTURE: + imagep = new LLViewerFetchedTexture(image_id, usemipmaps); + break ; + case LLViewerTexture::LOD_TEXTURE: + imagep = new LLViewerLODTexture(image_id, usemipmaps); + break ; + default: + llerrs << "Invalid texture type " << texture_type << llendl ; + } + + // Might want to request from host other than where the agent is. JC + imagep->setTargetHost(request_from_host); + + if (internal_format && primary_format) + { + imagep->setExplicitFormat(internal_format, primary_format); + } + + addImage(imagep); + + if (level_immediate) + { + imagep->dontDiscard(); + imagep->setBoostLevel(LLViewerFetchedTexture::BOOST_UI); + } + else + { + //by default, the texure can not be removed from memory even if it is not used. + //here turn this off + //if this texture should be set to NO_DELETE, either pass level_immediate == TRUE here, or call setNoDelete() afterwards. + imagep->forceActive() ; + } + + return imagep ; +} + +LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id) +{ + uuid_map_t::iterator iter = mUUIDMap.find(image_id); + if(iter == mUUIDMap.end()) + return NULL; + return iter->second; +} + +void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) +{ + llassert(image); + if (image->isInImageList()) + { + llerrs << "LLViewerTextureList::addImageToList - Image already in list" << llendl; + } + llverify((mImageList.insert(image)).second == true); + image->setInImageList(TRUE) ; +} + +void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) +{ + llassert(image); + if (!image->isInImageList()) + { + llinfos << "RefCount: " << image->getNumRefs() << llendl ; + uuid_map_t::iterator iter = mUUIDMap.find(image->getID()); + if(iter == mUUIDMap.end() || iter->second != image) + { + llinfos << "Image is not in mUUIDMap!" << llendl ; + } + llerrs << "LLViewerTextureList::removeImageFromList - Image not in list" << llendl; + } + llverify(mImageList.erase(image) == 1); + image->setInImageList(FALSE) ; +} + +void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image) +{ + if (!new_image) + { + llwarning("No image to add to image list", 0); + return; + } + LLUUID image_id = new_image->getID(); + + LLViewerFetchedTexture *image = findImage(image_id); + if (image) + { + llwarns << "Image with ID " << image_id << " already in list" << llendl; + } + mNumImages++; + + addImageToList(new_image); + mUUIDMap[image_id] = new_image; +} + + +void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image) +{ + if( image) + { + if (image->hasCallbacks()) + { + mCallbackList.erase(image); + } + + llverify(mUUIDMap.erase(image->getID()) == 1); + mNumImages--; + removeImageFromList(image); + } +} + +/////////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// + +void LLViewerTextureList::dirtyImage(LLViewerFetchedTexture *image) +{ + mDirtyTextureList.insert(image); +} + +//////////////////////////////////////////////////////////////////////////// + +void LLViewerTextureList::updateImages(F32 max_time) +{ + LLViewerStats::getInstance()->mNumImagesStat.addValue(mNumImages); + LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount); + LLViewerStats::getInstance()->mGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes)); + LLViewerStats::getInstance()->mGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes)); + LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory)); + LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); + + updateImagesDecodePriorities(); + max_time -= updateImagesFetchTextures(max_time); + max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); + max_time -= updateImagesCreateTextures(max_time); + max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); + if (!mDirtyTextureList.empty()) + { + LLFastTimer t(LLFastTimer::FTM_IMAGE_MARK_DIRTY); + gPipeline.dirtyPoolObjectTextures(mDirtyTextureList); + mDirtyTextureList.clear(); + } + bool didone = false; + for (image_list_t::iterator iter = mCallbackList.begin(); + iter != mCallbackList.end(); ) + { + //trigger loaded callbacks on local textures immediately + LLViewerFetchedTexture* image = *iter++; + if (!image->getLocalFileName().empty()) + { + // Do stuff to handle callbacks, update priorities, etc. + didone = image->doLoadedCallbacks(); + } + else if (!didone) + { + // Do stuff to handle callbacks, update priorities, etc. + didone = image->doLoadedCallbacks(); + } + } + if (!gNoRender && !gGLManager.mIsDisabled) + { + LLViewerMedia::updateImagesMediaStreams(); + } + updateImagesUpdateStats(); +} + +void LLViewerTextureList::updateImagesDecodePriorities() +{ + // Update the decode priority for N images each frame + { + const size_t max_update_count = llmin((S32) (1024*gFrameIntervalSeconds) + 1, 32); //target 1024 textures per second + S32 update_counter = llmin(max_update_count, mUUIDMap.size()/10); + uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID); + while(update_counter > 0 && !mUUIDMap.empty()) + { + if (iter == mUUIDMap.end()) + { + iter = mUUIDMap.begin(); + } + mLastUpdateUUID = iter->first; + LLPointer imagep = iter->second; + ++iter; // safe to incrament now + + // + // Flush formatted images using a lazy flush + // + const F32 LAZY_FLUSH_TIMEOUT = 30.f; // stop decoding + const F32 MAX_INACTIVE_TIME = 50.f; // actually delete + S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference + if (imagep->hasCallbacks()) + { + min_refs++; // Add an extra reference if we're on the loaded callback list + } + S32 num_refs = imagep->getNumRefs(); + if (num_refs == min_refs) + { + if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > LAZY_FLUSH_TIMEOUT) + { + // Remove the unused image from the image list + deleteImage(imagep); + imagep = NULL; // should destroy the image + } + continue; + } + else + { + if(imagep->isDeleted()) + { + continue ; + } + else if(imagep->isDeletionCandidate()) + { + imagep->destroyTexture() ; + continue ; + } + else if(imagep->isInactive()) + { + if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) + { + imagep->setDeletionCandidate() ; + } + continue ; + } + else + { + imagep->getLastReferencedTimer()->reset(); + + //reset texture state. + imagep->setInactive() ; + } + } + + imagep->processTextureStats(); + F32 old_priority = imagep->getDecodePriority(); + F32 old_priority_test = llmax(old_priority, 0.0f); + F32 decode_priority = imagep->calcDecodePriority(); + F32 decode_priority_test = llmax(decode_priority, 0.0f); + // Ignore < 20% difference + if ((decode_priority_test < old_priority_test * .8f) || + (decode_priority_test > old_priority_test * 1.25f)) + { + removeImageFromList(imagep); + imagep->setDecodePriority(decode_priority); + addImageToList(imagep); + } + update_counter--; + } + } +} + +/* + static U8 get_image_type(LLViewerFetchedTexture* imagep, LLHost target_host) + { + // Having a target host implies this is a baked image. I don't + // believe that boost level has been set at this point. JC + U8 type_from_host = (target_host.isOk() + ? LLImageBase::TYPE_AVATAR_BAKE + : LLImageBase::TYPE_NORMAL); + S32 boost_level = imagep->getBoostLevel(); + U8 type_from_boost = ( (boost_level == LLViewerFetchedTexture::BOOST_AVATAR_BAKED + || boost_level == LLViewerFetchedTexture::BOOST_AVATAR_BAKED_SELF) + ? LLImageBase::TYPE_AVATAR_BAKE + : LLImageBase::TYPE_NORMAL); + if (type_from_host == LLImageBase::TYPE_NORMAL + && type_from_boost == LLImageBase::TYPE_AVATAR_BAKE) + { + llwarns << "TAT: get_image_type() type_from_host doesn't match type_from_boost" + << " host " << target_host + << " boost " << imagep->getBoostLevel() + << " imageid " << imagep->getID() + << llendl; + imagep->dump(); + } + return type_from_host; + } + */ + +F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) +{ + if (gNoRender || gGLManager.mIsDisabled) return 0.0f; + + // + // Create GL textures for all textures that need them (images which have been + // decoded, but haven't been pushed into GL). + // + LLFastTimer t(LLFastTimer::FTM_IMAGE_CREATE); + + LLTimer create_timer; + image_list_t::iterator enditer = mCreateTextureList.begin(); + for (image_list_t::iterator iter = mCreateTextureList.begin(); + iter != mCreateTextureList.end();) + { + image_list_t::iterator curiter = iter++; + enditer = iter; + LLViewerFetchedTexture *imagep = *curiter; + imagep->createTexture(); + if (create_timer.getElapsedTimeF32() > max_time) + { + break; + } + } + mCreateTextureList.erase(mCreateTextureList.begin(), enditer); + return create_timer.getElapsedTimeF32(); +} + +void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) +{ + if(!imagep) + { + return ; + } + if(imagep->isInImageList()) + { + removeImageFromList(imagep); + } + + imagep->processTextureStats(); + F32 decode_priority = LLViewerFetchedTexture::maxDecodePriority() ; + imagep->setDecodePriority(decode_priority); + mImageList.insert(imagep); + imagep->setInImageList(TRUE) ; + + return ; +} + +F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) +{ + LLTimer image_op_timer; + + // Update the decode priority for N images each frame + // Make a list with 32 high priority entries + 256 cycled entries + const size_t max_priority_count = llmin((S32) (256*10.f*gFrameIntervalSeconds)+1, 32); + const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256); + + // 32 high priority entries + std::set entries; + size_t update_counter = llmin(max_priority_count, mImageList.size()); + image_priority_list_t::iterator iter1 = mImageList.begin(); + while(update_counter > 0) + { + // added extra granularity and verbosity for crash logging during 1.19.1 RC. -Brad + if(iter1 == mImageList.end()) + { + llerrs << "DEV-12002: update_counter not calculated correctly!" << llendl; + return 0.f; + } + + LLPointer const & ptr = *iter1; + + LLViewerFetchedTexture * img = ptr.get(); + + // added extra granularity and verbosity for crash logging during 1.19.1 RC. -Brad + if(img == NULL) + { + llwarns << "DEV-12002: image is NULL!" << llendl; + } + + entries.insert(img); + + ++iter1; + update_counter--; + } + + // 256 cycled entries + update_counter = llmin(max_update_count, mUUIDMap.size()); + uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID); + while(update_counter > 0) + { + if (iter2 == mUUIDMap.end()) + { + iter2 = mUUIDMap.begin(); + } + mLastFetchUUID = iter2->first; + entries.insert(iter2->second); + ++iter2; + update_counter--; + } + + S32 min_count = max_priority_count + max_update_count/4; + for (std::set::iterator iter3 = entries.begin(); + iter3 != entries.end(); ) + { + LLPointer imagep = *iter3++; + + imagep->updateFetch(); + if (min_count <= 0 && image_op_timer.getElapsedTimeF32() > max_time) + { + break; + } + min_count--; + } + return image_op_timer.getElapsedTimeF32(); +} + +void LLViewerTextureList::updateImagesUpdateStats() +{ + if (mUpdateStats) + { + for (image_priority_list_t::iterator iter = mImageList.begin(); + iter != mImageList.end(); ) + { + LLViewerFetchedTexture* imagep = *iter++; + imagep->resetTextureStats(mForceResetTextureStats); + } + mUpdateStats = FALSE; + mForceResetTextureStats = FALSE; + } +} + +void LLViewerTextureList::decodeAllImages(F32 max_time) +{ + LLTimer timer; + if(gNoRender) return; + + // Update texture stats and priorities + std::vector > image_list; + for (image_priority_list_t::iterator iter = mImageList.begin(); + iter != mImageList.end(); ) + { + LLViewerFetchedTexture* imagep = *iter++; + image_list.push_back(imagep); + imagep->setInImageList(FALSE) ; + } + mImageList.clear(); + for (std::vector >::iterator iter = image_list.begin(); + iter != image_list.end(); ++iter) + { + LLViewerFetchedTexture* imagep = *iter; + imagep->processTextureStats(); + F32 decode_priority = imagep->calcDecodePriority(); + imagep->setDecodePriority(decode_priority); + mImageList.insert(imagep); + imagep->setInImageList(TRUE) ; + } + image_list.clear(); + + // Update fetch (decode) + for (image_priority_list_t::iterator iter = mImageList.begin(); + iter != mImageList.end(); ) + { + LLViewerFetchedTexture* imagep = *iter++; + imagep->updateFetch(); + } + // Run threads + S32 fetch_pending = 0; + while (1) + { + LLAppViewer::instance()->getTextureCache()->update(1); // unpauses the texture cache thread + LLAppViewer::instance()->getImageDecodeThread()->update(1); // unpauses the image thread + fetch_pending = LLAppViewer::instance()->getTextureFetch()->update(1); // unpauses the texture fetch thread + if (fetch_pending == 0 || timer.getElapsedTimeF32() > max_time) + { + break; + } + } + // Update fetch again + for (image_priority_list_t::iterator iter = mImageList.begin(); + iter != mImageList.end(); ) + { + LLViewerFetchedTexture* imagep = *iter++; + imagep->updateFetch(); + } + max_time -= timer.getElapsedTimeF32(); + max_time = llmax(max_time, .001f); + F32 create_time = updateImagesCreateTextures(max_time); + + LL_DEBUGS("ViewerImages") << "decodeAllImages() took " << timer.getElapsedTimeF32() << " seconds. " + << " fetch_pending " << fetch_pending + << " create_time " << create_time + << LL_ENDL; +} + + +BOOL LLViewerTextureList::createUploadFile(const std::string& filename, + const std::string& out_filename, + const U8 codec) +{ + // First, load the image. + LLPointer raw_image = new LLImageRaw; + + switch (codec) + { + case IMG_CODEC_BMP: + { + LLPointer bmp_image = new LLImageBMP; + + if (!bmp_image->load(filename)) + { + return FALSE; + } + + if (!bmp_image->decode(raw_image, 0.0f)) + { + return FALSE; + } + } + break; + case IMG_CODEC_TGA: + { + LLPointer tga_image = new LLImageTGA; + + if (!tga_image->load(filename)) + { + return FALSE; + } + + if (!tga_image->decode(raw_image)) + { + return FALSE; + } + + if( (tga_image->getComponents() != 3) && + (tga_image->getComponents() != 4) ) + { + tga_image->setLastError( "Image files with less than 3 or more than 4 components are not supported." ); + return FALSE; + } + } + break; + case IMG_CODEC_JPEG: + { + LLPointer jpeg_image = new LLImageJPEG; + + if (!jpeg_image->load(filename)) + { + return FALSE; + } + + if (!jpeg_image->decode(raw_image, 0.0f)) + { + return FALSE; + } + } + break; + case IMG_CODEC_PNG: + { + LLPointer png_image = new LLImagePNG; + + if (!png_image->load(filename)) + { + return FALSE; + } + + if (!png_image->decode(raw_image, 0.0f)) + { + return FALSE; + } + } + break; + default: + return FALSE; + } + + LLPointer compressedImage = convertToUploadFile(raw_image); + + if( !compressedImage->save(out_filename) ) + { + llinfos << "Couldn't create output file " << out_filename << llendl; + return FALSE; + } + + // test to see if the encode and save worked. + LLPointer integrity_test = new LLImageJ2C; + if( !integrity_test->loadAndValidate( out_filename ) ) + { + llinfos << "Image: " << out_filename << " is corrupt." << llendl; + return FALSE; + } + + return TRUE; +} + +// note: modifies the argument raw_image!!!! +LLPointer LLViewerTextureList::convertToUploadFile(LLPointer raw_image) +{ + raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + LLPointer compressedImage = new LLImageJ2C(); + compressedImage->setRate(0.f); + + if (gSavedSettings.getBOOL("LosslessJ2CUpload") && + (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)) + compressedImage->setReversible(TRUE); + + compressedImage->encode(raw_image, 0.0f); + + return compressedImage; +} + +// Returns min setting for TextureMemory (in MB) +S32 LLViewerTextureList::getMinVideoRamSetting() +{ + S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); + //min texture mem sets to 64M if total physical mem is more than 1.5GB + return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM_IN_MEGA_BYTES ; +} + +//static +// Returns max setting for TextureMemory (in MB) +S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) +{ + S32 max_texmem; + if (gGLManager.mVRAM != 0) + { + // Treat any card with < 32 MB (shudder) as having 32 MB + // - it's going to be swapping constantly regardless + S32 max_vram = gGLManager.mVRAM; + max_vram = llmax(max_vram, getMinVideoRamSetting()); + max_texmem = max_vram; + if (!get_recommended) + max_texmem *= 2; + } + else + { + if (get_recommended) + max_texmem = 128; + else + max_texmem = 512; + llwarns << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << llendl; + } + + S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB + //llinfos << "*** DETECTED " << system_ram << " MB of system memory." << llendl; + if (get_recommended) + max_texmem = llmin(max_texmem, (S32)(system_ram/2)); + else + max_texmem = llmin(max_texmem, (S32)(system_ram)); + + max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES); + + return max_texmem; +} + +const S32 VIDEO_CARD_FRAMEBUFFER_MEM = 12; // MB +const S32 MIN_MEM_FOR_NON_TEXTURE = 512 ; //MB +void LLViewerTextureList::updateMaxResidentTexMem(S32 mem) +{ + // Initialize the image pipeline VRAM settings + S32 cur_mem = gSavedSettings.getS32("TextureMemory"); + F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); + S32 default_mem = getMaxVideoRamSetting(true); // recommended default + if (mem == 0) + { + mem = cur_mem > 0 ? cur_mem : default_mem; + } + else if (mem < 0) + { + mem = default_mem; + } + + // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise + mem = llmin(mem, (S32) (mem_multiplier * (F32) default_mem)); + + mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting()); + if (mem != cur_mem) + { + gSavedSettings.setS32("TextureMemory", mem); + return; //listener will re-enter this function + } + + // TODO: set available resident texture mem based on use by other subsystems + // currently max(12MB, VRAM/4) assumed... + + S32 vb_mem = mem; + S32 fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4); + mMaxResidentTexMemInMegaBytes = (vb_mem - fb_mem) ; //in MB + + mMaxTotalTextureMemInMegaBytes = mMaxResidentTexMemInMegaBytes * 2; + if (mMaxResidentTexMemInMegaBytes > 640) + { + mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes >> 2); + } + + //system mem + S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB + + //minimum memory reserved for non-texture use. + //if system_raw >= 1GB, reserve at least 512MB for non-texture use; + //otherwise reserve half of the system_ram for non-texture use. + S32 min_non_texture_mem = llmin(system_ram / 2, MIN_MEM_FOR_NON_TEXTURE) ; + + if (mMaxTotalTextureMemInMegaBytes > system_ram - min_non_texture_mem) + { + mMaxTotalTextureMemInMegaBytes = system_ram - min_non_texture_mem ; + } + + llinfos << "Total Video Memory set to: " << vb_mem << " MB" << llendl; + llinfos << "Available Texture Memory set to: " << (vb_mem - fb_mem) << " MB" << llendl; +} + +/////////////////////////////////////////////////////////////////////////////// + +// static +void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data) +{ + LLFastTimer t(LLFastTimer::FTM_PROCESS_IMAGES); + + // Receive image header, copy into image object and decompresses + // if this is a one-packet image. + + LLUUID id; + + char ip_string[256]; + u32_to_ip_string(msg->getSenderIP(),ip_string); + + if (msg->getReceiveCompressedSize()) + { + gTextureList.mTextureBits += msg->getReceiveCompressedSize() * 8; + } + else + { + gTextureList.mTextureBits += msg->getReceiveSize() * 8; + } + gTextureList.mTexturePackets++; + + U8 codec; + U16 packets; + U32 totalbytes; + msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); + msg->getU8Fast(_PREHASH_ImageID, _PREHASH_Codec, codec); + msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packets, packets); + msg->getU32Fast(_PREHASH_ImageID, _PREHASH_Size, totalbytes); + + S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); + if (!data_size) + { + return; + } + if (data_size < 0) + { + // msg->getSizeFast() is probably trying to tell us there + // was an error. + llerrs << "image header chunk size was negative: " + << data_size << llendl; + return; + } + + // this buffer gets saved off in the packet list + U8 *data = new U8[data_size]; + msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); + + LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); + if (!image) + { + delete [] data; + return; + } + image->getLastPacketTimer()->reset(); + bool res = LLAppViewer::getTextureFetch()->receiveImageHeader(msg->getSender(), id, codec, packets, totalbytes, data_size, data); + if (!res) + { + delete[] data; + } +} + +// static +void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_data) +{ + LLMemType mt1(LLMemType::MTYPE_APPFMTIMAGE); + LLFastTimer t(LLFastTimer::FTM_PROCESS_IMAGES); + + // Receives image packet, copy into image object, + // checks if all packets received, decompresses if so. + + LLUUID id; + U16 packet_num; + + char ip_string[256]; + u32_to_ip_string(msg->getSenderIP(),ip_string); + + if (msg->getReceiveCompressedSize()) + { + gTextureList.mTextureBits += msg->getReceiveCompressedSize() * 8; + } + else + { + gTextureList.mTextureBits += msg->getReceiveSize() * 8; + } + gTextureList.mTexturePackets++; + + //llprintline("Start decode, image header..."); + msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); + msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packet, packet_num); + S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); + + if (!data_size) + { + return; + } + if (data_size < 0) + { + // msg->getSizeFast() is probably trying to tell us there + // was an error. + llerrs << "image data chunk size was negative: " + << data_size << llendl; + return; + } + if (data_size > MTUBYTES) + { + llerrs << "image data chunk too large: " << data_size << " bytes" << llendl; + return; + } + U8 *data = new U8[data_size]; + msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); + + LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); + if (!image) + { + delete [] data; + return; + } + image->getLastPacketTimer()->reset(); + bool res = LLAppViewer::getTextureFetch()->receiveImagePacket(msg->getSender(), id, packet_num, data_size, data); + if (!res) + { + delete[] data; + } +} + + +// We've been that the asset server does not contain the requested image id. +// static +void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data) +{ + LLFastTimer t(LLFastTimer::FTM_PROCESS_IMAGES); + LLUUID image_id; + msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, image_id); + + LLViewerFetchedTexture* image = gTextureList.findImage( image_id ); + if( image ) + { + image->setIsMissingAsset(); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +//static +const U32 SIXTEEN_MEG = 0x1000000; +S32 LLViewerTextureList::calcMaxTextureRAM() +{ + // Decide the maximum amount of RAM we should allow the user to allocate to texture cache + LLMemoryInfo memory_info; + U32 available_memory = memory_info.getPhysicalMemoryClamped(); + + clamp_rescale((F32)available_memory, + (F32)(SIXTEEN_MEG * 16), + (F32)U32_MAX, + (F32)(SIXTEEN_MEG * 4), + (F32)(U32_MAX >> 1)); + return available_memory; +} + +/////////////////////////////////////////////////////////////////////////////// + +// explicitly cleanup resources, as this is a singleton class with process +// lifetime so ability to perform std::map operations in destructor is not +// guaranteed. +void LLUIImageList::cleanUp() +{ + mUIImages.clear(); + mUITextureList.clear() ; +} + +LLUIImagePtr LLUIImageList::getUIImageByID(const LLUUID& image_id) +{ + // use id as image name + std::string image_name = image_id.asString(); + + // look for existing image + uuid_ui_image_map_t::iterator found_it = mUIImages.find(image_name); + if (found_it != mUIImages.end()) + { + return found_it->second; + } + + return loadUIImageByID(image_id); +} + +LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name) +{ + // look for existing image + uuid_ui_image_map_t::iterator found_it = mUIImages.find(image_name); + if (found_it != mUIImages.end()) + { + return found_it->second; + } + + return loadUIImageByName(image_name, image_name); +} + +LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect) +{ + LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, MIPMAP_NO, IMMEDIATE_YES); + return loadUIImage(imagep, name, use_mips, scale_rect); +} + +LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id, BOOL use_mips, const LLRect& scale_rect) +{ + LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, MIPMAP_NO, IMMEDIATE_YES); + return loadUIImage(imagep, id.asString(), use_mips, scale_rect); +} + +LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips, const LLRect& scale_rect) +{ + if (!imagep) return NULL; + + imagep->setAddressMode(LLTexUnit::TAM_CLAMP); + + //all UI images are non-deletable + imagep->setNoDelete() ; + + LLUIImagePtr new_imagep = new LLUIImage(name, imagep); + mUIImages.insert(std::make_pair(name, new_imagep)); + mUITextureList.push_back(imagep) ; + + LLUIImageLoadData* datap = new LLUIImageLoadData; + datap->mImageName = name; + datap->mImageScaleRegion = scale_rect; + + imagep->setLoadedCallback(onUIImageLoaded, 0, FALSE, FALSE, datap); + + return new_imagep; +} + +LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect) +{ + // look for existing image + uuid_ui_image_map_t::iterator found_it = mUIImages.find(name); + if (found_it != mUIImages.end()) + { + // image already loaded! + llerrs << "UI Image " << name << " already loaded." << llendl; + } + + return loadUIImageByName(name, filename, use_mips, scale_rect); +} + +//static +void LLUIImageList::onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* user_data ) +{ + if(!success || !user_data) + { + return; + } + + LLUIImageLoadData* image_datap = (LLUIImageLoadData*)user_data; + std::string ui_image_name = image_datap->mImageName; + LLRect scale_rect = image_datap->mImageScaleRegion; + if (final) + { + delete image_datap; + } + + LLUIImageList* instance = getInstance(); + + uuid_ui_image_map_t::iterator found_it = instance->mUIImages.find(ui_image_name); + if (found_it != instance->mUIImages.end()) + { + LLUIImagePtr imagep = found_it->second; + + // for images grabbed from local files, apply clipping rectangle to restore original dimensions + // from power-of-2 gl image + if (success && imagep.notNull() && src_vi && !src_vi->getLocalFileName().empty()) + { + F32 clip_x = (F32)src_vi->getOriginalWidth() / (F32)src_vi->getFullWidth(); + F32 clip_y = (F32)src_vi->getOriginalHeight() / (F32)src_vi->getFullHeight(); + imagep->setClipRegion(LLRectf(0.f, clip_y, clip_x, 0.f)); + if (scale_rect != LLRect::null) + { + imagep->setScaleRegion( + LLRectf(llclamp((F32)scale_rect.mLeft / (F32)imagep->getWidth(), 0.f, 1.f), + llclamp((F32)scale_rect.mTop / (F32)imagep->getHeight(), 0.f, 1.f), + llclamp((F32)scale_rect.mRight / (F32)imagep->getWidth(), 0.f, 1.f), + llclamp((F32)scale_rect.mBottom / (F32)imagep->getHeight(), 0.f, 1.f))); + } + } + } +} + +struct UIImageDeclaration : public LLInitParam::Block +{ + Mandatory name; + Optional file_name; + Optional preload; + Optional scale_rect; + Optional use_mips; + + UIImageDeclaration() + : name("name"), + file_name("file_name"), + preload("preload", false), + scale_rect("scale"), + use_mips("use_mips", false) + {} +}; + +struct UIImageDeclarations : public LLInitParam::Block +{ + Mandatory version; + Multiple textures; + + UIImageDeclarations() + : version("version"), + textures("texture") + {} +}; + +bool LLUIImageList::initFromFile() +{ + // construct path to canonical textures.xml in default skin dir + std::string base_file_path = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "default", "textures", "textures.xml"); + + LLXMLNodePtr root; + + if (!LLXMLNode::parseFile(base_file_path, root, NULL)) + { + llwarns << "Unable to parse UI image list file " << base_file_path << llendl; + return false; + } + + std::vector paths; + // path to current selected skin + paths.push_back(gDirUtilp->getSkinDir() + + gDirUtilp->getDirDelimiter() + + "textures" + + gDirUtilp->getDirDelimiter() + + "textures.xml"); + // path to user overrides on current skin + paths.push_back(gDirUtilp->getUserSkinDir() + + gDirUtilp->getDirDelimiter() + + "textures" + + gDirUtilp->getDirDelimiter() + + "textures.xml"); + + // apply skinned xml files incrementally + for(std::vector::iterator path_it = paths.begin(); + path_it != paths.end(); + ++path_it) + { + // don't reapply base file to itself + if (!path_it->empty() && (*path_it) != base_file_path) + { + LLXMLNodePtr update_root; + if (LLXMLNode::parseFile(*path_it, update_root, NULL)) + { + LLXMLNode::updateNode(root, update_root); + } + } + } + + UIImageDeclarations images; + LLXUIParser::instance().readXUI(root, images); + + if (!images.validateBlock()) return false; + + enum e_decode_pass + { + PASS_DECODE_NOW, + PASS_DECODE_LATER, + NUM_PASSES + }; + + for (S32 cur_pass = PASS_DECODE_NOW; cur_pass < NUM_PASSES; cur_pass++) + { + for (LLInitParam::ParamIterator::const_iterator image_it = images.textures().begin(); + image_it != images.textures().end(); + ++image_it) + { + std::string file_name = image_it->file_name.isProvided() ? image_it->file_name() : image_it->name(); + + // load high priority textures on first pass (to kick off decode) + enum e_decode_pass decode_pass = image_it->preload ? PASS_DECODE_NOW : PASS_DECODE_LATER; + if (decode_pass != cur_pass) + { + continue; + } + preloadUIImage(image_it->name, file_name, image_it->use_mips, image_it->scale_rect); + } + + if (cur_pass == PASS_DECODE_NOW && !gSavedSettings.getBOOL("NoPreload")) + { + gTextureList.decodeAllImages(10.f); // decode preloaded images + } + } + return true; +} + + diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h new file mode 100644 index 0000000000..11d1dd855f --- /dev/null +++ b/indra/newview/llviewertexturelist.h @@ -0,0 +1,243 @@ +/** + * @file llviewertexturelist.h + * @brief Object for managing the list of images within a region + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLVIEWERTEXTURELIST_H +#define LL_LLVIEWERTEXTURELIST_H + +#include "lluuid.h" +//#include "message.h" +#include "llgl.h" +#include "llstat.h" +#include "llviewertexture.h" +#include "llui.h" +#include +#include + +const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128; + +const BOOL MIPMAP_YES = TRUE; +const BOOL MIPMAP_NO = FALSE; + +const BOOL GL_TEXTURE_YES = TRUE; +const BOOL GL_TEXTURE_NO = FALSE; + +const BOOL IMMEDIATE_YES = TRUE; +const BOOL IMMEDIATE_NO = FALSE; + +class LLImageJ2C; +class LLMessageSystem; +class LLTextureView; + +typedef void (*LLImageCallback)(BOOL success, + LLViewerFetchedTexture *src_vi, + LLImageRaw* src, + LLImageRaw* src_aux, + S32 discard_level, + BOOL final, + void* userdata); + +class LLViewerTextureList +{ + LOG_CLASS(LLViewerTextureList); + + friend class LLTextureView; + friend class LLViewerTextureManager; + +public: + static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec); + static LLPointer convertToUploadFile(LLPointer raw_image); + static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data ); + static S32 calcMaxTextureRAM(); + static void receiveImageHeader(LLMessageSystem *msg, void **user_data); + static void receiveImagePacket(LLMessageSystem *msg, void **user_data); + +public: + LLViewerTextureList(); + ~LLViewerTextureList(); + + void init(); + void shutdown(); + void dump(); + void destroyGL(BOOL save_state = TRUE); + void restoreGL(); + + LLViewerFetchedTexture *findImage(const LLUUID &image_id); + + void dirtyImage(LLViewerFetchedTexture *image); + + // Using image stats, determine what images are necessary, and perform image updates. + void updateImages(F32 max_time); + void forceImmediateUpdate(LLViewerFetchedTexture* imagep) ; + + // Decode and create textures for all images currently in list. + void decodeAllImages(F32 max_decode_time); + + void handleIRCallback(void **data, const S32 number); + + void setUpdateStats(BOOL b) { mUpdateStats = b; } + + S32 getMaxResidentTexMem() const { return mMaxResidentTexMemInMegaBytes; } + S32 getMaxTotalTextureMem() const { return mMaxTotalTextureMemInMegaBytes;} + S32 getNumImages() { return mImageList.size(); } + + void updateMaxResidentTexMem(S32 mem); + + void doPreloadImages(); + void doPrefetchImages(); + + static S32 getMinVideoRamSetting(); + static S32 getMaxVideoRamSetting(bool get_recommended = false); + +private: + void updateImagesDecodePriorities(); + F32 updateImagesCreateTextures(F32 max_time); + F32 updateImagesFetchTextures(F32 max_time); + void updateImagesUpdateStats(); + + void addImage(LLViewerFetchedTexture *image); + void deleteImage(LLViewerFetchedTexture *image); + + void addImageToList(LLViewerFetchedTexture *image); + void removeImageFromList(LLViewerFetchedTexture *image); + + LLViewerFetchedTexture * getImage(const LLUUID &image_id, + BOOL usemipmap = TRUE, + BOOL level_immediate = FALSE, // Get the requested level immediately upon creation. + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + LLHost request_from_host = LLHost() + ); + + LLViewerFetchedTexture * getImageFromFile(const std::string& filename, + BOOL usemipmap = TRUE, + BOOL level_immediate = FALSE, // Get the requested level immediately upon creation. + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + const LLUUID& force_id = LLUUID::null + ); + + LLViewerFetchedTexture* createImage(const LLUUID &image_id, + BOOL usemipmap = TRUE, + BOOL level_immediate = FALSE, // Get the requested level immediately upon creation. + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + LLHost request_from_host = LLHost() + ); + + // Request image from a specific host, used for baked avatar textures. + // Implemented in header in case someone changes default params above. JC + LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, LLHost host) + { return getImage(image_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); } + +public: + typedef std::set > image_list_t; + image_list_t mLoadingStreamList; + image_list_t mCreateTextureList; + image_list_t mCallbackList; + + // Note: just raw pointers because they are never referenced, just compared against + std::set mDirtyTextureList; + + BOOL mForceResetTextureStats; + +private: + typedef std::map< LLUUID, LLPointer > uuid_map_t; + uuid_map_t mUUIDMap; + LLUUID mLastUpdateUUID; + LLUUID mLastFetchUUID; + + typedef std::set, LLViewerFetchedTexture::Compare> image_priority_list_t; + image_priority_list_t mImageList; + + // simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon + std::set > mImagePreloads; + + BOOL mUpdateStats; + S32 mMaxResidentTexMemInMegaBytes; + S32 mMaxTotalTextureMemInMegaBytes; + LLFrameTimer mForceDecodeTimer; + +public: + U32 mTextureBits; + U32 mTexturePackets; + +private: + S32 mNumImages; + static void (*sUUIDCallback)(void**, const LLUUID &); +}; + +class LLUIImageList : public LLImageProviderInterface, public LLSingleton +{ +public: + // LLImageProviderInterface + LLUIImagePtr getUIImageByID(const LLUUID& id); + LLUIImagePtr getUIImage(const std::string& name); + void cleanUp(); + + bool initFromFile(); + + LLUIImagePtr preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect); + + static void onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); +private: + LLUIImagePtr loadUIImageByName(const std::string& name, const std::string& filename, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null); + LLUIImagePtr loadUIImageByID(const LLUUID& id, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null); + + LLUIImagePtr loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null); + + + struct LLUIImageLoadData + { + std::string mImageName; + LLRect mImageScaleRegion; + }; + + typedef std::map< std::string, LLPointer > uuid_ui_image_map_t; + uuid_ui_image_map_t mUIImages; + + // + //keep a copy of UI textures to prevent them to be deleted. + //mGLTexturep of each UI texture equals to some LLUIImage.mImage. + std::list< LLPointer > mUITextureList ; +}; + +const BOOL GLTEXTURE_TRUE = TRUE; +const BOOL GLTEXTURE_FALSE = FALSE; +const BOOL MIPMAP_TRUE = TRUE; +const BOOL MIPMAP_FALSE = FALSE; + +extern LLViewerTextureList gTextureList; + +#endif diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 91fc95cf6f..b4838db690 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -82,7 +82,6 @@ #include "llagent.h" #include "llalertdialog.h" #include "llbox.h" -#include "llchatbar.h" #include "llconsole.h" #include "llviewercontrol.h" #include "llcylinder.h" @@ -97,7 +96,6 @@ #include "llfeaturemanager.h" #include "llfilepicker.h" #include "llfloater.h" -#include "llfloateractivespeakers.h" #include "llfloaterbuildoptions.h" #include "llfloaterbuyland.h" #include "llfloatercamera.h" @@ -113,6 +111,7 @@ #include "llfloatertools.h" #include "llfloaterworldmap.h" #include "llfocusmgr.h" +#include "llfontfreetype.h" #include "llgesturemgr.h" #include "llglheaders.h" #include "llhoverview.h" @@ -120,7 +119,7 @@ #include "llhudview.h" #include "llimagebmp.h" #include "llimagej2c.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" @@ -166,7 +165,7 @@ #include "llvieweraudio.h" #include "llviewercamera.h" #include "llviewergesture.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerinventory.h" #include "llviewerkeyboard.h" #include "llviewermenu.h" @@ -189,10 +188,13 @@ #include "llviewernetwork.h" #include "llpostprocess.h" #include "llbottomtray.h" +#include "llnearbychatbar.h" + +#include "llnotificationmanager.h" #include "llfloaternotificationsconsole.h" -#include "llnearbychathistory.h" +#include "llnearbychat.h" #include "llviewerwindowlistener.h" #if LL_WINDOWS @@ -540,7 +542,7 @@ public: ypos += y_inc; } // only display these messages if we are actually rendering beacons at this moment - if (LLPipeline::getRenderBeacons(NULL) && gSavedSettings.getBOOL("BeaconAlwaysOn")) + if (LLPipeline::getRenderBeacons(NULL) && LLFloaterReg::instanceVisible("beacons")) { if (LLPipeline::getRenderParticleBeacons(NULL)) { @@ -607,11 +609,11 @@ bool LLViewerWindow::shouldShowToolTipFor(LLMouseHandler *mh) { LLMouseHandler::EShowToolTip showlevel = mh->getShowToolTip(); - return ( - showlevel == LLMouseHandler::SHOW_ALWAYS || - (showlevel == LLMouseHandler::SHOW_IF_NOT_BLOCKED && - !mToolTipBlocked) - ); + bool tool_tip_allowed = (showlevel == LLMouseHandler::SHOW_ALWAYS + || (showlevel == LLMouseHandler::SHOW_IF_NOT_BLOCKED + && !mToolTipBlocked)); + + return tool_tip_allowed; } return false; } @@ -1363,8 +1365,8 @@ LLViewerWindow::LLViewerWindow( // Init the image list. Must happen after GL is initialized and before the images that // LLViewerWindow needs are requested. - gImageList.init(); - LLViewerImage::initClass(); + gTextureList.init(); + LLViewerTextureManager::init() ; gBumpImageList.init(); // Init font system, but don't actually load the fonts yet @@ -1532,10 +1534,10 @@ void LLViewerWindow::initBase() params.rect(LLRect (0, 1, 1, 0)); params.h_pad(4); params.v_pad(2); - params.text_color(gSavedSkinSettings.getColor( "ToolTipTextColor" )); - params.border_color(gSavedSkinSettings.getColor( "ToolTipBorderColor" )); + params.text_color(LLUIColorTable::instance().getColor( "ToolTipTextColor" )); + params.border_color(LLUIColorTable::instance().getColor( "ToolTipBorderColor" )); params.border_visible(false); - params.background_color(gSavedSkinSettings.getColor( "ToolTipBgColor" )); + params.background_color(LLUIColorTable::instance().getColor( "ToolTipBgColor" )); params.bg_visible(true); params.font.style("NORMAL"); params.border_drop_shadow_visible(true); @@ -1557,22 +1559,22 @@ void LLViewerWindow::initWorldUI() gIMMgr = LLIMMgr::getInstance(); + // side tray + getRootView()->addChild(LLSideTray::getInstance()); + + getRootView()->sendChildToFront(gFloaterView); + getRootView()->sendChildToFront(gSnapshotFloaterView); + // new bottom panel + getRootView()->addChild(LLBottomTray::getInstance()); + // Make sure Bottom Tray is behind Side Tray regardless "addChild" order. + getRootView()->sendChildToBack(LLBottomTray::getInstance()); LLRect rc = LLBottomTray::getInstance()->getRect(); rc.mLeft = 0; rc.mRight = mRootView->getRect().getWidth(); - mRootView->addChild(LLBottomTray::getInstance()); LLBottomTray::getInstance()->reshape(rc.getWidth(),rc.getHeight(),FALSE); LLBottomTray::getInstance()->setRect(rc); - // Updating of bottom boundary of gConsole to avoid overlapping - if (gConsole) - { - LLRect cr = gConsole->getRect(); - cr.mBottom += LLBottomTray::getInstance()->getRect().getHeight(); - gConsole->setRect(cr); - } - // View for hover information LLHoverView::Params hvp; hvp.name("gHoverview"); @@ -1615,7 +1617,6 @@ void LLViewerWindow::initWorldUI() // Force gFloaterWorldMap to initialize LLFloaterReg::getInstance("world_map"); - LLFloaterReg::hideInstance("world_map"); // Force gFloaterTools to initialize LLFloaterReg::getInstance("build"); @@ -1643,16 +1644,22 @@ void LLViewerWindow::initWorldUI() getRootView()->addChild(gStatusBar); getRootView()->addChild(navbar); - // side tray - getRootView()->addChild(LLSideTray::getInstance()); //sidetray //then notify area //then menu - getRootView()->sendChildToFront(LLSideTray::getInstance()); + //getRootView()->sendChildToFront(LLSideTray::getInstance()); + getRootView()->sendChildToFront(gNotifyBoxView); // menu holder appears on top to get first pass at all mouse events getRootView()->sendChildToFront(gMenuHolder); + + //Channel Manager + LLNotificationsUI::LLChannelManager* channel_manager = LLNotificationsUI::LLChannelManager::getInstance(); + getRootView()->addChild(channel_manager); + //Notification Manager + LLNotificationsUI::LLNotificationManager* notify_manager = LLNotificationsUI::LLNotificationManager::getInstance(); + getRootView()->addChild(notify_manager); } // Destroy the UI @@ -1702,7 +1709,7 @@ void LLViewerWindow::shutdownGL() gSky.cleanup(); stop_glerror(); - gImageList.shutdown(); + gTextureList.shutdown(); stop_glerror(); gBumpImageList.shutdown(); @@ -1714,7 +1721,7 @@ void LLViewerWindow::shutdownGL() gPipeline.cleanup(); stop_glerror(); - LLViewerImage::cleanupClass(); + LLViewerTextureManager::cleanup() ; llinfos << "Cleaning up select manager" << llendl; LLSelectMgr::getInstance()->cleanup(); @@ -1837,7 +1844,7 @@ void LLViewerWindow::reshape(S32 width, S32 height) // store the mode the user wants (even if not there yet) - gSavedSettings.setBOOL("NotFullScreen", !mWantFullscreen); + gSavedSettings.setBOOL("WindowFullScreen", mWantFullscreen); // store new settings for the mode we are in, regardless if (!mWindow->getFullscreen()) @@ -1864,8 +1871,11 @@ void LLViewerWindow::reshape(S32 width, S32 height) // Hide normal UI when a logon fails void LLViewerWindow::setNormalControlsVisible( BOOL visible ) { - LLBottomTray::getInstance()->setVisible(visible); - LLBottomTray::getInstance()->setEnabled(visible); + if(LLBottomTray::instanceExists()) + { + LLBottomTray::getInstance()->setVisible(visible); + LLBottomTray::getInstance()->setEnabled(visible); + } if ( gMenuBarView ) { @@ -1897,19 +1907,19 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid) if(god_mode && LLViewerLogin::getInstance()->isInProductionGrid()) { - new_bg_color = gSavedSkinSettings.getColor( "MenuBarGodBgColor" ); + new_bg_color = LLUIColorTable::instance().getColor( "MenuBarGodBgColor" ); } else if(god_mode && !LLViewerLogin::getInstance()->isInProductionGrid()) { - new_bg_color = gSavedSkinSettings.getColor( "MenuNonProductionGodBgColor" ); + new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" ); } else if(!god_mode && !LLViewerLogin::getInstance()->isInProductionGrid()) { - new_bg_color = gSavedSkinSettings.getColor( "MenuNonProductionBgColor" ); + new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" ); } else { - new_bg_color = gSavedSkinSettings.getColor( "MenuBarBgColor" ); + new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBgColor" ); } if(gMenuBarView) @@ -2172,10 +2182,11 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus(); if( keyboard_focus ) { + LLLineEditor* chat_editor = LLBottomTray::instanceExists() ? LLBottomTray::getInstance()->getNearbyChatBar()->getChatBox() : NULL; // arrow keys move avatar while chatting hack - if (gChatBar && gChatBar->inputEditorHasFocus()) + if (chat_editor && chat_editor->hasFocus()) { - if (gChatBar->getCurrentChat().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar")) + if (chat_editor->getText().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar")) { switch(key) { @@ -2216,7 +2227,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) } // Try for a new-format gesture - if (gGestureManager.triggerGesture(key, mask)) + if (LLGestureManager::instance().triggerGesture(key, mask)) { return TRUE; } @@ -2392,6 +2403,29 @@ void LLViewerWindow::moveCursorToCenter() LLUI::setCursorPositionScreen(x, y); } +void LLViewerWindow::updateBottomTrayRect() +{ + if(LLBottomTray::instanceExists() && LLSideTray::instanceCreated()) + { + S32 side_tray_width = 0; + if(LLSideTray::getInstance()->getVisible()) + { + side_tray_width = LLSideTray::getInstance()->getTrayWidth(); + } + + LLBottomTray* bottom_tray = LLBottomTray::getInstance(); + S32 right = llround((F32)mWindowRect.mRight / mDisplayScale.mV[VX]) - side_tray_width; + + LLRect rc = bottom_tray->getRect(); + if (right != rc.mRight) + { + rc.mRight = right; + bottom_tray->reshape(rc.getWidth(), rc.getHeight(), FALSE); + bottom_tray->setRect(rc); + } + } +} + ////////////////////////////////////////////////////////////////////// // // Hover handlers @@ -2405,6 +2439,8 @@ void LLViewerWindow::updateUI() updateWorldViewRect(); + updateBottomTrayRect(); + LLView::sMouseHandlerMessage.clear(); S32 x = mCurrentMousePoint.mX; @@ -2621,57 +2657,91 @@ void LLViewerWindow::updateUI() // Show a new tool tip (or update one that is alrady shown) BOOL tool_tip_handled = FALSE; std::string tool_tip_msg; - F32 tooltip_delay = gSavedSettings.getF32( "ToolTipDelay" ); - //HACK: hack for tool-based tooltips which need to pop up more quickly - //Also for show xui names as tooltips debug mode - if ((mouse_captor && !mouse_captor->isView()) || LLUI::sShowXUINames) - { - tooltip_delay = gSavedSettings.getF32( "DragAndDropToolTipDelay" ); - } - if( handled && - gMouseIdleTimer.getElapsedTimeF32() > tooltip_delay && - !mWindow->isCursorHidden() ) + if( handled + && !mWindow->isCursorHidden() + && mToolTip) { LLRect screen_sticky_rect; - LLMouseHandler *mh; + LLMouseHandler *tooltip_source = NULL; S32 local_x, local_y; if (mouse_captor) { mouse_captor->screenPointToLocal(x, y, &local_x, &local_y); - mh = mouse_captor; + tooltip_source = mouse_captor; } else if (handled_by_top_ctrl) { top_ctrl->screenPointToLocal(x, y, &local_x, &local_y); - mh = top_ctrl; + tooltip_source = top_ctrl; } else { local_x = x; local_y = y; - mh = mRootView; + tooltip_source = mRootView; } - BOOL tooltip_vis = FALSE; - if (shouldShowToolTipFor(mh)) + F32 tooltip_delay = gSavedSettings.getF32( "ToolTipDelay" ); + //HACK: hack for tool-based tooltips which need to pop up more quickly + //Also for show xui names as tooltips debug mode + if ((gFocusMgr.getMouseCapture() + && !gFocusMgr.getMouseCapture()->isView()) + || LLUI::sShowXUINames) { - tool_tip_handled = mh->handleToolTip(local_x, local_y, tool_tip_msg, &screen_sticky_rect ); + tooltip_delay = gSavedSettings.getF32( "DragAndDropToolTipDelay" ); + } + + + BOOL tooltip_vis = FALSE; + if (shouldShowToolTipFor(tooltip_source)) + { + tool_tip_handled = tooltip_source->handleToolTip(local_x, local_y, tool_tip_msg, &screen_sticky_rect ); + // if we actually got a tooltip back... if( tool_tip_handled && !tool_tip_msg.empty() ) { - mToolTipStickyRect = screen_sticky_rect; - mToolTip->setWrappedText( tool_tip_msg, 200 ); - mToolTip->reshapeToFitText(); - mToolTip->setOrigin( x, y ); - LLRect virtual_window_rect(0, getWindowHeight(), getWindowWidth(), 0); - mToolTip->translateIntoRect( virtual_window_rect, FALSE ); - tooltip_vis = TRUE; + if (mToolTip->getVisible() // already showing a tooltip + || gMouseIdleTimer.getElapsedTimeF32() > tooltip_delay) // mouse has been still long enough to show the tooltip + { + // if tooltip has changed or mouse has moved outside of "sticky" rectangle... + if (mLastToolTipMessage != tool_tip_msg + || !mToolTipStickyRect.pointInRect(x, y)) + { + //...update "sticky" rect and tooltip position + mToolTipStickyRect = screen_sticky_rect; + mToolTip->setOrigin( x, y ); + } + + // remember this tooltip so we know when it changes + mLastToolTipMessage = tool_tip_msg; + mToolTip->setWrappedText( tool_tip_msg, 200 ); + mToolTip->reshapeToFitText(); + LLRect virtual_window_rect(0, getWindowHeight(), getWindowWidth(), 0); + mToolTip->translateIntoRect( virtual_window_rect, FALSE ); + tooltip_vis = TRUE; + } } } - if (mToolTip) + // HACK: assuming tooltip background is in ToolTipBGColor, perform fade out + LLColor4 bg_color = LLUIColorTable::instance().getColor( "ToolTipBgColor" ); + if (tooltip_vis) { - mToolTip->setVisible( tooltip_vis ); + mToolTipFadeTimer.stop(); + mToolTip->setBackgroundColor(bg_color); } + else + { + if (!mToolTipFadeTimer.getStarted()) + { + mToolTipFadeTimer.start(); + } + F32 tool_tip_fade_time = gSavedSettings.getF32("ToolTipFadeTime"); + bg_color.mV[VALPHA] = clamp_rescale(mToolTipFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time, bg_color.mV[VALPHA], 0.f); + mToolTip->setBackgroundColor(bg_color); + } + + // above interpolation of bg_color alpha is guaranteed to reach 0.f exactly + mToolTip->setVisible( bg_color.mV[VALPHA] != 0.f ); } updateLayout(); @@ -2781,6 +2851,14 @@ void LLViewerWindow::updateLayout() } gMenuBarView->setItemVisible("BuildTools", gFloaterTools->getVisible()); } + + // Always update console + if(gConsole) + { + LLRect console_rect = getChatConsoleRect(); + gConsole->reshape(console_rect.getWidth(), console_rect.getHeight()); + gConsole->setRect(console_rect); + } } void LLViewerWindow::updateMouseDelta() @@ -2897,40 +2975,33 @@ void LLViewerWindow::updateKeyboardFocus() if(LLSideTray::instanceCreated())//just getInstance will create sidetray. we don't want this LLSideTray::getInstance()->highlightFocused(); - - - if (gSavedSettings.getBOOL("ChatBarStealsFocus") - && gChatBar - && gFocusMgr.getKeyboardFocus() == NULL - && gChatBar->isInVisibleChain()) - { - gChatBar->startChat(NULL); - } - - } -void LLViewerWindow::updateWorldViewRect() +void LLViewerWindow::updateWorldViewRect(bool use_full_window) { if (!LLSideTray::instanceCreated()) return; + // start off using whole window to render world LLRect new_world_rect = mWindowRect; - // pull in right side of world view based on sidetray - LLSideTray* sidetray = LLSideTray::getInstance(); - if (sidetray->getVisible()) + if (use_full_window == false) { - new_world_rect.mRight -= llround((F32)sidetray->getTrayWidth() * mDisplayScale.mV[VX]); - } - - // push top of world view below nav bar - if (LLNavigationBar::getInstance()->getVisible()) - { - LLNavigationBar* barp = LLNavigationBar::getInstance(); - LLRect nav_bar_rect; - if(barp->localRectToOtherView(barp->getLocalRect(), &nav_bar_rect, mRootView)) + // pull in right side of world view based on sidetray + LLSideTray* sidetray = LLSideTray::getInstance(); + if (sidetray->getVisible()) { - new_world_rect.mTop = llround((F32)LLNavigationBar::getInstance()->getRect().mBottom * mDisplayScale.mV[VY]); + new_world_rect.mRight -= llround((F32)sidetray->getTrayWidth() * mDisplayScale.mV[VX]); + } + + // push top of world view below nav bar + if (LLNavigationBar::getInstance()->getVisible()) + { + LLNavigationBar* barp = LLNavigationBar::getInstance(); + LLRect nav_bar_rect; + if(barp->localRectToOtherView(barp->getLocalRect(), &nav_bar_rect, mRootView)) + { + new_world_rect.mTop = llround((F32)LLNavigationBar::getInstance()->getRect().mBottom * mDisplayScale.mV[VY]); + } } } @@ -3417,12 +3488,12 @@ LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const // find vertical field of view F32 fov = LLViewerCamera::getInstance()->getView(); - // find world view center - F32 center_x = (F32)getWorldViewRect().getCenterX(); - F32 center_y = (F32)getWorldViewRect().getCenterY(); + // find world view center in scaled ui coordinates + F32 center_x = (F32)getWorldViewRect().getCenterX() / mDisplayScale.mV[VX]; + F32 center_y = (F32)getWorldViewRect().getCenterY() / mDisplayScale.mV[VY]; // calculate pixel distance to screen - F32 distance = (getWorldViewHeight() / 2.f) / (tan(fov / 2.f)); + F32 distance = ((F32)getWorldViewHeight() / (mDisplayScale.mV[VY] * 2.f)) / (tan(fov / 2.f)); // calculate click point relative to middle of screen F32 click_x = x - center_x; @@ -3441,11 +3512,11 @@ LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const LLVector3 LLViewerWindow::mousePointHUD(const S32 x, const S32 y) const { // find screen resolution - S32 height = getWorldViewHeight(); + S32 height = llround((F32)getWorldViewHeight() / mDisplayScale.mV[VY]); // find world view center - F32 center_x = (F32)getWorldViewRect().getCenterX(); - F32 center_y = (F32)getWorldViewRect().getCenterY(); + F32 center_x = (F32)getWorldViewRect().getCenterX() / mDisplayScale.mV[VX]; + F32 center_y = (F32)getWorldViewRect().getCenterY() / mDisplayScale.mV[VY]; // remap with uniform scale (1/height) so that top is -0.5, bottom is +0.5 F32 hud_x = -((F32)x - center_x) / height; @@ -3463,12 +3534,12 @@ LLVector3 LLViewerWindow::mouseDirectionCamera(const S32 x, const S32 y) const F32 fov_width = fov_height * LLViewerCamera::getInstance()->getAspect(); // find screen resolution - S32 height = getWorldViewHeight(); - S32 width = getWorldViewWidth(); + S32 height = llround((F32)getWorldViewHeight() / mDisplayScale.mV[VY]); + S32 width = llround((F32)getWorldViewWidth() / mDisplayScale.mV[VX]); // find world view center - F32 center_x = (F32)getWorldViewRect().getCenterX(); - F32 center_y = (F32)getWorldViewRect().getCenterY(); + F32 center_x = (F32)getWorldViewRect().getCenterX() / mDisplayScale.mV[VX]; + F32 center_y = (F32)getWorldViewRect().getCenterY() / mDisplayScale.mV[VY]; // calculate click point relative to middle of screen F32 click_x = (((F32)x - center_x) / (F32)width) * fov_width * -1.f; @@ -3919,6 +3990,9 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei // PRE SNAPSHOT gDisplaySwapBuffers = FALSE; + // if not showing ui, use full window to render world view + updateWorldViewRect(!show_ui); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); setCursor(UI_CURSOR_WAIT); @@ -4186,30 +4260,19 @@ void LLViewerWindow::destroyWindow() void LLViewerWindow::drawMouselookInstructions() { - // Draw instructions for mouselook ("Press ESC to leave Mouselook" in a box at the top of the screen.) + // Draw instructions for mouselook ("Press ESC to return to World View" partially transparent at the bottom of the screen.) const std::string instructions = LLTrans::getString("LeaveMouselook"); - const LLFontGL* font = LLFontGL::getFontSansSerif(); - - const S32 INSTRUCTIONS_PAD = 5; - LLRect instructions_rect; - instructions_rect.setLeftTopAndSize( - mWorldViewRect.mLeft + INSTRUCTIONS_PAD, - mWorldViewRect.mTop - INSTRUCTIONS_PAD, - font->getWidth( instructions ) + 2 * INSTRUCTIONS_PAD, - llround(font->getLineHeight() + 2 * INSTRUCTIONS_PAD)); - - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color4f( 0.9f, 0.9f, 0.9f, 1.0f ); - gl_rect_2d( instructions_rect ); - } + const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Huge", LLFontGL::BOLD)); + //to be on top of Bottom bar when it is opened + const S32 INSTRUCTIONS_PAD = 50; + font->renderUTF8( instructions, 0, - instructions_rect.mLeft + INSTRUCTIONS_PAD, - instructions_rect.mTop - INSTRUCTIONS_PAD, - LLColor4( 0.0f, 0.0f, 0.0f, 1.f ), - LLFontGL::LEFT, LLFontGL::TOP); + mWorldViewRect.getCenterX(), + mWorldViewRect.mBottom + INSTRUCTIONS_PAD, + LLColor4( 0.0f, 0.0f, 0.0f, 0.6f ), + LLFontGL::HCENTER, LLFontGL::TOP); } @@ -4328,11 +4391,6 @@ BOOL LLViewerWindow::getShowProgress() const return (mProgressView && mProgressView->getVisible()); } -void LLViewerWindow::handleLoginComplete() -{ - LLNavigationBar::getInstance()->handleLoginComplete(); -} - void LLViewerWindow::moveProgressViewToFront() { if( mProgressView && mRootView ) @@ -4393,7 +4451,7 @@ void LLViewerWindow::stopGL(BOOL save_state) //Note: --bao //if not necessary, do not change the order of the function calls in this function. //if change something, make sure it will not break anything. - //especially be careful to put anything behind gImageList.destroyGL(save_state); + //especially be careful to put anything behind gTextureList.destroyGL(save_state); if (!gGLManager.mIsDisabled) { llinfos << "Shutting down GL..." << llendl; @@ -4418,7 +4476,7 @@ void LLViewerWindow::stopGL(BOOL save_state) LLVOAvatar::destroyGL(); stop_glerror(); - LLDynamicTexture::destroyGL(); + LLViewerDynamicTexture::destroyGL(); stop_glerror(); if (gPipeline.isInit()) @@ -4436,9 +4494,9 @@ void LLViewerWindow::stopGL(BOOL save_state) gPostProcess->invalidate(); } - gImageList.destroyGL(save_state); + gTextureList.destroyGL(save_state); stop_glerror(); - + gGLManager.mIsDisabled = TRUE; stop_glerror(); @@ -4451,7 +4509,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) //Note: --bao //if not necessary, do not change the order of the function calls in this function. //if change something, make sure it will not break anything. - //especially, be careful to put something before gImageList.restoreGL(); + //especially, be careful to put something before gTextureList.restoreGL(); if (gGLManager.mIsDisabled) { llinfos << "Restoring GL..." << llendl; @@ -4459,8 +4517,9 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) initGLDefaults(); LLGLState::restoreGL(); - gImageList.restoreGL(); - + + gTextureList.restoreGL(); + // for future support of non-square pixels, and fonts that are properly stretched //LLFontGL::destroyDefaultFonts(); initFonts(); @@ -4471,7 +4530,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) LLManipTranslate::restoreGL(); gBumpImageList.restoreGL(); - LLDynamicTexture::restoreGL(); + LLViewerDynamicTexture::restoreGL(); LLVOAvatar::restoreGL(); gResizeScreenTexture = TRUE; @@ -4651,7 +4710,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized"); mWantFullscreen = fullscreen; mShowFullscreenProgress = show_progress_bar; - gSavedSettings.setBOOL("NotFullScreen", !mWantFullscreen); + gSavedSettings.setBOOL("WindowFullScreen", mWantFullscreen); //gResizeScreenTexture = TRUE; @@ -4856,13 +4915,12 @@ void LLViewerWindow::calcDisplayScale() } } -S32 TOOL_BAR_HEIGHT = 20; // *TODO:Skinning Fix - S32 LLViewerWindow::getChatConsoleBottomPad() { S32 offset = 0; - if( gToolBar && gToolBar->getVisible() ) - offset += TOOL_BAR_HEIGHT; + + if(LLBottomTray::instanceExists()) + offset += LLBottomTray::getInstance()->getRect().getHeight(); return offset; } @@ -4881,7 +4939,9 @@ LLRect LLViewerWindow::getChatConsoleRect() console_rect.mLeft += CONSOLE_PADDING_LEFT; - if (gSavedSettings.getBOOL("ChatFullWidth")) + static const BOOL CHAT_FULL_WIDTH = gSavedSettings.getBOOL("ChatFullWidth"); + + if (CHAT_FULL_WIDTH) { console_rect.mRight -= CONSOLE_PADDING_RIGHT; } @@ -4963,10 +5023,6 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos, { } -LLPickInfo::~LLPickInfo() -{ -} - void LLPickInfo::fetchResults() { @@ -4985,59 +5041,14 @@ void LLPickInfo::fetchResults() NULL, -1, mPickTransparent, &face_hit, &intersection, &uv, &normal, &binormal); - // read back colors and depth values from buffer - //glReadPixels(mScreenRegion.mLeft, mScreenRegion.mBottom, mScreenRegion.getWidth(), mScreenRegion.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer); - //glReadPixels(mScreenRegion.mLeft, mScreenRegion.mBottom, mScreenRegion.getWidth(), mScreenRegion.getHeight(), GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, mPickDepthBuffer ); - - // find pick region that is fully onscreen - LLCoordGL scaled_pick_point;; - scaled_pick_point.mX = llclamp(llround((F32)mMousePt.mX * gViewerWindow->getDisplayScale().mV[VX]), PICK_HALF_WIDTH, gViewerWindow->getWorldViewWidth() - PICK_HALF_WIDTH); - scaled_pick_point.mY = llclamp(llround((F32)mMousePt.mY * gViewerWindow->getDisplayScale().mV[VY]), PICK_HALF_WIDTH, gViewerWindow->getWorldViewHeight() - PICK_HALF_WIDTH); - //S32 pixel_index = PICK_HALF_WIDTH * PICK_DIAMETER + PICK_HALF_WIDTH; - //S32 pick_id = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2]; - //F32 depth = mPickDepthBuffer[pixel_index]; - - //S32 x_offset = mMousePt.mX - llround((F32)scaled_pick_point.mX / gViewerWindow->getDisplayScale().mV[VX]); - //S32 y_offset = mMousePt.mY - llround((F32)scaled_pick_point.mY / gViewerWindow->getDisplayScale().mV[VY]); - mPickPt = mMousePt; - // we hit nothing, scan surrounding pixels for something useful - /*if (!pick_id) - { - S32 closest_distance = 10000; - //S32 closest_pick_name = 0; - for (S32 col = 0; col < PICK_DIAMETER; col++) - { - for (S32 row = 0; row < PICK_DIAMETER; row++) - { - S32 distance_squared = (llabs(col - x_offset - PICK_HALF_WIDTH) * llabs(col - x_offset - PICK_HALF_WIDTH)) + (llabs(row - y_offset - PICK_HALF_WIDTH) * llabs(row - y_offset - PICK_HALF_WIDTH)); - pixel_index = row * PICK_DIAMETER + col; - S32 test_name = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2]; - if (test_name && distance_squared < closest_distance) - { - closest_distance = distance_squared; - pick_id = test_name; - depth = mPickDepthBuffer[pixel_index]; - mPickPt.mX = mMousePt.mX + (col - PICK_HALF_WIDTH); - mPickPt.mY = mMousePt.mY + (row - PICK_HALF_WIDTH); - } - } - } - }*/ - - U32 te_offset = face_hit > -1 ? face_hit : 0; - //pick_id &= 0x000fffff; //unproject relative clicked coordinate from window coordinate using GL LLViewerObject* objectp = hit_object; - //if (pick_id == (S32)GL_NAME_PARCEL_WALL) - //{ - // mPickType = PICK_PARCEL_WALL; - //} if (hit_icon && (!objectp || icon_dist < (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec())) @@ -5081,20 +5092,6 @@ void LLPickInfo::fetchResults() mObjectID = objectp->mID; mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset; - /*glh::matrix4f newModel((F32*)LLViewerCamera::getInstance()->getModelview().mMatrix); - - for(U32 i = 0; i < 16; ++i) - { - modelview[i] = newModel.m[i]; - projection[i] = LLViewerCamera::getInstance()->getProjection().mMatrix[i/4][i%4]; - } - glGetIntegerv( GL_VIEWPORT, viewport ); - - winX = ((F32)mPickPt.mX) * gViewerWindow->getDisplayScale().mV[VX]; - winY = ((F32)mPickPt.mY) * gViewerWindow->getDisplayScale().mV[VY]; - - gluUnProject( winX, winY, depth, modelview, projection, viewport, &posX, &posY, &posZ);*/ - mPosGlobal = gAgent.getPosGlobalFromAgent(intersection); if (mWantSurfaceInfo) @@ -5120,7 +5117,7 @@ void LLPickInfo::updateXYCoords() if (mObjectFace > -1) { const LLTextureEntry* tep = getObject()->getTE(mObjectFace); - LLPointer imagep = gImageList.getImage(tep->getID()); + LLPointer imagep = LLViewerTextureManager::getFetchedTexture(tep->getID()); if(mUVCoords.mV[VX] >= 0.f && mUVCoords.mV[VY] >= 0.f && imagep.notNull()) { LLCoordGL coords; diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index b729889631..60b0d3c34b 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -50,6 +50,8 @@ #include "llnotifications.h" #include "llmousehandler.h" #include "llcursortypes.h" +#include "llhandle.h" + #include class LLView; @@ -78,7 +80,6 @@ public: BOOL pick_transparent, BOOL pick_surface_info, void (*pick_callback)(const LLPickInfo& pick_info)); - ~LLPickInfo(); void fetchResults(); LLPointer getObject() const; @@ -270,7 +271,6 @@ public: void setProgressMessage(const std::string& msg); void setProgressCancelButtonVisible( BOOL b, const std::string& label = LLStringUtil::null ); LLProgressView *getProgressView() const; - void handleLoginComplete(); void updateObjectUnderCursor(); @@ -280,7 +280,8 @@ public: void updateKeyboardFocus(); void updatePicking(S32 x, S32 y, MASK mask); - void updateWorldViewRect(); + void updateWorldViewRect(bool use_full_window=false); + void updateBottomTrayRect(); BOOL handleKey(KEY key, MASK mask); void handleScrollWheel (S32 clicks); @@ -417,7 +418,9 @@ protected: LLProgressView *mProgressView; + LLFrameTimer mToolTipFadeTimer; LLTextBox* mToolTip; + std::string mLastToolTipMessage; BOOL mToolTipBlocked; // True after a key press or a mouse button event. False once the mouse moves again. LLRect mToolTipStickyRect; // Once a tool tip is shown, it will stay visible until the mouse leaves this rect. diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index e52fec7909..f26ba6f46e 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -39,8 +39,8 @@ #include "v3math.h" #include "llsurface.h" #include "lltextureview.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "noise.h" #include "llregionhandle.h" // for from_region_handle @@ -106,7 +106,7 @@ void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id) { return; } - mDetailTextures[corner] = gImageList.getImage(id); + mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); mDetailTextures[corner]->setNoDelete() ; mRawImages[corner] = NULL; } @@ -229,7 +229,7 @@ BOOL LLVLComposition::generateComposition() { if (mDetailTextures[i]->getDiscardLevel() < 0) { - mDetailTextures[i]->setBoostLevel(LLViewerImage::BOOST_TERRAIN); // in case we are at low detail + mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); return FALSE; } @@ -237,8 +237,8 @@ BOOL LLVLComposition::generateComposition() (mDetailTextures[i]->getWidth() < BASE_SIZE || mDetailTextures[i]->getHeight() < BASE_SIZE))) { - S32 width = mDetailTextures[i]->getWidth(0); - S32 height = mDetailTextures[i]->getHeight(0); + S32 width = mDetailTextures[i]->getFullWidth(); + S32 height = mDetailTextures[i]->getFullHeight(); S32 min_dim = llmin(width, height); S32 ddiscard = 0; while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) @@ -246,7 +246,7 @@ BOOL LLVLComposition::generateComposition() ddiscard++; min_dim /= 2; } - mDetailTextures[i]->setBoostLevel(LLViewerImage::BOOST_TERRAIN); // in case we are at low detail + mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail mDetailTextures[i]->setMinDiscardLevel(ddiscard); return FALSE; } @@ -280,7 +280,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { // Read back a raw image for this discard level, if it exists mRawImages[i] = new LLImageRaw; - S32 min_dim = llmin(mDetailTextures[i]->getWidth(0), mDetailTextures[i]->getHeight(0)); + S32 min_dim = llmin(mDetailTextures[i]->getFullWidth(), mDetailTextures[i]->getFullHeight()); S32 ddiscard = 0; while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) { @@ -336,7 +336,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, // // - LLViewerImage *texturep; + LLViewerTexture *texturep; U32 tex_width, tex_height, tex_comps; U32 tex_stride; F32 tex_x_scalef, tex_y_scalef; @@ -455,7 +455,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, for (S32 i = 0; i < 4; i++) { // Un-boost detatil textures (will get re-boosted if rendering in high detail) - mDetailTextures[i]->setBoostLevel(LLViewerImage::BOOST_NONE); + mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_NONE); mDetailTextures[i]->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1); } @@ -467,7 +467,7 @@ LLUUID LLVLComposition::getDetailTextureID(S32 corner) return mDetailTextures[corner]->getID(); } -LLViewerImage* LLVLComposition::getDetailTexture(S32 corner) +LLViewerFetchedTexture* LLVLComposition::getDetailTexture(S32 corner) { return mDetailTextures[corner]; } diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 6d5db3c050..d1b3dc4495 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -34,7 +34,7 @@ #define LL_LLVLCOMPOSITION_H #include "llviewerlayer.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLSurface; @@ -62,7 +62,7 @@ public: CORNER_COUNT = 4 }; LLUUID getDetailTextureID(S32 corner); - LLViewerImage* getDetailTexture(S32 corner); + LLViewerFetchedTexture* getDetailTexture(S32 corner); F32 getStartHeight(S32 corner); F32 getHeightRange(S32 corner); @@ -79,7 +79,7 @@ protected: LLSurface *mSurfacep; BOOL mTexturesLoaded; - LLPointer mDetailTextures[CORNER_COUNT]; + LLPointer mDetailTextures[CORNER_COUNT]; LLPointer mRawImages[CORNER_COUNT]; F32 mStartHeight[CORNER_COUNT]; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index c2b54ec9c6..2b5c3361c4 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -52,11 +52,12 @@ #include "llheadrotmotion.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyframefallmotion.h" #include "llkeyframestandmotion.h" #include "llkeyframewalkmotion.h" #include "llmutelist.h" +#include "llmoveview.h" #include "llnotify.h" #include "llquantize.h" #include "llregionhandle.h" @@ -67,7 +68,7 @@ #include "lltexlayer.h" #include "lltoolmorph.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewermenu.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" @@ -170,8 +171,8 @@ const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0); enum ERenderName { RENDER_NAME_NEVER, - RENDER_NAME_FADE, - RENDER_NAME_ALWAYS + RENDER_NAME_ALWAYS, + RENDER_NAME_FADE }; //----------------------------------------------------------------------------- @@ -717,8 +718,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mRippleTimeLast = 0.f; - mShadowImagep = gImageList.getImageFromFile("foot_shadow.j2c"); - gGL.getTexUnit(0)->bind(mShadowImagep.get()); + mShadowImagep = LLViewerTextureManager::getFetchedTextureFromFile("foot_shadow.j2c"); + gGL.getTexUnit(0)->bind(mShadowImagep); mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP); mInAir = FALSE; @@ -2214,7 +2215,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) else { llinfos << "oops - CurrentGesticulationLevel can be only 0, 1, or 2" << llendl; } // this is the call that Karl S. created for triggering gestures from within the code. - gGestureManager.triggerAndReviseString( gestureString ); + LLGestureManager::instance().triggerAndReviseString( gestureString ); } } @@ -2499,7 +2500,7 @@ void LLVOAvatar::idleUpdateLoadingEffect() particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f); particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f); particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; - LLViewerImage* cloud = gImageList.getImageFromFile("cloud-particle.j2c"); + LLViewerTexture* cloud = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c"); particle_parameters.mPartImageID = cloud->getID(); particle_parameters.mMaxAge = 0.f; particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE; @@ -2603,7 +2604,8 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) { render_name = render_name && !gAgent.cameraMouselook() - && (visible_chat || !gSavedSettings.getBOOL("RenderNameHideSelf")); + && (visible_chat || (gSavedSettings.getBOOL("RenderNameShowSelf") + && gSavedSettings.getS32("AvatarNameTagMode") )); } if ( render_name ) @@ -2660,7 +2662,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) new_name = TRUE; } - LLColor4 avatar_name_color = gSavedSkinSettings.getColor( "AvatarNameColor" ); + LLColor4 avatar_name_color = LLUIColorTable::instance().getColor( "AvatarNameColor" ); avatar_name_color.setAlpha(alpha); mNameText->setColor(avatar_name_color); @@ -2802,7 +2804,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) std::deque::iterator chat_iter = mChats.begin(); mNameText->clearString(); - LLColor4 new_chat = gSavedSkinSettings.getColor( "AvatarNameColor" ); + LLColor4 new_chat = LLUIColorTable::instance().getColor( "AvatarNameColor" ); LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f); if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) @@ -3869,7 +3871,7 @@ U32 LLVOAvatar::renderFootShadows() LLGLDepthTest test(GL_TRUE, GL_FALSE); //render foot shadows LLGLEnable blend(GL_BLEND); - gGL.getTexUnit(0)->bind(mShadowImagep.get()); + gGL.getTexUnit(0)->bind(mShadowImagep); glColor4fv(mShadow0Facep->getRenderColor().mV); mShadow0Facep->renderIndexed(foot_mask); glColor4fv(mShadow1Facep->getRenderColor().mV); @@ -3945,7 +3947,7 @@ void LLVOAvatar::updateTextures(LLAgent &agent) { if (layer_baked[i] && !mBakedTextureDatas[i].mIsLoaded) { - gGL.getTexUnit(0)->bind(getImage(mBakedTextureDatas[i].mTextureIndex)); + gGL.getTexUnit(0)->bind(getImage( mBakedTextureDatas[i].mTextureIndex )); } } } @@ -3955,7 +3957,7 @@ void LLVOAvatar::updateTextures(LLAgent &agent) mHasGrey = FALSE; // debug for (U32 index = 0; index < getNumTEs(); index++) { - LLViewerImage *imagep = getImage(index); + LLViewerFetchedTexture *imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(index), TRUE); if (imagep) { const LLTextureEntry *te = getTE(index); @@ -4007,15 +4009,15 @@ void LLVOAvatar::updateTextures(LLAgent &agent) } -void LLVOAvatar::addLocalTextureStats(ETextureIndex idx, LLViewerImage* imagep, - F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index) +void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture* imagep, + F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index ) { // No local texture stats for non-self avatars return; } -void LLVOAvatar::addBakedTextureStats( LLViewerImage* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level) +void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level) { mMaxPixelArea = llmax(pixel_area, mMaxPixelArea); mMinPixelArea = llmin(pixel_area, mMinPixelArea); @@ -4024,13 +4026,13 @@ void LLVOAvatar::addBakedTextureStats( LLViewerImage* imagep, F32 pixel_area, F3 } //virtual -void LLVOAvatar::setImage(const U8 te, LLViewerImage *imagep) +void LLVOAvatar::setImage(const U8 te, LLViewerTexture *imagep) { setTEImage(te, imagep); } //virtual -LLViewerImage* LLVOAvatar::getImage(const U8 te) const +LLViewerTexture* LLVOAvatar::getImage(const U8 te) const { return getTEImage(te); } @@ -4243,7 +4245,7 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL } else if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED) { - mIsSitting = TRUE; + sitDown(TRUE); } @@ -4260,7 +4262,7 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL { if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED) { - mIsSitting = FALSE; + sitDown(FALSE); } stopMotion(anim_id); result = TRUE; @@ -5213,7 +5215,7 @@ void LLVOAvatar::updateShadowFaces() sprite.setSize(0.4f + cos_elev * 0.8f, 0.3f); LLVector3 sun_vec = gSky.mVOSkyp ? gSky.mVOSkyp->getToSun() : LLVector3(0.f, 0.f, 0.f); - if (mShadowImagep->getHasGLTexture()) + if (mShadowImagep->hasValidGLTexture()) { LLVector3 normal; LLVector3d shadow_pos; @@ -5482,6 +5484,19 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) return FALSE; } +//----------------------------------------------------------------------------- +// sitDown() +//----------------------------------------------------------------------------- +void LLVOAvatar::sitDown(BOOL bSitting) +{ + mIsSitting = bSitting; + if (isSelf()) + { + // Update Movement Controls according to own Sitting mode + LLFloaterMove::setSittingMode(bSitting); + } +} + //----------------------------------------------------------------------------- // sitOnObject() //----------------------------------------------------------------------------- @@ -5501,7 +5516,7 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) mDrawable->mXform.setRotation(mDrawable->getWorldRotation() * inv_obj_rot); gPipeline.markMoved(mDrawable, TRUE); - mIsSitting = TRUE; + sitDown(TRUE); mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject mRoot.setPosition(getPosition()); mRoot.updateWorldMatrixChildren(); @@ -5565,7 +5580,8 @@ void LLVOAvatar::getOffObject() gPipeline.markMoved(mDrawable, TRUE); - mIsSitting = FALSE; + sitDown(FALSE); + mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject mRoot.setPosition(cur_position_world); mRoot.setRotation(cur_rotation_world); @@ -5772,10 +5788,10 @@ void LLVOAvatar::updateMeshTextures() // if user has never specified a texture, assign the default for (U32 i=0; i < getNumTEs(); i++) { - const LLViewerImage* te_image = getImage(i); + const LLViewerTexture* te_image = getImage(i); if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT)) { - setImage(i, gImageList.getImage(i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR)); // IMG_DEFAULT_AVATAR = a special texture that's never rendered. + setImage(i, LLViewerTextureManager::getFetchedTexture(i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR)); // IMG_DEFAULT_AVATAR = a special texture that's never rendered. } } @@ -5829,7 +5845,7 @@ void LLVOAvatar::updateMeshTextures() { if (use_lkg_baked_layer[i] && !self_customizing ) { - LLViewerImage* baked_img = gImageList.getImageFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host ); + LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTextureFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host ); mBakedTextureDatas[i].mIsUsed = TRUE; for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++) { @@ -5838,7 +5854,7 @@ void LLVOAvatar::updateMeshTextures() } else if (!self_customizing && is_layer_baked[i]) { - LLViewerImage* baked_img = getImage( mBakedTextureDatas[i].mTextureIndex ); + LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex ), TRUE) ; if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureIndex ) { // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). @@ -5873,7 +5889,7 @@ void LLVOAvatar::updateMeshTextures() if (!is_layer_baked[BAKED_HAIR] || self_customizing) { const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1); - LLViewerImage* hair_img = getImage( TEX_HAIR ); + LLViewerTexture* hair_img = getImage( TEX_HAIR ); for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++) { mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); @@ -5907,7 +5923,7 @@ void LLVOAvatar::updateMeshTextures() //----------------------------------------------------------------------------- // setLocalTexture() //----------------------------------------------------------------------------- -void LLVOAvatar::setLocalTexture(ETextureIndex type, LLViewerImage* tex, BOOL baked_version_exists, U32 index) +void LLVOAvatar::setLocalTexture( ETextureIndex type, LLViewerTexture* in_tex, BOOL baked_version_ready, U32 index ) { // invalid for anyone but self llassert(0); @@ -6153,7 +6169,7 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) iter++) { const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; - const LLViewerImage* te_image = getImage(iter->first); + const LLViewerTexture* te_image = getImage(iter->first); if( !te_image ) { llinfos << " " << texture_dict->mName << ": null ptr" << llendl; @@ -6319,7 +6335,7 @@ void LLVOAvatar::onFirstTEMessageReceived() // (That is, don't do a transition from unbaked to baked.) if (layer_baked) { - LLViewerImage* image = getImage( mBakedTextureDatas[i].mTextureIndex ); + LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex ), TRUE) ; mBakedTextureDatas[i].mLastTextureIndex = image->getID(); // If we have more than one texture for the other baked layers, we'll want to call this for them too. if ( (i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER) ) @@ -6381,7 +6397,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) && mBakedTextureDatas[baked_index].mLastTextureIndex != IMG_DEFAULT && baked_index != BAKED_SKIRT) { - setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, gImageList.getImage(mBakedTextureDatas[baked_index].mLastTextureIndex)); + setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, + LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE)); } } @@ -6518,7 +6535,7 @@ void LLVOAvatar::getAnimNames( LLDynamicArray* names ) names->put( "enter_away_from_keyboard_state" ); } -void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) +void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { if (!userdata) return; @@ -6571,7 +6588,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi, if (texture_dict->mIsUsedByBakedTexture) { const ETextureIndex texture_index = iter->first; - const LLViewerImage *baked_img = self->getImage(texture_index); + const LLViewerTexture *baked_img = self->getImage(texture_index); if (id == baked_img->getID()) { const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; @@ -6609,7 +6626,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi, } // static -void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) +void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { LLUUID *avatar_idp = (LLUUID *)userdata; LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); @@ -6624,7 +6641,7 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerImage *src_v } } -void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) +void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { //llinfos << "onBakedTextureLoaded: " << src_vi->getID() << llendl; @@ -6659,7 +6676,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) mHeadMesh1.setTexture( head_baked ); */ for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - LLViewerImage* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex ); + LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex ); if (id == image_baked->getID()) { mBakedTextureDatas[i].mIsLoaded = true; @@ -6734,7 +6751,7 @@ void LLVOAvatar::dumpArchetypeXML( void* ) { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te) == type) { - LLViewerImage* te_image = avatar->getImage((ETextureIndex)te); + LLViewerTexture* te_image = avatar->getImage((ETextureIndex)te); if( te_image ) { std::string uuid_str; @@ -7623,7 +7640,7 @@ U32 calc_shame(LLVOVolume* volume, std::set &textures) { LLFace* face = drawablep->getFace(i); const LLTextureEntry* te = face->getTextureEntry(); - LLViewerImage* img = face->getTexture(); + LLViewerTexture* img = face->getTexture(); textures.insert(img->getID()); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index b22c0deb33..59be38a1b0 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -94,7 +94,7 @@ public: virtual void markDead(); static void initClass(); // Initialize data that's only init'd once per class. static void cleanupClass(); // Cleanup data that's only init'd once per class. - void initInstance(); // Called after construction to initialize the class. + virtual void initInstance(); // Called after construction to initialize the class. protected: virtual ~LLVOAvatar(); BOOL loadSkeletonNode(); @@ -370,7 +370,7 @@ public: private: LLFace* mShadow0Facep; LLFace* mShadow1Facep; - LLPointer mShadowImagep; + LLPointer mShadowImagep; //-------------------------------------------------------------------- // Impostors @@ -432,8 +432,8 @@ private: // Constants //-------------------------------------------------------------------- public: - virtual LLViewerImage::EBoostLevel getAvatarBoostLevel() const { return LLViewerImage::BOOST_AVATAR; } - virtual LLViewerImage::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerImage::BOOST_AVATAR_BAKED; } + virtual LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR; } + virtual LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED; } virtual S32 getTexImageSize() const; virtual S32 getTexImageArea() const { return getTexImageSize()*getTexImageSize(); } @@ -450,7 +450,7 @@ public: // Loading status //-------------------------------------------------------------------- public: - virtual BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; + virtual BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex index) const; protected: BOOL isFullyBaked(); @@ -462,9 +462,9 @@ protected: public: void releaseComponentTextures(); // ! BACKWARDS COMPATIBILITY ! protected: - static void onBakedTextureMasksLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); - static void onInitialBakedTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); - static void onBakedTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + static void onBakedTextureMasksLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + static void onInitialBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + static void onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); virtual void removeMissingBakedTextures(); void useBakedTexture(const LLUUID& id); @@ -489,15 +489,15 @@ protected: // Local Textures //-------------------------------------------------------------------- protected: - virtual void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerImage* tex, BOOL baked_version_exits, U32 index = 0); - virtual void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex type, LLViewerImage* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0); + virtual void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0); + virtual void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0); //-------------------------------------------------------------------- // Texture accessors //-------------------------------------------------------------------- private: - virtual void setImage(const U8 te, LLViewerImage *imagep); - virtual LLViewerImage* getImage(const U8 te) const; + virtual void setImage(const U8 te, LLViewerTexture *imagep); + virtual LLViewerTexture* getImage(const U8 te) const; virtual const LLTextureEntry* getTexEntry(const U8 te_num) const; virtual void setTexEntry(const U8 index, const LLTextureEntry &te); @@ -508,7 +508,7 @@ private: //-------------------------------------------------------------------- protected: void deleteLayerSetCaches(bool clearAll = true); - void addBakedTextureStats(LLViewerImage* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level); + void addBakedTextureStats(LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level); //-------------------------------------------------------------------- // Composites @@ -784,8 +784,13 @@ public: // Sitting //-------------------------------------------------------------------- public: + void sitDown(BOOL bSitting); + BOOL isSitting(){return mIsSitting;} void sitOnObject(LLViewerObject *sit_object); void getOffObject(); + +private: + // set this property only with LLVOAvatar::sitDown method BOOL mIsSitting; /** Hierarchy diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index e7d7d74f62..9df25bdb11 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -54,7 +54,7 @@ #include "llheadrotmotion.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" -#include "llinventoryview.h" +#include "llfloaterinventory.h" #include "llkeyframefallmotion.h" #include "llkeyframestandmotion.h" #include "llkeyframewalkmotion.h" @@ -69,7 +69,7 @@ #include "lltoolmorph.h" #include "lltrans.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewermenu.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" @@ -103,7 +103,7 @@ struct LocalTextureData mWearableID(IMG_DEFAULT_AVATAR), mTexEntry(NULL) {} - LLPointer mImage; + LLPointer mImage; BOOL mIsBakedReady; S32 mDiscard; LLUUID mWearableID; // UUID of the wearable that this texture belongs to, not of the image itself @@ -156,14 +156,17 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id, gAgentWearables.setAvatarObject(this); lldebugs << "Marking avatar as self " << id << llendl; - - for (U32 i = 0; i < TEX_NUM_INDICES; i++) - { - mLocalTextureDatas[(ETextureIndex)i].push_back(new LocalTextureData); - } +} +void LLVOAvatarSelf::initInstance() +{ BOOL status = TRUE; + // creates hud joint(mScreen) among other things status &= loadAvatarSelf(); + + // adds attachment points to mScreen among other things + LLVOAvatar::initInstance(); + status &= buildMenus(); if (!status) { @@ -528,19 +531,6 @@ LLVOAvatarSelf::~LLVOAvatarSelf() gAgentWearables.setAvatarObject(NULL); delete mScreenp; mScreenp = NULL; - - for (localtexture_map_t::iterator iter = mLocalTextureDatas.begin(); - iter != mLocalTextureDatas.end(); - iter++) - { - localtexture_vec_t &local_textures = iter->second; - for (U32 i = 0; i < local_textures.size(); i++) - { - LocalTextureData* loc_tex_data = local_textures[i]; - delete loc_tex_data; - local_textures[i] = NULL; - } - } } /** @@ -667,7 +657,7 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id) } // virtual -void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerImage* image, BOOL set_by_user, U32 index) +void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, BOOL set_by_user, U32 index) { if (te >= TEX_NUM_INDICES) { @@ -708,9 +698,10 @@ void LLVOAvatarSelf::removeMissingBakedTextures() for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { const S32 te = mBakedTextureDatas[i].mTextureIndex; - if (getTEImage(te)->isMissingAsset()) + LLViewerTexture* tex = getTEImage(te) ; + if (!tex || tex->isMissingAsset()) { - setTEImage(te, gImageList.getImage(IMG_DEFAULT_AVATAR)); + setTEImage(te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR)); removed = TRUE; } } @@ -999,24 +990,39 @@ LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_obj return attachment; } +U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const +{ + EWearableType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i); + return gAgentWearables.getWearableCount(type); +} + // virtual -void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) +void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { //llinfos << "onLocalTextureLoaded: " << src_vi->getID() << llendl; const LLUUID& src_id = src_vi->getID(); LLAvatarTexData *data = (LLAvatarTexData *)userdata; + ETextureIndex index = data->mIndex; + if (!isIndexLocalTexture(index)) return; + LLLocalTextureObject *local_tex_obj = getLocalTextureObject(index, 0); + + // fix for EXT-268. Preventing using of NULL pointer + if(NULL == local_tex_obj) + { + LL_WARNS("TAG") << "There is no Local Texture Object with index: " << index + << ", final: " << final + << LL_ENDL; + return; + } if (success) { - ETextureIndex index = data->mIndex; - if (!isIndexLocalTexture(index)) return; - LocalTextureData *local_tex_data = getLocalTextureData(index,0); - if (!local_tex_data->mIsBakedReady && - local_tex_data->mImage.notNull() && - (local_tex_data->mImage->getID() == src_id) && - discard_level < local_tex_data->mDiscard) + if (!local_tex_obj->getBakedReady() && + local_tex_obj->getImage() != NULL && + (local_tex_obj->getID() == src_id) && + discard_level < local_tex_obj->getDiscard()) { - local_tex_data->mDiscard = discard_level; + local_tex_obj->setDiscard(discard_level); if (!gAgent.cameraCustomizeAvatar()) { requestLayerSetUpdate(index); @@ -1030,15 +1036,12 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerImage *src_vi, LLI } else if (final) { - ETextureIndex index = data->mIndex; - if (!isIndexLocalTexture(index)) return; - LocalTextureData *local_tex_data = getLocalTextureData(index,0); // Failed: asset is missing - if (!local_tex_data->mIsBakedReady && - local_tex_data->mImage.notNull() && - local_tex_data->mImage->getID() == src_id) + if (!local_tex_obj->getBakedReady() && + local_tex_obj->getImage() != NULL && + local_tex_obj->getImage()->getID() == src_id) { - local_tex_data->mDiscard = 0; + local_tex_obj->setDiscard(0); requestLayerSetUpdate(index); updateMeshTextures(); } @@ -1066,19 +1069,19 @@ BOOL LLVOAvatarSelf::getLocalTextureRaw(ETextureIndex index, LLImageRaw* image_r */ // virtual -BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLImageGL** image_gl_pp, U32 index) const +BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex_pp, U32 index) const { - *image_gl_pp = NULL; + *tex_pp = NULL; if (!isIndexLocalTexture(type)) return FALSE; if (getLocalTextureID(type, index) == IMG_DEFAULT_AVATAR) return TRUE; - const LocalTextureData *local_tex_data = getLocalTextureData(type, index); - if (!local_tex_data) + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); + if (!local_tex_obj) { return FALSE; } - *image_gl_pp = local_tex_data->mImage; + *tex_pp = local_tex_obj->getImage(); return TRUE; } @@ -1086,10 +1089,10 @@ const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) c { if (!isIndexLocalTexture(type)) return IMG_DEFAULT_AVATAR; - const LocalTextureData *local_tex_data = getLocalTextureData(type,index); - if (local_tex_data && local_tex_data->mImage.notNull()) + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); + if (local_tex_obj && local_tex_obj->getImage() != NULL) { - return local_tex_data->mImage->getID(); + return local_tex_obj->getImage()->getID(); } return IMG_DEFAULT_AVATAR; } @@ -1222,7 +1225,7 @@ void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_u llassert(isSelf()); ETextureIndex baked_te = getBakedTE( layerset ); - setTEImage( baked_te, gImageList.getImage(IMG_DEFAULT_AVATAR) ); + setTEImage( baked_te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR) ); layerset->requestUpload(); } } @@ -1279,14 +1282,14 @@ S32 LLVOAvatarSelf::getLocalDiscardLevel(ETextureIndex type, U32 index) const { if (!isIndexLocalTexture(type)) return FALSE; - const LocalTextureData *local_tex_data = getLocalTextureData(type,index); - if (local_tex_data) + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); + if (local_tex_obj) { if (type >= 0 && getLocalTextureID(type,index) != IMG_DEFAULT_AVATAR - && !local_tex_data->mImage->isMissingAsset()) + && !local_tex_obj->getImage()->isMissingAsset()) { - return local_tex_data->mImage->getDiscardLevel(); + return local_tex_obj->getImage()->getDiscardLevel(); } else { @@ -1305,18 +1308,18 @@ void LLVOAvatarSelf::getLocalTextureByteCount(S32* gl_bytes) const for (S32 type = 0; type < TEX_NUM_INDICES; type++) { if (!isIndexLocalTexture((ETextureIndex)type)) continue; - const localtexture_vec_t & local_tex_vec = getLocalTextureData((ETextureIndex)type); - for (U32 num = 0; num < local_tex_vec.size(); num++) + U32 max_tex = getNumWearables((ETextureIndex) type); + for (U32 num = 0; num < max_tex; num++) { - const LocalTextureData *local_tex_data = local_tex_vec[num]; - if (local_tex_data) + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject((ETextureIndex) type, num); + if (local_tex_obj) { - const LLViewerImage* image_gl = local_tex_data->mImage; + const LLViewerFetchedTexture* image_gl = local_tex_obj->getImage(); if (image_gl) { S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); - if (image_gl->getHasGLTexture()) + if (image_gl->hasValidGLTexture()) { *gl_bytes += bytes; } @@ -1327,26 +1330,53 @@ void LLVOAvatarSelf::getLocalTextureByteCount(S32* gl_bytes) const } // virtual -void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerImage* tex, BOOL baked_version_ready, U32 index) +void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_tex, BOOL baked_version_ready, U32 index) { if (!isIndexLocalTexture(type)) return; + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(src_tex, TRUE) ; + if(!tex) + { + return ; + } + S32 desired_discard = isSelf() ? 0 : 2; - LocalTextureData *local_tex_data = getLocalTextureData(type,index); + LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index); + if (!local_tex_obj) + { + if (type >= TEX_NUM_INDICES) + { + llerrs << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << llendl; + return; + } + EWearableType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType(type); + if (!gAgentWearables.getWearable(wearable_type,0)) + { + // no wearable is loaded, cannot set the texture. + return; + } + gAgentWearables.addLocalTextureObject(wearable_type,type,index); + local_tex_obj = getLocalTextureObject(type,index); + if (!local_tex_obj) + { + llerrs << "Unable to create LocalTextureObject for wearable type & index: (" << (U32) wearable_type << ", " << index << ")" << llendl; + return; + } + } if (!baked_version_ready) { - if (tex != local_tex_data->mImage || local_tex_data->mIsBakedReady) + if (tex != local_tex_obj->getImage() || local_tex_obj->getBakedReady()) { - local_tex_data->mDiscard = MAX_DISCARD_LEVEL+1; + local_tex_obj->setDiscard(MAX_DISCARD_LEVEL+1); } if (tex->getID() != IMG_DEFAULT_AVATAR) { - if (local_tex_data->mDiscard > desired_discard) + if (local_tex_obj->getDiscard() > desired_discard) { S32 tex_discard = tex->getDiscardLevel(); if (tex_discard >= 0 && tex_discard <= desired_discard) { - local_tex_data->mDiscard = tex_discard; + local_tex_obj->setDiscard(tex_discard); if (isSelf() && !gAgent.cameraCustomizeAvatar()) { requestLayerSetUpdate(type); @@ -1364,8 +1394,8 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerImage* tex, BOO tex->setMinDiscardLevel(desired_discard); } } - local_tex_data->mIsBakedReady = baked_version_ready; - local_tex_data->mImage = tex; + local_tex_obj->setBakedReady( baked_version_ready ); + local_tex_obj->setImage(tex); } // virtual @@ -1388,7 +1418,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const const ETextureIndex baked_equiv = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex; const std::string &name = texture_dict->mName; - const LocalTextureData *local_tex_data = getLocalTextureData(iter->first,0); + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0); if (isTextureDefined(baked_equiv)) { #if LL_RELEASE_FOR_DOWNLOAD @@ -1399,15 +1429,15 @@ void LLVOAvatarSelf::dumpLocalTextures() const llinfos << "LocTex " << name << ": Baked " << getTEImage(baked_equiv)->getID() << llendl; #endif } - else if (local_tex_data->mImage.notNull()) + else if (local_tex_obj->getImage() != NULL) { - if (local_tex_data->mImage->getID() == IMG_DEFAULT_AVATAR) + if (local_tex_obj->getImage()->getID() == IMG_DEFAULT_AVATAR) { llinfos << "LocTex " << name << ": None" << llendl; } else { - const LLViewerImage* image = local_tex_data->mImage; + const LLViewerFetchedTexture* image = local_tex_obj->getImage(); llinfos << "LocTex " << name << ": " << "Discard " << image->getDiscardLevel() << ", " @@ -1423,7 +1453,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const } else { - llinfos << "LocTex " << name << ": No LLViewerImage" << llendl; + llinfos << "LocTex " << name << ": No LLViewerTexture" << llendl; } } } @@ -1433,7 +1463,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const // onLocalTextureLoaded() //----------------------------------------------------------------------------- -void LLVOAvatarSelf::onLocalTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) +void LLVOAvatarSelf::onLocalTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { LLAvatarTexData *data = (LLAvatarTexData *)userdata; LLVOAvatarSelf *self = (LLVOAvatarSelf *)gObjectList.findObject(data->mAvatarID); @@ -1449,57 +1479,6 @@ void LLVOAvatarSelf::onLocalTextureLoaded(BOOL success, LLViewerImage *src_vi, L } } - -const LLVOAvatarSelf::localtexture_vec_t &LLVOAvatarSelf::getLocalTextureData(LLVOAvatarDefines::ETextureIndex type) const -{ - localtexture_map_t::const_iterator found_localtexture = mLocalTextureDatas.find(type); - if (found_localtexture != mLocalTextureDatas.end()) - { - const localtexture_vec_t &local_tex_data = found_localtexture->second; - return local_tex_data; - } - llassert(0); - static localtexture_vec_t ret; - return ret; -} - -const LocalTextureData* LLVOAvatarSelf::getLocalTextureData(LLVOAvatarDefines::ETextureIndex type, U32 index ) const -{ - const localtexture_vec_t &local_tex_array = getLocalTextureData(type); - - if (index >= local_tex_array.size()) - { - return NULL; - } - - return local_tex_array[index]; -} - -LLVOAvatarSelf::localtexture_vec_t &LLVOAvatarSelf::getLocalTextureData(LLVOAvatarDefines::ETextureIndex type) -{ - localtexture_map_t::iterator found_localtexture = mLocalTextureDatas.find(type); - if (found_localtexture != mLocalTextureDatas.end()) - { - localtexture_vec_t &local_tex_data = found_localtexture->second; - return local_tex_data; - } - llassert(0); - static localtexture_vec_t ret; - return ret; -} - -LocalTextureData* LLVOAvatarSelf::getLocalTextureData(LLVOAvatarDefines::ETextureIndex type, U32 index ) -{ - localtexture_vec_t &local_tex_array = getLocalTextureData(type); - - if (index >= local_tex_array.size()) - { - return NULL; - } - - return local_tex_array[index]; -} - // static void LLVOAvatarSelf::dumpTotalLocalTextureByteCount() { @@ -1547,8 +1526,8 @@ BOOL LLVOAvatarSelf::updateIsFullyLoaded() continue; // Check for the case that texture is defined but not sufficiently loaded to display anything. - LLViewerImage* baked_img = getImage( texture_data.mTextureIndex ); - if (!baked_img || !baked_img->getHasGLTexture()) + LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex ); + if (!baked_img || !baked_img->hasValidGLTexture()) { loading = TRUE; } @@ -1638,7 +1617,7 @@ BOOL LLVOAvatarSelf::canGrabLocalTexture(ETextureIndex type, U32 index) const return TRUE; } -void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerImage* imagep, +void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index ) { if (!isIndexLocalTexture(type)) return; @@ -1664,6 +1643,18 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerImage* im } } +LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 wearable_index) const +{ + EWearableType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i); + LLWearable* wearable = gAgentWearables.getWearable(type, wearable_index); + if (wearable) + { + return wearable->getLocalTextureObject(i); + } + + return NULL; +} + //----------------------------------------------------------------------------- // getBakedTE() // Used by the LayerSet. (Layer sets don't in general know what textures depend on them.) @@ -1690,7 +1681,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) { // Baked textures live on other sims. LLHost target_host = getObjectHost(); - setTEImage( te, gImageList.getImageFromHost( uuid, target_host ) ); + setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, target_host ) ); updateMeshTextures(); dirtyMesh(); diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 02a77cba90..e34f09aca2 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -34,6 +34,7 @@ #ifndef LL_LLVOAVATARSELF_H #define LL_LLVOAVATARSELF_H +#include "llviewertexture.h" #include "llvoavatar.h" struct LocalTextureData; @@ -54,6 +55,7 @@ public: LLVOAvatarSelf(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); virtual ~LLVOAvatarSelf(); virtual void markDead(); + virtual void initInstance(); // Called after construction to initialize the class. protected: BOOL loadAvatarSelf(); BOOL buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info); @@ -140,8 +142,8 @@ private: // LLVOAvatar Constants //-------------------------------------------------------------------- public: - /*virtual*/ LLViewerImage::EBoostLevel getAvatarBoostLevel() const { return LLViewerImage::BOOST_AVATAR_SELF; } - /*virtual*/ LLViewerImage::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerImage::BOOST_AVATAR_BAKED_SELF; } + /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_SELF; } + /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED_SELF; } /*virtual*/ S32 getTexImageSize() const { return LLVOAvatar::getTexImageSize()*4; } /** Rendering @@ -168,18 +170,20 @@ public: // Local Textures //-------------------------------------------------------------------- public: - BOOL getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLImageGL** image_gl_pp, U32 index = 0) const; + BOOL getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index = 0) const; const LLUUID& getLocalTextureID(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; - void setLocalTextureTE(U8 te, LLViewerImage* image, BOOL set_by_user, U32 index = 0); + void setLocalTextureTE(U8 te, LLViewerTexture* image, BOOL set_by_user, U32 index = 0); const LLUUID& grabLocalTexture(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; BOOL canGrabLocalTexture(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; protected: - /*virtual*/ void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerImage* tex, BOOL baked_version_exits, U32 index = 0); - void localTextureLoaded(BOOL succcess, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + /*virtual*/ void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0); + void localTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); void getLocalTextureByteCount(S32* gl_byte_count) const; - /*virtual*/ void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerImage* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0); + /*virtual*/ void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0); + LLLocalTextureObject* getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 index = 0) const; + private: - static void onLocalTextureLoaded(BOOL succcess, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + static void onLocalTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); //-------------------------------------------------------------------- // Baked textures @@ -225,20 +229,6 @@ private: static LLMap< LLGLenum, LLGLuint*> sScratchTexNames; static LLMap< LLGLenum, F32*> sScratchTexLastBindTime; - //-------------------------------------------------------------------- - // Texture Data - //-------------------------------------------------------------------- -private: - typedef std::vector localtexture_vec_t; // all textures of a certain TE - typedef std::map localtexture_map_t; // texture TE vectors arranged by texture type - localtexture_map_t mLocalTextureDatas; - - const localtexture_vec_t& getLocalTextureData(LLVOAvatarDefines::ETextureIndex index) const; // const accessor into mLocalTextureDatas - const LocalTextureData* getLocalTextureData(LLVOAvatarDefines::ETextureIndex type, U32 index) const; // const accessor to individual LocalTextureData - - localtexture_vec_t& getLocalTextureData(LLVOAvatarDefines::ETextureIndex index); // accessor into mLocalTextureDatas - LocalTextureData* getLocalTextureData(LLVOAvatarDefines::ETextureIndex type, U32 index); // accessor to individual LocalTextureData - /** Textures ** ** *******************************************************************************/ @@ -276,6 +266,8 @@ public: // HUDs //-------------------------------------------------------------------- private: + U32 getNumWearables(LLVOAvatarDefines::ETextureIndex i) const; + LLViewerJoint* mScreenp; // special purpose joint for HUD attachments /** Attachments diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp index 9095ee43c8..fbc4e2e609 100644 --- a/indra/newview/llvoclouds.cpp +++ b/indra/newview/llvoclouds.cpp @@ -44,7 +44,7 @@ #include "llprimitive.h" #include "llsky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llvosky.h" @@ -61,8 +61,8 @@ LLVOClouds::LLVOClouds(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mCloudGroupp = NULL; mbCanSelect = FALSE; setNumTEs(1); - LLViewerImage* image = gImageList.getImage(gCloudTextureID); - image->setBoostLevel(LLViewerImage::BOOST_CLOUDS); + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(gCloudTextureID); + image->setBoostLevel(LLViewerTexture::BOOST_CLOUDS); setTEImage(0, image); } diff --git a/indra/newview/llvoclouds.h b/indra/newview/llvoclouds.h index f70ea5b9e7..95e6b96e4e 100644 --- a/indra/newview/llvoclouds.h +++ b/indra/newview/llvoclouds.h @@ -37,7 +37,7 @@ #include "lltable.h" #include "v4coloru.h" -class LLViewerImage; +class LLViewerTexture; class LLViewerCloudGroup; class LLCloudGroup; diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index a956ec8ab3..cf6eb8e9fd 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -46,7 +46,7 @@ #include "llsurfacepatch.h" #include "llvosky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "pipeline.h" #include "llspatialpartition.h" @@ -106,7 +106,7 @@ void LLVOGrass::updateSpecies() SpeciesMap::const_iterator it = sSpeciesTable.begin(); mSpecies = (*it).first; } - setTEImage(0, gImageList.getImage(sSpeciesTable[mSpecies]->mTextureID)); + setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE)); } diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h index 11b79d519c..124400d356 100644 --- a/indra/newview/llvograss.h +++ b/indra/newview/llvograss.h @@ -38,7 +38,7 @@ #include class LLSurfacePatch; -class LLViewerImage; +class LLViewerTexture; class LLVOGrass : public LLAlphaObject diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h index f485bd0aa4..af3fcd65d4 100644 --- a/indra/newview/llvoground.h +++ b/indra/newview/llvoground.h @@ -36,7 +36,7 @@ #include "stdtypes.h" #include "v3color.h" #include "v4coloru.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llviewerobject.h" class LLVOGround : public LLStaticViewerObject diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 082dcb50a2..f1d4520370 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -67,6 +67,9 @@ #include "llfloaterfriends.h" //VIVOX, inorder to refresh communicate panel #include "llfloaterchat.h" // for LLFloaterChat::addChat() +// for Talk Button's state updating +#include "llnearbychatbar.h" + // for base64 decoding #include "apr_base64.h" @@ -4551,7 +4554,7 @@ void LLVoiceClient::messageEvent( if(messageHeader.find("text/html") != std::string::npos) { - std::string rawMessage; + std::string message; { const std::string startMarker = "', start + 1)) != std::string::npos) + if((end = message.find('>', start + 1)) != std::string::npos) { // Strip out the tag - rawMessage.erase(start, (end + 1) - start); + message.erase(start, (end + 1) - start); } else { @@ -4626,31 +4629,31 @@ void LLVoiceClient::messageEvent( // The text may contain text encoded with <, >, and & mark = 0; - while((mark = rawMessage.find("<", mark)) != std::string::npos) + while((mark = message.find("<", mark)) != std::string::npos) { - rawMessage.replace(mark, 4, "<"); + message.replace(mark, 4, "<"); mark += 1; } mark = 0; - while((mark = rawMessage.find(">", mark)) != std::string::npos) + while((mark = message.find(">", mark)) != std::string::npos) { - rawMessage.replace(mark, 4, ">"); + message.replace(mark, 4, ">"); mark += 1; } mark = 0; - while((mark = rawMessage.find("&", mark)) != std::string::npos) + while((mark = message.find("&", mark)) != std::string::npos) { - rawMessage.replace(mark, 5, "&"); + message.replace(mark, 5, "&"); mark += 1; } } // strip leading/trailing whitespace (since we always seem to get a couple newlines) - LLStringUtil::trim(rawMessage); + LLStringUtil::trim(message); -// LL_DEBUGS("Voice") << " stripped message = \n" << rawMessage << LL_ENDL; +// LL_DEBUGS("Voice") << " stripped message = \n" << message << LL_ENDL; sessionState *session = findSession(sessionHandle); if(session) @@ -4674,14 +4677,12 @@ void LLVoiceClient::messageEvent( quiet_chat = true; // TODO: Question: Return busy mode response here? Or maybe when session is started instead? } - - std::string fullMessage = std::string(": ") + rawMessage; - + LL_DEBUGS("Voice") << "adding message, name " << session->mName << " session " << session->mIMSessionID << ", target " << session->mCallerID << LL_ENDL; gIMMgr->addMessage(session->mIMSessionID, session->mCallerID, session->mName.c_str(), - fullMessage.c_str(), + message.c_str(), LLStringUtil::null, // default arg IM_NOTHING_SPECIAL, // default arg 0, // default arg @@ -4689,7 +4690,7 @@ void LLVoiceClient::messageEvent( LLVector3::zero, // default arg true); // prepend name and make it a link to the user's profile - chat.mText = std::string("IM: ") + session->mName + std::string(": ") + rawMessage; + chat.mText = std::string("IM: ") + session->mName + std::string(": ") + message; // If the chat should come in quietly (i.e. we're in busy mode), pretend it's from a local agent. LLFloaterChat::addChat( chat, TRUE, quiet_chat ); } @@ -5785,6 +5786,7 @@ bool LLVoiceClient::getMuteMic() const void LLVoiceClient::setUserPTTState(bool ptt) { mUserPTTState = ptt; + LLNearbyChatBar::getInstance()->setPTTState(ptt); } bool LLVoiceClient::getUserPTTState() @@ -5795,6 +5797,7 @@ bool LLVoiceClient::getUserPTTState() void LLVoiceClient::toggleUserPTTState(void) { mUserPTTState = !mUserPTTState; + LLNearbyChatBar::getInstance()->setPTTState(mUserPTTState); } void LLVoiceClient::setVoiceEnabled(bool enabled) diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp index a361a1160c..9bafc03a6d 100644 --- a/indra/newview/llvoicevisualizer.cpp +++ b/indra/newview/llvoicevisualizer.cpp @@ -42,9 +42,8 @@ #include "llvoicevisualizer.h" #include "llviewercamera.h" #include "llviewerobject.h" -#include "llimagegl.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llvoiceclient.h" #include "llrender.h" @@ -143,7 +142,7 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type ) for (int i=0; i mTexture [ NUM_VOICE_SYMBOL_WAVES ]; + LLPointer mTexture [ NUM_VOICE_SYMBOL_WAVES ]; bool mActive; LLVector3 mPosition; }; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index d99758edf8..993cf522e9 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -49,7 +49,7 @@ #include "llglheaders.h" #include "llsky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llworld.h" @@ -212,8 +212,8 @@ void LLSkyTex::init() for (S32 i = 0; i < 2; ++i) { - mImageGL[i] = new LLImageGL(FALSE); - mImageGL[i]->setAddressMode(LLTexUnit::TAM_CLAMP); + mTexture[i] = LLViewerTextureManager::getLocalTexture(FALSE); + mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP); mImageRaw[i] = new LLImageRaw(sResolution, sResolution, sComponents); initEmpty(i); @@ -222,16 +222,16 @@ void LLSkyTex::init() void LLSkyTex::cleanupGL() { - mImageGL[0] = NULL; - mImageGL[1] = NULL; + mTexture[0] = NULL; + mTexture[1] = NULL; } void LLSkyTex::restoreGL() { for (S32 i = 0; i < 2; i++) { - mImageGL[i] = new LLImageGL(FALSE); - mImageGL[i]->setAddressMode(LLTexUnit::TAM_CLAMP); + mTexture[i] = LLViewerTextureManager::getLocalTexture(FALSE); + mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP); } } @@ -289,13 +289,13 @@ void LLSkyTex::create(const F32 brightness) void LLSkyTex::createGLImage(S32 which) { - mImageGL[which]->createGLTexture(0, mImageRaw[which]); - mImageGL[which]->setAddressMode(LLTexUnit::TAM_CLAMP); + mTexture[which]->createGLTexture(0, mImageRaw[which]); + mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP); } void LLSkyTex::bindTexture(BOOL curr) { - gGL.getTexUnit(0)->bind(mImageGL[getWhich(curr)]); + gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)]); } /*************************************** @@ -368,7 +368,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) initSunDirection(mSunDefaultPosition, LLVector3(0, 0, 0)); } mAmbientScale = gSavedSettings.getF32("SkyAmbientScale"); - mNightColorShift = gSavedSkinSettings.getColor3("SkyNightColorShift"); + mNightColorShift = gSavedSettings.getColor3("SkyNightColorShift"); mFogColor.mV[VRED] = mFogColor.mV[VGREEN] = mFogColor.mV[VBLUE] = 0.5f; mFogColor.mV[VALPHA] = 0.0f; mFogRatio = 1.2f; @@ -376,11 +376,11 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) mSun.setIntensity(SUN_INTENSITY); mMoon.setIntensity(0.1f * SUN_INTENSITY); - mSunTexturep = gImageList.getImage(gSunTextureID, TRUE, TRUE); + mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, TRUE); mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - mMoonTexturep = gImageList.getImage(gMoonTextureID, TRUE, TRUE); + mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, TRUE); mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - mBloomTexturep = gImageList.getImage(IMG_BLOOM1); + mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1); mBloomTexturep->setNoDelete() ; mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -390,7 +390,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) LLVOSky::~LLVOSky() { - // Don't delete images - it'll get deleted by gImageList on shutdown + // Don't delete images - it'll get deleted by gTextureList on shutdown // This needs to be done for each texture mCubeMap = NULL; @@ -472,11 +472,11 @@ void LLVOSky::restoreGL() { mSkyTex[i].restoreGL(); } - mSunTexturep = gImageList.getImage(gSunTextureID, TRUE, TRUE); + mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, TRUE); mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - mMoonTexturep = gImageList.getImage(gMoonTextureID, TRUE, TRUE); + mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, TRUE); mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - mBloomTexturep = gImageList.getImage(IMG_BLOOM1); + mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1); mBloomTexturep->setNoDelete() ; mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index 5e23065153..466cdfdcd0 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -36,7 +36,7 @@ #include "stdtypes.h" #include "v3color.h" #include "v4coloru.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llviewerobject.h" #include "llframetimer.h" @@ -122,7 +122,7 @@ class LLSkyTex private: static S32 sResolution; static S32 sComponents; - LLPointer mImageGL[2]; + LLPointer mTexture[2]; LLPointer mImageRaw[2]; LLColor4 *mSkyData; LLVector3 *mSkyDirs; // Cache of sky direction vectors @@ -567,9 +567,9 @@ public: BOOL isReflFace(const LLFace* face) const { return face == mFace[FACE_REFLECTION]; } LLFace* getReflFace() const { return mFace[FACE_REFLECTION]; } - LLViewerImage* getSunTex() const { return mSunTexturep; } - LLViewerImage* getMoonTex() const { return mMoonTexturep; } - LLViewerImage* getBloomTex() const { return mBloomTexturep; } + LLViewerTexture* getSunTex() const { return mSunTexturep; } + LLViewerTexture* getMoonTex() const { return mMoonTexturep; } + LLViewerTexture* getBloomTex() const { return mBloomTexturep; } void forceSkyUpdate(void) { mForceUpdate = TRUE; } public: @@ -579,9 +579,9 @@ public: protected: ~LLVOSky(); - LLPointer mSunTexturep; - LLPointer mMoonTexturep; - LLPointer mBloomTexturep; + LLPointer mSunTexturep; + LLPointer mMoonTexturep; + LLPointer mBloomTexturep; static S32 sResolution; static S32 sTileResX; diff --git a/indra/newview/llvotextbubble.cpp b/indra/newview/llvotextbubble.cpp index de69aac037..9871965458 100644 --- a/indra/newview/llvotextbubble.cpp +++ b/indra/newview/llvotextbubble.cpp @@ -43,7 +43,7 @@ #include "llbox.h" #include "lldrawable.h" #include "llface.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llvolume.h" #include "pipeline.h" #include "llviewerregion.h" @@ -125,7 +125,7 @@ void LLVOTextBubble::updateTextures(LLAgent &agent) const LLTextureEntry *te = getTE(i); F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT); texel_area_ratio = llclamp(texel_area_ratio, .125f, 16.f); - LLViewerImage *imagep = getTEImage(i); + LLViewerTexture *imagep = getTEImage(i); if (imagep) { imagep->addTextureStats(mPixelArea / texel_area_ratio); @@ -142,9 +142,9 @@ LLDrawable *LLVOTextBubble::createDrawable(LLPipeline *pipeline) for (U32 i = 0; i < getNumTEs(); i++) { - LLViewerImage *imagep; + LLViewerTexture *imagep; const LLTextureEntry *texture_entry = getTE(i); - imagep = gImageList.getImage(texture_entry->getID()); + imagep = LLViewerTextureManager::getFetchedTexture(texture_entry->getID()); mDrawable->addFace((LLFacePool*) NULL, imagep); } @@ -194,7 +194,7 @@ BOOL LLVOTextBubble::updateGeometry(LLDrawable *drawable) { LLFace *face = drawable->getFace(i); face->setTEOffset(i); - face->setTexture(LLViewerImage::sSmokeImagep); + face->setTexture(LLViewerFetchedTexture::sSmokeImagep); face->setState(LLFace::FULLBRIGHT); } diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index b602b93025..d1cac4c77e 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -48,7 +48,7 @@ #include "lldrawable.h" #include "llface.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llworld.h" @@ -311,10 +311,10 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys, // // Load Species-Specific data // - mTreeImagep = gImageList.getImage(sSpeciesTable[mSpecies]->mTextureID); + mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); if (mTreeImagep) { - gGL.getTexUnit(0)->bind(mTreeImagep.get()); + gGL.getTexUnit(0)->bind(mTreeImagep); } mBranchLength = sSpeciesTable[mSpecies]->mBranchLength; mTrunkLength = sSpeciesTable[mSpecies]->mTrunkLength; diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index 42a6d54f62..13817fa111 100644 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -39,7 +39,7 @@ class LLFace; class LLDrawPool; - +class LLViewerFetchedTexture; class LLVOTree : public LLViewerObject { @@ -160,7 +160,7 @@ protected: LLVector3 mWind; LLPointer mReferenceBuffer; //reference geometry for generating tree mesh - LLPointer mTreeImagep; // Pointer to proper tree image + LLPointer mTreeImagep; // Pointer to proper tree image U8 mSpecies; // Species of tree F32 mBranchLength; // Scale (length) of tree branches @@ -184,7 +184,7 @@ protected: // complete rebuild when not animating LLVector3 mLastPosition; LLQuaternion mLastRotation; - + U32 mFrameCount; typedef std::map SpeciesMap; diff --git a/indra/newview/llvotreenew.h b/indra/newview/llvotreenew.h index 02f6d3a056..3fec5855ef 100644 --- a/indra/newview/llvotreenew.h +++ b/indra/newview/llvotreenew.h @@ -41,7 +41,7 @@ #include "llstrider.h" #include "v2math.h" #include "v3math.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLFace; class LLDrawPool; @@ -187,7 +187,7 @@ public: //LLTreeParams mParams; U8 mSpecies; - LLPointer mTreeImagep; + LLPointer mTreeImagep; LLMatrix4 mTrunkFlareFrames[MAX_FLARE]; F32 mSegSplitsError[3]; U32 mRandOffset[MAX_LEVELS]; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f31f09f60e..bef38bb669 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -59,7 +59,7 @@ #include "llsky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "llviewertextureanim.h" #include "llworld.h" @@ -427,7 +427,7 @@ void LLVOVolume::updateTextures() return; } - if (LLViewerImage::sDontLoadVolumeTextures || mDrawable.isNull()) // || !mDrawable->isVisible()) + if (LLViewerTexture::sDontLoadVolumeTextures || mDrawable.isNull()) // || !mDrawable->isVisible()) { return; } @@ -443,7 +443,7 @@ void LLVOVolume::updateTextures() { LLFace* face = mDrawable->getFace(i); const LLTextureEntry *te = face->getTextureEntry(); - LLViewerImage *imagep = face->getTexture(); + LLViewerTexture *imagep = face->getTexture(); if (!imagep || !te || face->mExtents[0] == face->mExtents[1]) { @@ -456,7 +456,7 @@ void LLVOVolume::updateTextures() { F32 area = (F32) LLViewerCamera::getInstance()->getScreenPixelArea(); vsize = area; - imagep->setBoostLevel(LLViewerImage::BOOST_HUD); + imagep->setBoostLevel(LLViewerTexture::BOOST_HUD); face->setPixelArea(area); // treat as full screen } else @@ -486,10 +486,14 @@ void LLVOVolume::updateTextures() } else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) { - F32 pri = imagep->getDecodePriority(); - pri = llmax(pri, 0.0f); - if (pri < min_vsize) min_vsize = pri; - if (pri > max_vsize) max_vsize = pri; + LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ; + if(img) + { + F32 pri = img->getDecodePriority(); + pri = llmax(pri, 0.0f); + if (pri < min_vsize) min_vsize = pri; + if (pri > max_vsize) max_vsize = pri; + } } else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) { @@ -503,7 +507,7 @@ void LLVOVolume::updateTextures() { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); LLUUID id = sculpt_params->getSculptTexture(); - mSculptTexture = gImageList.getImage(id); + mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); if (mSculptTexture.notNull()) { S32 lod = llmin(mLOD, 3); @@ -511,7 +515,7 @@ void LLVOVolume::updateTextures() F32 tex_size = lodf * MAX_SCULPT_REZ; mSculptTexture->addTextureStats(2.f * tex_size * tex_size); mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), - (S32)LLViewerImage::BOOST_SCULPTED)); + (S32)LLViewerTexture::BOOST_SCULPTED)); mSculptTexture->setForSculpt() ; } @@ -625,7 +629,7 @@ void LLVOVolume::setScale(const LLVector3 &scale, BOOL damped) LLFace* LLVOVolume::addFace(S32 f) { const LLTextureEntry* te = getTE(f); - LLViewerImage* imagep = getTEImage(f); + LLViewerTexture* imagep = getTEImage(f); return mDrawable->addFace(te, imagep); } @@ -701,7 +705,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail if (isSculpted()) { - mSculptTexture = gImageList.getImage(volume_params.getSculptID()); + mSculptTexture = LLViewerTextureManager::getFetchedTexture(volume_params.getSculptID(), TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); if (mSculptTexture.notNull()) { sculpt(); @@ -783,9 +787,9 @@ void LLVOVolume::sculpt() sculpt_height = 0; sculpt_data = NULL ; - if(LLViewerImage::sTesterp) + if(LLViewerTextureManager::sTesterp) { - LLViewerImage::sTesterp->updateGrayTextureBinding(); + LLViewerTextureManager::sTesterp->updateGrayTextureBinding(); } } else @@ -796,9 +800,9 @@ void LLVOVolume::sculpt() sculpt_data = raw_image->getData(); - if(LLViewerImage::sTesterp) + if(LLViewerTextureManager::sTesterp) { - mSculptTexture->updateBindStats() ; + mSculptTexture->updateBindStatsForTester() ; } } getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level); @@ -1257,7 +1261,7 @@ BOOL LLVOVolume::isRootEdit() const return TRUE; } -void LLVOVolume::setTEImage(const U8 te, LLViewerImage *imagep) +void LLVOVolume::setTEImage(const U8 te, LLViewerTexture *imagep) { BOOL changed = (mTEImages[te] != imagep); LLViewerObject::setTEImage(te, imagep); @@ -2056,7 +2060,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e { LLFace* face = mDrawable->getFace(face_hit); - if (pick_transparent || !face->getTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))) + if (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))) { v_end = p; if (face_hitp != NULL) @@ -2167,7 +2171,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U8 bump = (type == LLRenderPass::PASS_BUMP ? facep->getTextureEntry()->getBumpmap() : 0); - LLViewerImage* tex = facep->getTexture(); + LLViewerTexture* tex = facep->getTexture(); U8 glow = 0; @@ -2318,7 +2322,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA) { const LLTextureEntry* te = facep->getTextureEntry(); - LLViewerImage* tex = facep->getTexture(); + LLViewerTexture* tex = facep->getTexture(); if (facep->isState(LLFace::TEXTURE_ANIM)) { @@ -2566,7 +2570,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: LLSpatialGroup::buffer_map_t buffer_map; - LLViewerImage* last_tex = NULL; + LLViewerTexture* last_tex = NULL; S32 buffer_index = 0; if (distance_sort) @@ -2578,7 +2582,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: { //pull off next face LLFace* facep = *face_iter; - LLViewerImage* tex = facep->getTexture(); + LLViewerTexture* tex = facep->getTexture(); if (distance_sort) { diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 5d7b373b3c..d343d4db74 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -34,7 +34,7 @@ #define LL_LLVOVOLUME_H #include "llviewerobject.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llframetimer.h" #include "llapr.h" #include "m3math.h" // LLMatrix3 @@ -153,7 +153,7 @@ public: /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped); - /*virtual*/ void setTEImage(const U8 te, LLViewerImage *imagep); + /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep); /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid); /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color); /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color); @@ -237,7 +237,7 @@ private: BOOL mVolumeChanged; F32 mVObjRadius; LLVolumeInterface *mVolumeImpl; - LLPointer mSculptTexture; + LLPointer mSculptTexture; // statics public: diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index d23c746b75..427119285b 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -45,7 +45,7 @@ #include "llsurface.h" #include "llvosky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "llworld.h" #include "pipeline.h" diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h index cdda48f6f2..28a5633c58 100644 --- a/indra/newview/llvowater.h +++ b/indra/newview/llvowater.h @@ -34,7 +34,7 @@ #define LL_VOWATER_H #include "llviewerobject.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "v2math.h" const U32 N_RES = 16; //32 // number of subdivisions of wave tile diff --git a/indra/newview/llwatchdog.h b/indra/newview/llwatchdog.h index ed7d5bdcfb..79398c434a 100644 --- a/indra/newview/llwatchdog.h +++ b/indra/newview/llwatchdog.h @@ -64,9 +64,10 @@ public: /* virtual */ bool isAlive() const; /* virtual */ void reset(); - /* virtual */ void start(const std::string& state); + /* virtual */ void start() { start(""); } /* virtual */ void stop(); + void start(const std::string& state); void setTimeout(F32 d); void ping(const std::string& state); const std::string& getState() {return mPingState; } diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 50e407739b..92c223e43d 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -39,6 +39,7 @@ #include "pipeline.h" #include "llsky.h" +#include "llfloaterreg.h" #include "llsliderctrl.h" #include "llspinctrl.h" #include "llcheckboxctrl.h" @@ -270,9 +271,10 @@ void LLWaterParamManager::update(LLViewerCamera * cam) propagateParameters(); // sync menus if they exist - if(LLFloaterWater::isOpen()) + LLFloaterWater* waterfloater = LLFloaterReg::findTypedInstance("env_water"); + if(waterfloater) { - LLFloaterWater::instance()->syncMenu(); + waterfloater->syncMenu(); } stop_glerror(); diff --git a/indra/newview/llwaterparamset.cpp b/indra/newview/llwaterparamset.cpp index a26ccedfb2..3e97f9dbef 100644 --- a/indra/newview/llwaterparamset.cpp +++ b/indra/newview/llwaterparamset.cpp @@ -39,7 +39,7 @@ #include "llwaterparammanager.h" #include "lluictrlfactory.h" #include "llsliderctrl.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewercontrol.h" #include "lluuid.h" diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 1e35a31cb6..0d3dd10a01 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -35,7 +35,7 @@ #include "llagent.h" #include "llagentwearables.h" #include "llfloatercustomize.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llinventorymodel.h" #include "llviewerregion.h" #include "llvoavatar.h" @@ -156,7 +156,7 @@ BOOL LLWearable::exportFile(LLFILE* file) const for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter) { S32 te = iter->first; - const LLUUID& image_id = iter->second; + const LLUUID& image_id = iter->second.getID(); if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 ) { return FALSE; @@ -350,7 +350,8 @@ BOOL LLWearable::importFile( LLFILE* file ) return FALSE; } - mTEMap[te] = LLUUID(text_buffer ); + //TODO: check old values + mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, LLUUID(text_buffer)); } return TRUE; @@ -459,16 +460,21 @@ BOOL LLWearable::isDirty() const { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - LLViewerImage* avatar_image = avatar->getTEImage( te ); + LLViewerTexture* avatar_image = avatar->getTEImage( te ); if( !avatar_image ) { llassert( 0 ); continue; } - const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te)); - if( avatar_image->getID() != image_id ) + + te_map_t::const_iterator iter = mTEMap.find(te); + if(iter != mTEMap.end()) { - return TRUE; + const LLUUID& image_id = iter->second.getID(); + if (avatar_image->getID() != image_id) + { + return TRUE; + } } } } @@ -511,7 +517,7 @@ void LLWearable::setTexturesToDefaults() { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - mTEMap[te] = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); + mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te)); } } } @@ -558,8 +564,17 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te)); - LLViewerImage* image = gImageList.getImage( image_id ); + te_map_t::const_iterator iter = mTEMap.find(te); + LLUUID image_id; + if(iter != mTEMap.end()) + { + image_id = iter->second.getID(); + } + else + { + image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); + } + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE ); avatar->setLocalTextureTE(te, image, set_by_user); } } @@ -570,7 +585,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) { LLViewerInventoryItem* item; // MULTI_WEARABLE: - item = (LLViewerInventoryItem*)gInventory.getItem(gAgentWearables.getWearableItem(mType,0)); + item = (LLViewerInventoryItem*)gInventory.getItem(gAgentWearables.getWearableItemID(mType,0)); U32 perm_mask = PERM_NONE; BOOL is_complete = FALSE; if(item) @@ -631,7 +646,7 @@ void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user ) } // Pull textures - LLViewerImage* image = gImageList.getImage( IMG_DEFAULT_AVATAR ); + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( IMG_DEFAULT_AVATAR ); for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == type) @@ -682,10 +697,10 @@ void LLWearable::readFromAvatar() { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - LLViewerImage* image = avatar->getTEImage( te ); + LLViewerTexture* image = avatar->getTEImage( te ); if( image ) { - mTEMap[te] = image->getID(); + mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, image->getID()); } } } @@ -733,12 +748,54 @@ void LLWearable::copyDataFrom(const LLWearable* src) { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - const LLUUID& image_id = get_if_there(src->mTEMap, te, LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te)); - mTEMap[te] = image_id; + te_map_t::const_iterator iter = mTEMap.find(te); + LLUUID image_id; + if(iter != mTEMap.end()) + { + image_id = iter->second.getID(); + } + else + { + image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); + } + mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, image_id); } } } +void LLWearable::setItemID(const LLUUID& item_id) +{ + mItemID = item_id; +} + +const LLUUID& LLWearable::getItemID() const +{ + return mItemID; +} + +LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const +{ + te_map_t::const_iterator iter = mTEMap.find(index); + if( iter != mTEMap.end() ) + { + return (LLLocalTextureObject*) &iter->second; + } + return NULL; +} + +void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject *lto) +{ + if( lto ) + { + LLLocalTextureObject obj(*lto); + mTEMap[index] = obj; + } + else + { + mTEMap.erase(index); + } +} + struct LLWearableSaveData { EWearableType mType; @@ -849,7 +906,7 @@ std::ostream& operator<<(std::ostream &s, const LLWearable &w) iter != w.mTEMap.end(); ++iter) { S32 te = iter->first; - const LLUUID& image_id = iter->second; + const LLUUID& image_id = iter->second.getID(); s << " " << te << " " << image_id << "\n"; } return s; diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h index 7ebdd788ce..5f0b235c7f 100644 --- a/indra/newview/llwearable.h +++ b/indra/newview/llwearable.h @@ -39,6 +39,8 @@ #include "llsaleinfo.h" #include "llassetstorage.h" #include "llwearabledictionary.h" +#include "llfile.h" +#include "lllocaltextureobject.h" class LLViewerInventoryItem; @@ -60,7 +62,7 @@ public: // Accessors //-------------------------------------------------------------------- public: - const LLAssetID& getID() const { return mAssetID; } + const LLAssetID& getAssetID() const { return mAssetID; } const LLTransactionID& getTransactionID() const { return mTransactionID; } EWearableType getType() const { return mType; } void setType(EWearableType type) { mType = type; } @@ -99,6 +101,10 @@ public: static void setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; } friend std::ostream& operator<<(std::ostream &s, const LLWearable &w); + void setItemID(const LLUUID& item_id); + const LLUUID& getItemID() const; + LLLocalTextureObject* getLocalTextureObject(S32 index) const; + void setLocalTextureObject(S32 index, LLLocalTextureObject *lto); private: static S32 sCurrentDefinitionVersion; // Depends on the current state of the avatar_lad.xml. @@ -113,8 +119,9 @@ private: typedef std::map param_map_t; param_map_t mVisualParamMap; // maps visual param id to weight - typedef std::map te_map_t; - te_map_t mTEMap; // maps TE to Image ID + typedef std::map te_map_t; + te_map_t mTEMap; // maps TE to LocalTextureObject + LLUUID mItemID; // ID of the inventory item in the agent's inventory }; #endif // LL_LLWEARABLE_H diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index 781f8298f7..57f57f75d7 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -41,6 +41,7 @@ #include "llviewerwindow.h" #include "llviewercontrol.h" #include "llfloaterhtmlhelp.h" +#include "llfloaterreg.h" #include "llalertdialog.h" class URLLoader : public LLAlertDialog::URLLoader @@ -75,7 +76,7 @@ void LLWeb::loadURL(const std::string& url) } else { - LLFloaterMediaBrowser::showInstance(url); + LLFloaterReg::showInstance("media_browser",url); } } diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index b8a2bf0bd2..c237c0bded 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -37,6 +37,7 @@ #include "pipeline.h" #include "llsky.h" +#include "llfloaterreg.h" #include "llsliderctrl.h" #include "llspinctrl.h" #include "llcheckboxctrl.h" @@ -377,17 +378,20 @@ void LLWLParamManager::update(LLViewerCamera * cam) propagateParameters(); // sync menus if they exist - if(LLFloaterWindLight::isOpen()) + LLFloaterWindLight* wlfloater = LLFloaterReg::findTypedInstance("env_windlight"); + if (wlfloater) { - LLFloaterWindLight::instance()->syncMenu(); + wlfloater->syncMenu(); } - if(LLFloaterDayCycle::isOpen()) + LLFloaterDayCycle* dlfloater = LLFloaterReg::findTypedInstance("env_day_cycle"); + if (dlfloater) { - LLFloaterDayCycle::instance()->syncMenu(); + dlfloater->syncMenu(); } - if(LLFloaterEnvSettings::isOpen()) + LLFloaterEnvSettings* envfloater = LLFloaterReg::findTypedInstance("env_settings"); + if (envfloater) { - LLFloaterEnvSettings::instance()->syncMenu(); + envfloater->syncMenu(); } F32 camYaw = cam->getYaw(); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 692efd2b7a..5c6fc2cf21 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -46,8 +46,8 @@ #include "llregionhandle.h" #include "llsurface.h" #include "llviewercamera.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewernetwork.h" #include "llviewerobjectlist.h" #include "llviewerparceloverlay.h" @@ -109,8 +109,8 @@ LLWorld::LLWorld() : *(default_texture++) = MAX_WATER_COLOR.mV[2]; *(default_texture++) = MAX_WATER_COLOR.mV[3]; - mDefaultWaterTexturep = new LLViewerImage(raw, FALSE); - gGL.getTexUnit(0)->bind(mDefaultWaterTexturep.get()); + mDefaultWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); + gGL.getTexUnit(0)->bind(mDefaultWaterTexturep); mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); } @@ -962,7 +962,7 @@ void LLWorld::shiftRegions(const LLVector3& offset) LLViewerPartSim::getInstance()->shift(offset); } -LLViewerImage* LLWorld::getDefaultWaterTexture() +LLViewerTexture* LLWorld::getDefaultWaterTexture() { return mDefaultWaterTexturep; } diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index b5380a6f6c..48025c700b 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -45,7 +45,7 @@ #include "llsingleton.h" #include "llstring.h" #include "llviewerpartsim.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llvowater.h" class LLViewerRegion; @@ -141,7 +141,7 @@ public: F32 getLandFarClip() const; void setLandFarClip(const F32 far_clip); - LLViewerImage *getDefaultWaterTexture(); + LLViewerTexture *getDefaultWaterTexture(); void updateWaterObjects(); void shiftRegions(const LLVector3& offset); @@ -192,7 +192,7 @@ private: std::list mHoleWaterObjects; LLPointer mEdgeWaterObjects[8]; - LLPointer mDefaultWaterTexturep; + LLPointer mDefaultWaterTexturep; }; diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index 827f12d19e..700971dcc4 100644 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -43,7 +43,7 @@ #include "llviewercontrol.h" #include "llfloaterworldmap.h" #include "lltracker.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "llregionflags.h" #include "lltrans.h" @@ -519,9 +519,9 @@ void LLWorldMap::processMapLayerReply(LLMessageSystem* msg, void**) LLWorldMapLayer new_layer; new_layer.LayerDefined = TRUE; msg->getUUIDFast(_PREHASH_LayerData, _PREHASH_ImageID, new_layer.LayerImageID, block); - new_layer.LayerImage = gImageList.getImage(new_layer.LayerImageID, MIPMAP_TRUE, FALSE); + new_layer.LayerImage = LLViewerTextureManager::getFetchedTexture(new_layer.LayerImageID, MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); - gGL.getTexUnit(0)->bind(new_layer.LayerImage.get()); + gGL.getTexUnit(0)->bind(new_layer.LayerImage); new_layer.LayerImage->setAddressMode(LLTexUnit::TAM_CLAMP); U32 left, right, top, bottom; @@ -634,15 +634,15 @@ void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) siminfo->mMapImageID[agent_flags] = image_id; #ifdef IMMEDIATE_IMAGE_LOAD - siminfo->mCurrentImage = gImageList.getImage(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE); - gGL.getTexUnit(0)->bind(siminfo->mCurrentImage.get()); + siminfo->mCurrentImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); + gGL.getTexUnit(0)->bind(siminfo->mCurrentImage); siminfo->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP); #endif if (siminfo->mMapImageID[2].notNull()) { #ifdef IMMEDIATE_IMAGE_LOAD - siminfo->mOverlayImage = gImageList.getImage(siminfo->mMapImageID[2], MIPMAP_TRUE, FALSE); + siminfo->mOverlayImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[2], MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); #endif } else @@ -862,10 +862,10 @@ void LLWorldMap::dump() if (info->mCurrentImage) { llinfos << "image discard " << (S32)info->mCurrentImage->getDiscardLevel() - << " fullwidth " << info->mCurrentImage->getWidth(0) - << " fullheight " << info->mCurrentImage->getHeight(0) - << " maxvirt " << info->mCurrentImage->mMaxVirtualSize - << " maxdisc " << (S32)info->mCurrentImage->getMaxDiscardLevel() + << " fullwidth " << info->mCurrentImage->getFullWidth() + << " fullheight " << info->mCurrentImage->getFullHeight() + << " maxvirt " << info->mCurrentImage->getMaxVirtualSize() + //<< " maxdisc " << (S32)info->mCurrentImage->getMaxDiscardLevel() << llendl; } } diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index 1db081c74a..9daee38752 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -45,7 +45,7 @@ #include "lluuid.h" #include "llpointer.h" #include "llsingleton.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "lleventinfo.h" #include "v3color.h" @@ -96,8 +96,8 @@ public: LLUUID mMapImageID[MAP_SIM_IMAGE_TYPES]; // Hold a reference to the currently displayed image. - LLPointer mCurrentImage; - LLPointer mOverlayImage; + LLPointer mCurrentImage; + LLPointer mOverlayImage; }; #define MAP_BLOCK_RES 256 @@ -105,7 +105,7 @@ public: struct LLWorldMapLayer { BOOL LayerDefined; - LLPointer LayerImage; + LLPointer LayerImage; LLUUID LayerImageID; LLRect LayerExtents; diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 9ac758433c..67bc205f62 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -54,8 +54,8 @@ #include "lltextureview.h" #include "lltracker.h" #include "llviewercamera.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewermenu.h" #include "llviewerparceloverlay.h" #include "llviewerregion.h" @@ -284,7 +284,7 @@ BOOL is_agent_in_region(LLViewerRegion* region, LLSimInfo* info) void LLWorldMapView::draw() { - static LLCachedControl map_track_color(gSavedSkinSettings, "MapTrackColor", LLColor4::white); + static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white); LLTextureView::clearDebugImages(); @@ -332,7 +332,7 @@ void LLWorldMapView::draw() continue; } LLWorldMapLayer *layer = &LLWorldMap::getInstance()->mMapLayers[LLWorldMap::getInstance()->mCurrentMap][layer_idx]; - LLViewerImage *current_image = layer->LayerImage; + LLViewerFetchedTexture *current_image = layer->LayerImage; if (current_image->isMissingAsset()) { @@ -367,10 +367,10 @@ void LLWorldMapView::draw() continue; } - current_image->setBoostLevel(LLViewerImage::BOOST_MAP_LAYER); + current_image->setBoostLevel(LLViewerTexture::BOOST_MAP_LAYER); current_image->setKnownDrawSize(llround(pix_width * LLUI::sGLScaleFactor.mV[VX]), llround(pix_height * LLUI::sGLScaleFactor.mV[VY])); - if (!current_image->getHasGLTexture()) + if (!current_image->hasValidGLTexture()) { continue; // better to draw nothing than the default image } @@ -434,8 +434,8 @@ void LLWorldMapView::draw() U64 handle = (*it).first; LLSimInfo* info = (*it).second; - LLViewerImage* simimage = info->mCurrentImage; - LLViewerImage* overlayimage = info->mOverlayImage; + LLViewerFetchedTexture* simimage = info->mCurrentImage; + LLViewerFetchedTexture* overlayimage = info->mOverlayImage; if (gMapScale < SIM_MAP_SCALE) { @@ -472,7 +472,7 @@ void LLWorldMapView::draw() bool sim_visible = (gMapScale >= map_scale_cutoff) && (simimage != NULL) && - (simimage->getHasGLTexture()); + (simimage->hasValidGLTexture()); if (sim_visible) { @@ -510,7 +510,7 @@ void LLWorldMapView::draw() (textures_requested_this_tick < MAX_REQUEST_PER_TICK))) { textures_requested_this_tick++; - info->mCurrentImage = gImageList.getImage(info->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE); + info->mCurrentImage = LLViewerTextureManager::getFetchedTexture(info->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); info->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP); simimage = info->mCurrentImage; gGL.getTexUnit(0)->bind(simimage); @@ -523,7 +523,7 @@ void LLWorldMapView::draw() (textures_requested_this_tick < MAX_REQUEST_PER_TICK))) { textures_requested_this_tick++; - info->mOverlayImage = gImageList.getImage(info->mMapImageID[2], MIPMAP_TRUE, FALSE); + info->mOverlayImage = LLViewerTextureManager::getFetchedTexture(info->mMapImageID[2], MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); info->mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP); overlayimage = info->mOverlayImage; gGL.getTexUnit(0)->bind(overlayimage); @@ -546,13 +546,13 @@ void LLWorldMapView::draw() S32 draw_size = llround(gMapScale); if (simimage != NULL) { - simimage->setBoostLevel(LLViewerImage::BOOST_MAP); + simimage->setBoostLevel(LLViewerTexture::BOOST_MAP); simimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY])); } if (overlayimage != NULL) { - overlayimage->setBoostLevel(LLViewerImage::BOOST_MAP); + overlayimage->setBoostLevel(LLViewerTexture::BOOST_MAP); overlayimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY])); } @@ -581,7 +581,7 @@ void LLWorldMapView::draw() gGL.vertex3f(right, top, 0.f); gGL.end(); - if (gSavedSettings.getBOOL("MapShowLandForSale") && overlayimage && overlayimage->getHasGLTexture()) + if (gSavedSettings.getBOOL("MapShowLandForSale") && overlayimage && overlayimage->hasValidGLTexture()) { gGL.getTexUnit(0)->bind(overlayimage); gGL.color4f(1.f, 1.f, 1.f, alpha); @@ -908,8 +908,8 @@ void LLWorldMapView::drawImageStack(const LLVector3d& global_pos, LLUIImagePtr i void LLWorldMapView::drawAgents() { - static LLCachedControl map_avatar_color(gSavedSkinSettings, "MapAvatarColor", LLColor4::white); - static LLCachedControl map_avatar_friend_color(gSavedSkinSettings, "MapAvatarFriendColor", LLColor4::white); + static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white); + static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white); F32 agents_scale = (gMapScale * 0.9f) / 256.f; @@ -1228,12 +1228,11 @@ BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* stic msg += region_flags; } - S32 SLOP = 4; - localPointToScreen( - x - SLOP, y - SLOP, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP; - sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP; + const S32 SLOP = 9; + S32 screen_x, screen_y; + + localPointToScreen(x, y, &screen_x, &screen_y); + sticky_rect_screen->setCenterAndSize(screen_x, screen_y, SLOP, SLOP); } return TRUE; } diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h index dd64da1371..41c9772694 100644 --- a/indra/newview/llworldmapview.h +++ b/indra/newview/llworldmapview.h @@ -39,7 +39,7 @@ #include "v3math.h" #include "v3dmath.h" #include "v4color.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llmapimagetype.h" #include "llworldmap.h" @@ -50,7 +50,7 @@ const S32 DEFAULT_TRACKING_ARROW_SIZE = 16; class LLColor4; class LLColor4U; class LLCoordGL; -class LLViewerImage; +class LLViewerTexture; class LLTextBox; diff --git a/indra/newview/macview_Prefix.h b/indra/newview/macview_Prefix.h index 33cf7d8cb0..0fcdf2da4f 100644 --- a/indra/newview/macview_Prefix.h +++ b/indra/newview/macview_Prefix.h @@ -63,7 +63,6 @@ #include "lldrawable.h" #include "llfirstuse.h" #include "llfloater.h" -#include "llfloateravatarinfo.h" #include "llfloaterbuildoptions.h" #include "llfloaterchat.h" #include "llfloatercustomize.h" @@ -75,7 +74,6 @@ #include "llfloatertools.h" #include "llhudeffectlookat.h" #include "llhudmanager.h" -#include "llinventoryview.h" #include "lljoystickbutton.h" #include "llmenugl.h" #include "llmorphview.h" diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 25ed853146..f422791868 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -66,6 +66,7 @@ #include "llface.h" #include "llfeaturemanager.h" #include "llfloatertelehub.h" +#include "llfloaterreg.h" #include "llgldbg.h" #include "llhudmanager.h" #include "lllightconstants.h" @@ -76,7 +77,7 @@ #include "lltool.h" #include "lltoolmgr.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" @@ -751,9 +752,9 @@ S32 LLPipeline::setLightingDetail(S32 level) class LLOctreeDirtyTexture : public LLOctreeTraveler { public: - const std::set& mTextures; + const std::set& mTextures; - LLOctreeDirtyTexture(const std::set& textures) : mTextures(textures) { } + LLOctreeDirtyTexture(const std::set& textures) : mTextures(textures) { } virtual void visit(const LLOctreeNode* node) { @@ -766,7 +767,8 @@ public: for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) { LLDrawInfo* params = *j; - if (mTextures.find(params->mTexture) != mTextures.end()) + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params->mTexture); + if (tex && mTextures.find(tex) != mTextures.end()) { group->setState(LLSpatialGroup::GEOM_DIRTY); } @@ -783,7 +785,7 @@ public: }; // Called when a texture changes # of channels (causes faces to move to alpha pool) -void LLPipeline::dirtyPoolObjectTextures(const std::set& textures) +void LLPipeline::dirtyPoolObjectTextures(const std::set& textures) { assertInitialized(); @@ -815,7 +817,7 @@ void LLPipeline::dirtyPoolObjectTextures(const std::set& texture } } -LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) +LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0) { assertInitialized(); @@ -887,7 +889,7 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) } -LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerImage *tex0) +LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0) { LLMemType mt(LLMemType::MTYPE_PIPELINE); LLDrawPool *poolp = findPool(type, tex0); @@ -904,7 +906,7 @@ LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerImage *tex0) // static -LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerImage* imagep) +LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* imagep) { LLMemType mt(LLMemType::MTYPE_PIPELINE); U32 type = getPoolTypeFromTE(te, imagep); @@ -912,7 +914,7 @@ LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerImage* i } //static -U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* imagep) +U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep) { LLMemType mt_gpt(LLMemType::MTYPE_PIPELINE_GET_POOL_TYPE); @@ -924,7 +926,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* image bool alpha = te->getColor().mV[3] < 0.999f; if (imagep) { - alpha = alpha || (imagep->getComponents() == 4 && ! imagep->mIsMediaTexture) || (imagep->getComponents() == 2); + alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2); } if (alpha) @@ -2298,7 +2300,7 @@ void LLPipeline::postSort(LLCamera& camera) } // only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus - if (gSavedSettings.getBOOL("BeaconAlwaysOn") && !sShadowRender) + if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender) { if (sRenderScriptedTouchBeacons) { @@ -2446,7 +2448,7 @@ void LLPipeline::renderHighlights() // Make sure the selection image gets downloaded and decoded if (!mFaceSelectImagep) { - mFaceSelectImagep = gImageList.getImage(IMG_FACE_SELECT); + mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT); } mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); @@ -2476,7 +2478,7 @@ void LLPipeline::renderHighlights() for (S32 i = 0; i < count; i++) { LLFace* facep = mHighlightFaces[i]; - facep->renderSelected(LLViewerImage::sNullImagep, color); + facep->renderSelected(LLViewerTexture::sNullImagep, color); } } @@ -2565,8 +2567,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) sUnderWaterRender = FALSE; } - gGL.getTexUnit(0)->bind(LLViewerImage::sDefaultImagep); - LLViewerImage::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sDefaultImagep); + LLViewerFetchedTexture::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP); ////////////////////////////////////////////// // @@ -5094,8 +5096,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) F32 minLum = llmax(gSavedSettings.getF32("RenderGlowMinLuminance"), 0.0f); F32 maxAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha"); F32 warmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount"); - LLVector3 lumWeights = gSavedSkinSettings.getVector3("RenderGlowLumWeights"); - LLVector3 warmthWeights = gSavedSkinSettings.getVector3("RenderGlowWarmthWeights"); + LLVector3 lumWeights = gSavedSettings.getVector3("RenderGlowLumWeights"); + LLVector3 warmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights"); gGlowExtractProgram.uniform1f("minLuminance", minLum); gGlowExtractProgram.uniform1f("maxExtractAlpha", maxAlpha); gGlowExtractProgram.uniform3f("lumWeights", lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 5358fce766..fc02e7dd88 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -46,7 +46,7 @@ #include "lldrawable.h" #include "llrendertarget.h" -class LLViewerImage; +class LLViewerTexture; class LLEdge; class LLFace; class LLViewerObject; @@ -104,15 +104,15 @@ public: /// @brief Get a draw pool from pool type (POOL_SIMPLE, POOL_MEDIA) and texture. /// @return Draw pool, or NULL if not found. - LLDrawPool *findPool(const U32 pool_type, LLViewerImage *tex0 = NULL); + LLDrawPool *findPool(const U32 pool_type, LLViewerTexture *tex0 = NULL); /// @brief Get a draw pool for faces of the appropriate type and texture. Create if necessary. /// @return Always returns a draw pool. - LLDrawPool *getPool(const U32 pool_type, LLViewerImage *tex0 = NULL); + LLDrawPool *getPool(const U32 pool_type, LLViewerTexture *tex0 = NULL); /// @brief Figures out draw pool type from texture entry. Creates pool if necessary. - static LLDrawPool* getPoolFromTE(const LLTextureEntry* te, LLViewerImage* te_image); - static U32 getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* imagep); + static LLDrawPool* getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* te_image); + static U32 getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep); void addPool(LLDrawPool *poolp); // Only to be used by LLDrawPool classes for splitting pools! void removePool( LLDrawPool* poolp ); @@ -150,7 +150,7 @@ public: ); // Something about these textures has changed. Dirty them. - void dirtyPoolObjectTextures(const std::set& textures); + void dirtyPoolObjectTextures(const std::set& textures); void resetDrawOrders(); @@ -561,9 +561,9 @@ public: protected: std::vector mSelectedFaces; - LLPointer mFaceSelectImagep; - LLPointer mBloomImagep; - LLPointer mBloomImage2p; + LLPointer mFaceSelectImagep; + LLPointer mBloomImagep; + LLPointer mBloomImage2p; U32 mLightMask; U32 mLightMovingMask; diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index a902a6dff0..87a8bd5787 100644 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -138,8 +138,8 @@ TOOLMEDIAOPEN CURSOR "toolmediaopen.cur" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,24,0,0 - PRODUCTVERSION 1,24,0,0 + FILEVERSION 2,0,0,0 + PRODUCTVERSION 2,0,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -156,12 +156,12 @@ BEGIN BEGIN VALUE "CompanyName", "Linden Lab" VALUE "FileDescription", "Second Life" - VALUE "FileVersion", "1.24.0.0" + VALUE "FileVersion", "2.0.0.0" VALUE "InternalName", "Second Life" VALUE "LegalCopyright", "Copyright 2001-2008, Linden Research, Inc." VALUE "OriginalFilename", "SecondLife.exe" VALUE "ProductName", "Second Life" - VALUE "ProductVersion", "1.24.0.0" + VALUE "ProductVersion", "2.0.0.0" END END BLOCK "VarFileInfo" diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 49ea0bc8aa..73f0d32d12 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -1,3157 +1,667 @@ - - - - AgentChatColor - - Comment - Color of chat messages from other residents - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 1.0 - 1.0 - - - AlertBoxColor - - Comment - Alert Box Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.24 - 0.24 - 1 - - - AlertCautionBoxColor - - Comment - Alert Caution Box Color - Persist - 1 - Type - Color4 - Value - - 1 - 0.82 - 0.46 - 1 - - - AlertCautionTextColor - - Comment - Alert Caution Text Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - AlertTextColor - - Comment - Alert Text Color - Persist - 1 - Type - Color4 - Value - - 0.58 - 0.66 - 0.84 - 1 - - - AvatarNameColor - - Comment - Avatar Name Color - Persist - 1 - Type - Color4 - Value - - 0.98 - 0.69 - 0.36 - 1 - - - BackgroundChatColor - - Comment - Color of chat bubble background - Persist - 1 - Type - Color4 - Value - - 0.0 - 0.0 - 0.0 - 1.0 - - - ButtonBorderColor - - Comment - Button Border Color - Persist - 1 - Type - Color4 - Value - - 0.94 - 0.61 - 0 - 1 - - - ButtonCautionImageColor - - Comment - Button Caution Image Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - ButtonColor - - Comment - Button Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - ButtonFlashBgColor - - Comment - Button Color - Persist - 1 - Type - Color4 - Value - - 1 - 0.75 - 0.24 - 0.5 - - - ButtonImageColor - - Comment - Button Image Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - ButtonLabelColor - - Comment - Button Label Color - Persist - 1 - Type - Color4 - Value - - 0.86 - 0.86 - 0.86 - 1 - - - ButtonLabelDisabledColor - - Comment - Button Label Disabled Color - Persist - 1 - Type - Color4 - Value - - 0.58 - 0.66 - 0.84 - 0.78 - - - ButtonLabelSelectedColor - - Comment - Button Label Selected Color - Persist - 1 - Type - Color4 - Value - - 0.86 - 0.86 - 0.86 - 1 - - - ButtonLabelSelectedDisabledColor - - Comment - Button Label Selected Disabled Color - Persist - 1 - Type - Color4 - Value - - 0.64 - 0.75 - 0.93 - 0.78 - - - ButtonSelectedBgColor - - Comment - Button Selected Bg Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.24 - 0.24 - 1 - - - ButtonSelectedColor - - Comment - Button Selected Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - ButtonUnselectedBgColor - - Comment - Button Unselected Bg Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.24 - 0.24 - 1 - - - ButtonUnselectedFgColor - - Comment - Button Unselected Fg Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - ChatHistoryBgColor - - Comment - Chat History Bg Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0 - - - ChatHistoryTextColor - - Comment - Chat History Text Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - ColorDropShadow - - Comment - Color Drop Shadow - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0.78 - - - ColorPaletteEntry01 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.0 - 0.0 - 0.0 - 1.0 - - - ColorPaletteEntry02 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.5 - 0.5 - 0.5 - 1.0 - - - ColorPaletteEntry03 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.5 - 0.0 - 0.0 - 1.0 - - - ColorPaletteEntry04 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.5 - 0.5 - 0.0 - 1.0 - - - ColorPaletteEntry05 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.0 - 0.5 - 0.0 - 1.0 - - - ColorPaletteEntry06 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.0 - 0.5 - 0.5 - 1.0 - - - ColorPaletteEntry07 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.0 - 0.0 - 0.5 - 1.0 - - - ColorPaletteEntry08 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.5 - 0.0 - 0.5 - 1.0 - - - ColorPaletteEntry09 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.5 - 0.5 - 0.0 - 1.0 - - - ColorPaletteEntry10 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.0 - 0.25 - 0.25 - 1.0 - - - ColorPaletteEntry11 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.0 - 0.5 - 1.0 - 1.0 - - - ColorPaletteEntry12 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.0 - 0.25 - 0.5 - 1.0 - - - ColorPaletteEntry13 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.5 - 0.0 - 1.0 - 1.0 - - - ColorPaletteEntry14 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.5 - 0.25 - 0.0 - 1.0 - - - ColorPaletteEntry15 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 1.0 - 1.0 - - - ColorPaletteEntry16 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 1.0 - 1.0 - - - ColorPaletteEntry17 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 1.0 - 1.0 - - - ColorPaletteEntry18 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.75 - 0.75 - 0.75 - 1.0 - - - ColorPaletteEntry19 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 1.0 - 0.0 - 0.0 - 1.0 - - - ColorPaletteEntry20 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 0.0 - 1.0 - - - ColorPaletteEntry21 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.0 - 1.0 - 0.0 - 1.0 - - - ColorPaletteEntry22 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.0 - 1.0 - 1.0 - 1.0 - - - ColorPaletteEntry23 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.0 - 0.0 - 1.0 - 1.0 - - - ColorPaletteEntry24 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 1.0 - 0.0 - 1.0 - 1.0 - - - ColorPaletteEntry25 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 0.5 - 1.0 - - - ColorPaletteEntry26 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.0 - 1.0 - 0.5 - 1.0 - - - ColorPaletteEntry27 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.5 - 1.0 - 1.0 - 1.0 - - - ColorPaletteEntry28 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 0.5 - 0.5 - 1.0 - 1.0 - - - ColorPaletteEntry29 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 1.0 - 0.0 - 0.5 - 1.0 - - - ColorPaletteEntry30 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 1.0 - 0.5 - 0.0 - 1.0 - - - ColorPaletteEntry31 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 1.0 - 1.0 - - - ColorPaletteEntry32 - - Comment - Color picker palette entry - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 1.0 - 1.0 - - - ConsoleBackground - - Comment - Console Background - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - ContextSilhouetteColor - - Comment - Context Silhouette Color - Persist - 1 - Type - Color4 - Value - - 0.94 - 0.61 - 0 - 1 - - - DefaultHighlightDark - - Comment - Default Highlight Dark - Persist - 1 - Type - Color4 - Value - - 0.1 - 0.1 - 0.1 - 1 - - - DefaultHighlightLight - - Comment - Default Highlight Light - Persist - 1 - Type - Color4 - Value - - 0.45 - 0.52 - 0.61 - 1 - - - DefaultShadowDark - - Comment - Default Shadow Dark - Persist - 1 - Type - Color4 - Value - - 0.1 - 0.1 - 0.1 - 1 - - - DefaultShadowLight - - Comment - Default Shadow Light - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - EffectColor - - Comment - Particle effects color - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 1.0 - 1.0 - - - FilterBackgroundColor - - Comment - Filter Background Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0.08 - 1 - - - FilterTextColor - - Comment - Filter Text Color - Persist - 1 - Type - Color4 - Value - - 1 - 0.78 - 0.27 - 1 - - - FloaterButtonImageColor - - Comment - Floater Button Image Color - Persist - 1 - Type - Color4 - Value - - 0.94 - 0.61 - 0 - 1 - - - FloaterDefaultBackgroundColor - - Comment - Default Background Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.24 - 0.24 - 0.55 - - - FloaterFocusBackgroundColor - - Comment - Focus Background Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.24 - 0.24 - 1 - - - FloaterFocusBorderColor - - Comment - Floater Focus Border Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0.31 - - - FloaterUnfocusBorderColor - - Comment - Floater Unfocus Border Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0.31 - - - FocusColor - - Comment - Focus Color - Persist - 1 - Type - Color4 - Value - - 0.94 - 0.61 - 0 - 1 - - - FolderViewLoadingMessageTextColor - - Comment - Folder View Loading Message Text Color - Persist - 1 - Type - Color4 - Value - - 0.94 - 0.65 - 0.35 - 1 - - - GridFocusPointColor - - Comment - Grid Focus Point Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 0.5 - - - GridlineBGColor - - Comment - Gridline BGColor - Persist - 1 - Type - Color4 - Value - - 0.92 - 0.92 - 1 - 0.78 - - - GridlineColor - - Comment - Gridline Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - GridlineShadowColor - - Comment - Gridline Shadow Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0.31 - - - GroupNotifyBoxColor - - Comment - Group Notify Box Color - Persist - 1 - Type - Color4 - Value - - 0.27 - 0.67 - 1 - 1 - - - GroupNotifyTextColor - - Comment - Group Notify Text Color - Persist - 1 - Type - Color4 - Value - - 0 - 0.12 - 0.24 - 1 - - - GroupOverTierColor - - Comment - Group Over Tier Color - Persist - 1 - Type - Color4 - Value - - 0.43 - 0.06 - 0.06 - 1 - - - HTMLLinkColor - - Comment - Color of hyperlinks - Persist - 1 - Type - Color4 - Value - - 0.60 - 0.60 - 1.0 - 1.0 - - - HealthTextColor - - Comment - Health Text Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - HelpBgColor - - Comment - Help Bg Color - Persist - 1 - Type - Color4 - Value - - 0.78 - 0.82 - 0.8 - 1 - - - HelpFgColor - - Comment - Help Fg Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - HelpScrollHighlightColor - - Comment - Help Scroll Highlight Color - Persist - 1 - Type - Color4 - Value - - 0.45 - 0.52 - 0.61 - 1 - - - HelpScrollShadowColor - - Comment - Help Scroll Shadow Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - HelpScrollThumbColor - - Comment - Help Scroll Thumb Color - Persist - 1 - Type - Color4 - Value - - 0.31 - 0.38 - 0.49 - 1 - - - HelpScrollTrackColor - - Comment - Help Scroll Track Color - Persist - 1 - Type - Color4 - Value - - 0.72 - 0.72 - 0.74 - 1 - - - HighlightChildColor - - Comment - Highlight Child Color - Persist - 1 - Type - Color4 - Value - - 0.67 - 0.83 - 0.96 - 1 - - - HighlightInspectColor - - Comment - Highlight Inspect Color - Persist - 1 - Type - Color4 - Value - - 1 - 0 - 1 - 1 - - - HighlightParentColor - - Comment - Highlight Parent Color - Persist - 1 - Type - Color4 - Value - - 0.67 - 0.83 - 0.96 - 1 - - - IMChatColor - - Comment - Color of instant messages from other residents - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 1.0 - 1.0 - - - IMHistoryBgColor - - Comment - IMHistory Bg Color - Persist - 1 - Type - Color4 - Value - - 0 - 0.12 - 0.31 - 0.78 - - - IMHistoryTextColor - - Comment - IMHistory Text Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - IconDisabledColor - - Comment - Icon Disabled Color - Persist - 1 - Type - Color4 - Value - - 0.58 - 0.66 - 0.84 - 0.78 - - - IconEnabledColor - - Comment - Icon Enabled Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - InventoryBackgroundColor - - Comment - Inventory Background Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.24 - 0.24 - 0.31 - - - InventoryItemSuffixColor - - Comment - Inventory Item Suffix Color - Persist - 1 - Type - Color4 - Value - - 0.75 - 0.85 - 0.85 - 1 - - - InventorySearchStatusColor - - Comment - Inventory Search Status Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - LabelDisabledColor - - Comment - Label Disabled Color - Persist - 1 - Type - Color4 - Value - - 0.58 - 0.66 - 0.84 - 0.3 - - - LabelSelectedColor - - Comment - Label Selected Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - LabelSelectedDisabledColor - - Comment - Label Selected Disabled Color - Persist - 1 - Type - Color4 - Value - - 0.64 - 0.75 - 0.93 - 0.5 - - - LabelTextColor - - Comment - Label Text Color - Persist - 1 - Type - Color4 - Value - - 0.58 - 0.66 - 0.84 - 1 - - - LoginProgressBarBgColor - - Comment - Login Progress Bar Bg Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - LoginProgressBarFgColor - - Comment - Login Progress Bar Fg Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - LoginProgressBoxBorderColor - - Comment - Login Progress Box Border Color - Persist - 1 - Type - Color4 - Value - - 0 - 0.12 - 0.24 - 0 - - - LoginProgressBoxCenterColor - - Comment - Login Progress Box Center Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0.78 - - - LoginProgressBoxShadowColor - - Comment - Login Progress Box Shadow Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0.78 - - - LoginProgressBoxTextColor - - Comment - Login Progress Box Text Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - MapAvatarColor - - Comment - Color of chat messages from other residents - Persist - 1 - Type - Color4 - Value - - 0.0 - 1.0 - 0.0 - 1.0 - - - MapAvatarFriendColor - - Comment - Color of chat messages from other residents - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 0.0 - 1.0 - - - MapAvatarSelfColor - - Comment - Color of chat messages from other residents - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 1.0 - 1.0 - - - MapFrustumColor - - Comment - Color of chat messages from other residents - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 1.0 - 0.1 - - - MapFrustumRotatingColor - - Comment - Color of chat messages from other residents - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 1.0 - 0.2 - - - MapTrackColor - - Comment - Color of chat messages from other residents - Persist - 1 - Type - Color4 - Value - - 1.0 - 0.0 - 0.0 - 1.0 - - - MapTrackDisabledColor - - Comment - Color of chat messages from other residents - Persist - 1 - Type - Color4 - Value - - 0.5 - 0.0 - 0.0 - 1.0 - - - - - MenuBarBgColor - - Comment - Menu Bar Bg Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.24 - 0.24 - 1 - - - MenuBarGodBgColor - - Comment - Menu Bar God Bg Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.5 - 0.24 - 1 - - - MenuDefaultBgColor - - Comment - Menu Default Bg Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - MenuItemDisabledColor - - Comment - Menu Item Disabled Color - Persist - 1 - Type - Color4 - Value - - 0.52 - 0.52 - 0.64 - 0.5 - - - MenuItemEnabledColor - - Comment - Menu Item Enabled Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - MenuItemHighlightBgColor - - Comment - Menu Item Highlight Bg Color - Persist - 1 - Type - Color4 - Value - - 0.72 - 0.72 - 0.74 - 0.39 - - - MenuItemHighlightFgColor - - Comment - Menu Item Highlight Fg Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - MenuNonProductionBgColor - - Comment - Menu Non Production Bg Color - Persist - 1 - Type - Color4 - Value - - 0.5 - 0 - 0 - 1 - - - MenuNonProductionGodBgColor - - Comment - Menu Non Production God Bg Color - Persist - 1 - Type - Color4 - Value - - 0 - 0.5 - 0 - 1 - - - MenuPopupBgColor - - Comment - Menu Popup Bg Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - MultiSliderDisabledThumbColor - - Comment - Multi Slider Disabled Thumb Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - MultiSliderThumbCenterColor - - Comment - Multi Slider Thumb Center Color - Persist - 1 - Type - Color4 - Value - - 0.72 - 0.72 - 0.74 - 1 - - - MultiSliderThumbCenterSelectedColor - - Comment - Multi Slider Thumb Center Selected Color - Persist - 1 - Type - Color4 - Value - - 1 - 0.2 - 0.2 - 1 - - - MultiSliderThumbOutlineColor - - Comment - Multi Slider Thumb Outline Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - MultiSliderTrackColor - - Comment - Multi Slider Track Color - Persist - 1 - Type - Color4 - Value - - 0.12 - 0.12 - 0.12 - 1 - - - MultiSliderTriangleColor - - Comment - Multi Slider Triangle Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 0.2 - 1 - - - NetMapBackgroundColor - - Comment - Net Map Background Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0.3 - - - NetMapGroupOwnAboveWater - - Comment - Net Map Group Own Above Water - Persist - 1 - Type - Color4 - Value - - 1 - 0 - 1 - 1 - - - NetMapGroupOwnBelowWater - - Comment - Net Map Group Own Below Water - Persist - 1 - Type - Color4 - Value - - 0.78 - 0 - 0.78 - 1 - - - NetMapOtherOwnAboveWater - - Comment - Net Map Other Own Above Water - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.24 - 0.24 - 1 - - - NetMapOtherOwnBelowWater - - Comment - Net Map Other Own Below Water - Persist - 1 - Type - Color4 - Value - - 0.12 - 0.12 - 0.12 - 1 - - - NetMapYouOwnAboveWater - - Comment - Net Map You Own Above Water - Persist - 1 - Type - Color4 - Value - - 0 - 1 - 1 - 1 - - - NetMapYouOwnBelowWater - - Comment - Net Map You Own Below Water - Persist - 1 - Type - Color4 - Value - - 0 - 0.78 - 0.78 - 1 - - - NotifyBoxColor - - Comment - Notify Box Color - Persist - 1 - Type - Color4 - Value - - 0.27 - 0.67 - 1 - 1 - - - NotifyCautionBoxColor - - Comment - Notify Caution Box Color - Persist - 1 - Type - Color4 - Value - - 1 - 0.82 - 0.46 - 1 - - - NotifyCautionWarnColor - - Comment - Notify Caution Warn Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - NotifyTextColor - - Comment - Notify Text Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - ObjectChatColor - - Comment - Color of chat messages from objects - Persist - 0 - Type - Color4 - Value - - 0.7 - 0.9 - 0.7 - 1.0 - - - OverdrivenColor - - Comment - Color of various indicators when resident is speaking too loud. - Persist - 0 - Type - Color4 - Value - - 1.0 - 0.0 - 0.0 - 1.0 - - - PanelDefaultBackgroundColor - - Comment - Default Background Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.24 - 0.24 - 0.55 - - - PanelDefaultHighlightLight - - Comment - Default Highlight Light - Persist - 1 - Type - Color4 - Value - - 0.45 - 0.52 - 0.61 - 1 - - - PanelFocusBackgroundColor - - Comment - Focus Background Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.24 - 0.24 - 1 - - - ParcelHoverColor - - Comment - Parcel Hover Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - PieMenuBgColor - - Comment - Pie Menu Bg Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.24 - 0.24 - 0.59 - - - PieMenuLineColor - - Comment - Pie Menu Line Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0.5 - - - PieMenuSelectedColor - - Comment - Pie Menu Selected Color - Persist - 1 - Type - Color4 - Value - - 0.72 - 0.72 - 0.74 - 0.3 - - - PropertyColorAuction - - Comment - Property Color Auction - Persist - 1 - Type - Color4 - Value - - 0.50 - 0 - 1 - 0.4 - - - PropertyColorAvail - - Comment - Property Color Avail - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0 - - - PropertyColorForSale - - Comment - Property Color For Sale - Persist - 1 - Type - Color4 - Value - - 1 - 0.50 - 0 - 0.4 - - - PropertyColorGroup - - Comment - Property Color Group - Persist - 1 - Type - Color4 - Value - - 0 - 0.72 - 0.72 - 0.4 - - - PropertyColorOther - - Comment - Property Color Other - Persist - 1 - Type - Color4 - Value - - 1 - 0 - 0 - 0.4 - - - PropertyColorSelf - - Comment - Property Color Self - Persist - 1 - Type - Color4 - Value - - 0 - 1 - 0 - 0.4 - - - RenderGlowLumWeights - - Comment - Weights for each color channel to be used in calculating luminance (should add up to 1.0) - Persist - 1 - Type - Vector3 - Value - - 0.299 - 0.587 - 0.114 - - - RenderGlowWarmthWeights - - Comment - Weight of each color channel used before finding the max warmth - Persist - 1 - Type - Vector3 - Value - - 1.0 - 0.5 - 0.7 - - - ScriptBgReadOnlyColor - - Comment - Script Bg Read Only Color - Persist - 1 - Type - Color4 - Value - - 0.39 - 0.39 - 0.39 - 1 - - - ScriptErrorColor - - Comment - Color of script error messages - Persist - 1 - Type - Color4 - Value - - 0.82 - 0.27 - 0.27 - 1.0 - - - ScrollBGStripeColor - - Comment - Scroll BGStripe Color - Persist - 1 - Type - Color4 - Value - - 0.39 - 0.39 - 0.39 - 0.16 - - - ScrollBgReadOnlyColor - - Comment - Scroll Bg Read Only Color - Persist - 1 - Type - Color4 - Value - - 0.78 - 0.82 - 0.8 - 1 - - - ScrollBgWriteableColor - - Comment - Scroll Bg Writeable Color - Persist - 1 - Type - Color4 - Value - - 0.78 - 0.82 - 0.8 - 1 - - - ScrollDisabledColor - - Comment - Scroll Disabled Color - Persist - 1 - Type - Color4 - Value - - 0.5 - 0.5 - 0.5 - 0.8 - - - ScrollHighlightedColor - - Comment - Scroll Highlighted Color - Persist - 1 - Type - Color4 - Value - - 0.72 - 0.72 - 0.74 - 0.5 - - - ScrollHoveredColor - - Comment - Scroll Hovered Color - Persist - 1 - Type - Color4 - Value - - 0.72 - 0.72 - 0.74 - 0.5 - - - ScrollSelectedBGColor - - Comment - Scroll Selected BGColor - Persist - 1 - Type - Color4 - Value - - 0.39 - 0.39 - 0.74 - 0.59 - - - ScrollSelectedFGColor - - Comment - Scroll Selected FGColor - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0.8 - - - ScrollUnselectedColor - - Comment - Scroll Unselected Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0.8 - - - ScrollbarThumbColor - - Comment - Scrollbar Thumb Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.3 - 0.49 - 1 - - - ScrollbarTrackColor - - Comment - Scrollbar Track Color - Persist - 1 - Type - Color4 - Value - - 0.6 - 0.6 - 0.62 - 1 - - - SilhouetteChildColor - - Comment - Silhouette Child Color - Persist - 1 - Type - Color4 - Value - - 0.13 - 0.42 - 0.77 - 1 - - - SilhouetteParentColor - - Comment - Silhouette Parent Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 0 - 1 - - - SkyNightColorShift - - Comment - Controls moonlight color (base color applied to moon as light source) - Persist - 1 - Type - Color3 - Value - - 0.67 - 0.67 - 1.0 - - - SliderDisabledThumbColor - - Comment - Slider Disabled Thumb Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - SliderThumbCenterColor - - Comment - Slider Thumb Center Color - Persist - 1 - Type - Color4 - Value - - 0.78 - 0.78 - 0.78 - 1 - - - SliderThumbOutlineColor - - Comment - Slider Thumb Outline Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - SliderTrackColor - - Comment - Slider Track Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - SpeakingColor - - Comment - Color of various indicators when resident is speaking on a voice channel. - Persist - 1 - Type - Color4 - Value - - 0.0 - 1.0 - 0.0 - 1.0 - - - SystemChatColor - - Comment - Color of chat messages from SL System - Persist - 1 - Type - Color4 - Value - - 0.800000011921 - 1.0 - 1.0 - 1.0 - - - TextBgFocusColor - - Comment - Text Bg Focus Color - Persist - 1 - Type - Color4 - Value - - 0.78 - 0.82 - 0.8 - 1 - - - TextBgReadOnlyColor - - Comment - Text Bg Read Only Color - Persist - 1 - Type - Color4 - Value - - 0.24 - 0.24 - 0.24 - 0.63 - - - TextBgWriteableColor - - Comment - Text Bg Writeable Color - Persist - 1 - Type - Color4 - Value - - 0.78 - 0.82 - 0.8 - 0.9 - - - TextCursorColor - - Comment - Text Cursor Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - TextDefaultColor - - Comment - Text Default Color - Persist - 1 - Type - Color4 - Value - - 0 - 0.08 - 0 - 1 - - - TextEmbeddedItemColor - - Comment - Text Embedded Item Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0.5 - 1 - - - TextEmbeddedItemReadOnlyColor - - Comment - Text Embedded Item Read Only Color - Persist - 1 - Type - Color4 - Value - - 0.23 - 0.58 - 0.95 - 1 - - - TextFgColor - - Comment - Text Fg Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - TextFgReadOnlyColor - - Comment - Text Fg Read Only Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 0.78 - - - TextFgTentativeColor - - Comment - Text Fg Tentative Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 0.5 - - - TimeTextColor - - Comment - Time Text Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 1 - - - TitleBarFocusColor - - Comment - Title Bar Focus Color - Persist - 1 - Type - Color4 - Value - - 1 - 1 - 1 - 0.12 - - - ToolTipBgColor - - Comment - Tool Tip Bg Color - Persist - 1 - Type - Color4 - Value - - 0.72 - 0.72 - 0.74 - 0.78 - - - ToolTipBorderColor - - Comment - Tool Tip Border Color - Persist - 1 - Type - Color4 - Value - - 0.67 - 0.83 - 0.96 - 1 - - - ToolTipTextColor - - Comment - Tool Tip Text Color - Persist - 1 - Type - Color4 - Value - - 0 - 0 - 0 - 1 - - - UserChatColor - - Comment - Color of your chat messages - Persist - 1 - Type - Color4 - Value - - 1.0 - 1.0 - 1.0 - 1.0 - - - llOwnerSayChatColor - - Comment - Color of chat messages from objects only visible to the owner - Persist - 1 - Type - Color4 - Value - - 0.99 - 0.99 - 0.67 - 1.0 - - - - + + + diff --git a/indra/newview/skins/default/textures/bottomtray/DownArrow.png b/indra/newview/skins/default/textures/bottomtray/DownArrow.png new file mode 100644 index 0000000000..82f58b22b9 Binary files /dev/null and b/indra/newview/skins/default/textures/bottomtray/DownArrow.png differ diff --git a/indra/newview/skins/default/textures/bottomtray/Unread_IM.png b/indra/newview/skins/default/textures/bottomtray/Unread_IM.png new file mode 100644 index 0000000000..a355917fca Binary files /dev/null and b/indra/newview/skins/default/textures/bottomtray/Unread_IM.png differ diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png new file mode 100644 index 0000000000..cd18ae310d Binary files /dev/null and b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png differ diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png new file mode 100644 index 0000000000..b0ed6ee8eb Binary files /dev/null and b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png differ diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3.png new file mode 100644 index 0000000000..14ec77b99a Binary files /dev/null and b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3.png differ diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off.png new file mode 100644 index 0000000000..48be51e9af Binary files /dev/null and b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off.png differ diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png new file mode 100644 index 0000000000..be4881b64c Binary files /dev/null and b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png differ diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Off.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Off.png new file mode 100644 index 0000000000..19c842b816 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Off.png differ diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Over.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Over.png new file mode 100644 index 0000000000..e47f913db1 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Over.png differ diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Press.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Press.png new file mode 100644 index 0000000000..b9879dcc8a Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Press.png differ diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Off.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Off.png new file mode 100644 index 0000000000..d506cda5c9 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Off.png differ diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Over.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Over.png new file mode 100644 index 0000000000..e2c67de9c0 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Over.png differ diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Press.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Press.png new file mode 100644 index 0000000000..08f7493a02 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Press.png differ diff --git a/indra/newview/skins/default/textures/containers/Accordion_Off.png b/indra/newview/skins/default/textures/containers/Accordion_Off.png new file mode 100644 index 0000000000..414f4509c6 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Accordion_Off.png differ diff --git a/indra/newview/skins/default/textures/containers/Accordion_Over.png b/indra/newview/skins/default/textures/containers/Accordion_Over.png new file mode 100644 index 0000000000..5416d73310 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Accordion_Over.png differ diff --git a/indra/newview/skins/default/textures/containers/Accordion_Press.png b/indra/newview/skins/default/textures/containers/Accordion_Press.png new file mode 100644 index 0000000000..1578e0dfc5 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Accordion_Press.png differ diff --git a/indra/newview/skins/default/textures/containers/Container.png b/indra/newview/skins/default/textures/containers/Container.png new file mode 100644 index 0000000000..511eb94386 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Container.png differ diff --git a/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png b/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png new file mode 100644 index 0000000000..1951413f8d Binary files /dev/null and b/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png differ diff --git a/indra/newview/skins/default/textures/containers/TabTop_Left_Over.png b/indra/newview/skins/default/textures/containers/TabTop_Left_Over.png new file mode 100644 index 0000000000..295cd89a57 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/TabTop_Left_Over.png differ diff --git a/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png b/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png new file mode 100644 index 0000000000..8364716e02 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png differ diff --git a/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png b/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png new file mode 100644 index 0000000000..21f1c2d8a8 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png differ diff --git a/indra/newview/skins/default/textures/containers/TabTop_Middle_Over.png b/indra/newview/skins/default/textures/containers/TabTop_Middle_Over.png new file mode 100644 index 0000000000..0758cbcf0d Binary files /dev/null and b/indra/newview/skins/default/textures/containers/TabTop_Middle_Over.png differ diff --git a/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png b/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png new file mode 100644 index 0000000000..3946917c7c Binary files /dev/null and b/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png differ diff --git a/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png b/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png new file mode 100644 index 0000000000..eeef28e5a5 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png differ diff --git a/indra/newview/skins/default/textures/containers/TabTop_Right_Over.png b/indra/newview/skins/default/textures/containers/TabTop_Right_Over.png new file mode 100644 index 0000000000..c2cbc2b1e5 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/TabTop_Right_Over.png differ diff --git a/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png b/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png new file mode 100644 index 0000000000..b0f1f16398 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png differ diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png new file mode 100644 index 0000000000..41b5d24d87 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png differ diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png new file mode 100644 index 0000000000..083acc0156 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png differ diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png new file mode 100644 index 0000000000..ee4649a8f9 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png differ diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png new file mode 100644 index 0000000000..55c02160e3 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png differ diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png new file mode 100644 index 0000000000..2f6ea90196 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png differ diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png new file mode 100644 index 0000000000..642113b135 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png differ diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png new file mode 100644 index 0000000000..01fd765c3d Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png differ diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png new file mode 100644 index 0000000000..74e00635f1 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png differ diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png new file mode 100644 index 0000000000..8a0d98a780 Binary files /dev/null and b/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png differ diff --git a/indra/newview/skins/default/textures/icons/AddItem_Off.png b/indra/newview/skins/default/textures/icons/AddItem_Off.png new file mode 100644 index 0000000000..52d4f9bc80 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/AddItem_Off.png differ diff --git a/indra/newview/skins/default/textures/icons/AddItem_Over.png b/indra/newview/skins/default/textures/icons/AddItem_Over.png new file mode 100644 index 0000000000..cad6e8d52f Binary files /dev/null and b/indra/newview/skins/default/textures/icons/AddItem_Over.png differ diff --git a/indra/newview/skins/default/textures/icons/AddItem_Press.png b/indra/newview/skins/default/textures/icons/AddItem_Press.png new file mode 100644 index 0000000000..acc898e5f4 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/AddItem_Press.png differ diff --git a/indra/newview/skins/default/textures/icons/BackArrow_Off.png b/indra/newview/skins/default/textures/icons/BackArrow_Off.png new file mode 100644 index 0000000000..ff32192856 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/BackArrow_Off.png differ diff --git a/indra/newview/skins/default/textures/icons/BackArrow_Over.png b/indra/newview/skins/default/textures/icons/BackArrow_Over.png new file mode 100644 index 0000000000..b36e03a8cf Binary files /dev/null and b/indra/newview/skins/default/textures/icons/BackArrow_Over.png differ diff --git a/indra/newview/skins/default/textures/icons/Info.png b/indra/newview/skins/default/textures/icons/Info.png new file mode 100644 index 0000000000..e52560281b Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Info.png differ diff --git a/indra/newview/skins/default/textures/icons/OptionsMenu_Off.png b/indra/newview/skins/default/textures/icons/OptionsMenu_Off.png new file mode 100644 index 0000000000..25b055bfc0 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OptionsMenu_Off.png differ diff --git a/indra/newview/skins/default/textures/icons/OptionsMenu_Over.png b/indra/newview/skins/default/textures/icons/OptionsMenu_Over.png new file mode 100644 index 0000000000..fcabd4c6d3 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OptionsMenu_Over.png differ diff --git a/indra/newview/skins/default/textures/icons/OptionsMenu_Press.png b/indra/newview/skins/default/textures/icons/OptionsMenu_Press.png new file mode 100644 index 0000000000..6e91dd7159 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OptionsMenu_Press.png differ diff --git a/indra/newview/skins/default/textures/icons/TrashItem_Off.png b/indra/newview/skins/default/textures/icons/TrashItem_Off.png new file mode 100644 index 0000000000..bb64920ec4 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/TrashItem_Off.png differ diff --git a/indra/newview/skins/default/textures/icons/TrashItem_Over.png b/indra/newview/skins/default/textures/icons/TrashItem_Over.png new file mode 100644 index 0000000000..1a0eea6c67 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/TrashItem_Over.png differ diff --git a/indra/newview/skins/default/textures/icons/TrashItem_Press.png b/indra/newview/skins/default/textures/icons/TrashItem_Press.png new file mode 100644 index 0000000000..c62f833d86 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/TrashItem_Press.png differ diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png new file mode 100644 index 0000000000..cd18ae310d Binary files /dev/null and b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png differ diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png new file mode 100644 index 0000000000..b0ed6ee8eb Binary files /dev/null and b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png differ diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl3.png b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl3.png new file mode 100644 index 0000000000..14ec77b99a Binary files /dev/null and b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl3.png differ diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Off.png b/indra/newview/skins/default/textures/icons/VoicePTT_Off.png new file mode 100644 index 0000000000..48be51e9af Binary files /dev/null and b/indra/newview/skins/default/textures/icons/VoicePTT_Off.png differ diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_On.png b/indra/newview/skins/default/textures/icons/VoicePTT_On.png new file mode 100644 index 0000000000..be4881b64c Binary files /dev/null and b/indra/newview/skins/default/textures/icons/VoicePTT_On.png differ diff --git a/indra/newview/skins/default/textures/image_edit_icon.tga b/indra/newview/skins/default/textures/image_edit_icon.tga new file mode 100644 index 0000000000..8666f0bbe6 Binary files /dev/null and b/indra/newview/skins/default/textures/image_edit_icon.tga differ diff --git a/indra/newview/skins/default/textures/navbar/Arrow_Left_Off.png b/indra/newview/skins/default/textures/navbar/Arrow_Left_Off.png new file mode 100644 index 0000000000..19569501fe Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Arrow_Left_Off.png differ diff --git a/indra/newview/skins/default/textures/navbar/Arrow_Left_Over.png b/indra/newview/skins/default/textures/navbar/Arrow_Left_Over.png new file mode 100644 index 0000000000..a91b74819f Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Arrow_Left_Over.png differ diff --git a/indra/newview/skins/default/textures/navbar/Arrow_Right_Off.png b/indra/newview/skins/default/textures/navbar/Arrow_Right_Off.png new file mode 100644 index 0000000000..3648c42656 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Arrow_Right_Off.png differ diff --git a/indra/newview/skins/default/textures/navbar/Arrow_Right_Over.png b/indra/newview/skins/default/textures/navbar/Arrow_Right_Over.png new file mode 100644 index 0000000000..a2caf227a7 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Arrow_Right_Over.png differ diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png new file mode 100644 index 0000000000..a4060e5e37 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png differ diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png new file mode 100644 index 0000000000..9c2815ebba Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png differ diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png new file mode 100644 index 0000000000..377b707529 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png differ diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png new file mode 100644 index 0000000000..a69a729bd4 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png differ diff --git a/indra/newview/skins/default/textures/navbar/FileMenu_Divider.png b/indra/newview/skins/default/textures/navbar/FileMenu_Divider.png new file mode 100644 index 0000000000..5ab4abc5b8 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/FileMenu_Divider.png differ diff --git a/indra/newview/skins/default/textures/navbar/Help_Over.png b/indra/newview/skins/default/textures/navbar/Help_Over.png new file mode 100644 index 0000000000..b9bc0d0f87 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Help_Over.png differ diff --git a/indra/newview/skins/default/textures/navbar/Help_Press.png b/indra/newview/skins/default/textures/navbar/Help_Press.png new file mode 100644 index 0000000000..ed3695f9d5 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Help_Press.png differ diff --git a/indra/newview/skins/default/textures/navbar/Home_Off.png b/indra/newview/skins/default/textures/navbar/Home_Off.png new file mode 100644 index 0000000000..fe3bc63b77 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Home_Off.png differ diff --git a/indra/newview/skins/default/textures/navbar/Home_Over.png b/indra/newview/skins/default/textures/navbar/Home_Over.png new file mode 100644 index 0000000000..d9c6b3842e Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Home_Over.png differ diff --git a/indra/newview/skins/default/textures/navbar/Info_Off.png b/indra/newview/skins/default/textures/navbar/Info_Off.png new file mode 100644 index 0000000000..64722255a3 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Info_Off.png differ diff --git a/indra/newview/skins/default/textures/navbar/Info_Over.png b/indra/newview/skins/default/textures/navbar/Info_Over.png new file mode 100644 index 0000000000..84f1d03129 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Info_Over.png differ diff --git a/indra/newview/skins/default/textures/navbar/Info_Press.png b/indra/newview/skins/default/textures/navbar/Info_Press.png new file mode 100644 index 0000000000..169105829e Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Info_Press.png differ diff --git a/indra/newview/skins/default/textures/navbar/NavBar_BG.png b/indra/newview/skins/default/textures/navbar/NavBar_BG.png new file mode 100644 index 0000000000..1df61751a8 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/NavBar_BG.png differ diff --git a/indra/newview/skins/default/textures/navbar/Row_Selection.png b/indra/newview/skins/default/textures/navbar/Row_Selection.png new file mode 100644 index 0000000000..fc4f0c07ef Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Row_Selection.png differ diff --git a/indra/newview/skins/default/textures/navbar/Search.png b/indra/newview/skins/default/textures/navbar/Search.png new file mode 100644 index 0000000000..c43519d5f1 Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Search.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/avatar_free_mode.png b/indra/newview/skins/default/textures/quick_tips/avatar_free_mode.png new file mode 100644 index 0000000000..be7c87efb6 Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/avatar_free_mode.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/camera_free_mode.png b/indra/newview/skins/default/textures/quick_tips/camera_free_mode.png new file mode 100644 index 0000000000..9a3f3703b2 Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/camera_free_mode.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/camera_orbit_mode.png b/indra/newview/skins/default/textures/quick_tips/camera_orbit_mode.png new file mode 100644 index 0000000000..dd72cc0162 Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/camera_orbit_mode.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/camera_pan_mode.png b/indra/newview/skins/default/textures/quick_tips/camera_pan_mode.png new file mode 100644 index 0000000000..b537dcbe46 Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/camera_pan_mode.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/camera_preset_front_view.png b/indra/newview/skins/default/textures/quick_tips/camera_preset_front_view.png new file mode 100644 index 0000000000..7674a75ac3 Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/camera_preset_front_view.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/camera_preset_group_view.png b/indra/newview/skins/default/textures/quick_tips/camera_preset_group_view.png new file mode 100644 index 0000000000..9c9b923a5a Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/camera_preset_group_view.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/camera_preset_rear_view.png b/indra/newview/skins/default/textures/quick_tips/camera_preset_rear_view.png new file mode 100644 index 0000000000..15c3053491 Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/camera_preset_rear_view.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/move_fly_first.png b/indra/newview/skins/default/textures/quick_tips/move_fly_first.png new file mode 100644 index 0000000000..b6e2ce60e4 Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/move_fly_first.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/move_fly_second.png b/indra/newview/skins/default/textures/quick_tips/move_fly_second.png new file mode 100644 index 0000000000..84b63cc338 Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/move_fly_second.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/move_run_first.png b/indra/newview/skins/default/textures/quick_tips/move_run_first.png new file mode 100644 index 0000000000..16093dc683 Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/move_run_first.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/move_run_second.png b/indra/newview/skins/default/textures/quick_tips/move_run_second.png new file mode 100644 index 0000000000..19fa43ec32 Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/move_run_second.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/move_walk_first.png b/indra/newview/skins/default/textures/quick_tips/move_walk_first.png new file mode 100644 index 0000000000..92d120d53e Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/move_walk_first.png differ diff --git a/indra/newview/skins/default/textures/quick_tips/move_walk_second.png b/indra/newview/skins/default/textures/quick_tips/move_walk_second.png new file mode 100644 index 0000000000..f8e28722be Binary files /dev/null and b/indra/newview/skins/default/textures/quick_tips/move_walk_second.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Close_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Close_Off.png new file mode 100644 index 0000000000..bc4e00c646 Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TabIcon_Close_Off.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Off.png new file mode 100644 index 0000000000..1e7d7beafa Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Off.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Selected.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Selected.png new file mode 100644 index 0000000000..a70d3abbbf Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Selected.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Off.png new file mode 100644 index 0000000000..2d36f70361 Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Off.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Selected.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Selected.png new file mode 100644 index 0000000000..3c20459126 Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Selected.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Open_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Open_Off.png new file mode 100644 index 0000000000..4556602f58 Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TabIcon_Open_Off.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Off.png new file mode 100644 index 0000000000..c272372a39 Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Off.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Selected.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Selected.png new file mode 100644 index 0000000000..3828752606 Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Selected.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Off.png new file mode 100644 index 0000000000..d7ec33af55 Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Off.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Selected.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Selected.png new file mode 100644 index 0000000000..dd7e361ea9 Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Selected.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Off.png new file mode 100644 index 0000000000..e56eda9802 Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Off.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Selected.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Selected.png new file mode 100644 index 0000000000..d4ac451c8e Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Selected.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Off.png b/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Off.png new file mode 100644 index 0000000000..918be7555f Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Off.png differ diff --git a/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Selected.png b/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Selected.png new file mode 100644 index 0000000000..b3316386b9 Binary files /dev/null and b/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Selected.png differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 84dd3ffd7a..96d93e7081 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -1,75 +1,349 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + - - - - - - - - - - - - + + + - + - - - - - - - - - - - - + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + @@ -115,7 +389,7 @@ - + @@ -142,13 +416,13 @@ - + - + - + @@ -158,17 +432,17 @@ - + - - - + + + - + @@ -199,11 +473,11 @@ - + - + @@ -214,7 +488,7 @@ - + @@ -226,7 +500,7 @@ - + @@ -234,104 +508,11 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_Disabled.png b/indra/newview/skins/default/textures/widgets/Checkbox_Disabled.png new file mode 100644 index 0000000000..c1ee210099 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Checkbox_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_Off.png b/indra/newview/skins/default/textures/widgets/Checkbox_Off.png new file mode 100644 index 0000000000..2525405f37 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Checkbox_Off.png differ diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_On.png b/indra/newview/skins/default/textures/widgets/Checkbox_On.png new file mode 100644 index 0000000000..2d9dba1592 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Checkbox_On.png differ diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_On_Disabled.png b/indra/newview/skins/default/textures/widgets/Checkbox_On_Disabled.png new file mode 100644 index 0000000000..beaa7bcbf6 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Checkbox_On_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_On_Over.png b/indra/newview/skins/default/textures/widgets/Checkbox_On_Over.png new file mode 100644 index 0000000000..bc504d130e Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Checkbox_On_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_On_Press.png b/indra/newview/skins/default/textures/widgets/Checkbox_On_Press.png new file mode 100644 index 0000000000..5bced95a89 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Checkbox_On_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_Over.png b/indra/newview/skins/default/textures/widgets/Checkbox_Over.png new file mode 100644 index 0000000000..5a7162addf Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Checkbox_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_Press.png b/indra/newview/skins/default/textures/widgets/Checkbox_Press.png new file mode 100644 index 0000000000..44be193678 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Checkbox_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_Disabled.png b/indra/newview/skins/default/textures/widgets/ComboButton_Disabled.png new file mode 100644 index 0000000000..d0fff1b3c3 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ComboButton_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_Off.png b/indra/newview/skins/default/textures/widgets/ComboButton_Off.png new file mode 100644 index 0000000000..80402458b7 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ComboButton_Off.png differ diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_On.png b/indra/newview/skins/default/textures/widgets/ComboButton_On.png new file mode 100644 index 0000000000..b42cc7542e Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ComboButton_On.png differ diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png b/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png new file mode 100644 index 0000000000..bbc0657487 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png differ diff --git a/indra/newview/skins/default/textures/widgets/DisclosureArrow_Closed_Over.png b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Closed_Over.png new file mode 100644 index 0000000000..45bcb0464e Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Closed_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Off.png b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Off.png new file mode 100644 index 0000000000..75057938d2 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Off.png differ diff --git a/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Over.png b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Over.png new file mode 100644 index 0000000000..dabbd85b34 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/DropDown_Disabled.png b/indra/newview/skins/default/textures/widgets/DropDown_Disabled.png new file mode 100644 index 0000000000..b295752ea9 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/DropDown_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/DropDown_Off.png b/indra/newview/skins/default/textures/widgets/DropDown_Off.png new file mode 100644 index 0000000000..4764ed4ee2 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/DropDown_Off.png differ diff --git a/indra/newview/skins/default/textures/widgets/DropDown_On.png b/indra/newview/skins/default/textures/widgets/DropDown_On.png new file mode 100644 index 0000000000..10262d3979 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/DropDown_On.png differ diff --git a/indra/newview/skins/default/textures/widgets/DropDown_Press.png b/indra/newview/skins/default/textures/widgets/DropDown_Press.png new file mode 100644 index 0000000000..16cb25cc77 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/DropDown_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/ListItem_Over.png b/indra/newview/skins/default/textures/widgets/ListItem_Over.png new file mode 100644 index 0000000000..4b2b9ab3e5 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ListItem_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/ListItem_Select.png b/indra/newview/skins/default/textures/widgets/ListItem_Select.png new file mode 100644 index 0000000000..317c672441 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ListItem_Select.png differ diff --git a/indra/newview/skins/default/textures/widgets/ProgressBar.png b/indra/newview/skins/default/textures/widgets/ProgressBar.png new file mode 100644 index 0000000000..edf11ac1f5 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ProgressBar.png differ diff --git a/indra/newview/skins/default/textures/widgets/ProgressTrack.png b/indra/newview/skins/default/textures/widgets/ProgressTrack.png new file mode 100644 index 0000000000..bb6d9f4144 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ProgressTrack.png differ diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Disabled.png b/indra/newview/skins/default/textures/widgets/PushButton_Disabled.png new file mode 100644 index 0000000000..04e91bdaab Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/PushButton_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Off.png b/indra/newview/skins/default/textures/widgets/PushButton_Off.png new file mode 100644 index 0000000000..1ee0329e66 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/PushButton_Off.png differ diff --git a/indra/newview/skins/default/textures/widgets/PushButton_On.png b/indra/newview/skins/default/textures/widgets/PushButton_On.png new file mode 100644 index 0000000000..661d1c5611 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/PushButton_On.png differ diff --git a/indra/newview/skins/default/textures/widgets/PushButton_On_Over.png b/indra/newview/skins/default/textures/widgets/PushButton_On_Over.png new file mode 100644 index 0000000000..064a4c4f7f Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/PushButton_On_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png b/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png new file mode 100644 index 0000000000..48e8aa2eab Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png differ diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Over.png b/indra/newview/skins/default/textures/widgets/PushButton_Over.png new file mode 100644 index 0000000000..c227f07513 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/PushButton_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Press.png b/indra/newview/skins/default/textures/widgets/PushButton_Press.png new file mode 100644 index 0000000000..0a4a3a6ad9 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/PushButton_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected.png new file mode 100644 index 0000000000..0a4a3a6ad9 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/PushButton_Selected.png differ diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png new file mode 100644 index 0000000000..661d1c5611 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Over.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Over.png new file mode 100644 index 0000000000..064a4c4f7f Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png new file mode 100644 index 0000000000..48e8aa2eab Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_Disabled.png b/indra/newview/skins/default/textures/widgets/RadioButton_Disabled.png new file mode 100644 index 0000000000..a1052684b9 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/RadioButton_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_Off.png b/indra/newview/skins/default/textures/widgets/RadioButton_Off.png new file mode 100644 index 0000000000..c58e0305ef Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/RadioButton_Off.png differ diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_On.png b/indra/newview/skins/default/textures/widgets/RadioButton_On.png new file mode 100644 index 0000000000..c09a2197c7 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/RadioButton_On.png differ diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_On_Disabled.png b/indra/newview/skins/default/textures/widgets/RadioButton_On_Disabled.png new file mode 100644 index 0000000000..d7d444fd0c Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/RadioButton_On_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_On_Over.png b/indra/newview/skins/default/textures/widgets/RadioButton_On_Over.png new file mode 100644 index 0000000000..3e7d803a28 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/RadioButton_On_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_On_Press.png b/indra/newview/skins/default/textures/widgets/RadioButton_On_Press.png new file mode 100644 index 0000000000..a707e8ceb8 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/RadioButton_On_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_Over.png b/indra/newview/skins/default/textures/widgets/RadioButton_Over.png new file mode 100644 index 0000000000..a5c8cbe293 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/RadioButton_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_Press.png b/indra/newview/skins/default/textures/widgets/RadioButton_Press.png new file mode 100644 index 0000000000..33eaa14030 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/RadioButton_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Down.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down.png new file mode 100644 index 0000000000..186822da43 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Over.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Over.png new file mode 100644 index 0000000000..605d159eaa Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Left.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left.png new file mode 100644 index 0000000000..42f999a451 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Over.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Over.png new file mode 100644 index 0000000000..c79547dffd Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Right.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right.png new file mode 100644 index 0000000000..176ffcdbb9 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Over.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Over.png new file mode 100644 index 0000000000..e353542ad9 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Up.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up.png new file mode 100644 index 0000000000..4d245eb57a Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Over.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Over.png new file mode 100644 index 0000000000..dd2fceb716 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz.png b/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz.png new file mode 100644 index 0000000000..8a085aa966 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz_Over.png b/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz_Over.png new file mode 100644 index 0000000000..cf78ea3924 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert.png b/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert.png new file mode 100644 index 0000000000..fc7fd93e7a Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert_Over.png b/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert_Over.png new file mode 100644 index 0000000000..53587197da Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollTrack_Horiz.png b/indra/newview/skins/default/textures/widgets/ScrollTrack_Horiz.png new file mode 100644 index 0000000000..4f31c48c02 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollTrack_Horiz.png differ diff --git a/indra/newview/skins/default/textures/widgets/ScrollTrack_Vert.png b/indra/newview/skins/default/textures/widgets/ScrollTrack_Vert.png new file mode 100644 index 0000000000..f89ee3f68f Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ScrollTrack_Vert.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Disabled.png new file mode 100644 index 0000000000..3b39c51a77 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Off.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Off.png new file mode 100644 index 0000000000..57ed79d733 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Off.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On.png new file mode 100644 index 0000000000..7afb9c99c3 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Disabled.png new file mode 100644 index 0000000000..77c4224539 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Over.png new file mode 100644 index 0000000000..8b93dd551e Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Selected.png new file mode 100644 index 0000000000..3f207cbea2 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Selected.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Over.png new file mode 100644 index 0000000000..5b8878e0cb Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Press.png new file mode 100644 index 0000000000..379953216b Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected.png new file mode 100644 index 0000000000..379953216b Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png new file mode 100644 index 0000000000..77c4224539 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png new file mode 100644 index 0000000000..8b93dd551e Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png new file mode 100644 index 0000000000..3f207cbea2 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Disabled.png new file mode 100644 index 0000000000..deb87c8489 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On.png new file mode 100644 index 0000000000..220df9db25 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Over.png new file mode 100644 index 0000000000..5bbcdcb0b4 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Press.png new file mode 100644 index 0000000000..dde367f05e Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Over.png new file mode 100644 index 0000000000..d4f30b9adb Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected.png new file mode 100644 index 0000000000..ca7027da91 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png new file mode 100644 index 0000000000..220df9db25 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Over.png new file mode 100644 index 0000000000..5bbcdcb0b4 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png new file mode 100644 index 0000000000..dde367f05e Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Disabled.png new file mode 100644 index 0000000000..8e6b9c8c6f Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Off.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Off.png new file mode 100644 index 0000000000..b1521199ff Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Off.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On.png new file mode 100644 index 0000000000..467c43fc90 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Over.png new file mode 100644 index 0000000000..2049736897 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png new file mode 100644 index 0000000000..1574f48b28 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Over.png new file mode 100644 index 0000000000..2717e7d7b0 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Press.png new file mode 100644 index 0000000000..3883518033 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected.png new file mode 100644 index 0000000000..3883518033 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png new file mode 100644 index 0000000000..ab31f6ded7 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Over.png new file mode 100644 index 0000000000..2049736897 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png new file mode 100644 index 0000000000..1574f48b28 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png b/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png new file mode 100644 index 0000000000..b627232012 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/SliderThumb_Off.png b/indra/newview/skins/default/textures/widgets/SliderThumb_Off.png new file mode 100644 index 0000000000..b627232012 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SliderThumb_Off.png differ diff --git a/indra/newview/skins/default/textures/widgets/SliderThumb_Over.png b/indra/newview/skins/default/textures/widgets/SliderThumb_Over.png new file mode 100644 index 0000000000..b6f900d3bd Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SliderThumb_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/SliderThumb_Press.png b/indra/newview/skins/default/textures/widgets/SliderThumb_Press.png new file mode 100644 index 0000000000..7081f9cfe0 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SliderThumb_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/SliderTrack_Horiz.png b/indra/newview/skins/default/textures/widgets/SliderTrack_Horiz.png new file mode 100644 index 0000000000..232006ee5a Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SliderTrack_Horiz.png differ diff --git a/indra/newview/skins/default/textures/widgets/SliderTrack_Vert.png b/indra/newview/skins/default/textures/widgets/SliderTrack_Vert.png new file mode 100644 index 0000000000..cd002b3973 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/SliderTrack_Vert.png differ diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png b/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png new file mode 100644 index 0000000000..cf0d8ee2c1 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png differ diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Down_Over.png b/indra/newview/skins/default/textures/widgets/Stepper_Down_Over.png new file mode 100644 index 0000000000..01e0a2d9f1 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Stepper_Down_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png b/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png new file mode 100644 index 0000000000..fe3a7beafd Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png b/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png new file mode 100644 index 0000000000..133589b8a6 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png differ diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Up_Over.png b/indra/newview/skins/default/textures/widgets/Stepper_Up_Over.png new file mode 100644 index 0000000000..2ce84ea5be Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Stepper_Up_Over.png differ diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png b/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png new file mode 100644 index 0000000000..e83babc519 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png differ diff --git a/indra/newview/skins/default/textures/widgets/TextField_Active.png b/indra/newview/skins/default/textures/widgets/TextField_Active.png new file mode 100644 index 0000000000..ca6daab4e0 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/TextField_Active.png differ diff --git a/indra/newview/skins/default/textures/widgets/TextField_Disabled.png b/indra/newview/skins/default/textures/widgets/TextField_Disabled.png new file mode 100644 index 0000000000..3d205a3f2e Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/TextField_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/TextField_Off.png b/indra/newview/skins/default/textures/widgets/TextField_Off.png new file mode 100644 index 0000000000..911d907acc Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/TextField_Off.png differ diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Active.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Active.png new file mode 100644 index 0000000000..fa79cb6260 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/TextField_Search_Active.png differ diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Disabled.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Disabled.png new file mode 100644 index 0000000000..8b504af101 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/TextField_Search_Disabled.png differ diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Off.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Off.png new file mode 100644 index 0000000000..862b13d219 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/TextField_Search_Off.png differ diff --git a/indra/newview/skins/default/textures/windows/Flyout.png b/indra/newview/skins/default/textures/windows/Flyout.png new file mode 100644 index 0000000000..5596b194c9 Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Flyout.png differ diff --git a/indra/newview/skins/default/textures/windows/Flyout_Pointer.png b/indra/newview/skins/default/textures/windows/Flyout_Pointer.png new file mode 100644 index 0000000000..69fc08ceaa Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Flyout_Pointer.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png new file mode 100644 index 0000000000..fb59f2e61e Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Press.png b/indra/newview/skins/default/textures/windows/Icon_Close_Press.png new file mode 100644 index 0000000000..7177c803b0 Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Close_Press.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Toast.png b/indra/newview/skins/default/textures/windows/Icon_Close_Toast.png new file mode 100644 index 0000000000..ecf01c617a Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Close_Toast.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png new file mode 100644 index 0000000000..cadd6bc8ce Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png b/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png new file mode 100644 index 0000000000..08f8cfc3d4 Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Gear_Background.png b/indra/newview/skins/default/textures/windows/Icon_Gear_Background.png new file mode 100644 index 0000000000..db74b93afd Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Gear_Background.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Gear_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Gear_Foreground.png new file mode 100644 index 0000000000..1032e45f7e Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Gear_Foreground.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Gear_Over.png b/indra/newview/skins/default/textures/windows/Icon_Gear_Over.png new file mode 100644 index 0000000000..01dbde102b Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Gear_Over.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Gear_Press.png b/indra/newview/skins/default/textures/windows/Icon_Gear_Press.png new file mode 100644 index 0000000000..6614bdd165 Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Gear_Press.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png new file mode 100644 index 0000000000..d790cf57ef Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png b/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png new file mode 100644 index 0000000000..fdae4b75f6 Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png differ diff --git a/indra/newview/skins/default/textures/windows/Resize_Corner.png b/indra/newview/skins/default/textures/windows/Resize_Corner.png new file mode 100644 index 0000000000..16ed63e428 Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Resize_Corner.png differ diff --git a/indra/newview/skins/default/textures/windows/Toast_CloseBtn.png b/indra/newview/skins/default/textures/windows/Toast_CloseBtn.png new file mode 100644 index 0000000000..78b137cdaf Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Toast_CloseBtn.png differ diff --git a/indra/newview/skins/default/textures/windows/Toast_Over.png b/indra/newview/skins/default/textures/windows/Toast_Over.png new file mode 100644 index 0000000000..807e8e553c Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Toast_Over.png differ diff --git a/indra/newview/skins/default/textures/windows/Window_Background.png b/indra/newview/skins/default/textures/windows/Window_Background.png new file mode 100644 index 0000000000..e9f15e76b9 Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Window_Background.png differ diff --git a/indra/newview/skins/default/textures/windows/Window_Foreground.png b/indra/newview/skins/default/textures/windows/Window_Foreground.png new file mode 100644 index 0000000000..e76e9f3c79 Binary files /dev/null and b/indra/newview/skins/default/textures/windows/Window_Foreground.png differ diff --git a/indra/newview/skins/default/textures/world/NoEntryLines.png b/indra/newview/skins/default/textures/world/NoEntryLines.png new file mode 100644 index 0000000000..18e270bde5 Binary files /dev/null and b/indra/newview/skins/default/textures/world/NoEntryLines.png differ diff --git a/indra/newview/skins/default/textures/world/NoEntryPassLines.png b/indra/newview/skins/default/textures/world/NoEntryPassLines.png new file mode 100644 index 0000000000..e4b8fc6ae2 Binary files /dev/null and b/indra/newview/skins/default/textures/world/NoEntryPassLines.png differ diff --git a/indra/newview/skins/default/xui/da/language_settings.xml b/indra/newview/skins/default/xui/da/language_settings.xml new file mode 100644 index 0000000000..71418d446a --- /dev/null +++ b/indra/newview/skins/default/xui/da/language_settings.xml @@ -0,0 +1,55 @@ + + + + + + english + C + C + + + + hour,datetime,slt + min,datetime,slt + year,datetime,slt + day,datetime,slt + mthnum,datetime,slt + wkday,datetime,slt + ampm,datetime,slt + hour12,datetime,slt + + mthnum,datetime,local + wkday,datetime,local + mth,datetime,local + day,datetime,local + second,datetime,local + hour,datetime,local + min,datetime,local + year,datetime,local + + weekday,datetime,utc + day,datetime,utc + mth,datetime,utc + year,datetime,utc + hour,datetime,utc + min,datetime,utc + second,datetime,utc + timezone,datetime,utc + diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml index cef204eb5f..8084d2427e 100644 --- a/indra/newview/skins/default/xui/de/floater_tools.xml +++ b/indra/newview/skins/default/xui/de/floater_tools.xml @@ -1,5 +1,633 @@ - + + diff --git a/indra/newview/skins/default/xui/en/floater_beacons.xml b/indra/newview/skins/default/xui/en/floater_beacons.xml index 41ddec6395..ea41289769 100644 --- a/indra/newview/skins/default/xui/en/floater_beacons.xml +++ b/indra/newview/skins/default/xui/en/floater_beacons.xml @@ -1,10 +1,11 @@ + name="touch_only" > + + + name="scripted"> + + + name="physical" > + + + name="sounds" > + + + name="particles" > + + + name="highlights" > + + + name="beacons" > + + + width="280"> Selection contains no editable contents. @@ -107,24 +107,6 @@ name="check_gesture" top_delta="0" width="126" /> - - + width="100"> + + @@ -253,7 +241,7 @@ height="16" label="Share with group" layout="topleft" - left="170" + left="140" name="share_with_group" top="54" width="106" /> @@ -295,36 +283,42 @@ left_delta="78" name="next_owner_copy" top_delta="0" - width="88" /> - + + + + top="185" + width="150" /> diff --git a/indra/newview/skins/default/xui/en/floater_buy_contents.xml b/indra/newview/skins/default/xui/en/floater_buy_contents.xml index 174337480a..0930043659 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_contents.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_contents.xml @@ -1,14 +1,14 @@ + width="280"> (no copy) @@ -41,7 +41,7 @@ left_delta="0" name="item_list" top_pad="4" - width="281"> + width="250"> @@ -62,33 +62,33 @@ width="281"> Buy for L$[AMOUNT] from [NAME]? - + + + + diff --git a/indra/newview/skins/default/xui/en/floater_first_time_tip.xml b/indra/newview/skins/default/xui/en/floater_first_time_tip.xml new file mode 100644 index 0000000000..c16373ba3c --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_first_time_tip.xml @@ -0,0 +1,20 @@ + + + + diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml index c4d024ae8b..f042385fb4 100644 --- a/indra/newview/skins/default/xui/en/floater_gesture.xml +++ b/indra/newview/skins/default/xui/en/floater_gesture.xml @@ -4,10 +4,10 @@ height="465" layout="topleft" min_height="200" - min_width="350" + min_width="280" name="gestures" title="Active Gestures" - width="350"> + width="280"> Loading... @@ -24,7 +24,7 @@ layout="topleft" left="15" name="help_label"> - Double-click a gesture to play animations and sounds. + Double-click a gesture to play. + - - + + label="Key" + name="shortcut" + width="50" /> + width="208"> + + + width="180"> + + + width="180"> + + + width="180"> + + + width="180"> + + + width="180"> + + + width="180"> + + + width="180"> + + + width="180"> + + + width="50"> + + + width="50"> + + + width="40"> + + + width="50"> + + + width="40"> + + + width="80"> + + + width="80"> + + - L$ per sq. meter: + L$ per m²: + width="110"> + + + width="121"> + + + width="130"> + + + + width="380"> + + + + width="100"> + + diff --git a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml index f0e2911fd8..19fba52500 100644 --- a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml @@ -50,18 +50,23 @@ width="64"> - You have muted this resident. Sending a message will automatically unmute them. + You have blocked this resident. Sending a message will automatically unblock them. diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml new file mode 100644 index 0000000000..4d7fa45a47 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -0,0 +1,67 @@ + + + + + + diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml index eb05fe1883..37c6cbf391 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory.xml @@ -9,6 +9,7 @@ name="Inventory" save_rect="true" save_visibility="true" + single_instance="true" title="Inventory" width="467"> Fetched - + width="280"> + name="ZoomDirect" + width="60" /> + name="Cursor3D" + width="60" /> + name="AutoLeveling" + width="60" /> + width="280"> - [AREA] sq. meters + [AREA] m² + width="270"> + width="69" /> + width="74" /> + width="55" /> + width="10" /> + follows="left|right|top" + halign="right" + height="20" + label="Location" + layout="topleft" + left_pad="5" + max_chars="254" + mouse_opaque="false" + top_delta="0" + width="340"> + + + + + - diff --git a/indra/newview/skins/default/xui/en/floater_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml index 47342ffc5b..17d12c89b7 100644 --- a/indra/newview/skins/default/xui/en/floater_moveview.xml +++ b/indra/newview/skins/default/xui/en/floater_moveview.xml @@ -1,127 +1,184 @@ - diff --git a/indra/newview/skins/default/xui/en/floater_perm_prefs.xml b/indra/newview/skins/default/xui/en/floater_perm_prefs.xml index 430cb940e5..e4cb97035c 100644 --- a/indra/newview/skins/default/xui/en/floater_perm_prefs.xml +++ b/indra/newview/skins/default/xui/en/floater_perm_prefs.xml @@ -24,7 +24,11 @@ left="260" name="help" top="7" - width="22" /> + width="22"> + + + width="88" > + + + width="100"> + + diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml index 1760d5b818..d9602c75ee 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences.xml @@ -15,7 +15,7 @@ label="OK" label_selected="OK" layout="topleft" - left="335" + left="427" name="OK" top="435" width="90"> @@ -35,44 +35,6 @@ - - - + width="100"> + + + width="100"> + + diff --git a/indra/newview/skins/default/xui/en/floater_ui_preview.xml b/indra/newview/skins/default/xui/en/floater_ui_preview.xml index 10968364f3..bbb17dfb8f 100644 --- a/indra/newview/skins/default/xui/en/floater_ui_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml @@ -41,6 +41,7 @@ width="55"> + + + width="60"> + + + + width="48"> + + + width="48" > + + + width="48"> + + - "MtBkLfRg.ttf" + Helvetica.dfont + + arial.ttf + + + Helvetica.dfont + - MtBdLfRg.ttf + Helvetica.dfont + + arialbd.ttf + + + Helvetica.dfont + + + + + + english + C + C + + + + hour,datetime,slt + min,datetime,slt + year,datetime,slt + day,datetime,slt + mthnum,datetime,slt + wkday,datetime,slt + ampm,datetime,slt + hour12,datetime,slt + + mthnum,datetime,local + wkday,datetime,local + mth,datetime,local + day,datetime,local + second,datetime,local + hour,datetime,local + min,datetime,local + year,datetime,local + + weekday,datetime,utc + day,datetime,utc + mth,datetime,utc + year,datetime,utc + hour,datetime,utc + min,datetime,utc + second,datetime,utc + timezone,datetime,utc + diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml new file mode 100644 index 0000000000..542e319792 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml new file mode 100644 index 0000000000..bad6e1e212 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 6f2fd5e5e5..c788f8f095 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -76,6 +76,14 @@ function="Inventory.DoCreate" parameter="category" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + name="About Second Life"> + parameter="sl_about" /> + + + diff --git a/indra/newview/skins/default/xui/en/menu_navbar.xml b/indra/newview/skins/default/xui/en/menu_navbar.xml index 725321648b..435d928f00 100644 --- a/indra/newview/skins/default/xui/en/menu_navbar.xml +++ b/indra/newview/skins/default/xui/en/menu_navbar.xml @@ -8,14 +8,17 @@ top="624" visible="false" width="128"> - - - + + + + + - - - diff --git a/indra/newview/skins/default/xui/en/menu_picks.xml b/indra/newview/skins/default/xui/en/menu_picks.xml new file mode 100644 index 0000000000..146d7d06fe --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_picks.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 926b51d4c1..44565333e5 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -15,7 +15,7 @@ name="Preferences" shortcut="control|P"> + parameter="land_holdings" /> - - - - + shortcut="control|H"> @@ -202,8 +192,34 @@ function="Floater.Toggle" parameter="nearby_chat" /> + + + + + + + + + + @@ -214,30 +230,15 @@ function="Floater.Toggle" parameter="communicate" /> - - - - - - - - - + name="Preferences" + shortcut="control|alt|M"> + + + function="Floater.Visible" + parameter="camera" /> + function="Floater.Toggle" + parameter="camera" /> + function="Floater.Visible" + parameter="moveview" /> + function="Floater.Toggle" + parameter="moveview" /> @@ -273,16 +274,16 @@ layout="topleft" name="About Land"> + function="Floater.Show" + parameter="about_land" /> + function="Floater.Show" + parameter="region_info" /> @@ -350,9 +351,10 @@ name="Mini-Map" shortcut="control|shift|M"> + function="Floater.Visible" + parameter="mini_map" /> + function="Floater.Show" + parameter="hud" /> - - + + + + + + + + - - - - - - - - - - + + + + function="Floater.Toggle" + parameter="perm_prefs" /> + function="Floater.Show" + parameter="build_options" /> @@ -720,10 +720,10 @@ name="beacons" shortcut="control|alt|shift|N"> + function="Floater.Show" + parameter="lagmeter" /> + function="Floater.Show" + parameter="notifications_console" /> @@ -1999,9 +2000,17 @@ layout="topleft" name="Memory Leaking Simulation"> + function="Floater.Show" + parameter="mem_leaking" /> + + + + + + + + + + function="Floater.Show" + parameter="font_test" /> + + + - +--> + function="Floater.Show" + parameter="god_tools" /> @@ -3481,6 +3516,7 @@ name="Official Linden Blog"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 47b21dc64d..17bb961308 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -13,7 +13,7 @@ Close - +