summaryrefslogtreecommitdiff
path: root/indra/llui/lllineeditor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/lllineeditor.cpp')
-rw-r--r--indra/llui/lllineeditor.cpp1521
1 files changed, 537 insertions, 984 deletions
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 96039ce943..2759167d04 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -2,30 +2,25 @@
* @file lllineeditor.cpp
* @brief LLLineEditor base class
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -33,9 +28,10 @@
#include "linden_common.h"
+#define LLLINEEDITOR_CPP
#include "lllineeditor.h"
-#include "audioengine.h"
+#include "lltexteditor.h"
#include "llmath.h"
#include "llfontgl.h"
#include "llgl.h"
@@ -53,6 +49,7 @@
#include "llui.h"
#include "lluictrlfactory.h"
#include "llclipboard.h"
+#include "llmenugl.h"
//
// Imported globals
@@ -62,132 +59,133 @@
// Constants
//
-const S32 UI_LINEEDITOR_CURSOR_THICKNESS = 2;
-const S32 UI_LINEEDITOR_H_PAD = 2;
-const S32 UI_LINEEDITOR_V_PAD = 1;
const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds
const S32 SCROLL_INCREMENT_ADD = 0; // make space for typing
const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing
const F32 AUTO_SCROLL_TIME = 0.05f;
+const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. *TODO: make this equal to the double click interval?
-const F32 PREEDIT_MARKER_BRIGHTNESS = 0.4f;
-const S32 PREEDIT_MARKER_GAP = 1;
-const S32 PREEDIT_MARKER_POSITION = 2;
-const S32 PREEDIT_MARKER_THICKNESS = 1;
-const F32 PREEDIT_STANDOUT_BRIGHTNESS = 0.6f;
-const S32 PREEDIT_STANDOUT_GAP = 1;
-const S32 PREEDIT_STANDOUT_POSITION = 2;
-const S32 PREEDIT_STANDOUT_THICKNESS = 2;
+const std::string PASSWORD_ASTERISK( "\xE2\x80\xA2" ); // U+2022 BULLET
-static LLRegisterWidget<LLLineEditor> r1("line_editor");
+static LLDefaultChildRegistry::Register<LLLineEditor> r1("line_editor");
-/* static */ LLPointer<LLUIImage> LLLineEditor::sImage;
+// Compiler optimization, generate extern template
+template class LLLineEditor* LLView::getChild<class LLLineEditor>(
+ const std::string& name, BOOL recurse) const;
//
// Member functions
//
-
-LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect,
- const LLString& default_text, const LLFontGL* font,
- S32 max_length_bytes,
- void (*commit_callback)(LLUICtrl* caller, void* user_data ),
- void (*keystroke_callback)(LLLineEditor* caller, void* user_data ),
- void (*focus_lost_callback)(LLFocusableElement* caller, void* user_data ),
- void* userdata,
- LLLinePrevalidateFunc prevalidate_func,
- LLViewBorder::EBevel border_bevel,
- LLViewBorder::EStyle border_style,
- S32 border_thickness)
- :
- LLUICtrl( name, rect, TRUE, commit_callback, userdata, FOLLOWS_TOP | FOLLOWS_LEFT ),
- mMaxLengthBytes(max_length_bytes),
- mCursorPos( 0 ),
- mScrollHPos( 0 ),
- mTextPadLeft(0),
- mTextPadRight(0),
- mCommitOnFocusLost( TRUE ),
- mRevertOnEsc( TRUE ),
- mKeystrokeCallback( keystroke_callback ),
- mIsSelecting( FALSE ),
- mSelectionStart( 0 ),
- mSelectionEnd( 0 ),
- mLastSelectionX(-1),
- mLastSelectionY(-1),
- mLastSelectionStart(-1),
- mLastSelectionEnd(-1),
- mPrevalidateFunc( prevalidate_func ),
- mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ),
- mFgColor( LLUI::sColorsGroup->getColor( "TextFgColor" ) ),
- mReadOnlyFgColor( LLUI::sColorsGroup->getColor( "TextFgReadOnlyColor" ) ),
- mTentativeFgColor( LLUI::sColorsGroup->getColor( "TextFgTentativeColor" ) ),
- mWriteableBgColor( LLUI::sColorsGroup->getColor( "TextBgWriteableColor" ) ),
- mReadOnlyBgColor( LLUI::sColorsGroup->getColor( "TextBgReadOnlyColor" ) ),
- mFocusBgColor( LLUI::sColorsGroup->getColor( "TextBgFocusColor" ) ),
- mBorderThickness( border_thickness ),
- mIgnoreArrowKeys( FALSE ),
- mIgnoreTab( TRUE ),
- mDrawAsterixes( FALSE ),
- mHandleEditKeysDirectly( FALSE ),
- mSelectAllonFocusReceived( FALSE ),
- mPassDelete(FALSE),
- mReadOnly(FALSE),
- mImage( sImage ),
- mReplaceNewlinesWithSpaces( TRUE )
-{
- llassert( max_length_bytes > 0 );
-
- // line history support:
- // - initialize line history list
- mLineHistory.insert( mLineHistory.end(), "" );
- // - disable line history by default
- mHaveHistory = FALSE;
- // - reset current history line pointer
- mCurrentHistoryLine = 0;
-
- if (font)
- {
- mGLFont = font;
- }
- else
- {
- mGLFont = LLFontGL::sSansSerifSmall;
- }
-
- setFocusLostCallback(focus_lost_callback);
- setTextPadding(0, 0);
+LLLineEditor::Params::Params()
+: max_length_bytes("max_length", 254),
+ keystroke_callback("keystroke_callback"),
+ prevalidate_callback("prevalidate_callback"),
+ background_image("background_image"),
+ background_image_disabled("background_image_disabled"),
+ background_image_focused("background_image_focused"),
+ select_on_focus("select_on_focus", false),
+ revert_on_esc("revert_on_esc", true),
+ commit_on_focus_lost("commit_on_focus_lost", true),
+ ignore_tab("ignore_tab", true),
+ cursor_color("cursor_color"),
+ text_color("text_color"),
+ text_readonly_color("text_readonly_color"),
+ text_tentative_color("text_tentative_color"),
+ highlight_color("highlight_color"),
+ preedit_bg_color("preedit_bg_color"),
+ border(""),
+ bg_visible("bg_visible"),
+ text_pad_left("text_pad_left"),
+ text_pad_right("text_pad_right"),
+ default_text("default_text")
+{
+ mouse_opaque = true;
+ addSynonym(select_on_focus, "select_all_on_focus_received");
+ addSynonym(border, "border");
+ addSynonym(label, "watermark_text");
+}
+
+LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
+: LLUICtrl(p),
+ mMaxLengthBytes(p.max_length_bytes),
+ mCursorPos( 0 ),
+ mScrollHPos( 0 ),
+ mTextPadLeft(p.text_pad_left),
+ mTextPadRight(p.text_pad_right),
+ mTextLeftEdge(0), // computed in updateTextPadding() below
+ mTextRightEdge(0), // computed in updateTextPadding() below
+ mCommitOnFocusLost( p.commit_on_focus_lost ),
+ mRevertOnEsc( p.revert_on_esc ),
+ mKeystrokeCallback( p.keystroke_callback() ),
+ mIsSelecting( FALSE ),
+ mSelectionStart( 0 ),
+ mSelectionEnd( 0 ),
+ mLastSelectionX(-1),
+ mLastSelectionY(-1),
+ mLastSelectionStart(-1),
+ mLastSelectionEnd(-1),
+ mBorderThickness( 0 ),
+ mIgnoreArrowKeys( FALSE ),
+ mIgnoreTab( p.ignore_tab ),
+ mDrawAsterixes( FALSE ),
+ mSelectAllonFocusReceived( p.select_on_focus ),
+ mPassDelete(FALSE),
+ mReadOnly(FALSE),
+ mBgImage( p.background_image ),
+ mBgImageDisabled( p.background_image_disabled ),
+ mBgImageFocused( p.background_image_focused ),
+ mHaveHistory(FALSE),
+ mReplaceNewlinesWithSpaces( TRUE ),
+ mLabel(p.label),
+ mCursorColor(p.cursor_color()),
+ mFgColor(p.text_color()),
+ mReadOnlyFgColor(p.text_readonly_color()),
+ mTentativeFgColor(p.text_tentative_color()),
+ mHighlightColor(p.highlight_color()),
+ mPreeditBgColor(p.preedit_bg_color()),
+ mGLFont(p.font),
+ mContextMenuHandle()
+{
+ llassert( mMaxLengthBytes > 0 );
mScrollTimer.reset();
+ mTripleClickTimer.reset();
+ setText(p.default_text());
+
+ // Initialize current history line iterator
+ mCurrentHistoryLine = mLineHistory.begin();
+
+ LLRect border_rect(getLocalRect());
+ // adjust for gl line drawing glitch
+ border_rect.mTop -= 1;
+ border_rect.mRight -=1;
+ LLViewBorder::Params border_p(p.border);
+ border_p.rect = border_rect;
+ border_p.follows.flags = FOLLOWS_ALL;
+ border_p.bevel_style = LLViewBorder::BEVEL_IN;
+ mBorder = LLUICtrlFactory::create<LLViewBorder>(border_p);
+ addChild( mBorder );
- setText(default_text);
-
+ // clamp text padding to current editor size
+ updateTextPadding();
setCursor(mText.length());
- // Scalable UI somehow made these rectangles off-by-one.
- // I don't know why. JC
- LLRect border_rect(0, getRect().getHeight()-1, getRect().getWidth()-1, 0);
- mBorder = new LLViewBorder( "line ed border", border_rect, border_bevel, border_style, mBorderThickness );
- addChild( mBorder );
- mBorder->setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP|FOLLOWS_BOTTOM);
+ setPrevalidate(p.prevalidate_callback());
- if( ! sImage)
- {
- sImage = LLUI::getUIImage("sm_rounded_corners_simple.tga");
- }
- mImage = sImage;
+ LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>
+ ("menu_text_editor.xml",
+ LLMenuGL::sMenuContainer,
+ LLMenuHolderGL::child_registry_t::instance());
+ setContextMenu(menu);
}
-
-
+
LLLineEditor::~LLLineEditor()
{
mCommitOnFocusLost = FALSE;
+ // calls onCommit() while LLLineEditor still valid
gFocusMgr.releaseFocusIfNeeded( this );
-
- if( gEditMenuHandler == this )
- {
- gEditMenuHandler = NULL;
- }
}
@@ -220,15 +218,44 @@ void LLLineEditor::onFocusLost()
LLUICtrl::onFocusLost();
}
+// virtual
void LLLineEditor::onCommit()
{
// put current line into the line history
updateHistory();
+ setControlValue(getValue());
LLUICtrl::onCommit();
selectAll();
}
+// Returns TRUE if user changed value at all
+// virtual
+BOOL LLLineEditor::isDirty() const
+{
+ return mText.getString() != mPrevText;
+}
+
+// Clear dirty state
+// virtual
+void LLLineEditor::resetDirty()
+{
+ mPrevText = mText.getString();
+}
+
+// assumes UTF8 text
+// virtual
+void LLLineEditor::setValue(const LLSD& value )
+{
+ setText(value.asString());
+}
+
+//virtual
+LLSD LLLineEditor::getValue() const
+{
+ return LLSD(getText());
+}
+
// line history support
void LLLineEditor::updateHistory()
@@ -237,23 +264,38 @@ void LLLineEditor::updateHistory()
// reset current history line number.
// Be sure only to remember lines that are not empty and that are
// different from the last on the list.
- if( mHaveHistory && mText.length() && ( mLineHistory.empty() || getText() != mLineHistory.back() ) )
+ if( mHaveHistory && getLength() )
{
- // discard possible empty line at the end of the history
- // inserted by setText()
- if( !mLineHistory.back().length() )
+ if( !mLineHistory.empty() )
{
- mLineHistory.pop_back();
+ // When not empty, last line of history should always be blank.
+ if( mLineHistory.back().empty() )
+ {
+ // discard the empty line
+ mLineHistory.pop_back();
+ }
+ else
+ {
+ LL_WARNS("") << "Last line of history was not blank." << LL_ENDL;
+ }
}
- mLineHistory.insert( mLineHistory.end(), getText() );
- mCurrentHistoryLine = mLineHistory.size() - 1;
+
+ // Add text to history, ignoring duplicates
+ if( mLineHistory.empty() || getText() != mLineHistory.back() )
+ {
+ mLineHistory.push_back( getText() );
+ }
+
+ // Restore the blank line and set mCurrentHistoryLine to point at it
+ mLineHistory.push_back( "" );
+ mCurrentHistoryLine = mLineHistory.end() - 1;
}
}
void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
{
LLUICtrl::reshape(width, height, called_from_parent);
- setTextPadding(mTextPadLeft, mTextPadRight); // For clamping side-effect.
+ updateTextPadding(); // For clamping side-effect.
setCursor(mCursorPos); // For clamping side-effect.
}
@@ -271,12 +313,23 @@ void LLLineEditor::setMaxTextLength(S32 max_text_length)
mMaxLengthBytes = max_len;
}
+void LLLineEditor::getTextPadding(S32 *left, S32 *right)
+{
+ *left = mTextPadLeft;
+ *right = mTextPadRight;
+}
+
void LLLineEditor::setTextPadding(S32 left, S32 right)
{
- mTextPadLeft = llclamp(left, 0, getRect().getWidth());
- mTextPadRight = llclamp(right, 0, getRect().getWidth());
- mMinHPixels = UI_LINEEDITOR_H_PAD + mTextPadLeft;
- mMaxHPixels = getRect().getWidth() - mMinHPixels - mTextPadRight;
+ mTextPadLeft = left;
+ mTextPadRight = right;
+ updateTextPadding();
+}
+
+void LLLineEditor::updateTextPadding()
+{
+ mTextLeftEdge = llclamp(mTextPadLeft, 0, getRect().getWidth());
+ mTextRightEdge = getRect().getWidth() - llclamp(mTextPadRight, 0, getRect().getWidth());
}
@@ -298,7 +351,7 @@ void LLLineEditor::setText(const LLStringExplicit &new_text)
// also consider entire string selected when mSelectAllonFocusReceived is set on an empty, focused line editor
all_selected = all_selected || (len == 0 && hasFocus() && mSelectAllonFocusReceived);
- LLString truncated_utf8 = new_text;
+ std::string truncated_utf8 = new_text;
if (truncated_utf8.size() > (U32)mMaxLengthBytes)
{
truncated_utf8 = utf8str_truncate(new_text, mMaxLengthBytes);
@@ -317,11 +370,11 @@ void LLLineEditor::setText(const LLStringExplicit &new_text)
}
setCursor(llmin((S32)mText.length(), getCursor()));
- // Newly set text goes always in the last line of history.
- // Possible empty strings (as with chat line) will be deleted later.
- mLineHistory.insert( mLineHistory.end(), new_text );
// Set current history line to end of history.
- mCurrentHistoryLine = mLineHistory.size() - 1;
+ if(mLineHistory.end() != mLineHistory.begin())
+ {
+ mCurrentHistoryLine = mLineHistory.end() - 1;
+ }
mPrevText = mText;
}
@@ -336,7 +389,7 @@ void LLLineEditor::setCursorAtLocalPos( S32 local_mouse_x )
{
for (S32 i = 0; i < mText.length(); i++)
{
- asterix_text += '*';
+ asterix_text += utf8str_to_wstring(PASSWORD_ASTERISK);
}
wtext = asterix_text.c_str();
}
@@ -345,8 +398,8 @@ void LLLineEditor::setCursorAtLocalPos( S32 local_mouse_x )
mScrollHPos +
mGLFont->charFromPixelOffset(
wtext, mScrollHPos,
- (F32)(local_mouse_x - mMinHPixels),
- (F32)(mMaxHPixels - mMinHPixels + 1)); // min-max range is inclusive
+ (F32)(local_mouse_x - mTextLeftEdge),
+ (F32)(mTextRightEdge - mTextLeftEdge + 1)); // min-max range is inclusive
setCursor(cursor_pos);
}
@@ -355,12 +408,16 @@ void LLLineEditor::setCursor( S32 pos )
S32 old_cursor_pos = getCursor();
mCursorPos = llclamp( pos, 0, mText.length());
+ // position of end of next character after cursor
S32 pixels_after_scroll = findPixelNearestPos();
- if( pixels_after_scroll > mMaxHPixels )
+ if( pixels_after_scroll > mTextRightEdge )
{
S32 width_chars_to_left = mGLFont->getWidth(mText.getWString().c_str(), 0, mScrollHPos);
- S32 last_visible_char = mGLFont->maxDrawableChars(mText.getWString().c_str(), llmax(0.f, (F32)(mMaxHPixels - mMinHPixels + width_chars_to_left)));
- S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mMaxHPixels - mMinHPixels), mText.length(), getCursor());
+ S32 last_visible_char = mGLFont->maxDrawableChars(mText.getWString().c_str(), llmax(0.f, (F32)(mTextRightEdge - mTextLeftEdge + width_chars_to_left)));
+ // character immediately to left of cursor should be last one visible (SCROLL_INCREMENT_ADD will scroll in more characters)
+ // or first character if cursor is at beginning
+ S32 new_last_visible_char = llmax(0, getCursor() - 1);
+ S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mTextRightEdge - mTextLeftEdge), mText.length(), new_last_visible_char);
if (old_cursor_pos == last_visible_char)
{
mScrollHPos = llmin(mText.length(), llmax(min_scroll, mScrollHPos + SCROLL_INCREMENT_ADD));
@@ -431,12 +488,14 @@ void LLLineEditor::selectAll()
setCursor(mSelectionEnd);
//mScrollHPos = 0;
mIsSelecting = TRUE;
+ updatePrimary();
}
BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
{
setFocus( TRUE );
+ mTripleClickTimer.setTimerExpirySec(TRIPLE_CLICK_INTERVAL);
if (mSelectionEnd == 0 && mSelectionStart == mText.length())
{
@@ -450,19 +509,19 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
BOOL doSelectAll = TRUE;
// Select the word we're on
- if( isPartOfWord( wtext[mCursorPos] ) )
+ if( LLWStringUtil::isPartOfWord( wtext[mCursorPos] ) )
{
S32 old_selection_start = mLastSelectionStart;
S32 old_selection_end = mLastSelectionEnd;
// Select word the cursor is over
- while ((mCursorPos > 0) && isPartOfWord( wtext[mCursorPos-1] ))
+ while ((mCursorPos > 0) && LLWStringUtil::isPartOfWord( wtext[mCursorPos-1] ))
{ // Find the start of the word
mCursorPos--;
}
startSelection();
- while ((mCursorPos < (S32)wtext.length()) && isPartOfWord( wtext[mCursorPos] ) )
+ while ((mCursorPos < (S32)wtext.length()) && LLWStringUtil::isPartOfWord( wtext[mCursorPos] ) )
{ // Find the end of the word
mCursorPos++;
}
@@ -487,6 +546,9 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
// delay cursor flashing
mKeystrokeTimer.reset();
+ // take selection to 'primary' clipboard
+ updatePrimary();
+
return TRUE;
}
@@ -497,18 +559,13 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{
return TRUE;
}
- if (mSelectAllonFocusReceived
- && gFocusMgr.getKeyboardFocus() != this)
- {
- setFocus( TRUE );
- }
- else
+
+ if (!mSelectAllonFocusReceived
+ || gFocusMgr.getKeyboardFocus() == this)
{
mLastSelectionStart = -1;
mLastSelectionStart = -1;
- setFocus( TRUE );
-
if (mask & MASK_SHIFT)
{
// Handle selection extension
@@ -550,25 +607,62 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
}
else
{
- // Save selection for word/line selecting on double-click
- mLastSelectionStart = mSelectionStart;
- mLastSelectionEnd = mSelectionEnd;
+ if (mTripleClickTimer.hasExpired())
+ {
+ // Save selection for word/line selecting on double-click
+ mLastSelectionStart = mSelectionStart;
+ mLastSelectionEnd = mSelectionEnd;
- // Move cursor and deselect for regular click
- setCursorAtLocalPos( x );
- deselect();
- startSelection();
+ // Move cursor and deselect for regular click
+ setCursorAtLocalPos( x );
+ deselect();
+ startSelection();
+ }
+ else // handle triple click
+ {
+ selectAll();
+ // We don't want handleMouseUp() to "finish" the selection (and thereby
+ // set mSelectionEnd to where the mouse is), so we finish the selection
+ // here.
+ mIsSelecting = FALSE;
+ }
}
gFocusMgr.setMouseCapture( this );
}
+ setFocus(TRUE);
+
// delay cursor flashing
mKeystrokeTimer.reset();
+
+ if (mMouseDownSignal)
+ (*mMouseDownSignal)(this,x,y,mask);
return TRUE;
}
+BOOL LLLineEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
+{
+ // llinfos << "MiddleMouseDown" << llendl;
+ setFocus( TRUE );
+ if( canPastePrimary() )
+ {
+ setCursorAtLocalPos(x);
+ pastePrimary();
+ }
+ return TRUE;
+}
+
+BOOL LLLineEditor::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ setFocus(TRUE);
+ if (!LLUICtrl::handleRightMouseDown(x, y, mask))
+ {
+ showContextMenu(x, y);
+ }
+ return TRUE;
+}
BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask)
{
@@ -595,17 +689,17 @@ BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask)
S32 increment = llround(mScrollTimer.getElapsedTimeF32() / AUTO_SCROLL_TIME);
mScrollTimer.reset();
mScrollTimer.setTimerExpirySec(AUTO_SCROLL_TIME);
- if( (x < mMinHPixels) && (mScrollHPos > 0 ) )
+ if( (x < mTextLeftEdge) && (mScrollHPos > 0 ) )
{
// Scroll to the left
mScrollHPos = llclamp(mScrollHPos - increment, 0, mText.length());
}
else
- if( (x > mMaxHPixels) && (mCursorPos < (S32)mText.length()) )
+ if( (x > mTextRightEdge) && (mCursorPos < (S32)mText.length()) )
{
// If scrolling one pixel would make a difference...
S32 pixels_after_scrolling_one_char = findPixelNearestPos(1);
- if( pixels_after_scrolling_one_char >= mMaxHPixels )
+ if( pixels_after_scrolling_one_char >= mTextRightEdge )
{
// ...scroll to the right
mScrollHPos = llclamp(mScrollHPos + increment, 0, mText.length());
@@ -663,8 +757,14 @@ BOOL LLLineEditor::handleMouseUp(S32 x, S32 y, MASK mask)
{
// delay cursor flashing
mKeystrokeTimer.reset();
- }
+ // take selection to 'primary' clipboard
+ updatePrimary();
+ }
+
+ // We won't call LLUICtrl::handleMouseUp to avoid double calls of childrenHandleMouseUp().Just invoke the signal manually.
+ if (mMouseUpSignal)
+ (*mMouseUpSignal)(this,x,y, mask);
return handled;
}
@@ -680,7 +780,7 @@ void LLLineEditor::removeChar()
}
else
{
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
}
@@ -719,7 +819,7 @@ void LLLineEditor::addChar(const llwchar uni_char)
}
else
{
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
getWindow()->hideCursorUntilMouseMove();
@@ -764,7 +864,7 @@ S32 LLLineEditor::prevWordPos(S32 cursorPos) const
{
cursorPos--;
}
- while( (cursorPos > 0) && isPartOfWord( wtext[cursorPos-1] ) )
+ while( (cursorPos > 0) && LLWStringUtil::isPartOfWord( wtext[cursorPos-1] ) )
{
cursorPos--;
}
@@ -774,7 +874,7 @@ S32 LLLineEditor::prevWordPos(S32 cursorPos) const
S32 LLLineEditor::nextWordPos(S32 cursorPos) const
{
const LLWString& wtext = mText.getWString();
- while( (cursorPos < getLength()) && isPartOfWord( wtext[cursorPos] ) )
+ while( (cursorPos < getLength()) && LLWStringUtil::isPartOfWord( wtext[cursorPos] ) )
{
cursorPos++;
}
@@ -808,7 +908,7 @@ BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask)
}
else
{
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
break;
@@ -824,7 +924,7 @@ BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask)
}
else
{
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
break;
@@ -850,23 +950,12 @@ BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask)
}
}
- if (!handled && mHandleEditKeysDirectly)
+ if(handled)
{
- if( (MASK_CONTROL & mask) && ('A' == key) )
- {
- if( canSelectAll() )
- {
- selectAll();
- }
- else
- {
- reportBadKeystroke();
- }
- handled = TRUE;
- }
+ // take selection to 'primary' clipboard
+ updatePrimary();
}
-
-
+
return handled;
}
@@ -875,7 +964,7 @@ void LLLineEditor::deleteSelection()
if( !mReadOnly && hasSelection() )
{
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
- S32 selection_length = abs( mSelectionStart - mSelectionEnd );
+ S32 selection_length = llabs( mSelectionStart - mSelectionEnd );
mText.erase(left_pos, selection_length);
deselect();
@@ -898,7 +987,7 @@ void LLLineEditor::cut()
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
- S32 length = abs( mSelectionStart - mSelectionEnd );
+ S32 length = llabs( mSelectionStart - mSelectionEnd );
gClipboard.copyFromSubstring( mText.getWString(), left_pos, length );
deleteSelection();
@@ -907,12 +996,12 @@ void LLLineEditor::cut()
if( need_to_rollback )
{
rollback.doRollback( this );
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
else
if( mKeystrokeCallback )
{
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
}
@@ -929,7 +1018,7 @@ void LLLineEditor::copy()
if( canCopy() )
{
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
- S32 length = abs( mSelectionStart - mSelectionEnd );
+ S32 length = llabs( mSelectionStart - mSelectionEnd );
gClipboard.copyFromSubstring( mText.getWString(), left_pos, length );
}
}
@@ -939,29 +1028,59 @@ BOOL LLLineEditor::canPaste() const
return !mReadOnly && gClipboard.canPasteString();
}
-
-// paste from clipboard
void LLLineEditor::paste()
{
- if (canPaste())
+ bool is_primary = false;
+ pasteHelper(is_primary);
+}
+
+void LLLineEditor::pastePrimary()
+{
+ bool is_primary = true;
+ pasteHelper(is_primary);
+}
+
+// paste from primary (is_primary==true) or clipboard (is_primary==false)
+void LLLineEditor::pasteHelper(bool is_primary)
+{
+ bool can_paste_it;
+ if (is_primary)
+ {
+ can_paste_it = canPastePrimary();
+ }
+ else
+ {
+ can_paste_it = canPaste();
+ }
+
+ if (can_paste_it)
{
- LLWString paste = gClipboard.getPasteWString();
+ LLWString paste;
+ if (is_primary)
+ {
+ paste = gClipboard.getPastePrimaryWString();
+ }
+ else
+ {
+ paste = gClipboard.getPasteWString();
+ }
+
if (!paste.empty())
{
// Prepare for possible rollback
LLLineEditorRollback rollback(this);
// Delete any selected characters
- if (hasSelection())
+ if ((!is_primary) && hasSelection())
{
deleteSelection();
}
// Clean up string (replace tabs and returns and remove characters that our fonts don't support.)
LLWString clean_string(paste);
- LLWString::replaceTabsWithSpaces(clean_string, 1);
+ LLWStringUtil::replaceTabsWithSpaces(clean_string, 1);
//clean_string = wstring_detabify(paste, 1);
- LLWString::replaceChar(clean_string, '\n', mReplaceNewlinesWithSpaces ? ' ' : 182); // 182 == paragraph character
+ LLWStringUtil::replaceChar(clean_string, '\n', mReplaceNewlinesWithSpaces ? ' ' : 182); // 182 == paragraph character
// Insert the string
@@ -986,9 +1105,9 @@ void LLLineEditor::paste()
}
// Truncate the clean string at the limit of what will fit
clean_string = clean_string.substr(0, wchars_that_fit);
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
-
+
mText.insert(getCursor(), clean_string);
setCursor( getCursor() + (S32)clean_string.length() );
deselect();
@@ -998,18 +1117,41 @@ void LLLineEditor::paste()
if( need_to_rollback )
{
rollback.doRollback( this );
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
else
if( mKeystrokeCallback )
{
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
}
}
-
+// copy selection to primary
+void LLLineEditor::copyPrimary()
+{
+ if( canCopy() )
+ {
+ S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
+ S32 length = llabs( mSelectionStart - mSelectionEnd );
+ gClipboard.copyFromPrimarySubstring( mText.getWString(), left_pos, length );
+ }
+}
+
+BOOL LLLineEditor::canPastePrimary() const
+{
+ return !mReadOnly && gClipboard.canPastePrimaryString();
+}
+
+void LLLineEditor::updatePrimary()
+{
+ if(canCopy() )
+ {
+ copyPrimary();
+ }
+}
+
BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
{
BOOL handled = FALSE;
@@ -1040,7 +1182,7 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
}
else
{
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
}
handled = TRUE;
@@ -1089,7 +1231,7 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
}
else
{
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
handled = TRUE;
}
@@ -1116,7 +1258,7 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
}
else
{
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
handled = TRUE;
}
@@ -1126,14 +1268,14 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
case KEY_UP:
if( mHaveHistory && ( MASK_CONTROL == mask ) )
{
- if( mCurrentHistoryLine > 0 )
+ if( mCurrentHistoryLine > mLineHistory.begin() )
{
- mText.assign( mLineHistory[ --mCurrentHistoryLine ] );
+ mText.assign( *(--mCurrentHistoryLine) );
setCursor(llmin((S32)mText.length(), getCursor()));
}
else
{
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
handled = TRUE;
}
@@ -1143,14 +1285,14 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
case KEY_DOWN:
if( mHaveHistory && ( MASK_CONTROL == mask ) )
{
- if( !mLineHistory.empty() && mCurrentHistoryLine < mLineHistory.size() - 1 )
+ if( !mLineHistory.empty() && mCurrentHistoryLine < mLineHistory.end() - 1 )
{
- mText.assign( mLineHistory[ ++mCurrentHistoryLine ] );
+ mText.assign( *(++mCurrentHistoryLine) );
setCursor(llmin((S32)mText.length(), getCursor()));
}
else
{
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
handled = TRUE;
}
@@ -1173,64 +1315,6 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
break;
}
- if( !handled && mHandleEditKeysDirectly )
- {
- // Standard edit keys (Ctrl-X, Delete, etc,) are handled here instead of routed by the menu system.
- if( KEY_DELETE == key )
- {
- if( canDoDelete() )
- {
- doDelete();
- }
- else
- {
- reportBadKeystroke();
- }
- handled = TRUE;
- }
- else
- if( MASK_CONTROL & mask )
- {
- if( 'C' == key )
- {
- if( canCopy() )
- {
- copy();
- }
- else
- {
- reportBadKeystroke();
- }
- handled = TRUE;
- }
- else
- if( 'V' == key )
- {
- if( canPaste() )
- {
- paste();
- }
- else
- {
- reportBadKeystroke();
- }
- handled = TRUE;
- }
- else
- if( 'X' == key )
- {
- if( canCut() )
- {
- cut();
- }
- else
- {
- reportBadKeystroke();
- }
- handled = TRUE;
- }
- }
- }
return handled;
}
@@ -1285,7 +1369,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
{
rollback.doRollback(this);
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
// Notify owner if requested
@@ -1293,7 +1377,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
{
if (mKeystrokeCallback)
{
- mKeystrokeCallback(this, mCallbackUserData);
+ mKeystrokeCallback(this);
}
}
}
@@ -1333,7 +1417,7 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
{
rollback.doRollback( this );
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
// Notify owner if requested
@@ -1343,7 +1427,7 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
{
// HACK! The only usage of this callback doesn't do anything with the character.
// We'll have to do something about this if something ever changes! - Doug
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
}
@@ -1353,7 +1437,7 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
BOOL LLLineEditor::canDoDelete() const
{
- return ( !mReadOnly && (!mPassDelete || (hasSelection() || (getCursor() < mText.length()))) );
+ return ( !mReadOnly && mText.length() > 0 && (!mPassDelete || (hasSelection() || (getCursor() < mText.length()))) );
}
void LLLineEditor::doDelete()
@@ -1378,31 +1462,73 @@ void LLLineEditor::doDelete()
if( need_to_rollback )
{
rollback.doRollback( this );
- reportBadKeystroke();
+ LLUI::reportBadKeystroke();
}
else
{
if( mKeystrokeCallback )
{
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
}
}
+void LLLineEditor::drawBackground()
+{
+ bool has_focus = hasFocus();
+ LLUIImage* image;
+ if ( mReadOnly )
+ {
+ image = mBgImageDisabled;
+ }
+ else if ( has_focus )
+ {
+ image = mBgImageFocused;
+ }
+ else
+ {
+ image = mBgImage;
+ }
+
+ F32 alpha = getDrawContext().mAlpha;
+ // optionally draw programmatic border
+ if (has_focus)
+ {
+ LLColor4 tmp_color = gFocusMgr.getFocusColor();
+ tmp_color.setAlpha(alpha);
+ image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(),
+ tmp_color,
+ gFocusMgr.getFocusFlashWidth());
+ }
+ LLColor4 tmp_color = UI_VERTEX_COLOR;
+ tmp_color.setAlpha(alpha);
+ image->draw(getLocalRect(), tmp_color);
+}
+
void LLLineEditor::draw()
{
+ F32 alpha = getDrawContext().mAlpha;
S32 text_len = mText.length();
-
- LLString saved_text;
+ static LLUICachedControl<S32> lineeditor_cursor_thickness ("UILineEditorCursorThickness", 0);
+ static LLUICachedControl<F32> preedit_marker_brightness ("UIPreeditMarkerBrightness", 0);
+ static LLUICachedControl<S32> preedit_marker_gap ("UIPreeditMarkerGap", 0);
+ static LLUICachedControl<S32> preedit_marker_position ("UIPreeditMarkerPosition", 0);
+ static LLUICachedControl<S32> preedit_marker_thickness ("UIPreeditMarkerThickness", 0);
+ static LLUICachedControl<F32> preedit_standout_brightness ("UIPreeditStandoutBrightness", 0);
+ static LLUICachedControl<S32> preedit_standout_gap ("UIPreeditStandoutGap", 0);
+ static LLUICachedControl<S32> preedit_standout_position ("UIPreeditStandoutPosition", 0);
+ static LLUICachedControl<S32> preedit_standout_thickness ("UIPreeditStandoutThickness", 0);
+
+ std::string saved_text;
if (mDrawAsterixes)
{
saved_text = mText.getString();
- LLString text;
+ std::string text;
for (S32 i = 0; i < mText.length(); i++)
{
- text += '*';
+ text += PASSWORD_ASTERISK;
}
mText = text;
}
@@ -1411,37 +1537,14 @@ void LLLineEditor::draw()
LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 );
background.stretch( -mBorderThickness );
- LLColor4 bg_color = mReadOnlyBgColor;
-
-#if 0 // for when we're ready for image art.
- if( hasFocus())
- {
- mImage->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
- }
- mImage->draw(getLocalRect(), mReadOnly ? mReadOnlyBgColor : mWriteableBgColor );
-#else // the old programmer art.
- // drawing solids requires texturing be disabled
- {
- LLGLSNoTexture no_texture;
- // draw background for text
- if( !mReadOnly )
- {
- if( gFocusMgr.getKeyboardFocus() == this )
- {
- bg_color = mFocusBgColor;
- }
- else
- {
- bg_color = mWriteableBgColor;
- }
- }
- gl_rect_2d(background, bg_color);
- }
-#endif
+ S32 lineeditor_v_pad = llround((background.getHeight() - mGLFont->getLineHeight())/2);
+ drawBackground();
+
// draw text
- S32 cursor_bottom = background.mBottom + 1;
+ // With viewer-2 art files, input region is 2 pixels up
+ S32 cursor_bottom = background.mBottom + 2;
S32 cursor_top = background.mTop - 1;
LLColor4 text_color;
@@ -1449,19 +1552,21 @@ void LLLineEditor::draw()
{
if (!getTentative())
{
- text_color = mFgColor;
+ text_color = mFgColor.get();
}
else
{
- text_color = mTentativeFgColor;
+ text_color = mTentativeFgColor.get();
}
}
else
{
- text_color = mReadOnlyFgColor;
+ text_color = mReadOnlyFgColor.get();
}
- LLColor4 label_color = mTentativeFgColor;
-
+ text_color.setAlpha(alpha);
+ LLColor4 label_color = mTentativeFgColor.get();
+ label_color.setAlpha(alpha);
+
if (hasPreeditString())
{
// Draw preedit markers. This needs to be before drawing letters.
@@ -1479,27 +1584,29 @@ void LLLineEditor::draw()
}
if (mPreeditStandouts[i])
{
- gl_rect_2d(preedit_pixels_left + PREEDIT_STANDOUT_GAP,
- background.mBottom + PREEDIT_STANDOUT_POSITION,
- preedit_pixels_right - PREEDIT_STANDOUT_GAP - 1,
- background.mBottom + PREEDIT_STANDOUT_POSITION - PREEDIT_STANDOUT_THICKNESS,
- (text_color * PREEDIT_STANDOUT_BRIGHTNESS + bg_color * (1 - PREEDIT_STANDOUT_BRIGHTNESS)).setAlpha(1.0f));
+ gl_rect_2d(preedit_pixels_left + preedit_standout_gap,
+ background.mBottom + preedit_standout_position,
+ preedit_pixels_right - preedit_standout_gap - 1,
+ background.mBottom + preedit_standout_position - preedit_standout_thickness,
+ (text_color * preedit_standout_brightness
+ + mPreeditBgColor * (1 - preedit_standout_brightness)).setAlpha(alpha/*1.0f*/));
}
else
{
- gl_rect_2d(preedit_pixels_left + PREEDIT_MARKER_GAP,
- background.mBottom + PREEDIT_MARKER_POSITION,
- preedit_pixels_right - PREEDIT_MARKER_GAP - 1,
- background.mBottom + PREEDIT_MARKER_POSITION - PREEDIT_MARKER_THICKNESS,
- (text_color * PREEDIT_MARKER_BRIGHTNESS + bg_color * (1 - PREEDIT_MARKER_BRIGHTNESS)).setAlpha(1.0f));
+ gl_rect_2d(preedit_pixels_left + preedit_marker_gap,
+ background.mBottom + preedit_marker_position,
+ preedit_pixels_right - preedit_marker_gap - 1,
+ background.mBottom + preedit_marker_position - preedit_marker_thickness,
+ (text_color * preedit_marker_brightness
+ + mPreeditBgColor * (1 - preedit_marker_brightness)).setAlpha(alpha/*1.0f*/));
}
}
}
}
S32 rendered_text = 0;
- F32 rendered_pixels_right = (F32)mMinHPixels;
- F32 text_bottom = (F32)background.mBottom + (F32)UI_LINEEDITOR_V_PAD;
+ F32 rendered_pixels_right = (F32)mTextLeftEdge;
+ F32 text_bottom = (F32)background.mBottom + (F32)lineeditor_v_pad;
if( (gFocusMgr.getKeyboardFocus() == this) && hasSelection() )
{
@@ -1524,32 +1631,36 @@ void LLLineEditor::draw()
rendered_pixels_right, text_bottom,
text_color,
LLFontGL::LEFT, LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
select_left - mScrollHPos,
- mMaxHPixels - llround(rendered_pixels_right),
+ mTextRightEdge - llround(rendered_pixels_right),
&rendered_pixels_right);
}
- if( (rendered_pixels_right < (F32)mMaxHPixels) && (rendered_text < text_len) )
+ if( (rendered_pixels_right < (F32)mTextRightEdge) && (rendered_text < text_len) )
{
- LLColor4 color(1.f - bg_color.mV[0], 1.f - bg_color.mV[1], 1.f - bg_color.mV[2], 1.f);
+ LLColor4 color = mHighlightColor;
+ color.setAlpha(alpha);
// selected middle
S32 width = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos + rendered_text, select_right - mScrollHPos - rendered_text);
- width = llmin(width, mMaxHPixels - llround(rendered_pixels_right));
+ width = llmin(width, mTextRightEdge - llround(rendered_pixels_right));
gl_rect_2d(llround(rendered_pixels_right), cursor_top, llround(rendered_pixels_right)+width, cursor_bottom, color);
+ LLColor4 tmp_color( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], alpha );
rendered_text += mGLFont->render(
mText, mScrollHPos + rendered_text,
rendered_pixels_right, text_bottom,
- LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ),
+ tmp_color,
LLFontGL::LEFT, LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
select_right - mScrollHPos - rendered_text,
- mMaxHPixels - llround(rendered_pixels_right),
+ mTextRightEdge - llround(rendered_pixels_right),
&rendered_pixels_right);
}
- if( (rendered_pixels_right < (F32)mMaxHPixels) && (rendered_text < text_len) )
+ if( (rendered_pixels_right < (F32)mTextRightEdge) && (rendered_text < text_len) )
{
// unselected, right side
mGLFont->render(
@@ -1557,9 +1668,10 @@ void LLLineEditor::draw()
rendered_pixels_right, text_bottom,
text_color,
LLFontGL::LEFT, LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
S32_MAX,
- mMaxHPixels - llround(rendered_pixels_right),
+ mTextRightEdge - llround(rendered_pixels_right),
&rendered_pixels_right);
}
}
@@ -1570,31 +1682,32 @@ void LLLineEditor::draw()
rendered_pixels_right, text_bottom,
text_color,
LLFontGL::LEFT, LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
S32_MAX,
- mMaxHPixels - llround(rendered_pixels_right),
+ mTextRightEdge - llround(rendered_pixels_right),
&rendered_pixels_right);
}
-#if 0 // for when we're ready for image art.
+#if 1 // for when we're ready for image art.
mBorder->setVisible(FALSE); // no more programmatic art.
#endif
// If we're editing...
- if( gFocusMgr.getKeyboardFocus() == this)
+ if( hasFocus())
{
//mBorder->setVisible(TRUE); // ok, programmer art just this once.
// (Flash the cursor every half second)
- if (gShowTextEditCursor && !mReadOnly)
+ if (!mReadOnly && gFocusMgr.getAppHasFocus())
{
F32 elapsed = mKeystrokeTimer.getElapsedTimeF32();
if( (elapsed < CURSOR_FLASH_DELAY ) || (S32(elapsed * 2) & 1) )
{
S32 cursor_left = findPixelNearestPos();
- cursor_left -= UI_LINEEDITOR_CURSOR_THICKNESS / 2;
- S32 cursor_right = cursor_left + UI_LINEEDITOR_CURSOR_THICKNESS;
+ cursor_left -= lineeditor_cursor_thickness / 2;
+ S32 cursor_right = cursor_left + lineeditor_cursor_thickness;
if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection())
{
- const LLWString space(utf8str_to_wstring(LLString(" ")));
+ const LLWString space(utf8str_to_wstring(std::string(" ")));
S32 wswidth = mGLFont->getWidth(space.c_str());
S32 width = mGLFont->getWidth(mText.getWString().c_str(), getCursor(), 1) + 1;
cursor_right = cursor_left + llmax(wswidth, width);
@@ -1604,17 +1717,19 @@ void LLLineEditor::draw()
cursor_right, cursor_bottom, text_color);
if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection())
{
- mGLFont->render(mText, getCursor(), (F32)(cursor_left + UI_LINEEDITOR_CURSOR_THICKNESS / 2), text_bottom,
- LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ),
+ LLColor4 tmp_color( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], alpha );
+ mGLFont->render(mText, getCursor(), (F32)(cursor_left + lineeditor_cursor_thickness / 2), text_bottom,
+ tmp_color,
LLFontGL::LEFT, LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
1);
}
// Make sure the IME is in the right place
S32 pixels_after_scroll = findPixelNearestPos(); // RCalculcate for IME position
- LLRect screen_pos = getScreenRect();
- LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - UI_LINEEDITOR_V_PAD );
+ LLRect screen_pos = calcScreenRect();
+ LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - lineeditor_v_pad );
ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
@@ -1622,6 +1737,24 @@ void LLLineEditor::draw()
}
}
+ //draw label if no text is provided
+ //but we should draw it in a different color
+ //to give indication that it is not text you typed in
+ if (0 == mText.length() && mReadOnly)
+ {
+ mGLFont->render(mLabel.getWString(), 0,
+ mTextLeftEdge, (F32)text_bottom,
+ label_color,
+ LLFontGL::LEFT,
+ LLFontGL::BOTTOM,
+ 0,
+ LLFontGL::NO_SHADOW,
+ S32_MAX,
+ mTextRightEdge - llround(rendered_pixels_right),
+ &rendered_pixels_right, FALSE);
+ }
+
+
// Draw children (border)
//mBorder->setVisible(TRUE);
mBorder->setKeyboardFocusHighlight( TRUE );
@@ -1634,13 +1767,15 @@ void LLLineEditor::draw()
// draw label if no text provided
if (0 == mText.length())
{
- mGLFont->render(mLabel.getWString(), 0,
- mMinHPixels, (F32)text_bottom,
+ mGLFont->render(mLabel.getWString(), 0,
+ mTextLeftEdge, (F32)text_bottom,
label_color,
- LLFontGL::LEFT, LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ LLFontGL::LEFT,
+ LLFontGL::BOTTOM,
+ 0,
+ LLFontGL::NO_SHADOW,
S32_MAX,
- mMaxHPixels - llround(rendered_pixels_right),
+ mTextRightEdge - llround(rendered_pixels_right),
&rendered_pixels_right, FALSE);
}
// Draw children (border)
@@ -1658,15 +1793,10 @@ void LLLineEditor::draw()
S32 LLLineEditor::findPixelNearestPos(const S32 cursor_offset) const
{
S32 dpos = getCursor() - mScrollHPos + cursor_offset;
- S32 result = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos, dpos) + mMinHPixels;
+ S32 result = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos, dpos) + mTextLeftEdge;
return result;
}
-void LLLineEditor::reportBadKeystroke()
-{
- make_ui_sound("UISndBadKeystroke");
-}
-
//virtual
void LLLineEditor::clear()
{
@@ -1754,56 +1884,14 @@ void LLLineEditor::setRect(const LLRect& rect)
}
}
-void LLLineEditor::setPrevalidate(BOOL (*func)(const LLWString &))
+void LLLineEditor::setPrevalidate(LLTextValidate::validate_func_t func)
{
mPrevalidateFunc = func;
updateAllowingLanguageInput();
}
-// Limits what characters can be used to [1234567890.-] with [-] only valid in the first position.
-// Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for
-// the simple reasons that intermediate states may be invalid even if the final result is valid.
-//
// static
-BOOL LLLineEditor::prevalidateFloat(const LLWString &str)
-{
- LLLocale locale(LLLocale::USER_LOCALE);
-
- BOOL success = TRUE;
- LLWString trimmed = str;
- LLWString::trim(trimmed);
- S32 len = trimmed.length();
- if( 0 < len )
- {
- // May be a comma or period, depending on the locale
- llwchar decimal_point = (llwchar)LLResMgr::getInstance()->getDecimalPoint();
-
- S32 i = 0;
-
- // First character can be a negative sign
- if( '-' == trimmed[0] )
- {
- i++;
- }
-
- for( ; i < len; i++ )
- {
- if( (decimal_point != trimmed[i] ) && !LLStringOps::isDigit( trimmed[i] ) )
- {
- success = FALSE;
- break;
- }
- }
- }
-
- return success;
-}
-
-//static
-BOOL LLLineEditor::isPartOfWord(llwchar c) { return (c == '_') || isalnum(c); }
-
-// static
-BOOL LLLineEditor::postvalidateFloat(const LLString &str)
+BOOL LLLineEditor::postvalidateFloat(const std::string &str)
{
LLLocale locale(LLLocale::USER_LOCALE);
@@ -1812,7 +1900,7 @@ BOOL LLLineEditor::postvalidateFloat(const LLString &str)
BOOL has_digit = FALSE;
LLWString trimmed = utf8str_to_wstring(str);
- LLWString::trim(trimmed);
+ LLWStringUtil::trim(trimmed);
S32 len = trimmed.length();
if( 0 < len )
{
@@ -1861,209 +1949,6 @@ BOOL LLLineEditor::postvalidateFloat(const LLString &str)
return success;
}
-// Limits what characters can be used to [1234567890-] with [-] only valid in the first position.
-// Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for
-// the simple reasons that intermediate states may be invalid even if the final result is valid.
-//
-// static
-BOOL LLLineEditor::prevalidateInt(const LLWString &str)
-{
- LLLocale locale(LLLocale::USER_LOCALE);
-
- BOOL success = TRUE;
- LLWString trimmed = str;
- LLWString::trim(trimmed);
- S32 len = trimmed.length();
- if( 0 < len )
- {
- S32 i = 0;
-
- // First character can be a negative sign
- if( '-' == trimmed[0] )
- {
- i++;
- }
-
- for( ; i < len; i++ )
- {
- if( !LLStringOps::isDigit( trimmed[i] ) )
- {
- success = FALSE;
- break;
- }
- }
- }
-
- return success;
-}
-
-// static
-BOOL LLLineEditor::prevalidatePositiveS32(const LLWString &str)
-{
- LLLocale locale(LLLocale::USER_LOCALE);
-
- LLWString trimmed = str;
- LLWString::trim(trimmed);
- S32 len = trimmed.length();
- BOOL success = TRUE;
- if(0 < len)
- {
- if(('-' == trimmed[0]) || ('0' == trimmed[0]))
- {
- success = FALSE;
- }
- S32 i = 0;
- while(success && (i < len))
- {
- if(!LLStringOps::isDigit(trimmed[i++]))
- {
- success = FALSE;
- }
- }
- }
- if (success)
- {
- S32 val = strtol(wstring_to_utf8str(trimmed).c_str(), NULL, 10);
- if (val <= 0)
- {
- success = FALSE;
- }
- }
- return success;
-}
-
-BOOL LLLineEditor::prevalidateNonNegativeS32(const LLWString &str)
-{
- LLLocale locale(LLLocale::USER_LOCALE);
-
- LLWString trimmed = str;
- LLWString::trim(trimmed);
- S32 len = trimmed.length();
- BOOL success = TRUE;
- if(0 < len)
- {
- if('-' == trimmed[0])
- {
- success = FALSE;
- }
- S32 i = 0;
- while(success && (i < len))
- {
- if(!LLStringOps::isDigit(trimmed[i++]))
- {
- success = FALSE;
- }
- }
- }
- if (success)
- {
- S32 val = strtol(wstring_to_utf8str(trimmed).c_str(), NULL, 10);
- if (val < 0)
- {
- success = FALSE;
- }
- }
- return success;
-}
-
-BOOL LLLineEditor::prevalidateAlphaNum(const LLWString &str)
-{
- LLLocale locale(LLLocale::USER_LOCALE);
-
- BOOL rv = TRUE;
- S32 len = str.length();
- if(len == 0) return rv;
- while(len--)
- {
- if( !isalnum(str[len]) )
- {
- rv = FALSE;
- break;
- }
- }
- return rv;
-}
-
-// static
-BOOL LLLineEditor::prevalidateAlphaNumSpace(const LLWString &str)
-{
- LLLocale locale(LLLocale::USER_LOCALE);
-
- BOOL rv = TRUE;
- S32 len = str.length();
- if(len == 0) return rv;
- while(len--)
- {
- if(!(isalnum(str[len]) || (' ' == str[len])))
- {
- rv = FALSE;
- break;
- }
- }
- return rv;
-}
-
-// static
-BOOL LLLineEditor::prevalidatePrintableNotPipe(const LLWString &str)
-{
- BOOL rv = TRUE;
- S32 len = str.length();
- if(len == 0) return rv;
- while(len--)
- {
- if('|' == str[len])
- {
- rv = FALSE;
- break;
- }
- if(!((' ' == str[len]) || isalnum(str[len]) || ispunct(str[len])))
- {
- rv = FALSE;
- break;
- }
- }
- return rv;
-}
-
-
-// static
-BOOL LLLineEditor::prevalidatePrintableNoSpace(const LLWString &str)
-{
- BOOL rv = TRUE;
- S32 len = str.length();
- if(len == 0) return rv;
- while(len--)
- {
- if(iswspace(str[len]))
- {
- rv = FALSE;
- break;
- }
- if( !(isalnum(str[len]) || ispunct(str[len]) ) )
- {
- rv = FALSE;
- break;
- }
- }
- return rv;
-}
-
-// static
-BOOL LLLineEditor::prevalidateASCII(const LLWString &str)
-{
- BOOL rv = TRUE;
- S32 len = str.length();
- while(len--)
- {
- if (str[len] < 0x20 || str[len] > 0x7f)
- {
- rv = FALSE;
- break;
- }
- }
- return rv;
-}
-
void LLLineEditor::onMouseCaptureLost()
{
endSelection();
@@ -2076,252 +1961,19 @@ void LLLineEditor::setSelectAllonFocusReceived(BOOL b)
}
-void LLLineEditor::setKeystrokeCallback(void (*keystroke_callback)(LLLineEditor* caller, void* user_data))
-{
- mKeystrokeCallback = keystroke_callback;
-}
-
-// virtual
-LLXMLNodePtr LLLineEditor::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("max_length", TRUE)->setIntValue(mMaxLengthBytes);
-
- node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mGLFont));
-
- if (mBorder)
- {
- LLString bevel;
- switch(mBorder->getBevel())
- {
- default:
- case LLViewBorder::BEVEL_NONE: bevel = "none"; break;
- case LLViewBorder::BEVEL_IN: bevel = "in"; break;
- case LLViewBorder::BEVEL_OUT: bevel = "out"; break;
- case LLViewBorder::BEVEL_BRIGHT:bevel = "bright"; break;
- }
- node->createChild("bevel_style", TRUE)->setStringValue(bevel);
-
- LLString style;
- switch(mBorder->getStyle())
- {
- default:
- case LLViewBorder::STYLE_LINE: style = "line"; break;
- case LLViewBorder::STYLE_TEXTURE: style = "texture"; break;
- }
- node->createChild("border_style", TRUE)->setStringValue(style);
-
- node->createChild("border_thickness", TRUE)->setIntValue(mBorder->getBorderWidth());
- }
-
- if (!mLabel.empty())
- {
- node->createChild("label", TRUE)->setStringValue(mLabel.getString());
- }
-
- node->createChild("select_all_on_focus_received", TRUE)->setBoolValue(mSelectAllonFocusReceived);
-
- node->createChild("handle_edit_keys_directly", TRUE)->setBoolValue(mHandleEditKeysDirectly );
-
- addColorXML(node, mCursorColor, "cursor_color", "TextCursorColor");
- addColorXML(node, mFgColor, "text_color", "TextFgColor");
- addColorXML(node, mReadOnlyFgColor, "text_readonly_color", "TextFgReadOnlyColor");
- addColorXML(node, mTentativeFgColor, "text_tentative_color", "TextFgTentativeColor");
- addColorXML(node, mReadOnlyBgColor, "bg_readonly_color", "TextBgReadOnlyColor");
- addColorXML(node, mWriteableBgColor, "bg_writeable_color", "TextBgWriteableColor");
- addColorXML(node, mFocusBgColor, "bg_focus_color", "TextBgFocusColor");
-
- node->createChild("select_on_focus", TRUE)->setBoolValue(mSelectAllonFocusReceived );
-
- return node;
-}
-
-// static
-LLView* LLLineEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- LLString name("line_editor");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- S32 max_text_length = 128;
- node->getAttributeS32("max_length", max_text_length);
-
- LLFontGL* font = LLView::selectFont(node);
-
- LLString text = node->getTextContents().substr(0, max_text_length - 1);
-
- LLViewBorder::EBevel bevel_style = LLViewBorder::BEVEL_IN;
- LLViewBorder::getBevelFromAttribute(node, bevel_style);
-
- LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE;
- LLString border_string;
- node->getAttributeString("border_style", border_string);
- LLString::toLower(border_string);
-
- if (border_string == "texture")
- {
- border_style = LLViewBorder::STYLE_TEXTURE;
- }
-
- S32 border_thickness = 1;
- node->getAttributeS32("border_thickness", border_thickness);
-
- LLUICtrlCallback commit_callback = NULL;
-
- LLLineEditor* line_editor = new LLLineEditor(name,
- rect,
- text,
- font,
- max_text_length,
- commit_callback,
- NULL,
- NULL,
- NULL,
- NULL,
- bevel_style,
- border_style,
- border_thickness);
-
- LLString label;
- if(node->getAttributeString("label", label))
- {
- line_editor->setLabel(label);
- }
- BOOL select_all_on_focus_received = FALSE;
- if (node->getAttributeBOOL("select_all_on_focus_received", select_all_on_focus_received))
- {
- line_editor->setSelectAllonFocusReceived(select_all_on_focus_received);
- }
- BOOL handle_edit_keys_directly = FALSE;
- if (node->getAttributeBOOL("handle_edit_keys_directly", handle_edit_keys_directly))
- {
- line_editor->setHandleEditKeysDirectly(handle_edit_keys_directly);
- }
- BOOL commit_on_focus_lost = TRUE;
- if (node->getAttributeBOOL("commit_on_focus_lost", commit_on_focus_lost))
- {
- line_editor->setCommitOnFocusLost(commit_on_focus_lost);
- }
-
- line_editor->setColorParameters(node);
-
- if(node->hasAttribute("select_on_focus"))
- {
- BOOL selectall = FALSE;
- node->getAttributeBOOL("select_on_focus", selectall);
- line_editor->setSelectAllonFocusReceived(selectall);
- }
-
- LLString prevalidate;
- if(node->getAttributeString("prevalidate", prevalidate))
- {
- LLString::toLower(prevalidate);
-
- if ("ascii" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidateASCII );
- }
- else if ("float" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidateFloat );
- }
- else if ("int" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidateInt );
- }
- else if ("positive_s32" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidatePositiveS32 );
- }
- else if ("non_negative_s32" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidateNonNegativeS32 );
- }
- else if ("alpha_num" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidateAlphaNum );
- }
- else if ("alpha_num_space" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidateAlphaNumSpace );
- }
- else if ("printable_not_pipe" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidatePrintableNotPipe );
- }
- else if ("printable_no_space" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidatePrintableNoSpace );
- }
- }
-
- line_editor->initFromXML(node, parent);
-
- return line_editor;
-}
-
-//static
-void LLLineEditor::cleanupClass()
-{
- sImage = NULL;
-}
-
-/* static */
-LLPointer<LLUIImage> LLLineEditor::parseImage(LLString name, LLXMLNodePtr from, LLPointer<LLUIImage> def)
+void LLLineEditor::setKeystrokeCallback(callback_t callback, void* user_data)
{
- LLString xml_name;
- if (from->hasAttribute(name)) from->getAttributeString(name, xml_name);
- if (xml_name == LLString::null) return def;
- LLPointer<LLUIImage> image = LLUI::getUIImage(xml_name);
- return image.isNull() ? def : image;
+ mKeystrokeCallback = boost::bind(callback, _1, user_data);
}
-void LLLineEditor::setColorParameters(LLXMLNodePtr node)
-{
- // overrides default image if supplied.
- mImage = parseImage("image", node, mImage);
-
- LLColor4 color;
- if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color))
- {
- setCursorColor(color);
- }
- if(node->hasAttribute("text_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"text_color", color);
- setFgColor(color);
- }
- if(node->hasAttribute("text_readonly_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"text_readonly_color", color);
- setReadOnlyFgColor(color);
- }
- if (LLUICtrlFactory::getAttributeColor(node,"text_tentative_color", color))
- {
- setTentativeFgColor(color);
- }
- if(node->hasAttribute("bg_readonly_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"bg_readonly_color", color);
- setReadOnlyBgColor(color);
- }
- if(node->hasAttribute("bg_writeable_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"bg_writeable_color", color);
- setWriteableBgColor(color);
- }
-}
-BOOL LLLineEditor::setTextArg( const LLString& key, const LLStringExplicit& text )
+BOOL LLLineEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
{
mText.setArg(key, text);
return TRUE;
}
-BOOL LLLineEditor::setLabelArg( const LLString& key, const LLStringExplicit& text )
+BOOL LLLineEditor::setLabelArg( const std::string& key, const LLStringExplicit& text )
{
mLabel.setArg(key, text);
return TRUE;
@@ -2336,13 +1988,19 @@ void LLLineEditor::updateAllowingLanguageInput()
// fine on 1.15.0.2, since all prevalidate func reject any
// non-ASCII characters. I'm not sure on future versions,
// however...
+ LLWindow* window = getWindow();
+ if (!window)
+ {
+ // test app, no window available
+ return;
+ }
if (hasFocus() && !mReadOnly && !mDrawAsterixes && mPrevalidateFunc == NULL)
{
- getWindow()->allowLanguageTextInput(this, TRUE);
+ window->allowLanguageTextInput(this, TRUE);
}
else
{
- getWindow()->allowLanguageTextInput(this, FALSE);
+ window->allowLanguageTextInput(this, FALSE);
}
}
@@ -2353,14 +2011,20 @@ BOOL LLLineEditor::hasPreeditString() const
void LLLineEditor::resetPreedit()
{
- if (hasPreeditString())
+ if (hasSelection())
{
- if (hasSelection())
+ if (hasPreeditString())
{
llwarns << "Preedit and selection!" << llendl;
deselect();
}
-
+ else
+ {
+ deleteSelection();
+ }
+ }
+ if (hasPreeditString())
+ {
const S32 preedit_pos = mPreeditPositions.front();
mText.erase(preedit_pos, mPreeditPositions.back() - preedit_pos);
mText.insert(preedit_pos, mPreeditOverwrittenWString);
@@ -2420,7 +2084,7 @@ void LLLineEditor::updatePreedit(const LLWString &preedit_string,
mKeystrokeTimer.reset();
if( mKeystrokeCallback )
{
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
@@ -2552,146 +2216,35 @@ void LLLineEditor::setReplaceNewlinesWithSpaces(BOOL replace)
mReplaceNewlinesWithSpaces = replace;
}
-static LLRegisterWidget<LLSearchEditor> r2("search_editor");
-
-
-LLSearchEditor::LLSearchEditor(const LLString& name,
- const LLRect& rect,
- S32 max_length_bytes,
- void (*search_callback)(const LLString& search_string, void* user_data),
- void* userdata)
- :
- LLUICtrl(name, rect, TRUE, NULL, userdata),
- mSearchCallback(search_callback)
+LLWString LLLineEditor::getConvertedText() const
{
- LLRect search_edit_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
- mSearchEdit = new LLLineEditor("search edit",
- search_edit_rect,
- LLString::null,
- NULL,
- max_length_bytes,
- NULL,
- onSearchEdit,
- NULL,
- this);
-
- mSearchEdit->setFollowsAll();
- mSearchEdit->setSelectAllonFocusReceived(TRUE);
-
- addChild(mSearchEdit);
-
- S32 btn_width = rect.getHeight(); // button is square, and as tall as search editor
- LLRect clear_btn_rect(rect.getWidth() - btn_width, rect.getHeight(), rect.getWidth(), 0);
- mClearSearchButton = new LLButton("clear search",
- clear_btn_rect,
- "icn_clear_lineeditor.tga",
- "UIImgBtnCloseInactiveUUID",
- LLString::null,
- onClearSearch,
- this,
- NULL,
- LLString::null);
- mClearSearchButton->setFollowsRight();
- mClearSearchButton->setFollowsTop();
- mClearSearchButton->setImageColor(LLUI::sColorsGroup->getColor("TextFgTentativeColor"));
- mClearSearchButton->setTabStop(FALSE);
- mSearchEdit->addChild(mClearSearchButton);
-
- mSearchEdit->setTextPadding(0, btn_width);
-}
-
-
-//virtual
-void LLSearchEditor::setValue(const LLSD& value )
-{
- mSearchEdit->setValue(value);
-}
-
-//virtual
-LLSD LLSearchEditor::getValue() const
-{
- return mSearchEdit->getValue();
-}
-
-//virtual
-BOOL LLSearchEditor::setTextArg( const LLString& key, const LLStringExplicit& text )
-{
- return mSearchEdit->setTextArg(key, text);
-}
-
-//virtual
-BOOL LLSearchEditor::setLabelArg( const LLString& key, const LLStringExplicit& text )
-{
- return mSearchEdit->setLabelArg(key, text);
-}
-
-//virtual
-void LLSearchEditor::clear()
-{
- if (mSearchEdit)
+ LLWString text = getWText();
+ LLWStringUtil::trim(text);
+ if (!mReplaceNewlinesWithSpaces)
{
- mSearchEdit->clear();
+ LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
}
+ return text;
}
-void LLSearchEditor::draw()
+void LLLineEditor::showContextMenu(S32 x, S32 y)
{
- mClearSearchButton->setVisible(!mSearchEdit->getWText().empty());
-
- LLUICtrl::draw();
-}
+ LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
-
-//static
-void LLSearchEditor::onSearchEdit(LLLineEditor* caller, void* user_data )
-{
- LLSearchEditor* search_editor = (LLSearchEditor*)user_data;
- if (search_editor->mSearchCallback)
+ if (menu)
{
- search_editor->mSearchCallback(caller->getText(), search_editor->mCallbackUserData);
- }
-}
-
-//static
-void LLSearchEditor::onClearSearch(void* user_data)
-{
- LLSearchEditor* search_editor = (LLSearchEditor*)user_data;
+ gEditMenuHandler = this;
- search_editor->setText(LLString::null);
- if (search_editor->mSearchCallback)
- {
- search_editor->mSearchCallback(LLString::null, search_editor->mCallbackUserData);
+ S32 screen_x, screen_y;
+ localPointToScreen(x, y, &screen_x, &screen_y);
+ menu->show(screen_x, screen_y);
}
}
-// static
-LLView* LLSearchEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
+void LLLineEditor::setContextMenu(LLContextMenu* new_context_menu)
{
- LLString name("search_editor");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- S32 max_text_length = 128;
- node->getAttributeS32("max_length", max_text_length);
-
- LLString text = node->getValue().substr(0, max_text_length - 1);
-
- LLSearchEditor* search_editor = new LLSearchEditor(name,
- rect,
- max_text_length,
- NULL, NULL);
-
- LLString label;
- if(node->getAttributeString("label", label))
- {
- search_editor->mSearchEdit->setLabel(label);
- }
-
- search_editor->setText(text);
-
- search_editor->initFromXML(node, parent);
-
- return search_editor;
+ if (new_context_menu)
+ mContextMenuHandle = new_context_menu->getHandle();
+ else
+ mContextMenuHandle.markDead();
}