diff options
Diffstat (limited to 'indra/llui')
91 files changed, 2534 insertions, 1300 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index a6a5ef1f92..269c02263d 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -37,6 +37,7 @@ set(llui_SOURCE_FILES lldraghandle.cpp
lleditmenuhandler.cpp
llf32uictrl.cpp
+ llfiltereditor.cpp
llfloater.cpp
llfloaterreg.cpp
llflyoutbutton.cpp
@@ -60,6 +61,7 @@ set(llui_SOURCE_FILES llresizebar.cpp
llresizehandle.cpp
llresmgr.cpp
+ llrngwriter.cpp
llscrollbar.cpp
llscrollcontainer.cpp
llscrollingpanellist.cpp
@@ -68,7 +70,7 @@ set(llui_SOURCE_FILES llscrolllistctrl.cpp
llscrolllistitem.cpp
llsdparam.cpp
- llsearcheditor.cpp
+ llsearcheditor.cpp
llslider.cpp
llsliderctrl.cpp
llspinctrl.cpp
@@ -82,6 +84,7 @@ set(llui_SOURCE_FILES lltextparser.cpp
lltrans.cpp
llui.cpp
+ lluicolor.cpp
lluicolortable.cpp
lluictrl.cpp
lluictrlfactory.cpp
@@ -109,11 +112,13 @@ set(llui_HEADER_FILES lldraghandle.h
lleditmenuhandler.h
llf32uictrl.h
+ llfiltereditor.h
llfloater.h
llfloaterreg.h
llflyoutbutton.h
llfocusmgr.h
llfunctorregistry.h
+ llhandle.h
llhtmlhelp.h
lliconctrl.h
llinitparam.h
@@ -135,6 +140,7 @@ set(llui_HEADER_FILES llresizebar.h
llresizehandle.h
llresmgr.h
+ llrngwriter.h
llsearcheditor.h
llscrollbar.h
llscrollcontainer.h
@@ -156,6 +162,7 @@ set(llui_HEADER_FILES lltexteditor.h
lltextparser.h
lltrans.h
+ lluicolor.h
lluicolortable.h
lluiconstants.h
lluictrlfactory.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index f2aa9c0d4c..fc3af34951 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -32,7 +32,6 @@ #include "linden_common.h" -#define INSTANTIATE_GETCHILD_BUTTON #include "llbutton.h" // Linden library includes @@ -53,7 +52,7 @@ #include "llrender.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLButton> r("button"); +static LLDefaultChildRegistry::Register<LLButton> r("button"); // globals loaded from settings.xml S32 LLBUTTON_H_PAD = 0; @@ -61,11 +60,9 @@ S32 LLBUTTON_V_PAD = 0; S32 BTN_HEIGHT_SMALL= 0; S32 BTN_HEIGHT = 0; -template LLButton* LLView::getChild<LLButton>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - LLButton::Params::Params() : label_selected("label_selected"), // requires is_toggle true - label_dropshadow("label_shadow", true), + label_shadow("label_shadow", true), auto_resize("auto_resize", false), image_unselected("image_unselected"), image_selected("image_selected"), @@ -136,7 +133,7 @@ LLButton::LLButton(const LLButton::Params& p) mImageOverlayAlignment(LLFontGL::hAlignFromName(p.image_overlay_alignment)), mIsToggle(p.is_toggle), mScaleImage(p.scale_image), - mDropShadowedText(p.label_dropshadow), + mDropShadowedText(p.label_shadow), mAutoResize(p.auto_resize), mHAlign(p.font_halign), mLeftHPad(p.pad_left), @@ -146,7 +143,7 @@ LLButton::LLButton(const LLButton::Params& p) mFadeWhenDisabled(FALSE) { static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0); - static Params default_params(LLUICtrlFactory::getDefaultParams<Params>()); + static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>()); //if we aren't a picture_style button set label as name if not provided if (!p.picture_style.isProvided() || !p.picture_style) @@ -328,25 +325,27 @@ BOOL LLButton::handleKeyHere(KEY key, MASK mask ) BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) { - // Route future Mouse messages here preemptively. (Release on mouse up.) - gFocusMgr.setMouseCapture( this ); - - if (hasTabStop() && !getIsChrome()) + if (!childrenHandleMouseDown(x, y, mask)) { - setFocus(TRUE); - } + // Route future Mouse messages here preemptively. (Release on mouse up.) + gFocusMgr.setMouseCapture( this ); - mMouseDownSignal(this, LLSD()); + if (hasTabStop() && !getIsChrome()) + { + setFocus(TRUE); + } - mMouseDownTimer.start(); - mMouseDownFrame = (S32) LLFrameTimer::getFrameCount(); - mMouseHeldDownCount = 0; - - if (getSoundFlags() & MOUSE_DOWN) - { - make_ui_sound("UISndClick"); - } + mMouseDownSignal(this, LLSD()); + mMouseDownTimer.start(); + mMouseDownFrame = (S32) LLFrameTimer::getFrameCount(); + mMouseHeldDownCount = 0; + + if (getSoundFlags() & MOUSE_DOWN) + { + make_ui_sound("UISndClick"); + } + } return TRUE; } @@ -381,20 +380,26 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) LLUICtrl::onCommit(); } } + else + { + childrenHandleMouseUp(x, y, mask); + } return TRUE; } BOOL LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask) { - // Route future Mouse messages here preemptively. (Release on mouse up.) - gFocusMgr.setMouseCapture( this ); - - if (hasTabStop() && !getIsChrome()) + if (!childrenHandleRightMouseDown(x, y, mask)) { - setFocus(TRUE); - } + // Route future Mouse messages here preemptively. (Release on mouse up.) + gFocusMgr.setMouseCapture( this ); + if (hasTabStop() && !getIsChrome()) + { + setFocus(TRUE); + } + } return TRUE; } @@ -412,6 +417,10 @@ BOOL LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask) mRightClickSignal(this, getValue()); } } + else + { + childrenHandleRightMouseUp(x, y, mask); + } return TRUE; } @@ -429,21 +438,23 @@ void LLButton::onMouseLeave(S32 x, S32 y, MASK mask) BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) { - if (mMouseDownTimer.getStarted()) + if (!childrenHandleHover(x, y, mask)) { - F32 elapsed = getHeldDownTime(); - if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame) + if (mMouseDownTimer.getStarted()) { - LLSD param; - param["count"] = mMouseHeldDownCount++; - mHeldDownSignal(this, param); + F32 elapsed = getHeldDownTime(); + if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame) + { + LLSD param; + param["count"] = mMouseHeldDownCount++; + mHeldDownSignal(this, param); + } } - } - - // We only handle the click if the click both started and ended within us - getWindow()->setCursor(UI_CURSOR_ARROW); - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; + // We only handle the click if the click both started and ended within us + getWindow()->setCursor(UI_CURSOR_ARROW); + lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; + } return TRUE; } diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 1398e5c14b..e387c91a17 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -74,7 +74,7 @@ public: { // text label Optional<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, @@ -352,11 +352,5 @@ private: LLFrameTimer mFlashingTimer; }; -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_BUTTON -#pragma warning (disable : 4231) -extern template LLButton* LLView::getChild<LLButton>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif #endif // LL_LLBUTTON_H diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 932a1b6297..b43f91e766 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -31,8 +31,6 @@ */ // The mutants are coming! -#define INSTANTIATE_GETCHILD_CHECKBOX - #include "linden_common.h" #include "llcheckboxctrl.h" @@ -50,9 +48,7 @@ const U32 MAX_STRING_LENGTH = 10; -template LLCheckBoxCtrl* LLView::getChild<LLCheckBoxCtrl>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - -static LLDefaultWidgetRegistry::Register<LLCheckBoxCtrl> r("check_box"); +static LLDefaultChildRegistry::Register<LLCheckBoxCtrl> r("check_box"); LLCheckBoxCtrl::Params::Params() : text_enabled_color("text_enabled_color"), diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h index 2f8f088a3e..2f8e8fdd23 100644 --- a/indra/llui/llcheckboxctrl.h +++ b/indra/llui/llcheckboxctrl.h @@ -126,11 +126,4 @@ protected: }; -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_CHECKBOX -#pragma warning (disable : 4231) -extern template LLCheckBoxCtrl* LLView::getChild<LLCheckBoxCtrl>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif - #endif // LL_LLCHECKBOXCTRL_H diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 51ab3326fe..51f9d6bd18 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -33,8 +33,6 @@ // A control that displays the name of the chosen item, which when // clicked shows a scrolling box of options. -#define INSTANTIATE_GETCHILD_COMBOBOX - #include "linden_common.h" // file includes @@ -63,9 +61,7 @@ S32 LLCOMBOBOX_HEIGHT = 0; S32 LLCOMBOBOX_WIDTH = 0; S32 MAX_COMBO_WIDTH = 500; -template LLComboBox* LLView::getChild<LLComboBox>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - -static LLDefaultWidgetRegistry::Register<LLComboBox> register_combo_box("combo_box"); +static LLDefaultChildRegistry::Register<LLComboBox> register_combo_box("combo_box"); void LLComboBox::PreferredPositionValues::declareValues() { @@ -83,12 +79,12 @@ LLComboBox::Params::Params() : allow_text_entry("allow_text_entry", false), show_text_as_tentative("show_text_as_tentative", true), max_chars("max_chars", 20), - arrow_image("arrow_image"), list_position("list_position", BELOW), items("item"), combo_button("combo_button"), combo_list("combo_list"), - combo_editor("combo_editor") + combo_editor("combo_editor"), + drop_down_button("drop_down_button") { addSynonym(items, "combo_item"); } @@ -104,19 +100,29 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) mPrearrangeCallback(p.prearrange_callback()), mTextEntryCallback(p.text_entry_callback()), mSelectionCallback(p.selection_callback()), - mArrowImage(p.arrow_image), mListPosition(p.list_position) { // Text label button - LLButton::Params button_params = p.combo_button; + LLButton::Params button_params = (mAllowTextEntry ? p.combo_button : p.drop_down_button); button_params.mouse_down_callback.function(boost::bind(&LLComboBox::onButtonDown, this)); button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT); button_params.rect(p.rect); - button_params.pad_right(2); + + if(mAllowTextEntry) + { + button_params.pad_right(2); + } + + mArrowImage = button_params.image_unselected; mButton = LLUICtrlFactory::create<LLButton>(button_params); - mButton->setRightHPad(2); //redo to compensate for button hack that leaves space for a character + if(mAllowTextEntry) + { + //redo to compensate for button hack that leaves space for a character + //unless it is a "minimal combobox"(drop down) + mButton->setRightHPad(2); + } addChild(mButton); LLScrollListCtrl::Params params = p.combo_list; @@ -135,7 +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); @@ -732,12 +738,7 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_re msg = tool_tip; // Convert rect local to screen coordinates - localPointToScreen( - 0, 0, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - getRect().getWidth(), getRect().getHeight(), - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); + *sticky_rect_screen = calcScreenRect(); } return TRUE; } diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index bc98690a01..517210f629 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -39,7 +39,6 @@ #include "llbutton.h" #include "lluictrl.h" #include "llctrlselectioninterface.h" -#include "llimagegl.h" #include "llrect.h" #include "llscrolllistctrl.h" #include "lllineeditor.h" @@ -84,7 +83,6 @@ public: Optional<commit_callback_t> prearrange_callback, text_entry_callback, selection_callback; - Optional<LLUIImage*> arrow_image; Optional<EPreferredPosition, PreferredPositionValues> list_position; @@ -93,6 +91,8 @@ public: Optional<LLScrollListCtrl::Params> combo_list; Optional<LLLineEditor::Params> combo_editor; + Optional<LLButton::Params> drop_down_button; + Multiple<ItemParams> items; Params(); @@ -233,12 +233,4 @@ private: commit_callback_t mTextEntryCallback; commit_callback_t mSelectionCallback; }; - -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_COMBOBOX -#pragma warning (disable : 4231) -extern template LLComboBox* LLView::getChild<LLComboBox>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif - #endif diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp index f1fc3d8f43..1e8b8a5537 100644 --- a/indra/llui/llconsole.cpp +++ b/indra/llui/llconsole.cpp @@ -177,8 +177,8 @@ void LLConsole::draw() // F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f); F32 console_opacity = llclamp(LLUI::sSettingGroups["config"]->getF32("ConsoleBackgroundOpacity"), 0.f, 1.f); -// LLColor4 color = gSavedSkinSettings.getColor("ConsoleBackground"); - LLColor4 color = LLUI::sSettingGroups["color"]->getColor("ConsoleBackground"); +// LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground"); + LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground"); color.mV[VALPHA] *= console_opacity; F32 line_height = mFont->getLineHeight(); diff --git a/indra/llui/llconsole.h b/indra/llui/llconsole.h index 65149b217f..56e1614948 100644 --- a/indra/llui/llconsole.h +++ b/indra/llui/llconsole.h @@ -58,7 +58,8 @@ public: Optional<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/llcontainerview.cpp b/indra/llui/llcontainerview.cpp index 40cc430e25..96948b659f 100644 --- a/indra/llui/llcontainerview.cpp +++ b/indra/llui/llcontainerview.cpp @@ -42,7 +42,7 @@ #include "llscrollcontainer.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLContainerView> r("container_view"); +static LLDefaultChildRegistry::Register<LLContainerView> r("container_view"); LLContainerView::LLContainerView(const LLContainerView::Params& p) : LLView(p), diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index 8ecbdb98e1..6e8e37ded3 100644 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -317,6 +317,23 @@ BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask) S32 delta_x = screen_x - mDragLastScreenX; S32 delta_y = screen_y - mDragLastScreenY; + // if dragging a docked floater we want to undock + if (((LLFloater*)getParent())->isDocked()) + { + const S32 SLOP = 12; + + if (delta_y <= -SLOP || + delta_y >= SLOP) + { + ((LLFloater*)getParent())->setDocked(false, false); + return TRUE; + } + else + { + return FALSE; + } + } + LLRect original_rect = getParent()->getRect(); LLRect translated_rect = getParent()->getRect(); translated_rect.translate(delta_x, delta_y); diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h index 8b53c46ae9..88ec1d21f8 100644 --- a/indra/llui/lldraghandle.h +++ b/indra/llui/lldraghandle.h @@ -53,8 +53,9 @@ public: Optional<LLUIColor> drag_shadow_color; Params() - : drag_highlight_color("", LLUI::getCachedColorFunctor("DefaultHighlightLight")), - drag_shadow_color("", LLUI::getCachedColorFunctor("DefaultShadowDark")) + : label("label"), + drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")), + drag_shadow_color("drag_shadow_color", LLUIColorTable::instance().getColor("DefaultShadowDark")) { mouse_opaque(true); follows.flags(FOLLOWS_ALL); diff --git a/indra/llui/llfiltereditor.cpp b/indra/llui/llfiltereditor.cpp new file mode 100644 index 0000000000..0f36483fc2 --- /dev/null +++ b/indra/llui/llfiltereditor.cpp @@ -0,0 +1,110 @@ +/** + * @file llfiltereditor.cpp + * @brief LLFilterEditor implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +// Text editor widget to let users enter a single line. + +#include "linden_common.h" + +#include "llfiltereditor.h" + +LLFilterEditor::LLFilterEditor(const LLFilterEditor::Params& p) +: LLUICtrl(p) +{ + LLLineEditor::Params line_editor_p(p); + line_editor_p.name("filter edit box"); + line_editor_p.rect(getLocalRect()); + line_editor_p.follows.flags(FOLLOWS_ALL); + line_editor_p.text_pad_right(getRect().getHeight()); + line_editor_p.keystroke_callback(boost::bind(&LLUICtrl::onCommit, this)); + + mFilterEditor = LLUICtrlFactory::create<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 8932a7ccf2..a397278a2b 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -66,29 +66,24 @@ const S32 TABBED_FLOATER_OFFSET = 0; std::string LLFloater::sButtonActiveImageNames[BUTTON_COUNT] = { - "closebox.tga", //BUTTON_CLOSE + "Icon_Close_Foreground", //BUTTON_CLOSE "restore.tga", //BUTTON_RESTORE "minimize.tga", //BUTTON_MINIMIZE "tearoffbox.tga", //BUTTON_TEAR_OFF "closebox.tga", //BUTTON_EDIT -}; - -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] = { - "close_in_blue.tga", //BUTTON_CLOSE + "Icon_Close_Press", //BUTTON_CLOSE "restore_pressed.tga", //BUTTON_RESTORE "minimize_pressed.tga", //BUTTON_MINIMIZE "tearoff_pressed.tga", //BUTTON_TEAR_OFF "close_in_blue.tga", //BUTTON_EDIT + "Icon_Dock_Press", + "Icon_Undock_Press" }; std::string LLFloater::sButtonNames[BUTTON_COUNT] = @@ -98,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,10 +122,13 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] = LLFloater::onClickMinimize, //BUTTON_MINIMIZE LLFloater::onClickTearOff, //BUTTON_TEAR_OFF LLFloater::onClickEdit, //BUTTON_EDIT + LLFloater::onClickDock, + LLFloater::onClickDock }; LLMultiFloater* LLFloater::sHostp = NULL; -BOOL LLFloater::sEditModeEnabled; +BOOL LLFloater::sEditModeEnabled = FALSE; +BOOL LLFloater::sQuitting = FALSE; // Temporary hack until onClose() behavior becomes data driven LLFloater::handle_map_t LLFloater::sFloaterMap; LLFloaterView* gFloaterView = NULL; @@ -188,10 +190,33 @@ bool LLFloater::KeyCompare::equate(const LLSD& a, const LLSD& b) //************************************ +LLFloater::Params::Params() +: title("title"), + short_title("short_title"), + single_instance("single_instance", false), + auto_tile("auto_tile", false), + can_resize("can_resize", false), + can_minimize("can_minimize", true), + can_close("can_close", true), + can_drag_on_left("can_drag_on_left", false), + can_tear_off("can_tear_off", true), + save_rect("save_rect", false), + save_visibility("save_visibility", false), + open_callback("open_callback"), + close_callback("close_callback"), + can_dock("can_dock", false) +{ + name = "floater"; + // defaults that differ from LLPanel: + background_visible = true; + visible = false; +} + + //static const LLFloater::Params& LLFloater::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams<LLFloater::Params>(); + return LLUICtrlFactory::getDefaultParams<LLFloater>(); } @@ -216,13 +241,15 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) mEditing(FALSE), mButtonScale(1.0f), mAutoFocus(TRUE), // automatically take focus when opened + mCanDock(false), + mDocked(false), mHasBeenDraggedWhileMinimized(FALSE), mPreviousMinimizedBottom(0), mPreviousMinimizedLeft(0), mNotificationContext(NULL) { - static LLUICachedControl<LLColor4> default_background_color ("FloaterDefaultBackgroundColor", *(new LLColor4)); - static LLUICachedControl<LLColor4> focus_background_color ("FloaterFocusBackgroundColor", *(new LLColor4)); + static LLUIColor default_background_color = LLUIColorTable::instance().getColor("FloaterDefaultBackgroundColor"); + static LLUIColor focus_background_color = LLUIColorTable::instance().getColor("FloaterFocusBackgroundColor"); for (S32 i = 0; i < BUTTON_COUNT; i++) { @@ -288,6 +315,11 @@ void LLFloater::initFloater() mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; } + if(mCanDock) + { + mButtonsEnabled[BUTTON_DOCK] = TRUE; + } + buildButtons(); // Floaters are created in the invisible state @@ -473,7 +505,8 @@ void LLFloater::storeRectControl() void LLFloater::storeVisibilityControl() { - if( mVisibilityControl.size() > 1 ) + // sQuitting is a temp hack until we standardize onClose() behavior so that it won't call this when quitting + if( !sQuitting && mVisibilityControl.size() > 1 ) { LLUI::sSettingGroups["floater"]->setBOOL( mVisibilityControl, getVisible() ); } @@ -560,11 +593,17 @@ void LLFloater::openFloater(const LLSD& key) setVisibleAndFrontmost(mAutoFocus); } + mOpenSignal(this, getValue()); onOpen(key); } void LLFloater::closeFloater(bool app_quitting) { + if (app_quitting) + { + LLFloater::sQuitting = true; // Temp hack until we standardize onClose() + } + // Always unminimize before trying to close. // Most of the time the user will never see this state. setMinimized(FALSE); @@ -623,6 +662,7 @@ void LLFloater::closeFloater(bool app_quitting) } // Let floater do cleanup. + mCloseSignal(this, getValue(), app_quitting); onClose(app_quitting); } } @@ -1296,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) { @@ -1372,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() { @@ -1449,7 +1528,7 @@ void LLFloater::draw() S32 bottom = LLPANEL_BORDER_WIDTH; static LLUICachedControl<S32> shadow_offset_S32 ("DropShadowFloater", 0); - static LLUICachedControl<LLColor4> shadow_color_cached ("ColorDropShadow", *(new LLColor4)); + static LLUIColor shadow_color_cached = LLUIColorTable::instance().getColor("ColorDropShadow"); LLColor4 shadow_color = shadow_color_cached; F32 shadow_offset = (F32)shadow_offset_S32; @@ -1474,7 +1553,7 @@ void LLFloater::draw() if(gFocusMgr.childHasKeyboardFocus(this) && !getIsChrome() && !getCurrentTitle().empty()) { - static LLUICachedControl<LLColor4> titlebar_focus_color ("TitleBarFocusColor", *(new LLColor4)); + static LLUIColor titlebar_focus_color = LLUIColorTable::instance().getColor("TitleBarFocusColor"); // draw highlight on title bar to indicate focus. RDW const LLFontGL* font = LLFontGL::getFontSansSerif(); LLRect r = getRect(); @@ -1533,10 +1612,10 @@ void LLFloater::draw() { // add in a border to improve spacialized visual aclarity ;) // use lines instead of gl_rect_2d so we can round the edges as per james' recommendation - static LLUICachedControl<LLColor4> focus_border_color ("FloaterFocusBorderColor", *(new LLColor4)); - static LLUICachedControl<LLColor4> unfocus_border_color ("FloaterUnfocusBorderColor", *(new LLColor4)); + static LLUIColor focus_border_color = LLUIColorTable::instance().getColor("FloaterFocusBorderColor"); + static LLUIColor unfocus_border_color = LLUIColorTable::instance().getColor("FloaterUnfocusBorderColor"); LLUI::setLineWidth(1.5f); - LLColor4 outlineColor = gFocusMgr.childHasKeyboardFocus(this) ? focus_border_color() : unfocus_border_color; + LLColor4 outlineColor = gFocusMgr.childHasKeyboardFocus(this) ? focus_border_color : unfocus_border_color; gl_rect_2d_offset_local(0, getRect().getHeight() + 1, getRect().getWidth() + 1, 0, outlineColor, -LLPANEL_BORDER_WIDTH, FALSE); LLUI::setLineWidth(1.f); } @@ -1699,7 +1778,6 @@ void LLFloater::buildButtons() p.tab_stop(false); p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT); p.tool_tip(sButtonToolTips[i]); - p.image_color(LLUI::getCachedColorFunctor("FloaterButtonImageColor")); p.scale_image(true); LLButton* buttonp = LLUICtrlFactory::create<LLButton>(p); @@ -1710,6 +1788,72 @@ void LLFloater::buildButtons() updateButtons(); } +void LLFloater::initOpenCallback(const OpenCallbackParam& cb, open_signal_t& sig) +{ + if (cb.function.isProvided()) + { + if (cb.parameter.isProvided()) + sig.connect(boost::bind(cb.function(), _1, cb.parameter)); + else + sig.connect(cb.function()); + } + else + { + std::string function_name = cb.function_name; + open_callback_t* func = (OpenCallbackRegistry::getValue(function_name)); + if (func) + { + if (cb.parameter.isProvided()) + sig.connect(boost::bind((*func), _1, cb.parameter)); + else + sig.connect(*func); + } + else if (!function_name.empty()) + { + llwarns << "No callback found for: '" << function_name << "' in control: " << getName() << llendl; + } + } +} + +void LLFloater::initCloseCallback(const CloseCallbackParam& cb, close_signal_t& sig) +{ + if (cb.function.isProvided()) + { + if (cb.parameter.isProvided()) + sig.connect(boost::bind(cb.function(), _1, cb.parameter, _3)); + else + sig.connect(cb.function()); + } + else + { + std::string function_name = cb.function_name; + close_callback_t* func = (CloseCallbackRegistry::getValue(function_name)); + if (func) + { + if (cb.parameter.isProvided()) + sig.connect(boost::bind((*func), _1, cb.parameter,_3)); + else + sig.connect(*func); + } + else if (!function_name.empty()) + { + llwarns << "No callback found for: '" << function_name << "' in control: " << getName() << llendl; + } + } +} + +namespace LLInitParam +{ + + template<> + bool ParamCompare<LLFloater::close_callback_t>::equals( + const LLFloater::close_callback_t &a, + const LLFloater::close_callback_t &b) + { + return false; + } +} + ///////////////////////////////////////////////////// // LLFloaterView @@ -2149,7 +2293,8 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out // convert to local coordinate frame LLRect snap_rect_local = getLocalSnapRect(); - if( floater->isResizable() ) + // only automatically resize non-minimized, resizable floaters + if( floater->isResizable() && !floater->isMinimized() ) { LLRect view_rect = floater->getRect(); S32 old_width = view_rect.getWidth(); @@ -2447,6 +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; @@ -2463,18 +2609,25 @@ void LLFloater::initFromParams(const LLFloater::Params& p) { mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set } + + // open callback + if (p.open_callback.isProvided()) + initOpenCallback(p.open_callback, mOpenSignal); + // close callback + if (p.close_callback.isProvided()) + initCloseCallback(p.close_callback, mCloseSignal); } void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floater, LLXMLNodePtr output_node) { - Params params(LLUICtrlFactory::getDefaultParams<LLFloater::Params>()); + Params params(LLUICtrlFactory::getDefaultParams<LLFloater>()); LLXUIParser::instance().readXUI(node, params); if (output_node) { Params output_params(params); setupParamsForExport(output_params, parent); - Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater::Params>()); + Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>()); output_node->setName(node->getName()->mString); LLXUIParser::instance().writeXUI( output_node, output_params, &default_params); @@ -2491,7 +2644,7 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floa LLFloater::setFloaterHost((LLMultiFloater*) this); } - LLUICtrlFactory::createChildren(this, node, output_node); + LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node); if (node->hasName("multi_floater")) { diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 3e80f1b284..f6c6dcf277 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -102,9 +102,27 @@ public: BUTTON_MINIMIZE, BUTTON_TEAR_OFF, BUTTON_EDIT, + BUTTON_DOCK, + BUTTON_UNDOCK, BUTTON_COUNT }; + typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param)> open_callback_t; + typedef boost::signals2::signal<void (LLUICtrl* ctrl, const LLSD& param)> open_signal_t; + + typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param, bool app_quitting)> close_callback_t; + typedef boost::signals2::signal<void (LLUICtrl* ctrl, const LLSD& param, bool app_quitting)> close_signal_t; + + struct OpenCallbackParam : public LLInitParam::Block<OpenCallbackParam, CallbackParam > + { + Optional<open_callback_t> function; + }; + + struct CloseCallbackParam : public LLInitParam::Block<CloseCallbackParam, CallbackParam > + { + Optional<close_callback_t> function; + }; + struct Params : public LLInitParam::Block<Params, LLPanel::Params> { @@ -119,26 +137,13 @@ public: can_drag_on_left, can_tear_off, save_rect, - save_visibility; - - Params() : - title("title"), - short_title("short_title"), - single_instance("single_instance", false), - auto_tile("auto_tile", false), - can_resize("can_resize", false), - can_minimize("can_minimize", true), - can_close("can_close", true), - can_drag_on_left("can_drag_on_left", false), - can_tear_off("can_tear_off", true), - save_rect("save_rect", false), - save_visibility("save_visibility", false) - { - name = "floater"; - // defaults that differ from LLPanel: - background_visible = true; - visible = false; - } + save_visibility, + can_dock; + + Optional<OpenCallbackParam> open_callback; + Optional<CloseCallbackParam> close_callback; + + Params(); }; // use this to avoid creating your own default LLFloater::Param instance @@ -246,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(); @@ -262,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); @@ -289,8 +301,10 @@ protected: void destroy() { die(); } // Don't call this directly. You probably want to call close(). JC + void initOpenCallback(const OpenCallbackParam& cb, open_signal_t& sig); + void initCloseCallback(const CloseCallbackParam& cb, close_signal_t& sig); + private: - void setForeground(BOOL b); // called only by floaterview void cleanupHandles(); // remove handles to dead floaters void createMinimizeButton(); @@ -299,18 +313,24 @@ private: BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index); void addResizeCtrls(); void addDragHandle(); - + +public: + class OpenCallbackRegistry : public CallbackRegistry<open_callback_t, OpenCallbackRegistry> {}; + class CloseCallbackRegistry : public CallbackRegistry<close_callback_t, CloseCallbackRegistry> {}; + protected: std::string mRectControl; std::string mVisibilityControl; - + open_signal_t mOpenSignal; + close_signal_t mCloseSignal; LLSD mKey; // Key used for retrieving instances; set (for now) by LLFLoaterReg - -private: - LLRect mExpandedRect; + LLDragHandle* mDragHandle; LLResizeBar* mResizeBar[4]; LLResizeHandle* mResizeHandle[4]; + +private: + LLRect mExpandedRect; LLUIString mTitle; LLUIString mShortTitle; @@ -349,10 +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]; @@ -378,6 +401,7 @@ private: LLRootHandle<LLFloater> mHandle; }; + ///////////////////////////////////////////////////////////// // LLFloaterView // Parent of all floating panels @@ -441,9 +465,6 @@ private: S32 mSnapOffsetRight; }; -// singleton implementation for floaters -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=164990 - //******************************************************* //* TO BE DEPRECATED //******************************************************* @@ -460,20 +481,21 @@ public: static void hide(LLFloater* instance, const LLSD& key); }; - -// singleton implementation for floaters (provides visibility policy) -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=164990 - -template <class T> class LLFloaterSingleton : public LLUISingleton<T, VisibilityPolicy<LLFloater> > -{ -}; - // // Globals // extern LLFloaterView* gFloaterView; +namespace LLInitParam +{ + template<> + bool ParamCompare<LLFloater::close_callback_t>::equals( + const LLFloater::close_callback_t &a, + const LLFloater::close_callback_t &b); +} + + #endif // LL_FLOATER_H diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index faa763cea9..d12f600503 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -363,6 +363,24 @@ std::string LLFloaterReg::declareVisibilityControl(const std::string& name) return controlname; } +//static +void LLFloaterReg::registerControlVariables() +{ + // Iterate through alll registered instance names and register rect and visibility control variables + for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter) + { + const std::string& name = iter->first; + if (LLUI::sSettingGroups["floater"]->controlExists(getRectControlName(name))) + { + declareRectControl(name); + } + if (LLUI::sSettingGroups["floater"]->controlExists(getVisibilityControlName(name))) + { + declareVisibilityControl(name); + } + } +} + // Callbacks // static diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index ef2f71ad18..7edac43c96 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -120,6 +120,7 @@ public: static std::string declareRectControl(const std::string& name); static std::string getVisibilityControlName(const std::string& name); static std::string declareVisibilityControl(const std::string& name); + static void registerControlVariables(); // Callback wrappers static void initUICtrlToFloaterVisibilityControl(LLUICtrl* ctrl, const LLSD& sdname); diff --git a/indra/llui/llflyoutbutton.cpp b/indra/llui/llflyoutbutton.cpp index 8846f2a8c4..536919c072 100644 --- a/indra/llui/llflyoutbutton.cpp +++ b/indra/llui/llflyoutbutton.cpp @@ -35,7 +35,7 @@ // file includes #include "llflyoutbutton.h" -//static LLDefaultWidgetRegistry::Register<LLFlyoutButton> r2("flyout_button"); +//static LLDefaultChildRegistry::Register<LLFlyoutButton> r2("flyout_button"); const S32 FLYOUT_BUTTON_ARROW_WIDTH = 24; @@ -54,11 +54,6 @@ LLFlyoutButton::LLFlyoutButton(const Params& p) mActionButton = LLUICtrlFactory::create<LLButton>(bp); addChild(mActionButton); - - mButton->setOrigin(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, 0); - mButton->reshape(FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight()); - mButton->setFollows(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); - mButton->setImageOverlay(mListPosition == BELOW ? "down_arrow.tga" : "up_arrow.tga", LLFontGL::RIGHT); } void LLFlyoutButton::onActionButtonClick(const LLSD& data) @@ -75,7 +70,7 @@ void LLFlyoutButton::draw() //FIXME: this should be an attribute of comboboxes, whether they have a distinct label or // the label reflects the last selected item, for now we have to manually remove the label - mButton->setLabel(LLStringUtil::null); + setLabel(LLStringUtil::null); LLComboBox::draw(); } diff --git a/indra/llui/llflyoutbutton.h b/indra/llui/llflyoutbutton.h index f60fe1eb35..1f1716593a 100644 --- a/indra/llui/llflyoutbutton.h +++ b/indra/llui/llflyoutbutton.h @@ -46,10 +46,14 @@ public: struct Params : public LLInitParam::Block<Params, LLComboBox::Params> { Optional<LLButton::Params> action_button; + Deprecated allow_text_entry; Params() - : action_button("action_button") - {} + : action_button("action_button"), + allow_text_entry("allow_text_entry") + { + LLComboBox::Params::allow_text_entry = false; + } }; protected: diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 9a4ec7627e..a66f147dcc 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -323,7 +323,7 @@ F32 LLFocusMgr::getFocusFlashAmt() const LLColor4 LLFocusMgr::getFocusColor() const { - static LLUICachedControl<LLColor4> focus_color_cached ("FocusColor", *(new LLColor4)); + static LLUIColor focus_color_cached = LLUIColorTable::instance().getColor("FocusColor"); LLColor4 focus_color = lerp(focus_color_cached, LLColor4::white, getFocusFlashAmt()); // de-emphasize keyboard focus when app has lost focus (to avoid typing into wrong window problem) if (!mAppHasFocus) diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h new file mode 100644 index 0000000000..10a7fd4544 --- /dev/null +++ b/indra/llui/llhandle.h @@ -0,0 +1,171 @@ +/** +* @file llhandle.h +* @brief "Handle" to an object (usually a floater) whose lifetime you don't +* control. +* +* $LicenseInfo:firstyear=2001&license=viewergpl$ +* +* Copyright (c) 2001-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#ifndef LLHANDLE_H +#define LLHANDLE_H + +#include "llpointer.h" + +template <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/lliconctrl.cpp b/indra/llui/lliconctrl.cpp index eddfc71284..5c6ea663f3 100644 --- a/indra/llui/lliconctrl.cpp +++ b/indra/llui/lliconctrl.cpp @@ -42,7 +42,7 @@ #include "lluictrlfactory.h" #include "lluiimage.h" -static LLDefaultWidgetRegistry::Register<LLIconCtrl> r("icon"); +static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon"); LLIconCtrl::Params::Params() : image("image_name"), diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h index a6cab0e9ee..ff25b0d53e 100644 --- a/indra/llui/lliconctrl.h +++ b/indra/llui/lliconctrl.h @@ -37,7 +37,6 @@ #include "v4color.h" #include "lluictrl.h" #include "stdenums.h" -#include "llimagegl.h" class LLTextBox; class LLUICtrlFactory; diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 39dac296ea..702d8e4a39 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -38,7 +38,7 @@ #include "llresizebar.h" #include "llcriticaldamp.h" -static LLDefaultWidgetRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack", &LLLayoutStack::fromXML); +static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack", &LLLayoutStack::fromXML); // @@ -120,7 +120,8 @@ struct LLLayoutStack::LayoutPanel LLLayoutStack::Params::Params() : orientation("orientation", std::string("vertical")), - animate("animate", TRUE), + animate("animate", true), + clip("clip", true), border_size("border_size", LLCachedControl<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()); } @@ -223,7 +225,7 @@ static void get_attribute_bool_and_write(LLXMLNodePtr node, //static LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { - LLLayoutStack::Params p(LLUICtrlFactory::getDefaultParams<LLLayoutStack::Params>()); + LLLayoutStack::Params p(LLUICtrlFactory::getDefaultParams<LLLayoutStack>()); LLXUIParser::instance().readXUI(node, p); // Export must happen before setupParams() mungles rectangles and before @@ -233,7 +235,7 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr o { Params output_params(p); setupParamsForExport(output_params, parent); - LLLayoutStack::Params default_params(LLUICtrlFactory::getDefaultParams<LLLayoutStack::Params>()); + LLLayoutStack::Params default_params(LLUICtrlFactory::getDefaultParams<LLLayoutStack>()); output_node->setName(node->getName()->mString); LLXUIParser::instance().writeXUI( output_node, output_params, &default_params); @@ -296,7 +298,7 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr o LLPanel::Params p; LLPanel* panelp = LLUICtrlFactory::create<LLPanel>(p); - LLView* new_child = LLUICtrlFactory::getInstance()->createFromXML(child_node, panelp, LLStringUtil::null, output_child, parent ? parent->getChildRegistry() : LLDefaultWidgetRegistry::instance()); + LLView* new_child = LLUICtrlFactory::getInstance()->createFromXML(child_node, panelp, LLStringUtil::null, LLPanel::child_registry_t::instance(), output_child); if (new_child) { // put child in new embedded panel diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 480bdb5c17..9459b9990c 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -43,7 +43,8 @@ public: { Optional<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 5ea45e13cf..f94eb7fcc3 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -34,8 +34,6 @@ #include "linden_common.h" -#define INSTANTIATE_GETCHILD_LINEEDITOR - #include "lllineeditor.h" #include "lltexteditor.h" @@ -72,9 +70,7 @@ const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing const F32 AUTO_SCROLL_TIME = 0.05f; const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. *TODO: make this equal to the double click interval? -static LLDefaultWidgetRegistry::Register<LLLineEditor> r1("line_editor"); - -template LLLineEditor* LLView::getChild<LLLineEditor>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; +static LLDefaultChildRegistry::Register<LLLineEditor> r1("line_editor"); // // Member functions @@ -95,7 +91,11 @@ void LLLineEditor::PrevalidateNamedFuncs::declareValues() LLLineEditor::Params::Params() : max_length_bytes("max_length", 254), + keystroke_callback("keystroke_callback"), + prevalidate_callback("prevalidate_callback"), background_image("background_image"), + background_image_disabled("background_image_disabled"), + background_image_focused("background_image_focused"), select_on_focus("select_on_focus", false), handle_edit_keys_directly("handle_edit_keys_directly", false), commit_on_focus_lost("commit_on_focus_lost", true), @@ -104,9 +104,8 @@ LLLineEditor::Params::Params() text_color("text_color"), text_readonly_color("text_readonly_color"), text_tentative_color("text_tentative_color"), - bg_readonly_color("bg_readonly_color"), - bg_writeable_color("bg_writeable_color"), - bg_focus_color("bg_focus_color"), + highlight_color("highlight_color"), + preedit_bg_color("preedit_bg_color"), border(""), is_unicode("is_unicode"), drop_shadow_visible("drop_shadow_visible"), @@ -119,6 +118,7 @@ LLLineEditor::Params::Params() mouse_opaque = true; addSynonym(select_on_focus, "select_all_on_focus_received"); addSynonym(border, "border"); + addSynonym(label, "watermark_text"); } LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) @@ -128,6 +128,8 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mScrollHPos( 0 ), mTextPadLeft(p.text_pad_left), mTextPadRight(p.text_pad_right), + mMinHPixels(0), // computed in updateTextPadding() below + mMaxHPixels(0), // computed in updateTextPadding() below mCommitOnFocusLost( p.commit_on_focus_lost ), mRevertOnEsc( TRUE ), mKeystrokeCallback( p.keystroke_callback() ), @@ -146,18 +148,18 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mSelectAllonFocusReceived( p.select_on_focus ), mPassDelete(FALSE), mReadOnly(FALSE), - mImage( NULL ), + mBgImage( p.background_image ), + mBgImageDisabled( p.background_image_disabled ), + mBgImageFocused( p.background_image_focused ), mReplaceNewlinesWithSpaces( TRUE ), mLabel(p.label), mCursorColor(p.cursor_color()), mFgColor(p.text_color()), mReadOnlyFgColor(p.text_readonly_color()), mTentativeFgColor(p.text_tentative_color()), - mWriteableBgColor(p.bg_writeable_color()), - mReadOnlyBgColor(p.bg_readonly_color()), - mFocusBgColor(p.bg_focus_color()), - mGLFont(p.font), - mGLFontStyle(LLFontGL::getStyleFromString(p.font.style)) + mHighlightColor(p.highlight_color()), + mPreeditBgColor(p.preedit_bg_color()), + mGLFont(p.font) { llassert( mMaxLengthBytes > 0 ); @@ -180,7 +182,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) LLViewBorder::Params border_p(p.border); border_p.rect = border_rect; border_p.follows.flags = FOLLOWS_ALL; - border_p.bevel_type = LLViewBorder::BEVEL_IN; + border_p.bevel_style = LLViewBorder::BEVEL_IN; mBorder = LLUICtrlFactory::create<LLViewBorder>(border_p); addChild( mBorder ); @@ -233,6 +235,7 @@ void LLLineEditor::onFocusLost() LLUICtrl::onFocusLost(); } +// virtual void LLLineEditor::onCommit() { // put current line into the line history @@ -243,6 +246,33 @@ void LLLineEditor::onCommit() selectAll(); } +// Returns TRUE if user changed value at all +// virtual +BOOL LLLineEditor::isDirty() const +{ + return mText.getString() != mPrevText; +} + +// Clear dirty state +// virtual +void LLLineEditor::resetDirty() +{ + mPrevText = mText.getString(); +} + +// assumes UTF8 text +// virtual +void LLLineEditor::setValue(const LLSD& value ) +{ + setText(value.asString()); +} + +//virtual +LLSD LLLineEditor::getValue() const +{ + return LLSD(getText()); +} + // line history support void LLLineEditor::updateHistory() @@ -1493,6 +1523,33 @@ void LLLineEditor::doDelete() } +void LLLineEditor::drawBackground() +{ + bool has_focus = hasFocus(); + LLUIImage* image; + if ( mReadOnly ) + { + image = mBgImageDisabled; + } + else if ( has_focus ) + { + image = mBgImageFocused; + } + else + { + image = mBgImage; + } + + // optionally draw programmatic border + if (has_focus) + { + image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), + gFocusMgr.getFocusColor(), + gFocusMgr.getFocusFlashWidth()); + } + image->draw(getLocalRect()); +} + void LLLineEditor::draw() { S32 text_len = mText.length(); @@ -1523,37 +1580,12 @@ void LLLineEditor::draw() LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 ); background.stretch( -mBorderThickness ); - LLColor4 bg_color = mReadOnlyBgColor.get(); - -#if 0 // for when we're ready for image art. - if( hasFocus()) - { - mImage->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); - } - mImage->draw(getLocalRect(), mReadOnly ? mReadOnlyBgColor : mWriteableBgColor ); -#else // the old programmer art. - // drawing solids requires texturing be disabled - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - // draw background for text - if( !mReadOnly ) - { - if( gFocusMgr.getKeyboardFocus() == this ) - { - bg_color = mFocusBgColor.get(); - } - else - { - bg_color = mWriteableBgColor.get(); - } - } - gl_rect_2d(background, bg_color); - } -#endif - + drawBackground(); + // draw text - S32 cursor_bottom = background.mBottom + 1; + // With viewer-2 art files, input region is 2 pixels up + S32 cursor_bottom = background.mBottom + 2; S32 cursor_top = background.mTop - 1; LLColor4 text_color; @@ -1595,7 +1627,8 @@ void LLLineEditor::draw() background.mBottom + preedit_standout_position, preedit_pixels_right - preedit_standout_gap - 1, background.mBottom + preedit_standout_position - preedit_standout_thickness, - (text_color * preedit_standout_brightness + bg_color * (1 - preedit_standout_brightness)).setAlpha(1.0f)); + (text_color * preedit_standout_brightness + + mPreeditBgColor * (1 - preedit_standout_brightness)).setAlpha(1.0f)); } else { @@ -1603,7 +1636,8 @@ void LLLineEditor::draw() background.mBottom + preedit_marker_position, preedit_pixels_right - preedit_marker_gap - 1, background.mBottom + preedit_marker_position - preedit_marker_thickness, - (text_color * preedit_marker_brightness + bg_color * (1 - preedit_marker_brightness)).setAlpha(1.0f)); + (text_color * preedit_marker_brightness + + mPreeditBgColor * (1 - preedit_marker_brightness)).setAlpha(1.0f)); } } } @@ -1636,7 +1670,7 @@ void LLLineEditor::draw() rendered_pixels_right, text_bottom, text_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, select_left - mScrollHPos, mMaxHPixels - llround(rendered_pixels_right), @@ -1645,7 +1679,7 @@ void LLLineEditor::draw() if( (rendered_pixels_right < (F32)mMaxHPixels) && (rendered_text < text_len) ) { - LLColor4 color(1.f - bg_color.mV[0], 1.f - bg_color.mV[1], 1.f - bg_color.mV[2], 1.f); + LLColor4 color = mHighlightColor; // selected middle S32 width = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos + rendered_text, select_right - mScrollHPos - rendered_text); width = llmin(width, mMaxHPixels - llround(rendered_pixels_right)); @@ -1656,7 +1690,7 @@ void LLLineEditor::draw() rendered_pixels_right, text_bottom, LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ), LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, select_right - mScrollHPos - rendered_text, mMaxHPixels - llround(rendered_pixels_right), @@ -1671,7 +1705,7 @@ void LLLineEditor::draw() rendered_pixels_right, text_bottom, text_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, S32_MAX, mMaxHPixels - llround(rendered_pixels_right), @@ -1685,13 +1719,13 @@ void LLLineEditor::draw() rendered_pixels_right, text_bottom, text_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, S32_MAX, mMaxHPixels - llround(rendered_pixels_right), &rendered_pixels_right); } -#if 0 // for when we're ready for image art. +#if 1 // for when we're ready for image art. mBorder->setVisible(FALSE); // no more programmatic art. #endif @@ -1723,7 +1757,7 @@ void LLLineEditor::draw() mGLFont->render(mText, getCursor(), (F32)(cursor_left + lineeditor_cursor_thickness / 2), text_bottom, LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ), LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, 1); } @@ -1749,7 +1783,7 @@ void LLLineEditor::draw() label_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, S32_MAX, mMaxHPixels - llround(rendered_pixels_right), @@ -1774,7 +1808,7 @@ void LLLineEditor::draw() label_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, S32_MAX, mMaxHPixels - llround(rendered_pixels_right), diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index eb021bace9..0986ce5a87 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -84,7 +84,9 @@ public: Optional<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. @@ -392,12 +390,6 @@ private: }; // end class LLLineEditor -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_LINEEDITOR -#pragma warning (disable : 4231) -extern template LLLineEditor* LLView::getChild<LLLineEditor>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif namespace LLInitParam { diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 4af1c1241b..ad2d8afe45 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" @@ -119,16 +119,12 @@ const F32 PIE_SHRINK_TIME = 0.2f; // time of transition between unbounded and bo const F32 ACTIVATE_HIGHLIGHT_TIME = 0.3f; -// widget registrars -struct MenuRegistry : public LLWidgetRegistry<MenuRegistry> -{}; - static MenuRegistry::Register<LLMenuItemSeparatorGL> register_separator("menu_item_separator"); static MenuRegistry::Register<LLMenuItemCallGL> register_menu_item_call("menu_item_call"); static MenuRegistry::Register<LLMenuItemCheckGL> register_menu_item_check("menu_item_check"); static MenuRegistry::Register<LLMenuGL> register_menu("menu"); -static LLDefaultWidgetRegistry::Register<LLMenuGL> register_menu_default("menu"); +static LLDefaultChildRegistry::Register<LLMenuGL> register_menu_default("menu"); @@ -797,6 +793,16 @@ BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask ) return FALSE; } +BOOL LLMenuItemCallGL::handleRightMouseUp(S32 x, S32 y, MASK mask) +{ + if (pointInView(x, y)) + { + mRightClickSignal(this, getValue()); + } + + return TRUE; +} + ///============================================================================ /// Class LLMenuItemCheckGL ///============================================================================ @@ -1457,6 +1463,7 @@ void LLMenuItemBranchDownGL::draw( void ) setHover(FALSE); } + class LLMenuScrollItem : public LLMenuItemCallGL { public: @@ -1465,10 +1472,18 @@ public: ARROW_DOWN, ARROW_UP }; + struct ArrowTypes : public LLInitParam::TypeValuesHelper<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; }; @@ -1646,15 +1661,17 @@ bool LLMenuGL::addChild(LLView* view, S32 tab_group) void LLMenuGL::removeChild( LLView* ctrl) { - LLMenuItemGL* itemp = dynamic_cast<LLMenuItemGL*>(ctrl); - if (itemp) + // previously a dynamic_cast with if statement to check validity + // unfortunately removeChild is called by ~LLView, and at that point the + // object being deleted is no longer a LLMenuItemGL so a dynamic_cast will fail + LLMenuItemGL* itemp = static_cast<LLMenuItemGL*>(ctrl); + + item_list_t::iterator found_it = std::find(mItems.begin(), mItems.end(), (itemp)); + if (found_it != mItems.end()) { - item_list_t::iterator found_it = std::find(mItems.begin(), mItems.end(), (itemp)); - if (found_it != mItems.end()) - { - mItems.erase(found_it); - } + mItems.erase(found_it); } + return LLUICtrl::removeChild(ctrl); } @@ -1664,12 +1681,6 @@ BOOL LLMenuGL::postBuild() return LLUICtrl::postBuild(); } -const widget_registry_t& LLMenuGL::getChildRegistry() const -{ - return MenuRegistry::instance(); -} - - // are we the childmost active menu and hence our jump keys should be enabled? // or are we a free-standing torn-off menu (which uses jump keys too) BOOL LLMenuGL::jumpKeysActive() @@ -2331,10 +2342,10 @@ BOOL LLMenuGL::appendMenu( LLMenuGL* menu ) p.label = menu->getLabel(); p.branch = menu; p.jump_key = menu->getJumpKey(); - p.enabled_color=LLUI::getCachedColorFunctor("MenuItemEnabledColor"); - p.disabled_color=LLUI::getCachedColorFunctor("MenuItemDisabledColor"); - p.highlight_bg_color=LLUI::getCachedColorFunctor("MenuItemHighlightBgColor"); - p.highlight_fg_color=LLUI::getCachedColorFunctor("MenuItemHighlightFgColor"); + p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor"); + p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor"); + p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor"); + p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor"); LLMenuItemBranchGL* branch = LLUICtrlFactory::create<LLMenuItemBranchGL>(p); success &= append( branch ); @@ -2741,7 +2752,7 @@ void LLMenuGL::draw( void ) if (mDropShadowed && !mTornOff) { static LLUICachedControl<S32> drop_shadow_floater ("DropShadowFloater", 0); - static LLUICachedControl<LLColor4> color_drop_shadow ("ColorDropShadow", *(new LLColor4)); + static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow"); gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, color_drop_shadow, drop_shadow_floater ); } @@ -2883,7 +2894,7 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) /// Class LLMenuBarGL ///============================================================================ -static LLDefaultWidgetRegistry::Register<LLMenuBarGL> r2("menu_bar"); +static LLDefaultChildRegistry::Register<LLMenuBarGL> r2("menu_bar"); LLMenuBarGL::LLMenuBarGL( const Params& p ) : LLMenuGL(p), @@ -3115,10 +3126,10 @@ BOOL LLMenuBarGL::appendMenu( LLMenuGL* menu ) p.label = menu->getLabel(); p.visible = menu->getVisible(); p.branch = menu; - p.enabled_color=LLUI::getCachedColorFunctor("MenuItemEnabledColor"); - p.disabled_color=LLUI::getCachedColorFunctor("MenuItemDisabledColor"); - p.highlight_bg_color=LLUI::getCachedColorFunctor("MenuItemHighlightBgColor"); - p.highlight_fg_color=LLUI::getCachedColorFunctor("MenuItemHighlightFgColor"); + p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor"); + p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor"); + p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor"); + p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor"); LLMenuItemBranchDownGL* branch = LLUICtrlFactory::create<LLMenuItemBranchDownGL>(p); success &= branch->addToAcceleratorList(&mAccelerators); @@ -3258,6 +3269,19 @@ BOOL LLMenuHolderGL::handleRightMouseDown( S32 x, S32 y, MASK mask ) return handled; } +// This occurs when you mouse-down to spawn a context menu, hold the button +// down, move off the menu, then mouse-up. We want this to close the menu. +BOOL LLMenuHolderGL::handleRightMouseUp( S32 x, S32 y, MASK mask ) +{ + BOOL handled = LLView::childrenHandleRightMouseUp(x, y, mask) != NULL; + if (!handled) + { + // clicked off of menu, hide them all + hideMenus(); + } + return handled; +} + void LLMenuHolderGL::reshape(S32 width, S32 height, BOOL called_from_parent) { if (width != getRect().getWidth() || height != getRect().getHeight()) @@ -3540,7 +3564,7 @@ void LLContextMenuBranch::showSubMenu() S32 center_x; S32 center_y; localPointToScreen(getRect().getWidth(), getRect().getHeight() , ¢er_x, ¢er_y); - mBranch->show( center_x, center_y, FALSE); + mBranch->show( center_x, center_y); } // onCommit() - do the primary funcationality of the menu item. @@ -3569,15 +3593,16 @@ void LLContextMenuBranch::setHighlight( BOOL highlight ) // class LLContextMenu // A context menu //----------------------------------------------------------------------------- -static LLDefaultWidgetRegistry::Register<LLContextMenu> context_menu_register("context_menu"); +static LLDefaultChildRegistry::Register<LLContextMenu> context_menu_register("context_menu"); static MenuRegistry::Register<LLContextMenu> context_menu_register2("context_menu"); LLContextMenu::LLContextMenu(const Params& p) : LLMenuGL(p), mHoveredAnyItem(FALSE), - mHoverItem(NULL) - + mHoverItem(NULL), + mSpawnMouseX(S32_MAX), // definitely not inside the window frame + mSpawnMouseY(S32_MAX) { //setBackgroundVisible(TRUE); } @@ -3588,7 +3613,8 @@ void LLContextMenu::setVisible(BOOL visible) hide(); } -void LLContextMenu::show(S32 x, S32 y,BOOL adjustCursor) +// Takes cursor position in screen space? +void LLContextMenu::show(S32 x, S32 y) { arrangeAndClear(); @@ -3597,12 +3623,30 @@ void LLContextMenu::show(S32 x, S32 y,BOOL adjustCursor) const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect(); LLView* parent_view = getParent(); - if(getParentMenuItem()) + // Open upwards if menu extends past bottom + if (y - height < menu_region_rect.mBottom) { - S32 parent_width = getParentMenuItem()->getRect().getWidth(); - - if(x + width > menu_region_rect.getWidth()) - x -= parent_width + width; + if (getParentMenuItem()) // Adjust if this is a submenu + { + y += height - getParentMenuItem()->getNominalHeight(); + } + else + { + y += height; + } + } + + // Open out to the left if menu extends past right edge + if (x + width > menu_region_rect.mRight) + { + if (getParentMenuItem()) + { + x -= getParentMenuItem()->getRect().getWidth() + width; + } + else + { + x -= width; + } } S32 local_x, local_y; @@ -3612,14 +3656,12 @@ void LLContextMenu::show(S32 x, S32 y,BOOL adjustCursor) const_cast<LLRect&>(getRect()).setCenterAndSize(local_x + width/2, local_y - height/2, width, height); arrange(); - - if (translateIntoRect(menu_region_rect,FALSE) && adjustCursor) - { - LLUI::setCursorPositionLocal(getParent(), getRect().mLeft , getRect().mTop); - } + // Save click point for detecting cursor moves before mouse-up. + // Must be in local coords to compare with mouseUp events. + // If the mouse doesn't move, the menu will stay open ala the Mac. + screenPointToLocal(x, y, &mSpawnMouseX, &mSpawnMouseY); LLView::setVisible(TRUE); - } void LLContextMenu::hide() @@ -3679,58 +3721,8 @@ BOOL LLContextMenu::handleHover( S32 x, S32 y, MASK mask ) return handled; } -BOOL LLContextMenu::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - // The click was somewhere within our rectangle - LLMenuItemGL *item = getHighlightedItem(); - - if (item) - { - // lie to the item about where the click happened - // to make sure it's within the item's rectangle - handled = item->handleMouseDown( 0, 0, mask ); - } - else - { - // call hidemenus to make sure transient selections get cleared - ((LLMenuHolderGL*)getParent())->hideMenus(); - } - - // always handle mouse down as mouse up will close open menus - return handled; -} -BOOL LLContextMenu::handleMouseUp( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - - // The click was somewhere within our rectangle - LLMenuItemGL *item = getHighlightedItem(); - - if (item) - { - // lie to the item about where the click happened - // to make sure it's within the item's rectangle - if (item->getEnabled()) - { - handled = item->handleMouseUp( 0, 0, mask ); - hide(); - } - } - else - { - // call hidemenus to make sure transient selections get cleared - ((LLMenuHolderGL*)getParent())->hideMenus(); - } - - if (!handled) - { - // call hidemenus to make sure transient selections get cleared - sMenuContainer->hideMenus(); - } +// handleMouseDown and handleMouseUp are handled by LLMenuGL - return handled; -} BOOL LLContextMenu::handleRightMouseDown(S32 x, S32 y, MASK mask) { @@ -3766,7 +3758,19 @@ BOOL LLContextMenu::handleRightMouseDown(S32 x, S32 y, MASK mask) BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask ) { - // release mouse capture when right mouse button released, and we're past the shrink time + const S32 SLOP = 2; + S32 spawn_dx = (x - mSpawnMouseX); + S32 spawn_dy = (y - mSpawnMouseY); + if (-SLOP <= spawn_dx && spawn_dx <= SLOP + && -SLOP <= spawn_dy && spawn_dy <= SLOP) + { + // we're still inside the slop region from spawning this menu + // so interpret the mouse-up as a single-click to show and leave on + // screen + mSpawnMouseX = S32_MAX; + mSpawnMouseY = S32_MAX; + return TRUE; + } S32 local_x = x - getRect().mLeft; S32 local_y = y - getRect().mBottom; @@ -3802,10 +3806,10 @@ BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu) p.name = menu->getName(); p.label = menu->getLabel(); p.branch = menu; - p.enabled_color=LLUI::getCachedColorFunctor("MenuItemEnabledColor"); - p.disabled_color=LLUI::getCachedColorFunctor("MenuItemDisabledColor"); - p.highlight_bg_color=LLUI::getCachedColorFunctor("MenuItemHighlightBgColor"); - p.highlight_fg_color=LLUI::getCachedColorFunctor("MenuItemHighlightFgColor"); + p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor"); + p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor"); + p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor"); + p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor"); item = LLUICtrlFactory::create<LLContextMenuBranch>(p); LLMenuGL::sMenuContainer->addChild(item->getBranch()); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 526e1c2583..f786c891d7 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -81,7 +81,7 @@ public: Params() : shortcut("shortcut"), - jump_key("", KEY_NONE), + jump_key("jump_key", KEY_NONE), use_mac_ctrl("use_mac_ctrl", false), rect("rect"), left("left"), @@ -283,6 +283,7 @@ public: virtual BOOL handleAcceleratorKey(KEY key, MASK mask); virtual BOOL handleKeyHere(KEY key, MASK mask); + virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); //virtual void draw(); @@ -295,6 +296,11 @@ public: { return mEnableSignal.connect(cb); } + + boost::signals2::connection setRightClickedCallback( const commit_signal_t::slot_type& cb ) + { + return mRightClickSignal.connect(cb); + } private: enable_signal_t mEnableSignal; @@ -356,6 +362,11 @@ private: // it in the appendMenu() method. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// child widget registry +struct MenuRegistry : public LLChildRegistry<MenuRegistry> +{}; + + class LLMenuGL : public LLUICtrl { @@ -374,12 +385,13 @@ public: Optional<LLUIColor> bg_color; Params() - : jump_key("", KEY_NONE), + : jump_key("jump_key", KEY_NONE), + horizontal_layout("horizontal_layout"), can_tear_off("tear_off", false), drop_shadow("drop_shadow", true), bg_visible("bg_visible", true), create_jump_keys("create_jump_keys", false), - bg_color("bg_color", LLUI::getCachedColorFunctor( "MenuDefaultBgColor" )), + bg_color("bg_color", LLUIColorTable::instance().getColor( "MenuDefaultBgColor" )), scrollable("scrollable", false) { addSynonym(bg_visible, "opaque"); @@ -388,6 +400,10 @@ public: name = "menu"; } }; + + // my valid children are contained in MenuRegistry + typedef MenuRegistry child_registry_t; + void initFromParams(const Params&); protected: @@ -410,7 +426,6 @@ public: /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0); /*virtual*/ void removeChild( LLView* ctrl); /*virtual*/ BOOL postBuild(); - /*virtual*/ const widget_registry_t& getChildRegistry() const; virtual BOOL handleAcceleratorKey(KEY key, MASK mask); @@ -651,16 +666,12 @@ public: virtual void draw (); - virtual void show (S32 x, S32 y, BOOL adjustCursor = TRUE); + virtual void show (S32 x, S32 y); virtual void hide (); - - virtual BOOL handleHover ( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseDown ( S32 x, S32 y, MASK mask ); virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleRightMouseUp ( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseUp ( S32 x, S32 y, MASK mask ); virtual bool addChild (LLView* view, S32 tab_group = 0); @@ -669,6 +680,11 @@ public: protected: BOOL mHoveredAnyItem; LLMenuItemGL* mHoverItem; + + // Cursor position when the menu was spawned, in menu-local coords + // Used to allow single right-click within a slop region to spawn the menu + S32 mSpawnMouseX; + S32 mSpawnMouseY; }; @@ -748,6 +764,7 @@ public: virtual void draw(); virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleRightMouseUp( S32 x, S32 y, MASK mask ); virtual const LLRect getMenuRect() const { return getLocalRect(); } virtual BOOL hasVisibleMenu() const; diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index 8779eee28d..7557b87b94 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -244,7 +244,7 @@ void LLModalDialog::onClose(bool app_quitting) // virtual void LLModalDialog::draw() { - static LLUICachedControl<LLColor4> shadow_color ("ColorDropShadow", *(new LLColor4)); + static LLUIColor shadow_color = LLUIColorTable::instance().getColor("ColorDropShadow"); static LLUICachedControl<S32> shadow_lines ("DropShadowFloater", 0); gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0, diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp index c0fe7ff32d..22683d7950 100644 --- a/indra/llui/llmultifloater.cpp +++ b/indra/llui/llmultifloater.cpp @@ -275,6 +275,7 @@ void LLMultiFloater::selectPrevFloater() void LLMultiFloater::showFloater(LLFloater* floaterp, LLTabContainer::eInsertionPoint insertion_point) { + if(!floaterp) return; // we won't select a panel that already is selected // it is hard to do this internally to tab container // as tab selection is handled via index and the tab at a given @@ -288,7 +289,7 @@ void LLMultiFloater::showFloater(LLFloater* floaterp, LLTabContainer::eInsertion void LLMultiFloater::removeFloater(LLFloater* floaterp) { - if ( floaterp->getHost() != this ) + if (!floaterp || floaterp->getHost() != this ) return; floater_data_map_t::iterator found_data_it = mFloaterDataMap.find(floaterp->getHandle()); diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 099a79278a..68e496aed1 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -40,12 +40,11 @@ #include "llfocusmgr.h" #include "llkeyboard.h" // for the MASK constants #include "llcontrol.h" -#include "llimagegl.h" #include "lluictrlfactory.h" #include <sstream> -static LLDefaultWidgetRegistry::Register<LLMultiSlider> r("multi_slider_bar"); +static LLDefaultChildRegistry::Register<LLMultiSlider> r("multi_slider_bar"); const F32 FLOAT_THRESHOLD = 0.00001f; diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index 312aceaaa2..1523d5d527 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -52,7 +52,7 @@ #include "llresmgr.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLMultiSliderCtrl> r("multi_slider"); +static LLDefaultChildRegistry::Register<LLMultiSliderCtrl> r("multi_slider"); const U32 MAX_STRING_LENGTH = 10; LLMultiSliderCtrl::Params::Params() diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index 4855ed4926..16d07541f2 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -90,8 +90,8 @@ public: void setCurSlider(const std::string& name); void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mMultiSlider->getCurSlider(), val, from_event); } - virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); } - virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); } + virtual void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); } + virtual void setMaxValue(const LLSD& max_value) { setMaxValue((F32)max_value.asReal()); } BOOL isMouseHeldDown(); @@ -108,8 +108,8 @@ public: void deleteSlider(const std::string& name); void deleteCurSlider() { deleteSlider(mMultiSlider->getCurSlider()); } - F32 getMinValue() { return mMultiSlider->getMinValue(); } - F32 getMaxValue() { return mMultiSlider->getMaxValue(); } + F32 getMinValue() const { return mMultiSlider->getMinValue(); } + F32 getMaxValue() const { return mMultiSlider->getMaxValue(); } void setLabel(const std::string& label) { if (mLabelBox) mLabelBox->setText(label); } void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; } diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index ec92e57b6e..2b4aad5e83 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -385,7 +385,7 @@ LLNotificationTemplate::LLNotificationTemplate() : }
LLNotification::LLNotification(const LLNotification::Params& p) :
- mTimestamp(p.timestamp),
+ mTimestamp(p.time_stamp),
mSubstitutions(p.substitutions),
mPayload(p.payload),
mExpiresAt(0),
@@ -711,6 +711,15 @@ LLBoundListener LLNotificationChannelBase::connectChangedImpl(const LLEventListe return mChanged.connect(slot);
}
+LLBoundListener LLNotificationChannelBase::connectAtFrontChangedImpl(const LLEventListener& slot)
+{
+ for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
+ {
+ slot(LLSD().insert("sigtype", "load").insert("id", (*it)->id()));
+ }
+ return mChanged.connect(slot, boost::signals2::at_front);
+}
+
LLBoundListener LLNotificationChannelBase::connectPassedFilterImpl(const LLEventListener& slot)
{
// these two filters only fire for notifications added after the current one, because
@@ -1079,10 +1088,13 @@ void LLNotifications::createDefaultChannels() // connect action methods to these channels
LLNotifications::instance().getChannel("Expiration")->
connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1));
+ // uniqueHandler slot should be added as first slot of the signal due to
+ // usage LLStopWhenHandled combiner in LLStandardSignal
LLNotifications::instance().getChannel("Unique")->
- connectChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1));
- LLNotifications::instance().getChannel("Unique")->
- connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
+ connectAtFrontChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1));
+// failedUniquenessTest slot isn't necessary
+// LLNotifications::instance().getChannel("Unique")->
+// connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
LLNotifications::instance().getChannel("Ignore")->
connectFailedFilter(&handleIgnoredNotification);
}
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index c534267fca..78a0b9f3fe 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -295,7 +295,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> @@ -313,19 +313,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(); } }; @@ -690,6 +694,14 @@ public: this, _1)); } + template <typename LISTENER> + LLBoundListener connectAtFrontChanged(const LISTENER& slot) + { + return LLEventDetail::visit_and_connect(slot, + boost::bind(&LLNotificationChannelBase::connectAtFrontChangedImpl, + this, + _1)); + } template <typename LISTENER> LLBoundListener connectPassedFilter(const LISTENER& slot) { @@ -715,6 +727,7 @@ public: protected: LLBoundListener connectChangedImpl(const LLEventListener& slot); + LLBoundListener connectAtFrontChangedImpl(const LLEventListener& slot); LLBoundListener connectPassedFilterImpl(const LLEventListener& slot); LLBoundListener connectFailedFilterImpl(const LLEventListener& slot); diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 0136a41d61..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,18 +54,18 @@ #include "lluictrl.h" #include "lluictrlfactory.h" #include "llviewborder.h" -#include "llbutton.h" #include "lltabcontainer.h" -static LLDefaultWidgetRegistry::Register<LLPanel> r1("panel", &LLPanel::fromXML); +static LLDefaultChildRegistry::Register<LLPanel> r1("panel", &LLPanel::fromXML); const LLPanel::Params& LLPanel::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams<LLPanel::Params>(); + return LLUICtrlFactory::getDefaultParams<LLPanel>(); } 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), @@ -418,6 +419,11 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_ void LLPanel::initFromParams(const LLPanel::Params& p) { + //setting these here since panel constructor not called with params + //and LLView::initFromParams will use them to set visible and enabled + setVisible(p.visible); + setEnabled(p.enabled); + // control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible LLUICtrl::initFromParams(p); @@ -425,19 +431,15 @@ void LLPanel::initFromParams(const LLPanel::Params& p) it != p.strings().end(); ++it) { - mUIStrings[it->name] = it->text; + mUIStrings[it->name] = it->value; } - setName(p.name()); setLabel(p.label()); - setShape(p.rect); parseFollowsFlags(p); - setEnabled(p.enabled); - setVisible(p.visible); setToolTip(p.tool_tip()); - setSaveToXML(p.serializable); + setSaveToXML(p.from_xui); mHoverCursor = getCursorFromString(p.hover_cursor); @@ -466,7 +468,7 @@ static LLFastTimer::DeclareTimer FTM_PANEL_POSTBUILD("Panel PostBuild"); BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { - const LLPanel::Params& default_params(LLUICtrlFactory::getDefaultParams<LLPanel::Params>()); + const LLPanel::Params& default_params(LLUICtrlFactory::getDefaultParams<LLPanel>()); Params params(default_params); { @@ -503,7 +505,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu // add children using dimensions from referenced xml for consistent layout setShape(params.rect); - LLUICtrlFactory::createChildren(this, referenced_xml); + LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance()); } LLXUIParser::instance().readXUI(node, params); @@ -524,7 +526,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu } // add children - LLUICtrlFactory::createChildren(this, node, output_node); + LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node); // Connect to parent after children are built, because tab containers // do a reshape() on their child panels, which requires that the children @@ -543,12 +545,6 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu return TRUE; } -const widget_registry_t& LLPanel::getChildRegistry() const -{ - // use default widget registry - return LLDefaultWidgetRegistry::instance(); -} - bool LLPanel::hasString(const std::string& name) { return mUIStrings.find(name) != mUIStrings.end(); @@ -804,24 +800,6 @@ BOOL LLPanel::childSetToolTipArg(const std::string& id, const std::string& key, return FALSE; } -void LLPanel::childSetMinValue(const std::string& id, LLSD min_value) -{ - LLUICtrl* child = findChild<LLUICtrl>(id); - if (child) - { - child->setMinValue(min_value); - } -} - -void LLPanel::childSetMaxValue(const std::string& id, LLSD max_value) -{ - LLUICtrl* child = findChild<LLUICtrl>(id); - if (child) - { - child->setMaxValue(max_value); - } -} - void LLPanel::childShowTab(const std::string& id, const std::string& tabname, bool visible) { LLTabContainer* child = findChild<LLTabContainer>(id); @@ -869,12 +847,12 @@ void LLPanel::childSetAction(const std::string& id, boost::function<void(void*)> } } -void LLPanel::childSetActionTextbox(const std::string& id, void(*function)(void*), void* value) +void LLPanel::childSetActionTextbox(const std::string& id, boost::function<void(void*)> function, void* value) { LLTextBox* textbox = findChild<LLTextBox>(id); if (textbox) { - textbox->setClickedCallback(function, value); + textbox->setClickedCallback(boost::bind(function, value)); } } diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index fc40cd77eb..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") {} }; @@ -93,6 +92,9 @@ public: Params(); }; + // valid children for LLPanel are stored in this registry + typedef LLDefaultChildRegistry child_registry_t; + protected: friend class LLUICtrlFactory; // RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8 @@ -165,7 +167,6 @@ public: void initFromParams(const Params& p); BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); - /*virtual*/ const widget_registry_t& getChildRegistry() const; bool hasString(const std::string& name); std::string getString(const std::string& name, const LLStringUtil::format_map_t& args) const; @@ -213,10 +214,6 @@ public: BOOL childSetLabelArg(const std::string& id, const std::string& key, const LLStringExplicit& text); BOOL childSetToolTipArg(const std::string& id, const std::string& key, const LLStringExplicit& text); - // LLSlider / LLMultiSlider / LLSpinCtrl - void childSetMinValue(const std::string& id, LLSD min_value); - void childSetMaxValue(const std::string& id, LLSD max_value); - // LLTabContainer void childShowTab(const std::string& id, const std::string& tabname, bool visible = true); LLPanel *childGetVisibleTab(const std::string& id) const; @@ -235,7 +232,10 @@ public: // LLButton void childSetAction(const std::string& id, boost::function<void(void*)> function, void* value = NULL); - void childSetActionTextbox(const std::string& id, void(*function)(void*), void* value = NULL); + + // LLTextBox + void childSetActionTextbox(const std::string& id, boost::function<void(void*)> function, void* value = NULL); + void childSetControlName(const std::string& id, const std::string& control_name); // Error reporting diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp index 779967940a..c8b6e814e1 100644 --- a/indra/llui/llprogressbar.cpp +++ b/indra/llui/llprogressbar.cpp @@ -39,22 +39,18 @@ #include "llgl.h" #include "llui.h" #include "llfontgl.h" -#include "llimagegl.h" #include "lltimer.h" #include "llglheaders.h" #include "llfocusmgr.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLProgressBar> r("progress_bar"); +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") {} @@ -62,12 +58,9 @@ LLProgressBar::Params::Params() LLProgressBar::LLProgressBar(const LLProgressBar::Params& p) : LLView(p), mImageBar(p.image_bar), - mImageShadow(p.image_shadow), mImageFill(p.image_fill), mColorBackground(p.color_bg()), mColorBar(p.color_bar()), - mColorBar2(p.color_bar2()), - mColorShadow(p.color_shadow()), mPercentDone(0.f) {} @@ -86,10 +79,10 @@ void LLProgressBar::draw() F32 alpha = 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32())); LLColor4 bar_color = mColorBar.get(); - bar_color.mV[3] = alpha; + bar_color.mV[VALPHA] *= alpha; // modulate alpha LLRect progress_rect = getLocalRect(); progress_rect.mRight = llround(getRect().getWidth() * (mPercentDone / 100.f)); - mImageFill->draw(progress_rect); + mImageFill->draw(progress_rect, bar_color); } void LLProgressBar::setPercent(const F32 percent) diff --git a/indra/llui/llprogressbar.h b/indra/llui/llprogressbar.h index 5c2f73ef9e..b6a5b0400d 100644 --- a/indra/llui/llprogressbar.h +++ b/indra/llui/llprogressbar.h @@ -43,12 +43,9 @@ public: struct Params : public LLInitParam::Block<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/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 70f98bd908..30adbb023c 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -44,10 +44,8 @@ #include "llfocusmgr.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLRadioGroup> r1("radio_group"); +static LLDefaultChildRegistry::Register<LLRadioGroup> r1("radio_group"); -struct RadioGroupRegistry : public LLWidgetRegistry<RadioGroupRegistry> -{}; static RadioGroupRegistry::Register<LLRadioCtrl> register_radio_ctrl("radio_item"); @@ -72,7 +70,7 @@ LLRadioGroup::LLRadioGroup(const LLRadioGroup::Params& p) LLViewBorder::Params params; params.name("radio group border"); params.rect(LLRect(0, getRect().getHeight(), getRect().getWidth(), 0)); - params.bevel_type(LLViewBorder::BEVEL_NONE); + params.bevel_style(LLViewBorder::BEVEL_NONE); LLViewBorder * vb = LLUICtrlFactory::create<LLViewBorder> (params); addChild (vb); } @@ -82,11 +80,6 @@ LLRadioGroup::~LLRadioGroup() { } -const widget_registry_t& LLRadioGroup::getChildRegistry() const -{ - return RadioGroupRegistry::instance(); -} - // virtual BOOL LLRadioGroup::postBuild() { diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h index 850d896e29..d04473fa44 100644 --- a/indra/llui/llradiogroup.h +++ b/indra/llui/llradiogroup.h @@ -70,6 +70,10 @@ protected: friend class LLUICtrlFactory; }; + +struct RadioGroupRegistry : public LLChildRegistry<RadioGroupRegistry> +{}; + /* * An invisible view containing multiple mutually exclusive toggling * buttons (usually radio buttons). Automatically handles the mutex @@ -86,6 +90,9 @@ public: Params(); }; + // my valid children are stored in this registry + typedef RadioGroupRegistry child_registry_t; + protected: LLRadioGroup(const Params&); friend class LLUICtrlFactory; @@ -118,8 +125,6 @@ public: // Update the control as needed. Userdata must be a pointer to the button. void onClickButton(LLUICtrl* clicked_radio); - virtual const widget_registry_t& getChildRegistry() const; - //======================================================================== LLCtrlSelectionInterface* getSelectionInterface() { return (LLCtrlSelectionInterface*)this; }; diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h index 4ad3d5035a..a7bc3c60f5 100644 --- a/indra/llui/llresizebar.h +++ b/indra/llui/llresizebar.h @@ -52,11 +52,11 @@ public: Optional<bool> allow_double_click_snapping; Params() - : max_size("", S32_MAX), - snapping_enabled("", true), + : max_size("max_size", S32_MAX), + snapping_enabled("snapping_enabled", true), resizing_view("resizing_view"), side("side"), - allow_double_click_snapping("", true) + allow_double_click_snapping("allow_double_click_snapping", true) { name = "resize_bar"; } diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp index 943e2f55f1..7449c339a0 100644 --- a/indra/llui/llresizehandle.cpp +++ b/indra/llui/llresizehandle.cpp @@ -45,7 +45,9 @@ const S32 RESIZE_BORDER_WIDTH = 3; LLResizeHandle::Params::Params() -: corner("corner") +: corner("corner"), + min_width("min_width"), + min_height("min_height") { name = "resize_handle"; } @@ -63,7 +65,7 @@ LLResizeHandle::LLResizeHandle(const LLResizeHandle::Params& p) { if( RIGHT_BOTTOM == mCorner) { - mImage = LLUI::getUIImage("resize_handle_bottom_right_blue.tga"); + mImage = LLUI::getUIImage("Resize_Corner"); } switch( p.corner ) { diff --git a/indra/llui/llresizehandle.h b/indra/llui/llresizehandle.h index e4e3c81cec..1560a03796 100644 --- a/indra/llui/llresizehandle.h +++ b/indra/llui/llresizehandle.h @@ -35,7 +35,6 @@ #include "stdtypes.h" #include "llview.h" -#include "llimagegl.h" #include "llcoord.h" diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp new file mode 100644 index 0000000000..cf23e3af15 --- /dev/null +++ b/indra/llui/llrngwriter.cpp @@ -0,0 +1,315 @@ +/** + * @file llrngwriter.cpp + * @brief Generates Relax NG schema from param blocks + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llrngwriter.h" +#include "lluicolor.h" +#include "lluictrlfactory.h" + +// +// LLRNGWriter - writes Relax NG schema files based on a param block +// +LLRNGWriter::LLRNGWriter() +{ + // register various callbacks for inspecting the contents of a param block + registerInspectFunc<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/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 3f1ff34419..3312064131 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -48,7 +48,7 @@ #include "llrender.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLScrollbar> register_scrollbar("scroll_bar"); +static LLDefaultChildRegistry::Register<LLScrollbar> register_scrollbar("scroll_bar"); LLScrollbar::Params::Params() : orientation ("orientation", HORIZONTAL), diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 2a2e56a92c..402c050d2e 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -63,7 +63,7 @@ static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; /// Class LLScrollContainer ///---------------------------------------------------------------------------- -static LLDefaultWidgetRegistry::Register<LLScrollContainer> r("scroll_container"); +static LLDefaultChildRegistry::Register<LLScrollContainer> r("scroll_container"); LLScrollContainer::Params::Params() : is_opaque("opaque"), @@ -91,7 +91,7 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) LLViewBorder::Params params; params.name("scroll border"); params.rect(border_rect); - params.bevel_type(LLViewBorder::BEVEL_IN); + params.bevel_style(LLViewBorder::BEVEL_IN); mBorder = LLUICtrlFactory::create<LLViewBorder> (params); LLView::addChild( mBorder ); @@ -333,34 +333,6 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, return TRUE; } - -BOOL LLScrollContainer::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect) -{ - S32 local_x, local_y; - for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) - { - local_x = x - mScrollbar[i]->getRect().mLeft; - local_y = y - mScrollbar[i]->getRect().mBottom; - if( mScrollbar[i]->handleToolTip(local_x, local_y, msg, sticky_rect) ) - { - return TRUE; - } - } - // Handle 'child' view. - if( mScrolledView ) - { - local_x = x - mScrolledView->getRect().mLeft; - local_y = y - mScrolledView->getRect().mBottom; - if( mScrolledView->handleToolTip(local_x, local_y, msg, sticky_rect) ) - { - return TRUE; - } - } - - // Opaque - return TRUE; -} - void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { const LLRect& rect = mScrolledView->getRect(); @@ -500,12 +472,8 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group) { if (!mScrolledView) { - //*TODO: Move LLFolderView to llui and enable this check -// if (dynamic_cast<LLPanel*>(view) || dynamic_cast<LLContainerView*>(view) || dynamic_cast<LLScrollingPanelList*>(view) || dynamic_cast<LLFolderView*>(view)) - { - // Use the first panel or container as the scrollable view (bit of a hack) - mScrolledView = view; - } + // Use the first panel or container as the scrollable view (bit of a hack) + mScrolledView = view; } bool ret_val = LLView::addChild(view, tab_group); @@ -517,12 +485,6 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group) return ret_val; } -const widget_registry_t& LLScrollContainer::getChildRegistry() const -{ - // a scroll container can contain any default widget - return LLDefaultWidgetRegistry::instance(); -} - void LLScrollContainer::updateScroll() { if (!mScrolledView) diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index 26d8cc824e..c2d4d2c861 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -68,6 +68,10 @@ public: Params(); }; + + // my valid children are stored in this registry + typedef LLDefaultChildRegistry child_registry_t; + protected: LLScrollContainer(const Params&); friend class LLUICtrlFactory; @@ -101,10 +105,8 @@ public: EAcceptance* accept, std::string& tooltip_msg); - virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); virtual void draw(); virtual bool addChild(LLView* view, S32 tab_group = 0); - virtual const widget_registry_t& getChildRegistry() const; private: // internal scrollbar handlers diff --git a/indra/llui/llscrollingpanellist.cpp b/indra/llui/llscrollingpanellist.cpp index 1f3a7f9fcf..0159cdd12c 100644 --- a/indra/llui/llscrollingpanellist.cpp +++ b/indra/llui/llscrollingpanellist.cpp @@ -35,7 +35,7 @@ #include "llscrollingpanellist.h" -static LLDefaultWidgetRegistry::Register<LLScrollingPanelList> r("scrolling_panel_list"); +static LLDefaultChildRegistry::Register<LLScrollingPanelList> r("scrolling_panel_list"); ///////////////////////////////////////////////////////////////////// diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 4e6de24160..cd43e194d2 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -177,7 +177,6 @@ LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p) mFont(p.font), mColor(p.color), mUseColor(p.color.isProvided()), - mFontStyle(LLFontGL::NORMAL), mFontAlignment(p.font_halign), mVisible(p.visible), mHighlightCount( 0 ), @@ -240,6 +239,13 @@ void LLScrollListText::setText(const LLStringExplicit& text) mText = text; } +void LLScrollListText::setFontStyle(const U8 font_style) +{ + LLFontDescriptor new_desc(mFont->getFontDesc()); + new_desc.setStyle(font_style); + mFont = LLFontGL::getFont(new_desc); +} + //virtual void LLScrollListText::setValue(const LLSD& text) { @@ -308,7 +314,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col display_color, mFontAlignment, LLFontGL::BOTTOM, - mFontStyle, + 0, LLFontGL::NO_SHADOW, string_chars, getWidth(), diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index 2ab13f7618..9d3fa65f64 100644 --- a/indra/llui/llscrolllistcell.h +++ b/indra/llui/llscrolllistcell.h @@ -145,14 +145,13 @@ public: /*virtual*/ BOOL isText() const; void setText(const LLStringExplicit& text); - void setFontStyle(const U8 font_style) { mFontStyle = font_style; } + void setFontStyle(const U8 font_style); private: LLUIString mText; const LLFontGL* mFont; LLColor4 mColor; U8 mUseColor; - U8 mFontStyle; LLFontGL::HAlign mFontAlignment; BOOL mVisible; S32 mHighlightCount; diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index 02f09bd9b4..073e14386f 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -65,8 +65,6 @@ LLScrollColumnHeader::LLScrollColumnHeader(const LLScrollColumnHeader::Params& p resize_bar_p.enabled(false); mResizeBar = LLUICtrlFactory::create<LLResizeBar>(resize_bar_p); addChild(mResizeBar); - - setToolTip(p.label()); } LLScrollColumnHeader::~LLScrollColumnHeader() @@ -291,7 +289,7 @@ void LLScrollListColumn::SortNames::declareValues() //static const LLScrollListColumn::Params& LLScrollListColumn::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams<LLScrollListColumn::Params>(); + return LLUICtrlFactory::getDefaultParams<LLScrollListColumn>(); } 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 6d91c784f7..e8627586ea 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -31,8 +31,6 @@ * $/LicenseInfo$ */ -#define INSTANTIATE_GETCHILD_SCROLLLIST - #include "linden_common.h" #include "llscrolllistctrl.h" @@ -60,9 +58,7 @@ #include "lltextbox.h" #include "llsdparam.h" -template LLScrollListCtrl* LLView::getChild<LLScrollListCtrl>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - -static LLDefaultWidgetRegistry::Register<LLScrollListCtrl> r("scroll_list"); +static LLDefaultChildRegistry::Register<LLScrollListCtrl> r("scroll_list"); // local structures & classes. struct SortScrollListItem @@ -106,11 +102,11 @@ struct SortScrollListItem //--------------------------------------------------------------------------- LLScrollListCtrl::Contents::Contents() -: columns("columns"), - rows("rows") +: columns("column"), + rows("row") { - addSynonym(columns, "column"); - addSynonym(rows, "row"); + addSynonym(columns, "columns"); + addSynonym(rows, "rows"); } LLScrollListCtrl::Params::Params() @@ -130,10 +126,11 @@ LLScrollListCtrl::Params::Params() bg_selected_color("bg_selected_color"), fg_disable_color("fg_disable_color"), bg_writeable_color("bg_writeable_color"), - bg_read_only_color("bg_read_only_color"), + bg_readonly_color("bg_readonly_color"), bg_stripe_color("bg_stripe_color"), hovered_color("hovered_color"), - highlighted_color("highlighted_color") + highlighted_color("highlighted_color"), + contents("") { name = "scroll_list"; mouse_opaque = true; @@ -174,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()), @@ -225,7 +222,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) LLViewBorder::Params params; params.name("dig border"); params.rect(border_rect); - params.bevel_type(LLViewBorder::BEVEL_IN); + params.bevel_style(LLViewBorder::BEVEL_IN); mBorder = LLUICtrlFactory::create<LLViewBorder> (params); addChild(mBorder); } @@ -1086,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 ); } @@ -1253,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 ); } @@ -1516,19 +1513,12 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti if (hit_cell && hit_cell->isText()) { - S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft; S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item)); LLRect cell_rect; cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->getWidth(), mLineHeight); // Convert rect local to screen coordinates - localPointToScreen( - cell_rect.mLeft, cell_rect.mBottom, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - cell_rect.mRight, cell_rect.mTop, - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); - + localRectToScreen(cell_rect, sticky_rect_screen); msg = hit_cell->getValue().asString(); } handled = TRUE; @@ -1853,8 +1843,7 @@ S32 LLScrollListCtrl::getColumnOffsetFromIndex(S32 index) S32 LLScrollListCtrl::getRowOffsetFromIndex(S32 index) { - S32 row_bottom = ((mItemListRect.mTop - (index - mScrollLines)) * mLineHeight) - - mLineHeight; + S32 row_bottom = (mItemListRect.mTop - ((index - mScrollLines + 1) * mLineHeight) ); return row_bottom; } @@ -2647,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; @@ -2699,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()) { @@ -2754,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 8d200fb73f..c1800419be 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -44,7 +44,6 @@ #include "llfontgl.h" #include "llui.h" #include "llstring.h" // LLWString -//#include "llimagegl.h" #include "lleditmenuhandler.h" #include "llframetimer.h" @@ -100,7 +99,7 @@ public: bg_selected_color, fg_disable_color, bg_writeable_color, - bg_read_only_color, + bg_readonly_color, bg_stripe_color, hovered_color, highlighted_color; @@ -453,11 +452,4 @@ private: LLTextBox* mCommentTextBox; }; // end class LLScrollListCtrl -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_SCROLLLIST -#pragma warning (disable : 4231) -extern template LLScrollListCtrl* LLView::getChild<LLScrollListCtrl>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif - #endif // LL_SCROLLLISTCTRL_H diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h index 4237d5b304..c2b7effbc7 100644 --- a/indra/llui/llscrolllistitem.h +++ b/indra/llui/llscrolllistitem.h @@ -68,7 +68,7 @@ public: Ignored type; Ignored length; - Multiple<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 9522d32a8b..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 LLDefaultWidgetRegistry::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/llslider.cpp b/indra/llui/llslider.cpp index 8070dc4d02..9483cca104 100644 --- a/indra/llui/llslider.cpp +++ b/indra/llui/llslider.cpp @@ -40,10 +40,9 @@ #include "llfocusmgr.h" #include "llkeyboard.h" // for the MASK constants #include "llcontrol.h" -#include "llimagegl.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLSlider> r1("slider_bar"); +static LLDefaultChildRegistry::Register<LLSlider> r1("slider_bar"); //FIXME: make this into an unregistered template so that code constructed sliders don't // have ambigious template lookup problem diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h index dad65fcce0..088fd20d94 100644 --- a/indra/llui/llslider.h +++ b/indra/llui/llslider.h @@ -36,8 +36,6 @@ #include "llf32uictrl.h" #include "v4color.h" -class LLImageGL; - class LLSlider : public LLF32UICtrl { public: @@ -64,6 +62,9 @@ public: void setValue( F32 value, BOOL from_event = FALSE ); // overrides for LLF32UICtrl methods virtual void setValue(const LLSD& value ) { setValue((F32)value.asReal(), TRUE); } + + virtual void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); } + virtual void setMaxValue(const LLSD& max_value) { setMaxValue((F32)max_value.asReal()); } virtual void setMinValue(F32 min_value) { LLF32UICtrl::setMinValue(min_value); updateThumbRect(); } virtual void setMaxValue(F32 max_value) { LLF32UICtrl::setMaxValue(max_value); updateThumbRect(); } diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index 8bdeddcf75..3176938ea2 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -53,7 +53,7 @@ const U32 MAX_STRING_LENGTH = 10; -static LLDefaultWidgetRegistry::Register<LLSliderCtrl> r("slider"); +static LLDefaultChildRegistry::Register<LLSliderCtrl> r("slider"); LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p) : LLF32UICtrl(p), diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h index 5bdbbfcbcc..4a1574d502 100644 --- a/indra/llui/llsliderctrl.h +++ b/indra/llui/llsliderctrl.h @@ -100,12 +100,15 @@ public: /*virtual*/ void setEnabled( BOOL b ); /*virtual*/ void clear(); + + /*virtual*/ void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); } + /*virtual*/ void setMaxValue(const LLSD& max_value) { setMaxValue((F32)max_value.asReal()); } /*virtual*/ void setMinValue(F32 min_value) { mSlider->setMinValue(min_value); updateText(); } /*virtual*/ void setMaxValue(F32 max_value) { mSlider->setMaxValue(max_value); updateText(); } /*virtual*/ void setIncrement(F32 increment) { mSlider->setIncrement(increment);} - F32 getMinValue() { return mSlider->getMinValue(); } - F32 getMaxValue() { return mSlider->getMaxValue(); } + F32 getMinValue() const { return mSlider->getMinValue(); } + F32 getMaxValue() const { return mSlider->getMaxValue(); } void setLabel(const LLStringExplicit& label) { if (mLabelBox) mLabelBox->setText(label); } void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; } diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 72329a4b32..2d70432182 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -53,14 +53,16 @@ const U32 MAX_STRING_LENGTH = 32; -static LLDefaultWidgetRegistry::Register<LLSpinCtrl> r2("spinner"); +static LLDefaultChildRegistry::Register<LLSpinCtrl> r2("spinner"); LLSpinCtrl::Params::Params() : label_width("label_width"), decimal_digits("decimal_digits"), allow_text_entry("allow_text_entry", true), text_enabled_color("text_enabled_color"), - text_disabled_color("text_disabled_color") + text_disabled_color("text_disabled_color"), + up_button("up_button"), + down_button("down_button") {} LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) @@ -103,38 +105,28 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) S32 btn_right = btn_left + spinctrl_btn_width; // Spin buttons - LLButton::Params up_button_params; - up_button_params.name(std::string("SpinCtrl Up")); + LLButton::Params up_button_params(p.up_button); up_button_params.rect .left(btn_left) .top(top) .right(btn_right) .height(spinctrl_btn_height); - up_button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM); - up_button_params.image_unselected.name("spin_up_out_blue.tga"); - up_button_params.image_selected.name("spin_up_in_blue.tga"); up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); - up_button_params.tab_stop(false); mUpBtn = LLUICtrlFactory::create<LLButton>(up_button_params); addChild(mUpBtn); LLRect down_rect( btn_left, top - spinctrl_btn_height, btn_right, bottom ); - LLButton::Params down_button_params; - down_button_params.name(std::string("SpinCtrl Down")); + LLButton::Params down_button_params(p.down_button); down_button_params.rect .left(btn_left) .right(btn_right) .bottom(bottom) .height(spinctrl_btn_height); - down_button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM); - down_button_params.image_unselected.name("spin_down_out_blue.tga"); - down_button_params.image_selected.name("spin_down_in_blue.tga"); down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); - down_button_params.tab_stop(false); mDownBtn = LLUICtrlFactory::create<LLButton>(down_button_params); addChild(mDownBtn); diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h index eb1a2eb8a7..0e610b7741 100644 --- a/indra/llui/llspinctrl.h +++ b/indra/llui/llspinctrl.h @@ -35,6 +35,7 @@ #include "stdtypes.h" +#include "llbutton.h" #include "llf32uictrl.h" #include "v4color.h" #include "llrect.h" @@ -53,6 +54,9 @@ public: Optional<LLUIColor> text_enabled_color; Optional<LLUIColor> text_disabled_color; + Optional<LLButton::Params> up_button; + Optional<LLButton::Params> down_button; + Params(); }; protected: diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp index 3bd2c9f9e7..55d6b3159f 100644 --- a/indra/llui/llstatgraph.cpp +++ b/indra/llui/llstatgraph.cpp @@ -107,10 +107,10 @@ void LLStatGraph::draw() } //gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, - // gSavedSkinSettings.getColor("ColorDropShadow"), + // LLUIColorTable::instance().getColor("ColorDropShadow"), // (S32) gSavedSettings.getF32("DropShadowFloater") ); - color = LLUI::sSettingGroups["color"]->getColor( "MenuDefaultBgColor" ); + color = LLUIColorTable::instance().getColor( "MenuDefaultBgColor" ); gGL.color4fv(color.mV); gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, TRUE); diff --git a/indra/llui/llstatview.cpp b/indra/llui/llstatview.cpp index 6691f16c1e..ab4b0be97a 100644 --- a/indra/llui/llstatview.cpp +++ b/indra/llui/llstatview.cpp @@ -65,16 +65,6 @@ LLStatView::~LLStatView() } -// widget registrars -struct StatViewRegistry : public LLWidgetRegistry<StatViewRegistry> -{}; - static StatViewRegistry::Register<LLStatBar> r1("stat_bar"); -const widget_registry_t& LLStatView::getChildRegistry() const -{ - return StatViewRegistry::instance(); -} - - diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h index 20aba7782b..eee4e2b7e4 100644 --- a/indra/llui/llstatview.h +++ b/indra/llui/llstatview.h @@ -39,6 +39,10 @@ class LLStatBar; +// widget registrars +struct StatViewRegistry : public LLChildRegistry<StatViewRegistry> +{}; + class LLStatView : public LLContainerView { public: @@ -51,9 +55,11 @@ public: follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT); } }; - ~LLStatView(); - virtual const widget_registry_t& getChildRegistry() const; + // my valid children are stored in this registry + typedef StatViewRegistry child_registry_t; + + ~LLStatView(); protected: LLStatView(const Params&); diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index 890abc7d67..32ddded2c8 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -34,7 +34,6 @@ #define LL_LLSTYLE_H #include "v4color.h" -#include "llfont.h" #include "llui.h" class LLFontGL; @@ -106,7 +105,7 @@ protected: private: BOOL mVisible; - LLColor4 mColor; + LLUIColor mColor; std::string mFontName; LLFontGL* mFont; // cached for performance std::string mLink; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 3391b1275c..29c30004ef 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -99,8 +99,8 @@ struct LLPlaceHolderPanel : public LLPanel LLPlaceHolderPanel(const Params& p) : LLPanel(p) {} }; -static LLDefaultWidgetRegistry::Register<LLPlaceHolderPanel> r1("placeholder"); -static LLDefaultWidgetRegistry::Register<LLTabContainer> r2("tab_container"); +static LLDefaultChildRegistry::Register<LLPlaceHolderPanel> r1("placeholder"); +static LLDefaultChildRegistry::Register<LLTabContainer> r2("tab_container"); LLTabContainer::Params::Params() : tab_width("tab_width"), @@ -108,6 +108,7 @@ LLTabContainer::Params::Params() tab_min_width("tab_min_width"), tab_max_width("tab_max_width"), hide_tabs("hide_tabs", false), + tab_padding_right("tab_padding_right"), tab_top_image_unselected("tab_top_image_unselected"), tab_top_image_selected("tab_top_image_selected"), tab_bottom_image_unselected("tab_bottom_image_unselected"), diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index ac8232bbb1..78592a0f9a 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -122,6 +122,10 @@ public: TabPanelParams() : panel("panel", NULL), + label("label"), + select_tab("select_tab"), + is_placeholder("is_placeholder"), + indent("indent"), insert_at("insert_at", END) {} }; diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 464e4be809..3dd8d21f6b 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -30,17 +30,13 @@ * $/LicenseInfo$ */ -#define INSTANTIATE_GETCHILD_TEXTBOX - #include "linden_common.h" #include "lltextbox.h" #include "lluictrlfactory.h" #include "llfocusmgr.h" #include "llwindow.h" -template LLTextBox* LLView::getChild<LLTextBox>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; - -static LLDefaultWidgetRegistry::Register<LLTextBox> r("text"); +static LLDefaultChildRegistry::Register<LLTextBox> r("text"); LLTextBox::Params::Params() : text_color("text_color"), @@ -86,8 +82,7 @@ LLTextBox::LLTextBox(const LLTextBox::Params& p) mHAlign(p.font_halign), mLineSpacing(p.line_spacing), mWordWrap( p.word_wrap ), - mDidWordWrap(FALSE), - mFontStyle(LLFontGL::getStyleFromString(p.font.style)) + mDidWordWrap(FALSE) { setText( p.text() ); } @@ -314,7 +309,7 @@ void LLTextBox::draw() if( mBorderDropShadowVisible ) { - static LLUICachedControl<LLColor4> color_drop_shadow ("ColorDropShadow", *(new LLColor4)); + static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow"); static LLUICachedControl<S32> drop_shadow_tooltip ("DropShadowTooltip", 0); gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, color_drop_shadow, drop_shadow_tooltip); @@ -386,7 +381,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) { mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color, mHAlign, mVAlign, - mFontStyle, + 0, mShadowType, S32_MAX, getRect().getWidth(), NULL, TRUE, mUseEllipses); } @@ -399,7 +394,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) S32 line_length = *iter; mFontGL->render(mText.getWString(), cur_pos, (F32)x, (F32)y, color, mHAlign, mVAlign, - mFontStyle, + 0, mShadowType, line_length, getRect().getWidth(), NULL, TRUE, mUseEllipses ); cur_pos += line_length + 1; diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index dca906decc..d807fe7639 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -143,7 +143,6 @@ private: BOOL mWordWrap; BOOL mDidWordWrap; - U8 mFontStyle; // style bit flags for font LLFontGL::ShadowType mShadowType; BOOL mBorderDropShadowVisible; BOOL mUseEllipses; @@ -159,11 +158,4 @@ private: callback_t mClickedCallback; }; -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_TEXTBOX -#pragma warning (disable : 4231) -extern template LLTextBox* LLView::getChild<LLTextBox>( const std::string& name, BOOL recurse, BOOL create_if_missing ) const; -#endif -#endif - #endif diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 34bced064e..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" @@ -55,7 +56,6 @@ #include "llundo.h" #include "llviewborder.h" #include "llcontrol.h" -#include "llimagegl.h" #include "llwindow.h" #include "lltextparser.h" #include <queue> @@ -63,7 +63,7 @@ // // Globals // -static LLDefaultWidgetRegistry::Register<LLTextEditor> r("simple_text_editor"); +static LLDefaultChildRegistry::Register<LLTextEditor> r("simple_text_editor"); // // Constants @@ -75,7 +75,7 @@ const S32 CURSOR_THICKNESS = 2; const S32 SPACES_PER_TAB = 4; -LLColor4 LLTextEditor::mLinkColor = LLColor4::blue; +LLUIColor LLTextEditor::mLinkColor = LLColor4::blue; void (* LLTextEditor::mURLcallback)(const std::string&) = NULL; bool (* LLTextEditor::mSecondlifeURLcallback)(const std::string&) = NULL; bool (* LLTextEditor::mSecondlifeURLcallbackRightClick)(const std::string&) = NULL; @@ -228,6 +228,29 @@ private: /////////////////////////////////////////////////////////////////// +LLTextEditor::Params::Params() +: default_text("default_text"), + max_text_length("max_length", 255), + read_only("read_only", false), + embedded_items("embedded_items", false), + hide_scrollbar("hide_scrollbar", false), + hide_border("hide_border", false), + word_wrap("word_wrap", false), + ignore_tab("ignore_tab", true), + track_bottom("track_bottom", false), + takes_non_scroll_clicks("takes_non_scroll_clicks", true), + cursor_color("cursor_color"), + default_color("default_color"), + text_color("text_color"), + text_readonly_color("text_readonly_color"), + bg_readonly_color("bg_readonly_color"), + bg_writeable_color("bg_writeable_color"), + bg_focus_color("bg_focus_color"), + length("length"), // ignored + type("type"), // ignored + is_unicode("is_unicode")// ignored +{} + LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) : LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)), mMaxTextByteLength( p.max_text_length ), @@ -255,8 +278,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) mHideScrollbarForShortDocs( FALSE ), mTakesNonScrollClicks( p.takes_non_scroll_clicks ), mTrackBottom( p.track_bottom ), - mAllowEmbeddedItems( p.allow_embedded_items ), - mAcceptCallingCardNames(FALSE), + mAllowEmbeddedItems( p.embedded_items ), mHandleEditKeysDirectly( FALSE ), mMouseDownX(0), mMouseDownY(0), @@ -265,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); @@ -304,7 +325,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) LLViewBorder::Params params; params.name("text ed border"); params.rect(getLocalRect()); - params.bevel_type(LLViewBorder::BEVEL_IN); + params.bevel_style(LLViewBorder::BEVEL_IN); params.border_thickness(text_editor_border); mBorder = LLUICtrlFactory::create<LLViewBorder> (params); addChild( mBorder ); @@ -1932,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; } @@ -3083,8 +3104,8 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 if (style->getIsEmbeddedItem()) { - static LLUICachedControl<LLColor4> text_embedded_item_readonly_color ("TextEmbeddedItemReadOnlyColor", *(new LLColor4)); - static LLUICachedControl<LLColor4> text_embedded_item_color ("TextEmbeddedItemColor", *(new LLColor4)); + static LLUIColor text_embedded_item_readonly_color = LLUIColorTable::instance().getColor("TextEmbeddedItemReadOnlyColor"); + static LLUIColor text_embedded_item_color = LLUIColorTable::instance().getColor("TextEmbeddedItemColor"); if (mReadOnly) { color = text_embedded_item_readonly_color; @@ -3103,7 +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; @@ -3116,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 ) @@ -3125,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 f64353555e..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&); @@ -268,8 +245,6 @@ public: void setSourceID(const LLUUID& id) { mSourceID = id; } const LLUUID& getSourceID() const { return mSourceID; } - void setAcceptCallingCardNames(BOOL enable) { mAcceptCallingCardNames = enable; } - BOOL acceptsCallingCardNames() const { return mAcceptCallingCardNames; } void setHandleEditKeysDirectly( BOOL b ) { mHandleEditKeysDirectly = b; } @@ -512,7 +487,7 @@ private: // Data // LLKeywords mKeywords; - static LLColor4 mLinkColor; + static LLUIColor mLinkColor; static void (*mURLcallback) (const std::string& url); static bool (*mSecondlifeURLcallback) (const std::string& url); static bool (*mSecondlifeURLcallbackRightClick) (const std::string& url); @@ -526,7 +501,6 @@ private: S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes const LLFontGL* mGLFont; - U8 mGLFontStyle; // the font style from xml class LLViewBorder* mBorder; @@ -586,8 +560,6 @@ private: BOOL mAllowEmbeddedItems; - BOOL mAcceptCallingCardNames; - LLUUID mSourceID; // If true, the standard edit keys (Ctrl-X, Delete, etc,) are handled here diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 1d3e5d7a15..6906f0befb 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -43,7 +43,6 @@ #include "v4color.h" #include "llrender.h" #include "llrect.h" -#include "llimagegl.h" #include "lldir.h" #include "llfontgl.h" @@ -59,8 +58,9 @@ #include "llwindow.h" // for registration -#include "llsearcheditor.h" +#include "llfiltereditor.h" #include "llflyoutbutton.h" +#include "llsearcheditor.h" // for XUIParse #include "llquaternion.h" @@ -89,9 +89,10 @@ std::list<std::string> gUntranslated; /*static*/ std::vector<std::string> LLUI::sXUIPaths; -// register searcheditor here -static LLDefaultWidgetRegistry::Register<LLSearchEditor> register_search_editor("search_editor"); -static LLDefaultWidgetRegistry::Register<LLFlyoutButton> register_flyout_button("flyout_button"); +// 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"); // @@ -424,7 +425,7 @@ void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max } -void gl_draw_image( S32 x, S32 y, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect ) +void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect ) { if (NULL == image) { @@ -434,7 +435,7 @@ void gl_draw_image( S32 x, S32 y, LLImageGL* image, const LLColor4& color, const gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect ); } -void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) +void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) { if (NULL == image) { @@ -444,7 +445,7 @@ void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect ); } -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLImageGL* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect) +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect) { if (NULL == image) { @@ -460,7 +461,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect); } -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, const LLRectf& scale_rect) +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, const LLRectf& scale_rect) { stop_glerror(); @@ -646,12 +647,12 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLIma } } -void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) +void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) { gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect ); } -void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) +void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) { if (NULL == image) { @@ -697,7 +698,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre } -void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) +void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) { if (NULL == image) { @@ -1579,7 +1580,6 @@ void LLUI::initClass(const settings_map_t& settings, sSettingGroups = settings; if ((get_ptr_in_map(sSettingGroups, std::string("config")) == NULL) || - (get_ptr_in_map(sSettingGroups, std::string("color")) == NULL) || (get_ptr_in_map(sSettingGroups, std::string("floater")) == NULL) || (get_ptr_in_map(sSettingGroups, std::string("ignores")) == NULL)) { @@ -1590,7 +1590,7 @@ void LLUI::initClass(const settings_map_t& settings, sAudioCallback = audio_callback; sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor; sWindow = NULL; // set later in startup - LLFontGL::sShadowColor = LLUI::sSettingGroups["color"]->getColor("ColorDropShadow"); + LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow"); static LLUICachedControl<bool> show_xui_names ("ShowXUINames", false); LLUI::sShowXUINames = show_xui_names; @@ -1855,13 +1855,6 @@ void LLUI::setHtmlHelp(LLHtmlHelp* html_help) LLUI::sHtmlHelp = html_help; } -// static -boost::function<const LLColor4&()> LLUI::getCachedColorFunctor(const std::string& color_name) -{ - return LLCachedControl<LLColor4>(*sSettingGroups["color"], color_name, LLColor4::magenta); -} - -// static LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname) { for (settings_map_t::iterator itor = sSettingGroups.begin(); @@ -1942,8 +1935,8 @@ LLLocalClipRect::LLLocalClipRect(const LLRect &rect, BOOL enabled) namespace LLInitParam { - TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func) - : super_t(descriptor, name, value, func), + TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count), red("red"), green("green"), blue("blue"), @@ -1972,11 +1965,22 @@ namespace LLInitParam declare("blue", LLColor4::blue); } - TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL*const value, ParamDescriptor::validation_func_t func) - : super_t(descriptor, name, value, func), - name("", std::string("")), - size("size", std::string("")), - style("style", std::string("")) + template<> + class ParamCompare<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(""), + size("size"), + style("style") {} const LLFontGL* TypedParam<const LLFontGL*>::getValueFromBlock() const @@ -2003,8 +2007,8 @@ namespace LLInitParam return mData.mValue; } - TypedParam<LLRect>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func) - : super_t(descriptor, name, value, func), + TypedParam<LLRect>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count), left("left"), top("top"), right("right"), diff --git a/indra/llui/llui.h b/indra/llui/llui.h index dbd295d4e8..413733a50b 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -39,14 +39,17 @@ #include "llrect.h" #include "llcontrol.h" #include "llcoord.h" -//#include "llhtmlhelp.h" #include "llgl.h" // *TODO: break this dependency #include <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 #include "llinitparam.h" #include "llregistry.h" +#include "lluicolor.h" +#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" @@ -56,7 +59,6 @@ class LLColor4; class LLHtmlHelp; -class LLImageGL; class LLVector3; class LLVector2; class LLUIImage; @@ -97,14 +99,14 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color); void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color); -void gl_draw_image(S32 x, S32 y, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLImageGL* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); // Flip vertical, used for LLFloaterHTML -void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom); void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); @@ -202,7 +204,6 @@ public: static void screenRectToGL(const LLRect& screen, LLRect *gl); static void glRectToScreen(const LLRect& gl, LLRect *screen); static void setHtmlHelp(LLHtmlHelp* html_help); - static boost::function<const LLColor4&()> getCachedColorFunctor(const std::string& color_name); // Returns the control group containing the control name, or the default group static LLControlGroup& getControlControlGroup (const std::string& controlname); @@ -397,8 +398,13 @@ public: delete sInstance; sInstance = NULL; } + + static bool instanceExists() { return NULL != sInstance; } private: + LLUISingleton(const LLUISingleton&){} + LLUISingleton& operator=(const LLUISingleton&){} +private: static T* sInstance; }; @@ -428,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 @@ -690,8 +564,6 @@ public: {} }; -typedef LLLazyValue<LLColor4> LLUIColor; - namespace LLInitParam { template<> @@ -707,7 +579,7 @@ namespace LLInitParam width, height; - TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func); + TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); LLRect getValueFromBlock() const; }; @@ -730,7 +602,7 @@ namespace LLInitParam Optional<F32> alpha; Optional<std::string> control; - TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func); + TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); LLUIColor getValueFromBlock() const; }; @@ -744,7 +616,7 @@ namespace LLInitParam Optional<std::string> size; Optional<std::string> style; - TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func); + TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); const LLFontGL* getValueFromBlock() const; }; @@ -767,11 +639,4 @@ namespace LLInitParam }; } -namespace LLInitParam -{ - template<> - bool ParamCompare<LLLazyValue<LLColor4> >::equals( - const LLLazyValue<LLColor4> &a, const LLLazyValue<LLColor4> &b); -} - #endif diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp index 27ba6cc8b4..087a99c2b0 100644 --- a/indra/llui/lluicolortable.cpp +++ b/indra/llui/lluicolortable.cpp @@ -11,7 +11,10 @@ #include <queue> +#include "lldir.h" +#include "llui.h" #include "lluicolortable.h" +#include "lluictrlfactory.h" LLUIColorTable::ColorParams::ColorParams() : value("value"), @@ -26,17 +29,16 @@ LLUIColorTable::ColorEntryParams::ColorEntryParams() } LLUIColorTable::Params::Params() -: color_entries("color_entries") +: color_entries("color") { } -void LLUIColorTable::init(const Params& p) +void LLUIColorTable::insertFromParams(const Params& p) { // this map will contain all color references after the following loop typedef std::map<std::string, std::string> string_string_map_t; string_string_map_t unresolved_refs; - mColors.clear(); for(LLInitParam::ParamIterator<ColorEntryParams>::const_iterator it = p.color_entries().begin(); it != p.color_entries().end(); ++it) @@ -44,7 +46,7 @@ void LLUIColorTable::init(const Params& p) ColorEntryParams color_entry = *it; if(color_entry.color.value.isChosen()) { - mColors.insert(string_color_map_t::value_type(color_entry.name, color_entry.color.value)); + setColor(color_entry.name, color_entry.color.value, mLoadedColors); } else { @@ -66,19 +68,21 @@ void LLUIColorTable::init(const Params& p) // we haven't visited any references yet visited_refs.clear(); - string_string_map_t::iterator it = unresolved_refs.begin(); + string_string_map_t::iterator current = unresolved_refs.begin(); + string_string_map_t::iterator previous; + while(true) { - if(it != unresolved_refs.end()) + if(current != unresolved_refs.end()) { // locate the current reference in the previously visited references... - string_color_ref_iter_map_t::iterator visited = visited_refs.lower_bound(it->first); + string_color_ref_iter_map_t::iterator visited = visited_refs.lower_bound(current->first); if(visited != visited_refs.end() - && !(visited_refs.key_comp()(it->first, visited->first))) + && !(visited_refs.key_comp()(current->first, visited->first))) { // ...if we find the current reference in the previously visited references // we know that there is a cycle - std::string ending_ref = it->first; + std::string ending_ref = current->first; std::string warning("The following colors form a cycle: "); // warn about the references in the chain and remove them from @@ -102,17 +106,17 @@ void LLUIColorTable::init(const Params& p) else { // ...continue along the reference chain - ref_chain.push(it->first); - visited_refs.insert(visited, string_color_ref_iter_map_t::value_type(it->first, it)); + ref_chain.push(current->first); + visited_refs.insert(visited, string_color_ref_iter_map_t::value_type(current->first, current)); } } else { // since this reference does not refer to another reference it must refer to an // actual color, lets find it... - string_color_map_t::iterator color_value = mColors.find(it->second); + string_color_map_t::iterator color_value = mLoadedColors.find(previous->second); - if(color_value != mColors.end()) + if(color_value != mLoadedColors.end()) { // ...we found the color, and we now add every reference in the reference chain // to the color map @@ -120,7 +124,7 @@ void LLUIColorTable::init(const Params& p) iter != visited_refs.end(); ++iter) { - mColors.insert(string_color_map_t::value_type(iter->first, color_value->second)); + setColor(iter->first, color_value->second, mLoadedColors); unresolved_refs.erase(iter->second); } @@ -143,13 +147,148 @@ void LLUIColorTable::init(const Params& p) } // find the next color reference in the reference chain - it = unresolved_refs.find(it->second); + previous = current; + current = unresolved_refs.find(current->second); } } } -const LLColor4& LLUIColorTable::getColor(const std::string& name) const +void LLUIColorTable::clear() +{ + clearTable(mLoadedColors); + clearTable(mUserSetColors); +} + +LLUIColor LLUIColorTable::getColor(const std::string& name, const LLColor4& default_color) const +{ + string_color_map_t::const_iterator iter = mUserSetColors.find(name); + if(iter != mUserSetColors.end()) + { + return LLUIColor(&iter->second); + } + + iter = mLoadedColors.find(name); + return (iter != mLoadedColors.end() ? LLUIColor(&iter->second) : LLUIColor(default_color)); +} + +// update user color, loaded colors are parsed on initialization +void LLUIColorTable::setColor(const std::string& name, const LLColor4& color) +{ + setColor(name, color, mUserSetColors); +} + +bool LLUIColorTable::loadFromSettings() +{ + bool result = false; + + std::string default_filename = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "colors.xml"); + result |= loadFromFilename(default_filename); + + std::string current_filename = gDirUtilp->getExpandedFilename(LL_PATH_TOP_SKIN, "colors.xml"); + if(current_filename != default_filename) + { + result |= loadFromFilename(current_filename); + } + + std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml"); + loadFromFilename(user_filename); + + return result; +} + +void LLUIColorTable::saveUserSettings() const { - string_color_map_t::const_iterator iter = mColors.find(name); - return (iter != mColors.end() ? iter->second : LLColor4::magenta); + Params params; + + for(string_color_map_t::const_iterator it = mUserSetColors.begin(); + it != mUserSetColors.end(); + ++it) + { + ColorEntryParams color_entry; + color_entry.name = it->first; + color_entry.color.value = it->second; + + params.color_entries.add(color_entry); + } + + LLXMLNodePtr output_node = new LLXMLNode("colors", false); + LLXUIParser::instance().writeXUI(output_node, params); + + if(!output_node->isNull()) + { + const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml"); + LLFILE *fp = LLFile::fopen(filename, "w"); + + if(fp != NULL) + { + LLXMLNode::writeHeaderToFile(fp); + output_node->writeToFile(fp); + + fclose(fp); + } + } +} + +bool LLUIColorTable::colorExists(const std::string& color_name) const +{ + return ((mLoadedColors.find(color_name) != mLoadedColors.end()) + || (mUserSetColors.find(color_name) != mUserSetColors.end())); +} + +void LLUIColorTable::clearTable(string_color_map_t& table) +{ + for(string_color_map_t::iterator it = table.begin(); + it != table.end(); + ++it) + { + it->second = LLColor4::magenta; + } +} + +// this method inserts a color into the table if it does not exist +// if the color already exists it changes the color +void LLUIColorTable::setColor(const std::string& name, const LLColor4& color, string_color_map_t& table) +{ + string_color_map_t::iterator it = table.lower_bound(name); + if(it != table.end() + && !(table.key_comp()(name, it->first))) + { + it->second = color; + } + else + { + table.insert(it, string_color_map_t::value_type(name, color)); + } +} + +bool LLUIColorTable::loadFromFilename(const std::string& filename) +{ + LLXMLNodePtr root; + + if(!LLXMLNode::parseFile(filename, root, NULL)) + { + llwarns << "Unable to parse color file " << filename << llendl; + return false; + } + + if(!root->hasName("colors")) + { + llwarns << filename << " is not a valid color definition file" << llendl; + return false; + } + + Params params; + LLXUIParser::instance().readXUI(root, params); + + if(params.validateBlock()) + { + insertFromParams(params); + } + else + { + llwarns << filename << " failed to load" << llendl; + return false; + } + + return true; } diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h index dcbb1ee5cb..f102a573b8 100644 --- a/indra/llui/lluicolortable.h +++ b/indra/llui/lluicolortable.h @@ -17,8 +17,11 @@ #include "v4color.h" +class LLUIColor; + class LLUIColorTable : public LLSingleton<LLUIColorTable> { +LOG_CLASS(LLUIColorTable); public: struct ColorParams : LLInitParam::Choice<ColorParams> { @@ -44,15 +47,37 @@ public: }; // define colors by passing in a param block that can be generated via XUI file or manually - void init(const Params& p); + void insertFromParams(const Params& p); + + // reset all colors to default magenta color + void clear(); // color lookup - const LLColor4& getColor(const std::string& name) const; + LLUIColor getColor(const std::string& name, const LLColor4& default_color = LLColor4::magenta) const; + + // if the color is in the table, it's value is changed, otherwise it is added + void setColor(const std::string& name, const LLColor4& color); + + // returns true if color_name exists in the table + bool colorExists(const std::string& color_name) const; + + // loads colors from settings files + bool loadFromSettings(); + + // saves colors specified by the user to the users skin directory + void saveUserSettings() const; private: - // consider using sorted vector + bool loadFromFilename(const std::string& filename); + + // consider using sorted vector, can be much faster typedef std::map<std::string, LLColor4> string_color_map_t; - string_color_map_t mColors; + + void clearTable(string_color_map_t& table); + void setColor(const std::string& name, const LLColor4& color, string_color_map_t& table); + + string_color_map_t mLoadedColors; + string_color_map_t mUserSetColors; }; #endif // LL_LLUICOLORTABLE_H diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 7b378fd9c7..aae4a86d87 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -38,21 +38,21 @@ #include "llpanel.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLUICtrl> r("ui_ctrl"); +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"), rightclick_callback("rightclick_callback"), + mouseenter_callback("mouseenter_callback"), + mouseleave_callback("mouseleave_callback"), control_name("control_name") { - addSynonym(initial_value, "initial_val"); - // this is the canonical name for text contents of an xml node - addSynonym(initial_value, "value"); + addSynonym(initial_value, "initial_value"); } LLFocusableElement::LLFocusableElement() @@ -114,7 +114,7 @@ void LLFocusableElement::setFocus(BOOL b) //static const LLUICtrl::Params& LLUICtrl::getDefaultParams() { - return LLUICtrlFactory::getDefaultParams<LLUICtrl::Params>(); + return LLUICtrlFactory::getDefaultParams<LLUICtrl>(); } @@ -189,7 +189,7 @@ void LLUICtrl::initFromParams(const Params& p) } else { - commit_callback_t* initfunc = (CallbackRegistry<commit_callback_t>::getValue(p.init_callback.function_name)); + commit_callback_t* initfunc = (CommitCallbackRegistry::getValue(p.init_callback.function_name)); if (initfunc) { (*initfunc)(this, p.init_callback.parameter); @@ -200,6 +200,11 @@ void LLUICtrl::initFromParams(const Params& p) if(p.rightclick_callback.isProvided()) initCommitCallback(p.rightclick_callback, mRightClickSignal); + if(p.mouseenter_callback.isProvided()) + initCommitCallback(p.mouseenter_callback, mMouseEnterSignal); + + if(p.mouseleave_callback.isProvided()) + initCommitCallback(p.mouseleave_callback, mMouseLeaveSignal); } @@ -226,7 +231,7 @@ void LLUICtrl::initCommitCallback(const CommitCallbackParam& cb, commit_signal_t else { std::string function_name = cb.function_name; - commit_callback_t* func = (CallbackRegistry<commit_callback_t>::getValue(function_name)); + commit_callback_t* func = (CommitCallbackRegistry::getValue(function_name)); if (func) { if (cb.parameter.isProvided()) @@ -264,6 +269,17 @@ void LLUICtrl::initEnableCallback(const EnableCallbackParam& cb, enable_signal_t } } +// virtual +void LLUICtrl::onMouseEnter(S32 x, S32 y, MASK mask) +{ + mMouseEnterSignal(this, getValue()); +} + +// virtual +void LLUICtrl::onMouseLeave(S32 x, S32 y, MASK mask) +{ + mMouseLeaveSignal(this, getValue()); +} void LLUICtrl::onCommit() { @@ -788,38 +804,6 @@ LLUICtrl* LLUICtrl::findRootMostFocusRoot() return focus_root; } - -/* -// Don't let the children handle the tool tip. Handle it here instead. -BOOL LLUICtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) -{ - BOOL handled = FALSE; - if (getVisible() && pointInView( x, y ) ) - { - if( !mToolTipMsg.empty() ) - { - msg = mToolTipMsg; - - // Convert rect local to screen coordinates - localPointToScreen( - 0, 0, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - getRect().getWidth(), getRect().getHeight(), - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); - - handled = TRUE; - } - } - - if (!handled) - { - return LLView::handleToolTip(x, y, msg, sticky_rect_screen); - } - - return handled; -}*/ - // Skip over any parents that are not LLUICtrl's // Used in focus logic since only LLUICtrl elements can have focus LLUICtrl* LLUICtrl::getParentUICtrl() const @@ -865,14 +849,6 @@ BOOL LLUICtrl::getTentative() const void LLUICtrl::setColor(const LLColor4& color) { } -// virtual -void LLUICtrl::setMinValue(LLSD min_value) -{ } - -// virtual -void LLUICtrl::setMaxValue(LLSD max_value) -{ } - namespace LLInitParam @@ -900,12 +876,4 @@ namespace LLInitParam { return false; } - - template<> - bool ParamCompare<LLLazyValue<LLColor4> >::equals( - const LLLazyValue<LLColor4> &a, - const LLLazyValue<LLColor4> &b) - { - return a.get() == b.get(); - } } diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 6dfbd9cf8b..cf6634f370 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -108,7 +108,7 @@ public: { Optional<commit_callback_t> function; }; - + struct EnableCallbackParam : public LLInitParam::Block<EnableCallbackParam, CallbackParam > { Optional<enable_callback_t> function; @@ -130,8 +130,8 @@ public: Alternative<std::string> invisible; ControlVisibility() - : visible("make_visible_control"), - invisible("make_invisible_control") + : visible("visiblity_control"), + invisible("invisiblity_control") {} }; struct Params : public LLInitParam::Block<Params, LLView::Params> @@ -145,6 +145,9 @@ public: Optional<EnableCallbackParam> validate_callback; Optional<CommitCallbackParam> rightclick_callback; + + Optional<CommitCallbackParam> mouseenter_callback; + Optional<CommitCallbackParam> mouseleave_callback; Optional<focus_callback_t> focus_lost_callback; @@ -181,6 +184,8 @@ public: /*virtual*/ BOOL isCtrl() const; /*virtual*/ void setTentative(BOOL b); /*virtual*/ BOOL getTentative() const; + /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); + /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); // From LLFocusableElement /*virtual*/ void setFocus( BOOL b ); @@ -227,8 +232,6 @@ public: virtual void onTabInto(); virtual void clear(); virtual void setColor(const LLColor4& color); - virtual void setMinValue(LLSD min_value); - virtual void setMaxValue(LLSD max_value); BOOL focusNextItem(BOOL text_entry_only); BOOL focusPrevItem(BOOL text_entry_only); @@ -246,6 +249,9 @@ public: boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ) { return mCommitSignal.connect(cb); } boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ) { return mValidateSignal.connect(cb); } + + boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb ) { return mMouseEnterSignal.connect(cb); } + boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb ) { return mMouseLeaveSignal.connect(cb); } // *TODO: Deprecate; for backwards compatability only: boost::signals2::connection setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data); @@ -261,11 +267,11 @@ public: } }; - template <typename F> class CallbackRegistry : public LLRegistrySingleton<std::string, F, CallbackRegistry<F> > + template <typename F, typename DERIVED> class CallbackRegistry : public LLRegistrySingleton<std::string, F, DERIVED > {}; - typedef CallbackRegistry<commit_callback_t> CommitCallbackRegistry; - typedef CallbackRegistry<enable_callback_t> EnableCallbackRegistry; + class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry>{}; + class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry>{}; protected: @@ -275,6 +281,9 @@ protected: enable_signal_t mValidateSignal; commit_signal_t mRightClickSignal; + commit_signal_t mMouseEnterSignal; + commit_signal_t mMouseLeaveSignal; + LLViewModelPtr mViewModel; LLControlVariable* mControlVariable; @@ -313,6 +322,10 @@ namespace LLInitParam bool ParamCompare<LLUICtrl::focus_callback_t>::equals( const LLUICtrl::focus_callback_t &a, const LLUICtrl::focus_callback_t &b); + + template<> + bool ParamCompare<LLLazyValue<LLColor4> >::equals( + const LLLazyValue<LLColor4> &a, const LLLazyValue<LLColor4> &b); } #endif // LL_LLUICTRL_H diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 24e4ad18e6..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"); @@ -85,7 +86,8 @@ LLFastTimer::DeclareTimer FTM_WIDGET_SETUP("Widget Setup"); //----------------------------------------------------------------------------- // Register widgets that are purely data driven here so they get linked in #include "llstatview.h" -static LLDefaultWidgetRegistry::Register<LLStatView> register_stat_view("stat_view"); +static LLDefaultChildRegistry::Register<LLStatView> + register_stat_view("stat_view"); //----------------------------------------------------------------------------- @@ -107,7 +109,7 @@ public: }; -static LLDefaultWidgetRegistry::Register<LLUICtrlLocate> r1("locate"); +static LLDefaultChildRegistry::Register<LLUICtrlLocate> r1("locate"); //----------------------------------------------------------------------------- // LLUICtrlFactory() @@ -135,7 +137,7 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa } //static -void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, LLXMLNodePtr output_node) +void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t& registry, LLXMLNodePtr output_node) { if (node.isNull()) return; @@ -147,7 +149,7 @@ void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, LLXMLNode outputChild = output_node->createChild("", FALSE); } - if (!instance().createFromXML(child_node, viewp, LLStringUtil::null, outputChild, viewp->getChildRegistry())) + if (!instance().createFromXML(child_node, viewp, LLStringUtil::null, registry, outputChild)) { std::string child_name = std::string(child_node->getName()->mString); llwarns << "Could not create widget named " << child_node->getName()->mString << llendl; @@ -338,12 +340,12 @@ BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename, L LLFastTimer::DeclareTimer FTM_CREATE_FROM_XML("Create child widget"); -LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, LLXMLNodePtr output_node, const widget_registry_t& registry) +LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t& registry, LLXMLNodePtr output_node) { LLFastTimer timer(FTM_CREATE_FROM_XML); std::string ctrl_type = node->getName()->mString; LLStringUtil::toLower(ctrl_type); - + const LLWidgetCreatorFunc* funcp = registry.getValue(ctrl_type); if (funcp == NULL) { @@ -398,11 +400,11 @@ BOOL LLUICtrlFactory::getAttributeColor(LLXMLNodePtr node, const std::string& na { std::string colorstring; BOOL res = node->getAttributeString(name.c_str(), colorstring); - if (res && LLUI::sSettingGroups["color"]) + if (res) { - if (LLUI::sSettingGroups["color"]->controlExists(colorstring)) + if (LLUIColorTable::instance().colorExists(colorstring)) { - color.setVec(LLUI::sSettingGroups["color"]->getColor(colorstring)); + color.setVec(LLUIColorTable::instance().getColor(colorstring)); } else { @@ -448,11 +450,326 @@ void LLUICtrlFactory::popFactoryFunctions() } } -const widget_registry_t& LLUICtrlFactory::getWidgetRegistry(LLView* viewp) +// +// LLXSDWriter +// +LLXSDWriter::LLXSDWriter() { - return viewp->getChildRegistry(); + registerInspectFunc<bool>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:boolean", _1, _2, _3, _4)); + registerInspectFunc<std::string>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); + registerInspectFunc<U8>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedByte", _1, _2, _3, _4)); + registerInspectFunc<S8>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:signedByte", _1, _2, _3, _4)); + registerInspectFunc<U16>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedShort", _1, _2, _3, _4)); + registerInspectFunc<S16>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:signedShort", _1, _2, _3, _4)); + registerInspectFunc<U32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedInt", _1, _2, _3, _4)); + registerInspectFunc<S32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:integer", _1, _2, _3, _4)); + registerInspectFunc<F32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:float", _1, _2, _3, _4)); + registerInspectFunc<F64>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:double", _1, _2, _3, _4)); + registerInspectFunc<LLColor4>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); + registerInspectFunc<LLUIColor>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); + registerInspectFunc<LLUUID>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); + registerInspectFunc<LLSD>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); } +void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace) +{ + mSchemaNode = node; + node->setName("xs:schema"); + node->createChild("attributeFormDefault", true)->setStringValue("unqualified"); + node->createChild("elementFormDefault", true)->setStringValue("qualified"); + node->createChild("targetNamespace", true)->setStringValue(xml_namespace); + node->createChild("xmlns:xs", true)->setStringValue("http://www.w3.org/2001/XMLSchema"); + node->createChild("xmlns", true)->setStringValue(xml_namespace); + + node = node->createChild("xs:complexType", false); + node->createChild("name", true)->setStringValue(type_name); + node->createChild("mixed", true)->setStringValue("true"); + + mAttributeNode = node; + mElementNode = node->createChild("xs:choice", false); + mElementNode->createChild("minOccurs", true)->setStringValue("0"); + mElementNode->createChild("maxOccurs", true)->setStringValue("unbounded"); + block.inspectBlock(*this); + + // duplicate element choices + LLXMLNodeList children; + mElementNode->getChildren("xs:element", children, FALSE); + for (LLXMLNodeList::iterator child_it = children.begin(); child_it != children.end(); ++child_it) + { + LLXMLNodePtr child_copy = child_it->second->deepCopy(); + std::string child_name; + child_copy->getAttributeString("name", child_name); + child_copy->setAttributeString("name", type_name + "." + child_name); + mElementNode->addChild(child_copy); + } + + LLXMLNodePtr element_declaration_node = mSchemaNode->createChild("xs:element", false); + element_declaration_node->createChild("name", true)->setStringValue(type_name); + element_declaration_node->createChild("type", true)->setStringValue(type_name); +} + +void LLXSDWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<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); + } + } + + for (name_stack_t::const_iterator it = non_empty_names.begin(); + it != non_empty_names.end(); + ++it) + { + if (!attribute_name.empty()) + { + attribute_name += "."; + } + attribute_name += it->first; + } + + // only flag non-nested attributes as mandatory, nested attributes have variant syntax + // that can't be properly constrained in XSD + // e.g. <foo mandatory.value="bar"/> vs <foo><mandatory value="bar"/></foo> + bool attribute_mandatory = min_count == 1 && max_count == 1 && non_empty_names.size() == 1; + + // don't bother supporting "Multiple" params as xml attributes + if (max_count <= 1) + { + // add compound attribute to root node + addAttributeToSchema(mAttributeNode, attribute_name, type, attribute_mandatory, possible_values); + } + + // now generated nested elements for compound attributes + if (non_empty_names.size() > 1 && !attribute_mandatory) + { + std::string element_name; + + // traverse all but last element, leaving that as an attribute name + name_stack_t::const_iterator end_it = non_empty_names.end(); + end_it--; + + for (name_stack_t::const_iterator it = non_empty_names.begin(); + it != end_it; + ++it) + { + if (it != non_empty_names.begin()) + { + element_name += "."; + } + element_name += it->first; + } + + std::string short_attribute_name = non_empty_names.back().first; + + LLXMLNodePtr complex_type_node; + + // find existing element node here, starting at tail of child list + if (mElementNode->mChildren.notNull()) + { + for(LLXMLNodePtr element = mElementNode->mChildren->tail; + element.notNull(); + element = element->mPrev) + { + std::string name; + if(element->getAttributeString("name", name) && name == element_name) + { + complex_type_node = element->mChildren->head; + break; + } + } + } + //create complex_type node + // + //<xs:element + // maxOccurs="1" + // minOccurs="0" + // name="name"> + // <xs:complexType> + // </xs:complexType> + //</xs:element> + if(complex_type_node.isNull()) + { + complex_type_node = mElementNode->createChild("xs:element", false); + + complex_type_node->createChild("minOccurs", true)->setIntValue(min_count); + complex_type_node->createChild("maxOccurs", true)->setIntValue(max_count); + complex_type_node->createChild("name", true)->setStringValue(element_name); + complex_type_node = complex_type_node->createChild("xs:complexType", false); + } + + addAttributeToSchema(complex_type_node, short_attribute_name, type, false, possible_values); + } +} + +void LLXSDWriter::addAttributeToSchema(LLXMLNodePtr type_declaration_node, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector<std::string>* possible_values) +{ + if (!attribute_name.empty()) + { + LLXMLNodePtr new_enum_type_node; + if (possible_values != NULL) + { + // custom attribute type, for example + //<xs:simpleType> + // <xs:restriction + // base="xs:string"> + // <xs:enumeration + // value="a" /> + // <xs:enumeration + // value="b" /> + // </xs:restriction> + // </xs:simpleType> + new_enum_type_node = new LLXMLNode("xs:simpleType", false); + + LLXMLNodePtr restriction_node = new_enum_type_node->createChild("xs:restriction", false); + restriction_node->createChild("base", true)->setStringValue("xs:string"); + + for (std::vector<std::string>::const_iterator it = possible_values->begin(); + it != possible_values->end(); + ++it) + { + LLXMLNodePtr enum_node = restriction_node->createChild("xs:enumeration", false); + enum_node->createChild("value", true)->setStringValue(*it); + } + } + + string_set_t& attributes_written = mAttributesWritten[type_declaration_node]; + + string_set_t::iterator found_it = attributes_written.lower_bound(attribute_name); + + // attribute not yet declared + if (found_it == attributes_written.end() || attributes_written.key_comp()(attribute_name, *found_it)) + { + attributes_written.insert(found_it, attribute_name); + + LLXMLNodePtr attribute_node = type_declaration_node->createChild("xs:attribute", false); + + // attribute name + attribute_node->createChild("name", true)->setStringValue(attribute_name); + + if (new_enum_type_node.notNull()) + { + attribute_node->addChild(new_enum_type_node); + } + else + { + // simple attribute type + attribute_node->createChild("type", true)->setStringValue(type); + } + + // required or optional + attribute_node->createChild("use", true)->setStringValue(mandatory ? "required" : "optional"); + } + // attribute exists...handle collision of same name attributes with potentially different types + else + { + LLXMLNodePtr attribute_declaration; + if (type_declaration_node.notNull()) + { + for(LLXMLNodePtr node = type_declaration_node->mChildren->tail; + node.notNull(); + node = node->mPrev) + { + std::string name; + if (node->getAttributeString("name", name) && name == attribute_name) + { + attribute_declaration = node; + break; + } + } + } + + bool new_type_is_enum = new_enum_type_node.notNull(); + bool existing_type_is_enum = !attribute_declaration->hasAttribute("type"); + + // either type is enum, revert to string in collision + // don't bother to check for enum equivalence + if (new_type_is_enum || existing_type_is_enum) + { + if (attribute_declaration->hasAttribute("type")) + { + attribute_declaration->setAttributeString("type", "xs:string"); + } + else + { + attribute_declaration->createChild("type", true)->setStringValue("xs:string"); + } + attribute_declaration->deleteChildren("xs:simpleType"); + } + else + { + // check for collision of different standard types + std::string existing_type; + attribute_declaration->getAttributeString("type", existing_type); + // if current type is not the same as the new type, revert to strnig + if (existing_type != type) + { + // ...than use most general type, string + attribute_declaration->setAttributeString("type", "string"); + } + } + } + } +} + +// +// LLXUIXSDWriter +// +void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& path, const LLInitParam::BaseBlock& block) +{ + std::string file_name(path); + file_name += type_name + ".xsd"; + LLXMLNodePtr root_nodep = new LLXMLNode(); + + LLXSDWriter::writeXSD(type_name, root_nodep, block, "http://www.lindenlab.com/xui"); + + // add includes for all possible children + const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); + + // add include declarations for all valid children + for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); + it != widget_registryp->currentRegistrar().endItems(); + ++it) + { + std::string widget_name = it->first; + if (widget_name == type_name) + { + continue; + } + LLXMLNodePtr nodep = new LLXMLNode("xs:include", false); + nodep->createChild("schemaLocation", true)->setStringValue(widget_name + ".xsd"); + + // add to front of schema + mSchemaNode->addChild(nodep, mSchemaNode); + } + + // add choices for valid children + if (widget_registryp) + { + for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); + it != widget_registryp->currentRegistrar().endItems(); + ++it) + { + std::string widget_name = it->first; + //<xs:element name="widget_name" type="widget_name"> + LLXMLNodePtr widget_node = mElementNode->createChild("xs:element", false); + widget_node->createChild("name", true)->setStringValue(widget_name); + widget_node->createChild("type", true)->setStringValue(widget_name); + } + } + + LLFILE* xsd_file = LLFile::fopen(file_name.c_str(), "w"); + LLXMLNode::writeHeaderToFile(xsd_file); + root_nodep->writeToFile(xsd_file); + fclose(xsd_file); +} // // LLXUIParser @@ -510,142 +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; @@ -665,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 @@ -784,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; @@ -814,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; @@ -1010,7 +1274,7 @@ bool LLXUIParser::writeUIColorValue(const void* val_ptr, const name_stack_t& sta LLUIColor color = *((LLUIColor*)val_ptr); //RN: don't write out the color that is represented by a function // rely on param block exporting to get the reference to the color settings - if (color.isUsingFunction()) return false; + if (color.isReference()) return false; node->setFloatValue(4, color.get().mV); return true; } @@ -1051,7 +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 b9c61b1fed..6374018ca6 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -41,11 +41,42 @@ #include <boost/function.hpp> #include <iosfwd> #include <stack> +#include <set> class LLPanel; class LLFloater; class LLView; +class LLXSDWriter : public LLInitParam::Parser +{ + LOG_CLASS(LLXSDWriter); +public: + void writeXSD(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace); + + /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; } + + LLXSDWriter(); + +protected: + void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values); + void addAttributeToSchema(LLXMLNodePtr nodep, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector<std::string>* possible_values); + LLXMLNodePtr mAttributeNode; + LLXMLNodePtr mElementNode; + LLXMLNodePtr mSchemaNode; + + typedef std::set<std::string> string_set_t; + typedef std::map<LLXMLNodePtr, string_set_t> attributes_map_t; + attributes_map_t mAttributesWritten; +}; + +// NOTE: DOES NOT WORK YET +// should support child widgets for XUI +class LLXUIXSDWriter : public LLXSDWriter +{ +public: + void writeXSD(const std::string& name, const std::string& path, const LLInitParam::BaseBlock& block); +}; + class LLXUIParser : public LLInitParam::Parser, public LLSingleton<LLXUIParser> { LOG_CLASS(LLXUIParser); @@ -108,6 +139,9 @@ private: LLXMLNodePtr mCurReadNode; // Root of the widget XML sub-tree, for example, "line_editor" LLXMLNodePtr mWriteRootNode; + + typedef std::map<S32, LLXMLNodePtr> out_nodes_t; + out_nodes_t mOutNodes; S32 mLastWriteGeneration; LLXMLNodePtr mLastWrittenChild; S32 mCurReadDepth; @@ -118,13 +152,23 @@ typedef boost::function<LLView* (LLXMLNodePtr node, LLView *parent, LLXMLNodePtr typedef LLRegistry<std::string, LLWidgetCreatorFunc> widget_registry_t; +// sort functor for typeid maps +struct LLCompareTypeID +{ + bool operator()(const std::type_info* lhs, const std::type_info* rhs) const + { + return lhs->before(*rhs); + } +}; + +// lookup widget constructor funcs by widget name template <typename DERIVED_TYPE> -class LLWidgetRegistry : public LLRegistrySingleton<std::string, LLWidgetCreatorFunc, DERIVED_TYPE> +class LLChildRegistry : public LLRegistrySingleton<std::string, LLWidgetCreatorFunc, DERIVED_TYPE> { public: typedef LLRegistrySingleton<std::string, LLWidgetCreatorFunc, DERIVED_TYPE> super_t; // local static instance for registering a particular widget - template<typename T, typename PARAM_BLOCK = typename T::Params> + template<typename T> class Register : public super_t::StaticRegistrar { public: @@ -133,35 +177,40 @@ public: }; protected: - LLWidgetRegistry() {} + LLChildRegistry() {} }; -class LLDefaultWidgetRegistry : public LLWidgetRegistry<LLDefaultWidgetRegistry> +class LLDefaultChildRegistry : public LLChildRegistry<LLDefaultChildRegistry> { protected: - LLDefaultWidgetRegistry() {} - friend class LLSingleton<LLDefaultWidgetRegistry>; -}; - -struct LLCompareTypeID -{ - bool operator()(const std::type_info* lhs, const std::type_info* rhs) const - { - return lhs->before(*rhs); - } + LLDefaultChildRegistry(){} + friend class LLSingleton<LLDefaultChildRegistry>; }; +// lookup widget name by type +class LLWidgetNameRegistry +: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry , LLCompareTypeID> +{}; -class LLWidgetTemplateRegistry -: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetTemplateRegistry, LLCompareTypeID> +// lookup widget type by name +class LLWidgetTypeRegistry +: public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry> {}; -// function used to create new default widgets via LLView::getChild<T> +// lookup factory functions for default widget instances by widget type typedef LLView* (*dummy_widget_creator_func_t)(const std::string&); +class LLDefaultWidgetRegistry +: public LLRegistrySingleton<const std::type_info*, dummy_widget_creator_func_t, LLDefaultWidgetRegistry, LLCompareTypeID> +{}; + +// lookup function for generating empty param block by widget type +typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)(); +class LLDefaultParamBlockRegistry +: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry, LLCompareTypeID> +{}; -// used to register factory functions for default widget instances -class LLDummyWidgetRegistry -: public LLRegistrySingleton<const std::type_info*, dummy_widget_creator_func_t, LLDummyWidgetRegistry, LLCompareTypeID> +class LLChildRegistryRegistry +: public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry> {}; extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP; @@ -176,26 +225,26 @@ private: ~LLUICtrlFactory(); // only partial specialization allowed in inner classes, so use extra dummy parameter - template <typename T, int DUMMY> - class ParamDefaults : public LLSingleton<ParamDefaults<T, DUMMY> > + template <typename PARAM_BLOCK, int DUMMY> + class ParamDefaults : public LLSingleton<ParamDefaults<PARAM_BLOCK, DUMMY> > { public: ParamDefaults() { // recursively initialize from base class param block - ((typename T::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename T::base_block_t, DUMMY>::instance().get()); + ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get()); // after initializing base classes, look up template file for this param block - std::string* param_block_tag = LLWidgetTemplateRegistry::instance().getValue(&typeid(T)); + std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK)); if (param_block_tag) { LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, mPrototype); } } - const T& get() { return mPrototype; } + const PARAM_BLOCK& get() { return mPrototype; } private: - T mPrototype; + PARAM_BLOCK mPrototype; }; // base case for recursion, there are NO base classes of LLInitParam::BaseBlock @@ -210,11 +259,12 @@ private: public: + // get default parameter block for widget of a specific type template<typename T> - static const T& getDefaultParams() + static const typename T::Params& getDefaultParams() { //#pragma message("Generating ParamDefaults") - return ParamDefaults<T, 0>::instance().get(); + return ParamDefaults<typename T::Params, 0>::instance().get(); } void buildFloater(LLFloater* floaterp, const std::string &filename, BOOL open_floater = TRUE, LLXMLNodePtr output_node = NULL); @@ -252,12 +302,10 @@ public: return widget; } - LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, LLXMLNodePtr output_node, const widget_registry_t& ); + LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t&, LLXMLNodePtr output_node ); - static const widget_registry_t& getWidgetRegistry(LLView*); - template<typename T> - static T* createFromFile(const std::string &filename, LLView *parent, LLXMLNodePtr output_node = NULL) + static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry, LLXMLNodePtr output_node = NULL) { //#pragma message("Generating LLUICtrlFactory::createFromFile") T* widget = NULL; @@ -283,7 +331,7 @@ public: goto fail; } - LLView* view = getInstance()->createFromXML(root_node, parent, filename, output_node, getWidgetRegistry(parent)); + LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, output_node); if (view) { widget = dynamic_cast<T*>(view); @@ -304,8 +352,8 @@ fail: template<class T> static T* getDefaultWidget(const std::string& name) { - dummy_widget_creator_func_t* dummy_func = LLDummyWidgetRegistry::instance().getValue(&typeid(T)); - return dynamic_cast<T*>((*dummy_func)(name)); + dummy_widget_creator_func_t* dummy_func = LLDefaultWidgetRegistry::instance().getValue(&typeid(T)); + return dummy_func ? dynamic_cast<T*>((*dummy_func)(name)) : NULL; } template <class T> @@ -317,23 +365,23 @@ fail: return create<T>(params); } - template<typename T, typename PARAM_BLOCK> + template<typename T> static T* defaultBuilder(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { LLFastTimer timer(FTM_WIDGET_SETUP); //#pragma message("Generating LLUICtrlFactory::defaultBuilder") - PARAM_BLOCK params(getDefaultParams<PARAM_BLOCK>()); + typename T::Params params(getDefaultParams<T>()); LLXUIParser::instance().readXUI(node, params); if (output_node) { // We always want to output top-left coordinates - PARAM_BLOCK output_params(params); + typename T::Params output_params(params); T::setupParamsForExport(output_params, parent); // Export only the differences between this any default params - PARAM_BLOCK default_params(getDefaultParams<PARAM_BLOCK>()); + typename T::Params default_params(getDefaultParams<T>()); output_node->setName(node->getName()->mString); LLXUIParser::instance().writeXUI( output_node, output_params, &default_params); @@ -361,8 +409,10 @@ fail: S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : -1; setCtrlParent(widget, parent, tab_group); } + + typedef typename T::child_registry_t registry_t; - createChildren(widget, node, output_node); + createChildren(widget, node, registry_t::instance(), output_node); if (!widget->postBuild()) { @@ -373,7 +423,7 @@ fail: return widget; } - static void createChildren(LLView* viewp, LLXMLNodePtr node, LLXMLNodePtr output_node = NULL); + static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL); static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root); @@ -395,20 +445,32 @@ private: std::vector<std::string> mFileNames; }; +template<typename T> +const LLInitParam::BaseBlock& getEmptyParamBlock() +{ + static typename T::Params params; + return params; +} + // this is here to make gcc happy with reference to LLUICtrlFactory template<typename DERIVED> -template<typename T, typename PARAM_BLOCK> -LLWidgetRegistry<DERIVED>::Register<T, PARAM_BLOCK>::Register(const char* tag, LLWidgetCreatorFunc func) -: LLWidgetRegistry<DERIVED>::StaticRegistrar(tag, func.empty() ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T, PARAM_BLOCK> : func) +template<typename T> +LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreatorFunc func) +: LLChildRegistry<DERIVED>::StaticRegistrar(tag, func.empty() ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T> : func) { + const std::type_info* widget_type_infop = &typeid(T); // associate parameter block type with template .xml file - LLWidgetTemplateRegistry::instance().defaultRegistrar().add(&typeid(PARAM_BLOCK), tag); + LLWidgetNameRegistry ::instance().defaultRegistrar().add(&typeid(typename T::Params), tag); // associate widget type with factory function - LLDummyWidgetRegistry::instance().defaultRegistrar().add(&typeid(T), &LLUICtrlFactory::createDefaultWidget<T>); + LLDefaultWidgetRegistry::instance().defaultRegistrar().add(widget_type_infop, &LLUICtrlFactory::createDefaultWidget<T>); + LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type_infop); + LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type_infop, &getEmptyParamBlock<T>); + typedef typename T::child_registry_t registry_t; + LLChildRegistryRegistry::instance().defaultRegistrar().add(widget_type_infop, registry_t::instance()); } -typedef boost::function<LLPanel* (void)> LLPannelClassCreatorFunc; +typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc; // local static instance for registering a particular panel class @@ -417,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(); } @@ -437,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/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp index 8e0de0cb0c..ab0d65e731 100644 --- a/indra/llui/lluiimage.cpp +++ b/indra/llui/lluiimage.cpp @@ -39,7 +39,7 @@ #include "lluiimage.h" #include "llui.h" -LLUIImage::LLUIImage(const std::string& name, LLPointer<LLImageGL> image) : +LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image) : mName(name), mImage(image), mScaleRegion(0.f, 1.f, 1.f, 0.f), @@ -74,7 +74,7 @@ void LLUIImage::setScaleRegion(const LLRectf& region) //TODO: move drawing implementation inside class void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const { - gl_draw_image(x, y, mImage, color, mClipRegion); + gl_draw_scaled_image(x, y, getWidth(), getHeight(), mImage, color, mClipRegion); } void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h index e35026cd3d..4ec24e98dc 100644 --- a/indra/llui/lluiimage.h +++ b/indra/llui/lluiimage.h @@ -33,26 +33,28 @@ #ifndef LL_LLUIIMAGE_H #define LL_LLUIIMAGE_H -//#include "llgl.h" -#include "llimagegl.h" +#include "v4color.h" +#include "llpointer.h" +#include "llrefcount.h" #include "llrefcount.h" #include "llrect.h" #include <boost/function.hpp> #include "llinitparam.h" +#include "lltexture.h" extern const LLColor4 UI_VERTEX_COLOR; class LLUIImage : public LLRefCount { public: - LLUIImage(const std::string& name, LLPointer<LLImageGL> image); + LLUIImage(const std::string& name, LLPointer<LLTexture> image); virtual ~LLUIImage(); void setClipRegion(const LLRectf& region); void setScaleRegion(const LLRectf& region); - LLPointer<LLImageGL> getImage() { return mImage; } - const LLPointer<LLImageGL>& getImage() const { return mImage; } + LLPointer<LLTexture> getImage() { return mImage; } + const LLPointer<LLTexture>& getImage() const { return mImage; } void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const; void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const; @@ -60,11 +62,11 @@ public: void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const; void drawSolid(const LLRect& rect, const LLColor4& color) const { drawSolid(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); } - void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, mImage->getWidth(0), mImage->getHeight(0), color); } + void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, getWidth(), getHeight(), color); } void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const; void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); } - void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, mImage->getWidth(0), mImage->getHeight(0), color, border_width); } + void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); } const std::string& getName() const { return mName; } @@ -79,7 +81,7 @@ protected: std::string mName; LLRectf mScaleRegion; LLRectf mClipRegion; - LLPointer<LLImageGL> mImage; + LLPointer<LLTexture> mImage; BOOL mUniformScaling; BOOL mNoClip; }; @@ -95,8 +97,8 @@ namespace LLInitParam public: Optional<std::string> name; - TypedParam(BlockDescriptor& descriptor, const char* name, super_t::value_assignment_t value, ParamDescriptor::validation_func_t func) - : super_t(descriptor, name, value, func) + TypedParam(BlockDescriptor& descriptor, const char* name, super_t::value_assignment_t value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count) { } diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index d225ad2767..2f9a6e7d46 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -99,10 +99,15 @@ LLView::Params::Params() left_delta("left_delta", S32_MAX), center_horiz("center_horiz", false), center_vert("center_vert", false), - serializable("", false), + from_xui("from_xui", false), user_resize("user_resize"), auto_resize("auto_resize"), - needs_translate("translate") + needs_translate("translate"), + xmlns("xmlns"), + xmlns_xsi("xmlns:xsi"), + xsi_schemaLocation("xsi:schemaLocation"), + xsi_type("xsi:type") + { addSynonym(rect, ""); } @@ -111,7 +116,7 @@ LLView::LLView(const LLView::Params& p) : mName(p.name), mParentView(NULL), mReshapeFlags(FOLLOWS_NONE), - mSaveToXML(p.serializable), + mSaveToXML(p.from_xui), mIsFocusRoot(FALSE), mLastVisible(FALSE), mNextInsertionOrdinal(0), @@ -396,32 +401,28 @@ bool LLCompareByTabOrder::operator() (const LLView* const a, const LLView* const return (a_score == b_score) ? a < b : a_score < b_score; } -BOOL LLView::isInVisibleChain() const +bool LLView::trueToRoot(const boost::function<bool (const LLView*)>& predicate) const { const LLView* cur_view = this; while(cur_view) { - if (!cur_view->getVisible()) + if(!predicate(cur_view)) { - return FALSE; + return false; } cur_view = cur_view->getParent(); } - return TRUE; + return true; +} + +BOOL LLView::isInVisibleChain() const +{ + return trueToRoot(&LLView::getVisible); } BOOL LLView::isInEnabledChain() const { - const LLView* cur_view = this; - while(cur_view) - { - if (!cur_view->getEnabled()) - { - return FALSE; - } - cur_view = cur_view->getParent(); - } - return TRUE; + return trueToRoot(&LLView::getEnabled); } // virtual @@ -738,12 +739,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_s msg = tool_tip; // Convert rect local to screen coordinates - localPointToScreen( - 0, 0, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - mRect.getWidth(), mRect.getHeight(), - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); + *sticky_rect_screen = calcScreenRect(); } // don't allow any siblings to handle this event // even if we don't have a tooltip @@ -1325,13 +1321,6 @@ void LLView::draw() LLRect rootRect = getRootView()->getRect(); LLRect screenRect; - // draw focused control on top of everything else - LLView* focus_view = gFocusMgr.getKeyboardFocus(); - if (focus_view && focus_view->getParent() != this) - { - focus_view = NULL; - } - ++sDepth; for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend();) // ++child_iter) @@ -1339,7 +1328,7 @@ void LLView::draw() child_list_reverse_iter_t child = child_iter++; LLView *viewp = *child; - if (viewp->getVisible() && viewp != focus_view && viewp->getRect().isValid()) + if (viewp->getVisible() && viewp->getRect().isValid()) { // Only draw views that are within the root view localRectToScreen(viewp->getRect(),&screenRect); @@ -1357,11 +1346,6 @@ void LLView::draw() } --sDepth; - - if (focus_view && focus_view->getVisible()) - { - drawChild(focus_view); - } } gGL.getTexUnit(0)->disable(); @@ -1398,7 +1382,7 @@ void LLView::drawDebugRect() } else { - static LLUICachedControl<LLColor4> scroll_highlighted_color ("ScrollHighlightedColor", *(new LLColor4)); + static LLUIColor scroll_highlighted_color = LLUIColorTable::instance().getColor("ScrollHighlightedColor"); border_color = scroll_highlighted_color; } } @@ -2303,13 +2287,6 @@ LLControlVariable *LLView::findControl(const std::string& name) return control_group.getControl(name); } -const widget_registry_t& LLView::getChildRegistry() const -{ - static widget_registry_t empty_registry; - return empty_registry; -} - - const S32 FLOATER_H_MARGIN = 15; const S32 MIN_WIDGET_HEIGHT = 10; const S32 VPAD = 4; @@ -2430,7 +2407,7 @@ void LLView::setupParams(LLView::Params& p, LLView* parent) const S32 VPAD = 4; const S32 MIN_WIDGET_HEIGHT = 10; - p.serializable(true); + p.from_xui(true); // *NOTE: This will confuse export of floater/panel coordinates unless // the default is also "topleft". JC diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 422f62f602..9138b04258 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -138,6 +138,9 @@ virtual BOOL handleUnicodeCharHere(llwchar uni_char); * */ +class LLViewWidgetRegistry : public LLChildRegistry<LLViewWidgetRegistry> +{}; + class LLView : public LLMouseHandler, public LLMortician { public: @@ -157,15 +160,16 @@ public: Mandatory<std::string> name; Optional<bool> enabled, - visible; - Optional<bool> mouse_opaque; - Optional<bool> use_bounding_rect; + visible, + mouse_opaque, + use_bounding_rect; + Optional<S32> tab_group, default_tab_group; Optional<std::string> tool_tip; Optional<S32> sound_flags; - Optional<bool> serializable; + Optional<bool> from_xui; Optional<Follows> follows; Optional<std::string> hover_cursor; @@ -192,10 +196,17 @@ public: //FIXME: get parent context involved in parsing traversal Ignored user_resize, auto_resize, - needs_translate; + needs_translate, + xmlns, + xmlns_xsi, + xsi_schemaLocation, + xsi_type; Params(); }; + + typedef LLViewWidgetRegistry child_registry_t; + void initFromParams(const LLView::Params&); protected: @@ -310,6 +321,7 @@ public: S32 getDefaultTabGroup() const { return mDefaultTabGroup; } S32 getLastTabGroup() { return mLastTabGroup; } + bool trueToRoot(const boost::function<bool (const LLView*)>& predicate) const; BOOL isInVisibleChain() const; BOOL isInEnabledChain() const; @@ -496,9 +508,6 @@ public: return dynamic_cast<T*>(found_it->second); } - // determines allowable children when parsing XUI - virtual const widget_registry_t& getChildRegistry() const; - ////////////////////////////////////////////// // statics ////////////////////////////////////////////// @@ -647,6 +656,9 @@ template <class T> T* LLView::getChild(const std::string& name, BOOL recurse, BO if (result) { + // *NOTE: You cannot call mFoo = getChild<LLFoo>("bar") + // in a floater or panel constructor. The widgets will not + // be ready. Instead, put it in postBuild(). llwarns << "Making dummy " << typeid(T).name() << " named \"" << name << "\" in " << getName() << llendl; } else diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp index a5b09671bb..860aa3302e 100644 --- a/indra/llui/llviewborder.cpp +++ b/indra/llui/llviewborder.cpp @@ -35,7 +35,7 @@ #include "llfocusmgr.h" #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLViewBorder> r("view_border"); +static LLDefaultChildRegistry::Register<LLViewBorder> r("view_border"); void LLViewBorder::BevelValues::declareValues() { @@ -52,7 +52,7 @@ void LLViewBorder::StyleValues::declareValues() } LLViewBorder::Params::Params() -: bevel_type("bevel_style", BEVEL_OUT), +: bevel_style("bevel_style", BEVEL_OUT), render_style("border_style", STYLE_LINE), border_thickness("border_thickness"), highlight_light_color("highlight_light_color"), @@ -60,6 +60,8 @@ LLViewBorder::Params::Params() shadow_light_color("shadow_light_color"), shadow_dark_color("shadow_dark_color") { + addSynonym(border_thickness, "thickness"); + addSynonym(render_style, "style"); name = "view_border"; mouse_opaque = false; follows.flags = FOLLOWS_ALL; @@ -75,7 +77,7 @@ LLViewBorder::LLViewBorder(const LLViewBorder::Params& p) mHighlightDark(p.highlight_dark_color()), mShadowLight(p.shadow_light_color()), mShadowDark(p.shadow_dark_color()), - mBevel(p.bevel_type), + mBevel(p.bevel_style), mStyle(p.render_style) {} diff --git a/indra/llui/llviewborder.h b/indra/llui/llviewborder.h index 37e13fb181..92fd569325 100644 --- a/indra/llui/llviewborder.h +++ b/indra/llui/llviewborder.h @@ -55,7 +55,7 @@ public: struct Params : public LLInitParam::Block<Params, LLView::Params> { - Optional<EBevel, BevelValues> bevel_type; + Optional<EBevel, BevelValues> bevel_style; Optional<EStyle, StyleValues> render_style; Optional<S32> border_thickness; |