diff options
| author | Palmer <palmer@lindenlab.com> | 2009-08-06 14:51:11 -0700 | 
|---|---|---|
| committer | Palmer <palmer@lindenlab.com> | 2009-08-06 14:51:11 -0700 | 
| commit | b2632c50efc12eacdcadace64e6c0f1906b86ff6 (patch) | |
| tree | c32d7e9b29e37d5c30ac16dfac55733456d7eee0 /indra/llui | |
| parent | 27cf39cdbf27fe52dcf9c70cfdadcc18ddf2e75c (diff) | |
| parent | a8d216e194327c7bee8a42c983f7f2ca01adb385 (diff) | |
Merge of my DEV-36732 work and all the main line login api work that went on.
Diffstat (limited to 'indra/llui')
94 files changed, 2723 insertions, 1720 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..f8c6204afb 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -33,8 +33,6 @@  // A control that displays the name of the chosen item, which when  // clicked shows a scrolling box of options. -#define INSTANTIATE_GETCHILD_COMBOBOX -  #include "linden_common.h"  // file includes @@ -63,9 +61,7 @@ S32 LLCOMBOBOX_HEIGHT = 0;  S32 LLCOMBOBOX_WIDTH = 0;  S32 MAX_COMBO_WIDTH = 500; -template LLComboBox* LLView::getChild<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,32 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)  	mPrearrangeCallback(p.prearrange_callback()),  	mTextEntryCallback(p.text_entry_callback()),  	mSelectionCallback(p.selection_callback()), -	mArrowImage(p.arrow_image), -	mListPosition(p.list_position) +	mListPosition(p.list_position), +	mLastSelectedIndex(-1)  {  	// Text label button -	LLButton::Params button_params = p.combo_button; +	LLButton::Params button_params = (mAllowTextEntry ? p.combo_button : p.drop_down_button);  	button_params.mouse_down_callback.function(boost::bind(&LLComboBox::onButtonDown, this));  	button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT);  	button_params.rect(p.rect); -	button_params.pad_right(2); + +	if(mAllowTextEntry) +	{ +		button_params.pad_right(2); +	} + +	mArrowImage = button_params.image_unselected;  	mButton = LLUICtrlFactory::create<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 +144,7 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)  		LLScrollListItem::Params item_params = *it;  		if (it->label.isProvided())  		{ -			item_params.cells.add().value(it->label()); +			item_params.columns.add().value(it->label());  		}  		mList->addRow(item_params); @@ -424,7 +433,8 @@ void LLComboBox::setButtonVisible(BOOL visible)  		LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);  		if (visible)  		{ -			text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * drop_shadow_button; +			S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0; +			text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;  		}  		//mTextEntry->setRect(text_entry_rect);  		mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE); @@ -466,14 +476,15 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p)  	LLRect rect = getLocalRect();  	if (mAllowTextEntry)  	{ +		S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;  		S32 shadow_size = drop_shadow_button; -		mButton->setRect(LLRect( getRect().getWidth() - llmax(8,mArrowImage->getWidth()) - 2 * shadow_size, +		mButton->setRect(LLRect( getRect().getWidth() - llmax(8,arrow_width) - 2 * shadow_size,  								rect.mTop, rect.mRight, rect.mBottom));  		mButton->setTabStop(FALSE);  		mButton->setHAlign(LLFontGL::HCENTER);  		LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); -		text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * drop_shadow_button; +		text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;  		// clear label on button  		std::string cur_label = mButton->getLabelSelected();  		LLLineEditor::Params params = p.combo_editor; @@ -615,15 +626,15 @@ void LLComboBox::showList()  	mList->setVisible(TRUE);  	setUseBoundingRect(TRUE); + +	mList->sortItems(); +	mLastSelectedIndex = mList->getFirstSelectedIndex();  }  void LLComboBox::hideList()  { -	//*HACK: store the original value explicitly somewhere, not just in label -	std::string orig_selection = mAllowTextEntry ? mTextEntry->getText() : mButton->getLabelSelected(); -  	// assert selection in list -	mList->selectItemByLabel(orig_selection, FALSE); +	mList->selectNthItem(mLastSelectedIndex);  	mButton->setToggleState(FALSE);  	mList->setVisible(FALSE); @@ -681,6 +692,7 @@ void LLComboBox::onItemSelected(const LLSD& data)  	const std::string name = mList->getSelectedItemLabel();  	S32 cur_id = getCurrentIndex(); +	mLastSelectedIndex = cur_id;  	if (cur_id != -1)  	{  		setLabel(name); @@ -732,12 +744,7 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_re  		msg = tool_tip;  		// Convert rect local to screen coordinates -		localPointToScreen(  -			0, 0,  -			&(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); -		localPointToScreen( -			getRect().getWidth(), getRect().getHeight(), -			&(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); +		*sticky_rect_screen = calcScreenRect();  	}  	return TRUE;  } diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index bc98690a01..db97b0df75 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -39,7 +39,6 @@  #include "llbutton.h"  #include "lluictrl.h"  #include "llctrlselectioninterface.h" -#include "llimagegl.h"  #include "llrect.h"  #include "llscrolllistctrl.h"  #include "lllineeditor.h" @@ -84,7 +83,6 @@ public:  		Optional<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(); @@ -232,13 +232,6 @@ private:  	commit_callback_t	mPrearrangeCallback;  	commit_callback_t	mTextEntryCallback;  	commit_callback_t	mSelectionCallback; +	S32                 mLastSelectedIndex;  }; - -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_COMBOBOX -#pragma warning (disable : 4231) -extern template LLComboBox* LLView::getChild<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..d420d1141e 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -66,29 +66,37 @@ const S32 TABBED_FLOATER_OFFSET = 0;  std::string	LLFloater::sButtonActiveImageNames[BUTTON_COUNT] =   { -	"closebox.tga",		//BUTTON_CLOSE +	"Icon_Close_Foreground",		//BUTTON_CLOSE  	"restore.tga",	//BUTTON_RESTORE  	"minimize.tga",	//BUTTON_MINIMIZE  	"tearoffbox.tga",	//BUTTON_TEAR_OFF  	"closebox.tga",		//BUTTON_EDIT +	"Icon_Dock_Foreground", +	"Icon_Undock_Foreground"  }; -std::string	LLFloater::sButtonInactiveImageNames[BUTTON_COUNT] =  +// Empty string means programmatic glow effect, achieved by +// not setting explicit image. +std::string	LLFloater::sButtonHoveredImageNames[BUTTON_COUNT] =   { -	"close_inactive_blue.tga",	//BUTTON_CLOSE -	"restore_inactive.tga",	//BUTTON_RESTORE -	"minimize_inactive.tga",	//BUTTON_MINIMIZE -	"tearoffbox.tga",	//BUTTON_TEAR_OFF -	"close_inactive_blue.tga",	//BUTTON_EDIT +	"",						//BUTTON_CLOSE +	"restore_pressed.tga",	//BUTTON_RESTORE +	"minimize_pressed.tga",	//BUTTON_MINIMIZE +	"tearoff_pressed.tga",	//BUTTON_TEAR_OFF +	"close_in_blue.tga",	//BUTTON_EDIT +	"",						//BUTTON_DOCK +	"",						//BUTTON_UNDOCK  };  std::string	LLFloater::sButtonPressedImageNames[BUTTON_COUNT] =   { -	"close_in_blue.tga",		//BUTTON_CLOSE +	"Icon_Close_Press",		//BUTTON_CLOSE  	"restore_pressed.tga",	//BUTTON_RESTORE  	"minimize_pressed.tga",	//BUTTON_MINIMIZE  	"tearoff_pressed.tga",	//BUTTON_TEAR_OFF  	"close_in_blue.tga",		//BUTTON_EDIT +	"Icon_Dock_Press", +	"Icon_Undock_Press"  };  std::string	LLFloater::sButtonNames[BUTTON_COUNT] =  @@ -98,22 +106,25 @@ std::string	LLFloater::sButtonNames[BUTTON_COUNT] =  	"llfloater_minimize_btn",	//BUTTON_MINIMIZE  	"llfloater_tear_off_btn",	//BUTTON_TEAR_OFF  	"llfloater_edit_btn",		//BUTTON_EDIT +	"llfloater_dock_btn", +	"llfloater_undock_btn"  }; -std::string LLFloater::sButtonToolTips[BUTTON_COUNT] = {}; - +std::string LLFloater::sButtonToolTips[BUTTON_COUNT];  std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]=  {  #ifdef LL_DARWIN -	"BUTTON_CLOSE_DARWIN",//LLTrans::getString("BUTTON_CLOSE_DARWIN"), //"Close (Cmd-W)",	//BUTTON_CLOSE +	"BUTTON_CLOSE_DARWIN",	//"Close (Cmd-W)",	//BUTTON_CLOSE  #else -	"BUTTON_CLOSE_WIN", //LLTrans::getString("BUTTON_CLOSE_WIN"), //"Close (Ctrl-W)",	//BUTTON_CLOSE +	"BUTTON_CLOSE_WIN",		//"Close (Ctrl-W)",	//BUTTON_CLOSE  #endif -	"BUTTON_RESTORE",//LLTrans::getString("BUTTON_RESTORE"), //"Restore",	//BUTTON_RESTORE -	"BUTTON_MINIMIZE",//LLTrans::getString("BUTTON_MINIMIZE"),	//"Minimize",	//BUTTON_MINIMIZE -	"BUTTON_TEAR_OFF",//LLTrans::getString("BUTTON_TEAR_OFF"),	//"Tear Off",	//BUTTON_TEAR_OFF -	"BUTTON_EDIT", //LLTrans::getString("BUTTON_EDIT"), //	"Edit",		//BUTTON_EDIT +	"BUTTON_RESTORE",		//"Restore",	//BUTTON_RESTORE +	"BUTTON_MINIMIZE",		//"Minimize",	//BUTTON_MINIMIZE +	"BUTTON_TEAR_OFF",		//"Tear Off",	//BUTTON_TEAR_OFF +	"BUTTON_EDIT",			//"Edit",		//BUTTON_EDIT +	"BUTTON_DOCK", +	"BUTTON_UNDOCK"  };  LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] = @@ -123,10 +134,13 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =  	LLFloater::onClickMinimize, //BUTTON_MINIMIZE  	LLFloater::onClickTearOff,	//BUTTON_TEAR_OFF  	LLFloater::onClickEdit,	//BUTTON_EDIT +	LLFloater::onClickDock, +	LLFloater::onClickDock  };  LLMultiFloater* LLFloater::sHostp = NULL; -BOOL			LLFloater::sEditModeEnabled; +BOOL			LLFloater::sEditModeEnabled = FALSE; +BOOL			LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting  LLFloater::handle_map_t	LLFloater::sFloaterMap;  LLFloaterView* gFloaterView = NULL; @@ -188,12 +202,44 @@ bool LLFloater::KeyCompare::equate(const LLSD& a, const LLSD& b)  //************************************ +LLFloater::Params::Params() +:	title("title"), +	short_title("short_title"), +	single_instance("single_instance", false), +	auto_tile("auto_tile", false), +	can_resize("can_resize", false), +	can_minimize("can_minimize", true), +	can_close("can_close", true), +	can_drag_on_left("can_drag_on_left", false), +	can_tear_off("can_tear_off", true), +	save_rect("save_rect", false), +	save_visibility("save_visibility", false), +	open_callback("open_callback"), +	close_callback("close_callback"), +	can_dock("can_dock", false) +{ +	name = "floater"; +	// defaults that differ from LLPanel: +	background_visible = true; +	visible = false; +} + +  //static   const LLFloater::Params& LLFloater::getDefaultParams()  { -	return LLUICtrlFactory::getDefaultParams<LLFloater::Params>(); +	return LLUICtrlFactory::getDefaultParams<LLFloater>();  } +//static +void LLFloater::initClass() +{ +	// translate tooltips for floater buttons +	for (S32 i = 0; i < BUTTON_COUNT; i++) +	{ +		sButtonToolTips[i] = LLTrans::getString( sButtonToolTipsIndex[i] ); +	} +}  LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)  	:	LLPanel(), @@ -216,30 +262,21 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)  		mEditing(FALSE),  		mButtonScale(1.0f),  		mAutoFocus(TRUE), // automatically take focus when opened +		mCanDock(false), +		mDocked(false),  		mHasBeenDraggedWhileMinimized(FALSE),  		mPreviousMinimizedBottom(0),  		mPreviousMinimizedLeft(0),  		mNotificationContext(NULL)  { -	static LLUICachedControl<LLColor4> default_background_color ("FloaterDefaultBackgroundColor", *(new LLColor4)); -	static LLUICachedControl<LLColor4> focus_background_color ("FloaterFocusBackgroundColor", *(new LLColor4)); -	 -	for (S32 i = 0; i < BUTTON_COUNT; i++) -	{ -		sButtonToolTips[i] =LLTrans::getString( sButtonToolTipsIndex[i]); -	} +	static LLUIColor default_background_color = LLUIColorTable::instance().getColor("FloaterDefaultBackgroundColor"); +	static LLUIColor focus_background_color = LLUIColorTable::instance().getColor("FloaterFocusBackgroundColor");  	mHandle.bind(this);  	mNotificationContext = new LLFloaterNotificationContext(getHandle());  	mBgColorAlpha        = default_background_color;  	mBgColorOpaque       = focus_background_color; -	for (S32 i = 0; i < 4; i++)  -	{ -		mResizeBar[i] = NULL; -		mResizeHandle[i] = NULL; -	} -  	// Clicks stop here.  	setMouseOpaque(TRUE); @@ -288,6 +325,11 @@ void LLFloater::initFloater()  		mButtonsEnabled[BUTTON_MINIMIZE] = TRUE;  	} +	if(mCanDock) +	{ +		mButtonsEnabled[BUTTON_DOCK] = TRUE; +	} +  	buildButtons();  	// Floaters are created in the invisible state	 @@ -399,6 +441,9 @@ void LLFloater::addResizeCtrls()  	// Resize handles (corners)  	LLResizeHandle::Params handle_p; +	// handles must not be mouse-opaque, otherwise they block hover events +	// to other buttons like the close box. JC +	handle_p.mouse_opaque(false);  	handle_p.rect(LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0));  	handle_p.min_width(mMinWidth);  	handle_p.min_height(mMinHeight); @@ -473,7 +518,7 @@ void LLFloater::storeRectControl()  void LLFloater::storeVisibilityControl()  { -	if( mVisibilityControl.size() > 1 ) +	if( !sQuitting && mVisibilityControl.size() > 1 )  	{  		LLUI::sSettingGroups["floater"]->setBOOL( mVisibilityControl, getVisible() );  	} @@ -481,7 +526,7 @@ void LLFloater::storeVisibilityControl()  void LLFloater::setVisible( BOOL visible )  { -	LLPanel::setVisible(visible); +	LLPanel::setVisible(visible); // calls handleVisibilityChange()  	if( visible && mFirstLook )  	{  		mFirstLook = FALSE; @@ -516,14 +561,14 @@ void LLFloater::setVisible( BOOL visible )  }  // virtual -void LLFloater::onVisibilityChange ( BOOL new_visibility ) +void LLFloater::handleVisibilityChange ( BOOL new_visibility )  {  	if (new_visibility)  	{  		if (getHost())  			getHost()->setFloaterFlashing(this, FALSE);  	} -	LLPanel::onVisibilityChange ( new_visibility ); +	LLPanel::handleVisibilityChange ( new_visibility );  }  void LLFloater::openFloater(const LLSD& key) @@ -560,11 +605,17 @@ void LLFloater::openFloater(const LLSD& key)  		setVisibleAndFrontmost(mAutoFocus);  	} +	mOpenSignal(this, key);  	onOpen(key);  }  void LLFloater::closeFloater(bool app_quitting)  { +	if (app_quitting) +	{ +		LLFloater::sQuitting = true; +	} +	  	// Always unminimize before trying to close.  	// Most of the time the user will never see this state.  	setMinimized(FALSE); @@ -622,8 +673,27 @@ void LLFloater::closeFloater(bool app_quitting)  			}  		} -		// Let floater do cleanup. -		onClose(app_quitting); +		// Close callback +		mCloseSignal(this, LLSD(app_quitting)); +		 +		// Hide or Destroy +		if (mSingleInstance) +		{ +			// Hide the instance +			if (getHost()) +			{ +				getHost()->setVisible(FALSE); +			} +			else +			{ +				setVisible(FALSE); +			} +		} +		else +		{ +			setVisible(FALSE); // hide before destroying (so handleVisibilityChange() gets called) +			destroy(); +		}  	}  } @@ -1296,6 +1366,36 @@ void LLFloater::setFrontmost(BOOL take_focus)  	}  } +void LLFloater::setCanDock(bool b) +{ +	if(b != mCanDock) +	{ +		mCanDock = b; +		if(mCanDock) +		{ +			mButtonsEnabled[BUTTON_DOCK] = !mDocked; +			mButtonsEnabled[BUTTON_UNDOCK] = mDocked; +		} +		else +		{ +			mButtonsEnabled[BUTTON_DOCK] = FALSE; +			mButtonsEnabled[BUTTON_UNDOCK] = FALSE; +		} +	} +	updateButtons(); +} + +void LLFloater::setDocked(bool docked, bool pop_on_undock) +{ +	if(docked != mDocked && mCanDock) +	{ +		mDocked = docked; +		mButtonsEnabled[BUTTON_DOCK] = !mDocked; +		mButtonsEnabled[BUTTON_UNDOCK] = mDocked; +		updateButtons(); +	} +} +  //static  void LLFloater::setEditModeEnabled(BOOL enable)  { @@ -1372,6 +1472,15 @@ void LLFloater::onClickEdit(LLFloater* self)  	self->mEditing = self->mEditing ? FALSE : TRUE;  } +// static +void LLFloater::onClickDock(LLFloater* self) +{ +	if(self && self->mCanDock) +	{ +		self->setDocked(!self->mDocked, true); +	} +} +  // static   LLFloater* LLFloater::getClosableFloaterFromFocus()  { @@ -1449,7 +1558,7 @@ void LLFloater::draw()  		S32 bottom = LLPANEL_BORDER_WIDTH;  		static LLUICachedControl<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 +1583,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 +1642,10 @@ void LLFloater::draw()  	{  		// add in a border to improve spacialized visual aclarity ;)  		// use lines instead of gl_rect_2d so we can round the edges as per james' recommendation -		static LLUICachedControl<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);  	} @@ -1692,14 +1801,24 @@ void LLFloater::buildButtons()  		p.rect(btn_rect);  		p.label("");  		p.image_unselected.name(sButtonActiveImageNames[i]); +		// Selected, no matter if hovered or not, is "pressed"  		p.image_selected.name(sButtonPressedImageNames[i]);  		p.image_hover_selected.name(sButtonPressedImageNames[i]); -		p.image_hover_unselected.name(sButtonPressedImageNames[i]); +		// Empty string means programmatic glow effect, achieved by +		// not setting explicit image. +		if (sButtonHoveredImageNames[i].empty()) +		{ +			// These icons are really small, need glow amount increased +			p.hover_glow_amount( 0.22f ); +		} +		else +		{ +			p.image_hover_unselected.name(sButtonHoveredImageNames[i]); +		}  		p.click_callback.function(boost::bind(sButtonCallbacks[i], this));  		p.tab_stop(false);  		p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT);  		p.tool_tip(sButtonToolTips[i]); -		p.image_color(LLUI::getCachedColorFunctor("FloaterButtonImageColor"));  		p.scale_image(true);  		LLButton* buttonp = LLUICtrlFactory::create<LLButton>(p); @@ -2149,7 +2268,8 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out  	// convert to local coordinate frame  	LLRect snap_rect_local = getLocalSnapRect(); -	if( floater->isResizable() ) +	// only automatically resize non-minimized, resizable floaters +	if( floater->isResizable() && !floater->isMinimized() )  	{  		LLRect view_rect = floater->getRect();  		S32 old_width = view_rect.getWidth(); @@ -2447,6 +2567,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p)  	setCanTearOff(p.can_tear_off);  	setCanMinimize(p.can_minimize);  	setCanClose(p.can_close); +	setCanDock(p.can_dock);  	mDragOnLeft = p.can_drag_on_left;  	mResizable = p.can_resize; @@ -2463,18 +2584,25 @@ void LLFloater::initFromParams(const LLFloater::Params& p)  	{  		mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set  	} +	 +	// open callback  +	if (p.open_callback.isProvided()) +		initCommitCallback(p.open_callback, mOpenSignal); +	// close callback  +	if (p.close_callback.isProvided()) +		initCommitCallback(p.close_callback, mCloseSignal);  } -void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floater, LLXMLNodePtr output_node) +void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)  { -	Params params(LLUICtrlFactory::getDefaultParams<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 +2619,7 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floa  		LLFloater::setFloaterHost((LLMultiFloater*) this);  	} -	LLUICtrlFactory::createChildren(this, node, output_node); +	LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node);  	if (node->hasName("multi_floater"))  	{ @@ -2508,38 +2636,6 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floa  	applyRectControl(); // If we have a saved rect control, apply it  	gFloaterView->adjustToFitScreen(this, FALSE); // Floaters loaded from XML should all fit on screen	 -	if (open_floater) -	{ -		this->openFloater(getKey()); -	} -  	moveResizeHandlesToFront();  } -// visibility methods -bool VisibilityPolicy<LLFloater>::visible(LLFloater* instance, const LLSD& key) -{ -	if (instance)  -	{ -		return !instance->isMinimized() && instance->isInVisibleChain(); -	} -	return FALSE; -} - -void VisibilityPolicy<LLFloater>::show(LLFloater* instance, const LLSD& key) -{ -	if (instance)  -	{ -		instance->openFloater(key); -		if (instance->getHost()) -		{ -			instance->getHost()->openFloater(key); -		} -	} -} - -void VisibilityPolicy<LLFloater>::hide(LLFloater* instance, const LLSD& key) -{ -	if (instance) instance->closeFloater(); -} - diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 3e80f1b284..ee066317e0 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -97,11 +97,13 @@ public:  	enum EFloaterButtons  	{ -		BUTTON_CLOSE, +		BUTTON_CLOSE = 0,  		BUTTON_RESTORE,  		BUTTON_MINIMIZE,  		BUTTON_TEAR_OFF,  		BUTTON_EDIT, +		BUTTON_DOCK, +		BUTTON_UNDOCK,  		BUTTON_COUNT  	}; @@ -119,32 +121,22 @@ public:  								can_drag_on_left,  								can_tear_off,  								save_rect, -								save_visibility; - -		Params() : -			title("title"), -			short_title("short_title"), -			single_instance("single_instance", false), -			auto_tile("auto_tile", false), -			can_resize("can_resize", false), -			can_minimize("can_minimize", true), -			can_close("can_close", true), -			can_drag_on_left("can_drag_on_left", false), -			can_tear_off("can_tear_off", true), -			save_rect("save_rect", false), -			save_visibility("save_visibility", false) -		{ -			name = "floater"; -			// defaults that differ from LLPanel: -			background_visible = true; -			visible = false; -		} +								save_visibility, +								can_dock; +		 +		Optional<CommitCallbackParam> open_callback, +									  close_callback; +		 +		Params();  	};  	// use this to avoid creating your own default LLFloater::Param instance  	static const Params& getDefaultParams(); -	LLFloater(const LLSD& key = LLSD(), const Params& params = getDefaultParams()); +	// Load translations for tooltips for standard buttons +	static void initClass(); + +	LLFloater(const LLSD& key, const Params& params = getDefaultParams());  	virtual ~LLFloater(); @@ -152,7 +144,7 @@ public:  	static void setupParamsForExport(Params& p, LLView* parent);  	void initFromParams(const LLFloater::Params& p); -	void initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floater = TRUE, LLXMLNodePtr output_node = NULL); +	void initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL);  	/*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);  	/*virtual*/ BOOL canSnapTo(const LLView* other_view); @@ -166,7 +158,6 @@ public:  	void			openFloater(const LLSD& key = LLSD());  	// If allowed, close the floater cleanly, releasing focus. -	// app_quitting is passed to onClose() below.  	void			closeFloater(bool app_quitting = false);  	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -216,20 +207,16 @@ public:  	virtual BOOL	handleDoubleClick(S32 x, S32 y, MASK mask);  	virtual BOOL	handleMiddleMouseDown(S32 x, S32 y, MASK mask);  	virtual void	draw(); - +	 +	// *TODO: Eliminate this in favor of mOpenSignal  	virtual void	onOpen(const LLSD& key) {} -	// Call destroy() to free memory, or setVisible(FALSE) to keep it -	// If app_quitting, you might not want to save your visibility. -	// Defaults to destroy(). -	virtual void	onClose(bool app_quitting) { destroy(); } -  	// This cannot be "const" until all derived floater canClose()  	// methods are const as well.  JC  	virtual BOOL	canClose() { return TRUE; } -	virtual void	setVisible(BOOL visible); -	virtual void	onVisibilityChange ( BOOL curVisibilityIn ); +	/*virtual*/ void setVisible(BOOL visible); // do not override +	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // do not override  	void			setFrontmost(BOOL take_focus = TRUE); @@ -245,6 +232,14 @@ public:  	LLHandle<LLFloater> getHandle() const { return mHandle; }  	const LLSD& 	getKey() { return mKey; }  	BOOL		 	matchesKey(const LLSD& key) { return mSingleInstance || KeyCompare::equate(key, mKey); } +	 +	const std::string& getInstanceName() { return mInstanceName; } +	 +	bool            isDockable() const { return mCanDock; } +	void            setCanDock(bool b); + +	bool            isDocked() const { return mDocked; } +	virtual void    setDocked(bool docked, bool pop_on_undock = true);  	// Return a closeable floater, if any, given the current focus.  	static LLFloater* getClosableFloaterFromFocus();  @@ -262,6 +257,7 @@ public:  	static void		onClickMinimize(LLFloater* floater);  	static void		onClickTearOff(LLFloater* floater);  	static void		onClickEdit(LLFloater* floater); +	static void     onClickDock(LLFloater* floater);  	static void		setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; }  	static void		setEditModeEnabled(BOOL enable); @@ -287,10 +283,9 @@ protected:  	void			setAutoFocus(BOOL focus) { mAutoFocus = focus; } // whether to automatically take focus when opened  	LLDragHandle*	getDragHandle() const { return mDragHandle; } -	void			destroy() { die(); } // Don't call this directly.  You probably want to call close(). JC +	void			destroy() { die(); } // Don't call this directly.  You probably want to call closeFloater()  private: -	  	void			setForeground(BOOL b);	// called only by floaterview  	void			cleanupHandles(); // remove handles to dead floaters  	void			createMinimizeButton(); @@ -299,18 +294,20 @@ private:  	BOOL			offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index);  	void			addResizeCtrls();  	void 			addDragHandle(); -	 +  protected:  	std::string		mRectControl;  	std::string		mVisibilityControl; -	 +	commit_signal_t mOpenSignal;		// Called when floater is opened, passes mKey +	commit_signal_t mCloseSignal;		// Called when floater is closed, passes app_qitting as LLSD()  	LLSD			mKey;				// Key used for retrieving instances; set (for now) by LLFLoaterReg -	 -private: -	LLRect			mExpandedRect; +  	LLDragHandle*	mDragHandle;  	LLResizeBar*	mResizeBar[4];  	LLResizeHandle*	mResizeHandle[4]; + +private: +	LLRect			mExpandedRect;  	LLUIString		mTitle;  	LLUIString		mShortTitle; @@ -349,10 +346,15 @@ private:  	LLHandle<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]; +	// Images to use when cursor hovered over an enabled button +	static std::string	sButtonHoveredImageNames[BUTTON_COUNT];  	static std::string	sButtonPressedImageNames[BUTTON_COUNT];  	static std::string	sButtonNames[BUTTON_COUNT];  	static std::string	sButtonToolTips[BUTTON_COUNT]; @@ -378,6 +380,7 @@ private:  	LLRootHandle<LLFloater>		mHandle;	  }; +  /////////////////////////////////////////////////////////////  // LLFloaterView  // Parent of all floating panels @@ -441,33 +444,6 @@ private:  	S32				mSnapOffsetRight;  }; -// singleton implementation for floaters -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=164990 - -//******************************************************* -//* TO BE DEPRECATED -//******************************************************* -// visibility policy specialized for floaters -template<> -class VisibilityPolicy<LLFloater> -{ -public: -	// visibility methods -	static bool visible(LLFloater* instance, const LLSD& key); - -	static void show(LLFloater* instance, const LLSD& key); - -	static void hide(LLFloater* instance, const LLSD& key); -}; - - -// singleton implementation for floaters (provides visibility policy) -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=164990 - -template <class T> class LLFloaterSingleton : public LLUISingleton<T, VisibilityPolicy<LLFloater> > -{ -}; -  //  // Globals  // diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index faa763cea9..a63b1b085c 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -121,8 +121,7 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)  				res = build_func(key); -				const bool DONT_OPEN_FLOATER = false; -				LLUICtrlFactory::getInstance()->buildFloater(res, xui_file, DONT_OPEN_FLOATER); +				LLUICtrlFactory::getInstance()->buildFloater(res, xui_file, NULL);  				// Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe  				res->mKey = key; @@ -363,6 +362,24 @@ std::string LLFloaterReg::declareVisibilityControl(const std::string& name)  	return controlname;  } +//static +void LLFloaterReg::registerControlVariables() +{ +	// Iterate through alll registered instance names and register rect and visibility control variables +	for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter) +	{ +		const std::string& name = iter->first; +		if (LLUI::sSettingGroups["floater"]->controlExists(getRectControlName(name))) +		{ +			declareRectControl(name); +		} +		if (LLUI::sSettingGroups["floater"]->controlExists(getVisibilityControlName(name))) +		{ +			declareVisibilityControl(name); +		} +	} +} +  // Callbacks  // static diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index ef2f71ad18..7edac43c96 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -120,6 +120,7 @@ public:  	static std::string declareRectControl(const std::string& name);  	static std::string getVisibilityControlName(const std::string& name);  	static std::string declareVisibilityControl(const std::string& name); +	static void registerControlVariables();  	// Callback wrappers  	static void initUICtrlToFloaterVisibilityControl(LLUICtrl* ctrl, const LLSD& sdname); diff --git a/indra/llui/llflyoutbutton.cpp b/indra/llui/llflyoutbutton.cpp index 8846f2a8c4..536919c072 100644 --- a/indra/llui/llflyoutbutton.cpp +++ b/indra/llui/llflyoutbutton.cpp @@ -35,7 +35,7 @@  // file includes  #include "llflyoutbutton.h" -//static LLDefaultWidgetRegistry::Register<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..e355cfda8b 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -49,12 +49,12 @@  #include "llmath.h"  #include "llrender.h"  #include "llfocusmgr.h" -#include "llfont.h"  #include "llcoord.h"  #include "llwindow.h"  #include "llcriticaldamp.h"  #include "lluictrlfactory.h" +#include "llbutton.h"  #include "llfontgl.h"  #include "llresmgr.h"  #include "llui.h" @@ -89,7 +89,6 @@ const U32 RIGHT_PAD_PIXELS = 2;  const U32 RIGHT_WIDTH_PIXELS = 15;  const U32 RIGHT_PLAIN_PIXELS = RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS; -const U32 ACCEL_PAD_PIXELS = 10;  const U32 PLAIN_PAD_PIXELS = LEFT_PAD_PIXELS + LEFT_WIDTH_PIXELS + RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS;  const U32 BRIEF_PAD_PIXELS = 2; @@ -119,16 +118,12 @@ const F32 PIE_SHRINK_TIME = 0.2f; // time of transition between unbounded and bo  const F32 ACTIVATE_HIGHLIGHT_TIME = 0.3f; -// widget registrars -struct MenuRegistry : public LLWidgetRegistry<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"); @@ -306,7 +301,7 @@ U32 LLMenuItemGL::getNominalHeight( void ) const  // Get the parent menu for this item -LLMenuGL* LLMenuItemGL::getMenu() +LLMenuGL* LLMenuItemGL::getMenu() const  {  	return (LLMenuGL*) getParent();  } @@ -330,7 +325,7 @@ U32 LLMenuItemGL::getNominalWidth( void ) const  	if( KEY_NONE != mAcceleratorKey )  	{ -		width += ACCEL_PAD_PIXELS; +		width += getMenu()->getShortcutPad();  		std::string temp;  		appendAcceleratorString( temp );  		width += mFont->getWidth( temp ); @@ -519,12 +514,13 @@ BOOL LLMenuItemGL::setLabelArg( const std::string& key, const LLStringExplicit&  	return TRUE;  } -void LLMenuItemGL::onVisibilityChange(BOOL new_visibility) +void LLMenuItemGL::handleVisibilityChange(BOOL new_visibility)  {  	if (getMenu())  	{  		getMenu()->needsArrange();  	} +	LLView::handleVisibilityChange(new_visibility);  }  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -797,6 +793,16 @@ BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask )  	return FALSE;  } +BOOL LLMenuItemCallGL::handleRightMouseUp(S32 x, S32 y, MASK mask) +{ +	if (pointInView(x, y)) +	{ +		mRightClickSignal(this, getValue()); +	} + +	return TRUE; +} +  ///============================================================================  /// Class LLMenuItemCheckGL  ///============================================================================ @@ -1061,13 +1067,13 @@ void LLMenuItemBranchGL::updateBranchParent(LLView* parentp)  	}  } -void LLMenuItemBranchGL::onVisibilityChange( BOOL new_visibility ) +void LLMenuItemBranchGL::handleVisibilityChange( BOOL new_visibility )  {  	if (new_visibility == FALSE && getBranch() && !getBranch()->getTornOff())  	{  		getBranch()->setVisible(FALSE);  	} -	LLMenuItemGL::onVisibilityChange(new_visibility); +	LLMenuItemGL::handleVisibilityChange(new_visibility);  }  BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask ) @@ -1457,6 +1463,7 @@ void LLMenuItemBranchDownGL::draw( void )  	setHover(FALSE);  } +  class LLMenuScrollItem : public LLMenuItemCallGL  {  public: @@ -1465,10 +1472,18 @@ public:  		ARROW_DOWN,  		ARROW_UP  	}; +	struct ArrowTypes : public LLInitParam::TypeValuesHelper<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;  	}; @@ -1572,7 +1587,8 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p)  	mJumpKey(p.jump_key),  	mCreateJumpKeys(p.create_jump_keys),  	mParentFloaterHandle(p.parent_floater), -	mNeedsArrange(FALSE) +	mNeedsArrange(FALSE),  +	mShortcutPad(p.shortcut_pad)  {  	typedef boost::tokenizer<boost::char_separator<char> > tokenizer;  	boost::char_separator<char> sep("_"); @@ -1646,15 +1662,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 +1682,6 @@ BOOL LLMenuGL::postBuild()  	return LLUICtrl::postBuild();  } -const widget_registry_t& LLMenuGL::getChildRegistry() const -{ -	return MenuRegistry::instance(); -} - -  // are we the childmost active menu and hence our jump keys should be enabled?  // or are we a free-standing torn-off menu (which uses jump keys too)  BOOL LLMenuGL::jumpKeysActive() @@ -2331,10 +2343,10 @@ BOOL LLMenuGL::appendMenu( LLMenuGL* menu )  	p.label = menu->getLabel();  	p.branch = menu;  	p.jump_key = menu->getJumpKey(); -	p.enabled_color=LLUI::getCachedColorFunctor("MenuItemEnabledColor"); -	p.disabled_color=LLUI::getCachedColorFunctor("MenuItemDisabledColor"); -	p.highlight_bg_color=LLUI::getCachedColorFunctor("MenuItemHighlightBgColor"); -	p.highlight_fg_color=LLUI::getCachedColorFunctor("MenuItemHighlightFgColor"); +	p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor"); +	p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor"); +	p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor"); +	p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");  	LLMenuItemBranchGL* branch = LLUICtrlFactory::create<LLMenuItemBranchGL>(p);  	success &= append( branch ); @@ -2741,7 +2753,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 +2895,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 +3127,10 @@ BOOL LLMenuBarGL::appendMenu( LLMenuGL* menu )  	p.label = menu->getLabel();  	p.visible = menu->getVisible();  	p.branch = menu; -	p.enabled_color=LLUI::getCachedColorFunctor("MenuItemEnabledColor"); -	p.disabled_color=LLUI::getCachedColorFunctor("MenuItemDisabledColor"); -	p.highlight_bg_color=LLUI::getCachedColorFunctor("MenuItemHighlightBgColor"); -	p.highlight_fg_color=LLUI::getCachedColorFunctor("MenuItemHighlightFgColor"); +	p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor"); +	p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor"); +	p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor"); +	p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");  	LLMenuItemBranchDownGL* branch = LLUICtrlFactory::create<LLMenuItemBranchDownGL>(p);  	success &= branch->addToAcceleratorList(&mAccelerators); @@ -3202,6 +3214,8 @@ BOOL LLMenuBarGL::handleHover( S32 x, S32 y, MASK mask )  ///============================================================================  /// Class LLMenuHolderGL  ///============================================================================ +LLCoordGL LLMenuHolderGL::sContextMenuSpawnPos(S32_MAX, S32_MAX); +  LLMenuHolderGL::LLMenuHolderGL()  	: LLPanel()  { @@ -3258,6 +3272,32 @@ BOOL LLMenuHolderGL::handleRightMouseDown( S32 x, S32 y, MASK mask )  	return handled;  } +// This occurs when you mouse-down to spawn a context menu, hold the button  +// down, move off the menu, then mouse-up.  We want this to close the menu. +BOOL LLMenuHolderGL::handleRightMouseUp( S32 x, S32 y, MASK mask ) +{ +	const S32 SLOP = 2; +	S32 spawn_dx = (x - sContextMenuSpawnPos.mX); +	S32 spawn_dy = (y - sContextMenuSpawnPos.mY); +	if (-SLOP <= spawn_dx && spawn_dx <= SLOP +		&& -SLOP <= spawn_dy && spawn_dy <= SLOP) +	{ +		// we're still inside the slop region from spawning this menu +		// so interpret the mouse-up as a single-click to show and leave on +		// screen +		sContextMenuSpawnPos.set(S32_MAX, S32_MAX); +		return TRUE; +	} + +	BOOL handled = LLView::childrenHandleRightMouseUp(x, y, mask) != NULL; +	if (!handled) +	{ +		// clicked off of menu, hide them all +		hideMenus(); +	} +	return handled; +} +  void LLMenuHolderGL::reshape(S32 width, S32 height, BOOL called_from_parent)  {  	if (width != getRect().getWidth() || height != getRect().getHeight()) @@ -3320,7 +3360,7 @@ void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item)  /// Class LLTearOffMenu  ///============================================================================  LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) :  -	LLFloater() +	LLFloater(LLSD())  {  	static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0); @@ -3353,6 +3393,16 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) :  	mMenu->highlightNextItem(NULL);  } +LLTearOffMenu::~LLTearOffMenu() +{ +} + +// virtual +BOOL LLTearOffMenu::postBuild() +{ +	mCloseSignal.connect(boost::bind(&LLTearOffMenu::closeTearOff, this)); +	return TRUE; +}  void LLTearOffMenu::draw()  { @@ -3452,7 +3502,7 @@ LLTearOffMenu* LLTearOffMenu::create(LLMenuGL* menup)  	return tearoffp;  } -void LLTearOffMenu::onClose(bool app_quitting) +void LLTearOffMenu::closeTearOff()  {  	removeChild(mMenu);  	mOldParent->addChild(mMenu); @@ -3462,7 +3512,6 @@ void LLTearOffMenu::onClose(bool app_quitting)  	mMenu->setVisible(FALSE);  	mMenu->setTornOff(FALSE);  	mMenu->setDropShadowed(TRUE); -	destroy();  } @@ -3540,7 +3589,7 @@ void	LLContextMenuBranch::showSubMenu()  	S32 center_x;  	S32 center_y;  	localPointToScreen(getRect().getWidth(), getRect().getHeight() , ¢er_x, ¢er_y); -	mBranch->show(	center_x, center_y, FALSE); +	mBranch->show(	center_x, center_y);  }  // onCommit() - do the primary funcationality of the menu item. @@ -3569,7 +3618,7 @@ void LLContextMenuBranch::setHighlight( BOOL highlight )  // class LLContextMenu  // A context menu  //----------------------------------------------------------------------------- -static LLDefaultWidgetRegistry::Register<LLContextMenu> context_menu_register("context_menu"); +static LLDefaultChildRegistry::Register<LLContextMenu> context_menu_register("context_menu");  static MenuRegistry::Register<LLContextMenu> context_menu_register2("context_menu"); @@ -3577,7 +3626,6 @@ LLContextMenu::LLContextMenu(const Params& p)  :	LLMenuGL(p),  	mHoveredAnyItem(FALSE),  	mHoverItem(NULL) -  {  	//setBackgroundVisible(TRUE);  } @@ -3588,8 +3636,14 @@ void LLContextMenu::setVisible(BOOL visible)  		hide();  } -void LLContextMenu::show(S32 x, S32 y,BOOL adjustCursor) +// Takes cursor position in screen space? +void LLContextMenu::show(S32 x, S32 y)  { +	// Save click point for detecting cursor moves before mouse-up. +	// Must be in local coords to compare with mouseUp events. +	// If the mouse doesn't move, the menu will stay open ala the Mac. +	LLMenuHolderGL::sContextMenuSpawnPos.set(x,y); +  	arrangeAndClear();  	S32 width = getRect().getWidth(); @@ -3597,29 +3651,41 @@ void LLContextMenu::show(S32 x, S32 y,BOOL adjustCursor)  	const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect();  	LLView* parent_view = getParent(); -	if(getParentMenuItem()) +	// Open upwards if menu extends past bottom +	if (y - height < menu_region_rect.mBottom)  	{ -		S32 parent_width = getParentMenuItem()->getRect().getWidth(); -		 -		if(x + width > menu_region_rect.getWidth()) -			x -= parent_width + width; +		if (getParentMenuItem()) // Adjust if this is a submenu +		{ +			y += height - getParentMenuItem()->getNominalHeight();		 +		} +		else +		{ +			y += height; +		} +	} + +	// Open out to the left if menu extends past right edge +	if (x + width > menu_region_rect.mRight) +	{ +		if (getParentMenuItem()) +		{ +			x -= getParentMenuItem()->getRect().getWidth() + width; +		} +		else +		{ +			x -= width; +		}  	}  	S32 local_x, local_y;  	parent_view->screenPointToLocal(x, y, &local_x, &local_y); -	// HACK: casting away const.  Should use setRect or some helper function instead. -	const_cast<LLRect&>(getRect()).setCenterAndSize(local_x + width/2, local_y - height/2, width, height); +	LLRect rect; +	rect.setLeftTopAndSize(local_x, local_y, width, height); +	setRect(rect);  	arrange(); - -	if (translateIntoRect(menu_region_rect,FALSE) && adjustCursor) -	{ -		LLUI::setCursorPositionLocal(getParent(), getRect().mLeft , getRect().mTop); -	} -  	LLView::setVisible(TRUE); -  }  void LLContextMenu::hide() @@ -3679,58 +3745,8 @@ BOOL LLContextMenu::handleHover( S32 x, S32 y, MASK mask )  	return handled;  } -BOOL LLContextMenu::handleMouseDown( S32 x, S32 y, MASK mask ) -{ -	BOOL handled = FALSE; -	// The click was somewhere within our rectangle -	LLMenuItemGL *item = getHighlightedItem(); +// handleMouseDown and handleMouseUp are handled by LLMenuGL -	if (item) -	{ -		// lie to the item about where the click happened -		// to make sure it's within the item's rectangle -		handled = item->handleMouseDown( 0, 0, mask ); -	} -	else  -	{ -		// call hidemenus to make sure transient selections get cleared -		((LLMenuHolderGL*)getParent())->hideMenus(); -	} - -	// always handle mouse down as mouse up will close open menus -	return handled; -} -BOOL LLContextMenu::handleMouseUp( S32 x, S32 y, MASK mask ) -{ -	BOOL handled = FALSE; - -	// The click was somewhere within our rectangle -	LLMenuItemGL *item = getHighlightedItem(); - -	if (item) -	{ -		// lie to the item about where the click happened -		// to make sure it's within the item's rectangle -		if (item->getEnabled()) -		{ -			handled = item->handleMouseUp( 0, 0, mask ); -			hide(); -		} -	} -	else  -	{ -		// call hidemenus to make sure transient selections get cleared -		((LLMenuHolderGL*)getParent())->hideMenus(); -	} - -	if (!handled) -	{ -		// call hidemenus to make sure transient selections get cleared -		sMenuContainer->hideMenus(); -	} - -	return handled; -}  BOOL LLContextMenu::handleRightMouseDown(S32 x, S32 y, MASK mask)  { @@ -3766,8 +3782,6 @@ BOOL LLContextMenu::handleRightMouseDown(S32 x, S32 y, MASK mask)  BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask )  { -	// release mouse capture when right mouse button released, and we're past the shrink time -  	S32 local_x = x - getRect().mLeft;  	S32 local_y = y - getRect().mBottom; @@ -3802,10 +3816,10 @@ BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu)  	p.name = menu->getName();  	p.label = menu->getLabel();  	p.branch = menu; -	p.enabled_color=LLUI::getCachedColorFunctor("MenuItemEnabledColor"); -	p.disabled_color=LLUI::getCachedColorFunctor("MenuItemDisabledColor"); -	p.highlight_bg_color=LLUI::getCachedColorFunctor("MenuItemHighlightBgColor"); -	p.highlight_fg_color=LLUI::getCachedColorFunctor("MenuItemHighlightFgColor"); +	p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor"); +	p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor"); +	p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor"); +	p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");  	item = LLUICtrlFactory::create<LLContextMenuBranch>(p);  	LLMenuGL::sMenuContainer->addChild(item->getBranch()); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 526e1c2583..828956a217 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -81,7 +81,7 @@ public:  		Params()  		:	shortcut("shortcut"), -			jump_key("", KEY_NONE), +			jump_key("jump_key", KEY_NONE),  			use_mac_ctrl("use_mac_ctrl", false),  			rect("rect"),  			left("left"), @@ -106,7 +106,7 @@ protected:  	friend class LLUICtrlFactory;  public:  	virtual void setValue(const LLSD& value) { setLabel(value.asString()); } -	/*virtual*/ void onVisibilityChange(BOOL new_visibility); +	/*virtual*/ void handleVisibilityChange(BOOL new_visibility);  	virtual BOOL handleHover(S32 x, S32 y, MASK mask);  	virtual BOOL handleAcceleratorKey(KEY key, MASK mask); @@ -137,7 +137,7 @@ public:  	virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );  	// Get the parent menu for this item -	virtual class LLMenuGL*	getMenu(); +	virtual class LLMenuGL*	getMenu() const;  	// returns the normal width of this control in pixels - this is  	// used for calculating the widest item, as well as for horizontal @@ -283,6 +283,7 @@ public:  	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);  	virtual BOOL handleKeyHere(KEY key, MASK mask); +	virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);  	//virtual void draw(); @@ -295,6 +296,11 @@ public:  	{  		return mEnableSignal.connect(cb);  	} + +	boost::signals2::connection setRightClickedCallback( const commit_signal_t::slot_type& cb ) +	{ +		return mRightClickSignal.connect(cb); +	}  private:  	enable_signal_t mEnableSignal; @@ -356,6 +362,11 @@ private:  // it in the appendMenu() method.  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// child widget registry +struct MenuRegistry : public LLChildRegistry<MenuRegistry> +{}; + +  class LLMenuGL   :	public LLUICtrl  { @@ -372,15 +383,18 @@ public:  										keep_fixed_size,  										scrollable;  		Optional<LLUIColor>				bg_color; +		Optional<S32>					shortcut_pad;  		Params() -		:	jump_key("", KEY_NONE), +		:	jump_key("jump_key", KEY_NONE), +			horizontal_layout("horizontal_layout"),  			can_tear_off("tear_off", false),  			drop_shadow("drop_shadow", true),  			bg_visible("bg_visible", true),  			create_jump_keys("create_jump_keys", false), -			bg_color("bg_color",  LLUI::getCachedColorFunctor( "MenuDefaultBgColor" )), -			scrollable("scrollable", false) +			bg_color("bg_color",  LLUIColorTable::instance().getColor( "MenuDefaultBgColor" )), +			scrollable("scrollable", false),  +			shortcut_pad("shortcut_pad")  		{  			addSynonym(bg_visible, "opaque");  			addSynonym(bg_color, "color"); @@ -388,6 +402,10 @@ public:  			name = "menu";  		}  	}; + +	// my valid children are contained in MenuRegistry +	typedef MenuRegistry child_registry_t; +  	void initFromParams(const Params&);  protected: @@ -410,7 +428,6 @@ public:  	/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);  	/*virtual*/ void removeChild( LLView* ctrl);  	/*virtual*/ BOOL postBuild(); -	/*virtual*/ const widget_registry_t& getChildRegistry() const;  	virtual BOOL handleAcceleratorKey(KEY key, MASK mask); @@ -498,6 +515,8 @@ public:  	static void setKeyboardMode(BOOL mode) { sKeyboardMode = mode; }  	static BOOL getKeyboardMode() { return sKeyboardMode; } +	S32 getShortcutPad() { return mShortcutPad; } +  	void scrollItemsUp();  	void scrollItemsDown();  	BOOL isScrollable() const { return mScrollable; } @@ -551,6 +570,7 @@ private:  	LLHandle<LLFloater>	mParentFloaterHandle;  	KEY				mJumpKey;  	BOOL			mCreateJumpKeys; +	S32				mShortcutPad;  }; // end class LLMenuGL @@ -606,7 +626,7 @@ public:  	virtual void updateBranchParent( LLView* parentp );  	// LLView Functionality -	virtual void onVisibilityChange( BOOL curVisibilityIn ); +	virtual void handleVisibilityChange( BOOL curVisibilityIn );  	virtual void draw(); @@ -651,16 +671,12 @@ public:  	virtual void	draw				(); -	virtual void	show				(S32 x, S32 y, BOOL adjustCursor = TRUE); +	virtual void	show				(S32 x, S32 y);  	virtual void	hide				(); -	 -  	virtual BOOL	handleHover			( S32 x, S32 y, MASK mask ); -	virtual BOOL	handleMouseDown		( S32 x, S32 y, MASK mask );  	virtual BOOL	handleRightMouseDown( S32 x, S32 y, MASK mask );  	virtual BOOL	handleRightMouseUp	( S32 x, S32 y, MASK mask ); -	virtual BOOL	handleMouseUp		( S32 x, S32 y, MASK mask );  	virtual bool	addChild			(LLView* view, S32 tab_group = 0); @@ -749,11 +765,18 @@ public:  	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );  	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); +	// Close context menus on right mouse up not handled by menus. +	/*virtual*/ BOOL handleRightMouseUp( S32 x, S32 y, MASK mask ); +  	virtual const LLRect getMenuRect() const { return getLocalRect(); }  	virtual BOOL hasVisibleMenu() const;  	static void setActivatedItem(LLMenuItemGL* item); +	// Need to detect if mouse-up after context menu spawn has moved. +	// If not, need to keep the menu up. +	static LLCoordGL sContextMenuSpawnPos; +  private:  	static LLHandle<LLView> sItemLastSelectedHandle;  	static LLFrameTimer sItemActivationTimer; @@ -771,8 +794,10 @@ class LLTearOffMenu : public LLFloater  {  public:  	static LLTearOffMenu* create(LLMenuGL* menup); -	virtual ~LLTearOffMenu() {} -	virtual void onClose(bool app_quitting); +	virtual ~LLTearOffMenu(); + +	virtual BOOL postBuild(); +	  	virtual void draw(void);  	virtual void onFocusReceived();  	virtual void onFocusLost(); @@ -782,7 +807,9 @@ public:  private:  	LLTearOffMenu(LLMenuGL* menup); - +	 +	void closeTearOff(); +	  	LLView*		mOldParent;  	LLMenuGL*	mMenu;  	F32			mTargetHeight; diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index 8779eee28d..11fa290de1 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -44,12 +44,11 @@  // static  std::list<LLModalDialog*> LLModalDialog::sModalStack; -LLModalDialog::LLModalDialog( const std::string& title, S32 width, S32 height, BOOL modal ) -	: LLFloater(), +LLModalDialog::LLModalDialog( const LLSD& key, S32 width, S32 height, BOOL modal ) +	: LLFloater(key),  	  mModal( modal )  {  	setRect(LLRect( 0, height, width, 0 )); -	setTitle(title);  	if (modal)  	{  		setCanMinimize(FALSE); @@ -59,6 +58,7 @@ LLModalDialog::LLModalDialog( const std::string& title, S32 width, S32 height, B  	setBackgroundVisible(TRUE);  	setBackgroundOpaque(TRUE);  	centerOnScreen(); // default position +	mCloseSignal.connect(boost::bind(&LLModalDialog::stopModal, this));  }  LLModalDialog::~LLModalDialog() @@ -68,6 +68,18 @@ LLModalDialog::~LLModalDialog()  	{  		gFocusMgr.unlockFocus();  	} +	 +	std::list<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this); +	if (iter != sModalStack.end()) +	{ +		llerrs << "Attempt to delete dialog while still in sModalStack!" << llendl; +	} +} + +// virtual +BOOL LLModalDialog::postBuild() +{ +	return LLFloater::postBuild();  }  // virtual @@ -235,16 +247,10 @@ BOOL LLModalDialog::handleKeyHere(KEY key, MASK mask )  	}	  } -void LLModalDialog::onClose(bool app_quitting) -{ -	stopModal(); -	LLFloater::onClose(app_quitting); -} -  // virtual  void LLModalDialog::draw()  { -	static LLUICachedControl<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/llmodaldialog.h b/indra/llui/llmodaldialog.h index dad92ab82a..4d5073024b 100644 --- a/indra/llui/llmodaldialog.h +++ b/indra/llui/llmodaldialog.h @@ -45,9 +45,11 @@ class LLModalDialog;  class LLModalDialog : public LLFloater  {  public: -	LLModalDialog( const std::string& title, S32 width, S32 height, BOOL modal = true ); +	LLModalDialog( const LLSD& key, S32 width, S32 height, BOOL modal = true );  	/*virtual*/ ~LLModalDialog(); - +	 +	/*virtual*/ BOOL 	postBuild(); +	  	/*virtual*/ void	openFloater(const LLSD& key = LLSD());  	/*virtual*/ void 	reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -63,8 +65,6 @@ public:  	/*virtual*/ BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);  	/*virtual*/ BOOL	handleKeyHere(KEY key, MASK mask ); -	/*virtual*/ void	onClose(bool app_quitting); -  	/*virtual*/ void	setVisible(BOOL visible);  	/*virtual*/ void	draw(); diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp index c0fe7ff32d..9f9e3aecac 100644 --- a/indra/llui/llmultifloater.cpp +++ b/indra/llui/llmultifloater.cpp @@ -42,8 +42,8 @@  // LLMultiFloater  // -LLMultiFloater::LLMultiFloater(const LLFloater::Params& params) -	: LLFloater(), +LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params) +	: LLFloater(key),  	  mTabContainer(NULL),  	  mTabPos(LLTabContainer::TOP),  	  mAutoResize(TRUE), @@ -74,20 +74,12 @@ void LLMultiFloater::buildTabContainer()  void LLMultiFloater::onOpen(const LLSD& key)  { -	if (mTabContainer->getTabCount() <= 0) -	{ -		// for now, don't allow multifloaters -		// without any child floaters -		closeFloater(); -	} -} - -void LLMultiFloater::onClose(bool app_quitting) -{ -	if(closeAllFloaters() == TRUE) -	{ -		LLFloater::onClose(app_quitting); -	}//else not all tabs could be closed... +// 	if (mTabContainer->getTabCount() <= 0) +// 	{ +// 		// for now, don't allow multifloaters +// 		// without any child floaters +// 		closeFloater(); +// 	}  }  void LLMultiFloater::draw() @@ -124,7 +116,8 @@ BOOL LLMultiFloater::closeAllFloaters()  			//Tab did not actually close, possibly due to a pending Save Confirmation dialog..  			//so try and close the next one in the list...  			tabToClose++; -		}else +		} +		else  		{  			//Tab closed ok.  			lastTabCount = mTabContainer->getTabCount(); @@ -246,6 +239,9 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,  	{  		floaterp->setVisible(FALSE);  	} +	 +	// Tabs sometimes overlap resize handle +	moveResizeHandlesToFront();  }  /** @@ -275,6 +271,7 @@ void LLMultiFloater::selectPrevFloater()  void LLMultiFloater::showFloater(LLFloater* floaterp, LLTabContainer::eInsertionPoint insertion_point)  { +	if(!floaterp) return;  	// we won't select a panel that already is selected  	// it is hard to do this internally to tab container  	// as tab selection is handled via index and the tab at a given @@ -288,7 +285,7 @@ void LLMultiFloater::showFloater(LLFloater* floaterp, LLTabContainer::eInsertion  void LLMultiFloater::removeFloater(LLFloater* floaterp)  { -	if ( floaterp->getHost() != this ) +	if (!floaterp || floaterp->getHost() != this )  		return;  	floater_data_map_t::iterator found_data_it = mFloaterDataMap.find(floaterp->getHandle()); @@ -447,6 +444,8 @@ void LLMultiFloater::setCanResize(BOOL can_resize)  BOOL LLMultiFloater::postBuild()  { +	mCloseSignal.connect(boost::bind(&LLMultiFloater::closeAllFloaters, this)); +		  	// remember any original xml minimum size  	getResizeLimits(&mOrigMinWidth, &mOrigMinHeight); diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h index 7f4c1c040a..bbf2c56fe7 100644 --- a/indra/llui/llmultifloater.h +++ b/indra/llui/llmultifloater.h @@ -44,14 +44,13 @@  class LLMultiFloater : public LLFloater  {  public: -	LLMultiFloater(const LLFloater::Params& params = LLFloater::getDefaultParams()); +	LLMultiFloater(const LLSD& key, const Params& params = getDefaultParams());  	virtual ~LLMultiFloater() {};  	void buildTabContainer();  	virtual BOOL postBuild();  	/*virtual*/ void onOpen(const LLSD& key); -	/*virtual*/ void onClose(bool app_quitting);  	/*virtual*/ void draw();  	/*virtual*/ void setVisible(BOOL visible);  	/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 099a79278a..68e496aed1 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -40,12 +40,11 @@  #include "llfocusmgr.h"  #include "llkeyboard.h"			// for the MASK constants  #include "llcontrol.h" -#include "llimagegl.h"  #include "lluictrlfactory.h"  #include <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..0335a265b6 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -100,8 +100,9 @@  // and we need this to manage the notification callbacks  #include "llevents.h"  #include "llfunctorregistry.h" -#include "llui.h" -#include "llmemory.h" +#include "llpointer.h" +#include "llinitparam.h" +#include "llxmlnode.h"  #include "llnotificationslistener.h"  class LLNotification; @@ -159,7 +160,8 @@ public:  	LLNotificationForm();  	LLNotificationForm(const LLSD& sd); -	LLNotificationForm(const std::string& name, const LLXMLNodePtr xml_node); +	LLNotificationForm(const std::string& name,  +		const LLPointer<LLXMLNode> xml_node);  	LLSD asLLSD() const; @@ -295,7 +297,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 +315,23 @@ public:  		Params()  		:	name("name"),  			priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), -			timestamp("time_stamp") +			time_stamp("time_stamp"), +			payload("payload"), +			form_elements("form_elements")  		{ -			timestamp = LLDate::now(); +			time_stamp = LLDate::now();  		}  		Params(const std::string& _name)  -			:	name("name"), -				priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), -				timestamp("time_stamp") +		:	name("name"), +			priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), +			time_stamp("time_stamp"), +			payload("payload"), +			form_elements("form_elements")  		{  			functor.name = _name;  			name = _name; -			timestamp = LLDate::now(); +			time_stamp = LLDate::now();  		}  	}; @@ -690,6 +696,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 +729,7 @@ public:  protected:      LLBoundListener connectChangedImpl(const LLEventListener& slot); +    LLBoundListener connectAtFrontChangedImpl(const LLEventListener& slot);      LLBoundListener connectPassedFilterImpl(const LLEventListener& slot);      LLBoundListener connectFailedFilterImpl(const LLEventListener& slot); @@ -822,7 +837,7 @@ public:  	// load notification descriptions from file;   	// OK to call more than once because it will reload  	bool loadTemplates();   -	LLXMLNodePtr checkForXMLTemplate(LLXMLNodePtr item); +	LLPointer<class LLXMLNode> checkForXMLTemplate(LLPointer<class LLXMLNode> item);  	// Add a simple notification (from XUI)  	void addFromCallback(const LLSD& name); @@ -905,7 +920,7 @@ private:  	std::string mFileName; -	typedef std::map<std::string, LLXMLNodePtr> XMLTemplateMap; +	typedef std::map<std::string, LLPointer<class LLXMLNode> > XMLTemplateMap;  	XMLTemplateMap mXmlTemplates;  	LLNotificationMap mUniqueNotifications; diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 0136a41d61..1a948fdd00 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -43,6 +43,7 @@  #include "llerror.h"  #include "lltimer.h" +#include "llbutton.h"  #include "llmenugl.h"  //#include "llstatusbar.h"  #include "llui.h" @@ -53,18 +54,18 @@  #include "lluictrl.h"  #include "lluictrlfactory.h"  #include "llviewborder.h" -#include "llbutton.h"  #include "lltabcontainer.h" -static LLDefaultWidgetRegistry::Register<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), @@ -73,7 +74,8 @@ LLPanel::Params::Params()  	min_height("min_height", 100),  	strings("string"),  	filename("filename"), -	class_name("class") +	class_name("class"), +	visible_callback("visible_callback")  {  	name = "panel";  	addSynonym(background_visible, "bg_visible"); @@ -306,6 +308,12 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask )  	return handled;  } +void LLPanel::handleVisibilityChange ( BOOL new_visibility ) +{ +	LLUICtrl::handleVisibilityChange ( new_visibility ); +	mVisibleSignal(this, LLSD(new_visibility) ); // Pass BOOL as LLSD +} +  BOOL LLPanel::checkRequirements()  {  	if (!mRequirementsError.empty()) @@ -418,26 +426,31 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_  void LLPanel::initFromParams(const LLPanel::Params& p)  { +    //setting these here since panel constructor not called with params +    //and LLView::initFromParams will use them to set visible and enabled   +	setVisible(p.visible); +	setEnabled(p.enabled); +  	 // control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible  	LLUICtrl::initFromParams(p); - +	 +	// visible callback  +	if (p.visible_callback.isProvided()) +		initCommitCallback(p.visible_callback, mVisibleSignal); +	  	for (LLInitParam::ParamIterator<LocalizedString>::const_iterator it = p.strings().begin();  		it != p.strings().end();  		++it)  	{ -		mUIStrings[it->name] = it->text; +		mUIStrings[it->name] = it->value;  	} -	setName(p.name());  	setLabel(p.label()); -  	setShape(p.rect);  	parseFollowsFlags(p); -	setEnabled(p.enabled); -	setVisible(p.visible);  	setToolTip(p.tool_tip()); -	setSaveToXML(p.serializable); +	setSaveToXML(p.from_xui);  	mHoverCursor = getCursorFromString(p.hover_cursor); @@ -466,7 +479,7 @@ static LLFastTimer::DeclareTimer FTM_PANEL_POSTBUILD("Panel PostBuild");  BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)  { -	const LLPanel::Params& default_params(LLUICtrlFactory::getDefaultParams<LLPanel::Params>()); +	const LLPanel::Params& default_params(LLUICtrlFactory::getDefaultParams<LLPanel>());  	Params params(default_params);  	{ @@ -503,7 +516,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu  			// add children using dimensions from referenced xml for consistent layout  			setShape(params.rect); -			LLUICtrlFactory::createChildren(this, referenced_xml); +			LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance());  		}  		LLXUIParser::instance().readXUI(node, params); @@ -524,7 +537,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu  		}  		// add children -		LLUICtrlFactory::createChildren(this, node, output_node); +		LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node);  		// Connect to parent after children are built, because tab containers  		// do a reshape() on their child panels, which requires that the children @@ -543,12 +556,6 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu  	return TRUE;  } -const widget_registry_t& LLPanel::getChildRegistry() const -{ -	// use default widget registry -	return LLDefaultWidgetRegistry::instance(); -} -  bool LLPanel::hasString(const std::string& name)  {  	return mUIStrings.find(name) != mUIStrings.end(); @@ -804,24 +811,6 @@ BOOL LLPanel::childSetToolTipArg(const std::string& id, const std::string& key,  	return FALSE;  } -void LLPanel::childSetMinValue(const std::string& id, LLSD min_value) -{ -	LLUICtrl* child = findChild<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 +858,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..552a621a8e 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -37,8 +37,6 @@  #include "llcallbackmap.h"  #include "lluictrl.h" -#include "llbutton.h" -#include "lllineeditor.h"  #include "llviewborder.h"  #include "lluistring.h"  #include "v4color.h" @@ -49,6 +47,7 @@ const S32 LLPANEL_BORDER_WIDTH = 1;  const BOOL BORDER_YES = TRUE;  const BOOL BORDER_NO = FALSE; +class LLButton;  /*   * General purpose concrete view base class. @@ -62,11 +61,11 @@ public:  	struct LocalizedString : public LLInitParam::Block<LocalizedString>  	{  		Mandatory<std::string>	name; -		Mandatory<std::string>	text; +		Mandatory<std::string>	value;  		LocalizedString()  		:	name("name"), -			text("value") +			value("value")  		{}  	}; @@ -89,10 +88,15 @@ public:  		Optional<std::string>	class_name;  		Multiple<LocalizedString>	strings; - +		 +		Optional<CommitCallbackParam> visible_callback; +		  		Params();  	}; +	// valid children for LLPanel are stored in this registry +	typedef LLDefaultChildRegistry child_registry_t; +  protected:  	friend class LLUICtrlFactory;  	// RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8 @@ -109,6 +113,7 @@ public:  	/*virtual*/ BOOL 	isPanel() const;  	/*virtual*/ void	draw();	  	/*virtual*/ BOOL	handleKeyHere( KEY key, MASK mask ); +	/*virtual*/ void 	handleVisibilityChange ( BOOL new_visibility );  	// Override to set not found list:  	/*virtual*/ LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; @@ -165,7 +170,6 @@ public:  	void initFromParams(const Params& p);  	BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); -	/*virtual*/ const widget_registry_t& getChildRegistry() const;  	bool hasString(const std::string& name);  	std::string getString(const std::string& name, const LLStringUtil::format_map_t& args) const; @@ -213,10 +217,6 @@ public:  	BOOL childSetLabelArg(const std::string& id, const std::string& key, const LLStringExplicit& text);  	BOOL childSetToolTipArg(const std::string& id, const std::string& key, const LLStringExplicit& text); -	// LLSlider / LLMultiSlider / LLSpinCtrl -	void childSetMinValue(const std::string& id, LLSD min_value); -	void childSetMaxValue(const std::string& id, LLSD max_value); -  	// LLTabContainer  	void childShowTab(const std::string& id, const std::string& tabname, bool visible = true);  	LLPanel *childGetVisibleTab(const std::string& id) const; @@ -235,7 +235,10 @@ public:  	// LLButton  	void childSetAction(const std::string& id, boost::function<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 @@ -254,6 +257,8 @@ protected:  	CommitCallbackRegistry::ScopedRegistrar mCommitCallbackRegistrar;  	EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar; +	commit_signal_t mVisibleSignal;		// Called when visibilit changes, passes new visibility as LLSD() +	  private:  	// Unified error reporting for the child* functions  	typedef std::set<std::string> expected_members_list_t; @@ -273,7 +278,7 @@ private:  	ui_string_map_t	mUIStrings;  	std::string		mRequirementsError; - +	  }; // end class LLPanel  #endif diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp index 779967940a..c8b6e814e1 100644 --- a/indra/llui/llprogressbar.cpp +++ b/indra/llui/llprogressbar.cpp @@ -39,22 +39,18 @@  #include "llgl.h"  #include "llui.h"  #include "llfontgl.h" -#include "llimagegl.h"  #include "lltimer.h"  #include "llglheaders.h"  #include "llfocusmgr.h"  #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<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..bc489592d4 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -48,7 +48,7 @@  #include "llrender.h"  #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<LLScrollbar> register_scrollbar("scroll_bar"); +static LLDefaultChildRegistry::Register<LLScrollbar> register_scrollbar("scroll_bar");  LLScrollbar::Params::Params()  :	orientation ("orientation", HORIZONTAL), @@ -56,8 +56,10 @@ LLScrollbar::Params::Params()  	doc_pos ("doc_pos", 0),  	page_size ("page_size", 0),  	step_size ("step_size", 1), -	thumb_image("thumb_image"), -	track_image("track_image"), +	thumb_image_vertical("thumb_image_vertical"), +	thumb_image_horizontal("thumb_image_horizontal"), +	track_image_vertical("track_image_vertical"), +	track_image_horizontal("track_image_horizontal"),  	track_color("track_color"),  	thumb_color("thumb_color"),  	thickness("thickness"), @@ -86,8 +88,10 @@ LLScrollbar::LLScrollbar(const Params & p)  		mThumbColor ( p.thumb_color() ),  		mOnScrollEndCallback( NULL ),  		mOnScrollEndData( NULL ), -		mThumbImage(p.thumb_image), -		mTrackImage(p.track_image), +		mThumbImageV(p.thumb_image_vertical), +		mThumbImageH(p.thumb_image_horizontal), +		mTrackImageV(p.track_image_vertical), +		mTrackImageH(p.track_image_horizontal),  		mThickness(p.thickness.isProvided() ? p.thickness : LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize"))  {  	updateThumbRect(); @@ -493,7 +497,8 @@ void LLScrollbar::draw()  	}  	// Draw background and thumb. -	if (mTrackImage.isNull() || mThumbImage.isNull()) +	if (   ( mOrientation == VERTICAL&&(mThumbImageV.isNull() || mThumbImageV.isNull()) )  +		|| (mOrientation == HORIZONTAL&&(mTrackImageH.isNull() || mThumbImageH.isNull()) ))  	{  		gl_rect_2d(mOrientation == HORIZONTAL ? mThickness : 0,   		mOrientation == VERTICAL ? getRect().getHeight() - 2 * mThickness : getRect().getHeight(), @@ -505,30 +510,54 @@ void LLScrollbar::draw()  	}  	else  	{ -		// Background -		mTrackImage->drawSolid(mOrientation == HORIZONTAL ? mThickness : 0,  -			mOrientation == VERTICAL ? mThickness : 0, -			mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * mThickness : getRect().getWidth(),  -			mOrientation == VERTICAL ? getRect().getHeight() - 2 * mThickness : getRect().getHeight(), -			mTrackColor.get()); -  		// Thumb  		LLRect outline_rect = mThumbRect;  		outline_rect.stretch(2); - -		if (gFocusMgr.getKeyboardFocus() == this) +		S32 rect_fix = 0; +		// Background +		 +		if(mOrientation == HORIZONTAL)  		{ -			mTrackImage->draw(outline_rect, gFocusMgr.getFocusColor()); +			mTrackImageH->drawSolid(mThickness								//S32 x +								   , 0										//S32 y +								   , getRect().getWidth() - 2 * mThickness  //S32 width +								   , getRect().getHeight()- rect_fix		//S32 height +								   , mTrackColor.get());                    //const LLColor4& color +			 +			if (gFocusMgr.getKeyboardFocus() == this) +			{ +				mTrackImageH->draw(outline_rect, gFocusMgr.getFocusColor()); +			} +			 +			mThumbImageH->draw(mThumbRect, mThumbColor.get()); +			if (mCurGlowStrength > 0.01f) +			{ +				gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); +				mThumbImageH->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); +				gGL.setSceneBlendType(LLRender::BT_ALPHA); +			} +			  		} - -		mThumbImage->draw(mThumbRect, mThumbColor.get()); -		if (mCurGlowStrength > 0.01f) +		else if(mOrientation == VERTICAL)  		{ -			gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); -			mThumbImage->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); -			gGL.setSceneBlendType(LLRender::BT_ALPHA); +			mTrackImageV->drawSolid(  0+rect_fix								//S32 x +								   , mThickness								//S32 y +								   , getRect().getWidth()					//S32 width +								   , getRect().getHeight() - 2 * mThickness	//S32 height +								   , mTrackColor.get());                    //const LLColor4& color +			if (gFocusMgr.getKeyboardFocus() == this) +			{ +				mTrackImageV->draw(outline_rect, gFocusMgr.getFocusColor()); +			} +			 +			mThumbImageV->draw(mThumbRect, mThumbColor.get()); +			if (mCurGlowStrength > 0.01f) +			{ +				gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); +				mThumbImageV->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); +				gGL.setSceneBlendType(LLRender::BT_ALPHA); +			}  		} -  	}  	BOOL was_scrolled_to_bottom = (getDocPos() == getDocPosMax()); diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index 43604d37b7..5522e5d0fa 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -61,8 +61,10 @@ public:  		Optional<S32>					step_size;  		Optional<S32>					thickness; -		Optional<LLUIImage*>			thumb_image, -										track_image; +		Optional<LLUIImage*>			thumb_image_vertical, +										thumb_image_horizontal, +										track_image_horizontal, +										track_image_vertical;  		Optional<LLUIColor>				track_color,  										thumb_color; @@ -155,8 +157,10 @@ private:  	LLUIColor			mTrackColor;  	LLUIColor			mThumbColor; -	LLUIImagePtr		mThumbImage; -	LLUIImagePtr		mTrackImage; +	LLUIImagePtr		mThumbImageV; +	LLUIImagePtr		mThumbImageH; +	LLUIImagePtr		mTrackImageV; +	LLUIImagePtr		mTrackImageH;  	S32					mThickness; diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 2a2e56a92c..402c050d2e 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -63,7 +63,7 @@ static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;  /// Class LLScrollContainer  ///---------------------------------------------------------------------------- -static LLDefaultWidgetRegistry::Register<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..79f0f9d71b 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -31,8 +31,6 @@   * $/LicenseInfo$   */ -#define INSTANTIATE_GETCHILD_SCROLLLIST -  #include "linden_common.h"  #include "llscrolllistctrl.h" @@ -60,9 +58,7 @@  #include "lltextbox.h"  #include "llsdparam.h" -template LLScrollListCtrl* LLView::getChild<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; @@ -166,7 +163,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)  	mSorted(FALSE),  	mDirty(FALSE),  	mOriginalSelection(-1), -	mDrewSelected(FALSE),  	mLastSelected(NULL),  	mHeadingHeight(p.heading_height),  	mAllowMultipleSelection(p.multi_select), @@ -174,7 +170,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)  	mBackgroundVisible(p.background_visible),  	mDrawStripes(p.draw_stripes),  	mBgWriteableColor(p.bg_writeable_color()), -	mBgReadOnlyColor(p.bg_read_only_color()), +	mBgReadOnlyColor(p.bg_readonly_color()),  	mBgSelectedColor(p.bg_selected_color()),  	mBgStripeColor(p.bg_stripe_color()),  	mFgSelectedColor(p.fg_selected_color()), @@ -225,7 +221,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)  		LLViewBorder::Params params;  		params.name("dig border");  		params.rect(border_rect); -		params.bevel_type(LLViewBorder::BEVEL_IN); +		params.bevel_style(LLViewBorder::BEVEL_IN);  		mBorder = LLUICtrlFactory::create<LLViewBorder> (params);  		addChild(mBorder);  	} @@ -1086,12 +1082,12 @@ LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos)  {  	LLScrollListItem::Params separator_params;  	separator_params.enabled(false); -	LLScrollListCell::Params cell_params; -	cell_params.type = "icon"; -	cell_params.value = "menu_separator"; -	cell_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f); -	cell_params.font_halign = LLFontGL::HCENTER; -	separator_params.cells.add(cell_params); +	LLScrollListCell::Params column_params; +	column_params.type = "icon"; +	column_params.value = "menu_separator"; +	column_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f); +	column_params.font_halign = LLFontGL::HCENTER; +	separator_params.columns.add(column_params);  	return addRow( separator_params, pos );  } @@ -1253,7 +1249,7 @@ LLScrollListItem* LLScrollListCtrl::addStringUUIDItem(const std::string& item_te  		LLScrollListItem::Params item_p;  		item_p.enabled(enabled);  		item_p.value(id); -		item_p.cells.add().value(item_text).type("text"); +		item_p.columns.add().value(item_text).type("text");  		return addRow( item_p, pos );  	} @@ -1356,8 +1352,6 @@ void LLScrollListCtrl::drawItems()  		S32 cur_y = y; -		mDrewSelected = FALSE; -  		S32 line = 0;  		S32 max_columns = 0; @@ -1378,11 +1372,6 @@ void LLScrollListCtrl::drawItems()  			//llinfos << item_rect.getWidth() << llendl; -			if (item->getSelected()) -			{ -				mDrewSelected = TRUE; -			} -  			max_columns = llmax(max_columns, item->getNumColumns());  			LLColor4 fg_color; @@ -1447,10 +1436,7 @@ void LLScrollListCtrl::draw()  	LLLocalClipRect clip(getLocalRect());  	// if user specifies sort, make sure it is maintained -	if (needsSorting() && !isSorted()) -	{ -		sortItems(); -	} +	sortItems();  	if (mNeedsScroll)  	{ @@ -1516,19 +1502,12 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti  		if (hit_cell   			&& hit_cell->isText())  		{ -  			S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft;  			S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item));  			LLRect cell_rect;  			cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->getWidth(), mLineHeight);  			// Convert rect local to screen coordinates -			localPointToScreen(  -				cell_rect.mLeft, cell_rect.mBottom,  -				&(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); -			localPointToScreen( -				cell_rect.mRight, cell_rect.mTop,  -				&(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); - +			localRectToScreen(cell_rect, sticky_rect_screen);  			msg = hit_cell->getValue().asString();  		}  		handled = TRUE; @@ -1853,8 +1832,7 @@ S32 LLScrollListCtrl::getColumnOffsetFromIndex(S32 index)  S32 LLScrollListCtrl::getRowOffsetFromIndex(S32 index)  { -	S32 row_bottom = ((mItemListRect.mTop - (index - mScrollLines)) * mLineHeight)  -						- mLineHeight; +	S32 row_bottom = (mItemListRect.mTop - ((index - mScrollLines + 1) * mLineHeight) );  	return row_bottom;  } @@ -2219,6 +2197,8 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending)  	sort_column->mSortDirection = ascending ? LLScrollListColumn::ASCENDING : LLScrollListColumn::DESCENDING;  	sort_column_t new_sort_column(column_idx, ascending); +	 +	setSorted(FALSE);  	if (mSortColumns.empty())  	{ @@ -2259,21 +2239,22 @@ void LLScrollListCtrl::sortByColumn(const std::string& name, BOOL ascending)  // First column is column 0  void  LLScrollListCtrl::sortByColumnIndex(U32 column, BOOL ascending)  { -	if (setSort(column, ascending)) -	{ -		sortItems(); -	} +	setSort(column, ascending); +	sortItems();  }  void LLScrollListCtrl::sortItems()  { -	// do stable sort to preserve any previous sorts -	std::stable_sort( -		mItemList.begin(),  -		mItemList.end(),  -		SortScrollListItem(mSortColumns)); +	if (hasSortOrder() && !isSorted()) +	{ +		// do stable sort to preserve any previous sorts +		std::stable_sort( +			mItemList.begin(),  +			mItemList.end(),  +			SortScrollListItem(mSortColumns)); -	setSorted(TRUE); +		setSorted(TRUE); +	}  }  // for one-shot sorts, does not save sort column/order @@ -2329,10 +2310,7 @@ void LLScrollListCtrl::scrollToShowSelected()  		return;  	} -	if (needsSorting() && !isSorted()) -	{ -		sortItems(); -	}	 +	sortItems();  	S32 index = getFirstSelectedIndex();  	if (index < 0) @@ -2573,7 +2551,7 @@ std::string LLScrollListCtrl::getSortColumnName()  	else return "";  } -BOOL LLScrollListCtrl::needsSorting() +BOOL LLScrollListCtrl::hasSortOrder()  {  	return !mSortColumns.empty();  } @@ -2647,8 +2625,8 @@ LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_  	// Add any columns we don't already have  	S32 col_index = 0; -	for(LLInitParam::ParamIterator<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 +2677,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_  		col_index++;  	} -	if (item_p.cells().empty()) +	if (item_p.columns().empty())  	{  		if (mColumns.empty())  		{ @@ -2754,7 +2732,7 @@ LLScrollListItem* LLScrollListCtrl::addSimpleElement(const std::string& value, E  	LLScrollListItem::Params item_params;  	item_params.value(entry_id); -	item_params.cells.add() +	item_params.columns.add()  		.value(value)  		.font(LLFontGL::getFontSansSerifSmall()); diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 8d200fb73f..e699711bd4 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -44,7 +44,6 @@  #include "llfontgl.h"  #include "llui.h"  #include "llstring.h"	// LLWString -//#include "llimagegl.h"  #include "lleditmenuhandler.h"  #include "llframetimer.h" @@ -100,7 +99,7 @@ public:  							bg_selected_color,  							fg_disable_color,  							bg_writeable_color, -							bg_read_only_color, +							bg_readonly_color,  							bg_stripe_color,  							hovered_color,  							highlighted_color; @@ -330,7 +329,7 @@ public:  	std::string     getSortColumnName();  	BOOL			getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; } -	BOOL			needsSorting(); +	BOOL			hasSortOrder();  	S32		selectMultiple( std::vector<LLUUID> ids );  	void			sortItems(); @@ -375,9 +374,6 @@ private:  	void			commitIfChanged();  	BOOL			setSort(S32 column, BOOL ascending); -	S32				mCurIndex;			// For get[First/Next]Data -	S32				mCurSelectedIndex;  // For get[First/Next]Selected -  	S32				mLineHeight;	// the max height of a single line  	S32				mScrollLines;	// how many lines we've scrolled down  	S32				mPageLines;		// max number of lines is it possible to see on the screen given mRect and mLineHeight @@ -446,18 +442,6 @@ private:  	typedef std::pair<S32, BOOL> sort_column_t;  	std::vector<sort_column_t>	mSortColumns; - -	// HACK:  Did we draw one selected item this frame? -	BOOL mDrewSelected; - -	LLTextBox*		mCommentTextBox;  }; // end class LLScrollListCtrl -#ifdef LL_WINDOWS -#ifndef INSTANTIATE_GETCHILD_SCROLLLIST -#pragma warning (disable : 4231) -extern template LLScrollListCtrl* LLView::getChild<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..fbcbb55b85 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -1,6 +1,6 @@  /**  - * @file lllineeditor.cpp - * @brief LLLineEditor base class + * @file llsearcheditor.cpp + * @brief LLSearchEditor implementation   *   * $LicenseInfo:firstyear=2001&license=viewergpl$   *  @@ -36,89 +36,63 @@  #include "llsearcheditor.h" -//static LLDefaultWidgetRegistry::Register<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) ; +	S32 btn_top = p.search_button.top_pad + p.search_button.rect.height; +	S32 btn_right = p.search_button.rect.width + p.search_button.left_pad; +	LLRect search_btn_rect(p.search_button.left_pad, btn_top, btn_right, p.search_button.top_pad); + +	LLLineEditor::Params line_editor_params(p); +	line_editor_params.name("filter edit box"); +	line_editor_params.rect(getLocalRect()); +	line_editor_params.follows.flags(FOLLOWS_ALL); +	line_editor_params.text_pad_left(p.text_pad_left + search_btn_rect.getWidth()); +	line_editor_params.commit_callback.function(boost::bind(&LLUICtrl::onCommit, this)); + +	mSearchEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_params); +	addChild(mSearchEditor); + +	LLButton::Params button_params(p.search_button); +	button_params.name(std::string("clear filter")); +	button_params.rect(search_btn_rect) ;  	button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP);  	button_params.tab_stop(false); -	button_params.click_callback.function(boost::bind(&LLSearchEditor::onClearSearch, this, _2)); +	button_params.click_callback.function(boost::bind(&LLUICtrl::onCommit, this)); -	mClearSearchButton = LLUICtrlFactory::create<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..48816e4b9e 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -36,6 +36,7 @@  #include "lltexteditor.h" +#include "llfontfreetype.h" // for LLFontFreetype::FIRST_CHAR  #include "llfontgl.h"  #include "llrender.h"  #include "llui.h" @@ -55,7 +56,6 @@  #include "llundo.h"  #include "llviewborder.h"  #include "llcontrol.h" -#include "llimagegl.h"  #include "llwindow.h"  #include "lltextparser.h"  #include <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), @@ -264,9 +286,10 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p)  	mReflowNeeded(FALSE),  	mScrollNeeded(FALSE),  	mLastSelectionY(-1), +	mParseHTML(FALSE), +	mParseHighlights(FALSE),  	mTabsToNextField(p.ignore_tab), -	mGLFont(p.font), -	mGLFontStyle(LLFontGL::getStyleFromString(p.font.style)) +	mGLFont(p.font)  {  	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); @@ -304,7 +327,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p)  	LLViewBorder::Params params;  	params.name("text ed border");  	params.rect(getLocalRect()); -	params.bevel_type(LLViewBorder::BEVEL_IN); +	params.bevel_style(LLViewBorder::BEVEL_IN);  	params.border_thickness(text_editor_border);  	mBorder = LLUICtrlFactory::create<LLViewBorder> (params);  	addChild( mBorder ); @@ -314,7 +337,6 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p)  	setHideScrollbarForShortDocs(p.hide_scrollbar); -	mParseHTML=FALSE;  	mHTML.clear();  } @@ -377,6 +399,7 @@ void LLTextEditor::updateLineStartList(S32 startpos)  	S32 seg_idx = 0;  	S32 seg_offset = 0; +  	if (!mLineStartList.empty())  	{  		getSegmentAndOffset(startpos, &seg_idx, &seg_offset); @@ -1932,7 +1955,7 @@ void LLTextEditor::pasteHelper(bool is_primary)  		for( S32 i = 0; i < len; i++ )  		{  			llwchar wc = clean_string[i]; -			if( (wc < LLFont::FIRST_CHAR) && (wc != LF) ) +			if( (wc < LLFontFreetype::FIRST_CHAR) && (wc != LF) )  			{  				clean_string[i] = LL_UNKNOWN_CHAR;  			} @@ -3083,8 +3106,8 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32  	if (style->getIsEmbeddedItem())  	{ -		static LLUICachedControl<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 +3126,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32  		S32 start = seg_start;  		S32 end = llmin( selection_left, seg_end );  		S32 length =  end - start; -		font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, mGLFontStyle, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); +		font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems);  	}  	x = *right_x; @@ -3116,7 +3139,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32  		font->render(text, start, x, y_top,  					 LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ), -					 LLFontGL::LEFT, LLFontGL::TOP, mGLFontStyle, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); +					 LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems);  	}  	x = *right_x;  	if( selection_right < seg_end ) @@ -3125,7 +3148,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32  		S32 start = llmax( selection_right, seg_start );  		S32 end = seg_end;  		S32 length = end - start; -		font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, mGLFontStyle, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); +		font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems);  	}   } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index f64353555e..0babd7ba58 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -63,7 +63,7 @@ public:  		Optional<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; @@ -541,6 +515,7 @@ private:  	S32				mDesiredXPixel;			// X pixel position where the user wants the cursor to be  	LLRect			mTextRect;				// The rect in which text is drawn.  Excludes borders.  	// List of offsets and segment index of the start of each line.  Always has at least one node (0). +	struct pred;  	struct line_info  	{  		line_info(S32 segment, S32 offset) : mSegment(segment), mOffset(offset) {} @@ -586,8 +561,6 @@ private:  	BOOL			mAllowEmbeddedItems; -	BOOL 			mAcceptCallingCardNames; -  	LLUUID			mSourceID;  	// If true, the standard edit keys (Ctrl-X, Delete, etc,) are handled here  diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 1d3e5d7a15..fab8f61356 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -43,7 +43,6 @@  #include "v4color.h"  #include "llrender.h"  #include "llrect.h" -#include "llimagegl.h"  #include "lldir.h"  #include "llfontgl.h" @@ -59,8 +58,9 @@  #include "llwindow.h"  // for registration -#include "llsearcheditor.h" +#include "llfiltereditor.h"  #include "llflyoutbutton.h" +#include "llsearcheditor.h"  // for XUIParse  #include "llquaternion.h" @@ -89,9 +89,10 @@ std::list<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,22 +1855,16 @@ 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();  		 itor != sSettingGroups.end(); ++itor)  	{ -		if(itor->second!= NULL) +		LLControlGroup* control_group = itor->second; +		if(control_group != NULL)  		{ -			if (sSettingGroups[(itor->first)]->controlExists(controlname)) -				return *sSettingGroups[(itor->first)]; +			if (control_group->controlExists(controlname)) +				return *control_group;  		}  	} @@ -1942,8 +1936,8 @@ LLLocalClipRect::LLLocalClipRect(const LLRect &rect, BOOL enabled)  namespace LLInitParam  { -	TypedParam<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 +1966,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 +2008,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..b1943a7b02 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -39,14 +39,17 @@  #include "llrect.h"  #include "llcontrol.h"  #include "llcoord.h" -//#include "llhtmlhelp.h"  #include "llgl.h"			// *TODO: break this dependency  #include <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); @@ -221,188 +222,6 @@ private:  	static std::vector<std::string> sXUIPaths;  }; -//	FactoryPolicy is a static class that controls the creation and lookup of UI elements,  -//	such as floaters. -//	The key parameter is used to provide a unique identifier and/or associated construction  -//	parameters for a given UI instance -// -//	Specialize this traits for different types, or provide a class with an identical interface  -//	in the place of the traits parameter -// -//	For example: -// -//	template <> -//	class FactoryPolicy<MyClass> /* FactoryPolicy specialized for MyClass */ -//	{ -//	public: -//		static MyClass* findInstance(const LLSD& key = LLSD()) -//		{ -//			/* return instance of MyClass associated with key */ -//		} -//	 -//		static MyClass* createInstance(const LLSD& key = LLSD()) -//		{ -//			/* create new instance of MyClass using key for construction parameters */ -//		} -//	} -//	 -//	class MyClass : public LLUIFactory<MyClass> -//	{ -//		/* uses FactoryPolicy<MyClass> by default */ -//	} - -template <class T> -class FactoryPolicy -{ -public: -	// basic factory methods -	static T* findInstance(const LLSD& key); // unimplemented, provide specialiation -	static T* createInstance(const LLSD& key); // unimplemented, provide specialiation -}; - -//	VisibilityPolicy controls the visibility of UI elements, such as floaters. -//	The key parameter is used to store the unique identifier of a given UI instance -// -//	Specialize this traits for different types, or duplicate this interface for specific instances -//	(see above) - -template <class T> -class VisibilityPolicy -{ -public: -	// visibility methods -	static bool visible(T* instance, const LLSD& key); // unimplemented, provide specialiation -	static void show(T* instance, const LLSD& key); // unimplemented, provide specialiation -	static void hide(T* instance, const LLSD& key); // unimplemented, provide specialiation -}; - -//	Manages generation of UI elements by LLSD, such that (generally) there is -//	a unique instance per distinct LLSD parameter -//	Class T is the instance type being managed, and the FACTORY_POLICY and VISIBILITY_POLICY  -//	classes provide static methods for creating, accessing, showing and hiding the associated  -//	element T -template <class T, class FACTORY_POLICY = FactoryPolicy<T>, class VISIBILITY_POLICY = VisibilityPolicy<T> > -class LLUIFactory -{ -public: -	// give names to the template parameters so derived classes can refer to them -	// except this doesn't work in gcc -	typedef FACTORY_POLICY factory_policy_t; -	typedef VISIBILITY_POLICY visibility_policy_t; - -	LLUIFactory() -	{ -	} - - 	virtual ~LLUIFactory()  -	{  -	} - -	// default show and hide methods -	static T* showInstance(const LLSD& key = LLSD())  -	{  -		T* instance = getInstance(key);  -		if (instance != NULL) -		{ -			VISIBILITY_POLICY::show(instance, key); -		} -		return instance; -	} - -	static void hideInstance(const LLSD& key = LLSD())  -	{  -		T* instance = getInstance(key);  -		if (instance != NULL) -		{ -			VISIBILITY_POLICY::hide(instance, key); -		} -	} - -	static void toggleInstance(const LLSD& key = LLSD()) -	{ -		if (instanceVisible(key)) -		{ -			hideInstance(key); -		} -		else -		{ -			showInstance(key); -		} -	} - -	static bool instanceVisible(const LLSD& key = LLSD()) -	{ -		T* instance = FACTORY_POLICY::findInstance(key); -		return instance != NULL && VISIBILITY_POLICY::visible(instance, key); -	} - -	static T* getInstance(const LLSD& key = LLSD())  -	{ -		T* instance = FACTORY_POLICY::findInstance(key); -		if (instance == NULL) -		{ -			instance = FACTORY_POLICY::createInstance(key); -		} -		return instance; -	} - -}; - - -//	Creates a UI singleton by ignoring the identifying parameter -//	and always generating the same instance via the LLUIFactory interface. -//	Note that since UI elements can be destroyed by their hierarchy, this singleton -//	pattern uses a static pointer to an instance that will be re-created as needed. -//	 -//	Usage Pattern: -//	 -//	class LLFloaterFoo : public LLFloater, public LLUISingleton<LLFloaterFoo> -//	{ -//		friend class LLUISingleton<LLFloaterFoo>; -//		private: -//			LLFloaterFoo(const LLSD& key); -//	}; -//	 -//	Note that LLUISingleton takes an option VisibilityPolicy parameter that defines -//	how showInstance(), hideInstance(), etc. work. -//  -//  https://wiki.lindenlab.com/mediawiki/index.php?title=LLUISingleton&oldid=79352 - -template <class T, class VISIBILITY_POLICY = VisibilityPolicy<T> > -class LLUISingleton: public LLUIFactory<T, LLUISingleton<T, VISIBILITY_POLICY>, VISIBILITY_POLICY> -{ -protected: - -	// T must derive from LLUISingleton<T> -	LLUISingleton() { sInstance = static_cast<T*>(this); } -	~LLUISingleton() { sInstance = NULL; } - -public: -	static T* findInstance(const LLSD& key = LLSD()) -	{ -		return sInstance; -	} -	 -	static T* createInstance(const LLSD& key = LLSD()) -	{ -		if (sInstance == NULL) -		{ -			sInstance = new T(key); -		} -		return sInstance; -	} - -	static void destroyInstance() -	{ -		delete sInstance; -		sInstance = NULL; -	} -	 -private: -	static T*	sInstance; -}; - -template <class T, class U> T* LLUISingleton<T,U>::sInstance = NULL;  class LLScreenClipRect  { @@ -428,139 +247,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 +377,6 @@ public:  	{}  }; -typedef LLLazyValue<LLColor4> LLUIColor; -  namespace LLInitParam  {  	template<> @@ -707,7 +392,7 @@ namespace LLInitParam  						width,  						height; -		TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func); +		TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);  		LLRect getValueFromBlock() const;  	}; @@ -730,7 +415,7 @@ namespace LLInitParam  		Optional<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 +429,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 +452,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..19d1d4040c 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -38,21 +38,21 @@  #include "llpanel.h"  #include "lluictrlfactory.h" -static LLDefaultWidgetRegistry::Register<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>();  } @@ -125,7 +125,9 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)      mViewModel(viewmodel),  	mControlVariable(NULL),  	mEnabledControlVariable(NULL), -	mDisabledControlVariable(NULL) +	mDisabledControlVariable(NULL), +	mMakeVisibleControlVariable(NULL), +	mMakeInvisibleControlVariable(NULL)  {  	mUICtrlHandle.bind(this);  } @@ -189,7 +191,7 @@ void LLUICtrl::initFromParams(const Params& p)  		}  		else  		{ -			commit_callback_t* initfunc = (CallbackRegistry<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 +202,11 @@ void LLUICtrl::initFromParams(const Params& p)  	if(p.rightclick_callback.isProvided())  		initCommitCallback(p.rightclick_callback, mRightClickSignal); +	if(p.mouseenter_callback.isProvided()) +		initCommitCallback(p.mouseenter_callback, mMouseEnterSignal); + +	if(p.mouseleave_callback.isProvided()) +		initCommitCallback(p.mouseleave_callback, mMouseLeaveSignal);  } @@ -226,7 +233,7 @@ void LLUICtrl::initCommitCallback(const CommitCallbackParam& cb, commit_signal_t  	else  	{  		std::string function_name = cb.function_name; -		commit_callback_t* func = (CallbackRegistry<commit_callback_t>::getValue(function_name)); +		commit_callback_t* func = (CommitCallbackRegistry::getValue(function_name));  		if (func)  		{  			if (cb.parameter.isProvided()) @@ -264,6 +271,17 @@ void LLUICtrl::initEnableCallback(const EnableCallbackParam& cb, enable_signal_t  	}  } +// virtual +void LLUICtrl::onMouseEnter(S32 x, S32 y, MASK mask) +{ +	mMouseEnterSignal(this, getValue()); +} + +// virtual +void LLUICtrl::onMouseLeave(S32 x, S32 y, MASK mask) +{ +	mMouseLeaveSignal(this, getValue()); +}  void LLUICtrl::onCommit()  { @@ -788,38 +806,6 @@ LLUICtrl* LLUICtrl::findRootMostFocusRoot()  	return focus_root;  } - -/* -// Don't let the children handle the tool tip.  Handle it here instead. -BOOL LLUICtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) -{ -	BOOL handled = FALSE; -	if (getVisible() && pointInView( x, y ) )  -	{ -		if( !mToolTipMsg.empty() ) -		{ -			msg = mToolTipMsg; - -			// Convert rect local to screen coordinates -			localPointToScreen(  -				0, 0,  -				&(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); -			localPointToScreen( -				getRect().getWidth(), getRect().getHeight(), -				&(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); - -			handled = TRUE; -		} -	} - -	if (!handled) -	{ -		return LLView::handleToolTip(x, y, msg, sticky_rect_screen); -	} - -	return handled; -}*/ -  // Skip over any parents that are not LLUICtrl's  //  Used in focus logic since only LLUICtrl elements can have focus  LLUICtrl* LLUICtrl::getParentUICtrl() const @@ -865,14 +851,6 @@ BOOL LLUICtrl::getTentative() const  void LLUICtrl::setColor(const LLColor4& color)							  { } -// virtual -void LLUICtrl::setMinValue(LLSD min_value)								 -{ } - -// virtual -void LLUICtrl::setMaxValue(LLSD max_value)								 -{ } -  namespace LLInitParam @@ -900,12 +878,4 @@ namespace LLInitParam      {      	return false;      } - -    template<>  -	bool ParamCompare<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..586b988c43 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -77,6 +77,7 @@ const S32 HPAD = 4;  const S32 VPAD = 4;  const S32 FLOATER_H_MARGIN = 15;  const S32 MIN_WIDGET_HEIGHT = 10; +const S32 MAX_STRING_ATTRIBUTE_SIZE = 40;  LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION("Widget Construction");  LLFastTimer::DeclareTimer FTM_INIT_FROM_PARAMS("Widget InitFromParams"); @@ -85,7 +86,8 @@ LLFastTimer::DeclareTimer FTM_WIDGET_SETUP("Widget Setup");  //-----------------------------------------------------------------------------  // Register widgets that are purely data driven here so they get linked in  #include "llstatview.h" -static LLDefaultWidgetRegistry::Register<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; @@ -194,7 +196,7 @@ static LLFastTimer::DeclareTimer BUILD_FLOATERS("Build Floaters");  //-----------------------------------------------------------------------------  // buildFloater()  //----------------------------------------------------------------------------- -void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename, BOOL open_floater, LLXMLNodePtr output_node) +void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename, LLXMLNodePtr output_node)  {  	LLFastTimer timer(BUILD_FLOATERS);  	LLXMLNodePtr root; @@ -234,7 +236,7 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen  		floaterp->getCommitCallbackRegistrar().pushScope();  		floaterp->getEnableCallbackRegistrar().pushScope(); -		floaterp->initFloaterXML(root, floaterp->getParent(), open_floater, output_node); +		floaterp->initFloaterXML(root, floaterp->getParent(), output_node);  		if (LLUI::sShowXUINames)  		{ @@ -252,13 +254,6 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen  	mFileNames.pop_back();  } -LLFloater* LLUICtrlFactory::buildFloaterFromXML(const std::string& filename, BOOL open_floater) -{ -	LLFloater* floater = new LLFloater(); -	buildFloater(floater, filename, open_floater); -	return floater; -} -  //-----------------------------------------------------------------------------  // saveToXML()  //----------------------------------------------------------------------------- @@ -338,12 +333,12 @@ BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename, L  LLFastTimer::DeclareTimer FTM_CREATE_FROM_XML("Create child widget"); -LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename,  LLXMLNodePtr output_node, const widget_registry_t& registry) +LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t& registry, LLXMLNodePtr output_node)  {  	LLFastTimer timer(FTM_CREATE_FROM_XML);  	std::string ctrl_type = node->getName()->mString;  	LLStringUtil::toLower(ctrl_type); -	 +  	const LLWidgetCreatorFunc* funcp = registry.getValue(ctrl_type);  	if (funcp == NULL)  	{ @@ -398,11 +393,11 @@ BOOL LLUICtrlFactory::getAttributeColor(LLXMLNodePtr node, const std::string& na  {  	std::string colorstring;  	BOOL res = node->getAttributeString(name.c_str(), colorstring); -	if (res && LLUI::sSettingGroups["color"]) +	if (res)  	{ -		if (LLUI::sSettingGroups["color"]->controlExists(colorstring)) +		if (LLUIColorTable::instance().colorExists(colorstring))  		{ -			color.setVec(LLUI::sSettingGroups["color"]->getColor(colorstring)); +			color.setVec(LLUIColorTable::instance().getColor(colorstring));  		}  		else  		{ @@ -448,11 +443,326 @@ void LLUICtrlFactory::popFactoryFunctions()  	}  } -const widget_registry_t& LLUICtrlFactory::getWidgetRegistry(LLView* viewp) +// +// LLXSDWriter +// +LLXSDWriter::LLXSDWriter() +{ +	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)  { -	return viewp->getChildRegistry(); +	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 +820,6 @@ void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, bool  	}  } -void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block) -{ -	mLastWriteGeneration = -1; -	mWriteRootNode = node; -	block.serializeBlock(*this, Parser::name_stack_t(), diff_block); -} - -// go from a stack of names to a specific XML node -LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack) -{ -	name_stack_t name_stack; - -	for (name_stack_t::const_iterator it = stack.begin(); -		it != stack.end(); -		++it) -	{ -		if (!it->first.empty()) -		{ -			name_stack.push_back(*it); -		} -	} - -	if (name_stack.empty() || mWriteRootNode.isNull()) return NULL; - -	std::string attribute_name = name_stack.front().first; - -	// heuristic to make font always attribute of parent node -	bool is_font = (attribute_name == "font"); -	// XML spec says that attributes have their whitespace normalized -	// on parse: http://www.w3.org/TR/REC-xml/#AVNormalize -	// Therefore text-oriented widgets that might have carriage returns -	// have their values serialized as text contents, not the -	// initial_value attribute. JC -	if (attribute_name == "initial_value") -	{ -		const char* root_node_name = mWriteRootNode->getName()->mString; -		if (!strcmp(root_node_name, "text")		// LLTextBox -			|| !strcmp(root_node_name, "text_editor")  -			|| !strcmp(root_node_name, "line_editor")) // for consistency -		{ -			// writeStringValue will write to this node -			return mWriteRootNode; -		} -	} - -	for (name_stack_t::const_iterator it = ++name_stack.begin(); -		it != name_stack.end(); -		++it) -	{ -		attribute_name += "."; -		attribute_name += it->first; -	} - -	// *NOTE: <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 +839,15 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLIn  		// child nodes are not necessarily valid parameters (could be a child widget)  		// so don't complain once we've recursed  		bool silent = mCurReadDepth > 0; -		block.submitValue(mNameStack, *this, silent); -		mNameStack.pop_back(); +		if (!block.submitValue(mNameStack, *this, true)) +		{ +			mNameStack.pop_back(); +			block.submitValue(mNameStack, *this, silent); +		} +		else +		{ +			mNameStack.pop_back(); +		}  	}  	// then traverse children @@ -784,6 +965,62 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo  	return any_parsed;  } +void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block) +{ +	mWriteRootNode = node; +	block.serializeBlock(*this, Parser::name_stack_t(), diff_block); +	mOutNodes.clear(); +} + +// go from a stack of names to a specific XML node +LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack) +{ +	name_stack_t name_stack; +	for (name_stack_t::const_iterator it = stack.begin(); +		it != stack.end(); +		++it) +	{ +		if (!it->first.empty()) +		{ +			name_stack.push_back(*it); +		} +	} + +	LLXMLNodePtr out_node = mWriteRootNode; + +	name_stack_t::const_iterator next_it = name_stack.begin(); +	for (name_stack_t::const_iterator it = name_stack.begin(); +		it != name_stack.end(); +		it = next_it) +	{ +		++next_it; +		if (it->first.empty()) +		{ +			continue; +		} + +		out_nodes_t::iterator found_it = mOutNodes.lower_bound(it->second); + +		// node with this name not yet written +		if (found_it == mOutNodes.end() || mOutNodes.key_comp()(found_it->first, it->second)) +		{ +			// make an attribute if we are the last element on the name stack +			bool is_attribute = next_it == name_stack.end(); +			LLXMLNodePtr new_node = new LLXMLNode(it->first.c_str(), is_attribute); +			out_node->addChild(new_node); +			mOutNodes.insert(found_it, std::make_pair(it->second, new_node)); +			out_node = new_node; +		} +		else +		{ +			out_node = found_it->second; +		} +	} + +	return (out_node == mWriteRootNode ? LLXMLNodePtr(NULL) : out_node); +} + +  bool LLXUIParser::readBoolValue(void* val_ptr)  {  	S32 value; @@ -814,7 +1051,27 @@ bool LLXUIParser::writeStringValue(const void* val_ptr, const name_stack_t& stac  	LLXMLNodePtr node = getNode(stack);  	if (node.notNull())  	{ -		node->setStringValue(*((std::string*)val_ptr)); +		const std::string* string_val = reinterpret_cast<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 +1267,7 @@ bool LLXUIParser::writeUIColorValue(const void* val_ptr, const name_stack_t& sta  		LLUIColor color = *((LLUIColor*)val_ptr);  		//RN: don't write out the color that is represented by a function  		// rely on param block exporting to get the reference to the color settings -		if (color.isUsingFunction()) return false; +		if (color.isReference()) return false;  		node->setFloatValue(4, color.get().mV);  		return true;  	} @@ -1051,7 +1308,26 @@ bool LLXUIParser::writeSDValue(const void* val_ptr, const name_stack_t& stack)  	LLXMLNodePtr node = getNode(stack);  	if (node.notNull())  	{ -		node->setStringValue(((LLSD*)val_ptr)->asString()); +		std::string string_val = ((LLSD*)val_ptr)->asString(); +		if (string_val.find('\n') != std::string::npos || string_val.size() > MAX_STRING_ATTRIBUTE_SIZE) +		{ +			// don't write strings with newlines into attributes +			std::string attribute_name = node->getName()->mString; +			LLXMLNodePtr parent_node = node->mParent; +			parent_node->deleteChild(node); +			// write results in text contents of node +			if (attribute_name == "value") +			{ +				// "value" is implicit, just write to parent +				node = parent_node; +			} +			else +			{ +				node = parent_node->createChild(attribute_name.c_str(), false); +			} +		} + +		node->setStringValue(string_val);  		return true;  	}  	return false; diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index b9c61b1fed..9dbe458bae 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -41,11 +41,42 @@  #include <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,15 +259,15 @@ 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); -	LLFloater* buildFloaterFromXML(const std::string& filename, BOOL open_floater = TRUE); +	void buildFloater(LLFloater* floaterp, const std::string &filename, LLXMLNodePtr output_node);  	BOOL buildPanel(LLPanel* panelp, const std::string &filename, LLXMLNodePtr output_node = NULL);  	// Does what you want for LLFloaters and LLPanels @@ -252,12 +301,10 @@ public:  		return widget;  	} -	LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename,  LLXMLNodePtr output_node, const widget_registry_t&  ); +	LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t&, LLXMLNodePtr output_node ); -	static const widget_registry_t& getWidgetRegistry(LLView*); -	  	template<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 +330,7 @@ public:  				goto fail;  			} -			LLView* view = getInstance()->createFromXML(root_node, parent, filename, output_node, getWidgetRegistry(parent)); +			LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, output_node);  			if (view)  			{  				widget = dynamic_cast<T*>(view); @@ -304,8 +351,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 +364,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 +408,10 @@ fail:  			S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : -1;  			setCtrlParent(widget, parent, tab_group);  		} +		 +		typedef typename T::child_registry_t registry_t; -		createChildren(widget, node, output_node); +		createChildren(widget, node, registry_t::instance(), output_node);  		if (!widget->postBuild())  		{ @@ -373,7 +422,7 @@ fail:  		return widget;  	} -	static void createChildren(LLView* viewp, LLXMLNodePtr node, LLXMLNodePtr output_node = NULL); +	static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL);  	static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root); @@ -395,20 +444,32 @@ private:  	std::vector<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 +478,15 @@ class LLRegisterPanelClass  {  public:  	// reigister with either the provided builder, or the generic templated builder -	void addPanelClass(const std::string& tag,LLPannelClassCreatorFunc func) +	void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func)  	{ -		mPannelClassesNames[tag] = func; +		mPanelClassesNames[tag] = func;  	}  	LLPanel* createPanelClass(const std::string& tag)  	{ -		param_name_map_t::iterator iT =  mPannelClassesNames.find(tag); -		if(iT == mPannelClassesNames.end()) +		param_name_map_t::iterator iT =  mPanelClassesNames.find(tag); +		if(iT == mPanelClassesNames.end())  			return 0;  		return iT->second();  	} @@ -437,9 +498,9 @@ public:  	}  private: -	typedef std::map< std::string, LLPannelClassCreatorFunc> param_name_map_t; +	typedef std::map< std::string, LLPanelClassCreatorFunc> param_name_map_t; -	param_name_map_t mPannelClassesNames; +	param_name_map_t mPanelClassesNames;  }; diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp index 8e0de0cb0c..ab0d65e731 100644 --- a/indra/llui/lluiimage.cpp +++ b/indra/llui/lluiimage.cpp @@ -39,7 +39,7 @@  #include "lluiimage.h"  #include "llui.h" -LLUIImage::LLUIImage(const std::string& name, LLPointer<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..d94472a8e5 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -99,10 +99,15 @@ LLView::Params::Params()  	left_delta("left_delta", S32_MAX),  	center_horiz("center_horiz", false),  	center_vert("center_vert", false), -	serializable("", false), +	from_xui("from_xui", false),  	user_resize("user_resize"),  	auto_resize("auto_resize"), -	needs_translate("translate") +	needs_translate("translate"), +	xmlns("xmlns"), +	xmlns_xsi("xmlns:xsi"), +	xsi_schemaLocation("xsi:schemaLocation"), +	xsi_type("xsi:type") +  {  	addSynonym(rect, "");  } @@ -111,7 +116,7 @@ LLView::LLView(const LLView::Params& p)  :	mName(p.name),  	mParentView(NULL),  	mReshapeFlags(FOLLOWS_NONE), -	mSaveToXML(p.serializable), +	mSaveToXML(p.from_xui),  	mIsFocusRoot(FALSE),  	mLastVisible(FALSE),  	mNextInsertionOrdinal(0), @@ -396,32 +401,28 @@ bool LLCompareByTabOrder::operator() (const LLView* const a, const LLView* const  	return (a_score == b_score) ? a < b : a_score < b_score;  } -BOOL LLView::isInVisibleChain() const +bool LLView::trueToRoot(const boost::function<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 @@ -602,14 +603,14 @@ void LLView::setVisible(BOOL visible)  		if (!getParent() || getParent()->isInVisibleChain())  		{  			// tell all children of this view that the visibility may have changed -			onVisibilityChange( visible ); +			handleVisibilityChange( visible );  		}  		updateBoundingRect();  	}  }  // virtual -void LLView::onVisibilityChange ( BOOL new_visibility ) +void LLView::handleVisibilityChange ( BOOL new_visibility )  {  	for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)  	{ @@ -617,7 +618,7 @@ void LLView::onVisibilityChange ( BOOL new_visibility )  		// only views that are themselves visible will have their overall visibility affected by their ancestors  		if (viewp->getVisible())  		{ -			viewp->onVisibilityChange ( new_visibility ); +			viewp->handleVisibilityChange ( new_visibility );  		}  	}  } @@ -738,12 +739,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_s  		msg = tool_tip;  		// Convert rect local to screen coordinates -		localPointToScreen( -			0, 0, -			&(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); -		localPointToScreen( -			mRect.getWidth(), mRect.getHeight(), -			&(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); +		*sticky_rect_screen = calcScreenRect();  	}  	// don't allow any siblings to handle this event  	// even if we don't have a tooltip @@ -1325,13 +1321,6 @@ void LLView::draw()  		LLRect rootRect = getRootView()->getRect();  		LLRect screenRect; -		// draw focused control on top of everything else -		LLView* focus_view = gFocusMgr.getKeyboardFocus(); -		if (focus_view && focus_view->getParent() != this) -		{ -			focus_view = NULL; -		} -  		++sDepth;  		for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend();)  // ++child_iter) @@ -1339,7 +1328,7 @@ void LLView::draw()  			child_list_reverse_iter_t child = child_iter++;  			LLView *viewp = *child; -			if (viewp->getVisible() && viewp != focus_view && viewp->getRect().isValid()) +			if (viewp->getVisible() && viewp->getRect().isValid())  			{  				// Only draw views that are within the root view  				localRectToScreen(viewp->getRect(),&screenRect); @@ -1357,11 +1346,6 @@ void LLView::draw()  		}  		--sDepth; - -		if (focus_view && focus_view->getVisible()) -		{ -			drawChild(focus_view); -		}  	}  	gGL.getTexUnit(0)->disable(); @@ -1398,7 +1382,7 @@ void LLView::drawDebugRect()  			}  			else  			{ -				static LLUICachedControl<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..ee49276139 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -93,7 +93,7 @@ virtual void	setEnabled(BOOL enabled)	{ mEnabled = enabled; }  		LLCheckBoxCtrl, LLComboBox, LLLineEditor, LLMenuGL, LLRadioGroup, etc  virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text ) { return FALSE; }  		LLUICtrl, LLButton, LLCheckBoxCtrl, LLLineEditor, LLMenuGL, LLSliderCtrl -virtual void	onVisibilityChange ( BOOL curVisibilityIn ); +virtual void	handleVisibilityChange ( BOOL curVisibilityIn );  		LLMenuGL  virtual LLRect getSnapRect() const	{ return mRect; } *TODO: Make non virtual  		LLFloater @@ -138,6 +138,9 @@ virtual BOOL	handleUnicodeCharHere(llwchar uni_char);  		*  */ +class LLViewWidgetRegistry : public LLChildRegistry<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; @@ -337,7 +349,7 @@ public:  	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text ); -	virtual void	onVisibilityChange ( BOOL curVisibilityIn ); +	virtual void	handleVisibilityChange ( BOOL new_visibility );  	void			pushVisible(BOOL visible)	{ mLastVisible = mVisible; setVisible(visible); }  	void			popVisible()				{ setVisible(mLastVisible); } @@ -496,9 +508,6 @@ public:  		return dynamic_cast<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;  | 
