summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorJames Cook <james@lindenlab.com>2009-07-27 17:56:26 +0000
committerJames Cook <james@lindenlab.com>2009-07-27 17:56:26 +0000
commit8f7ec64899c54dcee6caa0307510cc4003ba7bdd (patch)
tree513093c8550e0baf567d10168b9f750ba869fc21 /indra
parentca51e8f33dfa0cd455438f11902fb1d839bf6206 (diff)
Merged skinning-17 into viewer-2 for bug fixes. Commented out new IM window for now, not complete.
Merging revisions 127913-128319 of svn+ssh://svn.lindenlab.com/svn/linden/branches/skinning/skinning-17 into D:\viewer-2.0.0-3, respecting ancestry
Diffstat (limited to 'indra')
-rw-r--r--indra/integration_tests/llui_libtest/llui_libtest.cpp1
-rw-r--r--indra/integration_tests/llui_libtest/llwidgetreg.cpp6
-rw-r--r--indra/llrender/CMakeLists.txt4
-rw-r--r--indra/llrender/llfontbitmapcache.h2
-rw-r--r--indra/llrender/llfontfreetype.cpp630
-rw-r--r--indra/llrender/llfontfreetype.h380
-rw-r--r--indra/llrender/llfontgl.cpp864
-rw-r--r--indra/llrender/llfontgl.h217
-rw-r--r--indra/llrender/llfontregistry.cpp57
-rw-r--r--indra/llrender/llfontregistry.h2
-rw-r--r--indra/llui/CMakeLists.txt7
-rw-r--r--indra/llui/llbutton.cpp4
-rw-r--r--indra/llui/llbutton.h8
-rw-r--r--indra/llui/llcombobox.cpp2
-rw-r--r--indra/llui/llconsole.h3
-rw-r--r--indra/llui/lldraghandle.cpp17
-rw-r--r--indra/llui/lldraghandle.h3
-rw-r--r--indra/llui/llfiltereditor.cpp110
-rw-r--r--indra/llui/llfiltereditor.h86
-rw-r--r--indra/llui/llfloater.cpp89
-rw-r--r--indra/llui/llfloater.h39
-rw-r--r--indra/llui/llhandle.h171
-rw-r--r--indra/llui/lllayoutstack.cpp8
-rw-r--r--indra/llui/lllayoutstack.h4
-rw-r--r--indra/llui/lllineeditor.cpp133
-rw-r--r--indra/llui/lllineeditor.h40
-rw-r--r--indra/llui/llmenugl.cpp13
-rw-r--r--indra/llui/llmenugl.h1
-rw-r--r--indra/llui/llnotifications.cpp2
-rw-r--r--indra/llui/llnotifications.h18
-rw-r--r--indra/llui/llpanel.cpp5
-rw-r--r--indra/llui/llpanel.h7
-rw-r--r--indra/llui/llprogressbar.cpp10
-rw-r--r--indra/llui/llprogressbar.h8
-rw-r--r--indra/llui/llresizehandle.cpp4
-rw-r--r--indra/llui/llrngwriter.cpp315
-rw-r--r--indra/llui/llrngwriter.h69
-rw-r--r--indra/llui/llscrolllistcell.cpp10
-rw-r--r--indra/llui/llscrolllistcell.h3
-rw-r--r--indra/llui/llscrolllistcolumn.h2
-rw-r--r--indra/llui/llscrolllistctrl.cpp37
-rw-r--r--indra/llui/llscrolllistctrl.h2
-rw-r--r--indra/llui/llscrolllistitem.h6
-rw-r--r--indra/llui/llsearcheditor.cpp82
-rw-r--r--indra/llui/llsearcheditor.h33
-rw-r--r--indra/llui/llstyle.h1
-rw-r--r--indra/llui/lltabcontainer.cpp1
-rw-r--r--indra/llui/lltabcontainer.h4
-rw-r--r--indra/llui/lltextbox.cpp7
-rw-r--r--indra/llui/lltextbox.h1
-rw-r--r--indra/llui/lltexteditor.cpp37
-rw-r--r--indra/llui/lltexteditor.h28
-rw-r--r--indra/llui/llui.cpp19
-rw-r--r--indra/llui/llui.h137
-rw-r--r--indra/llui/lluictrl.cpp6
-rw-r--r--indra/llui/lluictrl.h2
-rw-r--r--indra/llui/lluictrlfactory.cpp420
-rw-r--r--indra/llui/lluictrlfactory.h39
-rw-r--r--indra/llxml/llxmlnode.cpp150
-rw-r--r--indra/llxml/llxmlnode.h4
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/app_settings/settings.xml6
-rw-r--r--indra/newview/llavatariconctrl.h3
-rw-r--r--indra/newview/llavatarlistitem.h4
-rw-r--r--indra/newview/llbottomtray.cpp9
-rw-r--r--indra/newview/llbottomtray.h1
-rw-r--r--indra/newview/llchatitemscontainerctrl.cpp2
-rw-r--r--indra/newview/llchiclet.cpp25
-rw-r--r--indra/newview/llchiclet.h4
-rw-r--r--indra/newview/llfloaterinventory.cpp22
-rw-r--r--indra/newview/llfloaterinventory.h6
-rw-r--r--indra/newview/llfloaterland.cpp18
-rw-r--r--indra/newview/llfloateruipreview.cpp15
-rw-r--r--indra/newview/llfloateruipreview.h1
-rw-r--r--indra/newview/llfloaterworldmap.h1
-rw-r--r--indra/newview/llfolderviewitem.cpp5
-rw-r--r--indra/newview/llimpanel.cpp235
-rw-r--r--indra/newview/llimpanel.h44
-rw-r--r--indra/newview/llimview.cpp12
-rw-r--r--indra/newview/llimview.h6
-rw-r--r--indra/newview/llmenucommands.cpp1
-rw-r--r--indra/newview/llnameeditor.h5
-rw-r--r--indra/newview/llnamelistctrl.cpp2
-rw-r--r--indra/newview/llnamelistctrl.h4
-rw-r--r--indra/newview/llnavigationbar.cpp10
-rw-r--r--indra/newview/llnavigationbar.h4
-rw-r--r--indra/newview/lloutputmonitorctrl.cpp3
-rw-r--r--indra/newview/llpanelavatar.cpp1
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp87
-rw-r--r--indra/newview/llpanelimcontrolpanel.h55
-rw-r--r--indra/newview/llpanellandmarks.cpp1
-rw-r--r--indra/newview/llpanellogin.h1
-rw-r--r--indra/newview/llpanelpeople.cpp12
-rw-r--r--indra/newview/llpanelpeople.h6
-rw-r--r--indra/newview/llpanelpick.cpp1
-rw-r--r--indra/newview/llpanelplaces.cpp18
-rw-r--r--indra/newview/llpanelplaces.h6
-rw-r--r--indra/newview/llpanelplacestab.cpp4
-rw-r--r--indra/newview/llsidetray.cpp2
-rw-r--r--indra/newview/llsidetray.h25
-rw-r--r--indra/newview/lltexturectrl.cpp22
-rw-r--r--indra/newview/lltexturectrl.h2
-rw-r--r--indra/newview/lltoast.cpp4
-rw-r--r--indra/newview/lltoastnotifypanel.cpp2
-rw-r--r--indra/newview/llviewermessage.cpp2
-rw-r--r--indra/newview/llviewerwindow.cpp1
-rw-r--r--indra/newview/skins/default/textures/textures.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml73
-rw-r--r--indra/newview/skins/default/xui/en/floater_inspect.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_widgets.xml8
-rw-r--r--indra/newview/skins/default/xui/en/floater_texture_ctrl.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_ui_preview.xml11
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_friends.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_im_control_panel.xml32
-rw-r--r--indra/newview/skins/default/xui/en/panel_navigation_bar.xml24
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_places.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_teleport_history.xml2
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/en/widgets/filter_editor.xml7
-rw-r--r--indra/newview/skins/default/xui/en/widgets/line_editor.xml10
-rw-r--r--indra/newview/skins/default/xui/en/widgets/scroll_list.xml2
-rw-r--r--indra/newview/skins/default/xui/en/widgets/search_editor.xml13
-rw-r--r--indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml32
-rw-r--r--indra/newview/skins/default/xui/en/widgets/text_editor.xml21
128 files changed, 3645 insertions, 1687 deletions
diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp
index e0117eca06..54fc167adf 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"
diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.cpp b/indra/integration_tests/llui_libtest/llwidgetreg.cpp
index 4e59971f29..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)
@@ -65,11 +66,11 @@ void LLWidgetReg::initClass(bool register_widgets)
LLDefaultChildRegistry::Register<LLButton> button("button");
LLDefaultChildRegistry::Register<LLCheckBoxCtrl> check_box("check_box");
LLDefaultChildRegistry::Register<LLComboBox> combo_box("combo_box");
+ LLDefaultChildRegistry::Register<LLFilterEditor> filter_editor("filter_editor");
LLDefaultChildRegistry::Register<LLFlyoutButton> flyout_button("flyout_button");
LLDefaultChildRegistry::Register<LLContainerView> container_view("container_view");
LLDefaultChildRegistry::Register<LLIconCtrl> icon("icon");
LLDefaultChildRegistry::Register<LLLineEditor> line_editor("line_editor");
- LLDefaultChildRegistry::Register<LLSearchEditor> search_editor("search_editor");
LLDefaultChildRegistry::Register<LLMenuItemSeparatorGL> menu_item_separator("menu_item_separator");
LLDefaultChildRegistry::Register<LLMenuItemCallGL> menu_item_call_gl("menu_item_call");
LLDefaultChildRegistry::Register<LLMenuItemCheckGL> menu_item_check_gl("menu_item_check");
@@ -83,6 +84,7 @@ void LLWidgetReg::initClass(bool register_widgets)
LLDefaultChildRegistry::Register<LLProgressBar> progress_bar("progress_bar");
LLDefaultChildRegistry::Register<LLRadioGroup> radio_group("radio_group");
LLDefaultChildRegistry::Register<LLRadioCtrl> radio_item("radio_item");
+ LLDefaultChildRegistry::Register<LLSearchEditor> search_editor("search_editor");
LLDefaultChildRegistry::Register<LLScrollContainer> scroll_container("scroll_container");
LLDefaultChildRegistry::Register<LLScrollingPanelList> scrolling_panel_list("scrolling_panel_list");
LLDefaultChildRegistry::Register<LLScrollListCtrl> scroll_list("scroll_list");
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 0e0fc6ce6c..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
@@ -45,7 +45,7 @@ set(llrender_HEADER_FILES
llcubemap.h
llfontgl.h
- llfont.h
+ llfontfreetype.h
llfontbitmapcache.h
llfontregistry.h
llgl.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 <vector>
// 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..91a95cdd25
--- /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 <ft2build.h>
+
+// 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<LLFontBitmapCache> 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 <map>
+#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<LLPointer<LLFontFreetype> > 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<LLFontBitmapCache> 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<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
+ mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
+
+ mutable LLPointer<LLFontBitmapCache> 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 <map>
+#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<LLPointer<LLFontFreetype> > 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<LLFontBitmapCache> 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<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
+ mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
+
+ mutable LLPointer<LLFontBitmapCache> mFontBitmapCachep;
+
+ mutable S32 mRenderGlyphCount;
+ mutable S32 mAddGlyphCount;
+};
+
+#endif // LL_FONTFREETYPE_H
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 0b57d86c78..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"
@@ -73,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();
@@ -128,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<std::string>& 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();
-}
-
-
-
-LLFontGL &LLFontGL::operator=(const LLFontGL &source)
-{
- 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))
- {
- 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;
- }
+ mFontFreetype->destroyGL();
}
-BOOL LLFontGL::addChar(const llwchar wch) const
+BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
{
- if (!LLFont::addChar(wch))
+ if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
{
- 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
{
@@ -430,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)
@@ -483,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.
@@ -517,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();
+
+ F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();
+ F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight();
- const S32 LAST_CHARACTER = LLFont::LAST_CHAR_FULL;
+ const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
BOOL draw_ellipses = FALSE;
@@ -576,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())
{
@@ -609,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);
@@ -646,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;
@@ -656,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.
@@ -680,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();
}
@@ -703,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,
@@ -716,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
{
@@ -728,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);
@@ -751,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;
@@ -783,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)
@@ -791,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.
@@ -801,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)
{
@@ -899,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)
{
@@ -910,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.
@@ -929,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)
@@ -948,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) )
{
@@ -966,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.
@@ -976,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)
{
@@ -1041,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)
{
@@ -1070,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.
@@ -1081,60 +819,370 @@ 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
{
- // Handle crappy embedded hack
- embedded_map_t::const_iterator iter = mEmbeddedChars.find(wch);
+ 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())
{
- return iter->second;
+ delete iter->second;
+ mEmbeddedChars.erase(wc);
}
- return NULL;
}
+BOOL LLFontGL::addChar(llwchar wch) const
+{
+ if (!mFontFreetype->addChar(wch))
+ {
+ return FALSE;
+ }
+
+ stop_glerror();
-F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const
+ 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
{
- const LLWString& label = ext_data->mLabel;
- LLImageGL* ext_image = ext_data->mImage;
+ return mFontDescriptor;
+}
- F32 ext_width = (F32)ext_image->getWidth();
- if( !label.empty() )
+// static
+void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& 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)
{
- ext_width += (EXT_X_BEARING + getFontExtChar()->getWidthF32(label.c_str())) * sScaleX;
+ sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures);
+ sFontRegistry->parseFontInfo("fonts.xml");
+ }
+ else
+ {
+ sFontRegistry->reset();
}
+}
- return (EXT_X_BEARING * sScaleX) + ext_width;
+// 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;
+}
-void LLFontGL::clearEmbeddedChars()
+//static
+void LLFontGL::destroyAllGL()
{
- for_each(mEmbeddedChars.begin(), mEmbeddedChars.end(), DeletePairedPointer());
- mEmbeddedChars.clear();
+ if (sFontRegistry)
+ {
+ sFontRegistry->destroyGL();
+ }
}
-void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label ) const
+// static
+U8 LLFontGL::getStyleFromString(const std::string &style)
{
- LLWString wlabel = utf8str_to_wstring(label);
- addEmbeddedChar(wc, image, wlabel);
+ 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;
}
-void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& wlabel ) const
+// static
+std::string LLFontGL::nameFromFont(const LLFontGL* fontp)
{
- embedded_data_t* ext_data = new embedded_data_t(image->getGLTexture(), wlabel);
- mEmbeddedChars[wc] = ext_data;
+ return fontp->mFontDescriptor.getName();
}
-void LLFontGL::removeEmbeddedChar( llwchar wc ) const
+// static
+std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align)
{
- embedded_map_t::iterator iter = mEmbeddedChars.find(wc);
+ 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);
if (iter != mEmbeddedChars.end())
{
- delete iter->second;
- mEmbeddedChars.erase(wc);
+ return iter->second;
+ }
+ return NULL;
+}
+
+F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const
+{
+ const LLWString& label = ext_data->mLabel;
+ LLImageGL* ext_image = ext_data->mImage;
+
+ F32 ext_width = (F32)ext_image->getWidth();
+ if( !label.empty() )
+ {
+ ext_width += (EXT_X_BEARING + getFontExtChar()->getWidthF32(label.c_str())) * sScaleX;
}
+
+ return (EXT_X_BEARING * sScaleX) + ext_width;
+}
+
+void LLFontGL::clearEmbeddedChars()
+{
+ for_each(mEmbeddedChars.begin(), mEmbeddedChars.end(), DeletePairedPointer());
+ mEmbeddedChars.clear();
}
@@ -1160,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);
{
@@ -1230,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 2298db0ef3..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);
-
- static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale,
- const std::string& app_dir,
- const std::vector<std::string>& xui_paths,
- bool create_gl_textures = true);
+ void reset(); // Reset a font after GL cleanup. ONLY works on an already loaded font.
- // 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);
+ 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;
- 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 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;
- 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;
+ // font metrics - override for LLFontFreetype that returns units of virtual pixels
+ F32 getLineHeight() const;
+ F32 getAscenderHeight() const;
+ F32 getDescenderHeight() 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;
+ 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
- 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;
+ 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).
- virtual S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const;
+ 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;
+ 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;
- LLImageGL *getImageGL() const;
+ const LLFontDescriptor& getFontDesc() 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;
+
+ static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& 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();
+
+ // 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<LLImageGL> 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 std::string getFontPathLocal();
+ static std::string getFontPathSystem();
+
+ static LLCoordFont sCurOrigin;
+ static std::vector<LLCoordFont> sOriginStack;
+
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;
-protected:
- /*virtual*/ BOOL addChar(const llwchar wch) const;
+ LLFontGL(const LLFontGL &source);
+ LLFontGL &operator=(const LLFontGL &source);
-protected:
- typedef std::map<llwchar,embedded_data_t*> embedded_map_t;
- mutable embedded_map_t mEmbeddedChars;
-
LLFontDescriptor mFontDescriptor;
+ LLPointer<LLFontFreetype> mFontFreetype;
- // Registry holds all instantiated fonts.
- static LLFontRegistry* sFontRegistry;
+ struct embedded_data_t
+ {
+ embedded_data_t(LLImageGL* image, const LLWString& label) : mImage(image), mLabel(label) {}
+ LLPointer<LLImageGL> mImage;
+ LLWString mLabel;
+ };
-public:
- static std::string getFontPathLocal();
- static std::string getFontPathSystem();
+ typedef std::map<llwchar,embedded_data_t*> embedded_map_t;
+ mutable embedded_map_t mEmbeddedChars;
- static LLCoordFont sCurOrigin;
- static std::vector<LLCoordFont> sOriginStack;
+ 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;
- const LLFontDescriptor &getFontDesc() const { return mFontDescriptor; }
- void setFontDesc(const LLFontDescriptor& font_desc) { mFontDescriptor = font_desc; }
+ // Registry holds all instantiated fonts.
+ static LLFontRegistry* sFontRegistry;
};
#endif
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 3b5c62a5ea..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 <boost/tokenizer.hpp>
#include "llcontrol.h"
#include "lldir.h"
@@ -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/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index e62d875a01..edd3fe2beb 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
@@ -59,6 +60,7 @@ set(llui_SOURCE_FILES
llresizebar.cpp
llresizehandle.cpp
llresmgr.cpp
+ llrngwriter.cpp
llscrollbar.cpp
llscrollcontainer.cpp
llscrollingpanellist.cpp
@@ -67,7 +69,7 @@ set(llui_SOURCE_FILES
llscrolllistctrl.cpp
llscrolllistitem.cpp
llsdparam.cpp
- llsearcheditor.cpp
+ llsearcheditor.cpp
llslider.cpp
llsliderctrl.cpp
llspinctrl.cpp
@@ -109,11 +111,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
@@ -134,6 +138,7 @@ set(llui_HEADER_FILES
llresizebar.h
llresizehandle.h
llresmgr.h
+ llrngwriter.h
llsearcheditor.h
llscrollbar.h
llscrollcontainer.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 9ad27e7c41..fc3af34951 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -62,7 +62,7 @@ S32 BTN_HEIGHT = 0;
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"),
@@ -133,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),
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 3fa62cc351..e387c91a17 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -74,7 +74,7 @@ public:
{
// text label
Optional<std::string> label_selected;
- Optional<bool> label_dropshadow;
+ Optional<bool> label_shadow;
Optional<bool> auto_resize;
// images
@@ -105,9 +105,9 @@ public:
// callbacks
Optional<CommitCallbackParam> 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<bool> is_toggle,
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 5caad1919a..51f9d6bd18 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -141,7 +141,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);
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<S32> 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/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 86eef7c42c..88ec1d21f8 100644
--- a/indra/llui/lldraghandle.h
+++ b/indra/llui/lldraghandle.h
@@ -53,7 +53,8 @@ public:
Optional<LLUIColor> drag_shadow_color;
Params()
- : drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")),
+ : 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);
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<LLLineEditor>(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<LLButton>(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<Params, LLLineEditor::Params>
+ {
+ Optional<LLButton::Params> 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 153e025385..a397278a2b 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -71,15 +71,8 @@ std::string LLFloater::sButtonActiveImageNames[BUTTON_COUNT] =
"minimize.tga", //BUTTON_MINIMIZE
"tearoffbox.tga", //BUTTON_TEAR_OFF
"closebox.tga", //BUTTON_EDIT
-};
-
-std::string LLFloater::sButtonInactiveImageNames[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
+ "Icon_Dock_Foreground",
+ "Icon_Undock_Foreground"
};
std::string LLFloater::sButtonPressedImageNames[BUTTON_COUNT] =
@@ -89,6 +82,8 @@ std::string LLFloater::sButtonPressedImageNames[BUTTON_COUNT] =
"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,6 +93,8 @@ 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] = {};
@@ -114,6 +111,8 @@ std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]=
"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_DOCK",
+ "BUTTON_UNDOCK"
};
LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
@@ -123,6 +122,8 @@ 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;
@@ -189,6 +190,29 @@ 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()
{
@@ -217,6 +241,8 @@ 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),
@@ -289,6 +315,11 @@ void LLFloater::initFloater()
mButtonsEnabled[BUTTON_MINIMIZE] = TRUE;
}
+ if(mCanDock)
+ {
+ mButtonsEnabled[BUTTON_DOCK] = TRUE;
+ }
+
buildButtons();
// Floaters are created in the invisible state
@@ -1305,6 +1336,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)
{
@@ -1381,6 +1442,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()
{
@@ -2522,6 +2592,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;
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index b1d33f48e9..f6c6dcf277 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -102,6 +102,8 @@ public:
BUTTON_MINIMIZE,
BUTTON_TEAR_OFF,
BUTTON_EDIT,
+ BUTTON_DOCK,
+ BUTTON_UNDOCK,
BUTTON_COUNT
};
@@ -120,7 +122,7 @@ public:
{
Optional<close_callback_t> function;
};
-
+
struct Params
: public LLInitParam::Block<Params, LLPanel::Params>
{
@@ -135,31 +137,13 @@ public:
can_drag_on_left,
can_tear_off,
save_rect,
- save_visibility;
+ save_visibility,
+ can_dock;
Optional<OpenCallbackParam> open_callback;
Optional<CloseCallbackParam> close_callback;
- 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")
- {
- name = "floater";
- // defaults that differ from LLPanel:
- background_visible = true;
- visible = false;
- }
+ Params();
};
// use this to avoid creating your own default LLFloater::Param instance
@@ -267,6 +251,12 @@ public:
const LLSD& getKey() { return mKey; }
BOOL matchesKey(const LLSD& key) { return mSingleInstance || KeyCompare::equate(key, mKey); }
+ 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();
@@ -283,6 +273,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);
@@ -378,11 +369,13 @@ private:
LLHandle<LLFloater> mHostHandle;
LLHandle<LLFloater> 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];
static std::string sButtonPressedImageNames[BUTTON_COUNT];
static std::string sButtonNames[BUTTON_COUNT];
static std::string sButtonToolTips[BUTTON_COUNT];
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 <typename T>
+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 <typename T>
+class LLHandle
+{
+public:
+ LLHandle() : mTombStone(sDefaultTombStone) {}
+ const LLHandle<T>& operator =(const LLHandle<T>& 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<T>& lhs, const LLHandle<T>& rhs)
+ {
+ return lhs.mTombStone == rhs.mTombStone;
+ }
+ friend bool operator!= (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+ {
+ return !(lhs == rhs);
+ }
+ friend bool operator< (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+ {
+ return lhs.mTombStone < rhs.mTombStone;
+ }
+ friend bool operator> (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+ {
+ return lhs.mTombStone > rhs.mTombStone;
+ }
+protected:
+
+protected:
+ LLPointer<LLTombStone<T> > mTombStone;
+
+private:
+ static LLPointer<LLTombStone<T> > sDefaultTombStone;
+};
+
+// initialize static "empty" tombstone pointer
+template <typename T> LLPointer<LLTombStone<T> > LLHandle<T>::sDefaultTombStone = new LLTombStone<T>();
+
+
+template <typename T>
+class LLRootHandle : public LLHandle<T>
+{
+public:
+ LLRootHandle(T* object) { bind(object); }
+ LLRootHandle() {};
+ ~LLRootHandle() { unbind(); }
+
+ // this is redundant, since a LLRootHandle *is* an LLHandle
+ LLHandle<T> getHandle() { return LLHandle<T>(*this); }
+
+ void bind(T* object)
+ {
+ // unbind existing tombstone
+ if (LLHandle<T>::mTombStone.notNull())
+ {
+ if (LLHandle<T>::mTombStone->getTarget() == object) return;
+ LLHandle<T>::mTombStone->setTarget(NULL);
+ }
+ // tombstone reference counted, so no paired delete
+ LLHandle<T>::mTombStone = new LLTombStone<T>(object);
+ }
+
+ void unbind()
+ {
+ LLHandle<T>::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 <typename T>
+class LLHandleProvider
+{
+protected:
+ typedef LLHandle<T> handle_type_t;
+ LLHandleProvider()
+ {
+ // provided here to enforce T deriving from LLHandleProvider<T>
+ }
+
+ LLHandle<T> getHandle()
+ {
+ // perform lazy binding to avoid small tombstone allocations for handle
+ // providers whose handles are never referenced
+ mHandle.bind(static_cast<T*>(this));
+ return mHandle;
+ }
+
+private:
+ LLRootHandle<T> mHandle;
+};
+
+#endif
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index f1e7d791d4..702d8e4a39 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -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<S32>(*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());
}
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<std::string> orientation;
Optional<S32> border_size;
- Optional<bool> animate;
+ Optional<bool> animate;
+ Optional<bool> 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 43c22cbf5d..f94eb7fcc3 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -91,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),
@@ -100,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"),
@@ -145,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 );
@@ -183,11 +186,6 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
mBorder = LLUICtrlFactory::create<LLViewBorder>(border_p);
addChild( mBorder );
- if(p.background_image.isProvided())
- {
- mImage = p.background_image;
- }
-
// clamp text padding to current editor size
updateTextPadding();
setCursor(mText.length());
@@ -237,6 +235,7 @@ void LLLineEditor::onFocusLost()
LLUICtrl::onFocusLost();
}
+// virtual
void LLLineEditor::onCommit()
{
// put current line into the line history
@@ -247,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()
@@ -1497,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();
@@ -1527,34 +1580,8 @@ void LLLineEditor::draw()
LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 );
background.stretch( -mBorderThickness );
- LLColor4 bg_color = mReadOnlyBgColor.get();
-
-#if 1 // 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());
-#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
// With viewer-2 art files, input region is 2 pixels up
@@ -1600,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
{
@@ -1608,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));
}
}
}
@@ -1641,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),
@@ -1650,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));
@@ -1661,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),
@@ -1676,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),
@@ -1690,7 +1719,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),
@@ -1728,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);
}
@@ -1754,7 +1783,7 @@ void LLLineEditor::draw()
label_color,
LLFontGL::LEFT,
LLFontGL::BOTTOM,
- mGLFontStyle,
+ 0,
LLFontGL::NO_SHADOW,
S32_MAX,
mMaxHPixels - llround(rendered_pixels_right),
@@ -1779,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 4362cff2fe..0986ce5a87 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -84,7 +84,9 @@ public:
Optional<LLViewBorder::Params> border;
- Optional<LLUIImage*> background_image;
+ Optional<LLUIImage*> background_image,
+ background_image_disabled,
+ background_image_focused;
Optional<bool> 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<S32> 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<LLUIImage> mImage;
+ LLPointer<LLUIImage> mBgImage;
+ LLPointer<LLUIImage> mBgImageDisabled;
+ LLPointer<LLUIImage> mBgImageFocused;
BOOL mReplaceNewlinesWithSpaces; // if false, will replace pasted newlines with paragraph symbol.
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index ade88d2714..fdb4bdd5c1 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"
@@ -1453,6 +1453,7 @@ void LLMenuItemBranchDownGL::draw( void )
setHover(FALSE);
}
+
class LLMenuScrollItem : public LLMenuItemCallGL
{
public:
@@ -1461,10 +1462,18 @@ public:
ARROW_DOWN,
ARROW_UP
};
+ struct ArrowTypes : public LLInitParam::TypeValuesHelper<EArrowType, ArrowTypes>
+ {
+ static void declareValues()
+ {
+ declare("up", ARROW_UP);
+ declare("down", ARROW_DOWN);
+ }
+ };
struct Params : public LLInitParam::Block<Params, LLMenuItemCallGL::Params>
{
- Optional<EArrowType> arrow_type;
+ Optional<EArrowType, ArrowTypes> arrow_type;
Optional<CommitCallbackParam> scroll_callback;
};
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 7d5cc25e1e..262f75f1e1 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -380,6 +380,7 @@ public:
Params()
: 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),
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 50fee41029..2b6ae1f67e 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -384,7 +384,7 @@ LLNotificationTemplate::LLNotificationTemplate() :
}
LLNotification::LLNotification(const LLNotification::Params& p) :
- mTimestamp(p.timestamp),
+ mTimestamp(p.time_stamp),
mSubstitutions(p.substitutions),
mPayload(p.payload),
mExpiresAt(0),
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 512886790c..63eae7278f 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -294,7 +294,7 @@ public:
Optional<LLSD> payload;
Optional<ENotificationPriority> priority;
Optional<LLSD> form_elements;
- Optional<LLDate> timestamp;
+ Optional<LLDate> time_stamp;
Optional<LLNotificationContext*> context;
struct Functor : public LLInitParam::Choice<Functor>
@@ -312,19 +312,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();
}
};
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 116096b7b3..9fb38bc316 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,7 +54,6 @@
#include "lluictrl.h"
#include "lluictrlfactory.h"
#include "llviewborder.h"
-#include "llbutton.h"
#include "lltabcontainer.h"
static LLDefaultChildRegistry::Register<LLPanel> r1("panel", &LLPanel::fromXML);
@@ -65,6 +65,7 @@ const LLPanel::Params& LLPanel::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),
@@ -430,7 +431,7 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
it != p.strings().end();
++it)
{
- mUIStrings[it->name] = it->text;
+ mUIStrings[it->name] = it->value;
}
setLabel(p.label());
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index 381cba2db3..4140e3aa93 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<LocalizedString>
{
Mandatory<std::string> name;
- Mandatory<std::string> text;
+ Mandatory<std::string> value;
LocalizedString()
: name("name"),
- text("value")
+ value("value")
{}
};
diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp
index 7a34cc6792..c8b6e814e1 100644
--- a/indra/llui/llprogressbar.cpp
+++ b/indra/llui/llprogressbar.cpp
@@ -50,10 +50,7 @@ static LLDefaultChildRegistry::Register<LLProgressBar> 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")
{}
@@ -61,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)
{}
@@ -85,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<Params, LLView::Params>
{
Optional<LLUIImage*> image_bar,
- image_fill,
- image_shadow;
+ image_fill;
Optional<LLUIColor> color_bar,
- color_bar2,
- color_shadow,
color_bg;
Params();
@@ -65,10 +62,7 @@ private:
LLPointer<LLUIImage> mImageBar;
LLUIColor mColorBar;
- LLUIColor mColorBar2;
- LLPointer<LLUIImage> mImageShadow;
- LLUIColor mColorShadow;
LLUIColor mColorBackground;
LLPointer<LLUIImage> mImageFill;
diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp
index 90f51b9919..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";
}
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<bool>(boost::bind(&LLRNGWriter::writeAttribute, this, "boolean", _1, _2, _3, _4));
+ registerInspectFunc<std::string>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+ registerInspectFunc<U8>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedByte", _1, _2, _3, _4));
+ registerInspectFunc<S8>(boost::bind(&LLRNGWriter::writeAttribute, this, "signedByte", _1, _2, _3, _4));
+ registerInspectFunc<U16>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedShort", _1, _2, _3, _4));
+ registerInspectFunc<S16>(boost::bind(&LLRNGWriter::writeAttribute, this, "signedShort", _1, _2, _3, _4));
+ registerInspectFunc<U32>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedInt", _1, _2, _3, _4));
+ registerInspectFunc<S32>(boost::bind(&LLRNGWriter::writeAttribute, this, "integer", _1, _2, _3, _4));
+ registerInspectFunc<F32>(boost::bind(&LLRNGWriter::writeAttribute, this, "float", _1, _2, _3, _4));
+ registerInspectFunc<F64>(boost::bind(&LLRNGWriter::writeAttribute, this, "double", _1, _2, _3, _4));
+ registerInspectFunc<LLColor4>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+ registerInspectFunc<LLUIColor>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+ registerInspectFunc<LLUUID>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+ registerInspectFunc<LLSD>(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<std::string>* 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. <foo bar="1"/>
+ 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);
+ // <choice>
+ // <group>
+ // <optional>
+ // <attribute name="foo.bar"><data type="string"/></attribute>
+ // </optional>
+ // <optional>
+ // <attribute name="foo.baz"><data type="integer"/></attribute>
+ // </optional>
+ // </group>
+ // <element name="foo">
+ // <optional>
+ // <attribute name="bar"><data type="string"/></attribute>
+ // </optional>
+ // <optional>
+ // <attribute name="baz"><data type="string"/></attribute>
+ // </optional>
+ // </element>
+ // <element name="outer.foo">
+ // <ref name="foo"/>
+ // </element>
+ // </choice>
+
+ 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 <group>
+ 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 <element>
+ 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 <element>
+ //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<std::string>* possible_values)
+{
+ if (possible_values)
+ {
+ LLXMLNodePtr enum_node = parent_node->createChild("choice", false);
+ for (std::vector<std::string>::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<std::string>* possible_values);
+
+ void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values);
+ LLXMLNodePtr mElementNode;
+ LLXMLNodePtr mChildrenNode;
+ LLXMLNodePtr mGrammarNode;
+ std::string mDefinitionName;
+
+ typedef std::pair<LLXMLNodePtr, std::set<std::string> > attribute_data_t;
+ typedef std::map<std::string, attribute_data_t> elements_map_t;
+ typedef std::set<std::string> defined_elements_t;
+
+ defined_elements_t mDefinedElements;
+ attribute_data_t mAttributesWritten;
+ elements_map_t mElementsWritten;
+};
+
+#endif //LLRNGWRITER_H
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.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<F32> 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 84a725ce02..e8627586ea 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -102,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()
@@ -126,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;
@@ -170,7 +171,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()),
@@ -1082,12 +1083,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 );
}
@@ -1249,7 +1250,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 );
}
@@ -2635,8 +2636,8 @@ LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_
// Add any columns we don't already have
S32 col_index = 0;
- for(LLInitParam::ParamIterator<LLScrollListCell::Params>::const_iterator itor = item_p.cells().begin();
- itor != item_p.cells().end();
+ for(LLInitParam::ParamIterator<LLScrollListCell::Params>::const_iterator itor = item_p.columns().begin();
+ itor != item_p.columns().end();
++itor)
{
LLScrollListCell::Params cell_p = *itor;
@@ -2687,7 +2688,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_
col_index++;
}
- if (item_p.cells().empty())
+ if (item_p.columns().empty())
{
if (mColumns.empty())
{
@@ -2742,7 +2743,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 60cd9239e2..c1800419be 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -99,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;
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<LLScrollListCell::Params> cells;
+ Multiple<LLScrollListCell::Params> 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 64583071a6..3516712dc9 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 LLDefaultChildRegistry::Register<LLSearchEditor> 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));
-
- mSearchEdit = LLUICtrlFactory::create<LLLineEditor>(line_editor_p);
- addChild(mSearchEdit);
-
- 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) ;
+ const S32 fudge = 2;
+ S32 btn_height = getRect().getHeight() - (fudge * 2);
+
+ 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(btn_height + fudge);
+ line_editor_params.commit_callback.function(boost::bind(&LLUICtrl::onCommit, this));
+
+ mSearchEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_params);
+ addChild(mSearchEditor);
+
+ LLRect search_btn_rect(fudge, fudge + btn_height, fudge + btn_height, fudge);
+ 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<LLButton>(button_params);
- mSearchEdit->addChild(mClearSearchButton);
+ mSearchButton = LLUICtrlFactory::create<LLButton>(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 <boost/function.hpp>
-
-/*
- * @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<Params, LLLineEditor::Params>
{
- Optional<boost::function<void(const std::string&, void*)> > search_callback;
-
- Optional<LLButton::Params> clear_search_button;
+ Optional<LLButton::Params> 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<void (const std::string& search_string)> 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/llstyle.h b/indra/llui/llstyle.h
index 1a94fcf2c6..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;
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 3d5b5caead..29c30004ef 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -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 56019171e1..3dd8d21f6b 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -82,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() );
}
@@ -382,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);
}
@@ -395,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 53d57ff785..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;
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 421ba32168..adeaf0a279 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"
@@ -227,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 ),
@@ -254,7 +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 ),
+ mAllowEmbeddedItems( p.embedded_items ),
mHandleEditKeysDirectly( FALSE ),
mMouseDownX(0),
mMouseDownY(0),
@@ -263,8 +287,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p)
mScrollNeeded(FALSE),
mLastSelectionY(-1),
mTabsToNextField(p.ignore_tab),
- mGLFont(p.font),
- mGLFontStyle(LLFontGL::getStyleFromString(p.font.style))
+ mGLFont(p.font)
{
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
@@ -1930,7 +1953,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;
}
@@ -3101,7 +3124,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;
@@ -3114,7 +3137,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 )
@@ -3123,7 +3146,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 5e423f8548..4da91cc1d7 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -63,7 +63,7 @@ public:
Optional<S32> max_text_length;
Optional<bool> 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&);
@@ -524,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;
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 7eaa118222..6906f0befb 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -58,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"
@@ -88,9 +89,10 @@ std::list<std::string> gUntranslated;
/*static*/ std::vector<std::string> LLUI::sXUIPaths;
-// register searcheditor here
-static LLDefaultChildRegistry::Register<LLSearchEditor> register_search_editor("search_editor");
+// register filtereditor here
+static LLDefaultChildRegistry::Register<LLFilterEditor> register_filter_editor("filter_editor");
static LLDefaultChildRegistry::Register<LLFlyoutButton> register_flyout_button("flyout_button");
+static LLDefaultChildRegistry::Register<LLSearchEditor> register_search_editor("search_editor");
//
@@ -1963,6 +1965,17 @@ namespace LLInitParam
declare("blue", LLColor4::blue);
}
+ template<>
+ class ParamCompare<const LLFontGL*>
+ {
+ public:
+ static bool equals(const LLFontGL* a, const LLFontGL* b)
+ {
+ return !(a->getFontDesc() < b->getFontDesc())
+ && !(b->getFontDesc() < a->getFontDesc());
+ }
+ };
+
TypedParam<const LLFontGL*>::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(""),
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 9399eff2ab..413733a50b 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -39,7 +39,6 @@
#include "llrect.h"
#include "llcontrol.h"
#include "llcoord.h"
-//#include "llhtmlhelp.h"
#include "llgl.h" // *TODO: break this dependency
#include <stack>
#include "lluiimage.h" // *TODO: break this dependency, need to add #include "lluiimage.h" to all widgets that hold an Optional<LLUIImage*> in their paramblocks
@@ -49,6 +48,8 @@
#include "lluicolortable.h"
#include <boost/signals2.hpp>
#include "lllazyvalue.h"
+#include "llhandle.h" // *TODO: remove this dependency, added as a
+ // convenience when LLHandle moved to llhandle.h
// LLUIFactory
#include "llsd.h"
@@ -433,139 +434,7 @@ public:
LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE);
};
-template <typename T>
-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 <typename T>
-class LLHandle
-{
-public:
- LLHandle() : mTombStone(sDefaultTombStone) {}
- const LLHandle<T>& operator =(const LLHandle<T>& 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<T>& lhs, const LLHandle<T>& rhs)
- {
- return lhs.mTombStone == rhs.mTombStone;
- }
- friend bool operator!= (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
- {
- return !(lhs == rhs);
- }
- friend bool operator< (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
- {
- return lhs.mTombStone < rhs.mTombStone;
- }
- friend bool operator> (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
- {
- return lhs.mTombStone > rhs.mTombStone;
- }
-protected:
-
-protected:
- LLPointer<LLTombStone<T> > mTombStone;
-
-private:
- static LLPointer<LLTombStone<T> > sDefaultTombStone;
-};
-
-// initialize static "empty" tombstone pointer
-template <typename T> LLPointer<LLTombStone<T> > LLHandle<T>::sDefaultTombStone = new LLTombStone<T>();
-
-
-template <typename T>
-class LLRootHandle : public LLHandle<T>
-{
-public:
- LLRootHandle(T* object) { bind(object); }
- LLRootHandle() {};
- ~LLRootHandle() { unbind(); }
-
- // this is redundant, since a LLRootHandle *is* an LLHandle
- LLHandle<T> getHandle() { return LLHandle<T>(*this); }
-
- void bind(T* object)
- {
- // unbind existing tombstone
- if (LLHandle<T>::mTombStone.notNull())
- {
- if (LLHandle<T>::mTombStone->getTarget() == object) return;
- LLHandle<T>::mTombStone->setTarget(NULL);
- }
- // tombstone reference counted, so no paired delete
- LLHandle<T>::mTombStone = new LLTombStone<T>(object);
- }
-
- void unbind()
- {
- LLHandle<T>::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 <typename T>
-class LLHandleProvider
-{
-protected:
- typedef LLHandle<T> handle_type_t;
- LLHandleProvider()
- {
- // provided here to enforce T deriving from LLHandleProvider<T>
- }
-
- LLHandle<T> getHandle()
- {
- // perform lazy binding to avoid small tombstone allocations for handle
- // providers whose handles are never referenced
- mHandle.bind(static_cast<T*>(this));
- return mHandle;
- }
-
-private:
- LLRootHandle<T> mHandle;
-};
-
+// Moved all LLHandle-related code to llhandle.h
//RN: maybe this needs to moved elsewhere?
class LLImageProviderInterface
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index ebf594ff66..aae4a86d87 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -43,7 +43,7 @@ static LLDefaultChildRegistry::Register<LLUICtrl> 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"),
@@ -52,9 +52,7 @@ LLUICtrl::Params::Params()
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()
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 16fbbf79ea..cf6634f370 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -108,7 +108,7 @@ public:
{
Optional<commit_callback_t> function;
};
-
+
struct EnableCallbackParam : public LLInitParam::Block<EnableCallbackParam, CallbackParam >
{
Optional<enable_callback_t> function;
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 9df22e39b4..3b2b56d48e 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");
@@ -449,177 +450,6 @@ void LLUICtrlFactory::popFactoryFunctions()
}
}
-
-//
-// 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<bool>(boost::bind(&LLRNGWriter::writeAttribute, this, "boolean", _1, _2, _3, _4));
- registerInspectFunc<std::string>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
- registerInspectFunc<U8>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedByte", _1, _2, _3, _4));
- registerInspectFunc<S8>(boost::bind(&LLRNGWriter::writeAttribute, this, "signedByte", _1, _2, _3, _4));
- registerInspectFunc<U16>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedShort", _1, _2, _3, _4));
- registerInspectFunc<S16>(boost::bind(&LLRNGWriter::writeAttribute, this, "signedShort", _1, _2, _3, _4));
- registerInspectFunc<U32>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedInt", _1, _2, _3, _4));
- registerInspectFunc<S32>(boost::bind(&LLRNGWriter::writeAttribute, this, "integer", _1, _2, _3, _4));
- registerInspectFunc<F32>(boost::bind(&LLRNGWriter::writeAttribute, this, "float", _1, _2, _3, _4));
- registerInspectFunc<F64>(boost::bind(&LLRNGWriter::writeAttribute, this, "double", _1, _2, _3, _4));
- registerInspectFunc<LLColor4>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
- registerInspectFunc<LLUIColor>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
- registerInspectFunc<LLUUID>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
- registerInspectFunc<LLSD>(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/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);
-
- node = mGrammarNode->createChild("define", false);
- node->createChild("name", true)->setStringValue(type_name);
-
- mElementNode = node->createChild("element", false);
- mElementNode->createChild("name", true)->setStringValue(type_name);
-
- block.inspectBlock(*this);
-}
-
-void LLRNGWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* 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);
- }
- }
-
- 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
- if (non_empty_names.size() == 1)
- {
- if (max_count == 1)
- {
- LLXMLNodePtr node = getCardinalityNode(mElementNode, min_count, max_count)->createChild("attribute", false);
- node->createChild("name", true)->setStringValue(attribute_name);
- node->createChild("data", false)->createChild("type", true)->setStringValue(type);
- }
- }
- // 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;
-
- LLXMLNodePtr node = choice_node->mChildren->head;
- node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
- node->createChild("name", true)->setStringValue(attribute_name);
- node->createChild("data", false)->createChild("type", true)->setStringValue(type);
-
- node = choice_node->mChildren->head->mNext->mChildren->head;
- node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
- node->createChild("name", true)->setStringValue(non_empty_names.back().first);
- node->createChild("data", false)->createChild("type", true)->setStringValue(type);
- }
- else
- {
- LLXMLNodePtr choice_node = mElementNode->createChild("choice", false);
-
- LLXMLNodePtr node = choice_node->createChild("group", false);
- node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
- node->createChild("name", true)->setStringValue(attribute_name);
- node->createChild("data", false)->createChild("type", true)->setStringValue(type);
-
- node = choice_node->createChild("element", false);
- node->createChild("name", true)->setStringValue(element_name);
- node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
- node->createChild("name", true)->setStringValue(non_empty_names.back().first);
- node->createChild("data", false)->createChild("type", true)->setStringValue(type);
-
- node = choice_node->createChild("element", false);
- node->createChild("name", true)->setStringValue(type + "." + element_name);
- node->createChild("ref", true)->createChild("name", true)->setStringValue(element_name);
-
- mElementsWritten[element_name] = choice_node;
- }
- }
-}
-
-LLXMLNodePtr LLRNGWriter::getCardinalityNode(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 >= 1)
- {
- if (max_count == 1 && min_count == 1)
- {
- // just add raw element, will count as 1 and only 1
- count_node = mElementNode;
- }
- else
- {
- count_node = mElementNode->createChild("oneOrMore", false);
- }
- }
- else
- {
- if (max_count == 1)
- {
- count_node = mElementNode->createChild("optional", false);
- }
- else if (max_count > 1)
- {
- count_node = mElementNode->createChild("zeroOrMore", false);
- }
- }
- return count_node;
-}
//
// LLXSDWriter
//
@@ -811,7 +641,7 @@ void LLXSDWriter::addAttributeToSchema(LLXMLNodePtr type_declaration_node, const
string_set_t& attributes_written = mAttributesWritten[type_declaration_node];
- string_set_t::iterator found_it = std::lower_bound(attributes_written.begin(), attributes_written.end(), attribute_name);
+ 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))
@@ -997,142 +827,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: <string> elements for translation need to have whitespace
- // preserved like "initial_value" above, however, the <string> node
- // becomes an attribute of the containing floater or panel.
- // Because all <string> 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<boost::char_separator<char> > tokenizer;
@@ -1152,8 +846,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
@@ -1271,6 +972,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;
@@ -1301,7 +1058,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<const std::string*>(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;
@@ -1538,7 +1315,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 894c77888c..6374018ca6 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -47,28 +47,6 @@ class LLPanel;
class LLFloater;
class LLView;
-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);
-
- /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; }
-
- LLRNGWriter();
-
-private:
- LLXMLNodePtr getCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count);
-
- void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values);
- LLXMLNodePtr mElementNode;
- LLXMLNodePtr mGrammarNode;
-
- typedef std::map<std::string, LLXMLNodePtr> elements_map_t;
- elements_map_t mElementsWritten;
-};
-
-
class LLXSDWriter : public LLInitParam::Parser
{
LOG_CLASS(LLXSDWriter);
@@ -161,6 +139,9 @@ private:
LLXMLNodePtr mCurReadNode;
// Root of the widget XML sub-tree, for example, "line_editor"
LLXMLNodePtr mWriteRootNode;
+
+ typedef std::map<S32, LLXMLNodePtr> out_nodes_t;
+ out_nodes_t mOutNodes;
S32 mLastWriteGeneration;
LLXMLNodePtr mLastWrittenChild;
S32 mCurReadDepth;
@@ -489,7 +470,7 @@ LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreator
}
-typedef boost::function<LLPanel* (void)> LLPannelClassCreatorFunc;
+typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc;
// local static instance for registering a particular panel class
@@ -498,15 +479,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();
}
@@ -518,9 +499,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/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index 5d43ac11e4..07cc612a0a 100644
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -922,7 +922,7 @@ void LLXMLNode::writeHeaderToFile(LLFILE *out_file)
fprintf(out_file, "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\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())
{
@@ -931,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())
@@ -940,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())
{
@@ -956,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";
- }
+ // ID
+ if (mID != "")
+ {
+ output_stream << indent << " id=\"" << mID << "\"\n";
+ }
- // Type
- if (!has_default_type)
- {
- switch (mType)
+ // Type
+ if (!has_default_type)
{
- 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;
- };
- }
+ 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;
+ };
+ }
- // Encoding
- if (!has_default_encoding)
- {
- switch (mEncoding)
+ // Encoding
+ if (!has_default_encoding)
{
- 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 (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;
+ };
+ }
- // Precision
- if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT))
- {
- output_stream << indent << " precision=\"" << mPrecision << "\"\n";
- }
+ // Precision
+ if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT))
+ {
+ output_stream << indent << " precision=\"" << mPrecision << "\"\n";
+ }
- // Version
- if (mVersionMajor > 0 || mVersionMinor > 0)
- {
- output_stream << indent << " version=\"" << mVersionMajor << "." << mVersionMinor << "\"\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";
+ // Array length
+ if (!has_default_length && mLength > 0)
+ {
+ output_stream << indent << " length=\"" << mLength << "\"\n";
+ }
}
{
@@ -1039,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
}
@@ -1074,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 cc9e5cb351..818d774f73 100644
--- a/indra/llxml/llxmlnode.h
+++ b/indra/llxml/llxmlnode.h
@@ -165,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 d06571fb7a..2e29a56e79 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -299,6 +299,7 @@ set(viewer_SOURCE_FILES
llpanelgroupnotices.cpp
llpanelgrouproles.cpp
llpanelinventory.cpp
+ llpanelimcontrolpanel.cpp
llpanelland.cpp
llpanellandmarks.cpp
llpanellandmedia.cpp
@@ -734,6 +735,7 @@ set(viewer_HEADER_FILES
llpanelgroupnotices.h
llpanelgrouproles.h
llpanelinventory.h
+ llpanelimcontrolpanel.h
llpanelland.h
llpanellandmarks.h
llpanellandmedia.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index cb30cada70..ab9b018150 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8091,7 +8091,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <real>1</real>
+ <integer>4</integer>
</map>
<key>UIPreeditMarkerThickness</key>
<map>
@@ -8135,7 +8135,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <real>2</real>
+ <integer>4</integer>
</map>
<key>UIPreeditStandoutThickness</key>
<map>
@@ -8146,7 +8146,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <real>2</real>
+ <integer>2</integer>
</map>
<key>UIResizeBarHeight</key>
<map>
diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h
index cb1e9584ba..e34f2ff474 100644
--- a/indra/newview/llavatariconctrl.h
+++ b/indra/newview/llavatariconctrl.h
@@ -46,9 +46,10 @@ public:
Optional <LLUUID> avatar_id;
Optional <bool> draw_tooltip;
Params()
+ : avatar_id("avatar_id"),
+ draw_tooltip("draw_tooltip", true)
{
name = "avatar_icon";
- draw_tooltip = TRUE;
}
};
protected:
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/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index d84dd09812..963946e888 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -32,11 +32,14 @@
#include "llviewerprecompiledheaders.h" // must be first include
#include "llbottomtray.h"
+
#include "llagent.h"
#include "llchiclet.h"
#include "llfloaterreg.h"
#include "llflyoutbutton.h"
+#include "llimpanel.h"
#include "llkeyboard.h"
+#include "lllineeditor.h"
#include "llgesturemgr.h"
#include "llanimationstates.h"
#include "llmultigesture.h"
@@ -233,7 +236,13 @@ void LLBottomTray::onChicletClick(LLUICtrl* ctrl)
LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(ctrl);
if (chiclet)
{
+ // Until you can type into an IM Window and have a conversation,
+ // still show the old communicate window
LLFloaterReg::showInstance("communicate", chiclet->getSessionId());
+ // DISABLED IN VIEWER-2 BRANCH UNTIL FEATURE IS DONE -- James
+ //// Show after comm window so it is frontmost (and hence will not
+ //// auto-hide)
+ //LLIMFloater::show(chiclet->getSessionId());
}
}
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 330afeb647..08f5cb91d8 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -40,6 +40,7 @@
#include "llcombobox.h"
class LLChicletPanel;
+class LLLineEditor;
class LLNotificationChiclet;
class LLTalkButton;
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 27ebccfe25..bb31b7f2e8 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -367,7 +367,7 @@ void LLChatItemsContainerCtrl::updateLayout (S32 width, S32 height)
}
- //set sizes for first pannels and dragbars
+ //set sizes for first panels and dragbars
for(size_t i=0;i<mItems.size();++i)
{
LLRect panel_rect = mItems[i]->getRect();
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 38a7494b5b..bfa4e06d2e 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -37,7 +37,7 @@
#include "llbottomtray.h"
#include "llgroupactions.h"
#include "lliconctrl.h"
-#include "llimpanel.h"
+#include "llimpanel.h" // LLFloaterIMPanel
#include "llimview.h"
#include "llfloatergroupinfo.h"
#include "llmenugl.h"
@@ -203,6 +203,7 @@ LLIMChiclet::LLIMChiclet(const Params& p)
, mSpeakerCtrl(NULL)
, mShowSpeaker(p.show_speaker)
, mPopupMenu(NULL)
+, mDockTongueVisible(false)
{
LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
mAvatarCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
@@ -227,6 +228,11 @@ LLIMChiclet::~LLIMChiclet()
}
+void LLIMChiclet::setDockTongueVisible(bool visible)
+{
+ mDockTongueVisible = visible;
+}
+
void LLIMChiclet::setCounter(S32 counter)
{
mCounterCtrl->setCounter(counter);
@@ -321,6 +327,13 @@ void LLIMChiclet::draw()
{
LLUICtrl::draw();
gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE);
+
+ if (mDockTongueVisible)
+ {
+ LLUIImagePtr flyout_tongue = LLUI::getUIImage("windows/Flyout_Pointer.png");
+ // was previously AVATAR_WIDTH-16 and CHICLET_HEIGHT-6
+ flyout_tongue->draw( getRect().getWidth()-31, getRect().getHeight()-5);
+ }
}
BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
@@ -552,14 +565,6 @@ void LLChicletPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param)
void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD&param)
{
- LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(ctrl);
- if (chiclet)
- {
- S32 x, y;
- LLRect rect = getRect();
- localPointToScreen(rect.getCenterX(), 0, &x, &y);
- LLIMFloater::show(chiclet->getSessionId(), x);
- }
mCommitSignal(ctrl,param);
}
@@ -653,7 +658,7 @@ void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent )
width, height - scroll_button_rect.getHeight()));
mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD,
- height + 1, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0));
+ height + 7, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0));
trimChiclets();
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index e467ec012a..415ae59ca2 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -34,6 +34,7 @@
#define LL_LLCHICLET_H
#include "llavatariconctrl.h"
+#include "llbutton.h"
#include "llpanel.h"
#include "lltextbox.h"
#include "lloutputmonitorctrl.h"
@@ -266,6 +267,8 @@ public:
*/
virtual void setShowSpeaker(bool show);
+ void setDockTongueVisible(bool visible);
+
/*
* Returns voice chat status control visibility.
*/
@@ -332,6 +335,7 @@ protected:
LLMenuGL* mPopupMenu;
bool mShowSpeaker;
+ bool mDockTongueVisible;
};
/*
diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp
index d05a32dc88..cf78d7d34f 100644
--- a/indra/newview/llfloaterinventory.cpp
+++ b/indra/newview/llfloaterinventory.cpp
@@ -42,7 +42,7 @@
#include "llcallingcard.h"
#include "llfloaterreg.h"
#include "llsdserialize.h"
-#include "llsearcheditor.h"
+#include "llfiltereditor.h"
#include "llspinctrl.h"
#include "llui.h"
#include "message.h"
@@ -530,10 +530,10 @@ BOOL LLFloaterInventory::postBuild()
}
- mSearchEditor = getChild<LLSearchEditor>("inventory search editor");
- if (mSearchEditor)
+ mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
+ if (mFilterEditor)
{
- mSearchEditor->setSearchCallback(boost::bind(&LLFloaterInventory::onSearchEdit, this, _1));
+ mFilterEditor->setCommitCallback(boost::bind(&LLFloaterInventory::onFilterEdit, this, _2));
}
// *TODO:Get the cost info from the server
@@ -598,9 +598,9 @@ void LLFloaterInventory::draw()
title << mFilterText;
setTitle(title.str());
}
- if (mActivePanel && mSearchEditor)
+ if (mActivePanel && mFilterEditor)
{
- mSearchEditor->setText(mActivePanel->getFilterSubString());
+ mFilterEditor->setText(mActivePanel->getFilterSubString());
}
LLFloater::draw();
}
@@ -673,9 +673,9 @@ void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder)
void LLFloaterInventory::startSearch()
{
// this forces focus to line editor portion of search editor
- if (mSearchEditor)
+ if (mFilterEditor)
{
- mSearchEditor->focusFirstItem(TRUE);
+ mFilterEditor->focusFirstItem(TRUE);
}
}
@@ -715,8 +715,8 @@ BOOL LLFloaterInventory::handleKeyHere(KEY key, MASK mask)
if (root_folder)
{
// first check for user accepting current search results
- if (mSearchEditor
- && mSearchEditor->hasFocus()
+ if (mFilterEditor
+ && mFilterEditor->hasFocus()
&& (key == KEY_RETURN
|| key == KEY_DOWN)
&& mask == MASK_NONE)
@@ -966,7 +966,7 @@ void LLFloaterInventory::onClearSearch()
}
}
-void LLFloaterInventory::onSearchEdit(const std::string& search_string )
+void LLFloaterInventory::onFilterEdit(const std::string& search_string )
{
if (search_string == "")
{
diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h
index cd60407507..35ac1ab380 100644
--- a/indra/newview/llfloaterinventory.h
+++ b/indra/newview/llfloaterinventory.h
@@ -64,7 +64,7 @@ class LLScrollContainer;
class LLTextBox;
class LLIconCtrl;
class LLSaveFolderState;
-class LLSearchEditor;
+class LLFilterEditor;
class LLTabContainer;
class LLInventoryPanel : public LLPanel
@@ -267,7 +267,7 @@ public:
void onClearSearch();
static void onFoldersByName(void *user_data);
static BOOL checkFoldersByName(void *user_data);
- void onSearchEdit(const std::string& search_string );
+ void onFilterEdit(const std::string& search_string );
static BOOL incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward);
void onFilterSelected();
@@ -291,7 +291,7 @@ public:
LLFloaterInventoryFinder* getFinder() { return (LLFloaterInventoryFinder*)mFinderHandle.get(); }
protected:
- LLSearchEditor* mSearchEditor;
+ LLFilterEditor* mFilterEditor;
LLTabContainer* mFilterTabs;
LLHandle<LLFloater> mFinderHandle;
LLInventoryPanel* mActivePanel;
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 08a042707d..149df61b35 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1490,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);
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 41e9ee3ccd..4870494b20 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 <boost/tokenizer.hpp>
@@ -354,6 +355,7 @@ void LLFloaterUIPreview::onLanguageComboSelect(LLUICtrl* ctrl)
void LLFloaterUIPreview::onClickExportSchema()
{
+ 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;
@@ -373,10 +375,12 @@ void LLFloaterUIPreview::onClickExportSchema()
LLFILE* rng_file = LLFile::fopen(file_name.c_str(), "w");
{
LLXMLNode::writeHeaderToFile(rng_file);
- root_nodep->writeToFile(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);
}
@@ -625,7 +629,8 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
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);
}
}
@@ -647,7 +652,8 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
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);
}
@@ -671,7 +677,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);
}
}
diff --git a/indra/newview/llfloateruipreview.h b/indra/newview/llfloateruipreview.h
index 1307d60689..eca8c0a141 100644
--- a/indra/newview/llfloateruipreview.h
+++ b/indra/newview/llfloateruipreview.h
@@ -49,6 +49,7 @@ class LLColor;
class LLScrollListCtrl;
class LLComboBox;
class LLButton;
+class LLLineEditor;
class LLXmlTreeNode;
class LLFloaterUIPreview;
class LLFadeEventTimer;
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index 5c1760ce22..d52079fc06 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
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 43f3ea8d8f..a6a8da2a76 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -81,8 +81,9 @@ void LLFolderViewItem::cleanupClass()
// NOTE: Optimize this, we call it a *lot* when opening a large inventory
LLFolderViewItem::Params::Params()
-: folder_arrow_image("", LLUI::getUIImage("folder_arrow.tga")),
- selection_image("", LLUI::getUIImage("rounded_square.tga"))
+: 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);
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 5b4f711099..248a8dbc4c 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -45,8 +45,10 @@
#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"
@@ -57,9 +59,12 @@
#include "llinventorymodel.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"
@@ -2040,7 +2045,7 @@ bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const
}
return false;
}
-
+
std::map<LLUUID, LLIMFloater*> LLIMFloater::sIMFloaterMap;
@@ -2048,23 +2053,183 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id,
const std::string title,
EInstantMessage dialog)
: mSessionID(session_id),
- mIndex(0)
+ mLastMessageIndex(-1),
+ mDialog(dialog)
{
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml");
sIMFloaterMap[mSessionID] = this;
+ LLPanelIMControlPanel* im_control_panel = getChild<LLPanelIMControlPanel>("panel_im_control_panel");
+
+ LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, session_id, (LLIMModel::LLIMSession*)NULL);
+ if(session)
+ {
+ mOtherParticipantUUID = session->mOtherParticipantID;
+ im_control_panel->setAvatarId(session->mOtherParticipantID);
+ }
+
+ LLButton* slide_left = getChild<LLButton>("slide_left_btn");
+ slide_left->setVisible(im_control_panel->getVisible());
+ slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
+
+ LLButton* slide_right = getChild<LLButton>("slide_right_btn");
+ slide_right->setVisible(!im_control_panel->getVisible());
+ slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
+
setTitle(title);
+ setDocked(true);
+
+ mInputEditor = getChild<LLLineEditor>("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);
+}
+
+/* static */
+void LLIMFloater::newIMCallback(const LLSD& data){
+
+ if (data["num_unread"].asInteger() > 0)
+ {
+ LLUUID session_id = data["session_id"].asUUID();
+
+ LLIMFloater* floater = get_if_there(sIMFloaterMap, session_id, (LLIMFloater*)NULL);
+
+ 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()
{
sIMFloaterMap.erase(mSessionID);
}
+//virtual
+BOOL LLIMFloater::postBuild()
+{
+ mHistoryEditor = getChild<LLViewerTextEditor>("im_text", true, false);
+ mChiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(mSessionID);
+
+ if (!mChiclet)
+ {
+ llwarns << "No chiclet found for the IMFloter" << llendl;
+ }
+ setDocked(false);
+ return TRUE;
+}
+
+const U32 UNDOCK_LEAP_HEIGHT = 12;
+const U32 DOCK_ICON_HEIGHT = 6;
-void LLIMFloater::show(const LLUUID& session_id, S32 center_x)
+//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);
+ mChiclet->setDockTongueVisible(docked);
+ if (docked)
+ {
+ S32 x, y;
+ mChiclet->localPointToScreen((mChiclet->getRect().getWidth())/2, 0, &x, &y);
+ translate(x - getRect().getCenterX(), DOCK_ICON_HEIGHT - getRect().mBottom);
+ }
+ else if (pop_on_undock)
+ {
+ // visually pop up a little bit to emphasize the undocking
+ translate(0, UNDOCK_LEAP_HEIGHT);
+ }
+}
+
+
+void LLIMFloater::onClose(bool app_quitting)
+{
+ mChiclet->setDockTongueVisible(false);
+ LLFloater::onClose(app_quitting);
+}
+
+void LLIMFloater::onSlide()
+{
+ LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel");
+ im_control_panel->setVisible(!im_control_panel->getVisible());
+
+ getChild<LLButton>("slide_left_btn")->setVisible(im_control_panel->getVisible());
+ getChild<LLButton>("slide_right_btn")->setVisible(!im_control_panel->getVisible());
+}
+
+//static
+LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
+{
LLIMFloater* floater = get_if_there(sIMFloaterMap, session_id, (LLIMFloater*)NULL);
if (floater == NULL)
@@ -2078,28 +2243,25 @@ void LLIMFloater::show(const LLUUID& session_id, S32 center_x)
{
LLIMFloater* floater = (*iter).second;
floater->setVisible(false);
+ floater->mChiclet->setDockTongueVisible(false);
+
}
- //floater->setVisibleAndFrontmost(true);
+ floater->setVisibleAndFrontmost(true);
- floater->updateMessages(session_id);
-
- floater->translate(center_x - floater->getRect().getCenterX(), gFloaterView->getRect().mBottom - floater->getRect().mBottom);
+ if (floater->isDocked())
+ {
+ floater->mChiclet->setDockTongueVisible(true);
+ }
+ floater->updateMessages();
+ return floater;
}
-void LLIMFloater::updateMessages(const LLUUID& session_id)
+void LLIMFloater::updateMessages()
{
- LLTextEditor* text_editor = getChild<LLTextEditor>("im_text", true, false);
-
- if (!text_editor)
- {
- llwarns << "Text editor not found! " << llendl;
- return;
- }
-
- std::list<LLSD> messages = LLIMModel::instance().getMessages(mSessionID, mIndex);
+ std::list<LLSD> messages = LLIMModel::instance().getMessages(mSessionID, mLastMessageIndex+1);
if (messages.size())
{
@@ -2112,10 +2274,45 @@ void LLIMFloater::updateMessages(const LLUUID& session_id)
message << msg["from"].asString() << " : " << msg["time"].asString() << "\n " << msg["message"].asString() << "\n";
- mIndex = msg["index"].asInteger();
+ mLastMessageIndex = msg["index"].asInteger();
}
- text_editor->setText(message.str());
+ 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)
+{
+}
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index 88f21864b5..e6bde5c93a 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -47,6 +47,7 @@ class LLInventoryItem;
class LLInventoryCategory;
class LLIMSpeakerMgr;
class LLPanelActiveSpeakers;
+class LLIMChiclet;
class LLVoiceChannel : public LLVoiceClientStatusObserver
{
@@ -359,6 +360,8 @@ private:
};
+// Individual IM window that appears at the bottom of the screen,
+// optionally "docked" to the bottom tray.
class LLIMFloater : public LLFloater
{
public:
@@ -367,14 +370,49 @@ public:
EInstantMessage dialog);
virtual ~LLIMFloater();
+
+ // LLView overrides
+ /*virtual*/ BOOL postBuild();
+
+ // 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);
+ void onClose(bool app_quitting);
- static void show(const LLUUID& session_id, S32 center_x);
- void updateMessages(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);
+
static std::map<LLUUID, LLIMFloater*> sIMFloaterMap;
+
+
+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;
- U32 mIndex;
+ S32 mLastMessageIndex;
+ EInstantMessage mDialog;
+ LLIMChiclet* mChiclet;
+ LLUUID mOtherParticipantUUID;
+ LLViewerTextEditor* mHistoryEditor;
+ LLLineEditor* mInputEditor;
+
};
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 38335fe68f..0505baac41 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -113,14 +113,16 @@ void toast_callback(const LLSD& msg){
LLIMModel::LLIMModel()
{
addChangedCallback(toast_callback);
+ addChangedCallback(LLIMFloater::newIMCallback);
}
void LLIMModel::testMessages()
{
- static LLUUID bot1_id, bot1_session_id;
- if (bot1_id.isNull()) bot1_id.generate();
- std::string from = "Bot1 TestLinden";
+ 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!");
@@ -158,7 +160,7 @@ bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage
}
-std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int index)
+std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
{
std::list<LLSD> return_list;
@@ -170,7 +172,7 @@ std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int index)
return return_list;
}
- int i = session->mMsgs.size() - index;
+ int i = session->mMsgs.size() - start_index;
for (std::list<LLSD>::iterator iter = session->mMsgs.begin();
iter != session->mMsgs.end() && i > 0;
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 6a354dfe92..b3b821f2ac 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -53,11 +53,11 @@ public:
struct LLIMSession
{
LLIMSession(std::string name, EInstantMessage type, LLUUID other_participant_id)
- :mName(name), mType(type), mNumUnread(0), mOtherPraticipantID(other_participant_id) {}
+ :mName(name), mType(type), mNumUnread(0), mOtherParticipantID(other_participant_id) {}
std::string mName;
EInstantMessage mType;
- LLUUID mOtherPraticipantID;
+ LLUUID mOtherParticipantID;
S32 mNumUnread;
std::list<LLSD> mMsgs;
};
@@ -70,7 +70,7 @@ public:
boost::signals2::connection addChangedCallback( boost::function<void (const LLSD& data)> cb );
bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id);
- std::list<LLSD> getMessages(LLUUID session_id, int index = 0);
+ std::list<LLSD> 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
diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp
index 0c652621f4..cfcb331912 100644
--- a/indra/newview/llmenucommands.cpp
+++ b/indra/newview/llmenucommands.cpp
@@ -51,6 +51,7 @@
#include "llfloaterworldmap.h"
#include "llgivemoney.h"
#include "llfloaterinventory.h"
+#include "lllineeditor.h"
#include "llnotify.h"
#include "llstatusbar.h"
#include "llimview.h"
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<bool> is_group;
Optional<LLUUID> 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 d7066cb140..ffc3b2f37a 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -169,7 +169,7 @@ LLScrollListItem* LLNameListCtrl::addRow(const LLNameListCtrl::NameItem& name_it
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 6692d4cff9..80feaea881 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -57,11 +57,11 @@ public:
struct NameItem : public LLInitParam::Block<NameItem, LLScrollListItem::Params>
{
- Optional<std::string> display_name;
+ Optional<std::string> name;
Optional<ENameType, NameTypeNames> target;
NameItem()
- : display_name("name"),
+ : name("name"),
target("target", INDIVIDUAL)
{}
};
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index fbeff2d628..c0bddd101e 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -45,6 +45,7 @@
#include "lllocationhistory.h"
#include "lllocationinputctrl.h"
#include "llteleporthistory.h"
+#include "llsearcheditor.h"
#include "llslurl.h"
#include "llurlsimstring.h"
#include "llviewerinventory.h"
@@ -204,12 +205,10 @@ BOOL LLNavigationBar::postBuild()
mBtnHelp = getChild<LLButton>("help_btn");
mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");
- mLeSearch = getChild<LLLineEditor>("search_input");
-
- LLButton* search_btn = getChild<LLButton>("search_btn");
+ mLeSearch = getChild<LLSearchEditor>("search_input");
if (!mBtnBack || !mBtnForward || !mBtnHome || !mBtnHelp ||
- !mCmbLocation || !mLeSearch || !search_btn)
+ !mCmbLocation || !mLeSearch)
{
llwarns << "Malformed navigation bar" << llendl;
return FALSE;
@@ -229,7 +228,6 @@ BOOL LLNavigationBar::postBuild()
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<LLMenuGL>("menu_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
@@ -306,7 +304,7 @@ void LLNavigationBar::onHelpButtonClicked()
void LLNavigationBar::onSearchCommit()
{
- invokeSearch(mLeSearch->getText());
+ invokeSearch(mLeSearch->getValue().asString());
}
void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 846040e506..a82dfc73ff 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.
@@ -97,7 +97,7 @@ private:
LLButton* mBtnForward;
LLButton* mBtnHome;
LLButton* mBtnHelp;
- LLLineEditor* mLeSearch;
+ LLSearchEditor* mLeSearch;
LLLocationInputCtrl* mCmbLocation;
bool mPurgeTPHistoryItems;
};
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 340cb8187d..955f50caf5 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -52,7 +52,8 @@ LLColor4 LLOutputMonitorCtrl::sColorBound;
//F32 LLOutputMonitorCtrl::sRectHeightRatio = 0.f;
LLOutputMonitorCtrl::Params::Params()
-: image_mute("image_mute"),
+: draw_border("draw_border"),
+ image_mute("image_mute"),
image_off("image_off"),
image_on("image_on"),
image_level_1("image_level_1"),
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 868d4d9200..bf6ecd6bf4 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -61,6 +61,7 @@ public:
{
Optional<LLUUID> agent_id;
Params()
+ : agent_id("agent_id")
{
mouse_opaque(false);
follows.flags(FOLLOWS_ALL);
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<LLPanelIMControlPanel> 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<LLAvatarIconCtrl>("avatar_icon")->getAvatarId());
+}
+
+void LLPanelIMControlPanel::onAddFriendButtonClicked()
+{
+ LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("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<LLAvatarIconCtrl>("avatar_icon")->setValue(avatar_id);
+}
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
new file mode 100644
index 0000000000..be3b2d3130
--- /dev/null
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -0,0 +1,55 @@
+/**
+ * @file llpanelimcontrolpanel.h
+ * @brief LLPanelIMControlPanel and related class definitions
+ *
+ * $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_LLPANELIMCONTROLPANEL_H
+#define LL_LLPANELIMCONTROLPANEL_H
+
+#include "llpanel.h"
+
+class LLPanelIMControlPanel : public LLPanel
+{
+public:
+ LLPanelIMControlPanel();
+ ~LLPanelIMControlPanel();
+
+ BOOL postBuild();
+
+ void setAvatarId(const LLUUID& avatar_id);
+
+private:
+ void onViewProfileButtonClicked();
+ void onAddFriendButtonClicked();
+ void onCallButtonClicked();
+ void onShareButtonClicked();
+};
+
+#endif // LL_LLPANELIMCONTROLPANEL_H
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 453183ad74..0cbf10f7c2 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -33,6 +33,7 @@
#include "llpanellandmarks.h"
+#include "llbutton.h"
#include "llfloaterreg.h"
#include "lllandmark.h"
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 d2879a675f..d947003109 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"
@@ -306,7 +306,7 @@ public:
LLPanelPeople::LLPanelPeople()
: LLPanel(),
mFilterSubString(LLStringUtil::null),
- mSearchEditor(NULL),
+ mFilterEditor(NULL),
mTabContainer(NULL),
mFriendList(NULL),
mNearbyList(NULL),
@@ -330,8 +330,8 @@ LLPanelPeople::~LLPanelPeople()
BOOL LLPanelPeople::postBuild()
{
- mSearchEditor = getChild<LLSearchEditor>("filter_input");
- mSearchEditor->setSearchCallback(boost::bind(&LLPanelPeople::onSearchEdit, this, _1));
+ mFilterEditor = getChild<LLFilterEditor>("filter_input");
+ mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
mTabContainer = getChild<LLTabContainer>("tabs");
mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2));
@@ -609,7 +609,7 @@ void LLPanelPeople::reSelectedCurrentTab()
mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex());
}
-void LLPanelPeople::onSearchEdit(const std::string& search_string)
+void LLPanelPeople::onFilterEdit(const std::string& search_string)
{
if (mFilterSubString == search_string)
return;
@@ -618,7 +618,7 @@ void LLPanelPeople::onSearchEdit(const std::string& search_string)
LLStringUtil::toUpper(mFilterSubString);
LLStringUtil::trimHead(mFilterSubString);
- mSearchEditor->setText(mFilterSubString);
+ mFilterEditor->setText(mFilterSubString);
// Apply new filter to all tabs.
filterNearbyList();
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 1131790106..6c3b5e0664 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;
@@ -77,7 +77,7 @@ private:
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();
@@ -104,7 +104,7 @@ private:
const std::vector<LLUUID>& ids,
void*);
- LLSearchEditor* mSearchEditor;
+ LLFilterEditor* mFilterEditor;
LLTabContainer* mTabContainer;
LLAvatarList* mFriendList;
LLAvatarList* mNearbyList;
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 961c54d667..cda1a9e7e7 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -38,6 +38,7 @@
#include "llpanel.h"
#include "message.h"
#include "llagent.h"
+#include "llbutton.h"
#include "llparcel.h"
#include "llviewerparcelmgr.h"
#include "lltexturectrl.h"
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index c162a9ba33..57c633dd74 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -32,7 +32,7 @@
#include "llviewerprecompiledheaders.h"
#include "llfloaterreg.h"
-#include "llsearcheditor.h"
+#include "llfiltereditor.h"
#include "lltabcontainer.h"
#include "lluictrlfactory.h"
@@ -67,7 +67,7 @@ LLPanelPlaces::LLPanelPlaces()
: LLPanel(),
mFilterSubString(LLStringUtil::null),
mActivePanel(NULL),
- mSearchEditor(NULL),
+ mFilterEditor(NULL),
mPlaceInfo(NULL)
{
gInventory.addObserver(this);
@@ -92,10 +92,10 @@ BOOL LLPanelPlaces::postBuild()
mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this));
}
- mSearchEditor = getChild<LLSearchEditor>("Filter");
- if (mSearchEditor)
+ mFilterEditor = getChild<LLFilterEditor>("Filter");
+ if (mFilterEditor)
{
- mSearchEditor->setSearchCallback(boost::bind(&LLPanelPlaces::onSearchEdit, this, _1));
+ mFilterEditor->setCommitCallback(boost::bind(&LLPanelPlaces::onFilterEdit, this, _2));
}
mPlaceInfo = getChild<LLPanelPlaceInfo>("panel_place_info", TRUE, FALSE);
@@ -187,7 +187,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
}
}
-void LLPanelPlaces::onSearchEdit(const std::string& search_string)
+void LLPanelPlaces::onFilterEdit(const std::string& search_string)
{
if (mFilterSubString != search_string)
{
@@ -196,7 +196,7 @@ void LLPanelPlaces::onSearchEdit(const std::string& search_string)
LLStringUtil::toUpper(mFilterSubString);
LLStringUtil::trimHead(mFilterSubString);
- mSearchEditor->setText(mFilterSubString);
+ mFilterEditor->setText(mFilterSubString);
mActivePanel->onSearchEdit(mFilterSubString);
}
@@ -208,7 +208,7 @@ void LLPanelPlaces::onTabSelected()
if (!mActivePanel)
return;
- onSearchEdit(mFilterSubString);
+ onFilterEdit(mFilterSubString);
mActivePanel->updateVerbs();
}
@@ -274,7 +274,7 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
return;
mPlaceInfo->setVisible(visible);
- mSearchEditor->setVisible(!visible);
+ mFilterEditor->setVisible(!visible);
mTabContainer->setVisible(!visible);
// Enable overflow button only for the information about agent's current location.
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 6fbb7562c9..e2ba4f39cd 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -42,7 +42,7 @@
#include "llpanelplaceinfo.h"
class LLPanelPlacesTab;
-class LLSearchEditor;
+class LLFilterEditor;
class LLTabContainer;
class LLPanelPlaces : public LLPanel, LLInventoryObserver
@@ -55,7 +55,7 @@ public:
/*virtual*/ void changed(U32 mask);
/*virtual*/ void onOpen(const LLSD& key);
- void onSearchEdit(const std::string& search_string);
+ void onFilterEdit(const std::string& search_string);
void onTabSelected();
//void onAddLandmarkButtonClicked();
//void onCopySLURLButtonClicked();
@@ -68,7 +68,7 @@ public:
void onAgentParcelChange();
private:
- LLSearchEditor* mSearchEditor;
+ LLFilterEditor* mFilterEditor;
LLPanelPlacesTab* mActivePanel;
LLTabContainer* mTabContainer;
LLPanelPlaceInfo* mPlaceInfo;
diff --git a/indra/newview/llpanelplacestab.cpp b/indra/newview/llpanelplacestab.cpp
index dc9119d2e3..e5b1f04064 100644
--- a/indra/newview/llpanelplacestab.cpp
+++ b/indra/newview/llpanelplacestab.cpp
@@ -31,12 +31,14 @@
#include "llviewerprecompiledheaders.h"
+#include "llpanelplacestab.h"
+
#include "llwindow.h"
#include "llnotifications.h"
+#include "llbutton.h"
#include "llslurl.h"
-#include "llpanelplacestab.h"
#include "llworldmap.h"
void LLPanelPlacesTab::setPanelPlacesButtons(LLPanelPlaces* panel)
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 37262b736e..abcff7cfb1 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -118,7 +118,7 @@ LLSideTrayTab::LLSideTrayTab(const Params& params):mAccordionCtrl(0)
{
mImagePath = params.image_path;
mTabTitle = params.tab_title;
- mDescription = params.tab_description;
+ mDescription = params.description;
}
LLSideTrayTab::~LLSideTrayTab()
{
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
index 7487c71bfc..7b1f4aee04 100644
--- a/indra/newview/llsidetray.h
+++ b/indra/newview/llsidetray.h
@@ -51,10 +51,11 @@ public:
// image name
Optional<std::string> image_path;
Optional<std::string> tab_title;
- Optional<std::string> tab_description;
- Params():image_path("image","")
- ,tab_title("tab_title","no title")
- ,tab_description("description","no description")
+ Optional<std::string> description;
+ Params()
+ : image_path("image"),
+ tab_title("tab_title","no title"),
+ description("description","no description")
{};
};
protected:
@@ -109,14 +110,14 @@ public:
Optional<S32> default_button_height;
Optional<S32> 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 ();
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 211a441d64..d792b972bb 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -60,7 +60,7 @@
#include "llscrollcontainer.h"
#include "lltoolmgr.h"
#include "lltoolpipette.h"
-#include "llsearcheditor.h"
+#include "llfiltereditor.h"
#include "lltool.h"
#include "llviewerwindow.h"
@@ -130,7 +130,7 @@ public:
void updateFilterPermMask();
void commitIfImmediateSet();
- void onSearchEdit(const std::string& search_string );
+ void onFilterEdit(const std::string& search_string );
static void onBtnSetToDefault( void* userdata );
static void onBtnSelect( void* userdata );
@@ -164,7 +164,7 @@ protected:
std::string mPendingName;
BOOL mActive;
- LLSearchEditor* mSearchEdit;
+ LLFilterEditor* mFilterEdit;
LLInventoryPanel* mInventoryPanel;
PermissionMask mImmediateFilterPermMask;
PermissionMask mNonImmediateFilterPermMask;
@@ -191,7 +191,7 @@ 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)
@@ -335,9 +335,9 @@ 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)
{
@@ -362,7 +362,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
if (mInventoryPanel->hasFocus() && key == KEY_UP)
{
- mSearchEdit->focusFirstItem(TRUE);
+ mFilterEdit->focusFirstItem(TRUE);
}
}
@@ -404,8 +404,8 @@ BOOL LLFloaterTexturePicker::postBuild()
childSetCommitCallback("show_folders_check", onShowFolders, this);
childSetVisible("show_folders_check", FALSE);
- mSearchEdit = getChild<LLSearchEditor>("inventory search editor");
- mSearchEdit->setSearchCallback(boost::bind(&LLFloaterTexturePicker::onSearchEdit, this, _1));
+ mFilterEdit = getChild<LLFilterEditor>("inventory search editor");
+ mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2));
mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
@@ -524,7 +524,7 @@ void LLFloaterTexturePicker::draw()
childSetValue("Pipette", LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
//RN: reset search bar to reflect actual search query (all caps, for example)
- mSearchEdit->setText(mInventoryPanel->getFilterSubString());
+ mFilterEdit->setText(mInventoryPanel->getFilterSubString());
//BOOL allow_copy = FALSE;
if( mOwner )
@@ -797,7 +797,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);
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index e30cdb2e97..0b232da62b 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -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"),
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 954418f7fb..9144f9c3e0 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -32,9 +32,11 @@
#include "llviewerprecompiledheaders.h" // must be first include
-#include "llfocusmgr.h"
#include "lltoast.h"
+#include "llbutton.h"
+#include "llfocusmgr.h"
+
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index c43618d330..a7b57802c1 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -174,7 +174,7 @@ LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification) : LLToas
params.max_text_length(MAX_LENGTH);
params.default_text(mMessage);
params.font(sFont);
- params.allow_embedded_items(false);
+ params.embedded_items(false);
params.word_wrap(true);
params.tab_stop(false);
params.mouse_opaque(false);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 8f1b105ba6..74ded99124 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1719,7 +1719,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.
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 24479485ef..3e86f48cc5 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -107,6 +107,7 @@
#include "llfloatertools.h"
#include "llfloaterworldmap.h"
#include "llfocusmgr.h"
+#include "llfontfreetype.h"
#include "llgesturemgr.h"
#include "llglheaders.h"
#include "llhoverview.h"
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 7703211c3d..dc5936a435 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -1,4 +1,5 @@
<textures version="101">
+ <!-- Please add new files alphabetically to prevent merge conflicts. JC -->
<texture name="ScrollThumb_Horiz" file_name="widgets/ScrollThumb_Horiz.png" preload="true" scale.left="4" scale.top="10" scale.bottom="53" scale.right="4" />
<texture name="ScrollThumb_Vert" file_name="widgets/ScrollThumb_Vert.png" preload="true" scale.left="4" scale.top="53" scale.bottom="10" scale.right="4" />
@@ -469,7 +470,6 @@
<texture name="Icon_Gear_Background" file_name="windows/Icon_Gear_Background.png" preload="true"/>
<texture name="Icon_Gear_Foreground" file_name="windows/Icon_Gear_Foreground.png" preload="true"/>
<texture name="Icon_Gear_Press" file_name="windows/Icon_Gear_Press.png" preload="true"/>
-
<texture name="Stepper_Down_Disabled" file_name="widgets/Stepper_Down_Disabled.png" preload="true"/>
<texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="true"/>
<texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="true"/>
@@ -477,4 +477,5 @@
<texture name="Stepper_Up_Off" file_name="widgets/Stepper_Up_Off.png" preload="true"/>
<texture name="Stepper_Up_Press" file_name="widgets/Stepper_Up_Press.png" preload="true"/>
+ <!-- Please add new files alphabetically to prevent merge conflicts. JC -->
</textures>
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 1fb0942461..cb3388ccbc 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1147,7 +1147,7 @@ Go to World menu &gt; About Land or select another parcel to show its details.
name="online_status"
width="-1" />
<name_list.columns
- dynamicwidth="true"
+ dynamic_width="true"
label="Name"
name="name" />
<name_list.columns
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 0856a787f3..44c56e4207 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -2,25 +2,66 @@
<floater
background_visible="true"
follows="left|top|right|bottom"
- height="200"
+ height="250"
layout="topleft"
left="0"
name="panel_im"
top="0"
+ can_dock="true"
+ can_minimize="false"
visible="false"
- width="300">
- <text_editor
- enabled="false"
- type="string"
- length="1"
- top="20"
- follows="left|top|right"
- font="SansSerif"
- height="175"
- layout="topleft"
- left="5"
- name="im_text"
- width="290"
- word_wrap="true">
- </text_editor>
+ width="315">
+ <layout_stack follows="left|top|right|bottom"
+ height="235"
+ width="315"
+ layout="topleft"
+ orientation="horizontal"
+ name="im_panels"
+ top="16"
+ left="2">
+ <layout_panel
+ class="panel_im_control_panel"
+ name="panel_im_control_panel"
+ filename="panel_im_control_panel.xml"
+ layout="topleft"
+ top_delta="-3"
+ min_width="96"
+ width="96"
+ height="225"
+ label="IM Control Panel"
+ user_resize="false" />
+ <layout_panel height="235"
+ width="200"
+ left_delta="96"
+ top="0"
+ user_resize="false">
+ <button height="12"
+ top="8"
+ label="&lt;&lt;"
+ layout="topleft"
+ width="35"
+ name="slide_left_btn" />
+ <button height="12"
+ top="8"
+ label="&gt;&gt;"
+ layout="topleft"
+ width="35"
+ name="slide_right_btn" />
+ <text_editor
+ enabled="false"
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="185"
+ layout="topleft"
+ max_length="2147483647"
+ name="im_text"
+ width="195"
+ word_wrap="true">
+ </text_editor>
+ <line_editor name="chat_editor" height="20" layout="topleft" width="190">
+ </line_editor>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inspect.xml b/indra/newview/skins/default/xui/en/floater_inspect.xml
index b11b3e4df5..b43cdca0d1 100644
--- a/indra/newview/skins/default/xui/en/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/en/floater_inspect.xml
@@ -25,15 +25,15 @@
tool_tip="Select an object from this list to highlight it in-world"
top="20">
<scroll_list.columns
- dynamicwidth="true"
+ dynamic_width="true"
label="Object Name"
name="object_name" />
<scroll_list.columns
- dynamicwidth="true"
+ dynamic_width="true"
label="Owner Name"
name="owner_name" />
<scroll_list.columns
- dynamicwidth="true"
+ dynamic_width="true"
label="Creator Name"
name="creator_name" />
<scroll_list.columns
diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml
index eb05fe1883..6a54c187cb 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory.xml
@@ -23,7 +23,7 @@
name="Fetched">
Fetched
</floater.string>
- <search_editor
+ <filter_editor
follows="left|top|right"
height="16"
label="Type here to search"
diff --git a/indra/newview/skins/default/xui/en/floater_test_widgets.xml b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
index c6b158fe6f..c6c561b497 100644
--- a/indra/newview/skins/default/xui/en/floater_test_widgets.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
@@ -156,9 +156,9 @@
width="200">
Line Editor Sample Text
</line_editor>
- <!-- "search_editor" is a specialized line_editor that shows read-only
+ <!-- "filter_editor" is a specialized line_editor that shows read-only
help text until the user clicks in the widget. -->
- <search_editor
+ <filter_editor
follows="left|top|right"
height="20"
label="Type here to search"
@@ -230,11 +230,11 @@
tool_tip="scroll list"
layout="topleft">
<scroll_list.columns
- dynamicwidth="true"
+ dynamic_width="true"
name="first_column"
label="Column A"/>
<scroll_list.columns
- dynamicwidth="true"
+ dynamic_width="true"
name="second_column"
label="Column B"/>
</scroll_list>
diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
index 8d85519610..dc048eb352 100644
--- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
@@ -86,7 +86,7 @@
name="show_folders_check"
top="20"
width="201" />
- <search_editor
+ <filter_editor
follows="left|top|right"
height="16"
label="Type here to search"
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 6934fad495..bbb17dfb8f 100644
--- a/indra/newview/skins/default/xui/en/floater_ui_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
@@ -163,6 +163,15 @@
tool_tip="Closes the currently-displayed floater, if one exists"
top_delta="0"
width="85" />
+ <button
+ follows="left|top"
+ height="25"
+ label="Export Schema"
+ layout="topleft"
+ left_pad="10"
+ name="export_schema"
+ top_delta="0"
+ width="120" />
<scroll_list
bottom="525"
column_padding="0"
@@ -185,7 +194,7 @@
name="file_column"
width="150" />
<scroll_list.columns
- dynamicwidth="true"
+ dynamic_width="true"
label="Top-Level Node"
name="top_level_node_column" />
</scroll_list>
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 7ac068df4b..bbef5a8892 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -13,6 +13,7 @@
width="1000">
<layout_stack
border_size="0"
+ clip="false"
follows="left|right|bottom|top"
height="28"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_friends.xml b/indra/newview/skins/default/xui/en/panel_friends.xml
index a151eed20f..3a35465df2 100644
--- a/indra/newview/skins/default/xui/en/panel_friends.xml
+++ b/indra/newview/skins/default/xui/en/panel_friends.xml
@@ -29,7 +29,7 @@
tool_tip="Online status"
width="20" />
<scroll_list.columns
- dynamicwidth="true"
+ dynamic_width="true"
label="Name"
name="friend_name"
tool_tip="Name" />
diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
new file mode 100644
index 0000000000..5067b4c1d8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="panel_im_control_panel"
+ width="96"
+ height="215"
+ border="false">
+
+ <avatar_icon name="avatar_icon"
+ width="96"
+ height="96" />
+
+ <button name="view_profile_btn"
+ label="View Profile"
+ left_delta="3"
+ width="90"
+ height="20" />
+
+ <button name="add_friend_btn"
+ label="Add Friend"
+ width="90"
+ height="20" />
+
+ <button name="call_btn"
+ label="Call"
+ width="90"
+ height="20" />
+
+ <button name="share_btn"
+ label="Share"
+ width="90"
+ height="20" />
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 9d4c411201..c9a0b6bc38 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -101,37 +101,21 @@
<!-- top_delta="0" -->
<!-- width="168" /> -->
- <button
- follows="right|top"
- height="16"
- image_disabled="Search"
- image_disabled_selected="Search"
- image_selected="Search"
- image_unselected="Search"
- layout="topleft"
- left_pad="5"
- name="search_btn"
- picture_style="true"
- scale_image="false"
- tool_tip="Search"
- top_delta="2"
- width="16" />
-
- <line_editor
+ <search_editor
bevel_style="none"
border_style="line"
border.border_thickness="0"
commit_on_focus_lost="false"
follows="right|top"
halign="right"
- height="18"
+ height="20"
label="Search All"
layout="topleft"
- left_pad="2"
+ left_pad="5"
mouse_opaque="false"
name="search_input"
tool_tip="Search All"
- top_delta="-1"
+ top_delta="0"
width="135" />
<button
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 4fc47d1c42..29f5d3aee8 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -7,9 +7,10 @@
height="465"
follows="left|top|right|bottom"
background_visible="true"
+ bg_alpha_color="0.3 0.3 0.3 1"
label="People"
name="people_panel">
- <search_editor
+ <filter_editor
layout="topleft"
top="3"
left="15"
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index 61b0ac9b72..c91cb2394c 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -19,7 +19,7 @@
name="teleport_history_tab_title">
Teleport History
</panel.string>
- <search_editor
+ <filter_editor
follows="left|top|right"
height="20"
label="Filter"
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
index 330bc362d2..05ebcbb50b 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
@@ -6,7 +6,7 @@
multi_select="false" name="history_items" search_column="1"
sort_column="1" height="326" width="380" >
<column name="landmark_icon" width="20" />
- <column dynamicwidth="true" label="Region" name="region" />
+ <column dynamic_width="true" label="Region" name="region" />
<column name="index" width="0" />
</scroll_list>
</panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index c6ee2ce364..149da313a2 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -82,6 +82,8 @@
<string name="BUTTON_MINIMIZE">Minimize</string>
<string name="BUTTON_TEAR_OFF">Tear Off</string>
<string name="BUTTON_EDIT">Edit</string>
+ <string name="BUTTON_DOCK">Dock</string>
+ <string name="BUTTON_UNDOCK">Undock</string>
<!-- searching - generic -->
<string name="Searching">Searching...</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
new file mode 100644
index 0000000000..f77aa396ec
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<filter_editor select_on_focus="true"
+ background="TextField_Search_Off" >
+ <clear_filter_button label=""
+ image_unselected="Icon_Close_Foreground"
+ image_selected="Icon_Close_Press" />
+</filter_editor>
diff --git a/indra/newview/skins/default/xui/en/widgets/line_editor.xml b/indra/newview/skins/default/xui/en/widgets/line_editor.xml
index 168609d5d7..08205cacbc 100644
--- a/indra/newview/skins/default/xui/en/widgets/line_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/line_editor.xml
@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<line_editor background_image="TextField_Off"
+<line_editor
+ background_image="TextField_Off"
+ background_image_disabled="TextField_Disabled"
+ background_image_focused="TextField_Active"
select_on_focus="false"
handle_edit_keys_directly="false"
commit_on_focus_lost="true"
@@ -8,9 +11,8 @@
text_color="TextFgColor"
text_readonly_color="Green"
text_tentative_color="TextFgTentativeColor"
- bg_readonly_color="TextBgReadOnlyColor"
- bg_writeable_color="TextBgWriteableColor"
- bg_focus_color="TextBgFocusColor"
+ highlight_color="EmphasisColor"
+ preedit_bg_color="White"
mouse_opaque="true"
name="line_editor"
font="SansSerifSmall">
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
index 9e2c52acca..e3a53eee4d 100644
--- a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
@@ -4,7 +4,7 @@
bg_selected_color="ScrollSelectedBGColor"
fg_disable_color="ScrollDisabledColor"
bg_writeable_color="ScrollBgWriteableColor"
- bg_read_only_color="ScrollBgReadOnlyColor"
+ bg_readonly_color="ScrollBgReadOnlyColor"
bg_stripe_color="ScrollBGStripeColor"
hovered_color="ScrollHoveredColor"
highlighted_color="ScrollHighlightedColor"
diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
index 67588d76ca..6f557e239d 100644
--- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
@@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<search_editor select_on_focus="true">
- <clear_search_button image_unselected="TextField_Search_Off"
- image_selected="TextField_Search_Active"
- image_disabled="TextField_Search_Disabled"
- image_color="TextFgTentativeColor"/>
+<search_editor
+ select_on_focus="true"
+ background_image="TextField_Search_Off"
+ background_image_disabled="TextField_Search_Disabled"
+ background_image_focused="TextField_Search_Active" >
+ <search_button label=""
+ image_unselected="Search"
+ image_selected="Search" />
</search_editor>
diff --git a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
index b39c2991a0..960c4e81e5 100644
--- a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
@@ -1,11 +1,23 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<simple_text_editor cursor_color="TextCursorColor"
- default_color="TextDefaultColor"
- text_color="TextFgColor"
- text_readonly_color="TextFgReadOnlyColor"
- bg_readonly_color="TextBgReadOnlyColor"
- bg_writeable_color="TextBgWriteableColor"
- bg_focus_color="TextBgFocusColor"
- hide_border="true"
- hide_scrollbar="false"
- font="SansSerif"/>
+<simple_text_editor
+ mouse_opaque="true"
+ font="SansSerifSmall"
+ max_length="255"
+ embedded_items="false"
+ hide_scrollbar="false"
+ hide_border="true"
+ word_wrap="false"
+ ignore_tab="true"
+ track_bottom="false"
+ takes_non_scroll_clicks="true"
+ cursor_color="TextCursorColor"
+ default_color="TextDefaultColor"
+ text_color="TextFgColor"
+ text_readonly_color="TextFgReadOnlyColor"
+ bg_readonly_color="TextBgReadOnlyColor"
+ bg_writeable_color="TextBgWriteableColor"
+ bg_focus_color="TextBgFocusColor">
+ <simple_text_editor.border
+ bevel_style="in"
+ follows="all" />
+</simple_text_editor>
diff --git a/indra/newview/skins/default/xui/en/widgets/text_editor.xml b/indra/newview/skins/default/xui/en/widgets/text_editor.xml
index a613c43f90..deaade04f8 100644
--- a/indra/newview/skins/default/xui/en/widgets/text_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/text_editor.xml
@@ -1,19 +1,4 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<line_editor background_image="TextField_Off"
- select_on_focus="false"
- handle_edit_keys_directly="false"
- commit_on_focus_lost="true"
- ignore_tab="true"
- cursor_color="TextCursorColor"
- text_color="TextFgColor"
- text_readonly_color="TextFgReadOnlyColor"
- text_tentative_color="TextFgTentativeColor"
- bg_readonly_color="TextBgReadOnlyColor"
- bg_writeable_color="TextBgWriteableColor"
- bg_focus_color="TextBgFocusColor"
- mouse_opaque="true"
- name="line_editor"
- font="SansSerifSmall">
- <line_editor.border bevel_style="in"
- follows="all" />
-</line_editor>
+<!-- Core parameters are in simple_text_editor.xml -->
+<text_editor
+ allow_html="false" />