diff options
author | Jacek Antonelli | 2008-08-15 23:45:27 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:27 -0500 |
commit | a8a62201ba762e98dff92cf49033e577fc34d8d4 (patch) | |
tree | 11f8513c5cdc222f2fac0c93eb724c089803c200 /linden/indra/llui | |
parent | Second Life viewer sources 1.18.6.4-RC (diff) | |
download | meta-impy-a8a62201ba762e98dff92cf49033e577fc34d8d4.zip meta-impy-a8a62201ba762e98dff92cf49033e577fc34d8d4.tar.gz meta-impy-a8a62201ba762e98dff92cf49033e577fc34d8d4.tar.bz2 meta-impy-a8a62201ba762e98dff92cf49033e577fc34d8d4.tar.xz |
Second Life viewer sources 1.19.0.0
Diffstat (limited to '')
88 files changed, 4267 insertions, 1963 deletions
diff --git a/linden/indra/llui/llalertdialog.cpp b/linden/indra/llui/llalertdialog.cpp index fd0262d..204fb10 100644 --- a/linden/indra/llui/llalertdialog.cpp +++ b/linden/indra/llui/llalertdialog.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -41,6 +41,7 @@ | |||
41 | #include "llcheckboxctrl.h" | 41 | #include "llcheckboxctrl.h" |
42 | #include "llkeyboard.h" | 42 | #include "llkeyboard.h" |
43 | #include "llfocusmgr.h" | 43 | #include "llfocusmgr.h" |
44 | #include "lliconctrl.h" | ||
44 | #include "llui.h" | 45 | #include "llui.h" |
45 | #include "llxmlnode.h" | 46 | #include "llxmlnode.h" |
46 | #include "lllineeditor.h" | 47 | #include "lllineeditor.h" |
@@ -143,6 +144,7 @@ LLAlertDialog::LLAlertDialog( const LLAlertDialogTemplate* xml_template, | |||
143 | mDefaultOption( 0 ), | 144 | mDefaultOption( 0 ), |
144 | mOptionChosen( -1 ), | 145 | mOptionChosen( -1 ), |
145 | mCheck(NULL), | 146 | mCheck(NULL), |
147 | mCaution(xml_template->mCaution), | ||
146 | mUnique(xml_template->mUnique), | 148 | mUnique(xml_template->mUnique), |
147 | mIgnorable(xml_template->mIgnorable), | 149 | mIgnorable(xml_template->mIgnorable), |
148 | mLabel(xml_template->mLabel), | 150 | mLabel(xml_template->mLabel), |
@@ -211,6 +213,16 @@ bool LLAlertDialog::show() | |||
211 | } | 213 | } |
212 | } | 214 | } |
213 | 215 | ||
216 | // If this is a caution message, change the color and add an icon. | ||
217 | if (mCaution) | ||
218 | { | ||
219 | setBackgroundColor( LLUI::sColorsGroup->getColor( "AlertCautionBoxColor" ) ); | ||
220 | } | ||
221 | else | ||
222 | { | ||
223 | setBackgroundColor( LLUI::sColorsGroup->getColor( "AlertBoxColor" ) ); | ||
224 | } | ||
225 | |||
214 | // Check to see if we are already displaying the alert | 226 | // Check to see if we are already displaying the alert |
215 | if (mUnique) | 227 | if (mUnique) |
216 | { | 228 | { |
@@ -311,19 +323,35 @@ void LLAlertDialog::createDialog(const std::vector<LLString>* optionsp, S32 defa | |||
311 | dialog_width = llmax(dialog_width, S32(font->getWidth( edit_text ) + 0.99f)); | 323 | dialog_width = llmax(dialog_width, S32(font->getWidth( edit_text ) + 0.99f)); |
312 | dialog_height += EDITOR_HEIGHT; | 324 | dialog_height += EDITOR_HEIGHT; |
313 | } | 325 | } |
314 | 326 | if (mCaution) | |
327 | { | ||
328 | // Make room for the caution icon. | ||
329 | dialog_width += 32 + HPAD; | ||
330 | } | ||
315 | reshape( dialog_width, dialog_height, FALSE ); | 331 | reshape( dialog_width, dialog_height, FALSE ); |
316 | 332 | ||
317 | S32 msg_y = mRect.getHeight() - VPAD; | 333 | S32 msg_y = mRect.getHeight() - VPAD; |
334 | S32 msg_x = HPAD; | ||
318 | if (hasTitleBar()) | 335 | if (hasTitleBar()) |
319 | { | 336 | { |
320 | msg_y -= LINE_HEIGHT; // room for title | 337 | msg_y -= LINE_HEIGHT; // room for title |
321 | } | 338 | } |
322 | 339 | ||
340 | if (mCaution) | ||
341 | { | ||
342 | LLIconCtrl* icon = new LLIconCtrl("icon", LLRect(msg_x, msg_y, msg_x+32, msg_y-32), "notify_caution_icon.tga"); | ||
343 | icon->setMouseOpaque(FALSE); | ||
344 | addChild(icon); | ||
345 | msg_x += 32 + HPAD; | ||
346 | msg_box->setColor( LLUI::sColorsGroup->getColor( "AlertCautionTextColor" ) ); | ||
347 | } | ||
348 | else | ||
349 | { | ||
350 | msg_box->setColor( LLUI::sColorsGroup->getColor( "AlertTextColor" ) ); | ||
351 | } | ||
323 | LLRect rect; | 352 | LLRect rect; |
324 | rect.setLeftTopAndSize( HPAD, msg_y, text_rect.getWidth(), text_rect.getHeight() ); | 353 | rect.setLeftTopAndSize( msg_x, msg_y, text_rect.getWidth(), text_rect.getHeight() ); |
325 | msg_box->setRect( rect ); | 354 | msg_box->setRect( rect ); |
326 | msg_box->setColor( LLUI::sColorsGroup->getColor( "LabelTextColor" ) ); | ||
327 | addChild(msg_box); | 355 | addChild(msg_box); |
328 | 356 | ||
329 | // Buttons | 357 | // Buttons |
@@ -688,6 +716,15 @@ bool LLAlertDialog::parseAlerts(const LLString& xml_filename, LLControlGroup* se | |||
688 | xml_template->mModal = modal; | 716 | xml_template->mModal = modal; |
689 | } | 717 | } |
690 | } | 718 | } |
719 | // caution= | ||
720 | BOOL caution; | ||
721 | if (alert->getAttributeBOOL("caution", caution)) | ||
722 | { | ||
723 | if (xml_template) | ||
724 | { | ||
725 | xml_template->mCaution = caution; | ||
726 | } | ||
727 | } | ||
691 | // unique= | 728 | // unique= |
692 | BOOL unique; | 729 | BOOL unique; |
693 | if (alert->getAttributeBOOL("unique", unique)) | 730 | if (alert->getAttributeBOOL("unique", unique)) |
diff --git a/linden/indra/llui/llalertdialog.h b/linden/indra/llui/llalertdialog.h index 016a4b4..31f4769 100644 --- a/linden/indra/llui/llalertdialog.h +++ b/linden/indra/llui/llalertdialog.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -78,6 +78,7 @@ public: | |||
78 | 78 | ||
79 | bool setCheckBox( const LLString&, const LLString& ); | 79 | bool setCheckBox( const LLString&, const LLString& ); |
80 | void setOptionEnabled( S32 option, BOOL enable ); | 80 | void setOptionEnabled( S32 option, BOOL enable ); |
81 | void setCaution(BOOL val = TRUE) { mCaution = val; } | ||
81 | // If mUnique==TRUE only one copy of this message should exist | 82 | // If mUnique==TRUE only one copy of this message should exist |
82 | void setUnique(BOOL val = TRUE) { mUnique = val; } | 83 | void setUnique(BOOL val = TRUE) { mUnique = val; } |
83 | void setEditTextCallback(alert_text_callback_t callback, void *user_data); | 84 | void setEditTextCallback(alert_text_callback_t callback, void *user_data); |
@@ -129,6 +130,7 @@ protected: | |||
129 | S32 mDefaultOption; | 130 | S32 mDefaultOption; |
130 | BOOL mOptionChosen; | 131 | BOOL mOptionChosen; |
131 | LLCheckBoxCtrl* mCheck; | 132 | LLCheckBoxCtrl* mCheck; |
133 | BOOL mCaution; | ||
132 | BOOL mUnique; | 134 | BOOL mUnique; |
133 | S32 mIgnorable; | 135 | S32 mIgnorable; |
134 | LLString mLabel; | 136 | LLString mLabel; |
@@ -163,7 +165,7 @@ private: | |||
163 | class LLAlertDialogTemplate : public LLRefCount | 165 | class LLAlertDialogTemplate : public LLRefCount |
164 | { | 166 | { |
165 | public: | 167 | public: |
166 | LLAlertDialogTemplate() : mTitle(), mURLOption(0), mModal(FALSE), mUnique(FALSE), mIgnorable(0), mDefaultOption(0) {} | 168 | LLAlertDialogTemplate() : mTitle(), mURLOption(0), mModal(FALSE), mCaution(FALSE), mUnique(FALSE), mIgnorable(0), mDefaultOption(0) {} |
167 | 169 | ||
168 | void addOption(const LLString& label, const LLString& ignore_text, BOOL is_default = FALSE) | 170 | void addOption(const LLString& label, const LLString& ignore_text, BOOL is_default = FALSE) |
169 | { | 171 | { |
@@ -205,6 +207,7 @@ public: | |||
205 | LLString mURL; // Some alerts will direct the resident to a URL | 207 | LLString mURL; // Some alerts will direct the resident to a URL |
206 | S32 mURLOption; | 208 | S32 mURLOption; |
207 | BOOL mModal; | 209 | BOOL mModal; |
210 | BOOL mCaution; | ||
208 | BOOL mUnique; | 211 | BOOL mUnique; |
209 | S32 mIgnorable; // 0 = Never Ignore, 1 = Do default option, 2 = Do saved option | 212 | S32 mIgnorable; // 0 = Never Ignore, 1 = Do default option, 2 = Do saved option |
210 | std::vector<LLString> mOptions; | 213 | std::vector<LLString> mOptions; |
diff --git a/linden/indra/llui/llbutton.cpp b/linden/indra/llui/llbutton.cpp index 71260b2..9fa1c8e 100644 --- a/linden/indra/llui/llbutton.cpp +++ b/linden/indra/llui/llbutton.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -59,9 +59,6 @@ S32 BTN_HEIGHT = 0; | |||
59 | S32 BTN_GRID = 12; | 59 | S32 BTN_GRID = 12; |
60 | S32 BORDER_SIZE = 1; | 60 | S32 BORDER_SIZE = 1; |
61 | 61 | ||
62 | // static | ||
63 | LLFrameTimer LLButton::sFlashingTimer; | ||
64 | |||
65 | LLButton::LLButton( const LLString& name, const LLRect& rect, const LLString& control_name, void (*click_callback)(void*), void *callback_data) | 62 | LLButton::LLButton( const LLString& name, const LLRect& rect, const LLString& control_name, void (*click_callback)(void*), void *callback_data) |
66 | : LLUICtrl(name, rect, TRUE, NULL, NULL), | 63 | : LLUICtrl(name, rect, TRUE, NULL, NULL), |
67 | mClickedCallback( click_callback ), | 64 | mClickedCallback( click_callback ), |
@@ -79,6 +76,7 @@ LLButton::LLButton( const LLString& name, const LLRect& rect, const LLString& co | |||
79 | mImageDisabled( NULL ), | 76 | mImageDisabled( NULL ), |
80 | mImageDisabledSelected( NULL ), | 77 | mImageDisabledSelected( NULL ), |
81 | mToggleState( FALSE ), | 78 | mToggleState( FALSE ), |
79 | mIsToggle( FALSE ), | ||
82 | mScaleImage( TRUE ), | 80 | mScaleImage( TRUE ), |
83 | mDropShadowedText( TRUE ), | 81 | mDropShadowedText( TRUE ), |
84 | mBorderEnabled( FALSE ), | 82 | mBorderEnabled( FALSE ), |
@@ -86,8 +84,6 @@ LLButton::LLButton( const LLString& name, const LLRect& rect, const LLString& co | |||
86 | mHAlign( LLFontGL::HCENTER ), | 84 | mHAlign( LLFontGL::HCENTER ), |
87 | mLeftHPad( LLBUTTON_H_PAD ), | 85 | mLeftHPad( LLBUTTON_H_PAD ), |
88 | mRightHPad( LLBUTTON_H_PAD ), | 86 | mRightHPad( LLBUTTON_H_PAD ), |
89 | mFixedWidth( 16 ), | ||
90 | mFixedHeight( 16 ), | ||
91 | mHoverGlowStrength(0.15f), | 87 | mHoverGlowStrength(0.15f), |
92 | mCurGlowStrength(0.f), | 88 | mCurGlowStrength(0.f), |
93 | mNeedsHighlight(FALSE), | 89 | mNeedsHighlight(FALSE), |
@@ -134,6 +130,7 @@ LLButton::LLButton(const LLString& name, const LLRect& rect, | |||
134 | mImageDisabled( NULL ), | 130 | mImageDisabled( NULL ), |
135 | mImageDisabledSelected( NULL ), | 131 | mImageDisabledSelected( NULL ), |
136 | mToggleState( FALSE ), | 132 | mToggleState( FALSE ), |
133 | mIsToggle( FALSE ), | ||
137 | mScaleImage( TRUE ), | 134 | mScaleImage( TRUE ), |
138 | mDropShadowedText( TRUE ), | 135 | mDropShadowedText( TRUE ), |
139 | mBorderEnabled( FALSE ), | 136 | mBorderEnabled( FALSE ), |
@@ -141,8 +138,6 @@ LLButton::LLButton(const LLString& name, const LLRect& rect, | |||
141 | mHAlign( LLFontGL::HCENTER ), | 138 | mHAlign( LLFontGL::HCENTER ), |
142 | mLeftHPad( LLBUTTON_H_PAD ), | 139 | mLeftHPad( LLBUTTON_H_PAD ), |
143 | mRightHPad( LLBUTTON_H_PAD ), | 140 | mRightHPad( LLBUTTON_H_PAD ), |
144 | mFixedWidth( 16 ), | ||
145 | mFixedHeight( 16 ), | ||
146 | mHoverGlowStrength(0.25f), | 141 | mHoverGlowStrength(0.25f), |
147 | mCurGlowStrength(0.f), | 142 | mCurGlowStrength(0.f), |
148 | mNeedsHighlight(FALSE), | 143 | mNeedsHighlight(FALSE), |
@@ -158,15 +153,11 @@ LLButton::LLButton(const LLString& name, const LLRect& rect, | |||
158 | 153 | ||
159 | if( unselected_image_name != "" ) | 154 | if( unselected_image_name != "" ) |
160 | { | 155 | { |
156 | // user-specified image - don't use fixed borders unless requested | ||
161 | setImageUnselected(unselected_image_name); | 157 | setImageUnselected(unselected_image_name); |
162 | setImageDisabled(unselected_image_name); | 158 | setImageDisabled(unselected_image_name); |
163 | 159 | ||
164 | mDisabledImageColor.mV[VALPHA] = 0.5f; | 160 | mDisabledImageColor.mV[VALPHA] = 0.5f; |
165 | mImageDisabled = mImageUnselected; | ||
166 | mDisabledImageColor.mV[VALPHA] = 0.5f; | ||
167 | // user-specified image - don't use fixed borders unless requested | ||
168 | mFixedWidth = 0; | ||
169 | mFixedHeight = 0; | ||
170 | mScaleImage = FALSE; | 161 | mScaleImage = FALSE; |
171 | } | 162 | } |
172 | else | 163 | else |
@@ -177,13 +168,11 @@ LLButton::LLButton(const LLString& name, const LLRect& rect, | |||
177 | 168 | ||
178 | if( selected_image_name != "" ) | 169 | if( selected_image_name != "" ) |
179 | { | 170 | { |
171 | // user-specified image - don't use fixed borders unless requested | ||
180 | setImageSelected(selected_image_name); | 172 | setImageSelected(selected_image_name); |
181 | setImageDisabledSelected(selected_image_name); | 173 | setImageDisabledSelected(selected_image_name); |
182 | 174 | ||
183 | mDisabledImageColor.mV[VALPHA] = 0.5f; | 175 | mDisabledImageColor.mV[VALPHA] = 0.5f; |
184 | // user-specified image - don't use fixed borders unless requested | ||
185 | mFixedWidth = 0; | ||
186 | mFixedHeight = 0; | ||
187 | mScaleImage = FALSE; | 176 | mScaleImage = FALSE; |
188 | } | 177 | } |
189 | else | 178 | else |
@@ -273,6 +262,12 @@ void LLButton::onCommit() | |||
273 | make_ui_sound("UISndClickRelease"); | 262 | make_ui_sound("UISndClickRelease"); |
274 | } | 263 | } |
275 | 264 | ||
265 | if (mIsToggle) | ||
266 | { | ||
267 | toggleState(); | ||
268 | } | ||
269 | |||
270 | // do this last, as it can result in destroying this button | ||
276 | if (mClickedCallback) | 271 | if (mClickedCallback) |
277 | { | 272 | { |
278 | (*mClickedCallback)( mCallbackUserData ); | 273 | (*mClickedCallback)( mCallbackUserData ); |
@@ -286,6 +281,11 @@ BOOL LLButton::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) | |||
286 | BOOL handled = FALSE; | 281 | BOOL handled = FALSE; |
287 | if( getVisible() && mEnabled && !called_from_parent && ' ' == uni_char && !gKeyboard->getKeyRepeated(' ')) | 282 | if( getVisible() && mEnabled && !called_from_parent && ' ' == uni_char && !gKeyboard->getKeyRepeated(' ')) |
288 | { | 283 | { |
284 | if (mIsToggle) | ||
285 | { | ||
286 | toggleState(); | ||
287 | } | ||
288 | |||
289 | if (mClickedCallback) | 289 | if (mClickedCallback) |
290 | { | 290 | { |
291 | (*mClickedCallback)( mCallbackUserData ); | 291 | (*mClickedCallback)( mCallbackUserData ); |
@@ -302,11 +302,17 @@ BOOL LLButton::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) | |||
302 | { | 302 | { |
303 | if( mCommitOnReturn && KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key)) | 303 | if( mCommitOnReturn && KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key)) |
304 | { | 304 | { |
305 | if (mIsToggle) | ||
306 | { | ||
307 | toggleState(); | ||
308 | } | ||
309 | |||
310 | handled = TRUE; | ||
311 | |||
305 | if (mClickedCallback) | 312 | if (mClickedCallback) |
306 | { | 313 | { |
307 | (*mClickedCallback)( mCallbackUserData ); | 314 | (*mClickedCallback)( mCallbackUserData ); |
308 | } | 315 | } |
309 | handled = TRUE; | ||
310 | } | 316 | } |
311 | } | 317 | } |
312 | return handled; | 318 | return handled; |
@@ -354,6 +360,9 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) | |||
354 | (*mMouseUpCallback)(mCallbackUserData); | 360 | (*mMouseUpCallback)(mCallbackUserData); |
355 | } | 361 | } |
356 | 362 | ||
363 | mMouseDownTimer.stop(); | ||
364 | mMouseDownTimer.reset(); | ||
365 | |||
357 | // DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked. | 366 | // DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked. |
358 | // If mouseup in the widget, it's been clicked | 367 | // If mouseup in the widget, it's been clicked |
359 | if (pointInView(x, y)) | 368 | if (pointInView(x, y)) |
@@ -363,6 +372,11 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) | |||
363 | make_ui_sound("UISndClickRelease"); | 372 | make_ui_sound("UISndClickRelease"); |
364 | } | 373 | } |
365 | 374 | ||
375 | if (mIsToggle) | ||
376 | { | ||
377 | toggleState(); | ||
378 | } | ||
379 | |||
366 | if (mClickedCallback) | 380 | if (mClickedCallback) |
367 | { | 381 | { |
368 | (*mClickedCallback)( mCallbackUserData ); | 382 | (*mClickedCallback)( mCallbackUserData ); |
@@ -422,8 +436,10 @@ void LLButton::draw() | |||
422 | BOOL flash = FALSE; | 436 | BOOL flash = FALSE; |
423 | if( mFlashing ) | 437 | if( mFlashing ) |
424 | { | 438 | { |
425 | F32 elapsed = LLButton::sFlashingTimer.getElapsedTimeF32(); | 439 | F32 elapsed = mFlashingTimer.getElapsedTimeF32(); |
426 | flash = S32(elapsed * 2) & 1; | 440 | S32 flash_count = S32(elapsed * LLUI::sConfigGroup->getF32("ButtonFlashRate") * 2.f); |
441 | // flash on or off? | ||
442 | flash = (flash_count % 2 == 0) || flash_count > (F32)LLUI::sConfigGroup->getS32("ButtonFlashCount"); | ||
427 | } | 443 | } |
428 | 444 | ||
429 | BOOL pressed_by_keyboard = FALSE; | 445 | BOOL pressed_by_keyboard = FALSE; |
@@ -443,24 +459,14 @@ void LLButton::draw() | |||
443 | cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]); | 459 | cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]); |
444 | screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y); | 460 | screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y); |
445 | 461 | ||
446 | BOOL pressed = pressed_by_keyboard || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y)); | 462 | BOOL pressed = pressed_by_keyboard |
447 | 463 | || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y)) | |
448 | BOOL display_state = FALSE; | 464 | || mToggleState; |
449 | if( pressed ) | ||
450 | { | ||
451 | mImagep = mImageSelected; | ||
452 | // show the resulting state after releasing the mouse button while it is down | ||
453 | display_state = mToggleState ? FALSE : TRUE; | ||
454 | } | ||
455 | else | ||
456 | { | ||
457 | display_state = mToggleState || flash; | ||
458 | } | ||
459 | 465 | ||
460 | BOOL use_glow_effect = FALSE; | 466 | BOOL use_glow_effect = FALSE; |
461 | if ( mNeedsHighlight ) | 467 | if ( mNeedsHighlight || flash ) |
462 | { | 468 | { |
463 | if (display_state) | 469 | if (pressed) |
464 | { | 470 | { |
465 | if (mImageHoverSelected) | 471 | if (mImageHoverSelected) |
466 | { | 472 | { |
@@ -485,7 +491,7 @@ void LLButton::draw() | |||
485 | } | 491 | } |
486 | } | 492 | } |
487 | } | 493 | } |
488 | else if ( display_state ) | 494 | else if ( pressed ) |
489 | { | 495 | { |
490 | mImagep = mImageSelected; | 496 | mImagep = mImageSelected; |
491 | } | 497 | } |
@@ -499,11 +505,11 @@ void LLButton::draw() | |||
499 | // enabled and tentative | 505 | // enabled and tentative |
500 | // or | 506 | // or |
501 | // disabled but checked | 507 | // disabled but checked |
502 | if (!mImageDisabledSelected.isNull() && ( (mEnabled && mTentative) || (!mEnabled && display_state ) ) ) | 508 | if (!mImageDisabledSelected.isNull() && ( (mEnabled && mTentative) || (!mEnabled && pressed ) ) ) |
503 | { | 509 | { |
504 | mImagep = mImageDisabledSelected; | 510 | mImagep = mImageDisabledSelected; |
505 | } | 511 | } |
506 | else if (!mImageDisabled.isNull() && !mEnabled && !display_state) | 512 | else if (!mImageDisabled.isNull() && !mEnabled && !pressed) |
507 | { | 513 | { |
508 | mImagep = mImageDisabled; | 514 | mImagep = mImageDisabled; |
509 | } | 515 | } |
@@ -516,33 +522,34 @@ void LLButton::draw() | |||
516 | // Figure out appropriate color for the text | 522 | // Figure out appropriate color for the text |
517 | LLColor4 label_color; | 523 | LLColor4 label_color; |
518 | 524 | ||
525 | // label changes when button state changes, not when pressed | ||
519 | if ( mEnabled ) | 526 | if ( mEnabled ) |
520 | { | 527 | { |
521 | if ( !display_state ) | 528 | if ( mToggleState ) |
522 | { | 529 | { |
523 | label_color = mUnselectedLabelColor; | 530 | label_color = mSelectedLabelColor; |
524 | } | 531 | } |
525 | else | 532 | else |
526 | { | 533 | { |
527 | label_color = mSelectedLabelColor; | 534 | label_color = mUnselectedLabelColor; |
528 | } | 535 | } |
529 | } | 536 | } |
530 | else | 537 | else |
531 | { | 538 | { |
532 | if ( !display_state ) | 539 | if ( mToggleState ) |
533 | { | 540 | { |
534 | label_color = mDisabledLabelColor; | 541 | label_color = mDisabledSelectedLabelColor; |
535 | } | 542 | } |
536 | else | 543 | else |
537 | { | 544 | { |
538 | label_color = mDisabledSelectedLabelColor; | 545 | label_color = mDisabledLabelColor; |
539 | } | 546 | } |
540 | } | 547 | } |
541 | 548 | ||
542 | // Unselected label assignments | 549 | // Unselected label assignments |
543 | LLWString label; | 550 | LLWString label; |
544 | 551 | ||
545 | if( display_state ) | 552 | if( mToggleState ) |
546 | { | 553 | { |
547 | if( mEnabled || mDisabledSelectedLabel.empty() ) | 554 | if( mEnabled || mDisabledSelectedLabel.empty() ) |
548 | { | 555 | { |
@@ -591,24 +598,22 @@ void LLButton::draw() | |||
591 | // Otherwise draw basic rectangular button. | 598 | // Otherwise draw basic rectangular button. |
592 | if( mImagep.notNull() && !mScaleImage) | 599 | if( mImagep.notNull() && !mScaleImage) |
593 | { | 600 | { |
594 | gl_draw_image( 0, 0, mImagep, mEnabled ? mImageColor : mDisabledImageColor ); | 601 | mImagep->draw(0, 0, mEnabled ? mImageColor : mDisabledImageColor ); |
595 | if (mCurGlowStrength > 0.01f) | 602 | if (mCurGlowStrength > 0.01f) |
596 | { | 603 | { |
597 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | 604 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); |
598 | gl_draw_scaled_image_with_border(0, 0, 0, 0, mImagep->getWidth(), mImagep->getHeight(), mImagep, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength), TRUE); | 605 | mImagep->drawSolid(0, 0, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); |
599 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 606 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
600 | } | 607 | } |
601 | } | 608 | } |
602 | else | 609 | else |
603 | if ( mImagep.notNull() && mScaleImage) | 610 | if ( mImagep.notNull() && mScaleImage) |
604 | { | 611 | { |
605 | gl_draw_scaled_image_with_border(0, 0, mFixedWidth, mFixedHeight, mRect.getWidth(), mRect.getHeight(), | 612 | mImagep->draw(0, 0, mRect.getWidth(), mRect.getHeight(), mEnabled ? mImageColor : mDisabledImageColor ); |
606 | mImagep, mEnabled ? mImageColor : mDisabledImageColor ); | ||
607 | if (mCurGlowStrength > 0.01f) | 613 | if (mCurGlowStrength > 0.01f) |
608 | { | 614 | { |
609 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | 615 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); |
610 | gl_draw_scaled_image_with_border(0, 0, mFixedWidth, mFixedHeight, mRect.getWidth(), mRect.getHeight(), | 616 | mImagep->drawSolid(0, 0, mRect.getWidth(), mRect.getHeight(), LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); |
611 | mImagep, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength), TRUE); | ||
612 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 617 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
613 | } | 618 | } |
614 | } | 619 | } |
@@ -620,13 +625,17 @@ void LLButton::draw() | |||
620 | gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4::pink1, FALSE); | 625 | gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4::pink1, FALSE); |
621 | } | 626 | } |
622 | 627 | ||
628 | // let overlay image and text play well together | ||
629 | S32 text_left = mLeftHPad; | ||
630 | S32 text_right = mRect.getWidth() - mRightHPad; | ||
631 | S32 text_width = mRect.getWidth() - mLeftHPad - mRightHPad; | ||
632 | |||
623 | // draw overlay image | 633 | // draw overlay image |
624 | if (mImageOverlay.notNull()) | 634 | if (mImageOverlay.notNull()) |
625 | { | 635 | { |
626 | const S32 IMG_PAD = 5; | ||
627 | // get max width and height (discard level 0) | 636 | // get max width and height (discard level 0) |
628 | S32 overlay_width = mImageOverlay->getWidth(0); | 637 | S32 overlay_width = mImageOverlay->getWidth(); |
629 | S32 overlay_height = mImageOverlay->getHeight(0); | 638 | S32 overlay_height = mImageOverlay->getHeight(); |
630 | 639 | ||
631 | F32 scale_factor = llmin((F32)mRect.getWidth() / (F32)overlay_width, (F32)mRect.getHeight() / (F32)overlay_height, 1.f); | 640 | F32 scale_factor = llmin((F32)mRect.getWidth() / (F32)overlay_width, (F32)mRect.getHeight() / (F32)overlay_height, 1.f); |
632 | overlay_width = llround((F32)overlay_width * scale_factor); | 641 | overlay_width = llround((F32)overlay_width * scale_factor); |
@@ -635,34 +644,49 @@ void LLButton::draw() | |||
635 | S32 center_x = getLocalRect().getCenterX(); | 644 | S32 center_x = getLocalRect().getCenterX(); |
636 | S32 center_y = getLocalRect().getCenterY(); | 645 | S32 center_y = getLocalRect().getCenterY(); |
637 | 646 | ||
647 | //FUGLY HACK FOR "DEPRESSED" BUTTONS | ||
648 | if (pressed) | ||
649 | { | ||
650 | center_y--; | ||
651 | center_x++; | ||
652 | } | ||
653 | |||
654 | // fade out overlay images on disabled buttons | ||
655 | LLColor4 overlay_color = mImageOverlayColor; | ||
656 | if (!getEnabled()) | ||
657 | { | ||
658 | overlay_color.mV[VALPHA] = 0.5f; | ||
659 | } | ||
660 | |||
638 | switch(mImageOverlayAlignment) | 661 | switch(mImageOverlayAlignment) |
639 | { | 662 | { |
640 | case LLFontGL::LEFT: | 663 | case LLFontGL::LEFT: |
641 | gl_draw_scaled_image( | 664 | text_left += overlay_width + 1; |
642 | IMG_PAD, | 665 | text_width -= overlay_width + 1; |
666 | mImageOverlay->draw( | ||
667 | mLeftHPad, | ||
643 | center_y - (overlay_height / 2), | 668 | center_y - (overlay_height / 2), |
644 | overlay_width, | 669 | overlay_width, |
645 | overlay_height, | 670 | overlay_height, |
646 | mImageOverlay, | 671 | overlay_color); |
647 | mImageOverlayColor); | ||
648 | break; | 672 | break; |
649 | case LLFontGL::HCENTER: | 673 | case LLFontGL::HCENTER: |
650 | gl_draw_scaled_image( | 674 | mImageOverlay->draw( |
651 | center_x - (overlay_width / 2), | 675 | center_x - (overlay_width / 2), |
652 | center_y - (overlay_height / 2), | 676 | center_y - (overlay_height / 2), |
653 | overlay_width, | 677 | overlay_width, |
654 | overlay_height, | 678 | overlay_height, |
655 | mImageOverlay, | 679 | overlay_color); |
656 | mImageOverlayColor); | ||
657 | break; | 680 | break; |
658 | case LLFontGL::RIGHT: | 681 | case LLFontGL::RIGHT: |
659 | gl_draw_scaled_image( | 682 | text_right -= overlay_width + 1; |
660 | mRect.getWidth() - IMG_PAD - overlay_width, | 683 | text_width -= overlay_width + 1; |
684 | mImageOverlay->draw( | ||
685 | mRect.getWidth() - mRightHPad - overlay_width, | ||
661 | center_y - (overlay_height / 2), | 686 | center_y - (overlay_height / 2), |
662 | overlay_width, | 687 | overlay_width, |
663 | overlay_height, | 688 | overlay_height, |
664 | mImageOverlay, | 689 | overlay_color); |
665 | mImageOverlayColor); | ||
666 | break; | 690 | break; |
667 | default: | 691 | default: |
668 | // draw nothing | 692 | // draw nothing |
@@ -673,28 +697,26 @@ void LLButton::draw() | |||
673 | // Draw label | 697 | // Draw label |
674 | if( !label.empty() ) | 698 | if( !label.empty() ) |
675 | { | 699 | { |
676 | S32 drawable_width = mRect.getWidth() - mLeftHPad - mRightHPad; | ||
677 | |||
678 | LLWString::trim(label); | 700 | LLWString::trim(label); |
679 | 701 | ||
680 | S32 x; | 702 | S32 x; |
681 | switch( mHAlign ) | 703 | switch( mHAlign ) |
682 | { | 704 | { |
683 | case LLFontGL::RIGHT: | 705 | case LLFontGL::RIGHT: |
684 | x = mRect.getWidth() - mRightHPad; | 706 | x = text_right; |
685 | break; | 707 | break; |
686 | case LLFontGL::HCENTER: | 708 | case LLFontGL::HCENTER: |
687 | x = mRect.getWidth() / 2; | 709 | x = mRect.getWidth() / 2; |
688 | break; | 710 | break; |
689 | case LLFontGL::LEFT: | 711 | case LLFontGL::LEFT: |
690 | default: | 712 | default: |
691 | x = mLeftHPad; | 713 | x = text_left; |
692 | break; | 714 | break; |
693 | } | 715 | } |
694 | 716 | ||
695 | S32 y_offset = 2 + (mRect.getHeight() - 20)/2; | 717 | S32 y_offset = 2 + (mRect.getHeight() - 20)/2; |
696 | 718 | ||
697 | if (pressed || display_state) | 719 | if (pressed) |
698 | { | 720 | { |
699 | y_offset--; | 721 | y_offset--; |
700 | x++; | 722 | x++; |
@@ -704,7 +726,7 @@ void LLButton::draw() | |||
704 | label_color, | 726 | label_color, |
705 | mHAlign, LLFontGL::BOTTOM, | 727 | mHAlign, LLFontGL::BOTTOM, |
706 | mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NORMAL, | 728 | mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NORMAL, |
707 | U32_MAX, drawable_width, | 729 | U32_MAX, text_width, |
708 | NULL, FALSE, FALSE); | 730 | NULL, FALSE, FALSE); |
709 | } | 731 | } |
710 | 732 | ||
@@ -733,13 +755,11 @@ void LLButton::drawBorder(const LLColor4& color, S32 size) | |||
733 | 755 | ||
734 | if (mScaleImage) | 756 | if (mScaleImage) |
735 | { | 757 | { |
736 | gl_draw_scaled_image_with_border(left, bottom, mFixedWidth, mFixedHeight, right-left, top-bottom, | 758 | mImagep->drawSolid(left, bottom, right-left, top-bottom, color); |
737 | mImagep, color, TRUE ); | ||
738 | } | 759 | } |
739 | else | 760 | else |
740 | { | 761 | { |
741 | gl_draw_scaled_image_with_border(left, bottom, 0, 0, mImagep->getWidth() + size * 2, | 762 | mImagep->drawSolid(left, bottom, mImagep->getWidth() + size * 2, mImagep->getHeight() + size * 2, color); |
742 | mImagep->getHeight() + size * 2, mImagep, color, TRUE ); | ||
743 | } | 763 | } |
744 | } | 764 | } |
745 | 765 | ||
@@ -763,6 +783,22 @@ void LLButton::setToggleState(BOOL b) | |||
763 | } | 783 | } |
764 | } | 784 | } |
765 | 785 | ||
786 | void LLButton::setFlashing( BOOL b ) | ||
787 | { | ||
788 | if (b != mFlashing) | ||
789 | { | ||
790 | mFlashing = b; | ||
791 | mFlashingTimer.reset(); | ||
792 | } | ||
793 | } | ||
794 | |||
795 | |||
796 | BOOL LLButton::toggleState() | ||
797 | { | ||
798 | setToggleState( !mToggleState ); | ||
799 | return mToggleState; | ||
800 | } | ||
801 | |||
766 | void LLButton::setValue(const LLSD& value ) | 802 | void LLButton::setValue(const LLSD& value ) |
767 | { | 803 | { |
768 | mToggleState = value.asBoolean(); | 804 | mToggleState = value.asBoolean(); |
@@ -770,7 +806,7 @@ void LLButton::setValue(const LLSD& value ) | |||
770 | 806 | ||
771 | LLSD LLButton::getValue() const | 807 | LLSD LLButton::getValue() const |
772 | { | 808 | { |
773 | return mToggleState; | 809 | return mToggleState == TRUE; |
774 | } | 810 | } |
775 | 811 | ||
776 | void LLButton::setLabel( const LLStringExplicit& label ) | 812 | void LLButton::setLabel( const LLStringExplicit& label ) |
@@ -807,10 +843,9 @@ void LLButton::setDisabledSelectedLabel( const LLStringExplicit& label ) | |||
807 | mDisabledSelectedLabel = label; | 843 | mDisabledSelectedLabel = label; |
808 | } | 844 | } |
809 | 845 | ||
810 | void LLButton::setImageUnselectedID( const LLUUID &image_id ) | 846 | void LLButton::setImageUnselected(LLPointer<LLUIImage> image) |
811 | { | 847 | { |
812 | mImageUnselectedName = ""; | 848 | mImageUnselected = image; |
813 | mImageUnselected = LLUI::sImageProvider->getUIImageByID(image_id); | ||
814 | } | 849 | } |
815 | 850 | ||
816 | void LLButton::setImages( const LLString &image_name, const LLString &selected_name ) | 851 | void LLButton::setImages( const LLString &image_name, const LLString &selected_name ) |
@@ -820,10 +855,9 @@ void LLButton::setImages( const LLString &image_name, const LLString &selected_n | |||
820 | 855 | ||
821 | } | 856 | } |
822 | 857 | ||
823 | void LLButton::setImageSelectedID( const LLUUID &image_id ) | 858 | void LLButton::setImageSelected(LLPointer<LLUIImage> image) |
824 | { | 859 | { |
825 | mImageSelectedName = ""; | 860 | mImageSelected = image; |
826 | mImageSelected = LLUI::sImageProvider->getUIImageByID(image_id); | ||
827 | } | 861 | } |
828 | 862 | ||
829 | void LLButton::setImageColor(const LLColor4& c) | 863 | void LLButton::setImageColor(const LLColor4& c) |
@@ -831,19 +865,22 @@ void LLButton::setImageColor(const LLColor4& c) | |||
831 | mImageColor = c; | 865 | mImageColor = c; |
832 | } | 866 | } |
833 | 867 | ||
868 | void LLButton::setColor(const LLColor4& color) | ||
869 | { | ||
870 | setImageColor(color); | ||
871 | } | ||
872 | |||
834 | 873 | ||
835 | void LLButton::setImageDisabledID( const LLUUID &image_id ) | 874 | void LLButton::setImageDisabled(LLPointer<LLUIImage> image) |
836 | { | 875 | { |
837 | mImageDisabledName = ""; | 876 | mImageDisabled = image; |
838 | mImageDisabled = LLUI::sImageProvider->getUIImageByID(image_id); | ||
839 | mDisabledImageColor = mImageColor; | 877 | mDisabledImageColor = mImageColor; |
840 | mDisabledImageColor.mV[VALPHA] *= 0.5f; | 878 | mDisabledImageColor.mV[VALPHA] *= 0.5f; |
841 | } | 879 | } |
842 | 880 | ||
843 | void LLButton::setImageDisabledSelectedID( const LLUUID &image_id ) | 881 | void LLButton::setImageDisabledSelected(LLPointer<LLUIImage> image) |
844 | { | 882 | { |
845 | mImageDisabledSelectedName = ""; | 883 | mImageDisabledSelected = image; |
846 | mImageDisabledSelected = LLUI::sImageProvider->getUIImageByID(image_id); | ||
847 | mDisabledImageColor = mImageColor; | 884 | mDisabledImageColor = mImageColor; |
848 | mDisabledImageColor.mV[VALPHA] *= 0.5f; | 885 | mDisabledImageColor.mV[VALPHA] *= 0.5f; |
849 | } | 886 | } |
@@ -855,11 +892,9 @@ void LLButton::setDisabledImages( const LLString &image_name, const LLString &se | |||
855 | mDisabledImageColor = c; | 892 | mDisabledImageColor = c; |
856 | } | 893 | } |
857 | 894 | ||
858 | 895 | void LLButton::setImageHoverSelected(LLPointer<LLUIImage> image) | |
859 | void LLButton::setImageHoverSelectedID( const LLUUID& image_id ) | ||
860 | { | 896 | { |
861 | mImageHoverSelectedName = ""; | 897 | mImageHoverSelected = image; |
862 | mImageHoverSelected = LLUI::sImageProvider->getUIImageByID(image_id); | ||
863 | } | 898 | } |
864 | 899 | ||
865 | void LLButton::setDisabledImages( const LLString &image_name, const LLString &selected_name) | 900 | void LLButton::setDisabledImages( const LLString &image_name, const LLString &selected_name) |
@@ -869,10 +904,9 @@ void LLButton::setDisabledImages( const LLString &image_name, const LLString &se | |||
869 | setDisabledImages( image_name, selected_name, clr ); | 904 | setDisabledImages( image_name, selected_name, clr ); |
870 | } | 905 | } |
871 | 906 | ||
872 | void LLButton::setImageHoverUnselectedID( const LLUUID& image_id ) | 907 | void LLButton::setImageHoverUnselected(LLPointer<LLUIImage> image) |
873 | { | 908 | { |
874 | mImageHoverUnselectedName = ""; | 909 | mImageHoverUnselected = image; |
875 | mImageHoverUnselected = LLUI::sImageProvider->getUIImageByID(image_id); | ||
876 | } | 910 | } |
877 | 911 | ||
878 | void LLButton::setHoverImages( const LLString& image_name, const LLString& selected_name ) | 912 | void LLButton::setHoverImages( const LLString& image_name, const LLString& selected_name ) |
@@ -889,8 +923,7 @@ void LLButton::setImageOverlay(const LLString &image_name, LLFontGL::HAlign alig | |||
889 | } | 923 | } |
890 | else | 924 | else |
891 | { | 925 | { |
892 | LLUUID overlay_image_id = LLUI::findAssetUUIDByName(image_name); | 926 | mImageOverlay = LLUI::getUIImageByName(image_name); |
893 | mImageOverlay = LLUI::sImageProvider->getUIImageByID(overlay_image_id); | ||
894 | mImageOverlayAlignment = alignment; | 927 | mImageOverlayAlignment = alignment; |
895 | mImageOverlayColor = color; | 928 | mImageOverlayColor = color; |
896 | } | 929 | } |
@@ -904,34 +937,6 @@ void LLButton::onMouseCaptureLost() | |||
904 | } | 937 | } |
905 | 938 | ||
906 | //------------------------------------------------------------------------- | 939 | //------------------------------------------------------------------------- |
907 | // LLSquareButton | ||
908 | //------------------------------------------------------------------------- | ||
909 | LLSquareButton::LLSquareButton(const LLString& name, const LLRect& rect, | ||
910 | const LLString& label, | ||
911 | const LLFontGL *font, | ||
912 | const LLString& control_name, | ||
913 | void (*click_callback)(void*), | ||
914 | void *callback_data, | ||
915 | const LLString& selected_label ) | ||
916 | : LLButton(name, rect, "","", | ||
917 | control_name, | ||
918 | click_callback, callback_data, | ||
919 | font, | ||
920 | label, | ||
921 | (selected_label.empty() ? label : selected_label) ) | ||
922 | { | ||
923 | setImageUnselected("square_btn_32x128.tga"); | ||
924 | // mImageUnselected = LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("square_btn_32x128.tga"))); | ||
925 | setImageSelected("square_btn_selected_32x128.tga"); | ||
926 | // mImageSelectedImage = LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("square_btn_selected_32x128.tga"))); | ||
927 | setImageDisabled("square_btn_32x128.tga"); | ||
928 | //mDisabledImage = LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("square_btn_32x128.tga"))); | ||
929 | setImageDisabledSelected("square_btn_selected_32x128.tga"); | ||
930 | //mDisabledSelectedImage = LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("square_btn_selected_32x128.tga"))); | ||
931 | mImageColor = LLUI::sColorsGroup->getColor("ButtonColor"); | ||
932 | } | ||
933 | |||
934 | //------------------------------------------------------------------------- | ||
935 | // Utilities | 940 | // Utilities |
936 | //------------------------------------------------------------------------- | 941 | //------------------------------------------------------------------------- |
937 | S32 round_up(S32 grid, S32 value) | 942 | S32 round_up(S32 grid, S32 value) |
@@ -951,37 +956,37 @@ S32 round_up(S32 grid, S32 value) | |||
951 | 956 | ||
952 | void LLButton::setImageUnselected(const LLString &image_name) | 957 | void LLButton::setImageUnselected(const LLString &image_name) |
953 | { | 958 | { |
954 | setImageUnselectedID(LLUI::findAssetUUIDByName(image_name)); | 959 | setImageUnselected(LLUI::getUIImageByName(image_name)); |
955 | mImageUnselectedName = image_name; | 960 | mImageUnselectedName = image_name; |
956 | } | 961 | } |
957 | 962 | ||
958 | void LLButton::setImageSelected(const LLString &image_name) | 963 | void LLButton::setImageSelected(const LLString &image_name) |
959 | { | 964 | { |
960 | setImageSelectedID(LLUI::findAssetUUIDByName(image_name)); | 965 | setImageSelected(LLUI::getUIImageByName(image_name)); |
961 | mImageSelectedName = image_name; | 966 | mImageSelectedName = image_name; |
962 | } | 967 | } |
963 | 968 | ||
964 | void LLButton::setImageHoverSelected(const LLString &image_name) | 969 | void LLButton::setImageHoverSelected(const LLString &image_name) |
965 | { | 970 | { |
966 | setImageHoverSelectedID(LLUI::findAssetUUIDByName(image_name)); | 971 | setImageHoverSelected(LLUI::getUIImageByName(image_name)); |
967 | mImageHoverSelectedName = image_name; | 972 | mImageHoverSelectedName = image_name; |
968 | } | 973 | } |
969 | 974 | ||
970 | void LLButton::setImageHoverUnselected(const LLString &image_name) | 975 | void LLButton::setImageHoverUnselected(const LLString &image_name) |
971 | { | 976 | { |
972 | setImageHoverUnselectedID(LLUI::findAssetUUIDByName(image_name)); | 977 | setImageHoverUnselected(LLUI::getUIImageByName(image_name)); |
973 | mImageHoverUnselectedName = image_name; | 978 | mImageHoverUnselectedName = image_name; |
974 | } | 979 | } |
975 | 980 | ||
976 | void LLButton::setImageDisabled(const LLString &image_name) | 981 | void LLButton::setImageDisabled(const LLString &image_name) |
977 | { | 982 | { |
978 | setImageDisabledID(LLUI::findAssetUUIDByName(image_name)); | 983 | setImageDisabled(LLUI::getUIImageByName(image_name)); |
979 | mImageDisabledName = image_name; | 984 | mImageDisabledName = image_name; |
980 | } | 985 | } |
981 | 986 | ||
982 | void LLButton::setImageDisabledSelected(const LLString &image_name) | 987 | void LLButton::setImageDisabledSelected(const LLString &image_name) |
983 | { | 988 | { |
984 | setImageDisabledSelectedID(LLUI::findAssetUUIDByName(image_name)); | 989 | setImageDisabledSelected(LLUI::getUIImageByName(image_name)); |
985 | mImageDisabledSelectedName = image_name; | 990 | mImageDisabledSelectedName = image_name; |
986 | } | 991 | } |
987 | 992 | ||
@@ -1009,8 +1014,6 @@ LLXMLNodePtr LLButton::getXML(bool save_children) const | |||
1009 | node->createChild("label_selected", TRUE)->setStringValue(getLabelSelected()); | 1014 | node->createChild("label_selected", TRUE)->setStringValue(getLabelSelected()); |
1010 | node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mGLFont)); | 1015 | node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mGLFont)); |
1011 | node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(mHAlign)); | 1016 | node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(mHAlign)); |
1012 | node->createChild("border_width", TRUE)->setIntValue(mFixedWidth); | ||
1013 | node->createChild("border_height", TRUE)->setIntValue(mFixedHeight); | ||
1014 | 1017 | ||
1015 | addImageAttributeToXML(node,mImageUnselectedName,mImageUnselectedID,"image_unselected"); | 1018 | addImageAttributeToXML(node,mImageUnselectedName,mImageUnselectedID,"image_unselected"); |
1016 | addImageAttributeToXML(node,mImageSelectedName,mImageSelectedID,"image_selected"); | 1019 | addImageAttributeToXML(node,mImageSelectedName,mImageSelectedID,"image_selected"); |
@@ -1092,8 +1095,12 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa | |||
1092 | label, | 1095 | label, |
1093 | label_selected); | 1096 | label_selected); |
1094 | 1097 | ||
1095 | node->getAttributeS32("border_width", button->mFixedWidth); | 1098 | node->getAttributeS32("pad_right", button->mRightHPad); |
1096 | node->getAttributeS32("border_height", button->mFixedHeight); | 1099 | node->getAttributeS32("pad_left", button->mLeftHPad); |
1100 | |||
1101 | BOOL is_toggle = button->getIsToggle(); | ||
1102 | node->getAttributeBOOL("toggle", is_toggle); | ||
1103 | button->setIsToggle(is_toggle); | ||
1097 | 1104 | ||
1098 | if(image_hover_selected != LLString::null) button->setImageHoverSelected(image_hover_selected); | 1105 | if(image_hover_selected != LLString::null) button->setImageHoverSelected(image_hover_selected); |
1099 | 1106 | ||
diff --git a/linden/indra/llui/llbutton.h b/linden/indra/llui/llbutton.h index 6a2b4a1..7d50f40 100644 --- a/linden/indra/llui/llbutton.h +++ b/linden/indra/llui/llbutton.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -114,11 +114,13 @@ public: | |||
114 | 114 | ||
115 | F32 getHeldDownTime() const { return mMouseDownTimer.getElapsedTimeF32(); } | 115 | F32 getHeldDownTime() const { return mMouseDownTimer.getElapsedTimeF32(); } |
116 | 116 | ||
117 | BOOL toggleState() { setToggleState( !mToggleState ); return mToggleState; } | 117 | BOOL getIsToggle() const { return mIsToggle; } |
118 | void setIsToggle(BOOL is_toggle) { mIsToggle = is_toggle; } | ||
119 | BOOL toggleState(); | ||
118 | BOOL getToggleState() const { return mToggleState; } | 120 | BOOL getToggleState() const { return mToggleState; } |
119 | void setToggleState(BOOL b); | 121 | void setToggleState(BOOL b); |
120 | 122 | ||
121 | void setFlashing( BOOL b ) { mFlashing = b; } | 123 | void setFlashing( BOOL b ); |
122 | BOOL getFlashing() const { return mFlashing; } | 124 | BOOL getFlashing() const { return mFlashing; } |
123 | 125 | ||
124 | void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } | 126 | void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } |
@@ -128,14 +130,11 @@ public: | |||
128 | const LLString getLabelUnselected() const { return wstring_to_utf8str(mUnselectedLabel); } | 130 | const LLString getLabelUnselected() const { return wstring_to_utf8str(mUnselectedLabel); } |
129 | const LLString getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); } | 131 | const LLString getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); } |
130 | 132 | ||
131 | |||
132 | // HACK to allow images to be freed when the caller knows he's done with it. | ||
133 | LLImageGL* getImageUnselected() const { return mImageUnselected; } | ||
134 | |||
135 | void setImageColor(const LLString& color_control); | 133 | void setImageColor(const LLString& color_control); |
136 | void setImages(const LLString &image_name, const LLString &selected_name); | ||
137 | void setImageColor(const LLColor4& c); | 134 | void setImageColor(const LLColor4& c); |
138 | 135 | virtual void setColor(const LLColor4& c); | |
136 | |||
137 | void setImages(const LLString &image_name, const LLString &selected_name); | ||
139 | void setDisabledImages(const LLString &image_name, const LLString &selected_name); | 138 | void setDisabledImages(const LLString &image_name, const LLString &selected_name); |
140 | void setDisabledImages(const LLString &image_name, const LLString &selected_name, const LLColor4& c); | 139 | void setDisabledImages(const LLString &image_name, const LLString &selected_name, const LLColor4& c); |
141 | 140 | ||
@@ -146,7 +145,7 @@ public: | |||
146 | void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; } | 145 | void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; } |
147 | 146 | ||
148 | void setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white); | 147 | void setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white); |
149 | LLPointer<LLImageGL> getImageOverlay() { return mImageOverlay; } | 148 | LLPointer<LLUIImage> getImageOverlay() { return mImageOverlay; } |
150 | 149 | ||
151 | 150 | ||
152 | virtual void setValue(const LLSD& value ); | 151 | virtual void setValue(const LLSD& value ); |
@@ -170,16 +169,8 @@ public: | |||
170 | 169 | ||
171 | static void onHeldDown(void *userdata); // to be called by gIdleCallbacks | 170 | static void onHeldDown(void *userdata); // to be called by gIdleCallbacks |
172 | 171 | ||
173 | void setFixedBorder(S32 width, S32 height) { mFixedWidth = width; mFixedHeight = height; } | ||
174 | void setHoverGlowStrength(F32 strength) { mHoverGlowStrength = strength; } | 172 | void setHoverGlowStrength(F32 strength) { mHoverGlowStrength = strength; } |
175 | 173 | ||
176 | private: | ||
177 | void setImageUnselectedID(const LLUUID &image_id); | ||
178 | void setImageSelectedID(const LLUUID &image_id); | ||
179 | void setImageHoverSelectedID(const LLUUID &image_id); | ||
180 | void setImageHoverUnselectedID(const LLUUID &image_id); | ||
181 | void setImageDisabledID(const LLUUID &image_id); | ||
182 | void setImageDisabledSelectedID(const LLUUID &image_id); | ||
183 | public: | 174 | public: |
184 | void setImageUnselected(const LLString &image_name); | 175 | void setImageUnselected(const LLString &image_name); |
185 | void setImageSelected(const LLString &image_name); | 176 | void setImageSelected(const LLString &image_name); |
@@ -187,6 +178,14 @@ public: | |||
187 | void setImageHoverUnselected(const LLString &image_name); | 178 | void setImageHoverUnselected(const LLString &image_name); |
188 | void setImageDisabled(const LLString &image_name); | 179 | void setImageDisabled(const LLString &image_name); |
189 | void setImageDisabledSelected(const LLString &image_name); | 180 | void setImageDisabledSelected(const LLString &image_name); |
181 | |||
182 | void setImageUnselected(LLPointer<LLUIImage> image); | ||
183 | void setImageSelected(LLPointer<LLUIImage> image); | ||
184 | void setImageHoverSelected(LLPointer<LLUIImage> image); | ||
185 | void setImageHoverUnselected(LLPointer<LLUIImage> image); | ||
186 | void setImageDisabled(LLPointer<LLUIImage> image); | ||
187 | void setImageDisabledSelected(LLPointer<LLUIImage> image); | ||
188 | |||
190 | void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; } | 189 | void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; } |
191 | BOOL getCommitOnReturn() { return mCommitOnReturn; } | 190 | BOOL getCommitOnReturn() { return mCommitOnReturn; } |
192 | 191 | ||
@@ -209,27 +208,27 @@ protected: | |||
209 | F32 mHeldDownDelay; // seconds, after which held-down callbacks get called | 208 | F32 mHeldDownDelay; // seconds, after which held-down callbacks get called |
210 | S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called | 209 | S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called |
211 | 210 | ||
212 | LLPointer<LLImageGL> mImageOverlay; | 211 | LLPointer<LLUIImage> mImageOverlay; |
213 | LLFontGL::HAlign mImageOverlayAlignment; | 212 | LLFontGL::HAlign mImageOverlayAlignment; |
214 | LLColor4 mImageOverlayColor; | 213 | LLColor4 mImageOverlayColor; |
215 | 214 | ||
216 | LLPointer<LLImageGL> mImageUnselected; | 215 | LLPointer<LLUIImage> mImageUnselected; |
217 | LLUIString mUnselectedLabel; | 216 | LLUIString mUnselectedLabel; |
218 | LLColor4 mUnselectedLabelColor; | 217 | LLColor4 mUnselectedLabelColor; |
219 | 218 | ||
220 | LLPointer<LLImageGL> mImageSelected; | 219 | LLPointer<LLUIImage> mImageSelected; |
221 | LLUIString mSelectedLabel; | 220 | LLUIString mSelectedLabel; |
222 | LLColor4 mSelectedLabelColor; | 221 | LLColor4 mSelectedLabelColor; |
223 | 222 | ||
224 | LLPointer<LLImageGL> mImageHoverSelected; | 223 | LLPointer<LLUIImage> mImageHoverSelected; |
225 | 224 | ||
226 | LLPointer<LLImageGL> mImageHoverUnselected; | 225 | LLPointer<LLUIImage> mImageHoverUnselected; |
227 | 226 | ||
228 | LLPointer<LLImageGL> mImageDisabled; | 227 | LLPointer<LLUIImage> mImageDisabled; |
229 | LLUIString mDisabledLabel; | 228 | LLUIString mDisabledLabel; |
230 | LLColor4 mDisabledLabelColor; | 229 | LLColor4 mDisabledLabelColor; |
231 | 230 | ||
232 | LLPointer<LLImageGL> mImageDisabledSelected; | 231 | LLPointer<LLUIImage> mImageDisabledSelected; |
233 | LLUIString mDisabledSelectedLabel; | 232 | LLUIString mDisabledSelectedLabel; |
234 | LLColor4 mDisabledSelectedLabelColor; | 233 | LLColor4 mDisabledSelectedLabelColor; |
235 | 234 | ||
@@ -254,6 +253,7 @@ protected: | |||
254 | LLColor4 mImageColor; | 253 | LLColor4 mImageColor; |
255 | LLColor4 mDisabledImageColor; | 254 | LLColor4 mDisabledImageColor; |
256 | 255 | ||
256 | BOOL mIsToggle; | ||
257 | BOOL mToggleState; | 257 | BOOL mToggleState; |
258 | BOOL mScaleImage; | 258 | BOOL mScaleImage; |
259 | 259 | ||
@@ -267,9 +267,6 @@ protected: | |||
267 | S32 mLeftHPad; | 267 | S32 mLeftHPad; |
268 | S32 mRightHPad; | 268 | S32 mRightHPad; |
269 | 269 | ||
270 | S32 mFixedWidth; | ||
271 | S32 mFixedHeight; | ||
272 | |||
273 | F32 mHoverGlowStrength; | 270 | F32 mHoverGlowStrength; |
274 | F32 mCurGlowStrength; | 271 | F32 mCurGlowStrength; |
275 | 272 | ||
@@ -278,22 +275,9 @@ protected: | |||
278 | 275 | ||
279 | LLString mHelpURL; | 276 | LLString mHelpURL; |
280 | 277 | ||
281 | LLPointer<LLImageGL> mImagep; | 278 | LLPointer<LLUIImage> mImagep; |
282 | |||
283 | static LLFrameTimer sFlashingTimer; | ||
284 | }; | ||
285 | 279 | ||
286 | class LLSquareButton | 280 | LLFrameTimer mFlashingTimer; |
287 | : public LLButton | ||
288 | { | ||
289 | public: | ||
290 | LLSquareButton(const LLString& name, const LLRect& rect, | ||
291 | const LLString& label, | ||
292 | const LLFontGL *font = NULL, | ||
293 | const LLString& control_name = LLString(), | ||
294 | void (*click_callback)(void*) = NULL, | ||
295 | void *callback_data = NULL, | ||
296 | const LLString& selected_label = LLString::null ); | ||
297 | }; | 281 | }; |
298 | 282 | ||
299 | // Helpful functions | 283 | // Helpful functions |
diff --git a/linden/indra/llui/llcallbackmap.h b/linden/indra/llui/llcallbackmap.h index 6b40f09..9241751 100644 --- a/linden/indra/llui/llcallbackmap.h +++ b/linden/indra/llui/llcallbackmap.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llcheckboxctrl.cpp b/linden/indra/llui/llcheckboxctrl.cpp index b184eda..ff46a80 100644 --- a/linden/indra/llui/llcheckboxctrl.cpp +++ b/linden/indra/llui/llcheckboxctrl.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -75,7 +75,7 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLString& name, const LLRect& rect, | |||
75 | } | 75 | } |
76 | 76 | ||
77 | // must be big enough to hold all children | 77 | // must be big enough to hold all children |
78 | setSpanChildren(TRUE); | 78 | setUseBoundingRect(TRUE); |
79 | 79 | ||
80 | mKeyboardFocusOnClick = TRUE; | 80 | mKeyboardFocusOnClick = TRUE; |
81 | 81 | ||
@@ -130,6 +130,7 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLString& name, const LLRect& rect, | |||
130 | mButton->setDisabledImages( inactive_false_id, inactive_true_id ); | 130 | mButton->setDisabledImages( inactive_false_id, inactive_true_id ); |
131 | mButton->setHoverGlowStrength(0.35f); | 131 | mButton->setHoverGlowStrength(0.35f); |
132 | } | 132 | } |
133 | mButton->setIsToggle(TRUE); | ||
133 | mButton->setToggleState( initial_value ); | 134 | mButton->setToggleState( initial_value ); |
134 | mButton->setFollowsLeft(); | 135 | mButton->setFollowsLeft(); |
135 | mButton->setFollowsBottom(); | 136 | mButton->setFollowsBottom(); |
@@ -150,16 +151,11 @@ void LLCheckBoxCtrl::onButtonPress( void *userdata ) | |||
150 | 151 | ||
151 | if (self->mRadioStyle) | 152 | if (self->mRadioStyle) |
152 | { | 153 | { |
153 | if (!self->getValue()) | 154 | self->setValue(TRUE); |
154 | { | ||
155 | self->setValue(TRUE); | ||
156 | } | ||
157 | } | ||
158 | else | ||
159 | { | ||
160 | self->toggle(); | ||
161 | } | 155 | } |
156 | |||
162 | self->setControlValue(self->getValue()); | 157 | self->setControlValue(self->getValue()); |
158 | // HACK: because buttons don't normally commit | ||
163 | self->onCommit(); | 159 | self->onCommit(); |
164 | 160 | ||
165 | if (self->mKeyboardFocusOnClick) | 161 | if (self->mKeyboardFocusOnClick) |
@@ -232,14 +228,13 @@ void LLCheckBoxCtrl::draw() | |||
232 | //virtual | 228 | //virtual |
233 | void LLCheckBoxCtrl::setValue(const LLSD& value ) | 229 | void LLCheckBoxCtrl::setValue(const LLSD& value ) |
234 | { | 230 | { |
235 | mSetValue = value.asBoolean(); | 231 | mButton->setValue( value ); |
236 | mButton->setToggleState( mSetValue ); | ||
237 | } | 232 | } |
238 | 233 | ||
239 | //virtual | 234 | //virtual |
240 | LLSD LLCheckBoxCtrl::getValue() const | 235 | LLSD LLCheckBoxCtrl::getValue() const |
241 | { | 236 | { |
242 | return mButton->getToggleState(); | 237 | return mButton->getValue(); |
243 | } | 238 | } |
244 | 239 | ||
245 | void LLCheckBoxCtrl::setLabel( const LLStringExplicit& label ) | 240 | void LLCheckBoxCtrl::setLabel( const LLStringExplicit& label ) |
diff --git a/linden/indra/llui/llcheckboxctrl.h b/linden/indra/llui/llcheckboxctrl.h index 3fd0be7..1f92708 100644 --- a/linden/indra/llui/llcheckboxctrl.h +++ b/linden/indra/llui/llcheckboxctrl.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llclipboard.cpp b/linden/indra/llui/llclipboard.cpp index 774bad6..eaf7798 100644 --- a/linden/indra/llui/llclipboard.cpp +++ b/linden/indra/llui/llclipboard.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llclipboard.h b/linden/indra/llui/llclipboard.h index d4efc3a..82ea334 100644 --- a/linden/indra/llui/llclipboard.h +++ b/linden/indra/llui/llclipboard.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llcombobox.cpp b/linden/indra/llui/llcombobox.cpp index cfdcf58..22b5033 100644 --- a/linden/indra/llui/llcombobox.cpp +++ b/linden/indra/llui/llcombobox.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -55,17 +55,16 @@ | |||
55 | // Globals | 55 | // Globals |
56 | S32 LLCOMBOBOX_HEIGHT = 0; | 56 | S32 LLCOMBOBOX_HEIGHT = 0; |
57 | S32 LLCOMBOBOX_WIDTH = 0; | 57 | S32 LLCOMBOBOX_WIDTH = 0; |
58 | 58 | S32 MAX_COMBO_WIDTH = 500; | |
59 | |||
59 | LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString& label, | 60 | LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString& label, |
60 | void (*commit_callback)(LLUICtrl*,void*), | 61 | void (*commit_callback)(LLUICtrl*,void*), |
61 | void *callback_userdata | 62 | void *callback_userdata |
62 | ) | 63 | ) |
63 | : LLUICtrl(name, rect, TRUE, commit_callback, callback_userdata, | 64 | : LLUICtrl(name, rect, TRUE, commit_callback, callback_userdata, |
64 | FOLLOWS_LEFT | FOLLOWS_TOP), | 65 | FOLLOWS_LEFT | FOLLOWS_TOP), |
65 | mDrawArrow(TRUE), | ||
66 | mTextEntry(NULL), | 66 | mTextEntry(NULL), |
67 | mArrowImage(NULL), | 67 | mArrowImage(NULL), |
68 | mArrowImageWidth(8), | ||
69 | mAllowTextEntry(FALSE), | 68 | mAllowTextEntry(FALSE), |
70 | mMaxChars(20), | 69 | mMaxChars(20), |
71 | mTextEntryTentative(TRUE), | 70 | mTextEntryTentative(TRUE), |
@@ -73,55 +72,43 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString | |||
73 | mPrearrangeCallback( NULL ), | 72 | mPrearrangeCallback( NULL ), |
74 | mTextEntryCallback( NULL ) | 73 | mTextEntryCallback( NULL ) |
75 | { | 74 | { |
76 | // For now, all comboboxes don't take keyboard focus when clicked. | ||
77 | // This might change if it is part of a modal dialog. | ||
78 | // mKeyboardFocusOnClick = FALSE; | ||
79 | |||
80 | // Revert to standard behavior. When this control's parent is hidden, it needs to | ||
81 | // hide this ctrl--which won't just happen automatically since when LLComboBox is | ||
82 | // showing its list, it's also set to TopCtrl. When keyboard focus is cleared all | ||
83 | // controls (including this one) know that they are no longer editing. | ||
84 | mKeyboardFocusOnClick = TRUE; | ||
85 | |||
86 | LLRect r; | ||
87 | r.setOriginAndSize(0, 0, rect.getWidth(), rect.getHeight()); | ||
88 | |||
89 | // Always use text box | 75 | // Always use text box |
90 | // Text label button | 76 | // Text label button |
91 | mButton = new LLSquareButton("comboxbox button", | 77 | mButton = new LLButton("comboxbox button", |
92 | r, label, NULL, LLString::null, | 78 | LLRect(), label, NULL, LLString::null, |
93 | NULL, this); | 79 | NULL, this); |
80 | mButton->setImageUnselected("square_btn_32x128.tga"); | ||
81 | mButton->setImageSelected("square_btn_selected_32x128.tga"); | ||
82 | mButton->setImageDisabled("square_btn_32x128.tga"); | ||
83 | mButton->setImageDisabledSelected("square_btn_selected_32x128.tga"); | ||
84 | mButton->setScaleImage(TRUE); | ||
85 | |||
94 | mButton->setMouseDownCallback(onButtonDown); | 86 | mButton->setMouseDownCallback(onButtonDown); |
95 | mButton->setFont(LLFontGL::sSansSerifSmall); | 87 | mButton->setFont(LLFontGL::sSansSerifSmall); |
96 | mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT); | 88 | mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT); |
97 | mButton->setHAlign( LLFontGL::LEFT ); | 89 | mButton->setHAlign( LLFontGL::LEFT ); |
98 | 90 | mButton->setRightHPad(2); | |
99 | const S32 ARROW_WIDTH = 16; | ||
100 | mButton->setRightHPad( ARROW_WIDTH ); | ||
101 | addChild(mButton); | 91 | addChild(mButton); |
102 | 92 | ||
103 | // Default size, will be set by arrange() call in button callback. | ||
104 | S32 list_width = mRect.getWidth() + SCROLLBAR_SIZE; | ||
105 | r.setOriginAndSize(0, 16, list_width, 220); | ||
106 | |||
107 | // disallow multiple selection | 93 | // disallow multiple selection |
108 | mList = new LLScrollListCtrl( | 94 | mList = new LLScrollListCtrl( |
109 | "ComboBox", r, | 95 | "ComboBox", LLRect(), |
110 | &LLComboBox::onItemSelected, this, FALSE); | 96 | &LLComboBox::onItemSelected, this, FALSE); |
111 | mList->setVisible(FALSE); | 97 | mList->setVisible(FALSE); |
112 | mList->setBgWriteableColor( LLColor4(1,1,1,1) ); | 98 | mList->setBgWriteableColor( LLColor4(1,1,1,1) ); |
113 | mList->setCommitOnKeyboardMovement(FALSE); | 99 | mList->setCommitOnKeyboardMovement(FALSE); |
114 | mList->setFocusChangedCallback(onListFocusChanged); | ||
115 | addChild(mList); | 100 | addChild(mList); |
116 | 101 | ||
117 | LLRect border_rect(0, mRect.getHeight(), mRect.getWidth(), 0); | 102 | LLRect border_rect(0, mRect.getHeight(), mRect.getWidth(), 0); |
118 | mBorder = new LLViewBorder( "combo border", border_rect ); | 103 | mBorder = new LLViewBorder( "combo border", border_rect ); |
119 | addChild( mBorder ); | 104 | addChild( mBorder ); |
120 | mBorder->setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP|FOLLOWS_BOTTOM); | 105 | mBorder->setFollowsAll(); |
121 | 106 | ||
122 | LLUUID arrow_image_id( LLUI::sAssetsGroup->getString("combobox_arrow.tga") ); | 107 | LLUUID arrow_image_id( LLUI::sAssetsGroup->getString("combobox_arrow.tga") ); |
123 | mArrowImage = LLUI::sImageProvider->getUIImageByID(arrow_image_id); | 108 | mArrowImage = LLUI::sImageProvider->getImageByID(arrow_image_id); |
124 | mArrowImageWidth = llmax(8,mArrowImage->getWidth(0)); // In case image hasn't loaded yet | 109 | mButton->setImageOverlay("combobox_arrow.tga", LLFontGL::RIGHT); |
110 | |||
111 | updateLayout(); | ||
125 | } | 112 | } |
126 | 113 | ||
127 | 114 | ||
@@ -155,7 +142,7 @@ LLXMLNodePtr LLComboBox::getXML(bool save_children) const | |||
155 | LLSD value = item->getValue(); | 142 | LLSD value = item->getValue(); |
156 | item_node->createChild("value", TRUE)->setStringValue(value.asString()); | 143 | item_node->createChild("value", TRUE)->setStringValue(value.asString()); |
157 | item_node->createChild("enabled", TRUE)->setBoolValue(item->getEnabled()); | 144 | item_node->createChild("enabled", TRUE)->setBoolValue(item->getEnabled()); |
158 | item_node->setStringValue(cell->getText()); | 145 | item_node->setStringValue(cell->getValue().asString()); |
159 | } | 146 | } |
160 | } | 147 | } |
161 | 148 | ||
@@ -272,34 +259,46 @@ void LLComboBox::resetDirty() | |||
272 | 259 | ||
273 | 260 | ||
274 | // add item "name" to menu | 261 | // add item "name" to menu |
275 | void LLComboBox::add(const LLString& name, EAddPosition pos, BOOL enabled) | 262 | LLScrollListItem* LLComboBox::add(const LLString& name, EAddPosition pos, BOOL enabled) |
276 | { | 263 | { |
277 | mList->addSimpleItem(name, pos, enabled); | 264 | LLScrollListItem* item = mList->addSimpleElement(name, pos); |
265 | item->setEnabled(enabled); | ||
278 | mList->selectFirstItem(); | 266 | mList->selectFirstItem(); |
267 | return item; | ||
279 | } | 268 | } |
280 | 269 | ||
281 | // add item "name" with a unique id to menu | 270 | // add item "name" with a unique id to menu |
282 | void LLComboBox::add(const LLString& name, const LLUUID& id, EAddPosition pos, BOOL enabled ) | 271 | LLScrollListItem* LLComboBox::add(const LLString& name, const LLUUID& id, EAddPosition pos, BOOL enabled ) |
283 | { | 272 | { |
284 | mList->addSimpleItem(name, LLSD(id), pos, enabled); | 273 | LLScrollListItem* item = mList->addSimpleElement(name, pos, id); |
274 | item->setEnabled(enabled); | ||
285 | mList->selectFirstItem(); | 275 | mList->selectFirstItem(); |
276 | return item; | ||
286 | } | 277 | } |
287 | 278 | ||
288 | // add item "name" with attached userdata | 279 | // add item "name" with attached userdata |
289 | void LLComboBox::add(const LLString& name, void* userdata, EAddPosition pos, BOOL enabled ) | 280 | LLScrollListItem* LLComboBox::add(const LLString& name, void* userdata, EAddPosition pos, BOOL enabled ) |
290 | { | 281 | { |
291 | LLScrollListItem* item = mList->addSimpleItem(name, pos, enabled); | 282 | LLScrollListItem* item = mList->addSimpleElement(name, pos); |
283 | item->setEnabled(enabled); | ||
292 | item->setUserdata( userdata ); | 284 | item->setUserdata( userdata ); |
293 | mList->selectFirstItem(); | 285 | mList->selectFirstItem(); |
286 | return item; | ||
294 | } | 287 | } |
295 | 288 | ||
296 | // add item "name" with attached generic data | 289 | // add item "name" with attached generic data |
297 | void LLComboBox::add(const LLString& name, LLSD value, EAddPosition pos, BOOL enabled ) | 290 | LLScrollListItem* LLComboBox::add(const LLString& name, LLSD value, EAddPosition pos, BOOL enabled ) |
298 | { | 291 | { |
299 | mList->addSimpleItem(name, value, pos, enabled); | 292 | LLScrollListItem* item = mList->addSimpleElement(name, pos, value); |
293 | item->setEnabled(enabled); | ||
300 | mList->selectFirstItem(); | 294 | mList->selectFirstItem(); |
295 | return item; | ||
301 | } | 296 | } |
302 | 297 | ||
298 | LLScrollListItem* LLComboBox::addSeparator(EAddPosition pos) | ||
299 | { | ||
300 | return mList->addSeparator(pos); | ||
301 | } | ||
303 | 302 | ||
304 | void LLComboBox::sortByName() | 303 | void LLComboBox::sortByName() |
305 | { | 304 | { |
@@ -311,7 +310,7 @@ void LLComboBox::sortByName() | |||
311 | // Returns TRUE if the item was found. | 310 | // Returns TRUE if the item was found. |
312 | BOOL LLComboBox::setSimple(const LLStringExplicit& name) | 311 | BOOL LLComboBox::setSimple(const LLStringExplicit& name) |
313 | { | 312 | { |
314 | BOOL found = mList->selectSimpleItem(name, FALSE); | 313 | BOOL found = mList->selectItemByLabel(name, FALSE); |
315 | 314 | ||
316 | if (found) | 315 | if (found) |
317 | { | 316 | { |
@@ -330,14 +329,14 @@ void LLComboBox::setValue(const LLSD& value) | |||
330 | LLScrollListItem* item = mList->getFirstSelected(); | 329 | LLScrollListItem* item = mList->getFirstSelected(); |
331 | if (item) | 330 | if (item) |
332 | { | 331 | { |
333 | setLabel( mList->getSimpleSelectedItem() ); | 332 | setLabel( mList->getSelectedItemLabel() ); |
334 | } | 333 | } |
335 | } | 334 | } |
336 | } | 335 | } |
337 | 336 | ||
338 | const LLString& LLComboBox::getSimple() const | 337 | const LLString LLComboBox::getSimple() const |
339 | { | 338 | { |
340 | const LLString& res = mList->getSimpleSelectedItem(); | 339 | const LLString res = mList->getSelectedItemLabel(); |
341 | if (res.empty() && mAllowTextEntry) | 340 | if (res.empty() && mAllowTextEntry) |
342 | { | 341 | { |
343 | return mTextEntry->getText(); | 342 | return mTextEntry->getText(); |
@@ -348,9 +347,9 @@ const LLString& LLComboBox::getSimple() const | |||
348 | } | 347 | } |
349 | } | 348 | } |
350 | 349 | ||
351 | const LLString& LLComboBox::getSimpleSelectedItem(S32 column) const | 350 | const LLString LLComboBox::getSelectedItemLabel(S32 column) const |
352 | { | 351 | { |
353 | return mList->getSimpleSelectedItem(column); | 352 | return mList->getSelectedItemLabel(column); |
354 | } | 353 | } |
355 | 354 | ||
356 | // virtual | 355 | // virtual |
@@ -373,10 +372,10 @@ LLSD LLComboBox::getValue() const | |||
373 | 372 | ||
374 | void LLComboBox::setLabel(const LLStringExplicit& name) | 373 | void LLComboBox::setLabel(const LLStringExplicit& name) |
375 | { | 374 | { |
376 | if ( mAllowTextEntry ) | 375 | if ( mTextEntry ) |
377 | { | 376 | { |
378 | mTextEntry->setText(name); | 377 | mTextEntry->setText(name); |
379 | if (mList->selectSimpleItem(name, FALSE)) | 378 | if (mList->selectItemByLabel(name, FALSE)) |
380 | { | 379 | { |
381 | mTextEntry->setTentative(FALSE); | 380 | mTextEntry->setTentative(FALSE); |
382 | } | 381 | } |
@@ -385,7 +384,8 @@ void LLComboBox::setLabel(const LLStringExplicit& name) | |||
385 | mTextEntry->setTentative(mTextEntryTentative); | 384 | mTextEntry->setTentative(mTextEntryTentative); |
386 | } | 385 | } |
387 | } | 386 | } |
388 | else | 387 | |
388 | if (!mAllowTextEntry) | ||
389 | { | 389 | { |
390 | mButton->setLabelUnselected(name); | 390 | mButton->setLabelUnselected(name); |
391 | mButton->setLabelSelected(name); | 391 | mButton->setLabelSelected(name); |
@@ -397,7 +397,7 @@ void LLComboBox::setLabel(const LLStringExplicit& name) | |||
397 | 397 | ||
398 | BOOL LLComboBox::remove(const LLString& name) | 398 | BOOL LLComboBox::remove(const LLString& name) |
399 | { | 399 | { |
400 | BOOL found = mList->selectSimpleItem(name); | 400 | BOOL found = mList->selectItemByLabel(name); |
401 | 401 | ||
402 | if (found) | 402 | if (found) |
403 | { | 403 | { |
@@ -433,16 +433,21 @@ void LLComboBox::onFocusLost() | |||
433 | LLUICtrl::onFocusLost(); | 433 | LLUICtrl::onFocusLost(); |
434 | } | 434 | } |
435 | 435 | ||
436 | void LLComboBox::onLostTop() | ||
437 | { | ||
438 | hideList(); | ||
439 | } | ||
440 | |||
441 | |||
436 | void LLComboBox::setButtonVisible(BOOL visible) | 442 | void LLComboBox::setButtonVisible(BOOL visible) |
437 | { | 443 | { |
438 | mButton->setVisible(visible); | 444 | mButton->setVisible(visible); |
439 | mDrawArrow = visible; | ||
440 | if (mTextEntry) | 445 | if (mTextEntry) |
441 | { | 446 | { |
442 | LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); | 447 | LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); |
443 | if (visible) | 448 | if (visible) |
444 | { | 449 | { |
445 | text_entry_rect.mRight -= mArrowImageWidth + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); | 450 | text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth(0)) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); |
446 | } | 451 | } |
447 | //mTextEntry->setRect(text_entry_rect); | 452 | //mTextEntry->setRect(text_entry_rect); |
448 | mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE); | 453 | mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE); |
@@ -457,22 +462,8 @@ void LLComboBox::draw() | |||
457 | 462 | ||
458 | mButton->setEnabled(mEnabled /*&& !mList->isEmpty()*/); | 463 | mButton->setEnabled(mEnabled /*&& !mList->isEmpty()*/); |
459 | 464 | ||
460 | // Draw children | 465 | // Draw children normally |
461 | LLUICtrl::draw(); | 466 | LLUICtrl::draw(); |
462 | |||
463 | if (mDrawArrow) | ||
464 | { | ||
465 | // Paste the graphic on the right edge | ||
466 | if (!mArrowImage.isNull()) | ||
467 | { | ||
468 | S32 arrow_height = llmin(mRect.getHeight(), mArrowImage->getHeight()); | ||
469 | S32 arrow_width = llround((F32)mArrowImage->getWidth() * ((F32)arrow_height / (F32)mArrowImage->getHeight())); | ||
470 | |||
471 | S32 left = mRect.getWidth() - mArrowImage->getWidth() - LLUI::sConfigGroup->getS32("DropShadowButton"); | ||
472 | |||
473 | gl_draw_scaled_image( left, 0, arrow_width, arrow_height, mArrowImage, LLColor4::white); | ||
474 | } | ||
475 | } | ||
476 | } | 467 | } |
477 | } | 468 | } |
478 | 469 | ||
@@ -481,7 +472,7 @@ BOOL LLComboBox::setCurrentByIndex( S32 index ) | |||
481 | BOOL found = mList->selectNthItem( index ); | 472 | BOOL found = mList->selectNthItem( index ); |
482 | if (found) | 473 | if (found) |
483 | { | 474 | { |
484 | setLabel(mList->getSimpleSelectedItem()); | 475 | setLabel(mList->getSelectedItemLabel()); |
485 | } | 476 | } |
486 | return found; | 477 | return found; |
487 | } | 478 | } |
@@ -497,6 +488,67 @@ S32 LLComboBox::getCurrentIndex() const | |||
497 | } | 488 | } |
498 | 489 | ||
499 | 490 | ||
491 | void LLComboBox::updateLayout() | ||
492 | { | ||
493 | LLRect rect = getLocalRect(); | ||
494 | if (mAllowTextEntry) | ||
495 | { | ||
496 | S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton"); | ||
497 | mButton->setRect(LLRect( mRect.getWidth() - llmax(8,mArrowImage->getWidth(0)) - 2 * shadow_size, | ||
498 | rect.mTop, rect.mRight, rect.mBottom)); | ||
499 | mButton->setTabStop(FALSE); | ||
500 | |||
501 | if (!mTextEntry) | ||
502 | { | ||
503 | LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); | ||
504 | text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth(0)) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); | ||
505 | // clear label on button | ||
506 | LLString cur_label = mButton->getLabelSelected(); | ||
507 | mTextEntry = new LLLineEditor("combo_text_entry", | ||
508 | text_entry_rect, | ||
509 | "", | ||
510 | LLFontGL::sSansSerifSmall, | ||
511 | mMaxChars, | ||
512 | onTextCommit, | ||
513 | onTextEntry, | ||
514 | NULL, | ||
515 | this, | ||
516 | NULL, // prevalidate func | ||
517 | LLViewBorder::BEVEL_NONE, | ||
518 | LLViewBorder::STYLE_LINE, | ||
519 | 0); // no border | ||
520 | mTextEntry->setSelectAllonFocusReceived(TRUE); | ||
521 | mTextEntry->setHandleEditKeysDirectly(TRUE); | ||
522 | mTextEntry->setCommitOnFocusLost(FALSE); | ||
523 | mTextEntry->setText(cur_label); | ||
524 | mTextEntry->setIgnoreTab(TRUE); | ||
525 | mTextEntry->setFollowsAll(); | ||
526 | addChild(mTextEntry); | ||
527 | } | ||
528 | else | ||
529 | { | ||
530 | mTextEntry->setVisible(TRUE); | ||
531 | mTextEntry->setMaxTextLength(mMaxChars); | ||
532 | } | ||
533 | |||
534 | // clear label on button | ||
535 | setLabel(LLString::null); | ||
536 | |||
537 | mButton->setFollows(FOLLOWS_BOTTOM | FOLLOWS_TOP | FOLLOWS_RIGHT); | ||
538 | } | ||
539 | else if (!mAllowTextEntry) | ||
540 | { | ||
541 | mButton->setRect(rect); | ||
542 | mButton->setTabStop(TRUE); | ||
543 | |||
544 | if (mTextEntry) | ||
545 | { | ||
546 | mTextEntry->setVisible(FALSE); | ||
547 | } | ||
548 | mButton->setFollowsAll(); | ||
549 | } | ||
550 | } | ||
551 | |||
500 | void* LLComboBox::getCurrentUserdata() | 552 | void* LLComboBox::getCurrentUserdata() |
501 | { | 553 | { |
502 | LLScrollListItem* item = mList->getFirstSelected(); | 554 | LLScrollListItem* item = mList->getFirstSelected(); |
@@ -514,7 +566,7 @@ void LLComboBox::showList() | |||
514 | LLCoordWindow window_size; | 566 | LLCoordWindow window_size; |
515 | getWindow()->getSize(&window_size); | 567 | getWindow()->getSize(&window_size); |
516 | //HACK: shouldn't have to know about scale here | 568 | //HACK: shouldn't have to know about scale here |
517 | mList->arrange( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 ); | 569 | mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 ); |
518 | 570 | ||
519 | // Make sure that we can see the whole list | 571 | // Make sure that we can see the whole list |
520 | LLRect root_view_local; | 572 | LLRect root_view_local; |
@@ -523,7 +575,9 @@ void LLComboBox::showList() | |||
523 | 575 | ||
524 | LLRect rect = mList->getRect(); | 576 | LLRect rect = mList->getRect(); |
525 | 577 | ||
526 | S32 list_width = mRect.getWidth() + SCROLLBAR_SIZE; | 578 | S32 min_width = mRect.getWidth(); |
579 | S32 max_width = llmax(min_width, MAX_COMBO_WIDTH); | ||
580 | S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width); | ||
527 | 581 | ||
528 | if (mListPosition == BELOW) | 582 | if (mListPosition == BELOW) |
529 | { | 583 | { |
@@ -583,12 +637,6 @@ void LLComboBox::showList() | |||
583 | mList->translate(0, -y); | 637 | mList->translate(0, -y); |
584 | } | 638 | } |
585 | 639 | ||
586 | // pass mouse capture on to list if button is depressed | ||
587 | if (mButton->hasMouseCapture()) | ||
588 | { | ||
589 | gFocusMgr.setMouseCapture(mList); | ||
590 | } | ||
591 | |||
592 | // NB: this call will trigger the focuslost callback which will hide the list, so do it first | 640 | // NB: this call will trigger the focuslost callback which will hide the list, so do it first |
593 | // before finally showing the list | 641 | // before finally showing the list |
594 | 642 | ||
@@ -604,24 +652,29 @@ void LLComboBox::showList() | |||
604 | mButton->setToggleState(TRUE); | 652 | mButton->setToggleState(TRUE); |
605 | mList->setVisible(TRUE); | 653 | mList->setVisible(TRUE); |
606 | 654 | ||
607 | gFocusMgr.setTopCtrl(mList); | 655 | setUseBoundingRect(TRUE); |
656 | gFocusMgr.setTopCtrl(this); | ||
608 | } | 657 | } |
609 | 658 | ||
610 | void LLComboBox::hideList() | 659 | void LLComboBox::hideList() |
611 | { | 660 | { |
661 | //*HACK: store the original value explicitly somewhere, not just in label | ||
662 | LLString orig_selection = mAllowTextEntry ? mTextEntry->getText() : mButton->getLabelSelected(); | ||
663 | |||
664 | // assert selection in list | ||
665 | mList->selectItemByLabel(orig_selection, FALSE); | ||
666 | |||
612 | mButton->setToggleState(FALSE); | 667 | mButton->setToggleState(FALSE); |
613 | mList->setVisible(FALSE); | 668 | mList->setVisible(FALSE); |
614 | mList->highlightNthItem(-1); | 669 | mList->highlightNthItem(-1); |
615 | 670 | ||
616 | if( gFocusMgr.getTopCtrl() == mList ) | 671 | setUseBoundingRect(FALSE); |
672 | if( gFocusMgr.getTopCtrl() == this ) | ||
617 | { | 673 | { |
618 | gFocusMgr.setTopCtrl(NULL); | 674 | gFocusMgr.setTopCtrl(NULL); |
619 | } | 675 | } |
620 | |||
621 | //mList->setFocus(FALSE); | ||
622 | } | 676 | } |
623 | 677 | ||
624 | |||
625 | //------------------------------------------------------------------ | 678 | //------------------------------------------------------------------ |
626 | // static functions | 679 | // static functions |
627 | //------------------------------------------------------------------ | 680 | //------------------------------------------------------------------ |
@@ -650,21 +703,20 @@ void LLComboBox::onButtonDown(void *userdata) | |||
650 | self->showList(); | 703 | self->showList(); |
651 | } | 704 | } |
652 | 705 | ||
653 | if (self->mKeyboardFocusOnClick && !self->hasFocus()) | 706 | self->setFocus( TRUE ); |
707 | |||
708 | // pass mouse capture on to list if button is depressed | ||
709 | if (self->mButton->hasMouseCapture()) | ||
654 | { | 710 | { |
655 | self->setFocus( TRUE ); | 711 | gFocusMgr.setMouseCapture(self->mList); |
656 | } | 712 | } |
657 | } | 713 | } |
658 | else | 714 | else |
659 | { | 715 | { |
660 | // hide and release keyboard focus | ||
661 | self->hideList(); | 716 | self->hideList(); |
662 | |||
663 | self->onCommit(); | ||
664 | } | 717 | } |
665 | } | ||
666 | |||
667 | 718 | ||
719 | } | ||
668 | 720 | ||
669 | // static | 721 | // static |
670 | void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata) | 722 | void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata) |
@@ -672,7 +724,7 @@ void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata) | |||
672 | // Note: item is the LLScrollListCtrl | 724 | // Note: item is the LLScrollListCtrl |
673 | LLComboBox *self = (LLComboBox *) userdata; | 725 | LLComboBox *self = (LLComboBox *) userdata; |
674 | 726 | ||
675 | const LLString& name = self->mList->getSimpleSelectedItem(); | 727 | const LLString name = self->mList->getSelectedItemLabel(); |
676 | 728 | ||
677 | S32 cur_id = self->getCurrentIndex(); | 729 | S32 cur_id = self->getCurrentIndex(); |
678 | if (cur_id != -1) | 730 | if (cur_id != -1) |
@@ -681,40 +733,24 @@ void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata) | |||
681 | 733 | ||
682 | if (self->mAllowTextEntry) | 734 | if (self->mAllowTextEntry) |
683 | { | 735 | { |
684 | gFocusMgr.setKeyboardFocus(self->mTextEntry, NULL); | 736 | gFocusMgr.setKeyboardFocus(self->mTextEntry); |
685 | self->mTextEntry->selectAll(); | 737 | self->mTextEntry->selectAll(); |
686 | } | 738 | } |
687 | } | 739 | } |
688 | else | 740 | else |
689 | { | 741 | { |
690 | // invalid selection, just restore existing value | 742 | // invalid selection, just restore existing value |
691 | self->mList->selectSimpleItem(self->mButton->getLabelSelected()); | 743 | LLString orig_selection = self->mAllowTextEntry ? self->mTextEntry->getText() : self->mButton->getLabelSelected(); |
744 | |||
745 | self->mList->selectItemByLabel(orig_selection); | ||
692 | } | 746 | } |
693 | self->onCommit(); | 747 | self->onCommit(); |
694 | 748 | ||
695 | self->hideList(); | 749 | self->hideList(); |
696 | } | 750 | } |
697 | 751 | ||
698 | // static | ||
699 | void LLComboBox::onListFocusChanged(LLUICtrl* list, void* user_data) | ||
700 | { | ||
701 | LLComboBox *self = (LLComboBox *) list->getParent(); | ||
702 | // user not manipulating list or clicking on drop down button | ||
703 | if (!self->mList->hasFocus() && !self->mButton->hasMouseCapture()) | ||
704 | { | ||
705 | //*HACK: store the original value explicitly somewhere, not just in label | ||
706 | LLString orig_selection = self->mAllowTextEntry ? self->mTextEntry->getText() : self->mButton->getLabelSelected(); | ||
707 | |||
708 | self->hideList(); | ||
709 | |||
710 | // reassert original selection | ||
711 | self->mList->selectSimpleItem(orig_selection, FALSE); | ||
712 | } | ||
713 | } | ||
714 | |||
715 | BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) | 752 | BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) |
716 | { | 753 | { |
717 | |||
718 | LLString tool_tip; | 754 | LLString tool_tip; |
719 | 755 | ||
720 | if (LLUI::sShowXUINames) | 756 | if (LLUI::sShowXUINames) |
@@ -726,23 +762,19 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_ | |||
726 | tool_tip = mToolTipMsg; | 762 | tool_tip = mToolTipMsg; |
727 | } | 763 | } |
728 | 764 | ||
729 | if( getVisible() && pointInView( x, y ) ) | 765 | if( !tool_tip.empty() ) |
730 | { | 766 | { |
731 | if( !tool_tip.empty() ) | 767 | msg = tool_tip; |
732 | { | 768 | |
733 | msg = tool_tip; | 769 | // Convert rect local to screen coordinates |
734 | 770 | localPointToScreen( | |
735 | // Convert rect local to screen coordinates | 771 | 0, 0, |
736 | localPointToScreen( | 772 | &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); |
737 | 0, 0, | 773 | localPointToScreen( |
738 | &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); | 774 | mRect.getWidth(), mRect.getHeight(), |
739 | localPointToScreen( | 775 | &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); |
740 | mRect.getWidth(), mRect.getHeight(), | ||
741 | &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); | ||
742 | } | ||
743 | return TRUE; | ||
744 | } | 776 | } |
745 | return FALSE; | 777 | return TRUE; |
746 | } | 778 | } |
747 | 779 | ||
748 | BOOL LLComboBox::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) | 780 | BOOL LLComboBox::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) |
@@ -793,63 +825,11 @@ BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent | |||
793 | 825 | ||
794 | void LLComboBox::setAllowTextEntry(BOOL allow, S32 max_chars, BOOL set_tentative) | 826 | void LLComboBox::setAllowTextEntry(BOOL allow, S32 max_chars, BOOL set_tentative) |
795 | { | 827 | { |
796 | LLRect rect( 0, mRect.getHeight(), mRect.getWidth(), 0); | ||
797 | if (allow && !mAllowTextEntry) | ||
798 | { | ||
799 | S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton"); | ||
800 | mButton->setRect(LLRect( mRect.getWidth() - mArrowImageWidth - 2 * shadow_size, | ||
801 | rect.mTop, rect.mRight, rect.mBottom)); | ||
802 | mButton->setTabStop(FALSE); | ||
803 | |||
804 | // clear label on button | ||
805 | LLString cur_label = mButton->getLabelSelected(); | ||
806 | setLabel(LLString::null); | ||
807 | if (!mTextEntry) | ||
808 | { | ||
809 | LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); | ||
810 | text_entry_rect.mRight -= mArrowImageWidth + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); | ||
811 | mTextEntry = new LLLineEditor("combo_text_entry", | ||
812 | text_entry_rect, | ||
813 | "", | ||
814 | LLFontGL::sSansSerifSmall, | ||
815 | max_chars, | ||
816 | onTextCommit, | ||
817 | onTextEntry, | ||
818 | NULL, | ||
819 | this, | ||
820 | NULL, // prevalidate func | ||
821 | LLViewBorder::BEVEL_NONE, | ||
822 | LLViewBorder::STYLE_LINE, | ||
823 | 0); // no border | ||
824 | mTextEntry->setSelectAllonFocusReceived(TRUE); | ||
825 | mTextEntry->setHandleEditKeysDirectly(TRUE); | ||
826 | mTextEntry->setCommitOnFocusLost(FALSE); | ||
827 | mTextEntry->setText(cur_label); | ||
828 | mTextEntry->setIgnoreTab(TRUE); | ||
829 | mTextEntry->setFollowsAll(); | ||
830 | addChild(mTextEntry); | ||
831 | mMaxChars = max_chars; | ||
832 | } | ||
833 | else | ||
834 | { | ||
835 | mTextEntry->setVisible(TRUE); | ||
836 | } | ||
837 | |||
838 | mButton->setFollows(FOLLOWS_BOTTOM | FOLLOWS_TOP | FOLLOWS_RIGHT); | ||
839 | } | ||
840 | else if (!allow && mAllowTextEntry) | ||
841 | { | ||
842 | mButton->setRect(rect); | ||
843 | mButton->setTabStop(TRUE); | ||
844 | |||
845 | if (mTextEntry) | ||
846 | { | ||
847 | mTextEntry->setVisible(FALSE); | ||
848 | } | ||
849 | mButton->setFollowsAll(); | ||
850 | } | ||
851 | mAllowTextEntry = allow; | 828 | mAllowTextEntry = allow; |
852 | mTextEntryTentative = set_tentative; | 829 | mTextEntryTentative = set_tentative; |
830 | mMaxChars = max_chars; | ||
831 | |||
832 | updateLayout(); | ||
853 | } | 833 | } |
854 | 834 | ||
855 | void LLComboBox::setTextEntry(const LLStringExplicit& text) | 835 | void LLComboBox::setTextEntry(const LLStringExplicit& text) |
@@ -875,7 +855,7 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor, void* user_data) | |||
875 | if (key == KEY_BACKSPACE || | 855 | if (key == KEY_BACKSPACE || |
876 | key == KEY_DELETE) | 856 | key == KEY_DELETE) |
877 | { | 857 | { |
878 | if (self->mList->selectSimpleItem(line_editor->getText(), FALSE)) | 858 | if (self->mList->selectItemByLabel(line_editor->getText(), FALSE)) |
879 | { | 859 | { |
880 | line_editor->setTentative(FALSE); | 860 | line_editor->setTentative(FALSE); |
881 | } | 861 | } |
@@ -955,11 +935,11 @@ void LLComboBox::updateSelection() | |||
955 | } | 935 | } |
956 | } | 936 | } |
957 | 937 | ||
958 | if (mList->selectSimpleItem(full_string, FALSE)) | 938 | if (mList->selectItemByLabel(full_string, FALSE)) |
959 | { | 939 | { |
960 | mTextEntry->setTentative(FALSE); | 940 | mTextEntry->setTentative(FALSE); |
961 | } | 941 | } |
962 | else if (!mList->selectSimpleItemByPrefix(left_wstring, FALSE)) | 942 | else if (!mList->selectItemByPrefix(left_wstring, FALSE)) |
963 | { | 943 | { |
964 | mList->deselectAllItems(); | 944 | mList->deselectAllItems(); |
965 | mTextEntry->setText(wstring_to_utf8str(user_wstring)); | 945 | mTextEntry->setText(wstring_to_utf8str(user_wstring)); |
@@ -967,7 +947,7 @@ void LLComboBox::updateSelection() | |||
967 | } | 947 | } |
968 | else | 948 | else |
969 | { | 949 | { |
970 | LLWString selected_item = utf8str_to_wstring(mList->getSimpleSelectedItem()); | 950 | LLWString selected_item = utf8str_to_wstring(mList->getSelectedItemLabel()); |
971 | LLWString wtext = left_wstring + selected_item.substr(left_wstring.size(), selected_item.size()); | 951 | LLWString wtext = left_wstring + selected_item.substr(left_wstring.size(), selected_item.size()); |
972 | mTextEntry->setText(wstring_to_utf8str(wtext)); | 952 | mTextEntry->setText(wstring_to_utf8str(wtext)); |
973 | mTextEntry->setSelection(left_wstring.size(), mTextEntry->getWText().size()); | 953 | mTextEntry->setSelection(left_wstring.size(), mTextEntry->getWText().size()); |
@@ -993,6 +973,10 @@ void LLComboBox::setFocus(BOOL b) | |||
993 | if (b) | 973 | if (b) |
994 | { | 974 | { |
995 | mList->clearSearchString(); | 975 | mList->clearSearchString(); |
976 | if (mList->getVisible()) | ||
977 | { | ||
978 | mList->setFocus(TRUE); | ||
979 | } | ||
996 | } | 980 | } |
997 | } | 981 | } |
998 | 982 | ||
@@ -1048,7 +1032,7 @@ BOOL LLComboBox::setCurrentByID(const LLUUID& id) | |||
1048 | 1032 | ||
1049 | if (found) | 1033 | if (found) |
1050 | { | 1034 | { |
1051 | setLabel(mList->getSimpleSelectedItem()); | 1035 | setLabel(mList->getSelectedItemLabel()); |
1052 | } | 1036 | } |
1053 | 1037 | ||
1054 | return found; | 1038 | return found; |
@@ -1063,14 +1047,14 @@ BOOL LLComboBox::setSelectedByValue(LLSD value, BOOL selected) | |||
1063 | BOOL found = mList->setSelectedByValue(value, selected); | 1047 | BOOL found = mList->setSelectedByValue(value, selected); |
1064 | if (found) | 1048 | if (found) |
1065 | { | 1049 | { |
1066 | setLabel(mList->getSimpleSelectedItem()); | 1050 | setLabel(mList->getSelectedItemLabel()); |
1067 | } | 1051 | } |
1068 | return found; | 1052 | return found; |
1069 | } | 1053 | } |
1070 | 1054 | ||
1071 | LLSD LLComboBox::getSimpleSelectedValue() | 1055 | LLSD LLComboBox::getSelectedValue() |
1072 | { | 1056 | { |
1073 | return mList->getSimpleSelectedValue(); | 1057 | return mList->getSelectedValue(); |
1074 | } | 1058 | } |
1075 | 1059 | ||
1076 | BOOL LLComboBox::isSelected(LLSD value) | 1060 | BOOL LLComboBox::isSelected(LLSD value) |
@@ -1097,3 +1081,155 @@ BOOL LLComboBox::operateOnAll(EOperation op) | |||
1097 | } | 1081 | } |
1098 | return FALSE; | 1082 | return FALSE; |
1099 | } | 1083 | } |
1084 | |||
1085 | |||
1086 | |||
1087 | // | ||
1088 | // LLFlyoutButton | ||
1089 | // | ||
1090 | |||
1091 | const S32 FLYOUT_BUTTON_ARROW_WIDTH = 24; | ||
1092 | |||
1093 | LLFlyoutButton::LLFlyoutButton( | ||
1094 | const LLString& name, | ||
1095 | const LLRect &rect, | ||
1096 | const LLString& label, | ||
1097 | void (*commit_callback)(LLUICtrl*, void*) , | ||
1098 | void *callback_userdata) | ||
1099 | : LLComboBox(name, rect, LLString::null, commit_callback, callback_userdata), | ||
1100 | mToggleState(FALSE), | ||
1101 | mActionButton(NULL) | ||
1102 | { | ||
1103 | // Always use text box | ||
1104 | // Text label button | ||
1105 | mActionButton = new LLButton("flyout_button_main", | ||
1106 | LLRect(), label, NULL, LLString::null, | ||
1107 | NULL, this); | ||
1108 | mActionButton->setScaleImage(TRUE); | ||
1109 | |||
1110 | mActionButton->setClickedCallback(onActionButtonClick); | ||
1111 | mActionButton->setFollowsAll(); | ||
1112 | mActionButton->setHAlign( LLFontGL::HCENTER ); | ||
1113 | mActionButton->setLabel(label); | ||
1114 | addChild(mActionButton); | ||
1115 | |||
1116 | mActionButtonImage = LLUI::getUIImageByName("flyout_btn_left.tga"); | ||
1117 | mExpanderButtonImage = LLUI::getUIImageByName("flyout_btn_right.tga"); | ||
1118 | mActionButtonImageSelected = LLUI::getUIImageByName("flyout_btn_left_selected.tga"); | ||
1119 | mExpanderButtonImageSelected = LLUI::getUIImageByName("flyout_btn_right_selected.tga"); | ||
1120 | |||
1121 | mActionButton->setImageSelected(mActionButtonImageSelected); | ||
1122 | mActionButton->setImageUnselected(mActionButtonImage); | ||
1123 | mActionButton->setImageDisabled(LLPointer<LLUIImage>(NULL)); | ||
1124 | mActionButton->setImageDisabledSelected(LLPointer<LLUIImage>(NULL)); | ||
1125 | |||
1126 | mButton->setImageSelected(mExpanderButtonImageSelected); | ||
1127 | mButton->setImageUnselected(mExpanderButtonImage); | ||
1128 | mButton->setImageDisabled(LLPointer<LLUIImage>(NULL)); | ||
1129 | mButton->setImageDisabledSelected(LLPointer<LLUIImage>(NULL)); | ||
1130 | mButton->setRightHPad(6); | ||
1131 | |||
1132 | mBorder->setVisible(FALSE); | ||
1133 | |||
1134 | updateLayout(); | ||
1135 | } | ||
1136 | |||
1137 | //static | ||
1138 | LLView* LLFlyoutButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) | ||
1139 | { | ||
1140 | LLString name = "flyout_button"; | ||
1141 | node->getAttributeString("name", name); | ||
1142 | |||
1143 | LLString label(""); | ||
1144 | node->getAttributeString("label", label); | ||
1145 | |||
1146 | LLRect rect; | ||
1147 | createRect(node, rect, parent, LLRect()); | ||
1148 | |||
1149 | LLUICtrlCallback callback = NULL; | ||
1150 | |||
1151 | LLFlyoutButton* flyout_button = new LLFlyoutButton(name, | ||
1152 | rect, | ||
1153 | label, | ||
1154 | callback, | ||
1155 | NULL); | ||
1156 | |||
1157 | LLString list_position; | ||
1158 | node->getAttributeString("list_position", list_position); | ||
1159 | if (list_position == "below") | ||
1160 | { | ||
1161 | flyout_button->mListPosition = BELOW; | ||
1162 | } | ||
1163 | else if (list_position == "above") | ||
1164 | { | ||
1165 | flyout_button->mListPosition = ABOVE; | ||
1166 | } | ||
1167 | |||
1168 | |||
1169 | flyout_button->initFromXML(node, parent); | ||
1170 | |||
1171 | LLXMLNodePtr child; | ||
1172 | for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) | ||
1173 | { | ||
1174 | if (child->hasName("flyout_button_item")) | ||
1175 | { | ||
1176 | LLString label = child->getTextContents(); | ||
1177 | |||
1178 | LLString value = label; | ||
1179 | child->getAttributeString("value", value); | ||
1180 | |||
1181 | flyout_button->add(label, LLSD(value) ); | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | flyout_button->updateLayout(); | ||
1186 | |||
1187 | return flyout_button; | ||
1188 | } | ||
1189 | |||
1190 | void LLFlyoutButton::updateLayout() | ||
1191 | { | ||
1192 | LLComboBox::updateLayout(); | ||
1193 | |||
1194 | mButton->setOrigin(mRect.getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, 0); | ||
1195 | mButton->reshape(FLYOUT_BUTTON_ARROW_WIDTH, mRect.getHeight()); | ||
1196 | mButton->setFollows(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); | ||
1197 | mButton->setTabStop(FALSE); | ||
1198 | mButton->setImageOverlay(mListPosition == BELOW ? "down_arrow.tga" : "up_arrow.tga", LLFontGL::RIGHT); | ||
1199 | |||
1200 | mActionButton->setOrigin(0, 0); | ||
1201 | mActionButton->reshape(mRect.getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, mRect.getHeight()); | ||
1202 | } | ||
1203 | |||
1204 | //static | ||
1205 | void LLFlyoutButton::onActionButtonClick(void *user_data) | ||
1206 | { | ||
1207 | LLFlyoutButton* buttonp = (LLFlyoutButton*)user_data; | ||
1208 | // remember last list selection? | ||
1209 | buttonp->mList->deselect(); | ||
1210 | buttonp->onCommit(); | ||
1211 | } | ||
1212 | |||
1213 | void LLFlyoutButton::draw() | ||
1214 | { | ||
1215 | mActionButton->setToggleState(mToggleState); | ||
1216 | mButton->setToggleState(mToggleState); | ||
1217 | |||
1218 | //FIXME: this should be an attribute of comboboxes, whether they have a distinct label or | ||
1219 | // the label reflects the last selected item, for now we have to manually remove the label | ||
1220 | mButton->setLabel(LLString::null); | ||
1221 | LLComboBox::draw(); | ||
1222 | } | ||
1223 | |||
1224 | void LLFlyoutButton::setEnabled(BOOL enabled) | ||
1225 | { | ||
1226 | mActionButton->setEnabled(enabled); | ||
1227 | LLComboBox::setEnabled(enabled); | ||
1228 | } | ||
1229 | |||
1230 | |||
1231 | void LLFlyoutButton::setToggleState(BOOL state) | ||
1232 | { | ||
1233 | mToggleState = state; | ||
1234 | } | ||
1235 | |||
diff --git a/linden/indra/llui/llcombobox.h b/linden/indra/llui/llcombobox.h index 6e5e4ab..2a70db2 100644 --- a/linden/indra/llui/llcombobox.h +++ b/linden/indra/llui/llcombobox.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -80,6 +80,7 @@ public: | |||
80 | 80 | ||
81 | virtual void draw(); | 81 | virtual void draw(); |
82 | virtual void onFocusLost(); | 82 | virtual void onFocusLost(); |
83 | virtual void onLostTop(); | ||
83 | 84 | ||
84 | virtual void setEnabled(BOOL enabled); | 85 | virtual void setEnabled(BOOL enabled); |
85 | 86 | ||
@@ -107,21 +108,22 @@ public: | |||
107 | void setAllowTextEntry(BOOL allow, S32 max_chars = 50, BOOL make_tentative = TRUE); | 108 | void setAllowTextEntry(BOOL allow, S32 max_chars = 50, BOOL make_tentative = TRUE); |
108 | void setTextEntry(const LLStringExplicit& text); | 109 | void setTextEntry(const LLStringExplicit& text); |
109 | 110 | ||
110 | void add(const LLString& name, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); // add item "name" to menu | 111 | LLScrollListItem* add(const LLString& name, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); // add item "name" to menu |
111 | void add(const LLString& name, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); | 112 | LLScrollListItem* add(const LLString& name, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); |
112 | void add(const LLString& name, void* userdata, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); | 113 | LLScrollListItem* add(const LLString& name, void* userdata, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); |
113 | void add(const LLString& name, LLSD value, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); | 114 | LLScrollListItem* add(const LLString& name, LLSD value, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); |
115 | LLScrollListItem* addSeparator(EAddPosition pos = ADD_BOTTOM); | ||
114 | BOOL remove( S32 index ); // remove item by index, return TRUE if found and removed | 116 | BOOL remove( S32 index ); // remove item by index, return TRUE if found and removed |
115 | void removeall() { clearRows(); } | 117 | void removeall() { clearRows(); } |
116 | 118 | ||
117 | void sortByName(); // Sort the entries in the combobox by name | 119 | void sortByName(); // Sort the entries in the combobox by name |
118 | 120 | ||
119 | // Select current item by name using selectSimpleItem. Returns FALSE if not found. | 121 | // Select current item by name using selectItemByLabel. Returns FALSE if not found. |
120 | BOOL setSimple(const LLStringExplicit& name); | 122 | BOOL setSimple(const LLStringExplicit& name); |
121 | // Get name of current item. Returns an empty string if not found. | 123 | // Get name of current item. Returns an empty string if not found. |
122 | const LLString& getSimple() const; | 124 | const LLString getSimple() const; |
123 | // Get contents of column x of selected row | 125 | // Get contents of column x of selected row |
124 | const LLString& getSimpleSelectedItem(S32 column = 0) const; | 126 | const LLString getSelectedItemLabel(S32 column = 0) const; |
125 | 127 | ||
126 | // Sets the label, which doesn't have to exist in the label. | 128 | // Sets the label, which doesn't have to exist in the label. |
127 | // This is probably a UI abuse. | 129 | // This is probably a UI abuse. |
@@ -132,6 +134,8 @@ public: | |||
132 | BOOL setCurrentByIndex( S32 index ); | 134 | BOOL setCurrentByIndex( S32 index ); |
133 | S32 getCurrentIndex() const; | 135 | S32 getCurrentIndex() const; |
134 | 136 | ||
137 | virtual void updateLayout(); | ||
138 | |||
135 | //======================================================================== | 139 | //======================================================================== |
136 | LLCtrlSelectionInterface* getSelectionInterface() { return (LLCtrlSelectionInterface*)this; }; | 140 | LLCtrlSelectionInterface* getSelectionInterface() { return (LLCtrlSelectionInterface*)this; }; |
137 | LLCtrlListInterface* getListInterface() { return (LLCtrlListInterface*)this; }; | 141 | LLCtrlListInterface* getListInterface() { return (LLCtrlListInterface*)this; }; |
@@ -156,7 +160,7 @@ public: | |||
156 | virtual BOOL setCurrentByID( const LLUUID& id ); | 160 | virtual BOOL setCurrentByID( const LLUUID& id ); |
157 | virtual LLUUID getCurrentID(); // LLUUID::null if no items in menu | 161 | virtual LLUUID getCurrentID(); // LLUUID::null if no items in menu |
158 | virtual BOOL setSelectedByValue(LLSD value, BOOL selected); | 162 | virtual BOOL setSelectedByValue(LLSD value, BOOL selected); |
159 | virtual LLSD getSimpleSelectedValue(); | 163 | virtual LLSD getSelectedValue(); |
160 | virtual BOOL isSelected(LLSD value); | 164 | virtual BOOL isSelected(LLSD value); |
161 | virtual BOOL operateOnSelection(EOperation op); | 165 | virtual BOOL operateOnSelection(EOperation op); |
162 | virtual BOOL operateOnAll(EOperation op); | 166 | virtual BOOL operateOnAll(EOperation op); |
@@ -172,7 +176,6 @@ public: | |||
172 | 176 | ||
173 | static void onButtonDown(void *userdata); | 177 | static void onButtonDown(void *userdata); |
174 | static void onItemSelected(LLUICtrl* item, void *userdata); | 178 | static void onItemSelected(LLUICtrl* item, void *userdata); |
175 | static void onListFocusChanged(LLUICtrl* item, void *userdata); | ||
176 | static void onTextEntry(LLLineEditor* line_editor, void* user_data); | 179 | static void onTextEntry(LLLineEditor* line_editor, void* user_data); |
177 | static void onTextCommit(LLUICtrl* caller, void* user_data); | 180 | static void onTextCommit(LLUICtrl* caller, void* user_data); |
178 | 181 | ||
@@ -183,12 +186,10 @@ public: | |||
183 | protected: | 186 | protected: |
184 | LLButton* mButton; | 187 | LLButton* mButton; |
185 | LLScrollListCtrl* mList; | 188 | LLScrollListCtrl* mList; |
189 | S32 mButtonPadding; | ||
186 | LLViewBorder* mBorder; | 190 | LLViewBorder* mBorder; |
187 | BOOL mKeyboardFocusOnClick; | ||
188 | BOOL mDrawArrow; | ||
189 | LLLineEditor* mTextEntry; | 191 | LLLineEditor* mTextEntry; |
190 | LLPointer<LLImageGL> mArrowImage; | 192 | LLPointer<LLImageGL> mArrowImage; |
191 | S32 mArrowImageWidth; | ||
192 | BOOL mAllowTextEntry; | 193 | BOOL mAllowTextEntry; |
193 | S32 mMaxChars; | 194 | S32 mMaxChars; |
194 | BOOL mTextEntryTentative; | 195 | BOOL mTextEntryTentative; |
@@ -197,4 +198,36 @@ protected: | |||
197 | void (*mTextEntryCallback)(LLLineEditor*, void*); | 198 | void (*mTextEntryCallback)(LLLineEditor*, void*); |
198 | }; | 199 | }; |
199 | 200 | ||
201 | class LLFlyoutButton : public LLComboBox | ||
202 | { | ||
203 | public: | ||
204 | LLFlyoutButton( | ||
205 | const LLString& name, | ||
206 | const LLRect &rect, | ||
207 | const LLString& label, | ||
208 | void (*commit_callback)(LLUICtrl*, void*) = NULL, | ||
209 | void *callback_userdata = NULL); | ||
210 | |||
211 | virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_FLYOUT_BUTTON; } | ||
212 | virtual LLString getWidgetTag() const { return LL_FLYOUT_BUTTON_TAG; } | ||
213 | |||
214 | virtual void updateLayout(); | ||
215 | virtual void draw(); | ||
216 | virtual void setEnabled(BOOL enabled); | ||
217 | |||
218 | void setToggleState(BOOL state); | ||
219 | |||
220 | static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); | ||
221 | static void onActionButtonClick(void *userdata); | ||
222 | static void onSelectAction(LLUICtrl* ctrl, void *userdata); | ||
223 | |||
224 | protected: | ||
225 | LLButton* mActionButton; | ||
226 | LLPointer<LLUIImage> mActionButtonImage; | ||
227 | LLPointer<LLUIImage> mExpanderButtonImage; | ||
228 | LLPointer<LLUIImage> mActionButtonImageSelected; | ||
229 | LLPointer<LLUIImage> mExpanderButtonImageSelected; | ||
230 | BOOL mToggleState; | ||
231 | }; | ||
232 | |||
200 | #endif | 233 | #endif |
diff --git a/linden/indra/llui/llctrlselectioninterface.cpp b/linden/indra/llui/llctrlselectioninterface.cpp index 6fb5df3..996f5b3 100644 --- a/linden/indra/llui/llctrlselectioninterface.cpp +++ b/linden/indra/llui/llctrlselectioninterface.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llctrlselectioninterface.h b/linden/indra/llui/llctrlselectioninterface.h index 20caa1e..121d971 100644 --- a/linden/indra/llui/llctrlselectioninterface.h +++ b/linden/indra/llui/llctrlselectioninterface.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -68,7 +68,7 @@ public: | |||
68 | BOOL selectByValue(LLSD value); | 68 | BOOL selectByValue(LLSD value); |
69 | BOOL deselectByValue(LLSD value); | 69 | BOOL deselectByValue(LLSD value); |
70 | virtual BOOL setSelectedByValue(LLSD value, BOOL selected) = 0; | 70 | virtual BOOL setSelectedByValue(LLSD value, BOOL selected) = 0; |
71 | virtual LLSD getSimpleSelectedValue() = 0; | 71 | virtual LLSD getSelectedValue() = 0; |
72 | 72 | ||
73 | virtual BOOL isSelected(LLSD value) = 0; | 73 | virtual BOOL isSelected(LLSD value) = 0; |
74 | 74 | ||
diff --git a/linden/indra/llui/lldraghandle.cpp b/linden/indra/llui/lldraghandle.cpp index fb91201..032cb91 100644 --- a/linden/indra/llui/lldraghandle.cpp +++ b/linden/indra/llui/lldraghandle.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/lldraghandle.h b/linden/indra/llui/lldraghandle.h index c085991..a48c0f7 100644 --- a/linden/indra/llui/lldraghandle.h +++ b/linden/indra/llui/lldraghandle.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -54,7 +54,6 @@ public: | |||
54 | 54 | ||
55 | virtual void setTitle( const LLString& title ) = 0; | 55 | virtual void setTitle( const LLString& title ) = 0; |
56 | virtual const LLString& getTitle() const = 0; | 56 | virtual const LLString& getTitle() const = 0; |
57 | virtual void draw() = 0; | ||
58 | virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) = 0; | 57 | virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) = 0; |
59 | 58 | ||
60 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); | 59 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); |
diff --git a/linden/indra/llui/lleditmenuhandler.cpp b/linden/indra/llui/lleditmenuhandler.cpp index b359098..6291088 100644 --- a/linden/indra/llui/lleditmenuhandler.cpp +++ b/linden/indra/llui/lleditmenuhandler.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/lleditmenuhandler.h b/linden/indra/llui/lleditmenuhandler.h index 394d27c..ef9b1dd 100644 --- a/linden/indra/llui/lleditmenuhandler.h +++ b/linden/indra/llui/lleditmenuhandler.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llfloater.cpp b/linden/indra/llui/llfloater.cpp index 8ff3c48..1500f9f 100644 --- a/linden/indra/llui/llfloater.cpp +++ b/linden/indra/llui/llfloater.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -128,7 +128,11 @@ LLFloater::handle_map_t LLFloater::sFloaterMap; | |||
128 | 128 | ||
129 | LLFloaterView* gFloaterView = NULL; | 129 | LLFloaterView* gFloaterView = NULL; |
130 | 130 | ||
131 | LLFloater::LLFloater() | 131 | LLFloater::LLFloater() : |
132 | //FIXME: we should initialize *all* member variables here | ||
133 | mResizable(FALSE), | ||
134 | mDragOnLeft(FALSE) | ||
135 | |||
132 | { | 136 | { |
133 | // automatically take focus when opened | 137 | // automatically take focus when opened |
134 | mAutoFocus = TRUE; | 138 | mAutoFocus = TRUE; |
@@ -215,9 +219,14 @@ void LLFloater::init(const LLString& title, | |||
215 | } | 219 | } |
216 | mButtonScale = 1.f; | 220 | mButtonScale = 1.f; |
217 | 221 | ||
218 | LLPanel::deleteAllChildren(); | 222 | BOOL need_border = mBorder != NULL; |
223 | |||
224 | // this will delete mBorder too | ||
225 | deleteAllChildren(); | ||
226 | // make sure we don't have a pointer to an old, deleted border | ||
227 | mBorder = NULL; | ||
219 | //sjb: HACK! we had a border which was just deleted, so re-create it | 228 | //sjb: HACK! we had a border which was just deleted, so re-create it |
220 | if (mBorder != NULL) | 229 | if (need_border) |
221 | { | 230 | { |
222 | addBorder(); | 231 | addBorder(); |
223 | } | 232 | } |
@@ -609,7 +618,7 @@ void LLFloater::releaseFocus() | |||
609 | 618 | ||
610 | if( gFocusMgr.childHasKeyboardFocus( this ) ) | 619 | if( gFocusMgr.childHasKeyboardFocus( this ) ) |
611 | { | 620 | { |
612 | gFocusMgr.setKeyboardFocus(NULL, NULL); | 621 | gFocusMgr.setKeyboardFocus(NULL); |
613 | } | 622 | } |
614 | 623 | ||
615 | if( gFocusMgr.childHasMouseCapture( this ) ) | 624 | if( gFocusMgr.childHasMouseCapture( this ) ) |
@@ -1026,13 +1035,10 @@ void LLFloater::setHost(LLMultiFloater* host) | |||
1026 | { | 1035 | { |
1027 | mButtonsEnabled[BUTTON_TEAR_OFF] = TRUE; | 1036 | mButtonsEnabled[BUTTON_TEAR_OFF] = TRUE; |
1028 | } | 1037 | } |
1029 | |||
1030 | mIsFocusRoot = FALSE; | ||
1031 | } | 1038 | } |
1032 | else if (!mHostHandle.isDead() && !host) | 1039 | else if (!mHostHandle.isDead() && !host) |
1033 | { | 1040 | { |
1034 | mButtonScale = 1.f; | 1041 | mButtonScale = 1.f; |
1035 | mIsFocusRoot = TRUE; | ||
1036 | //mButtonsEnabled[BUTTON_TEAR_OFF] = FALSE; | 1042 | //mButtonsEnabled[BUTTON_TEAR_OFF] = FALSE; |
1037 | } | 1043 | } |
1038 | updateButtons(); | 1044 | updateButtons(); |
@@ -1260,6 +1266,7 @@ void LLFloater::show(LLFloater* floaterp) | |||
1260 | { | 1266 | { |
1261 | if (floaterp) | 1267 | if (floaterp) |
1262 | { | 1268 | { |
1269 | gFocusMgr.triggerFocusFlash(); | ||
1263 | floaterp->open(); | 1270 | floaterp->open(); |
1264 | if (floaterp->getHost()) | 1271 | if (floaterp->getHost()) |
1265 | { | 1272 | { |
@@ -2245,7 +2252,8 @@ void LLFloaterView::refresh() | |||
2245 | LLFloater* floaterp = (LLFloater*)*child_it; | 2252 | LLFloater* floaterp = (LLFloater*)*child_it; |
2246 | if( floaterp->getVisible() ) | 2253 | if( floaterp->getVisible() ) |
2247 | { | 2254 | { |
2248 | adjustToFitScreen(floaterp, TRUE); | 2255 | // minimized floaters are kept fully onscreen |
2256 | adjustToFitScreen(floaterp, !floaterp->isMinimized()); | ||
2249 | } | 2257 | } |
2250 | } | 2258 | } |
2251 | } | 2259 | } |
@@ -2605,9 +2613,9 @@ void LLMultiFloater::draw() | |||
2605 | for (S32 i = 0; i < mTabContainer->getTabCount(); i++) | 2613 | for (S32 i = 0; i < mTabContainer->getTabCount(); i++) |
2606 | { | 2614 | { |
2607 | LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(i); | 2615 | LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(i); |
2608 | if (floaterp->getTitle() != mTabContainer->getPanelTitle(i)) | 2616 | if (floaterp->getShortTitle() != mTabContainer->getPanelTitle(i)) |
2609 | { | 2617 | { |
2610 | mTabContainer->setPanelTitle(i, floaterp->getTitle()); | 2618 | mTabContainer->setPanelTitle(i, floaterp->getShortTitle()); |
2611 | } | 2619 | } |
2612 | } | 2620 | } |
2613 | LLFloater::draw(); | 2621 | LLFloater::draw(); |
@@ -2725,7 +2733,7 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, | |||
2725 | 2733 | ||
2726 | if ( select_added_floater ) | 2734 | if ( select_added_floater ) |
2727 | { | 2735 | { |
2728 | mTabContainer->selectLastTab(); | 2736 | mTabContainer->selectTabPanel(floaterp); |
2729 | } | 2737 | } |
2730 | 2738 | ||
2731 | floaterp->setHost(this); | 2739 | floaterp->setHost(this); |
@@ -2970,8 +2978,9 @@ void LLMultiFloater::updateResizeLimits() | |||
2970 | // make sure upper left corner doesn't move | 2978 | // make sure upper left corner doesn't move |
2971 | translate(0, cur_height - mRect.getHeight()); | 2979 | translate(0, cur_height - mRect.getHeight()); |
2972 | 2980 | ||
2973 | // Try to keep whole view onscreen, don't allow partial offscreen. | 2981 | // make sure this window is visible on screen when it has been modified |
2974 | gFloaterView->adjustToFitScreen(this, FALSE); | 2982 | // (tab added, etc) |
2983 | gFloaterView->adjustToFitScreen(this, TRUE); | ||
2975 | } | 2984 | } |
2976 | } | 2985 | } |
2977 | 2986 | ||
diff --git a/linden/indra/llui/llfloater.h b/linden/indra/llui/llfloater.h index 3a34057..56b0e6e 100644 --- a/linden/indra/llui/llfloater.h +++ b/linden/indra/llui/llfloater.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llfocusmgr.cpp b/linden/indra/llui/llfocusmgr.cpp index 065c206..efca3d8 100644 --- a/linden/indra/llui/llfocusmgr.cpp +++ b/linden/indra/llui/llfocusmgr.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -42,11 +42,10 @@ LLFocusMgr gFocusMgr; | |||
42 | LLFocusMgr::LLFocusMgr() | 42 | LLFocusMgr::LLFocusMgr() |
43 | : | 43 | : |
44 | mLockedView( NULL ), | 44 | mLockedView( NULL ), |
45 | mKeyboardLockedFocusLostCallback( NULL ), | ||
46 | mMouseCaptor( NULL ), | 45 | mMouseCaptor( NULL ), |
47 | mKeyboardFocus( NULL ), | 46 | mKeyboardFocus( NULL ), |
47 | mLastKeyboardFocus( NULL ), | ||
48 | mDefaultKeyboardFocus( NULL ), | 48 | mDefaultKeyboardFocus( NULL ), |
49 | mKeyboardFocusLostCallback( NULL ), | ||
50 | mTopCtrl( NULL ), | 49 | mTopCtrl( NULL ), |
51 | mFocusWeight(0.f), | 50 | mFocusWeight(0.f), |
52 | mAppHasFocus(TRUE) // Macs don't seem to notify us that we've gotten focus, so default to true | 51 | mAppHasFocus(TRUE) // Macs don't seem to notify us that we've gotten focus, so default to true |
@@ -75,12 +74,11 @@ void LLFocusMgr::releaseFocusIfNeeded( LLView* view ) | |||
75 | if (view == mLockedView) | 74 | if (view == mLockedView) |
76 | { | 75 | { |
77 | mLockedView = NULL; | 76 | mLockedView = NULL; |
78 | mKeyboardLockedFocusLostCallback = NULL; | 77 | setKeyboardFocus( NULL ); |
79 | setKeyboardFocus( NULL, NULL ); | ||
80 | } | 78 | } |
81 | else | 79 | else |
82 | { | 80 | { |
83 | setKeyboardFocus( mLockedView, mKeyboardLockedFocusLostCallback ); | 81 | setKeyboardFocus( mLockedView ); |
84 | } | 82 | } |
85 | } | 83 | } |
86 | 84 | ||
@@ -91,7 +89,7 @@ void LLFocusMgr::releaseFocusIfNeeded( LLView* view ) | |||
91 | } | 89 | } |
92 | 90 | ||
93 | 91 | ||
94 | void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, FocusLostCallback on_focus_lost, BOOL lock) | 92 | void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock) |
95 | { | 93 | { |
96 | if (mLockedView && | 94 | if (mLockedView && |
97 | (new_focus == NULL || | 95 | (new_focus == NULL || |
@@ -101,28 +99,27 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, FocusLostCallback on_focu | |||
101 | // or one of its descendants | 99 | // or one of its descendants |
102 | return; | 100 | return; |
103 | } | 101 | } |
104 | FocusLostCallback old_callback = mKeyboardFocusLostCallback; | ||
105 | mKeyboardFocusLostCallback = on_focus_lost; | ||
106 | 102 | ||
107 | //llinfos << "Keyboard focus handled by " << (new_focus ? new_focus->getName() : "nothing") << llendl; | 103 | //llinfos << "Keyboard focus handled by " << (new_focus ? new_focus->getName() : "nothing") << llendl; |
108 | 104 | ||
109 | if( new_focus != mKeyboardFocus ) | 105 | if( new_focus != mKeyboardFocus ) |
110 | { | 106 | { |
111 | LLUICtrl* old_focus = mKeyboardFocus; | 107 | mLastKeyboardFocus = mKeyboardFocus; |
112 | mKeyboardFocus = new_focus; | 108 | mKeyboardFocus = new_focus; |
113 | 109 | ||
110 | if( mLastKeyboardFocus ) | ||
111 | { | ||
112 | mLastKeyboardFocus->onFocusLost(); | ||
113 | } | ||
114 | |||
114 | // clear out any existing flash | 115 | // clear out any existing flash |
115 | if (new_focus) | 116 | if (new_focus) |
116 | { | 117 | { |
117 | mFocusWeight = 0.f; | 118 | mFocusWeight = 0.f; |
119 | new_focus->onFocusReceived(); | ||
118 | } | 120 | } |
119 | mFocusTimer.reset(); | 121 | mFocusTimer.reset(); |
120 | 122 | ||
121 | if( old_callback ) | ||
122 | { | ||
123 | old_callback( old_focus ); | ||
124 | } | ||
125 | |||
126 | #ifdef _DEBUG | 123 | #ifdef _DEBUG |
127 | mKeyboardFocusName = new_focus ? new_focus->getName() : "none"; | 124 | mKeyboardFocusName = new_focus ? new_focus->getName() : "none"; |
128 | #endif | 125 | #endif |
@@ -204,13 +201,11 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( LLView* focus ) | |||
204 | if (focus == mLockedView) | 201 | if (focus == mLockedView) |
205 | { | 202 | { |
206 | mLockedView = NULL; | 203 | mLockedView = NULL; |
207 | mKeyboardLockedFocusLostCallback = NULL; | ||
208 | } | 204 | } |
209 | 205 | ||
210 | if( mKeyboardFocus == focus ) | 206 | if( mKeyboardFocus == focus ) |
211 | { | 207 | { |
212 | mKeyboardFocus = NULL; | 208 | mKeyboardFocus = NULL; |
213 | mKeyboardFocusLostCallback = NULL; | ||
214 | #ifdef _DEBUG | 209 | #ifdef _DEBUG |
215 | mKeyboardFocusName = "none"; | 210 | mKeyboardFocusName = "none"; |
216 | #endif | 211 | #endif |
@@ -293,13 +288,19 @@ BOOL LLFocusMgr::childIsTopCtrl( LLView* parent ) | |||
293 | // set new_top = NULL to release top_view. | 288 | // set new_top = NULL to release top_view. |
294 | void LLFocusMgr::setTopCtrl( LLUICtrl* new_top ) | 289 | void LLFocusMgr::setTopCtrl( LLUICtrl* new_top ) |
295 | { | 290 | { |
296 | if( new_top != mTopCtrl ) | 291 | LLUICtrl* old_top = mTopCtrl; |
292 | if( new_top != old_top ) | ||
297 | { | 293 | { |
298 | mTopCtrl = new_top; | 294 | mTopCtrl = new_top; |
299 | 295 | ||
300 | #ifdef _DEBUG | 296 | #ifdef _DEBUG |
301 | mTopCtrlName = new_top ? new_top->getName() : "none"; | 297 | mTopCtrlName = new_top ? new_top->getName() : "none"; |
302 | #endif | 298 | #endif |
299 | |||
300 | if (old_top) | ||
301 | { | ||
302 | old_top->onLostTop(); | ||
303 | } | ||
303 | } | 304 | } |
304 | } | 305 | } |
305 | 306 | ||
@@ -317,13 +318,11 @@ void LLFocusMgr::removeTopCtrlWithoutCallback( LLUICtrl* top_view ) | |||
317 | void LLFocusMgr::lockFocus() | 318 | void LLFocusMgr::lockFocus() |
318 | { | 319 | { |
319 | mLockedView = mKeyboardFocus; | 320 | mLockedView = mKeyboardFocus; |
320 | mKeyboardLockedFocusLostCallback = mKeyboardFocusLostCallback; | ||
321 | } | 321 | } |
322 | 322 | ||
323 | void LLFocusMgr::unlockFocus() | 323 | void LLFocusMgr::unlockFocus() |
324 | { | 324 | { |
325 | mLockedView = NULL; | 325 | mLockedView = NULL; |
326 | mKeyboardLockedFocusLostCallback = NULL; | ||
327 | } | 326 | } |
328 | 327 | ||
329 | F32 LLFocusMgr::getFocusFlashAmt() | 328 | F32 LLFocusMgr::getFocusFlashAmt() |
@@ -356,9 +355,9 @@ void LLFocusMgr::setAppHasFocus(BOOL focus) | |||
356 | } | 355 | } |
357 | 356 | ||
358 | // release focus from "top ctrl"s, which generally hides them | 357 | // release focus from "top ctrl"s, which generally hides them |
359 | if (!focus && mTopCtrl && mTopCtrl->hasFocus()) | 358 | if (!focus && mTopCtrl) |
360 | { | 359 | { |
361 | mTopCtrl->setFocus(FALSE); | 360 | setTopCtrl(NULL); |
362 | } | 361 | } |
363 | mAppHasFocus = focus; | 362 | mAppHasFocus = focus; |
364 | } | 363 | } |
diff --git a/linden/indra/llui/llfocusmgr.h b/linden/indra/llui/llfocusmgr.h index 02f588e..3bd5b35 100644 --- a/linden/indra/llui/llfocusmgr.h +++ b/linden/indra/llui/llfocusmgr.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -44,8 +44,6 @@ class LLMouseHandler; | |||
44 | class LLFocusMgr | 44 | class LLFocusMgr |
45 | { | 45 | { |
46 | public: | 46 | public: |
47 | typedef void (*FocusLostCallback)(LLUICtrl*); | ||
48 | |||
49 | LLFocusMgr(); | 47 | LLFocusMgr(); |
50 | ~LLFocusMgr(); | 48 | ~LLFocusMgr(); |
51 | 49 | ||
@@ -56,11 +54,11 @@ public: | |||
56 | BOOL childHasMouseCapture( LLView* parent ); | 54 | BOOL childHasMouseCapture( LLView* parent ); |
57 | 55 | ||
58 | // Keyboard Focus | 56 | // Keyboard Focus |
59 | void setKeyboardFocus(LLUICtrl* new_focus, FocusLostCallback on_focus_lost, BOOL lock = FALSE); // new_focus = NULL to release the focus. | 57 | void setKeyboardFocus(LLUICtrl* new_focus, BOOL lock = FALSE); // new_focus = NULL to release the focus. |
60 | LLUICtrl* getKeyboardFocus() const { return mKeyboardFocus; } | 58 | LLUICtrl* getKeyboardFocus() const { return mKeyboardFocus; } |
59 | LLUICtrl* getLastKeyboardFocus() const { return mLastKeyboardFocus; } | ||
61 | BOOL childHasKeyboardFocus( const LLView* parent ) const; | 60 | BOOL childHasKeyboardFocus( const LLView* parent ) const; |
62 | void removeKeyboardFocusWithoutCallback( LLView* focus ); | 61 | void removeKeyboardFocusWithoutCallback( LLView* focus ); |
63 | FocusLostCallback getFocusCallback() { return mKeyboardFocusLostCallback; } | ||
64 | F32 getFocusTime() const { return mFocusTimer.getElapsedTimeF32(); } | 62 | F32 getFocusTime() const { return mFocusTimer.getElapsedTimeF32(); } |
65 | F32 getFocusFlashAmt(); | 63 | F32 getFocusFlashAmt(); |
66 | LLColor4 getFocusColor(); | 64 | LLColor4 getFocusColor(); |
@@ -90,15 +88,14 @@ public: | |||
90 | 88 | ||
91 | protected: | 89 | protected: |
92 | LLUICtrl* mLockedView; | 90 | LLUICtrl* mLockedView; |
93 | FocusLostCallback mKeyboardLockedFocusLostCallback; | ||
94 | 91 | ||
95 | // Mouse Captor | 92 | // Mouse Captor |
96 | LLMouseHandler* mMouseCaptor; // Mouse events are premptively routed to this object | 93 | LLMouseHandler* mMouseCaptor; // Mouse events are premptively routed to this object |
97 | 94 | ||
98 | // Keyboard Focus | 95 | // Keyboard Focus |
99 | LLUICtrl* mKeyboardFocus; // Keyboard events are preemptively routed to this object | 96 | LLUICtrl* mKeyboardFocus; // Keyboard events are preemptively routed to this object |
97 | LLUICtrl* mLastKeyboardFocus; // who last had focus | ||
100 | LLUICtrl* mDefaultKeyboardFocus; | 98 | LLUICtrl* mDefaultKeyboardFocus; |
101 | FocusLostCallback mKeyboardFocusLostCallback; // The object to which keyboard events are routed is called before another object takes its place | ||
102 | 99 | ||
103 | // Top View | 100 | // Top View |
104 | LLUICtrl* mTopCtrl; | 101 | LLUICtrl* mTopCtrl; |
diff --git a/linden/indra/llui/llhtmlhelp.h b/linden/indra/llui/llhtmlhelp.h index 36324d0..d4ec9e3 100644 --- a/linden/indra/llui/llhtmlhelp.h +++ b/linden/indra/llui/llhtmlhelp.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -37,7 +37,6 @@ class LLHtmlHelp | |||
37 | public: | 37 | public: |
38 | virtual ~LLHtmlHelp() {} | 38 | virtual ~LLHtmlHelp() {} |
39 | virtual void show(std::string start_url, std::string title) = 0; | 39 | virtual void show(std::string start_url, std::string title) = 0; |
40 | virtual BOOL getFloaterOpened()=0; | ||
41 | }; | 40 | }; |
42 | 41 | ||
43 | #endif // LL_LLFLOATERHTMLHELP_H | 42 | #endif // LL_LLFLOATERHTMLHELP_H |
diff --git a/linden/indra/llui/lliconctrl.cpp b/linden/indra/llui/lliconctrl.cpp index 40272ee..79982c6 100644 --- a/linden/indra/llui/lliconctrl.cpp +++ b/linden/indra/llui/lliconctrl.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -88,18 +88,11 @@ void LLIconCtrl::draw() | |||
88 | { | 88 | { |
89 | if( getVisible() ) | 89 | if( getVisible() ) |
90 | { | 90 | { |
91 | // Border | 91 | if( mImagep.notNull() ) |
92 | BOOL has_image = !mImageID.isNull(); | ||
93 | |||
94 | if( has_image ) | ||
95 | { | 92 | { |
96 | if( mImagep.notNull() ) | 93 | mImagep->draw(0, 0, |
97 | { | 94 | mRect.getWidth(), mRect.getHeight(), |
98 | gl_draw_scaled_image(0, 0, | 95 | mColor ); |
99 | mRect.getWidth(), mRect.getHeight(), | ||
100 | mImagep, | ||
101 | mColor ); | ||
102 | } | ||
103 | } | 96 | } |
104 | 97 | ||
105 | LLUICtrl::draw(); | 98 | LLUICtrl::draw(); |
@@ -154,6 +147,7 @@ LLView* LLIconCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory * | |||
154 | LLUICtrlFactory::getAttributeColor(node,"color", color); | 147 | LLUICtrlFactory::getAttributeColor(node,"color", color); |
155 | 148 | ||
156 | LLIconCtrl* icon = new LLIconCtrl(name, rect, image_id); | 149 | LLIconCtrl* icon = new LLIconCtrl(name, rect, image_id); |
150 | |||
157 | icon->setColor(color); | 151 | icon->setColor(color); |
158 | 152 | ||
159 | icon->initFromXML(node, parent); | 153 | icon->initFromXML(node, parent); |
diff --git a/linden/indra/llui/lliconctrl.h b/linden/indra/llui/lliconctrl.h index 0cd43bb..f767b3c 100644 --- a/linden/indra/llui/lliconctrl.h +++ b/linden/indra/llui/lliconctrl.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -73,7 +73,7 @@ protected: | |||
73 | LLColor4 mColor; | 73 | LLColor4 mColor; |
74 | LLString mImageName; | 74 | LLString mImageName; |
75 | LLUUID mImageID; | 75 | LLUUID mImageID; |
76 | LLPointer<LLImageGL> mImagep; | 76 | LLPointer<LLUIImage> mImagep; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | #endif | 79 | #endif |
diff --git a/linden/indra/llui/llkeywords.cpp b/linden/indra/llui/llkeywords.cpp index 3adde76..1d157d2 100644 --- a/linden/indra/llui/llkeywords.cpp +++ b/linden/indra/llui/llkeywords.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -233,7 +233,7 @@ LLColor3 LLKeywords::readColor( const LLString& s ) | |||
233 | 233 | ||
234 | // Walk through a string, applying the rules specified by the keyword token list and | 234 | // Walk through a string, applying the rules specified by the keyword token list and |
235 | // create a list of color segments. | 235 | // create a list of color segments. |
236 | void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWString& wtext) | 236 | void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor) |
237 | { | 237 | { |
238 | std::for_each(seg_list->begin(), seg_list->end(), DeletePointer()); | 238 | std::for_each(seg_list->begin(), seg_list->end(), DeletePointer()); |
239 | seg_list->clear(); | 239 | seg_list->clear(); |
@@ -245,7 +245,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS | |||
245 | 245 | ||
246 | S32 text_len = wtext.size(); | 246 | S32 text_len = wtext.size(); |
247 | 247 | ||
248 | seg_list->push_back( new LLTextSegment( LLColor3(0,0,0), 0, text_len ) ); | 248 | seg_list->push_back( new LLTextSegment( LLColor3(defaultColor), 0, text_len ) ); |
249 | 249 | ||
250 | const llwchar* base = wtext.c_str(); | 250 | const llwchar* base = wtext.c_str(); |
251 | const llwchar* cur = base; | 251 | const llwchar* cur = base; |
@@ -299,7 +299,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS | |||
299 | //llinfos << "Seg: [" << (char*)LLString( base, seg_start, seg_end-seg_start) << "]" << llendl; | 299 | //llinfos << "Seg: [" << (char*)LLString( base, seg_start, seg_end-seg_start) << "]" << llendl; |
300 | LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end ); | 300 | LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end ); |
301 | text_segment->setToken( cur_token ); | 301 | text_segment->setToken( cur_token ); |
302 | insertSegment( seg_list, text_segment, text_len); | 302 | insertSegment( seg_list, text_segment, text_len, defaultColor); |
303 | line_done = TRUE; // to break out of second loop. | 303 | line_done = TRUE; // to break out of second loop. |
304 | break; | 304 | break; |
305 | } | 305 | } |
@@ -409,7 +409,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS | |||
409 | //llinfos << "Seg: [" << (char*)LLString( base, seg_start, seg_end-seg_start ) << "]" << llendl; | 409 | //llinfos << "Seg: [" << (char*)LLString( base, seg_start, seg_end-seg_start ) << "]" << llendl; |
410 | LLTextSegment* text_segment = new LLTextSegment( cur_delimiter->getColor(), seg_start, seg_end ); | 410 | LLTextSegment* text_segment = new LLTextSegment( cur_delimiter->getColor(), seg_start, seg_end ); |
411 | text_segment->setToken( cur_delimiter ); | 411 | text_segment->setToken( cur_delimiter ); |
412 | insertSegment( seg_list, text_segment, text_len); | 412 | insertSegment( seg_list, text_segment, text_len, defaultColor); |
413 | 413 | ||
414 | // Note: we don't increment cur, since the end of one delimited seg may be immediately | 414 | // Note: we don't increment cur, since the end of one delimited seg may be immediately |
415 | // followed by the start of another one. | 415 | // followed by the start of another one. |
@@ -442,7 +442,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS | |||
442 | 442 | ||
443 | LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end ); | 443 | LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end ); |
444 | text_segment->setToken( cur_token ); | 444 | text_segment->setToken( cur_token ); |
445 | insertSegment( seg_list, text_segment, text_len); | 445 | insertSegment( seg_list, text_segment, text_len, defaultColor); |
446 | } | 446 | } |
447 | cur += seg_len; | 447 | cur += seg_len; |
448 | continue; | 448 | continue; |
@@ -457,7 +457,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS | |||
457 | } | 457 | } |
458 | } | 458 | } |
459 | 459 | ||
460 | void LLKeywords::insertSegment(std::vector<LLTextSegment*>* seg_list, LLTextSegment* new_segment, S32 text_len ) | 460 | void LLKeywords::insertSegment(std::vector<LLTextSegment*>* seg_list, LLTextSegment* new_segment, S32 text_len, const LLColor4 &defaultColor ) |
461 | { | 461 | { |
462 | LLTextSegment* last = seg_list->back(); | 462 | LLTextSegment* last = seg_list->back(); |
463 | S32 new_seg_end = new_segment->getEnd(); | 463 | S32 new_seg_end = new_segment->getEnd(); |
@@ -475,7 +475,7 @@ void LLKeywords::insertSegment(std::vector<LLTextSegment*>* seg_list, LLTextSegm | |||
475 | 475 | ||
476 | if( new_seg_end < text_len ) | 476 | if( new_seg_end < text_len ) |
477 | { | 477 | { |
478 | seg_list->push_back( new LLTextSegment( LLColor3(0,0,0), new_seg_end, text_len ) ); | 478 | seg_list->push_back( new LLTextSegment( defaultColor, new_seg_end, text_len ) ); |
479 | } | 479 | } |
480 | } | 480 | } |
481 | 481 | ||
diff --git a/linden/indra/llui/llkeywords.h b/linden/indra/llui/llkeywords.h index e6ff029..d5d7302 100644 --- a/linden/indra/llui/llkeywords.h +++ b/linden/indra/llui/llkeywords.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -84,7 +84,7 @@ public: | |||
84 | BOOL loadFromFile(const LLString& filename); | 84 | BOOL loadFromFile(const LLString& filename); |
85 | BOOL isLoaded() { return mLoaded; } | 85 | BOOL isLoaded() { return mLoaded; } |
86 | 86 | ||
87 | void findSegments(std::vector<LLTextSegment *> *seg_list, const LLWString& text ); | 87 | void findSegments(std::vector<LLTextSegment *> *seg_list, const LLWString& text, const LLColor4 &defaultColor ); |
88 | 88 | ||
89 | #ifdef _DEBUG | 89 | #ifdef _DEBUG |
90 | void dump(); | 90 | void dump(); |
@@ -98,7 +98,7 @@ public: | |||
98 | 98 | ||
99 | private: | 99 | private: |
100 | LLColor3 readColor(const LLString& s); | 100 | LLColor3 readColor(const LLString& s); |
101 | void insertSegment(std::vector<LLTextSegment *> *seg_list, LLTextSegment* new_segment, S32 text_len); | 101 | void insertSegment(std::vector<LLTextSegment *> *seg_list, LLTextSegment* new_segment, S32 text_len, const LLColor4 &defaultColor); |
102 | 102 | ||
103 | private: | 103 | private: |
104 | BOOL mLoaded; | 104 | BOOL mLoaded; |
diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index 2851beb..88c8d75 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -72,6 +72,15 @@ const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing | |||
72 | const F32 AUTO_SCROLL_TIME = 0.05f; | 72 | const F32 AUTO_SCROLL_TIME = 0.05f; |
73 | const F32 LABEL_HPAD = 5.f; | 73 | const F32 LABEL_HPAD = 5.f; |
74 | 74 | ||
75 | const F32 PREEDIT_MARKER_BRIGHTNESS = 0.4f; | ||
76 | const S32 PREEDIT_MARKER_GAP = 1; | ||
77 | const S32 PREEDIT_MARKER_POSITION = 2; | ||
78 | const S32 PREEDIT_MARKER_THICKNESS = 1; | ||
79 | const F32 PREEDIT_STANDOUT_BRIGHTNESS = 0.6f; | ||
80 | const S32 PREEDIT_STANDOUT_GAP = 1; | ||
81 | const S32 PREEDIT_STANDOUT_POSITION = 2; | ||
82 | const S32 PREEDIT_STANDOUT_THICKNESS = 2; | ||
83 | |||
75 | // This is a friend class of and is only used by LLLineEditor | 84 | // This is a friend class of and is only used by LLLineEditor |
76 | class LLLineEditorRollback | 85 | class LLLineEditorRollback |
77 | { | 86 | { |
@@ -119,7 +128,7 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect, | |||
119 | S32 max_length_bytes, | 128 | S32 max_length_bytes, |
120 | void (*commit_callback)(LLUICtrl* caller, void* user_data ), | 129 | void (*commit_callback)(LLUICtrl* caller, void* user_data ), |
121 | void (*keystroke_callback)(LLLineEditor* caller, void* user_data ), | 130 | void (*keystroke_callback)(LLLineEditor* caller, void* user_data ), |
122 | void (*focus_lost_callback)(LLUICtrl* caller, void* user_data ), | 131 | void (*focus_lost_callback)(LLFocusableElement* caller, void* user_data ), |
123 | void* userdata, | 132 | void* userdata, |
124 | LLLinePrevalidateFunc prevalidate_func, | 133 | LLLinePrevalidateFunc prevalidate_func, |
125 | LLViewBorder::EBevel border_bevel, | 134 | LLViewBorder::EBevel border_bevel, |
@@ -127,7 +136,6 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect, | |||
127 | S32 border_thickness) | 136 | S32 border_thickness) |
128 | : | 137 | : |
129 | LLUICtrl( name, rect, TRUE, commit_callback, userdata, FOLLOWS_TOP | FOLLOWS_LEFT ), | 138 | LLUICtrl( name, rect, TRUE, commit_callback, userdata, FOLLOWS_TOP | FOLLOWS_LEFT ), |
130 | mMaxLengthChars(max_length_bytes), | ||
131 | mMaxLengthBytes(max_length_bytes), | 139 | mMaxLengthBytes(max_length_bytes), |
132 | mCursorPos( 0 ), | 140 | mCursorPos( 0 ), |
133 | mScrollHPos( 0 ), | 141 | mScrollHPos( 0 ), |
@@ -223,12 +231,19 @@ LLString LLLineEditor::getWidgetTag() const | |||
223 | return LL_LINE_EDITOR_TAG; | 231 | return LL_LINE_EDITOR_TAG; |
224 | } | 232 | } |
225 | 233 | ||
226 | void LLLineEditor::onFocusLost() | 234 | void LLLineEditor::onFocusReceived() |
227 | { | 235 | { |
228 | // Need to notify early when loosing focus. | 236 | LLUICtrl::onFocusReceived(); |
229 | getWindow()->allowLanguageTextInput(FALSE); | 237 | updateAllowingLanguageInput(); |
238 | } | ||
230 | 239 | ||
231 | LLUICtrl::onFocusLost(); | 240 | void LLLineEditor::onFocusLost() |
241 | { | ||
242 | // The call to updateAllowLanguageInput() | ||
243 | // when loosing the keyboard focus *may* | ||
244 | // indirectly invoke handleUnicodeCharHere(), | ||
245 | // so it must be called before onCommit. | ||
246 | updateAllowingLanguageInput(); | ||
232 | 247 | ||
233 | if( mCommitOnFocusLost && mText.getString() != mPrevText) | 248 | if( mCommitOnFocusLost && mText.getString() != mPrevText) |
234 | { | 249 | { |
@@ -241,6 +256,8 @@ void LLLineEditor::onFocusLost() | |||
241 | } | 256 | } |
242 | 257 | ||
243 | getWindow()->showCursorFromMouseMove(); | 258 | getWindow()->showCursorFromMouseMove(); |
259 | |||
260 | LLUICtrl::onFocusLost(); | ||
244 | } | 261 | } |
245 | 262 | ||
246 | void LLLineEditor::onCommit() | 263 | void LLLineEditor::onCommit() |
@@ -301,6 +318,7 @@ void LLLineEditor::setEnabled(BOOL enabled) | |||
301 | { | 318 | { |
302 | mReadOnly = !enabled; | 319 | mReadOnly = !enabled; |
303 | setTabStop(!mReadOnly); | 320 | setTabStop(!mReadOnly); |
321 | updateAllowingLanguageInput(); | ||
304 | } | 322 | } |
305 | 323 | ||
306 | 324 | ||
@@ -308,7 +326,6 @@ void LLLineEditor::setMaxTextLength(S32 max_text_length) | |||
308 | { | 326 | { |
309 | S32 max_len = llmax(0, max_text_length); | 327 | S32 max_len = llmax(0, max_text_length); |
310 | mMaxLengthBytes = max_len; | 328 | mMaxLengthBytes = max_len; |
311 | mMaxLengthChars = max_len; | ||
312 | } | 329 | } |
313 | 330 | ||
314 | void LLLineEditor::setBorderWidth(S32 left, S32 right) | 331 | void LLLineEditor::setBorderWidth(S32 left, S32 right) |
@@ -334,18 +351,22 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) | |||
334 | 351 | ||
335 | // Check to see if entire field is selected. | 352 | // Check to see if entire field is selected. |
336 | S32 len = mText.length(); | 353 | S32 len = mText.length(); |
337 | BOOL allSelected = (len > 0) && (( mSelectionStart == 0 && mSelectionEnd == len ) | 354 | BOOL all_selected = (len > 0) |
338 | || ( mSelectionStart == len && mSelectionEnd == 0 )); | 355 | && (( mSelectionStart == 0 && mSelectionEnd == len ) |
356 | || ( mSelectionStart == len && mSelectionEnd == 0 )); | ||
357 | |||
358 | // Do safe truncation so we don't split multi-byte characters | ||
359 | // also consider entire string selected when mSelectAllonFocusReceived is set on an empty, focused line editor | ||
360 | all_selected = all_selected || (len == 0 && hasFocus() && mSelectAllonFocusReceived); | ||
339 | 361 | ||
340 | LLString truncated_utf8 = new_text; | 362 | LLString truncated_utf8 = new_text; |
341 | if (truncated_utf8.size() > (U32)mMaxLengthBytes) | 363 | if (truncated_utf8.size() > (U32)mMaxLengthBytes) |
342 | { | 364 | { |
343 | utf8str_truncate(truncated_utf8, mMaxLengthBytes); | 365 | truncated_utf8 = utf8str_truncate(new_text, mMaxLengthBytes); |
344 | } | 366 | } |
345 | mText.assign(truncated_utf8); | 367 | mText.assign(truncated_utf8); |
346 | mText.truncate(mMaxLengthChars); | ||
347 | 368 | ||
348 | if (allSelected) | 369 | if (all_selected) |
349 | { | 370 | { |
350 | // ...keep whole thing selected | 371 | // ...keep whole thing selected |
351 | selectAll(); | 372 | selectAll(); |
@@ -735,17 +756,12 @@ void LLLineEditor::addChar(const llwchar uni_char) | |||
735 | mText.erase(getCursor(), 1); | 756 | mText.erase(getCursor(), 1); |
736 | } | 757 | } |
737 | 758 | ||
738 | S32 length_chars = mText.length(); | 759 | S32 cur_bytes = mText.getString().size(); |
739 | S32 cur_bytes = mText.getString().size();; | ||
740 | S32 new_bytes = wchar_utf8_length(new_c); | 760 | S32 new_bytes = wchar_utf8_length(new_c); |
741 | 761 | ||
742 | BOOL allow_char = TRUE; | 762 | BOOL allow_char = TRUE; |
743 | 763 | ||
744 | // Inserting character | 764 | // Check byte length limit |
745 | if (length_chars == mMaxLengthChars) | ||
746 | { | ||
747 | allow_char = FALSE; | ||
748 | } | ||
749 | if ((new_bytes + cur_bytes) > mMaxLengthBytes) | 765 | if ((new_bytes + cur_bytes) > mMaxLengthBytes) |
750 | { | 766 | { |
751 | allow_char = FALSE; | 767 | allow_char = FALSE; |
@@ -794,6 +810,12 @@ void LLLineEditor::setSelection(S32 start, S32 end) | |||
794 | setCursor(start); | 810 | setCursor(start); |
795 | } | 811 | } |
796 | 812 | ||
813 | void LLLineEditor::setDrawAsterixes(BOOL b) | ||
814 | { | ||
815 | mDrawAsterixes = b; | ||
816 | updateAllowingLanguageInput(); | ||
817 | } | ||
818 | |||
797 | S32 LLLineEditor::prevWordPos(S32 cursorPos) const | 819 | S32 LLLineEditor::prevWordPos(S32 cursorPos) const |
798 | { | 820 | { |
799 | const LLWString& wtext = mText.getWString(); | 821 | const LLWString& wtext = mText.getWString(); |
@@ -1022,13 +1044,11 @@ void LLLineEditor::paste() | |||
1022 | 1044 | ||
1023 | // Insert the string | 1045 | // Insert the string |
1024 | 1046 | ||
1025 | //check to see that the size isn't going to be larger than the | 1047 | // Check to see that the size isn't going to be larger than the max number of bytes |
1026 | //max number of characters or bytes | ||
1027 | U32 available_bytes = mMaxLengthBytes - wstring_utf8_length(mText); | 1048 | U32 available_bytes = mMaxLengthBytes - wstring_utf8_length(mText); |
1028 | size_t available_chars = mMaxLengthChars - mText.length(); | ||
1029 | 1049 | ||
1030 | if ( available_bytes < (U32) wstring_utf8_length(clean_string) ) | 1050 | if ( available_bytes < (U32) wstring_utf8_length(clean_string) ) |
1031 | { | 1051 | { // Doesn't all fit |
1032 | llwchar current_symbol = clean_string[0]; | 1052 | llwchar current_symbol = clean_string[0]; |
1033 | U32 wchars_that_fit = 0; | 1053 | U32 wchars_that_fit = 0; |
1034 | U32 total_bytes = wchar_utf8_length(current_symbol); | 1054 | U32 total_bytes = wchar_utf8_length(current_symbol); |
@@ -1043,20 +1063,13 @@ void LLLineEditor::paste() | |||
1043 | current_symbol = clean_string[++wchars_that_fit]; | 1063 | current_symbol = clean_string[++wchars_that_fit]; |
1044 | total_bytes += wchar_utf8_length(current_symbol); | 1064 | total_bytes += wchar_utf8_length(current_symbol); |
1045 | } | 1065 | } |
1046 | 1066 | // Truncate the clean string at the limit of what will fit | |
1047 | clean_string = clean_string.substr(0, wchars_that_fit); | 1067 | clean_string = clean_string.substr(0, wchars_that_fit); |
1048 | reportBadKeystroke(); | 1068 | reportBadKeystroke(); |
1049 | } | 1069 | } |
1050 | else if (available_chars < clean_string.length()) | ||
1051 | { | ||
1052 | // We can't insert all the characters. Insert as many as possible | ||
1053 | // but make a noise to alert the user. JC | ||
1054 | clean_string = clean_string.substr(0, available_chars); | ||
1055 | reportBadKeystroke(); | ||
1056 | } | ||
1057 | 1070 | ||
1058 | mText.insert(getCursor(), clean_string); | 1071 | mText.insert(getCursor(), clean_string); |
1059 | setCursor(llmin(mMaxLengthChars, getCursor() + (S32)clean_string.length())); | 1072 | setCursor( getCursor() + (S32)clean_string.length() ); |
1060 | deselect(); | 1073 | deselect(); |
1061 | 1074 | ||
1062 | // Validate new string and rollback the if needed. | 1075 | // Validate new string and rollback the if needed. |
@@ -1523,6 +1536,41 @@ void LLLineEditor::draw() | |||
1523 | } | 1536 | } |
1524 | LLColor4 label_color = mTentativeFgColor; | 1537 | LLColor4 label_color = mTentativeFgColor; |
1525 | 1538 | ||
1539 | if (hasPreeditString()) | ||
1540 | { | ||
1541 | // Draw preedit markers. This needs to be before drawing letters. | ||
1542 | for (U32 i = 0; i < mPreeditStandouts.size(); i++) | ||
1543 | { | ||
1544 | const S32 preedit_left = mPreeditPositions[i]; | ||
1545 | const S32 preedit_right = mPreeditPositions[i + 1]; | ||
1546 | if (preedit_right > mScrollHPos) | ||
1547 | { | ||
1548 | S32 preedit_pixels_left = findPixelNearestPos(llmax(preedit_left, mScrollHPos) - getCursor()); | ||
1549 | S32 preedit_pixels_right = llmin(findPixelNearestPos(preedit_right - getCursor()), background.mRight); | ||
1550 | if (preedit_pixels_left >= background.mRight) | ||
1551 | { | ||
1552 | break; | ||
1553 | } | ||
1554 | if (mPreeditStandouts[i]) | ||
1555 | { | ||
1556 | gl_rect_2d(preedit_pixels_left + PREEDIT_STANDOUT_GAP, | ||
1557 | background.mBottom + PREEDIT_STANDOUT_POSITION, | ||
1558 | preedit_pixels_right - PREEDIT_STANDOUT_GAP - 1, | ||
1559 | background.mBottom + PREEDIT_STANDOUT_POSITION - PREEDIT_STANDOUT_THICKNESS, | ||
1560 | (text_color * PREEDIT_STANDOUT_BRIGHTNESS + bg_color * (1 - PREEDIT_STANDOUT_BRIGHTNESS)).setAlpha(1.0f)); | ||
1561 | } | ||
1562 | else | ||
1563 | { | ||
1564 | gl_rect_2d(preedit_pixels_left + PREEDIT_MARKER_GAP, | ||
1565 | background.mBottom + PREEDIT_MARKER_POSITION, | ||
1566 | preedit_pixels_right - PREEDIT_MARKER_GAP - 1, | ||
1567 | background.mBottom + PREEDIT_MARKER_POSITION - PREEDIT_MARKER_THICKNESS, | ||
1568 | (text_color * PREEDIT_MARKER_BRIGHTNESS + bg_color * (1 - PREEDIT_MARKER_BRIGHTNESS)).setAlpha(1.0f)); | ||
1569 | } | ||
1570 | } | ||
1571 | } | ||
1572 | } | ||
1573 | |||
1526 | S32 rendered_text = 0; | 1574 | S32 rendered_text = 0; |
1527 | F32 rendered_pixels_right = (F32)mMinHPixels; | 1575 | F32 rendered_pixels_right = (F32)mMinHPixels; |
1528 | F32 text_bottom = (F32)background.mBottom + (F32)UI_LINEEDITOR_V_PAD; | 1576 | F32 text_bottom = (F32)background.mBottom + (F32)UI_LINEEDITOR_V_PAD; |
@@ -1677,7 +1725,7 @@ void LLLineEditor::draw() | |||
1677 | 1725 | ||
1678 | 1726 | ||
1679 | // Returns the local screen space X coordinate associated with the text cursor position. | 1727 | // Returns the local screen space X coordinate associated with the text cursor position. |
1680 | S32 LLLineEditor::findPixelNearestPos(const S32 cursor_offset) | 1728 | S32 LLLineEditor::findPixelNearestPos(const S32 cursor_offset) const |
1681 | { | 1729 | { |
1682 | S32 dpos = getCursor() - mScrollHPos + cursor_offset; | 1730 | S32 dpos = getCursor() - mScrollHPos + cursor_offset; |
1683 | S32 result = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos, dpos) + mMinHPixels; | 1731 | S32 result = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos, dpos) + mMinHPixels; |
@@ -1715,7 +1763,7 @@ void LLLineEditor::setFocus( BOOL new_state ) | |||
1715 | 1763 | ||
1716 | if (!new_state) | 1764 | if (!new_state) |
1717 | { | 1765 | { |
1718 | getWindow()->allowLanguageTextInput(FALSE); | 1766 | getWindow()->allowLanguageTextInput(this, FALSE); |
1719 | } | 1767 | } |
1720 | 1768 | ||
1721 | 1769 | ||
@@ -1757,7 +1805,7 @@ void LLLineEditor::setFocus( BOOL new_state ) | |||
1757 | // fine on 1.15.0.2, since all prevalidate func reject any | 1805 | // fine on 1.15.0.2, since all prevalidate func reject any |
1758 | // non-ASCII characters. I'm not sure on future versions, | 1806 | // non-ASCII characters. I'm not sure on future versions, |
1759 | // however. | 1807 | // however. |
1760 | getWindow()->allowLanguageTextInput(mPrevalidateFunc == NULL); | 1808 | getWindow()->allowLanguageTextInput(this, mPrevalidateFunc == NULL); |
1761 | } | 1809 | } |
1762 | } | 1810 | } |
1763 | 1811 | ||
@@ -1776,6 +1824,12 @@ void LLLineEditor::setRect(const LLRect& rect) | |||
1776 | } | 1824 | } |
1777 | } | 1825 | } |
1778 | 1826 | ||
1827 | void LLLineEditor::setPrevalidate(BOOL (*func)(const LLWString &)) | ||
1828 | { | ||
1829 | mPrevalidateFunc = func; | ||
1830 | updateAllowingLanguageInput(); | ||
1831 | } | ||
1832 | |||
1779 | // Limits what characters can be used to [1234567890.-] with [-] only valid in the first position. | 1833 | // Limits what characters can be used to [1234567890.-] with [-] only valid in the first position. |
1780 | // Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for | 1834 | // Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for |
1781 | // the simple reasons that intermediate states may be invalid even if the final result is valid. | 1835 | // the simple reasons that intermediate states may be invalid even if the final result is valid. |
@@ -2336,6 +2390,239 @@ BOOL LLLineEditor::setLabelArg( const LLString& key, const LLStringExplicit& tex | |||
2336 | return TRUE; | 2390 | return TRUE; |
2337 | } | 2391 | } |
2338 | 2392 | ||
2393 | |||
2394 | void LLLineEditor::updateAllowingLanguageInput() | ||
2395 | { | ||
2396 | // Allow Language Text Input only when this LineEditor has | ||
2397 | // no prevalidate function attached (as long as other criteria | ||
2398 | // common to LLTextEditor). This criterion works | ||
2399 | // fine on 1.15.0.2, since all prevalidate func reject any | ||
2400 | // non-ASCII characters. I'm not sure on future versions, | ||
2401 | // however... | ||
2402 | if (hasFocus() && !mReadOnly && !mDrawAsterixes && mPrevalidateFunc == NULL) | ||
2403 | { | ||
2404 | getWindow()->allowLanguageTextInput(this, TRUE); | ||
2405 | } | ||
2406 | else | ||
2407 | { | ||
2408 | getWindow()->allowLanguageTextInput(this, FALSE); | ||
2409 | } | ||
2410 | } | ||
2411 | |||
2412 | BOOL LLLineEditor::hasPreeditString() const | ||
2413 | { | ||
2414 | return (mPreeditPositions.size() > 1); | ||
2415 | } | ||
2416 | |||
2417 | void LLLineEditor::resetPreedit() | ||
2418 | { | ||
2419 | if (hasPreeditString()) | ||
2420 | { | ||
2421 | const S32 preedit_pos = mPreeditPositions.front(); | ||
2422 | mText.erase(preedit_pos, mPreeditPositions.back() - preedit_pos); | ||
2423 | mText.insert(preedit_pos, mPreeditOverwrittenWString); | ||
2424 | setCursor(preedit_pos); | ||
2425 | |||
2426 | mPreeditWString.clear(); | ||
2427 | mPreeditOverwrittenWString.clear(); | ||
2428 | mPreeditPositions.clear(); | ||
2429 | |||
2430 | mKeystrokeTimer.reset(); | ||
2431 | if (mKeystrokeCallback) | ||
2432 | { | ||
2433 | mKeystrokeCallback(this, mCallbackUserData); | ||
2434 | } | ||
2435 | } | ||
2436 | } | ||
2437 | |||
2438 | void LLLineEditor::updatePreedit(const LLWString &preedit_string, | ||
2439 | const segment_lengths_t &preedit_segment_lengths, const standouts_t &preedit_standouts, S32 caret_position) | ||
2440 | { | ||
2441 | // Just in case. | ||
2442 | if (mReadOnly) | ||
2443 | { | ||
2444 | return; | ||
2445 | } | ||
2446 | |||
2447 | if (hasSelection()) | ||
2448 | { | ||
2449 | if (hasPreeditString()) | ||
2450 | { | ||
2451 | llwarns << "Preedit and selection!" << llendl; | ||
2452 | deselect(); | ||
2453 | } | ||
2454 | else | ||
2455 | { | ||
2456 | deleteSelection(); | ||
2457 | } | ||
2458 | } | ||
2459 | |||
2460 | S32 insert_preedit_at = getCursor(); | ||
2461 | if (hasPreeditString()) | ||
2462 | { | ||
2463 | insert_preedit_at = mPreeditPositions.front(); | ||
2464 | //mText.replace(insert_preedit_at, mPreeditPositions.back() - insert_preedit_at, mPreeditOverwrittenWString); | ||
2465 | mText.erase(insert_preedit_at, mPreeditPositions.back() - insert_preedit_at); | ||
2466 | mText.insert(insert_preedit_at, mPreeditOverwrittenWString); | ||
2467 | } | ||
2468 | |||
2469 | mPreeditWString = preedit_string; | ||
2470 | mPreeditPositions.resize(preedit_segment_lengths.size() + 1); | ||
2471 | S32 position = insert_preedit_at; | ||
2472 | for (segment_lengths_t::size_type i = 0; i < preedit_segment_lengths.size(); i++) | ||
2473 | { | ||
2474 | mPreeditPositions[i] = position; | ||
2475 | position += preedit_segment_lengths[i]; | ||
2476 | } | ||
2477 | mPreeditPositions.back() = position; | ||
2478 | if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) | ||
2479 | { | ||
2480 | mPreeditOverwrittenWString.assign( LLWString( mText, insert_preedit_at, mPreeditWString.length() ) ); | ||
2481 | mText.erase(insert_preedit_at, mPreeditWString.length()); | ||
2482 | } | ||
2483 | else | ||
2484 | { | ||
2485 | mPreeditOverwrittenWString.clear(); | ||
2486 | } | ||
2487 | mText.insert(insert_preedit_at, mPreeditWString); | ||
2488 | |||
2489 | mPreeditStandouts = preedit_standouts; | ||
2490 | |||
2491 | setCursor(position); | ||
2492 | setCursor(mPreeditPositions.front() + caret_position); | ||
2493 | |||
2494 | // Update of the preedit should be caused by some key strokes. | ||
2495 | mKeystrokeTimer.reset(); | ||
2496 | if( mKeystrokeCallback ) | ||
2497 | { | ||
2498 | mKeystrokeCallback( this, mCallbackUserData ); | ||
2499 | } | ||
2500 | } | ||
2501 | |||
2502 | BOOL LLLineEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const | ||
2503 | { | ||
2504 | if (control) | ||
2505 | { | ||
2506 | LLRect control_rect_screen; | ||
2507 | localRectToScreen(mRect, &control_rect_screen); | ||
2508 | LLUI::screenRectToGL(control_rect_screen, control); | ||
2509 | } | ||
2510 | |||
2511 | S32 preedit_left_column, preedit_right_column; | ||
2512 | if (hasPreeditString()) | ||
2513 | { | ||
2514 | preedit_left_column = mPreeditPositions.front(); | ||
2515 | preedit_right_column = mPreeditPositions.back(); | ||
2516 | } | ||
2517 | else | ||
2518 | { | ||
2519 | preedit_left_column = preedit_right_column = getCursor(); | ||
2520 | } | ||
2521 | if (preedit_right_column < mScrollHPos) | ||
2522 | { | ||
2523 | // This should not occure... | ||
2524 | return FALSE; | ||
2525 | } | ||
2526 | |||
2527 | const S32 query = (query_offset >= 0 ? preedit_left_column + query_offset : getCursor()); | ||
2528 | if (query < mScrollHPos || query < preedit_left_column || query > preedit_right_column) | ||
2529 | { | ||
2530 | return FALSE; | ||
2531 | } | ||
2532 | |||
2533 | if (coord) | ||
2534 | { | ||
2535 | S32 query_local = findPixelNearestPos(query - getCursor()); | ||
2536 | S32 query_screen_x, query_screen_y; | ||
2537 | localPointToScreen(query_local, mRect.getHeight() / 2, &query_screen_x, &query_screen_y); | ||
2538 | LLUI::screenPointToGL(query_screen_x, query_screen_y, &coord->mX, &coord->mY); | ||
2539 | } | ||
2540 | |||
2541 | if (bounds) | ||
2542 | { | ||
2543 | S32 preedit_left_local = findPixelNearestPos(llmax(preedit_left_column, mScrollHPos) - getCursor()); | ||
2544 | S32 preedit_right_local = llmin(findPixelNearestPos(preedit_right_column - getCursor()), mRect.getWidth() - mBorderThickness); | ||
2545 | if (preedit_left_local > preedit_right_local) | ||
2546 | { | ||
2547 | // Is this condition possible? | ||
2548 | preedit_right_local = preedit_left_local; | ||
2549 | } | ||
2550 | |||
2551 | LLRect preedit_rect_local(preedit_left_local, mRect.getHeight(), preedit_right_local, 0); | ||
2552 | LLRect preedit_rect_screen; | ||
2553 | localRectToScreen(preedit_rect_local, &preedit_rect_screen); | ||
2554 | LLUI::screenRectToGL(preedit_rect_screen, bounds); | ||
2555 | } | ||
2556 | |||
2557 | return TRUE; | ||
2558 | } | ||
2559 | |||
2560 | void LLLineEditor::getPreeditRange(S32 *position, S32 *length) const | ||
2561 | { | ||
2562 | if (hasPreeditString()) | ||
2563 | { | ||
2564 | *position = mPreeditPositions.front(); | ||
2565 | *length = mPreeditPositions.back() - mPreeditPositions.front(); | ||
2566 | } | ||
2567 | else | ||
2568 | { | ||
2569 | *position = mCursorPos; | ||
2570 | *length = 0; | ||
2571 | } | ||
2572 | } | ||
2573 | |||
2574 | void LLLineEditor::getSelectionRange(S32 *position, S32 *length) const | ||
2575 | { | ||
2576 | if (hasSelection()) | ||
2577 | { | ||
2578 | *position = llmin(mSelectionStart, mSelectionEnd); | ||
2579 | *length = llabs(mSelectionStart - mSelectionEnd); | ||
2580 | } | ||
2581 | else | ||
2582 | { | ||
2583 | *position = mCursorPos; | ||
2584 | *length = 0; | ||
2585 | } | ||
2586 | } | ||
2587 | |||
2588 | void LLLineEditor::markAsPreedit(S32 position, S32 length) | ||
2589 | { | ||
2590 | deselect(); | ||
2591 | setCursor(position); | ||
2592 | if (hasPreeditString()) | ||
2593 | { | ||
2594 | llwarns << "markAsPreedit invoked when hasPreeditString is true." << llendl; | ||
2595 | } | ||
2596 | mPreeditWString.assign( LLWString( mText.getWString(), position, length ) ); | ||
2597 | if (length > 0) | ||
2598 | { | ||
2599 | mPreeditPositions.resize(2); | ||
2600 | mPreeditPositions[0] = position; | ||
2601 | mPreeditPositions[1] = position + length; | ||
2602 | mPreeditStandouts.resize(1); | ||
2603 | mPreeditStandouts[0] = FALSE; | ||
2604 | } | ||
2605 | else | ||
2606 | { | ||
2607 | mPreeditPositions.clear(); | ||
2608 | mPreeditStandouts.clear(); | ||
2609 | } | ||
2610 | if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) | ||
2611 | { | ||
2612 | mPreeditOverwrittenWString = mPreeditWString; | ||
2613 | } | ||
2614 | else | ||
2615 | { | ||
2616 | mPreeditOverwrittenWString.clear(); | ||
2617 | } | ||
2618 | } | ||
2619 | |||
2620 | S32 LLLineEditor::getPreeditFontSize() const | ||
2621 | { | ||
2622 | return llround(mGLFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]); | ||
2623 | } | ||
2624 | |||
2625 | |||
2339 | LLSearchEditor::LLSearchEditor(const LLString& name, | 2626 | LLSearchEditor::LLSearchEditor(const LLString& name, |
2340 | const LLRect& rect, | 2627 | const LLRect& rect, |
2341 | S32 max_length_bytes, | 2628 | S32 max_length_bytes, |
diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h index d4ebe3c..6d328e5 100644 --- a/linden/indra/llui/lllineeditor.h +++ b/linden/indra/llui/lllineeditor.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -53,6 +53,8 @@ | |||
53 | #include "lluistring.h" | 53 | #include "lluistring.h" |
54 | #include "llviewborder.h" | 54 | #include "llviewborder.h" |
55 | 55 | ||
56 | #include "llpreeditor.h" | ||
57 | |||
56 | class LLFontGL; | 58 | class LLFontGL; |
57 | class LLLineEditorRollback; | 59 | class LLLineEditorRollback; |
58 | class LLButton; | 60 | class LLButton; |
@@ -63,7 +65,7 @@ typedef BOOL (*LLLinePrevalidateFunc)(const LLWString &wstr); | |||
63 | // Classes | 65 | // Classes |
64 | // | 66 | // |
65 | class LLLineEditor | 67 | class LLLineEditor |
66 | : public LLUICtrl, public LLEditMenuHandler | 68 | : public LLUICtrl, public LLEditMenuHandler, protected LLPreeditor |
67 | { | 69 | { |
68 | friend class LLLineEditorRollback; | 70 | friend class LLLineEditorRollback; |
69 | 71 | ||
@@ -75,7 +77,7 @@ public: | |||
75 | S32 max_length_bytes = 254, | 77 | S32 max_length_bytes = 254, |
76 | void (*commit_callback)(LLUICtrl* caller, void* user_data) = NULL, | 78 | void (*commit_callback)(LLUICtrl* caller, void* user_data) = NULL, |
77 | void (*keystroke_callback)(LLLineEditor* caller, void* user_data) = NULL, | 79 | void (*keystroke_callback)(LLLineEditor* caller, void* user_data) = NULL, |
78 | void (*focus_lost_callback)(LLUICtrl* caller, void* user_data) = NULL, | 80 | void (*focus_lost_callback)(LLFocusableElement* caller, void* user_data) = NULL, |
79 | void* userdata = NULL, | 81 | void* userdata = NULL, |
80 | LLLinePrevalidateFunc prevalidate_func = NULL, | 82 | LLLinePrevalidateFunc prevalidate_func = NULL, |
81 | LLViewBorder::EBevel border_bevel = LLViewBorder::BEVEL_IN, | 83 | LLViewBorder::EBevel border_bevel = LLViewBorder::BEVEL_IN, |
@@ -120,6 +122,7 @@ public: | |||
120 | // view overrides | 122 | // view overrides |
121 | virtual void draw(); | 123 | virtual void draw(); |
122 | virtual void reshape(S32 width,S32 height,BOOL called_from_parent=TRUE); | 124 | virtual void reshape(S32 width,S32 height,BOOL called_from_parent=TRUE); |
125 | virtual void onFocusReceived(); | ||
123 | virtual void onFocusLost(); | 126 | virtual void onFocusLost(); |
124 | virtual void setEnabled(BOOL enabled); | 127 | virtual void setEnabled(BOOL enabled); |
125 | 128 | ||
@@ -146,7 +149,7 @@ public: | |||
146 | const LLWString& getWText() const { return mText.getWString(); } | 149 | const LLWString& getWText() const { return mText.getWString(); } |
147 | S32 getLength() const { return mText.length(); } | 150 | S32 getLength() const { return mText.length(); } |
148 | 151 | ||
149 | S32 getCursor() { return mCursorPos; } | 152 | S32 getCursor() const { return mCursorPos; } |
150 | void setCursor( S32 pos ); | 153 | void setCursor( S32 pos ); |
151 | void setCursorToEnd(); | 154 | void setCursorToEnd(); |
152 | 155 | ||
@@ -177,13 +180,13 @@ public: | |||
177 | void setIgnoreTab(BOOL b) { mIgnoreTab = b; } | 180 | void setIgnoreTab(BOOL b) { mIgnoreTab = b; } |
178 | void setPassDelete(BOOL b) { mPassDelete = b; } | 181 | void setPassDelete(BOOL b) { mPassDelete = b; } |
179 | 182 | ||
180 | void setDrawAsterixes(BOOL b) { mDrawAsterixes = b; } | 183 | void setDrawAsterixes(BOOL b); |
181 | 184 | ||
182 | // get the cursor position of the beginning/end of the prev/next word in the text | 185 | // get the cursor position of the beginning/end of the prev/next word in the text |
183 | S32 prevWordPos(S32 cursorPos) const; | 186 | S32 prevWordPos(S32 cursorPos) const; |
184 | S32 nextWordPos(S32 cursorPos) const; | 187 | S32 nextWordPos(S32 cursorPos) const; |
185 | 188 | ||
186 | BOOL hasSelection() { return (mSelectionStart != mSelectionEnd); } | 189 | BOOL hasSelection() const { return (mSelectionStart != mSelectionEnd); } |
187 | void startSelection(); | 190 | void startSelection(); |
188 | void endSelection(); | 191 | void endSelection(); |
189 | void extendSelection(S32 new_cursor_pos); | 192 | void extendSelection(S32 new_cursor_pos); |
@@ -199,7 +202,7 @@ public: | |||
199 | 202 | ||
200 | static BOOL isPartOfWord(llwchar c); | 203 | static BOOL isPartOfWord(llwchar c); |
201 | // Prevalidation controls which keystrokes can affect the editor | 204 | // Prevalidation controls which keystrokes can affect the editor |
202 | void setPrevalidate( BOOL (*func)(const LLWString &) ) { mPrevalidateFunc = func; } | 205 | void setPrevalidate( BOOL (*func)(const LLWString &) ); |
203 | static BOOL prevalidateFloat(const LLWString &str ); | 206 | static BOOL prevalidateFloat(const LLWString &str ); |
204 | static BOOL prevalidateInt(const LLWString &str ); | 207 | static BOOL prevalidateInt(const LLWString &str ); |
205 | static BOOL prevalidatePositiveS32(const LLWString &str); | 208 | static BOOL prevalidatePositiveS32(const LLWString &str); |
@@ -221,7 +224,7 @@ protected: | |||
221 | void addChar(const llwchar c); | 224 | void addChar(const llwchar c); |
222 | void setCursorAtLocalPos(S32 local_mouse_x); | 225 | void setCursorAtLocalPos(S32 local_mouse_x); |
223 | 226 | ||
224 | S32 findPixelNearestPos(S32 cursor_offset = 0); | 227 | S32 findPixelNearestPos(S32 cursor_offset = 0) const; |
225 | void reportBadKeystroke(); | 228 | void reportBadKeystroke(); |
226 | 229 | ||
227 | BOOL handleSpecialKey(KEY key, MASK mask); | 230 | BOOL handleSpecialKey(KEY key, MASK mask); |
@@ -230,6 +233,19 @@ protected: | |||
230 | S32 handleCommitKey(KEY key, MASK mask); | 233 | S32 handleCommitKey(KEY key, MASK mask); |
231 | 234 | ||
232 | protected: | 235 | protected: |
236 | void updateAllowingLanguageInput(); | ||
237 | BOOL hasPreeditString() const; | ||
238 | // Implementation (overrides) of LLPreeditor | ||
239 | virtual void resetPreedit(); | ||
240 | virtual void updatePreedit(const LLWString &preedit_string, | ||
241 | const segment_lengths_t &preedit_segment_lengths, const standouts_t &preedit_standouts, S32 caret_position); | ||
242 | virtual void markAsPreedit(S32 position, S32 length); | ||
243 | virtual void getPreeditRange(S32 *position, S32 *length) const; | ||
244 | virtual void getSelectionRange(S32 *position, S32 *length) const; | ||
245 | virtual BOOL getPreeditLocation(S32 query_position, LLCoordGL *coord, LLRect *bounds, LLRect *control) const; | ||
246 | virtual S32 getPreeditFontSize() const; | ||
247 | |||
248 | protected: | ||
233 | LLUIString mText; // The string being edited. | 249 | LLUIString mText; // The string being edited. |
234 | LLString mPrevText; // Saved string for 'ESC' revert | 250 | LLString mPrevText; // Saved string for 'ESC' revert |
235 | LLUIString mLabel; // text label that is visible when no user text provided | 251 | LLUIString mLabel; // text label that is visible when no user text provided |
@@ -241,8 +257,7 @@ protected: | |||
241 | 257 | ||
242 | LLViewBorder* mBorder; | 258 | LLViewBorder* mBorder; |
243 | const LLFontGL* mGLFont; | 259 | const LLFontGL* mGLFont; |
244 | S32 mMaxLengthChars; // Max number of characters | 260 | S32 mMaxLengthBytes; // Max length of the UTF8 string in bytes |
245 | S32 mMaxLengthBytes; // Max length of the UTF8 string. | ||
246 | S32 mCursorPos; // I-beam is just after the mCursorPos-th character. | 261 | S32 mCursorPos; // I-beam is just after the mCursorPos-th character. |
247 | S32 mScrollHPos; // Horizontal offset from the start of mText. Used for scrolling. | 262 | S32 mScrollHPos; // Horizontal offset from the start of mText. Used for scrolling. |
248 | LLFrameTimer mScrollTimer; | 263 | LLFrameTimer mScrollTimer; |
@@ -288,6 +303,11 @@ protected: | |||
288 | BOOL mPassDelete; | 303 | BOOL mPassDelete; |
289 | 304 | ||
290 | BOOL mReadOnly; | 305 | BOOL mReadOnly; |
306 | |||
307 | LLWString mPreeditWString; | ||
308 | LLWString mPreeditOverwrittenWString; | ||
309 | std::vector<S32> mPreeditPositions; | ||
310 | LLPreeditor::standouts_t mPreeditStandouts; | ||
291 | }; | 311 | }; |
292 | 312 | ||
293 | 313 | ||
diff --git a/linden/indra/llui/llmemberlistener.h b/linden/indra/llui/llmemberlistener.h index b4ee2f1..02aff17 100644 --- a/linden/indra/llui/llmemberlistener.h +++ b/linden/indra/llui/llmemberlistener.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llmenugl.cpp b/linden/indra/llui/llmenugl.cpp index 4afa6b9..a56b090 100644 --- a/linden/indra/llui/llmenugl.cpp +++ b/linden/indra/llui/llmenugl.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -632,7 +632,7 @@ public: | |||
632 | }; | 632 | }; |
633 | 633 | ||
634 | LLMenuItemSeparatorGL::LLMenuItemSeparatorGL( const LLString &name ) : | 634 | LLMenuItemSeparatorGL::LLMenuItemSeparatorGL( const LLString &name ) : |
635 | LLMenuItemGL( SEPARATOR_NAME, SEPARATOR_LABEL ) | 635 | LLMenuItemGL( name, SEPARATOR_LABEL ) |
636 | { | 636 | { |
637 | } | 637 | } |
638 | 638 | ||
@@ -2832,7 +2832,7 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa | |||
2832 | while(1) | 2832 | while(1) |
2833 | { | 2833 | { |
2834 | // skip separators and disabled items | 2834 | // skip separators and disabled items |
2835 | if ((*next_item_iter)->getEnabled() && (*next_item_iter)->getName() != SEPARATOR_NAME) | 2835 | if ((*next_item_iter)->getEnabled() && (*next_item_iter)->getType() != SEPARATOR_NAME) |
2836 | { | 2836 | { |
2837 | if (cur_item) | 2837 | if (cur_item) |
2838 | { | 2838 | { |
@@ -4514,7 +4514,7 @@ BOOL LLMenuHolderGL::hideMenus() | |||
4514 | } | 4514 | } |
4515 | //if (gFocusMgr.childHasKeyboardFocus(this)) | 4515 | //if (gFocusMgr.childHasKeyboardFocus(this)) |
4516 | //{ | 4516 | //{ |
4517 | // gFocusMgr.setKeyboardFocus(NULL, NULL); | 4517 | // gFocusMgr.setKeyboardFocus(NULL); |
4518 | //} | 4518 | //} |
4519 | 4519 | ||
4520 | return menu_visible; | 4520 | return menu_visible; |
@@ -4599,6 +4599,7 @@ void LLTearOffMenu::onFocusReceived() | |||
4599 | break; | 4599 | break; |
4600 | } | 4600 | } |
4601 | } | 4601 | } |
4602 | LLFloater::onFocusReceived(); | ||
4602 | } | 4603 | } |
4603 | 4604 | ||
4604 | void LLTearOffMenu::onFocusLost() | 4605 | void LLTearOffMenu::onFocusLost() |
diff --git a/linden/indra/llui/llmenugl.h b/linden/indra/llui/llmenugl.h index 21594f6..9274101 100644 --- a/linden/indra/llui/llmenugl.h +++ b/linden/indra/llui/llmenugl.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llmodaldialog.cpp b/linden/indra/llui/llmodaldialog.cpp index 72a7fcb..ff4858f 100644 --- a/linden/indra/llui/llmodaldialog.cpp +++ b/linden/indra/llui/llmodaldialog.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -70,6 +70,16 @@ LLModalDialog::~LLModalDialog() | |||
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | // virtual | ||
74 | void LLModalDialog::open() /* Flawfinder: ignore */ | ||
75 | { | ||
76 | // SJB: Hack! Make sure we don't ever host a modal dialog | ||
77 | LLMultiFloater* thost = LLFloater::sHostp; | ||
78 | LLFloater::sHostp = NULL; | ||
79 | LLFloater::open(); | ||
80 | LLFloater::sHostp = thost; | ||
81 | } | ||
82 | |||
73 | void LLModalDialog::reshape(S32 width, S32 height, BOOL called_from_parent) | 83 | void LLModalDialog::reshape(S32 width, S32 height, BOOL called_from_parent) |
74 | { | 84 | { |
75 | LLFloater::reshape(width, height, called_from_parent); | 85 | LLFloater::reshape(width, height, called_from_parent); |
@@ -287,7 +297,7 @@ void LLModalDialog::onAppFocusLost() | |||
287 | 297 | ||
288 | if( gFocusMgr.childHasKeyboardFocus( instance ) ) | 298 | if( gFocusMgr.childHasKeyboardFocus( instance ) ) |
289 | { | 299 | { |
290 | gFocusMgr.setKeyboardFocus( NULL, NULL ); | 300 | gFocusMgr.setKeyboardFocus( NULL ); |
291 | } | 301 | } |
292 | } | 302 | } |
293 | } | 303 | } |
diff --git a/linden/indra/llui/llmodaldialog.h b/linden/indra/llui/llmodaldialog.h index 1529ac3..342a0f6 100644 --- a/linden/indra/llui/llmodaldialog.h +++ b/linden/indra/llui/llmodaldialog.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -47,6 +47,8 @@ public: | |||
47 | LLModalDialog( const LLString& title, S32 width, S32 height, BOOL modal = true ); | 47 | LLModalDialog( const LLString& title, S32 width, S32 height, BOOL modal = true ); |
48 | /*virtual*/ ~LLModalDialog(); | 48 | /*virtual*/ ~LLModalDialog(); |
49 | 49 | ||
50 | /*virtual*/ void open(); /* Flawfinder: ignore */ | ||
51 | |||
50 | /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = 1); | 52 | /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = 1); |
51 | 53 | ||
52 | /*virtual*/ void startModal(); | 54 | /*virtual*/ void startModal(); |
diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp index 2c37dfd..af8aa21 100644 --- a/linden/indra/llui/llpanel.cpp +++ b/linden/indra/llui/llpanel.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -64,7 +64,6 @@ LLPanel::panel_map_t LLPanel::sPanelMap; | |||
64 | LLPanel::alert_queue_t LLPanel::sAlertQueue; | 64 | LLPanel::alert_queue_t LLPanel::sAlertQueue; |
65 | 65 | ||
66 | const S32 RESIZE_BAR_OVERLAP = 1; | 66 | const S32 RESIZE_BAR_OVERLAP = 1; |
67 | const S32 PANEL_STACK_GAP = RESIZE_BAR_HEIGHT; | ||
68 | 67 | ||
69 | void LLPanel::init() | 68 | void LLPanel::init() |
70 | { | 69 | { |
@@ -88,6 +87,7 @@ LLPanel::LLPanel() | |||
88 | : mRectControl() | 87 | : mRectControl() |
89 | { | 88 | { |
90 | init(); | 89 | init(); |
90 | setName("panel"); | ||
91 | } | 91 | } |
92 | 92 | ||
93 | LLPanel::LLPanel(const LLString& name) | 93 | LLPanel::LLPanel(const LLString& name) |
@@ -124,6 +124,7 @@ LLPanel::LLPanel(const LLString& name, const LLString& rect_control, BOOL border | |||
124 | void LLPanel::addBorder(LLViewBorder::EBevel border_bevel, | 124 | void LLPanel::addBorder(LLViewBorder::EBevel border_bevel, |
125 | LLViewBorder::EStyle border_style, S32 border_thickness) | 125 | LLViewBorder::EStyle border_style, S32 border_thickness) |
126 | { | 126 | { |
127 | removeBorder(); | ||
127 | mBorder = new LLViewBorder( "panel border", | 128 | mBorder = new LLViewBorder( "panel border", |
128 | LLRect(0, mRect.getHeight(), mRect.getWidth(), 0), | 129 | LLRect(0, mRect.getHeight(), mRect.getWidth(), 0), |
129 | border_bevel, border_style, border_thickness ); | 130 | border_bevel, border_style, border_thickness ); |
@@ -339,11 +340,6 @@ void LLPanel::addCtrl( LLUICtrl* ctrl, S32 tab_group) | |||
339 | mLastTabGroup = tab_group; | 340 | mLastTabGroup = tab_group; |
340 | 341 | ||
341 | LLView::addCtrl(ctrl, tab_group); | 342 | LLView::addCtrl(ctrl, tab_group); |
342 | // propagate chrome to children only if they have not been flagged as chrome | ||
343 | if (!ctrl->getIsChrome()) | ||
344 | { | ||
345 | ctrl->setIsChrome(getIsChrome()); | ||
346 | } | ||
347 | } | 343 | } |
348 | 344 | ||
349 | void LLPanel::addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group) | 345 | void LLPanel::addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group) |
@@ -351,22 +347,12 @@ void LLPanel::addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group) | |||
351 | mLastTabGroup = tab_group; | 347 | mLastTabGroup = tab_group; |
352 | 348 | ||
353 | LLView::addCtrlAtEnd(ctrl, tab_group); | 349 | LLView::addCtrlAtEnd(ctrl, tab_group); |
354 | if (!ctrl->getIsChrome()) | ||
355 | { | ||
356 | ctrl->setIsChrome(getIsChrome()); | ||
357 | } | ||
358 | } | 350 | } |
359 | 351 | ||
360 | BOOL LLPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) | 352 | BOOL LLPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) |
361 | { | 353 | { |
362 | BOOL handled = FALSE; | 354 | BOOL handled = FALSE; |
363 | 355 | ||
364 | if( getVisible() && getEnabled() && gFocusMgr.childHasKeyboardFocus(this) && KEY_ESCAPE == key ) | ||
365 | { | ||
366 | gFocusMgr.setKeyboardFocus(NULL, NULL); | ||
367 | return TRUE; | ||
368 | } | ||
369 | |||
370 | if( getVisible() && getEnabled() && | 356 | if( getVisible() && getEnabled() && |
371 | gFocusMgr.childHasKeyboardFocus(this) && !called_from_parent ) | 357 | gFocusMgr.childHasKeyboardFocus(this) && !called_from_parent ) |
372 | { | 358 | { |
@@ -472,7 +458,7 @@ void LLPanel::setFocus(BOOL b) | |||
472 | { | 458 | { |
473 | if( this == gFocusMgr.getKeyboardFocus() ) | 459 | if( this == gFocusMgr.getKeyboardFocus() ) |
474 | { | 460 | { |
475 | gFocusMgr.setKeyboardFocus( NULL, NULL ); | 461 | gFocusMgr.setKeyboardFocus( NULL ); |
476 | } | 462 | } |
477 | else | 463 | else |
478 | { | 464 | { |
@@ -595,7 +581,8 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory *fac | |||
595 | { | 581 | { |
596 | LLRect rect; | 582 | LLRect rect; |
597 | createRect(node, rect, parent, LLRect()); | 583 | createRect(node, rect, parent, LLRect()); |
598 | panelp = new LLPanel(name, rect); | 584 | // create a new panel without a border, by default |
585 | panelp = new LLPanel(name, rect, FALSE); | ||
599 | panelp->initPanelXML(node, parent, factory); | 586 | panelp->initPanelXML(node, parent, factory); |
600 | // preserve panel's width and height, but override the location | 587 | // preserve panel's width and height, but override the location |
601 | const LLRect& panelrect = panelp->getRect(); | 588 | const LLRect& panelrect = panelp->getRect(); |
@@ -608,12 +595,13 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory *fac | |||
608 | { | 595 | { |
609 | panelp->initPanelXML(node, parent, factory); | 596 | panelp->initPanelXML(node, parent, factory); |
610 | } | 597 | } |
598 | |||
611 | return panelp; | 599 | return panelp; |
612 | } | 600 | } |
613 | 601 | ||
614 | BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) | 602 | BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) |
615 | { | 603 | { |
616 | LLString name("panel"); | 604 | LLString name = getName(); |
617 | node->getAttributeString("name", name); | 605 | node->getAttributeString("name", name); |
618 | setName(name); | 606 | setName(name); |
619 | 607 | ||
@@ -628,13 +616,15 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f | |||
628 | 616 | ||
629 | if (!xml_filename.empty()) | 617 | if (!xml_filename.empty()) |
630 | { | 618 | { |
631 | // Preserve postion of embedded panel but allow panel to dictate width/height | ||
632 | LLRect rect(getRect()); | ||
633 | didPost = factory->buildPanel(this, xml_filename, NULL); | 619 | didPost = factory->buildPanel(this, xml_filename, NULL); |
634 | S32 w = getRect().getWidth(); | 620 | |
635 | S32 h = getRect().getHeight(); | 621 | LLRect new_rect = getRect(); |
636 | rect.setLeftTopAndSize(rect.mLeft, rect.mTop, w, h); | 622 | // override rectangle with embedding parameters as provided |
637 | setRect(rect); | 623 | createRect(node, new_rect, parent); |
624 | setOrigin(new_rect.mLeft, new_rect.mBottom); | ||
625 | reshape(new_rect.getWidth(), new_rect.getHeight()); | ||
626 | // optionally override follows flags from including nodes | ||
627 | parseFollowsFlags(node); | ||
638 | } | 628 | } |
639 | else | 629 | else |
640 | { | 630 | { |
@@ -678,7 +668,7 @@ void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parent) | |||
678 | initFromXML(node, parent); | 668 | initFromXML(node, parent); |
679 | 669 | ||
680 | /////// Border attributes /////// | 670 | /////// Border attributes /////// |
681 | BOOL border = FALSE; | 671 | BOOL border = mBorder != NULL; |
682 | node->getAttributeBOOL("border", border); | 672 | node->getAttributeBOOL("border", border); |
683 | if (border) | 673 | if (border) |
684 | { | 674 | { |
@@ -706,24 +696,24 @@ void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parent) | |||
706 | } | 696 | } |
707 | 697 | ||
708 | /////// Background attributes /////// | 698 | /////// Background attributes /////// |
709 | BOOL background_visible = FALSE; | 699 | BOOL background_visible = mBgVisible; |
710 | node->getAttributeBOOL("background_visible", background_visible); | 700 | node->getAttributeBOOL("background_visible", background_visible); |
711 | setBackgroundVisible(background_visible); | 701 | setBackgroundVisible(background_visible); |
712 | 702 | ||
713 | BOOL background_opaque = FALSE; | 703 | BOOL background_opaque = mBgOpaque; |
714 | node->getAttributeBOOL("background_opaque", background_opaque); | 704 | node->getAttributeBOOL("background_opaque", background_opaque); |
715 | setBackgroundOpaque(background_opaque); | 705 | setBackgroundOpaque(background_opaque); |
716 | 706 | ||
717 | LLColor4 color; | 707 | LLColor4 color; |
718 | color = LLUI::sColorsGroup->getColor( "FocusBackgroundColor" ); | 708 | color = mBgColorOpaque; |
719 | LLUICtrlFactory::getAttributeColor(node,"bg_opaque_color", color); | 709 | LLUICtrlFactory::getAttributeColor(node,"bg_opaque_color", color); |
720 | setBackgroundColor(color); | 710 | setBackgroundColor(color); |
721 | 711 | ||
722 | color = LLUI::sColorsGroup->getColor( "DefaultBackgroundColor" ); | 712 | color = mBgColorAlpha; |
723 | LLUICtrlFactory::getAttributeColor(node,"bg_alpha_color", color); | 713 | LLUICtrlFactory::getAttributeColor(node,"bg_alpha_color", color); |
724 | setTransparentColor(color); | 714 | setTransparentColor(color); |
725 | 715 | ||
726 | LLString label; | 716 | LLString label = getLabel(); |
727 | node->getAttributeString("label", label); | 717 | node->getAttributeString("label", label); |
728 | setLabel(label); | 718 | setLabel(label); |
729 | } | 719 | } |
@@ -853,12 +843,12 @@ BOOL LLPanel::childHasFocus(const LLString& id) | |||
853 | } | 843 | } |
854 | 844 | ||
855 | 845 | ||
856 | void LLPanel::childSetFocusChangedCallback(const LLString& id, void (*cb)(LLUICtrl*, void*)) | 846 | void LLPanel::childSetFocusChangedCallback(const LLString& id, void (*cb)(LLFocusableElement*, void*), void* user_data) |
857 | { | 847 | { |
858 | LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); | 848 | LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); |
859 | if (child) | 849 | if (child) |
860 | { | 850 | { |
861 | child->setFocusChangedCallback(cb); | 851 | child->setFocusChangedCallback(cb, user_data); |
862 | } | 852 | } |
863 | } | 853 | } |
864 | 854 | ||
@@ -1165,11 +1155,12 @@ void LLPanel::storeRectControl() | |||
1165 | // | 1155 | // |
1166 | struct LLLayoutStack::LLEmbeddedPanel | 1156 | struct LLLayoutStack::LLEmbeddedPanel |
1167 | { | 1157 | { |
1168 | LLEmbeddedPanel(LLPanel* panelp, eLayoutOrientation orientation, S32 min_width, S32 min_height, BOOL auto_resize) : | 1158 | LLEmbeddedPanel(LLPanel* panelp, eLayoutOrientation orientation, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize) : |
1169 | mPanel(panelp), | 1159 | mPanel(panelp), |
1170 | mMinWidth(min_width), | 1160 | mMinWidth(min_width), |
1171 | mMinHeight(min_height), | 1161 | mMinHeight(min_height), |
1172 | mAutoResize(auto_resize), | 1162 | mAutoResize(auto_resize), |
1163 | mUserResize(user_resize), | ||
1173 | mOrientation(orientation), | 1164 | mOrientation(orientation), |
1174 | mVisibleAmt(1.f) // default to fully visible | 1165 | mVisibleAmt(1.f) // default to fully visible |
1175 | { | 1166 | { |
@@ -1194,10 +1185,18 @@ struct LLLayoutStack::LLEmbeddedPanel | |||
1194 | } | 1185 | } |
1195 | } | 1186 | } |
1196 | 1187 | ||
1188 | ~LLEmbeddedPanel() | ||
1189 | { | ||
1190 | // probably not necessary, but... | ||
1191 | delete mResizeBar; | ||
1192 | mResizeBar = NULL; | ||
1193 | } | ||
1194 | |||
1197 | LLPanel* mPanel; | 1195 | LLPanel* mPanel; |
1198 | S32 mMinWidth; | 1196 | S32 mMinWidth; |
1199 | S32 mMinHeight; | 1197 | S32 mMinHeight; |
1200 | BOOL mAutoResize; | 1198 | BOOL mAutoResize; |
1199 | BOOL mUserResize; | ||
1201 | LLResizeBar* mResizeBar; | 1200 | LLResizeBar* mResizeBar; |
1202 | eLayoutOrientation mOrientation; | 1201 | eLayoutOrientation mOrientation; |
1203 | F32 mVisibleAmt; | 1202 | F32 mVisibleAmt; |
@@ -1206,36 +1205,40 @@ struct LLLayoutStack::LLEmbeddedPanel | |||
1206 | LLLayoutStack::LLLayoutStack(eLayoutOrientation orientation) : | 1205 | LLLayoutStack::LLLayoutStack(eLayoutOrientation orientation) : |
1207 | mOrientation(orientation), | 1206 | mOrientation(orientation), |
1208 | mMinWidth(0), | 1207 | mMinWidth(0), |
1209 | mMinHeight(0) | 1208 | mMinHeight(0), |
1209 | mPanelSpacing(RESIZE_BAR_HEIGHT) | ||
1210 | { | 1210 | { |
1211 | } | 1211 | } |
1212 | 1212 | ||
1213 | LLLayoutStack::~LLLayoutStack() | 1213 | LLLayoutStack::~LLLayoutStack() |
1214 | { | 1214 | { |
1215 | std::for_each(mPanels.begin(), mPanels.end(), DeletePointer()); | ||
1215 | } | 1216 | } |
1216 | 1217 | ||
1217 | void LLLayoutStack::draw() | 1218 | void LLLayoutStack::draw() |
1218 | { | 1219 | { |
1219 | updateLayout(); | 1220 | updateLayout(); |
1220 | { | 1221 | { |
1221 | // clip if outside nominal bounds | ||
1222 | LLLocalClipRect clip(getLocalRect(), mRect.getWidth() > mMinWidth || mRect.getHeight() > mMinHeight); | ||
1223 | e_panel_list_t::iterator panel_it; | 1222 | e_panel_list_t::iterator panel_it; |
1224 | for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) | 1223 | for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) |
1225 | { | 1224 | { |
1225 | // clip to layout rectangle, not bounding rectangle | ||
1226 | LLRect clip_rect = (*panel_it)->mPanel->getRect(); | 1226 | LLRect clip_rect = (*panel_it)->mPanel->getRect(); |
1227 | // scale clipping rectangle by visible amount | 1227 | // scale clipping rectangle by visible amount |
1228 | if (mOrientation == HORIZONTAL) | 1228 | if (mOrientation == HORIZONTAL) |
1229 | { | 1229 | { |
1230 | clip_rect.mRight = clip_rect.mLeft + llround(clip_rect.getWidth() * (*panel_it)->mVisibleAmt); | 1230 | clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->mVisibleAmt); |
1231 | } | 1231 | } |
1232 | else | 1232 | else |
1233 | { | 1233 | { |
1234 | clip_rect.mBottom = clip_rect.mTop - llround(clip_rect.getHeight() * (*panel_it)->mVisibleAmt); | 1234 | clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->mVisibleAmt); |
1235 | } | 1235 | } |
1236 | LLLocalClipRect clip(clip_rect, (*panel_it)->mVisibleAmt < 1.f); | 1236 | |
1237 | LLPanel* panelp = (*panel_it)->mPanel; | ||
1238 | |||
1239 | LLLocalClipRect clip(clip_rect); | ||
1237 | // only force drawing invisible children if visible amount is non-zero | 1240 | // only force drawing invisible children if visible amount is non-zero |
1238 | drawChild((*panel_it)->mPanel, 0, 0, (*panel_it)->mVisibleAmt > 0.f); | 1241 | drawChild(panelp, 0, 0, !clip_rect.isNull()); |
1239 | } | 1242 | } |
1240 | } | 1243 | } |
1241 | } | 1244 | } |
@@ -1250,17 +1253,13 @@ void LLLayoutStack::removeCtrl(LLUICtrl* ctrl) | |||
1250 | delete embedded_panelp; | 1253 | delete embedded_panelp; |
1251 | } | 1254 | } |
1252 | 1255 | ||
1256 | // need to update resizebars | ||
1257 | |||
1253 | calcMinExtents(); | 1258 | calcMinExtents(); |
1254 | 1259 | ||
1255 | LLView::removeCtrl(ctrl); | 1260 | LLView::removeCtrl(ctrl); |
1256 | } | 1261 | } |
1257 | 1262 | ||
1258 | void LLLayoutStack::reshape(S32 width, S32 height, BOOL called_from_parent) | ||
1259 | { | ||
1260 | LLView::reshape(width, height, called_from_parent); | ||
1261 | //updateLayout(); | ||
1262 | } | ||
1263 | |||
1264 | LLXMLNodePtr LLLayoutStack::getXML(bool save_children) const | 1263 | LLXMLNodePtr LLLayoutStack::getXML(bool save_children) const |
1265 | { | 1264 | { |
1266 | LLXMLNodePtr node = LLView::getXML(); | 1265 | LLXMLNodePtr node = LLView::getXML(); |
@@ -1290,6 +1289,14 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor | |||
1290 | 1289 | ||
1291 | LLLayoutStack* layout_stackp = new LLLayoutStack(orientation); | 1290 | LLLayoutStack* layout_stackp = new LLLayoutStack(orientation); |
1292 | 1291 | ||
1292 | node->getAttributeS32("border_size", layout_stackp->mPanelSpacing); | ||
1293 | // don't allow negative spacing values | ||
1294 | layout_stackp->mPanelSpacing = llmax(layout_stackp->mPanelSpacing, 0); | ||
1295 | |||
1296 | LLString name("stack"); | ||
1297 | node->getAttributeString("name", name); | ||
1298 | |||
1299 | layout_stackp->setName(name); | ||
1293 | layout_stackp->initFromXML(node, parent); | 1300 | layout_stackp->initFromXML(node, parent); |
1294 | 1301 | ||
1295 | LLXMLNodePtr child; | 1302 | LLXMLNodePtr child; |
@@ -1300,16 +1307,18 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor | |||
1300 | S32 min_width = 0; | 1307 | S32 min_width = 0; |
1301 | S32 min_height = 0; | 1308 | S32 min_height = 0; |
1302 | BOOL auto_resize = TRUE; | 1309 | BOOL auto_resize = TRUE; |
1310 | BOOL user_resize = TRUE; | ||
1303 | 1311 | ||
1304 | child->getAttributeS32("min_width", min_width); | 1312 | child->getAttributeS32("min_width", min_width); |
1305 | child->getAttributeS32("min_height", min_height); | 1313 | child->getAttributeS32("min_height", min_height); |
1306 | child->getAttributeBOOL("auto_resize", auto_resize); | 1314 | child->getAttributeBOOL("auto_resize", auto_resize); |
1315 | child->getAttributeBOOL("user_resize", user_resize); | ||
1307 | 1316 | ||
1308 | LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child, layout_stackp, factory); | 1317 | LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child, layout_stackp, factory); |
1309 | if (panelp) | 1318 | if (panelp) |
1310 | { | 1319 | { |
1311 | panelp->setFollowsNone(); | 1320 | panelp->setFollowsNone(); |
1312 | layout_stackp->addPanel(panelp, min_width, min_height, auto_resize); | 1321 | layout_stackp->addPanel(panelp, min_width, min_height, auto_resize, user_resize); |
1313 | } | 1322 | } |
1314 | } | 1323 | } |
1315 | } | 1324 | } |
@@ -1327,11 +1336,36 @@ S32 LLLayoutStack::getMinHeight() | |||
1327 | return mMinHeight; | 1336 | return mMinHeight; |
1328 | } | 1337 | } |
1329 | 1338 | ||
1330 | void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, S32 index) | 1339 | S32 LLLayoutStack::getDefaultHeight(S32 cur_height) |
1340 | { | ||
1341 | // if we are spanning our children (crude upward propagation of size) | ||
1342 | // then don't enforce our size on our children | ||
1343 | if (mOrientation == HORIZONTAL) | ||
1344 | { | ||
1345 | cur_height = llmax(mMinHeight, mRect.getHeight()); | ||
1346 | } | ||
1347 | |||
1348 | return cur_height; | ||
1349 | } | ||
1350 | |||
1351 | S32 LLLayoutStack::getDefaultWidth(S32 cur_width) | ||
1331 | { | 1352 | { |
1332 | LLEmbeddedPanel* embedded_panel = new LLEmbeddedPanel(panel, mOrientation, min_width, min_height, auto_resize); | 1353 | // if we are spanning our children (crude upward propagation of size) |
1354 | // then don't enforce our size on our children | ||
1355 | if (mOrientation == VERTICAL) | ||
1356 | { | ||
1357 | cur_width = llmax(mMinWidth, mRect.getWidth()); | ||
1358 | } | ||
1359 | |||
1360 | return cur_width; | ||
1361 | } | ||
1362 | |||
1363 | void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, S32 index) | ||
1364 | { | ||
1365 | LLEmbeddedPanel* embedded_panel = new LLEmbeddedPanel(panel, mOrientation, min_width, min_height, auto_resize, user_resize); | ||
1333 | 1366 | ||
1334 | mPanels.insert(mPanels.begin() + llclamp(index, 0, (S32)mPanels.size()), embedded_panel); | 1367 | mPanels.insert(mPanels.begin() + llclamp(index, 0, (S32)mPanels.size()), embedded_panel); |
1368 | |||
1335 | addChild(panel); | 1369 | addChild(panel); |
1336 | addChild(embedded_panel->mResizeBar); | 1370 | addChild(embedded_panel->mResizeBar); |
1337 | 1371 | ||
@@ -1339,29 +1373,15 @@ void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL | |||
1339 | // with a bit of overlap | 1373 | // with a bit of overlap |
1340 | for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) | 1374 | for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) |
1341 | { | 1375 | { |
1342 | e_panel_list_t::iterator next_it = panel_it; | ||
1343 | ++next_it; | ||
1344 | |||
1345 | LLResizeBar* resize_barp = (*panel_it)->mResizeBar; | 1376 | LLResizeBar* resize_barp = (*panel_it)->mResizeBar; |
1346 | sendChildToFront(resize_barp); | 1377 | sendChildToFront(resize_barp); |
1347 | // last resize bar is disabled, since its not between any two panels | ||
1348 | if ( next_it == mPanels.end() ) | ||
1349 | { | ||
1350 | resize_barp->setEnabled(FALSE); | ||
1351 | } | ||
1352 | else | ||
1353 | { | ||
1354 | resize_barp->setEnabled(TRUE); | ||
1355 | } | ||
1356 | } | 1378 | } |
1357 | 1379 | ||
1358 | //updateLayout(); | ||
1359 | } | 1380 | } |
1360 | 1381 | ||
1361 | void LLLayoutStack::removePanel(LLPanel* panel) | 1382 | void LLLayoutStack::removePanel(LLPanel* panel) |
1362 | { | 1383 | { |
1363 | removeChild(panel); | 1384 | removeChild(panel); |
1364 | //updateLayout(); | ||
1365 | } | 1385 | } |
1366 | 1386 | ||
1367 | void LLLayoutStack::updateLayout(BOOL force_resize) | 1387 | void LLLayoutStack::updateLayout(BOOL force_resize) |
@@ -1369,11 +1389,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1369 | calcMinExtents(); | 1389 | calcMinExtents(); |
1370 | 1390 | ||
1371 | // calculate current extents | 1391 | // calculate current extents |
1372 | S32 cur_width = 0; | 1392 | S32 total_width = 0; |
1373 | S32 cur_height = 0; | 1393 | S32 total_height = 0; |
1374 | 1394 | ||
1375 | const F32 ANIM_OPEN_TIME = 0.02f; | 1395 | const F32 ANIM_OPEN_TIME = 0.02f; |
1376 | const F32 ANIM_CLOSE_TIME = 0.02f; | 1396 | const F32 ANIM_CLOSE_TIME = 0.03f; |
1377 | 1397 | ||
1378 | e_panel_list_t::iterator panel_it; | 1398 | e_panel_list_t::iterator panel_it; |
1379 | for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) | 1399 | for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) |
@@ -1395,23 +1415,22 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1395 | (*panel_it)->mVisibleAmt = 0.f; | 1415 | (*panel_it)->mVisibleAmt = 0.f; |
1396 | } | 1416 | } |
1397 | } | 1417 | } |
1418 | |||
1398 | if (mOrientation == HORIZONTAL) | 1419 | if (mOrientation == HORIZONTAL) |
1399 | { | 1420 | { |
1400 | // all panels get expanded to max of all the minimum dimensions | 1421 | total_width += llround(panelp->getRect().getWidth() * (*panel_it)->mVisibleAmt); |
1401 | cur_height = llmax(mMinHeight, panelp->getRect().getHeight()); | 1422 | // want n-1 panel gaps for n panels |
1402 | cur_width += llround(panelp->getRect().getWidth() * (*panel_it)->mVisibleAmt); | 1423 | if (panel_it != mPanels.begin()) |
1403 | if (panel_it != mPanels.end()) | ||
1404 | { | 1424 | { |
1405 | cur_width += PANEL_STACK_GAP; | 1425 | total_width += mPanelSpacing; |
1406 | } | 1426 | } |
1407 | } | 1427 | } |
1408 | else //VERTICAL | 1428 | else //VERTICAL |
1409 | { | 1429 | { |
1410 | cur_width = llmax(mMinWidth, panelp->getRect().getWidth()); | 1430 | total_height += llround(panelp->getRect().getHeight() * (*panel_it)->mVisibleAmt); |
1411 | cur_height += llround(panelp->getRect().getHeight() * (*panel_it)->mVisibleAmt); | 1431 | if (panel_it != mPanels.begin()) |
1412 | if (panel_it != mPanels.end()) | ||
1413 | { | 1432 | { |
1414 | cur_height += PANEL_STACK_GAP; | 1433 | total_height += mPanelSpacing; |
1415 | } | 1434 | } |
1416 | } | 1435 | } |
1417 | } | 1436 | } |
@@ -1457,11 +1476,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1457 | S32 pixels_to_distribute; | 1476 | S32 pixels_to_distribute; |
1458 | if (mOrientation == HORIZONTAL) | 1477 | if (mOrientation == HORIZONTAL) |
1459 | { | 1478 | { |
1460 | pixels_to_distribute = mRect.getWidth() - cur_width; | 1479 | pixels_to_distribute = mRect.getWidth() - total_width; |
1461 | } | 1480 | } |
1462 | else //VERTICAL | 1481 | else //VERTICAL |
1463 | { | 1482 | { |
1464 | pixels_to_distribute = mRect.getHeight() - cur_height; | 1483 | pixels_to_distribute = mRect.getHeight() - total_height; |
1465 | } | 1484 | } |
1466 | 1485 | ||
1467 | S32 cur_x = 0; | 1486 | S32 cur_x = 0; |
@@ -1474,7 +1493,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1474 | S32 cur_width = panelp->getRect().getWidth(); | 1493 | S32 cur_width = panelp->getRect().getWidth(); |
1475 | S32 cur_height = panelp->getRect().getHeight(); | 1494 | S32 cur_height = panelp->getRect().getHeight(); |
1476 | S32 new_width = llmax((*panel_it)->mMinWidth, cur_width); | 1495 | S32 new_width = llmax((*panel_it)->mMinWidth, cur_width); |
1477 | S32 new_height = llmax((*panel_it)->mMinHeight, cur_height); | 1496 | S32 new_height = llmax((*panel_it)->mMinHeight, cur_height); |
1478 | 1497 | ||
1479 | S32 delta_size = 0; | 1498 | S32 delta_size = 0; |
1480 | 1499 | ||
@@ -1494,11 +1513,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1494 | // grow all elements equally | 1513 | // grow all elements equally |
1495 | delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels); | 1514 | delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels); |
1496 | } | 1515 | } |
1497 | new_width = llmax((*panel_it)->mMinWidth, panelp->getRect().getWidth() + delta_size); | 1516 | new_width = llmax((*panel_it)->mMinWidth, cur_width + delta_size); |
1498 | } | 1517 | } |
1499 | else | 1518 | else |
1500 | { | 1519 | { |
1501 | new_width = llmax(mMinWidth, mRect.getWidth()); | 1520 | new_width = getDefaultWidth(new_width); |
1502 | } | 1521 | } |
1503 | 1522 | ||
1504 | if (mOrientation == VERTICAL) | 1523 | if (mOrientation == VERTICAL) |
@@ -1512,22 +1531,22 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1512 | { | 1531 | { |
1513 | delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels); | 1532 | delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels); |
1514 | } | 1533 | } |
1515 | new_height = llmax((*panel_it)->mMinHeight, panelp->getRect().getHeight() + delta_size); | 1534 | new_height = llmax((*panel_it)->mMinHeight, cur_height + delta_size); |
1516 | } | 1535 | } |
1517 | else | 1536 | else |
1518 | { | 1537 | { |
1519 | new_height = llmax(mMinHeight, mRect.getHeight()); | 1538 | new_height = getDefaultHeight(new_height); |
1520 | } | 1539 | } |
1521 | } | 1540 | } |
1522 | else // don't resize | 1541 | else |
1523 | { | 1542 | { |
1524 | if (mOrientation == HORIZONTAL) | 1543 | if (mOrientation == HORIZONTAL) |
1525 | { | 1544 | { |
1526 | new_height = llmax(mMinHeight, mRect.getHeight()); | 1545 | new_height = getDefaultHeight(new_height); |
1527 | } | 1546 | } |
1528 | else // VERTICAL | 1547 | else // VERTICAL |
1529 | { | 1548 | { |
1530 | new_width = llmax(mMinWidth, mRect.getWidth()); | 1549 | new_width = getDefaultWidth(new_width); |
1531 | } | 1550 | } |
1532 | } | 1551 | } |
1533 | 1552 | ||
@@ -1542,22 +1561,22 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1542 | if (mOrientation == HORIZONTAL) | 1561 | if (mOrientation == HORIZONTAL) |
1543 | { | 1562 | { |
1544 | resize_bar_rect.mLeft = panel_rect.mRight - RESIZE_BAR_OVERLAP; | 1563 | resize_bar_rect.mLeft = panel_rect.mRight - RESIZE_BAR_OVERLAP; |
1545 | resize_bar_rect.mRight = panel_rect.mRight + PANEL_STACK_GAP + RESIZE_BAR_OVERLAP; | 1564 | resize_bar_rect.mRight = panel_rect.mRight + mPanelSpacing + RESIZE_BAR_OVERLAP; |
1546 | } | 1565 | } |
1547 | else | 1566 | else |
1548 | { | 1567 | { |
1549 | resize_bar_rect.mTop = panel_rect.mBottom + RESIZE_BAR_OVERLAP; | 1568 | resize_bar_rect.mTop = panel_rect.mBottom + RESIZE_BAR_OVERLAP; |
1550 | resize_bar_rect.mBottom = panel_rect.mBottom - PANEL_STACK_GAP - RESIZE_BAR_OVERLAP; | 1569 | resize_bar_rect.mBottom = panel_rect.mBottom - mPanelSpacing - RESIZE_BAR_OVERLAP; |
1551 | } | 1570 | } |
1552 | (*panel_it)->mResizeBar->setRect(resize_bar_rect); | 1571 | (*panel_it)->mResizeBar->setRect(resize_bar_rect); |
1553 | 1572 | ||
1554 | if (mOrientation == HORIZONTAL) | 1573 | if (mOrientation == HORIZONTAL) |
1555 | { | 1574 | { |
1556 | cur_x += llround(new_width * (*panel_it)->mVisibleAmt) + PANEL_STACK_GAP; | 1575 | cur_x += llround(new_width * (*panel_it)->mVisibleAmt) + mPanelSpacing; |
1557 | } | 1576 | } |
1558 | else //VERTICAL | 1577 | else //VERTICAL |
1559 | { | 1578 | { |
1560 | cur_y -= llround(new_height * (*panel_it)->mVisibleAmt) + PANEL_STACK_GAP; | 1579 | cur_y -= llround(new_height * (*panel_it)->mVisibleAmt) + mPanelSpacing; |
1561 | } | 1580 | } |
1562 | } | 1581 | } |
1563 | 1582 | ||
@@ -1569,29 +1588,38 @@ void LLLayoutStack::updateLayout(BOOL force_resize) | |||
1569 | 1588 | ||
1570 | if (mOrientation == HORIZONTAL) | 1589 | if (mOrientation == HORIZONTAL) |
1571 | { | 1590 | { |
1572 | (*panel_it)->mResizeBar->setResizeLimits((*panel_it)->mMinWidth, (*panel_it)->mMinWidth + shrink_headroom_total); | 1591 | (*panel_it)->mResizeBar->setResizeLimits( |
1592 | (*panel_it)->mMinWidth, | ||
1593 | (*panel_it)->mMinWidth + shrink_headroom_total); | ||
1573 | } | 1594 | } |
1574 | else //VERTICAL | 1595 | else //VERTICAL |
1575 | { | 1596 | { |
1576 | (*panel_it)->mResizeBar->setResizeLimits((*panel_it)->mMinHeight, (*panel_it)->mMinHeight + shrink_headroom_total); | 1597 | (*panel_it)->mResizeBar->setResizeLimits( |
1598 | (*panel_it)->mMinHeight, | ||
1599 | (*panel_it)->mMinHeight + shrink_headroom_total); | ||
1577 | } | 1600 | } |
1578 | // hide resize bars for invisible panels | 1601 | |
1579 | (*panel_it)->mResizeBar->setVisible(panelp->getVisible()); | 1602 | // toggle resize bars based on panel visibility, resizability, etc |
1580 | if (panelp->getVisible()) | 1603 | BOOL resize_bar_enabled = panelp->getVisible() && (*panel_it)->mUserResize; |
1604 | (*panel_it)->mResizeBar->setVisible(resize_bar_enabled); | ||
1605 | |||
1606 | if (resize_bar_enabled) | ||
1581 | { | 1607 | { |
1582 | last_resize_bar = (*panel_it)->mResizeBar; | 1608 | last_resize_bar = (*panel_it)->mResizeBar; |
1583 | } | 1609 | } |
1584 | } | 1610 | } |
1585 | 1611 | ||
1586 | // hide last resize bar as there is nothing past it | 1612 | // hide last resize bar as there is nothing past it |
1613 | // resize bars need to be in between two resizable panels | ||
1587 | if (last_resize_bar) | 1614 | if (last_resize_bar) |
1588 | { | 1615 | { |
1589 | last_resize_bar->setVisible(FALSE); | 1616 | last_resize_bar->setVisible(FALSE); |
1590 | } | 1617 | } |
1591 | 1618 | ||
1592 | // not enough room to fit existing contents | 1619 | // not enough room to fit existing contents |
1593 | if (!force_resize && | 1620 | if (!force_resize |
1594 | ((cur_y != -PANEL_STACK_GAP) || (cur_x != mRect.getWidth() + PANEL_STACK_GAP))) | 1621 | && ((cur_y != -mPanelSpacing) |
1622 | || (cur_x != mRect.getWidth() + mPanelSpacing))) | ||
1595 | { | 1623 | { |
1596 | // do another layout pass with all stacked elements contributing | 1624 | // do another layout pass with all stacked elements contributing |
1597 | // even those that don't usually resize | 1625 | // even those that don't usually resize |
@@ -1623,20 +1651,22 @@ void LLLayoutStack::calcMinExtents() | |||
1623 | { | 1651 | { |
1624 | if (mOrientation == HORIZONTAL) | 1652 | if (mOrientation == HORIZONTAL) |
1625 | { | 1653 | { |
1626 | mMinHeight = llmax(mMinHeight, (*panel_it)->mMinHeight); | 1654 | mMinHeight = llmax( mMinHeight, |
1655 | (*panel_it)->mMinHeight); | ||
1627 | mMinWidth += (*panel_it)->mMinWidth; | 1656 | mMinWidth += (*panel_it)->mMinWidth; |
1628 | if (panel_it != mPanels.begin()) | 1657 | if (panel_it != mPanels.begin()) |
1629 | { | 1658 | { |
1630 | mMinWidth += PANEL_STACK_GAP; | 1659 | mMinWidth += mPanelSpacing; |
1631 | } | 1660 | } |
1632 | } | 1661 | } |
1633 | else //VERTICAL | 1662 | else //VERTICAL |
1634 | { | 1663 | { |
1635 | mMinWidth = llmax(mMinWidth, (*panel_it)->mMinWidth); | 1664 | mMinWidth = llmax( mMinWidth, |
1665 | (*panel_it)->mMinWidth); | ||
1636 | mMinHeight += (*panel_it)->mMinHeight; | 1666 | mMinHeight += (*panel_it)->mMinHeight; |
1637 | if (panel_it != mPanels.begin()) | 1667 | if (panel_it != mPanels.begin()) |
1638 | { | 1668 | { |
1639 | mMinHeight += PANEL_STACK_GAP; | 1669 | mMinHeight += mPanelSpacing; |
1640 | } | 1670 | } |
1641 | } | 1671 | } |
1642 | } | 1672 | } |
diff --git a/linden/indra/llui/llpanel.h b/linden/indra/llui/llpanel.h index d706fc8..bcbda2c 100644 --- a/linden/indra/llui/llpanel.h +++ b/linden/indra/llui/llpanel.h | |||
@@ -13,12 +13,12 @@ | |||
13 | * ("GPL"), unless you have obtained a separate licensing agreement | 13 | * ("GPL"), unless you have obtained a separate licensing agreement |
14 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 14 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
16 | * online at http://secondlife.com/developers/opensource/gplv2 | 16 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
17 | * | 17 | * |
18 | * There are special exceptions to the terms and conditions of the GPL as | 18 | * There are special exceptions to the terms and conditions of the GPL as |
19 | * it is applied to this Source Code. View the full text of the exception | 19 | * it is applied to this Source Code. View the full text of the exception |
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 20 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
21 | * online at http://secondlife.com/developers/opensource/flossexception | 21 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
22 | * | 22 | * |
23 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
24 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -173,7 +173,7 @@ public: | |||
173 | // LLUICtrl | 173 | // LLUICtrl |
174 | void childSetFocus(const LLString& id, BOOL focus = TRUE); | 174 | void childSetFocus(const LLString& id, BOOL focus = TRUE); |
175 | BOOL childHasFocus(const LLString& id); | 175 | BOOL childHasFocus(const LLString& id); |
176 | void childSetFocusChangedCallback(const LLString& id, void (*cb)(LLUICtrl*, void*)); | 176 | void childSetFocusChangedCallback(const LLString& id, void (*cb)(LLFocusableElement*, void*), void* user_data = NULL); |
177 | 177 | ||
178 | void childSetCommitCallback(const LLString& id, void (*cb)(LLUICtrl*, void*), void* userdata = NULL ); | 178 | void childSetCommitCallback(const LLString& id, void (*cb)(LLUICtrl*, void*), void* userdata = NULL ); |
179 | void childSetDoubleClickCallback(const LLString& id, void (*cb)(void*), void* userdata = NULL ); | 179 | void childSetDoubleClickCallback(const LLString& id, void (*cb)(void*), void* userdata = NULL ); |
@@ -277,9 +277,9 @@ public: | |||
277 | virtual ~LLLayoutStack(); | 277 | virtual ~LLLayoutStack(); |
278 | 278 | ||
279 | /*virtual*/ void draw(); | 279 | /*virtual*/ void draw(); |
280 | /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); | ||
281 | /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; | 280 | /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; |
282 | /*virtual*/ void removeCtrl(LLUICtrl* ctrl); | 281 | /*virtual*/ void removeCtrl(LLUICtrl* ctrl); |
282 | |||
283 | virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_LAYOUT_STACK; } | 283 | virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_LAYOUT_STACK; } |
284 | virtual LLString getWidgetTag() const { return LL_LAYOUT_STACK_TAG; } | 284 | virtual LLString getWidgetTag() const { return LL_LAYOUT_STACK_TAG; } |
285 | 285 | ||
@@ -288,7 +288,7 @@ public: | |||
288 | S32 getMinWidth(); | 288 | S32 getMinWidth(); |
289 | S32 getMinHeight(); | 289 | S32 getMinHeight(); |
290 | 290 | ||
291 | void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, S32 index = S32_MAX); | 291 | void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, S32 index = S32_MAX); |
292 | void removePanel(LLPanel* panel); | 292 | void removePanel(LLPanel* panel); |
293 | void updateLayout(BOOL force_resize = FALSE); | 293 | void updateLayout(BOOL force_resize = FALSE); |
294 | 294 | ||
@@ -299,6 +299,8 @@ protected: | |||
299 | void calcMinExtents(); | 299 | void calcMinExtents(); |
300 | S32 getMinStackSize(); | 300 | S32 getMinStackSize(); |
301 | S32 getCurStackSize(); | 301 | S32 getCurStackSize(); |
302 | S32 getDefaultHeight(S32 cur_height); | ||
303 | S32 getDefaultWidth(S32 cur_width); | ||
302 | 304 | ||
303 | protected: | 305 | protected: |
304 | eLayoutOrientation mOrientation; | 306 | eLayoutOrientation mOrientation; |
@@ -308,6 +310,7 @@ protected: | |||
308 | 310 | ||
309 | S32 mMinWidth; | 311 | S32 mMinWidth; |
310 | S32 mMinHeight; | 312 | S32 mMinHeight; |
313 | S32 mPanelSpacing; | ||
311 | }; | 314 | }; |
312 | 315 | ||
313 | #endif | 316 | #endif |
diff --git a/linden/indra/llui/llradiogroup.cpp b/linden/indra/llui/llradiogroup.cpp index cfb11cd..dad1941 100644 --- a/linden/indra/llui/llradiogroup.cpp +++ b/linden/indra/llui/llradiogroup.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -473,7 +473,7 @@ BOOL LLRadioGroup::setSelectedByValue(LLSD value, BOOL selected) | |||
473 | return FALSE; | 473 | return FALSE; |
474 | } | 474 | } |
475 | 475 | ||
476 | LLSD LLRadioGroup::getSimpleSelectedValue() | 476 | LLSD LLRadioGroup::getSelectedValue() |
477 | { | 477 | { |
478 | return getValue(); | 478 | return getValue(); |
479 | } | 479 | } |
diff --git a/linden/indra/llui/llradiogroup.h b/linden/indra/llui/llradiogroup.h index 1eb6bb7..e0a4168 100644 --- a/linden/indra/llui/llradiogroup.h +++ b/linden/indra/llui/llradiogroup.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -122,7 +122,7 @@ public: | |||
122 | /*virtual*/ BOOL setCurrentByID( const LLUUID& id ); | 122 | /*virtual*/ BOOL setCurrentByID( const LLUUID& id ); |
123 | /*virtual*/ LLUUID getCurrentID(); // LLUUID::null if no items in menu | 123 | /*virtual*/ LLUUID getCurrentID(); // LLUUID::null if no items in menu |
124 | /*virtual*/ BOOL setSelectedByValue(LLSD value, BOOL selected); | 124 | /*virtual*/ BOOL setSelectedByValue(LLSD value, BOOL selected); |
125 | /*virtual*/ LLSD getSimpleSelectedValue(); | 125 | /*virtual*/ LLSD getSelectedValue(); |
126 | /*virtual*/ BOOL isSelected(LLSD value); | 126 | /*virtual*/ BOOL isSelected(LLSD value); |
127 | /*virtual*/ BOOL operateOnSelection(EOperation op); | 127 | /*virtual*/ BOOL operateOnSelection(EOperation op); |
128 | /*virtual*/ BOOL operateOnAll(EOperation op); | 128 | /*virtual*/ BOOL operateOnAll(EOperation op); |
diff --git a/linden/indra/llui/llresizebar.cpp b/linden/indra/llui/llresizebar.cpp index 8ac165c..e6ce03b 100644 --- a/linden/indra/llui/llresizebar.cpp +++ b/linden/indra/llui/llresizebar.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llresizebar.h b/linden/indra/llui/llresizebar.h index b9ad124..11fca9d 100644 --- a/linden/indra/llui/llresizebar.h +++ b/linden/indra/llui/llresizebar.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llresizehandle.cpp b/linden/indra/llui/llresizehandle.cpp index 36eb3b1..739d583 100644 --- a/linden/indra/llui/llresizehandle.cpp +++ b/linden/indra/llui/llresizehandle.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -60,7 +60,7 @@ LLResizeHandle::LLResizeHandle( const LLString& name, const LLRect& rect, S32 mi | |||
60 | if( RIGHT_BOTTOM == mCorner) | 60 | if( RIGHT_BOTTOM == mCorner) |
61 | { | 61 | { |
62 | LLUUID image_id(LLUI::sConfigGroup->getString("UIImgResizeBottomRightUUID")); | 62 | LLUUID image_id(LLUI::sConfigGroup->getString("UIImgResizeBottomRightUUID")); |
63 | mImage = LLUI::sImageProvider->getUIImageByID(image_id); | 63 | mImage = LLUI::sImageProvider->getImageByID(image_id); |
64 | } | 64 | } |
65 | 65 | ||
66 | switch( mCorner ) | 66 | switch( mCorner ) |
diff --git a/linden/indra/llui/llresizehandle.h b/linden/indra/llui/llresizehandle.h index 90c96d7..863ce70 100644 --- a/linden/indra/llui/llresizehandle.h +++ b/linden/indra/llui/llresizehandle.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llresmgr.cpp b/linden/indra/llui/llresmgr.cpp index 1922f3f..83ad440 100644 --- a/linden/indra/llui/llresmgr.cpp +++ b/linden/indra/llui/llresmgr.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llresmgr.h b/linden/indra/llui/llresmgr.h index 9f29282..b851795 100644 --- a/linden/indra/llui/llresmgr.h +++ b/linden/indra/llui/llresmgr.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llrootview.cpp b/linden/indra/llui/llrootview.cpp index 57fe3ee..1580f99 100644 --- a/linden/indra/llui/llrootview.cpp +++ b/linden/indra/llui/llrootview.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llrootview.h b/linden/indra/llui/llrootview.h index 0b6fea3..13037f0 100644 --- a/linden/indra/llui/llrootview.h +++ b/linden/indra/llui/llrootview.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llscrollbar.cpp b/linden/indra/llui/llscrollbar.cpp index 34acf03..ec46551 100644 --- a/linden/indra/llui/llscrollbar.cpp +++ b/linden/indra/llui/llscrollbar.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -159,30 +159,50 @@ void LLScrollbar::setDocParams( S32 size, S32 pos ) | |||
159 | 159 | ||
160 | void LLScrollbar::setDocPos(S32 pos) | 160 | void LLScrollbar::setDocPos(S32 pos) |
161 | { | 161 | { |
162 | mDocPos = llclamp( pos, 0, getDocPosMax() ); | 162 | if (pos != mDocPos) |
163 | mDocChanged = TRUE; | 163 | { |
164 | mDocPos = llclamp( pos, 0, getDocPosMax() ); | ||
165 | mDocChanged = TRUE; | ||
164 | 166 | ||
165 | updateThumbRect(); | 167 | updateThumbRect(); |
168 | } | ||
166 | } | 169 | } |
167 | 170 | ||
168 | void LLScrollbar::setDocSize(S32 size) | 171 | void LLScrollbar::setDocSize(S32 size) |
169 | { | 172 | { |
170 | mDocSize = size; | 173 | if (size != mDocSize) |
171 | mDocPos = llclamp( mDocPos, 0, getDocPosMax() ); | 174 | { |
172 | mDocChanged = TRUE; | 175 | mDocSize = size; |
176 | mDocPos = llclamp( mDocPos, 0, getDocPosMax() ); | ||
177 | mDocChanged = TRUE; | ||
173 | 178 | ||
174 | updateThumbRect(); | 179 | updateThumbRect(); |
180 | } | ||
175 | } | 181 | } |
176 | 182 | ||
177 | void LLScrollbar::setPageSize( S32 page_size ) | 183 | void LLScrollbar::setPageSize( S32 page_size ) |
178 | { | 184 | { |
179 | mPageSize = page_size; | 185 | if (page_size != mPageSize) |
180 | mDocPos = llclamp( mDocPos, 0, getDocPosMax() ); | 186 | { |
181 | mDocChanged = TRUE; | 187 | mPageSize = page_size; |
188 | mDocPos = llclamp( mDocPos, 0, getDocPosMax() ); | ||
189 | mDocChanged = TRUE; | ||
182 | 190 | ||
183 | updateThumbRect(); | 191 | updateThumbRect(); |
192 | } | ||
193 | } | ||
194 | |||
195 | BOOL LLScrollbar::isAtBeginning() | ||
196 | { | ||
197 | return mDocPos == 0; | ||
198 | } | ||
199 | |||
200 | BOOL LLScrollbar::isAtEnd() | ||
201 | { | ||
202 | return mDocPos == getDocPosMax(); | ||
184 | } | 203 | } |
185 | 204 | ||
205 | |||
186 | void LLScrollbar::updateThumbRect() | 206 | void LLScrollbar::updateThumbRect() |
187 | { | 207 | { |
188 | // llassert( 0 <= mDocSize ); | 208 | // llassert( 0 <= mDocSize ); |
@@ -479,7 +499,7 @@ void LLScrollbar::draw() | |||
479 | // Draw background and thumb. | 499 | // Draw background and thumb. |
480 | LLUUID rounded_rect_image_id; | 500 | LLUUID rounded_rect_image_id; |
481 | rounded_rect_image_id.set(LLUI::sAssetsGroup->getString("rounded_square.tga")); | 501 | rounded_rect_image_id.set(LLUI::sAssetsGroup->getString("rounded_square.tga")); |
482 | LLImageGL* rounded_rect_imagep = LLUI::sImageProvider->getUIImageByID(rounded_rect_image_id); | 502 | LLImageGL* rounded_rect_imagep = LLUI::sImageProvider->getImageByID(rounded_rect_image_id); |
483 | 503 | ||
484 | if (!rounded_rect_imagep) | 504 | if (!rounded_rect_imagep) |
485 | { | 505 | { |
diff --git a/linden/indra/llui/llscrollbar.h b/linden/indra/llui/llscrollbar.h index 1bfd0f6..464c9c1 100644 --- a/linden/indra/llui/llscrollbar.h +++ b/linden/indra/llui/llscrollbar.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -88,6 +88,9 @@ public: | |||
88 | void setDocPos( S32 pos ); | 88 | void setDocPos( S32 pos ); |
89 | S32 getDocPos() { return mDocPos; } | 89 | S32 getDocPos() { return mDocPos; } |
90 | 90 | ||
91 | BOOL isAtBeginning(); | ||
92 | BOOL isAtEnd(); | ||
93 | |||
91 | // How many "lines" of the "document" is can appear on a page. | 94 | // How many "lines" of the "document" is can appear on a page. |
92 | void setPageSize( S32 page_size ); | 95 | void setPageSize( S32 page_size ); |
93 | S32 getPageSize() { return mPageSize; } | 96 | S32 getPageSize() { return mPageSize; } |
diff --git a/linden/indra/llui/llscrollcontainer.cpp b/linden/indra/llui/llscrollcontainer.cpp index 414a2d7..8c8b40c 100644 --- a/linden/indra/llui/llscrollcontainer.cpp +++ b/linden/indra/llui/llscrollcontainer.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -394,33 +394,29 @@ BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask, | |||
394 | 394 | ||
395 | BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect) | 395 | BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect) |
396 | { | 396 | { |
397 | if( getVisible() && pointInView(x,y) ) | 397 | S32 local_x, local_y; |
398 | for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) | ||
398 | { | 399 | { |
399 | S32 local_x, local_y; | 400 | local_x = x - mScrollbar[i]->getRect().mLeft; |
400 | for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) | 401 | local_y = y - mScrollbar[i]->getRect().mBottom; |
402 | if( mScrollbar[i]->handleToolTip(local_x, local_y, msg, sticky_rect) ) | ||
401 | { | 403 | { |
402 | local_x = x - mScrollbar[i]->getRect().mLeft; | 404 | return TRUE; |
403 | local_y = y - mScrollbar[i]->getRect().mBottom; | ||
404 | if( mScrollbar[i]->handleToolTip(local_x, local_y, msg, sticky_rect) ) | ||
405 | { | ||
406 | return TRUE; | ||
407 | } | ||
408 | } | 405 | } |
409 | // Handle 'child' view. | 406 | } |
410 | if( mScrolledView ) | 407 | // Handle 'child' view. |
408 | if( mScrolledView ) | ||
409 | { | ||
410 | local_x = x - mScrolledView->getRect().mLeft; | ||
411 | local_y = y - mScrolledView->getRect().mBottom; | ||
412 | if( mScrolledView->handleToolTip(local_x, local_y, msg, sticky_rect) ) | ||
411 | { | 413 | { |
412 | local_x = x - mScrolledView->getRect().mLeft; | 414 | return TRUE; |
413 | local_y = y - mScrolledView->getRect().mBottom; | ||
414 | if( mScrolledView->handleToolTip(local_x, local_y, msg, sticky_rect) ) | ||
415 | { | ||
416 | return TRUE; | ||
417 | } | ||
418 | } | 415 | } |
419 | |||
420 | // Opaque | ||
421 | return TRUE; | ||
422 | } | 416 | } |
423 | return FALSE; | 417 | |
418 | // Opaque | ||
419 | return TRUE; | ||
424 | } | 420 | } |
425 | 421 | ||
426 | void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) | 422 | void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) |
diff --git a/linden/indra/llui/llscrollcontainer.h b/linden/indra/llui/llscrollcontainer.h index 682cade..fb7198c 100644 --- a/linden/indra/llui/llscrollcontainer.h +++ b/linden/indra/llui/llscrollcontainer.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llscrollingpanellist.cpp b/linden/indra/llui/llscrollingpanellist.cpp index 5f91644..a9d538e 100644 --- a/linden/indra/llui/llscrollingpanellist.cpp +++ b/linden/indra/llui/llscrollingpanellist.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llscrollingpanellist.h b/linden/indra/llui/llscrollingpanellist.h index 77002d0..84dc7f9 100644 --- a/linden/indra/llui/llscrollingpanellist.h +++ b/linden/indra/llui/llscrollingpanellist.h | |||
@@ -11,12 +11,12 @@ | |||
11 | * ("GPL"), unless you have obtained a separate licensing agreement | 11 | * ("GPL"), unless you have obtained a separate licensing agreement |
12 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 12 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
13 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 13 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
14 | * online at http://secondlife.com/developers/opensource/gplv2 | 14 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
15 | * | 15 | * |
16 | * There are special exceptions to the terms and conditions of the GPL as | 16 | * There are special exceptions to the terms and conditions of the GPL as |
17 | * it is applied to this Source Code. View the full text of the exception | 17 | * it is applied to this Source Code. View the full text of the exception |
18 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 18 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
19 | * online at http://secondlife.com/developers/opensource/flossexception | 19 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
20 | * | 20 | * |
21 | * By copying, modifying or distributing this software, you acknowledge | 21 | * By copying, modifying or distributing this software, you acknowledge |
22 | * that you have read and understood your obligations described above, | 22 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llscrolllistctrl.cpp b/linden/indra/llui/llscrolllistctrl.cpp index b80787f..d65ebd2 100644 --- a/linden/indra/llui/llscrolllistctrl.cpp +++ b/linden/indra/llui/llscrolllistctrl.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -61,73 +61,101 @@ const S32 LIST_SNAP_PADDING = 5; | |||
61 | // local structures & classes. | 61 | // local structures & classes. |
62 | struct SortScrollListItem | 62 | struct SortScrollListItem |
63 | { | 63 | { |
64 | SortScrollListItem(const S32 sort_col, BOOL sort_ascending) | 64 | SortScrollListItem(const std::vector<std::pair<S32, BOOL> >& sort_orders) |
65 | { | 65 | : mSortOrders(sort_orders) |
66 | mSortCol = sort_col; | 66 | {} |
67 | mSortAscending = sort_ascending; | ||
68 | } | ||
69 | 67 | ||
70 | bool operator()(const LLScrollListItem* i1, const LLScrollListItem* i2) | 68 | bool operator()(const LLScrollListItem* i1, const LLScrollListItem* i2) |
71 | { | 69 | { |
72 | const LLScrollListCell *cell1; | 70 | if ( mSortOrders.empty() ) return true; |
73 | const LLScrollListCell *cell2; | 71 | |
74 | 72 | const LLScrollListCell *cell1 = NULL; | |
75 | cell1 = i1->getColumn(mSortCol); | 73 | const LLScrollListCell *cell2 = NULL; |
76 | cell2 = i2->getColumn(mSortCol); | ||
77 | 74 | ||
78 | S32 order = 1; | 75 | sort_order_t::const_reverse_iterator end_it = mSortOrders.rend(); |
79 | if (!mSortAscending) | 76 | sort_order_t::const_reverse_iterator it; |
77 | |||
78 | // sort over all columns in order specified by mSortOrders | ||
79 | S32 sort_result = 0; | ||
80 | for (it = mSortOrders.rbegin(); it != end_it; ++it) | ||
80 | { | 81 | { |
81 | order = -1; | 82 | S32 col_idx = it->first; |
82 | } | 83 | BOOL sort_ascending = it->second; |
83 | 84 | ||
84 | BOOL retval = FALSE; | 85 | cell1 = i1->getColumn(col_idx); |
86 | cell2 = i2->getColumn(col_idx); | ||
87 | // ascending or descending sort for this column? | ||
88 | S32 order = 1; | ||
89 | if (!sort_ascending) | ||
90 | { | ||
91 | order = -1; | ||
92 | } | ||
85 | 93 | ||
86 | if (cell1 && cell2) | 94 | if (cell1 && cell2) |
87 | { | 95 | { |
88 | retval = ((order * LLString::compareDict(cell1->getText(), cell2->getText())) < 0); | 96 | sort_result = (order * LLString::compareDict(cell1->getValue().asString(), cell2->getValue().asString())); |
97 | if (sort_result != 0) | ||
98 | { | ||
99 | // we have a sort order! | ||
100 | break; | ||
101 | } | ||
102 | } | ||
89 | } | 103 | } |
90 | 104 | ||
91 | return (retval ? TRUE : FALSE); | 105 | return sort_result < 0; |
92 | } | 106 | } |
93 | 107 | ||
94 | protected: | 108 | typedef std::vector<std::pair<S32, BOOL> > sort_order_t; |
95 | S32 mSortCol; | 109 | const sort_order_t& mSortOrders; |
96 | S32 mSortAscending; | ||
97 | }; | 110 | }; |
98 | 111 | ||
99 | 112 | ||
100 | |||
101 | // | 113 | // |
102 | // LLScrollListIcon | 114 | // LLScrollListIcon |
103 | // | 115 | // |
104 | LLScrollListIcon::LLScrollListIcon(LLImageGL* icon, S32 width, LLUUID image_id) | 116 | LLScrollListIcon::LLScrollListIcon(const LLUUID& icon_id, S32 width) |
105 | : mIcon(icon), | 117 | : LLScrollListCell(width), |
106 | mImageUUID(image_id.asString()), | 118 | mColor(LLColor4::white), |
107 | mColor(LLColor4::white) | 119 | mImageUUID(icon_id) |
108 | { | 120 | { |
109 | if (width) | 121 | // don't use default image specified by LLUUID::null, use no image in that case |
110 | { | 122 | mIcon = icon_id.isNull() ? NULL : LLUI::sImageProvider->getImageByID(icon_id); |
111 | mWidth = width; | ||
112 | } | ||
113 | else | ||
114 | { | ||
115 | mWidth = icon->getWidth(); | ||
116 | } | ||
117 | } | 123 | } |
118 | 124 | ||
119 | LLScrollListIcon::~LLScrollListIcon() | 125 | LLScrollListIcon::~LLScrollListIcon() |
120 | { | 126 | { |
121 | } | 127 | } |
122 | 128 | ||
129 | void LLScrollListIcon::setValue(LLSD value) | ||
130 | { | ||
131 | mImageUUID = value.asUUID(); | ||
132 | // don't use default image specified by LLUUID::null, use no image in that case | ||
133 | mIcon = mImageUUID.isNull() ? NULL : LLUI::sImageProvider->getImageByID(mImageUUID); | ||
134 | } | ||
135 | |||
136 | |||
123 | void LLScrollListIcon::setColor(const LLColor4& color) | 137 | void LLScrollListIcon::setColor(const LLColor4& color) |
124 | { | 138 | { |
125 | mColor = color; | 139 | mColor = color; |
126 | } | 140 | } |
127 | 141 | ||
128 | void LLScrollListIcon::drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const | 142 | S32 LLScrollListIcon::getWidth() const |
143 | { | ||
144 | // if no specified fix width, use width of icon | ||
145 | if (mWidth == 0) | ||
146 | { | ||
147 | return mIcon->getWidth(); | ||
148 | } | ||
149 | return mWidth; | ||
150 | } | ||
151 | |||
152 | |||
153 | void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_color) const | ||
129 | { | 154 | { |
130 | gl_draw_image(0, 0, mIcon, mColor); | 155 | if (mIcon) |
156 | { | ||
157 | gl_draw_image(0, 0, mIcon, mColor); | ||
158 | } | ||
131 | } | 159 | } |
132 | 160 | ||
133 | // | 161 | // |
@@ -155,32 +183,32 @@ LLScrollListCheck::~LLScrollListCheck() | |||
155 | delete mCheckBox; | 183 | delete mCheckBox; |
156 | } | 184 | } |
157 | 185 | ||
158 | void LLScrollListCheck::drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const | 186 | void LLScrollListCheck::draw(const LLColor4& color, const LLColor4& highlight_color) const |
159 | { | 187 | { |
160 | mCheckBox->draw(); | 188 | mCheckBox->draw(); |
161 | |||
162 | } | 189 | } |
163 | 190 | ||
164 | BOOL LLScrollListCheck::handleClick() | 191 | BOOL LLScrollListCheck::handleClick() |
165 | { | 192 | { |
166 | if ( mCheckBox->getEnabled() ) | 193 | if (mCheckBox->getEnabled()) |
167 | { | 194 | { |
168 | LLCheckBoxCtrl::onButtonPress(mCheckBox); | 195 | mCheckBox->toggle(); |
169 | } | 196 | } |
197 | // don't change selection when clicking on embedded checkbox | ||
170 | return TRUE; | 198 | return TRUE; |
171 | } | 199 | } |
172 | 200 | ||
173 | // | 201 | // |
174 | // LLScrollListSeparator | 202 | // LLScrollListSeparator |
175 | // | 203 | // |
176 | LLScrollListSeparator::LLScrollListSeparator(S32 width) : mWidth(width) | 204 | LLScrollListSeparator::LLScrollListSeparator(S32 width) : LLScrollListCell(width) |
177 | { | 205 | { |
178 | } | 206 | } |
179 | 207 | ||
180 | void LLScrollListSeparator::drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const | 208 | void LLScrollListSeparator::draw(const LLColor4& color, const LLColor4& highlight_color) const |
181 | { | 209 | { |
182 | //*FIXME: use dynamic item heights and make separators narrow, and inactive | 210 | //*FIXME: use dynamic item heights and make separators narrow, and inactive |
183 | gl_line_2d(5, 8, llmax(5, width - 5), 8, color); | 211 | gl_line_2d(5, 8, llmax(5, getWidth() - 5), 8, color); |
184 | } | 212 | } |
185 | 213 | ||
186 | // | 214 | // |
@@ -189,11 +217,11 @@ void LLScrollListSeparator::drawToWidth(S32 width, const LLColor4& color, const | |||
189 | U32 LLScrollListText::sCount = 0; | 217 | U32 LLScrollListText::sCount = 0; |
190 | 218 | ||
191 | LLScrollListText::LLScrollListText( const LLString& text, const LLFontGL* font, S32 width, U8 font_style, LLFontGL::HAlign font_alignment, LLColor4& color, BOOL use_color, BOOL visible) | 219 | LLScrollListText::LLScrollListText( const LLString& text, const LLFontGL* font, S32 width, U8 font_style, LLFontGL::HAlign font_alignment, LLColor4& color, BOOL use_color, BOOL visible) |
192 | : mText( text ), | 220 | : LLScrollListCell(width), |
221 | mText( text ), | ||
193 | mFont( font ), | 222 | mFont( font ), |
194 | mFontStyle( font_style ), | 223 | mFontStyle( font_style ), |
195 | mFontAlignment( font_alignment ), | 224 | mFontAlignment( font_alignment ), |
196 | mWidth( width ), | ||
197 | mVisible( visible ), | 225 | mVisible( visible ), |
198 | mHighlightCount( 0 ), | 226 | mHighlightCount( 0 ), |
199 | mHighlightOffset( 0 ) | 227 | mHighlightOffset( 0 ) |
@@ -213,7 +241,7 @@ LLScrollListText::LLScrollListText( const LLString& text, const LLFontGL* font, | |||
213 | // initialize rounded rect image | 241 | // initialize rounded rect image |
214 | if (!mRoundedRectImage) | 242 | if (!mRoundedRectImage) |
215 | { | 243 | { |
216 | mRoundedRectImage = LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("rounded_square.tga"))); | 244 | mRoundedRectImage = LLUI::sImageProvider->getImageByID(LLUUID(LLUI::sAssetsGroup->getString("rounded_square.tga"))); |
217 | } | 245 | } |
218 | } | 246 | } |
219 | 247 | ||
@@ -223,6 +251,12 @@ LLScrollListText::~LLScrollListText() | |||
223 | delete mColor; | 251 | delete mColor; |
224 | } | 252 | } |
225 | 253 | ||
254 | S32 LLScrollListText::getContentWidth() const | ||
255 | { | ||
256 | return mFont->getWidth(mText.getString()); | ||
257 | } | ||
258 | |||
259 | |||
226 | void LLScrollListText::setColor(const LLColor4& color) | 260 | void LLScrollListText::setColor(const LLColor4& color) |
227 | { | 261 | { |
228 | if (!mColor) | 262 | if (!mColor) |
@@ -237,14 +271,8 @@ void LLScrollListText::setText(const LLStringExplicit& text) | |||
237 | mText = text; | 271 | mText = text; |
238 | } | 272 | } |
239 | 273 | ||
240 | void LLScrollListText::drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const | 274 | void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_color) const |
241 | { | 275 | { |
242 | // If the user has specified a small minimum width, use that. | ||
243 | if (mWidth > 0 && mWidth < width) | ||
244 | { | ||
245 | width = mWidth; | ||
246 | } | ||
247 | |||
248 | const LLColor4* display_color; | 276 | const LLColor4* display_color; |
249 | if (mColor) | 277 | if (mColor) |
250 | { | 278 | { |
@@ -266,10 +294,10 @@ void LLScrollListText::drawToWidth(S32 width, const LLColor4& color, const LLCol | |||
266 | left = mFont->getWidth(mText.getString(), 0, mHighlightOffset); | 294 | left = mFont->getWidth(mText.getString(), 0, mHighlightOffset); |
267 | break; | 295 | break; |
268 | case LLFontGL::RIGHT: | 296 | case LLFontGL::RIGHT: |
269 | left = width - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX); | 297 | left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX); |
270 | break; | 298 | break; |
271 | case LLFontGL::HCENTER: | 299 | case LLFontGL::HCENTER: |
272 | left = (width - mFont->getWidth(mText.getString())) / 2; | 300 | left = (getWidth() - mFont->getWidth(mText.getString())) / 2; |
273 | break; | 301 | break; |
274 | } | 302 | } |
275 | gl_segmented_rect_2d_tex(left - 2, | 303 | gl_segmented_rect_2d_tex(left - 2, |
@@ -291,10 +319,10 @@ void LLScrollListText::drawToWidth(S32 width, const LLColor4& color, const LLCol | |||
291 | start_x = 0.f; | 319 | start_x = 0.f; |
292 | break; | 320 | break; |
293 | case LLFontGL::RIGHT: | 321 | case LLFontGL::RIGHT: |
294 | start_x = (F32)width; | 322 | start_x = (F32)getWidth(); |
295 | break; | 323 | break; |
296 | case LLFontGL::HCENTER: | 324 | case LLFontGL::HCENTER: |
297 | start_x = (F32)width * 0.5f; | 325 | start_x = (F32)getWidth() * 0.5f; |
298 | break; | 326 | break; |
299 | } | 327 | } |
300 | mFont->render(mText.getWString(), 0, | 328 | mFont->render(mText.getWString(), 0, |
@@ -304,8 +332,10 @@ void LLScrollListText::drawToWidth(S32 width, const LLColor4& color, const LLCol | |||
304 | LLFontGL::BOTTOM, | 332 | LLFontGL::BOTTOM, |
305 | mFontStyle, | 333 | mFontStyle, |
306 | string_chars, | 334 | string_chars, |
307 | width, | 335 | getWidth(), |
308 | &right_x, FALSE, TRUE); | 336 | &right_x, |
337 | FALSE, | ||
338 | TRUE); | ||
309 | } | 339 | } |
310 | 340 | ||
311 | 341 | ||
@@ -314,31 +344,6 @@ LLScrollListItem::~LLScrollListItem() | |||
314 | std::for_each(mColumns.begin(), mColumns.end(), DeletePointer()); | 344 | std::for_each(mColumns.begin(), mColumns.end(), DeletePointer()); |
315 | } | 345 | } |
316 | 346 | ||
317 | BOOL LLScrollListItem::handleClick(S32 x, S32 y, MASK mask) | ||
318 | { | ||
319 | BOOL handled = FALSE; | ||
320 | |||
321 | S32 left = 0; | ||
322 | S32 right = 0; | ||
323 | S32 width = 0; | ||
324 | |||
325 | std::vector<LLScrollListCell *>::iterator iter = mColumns.begin(); | ||
326 | std::vector<LLScrollListCell *>::iterator end = mColumns.end(); | ||
327 | for ( ; iter != end; ++iter) | ||
328 | { | ||
329 | width = (*iter)->getWidth(); | ||
330 | right += width; | ||
331 | if (left <= x && x < right ) | ||
332 | { | ||
333 | handled = (*iter)->handleClick(); | ||
334 | break; | ||
335 | } | ||
336 | |||
337 | left += width; | ||
338 | } | ||
339 | return handled; | ||
340 | } | ||
341 | |||
342 | void LLScrollListItem::setNumColumns(S32 columns) | 347 | void LLScrollListItem::setNumColumns(S32 columns) |
343 | { | 348 | { |
344 | S32 prev_columns = mColumns.size(); | 349 | S32 prev_columns = mColumns.size(); |
@@ -375,7 +380,7 @@ LLString LLScrollListItem::getContentsCSV() | |||
375 | S32 count = getNumColumns(); | 380 | S32 count = getNumColumns(); |
376 | for (S32 i=0; i<count; ++i) | 381 | for (S32 i=0; i<count; ++i) |
377 | { | 382 | { |
378 | ret += getColumn(i)->getText(); | 383 | ret += getColumn(i)->getValue().asString(); |
379 | if (i < count-1) | 384 | if (i < count-1) |
380 | { | 385 | { |
381 | ret += ", "; | 386 | ret += ", "; |
@@ -385,17 +390,107 @@ LLString LLScrollListItem::getContentsCSV() | |||
385 | return ret; | 390 | return ret; |
386 | } | 391 | } |
387 | 392 | ||
393 | void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) | ||
394 | { | ||
395 | // draw background rect | ||
396 | LLRect bg_rect = rect; | ||
397 | // pad background rectangle to separate it from contents | ||
398 | bg_rect.stretch(LIST_BORDER_PAD, 0); | ||
399 | { | ||
400 | LLGLSNoTexture no_texture; | ||
401 | glColor4fv(bg_color.mV); | ||
402 | gl_rect_2d( bg_rect ); | ||
403 | } | ||
404 | |||
405 | S32 cur_x = rect.mLeft; | ||
406 | S32 num_cols = getNumColumns(); | ||
407 | S32 cur_col = 0; | ||
408 | |||
409 | for (LLScrollListCell* cell = getColumn(0); cur_col < num_cols; cell = getColumn(++cur_col)) | ||
410 | { | ||
411 | // Two ways a cell could be hidden | ||
412 | if (cell->getWidth() < 0 | ||
413 | || !cell->getVisible()) continue; | ||
414 | |||
415 | LLUI::pushMatrix(); | ||
416 | { | ||
417 | LLUI::translate((F32) cur_x, (F32) rect.mBottom, 0.0f); | ||
418 | |||
419 | cell->draw( fg_color, highlight_color ); | ||
420 | } | ||
421 | LLUI::popMatrix(); | ||
422 | |||
423 | cur_x += cell->getWidth() + column_padding; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | |||
388 | void LLScrollListItem::setEnabled(BOOL b) | 428 | void LLScrollListItem::setEnabled(BOOL b) |
389 | { | 429 | { |
390 | if (b != mEnabled) | 430 | mEnabled = b; |
431 | } | ||
432 | |||
433 | //--------------------------------------------------------------------------- | ||
434 | // LLScrollListItemComment | ||
435 | //--------------------------------------------------------------------------- | ||
436 | LLScrollListItemComment::LLScrollListItemComment(const LLString& comment_string, const LLColor4& color) | ||
437 | : LLScrollListItem(FALSE), | ||
438 | mColor(color) | ||
439 | { | ||
440 | addColumn( comment_string, gResMgr->getRes( LLFONT_SANSSERIF_SMALL ) ); | ||
441 | } | ||
442 | |||
443 | void LLScrollListItemComment::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) | ||
444 | { | ||
445 | LLScrollListCell* cell = getColumn(0); | ||
446 | if (cell) | ||
447 | { | ||
448 | // Two ways a cell could be hidden | ||
449 | if (cell->getWidth() < 0 | ||
450 | || !cell->getVisible()) return; | ||
451 | |||
452 | LLUI::pushMatrix(); | ||
453 | { | ||
454 | LLUI::translate((F32)rect.mLeft, (F32)rect.mBottom, 0.0f); | ||
455 | |||
456 | // force first cell to be width of entire item | ||
457 | cell->setWidth(rect.getWidth()); | ||
458 | cell->draw( mColor, highlight_color ); | ||
459 | } | ||
460 | LLUI::popMatrix(); | ||
461 | } | ||
462 | } | ||
463 | |||
464 | //--------------------------------------------------------------------------- | ||
465 | // LLScrollListItemSeparator | ||
466 | //--------------------------------------------------------------------------- | ||
467 | LLScrollListItemSeparator::LLScrollListItemSeparator() | ||
468 | : LLScrollListItem(FALSE) | ||
469 | { | ||
470 | LLScrollListSeparator* cell = new LLScrollListSeparator(0); | ||
471 | setNumColumns(1); | ||
472 | setColumn(0, cell); | ||
473 | } | ||
474 | |||
475 | void LLScrollListItemSeparator::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) | ||
476 | { | ||
477 | //TODO* move LLScrollListSeparator::draw into here and get rid of it | ||
478 | LLScrollListCell* cell = getColumn(0); | ||
479 | if (cell) | ||
391 | { | 480 | { |
392 | std::vector<LLScrollListCell *>::iterator iter = mColumns.begin(); | 481 | // Two ways a cell could be hidden |
393 | std::vector<LLScrollListCell *>::iterator end = mColumns.end(); | 482 | if (cell->getWidth() < 0 |
394 | for ( ; iter != end; ++iter) | 483 | || !cell->getVisible()) return; |
484 | |||
485 | LLUI::pushMatrix(); | ||
395 | { | 486 | { |
396 | (*iter)->setEnabled(b); | 487 | LLUI::translate((F32)rect.mLeft, (F32)rect.mBottom, 0.0f); |
488 | |||
489 | // force first cell to be width of entire item | ||
490 | cell->setWidth(rect.getWidth()); | ||
491 | cell->draw( fg_color, highlight_color ); | ||
397 | } | 492 | } |
398 | mEnabled = b; | 493 | LLUI::popMatrix(); |
399 | } | 494 | } |
400 | } | 495 | } |
401 | 496 | ||
@@ -423,10 +518,8 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, | |||
423 | mNeedsScroll(FALSE), | 518 | mNeedsScroll(FALSE), |
424 | mCanSelect(TRUE), | 519 | mCanSelect(TRUE), |
425 | mDisplayColumnHeaders(FALSE), | 520 | mDisplayColumnHeaders(FALSE), |
426 | mCollapseEmptyColumns(FALSE), | ||
427 | mIsPopup(FALSE), | ||
428 | mMaxItemCount(INT_MAX), | 521 | mMaxItemCount(INT_MAX), |
429 | //mItemCount(0), | 522 | mMaxContentWidth(0), |
430 | mBackgroundVisible( TRUE ), | 523 | mBackgroundVisible( TRUE ), |
431 | mDrawStripes(TRUE), | 524 | mDrawStripes(TRUE), |
432 | mBgWriteableColor( LLUI::sColorsGroup->getColor( "ScrollBgWriteableColor" ) ), | 525 | mBgWriteableColor( LLUI::sColorsGroup->getColor( "ScrollBgWriteableColor" ) ), |
@@ -443,12 +536,9 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, | |||
443 | mOnSortChangedCallback( NULL ), | 536 | mOnSortChangedCallback( NULL ), |
444 | mHighlightedItem(-1), | 537 | mHighlightedItem(-1), |
445 | mBorder(NULL), | 538 | mBorder(NULL), |
446 | mDefaultColumn("SIMPLE"), | ||
447 | mSearchColumn(0), | 539 | mSearchColumn(0), |
448 | mNumDynamicWidthColumns(0), | 540 | mNumDynamicWidthColumns(0), |
449 | mTotalStaticColumnWidth(0), | 541 | mTotalStaticColumnWidth(0), |
450 | mSortColumn(-1), | ||
451 | mSortAscending(TRUE), | ||
452 | mSorted(TRUE), | 542 | mSorted(TRUE), |
453 | mDirty(FALSE), | 543 | mDirty(FALSE), |
454 | mOriginalSelection(-1), | 544 | mOriginalSelection(-1), |
@@ -457,7 +547,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, | |||
457 | mItemListRect.setOriginAndSize( | 547 | mItemListRect.setOriginAndSize( |
458 | mBorderThickness + LIST_BORDER_PAD, | 548 | mBorderThickness + LIST_BORDER_PAD, |
459 | mBorderThickness + LIST_BORDER_PAD, | 549 | mBorderThickness + LIST_BORDER_PAD, |
460 | mRect.getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ) - SCROLLBAR_SIZE, | 550 | mRect.getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ), |
461 | mRect.getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) ); | 551 | mRect.getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) ); |
462 | 552 | ||
463 | updateLineHeight(); | 553 | updateLineHeight(); |
@@ -481,7 +571,8 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, | |||
481 | mScrollbar->setFollowsTop(); | 571 | mScrollbar->setFollowsTop(); |
482 | mScrollbar->setFollowsBottom(); | 572 | mScrollbar->setFollowsBottom(); |
483 | mScrollbar->setEnabled( TRUE ); | 573 | mScrollbar->setEnabled( TRUE ); |
484 | mScrollbar->setVisible( TRUE ); | 574 | // scrollbar is visible only when needed |
575 | mScrollbar->setVisible(FALSE); | ||
485 | addChild(mScrollbar); | 576 | addChild(mScrollbar); |
486 | 577 | ||
487 | // Border | 578 | // Border |
@@ -539,7 +630,8 @@ void LLScrollListCtrl::clearRows() | |||
539 | 630 | ||
540 | mScrollLines = 0; | 631 | mScrollLines = 0; |
541 | mLastSelected = NULL; | 632 | mLastSelected = NULL; |
542 | updateMaxContentWidth(NULL); | 633 | calcMaxContentWidth(NULL); |
634 | updateLayout(); | ||
543 | mDirty = FALSE; | 635 | mDirty = FALSE; |
544 | } | 636 | } |
545 | 637 | ||
@@ -620,38 +712,64 @@ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllData() const | |||
620 | return ret; | 712 | return ret; |
621 | } | 713 | } |
622 | 714 | ||
715 | // returns first matching item | ||
716 | LLScrollListItem* LLScrollListCtrl::getItem(const LLSD& sd) const | ||
717 | { | ||
718 | LLString string_val = sd.asString(); | ||
719 | |||
720 | item_list::const_iterator iter; | ||
721 | for(iter = mItemList.begin(); iter != mItemList.end(); iter++) | ||
722 | { | ||
723 | LLScrollListItem* item = *iter; | ||
724 | // assumes string representation is good enough for comparison | ||
725 | if (item->getValue().asString() == string_val) | ||
726 | { | ||
727 | return item; | ||
728 | } | ||
729 | } | ||
730 | return NULL; | ||
731 | } | ||
732 | |||
623 | 733 | ||
624 | void LLScrollListCtrl::reshape( S32 width, S32 height, BOOL called_from_parent ) | 734 | void LLScrollListCtrl::reshape( S32 width, S32 height, BOOL called_from_parent ) |
625 | { | 735 | { |
626 | S32 old_height = mRect.getHeight(); | ||
627 | LLUICtrl::reshape( width, height, called_from_parent ); | 736 | LLUICtrl::reshape( width, height, called_from_parent ); |
628 | 737 | ||
629 | S32 heading_size = (mDisplayColumnHeaders ? mHeadingHeight : 0); | 738 | updateLayout(); |
739 | } | ||
630 | 740 | ||
741 | void LLScrollListCtrl::updateLayout() | ||
742 | { | ||
743 | // reserve room for column headers, if needed | ||
744 | S32 heading_size = (mDisplayColumnHeaders ? mHeadingHeight : 0); | ||
631 | mItemListRect.setOriginAndSize( | 745 | mItemListRect.setOriginAndSize( |
632 | mBorderThickness + LIST_BORDER_PAD, | 746 | mBorderThickness + LIST_BORDER_PAD, |
633 | mBorderThickness + LIST_BORDER_PAD, | 747 | mBorderThickness + LIST_BORDER_PAD, |
634 | mRect.getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ) - SCROLLBAR_SIZE, | 748 | mRect.getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ), |
635 | mRect.getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) - heading_size ); | 749 | mRect.getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) - heading_size ); |
636 | 750 | ||
751 | // how many lines of content in a single "page" | ||
637 | mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0; | 752 | mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0; |
638 | if(old_height < height && getScrollPos() == mScrollbar->getDocPosMax()) | 753 | BOOL scrollbar_visible = getItemCount() > mPageLines; |
754 | if (scrollbar_visible) | ||
639 | { | 755 | { |
640 | setScrollPos(mScrollbar->getDocPosMax()); | 756 | // provide space on the right for scrollbar |
757 | mItemListRect.mRight = mRect.getWidth() - ( mBorderThickness + LIST_BORDER_PAD ) - SCROLLBAR_SIZE; | ||
641 | } | 758 | } |
642 | mScrollbar->setVisible(mPageLines < getItemCount()); | 759 | |
760 | mScrollbar->reshape(SCROLLBAR_SIZE, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0)); | ||
643 | mScrollbar->setPageSize( mPageLines ); | 761 | mScrollbar->setPageSize( mPageLines ); |
644 | 762 | mScrollbar->setDocSize( getItemCount() ); | |
763 | mScrollbar->setVisible(scrollbar_visible); | ||
764 | |||
645 | updateColumns(); | 765 | updateColumns(); |
646 | } | 766 | } |
647 | 767 | ||
648 | // Attempt to size the control to show all items. | 768 | // Attempt to size the control to show all items. |
649 | // Do not make larger than width or height. | 769 | // Do not make larger than width or height. |
650 | void LLScrollListCtrl::arrange(S32 max_width, S32 max_height) | 770 | void LLScrollListCtrl::fitContents(S32 max_width, S32 max_height) |
651 | { | 771 | { |
652 | S32 height = mLineHeight * (getItemCount() + 1); | 772 | S32 height = llmin( getRequiredRect().getHeight(), max_height ); |
653 | height = llmin( height, max_height ); | ||
654 | |||
655 | S32 width = mRect.getWidth(); | 773 | S32 width = mRect.getWidth(); |
656 | 774 | ||
657 | reshape( width, height ); | 775 | reshape( width, height ); |
@@ -660,14 +778,17 @@ void LLScrollListCtrl::arrange(S32 max_width, S32 max_height) | |||
660 | 778 | ||
661 | LLRect LLScrollListCtrl::getRequiredRect() | 779 | LLRect LLScrollListCtrl::getRequiredRect() |
662 | { | 780 | { |
663 | S32 height = mLineHeight * (getItemCount() + 1); | 781 | S32 heading_size = (mDisplayColumnHeaders ? mHeadingHeight : 0); |
782 | S32 height = (mLineHeight * getItemCount()) | ||
783 | + (2 * ( mBorderThickness + LIST_BORDER_PAD )) | ||
784 | + heading_size; | ||
664 | S32 width = mRect.getWidth(); | 785 | S32 width = mRect.getWidth(); |
665 | 786 | ||
666 | return LLRect(0, height, width, 0); | 787 | return LLRect(0, height, width, 0); |
667 | } | 788 | } |
668 | 789 | ||
669 | 790 | ||
670 | BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos ) | 791 | BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL requires_column ) |
671 | { | 792 | { |
672 | BOOL not_too_big = getItemCount() < mMaxItemCount; | 793 | BOOL not_too_big = getItemCount() < mMaxItemCount; |
673 | if (not_too_big) | 794 | if (not_too_big) |
@@ -680,15 +801,22 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos ) | |||
680 | break; | 801 | break; |
681 | 802 | ||
682 | case ADD_SORTED: | 803 | case ADD_SORTED: |
683 | if (mSortColumn == -1) | ||
684 | { | 804 | { |
685 | mSortColumn = 0; | 805 | // sort by column 0, in ascending order |
686 | mSortAscending = TRUE; | 806 | std::vector<sort_column_t> single_sort_column; |
687 | } | 807 | single_sort_column.push_back(std::make_pair(0, TRUE)); |
688 | mItemList.push_back(item); | 808 | |
689 | std::sort(mItemList.begin(), mItemList.end(), SortScrollListItem(mSortColumn, mSortAscending)); | 809 | mItemList.push_back(item); |
690 | break; | 810 | std::stable_sort( |
691 | 811 | mItemList.begin(), | |
812 | mItemList.end(), | ||
813 | SortScrollListItem(single_sort_column)); | ||
814 | |||
815 | // ADD_SORTED just sorts by first column... | ||
816 | // this might not match user sort criteria, so flag list as being in unsorted state | ||
817 | setSorted(FALSE); | ||
818 | break; | ||
819 | } | ||
692 | case ADD_BOTTOM: | 820 | case ADD_BOTTOM: |
693 | mItemList.push_back(item); | 821 | mItemList.push_back(item); |
694 | setSorted(FALSE); | 822 | setSorted(FALSE); |
@@ -701,34 +829,42 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos ) | |||
701 | break; | 829 | break; |
702 | } | 830 | } |
703 | 831 | ||
704 | updateLineHeightInsert(item); | 832 | // create new column on demand |
705 | mPageLines = mLineHeight ? mItemListRect.getHeight() / mLineHeight : 0; | 833 | if (mColumns.empty() && requires_column) |
706 | BOOL scrollbar_visible = mPageLines < getItemCount(); | ||
707 | |||
708 | if (scrollbar_visible != mScrollbar->getVisible()) | ||
709 | { | 834 | { |
710 | mScrollbar->setVisible(mPageLines < getItemCount()); | 835 | LLSD new_column; |
711 | updateColumns(); | 836 | new_column["name"] = "default_column"; |
837 | new_column["label"] = ""; | ||
838 | new_column["dynamicwidth"] = TRUE; | ||
839 | addColumn(new_column); | ||
712 | } | 840 | } |
713 | mScrollbar->setPageSize( mPageLines ); | ||
714 | |||
715 | mScrollbar->setDocSize( getItemCount() ); | ||
716 | 841 | ||
717 | updateMaxContentWidth(item); | 842 | updateLineHeightInsert(item); |
843 | calcMaxContentWidth(item); | ||
844 | |||
845 | updateLayout(); | ||
718 | } | 846 | } |
719 | 847 | ||
720 | return not_too_big; | 848 | return not_too_big; |
721 | } | 849 | } |
722 | 850 | ||
723 | void LLScrollListCtrl::updateMaxContentWidth(LLScrollListItem* added_item) | 851 | void LLScrollListCtrl::calcMaxContentWidth(LLScrollListItem* added_item) |
724 | { | 852 | { |
725 | const S32 HEADING_TEXT_PADDING = 30; | 853 | const S32 HEADING_TEXT_PADDING = 30; |
726 | const S32 COLUMN_TEXT_PADDING = 20; | 854 | const S32 COLUMN_TEXT_PADDING = 20; |
727 | 855 | ||
728 | std::map<LLString, LLScrollListColumn>::iterator column_itor; | 856 | if (added_item == NULL) |
729 | for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor) | ||
730 | { | 857 | { |
731 | LLScrollListColumn* column = &column_itor->second; | 858 | mMaxContentWidth = 0; |
859 | } | ||
860 | |||
861 | S32 item_content_width = 0; | ||
862 | |||
863 | ordered_columns_t::iterator column_itor; | ||
864 | for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) | ||
865 | { | ||
866 | LLScrollListColumn* column = *column_itor; | ||
867 | if (!column) continue; | ||
732 | 868 | ||
733 | if (!added_item) | 869 | if (!added_item) |
734 | { | 870 | { |
@@ -740,7 +876,7 @@ void LLScrollListCtrl::updateMaxContentWidth(LLScrollListItem* added_item) | |||
740 | LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); | 876 | LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); |
741 | if (!cellp) continue; | 877 | if (!cellp) continue; |
742 | 878 | ||
743 | column->mMaxContentWidth = llmax(LLFontGL::sSansSerifSmall->getWidth(cellp->getText()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); | 879 | column->mMaxContentWidth = llmax(LLFontGL::sSansSerifSmall->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); |
744 | } | 880 | } |
745 | } | 881 | } |
746 | else | 882 | else |
@@ -748,9 +884,13 @@ void LLScrollListCtrl::updateMaxContentWidth(LLScrollListItem* added_item) | |||
748 | LLScrollListCell* cellp = added_item->getColumn(column->mIndex); | 884 | LLScrollListCell* cellp = added_item->getColumn(column->mIndex); |
749 | if (!cellp) continue; | 885 | if (!cellp) continue; |
750 | 886 | ||
751 | column->mMaxContentWidth = llmax(LLFontGL::sSansSerifSmall->getWidth(cellp->getText()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); | 887 | column->mMaxContentWidth = llmax(LLFontGL::sSansSerifSmall->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); |
752 | } | 888 | } |
889 | |||
890 | item_content_width += column->mMaxContentWidth; | ||
753 | } | 891 | } |
892 | |||
893 | mMaxContentWidth = llmax(mMaxContentWidth, item_content_width); | ||
754 | } | 894 | } |
755 | 895 | ||
756 | const S32 SCROLL_LIST_ROW_PAD = 2; | 896 | const S32 SCROLL_LIST_ROW_PAD = 2; |
@@ -789,7 +929,6 @@ void LLScrollListCtrl::updateColumns() | |||
789 | mColumnsIndexed.resize(mColumns.size()); | 929 | mColumnsIndexed.resize(mColumns.size()); |
790 | 930 | ||
791 | std::map<LLString, LLScrollListColumn>::iterator column_itor; | 931 | std::map<LLString, LLScrollListColumn>::iterator column_itor; |
792 | bool first_dynamic = true; | ||
793 | for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor) | 932 | for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor) |
794 | { | 933 | { |
795 | LLScrollListColumn *column = &column_itor->second; | 934 | LLScrollListColumn *column = &column_itor->second; |
@@ -801,11 +940,6 @@ void LLScrollListCtrl::updateColumns() | |||
801 | else if (column->mDynamicWidth) | 940 | else if (column->mDynamicWidth) |
802 | { | 941 | { |
803 | new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; | 942 | new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; |
804 | if(first_dynamic) | ||
805 | { | ||
806 | first_dynamic = false; | ||
807 | new_width += (mScrollbar->getVisible() ? 0 : SCROLLBAR_SIZE); | ||
808 | } | ||
809 | } | 943 | } |
810 | 944 | ||
811 | if (new_width != column->mWidth) | 945 | if (new_width != column->mWidth) |
@@ -854,48 +988,38 @@ void LLScrollListCtrl::updateColumns() | |||
854 | } | 988 | } |
855 | right = llmax(left, llmin(mItemListRect.getWidth(), right)); | 989 | right = llmax(left, llmin(mItemListRect.getWidth(), right)); |
856 | S32 header_width = right - left; | 990 | S32 header_width = right - left; |
857 | 991 | ||
858 | last_header->reshape(header_width, mHeadingHeight); | 992 | last_header->reshape(header_width, mHeadingHeight); |
859 | last_header->translate(left - last_header->getRect().mLeft, top - last_header->getRect().mBottom); | 993 | last_header->translate( |
994 | left - last_header->getRect().mLeft, | ||
995 | top - last_header->getRect().mBottom); | ||
860 | last_header->setVisible(mDisplayColumnHeaders && header_width > 0); | 996 | last_header->setVisible(mDisplayColumnHeaders && header_width > 0); |
861 | left = right; | 997 | left = right; |
862 | } | 998 | } |
863 | } | 999 | } |
864 | 1000 | ||
865 | // expand last column header we encountered to full list width | 1001 | // expand last column header we encountered to full list width |
866 | |||
867 | if (last_header) | 1002 | if (last_header) |
868 | { | 1003 | { |
869 | S32 header_strip_width = mItemListRect.getWidth() + (mScrollbar->getVisible() ? 0 : SCROLLBAR_SIZE); | 1004 | S32 new_width = llmax(0, mItemListRect.mRight - last_header->getRect().mLeft); |
870 | S32 new_width = llmax(0, mItemListRect.mLeft + header_strip_width - last_header->getRect().mLeft); | ||
871 | last_header->reshape(new_width, last_header->getRect().getHeight()); | 1005 | last_header->reshape(new_width, last_header->getRect().getHeight()); |
872 | last_header->setVisible(mDisplayColumnHeaders && new_width > 0); | 1006 | last_header->setVisible(mDisplayColumnHeaders && new_width > 0); |
873 | } | 1007 | } |
874 | |||
875 | } | 1008 | } |
876 | 1009 | ||
877 | void LLScrollListCtrl::setDisplayHeading(BOOL display) | 1010 | void LLScrollListCtrl::setDisplayHeading(BOOL display) |
878 | { | 1011 | { |
879 | mDisplayColumnHeaders = display; | 1012 | mDisplayColumnHeaders = display; |
880 | 1013 | ||
881 | updateColumns(); | 1014 | updateLayout(); |
882 | |||
883 | setHeadingHeight(mHeadingHeight); | ||
884 | } | 1015 | } |
885 | 1016 | ||
886 | void LLScrollListCtrl::setHeadingHeight(S32 heading_height) | 1017 | void LLScrollListCtrl::setHeadingHeight(S32 heading_height) |
887 | { | 1018 | { |
888 | mHeadingHeight = heading_height; | 1019 | mHeadingHeight = heading_height; |
889 | 1020 | ||
890 | reshape(mRect.getWidth(), mRect.getHeight()); | 1021 | updateLayout(); |
891 | |||
892 | // Resize | ||
893 | mScrollbar->reshape(SCROLLBAR_SIZE, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0)); | ||
894 | } | ||
895 | 1022 | ||
896 | void LLScrollListCtrl::setCollapseEmptyColumns(BOOL collapse) | ||
897 | { | ||
898 | mCollapseEmptyColumns = collapse; | ||
899 | } | 1023 | } |
900 | 1024 | ||
901 | BOOL LLScrollListCtrl::selectFirstItem() | 1025 | BOOL LLScrollListCtrl::selectFirstItem() |
@@ -934,6 +1058,8 @@ BOOL LLScrollListCtrl::selectFirstItem() | |||
934 | 1058 | ||
935 | BOOL LLScrollListCtrl::selectNthItem( S32 target_index ) | 1059 | BOOL LLScrollListCtrl::selectNthItem( S32 target_index ) |
936 | { | 1060 | { |
1061 | if (mItemList.empty()) return FALSE; | ||
1062 | |||
937 | // Deselects all other items | 1063 | // Deselects all other items |
938 | BOOL success = FALSE; | 1064 | BOOL success = FALSE; |
939 | S32 index = 0; | 1065 | S32 index = 0; |
@@ -1012,7 +1138,32 @@ void LLScrollListCtrl::deleteSingleItem(S32 target_index) | |||
1012 | } | 1138 | } |
1013 | delete itemp; | 1139 | delete itemp; |
1014 | mItemList.erase(mItemList.begin() + target_index); | 1140 | mItemList.erase(mItemList.begin() + target_index); |
1015 | updateMaxContentWidth(NULL); | 1141 | calcMaxContentWidth(NULL); |
1142 | } | ||
1143 | |||
1144 | //FIXME: refactor item deletion | ||
1145 | void LLScrollListCtrl::deleteItems(const LLSD& sd) | ||
1146 | { | ||
1147 | item_list::iterator iter; | ||
1148 | for (iter = mItemList.begin(); iter < mItemList.end(); ) | ||
1149 | { | ||
1150 | LLScrollListItem* itemp = *iter; | ||
1151 | if (itemp->getValue().asString() == sd.asString()) | ||
1152 | { | ||
1153 | if (itemp == mLastSelected) | ||
1154 | { | ||
1155 | mLastSelected = NULL; | ||
1156 | } | ||
1157 | delete itemp; | ||
1158 | mItemList.erase(iter++); | ||
1159 | } | ||
1160 | else | ||
1161 | { | ||
1162 | iter++; | ||
1163 | } | ||
1164 | } | ||
1165 | |||
1166 | calcMaxContentWidth(NULL); | ||
1016 | } | 1167 | } |
1017 | 1168 | ||
1018 | void LLScrollListCtrl::deleteSelectedItems() | 1169 | void LLScrollListCtrl::deleteSelectedItems() |
@@ -1032,7 +1183,7 @@ void LLScrollListCtrl::deleteSelectedItems() | |||
1032 | } | 1183 | } |
1033 | } | 1184 | } |
1034 | mLastSelected = NULL; | 1185 | mLastSelected = NULL; |
1035 | updateMaxContentWidth(NULL); | 1186 | calcMaxContentWidth(NULL); |
1036 | } | 1187 | } |
1037 | 1188 | ||
1038 | void LLScrollListCtrl::highlightNthItem(S32 target_index) | 1189 | void LLScrollListCtrl::highlightNthItem(S32 target_index) |
@@ -1108,7 +1259,8 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection) | |||
1108 | 1259 | ||
1109 | if (!getFirstSelected()) | 1260 | if (!getFirstSelected()) |
1110 | { | 1261 | { |
1111 | selectFirstItem(); | 1262 | // select last item |
1263 | selectNthItem(getItemCount() - 1); | ||
1112 | } | 1264 | } |
1113 | else | 1265 | else |
1114 | { | 1266 | { |
@@ -1130,7 +1282,8 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection) | |||
1130 | break; | 1282 | break; |
1131 | } | 1283 | } |
1132 | 1284 | ||
1133 | prev_item = cur_item; | 1285 | // don't allow navigation to disabled elements |
1286 | prev_item = cur_item->getEnabled() ? cur_item : prev_item; | ||
1134 | } | 1287 | } |
1135 | } | 1288 | } |
1136 | 1289 | ||
@@ -1145,32 +1298,34 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection) | |||
1145 | 1298 | ||
1146 | void LLScrollListCtrl::selectNextItem( BOOL extend_selection) | 1299 | void LLScrollListCtrl::selectNextItem( BOOL extend_selection) |
1147 | { | 1300 | { |
1301 | LLScrollListItem* next_item = NULL; | ||
1302 | |||
1148 | if (!getFirstSelected()) | 1303 | if (!getFirstSelected()) |
1149 | { | 1304 | { |
1150 | selectFirstItem(); | 1305 | selectFirstItem(); |
1151 | } | 1306 | } |
1152 | else | 1307 | else |
1153 | { | 1308 | { |
1154 | item_list::iterator iter; | 1309 | item_list::reverse_iterator iter; |
1155 | for (iter = mItemList.begin(); iter != mItemList.end(); iter++) | 1310 | for (iter = mItemList.rbegin(); iter != mItemList.rend(); iter++) |
1156 | { | 1311 | { |
1157 | LLScrollListItem* item = *iter; | 1312 | LLScrollListItem* cur_item = *iter; |
1158 | if (item->getSelected()) | 1313 | |
1314 | if (cur_item->getSelected()) | ||
1159 | { | 1315 | { |
1160 | if (++iter != mItemList.end()) | 1316 | if (next_item) |
1161 | { | 1317 | { |
1162 | LLScrollListItem *next_item = *iter; | 1318 | selectItem(next_item, !extend_selection); |
1163 | if (next_item) | 1319 | } |
1164 | { | 1320 | else |
1165 | selectItem(next_item, !extend_selection); | 1321 | { |
1166 | } | 1322 | reportInvalidInput(); |
1167 | else | ||
1168 | { | ||
1169 | reportInvalidInput(); | ||
1170 | } | ||
1171 | } | 1323 | } |
1172 | break; | 1324 | break; |
1173 | } | 1325 | } |
1326 | |||
1327 | // don't allow navigation to disabled items | ||
1328 | next_item = cur_item->getEnabled() ? cur_item : next_item; | ||
1174 | } | 1329 | } |
1175 | } | 1330 | } |
1176 | 1331 | ||
@@ -1200,27 +1355,31 @@ void LLScrollListCtrl::deselectAllItems(BOOL no_commit_on_change) | |||
1200 | } | 1355 | } |
1201 | 1356 | ||
1202 | /////////////////////////////////////////////////////////////////////////////////////////////////// | 1357 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
1203 | // "Simple" interface: use this when you're creating a list that contains only unique strings, only | 1358 | // Use this to add comment text such as "Searching", which ignores column settings of list |
1204 | // one of which can be selected at a time. | ||
1205 | 1359 | ||
1206 | LLScrollListItem* LLScrollListCtrl::addSimpleItem(const LLString& item_text, EAddPosition pos, BOOL enabled) | 1360 | LLScrollListItem* LLScrollListCtrl::addCommentText(const LLString& comment_text, EAddPosition pos) |
1207 | { | 1361 | { |
1208 | LLScrollListItem* item = NULL; | 1362 | LLScrollListItem* item = NULL; |
1209 | if (getItemCount() < mMaxItemCount) | 1363 | if (getItemCount() < mMaxItemCount) |
1210 | { | 1364 | { |
1211 | // simple items have their LLSD data set to their label | 1365 | // simple items have their LLSD data set to their label |
1212 | item = new LLScrollListItem( LLSD(item_text) ); | 1366 | // always draw comment text with "enabled" color |
1213 | item->setEnabled(enabled); | 1367 | item = new LLScrollListItemComment( comment_text, mFgUnselectedColor ); |
1214 | item->addColumn( item_text, gResMgr->getRes( LLFONT_SANSSERIF_SMALL ) ); | 1368 | addItem( item, pos, FALSE ); |
1215 | addItem( item, pos ); | ||
1216 | } | 1369 | } |
1217 | return item; | 1370 | return item; |
1218 | } | 1371 | } |
1219 | 1372 | ||
1373 | LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos) | ||
1374 | { | ||
1375 | LLScrollListItem* item = new LLScrollListItemSeparator(); | ||
1376 | addItem(item, pos, FALSE); | ||
1377 | return item; | ||
1378 | } | ||
1220 | 1379 | ||
1221 | // Selects first enabled item of the given name. | 1380 | // Selects first enabled item of the given name. |
1222 | // Returns false if item not found. | 1381 | // Returns false if item not found. |
1223 | BOOL LLScrollListCtrl::selectSimpleItem(const LLString& label, BOOL case_sensitive) | 1382 | BOOL LLScrollListCtrl::selectItemByLabel(const LLString& label, BOOL case_sensitive) |
1224 | { | 1383 | { |
1225 | //RN: assume no empty items | 1384 | //RN: assume no empty items |
1226 | if (label.empty()) | 1385 | if (label.empty()) |
@@ -1242,7 +1401,7 @@ BOOL LLScrollListCtrl::selectSimpleItem(const LLString& label, BOOL case_sensiti | |||
1242 | { | 1401 | { |
1243 | LLScrollListItem* item = *iter; | 1402 | LLScrollListItem* item = *iter; |
1244 | // Only select enabled items with matching names | 1403 | // Only select enabled items with matching names |
1245 | LLString item_text = item->getColumn(0)->getText(); | 1404 | LLString item_text = item->getColumn(0)->getValue().asString(); |
1246 | if (!case_sensitive) | 1405 | if (!case_sensitive) |
1247 | { | 1406 | { |
1248 | LLString::toLower(item_text); | 1407 | LLString::toLower(item_text); |
@@ -1265,14 +1424,14 @@ BOOL LLScrollListCtrl::selectSimpleItem(const LLString& label, BOOL case_sensiti | |||
1265 | } | 1424 | } |
1266 | 1425 | ||
1267 | 1426 | ||
1268 | BOOL LLScrollListCtrl::selectSimpleItemByPrefix(const LLString& target, BOOL case_sensitive) | 1427 | BOOL LLScrollListCtrl::selectItemByPrefix(const LLString& target, BOOL case_sensitive) |
1269 | { | 1428 | { |
1270 | return selectSimpleItemByPrefix(utf8str_to_wstring(target), case_sensitive); | 1429 | return selectItemByPrefix(utf8str_to_wstring(target), case_sensitive); |
1271 | } | 1430 | } |
1272 | 1431 | ||
1273 | // Selects first enabled item that has a name where the name's first part matched the target string. | 1432 | // Selects first enabled item that has a name where the name's first part matched the target string. |
1274 | // Returns false if item not found. | 1433 | // Returns false if item not found. |
1275 | BOOL LLScrollListCtrl::selectSimpleItemByPrefix(const LLWString& target, BOOL case_sensitive) | 1434 | BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sensitive) |
1276 | { | 1435 | { |
1277 | BOOL found = FALSE; | 1436 | BOOL found = FALSE; |
1278 | 1437 | ||
@@ -1288,7 +1447,7 @@ BOOL LLScrollListCtrl::selectSimpleItemByPrefix(const LLWString& target, BOOL ca | |||
1288 | LLScrollListItem* item = *iter; | 1447 | LLScrollListItem* item = *iter; |
1289 | // Only select enabled items with matching names | 1448 | // Only select enabled items with matching names |
1290 | LLScrollListCell* cellp = item->getColumn(mSearchColumn); | 1449 | LLScrollListCell* cellp = item->getColumn(mSearchColumn); |
1291 | BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getText()[0]) : FALSE; | 1450 | BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE; |
1292 | if (select) | 1451 | if (select) |
1293 | { | 1452 | { |
1294 | selectItem(item); | 1453 | selectItem(item); |
@@ -1315,7 +1474,7 @@ BOOL LLScrollListCtrl::selectSimpleItemByPrefix(const LLWString& target, BOOL ca | |||
1315 | { | 1474 | { |
1316 | continue; | 1475 | continue; |
1317 | } | 1476 | } |
1318 | LLWString item_label = utf8str_to_wstring(cellp->getText()); | 1477 | LLWString item_label = utf8str_to_wstring(cellp->getValue().asString()); |
1319 | if (!case_sensitive) | 1478 | if (!case_sensitive) |
1320 | { | 1479 | { |
1321 | LLWString::toLower(item_label); | 1480 | LLWString::toLower(item_label); |
@@ -1346,14 +1505,14 @@ BOOL LLScrollListCtrl::selectSimpleItemByPrefix(const LLWString& target, BOOL ca | |||
1346 | return found; | 1505 | return found; |
1347 | } | 1506 | } |
1348 | 1507 | ||
1349 | const LLString& LLScrollListCtrl::getSimpleSelectedItem(S32 column) const | 1508 | const LLString LLScrollListCtrl::getSelectedItemLabel(S32 column) const |
1350 | { | 1509 | { |
1351 | LLScrollListItem* item; | 1510 | LLScrollListItem* item; |
1352 | 1511 | ||
1353 | item = getFirstSelected(); | 1512 | item = getFirstSelected(); |
1354 | if (item) | 1513 | if (item) |
1355 | { | 1514 | { |
1356 | return item->getColumn(column)->getText(); | 1515 | return item->getColumn(column)->getValue().asString(); |
1357 | } | 1516 | } |
1358 | 1517 | ||
1359 | return LLString::null; | 1518 | return LLString::null; |
@@ -1375,20 +1534,6 @@ LLScrollListItem* LLScrollListCtrl::addStringUUIDItem(const LLString& item_text, | |||
1375 | return item; | 1534 | return item; |
1376 | } | 1535 | } |
1377 | 1536 | ||
1378 | LLScrollListItem* LLScrollListCtrl::addSimpleItem(const LLString& item_text, LLSD sd, EAddPosition pos, BOOL enabled, S32 column_width) | ||
1379 | { | ||
1380 | LLScrollListItem* item = NULL; | ||
1381 | if (getItemCount() < mMaxItemCount) | ||
1382 | { | ||
1383 | item = new LLScrollListItem( sd ); | ||
1384 | item->setEnabled(enabled); | ||
1385 | item->addColumn(item_text, gResMgr->getRes(LLFONT_SANSSERIF_SMALL), column_width); | ||
1386 | addItem( item, pos ); | ||
1387 | } | ||
1388 | return item; | ||
1389 | } | ||
1390 | |||
1391 | |||
1392 | // Select the line or lines that match this UUID | 1537 | // Select the line or lines that match this UUID |
1393 | BOOL LLScrollListCtrl::selectByID( const LLUUID& id ) | 1538 | BOOL LLScrollListCtrl::selectByID( const LLUUID& id ) |
1394 | { | 1539 | { |
@@ -1454,7 +1599,7 @@ LLUUID LLScrollListCtrl::getStringUUIDSelectedItem() | |||
1454 | return LLUUID::null; | 1599 | return LLUUID::null; |
1455 | } | 1600 | } |
1456 | 1601 | ||
1457 | LLSD LLScrollListCtrl::getSimpleSelectedValue() | 1602 | LLSD LLScrollListCtrl::getSelectedValue() |
1458 | { | 1603 | { |
1459 | LLScrollListItem* item = getFirstSelected(); | 1604 | LLScrollListItem* item = getFirstSelected(); |
1460 | 1605 | ||
@@ -1481,28 +1626,28 @@ void LLScrollListCtrl::drawItems() | |||
1481 | LLGLSUIDefault gls_ui; | 1626 | LLGLSUIDefault gls_ui; |
1482 | 1627 | ||
1483 | { | 1628 | { |
1484 | LLRect clip_rect = mItemListRect; | 1629 | LLLocalClipRect clip(mItemListRect); |
1485 | if(!mScrollbar->getVisible()) clip_rect.mRight += SCROLLBAR_SIZE; | ||
1486 | LLLocalClipRect clip(clip_rect); | ||
1487 | 1630 | ||
1488 | S32 cur_x = x; | ||
1489 | S32 cur_y = y; | 1631 | S32 cur_y = y; |
1490 | 1632 | ||
1491 | mDrewSelected = FALSE; | 1633 | mDrewSelected = FALSE; |
1492 | 1634 | ||
1493 | S32 line = 0; | 1635 | S32 line = 0; |
1494 | LLColor4 color; | ||
1495 | S32 max_columns = 0; | 1636 | S32 max_columns = 0; |
1496 | 1637 | ||
1638 | LLColor4 highlight_color = LLColor4::white; | ||
1639 | F32 type_ahead_timeout = LLUI::sConfigGroup->getF32("TypeAheadTimeout"); | ||
1640 | highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout, 0.4f, 0.f); | ||
1641 | |||
1497 | item_list::iterator iter; | 1642 | item_list::iterator iter; |
1498 | for (iter = mItemList.begin(); iter != mItemList.end(); iter++) | 1643 | for (iter = mItemList.begin(); iter != mItemList.end(); iter++) |
1499 | { | 1644 | { |
1500 | LLScrollListItem* item = *iter; | 1645 | LLScrollListItem* item = *iter; |
1501 | 1646 | ||
1502 | item_rect.setOriginAndSize( | 1647 | item_rect.setOriginAndSize( |
1503 | cur_x, | 1648 | x, |
1504 | cur_y, | 1649 | cur_y, |
1505 | mScrollbar->getVisible() ? mItemListRect.getWidth() : mItemListRect.getWidth() + SCROLLBAR_SIZE, | 1650 | mItemListRect.getWidth(), |
1506 | mLineHeight ); | 1651 | mLineHeight ); |
1507 | 1652 | ||
1508 | //llinfos << item_rect.getWidth() << llendl; | 1653 | //llinfos << item_rect.getWidth() << llendl; |
@@ -1514,85 +1659,37 @@ void LLScrollListCtrl::drawItems() | |||
1514 | 1659 | ||
1515 | max_columns = llmax(max_columns, item->getNumColumns()); | 1660 | max_columns = llmax(max_columns, item->getNumColumns()); |
1516 | 1661 | ||
1517 | LLRect bg_rect = item_rect; | 1662 | LLColor4 fg_color; |
1518 | // pad background rectangle to separate it from contents | 1663 | LLColor4 bg_color(LLColor4::transparent); |
1519 | bg_rect.stretch(LIST_BORDER_PAD, 0); | ||
1520 | 1664 | ||
1521 | if( mScrollLines <= line && line < mScrollLines + num_page_lines ) | 1665 | if( mScrollLines <= line && line < mScrollLines + num_page_lines ) |
1522 | { | 1666 | { |
1667 | fg_color = (item->getEnabled() ? mFgUnselectedColor : mFgDisabledColor); | ||
1523 | if( item->getSelected() && mCanSelect) | 1668 | if( item->getSelected() && mCanSelect) |
1524 | { | 1669 | { |
1525 | // Draw background of selected item | 1670 | // Draw background of selected item |
1526 | LLGLSNoTexture no_texture; | 1671 | bg_color = mBgSelectedColor; |
1527 | glColor4fv(mBgSelectedColor.mV); | 1672 | fg_color = (item->getEnabled() ? mFgSelectedColor : mFgDisabledColor); |
1528 | gl_rect_2d( bg_rect ); | ||
1529 | |||
1530 | color = mFgSelectedColor; | ||
1531 | } | 1673 | } |
1532 | else if (mHighlightedItem == line && mCanSelect) | 1674 | else if (mHighlightedItem == line && mCanSelect) |
1533 | { | 1675 | { |
1534 | LLGLSNoTexture no_texture; | 1676 | bg_color = mHighlightedColor; |
1535 | glColor4fv(mHighlightedColor.mV); | ||
1536 | gl_rect_2d( bg_rect ); | ||
1537 | color = (item->getEnabled() ? mFgUnselectedColor : mFgDisabledColor); | ||
1538 | } | 1677 | } |
1539 | else | 1678 | else |
1540 | { | 1679 | { |
1541 | color = (item->getEnabled() ? mFgUnselectedColor : mFgDisabledColor); | 1680 | if (mDrawStripes && (line % 2 == 0) && (max_columns > 1)) |
1542 | if (mDrawStripes && (line%2 == 0) && (max_columns > 1)) | ||
1543 | { | 1681 | { |
1544 | LLGLSNoTexture no_texture; | 1682 | bg_color = mBgStripeColor; |
1545 | glColor4fv(mBgStripeColor.mV); | ||
1546 | gl_rect_2d( bg_rect ); | ||
1547 | } | 1683 | } |
1548 | } | 1684 | } |
1549 | 1685 | ||
1550 | S32 line_x = cur_x; | 1686 | if (!item->getEnabled()) |
1551 | { | 1687 | { |
1552 | S32 num_cols = item->getNumColumns(); | 1688 | bg_color = mBgReadOnlyColor; |
1553 | S32 cur_col = 0; | 1689 | } |
1554 | S32 dynamic_width = 0; | ||
1555 | S32 dynamic_remainder = 0; | ||
1556 | bool first_dynamic = true; | ||
1557 | if(mNumDynamicWidthColumns > 0) | ||
1558 | { | ||
1559 | dynamic_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; | ||
1560 | dynamic_remainder = (mItemListRect.getWidth() - mTotalStaticColumnWidth) % mNumDynamicWidthColumns; | ||
1561 | } | ||
1562 | 1690 | ||
1563 | for (LLScrollListCell* cell = item->getColumn(0); cur_col < num_cols; cell = item->getColumn(++cur_col)) | 1691 | item->draw(item_rect, fg_color, bg_color, highlight_color, mColumnPadding); |
1564 | { | ||
1565 | S32 cell_width = cell->getWidth(); | ||
1566 | |||
1567 | if(mColumnsIndexed.size() > (U32)cur_col && mColumnsIndexed[cur_col] && mColumnsIndexed[cur_col]->mDynamicWidth) | ||
1568 | { | ||
1569 | cell_width = dynamic_width + (--dynamic_remainder ? 1 : 0); | ||
1570 | if(first_dynamic) | ||
1571 | { | ||
1572 | cell_width += mScrollbar->getVisible() ? 0 : SCROLLBAR_SIZE; | ||
1573 | first_dynamic = false; | ||
1574 | } | ||
1575 | cell->setWidth(cell_width); | ||
1576 | } | ||
1577 | // Two ways a cell could be hidden | ||
1578 | if (cell_width < 0 | ||
1579 | || !cell->getVisible()) continue; | ||
1580 | |||
1581 | LLUI::pushMatrix(); | ||
1582 | LLUI::translate((F32) cur_x, (F32) cur_y, 0.0f); | ||
1583 | S32 space_left = mItemListRect.mRight - cur_x; | ||
1584 | LLColor4 highlight_color = LLColor4::white; | ||
1585 | F32 type_ahead_timeout = LLUI::sConfigGroup->getF32("TypeAheadTimeout"); | ||
1586 | |||
1587 | highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout, 0.4f, 0.f); | ||
1588 | cell->drawToWidth( space_left, color, highlight_color ); | ||
1589 | LLUI::popMatrix(); | ||
1590 | |||
1591 | cur_x += cell_width + mColumnPadding; | ||
1592 | 1692 | ||
1593 | } | ||
1594 | } | ||
1595 | cur_x = line_x; | ||
1596 | cur_y -= mLineHeight; | 1693 | cur_y -= mLineHeight; |
1597 | } | 1694 | } |
1598 | line++; | 1695 | line++; |
@@ -1605,6 +1702,12 @@ void LLScrollListCtrl::draw() | |||
1605 | { | 1702 | { |
1606 | if( getVisible() ) | 1703 | if( getVisible() ) |
1607 | { | 1704 | { |
1705 | // if user specifies sort, make sure it is maintained | ||
1706 | if (needsSorting() && !isSorted()) | ||
1707 | { | ||
1708 | sortItems(); | ||
1709 | } | ||
1710 | |||
1608 | if (mNeedsScroll) | 1711 | if (mNeedsScroll) |
1609 | { | 1712 | { |
1610 | scrollToShowSelected(); | 1713 | scrollToShowSelected(); |
@@ -1645,6 +1748,54 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks) | |||
1645 | return handled; | 1748 | return handled; |
1646 | } | 1749 | } |
1647 | 1750 | ||
1751 | BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) | ||
1752 | { | ||
1753 | S32 column_index = getColumnIndexFromOffset(x); | ||
1754 | LLScrollListColumn* columnp = getColumn(column_index); | ||
1755 | |||
1756 | if (columnp == NULL) return FALSE; | ||
1757 | |||
1758 | BOOL handled = FALSE; | ||
1759 | // show tooltip for full name of hovered item if it has been truncated | ||
1760 | LLScrollListItem* hit_item = hitItem(x, y); | ||
1761 | if (hit_item) | ||
1762 | { | ||
1763 | LLScrollListCell* hit_cell = hit_item->getColumn(column_index); | ||
1764 | if (!hit_cell) return FALSE; | ||
1765 | S32 cell_required_width = hit_cell->getContentWidth(); | ||
1766 | if (hit_cell | ||
1767 | && hit_cell->isText() | ||
1768 | && cell_required_width > columnp->mWidth) | ||
1769 | { | ||
1770 | |||
1771 | S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft; | ||
1772 | S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item)); | ||
1773 | LLRect cell_rect; | ||
1774 | cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->mWidth, mLineHeight); | ||
1775 | // Convert rect local to screen coordinates | ||
1776 | localPointToScreen( | ||
1777 | cell_rect.mLeft, cell_rect.mBottom, | ||
1778 | &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); | ||
1779 | localPointToScreen( | ||
1780 | cell_rect.mRight, cell_rect.mTop, | ||
1781 | &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); | ||
1782 | |||
1783 | msg = hit_cell->getValue().asString(); | ||
1784 | handled = TRUE; | ||
1785 | } | ||
1786 | } | ||
1787 | |||
1788 | // otherwise, look for a tooltip associated with this column | ||
1789 | LLColumnHeader* headerp = columnp->mHeader; | ||
1790 | if (headerp && !handled) | ||
1791 | { | ||
1792 | headerp->handleToolTip(x, y, msg, sticky_rect_screen); | ||
1793 | handled = !msg.empty(); | ||
1794 | } | ||
1795 | |||
1796 | return handled; | ||
1797 | } | ||
1798 | |||
1648 | BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) | 1799 | BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) |
1649 | { | 1800 | { |
1650 | if (!mCanSelect) return FALSE; | 1801 | if (!mCanSelect) return FALSE; |
@@ -1652,6 +1803,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) | |||
1652 | BOOL selection_changed = FALSE; | 1803 | BOOL selection_changed = FALSE; |
1653 | 1804 | ||
1654 | LLScrollListItem* hit_item = hitItem(x, y); | 1805 | LLScrollListItem* hit_item = hitItem(x, y); |
1806 | |||
1655 | if( hit_item ) | 1807 | if( hit_item ) |
1656 | { | 1808 | { |
1657 | if( mAllowMultipleSelection ) | 1809 | if( mAllowMultipleSelection ) |
@@ -1686,6 +1838,11 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) | |||
1686 | { | 1838 | { |
1687 | selectItem(item, FALSE); | 1839 | selectItem(item, FALSE); |
1688 | selecting = !selecting; | 1840 | selecting = !selecting; |
1841 | if (hit_item == lastSelected) | ||
1842 | { | ||
1843 | // stop selecting now, since we just clicked on our last selected item | ||
1844 | selecting = FALSE; | ||
1845 | } | ||
1689 | } | 1846 | } |
1690 | if (selecting) | 1847 | if (selecting) |
1691 | { | 1848 | { |
@@ -1726,9 +1883,6 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) | |||
1726 | selectItem(hit_item); | 1883 | selectItem(hit_item); |
1727 | } | 1884 | } |
1728 | 1885 | ||
1729 | hit_item->handleClick(x - mBorderThickness - LIST_BORDER_PAD, | ||
1730 | 1, mask); | ||
1731 | |||
1732 | selection_changed = mSelectionChanged; | 1886 | selection_changed = mSelectionChanged; |
1733 | if (mCommitOnSelectionChange) | 1887 | if (mCommitOnSelectionChange) |
1734 | { | 1888 | { |
@@ -1750,19 +1904,17 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) | |||
1750 | 1904 | ||
1751 | BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask) | 1905 | BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask) |
1752 | { | 1906 | { |
1753 | BOOL handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL; | 1907 | BOOL handled = childrenHandleMouseDown(x, y, mask) != NULL; |
1754 | 1908 | ||
1755 | if( !handled ) | 1909 | if( !handled ) |
1756 | { | 1910 | { |
1757 | // set keyboard focus first, in case click action wants to move focus elsewhere | 1911 | // set keyboard focus first, in case click action wants to move focus elsewhere |
1758 | setFocus(TRUE); | 1912 | setFocus(TRUE); |
1759 | 1913 | ||
1760 | // clear selection changed flag so because user is starting a selection operation | 1914 | // clear selection changed flag because user is starting a selection operation |
1761 | mSelectionChanged = FALSE; | 1915 | mSelectionChanged = FALSE; |
1762 | 1916 | ||
1763 | gFocusMgr.setMouseCapture(this); | 1917 | handleClick(x, y, mask); |
1764 | selectItemAt(x, y, mask); | ||
1765 | mNeedsScroll = TRUE; | ||
1766 | } | 1918 | } |
1767 | 1919 | ||
1768 | return TRUE; | 1920 | return TRUE; |
@@ -1798,19 +1950,79 @@ BOOL LLScrollListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask) | |||
1798 | //BOOL handled = FALSE; | 1950 | //BOOL handled = FALSE; |
1799 | if(getVisible()) | 1951 | if(getVisible()) |
1800 | { | 1952 | { |
1801 | // Offer the click to the children, even if we aren't enabled | 1953 | BOOL handled = handleClick(x, y, mask); |
1802 | // so the scroll bars will work. | 1954 | |
1803 | if (NULL == LLView::childrenHandleDoubleClick(x, y, mask)) | 1955 | if (!handled) |
1804 | { | 1956 | { |
1805 | if( mCanSelect && mOnDoubleClickCallback ) | 1957 | // Offer the click to the children, even if we aren't enabled |
1958 | // so the scroll bars will work. | ||
1959 | if (NULL == LLView::childrenHandleDoubleClick(x, y, mask)) | ||
1806 | { | 1960 | { |
1807 | mOnDoubleClickCallback( mCallbackUserData ); | 1961 | if( mCanSelect && mOnDoubleClickCallback ) |
1962 | { | ||
1963 | mOnDoubleClickCallback( mCallbackUserData ); | ||
1964 | } | ||
1808 | } | 1965 | } |
1809 | } | 1966 | } |
1810 | } | 1967 | } |
1811 | return TRUE; | 1968 | return TRUE; |
1812 | } | 1969 | } |
1813 | 1970 | ||
1971 | BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) | ||
1972 | { | ||
1973 | // which row was clicked on? | ||
1974 | LLScrollListItem* hit_item = hitItem(x, y); | ||
1975 | if (!hit_item) return FALSE; | ||
1976 | |||
1977 | // get appropriate cell from that row | ||
1978 | S32 column_index = getColumnIndexFromOffset(x); | ||
1979 | LLScrollListCell* hit_cell = hit_item->getColumn(column_index); | ||
1980 | if (!hit_cell) return FALSE; | ||
1981 | |||
1982 | // if cell handled click directly (i.e. clicked on an embedded checkbox) | ||
1983 | if (hit_cell->handleClick()) | ||
1984 | { | ||
1985 | // if item not currently selected, select it | ||
1986 | if (!hit_item->getSelected()) | ||
1987 | { | ||
1988 | selectItemAt(x, y, mask); | ||
1989 | gFocusMgr.setMouseCapture(this); | ||
1990 | mNeedsScroll = TRUE; | ||
1991 | } | ||
1992 | // otherwise we already have this item selected | ||
1993 | // so propagate state of cell to rest of selected column | ||
1994 | else | ||
1995 | { | ||
1996 | // propagate value of this cell to other selected items | ||
1997 | // and commit the respective widgets | ||
1998 | LLSD item_value = hit_cell->getValue(); | ||
1999 | for (item_list::iterator iter = mItemList.begin(); iter != mItemList.end(); iter++) | ||
2000 | { | ||
2001 | LLScrollListItem* item = *iter; | ||
2002 | if (item->getSelected()) | ||
2003 | { | ||
2004 | LLScrollListCell* cellp = item->getColumn(column_index); | ||
2005 | cellp->setValue(item_value); | ||
2006 | cellp->onCommit(); | ||
2007 | } | ||
2008 | } | ||
2009 | //FIXME: find a better way to signal cell changes | ||
2010 | onCommit(); | ||
2011 | } | ||
2012 | // eat click (e.g. do not trigger double click callback) | ||
2013 | return TRUE; | ||
2014 | } | ||
2015 | else | ||
2016 | { | ||
2017 | // treat this as a normal single item selection | ||
2018 | selectItemAt(x, y, mask); | ||
2019 | gFocusMgr.setMouseCapture(this); | ||
2020 | mNeedsScroll = TRUE; | ||
2021 | // do not eat click (allow double click callback) | ||
2022 | return FALSE; | ||
2023 | } | ||
2024 | } | ||
2025 | |||
1814 | LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y ) | 2026 | LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y ) |
1815 | { | 2027 | { |
1816 | // Excludes disabled items. | 2028 | // Excludes disabled items. |
@@ -1847,6 +2059,59 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y ) | |||
1847 | return hit_item; | 2059 | return hit_item; |
1848 | } | 2060 | } |
1849 | 2061 | ||
2062 | S32 LLScrollListCtrl::getColumnIndexFromOffset(S32 x) | ||
2063 | { | ||
2064 | // which column did we hit? | ||
2065 | S32 left = 0; | ||
2066 | S32 right = 0; | ||
2067 | S32 width = 0; | ||
2068 | S32 column_index = 0; | ||
2069 | |||
2070 | ordered_columns_t::const_iterator iter = mColumnsIndexed.begin(); | ||
2071 | ordered_columns_t::const_iterator end = mColumnsIndexed.end(); | ||
2072 | for ( ; iter != end; ++iter) | ||
2073 | { | ||
2074 | width = (*iter)->mWidth + mColumnPadding; | ||
2075 | right += width; | ||
2076 | if (left <= x && x < right ) | ||
2077 | { | ||
2078 | break; | ||
2079 | } | ||
2080 | |||
2081 | // set left for next column as right of current column | ||
2082 | left = right; | ||
2083 | column_index++; | ||
2084 | } | ||
2085 | |||
2086 | return llclamp(column_index, 0, getNumColumns() - 1); | ||
2087 | } | ||
2088 | |||
2089 | |||
2090 | S32 LLScrollListCtrl::getColumnOffsetFromIndex(S32 index) | ||
2091 | { | ||
2092 | S32 column_offset = 0; | ||
2093 | ordered_columns_t::const_iterator iter = mColumnsIndexed.begin(); | ||
2094 | ordered_columns_t::const_iterator end = mColumnsIndexed.end(); | ||
2095 | for ( ; iter != end; ++iter) | ||
2096 | { | ||
2097 | if (index-- <= 0) | ||
2098 | { | ||
2099 | return column_offset; | ||
2100 | } | ||
2101 | column_offset += (*iter)->mWidth + mColumnPadding; | ||
2102 | } | ||
2103 | |||
2104 | // when running off the end, return the rightmost pixel | ||
2105 | return mItemListRect.mRight; | ||
2106 | } | ||
2107 | |||
2108 | S32 LLScrollListCtrl::getRowOffsetFromIndex(S32 index) | ||
2109 | { | ||
2110 | S32 row_bottom = ((mItemListRect.mTop - (index - mScrollLines)) * mLineHeight) | ||
2111 | - mLineHeight; | ||
2112 | return row_bottom; | ||
2113 | } | ||
2114 | |||
1850 | 2115 | ||
1851 | BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) | 2116 | BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) |
1852 | { | 2117 | { |
@@ -1860,7 +2125,8 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) | |||
1860 | mNeedsScroll = TRUE; | 2125 | mNeedsScroll = TRUE; |
1861 | } | 2126 | } |
1862 | } | 2127 | } |
1863 | else if (mCanSelect) | 2128 | else |
2129 | if (mCanSelect) | ||
1864 | { | 2130 | { |
1865 | LLScrollListItem* item = hitItem(x, y); | 2131 | LLScrollListItem* item = hitItem(x, y); |
1866 | if (item) | 2132 | if (item) |
@@ -1875,13 +2141,6 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) | |||
1875 | 2141 | ||
1876 | handled = LLUICtrl::handleHover( x, y, mask ); | 2142 | handled = LLUICtrl::handleHover( x, y, mask ); |
1877 | 2143 | ||
1878 | //if( !handled ) | ||
1879 | //{ | ||
1880 | // // Opaque | ||
1881 | // getWindow()->setCursor(UI_CURSOR_ARROW); | ||
1882 | // lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; | ||
1883 | // handled = TRUE; | ||
1884 | //} | ||
1885 | return handled; | 2144 | return handled; |
1886 | } | 2145 | } |
1887 | 2146 | ||
@@ -1998,7 +2257,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask, BOOL called_from_parent | |||
1998 | } | 2257 | } |
1999 | } | 2258 | } |
2000 | } | 2259 | } |
2001 | else if (selectSimpleItemByPrefix(wstring_to_utf8str(mSearchString), FALSE)) | 2260 | else if (selectItemByPrefix(wstring_to_utf8str(mSearchString), FALSE)) |
2002 | { | 2261 | { |
2003 | mNeedsScroll = TRUE; | 2262 | mNeedsScroll = TRUE; |
2004 | // update search string only on successful match | 2263 | // update search string only on successful match |
@@ -2037,7 +2296,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_ | |||
2037 | // type ahead search is case insensitive | 2296 | // type ahead search is case insensitive |
2038 | uni_char = LLStringOps::toLower((llwchar)uni_char); | 2297 | uni_char = LLStringOps::toLower((llwchar)uni_char); |
2039 | 2298 | ||
2040 | if (selectSimpleItemByPrefix(wstring_to_utf8str(mSearchString + (llwchar)uni_char), FALSE)) | 2299 | if (selectItemByPrefix(wstring_to_utf8str(mSearchString + (llwchar)uni_char), FALSE)) |
2041 | { | 2300 | { |
2042 | // update search string only on successful match | 2301 | // update search string only on successful match |
2043 | mNeedsScroll = TRUE; | 2302 | mNeedsScroll = TRUE; |
@@ -2082,7 +2341,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_ | |||
2082 | if (cellp) | 2341 | if (cellp) |
2083 | { | 2342 | { |
2084 | // Only select enabled items with matching first characters | 2343 | // Only select enabled items with matching first characters |
2085 | LLWString item_label = utf8str_to_wstring(cellp->getText()); | 2344 | LLWString item_label = utf8str_to_wstring(cellp->getValue().asString()); |
2086 | if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char) | 2345 | if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char) |
2087 | { | 2346 | { |
2088 | selectItem(item); | 2347 | selectItem(item); |
@@ -2176,7 +2435,7 @@ void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp) | |||
2176 | LLScrollListCell* cellp = itemp->getColumn(mSearchColumn); | 2435 | LLScrollListCell* cellp = itemp->getColumn(mSearchColumn); |
2177 | if (cellp) | 2436 | if (cellp) |
2178 | { | 2437 | { |
2179 | cellp->highlightText(0, 0); | 2438 | cellp->highlightText(0, 0); |
2180 | } | 2439 | } |
2181 | mSelectionChanged = TRUE; | 2440 | mSelectionChanged = TRUE; |
2182 | } | 2441 | } |
@@ -2202,38 +2461,52 @@ BOOL LLScrollListCtrl::isSorted() | |||
2202 | return mSorted; | 2461 | return mSorted; |
2203 | } | 2462 | } |
2204 | 2463 | ||
2205 | // Called by scrollbar | 2464 | struct SameSortColumn |
2206 | //static | ||
2207 | void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void* userdata ) | ||
2208 | { | 2465 | { |
2209 | LLScrollListCtrl* self = (LLScrollListCtrl*) userdata; | 2466 | SameSortColumn(S32 column) : mColumn(column) {} |
2210 | self->mScrollLines = new_pos; | 2467 | S32 mColumn; |
2211 | } | ||
2212 | 2468 | ||
2469 | bool operator()(std::pair<S32, BOOL> sort_column) { return sort_column.first == mColumn; } | ||
2470 | }; | ||
2213 | 2471 | ||
2214 | // First column is column 0 | 2472 | BOOL LLScrollListCtrl::setSort(S32 column, BOOL ascending) |
2215 | void LLScrollListCtrl::sortByColumn(U32 column, BOOL ascending) | ||
2216 | { | 2473 | { |
2217 | if (!mSorted || mSortColumn != column) | 2474 | sort_column_t new_sort_column(column, ascending); |
2475 | |||
2476 | if (mSortColumns.empty()) | ||
2218 | { | 2477 | { |
2219 | mSortColumn = column; | 2478 | mSortColumns.push_back(new_sort_column); |
2220 | std::sort(mItemList.begin(), mItemList.end(), SortScrollListItem(mSortColumn, mSortAscending)); | 2479 | return TRUE; |
2221 | setSorted(TRUE); | ||
2222 | } | 2480 | } |
2481 | else | ||
2482 | { | ||
2483 | // grab current sort column | ||
2484 | sort_column_t cur_sort_column = mSortColumns.back(); | ||
2485 | |||
2486 | // remove any existing sort criterion referencing this column | ||
2487 | // and add the new one | ||
2488 | mSortColumns.erase(remove_if(mSortColumns.begin(), mSortColumns.end(), SameSortColumn(column)), mSortColumns.end()); | ||
2489 | mSortColumns.push_back(new_sort_column); | ||
2223 | 2490 | ||
2224 | // just reverse the list if changing sort order | 2491 | // did the sort criteria change? |
2225 | if(mSortAscending != ascending) | 2492 | return (cur_sort_column != new_sort_column); |
2226 | { | ||
2227 | std::reverse(mItemList.begin(), mItemList.end()); | ||
2228 | mSortAscending = ascending; | ||
2229 | } | 2493 | } |
2230 | } | 2494 | } |
2231 | 2495 | ||
2496 | // Called by scrollbar | ||
2497 | //static | ||
2498 | void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void* userdata ) | ||
2499 | { | ||
2500 | LLScrollListCtrl* self = (LLScrollListCtrl*) userdata; | ||
2501 | self->mScrollLines = new_pos; | ||
2502 | } | ||
2503 | |||
2504 | |||
2232 | void LLScrollListCtrl::sortByColumn(LLString name, BOOL ascending) | 2505 | void LLScrollListCtrl::sortByColumn(LLString name, BOOL ascending) |
2233 | { | 2506 | { |
2234 | if (name.empty()) | 2507 | if (name.empty()) |
2235 | { | 2508 | { |
2236 | sortByColumn(mSortColumn, mSortAscending); | 2509 | sortItems(); |
2237 | return; | 2510 | return; |
2238 | } | 2511 | } |
2239 | 2512 | ||
@@ -2244,6 +2517,26 @@ void LLScrollListCtrl::sortByColumn(LLString name, BOOL ascending) | |||
2244 | } | 2517 | } |
2245 | } | 2518 | } |
2246 | 2519 | ||
2520 | // First column is column 0 | ||
2521 | void LLScrollListCtrl::sortByColumn(U32 column, BOOL ascending) | ||
2522 | { | ||
2523 | if (setSort(column, ascending)) | ||
2524 | { | ||
2525 | sortItems(); | ||
2526 | } | ||
2527 | } | ||
2528 | |||
2529 | void LLScrollListCtrl::sortItems() | ||
2530 | { | ||
2531 | // do stable sort to preserve any previous sorts | ||
2532 | std::stable_sort( | ||
2533 | mItemList.begin(), | ||
2534 | mItemList.end(), | ||
2535 | SortScrollListItem(mSortColumns)); | ||
2536 | |||
2537 | setSorted(TRUE); | ||
2538 | } | ||
2539 | |||
2247 | S32 LLScrollListCtrl::getScrollPos() | 2540 | S32 LLScrollListCtrl::getScrollPos() |
2248 | { | 2541 | { |
2249 | return mScrollbar->getDocPos(); | 2542 | return mScrollbar->getDocPos(); |
@@ -2431,9 +2724,6 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac | |||
2431 | BOOL draw_heading = FALSE; | 2724 | BOOL draw_heading = FALSE; |
2432 | node->getAttributeBOOL("draw_heading", draw_heading); | 2725 | node->getAttributeBOOL("draw_heading", draw_heading); |
2433 | 2726 | ||
2434 | BOOL collapse_empty_columns = FALSE; | ||
2435 | node->getAttributeBOOL("collapse_empty_columns", collapse_empty_columns); | ||
2436 | |||
2437 | S32 search_column = 0; | 2727 | S32 search_column = 0; |
2438 | node->getAttributeS32("search_column", search_column); | 2728 | node->getAttributeS32("search_column", search_column); |
2439 | 2729 | ||
@@ -2454,7 +2744,6 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac | |||
2454 | node->getAttributeS32("heading_height", heading_height); | 2744 | node->getAttributeS32("heading_height", heading_height); |
2455 | scroll_list->setHeadingHeight(heading_height); | 2745 | scroll_list->setHeadingHeight(heading_height); |
2456 | } | 2746 | } |
2457 | scroll_list->setCollapseEmptyColumns(collapse_empty_columns); | ||
2458 | 2747 | ||
2459 | scroll_list->setScrollListParameters(node); | 2748 | scroll_list->setScrollListParameters(node); |
2460 | 2749 | ||
@@ -2465,7 +2754,7 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac | |||
2465 | LLSD columns; | 2754 | LLSD columns; |
2466 | S32 index = 0; | 2755 | S32 index = 0; |
2467 | LLXMLNodePtr child; | 2756 | LLXMLNodePtr child; |
2468 | S32 total_static = 0, num_dynamic = 0; | 2757 | S32 total_static = 0; |
2469 | for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) | 2758 | for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) |
2470 | { | 2759 | { |
2471 | if (child->hasName("column")) | 2760 | if (child->hasName("column")) |
@@ -2491,8 +2780,10 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac | |||
2491 | S32 columnwidth = -1; | 2780 | S32 columnwidth = -1; |
2492 | child->getAttributeS32("width", columnwidth); | 2781 | child->getAttributeS32("width", columnwidth); |
2493 | 2782 | ||
2494 | if(!columndynamicwidth) total_static += columnwidth; | 2783 | LLString tooltip; |
2495 | else ++num_dynamic; | 2784 | child->getAttributeString("tool_tip", tooltip); |
2785 | |||
2786 | if(!columndynamicwidth) total_static += llmax(0, columnwidth); | ||
2496 | 2787 | ||
2497 | F32 columnrelwidth = 0.f; | 2788 | F32 columnrelwidth = 0.f; |
2498 | child->getAttributeF32("relwidth", columnrelwidth); | 2789 | child->getAttributeF32("relwidth", columnrelwidth); |
@@ -2509,10 +2800,11 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac | |||
2509 | columns[index]["relwidth"] = columnrelwidth; | 2800 | columns[index]["relwidth"] = columnrelwidth; |
2510 | columns[index]["dynamicwidth"] = columndynamicwidth; | 2801 | columns[index]["dynamicwidth"] = columndynamicwidth; |
2511 | columns[index]["halign"] = (S32)h_align; | 2802 | columns[index]["halign"] = (S32)h_align; |
2803 | columns[index]["tool_tip"] = tooltip; | ||
2804 | |||
2512 | index++; | 2805 | index++; |
2513 | } | 2806 | } |
2514 | } | 2807 | } |
2515 | scroll_list->setNumDynamicColumns(num_dynamic); | ||
2516 | scroll_list->setTotalStaticColumnWidth(total_static); | 2808 | scroll_list->setTotalStaticColumnWidth(total_static); |
2517 | scroll_list->setColumnHeadings(columns); | 2809 | scroll_list->setColumnHeadings(columns); |
2518 | 2810 | ||
@@ -2566,7 +2858,7 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac | |||
2566 | while(token_iter != tokens.end()) | 2858 | while(token_iter != tokens.end()) |
2567 | { | 2859 | { |
2568 | const char* line = token_iter->c_str(); | 2860 | const char* line = token_iter->c_str(); |
2569 | scroll_list->addSimpleItem(line); | 2861 | scroll_list->addSimpleElement(line); |
2570 | ++token_iter; | 2862 | ++token_iter; |
2571 | } | 2863 | } |
2572 | } | 2864 | } |
@@ -2663,10 +2955,6 @@ BOOL LLScrollListCtrl::canDeselect() | |||
2663 | void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) | 2955 | void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) |
2664 | { | 2956 | { |
2665 | LLString name = column["name"].asString(); | 2957 | LLString name = column["name"].asString(); |
2666 | if (mColumns.empty()) | ||
2667 | { | ||
2668 | mDefaultColumn = 0; | ||
2669 | } | ||
2670 | // if no column name provided, just use ordinal as name | 2958 | // if no column name provided, just use ordinal as name |
2671 | if (name.empty()) | 2959 | if (name.empty()) |
2672 | { | 2960 | { |
@@ -2691,6 +2979,7 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) | |||
2691 | } | 2979 | } |
2692 | else if(new_column->mDynamicWidth) | 2980 | else if(new_column->mDynamicWidth) |
2693 | { | 2981 | { |
2982 | mNumDynamicWidthColumns++; | ||
2694 | new_column->mWidth = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; | 2983 | new_column->mWidth = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; |
2695 | } | 2984 | } |
2696 | S32 top = mItemListRect.mTop; | 2985 | S32 top = mItemListRect.mTop; |
@@ -2724,19 +3013,19 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) | |||
2724 | new_column->mHeader->setLabel(new_column->mLabel); | 3013 | new_column->mHeader->setLabel(new_column->mLabel); |
2725 | //new_column->mHeader->setLabel(new_column->mLabel); | 3014 | //new_column->mHeader->setLabel(new_column->mLabel); |
2726 | } | 3015 | } |
3016 | |||
3017 | new_column->mHeader->setToolTip(column["tool_tip"].asString()); | ||
3018 | |||
2727 | //RN: although it might be useful to change sort order with the keyboard, | 3019 | //RN: although it might be useful to change sort order with the keyboard, |
2728 | // mixing tab stops on child items along with the parent item is not supported yet | 3020 | // mixing tab stops on child items along with the parent item is not supported yet |
2729 | new_column->mHeader->setTabStop(FALSE); | 3021 | new_column->mHeader->setTabStop(FALSE); |
2730 | addChild(new_column->mHeader); | 3022 | addChild(new_column->mHeader); |
2731 | new_column->mHeader->setVisible(mDisplayColumnHeaders); | 3023 | new_column->mHeader->setVisible(mDisplayColumnHeaders); |
2732 | 3024 | ||
2733 | 3025 | sendChildToFront(mScrollbar); | |
2734 | // Move scroll to front | ||
2735 | removeChild(mScrollbar); | ||
2736 | addChild(mScrollbar); | ||
2737 | |||
2738 | } | 3026 | } |
2739 | } | 3027 | } |
3028 | |||
2740 | updateColumns(); | 3029 | updateColumns(); |
2741 | } | 3030 | } |
2742 | 3031 | ||
@@ -2753,18 +3042,18 @@ void LLScrollListCtrl::onClickColumn(void *userdata) | |||
2753 | 3042 | ||
2754 | LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex]; | 3043 | LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex]; |
2755 | bool ascending = column->mSortAscending; | 3044 | bool ascending = column->mSortAscending; |
2756 | if (column->mSortingColumn != column->mName) | 3045 | if (column->mSortingColumn != column->mName |
3046 | && parent->mColumns.find(column->mSortingColumn) != parent->mColumns.end()) | ||
2757 | { | 3047 | { |
2758 | if (parent->mColumns.find(column->mSortingColumn) != parent->mColumns.end()) | 3048 | LLScrollListColumn& info_redir = parent->mColumns[column->mSortingColumn]; |
2759 | { | 3049 | column_index = info_redir.mIndex; |
2760 | LLScrollListColumn& info_redir = parent->mColumns[column->mSortingColumn]; | ||
2761 | column_index = info_redir.mIndex; | ||
2762 | } | ||
2763 | } | 3050 | } |
2764 | 3051 | ||
2765 | if (column_index == parent->mSortColumn) | 3052 | // if this column is the primary sort key, reverse the direction |
3053 | sort_column_t cur_sort_column; | ||
3054 | if (!parent->mSortColumns.empty() && parent->mSortColumns.back().first == column_index) | ||
2766 | { | 3055 | { |
2767 | ascending = !parent->mSortAscending; | 3056 | ascending = !parent->mSortColumns.back().second; |
2768 | } | 3057 | } |
2769 | 3058 | ||
2770 | parent->sortByColumn(column_index, ascending); | 3059 | parent->sortByColumn(column_index, ascending); |
@@ -2777,12 +3066,17 @@ void LLScrollListCtrl::onClickColumn(void *userdata) | |||
2777 | 3066 | ||
2778 | std::string LLScrollListCtrl::getSortColumnName() | 3067 | std::string LLScrollListCtrl::getSortColumnName() |
2779 | { | 3068 | { |
2780 | LLScrollListColumn* column = mSortColumn >= 0 ? mColumnsIndexed[mSortColumn] : NULL; | 3069 | LLScrollListColumn* column = mSortColumns.empty() ? NULL : mColumnsIndexed[mSortColumns.back().first]; |
2781 | 3070 | ||
2782 | if (column) return column->mName; | 3071 | if (column) return column->mName; |
2783 | else return ""; | 3072 | else return ""; |
2784 | } | 3073 | } |
2785 | 3074 | ||
3075 | BOOL LLScrollListCtrl::needsSorting() | ||
3076 | { | ||
3077 | return !mSortColumns.empty(); | ||
3078 | } | ||
3079 | |||
2786 | void LLScrollListCtrl::clearColumns() | 3080 | void LLScrollListCtrl::clearColumns() |
2787 | { | 3081 | { |
2788 | std::map<LLString, LLScrollListColumn>::iterator itor; | 3082 | std::map<LLString, LLScrollListColumn>::iterator itor; |
@@ -2796,6 +3090,7 @@ void LLScrollListCtrl::clearColumns() | |||
2796 | } | 3090 | } |
2797 | } | 3091 | } |
2798 | mColumns.clear(); | 3092 | mColumns.clear(); |
3093 | mSortColumns.clear(); | ||
2799 | } | 3094 | } |
2800 | 3095 | ||
2801 | void LLScrollListCtrl::setColumnLabel(const LLString& column, const LLString& label) | 3096 | void LLScrollListCtrl::setColumnLabel(const LLString& column, const LLString& label) |
@@ -2849,12 +3144,12 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p | |||
2849 | S32 col_index = 0 ; | 3144 | S32 col_index = 0 ; |
2850 | for (itor = columns.beginArray(); itor != columns.endArray(); ++itor) | 3145 | for (itor = columns.beginArray(); itor != columns.endArray(); ++itor) |
2851 | { | 3146 | { |
2852 | LLString column = (*itor)["column"].asString(); | 3147 | if (itor->isUndefined()) |
2853 | |||
2854 | if (mColumns.size() == 0) | ||
2855 | { | 3148 | { |
2856 | mDefaultColumn = 0; | 3149 | // skip unused columns in item passed in |
3150 | continue; | ||
2857 | } | 3151 | } |
3152 | LLString column = (*itor)["column"].asString(); | ||
2858 | 3153 | ||
2859 | LLScrollListColumn* columnp = NULL; | 3154 | LLScrollListColumn* columnp = NULL; |
2860 | 3155 | ||
@@ -2879,9 +3174,18 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p | |||
2879 | LLSD new_column; | 3174 | LLSD new_column; |
2880 | new_column["name"] = column; | 3175 | new_column["name"] = column; |
2881 | new_column["label"] = column; | 3176 | new_column["label"] = column; |
2882 | new_column["width"] = (*itor)["width"]; | 3177 | // if width supplied for column, use it, otherwise |
3178 | // use adaptive width | ||
3179 | if (itor->has("width")) | ||
3180 | { | ||
3181 | new_column["width"] = (*itor)["width"]; | ||
3182 | } | ||
3183 | else | ||
3184 | { | ||
3185 | new_column["dynamicwidth"] = true; | ||
3186 | } | ||
2883 | addColumn(new_column); | 3187 | addColumn(new_column); |
2884 | columnp = &mColumns.find(column)->second; | 3188 | columnp = &mColumns[column]; |
2885 | new_item->setNumColumns(mColumns.size()); | 3189 | new_item->setNumColumns(mColumns.size()); |
2886 | } | 3190 | } |
2887 | 3191 | ||
@@ -2895,6 +3199,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p | |||
2895 | LLString type = (*itor)["type"].asString(); | 3199 | LLString type = (*itor)["type"].asString(); |
2896 | BOOL has_color = (*itor).has("color"); | 3200 | BOOL has_color = (*itor).has("color"); |
2897 | LLColor4 color = ((*itor)["color"]); | 3201 | LLColor4 color = ((*itor)["color"]); |
3202 | BOOL enabled = !(*itor).has("enabled") || (*itor)["enabled"].asBoolean() == true; | ||
2898 | 3203 | ||
2899 | const LLFontGL *font = gResMgr->getRes(fontname); | 3204 | const LLFontGL *font = gResMgr->getRes(fontname); |
2900 | if (!font) | 3205 | if (!font) |
@@ -2906,8 +3211,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p | |||
2906 | if (type == "icon") | 3211 | if (type == "icon") |
2907 | { | 3212 | { |
2908 | LLUUID image_id = value.asUUID(); | 3213 | LLUUID image_id = value.asUUID(); |
2909 | LLImageGL* icon = LLUI::sImageProvider->getUIImageByID(image_id); | 3214 | LLScrollListIcon* cell = new LLScrollListIcon(value.asUUID(), width); |
2910 | LLScrollListIcon* cell = new LLScrollListIcon(icon, width, image_id); | ||
2911 | if (has_color) | 3215 | if (has_color) |
2912 | { | 3216 | { |
2913 | cell->setColor(color); | 3217 | cell->setColor(color); |
@@ -2916,8 +3220,10 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p | |||
2916 | } | 3220 | } |
2917 | else if (type == "checkbox") | 3221 | else if (type == "checkbox") |
2918 | { | 3222 | { |
2919 | LLCheckBoxCtrl* ctrl = new LLCheckBoxCtrl(value.asString(), | 3223 | LLCheckBoxCtrl* ctrl = new LLCheckBoxCtrl("check", |
2920 | LLRect(0, 0, width, width), "label"); | 3224 | LLRect(0, width, width, 0), " "); |
3225 | ctrl->setEnabled(enabled); | ||
3226 | ctrl->setValue(value); | ||
2921 | LLScrollListCheck* cell = new LLScrollListCheck(ctrl,width); | 3227 | LLScrollListCheck* cell = new LLScrollListCheck(ctrl,width); |
2922 | if (has_color) | 3228 | if (has_color) |
2923 | { | 3229 | { |
@@ -3070,18 +3376,12 @@ void LLScrollListCtrl::onFocusReceived() | |||
3070 | { | 3376 | { |
3071 | // forget latent selection changes when getting focus | 3377 | // forget latent selection changes when getting focus |
3072 | mSelectionChanged = FALSE; | 3378 | mSelectionChanged = FALSE; |
3379 | LLUICtrl::onFocusReceived(); | ||
3073 | } | 3380 | } |
3074 | 3381 | ||
3075 | //virtual | 3382 | //virtual |
3076 | void LLScrollListCtrl::onFocusLost() | 3383 | void LLScrollListCtrl::onFocusLost() |
3077 | { | 3384 | { |
3078 | if (mIsPopup) | ||
3079 | { | ||
3080 | if (getParent()) | ||
3081 | { | ||
3082 | getParent()->onFocusLost(); | ||
3083 | } | ||
3084 | } | ||
3085 | if (hasMouseCapture()) | 3385 | if (hasMouseCapture()) |
3086 | { | 3386 | { |
3087 | gFocusMgr.setMouseCapture(NULL); | 3387 | gFocusMgr.setMouseCapture(NULL); |
@@ -3133,11 +3433,11 @@ void LLColumnHeader::draw() | |||
3133 | { | 3433 | { |
3134 | if( getVisible() ) | 3434 | if( getVisible() ) |
3135 | { | 3435 | { |
3136 | mDrawArrow = !mColumn->mLabel.empty() && mColumn->mParentCtrl->isSorted() && mColumn->mParentCtrl->getSortColumnName() == mColumn->mSortingColumn; | 3436 | BOOL draw_arrow = !mColumn->mLabel.empty() && mColumn->mParentCtrl->isSorted() && mColumn->mParentCtrl->getSortColumnName() == mColumn->mSortingColumn; |
3137 | 3437 | ||
3138 | BOOL is_ascending = mColumn->mParentCtrl->getSortAscending(); | 3438 | BOOL is_ascending = mColumn->mParentCtrl->getSortAscending(); |
3139 | mArrowImage = is_ascending ? LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("up_arrow.tga"))) | 3439 | mButton->setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, draw_arrow ? LLColor4::white : LLColor4::transparent); |
3140 | : LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("down_arrow.tga"))); | 3440 | mArrowImage = mButton->getImageOverlay()->getImage(); |
3141 | 3441 | ||
3142 | //BOOL clip = mRect.mRight > mColumn->mParentCtrl->getItemListRect().getWidth(); | 3442 | //BOOL clip = mRect.mRight > mColumn->mParentCtrl->getItemListRect().getWidth(); |
3143 | //LLGLEnable scissor_test(clip ? GL_SCISSOR_TEST : GL_FALSE); | 3443 | //LLGLEnable scissor_test(clip ? GL_SCISSOR_TEST : GL_FALSE); |
@@ -3237,11 +3537,11 @@ void LLColumnHeader::showList() | |||
3237 | { | 3537 | { |
3238 | if (mColumn->mParentCtrl->getSortAscending()) | 3538 | if (mColumn->mParentCtrl->getSortAscending()) |
3239 | { | 3539 | { |
3240 | low_item_text = cell->getText(); | 3540 | low_item_text = cell->getValue().asString(); |
3241 | } | 3541 | } |
3242 | else | 3542 | else |
3243 | { | 3543 | { |
3244 | high_item_text = cell->getText(); | 3544 | high_item_text = cell->getValue().asString(); |
3245 | } | 3545 | } |
3246 | } | 3546 | } |
3247 | } | 3547 | } |
@@ -3254,11 +3554,11 @@ void LLColumnHeader::showList() | |||
3254 | { | 3554 | { |
3255 | if (mColumn->mParentCtrl->getSortAscending()) | 3555 | if (mColumn->mParentCtrl->getSortAscending()) |
3256 | { | 3556 | { |
3257 | high_item_text = cell->getText(); | 3557 | high_item_text = cell->getValue().asString(); |
3258 | } | 3558 | } |
3259 | else | 3559 | else |
3260 | { | 3560 | { |
3261 | low_item_text = cell->getText(); | 3561 | low_item_text = cell->getValue().asString(); |
3262 | } | 3562 | } |
3263 | } | 3563 | } |
3264 | } | 3564 | } |
diff --git a/linden/indra/llui/llscrolllistctrl.h b/linden/indra/llui/llscrolllistctrl.h index c548727..ada4f9b 100644 --- a/linden/indra/llui/llscrolllistctrl.h +++ b/linden/indra/llui/llscrolllistctrl.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -56,20 +56,26 @@ class LLResizeBar; | |||
56 | class LLScrollListCell | 56 | class LLScrollListCell |
57 | { | 57 | { |
58 | public: | 58 | public: |
59 | LLScrollListCell(S32 width = 0) : mWidth(width) {}; | ||
59 | virtual ~LLScrollListCell() {}; | 60 | virtual ~LLScrollListCell() {}; |
60 | virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const = 0; // truncate to given width, if possible | 61 | virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const = 0; // truncate to given width, if possible |
61 | virtual S32 getWidth() const = 0; | 62 | virtual S32 getWidth() const {return mWidth;} |
63 | virtual S32 getContentWidth() const { return 0; } | ||
62 | virtual S32 getHeight() const = 0; | 64 | virtual S32 getHeight() const = 0; |
63 | virtual const LLString& getText() const { return LLString::null; } | 65 | virtual const LLSD getValue() const { return LLString::null; } |
64 | virtual const LLString& getTextLower() const { return LLString::null; } | 66 | virtual void setValue(LLSD value) { } |
65 | virtual BOOL getVisible() const { return TRUE; } | 67 | virtual BOOL getVisible() const { return TRUE; } |
66 | virtual void setWidth(S32 width) = 0; | 68 | virtual void setWidth(S32 width) { mWidth = width; } |
67 | virtual void highlightText(S32 offset, S32 num_chars) {} | 69 | virtual void highlightText(S32 offset, S32 num_chars) {} |
68 | virtual BOOL isText() = 0; | 70 | virtual BOOL isText() = 0; |
69 | virtual void setColor(const LLColor4&) = 0; | 71 | virtual void setColor(const LLColor4&) {} |
72 | virtual void onCommit() {}; | ||
70 | 73 | ||
71 | virtual BOOL handleClick() { return FALSE; } | 74 | virtual BOOL handleClick() { return FALSE; } |
72 | virtual void setEnabled(BOOL enable) { } | 75 | virtual void setEnabled(BOOL enable) { } |
76 | |||
77 | protected: | ||
78 | S32 mWidth; | ||
73 | }; | 79 | }; |
74 | 80 | ||
75 | class LLScrollListSeparator : public LLScrollListCell | 81 | class LLScrollListSeparator : public LLScrollListCell |
@@ -77,15 +83,9 @@ class LLScrollListSeparator : public LLScrollListCell | |||
77 | public: | 83 | public: |
78 | LLScrollListSeparator(S32 width); | 84 | LLScrollListSeparator(S32 width); |
79 | virtual ~LLScrollListSeparator() {}; | 85 | virtual ~LLScrollListSeparator() {}; |
80 | virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const; // truncate to given width, if possible | 86 | virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; // truncate to given width, if possible |
81 | virtual S32 getWidth() const {return mWidth;} | ||
82 | virtual S32 getHeight() const { return 5; }; | 87 | virtual S32 getHeight() const { return 5; }; |
83 | virtual void setWidth(S32 width) {mWidth = width; } | ||
84 | virtual void setColor(const LLColor4&) {}; | ||
85 | virtual BOOL isText() { return FALSE; } | 88 | virtual BOOL isText() { return FALSE; } |
86 | |||
87 | protected: | ||
88 | S32 mWidth; | ||
89 | }; | 89 | }; |
90 | 90 | ||
91 | class LLScrollListText : public LLScrollListCell | 91 | class LLScrollListText : public LLScrollListCell |
@@ -94,24 +94,25 @@ public: | |||
94 | LLScrollListText( const LLString& text, const LLFontGL* font, S32 width = 0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE); | 94 | LLScrollListText( const LLString& text, const LLFontGL* font, S32 width = 0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE); |
95 | /*virtual*/ ~LLScrollListText(); | 95 | /*virtual*/ ~LLScrollListText(); |
96 | 96 | ||
97 | virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const; | 97 | virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; |
98 | virtual S32 getWidth() const { return mWidth; } | 98 | virtual S32 getContentWidth() const; |
99 | virtual void setWidth(S32 width) { mWidth = width; } | ||
100 | virtual S32 getHeight() const { return llround(mFont->getLineHeight()); } | 99 | virtual S32 getHeight() const { return llround(mFont->getLineHeight()); } |
101 | virtual const LLString& getText() const { return mText.getString(); } | 100 | virtual const LLSD getValue() const { return LLSD(mText.getString()); } |
102 | virtual BOOL getVisible() const { return mVisible; } | 101 | virtual BOOL getVisible() const { return mVisible; } |
103 | virtual void highlightText(S32 offset, S32 num_chars) {mHighlightOffset = offset; mHighlightCount = num_chars;} | 102 | virtual void highlightText(S32 offset, S32 num_chars) {mHighlightOffset = offset; mHighlightCount = num_chars;} |
104 | void setText(const LLStringExplicit& text); | 103 | |
105 | virtual void setColor(const LLColor4&); | 104 | virtual void setColor(const LLColor4&); |
106 | virtual BOOL isText() { return TRUE; } | 105 | virtual BOOL isText() { return TRUE; } |
107 | 106 | ||
107 | void setText(const LLStringExplicit& text); | ||
108 | void setFontStyle(const U8 font_style) { mFontStyle = font_style; } | ||
109 | |||
108 | private: | 110 | private: |
109 | LLUIString mText; | 111 | LLUIString mText; |
110 | const LLFontGL* mFont; | 112 | const LLFontGL* mFont; |
111 | LLColor4* mColor; | 113 | LLColor4* mColor; |
112 | const U8 mFontStyle; | 114 | U8 mFontStyle; |
113 | LLFontGL::HAlign mFontAlignment; | 115 | LLFontGL::HAlign mFontAlignment; |
114 | S32 mWidth; | ||
115 | BOOL mVisible; | 116 | BOOL mVisible; |
116 | S32 mHighlightCount; | 117 | S32 mHighlightCount; |
117 | S32 mHighlightOffset; | 118 | S32 mHighlightOffset; |
@@ -124,21 +125,20 @@ private: | |||
124 | class LLScrollListIcon : public LLScrollListCell | 125 | class LLScrollListIcon : public LLScrollListCell |
125 | { | 126 | { |
126 | public: | 127 | public: |
127 | LLScrollListIcon( LLImageGL* icon, S32 width = 0, LLUUID image_id = LLUUID::null); | 128 | LLScrollListIcon( const LLUUID& icon_id, S32 width = 0); |
128 | /*virtual*/ ~LLScrollListIcon(); | 129 | /*virtual*/ ~LLScrollListIcon(); |
129 | virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const; | 130 | virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; |
130 | virtual S32 getWidth() const { return mWidth; } | 131 | virtual S32 getWidth() const; |
131 | virtual S32 getHeight() const { return mIcon->getHeight(); } | 132 | virtual S32 getHeight() const { return mIcon ? mIcon->getHeight() : 0; } |
132 | virtual const LLString& getText() const { return mImageUUID; } | 133 | // used as sort criterion |
133 | virtual const LLString& getTextLower() const { return mImageUUID; } | 134 | virtual const LLSD getValue() const { return LLSD(mImageUUID); } |
134 | virtual void setWidth(S32 width) { mWidth = width; } | ||
135 | virtual void setColor(const LLColor4&); | 135 | virtual void setColor(const LLColor4&); |
136 | virtual BOOL isText() { return FALSE; } | 136 | virtual BOOL isText() { return FALSE; } |
137 | virtual void setValue(LLSD value); | ||
137 | 138 | ||
138 | private: | 139 | private: |
139 | LLPointer<LLImageGL> mIcon; | 140 | LLPointer<LLImageGL> mIcon; |
140 | LLString mImageUUID; | 141 | LLUUID mImageUUID; |
141 | S32 mWidth; | ||
142 | LLColor4 mColor; | 142 | LLColor4 mColor; |
143 | }; | 143 | }; |
144 | 144 | ||
@@ -147,21 +147,20 @@ class LLScrollListCheck : public LLScrollListCell | |||
147 | public: | 147 | public: |
148 | LLScrollListCheck( LLCheckBoxCtrl* check_box, S32 width = 0); | 148 | LLScrollListCheck( LLCheckBoxCtrl* check_box, S32 width = 0); |
149 | /*virtual*/ ~LLScrollListCheck(); | 149 | /*virtual*/ ~LLScrollListCheck(); |
150 | virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const; | 150 | virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; |
151 | virtual S32 getWidth() const { return mWidth; } | ||
152 | virtual S32 getHeight() const { return 0; } | 151 | virtual S32 getHeight() const { return 0; } |
153 | virtual void setWidth(S32 width) { mWidth = width; } | 152 | virtual const LLSD getValue() const { return mCheckBox->getValue(); } |
153 | virtual void setValue(LLSD value) { mCheckBox->setValue(value); } | ||
154 | virtual void onCommit() { mCheckBox->onCommit(); } | ||
154 | 155 | ||
155 | virtual BOOL handleClick(); | 156 | virtual BOOL handleClick(); |
156 | virtual void setEnabled(BOOL enable) { if (mCheckBox) mCheckBox->setEnabled(enable); } | 157 | virtual void setEnabled(BOOL enable) { mCheckBox->setEnabled(enable); } |
157 | virtual void setColor(const LLColor4& color) {}; | ||
158 | 158 | ||
159 | LLCheckBoxCtrl* getCheckBox() { return mCheckBox; } | 159 | LLCheckBoxCtrl* getCheckBox() { return mCheckBox; } |
160 | virtual BOOL isText() { return FALSE; } | 160 | virtual BOOL isText() { return FALSE; } |
161 | 161 | ||
162 | private: | 162 | private: |
163 | LLCheckBoxCtrl* mCheckBox; | 163 | LLCheckBoxCtrl* mCheckBox; |
164 | S32 mWidth; | ||
165 | }; | 164 | }; |
166 | 165 | ||
167 | class LLScrollListColumn | 166 | class LLScrollListColumn |
@@ -266,6 +265,7 @@ public: | |||
266 | 265 | ||
267 | /*virtual*/ void draw(); | 266 | /*virtual*/ void draw(); |
268 | /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); | 267 | /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); |
268 | |||
269 | /*virtual*/ void showList(); | 269 | /*virtual*/ void showList(); |
270 | /*virtual*/ LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding); | 270 | /*virtual*/ LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding); |
271 | /*virtual*/ void userSetShape(const LLRect& new_rect); | 271 | /*virtual*/ void userSetShape(const LLRect& new_rect); |
@@ -319,8 +319,8 @@ public: | |||
319 | void addColumn( const LLString& text, const LLFontGL* font, S32 width = 0 , U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, BOOL visible = TRUE) | 319 | void addColumn( const LLString& text, const LLFontGL* font, S32 width = 0 , U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, BOOL visible = TRUE) |
320 | { mColumns.push_back( new LLScrollListText(text, font, width, font_style, font_alignment, LLColor4::black, FALSE, visible) ); } | 320 | { mColumns.push_back( new LLScrollListText(text, font, width, font_style, font_alignment, LLColor4::black, FALSE, visible) ); } |
321 | 321 | ||
322 | void addColumn( LLImageGL* icon, S32 width = 0 ) | 322 | void addColumn( const LLUUID& icon_id, S32 width = 0 ) |
323 | { mColumns.push_back( new LLScrollListIcon(icon, width) ); } | 323 | { mColumns.push_back( new LLScrollListIcon(icon_id, width) ); } |
324 | 324 | ||
325 | void addColumn( LLCheckBoxCtrl* check, S32 width = 0 ) | 325 | void addColumn( LLCheckBoxCtrl* check, S32 width = 0 ) |
326 | { mColumns.push_back( new LLScrollListCheck(check,width) ); } | 326 | { mColumns.push_back( new LLScrollListCheck(check,width) ); } |
@@ -333,10 +333,10 @@ public: | |||
333 | 333 | ||
334 | LLScrollListCell *getColumn(const S32 i) const { if (0 <= i && i < (S32)mColumns.size()) { return mColumns[i]; } return NULL; } | 334 | LLScrollListCell *getColumn(const S32 i) const { if (0 <= i && i < (S32)mColumns.size()) { return mColumns[i]; } return NULL; } |
335 | 335 | ||
336 | virtual BOOL handleClick(S32 x, S32 y, MASK mask); | ||
337 | |||
338 | LLString getContentsCSV(); | 336 | LLString getContentsCSV(); |
339 | 337 | ||
338 | virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); | ||
339 | |||
340 | private: | 340 | private: |
341 | BOOL mSelected; | 341 | BOOL mSelected; |
342 | BOOL mEnabled; | 342 | BOOL mEnabled; |
@@ -345,6 +345,23 @@ private: | |||
345 | std::vector<LLScrollListCell *> mColumns; | 345 | std::vector<LLScrollListCell *> mColumns; |
346 | }; | 346 | }; |
347 | 347 | ||
348 | class LLScrollListItemComment : public LLScrollListItem | ||
349 | { | ||
350 | public: | ||
351 | LLScrollListItemComment(const LLString& comment_string, const LLColor4& color); | ||
352 | |||
353 | /*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); | ||
354 | private: | ||
355 | LLColor4 mColor; | ||
356 | }; | ||
357 | |||
358 | class LLScrollListItemSeparator : public LLScrollListItem | ||
359 | { | ||
360 | public: | ||
361 | LLScrollListItemSeparator(); | ||
362 | |||
363 | /*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); | ||
364 | }; | ||
348 | 365 | ||
349 | class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, | 366 | class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, |
350 | public LLCtrlListInterface, public LLCtrlScrollInterface | 367 | public LLCtrlListInterface, public LLCtrlScrollInterface |
@@ -370,9 +387,8 @@ public: | |||
370 | void deleteAllItems() { clearRows(); } | 387 | void deleteAllItems() { clearRows(); } |
371 | 388 | ||
372 | // Sets an array of column descriptors | 389 | // Sets an array of column descriptors |
373 | void setColumnHeadings(LLSD headings); | 390 | void setColumnHeadings(LLSD headings); |
374 | // Numerical based sort by column function (used by LLComboBox) | 391 | void sortByColumn(U32 column, BOOL ascending); |
375 | void sortByColumn(U32 column, BOOL ascending); | ||
376 | 392 | ||
377 | // LLCtrlListInterface functions | 393 | // LLCtrlListInterface functions |
378 | virtual S32 getItemCount() const; | 394 | virtual S32 getItemCount() const; |
@@ -390,7 +406,6 @@ public: | |||
390 | virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); | 406 | virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); |
391 | // Simple add element. Takes a single array of: | 407 | // Simple add element. Takes a single array of: |
392 | // [ "value" => value, "font" => font, "font-style" => style ] | 408 | // [ "value" => value, "font" => font, "font-style" => style ] |
393 | virtual LLScrollListItem* addSimpleElement(const LLString& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD()); | ||
394 | virtual void clearRows(); // clears all elements | 409 | virtual void clearRows(); // clears all elements |
395 | virtual void sortByColumn(LLString name, BOOL ascending); | 410 | virtual void sortByColumn(LLString name, BOOL ascending); |
396 | 411 | ||
@@ -421,18 +436,20 @@ public: | |||
421 | BOOL isSorted(); | 436 | BOOL isSorted(); |
422 | 437 | ||
423 | virtual BOOL isSelected(LLSD value); | 438 | virtual BOOL isSelected(LLSD value); |
424 | 439 | ||
440 | BOOL handleClick(S32 x, S32 y, MASK mask); | ||
425 | BOOL selectFirstItem(); | 441 | BOOL selectFirstItem(); |
426 | BOOL selectNthItem( S32 index ); | 442 | BOOL selectNthItem( S32 index ); |
427 | BOOL selectItemAt(S32 x, S32 y, MASK mask); | 443 | BOOL selectItemAt(S32 x, S32 y, MASK mask); |
428 | 444 | ||
429 | void deleteSingleItem( S32 index ) ; | 445 | void deleteSingleItem( S32 index ); |
446 | void deleteItems(const LLSD& sd); | ||
430 | void deleteSelectedItems(); | 447 | void deleteSelectedItems(); |
431 | void deselectAllItems(BOOL no_commit_on_change = FALSE); // by default, go ahead and commit on selection change | 448 | void deselectAllItems(BOOL no_commit_on_change = FALSE); // by default, go ahead and commit on selection change |
432 | 449 | ||
433 | void highlightNthItem( S32 index ); | 450 | void highlightNthItem( S32 index ); |
434 | void setDoubleClickCallback( void (*cb)(void*) ) { mOnDoubleClickCallback = cb; } | 451 | void setDoubleClickCallback( void (*cb)(void*) ) { mOnDoubleClickCallback = cb; } |
435 | void setMaxiumumSelectCallback( void (*cb)(void*) ) { mOnMaximumSelectCallback = cb; } | 452 | void setMaximumSelectCallback( void (*cb)(void*) ) { mOnMaximumSelectCallback = cb; } |
436 | void setSortChangedCallback( void (*cb)(void*) ) { mOnSortChangedCallback = cb; } | 453 | void setSortChangedCallback( void (*cb)(void*) ) { mOnSortChangedCallback = cb; } |
437 | 454 | ||
438 | void swapWithNext(S32 index); | 455 | void swapWithNext(S32 index); |
@@ -444,19 +461,21 @@ public: | |||
444 | S32 getItemIndex( LLScrollListItem* item ); | 461 | S32 getItemIndex( LLScrollListItem* item ); |
445 | S32 getItemIndex( LLUUID& item_id ); | 462 | S32 getItemIndex( LLUUID& item_id ); |
446 | 463 | ||
464 | LLScrollListItem* addCommentText( const LLString& comment_text, EAddPosition pos = ADD_BOTTOM); | ||
465 | LLScrollListItem* addSeparator(EAddPosition pos); | ||
466 | |||
447 | // "Simple" interface: use this when you're creating a list that contains only unique strings, only | 467 | // "Simple" interface: use this when you're creating a list that contains only unique strings, only |
448 | // one of which can be selected at a time. | 468 | // one of which can be selected at a time. |
449 | LLScrollListItem* addSimpleItem( const LLString& item_text, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE ); | 469 | virtual LLScrollListItem* addSimpleElement(const LLString& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD()); |
450 | // Add an item with an associated LLSD | 470 | |
451 | LLScrollListItem* addSimpleItem(const LLString& item_text, LLSD sd, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, S32 column_width = 0 ); | ||
452 | 471 | ||
453 | BOOL selectSimpleItem( const LLString& item, BOOL case_sensitive = TRUE ); // FALSE if item not found | 472 | BOOL selectItemByLabel( const LLString& item, BOOL case_sensitive = TRUE ); // FALSE if item not found |
454 | BOOL selectSimpleItemByPrefix(const LLString& target, BOOL case_sensitive); | 473 | BOOL selectItemByPrefix(const LLString& target, BOOL case_sensitive = TRUE); |
455 | BOOL selectSimpleItemByPrefix(const LLWString& target, BOOL case_sensitive); | 474 | BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE); |
456 | const LLString& getSimpleSelectedItem(S32 column = 0) const; | 475 | const LLString getSelectedItemLabel(S32 column = 0) const; |
457 | LLSD getSimpleSelectedValue(); | 476 | LLSD getSelectedValue(); |
458 | 477 | ||
459 | // DEPRECATED: Use LLSD versions of addSimpleItem() and getSimpleSelectedValue(). | 478 | // DEPRECATED: Use LLSD versions of addCommentText() and getSelectedValue(). |
460 | // "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which | 479 | // "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which |
461 | // has an associated, unique UUID, and only one of which can be selected at a time. | 480 | // has an associated, unique UUID, and only one of which can be selected at a time. |
462 | LLScrollListItem* addStringUUIDItem(const LLString& item_text, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, S32 column_width = 0); | 481 | LLScrollListItem* addStringUUIDItem(const LLString& item_text, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, S32 column_width = 0); |
@@ -472,6 +491,8 @@ public: | |||
472 | LLScrollListItem* getFirstData() const; | 491 | LLScrollListItem* getFirstData() const; |
473 | LLScrollListItem* getLastData() const; | 492 | LLScrollListItem* getLastData() const; |
474 | std::vector<LLScrollListItem*> getAllData() const; | 493 | std::vector<LLScrollListItem*> getAllData() const; |
494 | |||
495 | LLScrollListItem* getItem(const LLSD& sd) const; | ||
475 | 496 | ||
476 | void setAllowMultipleSelection(BOOL mult ) { mAllowMultipleSelection = mult; } | 497 | void setAllowMultipleSelection(BOOL mult ) { mAllowMultipleSelection = mult; } |
477 | 498 | ||
@@ -501,28 +522,34 @@ public: | |||
501 | 522 | ||
502 | S32 getSearchColumn() { return mSearchColumn; } | 523 | S32 getSearchColumn() { return mSearchColumn; } |
503 | void setSearchColumn(S32 column) { mSearchColumn = column; } | 524 | void setSearchColumn(S32 column) { mSearchColumn = column; } |
525 | S32 getColumnIndexFromOffset(S32 x); | ||
526 | S32 getColumnOffsetFromIndex(S32 index); | ||
527 | S32 getRowOffsetFromIndex(S32 index); | ||
504 | 528 | ||
505 | void clearSearchString() { mSearchString.clear(); } | 529 | void clearSearchString() { mSearchString.clear(); } |
506 | 530 | ||
507 | // Overridden from LLView | 531 | // Overridden from LLView |
508 | virtual void draw(); | 532 | /*virtual*/ void draw(); |
509 | virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); | 533 | /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); |
510 | virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); | 534 | /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); |
511 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); | 535 | /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); |
512 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); | 536 | /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); |
513 | virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); | 537 | /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); |
514 | virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); | 538 | /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); |
515 | virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); | 539 | /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); |
516 | virtual void setEnabled(BOOL enabled); | 540 | /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect); |
517 | virtual void setFocus( BOOL b ); | 541 | /*virtual*/ void setEnabled(BOOL enabled); |
518 | virtual void onFocusReceived(); | 542 | /*virtual*/ void setFocus( BOOL b ); |
519 | virtual void onFocusLost(); | 543 | /*virtual*/ void onFocusReceived(); |
544 | /*virtual*/ void onFocusLost(); | ||
545 | /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); | ||
520 | 546 | ||
521 | virtual BOOL isDirty() const; | 547 | virtual BOOL isDirty() const; |
522 | virtual void resetDirty(); // Clear dirty state | 548 | virtual void resetDirty(); // Clear dirty state |
523 | 549 | ||
524 | virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); | 550 | virtual void updateLayout(); |
525 | virtual void arrange(S32 max_width, S32 max_height); | 551 | virtual void fitContents(S32 max_width, S32 max_height); |
552 | |||
526 | virtual LLRect getRequiredRect(); | 553 | virtual LLRect getRequiredRect(); |
527 | static BOOL rowPreceeds(LLScrollListItem *new_row, LLScrollListItem *test_row); | 554 | static BOOL rowPreceeds(LLScrollListItem *new_row, LLScrollListItem *test_row); |
528 | 555 | ||
@@ -534,12 +561,12 @@ public: | |||
534 | static void onClickColumn(void *userdata); | 561 | static void onClickColumn(void *userdata); |
535 | 562 | ||
536 | void updateColumns(); | 563 | void updateColumns(); |
537 | void updateMaxContentWidth(LLScrollListItem* changed_item); | 564 | void calcMaxContentWidth(LLScrollListItem* changed_item); |
565 | S32 getMaxContentWidth() { return mMaxContentWidth; } | ||
538 | 566 | ||
539 | void setDisplayHeading(BOOL display); | 567 | void setDisplayHeading(BOOL display); |
540 | void setHeadingHeight(S32 heading_height); | 568 | void setHeadingHeight(S32 heading_height); |
541 | void setCollapseEmptyColumns(BOOL collapse); | 569 | void setCollapseEmptyColumns(BOOL collapse); |
542 | void setIsPopup(BOOL is_popup) { mIsPopup = is_popup; } | ||
543 | 570 | ||
544 | LLScrollListItem* hitItem(S32 x,S32 y); | 571 | LLScrollListItem* hitItem(S32 x,S32 y); |
545 | virtual void scrollToShowSelected(); | 572 | virtual void scrollToShowSelected(); |
@@ -564,9 +591,11 @@ public: | |||
564 | void setTotalStaticColumnWidth(int width) { mTotalStaticColumnWidth = width; } | 591 | void setTotalStaticColumnWidth(int width) { mTotalStaticColumnWidth = width; } |
565 | 592 | ||
566 | std::string getSortColumnName(); | 593 | std::string getSortColumnName(); |
567 | BOOL getSortAscending() { return mSortAscending; } | 594 | BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; } |
595 | BOOL needsSorting(); | ||
568 | 596 | ||
569 | S32 selectMultiple( LLDynamicArray<LLUUID> ids ); | 597 | S32 selectMultiple( LLDynamicArray<LLUUID> ids ); |
598 | void sortItems(); | ||
570 | 599 | ||
571 | protected: | 600 | protected: |
572 | // "Full" interface: use this when you're creating a list that has one or more of the following: | 601 | // "Full" interface: use this when you're creating a list that has one or more of the following: |
@@ -584,7 +613,7 @@ protected: | |||
584 | // to the caller to delete the item) | 613 | // to the caller to delete the item) |
585 | 614 | ||
586 | // returns FALSE if item faile to be added to list, does NOT delete 'item' | 615 | // returns FALSE if item faile to be added to list, does NOT delete 'item' |
587 | BOOL addItem( LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM ); | 616 | BOOL addItem( LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM, BOOL requires_column = TRUE ); |
588 | void selectPrevItem(BOOL extend_selection); | 617 | void selectPrevItem(BOOL extend_selection); |
589 | void selectNextItem(BOOL extend_selection); | 618 | void selectNextItem(BOOL extend_selection); |
590 | void drawItems(); | 619 | void drawItems(); |
@@ -596,6 +625,7 @@ protected: | |||
596 | void deselectItem(LLScrollListItem* itemp); | 625 | void deselectItem(LLScrollListItem* itemp); |
597 | void commitIfChanged(); | 626 | void commitIfChanged(); |
598 | void setSorted(BOOL sorted); | 627 | void setSorted(BOOL sorted); |
628 | BOOL setSort(S32 column, BOOL ascending); | ||
599 | 629 | ||
600 | protected: | 630 | protected: |
601 | S32 mCurIndex; // For get[First/Next]Data | 631 | S32 mCurIndex; // For get[First/Next]Data |
@@ -615,8 +645,6 @@ protected: | |||
615 | BOOL mNeedsScroll; | 645 | BOOL mNeedsScroll; |
616 | BOOL mCanSelect; | 646 | BOOL mCanSelect; |
617 | BOOL mDisplayColumnHeaders; | 647 | BOOL mDisplayColumnHeaders; |
618 | BOOL mCollapseEmptyColumns; | ||
619 | BOOL mIsPopup; | ||
620 | 648 | ||
621 | typedef std::deque<LLScrollListItem *> item_list; | 649 | typedef std::deque<LLScrollListItem *> item_list; |
622 | item_list mItemList; | 650 | item_list mItemList; |
@@ -626,7 +654,7 @@ protected: | |||
626 | S32 mMaxItemCount; | 654 | S32 mMaxItemCount; |
627 | 655 | ||
628 | LLRect mItemListRect; | 656 | LLRect mItemListRect; |
629 | 657 | S32 mMaxContentWidth; | |
630 | S32 mColumnPadding; | 658 | S32 mColumnPadding; |
631 | 659 | ||
632 | BOOL mBackgroundVisible; | 660 | BOOL mBackgroundVisible; |
@@ -652,22 +680,23 @@ protected: | |||
652 | LLWString mSearchString; | 680 | LLWString mSearchString; |
653 | LLFrameTimer mSearchTimer; | 681 | LLFrameTimer mSearchTimer; |
654 | 682 | ||
655 | LLString mDefaultColumn; | ||
656 | |||
657 | S32 mSearchColumn; | 683 | S32 mSearchColumn; |
658 | S32 mNumDynamicWidthColumns; | 684 | S32 mNumDynamicWidthColumns; |
659 | S32 mTotalStaticColumnWidth; | 685 | S32 mTotalStaticColumnWidth; |
660 | 686 | ||
661 | S32 mSortColumn; | ||
662 | BOOL mSortAscending; | ||
663 | BOOL mSorted; | 687 | BOOL mSorted; |
664 | 688 | ||
665 | std::map<LLString, LLScrollListColumn> mColumns; | 689 | std::map<LLString, LLScrollListColumn> mColumns; |
666 | std::vector<LLScrollListColumn*> mColumnsIndexed; | ||
667 | 690 | ||
668 | BOOL mDirty; | 691 | BOOL mDirty; |
669 | S32 mOriginalSelection; | 692 | S32 mOriginalSelection; |
670 | 693 | ||
694 | typedef std::vector<LLScrollListColumn*> ordered_columns_t; | ||
695 | ordered_columns_t mColumnsIndexed; | ||
696 | |||
697 | typedef std::pair<S32, BOOL> sort_column_t; | ||
698 | std::vector<sort_column_t> mSortColumns; | ||
699 | |||
671 | public: | 700 | public: |
672 | // HACK: Did we draw one selected item this frame? | 701 | // HACK: Did we draw one selected item this frame? |
673 | BOOL mDrewSelected; | 702 | BOOL mDrewSelected; |
diff --git a/linden/indra/llui/llslider.cpp b/linden/indra/llui/llslider.cpp index 606a8a1..e03603d 100644 --- a/linden/indra/llui/llslider.cpp +++ b/linden/indra/llui/llslider.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -41,9 +41,6 @@ | |||
41 | #include "llcontrol.h" | 41 | #include "llcontrol.h" |
42 | #include "llimagegl.h" | 42 | #include "llimagegl.h" |
43 | 43 | ||
44 | const S32 THUMB_WIDTH = 8; | ||
45 | const S32 TRACK_HEIGHT = 6; | ||
46 | |||
47 | LLSlider::LLSlider( | 44 | LLSlider::LLSlider( |
48 | const LLString& name, | 45 | const LLString& name, |
49 | const LLRect& rect, | 46 | const LLRect& rect, |
@@ -65,20 +62,24 @@ LLSlider::LLSlider( | |||
65 | mIncrement( increment ), | 62 | mIncrement( increment ), |
66 | mVolumeSlider( volume ), | 63 | mVolumeSlider( volume ), |
67 | mMouseOffset( 0 ), | 64 | mMouseOffset( 0 ), |
68 | mDragStartThumbRect( 0, mRect.getHeight(), THUMB_WIDTH, 0 ), | ||
69 | mThumbRect( 0, mRect.getHeight(), THUMB_WIDTH, 0 ), | ||
70 | mTrackColor( LLUI::sColorsGroup->getColor( "SliderTrackColor" ) ), | 65 | mTrackColor( LLUI::sColorsGroup->getColor( "SliderTrackColor" ) ), |
71 | mThumbOutlineColor( LLUI::sColorsGroup->getColor( "SliderThumbOutlineColor" ) ), | 66 | mThumbOutlineColor( LLUI::sColorsGroup->getColor( "SliderThumbOutlineColor" ) ), |
72 | mThumbCenterColor( LLUI::sColorsGroup->getColor( "SliderThumbCenterColor" ) ), | 67 | mThumbCenterColor( LLUI::sColorsGroup->getColor( "SliderThumbCenterColor" ) ), |
73 | mDisabledThumbColor(LLUI::sColorsGroup->getColor( "SliderDisabledThumbColor" ) ), | ||
74 | mMouseDownCallback( NULL ), | 68 | mMouseDownCallback( NULL ), |
75 | mMouseUpCallback( NULL ) | 69 | mMouseUpCallback( NULL ) |
76 | { | 70 | { |
71 | mThumbImage = LLUI::sImageProvider->getImageByID(LLUUID(LLUI::sAssetsGroup->getString("icn_slide-thumb_dark.tga"))); | ||
72 | mTrackImage = LLUI::sImageProvider->getImageByID(LLUUID(LLUI::sAssetsGroup->getString("icn_slide-groove_dark.tga"))); | ||
73 | mTrackHighlightImage = LLUI::sImageProvider->getImageByID(LLUUID(LLUI::sAssetsGroup->getString("icn_slide-highlight.tga"))); | ||
74 | |||
77 | // properly handle setting the starting thumb rect | 75 | // properly handle setting the starting thumb rect |
78 | // do it this way to handle both the operating-on-settings | 76 | // do it this way to handle both the operating-on-settings |
79 | // and standalone ways of using this | 77 | // and standalone ways of using this |
80 | setControlName(control_name, NULL); | 78 | setControlName(control_name, NULL); |
81 | setValue(getValueF32()); | 79 | setValue(getValueF32()); |
80 | |||
81 | updateThumbRect(); | ||
82 | mDragStartThumbRect = mThumbRect; | ||
82 | } | 83 | } |
83 | 84 | ||
84 | EWidgetType LLSlider::getWidgetType() const | 85 | EWidgetType LLSlider::getWidgetType() const |
@@ -107,17 +108,26 @@ void LLSlider::setValue(F32 value, BOOL from_event) | |||
107 | } | 108 | } |
108 | 109 | ||
109 | mValue = value; | 110 | mValue = value; |
111 | updateThumbRect(); | ||
112 | } | ||
110 | 113 | ||
114 | void LLSlider::updateThumbRect() | ||
115 | { | ||
111 | F32 t = (mValue - mMinValue) / (mMaxValue - mMinValue); | 116 | F32 t = (mValue - mMinValue) / (mMaxValue - mMinValue); |
112 | 117 | ||
113 | S32 left_edge = THUMB_WIDTH/2; | 118 | S32 thumb_width = mThumbImage->getWidth(); |
114 | S32 right_edge = mRect.getWidth() - (THUMB_WIDTH/2); | 119 | S32 thumb_height = mThumbImage->getHeight(); |
120 | S32 left_edge = (thumb_width / 2); | ||
121 | S32 right_edge = mRect.getWidth() - (thumb_width / 2); | ||
115 | 122 | ||
116 | S32 x = left_edge + S32( t * (right_edge - left_edge) ); | 123 | S32 x = left_edge + S32( t * (right_edge - left_edge) ); |
117 | mThumbRect.mLeft = x - (THUMB_WIDTH/2); | 124 | mThumbRect.mLeft = x - (thumb_width / 2); |
118 | mThumbRect.mRight = x + (THUMB_WIDTH/2); | 125 | mThumbRect.mRight = mThumbRect.mLeft + thumb_width; |
126 | mThumbRect.mBottom = getLocalRect().getCenterY() - (thumb_height / 2); | ||
127 | mThumbRect.mTop = mThumbRect.mBottom + thumb_height; | ||
119 | } | 128 | } |
120 | 129 | ||
130 | |||
121 | void LLSlider::setValueAndCommit(F32 value) | 131 | void LLSlider::setValueAndCommit(F32 value) |
122 | { | 132 | { |
123 | F32 old_value = mValue; | 133 | F32 old_value = mValue; |
@@ -139,8 +149,9 @@ BOOL LLSlider::handleHover(S32 x, S32 y, MASK mask) | |||
139 | { | 149 | { |
140 | if( hasMouseCapture() ) | 150 | if( hasMouseCapture() ) |
141 | { | 151 | { |
142 | S32 left_edge = THUMB_WIDTH/2; | 152 | S32 thumb_half_width = mThumbImage->getWidth()/2; |
143 | S32 right_edge = mRect.getWidth() - (THUMB_WIDTH/2); | 153 | S32 left_edge = thumb_half_width; |
154 | S32 right_edge = mRect.getWidth() - (thumb_half_width); | ||
144 | 155 | ||
145 | x += mMouseOffset; | 156 | x += mMouseOffset; |
146 | x = llclamp( x, left_edge, right_edge ); | 157 | x = llclamp( x, left_edge, right_edge ); |
@@ -203,7 +214,7 @@ BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask) | |||
203 | // Find the offset of the actual mouse location from the center of the thumb. | 214 | // Find the offset of the actual mouse location from the center of the thumb. |
204 | if (mThumbRect.pointInRect(x,y)) | 215 | if (mThumbRect.pointInRect(x,y)) |
205 | { | 216 | { |
206 | mMouseOffset = (mThumbRect.mLeft + THUMB_WIDTH/2) - x; | 217 | mMouseOffset = (mThumbRect.mLeft + mThumbImage->getWidth()/2) - x; |
207 | } | 218 | } |
208 | else | 219 | else |
209 | { | 220 | { |
@@ -251,6 +262,9 @@ void LLSlider::draw() | |||
251 | { | 262 | { |
252 | if( getVisible() ) | 263 | if( getVisible() ) |
253 | { | 264 | { |
265 | // since thumb image might still be decoding, need thumb to accomodate image size | ||
266 | updateThumbRect(); | ||
267 | |||
254 | // Draw background and thumb. | 268 | // Draw background and thumb. |
255 | 269 | ||
256 | // drawing solids requires texturing be disabled | 270 | // drawing solids requires texturing be disabled |
@@ -260,104 +274,37 @@ void LLSlider::draw() | |||
260 | 274 | ||
261 | F32 opacity = mEnabled ? 1.f : 0.3f; | 275 | F32 opacity = mEnabled ? 1.f : 0.3f; |
262 | LLColor4 center_color = (mThumbCenterColor % opacity); | 276 | LLColor4 center_color = (mThumbCenterColor % opacity); |
263 | LLColor4 outline_color = (mThumbOutlineColor % opacity); | ||
264 | LLColor4 track_color = (mTrackColor % opacity); | 277 | LLColor4 track_color = (mTrackColor % opacity); |
265 | 278 | ||
266 | LLImageGL* thumb_imagep = NULL; | ||
267 | |||
268 | // Track | 279 | // Track |
269 | if (mVolumeSlider) | 280 | LLRect track_rect(mThumbImage->getWidth() / 2, |
270 | { | 281 | getLocalRect().getCenterY() + (mTrackImage->getHeight() / 2), |
271 | LLRect track(0, mRect.getHeight(), mRect.getWidth(), 0); | 282 | mRect.getWidth() - mThumbImage->getWidth() / 2, |
272 | 283 | getLocalRect().getCenterY() - (mTrackImage->getHeight() / 2) ); | |
273 | track.mBottom += 3; | ||
274 | track.mTop -= 1; | ||
275 | track.mRight -= 1; | ||
276 | |||
277 | gl_triangle_2d(track.mLeft, track.mBottom, | ||
278 | track.mRight, track.mBottom, | ||
279 | track.mRight, track.mTop, | ||
280 | center_color, | ||
281 | TRUE); | ||
282 | gl_triangle_2d(track.mLeft, track.mBottom, | ||
283 | track.mRight, track.mBottom, | ||
284 | track.mRight, track.mTop, | ||
285 | outline_color, | ||
286 | FALSE); | ||
287 | } | ||
288 | else | ||
289 | { | ||
290 | LLUUID thumb_image_id; | ||
291 | thumb_image_id.set(LLUI::sAssetsGroup->getString("rounded_square.tga")); | ||
292 | thumb_imagep = LLUI::sImageProvider->getUIImageByID(thumb_image_id); | ||
293 | 284 | ||
294 | S32 height_offset = (mRect.getHeight() - TRACK_HEIGHT) / 2; | 285 | gl_draw_scaled_image_with_border(track_rect.mLeft, track_rect.mBottom, 3, 3, track_rect.getWidth(), track_rect.getHeight(), |
295 | LLRect track_rect(0, mRect.getHeight() - height_offset, mRect.getWidth(), height_offset ); | 286 | mTrackImage, track_color); |
287 | gl_draw_scaled_image_with_border(track_rect.mLeft, track_rect.mBottom, 3, 3, mThumbRect.mLeft, track_rect.getHeight(), | ||
288 | mTrackHighlightImage, track_color); | ||
296 | 289 | ||
297 | track_rect.stretch(-1); | ||
298 | gl_draw_scaled_image_with_border(track_rect.mLeft, track_rect.mBottom, 16, 16, track_rect.getWidth(), track_rect.getHeight(), | ||
299 | thumb_imagep, track_color); | ||
300 | } | ||
301 | 290 | ||
302 | // Thumb | 291 | // Thumb |
303 | if (!thumb_imagep) | 292 | if( hasMouseCapture() ) |
304 | { | ||
305 | if (mVolumeSlider) | ||
306 | { | ||
307 | if (hasMouseCapture()) | ||
308 | { | ||
309 | LLRect rect(mDragStartThumbRect); | ||
310 | gl_rect_2d( rect, outline_color ); | ||
311 | rect.stretch(-1); | ||
312 | gl_rect_2d( rect, mThumbCenterColor % 0.3f ); | ||
313 | |||
314 | if (hasFocus()) | ||
315 | { | ||
316 | LLRect thumb_rect = mThumbRect; | ||
317 | thumb_rect.stretch(llround(lerp(1.f, 3.f, gFocusMgr.getFocusFlashAmt()))); | ||
318 | gl_rect_2d(thumb_rect, gFocusMgr.getFocusColor()); | ||
319 | } | ||
320 | gl_rect_2d( mThumbRect, mThumbOutlineColor ); | ||
321 | } | ||
322 | else | ||
323 | { | ||
324 | if (hasFocus()) | ||
325 | { | ||
326 | LLRect thumb_rect = mThumbRect; | ||
327 | thumb_rect.stretch(llround(lerp(1.f, 3.f, gFocusMgr.getFocusFlashAmt()))); | ||
328 | gl_rect_2d(thumb_rect, gFocusMgr.getFocusColor()); | ||
329 | } | ||
330 | LLRect rect(mThumbRect); | ||
331 | gl_rect_2d(rect, outline_color); | ||
332 | rect.stretch(-1); | ||
333 | gl_rect_2d( rect, center_color); | ||
334 | } | ||
335 | } | ||
336 | else | ||
337 | { | ||
338 | gl_rect_2d(mThumbRect, mThumbCenterColor, TRUE); | ||
339 | if (hasMouseCapture()) | ||
340 | { | ||
341 | gl_rect_2d(mDragStartThumbRect, center_color, FALSE); | ||
342 | } | ||
343 | } | ||
344 | } | ||
345 | else if( hasMouseCapture() ) | ||
346 | { | 293 | { |
347 | gl_draw_scaled_image_with_border(mDragStartThumbRect.mLeft, mDragStartThumbRect.mBottom, 16, 16, mDragStartThumbRect.getWidth(), mDragStartThumbRect.getHeight(), | 294 | gl_draw_scaled_image(mDragStartThumbRect.mLeft, mDragStartThumbRect.mBottom, mDragStartThumbRect.getWidth(), mDragStartThumbRect.getHeight(), |
348 | thumb_imagep, mThumbCenterColor % 0.3f, TRUE); | 295 | mThumbImage, mThumbCenterColor % 0.3f); |
349 | 296 | ||
350 | if (hasFocus()) | 297 | if (hasFocus()) |
351 | { | 298 | { |
352 | F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); | 299 | F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); |
353 | LLRect highlight_rect = mThumbRect; | 300 | LLRect highlight_rect = mThumbRect; |
354 | highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt))); | 301 | highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt))); |
355 | gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 16, 16, highlight_rect.getWidth(), highlight_rect.getHeight(), | 302 | gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 0, 0, highlight_rect.getWidth(), highlight_rect.getHeight(), |
356 | thumb_imagep, gFocusMgr.getFocusColor()); | 303 | mThumbImage, gFocusMgr.getFocusColor(), TRUE); |
357 | } | 304 | } |
358 | 305 | ||
359 | gl_draw_scaled_image_with_border(mThumbRect.mLeft, mThumbRect.mBottom, 16, 16, mThumbRect.getWidth(), mThumbRect.getHeight(), | 306 | gl_draw_scaled_image(mThumbRect.mLeft, mThumbRect.mBottom, mThumbRect.getWidth(), mThumbRect.getHeight(), |
360 | thumb_imagep, mThumbOutlineColor, TRUE); | 307 | mThumbImage, mThumbOutlineColor); |
361 | 308 | ||
362 | } | 309 | } |
363 | else | 310 | else |
@@ -367,12 +314,12 @@ void LLSlider::draw() | |||
367 | F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); | 314 | F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); |
368 | LLRect highlight_rect = mThumbRect; | 315 | LLRect highlight_rect = mThumbRect; |
369 | highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt))); | 316 | highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt))); |
370 | gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 16, 16, highlight_rect.getWidth(), highlight_rect.getHeight(), | 317 | gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 0, 0, highlight_rect.getWidth(), highlight_rect.getHeight(), |
371 | thumb_imagep, gFocusMgr.getFocusColor()); | 318 | mThumbImage, gFocusMgr.getFocusColor(), TRUE); |
372 | } | 319 | } |
373 | 320 | ||
374 | gl_draw_scaled_image_with_border(mThumbRect.mLeft, mThumbRect.mBottom, 16, 16, mThumbRect.getWidth(), mThumbRect.getHeight(), | 321 | gl_draw_scaled_image(mThumbRect.mLeft, mThumbRect.mBottom, mThumbRect.getWidth(), mThumbRect.getHeight(), |
375 | thumb_imagep, center_color, TRUE); | 322 | mThumbImage, center_color); |
376 | } | 323 | } |
377 | LLUICtrl::draw(); | 324 | LLUICtrl::draw(); |
378 | } | 325 | } |
diff --git a/linden/indra/llui/llslider.h b/linden/indra/llui/llslider.h index 28a8d07..08ab600 100644 --- a/linden/indra/llui/llslider.h +++ b/linden/indra/llui/llslider.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -36,6 +36,7 @@ | |||
36 | #include "v4color.h" | 36 | #include "v4color.h" |
37 | 37 | ||
38 | class LLUICtrlFactory; | 38 | class LLUICtrlFactory; |
39 | class LLImageGL; | ||
39 | 40 | ||
40 | class LLSlider : public LLUICtrl | 41 | class LLSlider : public LLUICtrl |
41 | { | 42 | { |
@@ -85,6 +86,7 @@ public: | |||
85 | 86 | ||
86 | protected: | 87 | protected: |
87 | void setValueAndCommit(F32 value); | 88 | void setValueAndCommit(F32 value); |
89 | void updateThumbRect(); | ||
88 | 90 | ||
89 | protected: | 91 | protected: |
90 | F32 mValue; | 92 | F32 mValue; |
@@ -97,11 +99,14 @@ protected: | |||
97 | S32 mMouseOffset; | 99 | S32 mMouseOffset; |
98 | LLRect mDragStartThumbRect; | 100 | LLRect mDragStartThumbRect; |
99 | 101 | ||
102 | LLImageGL* mThumbImage; | ||
103 | LLImageGL* mTrackImage; | ||
104 | LLImageGL* mTrackHighlightImage; | ||
105 | |||
100 | LLRect mThumbRect; | 106 | LLRect mThumbRect; |
101 | LLColor4 mTrackColor; | 107 | LLColor4 mTrackColor; |
102 | LLColor4 mThumbOutlineColor; | 108 | LLColor4 mThumbOutlineColor; |
103 | LLColor4 mThumbCenterColor; | 109 | LLColor4 mThumbCenterColor; |
104 | LLColor4 mDisabledThumbColor; | ||
105 | 110 | ||
106 | void (*mMouseDownCallback)(LLUICtrl* ctrl, void* userdata); | 111 | void (*mMouseDownCallback)(LLUICtrl* ctrl, void* userdata); |
107 | void (*mMouseUpCallback)(LLUICtrl* ctrl, void* userdata); | 112 | void (*mMouseUpCallback)(LLUICtrl* ctrl, void* userdata); |
diff --git a/linden/indra/llui/llsliderctrl.cpp b/linden/indra/llui/llsliderctrl.cpp index 8bb8e24..17854d0 100644 --- a/linden/indra/llui/llsliderctrl.cpp +++ b/linden/indra/llui/llsliderctrl.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -125,7 +125,7 @@ LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect, | |||
125 | &LLLineEditor::prevalidateFloat ); | 125 | &LLLineEditor::prevalidateFloat ); |
126 | mEditor->setFollowsLeft(); | 126 | mEditor->setFollowsLeft(); |
127 | mEditor->setFollowsBottom(); | 127 | mEditor->setFollowsBottom(); |
128 | mEditor->setFocusReceivedCallback( &LLSliderCtrl::onEditorGainFocus ); | 128 | mEditor->setFocusReceivedCallback( &LLSliderCtrl::onEditorGainFocus, this ); |
129 | mEditor->setIgnoreTab(TRUE); | 129 | mEditor->setIgnoreTab(TRUE); |
130 | // don't do this, as selecting the entire text is single clicking in some cases | 130 | // don't do this, as selecting the entire text is single clicking in some cases |
131 | // and double clicking in others | 131 | // and double clicking in others |
@@ -150,7 +150,7 @@ LLSliderCtrl::~LLSliderCtrl() | |||
150 | } | 150 | } |
151 | 151 | ||
152 | // static | 152 | // static |
153 | void LLSliderCtrl::onEditorGainFocus( LLUICtrl* caller, void *userdata ) | 153 | void LLSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata ) |
154 | { | 154 | { |
155 | LLSliderCtrl* self = (LLSliderCtrl*) userdata; | 155 | LLSliderCtrl* self = (LLSliderCtrl*) userdata; |
156 | llassert( caller == self->mEditor ); | 156 | llassert( caller == self->mEditor ); |
diff --git a/linden/indra/llui/llsliderctrl.h b/linden/indra/llui/llsliderctrl.h index 87d2d89..7af0abf 100644 --- a/linden/indra/llui/llsliderctrl.h +++ b/linden/indra/llui/llsliderctrl.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -117,7 +117,7 @@ public: | |||
117 | static void onSliderMouseUp(LLUICtrl* caller,void* userdata); | 117 | static void onSliderMouseUp(LLUICtrl* caller,void* userdata); |
118 | 118 | ||
119 | static void onEditorCommit(LLUICtrl* caller, void* userdata); | 119 | static void onEditorCommit(LLUICtrl* caller, void* userdata); |
120 | static void onEditorGainFocus(LLUICtrl* caller, void *userdata); | 120 | static void onEditorGainFocus(LLFocusableElement* caller, void *userdata); |
121 | static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata); | 121 | static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata); |
122 | 122 | ||
123 | private: | 123 | private: |
diff --git a/linden/indra/llui/llspinctrl.cpp b/linden/indra/llui/llspinctrl.cpp index 0cd9390..4bd79e6 100644 --- a/linden/indra/llui/llspinctrl.cpp +++ b/linden/indra/llui/llspinctrl.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -128,7 +128,7 @@ LLSpinCtrl::LLSpinCtrl( const LLString& name, const LLRect& rect, const LLString | |||
128 | &LLLineEditor::prevalidateFloat ); | 128 | &LLLineEditor::prevalidateFloat ); |
129 | mEditor->setFollowsLeft(); | 129 | mEditor->setFollowsLeft(); |
130 | mEditor->setFollowsBottom(); | 130 | mEditor->setFollowsBottom(); |
131 | mEditor->setFocusReceivedCallback( &LLSpinCtrl::onEditorGainFocus ); | 131 | mEditor->setFocusReceivedCallback( &LLSpinCtrl::onEditorGainFocus, this ); |
132 | //RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus | 132 | //RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus |
133 | // than when it doesn't. Instead, if you always have to double click to select all the text, | 133 | // than when it doesn't. Instead, if you always have to double click to select all the text, |
134 | // it's easier to understand | 134 | // it's easier to understand |
@@ -137,7 +137,7 @@ LLSpinCtrl::LLSpinCtrl( const LLString& name, const LLRect& rect, const LLString | |||
137 | addChild(mEditor); | 137 | addChild(mEditor); |
138 | 138 | ||
139 | updateEditor(); | 139 | updateEditor(); |
140 | setSpanChildren( TRUE ); | 140 | setUseBoundingRect( TRUE ); |
141 | } | 141 | } |
142 | 142 | ||
143 | LLSpinCtrl::~LLSpinCtrl() | 143 | LLSpinCtrl::~LLSpinCtrl() |
@@ -230,7 +230,7 @@ void LLSpinCtrl::onDownBtn( void *userdata ) | |||
230 | } | 230 | } |
231 | 231 | ||
232 | // static | 232 | // static |
233 | void LLSpinCtrl::onEditorGainFocus( LLUICtrl* caller, void *userdata ) | 233 | void LLSpinCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata ) |
234 | { | 234 | { |
235 | LLSpinCtrl* self = (LLSpinCtrl*) userdata; | 235 | LLSpinCtrl* self = (LLSpinCtrl*) userdata; |
236 | llassert( caller == self->mEditor ); | 236 | llassert( caller == self->mEditor ); |
diff --git a/linden/indra/llui/llspinctrl.h b/linden/indra/llui/llspinctrl.h index de8513e..c5a36f5 100644 --- a/linden/indra/llui/llspinctrl.h +++ b/linden/indra/llui/llspinctrl.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -113,7 +113,7 @@ public: | |||
113 | virtual void draw(); | 113 | virtual void draw(); |
114 | 114 | ||
115 | static void onEditorCommit(LLUICtrl* caller, void* userdata); | 115 | static void onEditorCommit(LLUICtrl* caller, void* userdata); |
116 | static void onEditorGainFocus(LLUICtrl* caller, void *userdata); | 116 | static void onEditorGainFocus(LLFocusableElement* caller, void *userdata); |
117 | static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata); | 117 | static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata); |
118 | 118 | ||
119 | static void onUpBtn(void *userdata); | 119 | static void onUpBtn(void *userdata); |
diff --git a/linden/indra/llui/llstyle.cpp b/linden/indra/llui/llstyle.cpp index 2281d44..693e0be 100644 --- a/linden/indra/llui/llstyle.cpp +++ b/linden/indra/llui/llstyle.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -230,7 +230,7 @@ void LLStyle::setImage(const LLString& src) | |||
230 | } | 230 | } |
231 | else | 231 | else |
232 | { | 232 | { |
233 | mImagep = LLUI::sImageProvider->getUIImageByID(LLUUID(src)); | 233 | mImagep = LLUI::sImageProvider->getImageByID(LLUUID(src)); |
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
diff --git a/linden/indra/llui/llstyle.h b/linden/indra/llui/llstyle.h index fcff789..1712dc0 100644 --- a/linden/indra/llui/llstyle.h +++ b/linden/indra/llui/llstyle.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/lltabcontainer.cpp b/linden/indra/llui/lltabcontainer.cpp index 19dc6ec..0400b50 100644 --- a/linden/indra/llui/lltabcontainer.cpp +++ b/linden/indra/llui/lltabcontainer.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -156,7 +156,12 @@ void LLTabContainerCommon::lockTabs(S32 num_tabs) | |||
156 | { | 156 | { |
157 | // count current tabs or use supplied value and ensure no new tabs get | 157 | // count current tabs or use supplied value and ensure no new tabs get |
158 | // inserted between them | 158 | // inserted between them |
159 | mLockedTabCount = num_tabs > 0 ? num_tabs : getTabCount(); | 159 | mLockedTabCount = num_tabs > 0 ? llmin(getTabCount(), num_tabs) : getTabCount(); |
160 | } | ||
161 | |||
162 | void LLTabContainerCommon::unlockTabs() | ||
163 | { | ||
164 | mLockedTabCount = 0; | ||
160 | } | 165 | } |
161 | 166 | ||
162 | void LLTabContainerCommon::removeTabPanel(LLPanel* child) | 167 | void LLTabContainerCommon::removeTabPanel(LLPanel* child) |
@@ -557,7 +562,7 @@ void LLTabContainerCommon::setTabImage(LLPanel* child, std::string img_name, con | |||
557 | } | 562 | } |
558 | 563 | ||
559 | void LLTabContainerCommon::setTitle(const LLString& title) | 564 | void LLTabContainerCommon::setTitle(const LLString& title) |
560 | { | 565 | { |
561 | if (mTitleBox) | 566 | if (mTitleBox) |
562 | { | 567 | { |
563 | mTitleBox->setText( title ); | 568 | mTitleBox->setText( title ); |
@@ -721,6 +726,14 @@ void LLTabContainerCommon::insertTuple(LLTabTuple * tuple, eInsertionPoint inser | |||
721 | // insert the new tab in the front of the list | 726 | // insert the new tab in the front of the list |
722 | mTabList.insert(mTabList.begin() + mLockedTabCount, tuple); | 727 | mTabList.insert(mTabList.begin() + mLockedTabCount, tuple); |
723 | break; | 728 | break; |
729 | case LEFT_OF_CURRENT: | ||
730 | // insert the new tab before the current tab (but not before mLockedTabCount) | ||
731 | { | ||
732 | tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx); | ||
733 | mTabList.insert(current_iter, tuple); | ||
734 | } | ||
735 | break; | ||
736 | |||
724 | case RIGHT_OF_CURRENT: | 737 | case RIGHT_OF_CURRENT: |
725 | // insert the new tab after the current tab (but not before mLockedTabCount) | 738 | // insert the new tab after the current tab (but not before mLockedTabCount) |
726 | { | 739 | { |
@@ -946,14 +959,14 @@ void LLTabContainer::addTabPanel(LLPanel* child, | |||
946 | if( LLTabContainer::TOP == mTabPosition ) | 959 | if( LLTabContainer::TOP == mTabPosition ) |
947 | { | 960 | { |
948 | btn_rect.setLeftTopAndSize( 0, mRect.getHeight() - mTopBorderHeight + tab_fudge, button_width, TABCNTR_TAB_HEIGHT ); | 961 | btn_rect.setLeftTopAndSize( 0, mRect.getHeight() - mTopBorderHeight + tab_fudge, button_width, TABCNTR_TAB_HEIGHT ); |
949 | tab_img = "UIImgBtnTabTopOutUUID"; | 962 | tab_img = "tab_top_blue.tga"; |
950 | tab_selected_img = "UIImgBtnTabTopInUUID"; | 963 | tab_selected_img = "tab_top_selected_blue.tga"; |
951 | } | 964 | } |
952 | else | 965 | else |
953 | { | 966 | { |
954 | btn_rect.setOriginAndSize( 0, 0 + tab_fudge, button_width, TABCNTR_TAB_HEIGHT ); | 967 | btn_rect.setOriginAndSize( 0, 0 + tab_fudge, button_width, TABCNTR_TAB_HEIGHT ); |
955 | tab_img = "UIImgBtnTabBottomOutUUID"; | 968 | tab_img = "tab_bottom_blue.tga"; |
956 | tab_selected_img = "UIImgBtnTabBottomInUUID"; | 969 | tab_selected_img = "tab_bottom_selected_blue.tga"; |
957 | } | 970 | } |
958 | 971 | ||
959 | if (placeholder) | 972 | if (placeholder) |
@@ -979,7 +992,7 @@ void LLTabContainer::addTabPanel(LLPanel* child, | |||
979 | LLButton* btn = new LLButton( | 992 | LLButton* btn = new LLButton( |
980 | LLString(child->getName()) + " tab", | 993 | LLString(child->getName()) + " tab", |
981 | btn_rect, | 994 | btn_rect, |
982 | tab_img, tab_selected_img, "", | 995 | "", "", "", |
983 | &LLTabContainer::onTabBtn, NULL, // set userdata below | 996 | &LLTabContainer::onTabBtn, NULL, // set userdata below |
984 | font, | 997 | font, |
985 | trimmed_label, trimmed_label ); | 998 | trimmed_label, trimmed_label ); |
@@ -987,7 +1000,7 @@ void LLTabContainer::addTabPanel(LLPanel* child, | |||
987 | btn->setVisible( FALSE ); | 1000 | btn->setVisible( FALSE ); |
988 | btn->setToolTip( tooltip ); | 1001 | btn->setToolTip( tooltip ); |
989 | btn->setScaleImage(TRUE); | 1002 | btn->setScaleImage(TRUE); |
990 | btn->setFixedBorder(14, 14); | 1003 | btn->setImages(tab_img, tab_selected_img); |
991 | 1004 | ||
992 | // Try to squeeze in a bit more text | 1005 | // Try to squeeze in a bit more text |
993 | btn->setLeftHPad( 4 ); | 1006 | btn->setLeftHPad( 4 ); |
@@ -1139,7 +1152,7 @@ BOOL LLTabContainer::selectTab(S32 which) | |||
1139 | 1152 | ||
1140 | //if( gFocusMgr.childHasKeyboardFocus( this ) ) | 1153 | //if( gFocusMgr.childHasKeyboardFocus( this ) ) |
1141 | //{ | 1154 | //{ |
1142 | // gFocusMgr.setKeyboardFocus( NULL, NULL ); | 1155 | // gFocusMgr.setKeyboardFocus( NULL ); |
1143 | //} | 1156 | //} |
1144 | 1157 | ||
1145 | LLTabTuple* selected_tuple = mTabList[which]; | 1158 | LLTabTuple* selected_tuple = mTabList[which]; |
@@ -1370,7 +1383,7 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) | |||
1370 | { | 1383 | { |
1371 | LLButton* tab_button = mTabList[getCurrentPanelIndex()]->mButton; | 1384 | LLButton* tab_button = mTabList[getCurrentPanelIndex()]->mButton; |
1372 | gFocusMgr.setMouseCapture(this); | 1385 | gFocusMgr.setMouseCapture(this); |
1373 | gFocusMgr.setKeyboardFocus(tab_button, NULL); | 1386 | gFocusMgr.setKeyboardFocus(tab_button); |
1374 | } | 1387 | } |
1375 | } | 1388 | } |
1376 | return handled; | 1389 | return handled; |
@@ -1475,7 +1488,7 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask ) | |||
1475 | BOOL LLTabContainer::handleToolTip( S32 x, S32 y, LLString& msg, LLRect* sticky_rect ) | 1488 | BOOL LLTabContainer::handleToolTip( S32 x, S32 y, LLString& msg, LLRect* sticky_rect ) |
1476 | { | 1489 | { |
1477 | BOOL handled = LLPanel::handleToolTip( x, y, msg, sticky_rect ); | 1490 | BOOL handled = LLPanel::handleToolTip( x, y, msg, sticky_rect ); |
1478 | if (!handled && mTabList.size() > 0 && getVisible() && pointInView( x, y ) ) | 1491 | if (!handled && mTabList.size() > 0) |
1479 | { | 1492 | { |
1480 | LLTabTuple* firsttuple = mTabList[0]; | 1493 | LLTabTuple* firsttuple = mTabList[0]; |
1481 | 1494 | ||
@@ -1645,12 +1658,12 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const L | |||
1645 | mTotalTabWidth -= tuple->mButton->getRect().getWidth(); | 1658 | mTotalTabWidth -= tuple->mButton->getRect().getWidth(); |
1646 | 1659 | ||
1647 | S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? | 1660 | S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? |
1648 | tuple->mButton->getImageOverlay()->getWidth(0) : | 1661 | tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : |
1649 | 0; | 1662 | 0; |
1650 | 1663 | ||
1651 | tuple->mPadding = image_overlay_width; | 1664 | tuple->mPadding = image_overlay_width; |
1652 | 1665 | ||
1653 | tuple->mButton->setRightHPad(tuple->mPadding + LLBUTTON_H_PAD); | 1666 | tuple->mButton->setRightHPad(6); |
1654 | tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), | 1667 | tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), |
1655 | tuple->mButton->getRect().getHeight()); | 1668 | tuple->mButton->getRect().getHeight()); |
1656 | // add back in button width to total tab strip width | 1669 | // add back in button width to total tab strip width |
diff --git a/linden/indra/llui/lltabcontainer.h b/linden/indra/llui/lltabcontainer.h index 3f2b1b4..e2770ee 100644 --- a/linden/indra/llui/lltabcontainer.h +++ b/linden/indra/llui/lltabcontainer.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -54,6 +54,7 @@ public: | |||
54 | { | 54 | { |
55 | START, | 55 | START, |
56 | END, | 56 | END, |
57 | LEFT_OF_CURRENT, | ||
57 | RIGHT_OF_CURRENT | 58 | RIGHT_OF_CURRENT |
58 | } eInsertionPoint; | 59 | } eInsertionPoint; |
59 | 60 | ||
@@ -91,6 +92,8 @@ public: | |||
91 | eInsertionPoint insertion_point = END) = 0; | 92 | eInsertionPoint insertion_point = END) = 0; |
92 | virtual void addPlaceholder(LLPanel* child, const LLString& label); | 93 | virtual void addPlaceholder(LLPanel* child, const LLString& label); |
93 | virtual void lockTabs(S32 num_tabs = 0); | 94 | virtual void lockTabs(S32 num_tabs = 0); |
95 | virtual void unlockTabs(); | ||
96 | S32 getNumLockedTabs() { return mLockedTabCount; } | ||
94 | 97 | ||
95 | virtual void enableTabButton(S32 which, BOOL enable); | 98 | virtual void enableTabButton(S32 which, BOOL enable); |
96 | 99 | ||
diff --git a/linden/indra/llui/lltabcontainervertical.cpp b/linden/indra/llui/lltabcontainervertical.cpp index 5a04417..334cb43 100644 --- a/linden/indra/llui/lltabcontainervertical.cpp +++ b/linden/indra/llui/lltabcontainervertical.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -185,14 +185,14 @@ void LLTabContainerVertical::addTabPanel(LLPanel* child, const LLString& label, | |||
185 | { | 185 | { |
186 | LLButton *btn = new LLButton("vert tab button", | 186 | LLButton *btn = new LLButton("vert tab button", |
187 | btn_rect, | 187 | btn_rect, |
188 | "tab_left.tga", | 188 | "", |
189 | "tab_left_selected.tga", | 189 | "", |
190 | "", | 190 | "", |
191 | &LLTabContainerVertical::onTabBtn, NULL, | 191 | &LLTabContainerVertical::onTabBtn, NULL, |
192 | font, | 192 | font, |
193 | trimmed_label, trimmed_label); | 193 | trimmed_label, trimmed_label); |
194 | btn->setSaveToXML(false); | 194 | btn->setSaveToXML(false); |
195 | btn->setFixedBorder(16, 16); | 195 | btn->setImages("tab_left.tga", "tab_left_selected.tga"); |
196 | btn->setScaleImage(TRUE); | 196 | btn->setScaleImage(TRUE); |
197 | btn->setHAlign(LLFontGL::LEFT); | 197 | btn->setHAlign(LLFontGL::LEFT); |
198 | btn->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); | 198 | btn->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); |
@@ -306,7 +306,7 @@ BOOL LLTabContainerVertical::selectTab(S32 which) | |||
306 | 306 | ||
307 | //if( gFocusMgr.childHasKeyboardFocus( this ) ) | 307 | //if( gFocusMgr.childHasKeyboardFocus( this ) ) |
308 | //{ | 308 | //{ |
309 | // gFocusMgr.setKeyboardFocus( NULL, NULL ); | 309 | // gFocusMgr.setKeyboardFocus( NULL ); |
310 | //} | 310 | //} |
311 | 311 | ||
312 | LLTabTuple* selected_tuple = mTabList[which]; | 312 | LLTabTuple* selected_tuple = mTabList[which]; |
@@ -476,7 +476,7 @@ BOOL LLTabContainerVertical::handleMouseDown( S32 x, S32 y, MASK mask ) | |||
476 | { | 476 | { |
477 | LLButton* tab_button = mTabList[getCurrentPanelIndex()]->mButton; | 477 | LLButton* tab_button = mTabList[getCurrentPanelIndex()]->mButton; |
478 | gFocusMgr.setMouseCapture(this); | 478 | gFocusMgr.setMouseCapture(this); |
479 | gFocusMgr.setKeyboardFocus(tab_button, NULL); | 479 | gFocusMgr.setKeyboardFocus(tab_button); |
480 | } | 480 | } |
481 | } | 481 | } |
482 | return handled; | 482 | return handled; |
diff --git a/linden/indra/llui/lltabcontainervertical.h b/linden/indra/llui/lltabcontainervertical.h index bfaf461..e887e53 100644 --- a/linden/indra/llui/lltabcontainervertical.h +++ b/linden/indra/llui/lltabcontainervertical.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/lltextbox.cpp b/linden/indra/llui/lltextbox.cpp index d2dae30..1422e0a 100644 --- a/linden/indra/llui/lltextbox.cpp +++ b/linden/indra/llui/lltextbox.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -56,6 +56,7 @@ LLTextBox::LLTextBox(const LLString& name, const LLRect& rect, const LLString& t | |||
56 | mBorderVisible( FALSE ), | 56 | mBorderVisible( FALSE ), |
57 | mFontStyle(LLFontGL::DROP_SHADOW_SOFT), | 57 | mFontStyle(LLFontGL::DROP_SHADOW_SOFT), |
58 | mBorderDropShadowVisible( FALSE ), | 58 | mBorderDropShadowVisible( FALSE ), |
59 | mUseEllipses( FALSE ), | ||
59 | mHPad(0), | 60 | mHPad(0), |
60 | mVPad(0), | 61 | mVPad(0), |
61 | mHAlign( LLFontGL::LEFT ), | 62 | mHAlign( LLFontGL::LEFT ), |
@@ -84,6 +85,7 @@ LLTextBox::LLTextBox(const LLString& name, const LLString& text, F32 max_width, | |||
84 | mBorderVisible(FALSE), | 85 | mBorderVisible(FALSE), |
85 | mFontStyle(LLFontGL::DROP_SHADOW_SOFT), | 86 | mFontStyle(LLFontGL::DROP_SHADOW_SOFT), |
86 | mBorderDropShadowVisible(FALSE), | 87 | mBorderDropShadowVisible(FALSE), |
88 | mUseEllipses( FALSE ), | ||
87 | mHPad(0), | 89 | mHPad(0), |
88 | mVPad(0), | 90 | mVPad(0), |
89 | mHAlign(LLFontGL::LEFT), | 91 | mHAlign(LLFontGL::LEFT), |
@@ -174,7 +176,7 @@ BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask) | |||
174 | mHasHover = TRUE; // This should be set every frame during a hover. | 176 | mHasHover = TRUE; // This should be set every frame during a hover. |
175 | return TRUE; | 177 | return TRUE; |
176 | } | 178 | } |
177 | return FALSE; | 179 | return LLView::handleHover(x,y,mask); |
178 | } | 180 | } |
179 | 181 | ||
180 | void LLTextBox::setText(const LLStringExplicit& text) | 182 | void LLTextBox::setText(const LLStringExplicit& text) |
@@ -393,7 +395,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) | |||
393 | mFontGL->render(mText.getWString(), cur_pos, (F32)x, (F32)y, color, | 395 | mFontGL->render(mText.getWString(), cur_pos, (F32)x, (F32)y, color, |
394 | mHAlign, mVAlign, | 396 | mHAlign, mVAlign, |
395 | mFontStyle, | 397 | mFontStyle, |
396 | line_length, mRect.getWidth(), NULL, TRUE ); | 398 | line_length, mRect.getWidth(), NULL, TRUE, mUseEllipses ); |
397 | cur_pos += line_length + 1; | 399 | cur_pos += line_length + 1; |
398 | y -= llfloor(mFontGL->getLineHeight()); | 400 | y -= llfloor(mFontGL->getLineHeight()); |
399 | } | 401 | } |
@@ -403,7 +405,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) | |||
403 | mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color, | 405 | mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color, |
404 | mHAlign, mVAlign, | 406 | mHAlign, mVAlign, |
405 | mFontStyle, | 407 | mFontStyle, |
406 | S32_MAX, mRect.getWidth(), NULL, TRUE); | 408 | S32_MAX, mRect.getWidth(), NULL, TRUE, mUseEllipses); |
407 | } | 409 | } |
408 | } | 410 | } |
409 | 411 | ||
@@ -481,7 +483,7 @@ LLView* LLTextBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f | |||
481 | text_box->mFontStyle = LLFontGL::getStyleFromString(font_style); | 483 | text_box->mFontStyle = LLFontGL::getStyleFromString(font_style); |
482 | } | 484 | } |
483 | 485 | ||
484 | BOOL mouse_opaque; | 486 | BOOL mouse_opaque = text_box->getMouseOpaque(); |
485 | if (node->getAttributeBOOL("mouse_opaque", mouse_opaque)) | 487 | if (node->getAttributeBOOL("mouse_opaque", mouse_opaque)) |
486 | { | 488 | { |
487 | text_box->setMouseOpaque(mouse_opaque); | 489 | text_box->setMouseOpaque(mouse_opaque); |
diff --git a/linden/indra/llui/lltextbox.h b/linden/indra/llui/lltextbox.h index bdcccf7..c8bdfc5 100644 --- a/linden/indra/llui/lltextbox.h +++ b/linden/indra/llui/lltextbox.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -79,6 +79,7 @@ public: | |||
79 | void setText( const LLStringExplicit& text ); | 79 | void setText( const LLStringExplicit& text ); |
80 | void setWrappedText(const LLStringExplicit& text, F32 max_width = -1.0); | 80 | void setWrappedText(const LLStringExplicit& text, F32 max_width = -1.0); |
81 | // default width means use existing control width | 81 | // default width means use existing control width |
82 | void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; } | ||
82 | 83 | ||
83 | void setBackgroundVisible(BOOL visible) { mBackgroundVisible = visible; } | 84 | void setBackgroundVisible(BOOL visible) { mBackgroundVisible = visible; } |
84 | void setBorderVisible(BOOL visible) { mBorderVisible = visible; } | 85 | void setBorderVisible(BOOL visible) { mBorderVisible = visible; } |
@@ -124,6 +125,7 @@ protected: | |||
124 | 125 | ||
125 | U8 mFontStyle; // style bit flags for font | 126 | U8 mFontStyle; // style bit flags for font |
126 | BOOL mBorderDropShadowVisible; | 127 | BOOL mBorderDropShadowVisible; |
128 | BOOL mUseEllipses; | ||
127 | 129 | ||
128 | S32 mHPad; | 130 | S32 mHPad; |
129 | S32 mVPad; | 131 | S32 mVPad; |
diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index b4d693b..ca9ea0a 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -79,6 +79,15 @@ const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds | |||
79 | const S32 CURSOR_THICKNESS = 2; | 79 | const S32 CURSOR_THICKNESS = 2; |
80 | const S32 SPACES_PER_TAB = 4; | 80 | const S32 SPACES_PER_TAB = 4; |
81 | 81 | ||
82 | const F32 PREEDIT_MARKER_BRIGHTNESS = 0.4f; | ||
83 | const S32 PREEDIT_MARKER_GAP = 1; | ||
84 | const S32 PREEDIT_MARKER_POSITION = 2; | ||
85 | const S32 PREEDIT_MARKER_THICKNESS = 1; | ||
86 | const F32 PREEDIT_STANDOUT_BRIGHTNESS = 0.6f; | ||
87 | const S32 PREEDIT_STANDOUT_GAP = 1; | ||
88 | const S32 PREEDIT_STANDOUT_POSITION = 2; | ||
89 | const S32 PREEDIT_STANDOUT_THICKNESS = 2; | ||
90 | |||
82 | LLColor4 LLTextEditor::mLinkColor = LLColor4::blue; | 91 | LLColor4 LLTextEditor::mLinkColor = LLColor4::blue; |
83 | void (* LLTextEditor::mURLcallback)(const char*) = NULL; | 92 | void (* LLTextEditor::mURLcallback)(const char*) = NULL; |
84 | bool (* LLTextEditor::mSecondlifeURLcallback)(const std::string&) = NULL; | 93 | bool (* LLTextEditor::mSecondlifeURLcallback)(const std::string&) = NULL; |
@@ -274,14 +283,14 @@ private: | |||
274 | LLTextEditor::LLTextEditor( | 283 | LLTextEditor::LLTextEditor( |
275 | const LLString& name, | 284 | const LLString& name, |
276 | const LLRect& rect, | 285 | const LLRect& rect, |
277 | S32 max_length, | 286 | S32 max_length, // In bytes |
278 | const LLString &default_text, | 287 | const LLString &default_text, |
279 | const LLFontGL* font, | 288 | const LLFontGL* font, |
280 | BOOL allow_embedded_items) | 289 | BOOL allow_embedded_items) |
281 | : | 290 | : |
282 | LLUICtrl( name, rect, TRUE, NULL, NULL, FOLLOWS_TOP | FOLLOWS_LEFT ), | 291 | LLUICtrl( name, rect, TRUE, NULL, NULL, FOLLOWS_TOP | FOLLOWS_LEFT ), |
283 | mTextIsUpToDate(TRUE), | 292 | mTextIsUpToDate(TRUE), |
284 | mMaxTextLength( max_length ), | 293 | mMaxTextByteLength( max_length ), |
285 | mBaseDocIsPristine(TRUE), | 294 | mBaseDocIsPristine(TRUE), |
286 | mPristineCmd( NULL ), | 295 | mPristineCmd( NULL ), |
287 | mLastCmd( NULL ), | 296 | mLastCmd( NULL ), |
@@ -293,6 +302,7 @@ LLTextEditor::LLTextEditor( | |||
293 | mOnScrollEndData( NULL ), | 302 | mOnScrollEndData( NULL ), |
294 | mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ), | 303 | mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ), |
295 | mFgColor( LLUI::sColorsGroup->getColor( "TextFgColor" ) ), | 304 | mFgColor( LLUI::sColorsGroup->getColor( "TextFgColor" ) ), |
305 | mDefaultColor( LLUI::sColorsGroup->getColor( "TextDefaultColor" ) ), | ||
296 | mReadOnlyFgColor( LLUI::sColorsGroup->getColor( "TextFgReadOnlyColor" ) ), | 306 | mReadOnlyFgColor( LLUI::sColorsGroup->getColor( "TextFgReadOnlyColor" ) ), |
297 | mWriteableBgColor( LLUI::sColorsGroup->getColor( "TextBgWriteableColor" ) ), | 307 | mWriteableBgColor( LLUI::sColorsGroup->getColor( "TextBgWriteableColor" ) ), |
298 | mReadOnlyBgColor( LLUI::sColorsGroup->getColor( "TextBgReadOnlyColor" ) ), | 308 | mReadOnlyBgColor( LLUI::sColorsGroup->getColor( "TextBgReadOnlyColor" ) ), |
@@ -301,9 +311,9 @@ LLTextEditor::LLTextEditor( | |||
301 | mWordWrap( FALSE ), | 311 | mWordWrap( FALSE ), |
302 | mTabToNextField( TRUE ), | 312 | mTabToNextField( TRUE ), |
303 | mCommitOnFocusLost( FALSE ), | 313 | mCommitOnFocusLost( FALSE ), |
304 | mTakesFocus( TRUE ), | ||
305 | mHideScrollbarForShortDocs( FALSE ), | 314 | mHideScrollbarForShortDocs( FALSE ), |
306 | mTakesNonScrollClicks( TRUE ), | 315 | mTakesNonScrollClicks( TRUE ), |
316 | mTrackBottom( TRUE ), | ||
307 | mAllowEmbeddedItems( allow_embedded_items ), | 317 | mAllowEmbeddedItems( allow_embedded_items ), |
308 | mAcceptCallingCardNames(FALSE), | 318 | mAcceptCallingCardNames(FALSE), |
309 | mHandleEditKeysDirectly( FALSE ), | 319 | mHandleEditKeysDirectly( FALSE ), |
@@ -510,13 +520,27 @@ BOOL LLTextEditor::isPartOfWord(llwchar c) { return (c == '_') || isalnum(c); } | |||
510 | 520 | ||
511 | 521 | ||
512 | 522 | ||
513 | void LLTextEditor::truncate() | 523 | BOOL LLTextEditor::truncate() |
514 | { | 524 | { |
515 | if (mWText.size() > (size_t)mMaxTextLength) | 525 | BOOL did_truncate = FALSE; |
516 | { | 526 | |
517 | LLWString::truncate(mWText, mMaxTextLength); | 527 | // First rough check - if we're less than 1/4th the size, we're OK |
518 | mTextIsUpToDate = FALSE; | 528 | if (mWText.size() >= (size_t) (mMaxTextByteLength / 4)) |
529 | { | ||
530 | // Have to check actual byte size | ||
531 | S32 utf8_byte_size = wstring_utf8_length( mWText ); | ||
532 | if ( utf8_byte_size > mMaxTextByteLength ) | ||
533 | { | ||
534 | // Truncate safely in UTF-8 | ||
535 | std::string temp_utf8_text = wstring_to_utf8str( mWText ); | ||
536 | temp_utf8_text = utf8str_truncate( temp_utf8_text, mMaxTextByteLength ); | ||
537 | mWText = utf8str_to_wstring( temp_utf8_text ); | ||
538 | mTextIsUpToDate = FALSE; | ||
539 | did_truncate = TRUE; | ||
540 | } | ||
519 | } | 541 | } |
542 | |||
543 | return did_truncate; | ||
520 | } | 544 | } |
521 | 545 | ||
522 | void LLTextEditor::setText(const LLStringExplicit &utf8str) | 546 | void LLTextEditor::setText(const LLStringExplicit &utf8str) |
@@ -750,12 +774,12 @@ S32 LLTextEditor::nextWordPos(S32 cursorPos) const | |||
750 | return cursorPos; | 774 | return cursorPos; |
751 | } | 775 | } |
752 | 776 | ||
753 | S32 LLTextEditor::getLineCount() | 777 | S32 LLTextEditor::getLineCount() const |
754 | { | 778 | { |
755 | return mLineStartList.size(); | 779 | return mLineStartList.size(); |
756 | } | 780 | } |
757 | 781 | ||
758 | S32 LLTextEditor::getLineStart( S32 line ) | 782 | S32 LLTextEditor::getLineStart( S32 line ) const |
759 | { | 783 | { |
760 | S32 num_lines = getLineCount(); | 784 | S32 num_lines = getLineCount(); |
761 | if (num_lines == 0) | 785 | if (num_lines == 0) |
@@ -1118,46 +1142,42 @@ void LLTextEditor::selectAll() | |||
1118 | 1142 | ||
1119 | BOOL LLTextEditor::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) | 1143 | BOOL LLTextEditor::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) |
1120 | { | 1144 | { |
1121 | if (pointInView(x, y) && getVisible()) | 1145 | for ( child_list_const_iter_t child_it = getChildList()->begin(); |
1146 | child_it != getChildList()->end(); ++child_it) | ||
1122 | { | 1147 | { |
1123 | for ( child_list_const_iter_t child_it = getChildList()->begin(); | 1148 | LLView* viewp = *child_it; |
1124 | child_it != getChildList()->end(); ++child_it) | 1149 | S32 local_x = x - viewp->getRect().mLeft; |
1125 | { | 1150 | S32 local_y = y - viewp->getRect().mBottom; |
1126 | LLView* viewp = *child_it; | 1151 | if( viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen ) ) |
1127 | S32 local_x = x - viewp->getRect().mLeft; | ||
1128 | S32 local_y = y - viewp->getRect().mBottom; | ||
1129 | if( viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen ) ) | ||
1130 | { | ||
1131 | return TRUE; | ||
1132 | } | ||
1133 | } | ||
1134 | |||
1135 | if( mSegments.empty() ) | ||
1136 | { | 1152 | { |
1137 | return TRUE; | 1153 | return TRUE; |
1138 | } | 1154 | } |
1155 | } | ||
1139 | 1156 | ||
1140 | LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); | 1157 | if( mSegments.empty() ) |
1141 | if( cur_segment ) | 1158 | { |
1142 | { | 1159 | return TRUE; |
1143 | BOOL has_tool_tip = FALSE; | 1160 | } |
1144 | has_tool_tip = cur_segment->getToolTip( msg ); | ||
1145 | 1161 | ||
1146 | if( has_tool_tip ) | 1162 | LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); |
1147 | { | 1163 | if( cur_segment ) |
1148 | // Just use a slop area around the cursor | 1164 | { |
1149 | // Convert rect local to screen coordinates | 1165 | BOOL has_tool_tip = FALSE; |
1150 | S32 SLOP = 8; | 1166 | has_tool_tip = cur_segment->getToolTip( msg ); |
1151 | localPointToScreen( | 1167 | |
1152 | x - SLOP, y - SLOP, | 1168 | if( has_tool_tip ) |
1153 | &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); | 1169 | { |
1154 | sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP; | 1170 | // Just use a slop area around the cursor |
1155 | sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP; | 1171 | // Convert rect local to screen coordinates |
1156 | } | 1172 | S32 SLOP = 8; |
1173 | localPointToScreen( | ||
1174 | x - SLOP, y - SLOP, | ||
1175 | &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); | ||
1176 | sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP; | ||
1177 | sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP; | ||
1157 | } | 1178 | } |
1158 | return TRUE; | ||
1159 | } | 1179 | } |
1160 | return FALSE; | 1180 | return TRUE; |
1161 | } | 1181 | } |
1162 | 1182 | ||
1163 | BOOL LLTextEditor::handleScrollWheel(S32 x, S32 y, S32 clicks) | 1183 | BOOL LLTextEditor::handleScrollWheel(S32 x, S32 y, S32 clicks) |
@@ -1240,7 +1260,7 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) | |||
1240 | handled = TRUE; | 1260 | handled = TRUE; |
1241 | } | 1261 | } |
1242 | 1262 | ||
1243 | if (mTakesFocus) | 1263 | if (hasTabStop()) |
1244 | { | 1264 | { |
1245 | setFocus( TRUE ); | 1265 | setFocus( TRUE ); |
1246 | handled = TRUE; | 1266 | handled = TRUE; |
@@ -1413,11 +1433,6 @@ BOOL LLTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) | |||
1413 | 1433 | ||
1414 | if( !handled && mTakesNonScrollClicks) | 1434 | if( !handled && mTakesNonScrollClicks) |
1415 | { | 1435 | { |
1416 | if (mTakesFocus) | ||
1417 | { | ||
1418 | setFocus( TRUE ); | ||
1419 | } | ||
1420 | |||
1421 | setCursorAtLocalPos( x, y, FALSE ); | 1436 | setCursorAtLocalPos( x, y, FALSE ); |
1422 | deselect(); | 1437 | deselect(); |
1423 | 1438 | ||
@@ -1604,7 +1619,7 @@ void LLTextEditor::removeChar() | |||
1604 | // Add a single character to the text | 1619 | // Add a single character to the text |
1605 | S32 LLTextEditor::addChar(S32 pos, llwchar wc) | 1620 | S32 LLTextEditor::addChar(S32 pos, llwchar wc) |
1606 | { | 1621 | { |
1607 | if ((S32)mWText.length() == mMaxTextLength) | 1622 | if ( (wstring_utf8_length( mWText ) + wchar_utf8_length( wc )) >= mMaxTextByteLength) |
1608 | { | 1623 | { |
1609 | make_ui_sound("UISndBadKeystroke"); | 1624 | make_ui_sound("UISndBadKeystroke"); |
1610 | return 0; | 1625 | return 0; |
@@ -2490,11 +2505,16 @@ void LLTextEditor::redo() | |||
2490 | } | 2505 | } |
2491 | } | 2506 | } |
2492 | 2507 | ||
2508 | void LLTextEditor::onFocusReceived() | ||
2509 | { | ||
2510 | LLUICtrl::onFocusReceived(); | ||
2511 | updateAllowingLanguageInput(); | ||
2512 | } | ||
2493 | 2513 | ||
2494 | // virtual, from LLView | 2514 | // virtual, from LLView |
2495 | void LLTextEditor::onFocusLost() | 2515 | void LLTextEditor::onFocusLost() |
2496 | { | 2516 | { |
2497 | getWindow()->allowLanguageTextInput(FALSE); | 2517 | updateAllowingLanguageInput(); |
2498 | 2518 | ||
2499 | // Route menu back to the default | 2519 | // Route menu back to the default |
2500 | if( gEditMenuHandler == this ) | 2520 | if( gEditMenuHandler == this ) |
@@ -2521,6 +2541,7 @@ void LLTextEditor::setEnabled(BOOL enabled) | |||
2521 | { | 2541 | { |
2522 | mReadOnly = read_only; | 2542 | mReadOnly = read_only; |
2523 | updateSegments(); | 2543 | updateSegments(); |
2544 | updateAllowingLanguageInput(); | ||
2524 | } | 2545 | } |
2525 | } | 2546 | } |
2526 | 2547 | ||
@@ -2825,6 +2846,100 @@ void LLTextEditor::drawCursor() | |||
2825 | } | 2846 | } |
2826 | } | 2847 | } |
2827 | 2848 | ||
2849 | void LLTextEditor::drawPreeditMarker() | ||
2850 | { | ||
2851 | if (!hasPreeditString()) | ||
2852 | { | ||
2853 | return; | ||
2854 | } | ||
2855 | |||
2856 | const llwchar *text = mWText.c_str(); | ||
2857 | const S32 text_len = getLength(); | ||
2858 | const S32 num_lines = getLineCount(); | ||
2859 | |||
2860 | S32 cur_line = mScrollbar->getDocPos(); | ||
2861 | if (cur_line >= num_lines) | ||
2862 | { | ||
2863 | return; | ||
2864 | } | ||
2865 | |||
2866 | const S32 line_height = llround( mGLFont->getLineHeight() ); | ||
2867 | |||
2868 | S32 line_start = getLineStart(cur_line); | ||
2869 | S32 line_y = mTextRect.mTop - line_height; | ||
2870 | while((mTextRect.mBottom <= line_y) && (num_lines > cur_line)) | ||
2871 | { | ||
2872 | S32 next_start = -1; | ||
2873 | S32 line_end = text_len; | ||
2874 | |||
2875 | if ((cur_line + 1) < num_lines) | ||
2876 | { | ||
2877 | next_start = getLineStart(cur_line + 1); | ||
2878 | line_end = next_start; | ||
2879 | } | ||
2880 | if ( text[line_end-1] == '\n' ) | ||
2881 | { | ||
2882 | --line_end; | ||
2883 | } | ||
2884 | |||
2885 | // Does this line contain preedits? | ||
2886 | if (line_start >= mPreeditPositions.back()) | ||
2887 | { | ||
2888 | // We have passed the preedits. | ||
2889 | break; | ||
2890 | } | ||
2891 | if (line_end > mPreeditPositions.front()) | ||
2892 | { | ||
2893 | for (U32 i = 0; i < mPreeditStandouts.size(); i++) | ||
2894 | { | ||
2895 | S32 left = mPreeditPositions[i]; | ||
2896 | S32 right = mPreeditPositions[i + 1]; | ||
2897 | if (right <= line_start || left >= line_end) | ||
2898 | { | ||
2899 | continue; | ||
2900 | } | ||
2901 | |||
2902 | S32 preedit_left = mTextRect.mLeft; | ||
2903 | if (left > line_start) | ||
2904 | { | ||
2905 | preedit_left += mGLFont->getWidth(text, line_start, left - line_start, mAllowEmbeddedItems); | ||
2906 | } | ||
2907 | S32 preedit_right = mTextRect.mLeft; | ||
2908 | if (right < line_end) | ||
2909 | { | ||
2910 | preedit_right += mGLFont->getWidth(text, line_start, right - line_start, mAllowEmbeddedItems); | ||
2911 | } | ||
2912 | else | ||
2913 | { | ||
2914 | preedit_right += mGLFont->getWidth(text, line_start, line_end - line_start, mAllowEmbeddedItems); | ||
2915 | } | ||
2916 | |||
2917 | if (mPreeditStandouts[i]) | ||
2918 | { | ||
2919 | gl_rect_2d(preedit_left + PREEDIT_STANDOUT_GAP, | ||
2920 | line_y + PREEDIT_STANDOUT_POSITION, | ||
2921 | preedit_right - PREEDIT_STANDOUT_GAP - 1, | ||
2922 | line_y + PREEDIT_STANDOUT_POSITION - PREEDIT_STANDOUT_THICKNESS, | ||
2923 | (mCursorColor * PREEDIT_STANDOUT_BRIGHTNESS + mWriteableBgColor * (1 - PREEDIT_STANDOUT_BRIGHTNESS)).setAlpha(1.0f)); | ||
2924 | } | ||
2925 | else | ||
2926 | { | ||
2927 | gl_rect_2d(preedit_left + PREEDIT_MARKER_GAP, | ||
2928 | line_y + PREEDIT_MARKER_POSITION, | ||
2929 | preedit_right - PREEDIT_MARKER_GAP - 1, | ||
2930 | line_y + PREEDIT_MARKER_POSITION - PREEDIT_MARKER_THICKNESS, | ||
2931 | (mCursorColor * PREEDIT_MARKER_BRIGHTNESS + mWriteableBgColor * (1 - PREEDIT_MARKER_BRIGHTNESS)).setAlpha(1.0f)); | ||
2932 | } | ||
2933 | } | ||
2934 | } | ||
2935 | |||
2936 | // move down one line | ||
2937 | line_y -= line_height; | ||
2938 | line_start = next_start; | ||
2939 | cur_line++; | ||
2940 | } | ||
2941 | } | ||
2942 | |||
2828 | 2943 | ||
2829 | void LLTextEditor::drawText() | 2944 | void LLTextEditor::drawText() |
2830 | { | 2945 | { |
@@ -3025,6 +3140,7 @@ void LLTextEditor::draw() | |||
3025 | 3140 | ||
3026 | drawBackground(); | 3141 | drawBackground(); |
3027 | drawSelectionBackground(); | 3142 | drawSelectionBackground(); |
3143 | drawPreeditMarker(); | ||
3028 | drawText(); | 3144 | drawText(); |
3029 | drawCursor(); | 3145 | drawCursor(); |
3030 | 3146 | ||
@@ -3036,6 +3152,9 @@ void LLTextEditor::draw() | |||
3036 | } | 3152 | } |
3037 | LLView::draw(); // Draw children (scrollbar and border) | 3153 | LLView::draw(); // Draw children (scrollbar and border) |
3038 | } | 3154 | } |
3155 | |||
3156 | // remember if we are supposed to be at the bottom of the buffer | ||
3157 | mScrolledToBottom = isScrolledToBottom(); | ||
3039 | } | 3158 | } |
3040 | 3159 | ||
3041 | void LLTextEditor::reportBadKeystroke() | 3160 | void LLTextEditor::reportBadKeystroke() |
@@ -3067,10 +3186,10 @@ void LLTextEditor::setFocus( BOOL new_state ) | |||
3067 | // Don't change anything if the focus state didn't change | 3186 | // Don't change anything if the focus state didn't change |
3068 | if (new_state == old_state) return; | 3187 | if (new_state == old_state) return; |
3069 | 3188 | ||
3070 | // Notify early if we are loosing focus. | 3189 | // Notify early if we are losing focus. |
3071 | if (!new_state) | 3190 | if (!new_state) |
3072 | { | 3191 | { |
3073 | getWindow()->allowLanguageTextInput(FALSE); | 3192 | getWindow()->allowLanguageTextInput(this, FALSE); |
3074 | } | 3193 | } |
3075 | 3194 | ||
3076 | LLUICtrl::setFocus( new_state ); | 3195 | LLUICtrl::setFocus( new_state ); |
@@ -3093,12 +3212,6 @@ void LLTextEditor::setFocus( BOOL new_state ) | |||
3093 | 3212 | ||
3094 | endSelection(); | 3213 | endSelection(); |
3095 | } | 3214 | } |
3096 | |||
3097 | // Notify late if we are gaining focus. | ||
3098 | if (new_state && !mReadOnly) | ||
3099 | { | ||
3100 | getWindow()->allowLanguageTextInput(TRUE); | ||
3101 | } | ||
3102 | } | 3215 | } |
3103 | 3216 | ||
3104 | BOOL LLTextEditor::acceptsTextInput() const | 3217 | BOOL LLTextEditor::acceptsTextInput() const |
@@ -3210,6 +3323,17 @@ void LLTextEditor::changeLine( S32 delta ) | |||
3210 | unbindEmbeddedChars( mGLFont ); | 3323 | unbindEmbeddedChars( mGLFont ); |
3211 | } | 3324 | } |
3212 | 3325 | ||
3326 | BOOL LLTextEditor::isScrolledToTop() | ||
3327 | { | ||
3328 | return mScrollbar->isAtBeginning(); | ||
3329 | } | ||
3330 | |||
3331 | BOOL LLTextEditor::isScrolledToBottom() | ||
3332 | { | ||
3333 | return mScrollbar->isAtEnd(); | ||
3334 | } | ||
3335 | |||
3336 | |||
3213 | void LLTextEditor::startOfLine() | 3337 | void LLTextEditor::startOfLine() |
3214 | { | 3338 | { |
3215 | S32 line, offset; | 3339 | S32 line, offset; |
@@ -3330,6 +3454,13 @@ void LLTextEditor::reshape(S32 width, S32 height, BOOL called_from_parent) | |||
3330 | { | 3454 | { |
3331 | LLView::reshape( width, height, called_from_parent ); | 3455 | LLView::reshape( width, height, called_from_parent ); |
3332 | 3456 | ||
3457 | // if scrolled to bottom, stay at bottom | ||
3458 | // unless user is editing text | ||
3459 | if (mScrolledToBottom && mTrackBottom && !hasFocus()) | ||
3460 | { | ||
3461 | endOfDoc(); | ||
3462 | } | ||
3463 | |||
3333 | updateTextRect(); | 3464 | updateTextRect(); |
3334 | 3465 | ||
3335 | S32 line_height = llround( mGLFont->getLineHeight() ); | 3466 | S32 line_height = llround( mGLFont->getLineHeight() ); |
@@ -3540,22 +3671,20 @@ void LLTextEditor::removeTextFromEnd(S32 num_chars) | |||
3540 | 3671 | ||
3541 | S32 LLTextEditor::insertStringNoUndo(const S32 pos, const LLWString &wstr) | 3672 | S32 LLTextEditor::insertStringNoUndo(const S32 pos, const LLWString &wstr) |
3542 | { | 3673 | { |
3543 | S32 len = mWText.length(); | 3674 | S32 old_len = mWText.length(); // length() returns character length |
3544 | S32 s_len = wstr.length(); | 3675 | S32 insert_len = wstr.length(); |
3545 | S32 new_len = len + s_len; | 3676 | |
3546 | if( new_len > mMaxTextLength ) | 3677 | mWText.insert(pos, wstr); |
3547 | { | 3678 | mTextIsUpToDate = FALSE; |
3548 | new_len = mMaxTextLength; | ||
3549 | 3679 | ||
3680 | if ( truncate() ) | ||
3681 | { | ||
3550 | // The user's not getting everything he's hoping for | 3682 | // The user's not getting everything he's hoping for |
3551 | make_ui_sound("UISndBadKeystroke"); | 3683 | make_ui_sound("UISndBadKeystroke"); |
3684 | insert_len = mWText.length() - old_len; | ||
3552 | } | 3685 | } |
3553 | 3686 | ||
3554 | mWText.insert(pos, wstr); | 3687 | return insert_len; |
3555 | mTextIsUpToDate = FALSE; | ||
3556 | truncate(); | ||
3557 | |||
3558 | return new_len - len; | ||
3559 | } | 3688 | } |
3560 | 3689 | ||
3561 | S32 LLTextEditor::removeStringNoUndo(S32 pos, S32 length) | 3690 | S32 LLTextEditor::removeStringNoUndo(S32 pos, S32 length) |
@@ -3671,7 +3800,7 @@ void LLTextEditor::loadKeywords(const LLString& filename, | |||
3671 | mKeywords.addToken(LLKeywordToken::WORD, name.c_str(), color, tooltips.get(i) ); | 3800 | mKeywords.addToken(LLKeywordToken::WORD, name.c_str(), color, tooltips.get(i) ); |
3672 | } | 3801 | } |
3673 | 3802 | ||
3674 | mKeywords.findSegments( &mSegments, mWText ); | 3803 | mKeywords.findSegments( &mSegments, mWText, mDefaultColor ); |
3675 | 3804 | ||
3676 | llassert( mSegments.front()->getStart() == 0 ); | 3805 | llassert( mSegments.front()->getStart() == 0 ); |
3677 | llassert( mSegments.back()->getEnd() == getLength() ); | 3806 | llassert( mSegments.back()->getEnd() == getLength() ); |
@@ -3683,7 +3812,7 @@ void LLTextEditor::updateSegments() | |||
3683 | if (mKeywords.isLoaded()) | 3812 | if (mKeywords.isLoaded()) |
3684 | { | 3813 | { |
3685 | // HACK: No non-ascii keywords for now | 3814 | // HACK: No non-ascii keywords for now |
3686 | mKeywords.findSegments(&mSegments, mWText); | 3815 | mKeywords.findSegments(&mSegments, mWText, mDefaultColor); |
3687 | } | 3816 | } |
3688 | else if (mAllowEmbeddedItems) | 3817 | else if (mAllowEmbeddedItems) |
3689 | { | 3818 | { |
@@ -3920,7 +4049,7 @@ BOOL LLTextEditor::importBuffer(const LLString& buffer ) | |||
3920 | return FALSE; | 4049 | return FALSE; |
3921 | } | 4050 | } |
3922 | 4051 | ||
3923 | if( text_len > mMaxTextLength ) | 4052 | if( text_len > mMaxTextByteLength ) |
3924 | { | 4053 | { |
3925 | llwarns << "Invalid Linden text length: " << text_len << llendl; | 4054 | llwarns << "Invalid Linden text length: " << text_len << llendl; |
3926 | return FALSE; | 4055 | return FALSE; |
@@ -4064,6 +4193,7 @@ LLXMLNodePtr LLTextEditor::getXML(bool save_children) const | |||
4064 | 4193 | ||
4065 | addColorXML(node, mCursorColor, "cursor_color", "TextCursorColor"); | 4194 | addColorXML(node, mCursorColor, "cursor_color", "TextCursorColor"); |
4066 | addColorXML(node, mFgColor, "text_color", "TextFgColor"); | 4195 | addColorXML(node, mFgColor, "text_color", "TextFgColor"); |
4196 | addColorXML(node, mDefaultColor, "text_default_color", "TextDefaultColor"); | ||
4067 | addColorXML(node, mReadOnlyFgColor, "text_readonly_color", "TextFgReadOnlyColor"); | 4197 | addColorXML(node, mReadOnlyFgColor, "text_readonly_color", "TextFgReadOnlyColor"); |
4068 | addColorXML(node, mReadOnlyBgColor, "bg_readonly_color", "TextBgReadOnlyColor"); | 4198 | addColorXML(node, mReadOnlyBgColor, "bg_readonly_color", "TextBgReadOnlyColor"); |
4069 | addColorXML(node, mWriteableBgColor, "bg_writeable_color", "TextBgWriteableColor"); | 4199 | addColorXML(node, mWriteableBgColor, "bg_writeable_color", "TextBgWriteableColor"); |
@@ -4118,6 +4248,8 @@ void LLTextEditor::setTextEditorParameters(LLXMLNodePtr node) | |||
4118 | node->getAttributeBOOL("word_wrap", word_wrap); | 4248 | node->getAttributeBOOL("word_wrap", word_wrap); |
4119 | setWordWrap(word_wrap); | 4249 | setWordWrap(word_wrap); |
4120 | 4250 | ||
4251 | node->getAttributeBOOL("track_bottom", mTrackBottom); | ||
4252 | |||
4121 | LLColor4 color; | 4253 | LLColor4 color; |
4122 | if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color)) | 4254 | if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color)) |
4123 | { | 4255 | { |
@@ -4281,3 +4413,262 @@ BOOL LLTextEditor::findHTML(const LLString &line, S32 *begin, S32 *end) | |||
4281 | } | 4413 | } |
4282 | return matched; | 4414 | return matched; |
4283 | } | 4415 | } |
4416 | |||
4417 | |||
4418 | |||
4419 | void LLTextEditor::updateAllowingLanguageInput() | ||
4420 | { | ||
4421 | if (hasFocus() && !mReadOnly) | ||
4422 | { | ||
4423 | getWindow()->allowLanguageTextInput(this, TRUE); | ||
4424 | } | ||
4425 | else | ||
4426 | { | ||
4427 | getWindow()->allowLanguageTextInput(this, FALSE); | ||
4428 | } | ||
4429 | } | ||
4430 | |||
4431 | // Preedit is managed off the undo/redo command stack. | ||
4432 | |||
4433 | BOOL LLTextEditor::hasPreeditString() const | ||
4434 | { | ||
4435 | return (mPreeditPositions.size() > 1); | ||
4436 | } | ||
4437 | |||
4438 | void LLTextEditor::resetPreedit() | ||
4439 | { | ||
4440 | if (hasPreeditString()) | ||
4441 | { | ||
4442 | mCursorPos = mPreeditPositions.front(); | ||
4443 | removeStringNoUndo(mCursorPos, mPreeditPositions.back() - mCursorPos); | ||
4444 | insertStringNoUndo(mCursorPos, mPreeditOverwrittenWString); | ||
4445 | |||
4446 | mPreeditWString.clear(); | ||
4447 | mPreeditOverwrittenWString.clear(); | ||
4448 | mPreeditPositions.clear(); | ||
4449 | |||
4450 | updateLineStartList(); | ||
4451 | setCursorPos(mCursorPos); | ||
4452 | // updateScrollFromCursor(); | ||
4453 | } | ||
4454 | } | ||
4455 | |||
4456 | void LLTextEditor::updatePreedit(const LLWString &preedit_string, | ||
4457 | const segment_lengths_t &preedit_segment_lengths, const standouts_t &preedit_standouts, S32 caret_position) | ||
4458 | { | ||
4459 | // Just in case. | ||
4460 | if (mReadOnly) | ||
4461 | { | ||
4462 | return; | ||
4463 | } | ||
4464 | |||
4465 | if (hasSelection()) | ||
4466 | { | ||
4467 | if (hasPreeditString()) | ||
4468 | { | ||
4469 | llwarns << "Preedit and selection!" << llendl; | ||
4470 | deselect(); | ||
4471 | } | ||
4472 | else | ||
4473 | { | ||
4474 | deleteSelection(TRUE); | ||
4475 | } | ||
4476 | } | ||
4477 | |||
4478 | getWindow()->hideCursorUntilMouseMove(); | ||
4479 | |||
4480 | S32 insert_preedit_at = mCursorPos; | ||
4481 | if (hasPreeditString()) | ||
4482 | { | ||
4483 | insert_preedit_at = mPreeditPositions.front(); | ||
4484 | removeStringNoUndo(insert_preedit_at, mPreeditPositions.back() - insert_preedit_at); | ||
4485 | insertStringNoUndo(insert_preedit_at, mPreeditOverwrittenWString); | ||
4486 | } | ||
4487 | |||
4488 | mPreeditWString = preedit_string; | ||
4489 | mPreeditPositions.resize(preedit_segment_lengths.size() + 1); | ||
4490 | S32 position = insert_preedit_at; | ||
4491 | for (segment_lengths_t::size_type i = 0; i < preedit_segment_lengths.size(); i++) | ||
4492 | { | ||
4493 | mPreeditPositions[i] = position; | ||
4494 | position += preedit_segment_lengths[i]; | ||
4495 | } | ||
4496 | mPreeditPositions.back() = position; | ||
4497 | |||
4498 | if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) | ||
4499 | { | ||
4500 | mPreeditOverwrittenWString = getWSubString(insert_preedit_at, mPreeditWString.length()); | ||
4501 | removeStringNoUndo(insert_preedit_at, mPreeditWString.length()); | ||
4502 | } | ||
4503 | else | ||
4504 | { | ||
4505 | mPreeditOverwrittenWString.clear(); | ||
4506 | } | ||
4507 | insertStringNoUndo(insert_preedit_at, mPreeditWString); | ||
4508 | |||
4509 | mPreeditStandouts = preedit_standouts; | ||
4510 | |||
4511 | updateLineStartList(); | ||
4512 | setCursorPos(insert_preedit_at + caret_position); | ||
4513 | // updateScrollFromCursor(); | ||
4514 | |||
4515 | // Update of the preedit should be caused by some key strokes. | ||
4516 | mKeystrokeTimer.reset(); | ||
4517 | } | ||
4518 | |||
4519 | BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const | ||
4520 | { | ||
4521 | if (control) | ||
4522 | { | ||
4523 | LLRect control_rect_screen; | ||
4524 | localRectToScreen(mTextRect, &control_rect_screen); | ||
4525 | LLUI::screenRectToGL(control_rect_screen, control); | ||
4526 | } | ||
4527 | |||
4528 | S32 preedit_left_position, preedit_right_position; | ||
4529 | if (hasPreeditString()) | ||
4530 | { | ||
4531 | preedit_left_position = mPreeditPositions.front(); | ||
4532 | preedit_right_position = mPreeditPositions.back(); | ||
4533 | } | ||
4534 | else | ||
4535 | { | ||
4536 | preedit_left_position = preedit_right_position = mCursorPos; | ||
4537 | } | ||
4538 | |||
4539 | const S32 query = (query_offset >= 0 ? preedit_left_position + query_offset : mCursorPos); | ||
4540 | if (query < preedit_left_position || query > preedit_right_position) | ||
4541 | { | ||
4542 | return FALSE; | ||
4543 | } | ||
4544 | |||
4545 | const S32 first_visible_line = mScrollbar->getDocPos(); | ||
4546 | if (query < getLineStart(first_visible_line)) | ||
4547 | { | ||
4548 | return FALSE; | ||
4549 | } | ||
4550 | |||
4551 | S32 current_line = first_visible_line; | ||
4552 | S32 current_line_start, current_line_end; | ||
4553 | for (;;) | ||
4554 | { | ||
4555 | current_line_start = getLineStart(current_line); | ||
4556 | current_line_end = getLineStart(current_line + 1); | ||
4557 | if (query >= current_line_start && query < current_line_end) | ||
4558 | { | ||
4559 | break; | ||
4560 | } | ||
4561 | if (current_line_start == current_line_end) | ||
4562 | { | ||
4563 | // We have reached on the last line. The query position must be here. | ||
4564 | break; | ||
4565 | } | ||
4566 | current_line++; | ||
4567 | } | ||
4568 | |||
4569 | const llwchar * const text = mWText.c_str(); | ||
4570 | const S32 line_height = llround(mGLFont->getLineHeight()); | ||
4571 | |||
4572 | if (coord) | ||
4573 | { | ||
4574 | const S32 query_x = mTextRect.mLeft + mGLFont->getWidth(text, current_line_start, query - current_line_start, mAllowEmbeddedItems); | ||
4575 | const S32 query_y = mTextRect.mTop - (current_line - first_visible_line) * line_height - line_height / 2; | ||
4576 | S32 query_screen_x, query_screen_y; | ||
4577 | localPointToScreen(query_x, query_y, &query_screen_x, &query_screen_y); | ||
4578 | LLUI::screenPointToGL(query_screen_x, query_screen_y, &coord->mX, &coord->mY); | ||
4579 | } | ||
4580 | |||
4581 | if (bounds) | ||
4582 | { | ||
4583 | S32 preedit_left = mTextRect.mLeft; | ||
4584 | if (preedit_left_position > current_line_start) | ||
4585 | { | ||
4586 | preedit_left += mGLFont->getWidth(text, current_line_start, preedit_left_position - current_line_start, mAllowEmbeddedItems); | ||
4587 | } | ||
4588 | |||
4589 | S32 preedit_right = mTextRect.mLeft; | ||
4590 | if (preedit_right_position < current_line_end) | ||
4591 | { | ||
4592 | preedit_right += mGLFont->getWidth(text, current_line_start, preedit_right_position - current_line_start, mAllowEmbeddedItems); | ||
4593 | } | ||
4594 | else | ||
4595 | { | ||
4596 | preedit_right += mGLFont->getWidth(text, current_line_start, current_line_end - current_line_start, mAllowEmbeddedItems); | ||
4597 | } | ||
4598 | |||
4599 | const S32 preedit_top = mTextRect.mTop - (current_line - first_visible_line) * line_height; | ||
4600 | const S32 preedit_bottom = preedit_top - line_height; | ||
4601 | |||
4602 | const LLRect preedit_rect_local(preedit_left, preedit_top, preedit_right, preedit_bottom); | ||
4603 | LLRect preedit_rect_screen; | ||
4604 | localRectToScreen(preedit_rect_local, &preedit_rect_screen); | ||
4605 | LLUI::screenRectToGL(preedit_rect_screen, bounds); | ||
4606 | } | ||
4607 | |||
4608 | return TRUE; | ||
4609 | } | ||
4610 | |||
4611 | void LLTextEditor::getSelectionRange(S32 *position, S32 *length) const | ||
4612 | { | ||
4613 | if (hasSelection()) | ||
4614 | { | ||
4615 | *position = llmin(mSelectionStart, mSelectionEnd); | ||
4616 | *length = llabs(mSelectionStart - mSelectionEnd); | ||
4617 | } | ||
4618 | else | ||
4619 | { | ||
4620 | *position = mCursorPos; | ||
4621 | *length = 0; | ||
4622 | } | ||
4623 | } | ||
4624 | |||
4625 | void LLTextEditor::getPreeditRange(S32 *position, S32 *length) const | ||
4626 | { | ||
4627 | if (hasPreeditString()) | ||
4628 | { | ||
4629 | *position = mPreeditPositions.front(); | ||
4630 | *length = mPreeditPositions.back() - mPreeditPositions.front(); | ||
4631 | } | ||
4632 | else | ||
4633 | { | ||
4634 | *position = mCursorPos; | ||
4635 | *length = 0; | ||
4636 | } | ||
4637 | } | ||
4638 | |||
4639 | void LLTextEditor::markAsPreedit(S32 position, S32 length) | ||
4640 | { | ||
4641 | deselect(); | ||
4642 | setCursorPos(position); | ||
4643 | if (hasPreeditString()) | ||
4644 | { | ||
4645 | llwarns << "markAsPreedit invoked when hasPreeditString is true." << llendl; | ||
4646 | } | ||
4647 | mPreeditWString = LLWString( mWText, position, length ); | ||
4648 | if (length > 0) | ||
4649 | { | ||
4650 | mPreeditPositions.resize(2); | ||
4651 | mPreeditPositions[0] = position; | ||
4652 | mPreeditPositions[1] = position + length; | ||
4653 | mPreeditStandouts.resize(1); | ||
4654 | mPreeditStandouts[0] = FALSE; | ||
4655 | } | ||
4656 | else | ||
4657 | { | ||
4658 | mPreeditPositions.clear(); | ||
4659 | mPreeditStandouts.clear(); | ||
4660 | } | ||
4661 | if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) | ||
4662 | { | ||
4663 | mPreeditOverwrittenWString = mPreeditWString; | ||
4664 | } | ||
4665 | else | ||
4666 | { | ||
4667 | mPreeditOverwrittenWString.clear(); | ||
4668 | } | ||
4669 | } | ||
4670 | |||
4671 | S32 LLTextEditor::getPreeditFontSize() const | ||
4672 | { | ||
4673 | return llround(mGLFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]); | ||
4674 | } | ||
diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h index 33ec1c6..4c92297 100644 --- a/linden/indra/llui/lltexteditor.h +++ b/linden/indra/llui/lltexteditor.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -43,6 +43,8 @@ | |||
43 | #include "lleditmenuhandler.h" | 43 | #include "lleditmenuhandler.h" |
44 | #include "lldarray.h" | 44 | #include "lldarray.h" |
45 | 45 | ||
46 | #include "llpreeditor.h" | ||
47 | |||
46 | class LLFontGL; | 48 | class LLFontGL; |
47 | class LLScrollbar; | 49 | class LLScrollbar; |
48 | class LLViewBorder; | 50 | class LLViewBorder; |
@@ -64,7 +66,7 @@ const S32 MAX_EMBEDDED_ITEMS = LAST_EMBEDDED_CHAR - FIRST_EMBEDDED_CHAR + 1; | |||
64 | class LLTextSegment; | 66 | class LLTextSegment; |
65 | class LLTextCmd; | 67 | class LLTextCmd; |
66 | 68 | ||
67 | class LLTextEditor : public LLUICtrl, LLEditMenuHandler | 69 | class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor |
68 | { | 70 | { |
69 | friend class LLTextCmd; | 71 | friend class LLTextCmd; |
70 | public: | 72 | public: |
@@ -104,6 +106,7 @@ public: | |||
104 | // view overrides | 106 | // view overrides |
105 | virtual void reshape(S32 width, S32 height, BOOL called_from_parent); | 107 | virtual void reshape(S32 width, S32 height, BOOL called_from_parent); |
106 | virtual void draw(); | 108 | virtual void draw(); |
109 | virtual void onFocusReceived(); | ||
107 | virtual void onFocusLost(); | 110 | virtual void onFocusLost(); |
108 | virtual void setEnabled(BOOL enabled); | 111 | virtual void setEnabled(BOOL enabled); |
109 | 112 | ||
@@ -184,6 +187,7 @@ public: | |||
184 | 187 | ||
185 | void setCursorColor(const LLColor4& c) { mCursorColor = c; } | 188 | void setCursorColor(const LLColor4& c) { mCursorColor = c; } |
186 | void setFgColor( const LLColor4& c ) { mFgColor = c; } | 189 | void setFgColor( const LLColor4& c ) { mFgColor = c; } |
190 | void setTextDefaultColor( const LLColor4& c ) { mDefaultColor = c; } | ||
187 | void setReadOnlyFgColor( const LLColor4& c ) { mReadOnlyFgColor = c; } | 191 | void setReadOnlyFgColor( const LLColor4& c ) { mReadOnlyFgColor = c; } |
188 | void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; } | 192 | void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; } |
189 | void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } | 193 | void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } |
@@ -203,13 +207,13 @@ public: | |||
203 | void setTabToNextField(BOOL b) { mTabToNextField = b; } | 207 | void setTabToNextField(BOOL b) { mTabToNextField = b; } |
204 | void setCommitOnFocusLost(BOOL b) { mCommitOnFocusLost = b; } | 208 | void setCommitOnFocusLost(BOOL b) { mCommitOnFocusLost = b; } |
205 | 209 | ||
206 | // If takes focus, will take keyboard focus on click. | ||
207 | void setTakesFocus(BOOL b) { mTakesFocus = b; } | ||
208 | |||
209 | // Hack to handle Notecards | 210 | // Hack to handle Notecards |
210 | virtual BOOL importBuffer(const LLString& buffer ); | 211 | virtual BOOL importBuffer(const LLString& buffer ); |
211 | virtual BOOL exportBuffer(LLString& buffer ); | 212 | virtual BOOL exportBuffer(LLString& buffer ); |
212 | 213 | ||
214 | // If takes focus, will take keyboard focus on click. | ||
215 | void setTakesFocus(BOOL b) { mTakesFocus = b; } | ||
216 | |||
213 | void setSourceID(const LLUUID& id) { mSourceID = id; } | 217 | void setSourceID(const LLUUID& id) { mSourceID = id; } |
214 | void setAcceptCallingCardNames(BOOL enable) { mAcceptCallingCardNames = enable; } | 218 | void setAcceptCallingCardNames(BOOL enable) { mAcceptCallingCardNames = enable; } |
215 | 219 | ||
@@ -234,13 +238,17 @@ public: | |||
234 | void setText(const LLStringExplicit &utf8str); | 238 | void setText(const LLStringExplicit &utf8str); |
235 | void setWText(const LLWString &wtext); | 239 | void setWText(const LLWString &wtext); |
236 | 240 | ||
237 | S32 getMaxLength() const { return mMaxTextLength; } | 241 | // Returns byte length limit |
242 | S32 getMaxLength() const { return mMaxTextByteLength; } | ||
238 | 243 | ||
239 | // Change cursor | 244 | // Change cursor |
240 | void startOfLine(); | 245 | void startOfLine(); |
241 | void endOfLine(); | 246 | void endOfLine(); |
242 | void endOfDoc(); | 247 | void endOfDoc(); |
243 | 248 | ||
249 | BOOL isScrolledToTop(); | ||
250 | BOOL isScrolledToBottom(); | ||
251 | |||
244 | // Getters | 252 | // Getters |
245 | const LLWString& getWText() const; | 253 | const LLWString& getWText() const; |
246 | llwchar getWChar(S32 pos); | 254 | llwchar getWChar(S32 pos); |
@@ -259,6 +267,7 @@ protected: | |||
259 | void drawCursor(); | 267 | void drawCursor(); |
260 | void drawText(); | 268 | void drawText(); |
261 | void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyle& color, F32* right_x); | 269 | void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyle& color, F32* right_x); |
270 | void drawPreeditMarker(); | ||
262 | 271 | ||
263 | void updateLineStartList(S32 startpos = 0); | 272 | void updateLineStartList(S32 startpos = 0); |
264 | void updateScrollFromCursor(); | 273 | void updateScrollFromCursor(); |
@@ -267,7 +276,7 @@ protected: | |||
267 | void pruneSegments(); | 276 | void pruneSegments(); |
268 | 277 | ||
269 | void assignEmbedded(const LLString &s); | 278 | void assignEmbedded(const LLString &s); |
270 | void truncate(); | 279 | BOOL truncate(); // Returns true if truncation occurs |
271 | 280 | ||
272 | static BOOL isPartOfWord(llwchar c); | 281 | static BOOL isPartOfWord(llwchar c); |
273 | 282 | ||
@@ -291,7 +300,7 @@ protected: | |||
291 | BOOL handleControlKey(const KEY key, const MASK mask); | 300 | BOOL handleControlKey(const KEY key, const MASK mask); |
292 | BOOL handleEditKey(const KEY key, const MASK mask); | 301 | BOOL handleEditKey(const KEY key, const MASK mask); |
293 | 302 | ||
294 | BOOL hasSelection() { return (mSelectionStart !=mSelectionEnd); } | 303 | BOOL hasSelection() const { return (mSelectionStart !=mSelectionEnd); } |
295 | BOOL selectionContainsLineBreaks(); | 304 | BOOL selectionContainsLineBreaks(); |
296 | void startSelection(); | 305 | void startSelection(); |
297 | void endSelection(); | 306 | void endSelection(); |
@@ -300,8 +309,8 @@ protected: | |||
300 | S32 prevWordPos(S32 cursorPos) const; | 309 | S32 prevWordPos(S32 cursorPos) const; |
301 | S32 nextWordPos(S32 cursorPos) const; | 310 | S32 nextWordPos(S32 cursorPos) const; |
302 | 311 | ||
303 | S32 getLineCount(); | 312 | S32 getLineCount() const; |
304 | S32 getLineStart( S32 line ); | 313 | S32 getLineStart( S32 line ) const; |
305 | void getLineAndOffset(S32 pos, S32* linep, S32* offsetp); | 314 | void getLineAndOffset(S32 pos, S32* linep, S32* offsetp); |
306 | S32 getPos(S32 line, S32 offset); | 315 | S32 getPos(S32 line, S32 offset); |
307 | 316 | ||
@@ -338,6 +347,20 @@ protected: | |||
338 | S32 removeStringNoUndo(S32 pos, S32 length); | 347 | S32 removeStringNoUndo(S32 pos, S32 length); |
339 | S32 overwriteCharNoUndo(S32 pos, llwchar wc); | 348 | S32 overwriteCharNoUndo(S32 pos, llwchar wc); |
340 | 349 | ||
350 | protected: | ||
351 | void updateAllowingLanguageInput(); | ||
352 | BOOL hasPreeditString() const; | ||
353 | |||
354 | // Overrides LLPreeditor | ||
355 | virtual void resetPreedit(); | ||
356 | virtual void updatePreedit(const LLWString &preedit_string, | ||
357 | const segment_lengths_t &preedit_segment_lengths, const standouts_t &preedit_standouts, S32 caret_position); | ||
358 | virtual void markAsPreedit(S32 position, S32 length); | ||
359 | virtual void getPreeditRange(S32 *position, S32 *length) const; | ||
360 | virtual void getSelectionRange(S32 *position, S32 *length) const; | ||
361 | virtual BOOL getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const; | ||
362 | virtual S32 getPreeditFontSize() const; | ||
363 | |||
341 | public: | 364 | public: |
342 | LLKeywords mKeywords; | 365 | LLKeywords mKeywords; |
343 | static LLColor4 mLinkColor; | 366 | static LLColor4 mLinkColor; |
@@ -349,7 +372,7 @@ protected: | |||
349 | mutable LLString mUTF8Text; | 372 | mutable LLString mUTF8Text; |
350 | mutable BOOL mTextIsUpToDate; | 373 | mutable BOOL mTextIsUpToDate; |
351 | 374 | ||
352 | S32 mMaxTextLength; // Maximum length mText is allowed to be | 375 | S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes |
353 | 376 | ||
354 | const LLFontGL* mGLFont; | 377 | const LLFontGL* mGLFont; |
355 | 378 | ||
@@ -407,6 +430,7 @@ protected: | |||
407 | LLColor4 mCursorColor; | 430 | LLColor4 mCursorColor; |
408 | 431 | ||
409 | LLColor4 mFgColor; | 432 | LLColor4 mFgColor; |
433 | LLColor4 mDefaultColor; | ||
410 | LLColor4 mReadOnlyFgColor; | 434 | LLColor4 mReadOnlyFgColor; |
411 | LLColor4 mWriteableBgColor; | 435 | LLColor4 mWriteableBgColor; |
412 | LLColor4 mReadOnlyBgColor; | 436 | LLColor4 mReadOnlyBgColor; |
@@ -420,6 +444,8 @@ protected: | |||
420 | BOOL mTakesFocus; | 444 | BOOL mTakesFocus; |
421 | BOOL mHideScrollbarForShortDocs; | 445 | BOOL mHideScrollbarForShortDocs; |
422 | BOOL mTakesNonScrollClicks; | 446 | BOOL mTakesNonScrollClicks; |
447 | BOOL mTrackBottom; // if true, keeps scroll position at bottom during resize | ||
448 | BOOL mScrolledToBottom; | ||
423 | 449 | ||
424 | BOOL mAllowEmbeddedItems; | 450 | BOOL mAllowEmbeddedItems; |
425 | 451 | ||
@@ -439,6 +465,11 @@ protected: | |||
439 | 465 | ||
440 | BOOL mParseHTML; | 466 | BOOL mParseHTML; |
441 | LLString mHTML; | 467 | LLString mHTML; |
468 | |||
469 | LLWString mPreeditWString; | ||
470 | LLWString mPreeditOverwrittenWString; | ||
471 | std::vector<S32> mPreeditPositions; | ||
472 | std::vector<BOOL> mPreeditStandouts; | ||
442 | }; | 473 | }; |
443 | 474 | ||
444 | class LLTextSegment | 475 | class LLTextSegment |
diff --git a/linden/indra/llui/llui.cpp b/linden/indra/llui/llui.cpp index 96f293e..f6ce985 100644 --- a/linden/indra/llui/llui.cpp +++ b/linden/indra/llui/llui.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -79,7 +79,7 @@ LLVector2 LLUI::sGLScaleFactor(1.f, 1.f); | |||
79 | LLWindow* LLUI::sWindow = NULL; | 79 | LLWindow* LLUI::sWindow = NULL; |
80 | LLHtmlHelp* LLUI::sHtmlHelp = NULL; | 80 | LLHtmlHelp* LLUI::sHtmlHelp = NULL; |
81 | BOOL LLUI::sShowXUINames = FALSE; | 81 | BOOL LLUI::sShowXUINames = FALSE; |
82 | std::stack<LLRect> LLUI::sClipRectStack; | 82 | std::stack<LLRect> LLScreenClipRect::sClipRectStack; |
83 | 83 | ||
84 | // | 84 | // |
85 | // Functions | 85 | // Functions |
@@ -410,39 +410,76 @@ void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max | |||
410 | } | 410 | } |
411 | 411 | ||
412 | 412 | ||
413 | void gl_draw_image( S32 x, S32 y, LLImageGL* image, const LLColor4& color ) | 413 | void gl_draw_image( S32 x, S32 y, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect ) |
414 | { | 414 | { |
415 | gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color ); | 415 | if (NULL == image) |
416 | { | ||
417 | llwarns << "image == NULL; aborting function" << llendl; | ||
418 | return; | ||
419 | } | ||
420 | gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect ); | ||
416 | } | 421 | } |
417 | 422 | ||
418 | void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color) | 423 | void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) |
419 | { | 424 | { |
420 | gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color ); | 425 | if (NULL == image) |
426 | { | ||
427 | llwarns << "image == NULL; aborting function" << llendl; | ||
428 | return; | ||
429 | } | ||
430 | gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect ); | ||
421 | } | 431 | } |
422 | 432 | ||
423 | 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) | 433 | 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) |
424 | { | 434 | { |
425 | stop_glerror(); | ||
426 | F32 border_scale = 1.f; | ||
427 | |||
428 | if (NULL == image) | 435 | if (NULL == image) |
429 | { | 436 | { |
430 | llwarns << "image == NULL; aborting function" << llendl; | 437 | llwarns << "image == NULL; aborting function" << llendl; |
431 | return; | 438 | return; |
432 | } | 439 | } |
433 | 440 | ||
434 | if (border_height * 2 > height) | 441 | // scale screen size of borders down |
435 | { | 442 | F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0); |
436 | border_scale = (F32)height / ((F32)border_height * 2.f); | 443 | F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0); |
437 | } | 444 | |
438 | if (border_width * 2 > width) | 445 | LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction); |
446 | gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect); | ||
447 | } | ||
448 | |||
449 | 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) | ||
450 | { | ||
451 | stop_glerror(); | ||
452 | |||
453 | if (NULL == image) | ||
439 | { | 454 | { |
440 | border_scale = llmin(border_scale, (F32)width / ((F32)border_width * 2.f)); | 455 | llwarns << "image == NULL; aborting function" << llendl; |
456 | return; | ||
441 | } | 457 | } |
442 | 458 | ||
443 | // scale screen size of borders down | 459 | // scale screen size of borders down |
444 | S32 scaled_border_width = llfloor(border_scale * (F32)border_width); | 460 | LLRectf clipped_scale_rect = uv_rect; |
445 | S32 scaled_border_height = llfloor(border_scale * (F32)border_height); | 461 | clipped_scale_rect.intersectWith(scale_rect); |
462 | |||
463 | LLRect draw_rect(0, height, width, 0); | ||
464 | LLRect draw_scale_rect(llround((F32)image->getWidth() * scale_rect.mLeft), | ||
465 | llround((F32)image->getHeight() * scale_rect.mTop), | ||
466 | llround((F32)image->getWidth() * scale_rect.mRight), | ||
467 | llround((F32)image->getHeight() * scale_rect.mBottom)); | ||
468 | // scale fixed region of image up with drawn region | ||
469 | draw_scale_rect.mRight += width - image->getWidth(); | ||
470 | draw_scale_rect.mTop += height - image->getHeight(); | ||
471 | |||
472 | S32 border_shrink_width = llmax(0, draw_scale_rect.mLeft - draw_scale_rect.mRight); | ||
473 | S32 border_shrink_height = llmax(0, draw_scale_rect.mBottom - draw_scale_rect.mTop); | ||
474 | |||
475 | F32 shrink_width_ratio = scale_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image->getWidth() * (1.f - scale_rect.getWidth())); | ||
476 | F32 shrink_height_ratio = scale_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image->getHeight() * (1.f - scale_rect.getHeight())); | ||
477 | |||
478 | F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio); | ||
479 | draw_scale_rect.mLeft = llround((F32)draw_scale_rect.mLeft * shrink_scale); | ||
480 | draw_scale_rect.mTop = llround(lerp((F32)height, (F32)draw_scale_rect.mTop, shrink_scale)); | ||
481 | draw_scale_rect.mRight = llround(lerp((F32)width, (F32)draw_scale_rect.mRight, shrink_scale)); | ||
482 | draw_scale_rect.mBottom = llround((F32)draw_scale_rect.mBottom * shrink_scale); | ||
446 | 483 | ||
447 | LLGLSUIDefault gls_ui; | 484 | LLGLSUIDefault gls_ui; |
448 | 485 | ||
@@ -470,127 +507,124 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border | |||
470 | 507 | ||
471 | glColor4fv(color.mV); | 508 | glColor4fv(color.mV); |
472 | 509 | ||
473 | F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0); | ||
474 | F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0); | ||
475 | |||
476 | glBegin(GL_QUADS); | 510 | glBegin(GL_QUADS); |
477 | { | 511 | { |
478 | // draw bottom left | 512 | // draw bottom left |
479 | glTexCoord2f(0.f, 0.f); | 513 | glTexCoord2d(uv_rect.mLeft, uv_rect.mBottom); |
480 | glVertex2i(0, 0); | 514 | glVertex2i(0, 0); |
481 | 515 | ||
482 | glTexCoord2f(border_width_fraction, 0.f); | 516 | glTexCoord2f(clipped_scale_rect.mLeft, uv_rect.mBottom); |
483 | glVertex2i(scaled_border_width, 0); | 517 | glVertex2i(draw_scale_rect.mLeft, 0); |
484 | 518 | ||
485 | glTexCoord2f(border_width_fraction, border_height_fraction); | 519 | glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); |
486 | glVertex2i(scaled_border_width, scaled_border_height); | 520 | glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); |
487 | 521 | ||
488 | glTexCoord2f(0.f, border_height_fraction); | 522 | glTexCoord2d(uv_rect.mLeft, clipped_scale_rect.mBottom); |
489 | glVertex2i(0, scaled_border_height); | 523 | glVertex2i(0, draw_scale_rect.mBottom); |
490 | 524 | ||
491 | // draw bottom middle | 525 | // draw bottom middle |
492 | glTexCoord2f(border_width_fraction, 0.f); | 526 | glTexCoord2f(clipped_scale_rect.mLeft, uv_rect.mBottom); |
493 | glVertex2i(scaled_border_width, 0); | 527 | glVertex2i(draw_scale_rect.mLeft, 0); |
494 | 528 | ||
495 | glTexCoord2f(1.f - border_width_fraction, 0.f); | 529 | glTexCoord2d(clipped_scale_rect.mRight, uv_rect.mBottom); |
496 | glVertex2i(width - scaled_border_width, 0); | 530 | glVertex2i(draw_scale_rect.mRight, 0); |
497 | 531 | ||
498 | glTexCoord2f(1.f - border_width_fraction, border_height_fraction); | 532 | glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); |
499 | glVertex2i(width - scaled_border_width, scaled_border_height); | 533 | glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); |
500 | 534 | ||
501 | glTexCoord2f(border_width_fraction, border_height_fraction); | 535 | glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); |
502 | glVertex2i(scaled_border_width, scaled_border_height); | 536 | glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); |
503 | 537 | ||
504 | // draw bottom right | 538 | // draw bottom right |
505 | glTexCoord2f(1.f - border_width_fraction, 0.f); | 539 | glTexCoord2d(clipped_scale_rect.mRight, uv_rect.mBottom); |
506 | glVertex2i(width - scaled_border_width, 0); | 540 | glVertex2i(draw_scale_rect.mRight, 0); |
507 | 541 | ||
508 | glTexCoord2f(1.f, 0.f); | 542 | glTexCoord2d(uv_rect.mRight, uv_rect.mBottom); |
509 | glVertex2i(width, 0); | 543 | glVertex2i(width, 0); |
510 | 544 | ||
511 | glTexCoord2f(1.f, border_height_fraction); | 545 | glTexCoord2d(uv_rect.mRight, clipped_scale_rect.mBottom); |
512 | glVertex2i(width, scaled_border_height); | 546 | glVertex2i(width, draw_scale_rect.mBottom); |
513 | 547 | ||
514 | glTexCoord2f(1.f - border_width_fraction, border_height_fraction); | 548 | glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); |
515 | glVertex2i(width - scaled_border_width, scaled_border_height); | 549 | glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); |
516 | 550 | ||
517 | // draw left | 551 | // draw left |
518 | glTexCoord2f(0.f, border_height_fraction); | 552 | glTexCoord2d(uv_rect.mLeft, clipped_scale_rect.mBottom); |
519 | glVertex2i(0, scaled_border_height); | 553 | glVertex2i(0, draw_scale_rect.mBottom); |
520 | 554 | ||
521 | glTexCoord2f(border_width_fraction, border_height_fraction); | 555 | glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); |
522 | glVertex2i(scaled_border_width, scaled_border_height); | 556 | glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); |
523 | 557 | ||
524 | glTexCoord2f(border_width_fraction, 1.f - border_height_fraction); | 558 | glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); |
525 | glVertex2i(scaled_border_width, height - scaled_border_height); | 559 | glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); |
526 | 560 | ||
527 | glTexCoord2f(0.f, 1.f - border_height_fraction); | 561 | glTexCoord2d(uv_rect.mLeft, clipped_scale_rect.mTop); |
528 | glVertex2i(0, height - scaled_border_height); | 562 | glVertex2i(0, draw_scale_rect.mTop); |
529 | 563 | ||
530 | // draw middle | 564 | // draw middle |
531 | glTexCoord2f(border_width_fraction, border_height_fraction); | 565 | glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); |
532 | glVertex2i(scaled_border_width, scaled_border_height); | 566 | glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); |
533 | 567 | ||
534 | glTexCoord2f(1.f - border_width_fraction, border_height_fraction); | 568 | glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); |
535 | glVertex2i(width - scaled_border_width, scaled_border_height); | 569 | glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); |
536 | 570 | ||
537 | glTexCoord2f(1.f - border_width_fraction, 1.f - border_height_fraction); | 571 | glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mTop); |
538 | glVertex2i(width - scaled_border_width, height - scaled_border_height); | 572 | glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); |
539 | 573 | ||
540 | glTexCoord2f(border_width_fraction, 1.f - border_height_fraction); | 574 | glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); |
541 | glVertex2i(scaled_border_width, height - scaled_border_height); | 575 | glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); |
542 | 576 | ||
543 | // draw right | 577 | // draw right |
544 | glTexCoord2f(1.f - border_width_fraction, border_height_fraction); | 578 | glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); |
545 | glVertex2i(width - scaled_border_width, scaled_border_height); | 579 | glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); |
546 | 580 | ||
547 | glTexCoord2f(1.f, border_height_fraction); | 581 | glTexCoord2d(uv_rect.mRight, clipped_scale_rect.mBottom); |
548 | glVertex2i(width, scaled_border_height); | 582 | glVertex2i(width, draw_scale_rect.mBottom); |
549 | 583 | ||
550 | glTexCoord2f(1.f, 1.f - border_height_fraction); | 584 | glTexCoord2d(uv_rect.mRight, clipped_scale_rect.mTop); |
551 | glVertex2i(width, height - scaled_border_height); | 585 | glVertex2i(width, draw_scale_rect.mTop); |
552 | 586 | ||
553 | glTexCoord2f(1.f - border_width_fraction, 1.f - border_height_fraction); | 587 | glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mTop); |
554 | glVertex2i(width - scaled_border_width, height - scaled_border_height); | 588 | glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); |
555 | 589 | ||
556 | // draw top left | 590 | // draw top left |
557 | glTexCoord2f(0.f, 1.f - border_height_fraction); | 591 | glTexCoord2d(uv_rect.mLeft, clipped_scale_rect.mTop); |
558 | glVertex2i(0, height - scaled_border_height); | 592 | glVertex2i(0, draw_scale_rect.mTop); |
559 | 593 | ||
560 | glTexCoord2f(border_width_fraction, 1.f - border_height_fraction); | 594 | glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); |
561 | glVertex2i(scaled_border_width, height - scaled_border_height); | 595 | glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); |
562 | 596 | ||
563 | glTexCoord2f(border_width_fraction, 1.f); | 597 | glTexCoord2f(clipped_scale_rect.mLeft, uv_rect.mTop); |
564 | glVertex2i(scaled_border_width, height); | 598 | glVertex2i(draw_scale_rect.mLeft, height); |
565 | 599 | ||
566 | glTexCoord2f(0.f, 1.f); | 600 | glTexCoord2d(uv_rect.mLeft, uv_rect.mTop); |
567 | glVertex2i(0, height); | 601 | glVertex2i(0, height); |
568 | 602 | ||
569 | // draw top middle | 603 | // draw top middle |
570 | glTexCoord2f(border_width_fraction, 1.f - border_height_fraction); | 604 | glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); |
571 | glVertex2i(scaled_border_width, height - scaled_border_height); | 605 | glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); |
572 | 606 | ||
573 | glTexCoord2f(1.f - border_width_fraction, 1.f - border_height_fraction); | 607 | glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mTop); |
574 | glVertex2i(width - scaled_border_width, height - scaled_border_height); | 608 | glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); |
575 | 609 | ||
576 | glTexCoord2f(1.f - border_width_fraction, 1.f); | 610 | glTexCoord2d(clipped_scale_rect.mRight, uv_rect.mTop); |
577 | glVertex2i(width - scaled_border_width, height); | 611 | glVertex2i(draw_scale_rect.mRight, height); |
578 | 612 | ||
579 | glTexCoord2f(border_width_fraction, 1.f); | 613 | glTexCoord2f(clipped_scale_rect.mLeft, uv_rect.mTop); |
580 | glVertex2i(scaled_border_width, height); | 614 | glVertex2i(draw_scale_rect.mLeft, height); |
581 | 615 | ||
582 | // draw top right | 616 | // draw top right |
583 | glTexCoord2f(1.f - border_width_fraction, 1.f - border_height_fraction); | 617 | glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mTop); |
584 | glVertex2i(width - scaled_border_width, height - scaled_border_height); | 618 | glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); |
585 | 619 | ||
586 | glTexCoord2f(1.f, 1.f - border_height_fraction); | 620 | glTexCoord2d(uv_rect.mRight, clipped_scale_rect.mTop); |
587 | glVertex2i(width, height - scaled_border_height); | 621 | glVertex2i(width, draw_scale_rect.mTop); |
588 | 622 | ||
589 | glTexCoord2f(1.f, 1.f); | 623 | glTexCoord2d(uv_rect.mRight, uv_rect.mTop); |
590 | glVertex2i(width, height); | 624 | glVertex2i(width, height); |
591 | 625 | ||
592 | glTexCoord2f(1.f - border_width_fraction, 1.f); | 626 | glTexCoord2d(clipped_scale_rect.mRight, uv_rect.mTop); |
593 | glVertex2i(width - scaled_border_width, height); | 627 | glVertex2i(draw_scale_rect.mRight, height); |
594 | } | 628 | } |
595 | glEnd(); | 629 | glEnd(); |
596 | } | 630 | } |
@@ -602,12 +636,12 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border | |||
602 | } | 636 | } |
603 | } | 637 | } |
604 | 638 | ||
605 | void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color) | 639 | void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) |
606 | { | 640 | { |
607 | gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color ); | 641 | gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect ); |
608 | } | 642 | } |
609 | 643 | ||
610 | void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLImageGL* image, const LLColor4& color) | 644 | 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) |
611 | { | 645 | { |
612 | if (NULL == image) | 646 | if (NULL == image) |
613 | { | 647 | { |
@@ -635,16 +669,16 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre | |||
635 | 669 | ||
636 | glBegin(GL_QUADS); | 670 | glBegin(GL_QUADS); |
637 | { | 671 | { |
638 | glTexCoord2f(1.f, 1.f); | 672 | glTexCoord2f(uv_rect.mRight, uv_rect.mTop); |
639 | glVertex2i(width, height ); | 673 | glVertex2i(width, height ); |
640 | 674 | ||
641 | glTexCoord2f(0.f, 1.f); | 675 | glTexCoord2f(uv_rect.mLeft, uv_rect.mTop); |
642 | glVertex2i(0, height ); | 676 | glVertex2i(0, height ); |
643 | 677 | ||
644 | glTexCoord2f(0.f, 0.f); | 678 | glTexCoord2f(uv_rect.mLeft, uv_rect.mBottom); |
645 | glVertex2i(0, 0); | 679 | glVertex2i(0, 0); |
646 | 680 | ||
647 | glTexCoord2f(1.f, 0.f); | 681 | glTexCoord2f(uv_rect.mRight, uv_rect.mBottom); |
648 | glVertex2i(width, 0); | 682 | glVertex2i(width, 0); |
649 | } | 683 | } |
650 | glEnd(); | 684 | glEnd(); |
@@ -653,7 +687,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre | |||
653 | } | 687 | } |
654 | 688 | ||
655 | 689 | ||
656 | void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color) | 690 | void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) |
657 | { | 691 | { |
658 | if (NULL == image) | 692 | if (NULL == image) |
659 | { | 693 | { |
@@ -673,16 +707,16 @@ void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageG | |||
673 | 707 | ||
674 | glBegin(GL_QUADS); | 708 | glBegin(GL_QUADS); |
675 | { | 709 | { |
676 | glTexCoord2f(1.f, 0.f); | 710 | glTexCoord2f(uv_rect.mRight, uv_rect.mBottom); |
677 | glVertex2i(width, height ); | 711 | glVertex2i(width, height ); |
678 | 712 | ||
679 | glTexCoord2f(0.f, 0.f); | 713 | glTexCoord2f(uv_rect.mLeft, uv_rect.mBottom); |
680 | glVertex2i(0, height ); | 714 | glVertex2i(0, height ); |
681 | 715 | ||
682 | glTexCoord2f(0.f, 1.f); | 716 | glTexCoord2f(uv_rect.mLeft, uv_rect.mTop); |
683 | glVertex2i(0, 0); | 717 | glVertex2i(0, 0); |
684 | 718 | ||
685 | glTexCoord2f(1.f, 1.f); | 719 | glTexCoord2f(uv_rect.mRight, uv_rect.mTop); |
686 | glVertex2i(width, 0); | 720 | glVertex2i(width, 0); |
687 | } | 721 | } |
688 | glEnd(); | 722 | glEnd(); |
@@ -1584,40 +1618,6 @@ void LLUI::loadIdentity() | |||
1584 | LLFontGL::sCurOrigin.mZ = 0; | 1618 | LLFontGL::sCurOrigin.mZ = 0; |
1585 | } | 1619 | } |
1586 | 1620 | ||
1587 | //static | ||
1588 | void LLUI::setScissorRegionScreen(const LLRect& rect) | ||
1589 | { | ||
1590 | stop_glerror(); | ||
1591 | S32 x,y,w,h; | ||
1592 | x = llround(rect.mLeft * LLUI::sGLScaleFactor.mV[VX]); | ||
1593 | y = llround(rect.mBottom * LLUI::sGLScaleFactor.mV[VY]); | ||
1594 | w = llround(rect.getWidth() * LLUI::sGLScaleFactor.mV[VX]); | ||
1595 | h = llround(rect.getHeight() * LLUI::sGLScaleFactor.mV[VY]); | ||
1596 | glScissor( x,y,w,h ); | ||
1597 | stop_glerror(); | ||
1598 | } | ||
1599 | |||
1600 | //static | ||
1601 | void LLUI::setScissorRegionLocal(const LLRect& rect) | ||
1602 | { | ||
1603 | stop_glerror(); | ||
1604 | S32 screen_left = LLFontGL::sCurOrigin.mX + rect.mLeft; | ||
1605 | S32 screen_bottom = LLFontGL::sCurOrigin.mY + rect.mBottom; | ||
1606 | |||
1607 | S32 x,y,w,h; | ||
1608 | |||
1609 | x = llround((F32)screen_left * LLUI::sGLScaleFactor.mV[VX]); | ||
1610 | y = llround((F32)screen_bottom * LLUI::sGLScaleFactor.mV[VY]); | ||
1611 | w = llround((F32)rect.getWidth() * LLUI::sGLScaleFactor.mV[VX]); | ||
1612 | h = llround((F32)rect.getHeight() * LLUI::sGLScaleFactor.mV[VY]); | ||
1613 | |||
1614 | w = llmax(0,w); | ||
1615 | h = llmax(0,h); | ||
1616 | |||
1617 | glScissor(x,y,w,h); | ||
1618 | stop_glerror(); | ||
1619 | } | ||
1620 | |||
1621 | //static | 1621 | //static |
1622 | void LLUI::setScaleFactor(const LLVector2 &scale_factor) | 1622 | void LLUI::setScaleFactor(const LLVector2 &scale_factor) |
1623 | { | 1623 | { |
@@ -1696,6 +1696,34 @@ LLVector2 LLUI::getWindowSize() | |||
1696 | } | 1696 | } |
1697 | 1697 | ||
1698 | //static | 1698 | //static |
1699 | void LLUI::screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y) | ||
1700 | { | ||
1701 | *gl_x = llround((F32)screen_x * sGLScaleFactor.mV[VX]); | ||
1702 | *gl_y = llround((F32)screen_y * sGLScaleFactor.mV[VY]); | ||
1703 | } | ||
1704 | |||
1705 | //static | ||
1706 | void LLUI::glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y) | ||
1707 | { | ||
1708 | *screen_x = llround((F32)gl_x / sGLScaleFactor.mV[VX]); | ||
1709 | *screen_y = llround((F32)gl_y / sGLScaleFactor.mV[VY]); | ||
1710 | } | ||
1711 | |||
1712 | //static | ||
1713 | void LLUI::screenRectToGL(const LLRect& screen, LLRect *gl) | ||
1714 | { | ||
1715 | screenPointToGL(screen.mLeft, screen.mTop, &gl->mLeft, &gl->mTop); | ||
1716 | screenPointToGL(screen.mRight, screen.mBottom, &gl->mRight, &gl->mBottom); | ||
1717 | } | ||
1718 | |||
1719 | //static | ||
1720 | void LLUI::glRectToScreen(const LLRect& gl, LLRect *screen) | ||
1721 | { | ||
1722 | glPointToScreen(gl.mLeft, gl.mTop, &screen->mLeft, &screen->mTop); | ||
1723 | glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom); | ||
1724 | } | ||
1725 | |||
1726 | //static | ||
1699 | LLUUID LLUI::findAssetUUIDByName(const LLString &asset_name) | 1727 | LLUUID LLUI::findAssetUUIDByName(const LLString &asset_name) |
1700 | { | 1728 | { |
1701 | if(asset_name == LLString::null) return LLUUID::null; | 1729 | if(asset_name == LLString::null) return LLUUID::null; |
@@ -1710,64 +1738,169 @@ LLUUID LLUI::findAssetUUIDByName(const LLString &asset_name) | |||
1710 | return LLUUID( foundValue ); | 1738 | return LLUUID( foundValue ); |
1711 | } | 1739 | } |
1712 | 1740 | ||
1741 | //static | ||
1742 | LLUIImage* LLUI::getUIImageByName(const LLString& name) | ||
1743 | { | ||
1744 | return sImageProvider->getUIImageByID(findAssetUUIDByName(name)); | ||
1745 | } | ||
1746 | |||
1747 | |||
1713 | // static | 1748 | // static |
1714 | void LLUI::setHtmlHelp(LLHtmlHelp* html_help) | 1749 | void LLUI::setHtmlHelp(LLHtmlHelp* html_help) |
1715 | { | 1750 | { |
1716 | LLUI::sHtmlHelp = html_help; | 1751 | LLUI::sHtmlHelp = html_help; |
1717 | } | 1752 | } |
1718 | 1753 | ||
1754 | LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled) : mScissorState(GL_SCISSOR_TEST), mEnabled(enabled) | ||
1755 | { | ||
1756 | if (mEnabled) | ||
1757 | { | ||
1758 | pushClipRect(rect); | ||
1759 | } | ||
1760 | mScissorState.setEnabled(!sClipRectStack.empty()); | ||
1761 | updateScissorRegion(); | ||
1762 | } | ||
1763 | |||
1764 | LLScreenClipRect::~LLScreenClipRect() | ||
1765 | { | ||
1766 | if (mEnabled) | ||
1767 | { | ||
1768 | popClipRect(); | ||
1769 | } | ||
1770 | updateScissorRegion(); | ||
1771 | } | ||
1772 | |||
1719 | //static | 1773 | //static |
1720 | void LLUI::pushClipRect(const LLRect& rect) | 1774 | void LLScreenClipRect::pushClipRect(const LLRect& rect) |
1721 | { | 1775 | { |
1722 | LLRect combined_clip_rect = rect; | 1776 | LLRect combined_clip_rect = rect; |
1723 | if (!sClipRectStack.empty()) | 1777 | if (!sClipRectStack.empty()) |
1724 | { | 1778 | { |
1725 | combined_clip_rect.intersectWith(sClipRectStack.top()); | 1779 | LLRect top = sClipRectStack.top(); |
1780 | combined_clip_rect.intersectWith(top); | ||
1726 | } | 1781 | } |
1727 | sClipRectStack.push(combined_clip_rect); | 1782 | sClipRectStack.push(combined_clip_rect); |
1728 | setScissorRegionScreen(combined_clip_rect); | ||
1729 | } | 1783 | } |
1730 | 1784 | ||
1731 | //static | 1785 | //static |
1732 | void LLUI::popClipRect() | 1786 | void LLScreenClipRect::popClipRect() |
1733 | { | 1787 | { |
1734 | sClipRectStack.pop(); | 1788 | sClipRectStack.pop(); |
1735 | if (!sClipRectStack.empty()) | ||
1736 | { | ||
1737 | setScissorRegionScreen(sClipRectStack.top()); | ||
1738 | } | ||
1739 | } | 1789 | } |
1740 | 1790 | ||
1741 | LLClipRect::LLClipRect(const LLRect& rect, BOOL enabled) : mScissorState(GL_SCISSOR_TEST, enabled), mEnabled(enabled) | 1791 | //static |
1792 | void LLScreenClipRect::updateScissorRegion() | ||
1742 | { | 1793 | { |
1743 | if (mEnabled) | 1794 | if (sClipRectStack.empty()) return; |
1744 | { | 1795 | |
1745 | LLUI::pushClipRect(rect); | 1796 | LLRect rect = sClipRectStack.top(); |
1746 | } | 1797 | stop_glerror(); |
1798 | S32 x,y,w,h; | ||
1799 | x = llfloor(rect.mLeft * LLUI::sGLScaleFactor.mV[VX]); | ||
1800 | y = llfloor(rect.mBottom * LLUI::sGLScaleFactor.mV[VY]); | ||
1801 | w = llmax(0, llceil(rect.getWidth() * LLUI::sGLScaleFactor.mV[VX])) + 1; | ||
1802 | h = llmax(0, llceil(rect.getHeight() * LLUI::sGLScaleFactor.mV[VY])) + 1; | ||
1803 | glScissor( x,y,w,h ); | ||
1804 | stop_glerror(); | ||
1747 | } | 1805 | } |
1748 | 1806 | ||
1749 | LLClipRect::~LLClipRect() | 1807 | |
1808 | LLLocalClipRect::LLLocalClipRect(const LLRect &rect, BOOL enabled) | ||
1809 | : LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX, | ||
1810 | rect.mTop + LLFontGL::sCurOrigin.mY, | ||
1811 | rect.mRight + LLFontGL::sCurOrigin.mX, | ||
1812 | rect.mBottom + LLFontGL::sCurOrigin.mY), | ||
1813 | enabled) | ||
1750 | { | 1814 | { |
1751 | if (mEnabled) | ||
1752 | { | ||
1753 | LLUI::popClipRect(); | ||
1754 | } | ||
1755 | } | 1815 | } |
1756 | 1816 | ||
1757 | LLLocalClipRect::LLLocalClipRect(const LLRect &rect, BOOL enabled) : mScissorState(GL_SCISSOR_TEST, enabled), mEnabled(enabled) | 1817 | |
1818 | // | ||
1819 | // LLUIImage | ||
1820 | // | ||
1821 | |||
1822 | LLUIImage::LLUIImage(LLPointer<LLImageGL> image) : | ||
1823 | mImage(image), | ||
1824 | mScaleRegion(0.f, 1.f, 1.f, 0.f), | ||
1825 | mClipRegion(0.f, 1.f, 1.f, 0.f), | ||
1826 | mUniformScaling(TRUE), | ||
1827 | mNoClip(TRUE) | ||
1758 | { | 1828 | { |
1759 | if (mEnabled) | ||
1760 | { | ||
1761 | LLRect scissor_rect = rect; | ||
1762 | scissor_rect.translate(LLFontGL::sCurOrigin.mX, LLFontGL::sCurOrigin.mY); | ||
1763 | LLUI::pushClipRect(scissor_rect); | ||
1764 | } | ||
1765 | } | 1829 | } |
1766 | 1830 | ||
1767 | LLLocalClipRect::~LLLocalClipRect() | 1831 | void LLUIImage::setClipRegion(const LLRectf& region) |
1832 | { | ||
1833 | mClipRegion = region; | ||
1834 | mNoClip = mClipRegion.mLeft == 0.f | ||
1835 | && mClipRegion.mRight == 1.f | ||
1836 | && mClipRegion.mBottom == 0.f | ||
1837 | && mClipRegion.mTop == 1.f; | ||
1838 | } | ||
1839 | |||
1840 | void LLUIImage::setScaleRegion(const LLRectf& region) | ||
1841 | { | ||
1842 | mScaleRegion = region; | ||
1843 | mUniformScaling = mScaleRegion.mLeft == 0.f | ||
1844 | && mScaleRegion.mRight == 1.f | ||
1845 | && mScaleRegion.mBottom == 0.f | ||
1846 | && mScaleRegion.mTop == 1.f; | ||
1847 | } | ||
1848 | |||
1849 | //TODO: move drawing implementation inside class | ||
1850 | void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) | ||
1768 | { | 1851 | { |
1769 | if (mEnabled) | 1852 | gl_draw_image(x, y, mImage, color, mClipRegion); |
1853 | } | ||
1854 | |||
1855 | void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) | ||
1856 | { | ||
1857 | if (mUniformScaling) | ||
1858 | { | ||
1859 | gl_draw_scaled_image(x, y, width, height, mImage, color, mClipRegion); | ||
1860 | } | ||
1861 | else | ||
1770 | { | 1862 | { |
1771 | LLUI::popClipRect(); | 1863 | gl_draw_scaled_image_with_border( |
1864 | x, y, | ||
1865 | width, height, | ||
1866 | mImage, | ||
1867 | color, | ||
1868 | FALSE, | ||
1869 | mClipRegion, | ||
1870 | mScaleRegion); | ||
1772 | } | 1871 | } |
1773 | } | 1872 | } |
1873 | |||
1874 | void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) | ||
1875 | { | ||
1876 | gl_draw_scaled_image_with_border( | ||
1877 | x, y, | ||
1878 | width, height, | ||
1879 | mImage, | ||
1880 | color, | ||
1881 | TRUE, | ||
1882 | mClipRegion, | ||
1883 | mScaleRegion); | ||
1884 | } | ||
1885 | |||
1886 | void LLUIImage::drawSolid(S32 x, S32 y, const LLColor4& color) | ||
1887 | { | ||
1888 | gl_draw_scaled_image_with_border( | ||
1889 | x, y, | ||
1890 | getWidth(), getHeight(), | ||
1891 | mImage, | ||
1892 | color, | ||
1893 | TRUE, | ||
1894 | mClipRegion, | ||
1895 | mScaleRegion); | ||
1896 | } | ||
1897 | |||
1898 | S32 LLUIImage::getWidth() | ||
1899 | { | ||
1900 | return mImage->getWidth(0); | ||
1901 | } | ||
1902 | |||
1903 | S32 LLUIImage::getHeight() | ||
1904 | { | ||
1905 | return mImage->getHeight(0); | ||
1906 | } | ||
diff --git a/linden/indra/llui/llui.h b/linden/indra/llui/llui.h index 2832b39..9d98620 100644 --- a/linden/indra/llui/llui.h +++ b/linden/indra/llui/llui.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -41,14 +41,15 @@ | |||
41 | #include "llhtmlhelp.h" | 41 | #include "llhtmlhelp.h" |
42 | #include "llgl.h" | 42 | #include "llgl.h" |
43 | #include <stack> | 43 | #include <stack> |
44 | #include "llimagegl.h" | ||
44 | 45 | ||
45 | class LLColor4; | 46 | class LLColor4; |
46 | class LLVector3; | 47 | class LLVector3; |
47 | class LLVector2; | 48 | class LLVector2; |
48 | class LLImageGL; | ||
49 | class LLUUID; | 49 | class LLUUID; |
50 | class LLWindow; | 50 | class LLWindow; |
51 | class LLView; | 51 | class LLView; |
52 | class LLUIImage; | ||
52 | 53 | ||
53 | // UI colors | 54 | // UI colors |
54 | extern const LLColor4 UI_VERTEX_COLOR; | 55 | extern const LLColor4 UI_VERTEX_COLOR; |
@@ -83,13 +84,14 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& | |||
83 | 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); | 84 | 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); |
84 | void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color); | 85 | void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color); |
85 | 86 | ||
86 | void gl_draw_image(S32 x, S32 y, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR); | 87 | 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)); |
87 | void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR); | 88 | 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)); |
88 | void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR); | 89 | 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)); |
89 | void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR); | 90 | 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)); |
90 | 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); | 91 | 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)); |
92 | 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)); | ||
91 | // Flip vertical, used for LLFloaterHTML | 93 | // Flip vertical, used for LLFloaterHTML |
92 | void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR); | 94 | 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)); |
93 | 95 | ||
94 | void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom); | 96 | void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom); |
95 | void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); | 97 | void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); |
@@ -166,20 +168,19 @@ public: | |||
166 | 168 | ||
167 | //helper functions (should probably move free standing rendering helper functions here) | 169 | //helper functions (should probably move free standing rendering helper functions here) |
168 | static LLString locateSkin(const LLString& filename); | 170 | static LLString locateSkin(const LLString& filename); |
169 | static void pushClipRect(const LLRect& rect); | ||
170 | static void popClipRect(); | ||
171 | static void setCursorPositionScreen(S32 x, S32 y); | 171 | static void setCursorPositionScreen(S32 x, S32 y); |
172 | static void setCursorPositionLocal(LLView* viewp, S32 x, S32 y); | 172 | static void setCursorPositionLocal(LLView* viewp, S32 x, S32 y); |
173 | static void setScaleFactor(const LLVector2& scale_factor); | 173 | static void setScaleFactor(const LLVector2& scale_factor); |
174 | static void setLineWidth(F32 width); | 174 | static void setLineWidth(F32 width); |
175 | static LLUUID findAssetUUIDByName(const LLString& name); | 175 | static LLUUID findAssetUUIDByName(const LLString& name); |
176 | static LLUIImage* getUIImageByName(const LLString& name); | ||
176 | static LLVector2 getWindowSize(); | 177 | static LLVector2 getWindowSize(); |
178 | static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y); | ||
179 | static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y); | ||
180 | static void screenRectToGL(const LLRect& screen, LLRect *gl); | ||
181 | static void glRectToScreen(const LLRect& gl, LLRect *screen); | ||
177 | static void setHtmlHelp(LLHtmlHelp* html_help); | 182 | static void setHtmlHelp(LLHtmlHelp* html_help); |
178 | 183 | ||
179 | private: | ||
180 | static void setScissorRegionScreen(const LLRect& rect); | ||
181 | static void setScissorRegionLocal(const LLRect& rect); // works assuming LLUI::translate has been called | ||
182 | |||
183 | public: | 184 | public: |
184 | static LLControlGroup* sConfigGroup; | 185 | static LLControlGroup* sConfigGroup; |
185 | static LLControlGroup* sColorsGroup; | 186 | static LLControlGroup* sColorsGroup; |
@@ -190,7 +191,6 @@ public: | |||
190 | static LLWindow* sWindow; | 191 | static LLWindow* sWindow; |
191 | static BOOL sShowXUINames; | 192 | static BOOL sShowXUINames; |
192 | static LLHtmlHelp* sHtmlHelp; | 193 | static LLHtmlHelp* sHtmlHelp; |
193 | static std::stack<LLRect> sClipRectStack; | ||
194 | 194 | ||
195 | }; | 195 | }; |
196 | 196 | ||
@@ -282,6 +282,7 @@ typedef enum e_widget_type | |||
282 | WIDGET_TYPE_MEMORY_VIEW, | 282 | WIDGET_TYPE_MEMORY_VIEW, |
283 | WIDGET_TYPE_FRAME_STAT_VIEW, | 283 | WIDGET_TYPE_FRAME_STAT_VIEW, |
284 | WIDGET_TYPE_LAYOUT_STACK, | 284 | WIDGET_TYPE_LAYOUT_STACK, |
285 | WIDGET_TYPE_FLYOUT_BUTTON, | ||
285 | WIDGET_TYPE_DONTCARE, | 286 | WIDGET_TYPE_DONTCARE, |
286 | WIDGET_TYPE_COUNT | 287 | WIDGET_TYPE_COUNT |
287 | } EWidgetType; | 288 | } EWidgetType; |
@@ -378,24 +379,65 @@ protected: | |||
378 | 379 | ||
379 | template <class T, class U> T* LLUISingleton<T,U>::sInstance = NULL; | 380 | template <class T, class U> T* LLUISingleton<T,U>::sInstance = NULL; |
380 | 381 | ||
381 | class LLClipRect | 382 | class LLScreenClipRect |
382 | { | 383 | { |
383 | public: | 384 | public: |
384 | LLClipRect(const LLRect& rect, BOOL enabled = TRUE); | 385 | LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE); |
385 | virtual ~LLClipRect(); | 386 | virtual ~LLScreenClipRect(); |
386 | protected: | 387 | |
388 | private: | ||
389 | static void pushClipRect(const LLRect& rect); | ||
390 | static void popClipRect(); | ||
391 | static void updateScissorRegion(); | ||
392 | |||
393 | private: | ||
387 | LLGLState mScissorState; | 394 | LLGLState mScissorState; |
388 | BOOL mEnabled; | 395 | BOOL mEnabled; |
396 | |||
397 | static std::stack<LLRect> sClipRectStack; | ||
389 | }; | 398 | }; |
390 | 399 | ||
391 | class LLLocalClipRect | 400 | class LLLocalClipRect : public LLScreenClipRect |
392 | { | 401 | { |
393 | public: | 402 | public: |
394 | LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE); | 403 | LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE); |
395 | virtual ~LLLocalClipRect(); | 404 | }; |
405 | |||
406 | class LLUIImage : public LLRefCount | ||
407 | { | ||
408 | public: | ||
409 | LLUIImage(LLPointer<LLImageGL> image); | ||
410 | |||
411 | void setClipRegion(const LLRectf& region); | ||
412 | void setScaleRegion(const LLRectf& region); | ||
413 | |||
414 | LLPointer<LLImageGL> getImage() { return mImage; } | ||
415 | |||
416 | void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR); | ||
417 | void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR); | ||
418 | void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color); | ||
419 | void drawSolid(S32 x, S32 y, const LLColor4& color); | ||
420 | |||
421 | S32 getWidth(); | ||
422 | S32 getHeight(); | ||
423 | |||
396 | protected: | 424 | protected: |
397 | LLGLState mScissorState; | 425 | LLRectf mScaleRegion; |
398 | BOOL mEnabled; | 426 | LLRectf mClipRegion; |
427 | LLPointer<LLImageGL> mImage; | ||
428 | BOOL mUniformScaling; | ||
429 | BOOL mNoClip; | ||
430 | }; | ||
431 | |||
432 | //RN: maybe this needs to moved elsewhere? | ||
433 | class LLImageProviderInterface | ||
434 | { | ||
435 | public: | ||
436 | LLImageProviderInterface() {}; | ||
437 | virtual ~LLImageProviderInterface() {}; | ||
438 | |||
439 | virtual LLUIImage* getUIImageByID(const LLUUID& id, BOOL clamped = TRUE) = 0; | ||
440 | virtual LLImageGL* getImageByID(const LLUUID& id, BOOL clamped = TRUE) = 0; | ||
399 | }; | 441 | }; |
400 | 442 | ||
401 | #endif | 443 | #endif |
diff --git a/linden/indra/llui/llui_vc9.vcproj b/linden/indra/llui/llui_vc9.vcproj new file mode 100644 index 0000000..cfaaf66 --- /dev/null +++ b/linden/indra/llui/llui_vc9.vcproj | |||
@@ -0,0 +1,596 @@ | |||
1 | <?xml version="1.0" encoding="Windows-1252"?> | ||
2 | <VisualStudioProject | ||
3 | ProjectType="Visual C++" | ||
4 | Version="9.00" | ||
5 | Name="llui" | ||
6 | ProjectGUID="{DE55D666-6A3D-476C-937F-109269B83681}" | ||
7 | RootNamespace="llui" | ||
8 | Keyword="Win32Proj" | ||
9 | TargetFrameworkVersion="131072" | ||
10 | > | ||
11 | <Platforms> | ||
12 | <Platform | ||
13 | Name="Win32" | ||
14 | /> | ||
15 | </Platforms> | ||
16 | <ToolFiles> | ||
17 | </ToolFiles> | ||
18 | <Configurations> | ||
19 | <Configuration | ||
20 | Name="Debug|Win32" | ||
21 | OutputDirectory="../lib_$(ConfigurationName)/i686-win32" | ||
22 | IntermediateDirectory="Debug" | ||
23 | ConfigurationType="4" | ||
24 | InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" | ||
25 | CharacterSet="1" | ||
26 | > | ||
27 | <Tool | ||
28 | Name="VCPreBuildEventTool" | ||
29 | /> | ||
30 | <Tool | ||
31 | Name="VCCustomBuildTool" | ||
32 | /> | ||
33 | <Tool | ||
34 | Name="VCXMLDataGeneratorTool" | ||
35 | /> | ||
36 | <Tool | ||
37 | Name="VCWebServiceProxyGeneratorTool" | ||
38 | /> | ||
39 | <Tool | ||
40 | Name="VCMIDLTool" | ||
41 | /> | ||
42 | <Tool | ||
43 | Name="VCCLCompilerTool" | ||
44 | Optimization="0" | ||
45 | AdditionalIncludeDirectories="..\llmath;..\llvfs;..\llcommon;..\llprimitive;..\llwindow;..\llrender;..\llimage;..\llaudio;..\llxml;..\llmessage;"..\..\libraries\i686-win32\include";..\..\libraries\include\" | ||
46 | PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_DEBUG" | ||
47 | MinimalRebuild="true" | ||
48 | BasicRuntimeChecks="3" | ||
49 | RuntimeLibrary="1" | ||
50 | StructMemberAlignment="4" | ||
51 | TreatWChar_tAsBuiltInType="false" | ||
52 | ForceConformanceInForLoopScope="true" | ||
53 | UsePrecompiledHeader="0" | ||
54 | WarningLevel="3" | ||
55 | WarnAsError="true" | ||
56 | Detect64BitPortabilityProblems="false" | ||
57 | DebugInformationFormat="4" | ||
58 | /> | ||
59 | <Tool | ||
60 | Name="VCManagedResourceCompilerTool" | ||
61 | /> | ||
62 | <Tool | ||
63 | Name="VCResourceCompilerTool" | ||
64 | /> | ||
65 | <Tool | ||
66 | Name="VCPreLinkEventTool" | ||
67 | /> | ||
68 | <Tool | ||
69 | Name="VCLibrarianTool" | ||
70 | OutputFile="$(OutDir)/llui.lib" | ||
71 | /> | ||
72 | <Tool | ||
73 | Name="VCALinkTool" | ||
74 | /> | ||
75 | <Tool | ||
76 | Name="VCXDCMakeTool" | ||
77 | /> | ||
78 | <Tool | ||
79 | Name="VCBscMakeTool" | ||
80 | /> | ||
81 | <Tool | ||
82 | Name="VCFxCopTool" | ||
83 | /> | ||
84 | <Tool | ||
85 | Name="VCPostBuildEventTool" | ||
86 | /> | ||
87 | </Configuration> | ||
88 | <Configuration | ||
89 | Name="Release|Win32" | ||
90 | OutputDirectory="../lib_$(ConfigurationName)/i686-win32" | ||
91 | IntermediateDirectory="Release" | ||
92 | ConfigurationType="4" | ||
93 | InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" | ||
94 | CharacterSet="1" | ||
95 | > | ||
96 | <Tool | ||
97 | Name="VCPreBuildEventTool" | ||
98 | /> | ||
99 | <Tool | ||
100 | Name="VCCustomBuildTool" | ||
101 | /> | ||
102 | <Tool | ||
103 | Name="VCXMLDataGeneratorTool" | ||
104 | /> | ||
105 | <Tool | ||
106 | Name="VCWebServiceProxyGeneratorTool" | ||
107 | /> | ||
108 | <Tool | ||
109 | Name="VCMIDLTool" | ||
110 | /> | ||
111 | <Tool | ||
112 | Name="VCCLCompilerTool" | ||
113 | AdditionalOptions="/Oy-" | ||
114 | AdditionalIncludeDirectories="..\llmath;..\llvfs;..\llcommon;..\llprimitive;..\llwindow;..\llrender;..\llimage;..\llaudio;..\llxml;..\llmessage;"..\..\libraries\i686-win32\include";..\..\libraries\include\" | ||
115 | PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE" | ||
116 | RuntimeLibrary="0" | ||
117 | StructMemberAlignment="0" | ||
118 | TreatWChar_tAsBuiltInType="false" | ||
119 | ForceConformanceInForLoopScope="true" | ||
120 | UsePrecompiledHeader="0" | ||
121 | WarningLevel="3" | ||
122 | WarnAsError="true" | ||
123 | Detect64BitPortabilityProblems="false" | ||
124 | DebugInformationFormat="3" | ||
125 | /> | ||
126 | <Tool | ||
127 | Name="VCManagedResourceCompilerTool" | ||
128 | /> | ||
129 | <Tool | ||
130 | Name="VCResourceCompilerTool" | ||
131 | /> | ||
132 | <Tool | ||
133 | Name="VCPreLinkEventTool" | ||
134 | /> | ||
135 | <Tool | ||
136 | Name="VCLibrarianTool" | ||
137 | OutputFile="$(OutDir)/llui.lib" | ||
138 | /> | ||
139 | <Tool | ||
140 | Name="VCALinkTool" | ||
141 | /> | ||
142 | <Tool | ||
143 | Name="VCXDCMakeTool" | ||
144 | /> | ||
145 | <Tool | ||
146 | Name="VCBscMakeTool" | ||
147 | /> | ||
148 | <Tool | ||
149 | Name="VCFxCopTool" | ||
150 | /> | ||
151 | <Tool | ||
152 | Name="VCPostBuildEventTool" | ||
153 | /> | ||
154 | </Configuration> | ||
155 | <Configuration | ||
156 | Name="ReleaseNoOpt|Win32" | ||
157 | OutputDirectory="../lib_$(ConfigurationName)/i686-win32" | ||
158 | IntermediateDirectory="$(ConfigurationName)" | ||
159 | ConfigurationType="4" | ||
160 | InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" | ||
161 | CharacterSet="1" | ||
162 | > | ||
163 | <Tool | ||
164 | Name="VCPreBuildEventTool" | ||
165 | /> | ||
166 | <Tool | ||
167 | Name="VCCustomBuildTool" | ||
168 | /> | ||
169 | <Tool | ||
170 | Name="VCXMLDataGeneratorTool" | ||
171 | /> | ||
172 | <Tool | ||
173 | Name="VCWebServiceProxyGeneratorTool" | ||
174 | /> | ||
175 | <Tool | ||
176 | Name="VCMIDLTool" | ||
177 | /> | ||
178 | <Tool | ||
179 | Name="VCCLCompilerTool" | ||
180 | AdditionalOptions="/Oy-" | ||
181 | Optimization="0" | ||
182 | AdditionalIncludeDirectories="..\llmath;..\llvfs;..\llcommon;..\llprimitive;..\llwindow;..\llrender;..\llimage;..\llaudio;..\llxml;..\llmessage;"..\..\libraries\i686-win32\include";..\..\libraries\include\" | ||
183 | PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE" | ||
184 | RuntimeLibrary="0" | ||
185 | StructMemberAlignment="0" | ||
186 | TreatWChar_tAsBuiltInType="false" | ||
187 | ForceConformanceInForLoopScope="true" | ||
188 | UsePrecompiledHeader="0" | ||
189 | WarningLevel="3" | ||
190 | WarnAsError="true" | ||
191 | Detect64BitPortabilityProblems="false" | ||
192 | DebugInformationFormat="3" | ||
193 | /> | ||
194 | <Tool | ||
195 | Name="VCManagedResourceCompilerTool" | ||
196 | /> | ||
197 | <Tool | ||
198 | Name="VCResourceCompilerTool" | ||
199 | /> | ||
200 | <Tool | ||
201 | Name="VCPreLinkEventTool" | ||
202 | /> | ||
203 | <Tool | ||
204 | Name="VCLibrarianTool" | ||
205 | OutputFile="$(OutDir)/llui.lib" | ||
206 | /> | ||
207 | <Tool | ||
208 | Name="VCALinkTool" | ||
209 | /> | ||
210 | <Tool | ||
211 | Name="VCXDCMakeTool" | ||
212 | /> | ||
213 | <Tool | ||
214 | Name="VCBscMakeTool" | ||
215 | /> | ||
216 | <Tool | ||
217 | Name="VCFxCopTool" | ||
218 | /> | ||
219 | <Tool | ||
220 | Name="VCPostBuildEventTool" | ||
221 | /> | ||
222 | </Configuration> | ||
223 | </Configurations> | ||
224 | <References> | ||
225 | </References> | ||
226 | <Files> | ||
227 | <Filter | ||
228 | Name="Source Files" | ||
229 | Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" | ||
230 | UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" | ||
231 | > | ||
232 | <File | ||
233 | RelativePath=".\llalertdialog.cpp" | ||
234 | > | ||
235 | </File> | ||
236 | <File | ||
237 | RelativePath=".\llbutton.cpp" | ||
238 | > | ||
239 | </File> | ||
240 | <File | ||
241 | RelativePath=".\llcheckboxctrl.cpp" | ||
242 | > | ||
243 | </File> | ||
244 | <File | ||
245 | RelativePath=".\llclipboard.cpp" | ||
246 | > | ||
247 | </File> | ||
248 | <File | ||
249 | RelativePath=".\llcombobox.cpp" | ||
250 | > | ||
251 | </File> | ||
252 | <File | ||
253 | RelativePath=".\llctrlselectioninterface.cpp" | ||
254 | > | ||
255 | </File> | ||
256 | <File | ||
257 | RelativePath=".\lldraghandle.cpp" | ||
258 | > | ||
259 | </File> | ||
260 | <File | ||
261 | RelativePath=".\lleditmenuhandler.cpp" | ||
262 | > | ||
263 | </File> | ||
264 | <File | ||
265 | RelativePath=".\llfloater.cpp" | ||
266 | > | ||
267 | </File> | ||
268 | <File | ||
269 | RelativePath=".\llfocusmgr.cpp" | ||
270 | > | ||
271 | </File> | ||
272 | <File | ||
273 | RelativePath=".\lliconctrl.cpp" | ||
274 | > | ||
275 | </File> | ||
276 | <File | ||
277 | RelativePath=".\llkeywords.cpp" | ||
278 | > | ||
279 | </File> | ||
280 | <File | ||
281 | RelativePath=".\lllineeditor.cpp" | ||
282 | > | ||
283 | </File> | ||
284 | <File | ||
285 | RelativePath=".\llmenugl.cpp" | ||
286 | > | ||
287 | </File> | ||
288 | <File | ||
289 | RelativePath=".\llmodaldialog.cpp" | ||
290 | > | ||
291 | </File> | ||
292 | <File | ||
293 | RelativePath=".\llpanel.cpp" | ||
294 | > | ||
295 | </File> | ||
296 | <File | ||
297 | RelativePath=".\llradiogroup.cpp" | ||
298 | > | ||
299 | </File> | ||
300 | <File | ||
301 | RelativePath=".\llresizebar.cpp" | ||
302 | > | ||
303 | </File> | ||
304 | <File | ||
305 | RelativePath=".\llresizehandle.cpp" | ||
306 | > | ||
307 | </File> | ||
308 | <File | ||
309 | RelativePath=".\llresmgr.cpp" | ||
310 | > | ||
311 | </File> | ||
312 | <File | ||
313 | RelativePath=".\llrootview.cpp" | ||
314 | > | ||
315 | </File> | ||
316 | <File | ||
317 | RelativePath=".\llscrollbar.cpp" | ||
318 | > | ||
319 | </File> | ||
320 | <File | ||
321 | RelativePath=".\llscrollcontainer.cpp" | ||
322 | > | ||
323 | </File> | ||
324 | <File | ||
325 | RelativePath=".\llscrollingpanellist.cpp" | ||
326 | > | ||
327 | </File> | ||
328 | <File | ||
329 | RelativePath=".\llscrolllistctrl.cpp" | ||
330 | > | ||
331 | </File> | ||
332 | <File | ||
333 | RelativePath=".\llslider.cpp" | ||
334 | > | ||
335 | </File> | ||
336 | <File | ||
337 | RelativePath=".\llsliderctrl.cpp" | ||
338 | > | ||
339 | </File> | ||
340 | <File | ||
341 | RelativePath=".\llspinctrl.cpp" | ||
342 | > | ||
343 | </File> | ||
344 | <File | ||
345 | RelativePath=".\llstyle.cpp" | ||
346 | > | ||
347 | </File> | ||
348 | <File | ||
349 | RelativePath=".\lltabcontainer.cpp" | ||
350 | > | ||
351 | </File> | ||
352 | <File | ||
353 | RelativePath=".\lltabcontainervertical.cpp" | ||
354 | > | ||
355 | </File> | ||
356 | <File | ||
357 | RelativePath=".\lltextbox.cpp" | ||
358 | > | ||
359 | </File> | ||
360 | <File | ||
361 | RelativePath=".\lltexteditor.cpp" | ||
362 | > | ||
363 | </File> | ||
364 | <File | ||
365 | RelativePath=".\llui.cpp" | ||
366 | > | ||
367 | </File> | ||
368 | <File | ||
369 | RelativePath=".\lluictrl.cpp" | ||
370 | > | ||
371 | </File> | ||
372 | <File | ||
373 | RelativePath=".\lluictrlfactory.cpp" | ||
374 | > | ||
375 | </File> | ||
376 | <File | ||
377 | RelativePath=".\lluistring.cpp" | ||
378 | > | ||
379 | </File> | ||
380 | <File | ||
381 | RelativePath=".\llundo.cpp" | ||
382 | > | ||
383 | </File> | ||
384 | <File | ||
385 | RelativePath=".\llview.cpp" | ||
386 | > | ||
387 | </File> | ||
388 | <File | ||
389 | RelativePath=".\llviewborder.cpp" | ||
390 | > | ||
391 | </File> | ||
392 | <File | ||
393 | RelativePath=".\llviewquery.cpp" | ||
394 | > | ||
395 | </File> | ||
396 | </Filter> | ||
397 | <Filter | ||
398 | Name="Header Files" | ||
399 | Filter="h;hpp;hxx;hm;inl;inc;xsd" | ||
400 | UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" | ||
401 | > | ||
402 | <File | ||
403 | RelativePath=".\llalertdialog.h" | ||
404 | > | ||
405 | </File> | ||
406 | <File | ||
407 | RelativePath=".\llbutton.h" | ||
408 | > | ||
409 | </File> | ||
410 | <File | ||
411 | RelativePath=".\llcallbackmap.h" | ||
412 | > | ||
413 | </File> | ||
414 | <File | ||
415 | RelativePath=".\llcheckboxctrl.h" | ||
416 | > | ||
417 | </File> | ||
418 | <File | ||
419 | RelativePath=".\llclipboard.h" | ||
420 | > | ||
421 | </File> | ||
422 | <File | ||
423 | RelativePath=".\llcombobox.h" | ||
424 | > | ||
425 | </File> | ||
426 | <File | ||
427 | RelativePath=".\llctrlselectioninterface.h" | ||
428 | > | ||
429 | </File> | ||
430 | <File | ||
431 | RelativePath=".\lldraghandle.h" | ||
432 | > | ||
433 | </File> | ||
434 | <File | ||
435 | RelativePath=".\lleditmenuhandler.h" | ||
436 | > | ||
437 | </File> | ||
438 | <File | ||
439 | RelativePath=".\llfloater.h" | ||
440 | > | ||
441 | </File> | ||
442 | <File | ||
443 | RelativePath=".\llfocusmgr.h" | ||
444 | > | ||
445 | </File> | ||
446 | <File | ||
447 | RelativePath=".\llhtmlhelp.h" | ||
448 | > | ||
449 | </File> | ||
450 | <File | ||
451 | RelativePath=".\lliconctrl.h" | ||
452 | > | ||
453 | </File> | ||
454 | <File | ||
455 | RelativePath=".\llkeywords.h" | ||
456 | > | ||
457 | </File> | ||
458 | <File | ||
459 | RelativePath=".\lllineeditor.h" | ||
460 | > | ||
461 | </File> | ||
462 | <File | ||
463 | RelativePath=".\llmemberlistener.h" | ||
464 | > | ||
465 | </File> | ||
466 | <File | ||
467 | RelativePath=".\llmenugl.h" | ||
468 | > | ||
469 | </File> | ||
470 | <File | ||
471 | RelativePath=".\llmodaldialog.h" | ||
472 | > | ||
473 | </File> | ||
474 | <File | ||
475 | RelativePath=".\llpanel.h" | ||
476 | > | ||
477 | </File> | ||
478 | <File | ||
479 | RelativePath=".\llradiogroup.h" | ||
480 | > | ||
481 | </File> | ||
482 | <File | ||
483 | RelativePath=".\llresizebar.h" | ||
484 | > | ||
485 | </File> | ||
486 | <File | ||
487 | RelativePath=".\llresizehandle.h" | ||
488 | > | ||
489 | </File> | ||
490 | <File | ||
491 | RelativePath=".\llresmgr.h" | ||
492 | > | ||
493 | </File> | ||
494 | <File | ||
495 | RelativePath=".\llrootview.h" | ||
496 | > | ||
497 | </File> | ||
498 | <File | ||
499 | RelativePath=".\llscrollbar.h" | ||
500 | > | ||
501 | </File> | ||
502 | <File | ||
503 | RelativePath=".\llscrollcontainer.h" | ||
504 | > | ||
505 | </File> | ||
506 | <File | ||
507 | RelativePath=".\llscrollingpanellist.h" | ||
508 | > | ||
509 | </File> | ||
510 | <File | ||
511 | RelativePath=".\llscrolllistctrl.h" | ||
512 | > | ||
513 | </File> | ||
514 | <File | ||
515 | RelativePath=".\llslider.h" | ||
516 | > | ||
517 | </File> | ||
518 | <File | ||
519 | RelativePath=".\llsliderctrl.h" | ||
520 | > | ||
521 | </File> | ||
522 | <File | ||
523 | RelativePath=".\llspinctrl.h" | ||
524 | > | ||
525 | </File> | ||
526 | <File | ||
527 | RelativePath=".\llstyle.h" | ||
528 | > | ||
529 | </File> | ||
530 | <File | ||
531 | RelativePath=".\lltabcontainer.h" | ||
532 | > | ||
533 | </File> | ||
534 | <File | ||
535 | RelativePath=".\lltabcontainervertical.h" | ||
536 | > | ||
537 | </File> | ||
538 | <File | ||
539 | RelativePath=".\lltextbox.h" | ||
540 | > | ||
541 | </File> | ||
542 | <File | ||
543 | RelativePath=".\lltexteditor.h" | ||
544 | > | ||
545 | </File> | ||
546 | <File | ||
547 | RelativePath=".\llui.h" | ||
548 | > | ||
549 | </File> | ||
550 | <File | ||
551 | RelativePath=".\lluiconstants.h" | ||
552 | > | ||
553 | </File> | ||
554 | <File | ||
555 | RelativePath=".\lluictrl.h" | ||
556 | > | ||
557 | </File> | ||
558 | <File | ||
559 | RelativePath=".\lluictrlfactory.h" | ||
560 | > | ||
561 | </File> | ||
562 | <File | ||
563 | RelativePath=".\lluistring.h" | ||
564 | > | ||
565 | </File> | ||
566 | <File | ||
567 | RelativePath=".\lluixmltags.h" | ||
568 | > | ||
569 | </File> | ||
570 | <File | ||
571 | RelativePath=".\llundo.h" | ||
572 | > | ||
573 | </File> | ||
574 | <File | ||
575 | RelativePath=".\llview.h" | ||
576 | > | ||
577 | </File> | ||
578 | <File | ||
579 | RelativePath=".\llviewborder.h" | ||
580 | > | ||
581 | </File> | ||
582 | <File | ||
583 | RelativePath=".\llviewquery.h" | ||
584 | > | ||
585 | </File> | ||
586 | </Filter> | ||
587 | <Filter | ||
588 | Name="Resource Files" | ||
589 | Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" | ||
590 | UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" | ||
591 | > | ||
592 | </Filter> | ||
593 | </Files> | ||
594 | <Globals> | ||
595 | </Globals> | ||
596 | </VisualStudioProject> | ||
diff --git a/linden/indra/llui/lluiconstants.h b/linden/indra/llui/lluiconstants.h index bd75d27..b3b9297 100644 --- a/linden/indra/llui/lluiconstants.h +++ b/linden/indra/llui/lluiconstants.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/lluictrl.cpp b/linden/indra/llui/lluictrl.cpp index 61d6c8c..63db1cc 100644 --- a/linden/indra/llui/lluictrl.cpp +++ b/linden/indra/llui/lluictrl.cpp | |||
@@ -13,12 +13,12 @@ | |||
13 | * ("GPL"), unless you have obtained a separate licensing agreement | 13 | * ("GPL"), unless you have obtained a separate licensing agreement |
14 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 14 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
16 | * online at http://secondlife.com/developers/opensource/gplv2 | 16 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
17 | * | 17 | * |
18 | * There are special exceptions to the terms and conditions of the GPL as | 18 | * There are special exceptions to the terms and conditions of the GPL as |
19 | * it is applied to this Source Code. View the full text of the exception | 19 | * it is applied to this Source Code. View the full text of the exception |
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 20 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
21 | * online at http://secondlife.com/developers/opensource/flossexception | 21 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
22 | * | 22 | * |
23 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
24 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -47,11 +47,53 @@ | |||
47 | 47 | ||
48 | const U32 MAX_STRING_LENGTH = 10; | 48 | const U32 MAX_STRING_LENGTH = 10; |
49 | 49 | ||
50 | LLUICtrl::LLUICtrl() : | 50 | LLFocusableElement::LLFocusableElement() |
51 | mCommitCallback(NULL), | 51 | : mFocusLostCallback(NULL), |
52 | mFocusLostCallback(NULL), | ||
53 | mFocusReceivedCallback(NULL), | 52 | mFocusReceivedCallback(NULL), |
54 | mFocusChangedCallback(NULL), | 53 | mFocusChangedCallback(NULL), |
54 | mFocusCallbackUserData(NULL) | ||
55 | { | ||
56 | } | ||
57 | |||
58 | void LLFocusableElement::onFocusReceived() | ||
59 | { | ||
60 | if( mFocusReceivedCallback ) | ||
61 | { | ||
62 | mFocusReceivedCallback( this, mFocusCallbackUserData ); | ||
63 | } | ||
64 | if( mFocusChangedCallback ) | ||
65 | { | ||
66 | mFocusChangedCallback( this, mFocusCallbackUserData ); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | void LLFocusableElement::onFocusLost() | ||
71 | { | ||
72 | if( mFocusLostCallback ) | ||
73 | { | ||
74 | mFocusLostCallback( this, mFocusCallbackUserData ); | ||
75 | } | ||
76 | |||
77 | if( mFocusChangedCallback ) | ||
78 | { | ||
79 | mFocusChangedCallback( this, mFocusCallbackUserData ); | ||
80 | } | ||
81 | } | ||
82 | |||
83 | BOOL LLFocusableElement::hasFocus() const | ||
84 | { | ||
85 | return FALSE; | ||
86 | } | ||
87 | |||
88 | void LLFocusableElement::setFocus(BOOL b) | ||
89 | { | ||
90 | } | ||
91 | |||
92 | |||
93 | |||
94 | LLUICtrl::LLUICtrl() : | ||
95 | mCommitCallback(NULL), | ||
96 | mLostTopCallback(NULL), | ||
55 | mValidateCallback(NULL), | 97 | mValidateCallback(NULL), |
56 | mCallbackUserData(NULL), | 98 | mCallbackUserData(NULL), |
57 | mTentative(FALSE), | 99 | mTentative(FALSE), |
@@ -68,9 +110,7 @@ LLUICtrl::LLUICtrl(const LLString& name, const LLRect& rect, BOOL mouse_opaque, | |||
68 | // of buttons in the UI. JC 7/20/2002 | 110 | // of buttons in the UI. JC 7/20/2002 |
69 | LLView( name, rect, mouse_opaque, reshape ), | 111 | LLView( name, rect, mouse_opaque, reshape ), |
70 | mCommitCallback( on_commit_callback) , | 112 | mCommitCallback( on_commit_callback) , |
71 | mFocusLostCallback( NULL ), | 113 | mLostTopCallback( NULL ), |
72 | mFocusReceivedCallback( NULL ), | ||
73 | mFocusChangedCallback( NULL ), | ||
74 | mValidateCallback( NULL ), | 114 | mValidateCallback( NULL ), |
75 | mCallbackUserData( callback_userdata ), | 115 | mCallbackUserData( callback_userdata ), |
76 | mTentative( FALSE ), | 116 | mTentative( FALSE ), |
@@ -128,6 +168,86 @@ LLCtrlScrollInterface* LLUICtrl::getScrollInterface() | |||
128 | return NULL; | 168 | return NULL; |
129 | } | 169 | } |
130 | 170 | ||
171 | BOOL LLUICtrl::hasFocus() const | ||
172 | { | ||
173 | return (gFocusMgr.childHasKeyboardFocus(this)); | ||
174 | } | ||
175 | |||
176 | void LLUICtrl::setFocus(BOOL b) | ||
177 | { | ||
178 | // focus NEVER goes to ui ctrls that are disabled! | ||
179 | if (!mEnabled) | ||
180 | { | ||
181 | return; | ||
182 | } | ||
183 | if( b ) | ||
184 | { | ||
185 | if (!hasFocus()) | ||
186 | { | ||
187 | gFocusMgr.setKeyboardFocus( this ); | ||
188 | } | ||
189 | } | ||
190 | else | ||
191 | { | ||
192 | if( gFocusMgr.childHasKeyboardFocus(this)) | ||
193 | { | ||
194 | gFocusMgr.setKeyboardFocus( NULL ); | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | |||
199 | void LLUICtrl::onFocusReceived() | ||
200 | { | ||
201 | // trigger callbacks | ||
202 | LLFocusableElement::onFocusReceived(); | ||
203 | |||
204 | // find first view in hierarchy above new focus that is a LLUICtrl | ||
205 | LLView* viewp = getParent(); | ||
206 | LLUICtrl* last_focus = gFocusMgr.getLastKeyboardFocus(); | ||
207 | |||
208 | while (viewp && !viewp->isCtrl()) | ||
209 | { | ||
210 | viewp = viewp->getParent(); | ||
211 | } | ||
212 | |||
213 | // and if it has newly gained focus, call onFocusReceived() | ||
214 | LLUICtrl* ctrlp = static_cast<LLUICtrl*>(viewp); | ||
215 | if (ctrlp && (!last_focus || !last_focus->hasAncestor(ctrlp))) | ||
216 | { | ||
217 | ctrlp->onFocusReceived(); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | void LLUICtrl::onFocusLost() | ||
222 | { | ||
223 | // trigger callbacks | ||
224 | LLFocusableElement::onFocusLost(); | ||
225 | |||
226 | // find first view in hierarchy above old focus that is a LLUICtrl | ||
227 | LLView* viewp = getParent(); | ||
228 | while (viewp && !viewp->isCtrl()) | ||
229 | { | ||
230 | viewp = viewp->getParent(); | ||
231 | } | ||
232 | |||
233 | // and if it has just lost focus, call onFocusReceived() | ||
234 | LLUICtrl* ctrlp = static_cast<LLUICtrl*>(viewp); | ||
235 | // hasFocus() includes any descendants | ||
236 | if (ctrlp && !ctrlp->hasFocus()) | ||
237 | { | ||
238 | ctrlp->onFocusLost(); | ||
239 | } | ||
240 | } | ||
241 | |||
242 | void LLUICtrl::onLostTop() | ||
243 | { | ||
244 | if (mLostTopCallback) | ||
245 | { | ||
246 | mLostTopCallback(this, mCallbackUserData); | ||
247 | } | ||
248 | } | ||
249 | |||
250 | |||
131 | // virtual | 251 | // virtual |
132 | void LLUICtrl::setTabStop( BOOL b ) | 252 | void LLUICtrl::setTabStop( BOOL b ) |
133 | { | 253 | { |
@@ -165,68 +285,26 @@ void LLUICtrl::setIsChrome(BOOL is_chrome) | |||
165 | // virtual | 285 | // virtual |
166 | BOOL LLUICtrl::getIsChrome() const | 286 | BOOL LLUICtrl::getIsChrome() const |
167 | { | 287 | { |
168 | return mIsChrome; | 288 | // am I or any of my ancestors flagged as "chrome"? |
169 | } | 289 | if (mIsChrome) return TRUE; |
170 | 290 | ||
171 | void LLUICtrl::onFocusReceived() | 291 | LLView* parent_ctrl = getParent(); |
172 | { | 292 | while(parent_ctrl) |
173 | if( mFocusReceivedCallback ) | ||
174 | { | ||
175 | mFocusReceivedCallback( this, mCallbackUserData ); | ||
176 | } | ||
177 | if( mFocusChangedCallback ) | ||
178 | { | 293 | { |
179 | mFocusChangedCallback( this, mCallbackUserData ); | 294 | if(parent_ctrl->isCtrl()) |
180 | } | ||
181 | } | ||
182 | |||
183 | void LLUICtrl::onFocusLost() | ||
184 | { | ||
185 | if( mFocusLostCallback ) | ||
186 | { | ||
187 | mFocusLostCallback( this, mCallbackUserData ); | ||
188 | } | ||
189 | |||
190 | if( mFocusChangedCallback ) | ||
191 | { | ||
192 | mFocusChangedCallback( this, mCallbackUserData ); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | BOOL LLUICtrl::hasFocus() const | ||
197 | { | ||
198 | return (gFocusMgr.childHasKeyboardFocus(this)); | ||
199 | } | ||
200 | |||
201 | void LLUICtrl::setFocus(BOOL b) | ||
202 | { | ||
203 | // focus NEVER goes to ui ctrls that are disabled! | ||
204 | if (!mEnabled) | ||
205 | { | ||
206 | return; | ||
207 | } | ||
208 | if( b ) | ||
209 | { | ||
210 | if (!hasFocus()) | ||
211 | { | 295 | { |
212 | gFocusMgr.setKeyboardFocus( this, &LLUICtrl::onFocusLostCallback ); | 296 | break; |
213 | onFocusReceived(); | ||
214 | } | 297 | } |
298 | parent_ctrl = parent_ctrl->getParent(); | ||
215 | } | 299 | } |
216 | else | 300 | |
301 | if(parent_ctrl) | ||
217 | { | 302 | { |
218 | if( gFocusMgr.childHasKeyboardFocus(this)) | 303 | // recurse into parent_ctrl and ask if it is in a chrome subtree |
219 | { | 304 | return ((LLUICtrl*)parent_ctrl)->getIsChrome(); |
220 | gFocusMgr.setKeyboardFocus( NULL, NULL ); | ||
221 | onFocusLost(); | ||
222 | } | ||
223 | } | 305 | } |
224 | } | ||
225 | 306 | ||
226 | // static | 307 | return FALSE; |
227 | void LLUICtrl::onFocusLostCallback( LLUICtrl* old_focus ) | ||
228 | { | ||
229 | old_focus->onFocusLost(); | ||
230 | } | 308 | } |
231 | 309 | ||
232 | // this comparator uses the crazy disambiguating logic of LLCompareByTabOrder, | 310 | // this comparator uses the crazy disambiguating logic of LLCompareByTabOrder, |
@@ -262,6 +340,7 @@ public: | |||
262 | } | 340 | } |
263 | }; | 341 | }; |
264 | 342 | ||
343 | |||
265 | BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields) | 344 | BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields) |
266 | { | 345 | { |
267 | // try to select default tab group child | 346 | // try to select default tab group child |
diff --git a/linden/indra/llui/lluictrl.h b/linden/indra/llui/lluictrl.h index bf61f8b..55e804c 100644 --- a/linden/indra/llui/lluictrl.h +++ b/linden/indra/llui/lluictrl.h | |||
@@ -13,12 +13,12 @@ | |||
13 | * ("GPL"), unless you have obtained a separate licensing agreement | 13 | * ("GPL"), unless you have obtained a separate licensing agreement |
14 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 14 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
16 | * online at http://secondlife.com/developers/opensource/gplv2 | 16 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
17 | * | 17 | * |
18 | * There are special exceptions to the terms and conditions of the GPL as | 18 | * There are special exceptions to the terms and conditions of the GPL as |
19 | * it is applied to this Source Code. View the full text of the exception | 19 | * it is applied to this Source Code. View the full text of the exception |
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 20 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
21 | * online at http://secondlife.com/developers/opensource/flossexception | 21 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
22 | * | 22 | * |
23 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
24 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -53,8 +53,31 @@ class LLCtrlScrollInterface; | |||
53 | typedef void (*LLUICtrlCallback)(LLUICtrl* ctrl, void* userdata); | 53 | typedef void (*LLUICtrlCallback)(LLUICtrl* ctrl, void* userdata); |
54 | typedef BOOL (*LLUICtrlValidate)(LLUICtrl* ctrl, void* userdata); | 54 | typedef BOOL (*LLUICtrlValidate)(LLUICtrl* ctrl, void* userdata); |
55 | 55 | ||
56 | class LLFocusableElement | ||
57 | { | ||
58 | friend class LLFocusMgr; // allow access to focus change handlers | ||
59 | public: | ||
60 | LLFocusableElement(); | ||
61 | virtual ~LLFocusableElement() {}; | ||
62 | |||
63 | virtual void setFocus( BOOL b ); | ||
64 | virtual BOOL hasFocus() const; | ||
65 | |||
66 | void setFocusLostCallback(void (*cb)(LLFocusableElement* caller, void*), void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; } | ||
67 | void setFocusReceivedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; } | ||
68 | void setFocusChangedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; } | ||
69 | |||
70 | protected: | ||
71 | virtual void onFocusReceived(); | ||
72 | virtual void onFocusLost(); | ||
73 | void (*mFocusLostCallback)( LLFocusableElement* caller, void* userdata ); | ||
74 | void (*mFocusReceivedCallback)( LLFocusableElement* ctrl, void* userdata ); | ||
75 | void (*mFocusChangedCallback)( LLFocusableElement* ctrl, void* userdata ); | ||
76 | void* mFocusCallbackUserData; | ||
77 | }; | ||
78 | |||
56 | class LLUICtrl | 79 | class LLUICtrl |
57 | : public LLView | 80 | : public LLView, public LLFocusableElement |
58 | { | 81 | { |
59 | public: | 82 | public: |
60 | LLUICtrl(); | 83 | LLUICtrl(); |
@@ -85,6 +108,11 @@ public: | |||
85 | virtual void setFocus( BOOL b ); | 108 | virtual void setFocus( BOOL b ); |
86 | virtual BOOL hasFocus() const; | 109 | virtual BOOL hasFocus() const; |
87 | 110 | ||
111 | virtual void onFocusReceived(); | ||
112 | virtual void onFocusLost(); | ||
113 | |||
114 | virtual void onLostTop(); // called when registered as top ctrl and user clicks elsewhere | ||
115 | |||
88 | virtual void setTabStop( BOOL b ); | 116 | virtual void setTabStop( BOOL b ); |
89 | virtual BOOL hasTabStop() const; | 117 | virtual BOOL hasTabStop() const; |
90 | 118 | ||
@@ -115,6 +143,7 @@ public: | |||
115 | 143 | ||
116 | void setCommitCallback( void (*cb)(LLUICtrl*, void*) ) { mCommitCallback = cb; } | 144 | void setCommitCallback( void (*cb)(LLUICtrl*, void*) ) { mCommitCallback = cb; } |
117 | void setValidateBeforeCommit( BOOL(*cb)(LLUICtrl*, void*) ) { mValidateCallback = cb; } | 145 | void setValidateBeforeCommit( BOOL(*cb)(LLUICtrl*, void*) ) { mValidateCallback = cb; } |
146 | void setLostTopCallback( void (*cb)(LLUICtrl*, void*) ) { mLostTopCallback = cb; } | ||
118 | 147 | ||
119 | // Defaults to no-op! | 148 | // Defaults to no-op! |
120 | virtual void setDoubleClickCallback( void (*cb)(void*) ); | 149 | virtual void setDoubleClickCallback( void (*cb)(void*) ); |
@@ -126,23 +155,8 @@ public: | |||
126 | virtual void setMinValue(LLSD min_value); | 155 | virtual void setMinValue(LLSD min_value); |
127 | virtual void setMaxValue(LLSD max_value); | 156 | virtual void setMaxValue(LLSD max_value); |
128 | 157 | ||
129 | // In general, only LLPanel uses these. | ||
130 | void setFocusLostCallback(void (*cb)(LLUICtrl* caller, void* user_data)) { mFocusLostCallback = cb; } | ||
131 | void setFocusReceivedCallback( void (*cb)(LLUICtrl*, void*) ) { mFocusReceivedCallback = cb; } | ||
132 | void setFocusChangedCallback( void (*cb)(LLUICtrl*, void*) ) { mFocusChangedCallback = cb; } | ||
133 | |||
134 | static void onFocusLostCallback(LLUICtrl* old_focus); | ||
135 | |||
136 | /*virtual*/ BOOL focusFirstItem(BOOL prefer_text_fields = FALSE ); | 158 | /*virtual*/ BOOL focusFirstItem(BOOL prefer_text_fields = FALSE ); |
137 | 159 | ||
138 | class LLTabStopPostFilter : public LLQueryFilter, public LLSingleton<LLTabStopPostFilter> | ||
139 | { | ||
140 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const | ||
141 | { | ||
142 | return filterResult_t(view->isCtrl() && static_cast<const LLUICtrl *>(view)->hasTabStop() && children.size() == 0, TRUE); | ||
143 | } | ||
144 | }; | ||
145 | |||
146 | class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter> | 160 | class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter> |
147 | { | 161 | { |
148 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const | 162 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const |
@@ -157,16 +171,9 @@ public: | |||
157 | virtual void resetDirty() {}; | 171 | virtual void resetDirty() {}; |
158 | 172 | ||
159 | protected: | 173 | protected: |
160 | virtual void onFocusReceived(); | ||
161 | virtual void onFocusLost(); | ||
162 | void onChangeFocus( S32 direction ); | ||
163 | |||
164 | protected: | ||
165 | 174 | ||
166 | void (*mCommitCallback)( LLUICtrl* ctrl, void* userdata ); | 175 | void (*mCommitCallback)( LLUICtrl* ctrl, void* userdata ); |
167 | void (*mFocusLostCallback)( LLUICtrl* caller, void* userdata ); | 176 | void (*mLostTopCallback)( LLUICtrl* ctrl, void* userdata ); |
168 | void (*mFocusReceivedCallback)( LLUICtrl* ctrl, void* userdata ); | ||
169 | void (*mFocusChangedCallback)( LLUICtrl* ctrl, void* userdata ); | ||
170 | BOOL (*mValidateCallback)( LLUICtrl* ctrl, void* userdata ); | 177 | BOOL (*mValidateCallback)( LLUICtrl* ctrl, void* userdata ); |
171 | 178 | ||
172 | void* mCallbackUserData; | 179 | void* mCallbackUserData; |
diff --git a/linden/indra/llui/lluictrlfactory.cpp b/linden/indra/llui/lluictrlfactory.cpp index 98228d5..a51d8e4 100644 --- a/linden/indra/llui/lluictrlfactory.cpp +++ b/linden/indra/llui/lluictrlfactory.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -173,7 +173,7 @@ std::vector<LLString> LLUICtrlFactory::mXUIPaths; | |||
173 | class LLUICtrlLocate : public LLUICtrl | 173 | class LLUICtrlLocate : public LLUICtrl |
174 | { | 174 | { |
175 | public: | 175 | public: |
176 | LLUICtrlLocate() : LLUICtrl("locate", LLRect(0,0,0,0), FALSE, NULL, NULL) {} | 176 | LLUICtrlLocate() : LLUICtrl("locate", LLRect(0,0,0,0), FALSE, NULL, NULL) { setTabStop(FALSE); } |
177 | virtual void draw() { } | 177 | virtual void draw() { } |
178 | 178 | ||
179 | virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_LOCATE; } | 179 | virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_LOCATE; } |
@@ -181,7 +181,11 @@ public: | |||
181 | 181 | ||
182 | static LLView *fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) | 182 | static LLView *fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) |
183 | { | 183 | { |
184 | LLString name("pad"); | ||
185 | node->getAttributeString("name", name); | ||
186 | |||
184 | LLUICtrlLocate *new_ctrl = new LLUICtrlLocate(); | 187 | LLUICtrlLocate *new_ctrl = new LLUICtrlLocate(); |
188 | new_ctrl->setName(name); | ||
185 | new_ctrl->initFromXML(node, parent); | 189 | new_ctrl->initFromXML(node, parent); |
186 | return new_ctrl; | 190 | return new_ctrl; |
187 | } | 191 | } |
@@ -196,6 +200,7 @@ LLUICtrlFactory::LLUICtrlFactory() | |||
196 | LLUICtrlCreator<LLButton>::registerCreator(LL_BUTTON_TAG, this); | 200 | LLUICtrlCreator<LLButton>::registerCreator(LL_BUTTON_TAG, this); |
197 | LLUICtrlCreator<LLCheckBoxCtrl>::registerCreator(LL_CHECK_BOX_CTRL_TAG, this); | 201 | LLUICtrlCreator<LLCheckBoxCtrl>::registerCreator(LL_CHECK_BOX_CTRL_TAG, this); |
198 | LLUICtrlCreator<LLComboBox>::registerCreator(LL_COMBO_BOX_TAG, this); | 202 | LLUICtrlCreator<LLComboBox>::registerCreator(LL_COMBO_BOX_TAG, this); |
203 | LLUICtrlCreator<LLFlyoutButton>::registerCreator(LL_FLYOUT_BUTTON_TAG, this); | ||
199 | LLUICtrlCreator<LLLineEditor>::registerCreator(LL_LINE_EDITOR_TAG, this); | 204 | LLUICtrlCreator<LLLineEditor>::registerCreator(LL_LINE_EDITOR_TAG, this); |
200 | LLUICtrlCreator<LLSearchEditor>::registerCreator(LL_SEARCH_EDITOR_TAG, this); | 205 | LLUICtrlCreator<LLSearchEditor>::registerCreator(LL_SEARCH_EDITOR_TAG, this); |
201 | LLUICtrlCreator<LLScrollListCtrl>::registerCreator(LL_SCROLL_LIST_CTRL_TAG, this); | 206 | LLUICtrlCreator<LLScrollListCtrl>::registerCreator(LL_SCROLL_LIST_CTRL_TAG, this); |
@@ -282,8 +287,11 @@ bool LLUICtrlFactory::getLayeredXMLNode(const LLString &filename, LLXMLNodePtr& | |||
282 | 287 | ||
283 | if (!LLXMLNode::parseFile(mXUIPaths.front() + filename, root, NULL)) | 288 | if (!LLXMLNode::parseFile(mXUIPaths.front() + filename, root, NULL)) |
284 | { | 289 | { |
285 | llwarns << "Problem reading UI description file: " << mXUIPaths.front() + filename << llendl; | 290 | if (!LLXMLNode::parseFile(filename, root, NULL)) |
286 | return FALSE; | 291 | { |
292 | llwarns << "Problem reading UI description file: " << mXUIPaths.front() + filename << llendl; | ||
293 | return FALSE; | ||
294 | } | ||
287 | } | 295 | } |
288 | 296 | ||
289 | LLXMLNodePtr updateRoot; | 297 | LLXMLNodePtr updateRoot; |
diff --git a/linden/indra/llui/lluictrlfactory.h b/linden/indra/llui/lluictrlfactory.h index 22fac59..fbb8d96 100644 --- a/linden/indra/llui/lluictrlfactory.h +++ b/linden/indra/llui/lluictrlfactory.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/lluistring.cpp b/linden/indra/llui/lluistring.cpp index 36fba17..d3b5a52 100644 --- a/linden/indra/llui/lluistring.cpp +++ b/linden/indra/llui/lluistring.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/lluistring.h b/linden/indra/llui/lluistring.h index e52f718..4e9bb55 100644 --- a/linden/indra/llui/lluistring.h +++ b/linden/indra/llui/lluistring.h | |||
@@ -13,12 +13,12 @@ | |||
13 | * ("GPL"), unless you have obtained a separate licensing agreement | 13 | * ("GPL"), unless you have obtained a separate licensing agreement |
14 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 14 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
16 | * online at http://secondlife.com/developers/opensource/gplv2 | 16 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
17 | * | 17 | * |
18 | * There are special exceptions to the terms and conditions of the GPL as | 18 | * There are special exceptions to the terms and conditions of the GPL as |
19 | * it is applied to this Source Code. View the full text of the exception | 19 | * it is applied to this Source Code. View the full text of the exception |
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 20 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
21 | * online at http://secondlife.com/developers/opensource/flossexception | 21 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
22 | * | 22 | * |
23 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
24 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/lluixmltags.h b/linden/indra/llui/lluixmltags.h index 84e571f..1afcb00 100644 --- a/linden/indra/llui/lluixmltags.h +++ b/linden/indra/llui/lluixmltags.h | |||
@@ -11,12 +11,12 @@ | |||
11 | * ("GPL"), unless you have obtained a separate licensing agreement | 11 | * ("GPL"), unless you have obtained a separate licensing agreement |
12 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 12 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
13 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 13 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
14 | * online at http://secondlife.com/developers/opensource/gplv2 | 14 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
15 | * | 15 | * |
16 | * There are special exceptions to the terms and conditions of the GPL as | 16 | * There are special exceptions to the terms and conditions of the GPL as |
17 | * it is applied to this Source Code. View the full text of the exception | 17 | * it is applied to this Source Code. View the full text of the exception |
18 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 18 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
19 | * online at http://secondlife.com/developers/opensource/flossexception | 19 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
20 | * | 20 | * |
21 | * By copying, modifying or distributing this software, you acknowledge | 21 | * By copying, modifying or distributing this software, you acknowledge |
22 | * that you have read and understood your obligations described above, | 22 | * that you have read and understood your obligations described above, |
@@ -120,4 +120,5 @@ | |||
120 | #define LL_JOYSTICK_TURN LLString("joystick_turn") | 120 | #define LL_JOYSTICK_TURN LLString("joystick_turn") |
121 | #define LL_GROUP_DROP_TARGET_TAG LLString("group_drop_target") | 121 | #define LL_GROUP_DROP_TARGET_TAG LLString("group_drop_target") |
122 | #define LL_LAYOUT_STACK_TAG LLString("layout_stack") | 122 | #define LL_LAYOUT_STACK_TAG LLString("layout_stack") |
123 | #define LL_FLYOUT_BUTTON_TAG "flyout_button" | ||
123 | #endif | 124 | #endif |
diff --git a/linden/indra/llui/llundo.cpp b/linden/indra/llui/llundo.cpp index 3580d31..a267ae2 100644 --- a/linden/indra/llui/llundo.cpp +++ b/linden/indra/llui/llundo.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llundo.h b/linden/indra/llui/llundo.h index b3e2457..2bf04bc 100644 --- a/linden/indra/llui/llundo.h +++ b/linden/indra/llui/llundo.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp index e18dbb0..04d33a6 100644 --- a/linden/indra/llui/llview.cpp +++ b/linden/indra/llui/llview.cpp | |||
@@ -13,12 +13,12 @@ | |||
13 | * ("GPL"), unless you have obtained a separate licensing agreement | 13 | * ("GPL"), unless you have obtained a separate licensing agreement |
14 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 14 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
16 | * online at http://secondlife.com/developers/opensource/gplv2 | 16 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
17 | * | 17 | * |
18 | * There are special exceptions to the terms and conditions of the GPL as | 18 | * There are special exceptions to the terms and conditions of the GPL as |
19 | * it is applied to this Source Code. View the full text of the exception | 19 | * it is applied to this Source Code. View the full text of the exception |
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 20 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
21 | * online at http://secondlife.com/developers/opensource/flossexception | 21 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
22 | * | 22 | * |
23 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
24 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -113,7 +113,7 @@ LLView::LLView() : | |||
113 | mSaveToXML(TRUE), | 113 | mSaveToXML(TRUE), |
114 | mIsFocusRoot(FALSE), | 114 | mIsFocusRoot(FALSE), |
115 | mLastVisible(TRUE), | 115 | mLastVisible(TRUE), |
116 | mSpanChildren(FALSE), | 116 | mUseBoundingRect(FALSE), |
117 | mVisible(TRUE), | 117 | mVisible(TRUE), |
118 | mHidden(FALSE), | 118 | mHidden(FALSE), |
119 | mNextInsertionOrdinal(0) | 119 | mNextInsertionOrdinal(0) |
@@ -133,7 +133,7 @@ LLView::LLView(const LLString& name, BOOL mouse_opaque) : | |||
133 | mSaveToXML(TRUE), | 133 | mSaveToXML(TRUE), |
134 | mIsFocusRoot(FALSE), | 134 | mIsFocusRoot(FALSE), |
135 | mLastVisible(TRUE), | 135 | mLastVisible(TRUE), |
136 | mSpanChildren(FALSE), | 136 | mUseBoundingRect(FALSE), |
137 | mVisible(TRUE), | 137 | mVisible(TRUE), |
138 | mHidden(FALSE), | 138 | mHidden(FALSE), |
139 | mNextInsertionOrdinal(0) | 139 | mNextInsertionOrdinal(0) |
@@ -148,6 +148,7 @@ LLView::LLView( | |||
148 | mParentView(NULL), | 148 | mParentView(NULL), |
149 | mName(name), | 149 | mName(name), |
150 | mRect(rect), | 150 | mRect(rect), |
151 | mBoundingRect(rect), | ||
151 | mReshapeFlags(reshape), | 152 | mReshapeFlags(reshape), |
152 | mDefaultTabGroup(0), | 153 | mDefaultTabGroup(0), |
153 | mEnabled(TRUE), | 154 | mEnabled(TRUE), |
@@ -156,7 +157,7 @@ LLView::LLView( | |||
156 | mSaveToXML(TRUE), | 157 | mSaveToXML(TRUE), |
157 | mIsFocusRoot(FALSE), | 158 | mIsFocusRoot(FALSE), |
158 | mLastVisible(TRUE), | 159 | mLastVisible(TRUE), |
159 | mSpanChildren(FALSE), | 160 | mUseBoundingRect(FALSE), |
160 | mVisible(TRUE), | 161 | mVisible(TRUE), |
161 | mHidden(FALSE), | 162 | mHidden(FALSE), |
162 | mNextInsertionOrdinal(0) | 163 | mNextInsertionOrdinal(0) |
@@ -235,10 +236,16 @@ BOOL LLView::setToolTipArg(const LLStringExplicit& key, const LLStringExplicit& | |||
235 | return TRUE; | 236 | return TRUE; |
236 | } | 237 | } |
237 | 238 | ||
239 | void LLView::setToolTipArgs( const LLString::format_map_t& args ) | ||
240 | { | ||
241 | mToolTipMsg.setArgList(args); | ||
242 | } | ||
243 | |||
238 | // virtual | 244 | // virtual |
239 | void LLView::setRect(const LLRect& rect) | 245 | void LLView::setRect(const LLRect& rect) |
240 | { | 246 | { |
241 | mRect = rect; | 247 | mRect = rect; |
248 | updateBoundingRect(); | ||
242 | } | 249 | } |
243 | 250 | ||
244 | 251 | ||
@@ -287,9 +294,18 @@ void LLView::setName(LLString name) | |||
287 | mName = name; | 294 | mName = name; |
288 | } | 295 | } |
289 | 296 | ||
290 | void LLView::setSpanChildren( BOOL span_children ) | 297 | void LLView::setUseBoundingRect( BOOL use_bounding_rect ) |
298 | { | ||
299 | if (mUseBoundingRect != use_bounding_rect) | ||
300 | { | ||
301 | mUseBoundingRect = use_bounding_rect; | ||
302 | updateBoundingRect(); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | BOOL LLView::getUseBoundingRect() | ||
291 | { | 307 | { |
292 | mSpanChildren = span_children; updateRect(); | 308 | return mUseBoundingRect; |
293 | } | 309 | } |
294 | 310 | ||
295 | const LLString& LLView::getToolTip() | 311 | const LLString& LLView::getToolTip() |
@@ -306,7 +322,7 @@ const LLString& LLView::getName() const | |||
306 | 322 | ||
307 | void LLView::sendChildToFront(LLView* child) | 323 | void LLView::sendChildToFront(LLView* child) |
308 | { | 324 | { |
309 | if (child->mParentView == this) | 325 | if (child && child->getParent() == this) |
310 | { | 326 | { |
311 | mChildList.remove( child ); | 327 | mChildList.remove( child ); |
312 | mChildList.push_front(child); | 328 | mChildList.push_front(child); |
@@ -315,7 +331,7 @@ void LLView::sendChildToFront(LLView* child) | |||
315 | 331 | ||
316 | void LLView::sendChildToBack(LLView* child) | 332 | void LLView::sendChildToBack(LLView* child) |
317 | { | 333 | { |
318 | if (child->mParentView == this) | 334 | if (child && child->getParent() == this) |
319 | { | 335 | { |
320 | mChildList.remove( child ); | 336 | mChildList.remove( child ); |
321 | mChildList.push_back(child); | 337 | mChildList.push_back(child); |
@@ -330,6 +346,14 @@ void LLView::moveChildToFrontOfTabGroup(LLUICtrl* child) | |||
330 | } | 346 | } |
331 | } | 347 | } |
332 | 348 | ||
349 | void LLView::moveChildToBackOfTabGroup(LLUICtrl* child) | ||
350 | { | ||
351 | if(mCtrlOrder.find(child) != mCtrlOrder.end()) | ||
352 | { | ||
353 | mCtrlOrder[child].second = mNextInsertionOrdinal++; | ||
354 | } | ||
355 | } | ||
356 | |||
333 | void LLView::addChild(LLView* child, S32 tab_group) | 357 | void LLView::addChild(LLView* child, S32 tab_group) |
334 | { | 358 | { |
335 | if (mParentView == child) | 359 | if (mParentView == child) |
@@ -353,7 +377,7 @@ void LLView::addChild(LLView* child, S32 tab_group) | |||
353 | } | 377 | } |
354 | 378 | ||
355 | child->mParentView = this; | 379 | child->mParentView = this; |
356 | updateRect(); | 380 | updateBoundingRect(); |
357 | } | 381 | } |
358 | 382 | ||
359 | 383 | ||
@@ -380,7 +404,7 @@ void LLView::addChildAtEnd(LLView* child, S32 tab_group) | |||
380 | } | 404 | } |
381 | 405 | ||
382 | child->mParentView = this; | 406 | child->mParentView = this; |
383 | updateRect(); | 407 | updateBoundingRect(); |
384 | } | 408 | } |
385 | 409 | ||
386 | // remove the specified child from the view, and set it's parent to NULL. | 410 | // remove the specified child from the view, and set it's parent to NULL. |
@@ -403,6 +427,7 @@ void LLView::removeChild(LLView* child, BOOL deleteIt) | |||
403 | { | 427 | { |
404 | llerrs << "LLView::removeChild called with non-child" << llendl; | 428 | llerrs << "LLView::removeChild called with non-child" << llendl; |
405 | } | 429 | } |
430 | updateBoundingRect(); | ||
406 | } | 431 | } |
407 | 432 | ||
408 | void LLView::addCtrlAtEnd(LLUICtrl* ctrl, S32 tab_group) | 433 | void LLView::addCtrlAtEnd(LLUICtrl* ctrl, S32 tab_group) |
@@ -782,6 +807,7 @@ void LLView::setVisible(BOOL visible) | |||
782 | // tell all children of this view that the visibility may have changed | 807 | // tell all children of this view that the visibility may have changed |
783 | onVisibilityChange( visible ); | 808 | onVisibilityChange( visible ); |
784 | } | 809 | } |
810 | updateBoundingRect(); | ||
785 | } | 811 | } |
786 | } | 812 | } |
787 | 813 | ||
@@ -815,6 +841,7 @@ void LLView::onVisibilityChange ( BOOL new_visibility ) | |||
815 | void LLView::translate(S32 x, S32 y) | 841 | void LLView::translate(S32 x, S32 y) |
816 | { | 842 | { |
817 | mRect.translate(x, y); | 843 | mRect.translate(x, y); |
844 | updateBoundingRect(); | ||
818 | } | 845 | } |
819 | 846 | ||
820 | // virtual | 847 | // virtual |
@@ -831,7 +858,8 @@ void LLView::snappedTo(LLView* snap_view) | |||
831 | BOOL LLView::handleHover(S32 x, S32 y, MASK mask) | 858 | BOOL LLView::handleHover(S32 x, S32 y, MASK mask) |
832 | { | 859 | { |
833 | BOOL handled = childrenHandleHover( x, y, mask ) != NULL; | 860 | BOOL handled = childrenHandleHover( x, y, mask ) != NULL; |
834 | if( !handled && mMouseOpaque && pointInView( x, y ) ) | 861 | if( !handled |
862 | && blockMouseEvent(x, y) ) | ||
835 | { | 863 | { |
836 | LLUI::sWindow->setCursor(UI_CURSOR_ARROW); | 864 | LLUI::sWindow->setCursor(UI_CURSOR_ARROW); |
837 | lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; | 865 | lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; |
@@ -876,45 +904,46 @@ BOOL LLView::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_scre | |||
876 | 904 | ||
877 | LLString tool_tip; | 905 | LLString tool_tip; |
878 | 906 | ||
879 | if ( getVisible() && getEnabled()) | 907 | for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) |
880 | { | 908 | { |
881 | for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) | 909 | LLView* viewp = *child_it; |
910 | S32 local_x = x - viewp->mRect.mLeft; | ||
911 | S32 local_y = y - viewp->mRect.mBottom; | ||
912 | if( viewp->pointInView(local_x, local_y) | ||
913 | && viewp->getVisible() | ||
914 | && viewp->getEnabled() | ||
915 | && viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen )) | ||
882 | { | 916 | { |
883 | LLView* viewp = *child_it; | 917 | handled = TRUE; |
884 | S32 local_x = x - viewp->mRect.mLeft; | 918 | break; |
885 | S32 local_y = y - viewp->mRect.mBottom; | ||
886 | if( viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen ) ) | ||
887 | { | ||
888 | handled = TRUE; | ||
889 | break; | ||
890 | } | ||
891 | } | 919 | } |
920 | } | ||
892 | 921 | ||
893 | tool_tip = mToolTipMsg.getString(); | 922 | tool_tip = mToolTipMsg.getString(); |
894 | if (LLUI::sShowXUINames && (tool_tip.find(".xml", 0) == LLString::npos) && | 923 | if ( |
895 | (mName.find("Drag", 0) == LLString::npos)) | 924 | LLUI::sShowXUINames && |
896 | { | 925 | (tool_tip.find(".xml", 0) == LLString::npos) && |
897 | tool_tip = getShowNamesToolTip(); | 926 | (mName.find("Drag", 0) == LLString::npos)) |
898 | } | 927 | { |
899 | 928 | tool_tip = getShowNamesToolTip(); | |
929 | } | ||
900 | 930 | ||
901 | BOOL showNamesTextBox = LLUI::sShowXUINames && (getWidgetType() == WIDGET_TYPE_TEXT_BOX); | 931 | BOOL showNamesTextBox = LLUI::sShowXUINames && (getWidgetType() == WIDGET_TYPE_TEXT_BOX); |
902 | 932 | ||
903 | if( !handled && (mMouseOpaque || showNamesTextBox) && pointInView( x, y ) && !tool_tip.empty()) | 933 | if( !handled && (blockMouseEvent(x, y) || showNamesTextBox) && !tool_tip.empty()) |
904 | { | 934 | { |
905 | 935 | ||
906 | msg = tool_tip; | 936 | msg = tool_tip; |
907 | 937 | ||
908 | // Convert rect local to screen coordinates | 938 | // Convert rect local to screen coordinates |
909 | localPointToScreen( | 939 | localPointToScreen( |
910 | 0, 0, | 940 | 0, 0, |
911 | &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); | 941 | &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); |
912 | localPointToScreen( | 942 | localPointToScreen( |
913 | mRect.getWidth(), mRect.getHeight(), | 943 | mRect.getWidth(), mRect.getHeight(), |
914 | &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); | 944 | &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); |
915 | 945 | ||
916 | handled = TRUE; | 946 | handled = TRUE; |
917 | } | ||
918 | } | 947 | } |
919 | 948 | ||
920 | return handled; | 949 | return handled; |
@@ -1025,7 +1054,7 @@ BOOL LLView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, | |||
1025 | cargo_data, | 1054 | cargo_data, |
1026 | accept, | 1055 | accept, |
1027 | tooltip_msg) != NULL; | 1056 | tooltip_msg) != NULL; |
1028 | if( !handled && mMouseOpaque ) | 1057 | if( !handled && blockMouseEvent(x, y) ) |
1029 | { | 1058 | { |
1030 | *accept = ACCEPT_NO; | 1059 | *accept = ACCEPT_NO; |
1031 | handled = TRUE; | 1060 | handled = TRUE; |
@@ -1081,7 +1110,7 @@ BOOL LLView::hasMouseCapture() | |||
1081 | BOOL LLView::handleMouseUp(S32 x, S32 y, MASK mask) | 1110 | BOOL LLView::handleMouseUp(S32 x, S32 y, MASK mask) |
1082 | { | 1111 | { |
1083 | BOOL handled = childrenHandleMouseUp( x, y, mask ) != NULL; | 1112 | BOOL handled = childrenHandleMouseUp( x, y, mask ) != NULL; |
1084 | if( !handled && mMouseOpaque ) | 1113 | if( !handled && blockMouseEvent(x, y) ) |
1085 | { | 1114 | { |
1086 | handled = TRUE; | 1115 | handled = TRUE; |
1087 | } | 1116 | } |
@@ -1092,7 +1121,7 @@ BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask) | |||
1092 | { | 1121 | { |
1093 | LLView* handled_view = childrenHandleMouseDown( x, y, mask ); | 1122 | LLView* handled_view = childrenHandleMouseDown( x, y, mask ); |
1094 | BOOL handled = (handled_view != NULL); | 1123 | BOOL handled = (handled_view != NULL); |
1095 | if( !handled && mMouseOpaque ) | 1124 | if( !handled && blockMouseEvent(x, y) ) |
1096 | { | 1125 | { |
1097 | handled = TRUE; | 1126 | handled = TRUE; |
1098 | handled_view = this; | 1127 | handled_view = this; |
@@ -1118,7 +1147,7 @@ BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask) | |||
1118 | BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask) | 1147 | BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask) |
1119 | { | 1148 | { |
1120 | BOOL handled = childrenHandleDoubleClick( x, y, mask ) != NULL; | 1149 | BOOL handled = childrenHandleDoubleClick( x, y, mask ) != NULL; |
1121 | if( !handled && mMouseOpaque ) | 1150 | if( !handled && blockMouseEvent(x, y) ) |
1122 | { | 1151 | { |
1123 | handleMouseDown(x, y, mask); | 1152 | handleMouseDown(x, y, mask); |
1124 | handled = TRUE; | 1153 | handled = TRUE; |
@@ -1132,7 +1161,7 @@ BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks) | |||
1132 | if( getVisible() && mEnabled ) | 1161 | if( getVisible() && mEnabled ) |
1133 | { | 1162 | { |
1134 | handled = childrenHandleScrollWheel( x, y, clicks ) != NULL; | 1163 | handled = childrenHandleScrollWheel( x, y, clicks ) != NULL; |
1135 | if( !handled && mMouseOpaque ) | 1164 | if( !handled && blockMouseEvent(x, y) ) |
1136 | { | 1165 | { |
1137 | handled = TRUE; | 1166 | handled = TRUE; |
1138 | } | 1167 | } |
@@ -1143,7 +1172,7 @@ BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks) | |||
1143 | BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask) | 1172 | BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask) |
1144 | { | 1173 | { |
1145 | BOOL handled = childrenHandleRightMouseDown( x, y, mask ) != NULL; | 1174 | BOOL handled = childrenHandleRightMouseDown( x, y, mask ) != NULL; |
1146 | if( !handled && mMouseOpaque ) | 1175 | if( !handled && blockMouseEvent(x, y) ) |
1147 | { | 1176 | { |
1148 | handled = TRUE; | 1177 | handled = TRUE; |
1149 | } | 1178 | } |
@@ -1153,7 +1182,7 @@ BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask) | |||
1153 | BOOL LLView::handleRightMouseUp(S32 x, S32 y, MASK mask) | 1182 | BOOL LLView::handleRightMouseUp(S32 x, S32 y, MASK mask) |
1154 | { | 1183 | { |
1155 | BOOL handled = childrenHandleRightMouseUp( x, y, mask ) != NULL; | 1184 | BOOL handled = childrenHandleRightMouseUp( x, y, mask ) != NULL; |
1156 | if( !handled && mMouseOpaque ) | 1185 | if( !handled && blockMouseEvent(x, y) ) |
1157 | { | 1186 | { |
1158 | handled = TRUE; | 1187 | handled = TRUE; |
1159 | } | 1188 | } |
@@ -1428,10 +1457,10 @@ void LLView::draw() | |||
1428 | focus_view = NULL; | 1457 | focus_view = NULL; |
1429 | } | 1458 | } |
1430 | 1459 | ||
1460 | ++sDepth; | ||
1431 | for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend(); ++child_iter) | 1461 | for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend(); ++child_iter) |
1432 | { | 1462 | { |
1433 | LLView *viewp = *child_iter; | 1463 | LLView *viewp = *child_iter; |
1434 | ++sDepth; | ||
1435 | 1464 | ||
1436 | if (viewp->getVisible() && viewp != focus_view) | 1465 | if (viewp->getVisible() && viewp != focus_view) |
1437 | { | 1466 | { |
@@ -1449,8 +1478,8 @@ void LLView::draw() | |||
1449 | } | 1478 | } |
1450 | } | 1479 | } |
1451 | 1480 | ||
1452 | --sDepth; | ||
1453 | } | 1481 | } |
1482 | --sDepth; | ||
1454 | 1483 | ||
1455 | if (focus_view && focus_view->getVisible()) | 1484 | if (focus_view && focus_view->getVisible()) |
1456 | { | 1485 | { |
@@ -1467,50 +1496,61 @@ void LLView::draw() | |||
1467 | //Draw a box for debugging. | 1496 | //Draw a box for debugging. |
1468 | void LLView::drawDebugRect() | 1497 | void LLView::drawDebugRect() |
1469 | { | 1498 | { |
1470 | // drawing solids requires texturing be disabled | 1499 | LLUI::pushMatrix(); |
1471 | LLGLSNoTexture no_texture; | ||
1472 | |||
1473 | // draw red rectangle for the border | ||
1474 | LLColor4 border_color(0.f, 0.f, 0.f, 1.f); | ||
1475 | if (sEditingUI) | ||
1476 | { | 1500 | { |
1477 | border_color.mV[0] = 1.f; | 1501 | // drawing solids requires texturing be disabled |
1478 | } | 1502 | LLGLSNoTexture no_texture; |
1479 | else | ||
1480 | { | ||
1481 | border_color.mV[sDepth%3] = 1.f; | ||
1482 | } | ||
1483 | 1503 | ||
1484 | glColor4fv( border_color.mV ); | 1504 | if (mUseBoundingRect) |
1505 | { | ||
1506 | LLUI::translate((F32)mBoundingRect.mLeft - (F32)mRect.mLeft, (F32)mBoundingRect.mBottom - (F32)mRect.mBottom, 0.f); | ||
1507 | } | ||
1485 | 1508 | ||
1486 | glBegin(GL_LINES); | 1509 | LLRect debug_rect = mUseBoundingRect ? mBoundingRect : mRect; |
1487 | glVertex2i(0, mRect.getHeight() - 1); | ||
1488 | glVertex2i(0, 0); | ||
1489 | 1510 | ||
1490 | glVertex2i(0, 0); | 1511 | // draw red rectangle for the border |
1491 | glVertex2i(mRect.getWidth() - 1, 0); | 1512 | LLColor4 border_color(0.f, 0.f, 0.f, 1.f); |
1513 | if (sEditingUI) | ||
1514 | { | ||
1515 | border_color.mV[0] = 1.f; | ||
1516 | } | ||
1517 | else | ||
1518 | { | ||
1519 | border_color.mV[sDepth%3] = 1.f; | ||
1520 | } | ||
1492 | 1521 | ||
1493 | glVertex2i(mRect.getWidth() - 1, 0); | 1522 | glColor4fv( border_color.mV ); |
1494 | glVertex2i(mRect.getWidth() - 1, mRect.getHeight() - 1); | ||
1495 | 1523 | ||
1496 | glVertex2i(mRect.getWidth() - 1, mRect.getHeight() - 1); | 1524 | glBegin(GL_LINES); |
1497 | glVertex2i(0, mRect.getHeight() - 1); | 1525 | glVertex2i(0, debug_rect.getHeight() - 1); |
1498 | glEnd(); | 1526 | glVertex2i(0, 0); |
1499 | 1527 | ||
1500 | // Draw the name if it's not a leaf node | 1528 | glVertex2i(0, 0); |
1501 | if (mChildList.size() && !sEditingUI) | 1529 | glVertex2i(debug_rect.getWidth() - 1, 0); |
1502 | { | 1530 | |
1503 | //char temp[256]; | 1531 | glVertex2i(debug_rect.getWidth() - 1, 0); |
1504 | S32 x, y; | 1532 | glVertex2i(debug_rect.getWidth() - 1, debug_rect.getHeight() - 1); |
1505 | glColor4fv( border_color.mV ); | 1533 | |
1506 | x = mRect.getWidth()/2; | 1534 | glVertex2i(debug_rect.getWidth() - 1, debug_rect.getHeight() - 1); |
1507 | y = mRect.getHeight()/2; | 1535 | glVertex2i(0, debug_rect.getHeight() - 1); |
1508 | LLString debug_text = llformat("%s (%d x %d)", getName().c_str(), | 1536 | glEnd(); |
1509 | mRect.getWidth(), mRect.getHeight()); | 1537 | |
1510 | LLFontGL::sSansSerifSmall->renderUTF8(debug_text, 0, (F32)x, (F32)y, border_color, | 1538 | // Draw the name if it's not a leaf node |
1511 | LLFontGL::HCENTER, LLFontGL::BASELINE, LLFontGL::NORMAL, | 1539 | if (mChildList.size() && !sEditingUI) |
1512 | S32_MAX, S32_MAX, NULL, FALSE); | 1540 | { |
1541 | //char temp[256]; | ||
1542 | S32 x, y; | ||
1543 | glColor4fv( border_color.mV ); | ||
1544 | x = debug_rect.getWidth()/2; | ||
1545 | y = debug_rect.getHeight()/2; | ||
1546 | LLString debug_text = llformat("%s (%d x %d)", getName().c_str(), | ||
1547 | debug_rect.getWidth(), debug_rect.getHeight()); | ||
1548 | LLFontGL::sSansSerifSmall->renderUTF8(debug_text, 0, (F32)x, (F32)y, border_color, | ||
1549 | LLFontGL::HCENTER, LLFontGL::BASELINE, LLFontGL::NORMAL, | ||
1550 | S32_MAX, S32_MAX, NULL, FALSE); | ||
1551 | } | ||
1513 | } | 1552 | } |
1553 | LLUI::popMatrix(); | ||
1514 | } | 1554 | } |
1515 | 1555 | ||
1516 | void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_draw) | 1556 | void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_draw) |
@@ -1537,9 +1577,6 @@ void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_dr | |||
1537 | 1577 | ||
1538 | void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) | 1578 | void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) |
1539 | { | 1579 | { |
1540 | // make sure this view contains all its children | ||
1541 | updateRect(); | ||
1542 | |||
1543 | // compute how much things changed and apply reshape logic to children | 1580 | // compute how much things changed and apply reshape logic to children |
1544 | S32 delta_width = width - mRect.getWidth(); | 1581 | S32 delta_width = width - mRect.getWidth(); |
1545 | S32 delta_height = height - mRect.getHeight(); | 1582 | S32 delta_height = height - mRect.getHeight(); |
@@ -1608,6 +1645,8 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) | |||
1608 | mParentView->reshape(mParentView->getRect().getWidth(), mParentView->getRect().getHeight(), FALSE); | 1645 | mParentView->reshape(mParentView->getRect().getWidth(), mParentView->getRect().getHeight(), FALSE); |
1609 | } | 1646 | } |
1610 | } | 1647 | } |
1648 | |||
1649 | updateBoundingRect(); | ||
1611 | } | 1650 | } |
1612 | 1651 | ||
1613 | LLRect LLView::getRequiredRect() | 1652 | LLRect LLView::getRequiredRect() |
@@ -1615,6 +1654,53 @@ LLRect LLView::getRequiredRect() | |||
1615 | return mRect; | 1654 | return mRect; |
1616 | } | 1655 | } |
1617 | 1656 | ||
1657 | void LLView::updateBoundingRect() | ||
1658 | { | ||
1659 | if (isDead()) return; | ||
1660 | |||
1661 | if (mUseBoundingRect) | ||
1662 | { | ||
1663 | LLRect local_bounding_rect = LLRect::null; | ||
1664 | |||
1665 | child_list_const_iter_t child_it; | ||
1666 | for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) | ||
1667 | { | ||
1668 | LLView* childp = *child_it; | ||
1669 | if (!childp->getVisible()) continue; | ||
1670 | |||
1671 | LLRect child_bounding_rect = childp->getBoundingRect(); | ||
1672 | |||
1673 | if (local_bounding_rect.isNull()) | ||
1674 | { | ||
1675 | // start out with bounding rect equal to first visible child's bounding rect | ||
1676 | local_bounding_rect = child_bounding_rect; | ||
1677 | } | ||
1678 | else | ||
1679 | { | ||
1680 | // accumulate non-null children rectangles | ||
1681 | if (!child_bounding_rect.isNull()) | ||
1682 | { | ||
1683 | local_bounding_rect.unionWith(child_bounding_rect); | ||
1684 | } | ||
1685 | } | ||
1686 | } | ||
1687 | |||
1688 | mBoundingRect = local_bounding_rect; | ||
1689 | // translate into parent-relative coordinates | ||
1690 | mBoundingRect.translate(mRect.mLeft, mRect.mBottom); | ||
1691 | } | ||
1692 | else | ||
1693 | { | ||
1694 | mBoundingRect = mRect; | ||
1695 | } | ||
1696 | |||
1697 | // give parent view a chance to resize, in case we just moved, for example | ||
1698 | if (getParent() && getParent()->mUseBoundingRect) | ||
1699 | { | ||
1700 | getParent()->updateBoundingRect(); | ||
1701 | } | ||
1702 | } | ||
1703 | |||
1618 | const LLRect LLView::getScreenRect() const | 1704 | const LLRect LLView::getScreenRect() const |
1619 | { | 1705 | { |
1620 | // *FIX: check for one-off error | 1706 | // *FIX: check for one-off error |
@@ -1624,6 +1710,15 @@ const LLRect LLView::getScreenRect() const | |||
1624 | return screen_rect; | 1710 | return screen_rect; |
1625 | } | 1711 | } |
1626 | 1712 | ||
1713 | const LLRect LLView::getLocalBoundingRect() const | ||
1714 | { | ||
1715 | LLRect local_bounding_rect = getBoundingRect(); | ||
1716 | local_bounding_rect.translate(-mRect.mLeft, -mRect.mBottom); | ||
1717 | |||
1718 | return local_bounding_rect; | ||
1719 | } | ||
1720 | |||
1721 | |||
1627 | const LLRect LLView::getLocalRect() const | 1722 | const LLRect LLView::getLocalRect() const |
1628 | { | 1723 | { |
1629 | LLRect local_rect(0, mRect.getHeight(), mRect.getWidth(), 0); | 1724 | LLRect local_rect(0, mRect.getHeight(), mRect.getWidth(), 0); |
@@ -1637,38 +1732,7 @@ const LLRect LLView::getLocalSnapRect() const | |||
1637 | return local_snap_rect; | 1732 | return local_snap_rect; |
1638 | } | 1733 | } |
1639 | 1734 | ||
1640 | void LLView::updateRect() | 1735 | BOOL LLView::hasAncestor(const LLView* parentp) |
1641 | { | ||
1642 | if (mSpanChildren && mChildList.size()) | ||
1643 | { | ||
1644 | LLView* first_child = (*mChildList.begin()); | ||
1645 | LLRect child_spanning_rect = first_child->mRect; | ||
1646 | |||
1647 | for ( child_list_iter_t child_it = ++mChildList.begin(); child_it != mChildList.end(); ++child_it) | ||
1648 | { | ||
1649 | LLView* viewp = *child_it; | ||
1650 | if (viewp->getVisible()) | ||
1651 | { | ||
1652 | child_spanning_rect.unionWith(viewp->mRect); | ||
1653 | } | ||
1654 | } | ||
1655 | |||
1656 | S32 translate_x = llmin(0, child_spanning_rect.mLeft); | ||
1657 | S32 translate_y = llmin(0, child_spanning_rect.mBottom); | ||
1658 | S32 new_width = llmax(mRect.getWidth() + translate_x, child_spanning_rect.getWidth()); | ||
1659 | S32 new_height = llmax(mRect.getHeight() + translate_y, child_spanning_rect.getHeight()); | ||
1660 | |||
1661 | mRect.setOriginAndSize(mRect.mLeft + translate_x, mRect.mBottom + translate_y, new_width, new_height); | ||
1662 | |||
1663 | for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) | ||
1664 | { | ||
1665 | LLView* viewp = *child_it; | ||
1666 | viewp->mRect.translate(-translate_x, -translate_y); | ||
1667 | } | ||
1668 | } | ||
1669 | } | ||
1670 | |||
1671 | BOOL LLView::hasAncestor(LLView* parentp) | ||
1672 | { | 1736 | { |
1673 | if (!parentp) | 1737 | if (!parentp) |
1674 | { | 1738 | { |
@@ -1743,14 +1807,23 @@ LLView* LLView::getChildByName(const LLString& name, BOOL recurse) const | |||
1743 | return NULL; | 1807 | return NULL; |
1744 | } | 1808 | } |
1745 | 1809 | ||
1746 | // virtual | 1810 | BOOL LLView::parentPointInView(S32 x, S32 y, EHitTestType type) const |
1747 | void LLView::onFocusLost() | 1811 | { |
1748 | { | 1812 | return (mUseBoundingRect && type == HIT_TEST_USE_BOUNDING_RECT) |
1813 | ? mBoundingRect.pointInRect( x, y ) | ||
1814 | : mRect.pointInRect( x, y ); | ||
1749 | } | 1815 | } |
1750 | 1816 | ||
1751 | // virtual | 1817 | BOOL LLView::pointInView(S32 x, S32 y, EHitTestType type) const |
1752 | void LLView::onFocusReceived() | 1818 | { |
1819 | return (mUseBoundingRect && type == HIT_TEST_USE_BOUNDING_RECT) | ||
1820 | ? mBoundingRect.pointInRect( x + mRect.mLeft, y + mRect.mBottom ) | ||
1821 | : mRect.localPointInRect( x, y ); | ||
1822 | } | ||
1823 | |||
1824 | BOOL LLView::blockMouseEvent(S32 x, S32 y) const | ||
1753 | { | 1825 | { |
1826 | return mMouseOpaque && pointInView(x, y, HIT_TEST_IGNORE_BOUNDING_RECT); | ||
1754 | } | 1827 | } |
1755 | 1828 | ||
1756 | // virtual | 1829 | // virtual |
@@ -2024,9 +2097,9 @@ LLXMLNodePtr LLView::getXML(bool save_children) const | |||
2024 | // Export all widgets as enabled and visible - code must disable. | 2097 | // Export all widgets as enabled and visible - code must disable. |
2025 | node->createChild("hidden", TRUE)->setBoolValue(mHidden); | 2098 | node->createChild("hidden", TRUE)->setBoolValue(mHidden); |
2026 | node->createChild("mouse_opaque", TRUE)->setBoolValue(mMouseOpaque ); | 2099 | node->createChild("mouse_opaque", TRUE)->setBoolValue(mMouseOpaque ); |
2027 | if (!mToolTipMsg.empty()) | 2100 | if (!mToolTipMsg.getString().empty()) |
2028 | { | 2101 | { |
2029 | node->createChild("tool_tip", TRUE)->setStringValue(mToolTipMsg); | 2102 | node->createChild("tool_tip", TRUE)->setStringValue(mToolTipMsg.getString()); |
2030 | } | 2103 | } |
2031 | if (mSoundFlags != MOUSE_UP) | 2104 | if (mSoundFlags != MOUSE_UP) |
2032 | { | 2105 | { |
@@ -2116,7 +2189,7 @@ const LLCtrlQuery & LLView::getTabOrderQuery() | |||
2116 | query.addPreFilter(LLVisibleFilter::getInstance()); | 2189 | query.addPreFilter(LLVisibleFilter::getInstance()); |
2117 | query.addPreFilter(LLEnabledFilter::getInstance()); | 2190 | query.addPreFilter(LLEnabledFilter::getInstance()); |
2118 | query.addPreFilter(LLTabStopFilter::getInstance()); | 2191 | query.addPreFilter(LLTabStopFilter::getInstance()); |
2119 | query.addPostFilter(LLUICtrl::LLTabStopPostFilter::getInstance()); | 2192 | query.addPostFilter(LLLeavesFilter::getInstance()); |
2120 | } | 2193 | } |
2121 | return query; | 2194 | return query; |
2122 | } | 2195 | } |
@@ -2129,6 +2202,7 @@ const LLCtrlQuery & LLView::getFocusRootsQuery() | |||
2129 | query.addPreFilter(LLVisibleFilter::getInstance()); | 2202 | query.addPreFilter(LLVisibleFilter::getInstance()); |
2130 | query.addPreFilter(LLEnabledFilter::getInstance()); | 2203 | query.addPreFilter(LLEnabledFilter::getInstance()); |
2131 | query.addPreFilter(LLView::LLFocusRootsFilter::getInstance()); | 2204 | query.addPreFilter(LLView::LLFocusRootsFilter::getInstance()); |
2205 | query.addPostFilter(LLRootsFilter::getInstance()); | ||
2132 | } | 2206 | } |
2133 | return query; | 2207 | return query; |
2134 | } | 2208 | } |
@@ -2593,10 +2667,10 @@ const S32 VPAD = 4; | |||
2593 | U32 LLView::createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect) | 2667 | U32 LLView::createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect) |
2594 | { | 2668 | { |
2595 | U32 follows = 0; | 2669 | U32 follows = 0; |
2596 | S32 x = FLOATER_H_MARGIN; | 2670 | S32 x = rect.mLeft; |
2597 | S32 y = 0; | 2671 | S32 y = rect.mBottom; |
2598 | S32 w = 0; | 2672 | S32 w = rect.getWidth(); |
2599 | S32 h = 0; | 2673 | S32 h = rect.getHeight(); |
2600 | 2674 | ||
2601 | U32 last_x = 0; | 2675 | U32 last_x = 0; |
2602 | U32 last_y = 0; | 2676 | U32 last_y = 0; |
@@ -2639,8 +2713,15 @@ U32 LLView::createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, con | |||
2639 | // view if you don't specify a width. | 2713 | // view if you don't specify a width. |
2640 | if (parent_view) | 2714 | if (parent_view) |
2641 | { | 2715 | { |
2642 | w = llmax(required_rect.getWidth(), parent_view->getRect().getWidth() - (FLOATER_H_MARGIN) - x); | 2716 | if(w == 0) |
2643 | h = llmax(MIN_WIDGET_HEIGHT, required_rect.getHeight()); | 2717 | { |
2718 | w = llmax(required_rect.getWidth(), parent_view->getRect().getWidth() - (FLOATER_H_MARGIN) - x); | ||
2719 | } | ||
2720 | |||
2721 | if(h == 0) | ||
2722 | { | ||
2723 | h = llmax(MIN_WIDGET_HEIGHT, required_rect.getHeight()); | ||
2724 | } | ||
2644 | } | 2725 | } |
2645 | 2726 | ||
2646 | if (node->hasAttribute("width")) | 2727 | if (node->hasAttribute("width")) |
@@ -2765,44 +2846,7 @@ void LLView::initFromXML(LLXMLNodePtr node, LLView* parent) | |||
2765 | setRect(view_rect); | 2846 | setRect(view_rect); |
2766 | setFollows(follows_flags); | 2847 | setFollows(follows_flags); |
2767 | 2848 | ||
2768 | if (node->hasAttribute("follows")) | 2849 | parseFollowsFlags(node); |
2769 | { | ||
2770 | setFollowsNone(); | ||
2771 | |||
2772 | LLString follows; | ||
2773 | node->getAttributeString("follows", follows); | ||
2774 | |||
2775 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | ||
2776 | boost::char_separator<char> sep("|"); | ||
2777 | tokenizer tokens(follows, sep); | ||
2778 | tokenizer::iterator token_iter = tokens.begin(); | ||
2779 | |||
2780 | while(token_iter != tokens.end()) | ||
2781 | { | ||
2782 | const std::string& token_str = *token_iter; | ||
2783 | if (token_str == "left") | ||
2784 | { | ||
2785 | setFollowsLeft(); | ||
2786 | } | ||
2787 | else if (token_str == "right") | ||
2788 | { | ||
2789 | setFollowsRight(); | ||
2790 | } | ||
2791 | else if (token_str == "top") | ||
2792 | { | ||
2793 | setFollowsTop(); | ||
2794 | } | ||
2795 | else if (token_str == "bottom") | ||
2796 | { | ||
2797 | setFollowsBottom(); | ||
2798 | } | ||
2799 | else if (token_str == "all") | ||
2800 | { | ||
2801 | setFollowsAll(); | ||
2802 | } | ||
2803 | ++token_iter; | ||
2804 | } | ||
2805 | } | ||
2806 | 2850 | ||
2807 | if (node->hasAttribute("control_name")) | 2851 | if (node->hasAttribute("control_name")) |
2808 | { | 2852 | { |
@@ -2839,11 +2883,57 @@ void LLView::initFromXML(LLXMLNodePtr node, LLView* parent) | |||
2839 | setHidden(hidden); | 2883 | setHidden(hidden); |
2840 | } | 2884 | } |
2841 | 2885 | ||
2886 | node->getAttributeBOOL("use_bounding_rect", mUseBoundingRect); | ||
2887 | node->getAttributeBOOL("mouse_opaque", mMouseOpaque); | ||
2888 | |||
2842 | node->getAttributeS32("default_tab_group", mDefaultTabGroup); | 2889 | node->getAttributeS32("default_tab_group", mDefaultTabGroup); |
2843 | 2890 | ||
2844 | reshape(view_rect.getWidth(), view_rect.getHeight()); | 2891 | reshape(view_rect.getWidth(), view_rect.getHeight()); |
2845 | } | 2892 | } |
2846 | 2893 | ||
2894 | void LLView::parseFollowsFlags(LLXMLNodePtr node) | ||
2895 | { | ||
2896 | if (node->hasAttribute("follows")) | ||
2897 | { | ||
2898 | setFollowsNone(); | ||
2899 | |||
2900 | LLString follows; | ||
2901 | node->getAttributeString("follows", follows); | ||
2902 | |||
2903 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | ||
2904 | boost::char_separator<char> sep("|"); | ||
2905 | tokenizer tokens(follows, sep); | ||
2906 | tokenizer::iterator token_iter = tokens.begin(); | ||
2907 | |||
2908 | while(token_iter != tokens.end()) | ||
2909 | { | ||
2910 | const std::string& token_str = *token_iter; | ||
2911 | if (token_str == "left") | ||
2912 | { | ||
2913 | setFollowsLeft(); | ||
2914 | } | ||
2915 | else if (token_str == "right") | ||
2916 | { | ||
2917 | setFollowsRight(); | ||
2918 | } | ||
2919 | else if (token_str == "top") | ||
2920 | { | ||
2921 | setFollowsTop(); | ||
2922 | } | ||
2923 | else if (token_str == "bottom") | ||
2924 | { | ||
2925 | setFollowsBottom(); | ||
2926 | } | ||
2927 | else if (token_str == "all") | ||
2928 | { | ||
2929 | setFollowsAll(); | ||
2930 | } | ||
2931 | ++token_iter; | ||
2932 | } | ||
2933 | } | ||
2934 | } | ||
2935 | |||
2936 | |||
2847 | // static | 2937 | // static |
2848 | LLFontGL* LLView::selectFont(LLXMLNodePtr node) | 2938 | LLFontGL* LLView::selectFont(LLXMLNodePtr node) |
2849 | { | 2939 | { |
diff --git a/linden/indra/llui/llview.h b/linden/indra/llui/llview.h index bd99a13..67a4d56 100644 --- a/linden/indra/llui/llview.h +++ b/linden/indra/llui/llview.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -50,6 +50,7 @@ | |||
50 | #include "llviewquery.h" | 50 | #include "llviewquery.h" |
51 | #include "llxmlnode.h" | 51 | #include "llxmlnode.h" |
52 | #include "stdenums.h" | 52 | #include "stdenums.h" |
53 | #include "lluistring.h" | ||
53 | 54 | ||
54 | class LLColor4; | 55 | class LLColor4; |
55 | class LLWindow; | 56 | class LLWindow; |
@@ -146,6 +147,7 @@ protected: | |||
146 | LLString mName; | 147 | LLString mName; |
147 | // location in pixels, relative to surrounding structure, bottom,left=0,0 | 148 | // location in pixels, relative to surrounding structure, bottom,left=0,0 |
148 | LLRect mRect; | 149 | LLRect mRect; |
150 | LLRect mBoundingRect; | ||
149 | 151 | ||
150 | U32 mReshapeFlags; | 152 | U32 mReshapeFlags; |
151 | 153 | ||
@@ -161,11 +163,11 @@ protected: | |||
161 | BOOL mSaveToXML; | 163 | BOOL mSaveToXML; |
162 | 164 | ||
163 | BOOL mIsFocusRoot; | 165 | BOOL mIsFocusRoot; |
166 | BOOL mUseBoundingRect; // hit test against bounding rectangle that includes all child elements | ||
164 | 167 | ||
165 | public: | 168 | public: |
166 | LLViewHandle mViewHandle; | 169 | LLViewHandle mViewHandle; |
167 | BOOL mLastVisible; | 170 | BOOL mLastVisible; |
168 | BOOL mSpanChildren; | ||
169 | 171 | ||
170 | private: | 172 | private: |
171 | BOOL mVisible; | 173 | BOOL mVisible; |
@@ -217,6 +219,7 @@ public: | |||
217 | void setMouseOpaque( BOOL b ); | 219 | void setMouseOpaque( BOOL b ); |
218 | void setToolTip( const LLStringExplicit& msg ); | 220 | void setToolTip( const LLStringExplicit& msg ); |
219 | BOOL setToolTipArg( const LLStringExplicit& key, const LLStringExplicit& text ); | 221 | BOOL setToolTipArg( const LLStringExplicit& key, const LLStringExplicit& text ); |
222 | void setToolTipArgs( const LLString::format_map_t& args ); | ||
220 | 223 | ||
221 | virtual void setRect(const LLRect &rect); | 224 | virtual void setRect(const LLRect &rect); |
222 | void setFollows(U32 flags); | 225 | void setFollows(U32 flags); |
@@ -231,13 +234,15 @@ public: | |||
231 | 234 | ||
232 | void setSoundFlags(U8 flags); | 235 | void setSoundFlags(U8 flags); |
233 | void setName(LLString name); | 236 | void setName(LLString name); |
234 | void setSpanChildren( BOOL span_children ); | 237 | void setUseBoundingRect( BOOL use_bounding_rect ); |
238 | BOOL getUseBoundingRect(); | ||
235 | 239 | ||
236 | const LLString& getToolTip(); | 240 | const LLString& getToolTip(); |
237 | 241 | ||
238 | void sendChildToFront(LLView* child); | 242 | void sendChildToFront(LLView* child); |
239 | void sendChildToBack(LLView* child); | 243 | void sendChildToBack(LLView* child); |
240 | void moveChildToFrontOfTabGroup(LLUICtrl* child); | 244 | void moveChildToFrontOfTabGroup(LLUICtrl* child); |
245 | void moveChildToBackOfTabGroup(LLUICtrl* child); | ||
241 | 246 | ||
242 | void addChild(LLView* view, S32 tab_group = 0); | 247 | void addChild(LLView* view, S32 tab_group = 0); |
243 | void addChildAtEnd(LLView* view, S32 tab_group = 0); | 248 | void addChildAtEnd(LLView* view, S32 tab_group = 0); |
@@ -264,7 +269,7 @@ public: | |||
264 | { | 269 | { |
265 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const | 270 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const |
266 | { | 271 | { |
267 | return filterResult_t(view->isCtrl() && view->isFocusRoot(), !view->isFocusRoot()); | 272 | return filterResult_t(view->isCtrl() && view->isFocusRoot(), TRUE); |
268 | } | 273 | } |
269 | }; | 274 | }; |
270 | 275 | ||
@@ -312,20 +317,22 @@ public: | |||
312 | BOOL followsAll() const { return mReshapeFlags & FOLLOWS_ALL; } | 317 | BOOL followsAll() const { return mReshapeFlags & FOLLOWS_ALL; } |
313 | 318 | ||
314 | const LLRect& getRect() const { return mRect; } | 319 | const LLRect& getRect() const { return mRect; } |
320 | const LLRect& getBoundingRect() const { return mBoundingRect; } | ||
321 | const LLRect getLocalBoundingRect() const; | ||
315 | const LLRect getScreenRect() const; | 322 | const LLRect getScreenRect() const; |
316 | const LLRect getLocalRect() const; | 323 | const LLRect getLocalRect() const; |
317 | virtual const LLRect getSnapRect() const { return mRect; } | 324 | virtual const LLRect getSnapRect() const { return mRect; } |
318 | virtual const LLRect getLocalSnapRect() const; | 325 | virtual const LLRect getLocalSnapRect() const; |
319 | 326 | ||
320 | virtual LLRect getRequiredRect(); // Get required size for this object. 0 for width/height means don't care. | 327 | virtual LLRect getRequiredRect(); // Get required size for this object. 0 for width/height means don't care. |
321 | virtual void updateRect(); // apply procedural updates to own rectangle | 328 | void updateBoundingRect(); |
322 | 329 | ||
323 | LLView* getRootView(); | 330 | LLView* getRootView(); |
324 | LLView* getParent() const { return mParentView; } | 331 | LLView* getParent() const { return mParentView; } |
325 | LLView* getFirstChild() { return (mChildList.empty()) ? NULL : *(mChildList.begin()); } | 332 | LLView* getFirstChild() { return (mChildList.empty()) ? NULL : *(mChildList.begin()); } |
326 | S32 getChildCount() const { return (S32)mChildList.size(); } | 333 | S32 getChildCount() const { return (S32)mChildList.size(); } |
327 | template<class _Pr3> void sortChildren(_Pr3 _Pred) { mChildList.sort(_Pred); } | 334 | template<class _Pr3> void sortChildren(_Pr3 _Pred) { mChildList.sort(_Pred); } |
328 | BOOL hasAncestor(LLView* parentp); | 335 | BOOL hasAncestor(const LLView* parentp); |
329 | 336 | ||
330 | BOOL hasChild(const LLString& childname, BOOL recurse = FALSE) const; | 337 | BOOL hasChild(const LLString& childname, BOOL recurse = FALSE) const; |
331 | 338 | ||
@@ -390,6 +397,7 @@ public: | |||
390 | 397 | ||
391 | static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect()); | 398 | static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect()); |
392 | virtual void initFromXML(LLXMLNodePtr node, LLView* parent); | 399 | virtual void initFromXML(LLXMLNodePtr node, LLView* parent); |
400 | void parseFollowsFlags(LLXMLNodePtr node); | ||
393 | 401 | ||
394 | static LLFontGL* selectFont(LLXMLNodePtr node); | 402 | static LLFontGL* selectFont(LLXMLNodePtr node); |
395 | static LLFontGL::HAlign selectFontHAlign(LLXMLNodePtr node); | 403 | static LLFontGL::HAlign selectFontHAlign(LLXMLNodePtr node); |
@@ -428,12 +436,16 @@ public: | |||
428 | BOOL getVisible() const { return mVisible && !mHidden; } | 436 | BOOL getVisible() const { return mVisible && !mHidden; } |
429 | U8 getSoundFlags() const { return mSoundFlags; } | 437 | U8 getSoundFlags() const { return mSoundFlags; } |
430 | 438 | ||
431 | // Default to no action | 439 | typedef enum e_hit_test_type |
432 | virtual void onFocusLost(); | 440 | { |
433 | virtual void onFocusReceived(); | 441 | HIT_TEST_USE_BOUNDING_RECT, |
442 | HIT_TEST_IGNORE_BOUNDING_RECT | ||
443 | }EHitTestType; | ||
444 | |||
445 | BOOL parentPointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const; | ||
446 | BOOL pointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const; | ||
447 | BOOL blockMouseEvent(S32 x, S32 y) const; | ||
434 | 448 | ||
435 | BOOL parentPointInView(S32 x, S32 y) const { return mRect.pointInRect( x, y ); } | ||
436 | BOOL pointInView(S32 x, S32 y) const { return mRect.localPointInRect( x, y ); } | ||
437 | virtual void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const; | 449 | virtual void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const; |
438 | virtual void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const; | 450 | virtual void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const; |
439 | virtual BOOL localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view); | 451 | virtual BOOL localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view); |
diff --git a/linden/indra/llui/llviewborder.cpp b/linden/indra/llui/llviewborder.cpp index f2ff8a3..b70edec 100644 --- a/linden/indra/llui/llviewborder.cpp +++ b/linden/indra/llui/llviewborder.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -84,7 +84,7 @@ void LLViewBorder::setColorsExtended( const LLColor4& shadow_light, const LLColo | |||
84 | 84 | ||
85 | void LLViewBorder::setTexture( const LLUUID &image_id ) | 85 | void LLViewBorder::setTexture( const LLUUID &image_id ) |
86 | { | 86 | { |
87 | mTexture = LLUI::sImageProvider->getUIImageByID(image_id); | 87 | mTexture = LLUI::sImageProvider->getImageByID(image_id); |
88 | } | 88 | } |
89 | 89 | ||
90 | 90 | ||
diff --git a/linden/indra/llui/llviewborder.h b/linden/indra/llui/llviewborder.h index 935257c..d9c2916 100644 --- a/linden/indra/llui/llviewborder.h +++ b/linden/indra/llui/llviewborder.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llui/llviewquery.cpp b/linden/indra/llui/llviewquery.cpp index f86f855..40c2d61 100644 --- a/linden/indra/llui/llviewquery.cpp +++ b/linden/indra/llui/llviewquery.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -37,9 +37,14 @@ | |||
37 | 37 | ||
38 | void LLQuerySorter::operator() (LLView * parent, viewList_t &children) const {} | 38 | void LLQuerySorter::operator() (LLView * parent, viewList_t &children) const {} |
39 | 39 | ||
40 | filterResult_t LLNoLeavesFilter::operator() (const LLView* const view, const viewList_t & children) const | 40 | filterResult_t LLLeavesFilter::operator() (const LLView* const view, const viewList_t & children) const |
41 | { | 41 | { |
42 | return filterResult_t(!(view->getChildList()->size() == 0), TRUE); | 42 | return filterResult_t(children.empty(), TRUE); |
43 | } | ||
44 | |||
45 | filterResult_t LLRootsFilter::operator() (const LLView* const view, const viewList_t & children) const | ||
46 | { | ||
47 | return filterResult_t(TRUE, FALSE); | ||
43 | } | 48 | } |
44 | 49 | ||
45 | filterResult_t LLVisibleFilter::operator() (const LLView* const view, const viewList_t & children) const | 50 | filterResult_t LLVisibleFilter::operator() (const LLView* const view, const viewList_t & children) const |
@@ -56,6 +61,16 @@ filterResult_t LLTabStopFilter::operator() (const LLView* const view, const view | |||
56 | view->canFocusChildren()); | 61 | view->canFocusChildren()); |
57 | } | 62 | } |
58 | 63 | ||
64 | filterResult_t LLCtrlFilter::operator() (const LLView* const view, const viewList_t & children) const | ||
65 | { | ||
66 | return filterResult_t(view->isCtrl(),TRUE); | ||
67 | } | ||
68 | |||
69 | filterResult_t LLWidgetTypeFilter::operator() (const LLView* const view, const viewList_t & children) const | ||
70 | { | ||
71 | return filterResult_t(view->getWidgetType() == mType, TRUE); | ||
72 | } | ||
73 | |||
59 | // LLViewQuery | 74 | // LLViewQuery |
60 | 75 | ||
61 | LLViewQuery::LLViewQuery(): mPreFilters(), mPostFilters(), mSorterp() | 76 | LLViewQuery::LLViewQuery(): mPreFilters(), mPostFilters(), mSorterp() |
@@ -73,45 +88,53 @@ const LLViewQuery::filterList_t & LLViewQuery::getPostFilters() const { return m | |||
73 | void LLViewQuery::setSorter(const LLQuerySorter* sorterp) { mSorterp = sorterp; } | 88 | void LLViewQuery::setSorter(const LLQuerySorter* sorterp) { mSorterp = sorterp; } |
74 | const LLQuerySorter* LLViewQuery::getSorter() const { return mSorterp; } | 89 | const LLQuerySorter* LLViewQuery::getSorter() const { return mSorterp; } |
75 | 90 | ||
76 | viewList_t LLViewQuery::run(LLView * view) const | 91 | viewList_t LLViewQuery::run(LLView* view) const |
77 | { | 92 | { |
78 | viewList_t result; | 93 | viewList_t result; |
79 | 94 | ||
80 | filterResult_t pre = runFilters(view, viewList_t(), mPreFilters); | 95 | // prefilter gets immediate children of view |
96 | filterResult_t pre = runFilters(view, *view->getChildList(), mPreFilters); | ||
81 | if(!pre.first && !pre.second) | 97 | if(!pre.first && !pre.second) |
82 | { | 98 | { |
83 | // skip post filters completely if we're not including ourselves or the children | 99 | // not including ourselves or the children |
100 | // nothing more to do | ||
84 | return result; | 101 | return result; |
85 | } | 102 | } |
103 | |||
104 | viewList_t filtered_children; | ||
105 | filterResult_t post(TRUE, TRUE); | ||
86 | if(pre.second) | 106 | if(pre.second) |
87 | { | 107 | { |
88 | // run filters on children | 108 | // run filters on children |
89 | viewList_t filtered_children; | ||
90 | filterChildren(view, filtered_children); | 109 | filterChildren(view, filtered_children); |
91 | filterResult_t post = runFilters(view, filtered_children, mPostFilters); | 110 | // only run post filters if this element passed pre filters |
92 | if(pre.first && post.first) | 111 | // so if you failed to pass the pre filter, you can't filter out children in post |
93 | { | 112 | if (pre.first) |
94 | result.push_back(view); | ||
95 | } | ||
96 | if(post.second) | ||
97 | { | 113 | { |
98 | result.insert(result.end(), filtered_children.begin(), filtered_children.end()); | 114 | post = runFilters(view, filtered_children, mPostFilters); |
99 | } | 115 | } |
100 | } | 116 | } |
101 | else | 117 | |
118 | if(pre.first && post.first) | ||
102 | { | 119 | { |
103 | if(pre.first) | 120 | result.push_back(view); |
104 | { | 121 | } |
105 | result.push_back(view); | 122 | |
106 | } | 123 | if(pre.second && post.second) |
124 | { | ||
125 | result.insert(result.end(), filtered_children.begin(), filtered_children.end()); | ||
107 | } | 126 | } |
127 | |||
108 | return result; | 128 | return result; |
109 | } | 129 | } |
110 | 130 | ||
111 | void LLViewQuery::filterChildren(LLView * view, viewList_t & filtered_children) const | 131 | void LLViewQuery::filterChildren(LLView * view, viewList_t & filtered_children) const |
112 | { | 132 | { |
113 | LLView::child_list_t views(*(view->getChildList())); | 133 | LLView::child_list_t views(*(view->getChildList())); |
114 | (*mSorterp)(view, views); // sort the children per the sorter | 134 | if (mSorterp) |
135 | { | ||
136 | (*mSorterp)(view, views); // sort the children per the sorter | ||
137 | } | ||
115 | for(LLView::child_list_iter_t iter = views.begin(); | 138 | for(LLView::child_list_iter_t iter = views.begin(); |
116 | iter != views.end(); | 139 | iter != views.end(); |
117 | iter++) | 140 | iter++) |
diff --git a/linden/indra/llui/llviewquery.h b/linden/indra/llui/llviewquery.h index 9fe51a4..2e2b50d 100644 --- a/linden/indra/llui/llviewquery.h +++ b/linden/indra/llui/llviewquery.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -35,6 +35,7 @@ | |||
35 | #include <list> | 35 | #include <list> |
36 | 36 | ||
37 | #include "llmemory.h" | 37 | #include "llmemory.h" |
38 | #include "llui.h" | ||
38 | 39 | ||
39 | class LLView; | 40 | class LLView; |
40 | 41 | ||
@@ -42,35 +43,60 @@ typedef std::list<LLView *> viewList_t; | |||
42 | typedef std::pair<BOOL, BOOL> filterResult_t; | 43 | typedef std::pair<BOOL, BOOL> filterResult_t; |
43 | 44 | ||
44 | // Abstract base class for all filters. | 45 | // Abstract base class for all filters. |
45 | class LLQueryFilter : public LLRefCount | 46 | class LLQueryFilter |
46 | { | 47 | { |
47 | public: | 48 | public: |
49 | virtual ~LLQueryFilter() {}; | ||
48 | virtual filterResult_t operator() (const LLView* const view, const viewList_t & children) const =0; | 50 | virtual filterResult_t operator() (const LLView* const view, const viewList_t & children) const =0; |
49 | }; | 51 | }; |
50 | 52 | ||
51 | class LLQuerySorter : public LLRefCount | 53 | class LLQuerySorter |
52 | { | 54 | { |
53 | public: | 55 | public: |
56 | virtual ~LLQuerySorter() {}; | ||
54 | virtual void operator() (LLView * parent, viewList_t &children) const; | 57 | virtual void operator() (LLView * parent, viewList_t &children) const; |
55 | }; | 58 | }; |
56 | 59 | ||
57 | class LLNoLeavesFilter : public LLQueryFilter, public LLSingleton<LLNoLeavesFilter> | 60 | class LLLeavesFilter : public LLQueryFilter, public LLSingleton<LLLeavesFilter> |
58 | { | 61 | { |
59 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; | 62 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; |
60 | }; | 63 | }; |
64 | |||
65 | class LLRootsFilter : public LLQueryFilter, public LLSingleton<LLRootsFilter> | ||
66 | { | ||
67 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; | ||
68 | }; | ||
69 | |||
61 | class LLVisibleFilter : public LLQueryFilter, public LLSingleton<LLVisibleFilter> | 70 | class LLVisibleFilter : public LLQueryFilter, public LLSingleton<LLVisibleFilter> |
62 | { | 71 | { |
63 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; | 72 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; |
64 | }; | 73 | }; |
74 | |||
65 | class LLEnabledFilter : public LLQueryFilter, public LLSingleton<LLEnabledFilter> | 75 | class LLEnabledFilter : public LLQueryFilter, public LLSingleton<LLEnabledFilter> |
66 | { | 76 | { |
67 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; | 77 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; |
68 | }; | 78 | }; |
79 | |||
69 | class LLTabStopFilter : public LLQueryFilter, public LLSingleton<LLTabStopFilter> | 80 | class LLTabStopFilter : public LLQueryFilter, public LLSingleton<LLTabStopFilter> |
70 | { | 81 | { |
71 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; | 82 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; |
72 | }; | 83 | }; |
73 | 84 | ||
85 | class LLCtrlFilter : public LLQueryFilter, public LLSingleton<LLCtrlFilter> | ||
86 | { | ||
87 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; | ||
88 | }; | ||
89 | |||
90 | class LLWidgetTypeFilter : public LLQueryFilter | ||
91 | { | ||
92 | public: | ||
93 | LLWidgetTypeFilter(EWidgetType type) : mType(type) {}; | ||
94 | private: | ||
95 | /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; | ||
96 | |||
97 | EWidgetType mType; | ||
98 | }; | ||
99 | |||
74 | // Algorithm for flattening | 100 | // Algorithm for flattening |
75 | class LLViewQuery | 101 | class LLViewQuery |
76 | { | 102 | { |