aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui/lllineeditor.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:42 -0500
committerJacek Antonelli2008-08-15 23:45:42 -0500
commitce28e056c20bf2723f565bbf464b87781ec248a2 (patch)
treeef7b0501c4de4b631a916305cbc2a5fdc125e52d /linden/indra/llui/lllineeditor.cpp
parentSecond Life viewer sources 1.19.1.4b (diff)
downloadmeta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.zip
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.gz
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.bz2
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.xz
Second Life viewer sources 1.20.2
Diffstat (limited to 'linden/indra/llui/lllineeditor.cpp')
-rw-r--r--linden/indra/llui/lllineeditor.cpp216
1 files changed, 145 insertions, 71 deletions
diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp
index 1c96bc4..aeb906c 100644
--- a/linden/indra/llui/lllineeditor.cpp
+++ b/linden/indra/llui/lllineeditor.cpp
@@ -70,7 +70,6 @@ const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds
70const S32 SCROLL_INCREMENT_ADD = 0; // make space for typing 70const S32 SCROLL_INCREMENT_ADD = 0; // make space for typing
71const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing 71const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing
72const F32 AUTO_SCROLL_TIME = 0.05f; 72const F32 AUTO_SCROLL_TIME = 0.05f;
73const F32 LABEL_HPAD = 5.f;
74 73
75const F32 PREEDIT_MARKER_BRIGHTNESS = 0.4f; 74const F32 PREEDIT_MARKER_BRIGHTNESS = 0.4f;
76const S32 PREEDIT_MARKER_GAP = 1; 75const S32 PREEDIT_MARKER_GAP = 1;
@@ -81,6 +80,10 @@ const S32 PREEDIT_STANDOUT_GAP = 1;
81const S32 PREEDIT_STANDOUT_POSITION = 2; 80const S32 PREEDIT_STANDOUT_POSITION = 2;
82const S32 PREEDIT_STANDOUT_THICKNESS = 2; 81const S32 PREEDIT_STANDOUT_THICKNESS = 2;
83 82
83static LLRegisterWidget<LLLineEditor> r1("line_editor");
84
85/* static */ LLPointer<LLUIImage> LLLineEditor::sImage;
86
84// 87//
85// Member functions 88// Member functions
86// 89//
@@ -101,8 +104,8 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect,
101 mMaxLengthBytes(max_length_bytes), 104 mMaxLengthBytes(max_length_bytes),
102 mCursorPos( 0 ), 105 mCursorPos( 0 ),
103 mScrollHPos( 0 ), 106 mScrollHPos( 0 ),
104 mBorderLeft(0), 107 mTextPadLeft(0),
105 mBorderRight(0), 108 mTextPadRight(0),
106 mCommitOnFocusLost( TRUE ), 109 mCommitOnFocusLost( TRUE ),
107 mRevertOnEsc( TRUE ), 110 mRevertOnEsc( TRUE ),
108 mKeystrokeCallback( keystroke_callback ), 111 mKeystrokeCallback( keystroke_callback ),
@@ -128,7 +131,8 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect,
128 mHandleEditKeysDirectly( FALSE ), 131 mHandleEditKeysDirectly( FALSE ),
129 mSelectAllonFocusReceived( FALSE ), 132 mSelectAllonFocusReceived( FALSE ),
130 mPassDelete(FALSE), 133 mPassDelete(FALSE),
131 mReadOnly(FALSE) 134 mReadOnly(FALSE),
135 mImage( sImage )
132{ 136{
133 llassert( max_length_bytes > 0 ); 137 llassert( max_length_bytes > 0 );
134 138
@@ -151,8 +155,7 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect,
151 155
152 setFocusLostCallback(focus_lost_callback); 156 setFocusLostCallback(focus_lost_callback);
153 157
154 mMinHPixels = mBorderThickness + UI_LINEEDITOR_H_PAD + mBorderLeft; 158 setTextPadding(0, 0);
155 mMaxHPixels = getRect().getWidth() - mMinHPixels - mBorderThickness - mBorderRight;
156 159
157 mScrollTimer.reset(); 160 mScrollTimer.reset();
158 161
@@ -166,6 +169,12 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect,
166 mBorder = new LLViewBorder( "line ed border", border_rect, border_bevel, border_style, mBorderThickness ); 169 mBorder = new LLViewBorder( "line ed border", border_rect, border_bevel, border_style, mBorderThickness );
167 addChild( mBorder ); 170 addChild( mBorder );
168 mBorder->setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP|FOLLOWS_BOTTOM); 171 mBorder->setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP|FOLLOWS_BOTTOM);
172
173 if( ! sImage)
174 {
175 sImage = LLUI::getUIImage("sm_rounded_corners_simple.tga");
176 }
177 mImage = sImage;
169} 178}
170 179
171 180
@@ -243,9 +252,9 @@ void LLLineEditor::updateHistory()
243 252
244void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent) 253void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
245{ 254{
246 LLUICtrl::reshape(width, height, called_from_parent ); 255 LLUICtrl::reshape(width, height, called_from_parent);
247 256 setTextPadding(mTextPadLeft, mTextPadRight); // For clamping side-effect.
248 mMaxHPixels = getRect().getWidth() - 2 * (mBorderThickness + UI_LINEEDITOR_H_PAD) + 1 - mBorderRight; 257 setCursor(mCursorPos); // For clamping side-effect.
249} 258}
250 259
251void LLLineEditor::setEnabled(BOOL enabled) 260void LLLineEditor::setEnabled(BOOL enabled)
@@ -262,12 +271,12 @@ void LLLineEditor::setMaxTextLength(S32 max_text_length)
262 mMaxLengthBytes = max_len; 271 mMaxLengthBytes = max_len;
263} 272}
264 273
265void LLLineEditor::setBorderWidth(S32 left, S32 right) 274void LLLineEditor::setTextPadding(S32 left, S32 right)
266{ 275{
267 mBorderLeft = llclamp(left, 0, getRect().getWidth()); 276 mTextPadLeft = llclamp(left, 0, getRect().getWidth());
268 mBorderRight = llclamp(right, 0, getRect().getWidth()); 277 mTextPadRight = llclamp(right, 0, getRect().getWidth());
269 mMinHPixels = mBorderThickness + UI_LINEEDITOR_H_PAD + mBorderLeft; 278 mMinHPixels = UI_LINEEDITOR_H_PAD + mTextPadLeft;
270 mMaxHPixels = getRect().getWidth() - mMinHPixels - mBorderThickness - mBorderRight; 279 mMaxHPixels = getRect().getWidth() - mMinHPixels - mTextPadRight;
271} 280}
272 281
273 282
@@ -483,9 +492,10 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
483 492
484BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask) 493BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
485{ 494{
486 if (x < mBorderLeft || x > (getRect().getWidth() - mBorderRight)) 495 // Check first whether the "clear search" button wants to deal with this.
496 if(childrenHandleMouseDown(x, y, mask) != NULL)
487 { 497 {
488 return LLUICtrl::handleMouseDown(x, y, mask); 498 return TRUE;
489 } 499 }
490 if (mSelectAllonFocusReceived 500 if (mSelectAllonFocusReceived
491 && gFocusMgr.getKeyboardFocus() != this) 501 && gFocusMgr.getKeyboardFocus() != this)
@@ -563,61 +573,62 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
563BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask) 573BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask)
564{ 574{
565 BOOL handled = FALSE; 575 BOOL handled = FALSE;
566 if (!hasMouseCapture() && (x < mBorderLeft || x > (getRect().getWidth() - mBorderRight))) 576 // Check first whether the "clear search" button wants to deal with this.
577 if(!hasMouseCapture())
567 { 578 {
568 return LLUICtrl::handleHover(x, y, mask); 579 if(childrenHandleHover(x, y, mask) != NULL)
580 {
581 return TRUE;
582 }
569 } 583 }
570 584
571 if( getVisible() ) 585 if( (hasMouseCapture()) && mIsSelecting )
572 { 586 {
573 if( (hasMouseCapture()) && mIsSelecting ) 587 if (x != mLastSelectionX || y != mLastSelectionY)
574 { 588 {
575 if (x != mLastSelectionX || y != mLastSelectionY) 589 mLastSelectionX = x;
590 mLastSelectionY = y;
591 }
592 // Scroll if mouse cursor outside of bounds
593 if (mScrollTimer.hasExpired())
594 {
595 S32 increment = llround(mScrollTimer.getElapsedTimeF32() / AUTO_SCROLL_TIME);
596 mScrollTimer.reset();
597 mScrollTimer.setTimerExpirySec(AUTO_SCROLL_TIME);
598 if( (x < mMinHPixels) && (mScrollHPos > 0 ) )
576 { 599 {
577 mLastSelectionX = x; 600 // Scroll to the left
578 mLastSelectionY = y; 601 mScrollHPos = llclamp(mScrollHPos - increment, 0, mText.length());
579 } 602 }
580 // Scroll if mouse cursor outside of bounds 603 else
581 if (mScrollTimer.hasExpired()) 604 if( (x > mMaxHPixels) && (mCursorPos < (S32)mText.length()) )
582 { 605 {
583 S32 increment = llround(mScrollTimer.getElapsedTimeF32() / AUTO_SCROLL_TIME); 606 // If scrolling one pixel would make a difference...
584 mScrollTimer.reset(); 607 S32 pixels_after_scrolling_one_char = findPixelNearestPos(1);
585 mScrollTimer.setTimerExpirySec(AUTO_SCROLL_TIME); 608 if( pixels_after_scrolling_one_char >= mMaxHPixels )
586 if( (x < mMinHPixels) && (mScrollHPos > 0 ) )
587 {
588 // Scroll to the left
589 mScrollHPos = llclamp(mScrollHPos - increment, 0, mText.length());
590 }
591 else
592 if( (x > mMaxHPixels) && (mCursorPos < (S32)mText.length()) )
593 { 609 {
594 // If scrolling one pixel would make a difference... 610 // ...scroll to the right
595 S32 pixels_after_scrolling_one_char = findPixelNearestPos(1); 611 mScrollHPos = llclamp(mScrollHPos + increment, 0, mText.length());
596 if( pixels_after_scrolling_one_char >= mMaxHPixels )
597 {
598 // ...scroll to the right
599 mScrollHPos = llclamp(mScrollHPos + increment, 0, mText.length());
600 }
601 } 612 }
602 } 613 }
614 }
603 615
604 setCursorAtLocalPos( x ); 616 setCursorAtLocalPos( x );
605 mSelectionEnd = getCursor(); 617 mSelectionEnd = getCursor();
606 618
607 // delay cursor flashing 619 // delay cursor flashing
608 mKeystrokeTimer.reset(); 620 mKeystrokeTimer.reset();
609 621
610 getWindow()->setCursor(UI_CURSOR_IBEAM); 622 getWindow()->setCursor(UI_CURSOR_IBEAM);
611 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl; 623 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;
612 handled = TRUE; 624 handled = TRUE;
613 } 625 }
614 626
615 if( !handled ) 627 if( !handled )
616 { 628 {
617 getWindow()->setCursor(UI_CURSOR_IBEAM); 629 getWindow()->setCursor(UI_CURSOR_IBEAM);
618 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl; 630 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl;
619 handled = TRUE; 631 handled = TRUE;
620 }
621 } 632 }
622 633
623 return handled; 634 return handled;
@@ -634,9 +645,10 @@ BOOL LLLineEditor::handleMouseUp(S32 x, S32 y, MASK mask)
634 handled = TRUE; 645 handled = TRUE;
635 } 646 }
636 647
637 if (!handled && (x < mBorderLeft || x > (getRect().getWidth() - mBorderRight))) 648 // Check first whether the "clear search" button wants to deal with this.
649 if(!handled && childrenHandleMouseUp(x, y, mask) != NULL)
638 { 650 {
639 return LLUICtrl::handleMouseUp(x, y, mask); 651 return TRUE;
640 } 652 }
641 653
642 if( mIsSelecting ) 654 if( mIsSelecting )
@@ -1223,12 +1235,12 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
1223} 1235}
1224 1236
1225 1237
1226BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) 1238BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
1227{ 1239{
1228 BOOL handled = FALSE; 1240 BOOL handled = FALSE;
1229 BOOL selection_modified = FALSE; 1241 BOOL selection_modified = FALSE;
1230 1242
1231 if ( (gFocusMgr.getKeyboardFocus() == this) && getVisible()) 1243 if ( gFocusMgr.getKeyboardFocus() == this )
1232 { 1244 {
1233 LLLineEditorRollback rollback( this ); 1245 LLLineEditorRollback rollback( this );
1234 1246
@@ -1291,7 +1303,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent )
1291} 1303}
1292 1304
1293 1305
1294BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) 1306BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
1295{ 1307{
1296 if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL 1308 if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL
1297 { 1309 {
@@ -1381,11 +1393,6 @@ void LLLineEditor::doDelete()
1381 1393
1382void LLLineEditor::draw() 1394void LLLineEditor::draw()
1383{ 1395{
1384 if( !getVisible() )
1385 {
1386 return;
1387 }
1388
1389 S32 text_len = mText.length(); 1396 S32 text_len = mText.length();
1390 1397
1391 LLString saved_text; 1398 LLString saved_text;
@@ -1406,6 +1413,13 @@ void LLLineEditor::draw()
1406 1413
1407 LLColor4 bg_color = mReadOnlyBgColor; 1414 LLColor4 bg_color = mReadOnlyBgColor;
1408 1415
1416#if 0 // for when we're ready for image art.
1417 if( hasFocus())
1418 {
1419 mImage->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
1420 }
1421 mImage->draw(getLocalRect(), mReadOnly ? mReadOnlyBgColor : mWriteableBgColor );
1422#else // the old programmer art.
1409 // drawing solids requires texturing be disabled 1423 // drawing solids requires texturing be disabled
1410 { 1424 {
1411 LLGLSNoTexture no_texture; 1425 LLGLSNoTexture no_texture;
@@ -1423,6 +1437,7 @@ void LLLineEditor::draw()
1423 } 1437 }
1424 gl_rect_2d(background, bg_color); 1438 gl_rect_2d(background, bg_color);
1425 } 1439 }
1440#endif
1426 1441
1427 // draw text 1442 // draw text
1428 1443
@@ -1560,10 +1575,14 @@ void LLLineEditor::draw()
1560 mMaxHPixels - llround(rendered_pixels_right), 1575 mMaxHPixels - llround(rendered_pixels_right),
1561 &rendered_pixels_right); 1576 &rendered_pixels_right);
1562 } 1577 }
1578#if 0 // for when we're ready for image art.
1579 mBorder->setVisible(FALSE); // no more programmatic art.
1580#endif
1563 1581
1564 // If we're editing... 1582 // If we're editing...
1565 if( gFocusMgr.getKeyboardFocus() == this) 1583 if( gFocusMgr.getKeyboardFocus() == this)
1566 { 1584 {
1585 //mBorder->setVisible(TRUE); // ok, programmer art just this once.
1567 // (Flash the cursor every half second) 1586 // (Flash the cursor every half second)
1568 if (gShowTextEditCursor && !mReadOnly) 1587 if (gShowTextEditCursor && !mReadOnly)
1569 { 1588 {
@@ -1616,7 +1635,7 @@ void LLLineEditor::draw()
1616 if (0 == mText.length()) 1635 if (0 == mText.length())
1617 { 1636 {
1618 mGLFont->render(mLabel.getWString(), 0, 1637 mGLFont->render(mLabel.getWString(), 0,
1619 LABEL_HPAD, (F32)text_bottom, 1638 mMinHPixels, (F32)text_bottom,
1620 label_color, 1639 label_color,
1621 LLFontGL::LEFT, LLFontGL::BOTTOM, 1640 LLFontGL::LEFT, LLFontGL::BOTTOM,
1622 LLFontGL::NORMAL, 1641 LLFontGL::NORMAL,
@@ -1757,7 +1776,7 @@ BOOL LLLineEditor::prevalidateFloat(const LLWString &str)
1757 if( 0 < len ) 1776 if( 0 < len )
1758 { 1777 {
1759 // May be a comma or period, depending on the locale 1778 // May be a comma or period, depending on the locale
1760 llwchar decimal_point = (llwchar)gResMgr->getDecimalPoint(); 1779 llwchar decimal_point = (llwchar)LLResMgr::getInstance()->getDecimalPoint();
1761 1780
1762 S32 i = 0; 1781 S32 i = 0;
1763 1782
@@ -1806,7 +1825,7 @@ BOOL LLLineEditor::postvalidateFloat(const LLString &str)
1806 } 1825 }
1807 1826
1808 // May be a comma or period, depending on the locale 1827 // May be a comma or period, depending on the locale
1809 llwchar decimal_point = (llwchar)gResMgr->getDecimalPoint(); 1828 llwchar decimal_point = (llwchar)LLResMgr::getInstance()->getDecimalPoint();
1810 1829
1811 for( ; i < len; i++ ) 1830 for( ; i < len; i++ )
1812 { 1831 {
@@ -2244,8 +2263,27 @@ LLView* LLLineEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
2244 return line_editor; 2263 return line_editor;
2245} 2264}
2246 2265
2266//static
2267void LLLineEditor::cleanupClass()
2268{
2269 sImage = NULL;
2270}
2271
2272/* static */
2273LLPointer<LLUIImage> LLLineEditor::parseImage(LLString name, LLXMLNodePtr from, LLPointer<LLUIImage> def)
2274{
2275 LLString xml_name;
2276 if (from->hasAttribute(name)) from->getAttributeString(name, xml_name);
2277 if (xml_name == LLString::null) return def;
2278 LLPointer<LLUIImage> image = LLUI::getUIImage(xml_name);
2279 return image.isNull() ? def : image;
2280}
2281
2247void LLLineEditor::setColorParameters(LLXMLNodePtr node) 2282void LLLineEditor::setColorParameters(LLXMLNodePtr node)
2248{ 2283{
2284 // overrides default image if supplied.
2285 mImage = parseImage("image", node, mImage);
2286
2249 LLColor4 color; 2287 LLColor4 color;
2250 if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color)) 2288 if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color))
2251 { 2289 {
@@ -2510,6 +2548,9 @@ S32 LLLineEditor::getPreeditFontSize() const
2510} 2548}
2511 2549
2512 2550
2551static LLRegisterWidget<LLSearchEditor> r2("search_editor");
2552
2553
2513LLSearchEditor::LLSearchEditor(const LLString& name, 2554LLSearchEditor::LLSearchEditor(const LLString& name,
2514 const LLRect& rect, 2555 const LLRect& rect,
2515 S32 max_length_bytes, 2556 S32 max_length_bytes,
@@ -2539,7 +2580,7 @@ LLSearchEditor::LLSearchEditor(const LLString& name,
2539 LLRect clear_btn_rect(rect.getWidth() - btn_width, rect.getHeight(), rect.getWidth(), 0); 2580 LLRect clear_btn_rect(rect.getWidth() - btn_width, rect.getHeight(), rect.getWidth(), 0);
2540 mClearSearchButton = new LLButton("clear search", 2581 mClearSearchButton = new LLButton("clear search",
2541 clear_btn_rect, 2582 clear_btn_rect,
2542 "closebox.tga", 2583 "icn_clear_lineeditor.tga",
2543 "UIImgBtnCloseInactiveUUID", 2584 "UIImgBtnCloseInactiveUUID",
2544 LLString::null, 2585 LLString::null,
2545 onClearSearch, 2586 onClearSearch,
@@ -2552,9 +2593,42 @@ LLSearchEditor::LLSearchEditor(const LLString& name,
2552 mClearSearchButton->setTabStop(FALSE); 2593 mClearSearchButton->setTabStop(FALSE);
2553 mSearchEdit->addChild(mClearSearchButton); 2594 mSearchEdit->addChild(mClearSearchButton);
2554 2595
2555 mSearchEdit->setBorderWidth(0, btn_width); 2596 mSearchEdit->setTextPadding(0, btn_width);
2597}
2598
2599
2600//virtual
2601void LLSearchEditor::setValue(const LLSD& value )
2602{
2603 mSearchEdit->setValue(value);
2604}
2605
2606//virtual
2607LLSD LLSearchEditor::getValue() const
2608{
2609 return mSearchEdit->getValue();
2556} 2610}
2557 2611
2612//virtual
2613BOOL LLSearchEditor::setTextArg( const LLString& key, const LLStringExplicit& text )
2614{
2615 return mSearchEdit->setTextArg(key, text);
2616}
2617
2618//virtual
2619BOOL LLSearchEditor::setLabelArg( const LLString& key, const LLStringExplicit& text )
2620{
2621 return mSearchEdit->setLabelArg(key, text);
2622}
2623
2624//virtual
2625void LLSearchEditor::clear()
2626{
2627 if (mSearchEdit)
2628 {
2629 mSearchEdit->clear();
2630 }
2631}
2558 2632
2559void LLSearchEditor::draw() 2633void LLSearchEditor::draw()
2560{ 2634{