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.cpp833
1 files changed, 278 insertions, 555 deletions
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 964254d93f..5435b9ffbf 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -37,7 +37,6 @@
#include "lllineeditor.h"
#include "lltexteditor.h"
-#include "audioengine.h"
#include "llmath.h"
#include "llfontgl.h"
#include "llgl.h"
@@ -64,79 +63,108 @@
// 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;
-
-static LLRegisterWidget<LLLineEditor> r1("line_editor");
-
-/* static */ LLPointer<LLUIImage> LLLineEditor::sImage;
+static LLDefaultChildRegistry::Register<LLLineEditor> r1("line_editor");
//
// Member functions
//
-
-LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
- const std::string& 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 );
+
+void LLLineEditor::PrevalidateNamedFuncs::declareValues()
+{
+ declare("ascii", LLLineEditor::prevalidateASCII);
+ declare("float", LLLineEditor::prevalidateFloat);
+ declare("int", LLLineEditor::prevalidateInt);
+ declare("positive_s32", LLLineEditor::prevalidatePositiveS32);
+ declare("non_negative_s32", LLLineEditor::prevalidateNonNegativeS32);
+ declare("alpha_num", LLLineEditor::prevalidateAlphaNum);
+ declare("alpha_num_space", LLLineEditor::prevalidateAlphaNumSpace);
+ declare("printable_not_pipe", LLLineEditor::prevalidatePrintableNotPipe);
+ declare("printable_no_space", LLLineEditor::prevalidatePrintableNoSpace);
+}
+
+LLLineEditor::Params::Params()
+: max_length_bytes("max_length", 254),
+ keystroke_callback("keystroke_callback"),
+ prevalidate_callback("prevalidate_callback"),
+ background_image("background_image"),
+ background_image_disabled("background_image_disabled"),
+ background_image_focused("background_image_focused"),
+ select_on_focus("select_on_focus", false),
+ handle_edit_keys_directly("handle_edit_keys_directly", false),
+ commit_on_focus_lost("commit_on_focus_lost", true),
+ 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(""),
+ is_unicode("is_unicode"),
+ drop_shadow_visible("drop_shadow_visible"),
+ border_drop_shadow_visible("border_drop_shadow_visible"),
+ 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),
+ mMinHPixels(0), // computed in updateTextPadding() below
+ mMaxHPixels(0), // computed in updateTextPadding() below
+ mCommitOnFocusLost( p.commit_on_focus_lost ),
+ mRevertOnEsc( TRUE ),
+ 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 ),
+ mHandleEditKeysDirectly(p.handle_edit_keys_directly),
+ mSelectAllonFocusReceived( p.select_on_focus ),
+ mPassDelete(FALSE),
+ mReadOnly(FALSE),
+ mBgImage( p.background_image ),
+ mBgImageDisabled( p.background_image_disabled ),
+ mBgImageFocused( p.background_image_focused ),
+ mReplaceNewlinesWithSpaces( TRUE ),
+ mLabel(p.label),
+ mCursorColor(p.cursor_color()),
+ mFgColor(p.text_color()),
+ mReadOnlyFgColor(p.text_readonly_color()),
+ mTentativeFgColor(p.text_tentative_color()),
+ mHighlightColor(p.highlight_color()),
+ mPreeditBgColor(p.preedit_bg_color()),
+ mGLFont(p.font)
+{
+ llassert( mMaxLengthBytes > 0 );
+
+ mScrollTimer.reset();
+ mTripleClickTimer.reset();
+ setText(p.default_text());
// line history support:
// - initialize line history list
@@ -146,40 +174,24 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
// - reset current history line pointer
mCurrentHistoryLine = 0;
- if (font)
- {
- mGLFont = font;
- }
- else
- {
- mGLFont = LLFontGL::getFontSansSerifSmall();
- }
-
- setFocusLostCallback(focus_lost_callback);
-
- setTextPadding(0, 0);
-
- mScrollTimer.reset();
+ 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( std::string("line ed border"), border_rect, border_bevel, border_style, mBorderThickness );
- addChild( mBorder );
- mBorder->setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP|FOLLOWS_BOTTOM);
-
- if( ! sImage)
- {
- sImage = LLUI::getUIImage("sm_rounded_corners_simple.tga");
- }
- mImage = sImage;
+ setPrevalidate(p.prevalidate_callback());
}
-
-
+
LLLineEditor::~LLLineEditor()
{
mCommitOnFocusLost = FALSE;
@@ -222,15 +234,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()
@@ -255,7 +296,7 @@ void LLLineEditor::updateHistory()
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.
}
@@ -273,12 +314,11 @@ void LLLineEditor::setMaxTextLength(S32 max_text_length)
mMaxLengthBytes = max_len;
}
-void LLLineEditor::setTextPadding(S32 left, S32 right)
+void LLLineEditor::updateTextPadding()
{
- mTextPadLeft = llclamp(left, 0, getRect().getWidth());
- mTextPadRight = llclamp(right, 0, getRect().getWidth());
- mMinHPixels = UI_LINEEDITOR_H_PAD + mTextPadLeft;
- mMaxHPixels = getRect().getWidth() - mMinHPixels - mTextPadRight;
+ static LLUICachedControl<S32> line_editor_hpad ("UILineEditorHPad", 0);
+ mMinHPixels = line_editor_hpad + llclamp(mTextPadLeft, 0, getRect().getWidth());;
+ mMaxHPixels = getRect().getWidth() - mMinHPixels - llclamp(mTextPadRight, 0, getRect().getWidth());
}
@@ -362,7 +402,7 @@ void LLLineEditor::setCursor( S32 pos )
{
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 - UI_LINEEDITOR_CURSOR_THICKNESS - UI_LINEEDITOR_H_PAD), mText.length(), getCursor());
+ S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mMaxHPixels - mMinHPixels), mText.length(), getCursor());
if (old_cursor_pos == last_visible_char)
{
mScrollHPos = llmin(mText.length(), llmax(min_scroll, mScrollHPos + SCROLL_INCREMENT_ADD));
@@ -439,6 +479,7 @@ void LLLineEditor::selectAll()
BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
{
setFocus( TRUE );
+ mTripleClickTimer.setTimerExpirySec(TRIPLE_CLICK_INTERVAL);
if (mSelectionEnd == 0 && mSelectionStart == mText.length())
{
@@ -452,19 +493,19 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
BOOL doSelectAll = TRUE;
// Select the word we're on
- if( LLTextEditor::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) && LLTextEditor::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()) && LLTextEditor::isPartOfWord( wtext[mCursorPos] ) )
+ while ((mCursorPos < (S32)wtext.length()) && LLWStringUtil::isPartOfWord( wtext[mCursorPos] ) )
{ // Find the end of the word
mCursorPos++;
}
@@ -555,14 +596,25 @@ 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 );
@@ -570,6 +622,8 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
// delay cursor flashing
mKeystrokeTimer.reset();
+
+ mMouseDownSignal(this,x,y,mask);
return TRUE;
}
@@ -683,7 +737,9 @@ BOOL LLLineEditor::handleMouseUp(S32 x, S32 y, MASK mask)
// take selection to 'primary' clipboard
updatePrimary();
}
-
+
+ // We won't call LLUICtrl::handleMouseUp to avoid double calls of childrenHandleMouseUp().Just invoke the signal manually.
+ mMouseUpSignal(this,x,y, mask);
return handled;
}
@@ -783,7 +839,7 @@ S32 LLLineEditor::prevWordPos(S32 cursorPos) const
{
cursorPos--;
}
- while( (cursorPos > 0) && LLTextEditor::isPartOfWord( wtext[cursorPos-1] ) )
+ while( (cursorPos > 0) && LLWStringUtil::isPartOfWord( wtext[cursorPos-1] ) )
{
cursorPos--;
}
@@ -793,7 +849,7 @@ S32 LLLineEditor::prevWordPos(S32 cursorPos) const
S32 LLLineEditor::nextWordPos(S32 cursorPos) const
{
const LLWString& wtext = mText.getWString();
- while( (cursorPos < getLength()) && LLTextEditor::isPartOfWord( wtext[cursorPos] ) )
+ while( (cursorPos < getLength()) && LLWStringUtil::isPartOfWord( wtext[cursorPos] ) )
{
cursorPos++;
}
@@ -936,7 +992,7 @@ void LLLineEditor::cut()
else
if( mKeystrokeCallback )
{
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
}
@@ -1057,7 +1113,7 @@ void LLLineEditor::pasteHelper(bool is_primary)
else
if( mKeystrokeCallback )
{
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
}
@@ -1370,7 +1426,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
{
if (mKeystrokeCallback)
{
- mKeystrokeCallback(this, mCallbackUserData);
+ mKeystrokeCallback(this);
}
}
}
@@ -1420,7 +1476,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 );
}
}
}
@@ -1461,16 +1517,53 @@ void LLLineEditor::doDelete()
{
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;
+ }
+
+ // optionally draw programmatic border
+ if (has_focus)
+ {
+ image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(),
+ gFocusMgr.getFocusColor(),
+ gFocusMgr.getFocusFlashWidth());
+ }
+ image->draw(getLocalRect());
+}
+
void LLLineEditor::draw()
{
S32 text_len = mText.length();
+ static LLUICachedControl<S32> lineeditor_cursor_thickness ("UILineEditorCursorThickness", 0);
+ static LLUICachedControl<S32> lineeditor_v_pad ("UILineEditorVPad", 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)
@@ -1488,37 +1581,12 @@ 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
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_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
-
+ 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;
@@ -1526,18 +1594,18 @@ 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;
+ LLColor4 label_color = mTentativeFgColor.get();
if (hasPreeditString())
{
@@ -1556,19 +1624,21 @@ 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(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(1.0f));
}
}
}
@@ -1576,7 +1646,7 @@ void LLLineEditor::draw()
S32 rendered_text = 0;
F32 rendered_pixels_right = (F32)mMinHPixels;
- F32 text_bottom = (F32)background.mBottom + (F32)UI_LINEEDITOR_V_PAD;
+ F32 text_bottom = (F32)background.mBottom + (F32)lineeditor_v_pad;
if( (gFocusMgr.getKeyboardFocus() == this) && hasSelection() )
{
@@ -1601,7 +1671,8 @@ 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),
&rendered_pixels_right);
@@ -1609,7 +1680,7 @@ void LLLineEditor::draw()
if( (rendered_pixels_right < (F32)mMaxHPixels) && (rendered_text < text_len) )
{
- LLColor4 color(1.f - bg_color.mV[0], 1.f - bg_color.mV[1], 1.f - bg_color.mV[2], 1.f);
+ LLColor4 color = mHighlightColor;
// selected middle
S32 width = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos + rendered_text, select_right - mScrollHPos - rendered_text);
width = llmin(width, mMaxHPixels - llround(rendered_pixels_right));
@@ -1620,7 +1691,8 @@ void LLLineEditor::draw()
rendered_pixels_right, text_bottom,
LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ),
LLFontGL::LEFT, LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
select_right - mScrollHPos - rendered_text,
mMaxHPixels - llround(rendered_pixels_right),
&rendered_pixels_right);
@@ -1634,7 +1706,8 @@ 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),
&rendered_pixels_right);
@@ -1647,28 +1720,29 @@ 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),
&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(std::string(" ")));
@@ -1681,17 +1755,18 @@ 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,
+ mGLFont->render(mText, getCursor(), (F32)(cursor_left + lineeditor_cursor_thickness / 2), text_bottom,
LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ),
LLFontGL::LEFT, LLFontGL::BOTTOM,
- 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]);
@@ -1709,7 +1784,8 @@ void LLLineEditor::draw()
label_color,
LLFontGL::LEFT,
LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
S32_MAX,
mMaxHPixels - llround(rendered_pixels_right),
&rendered_pixels_right, FALSE);
@@ -1733,7 +1809,8 @@ void LLLineEditor::draw()
label_color,
LLFontGL::LEFT,
LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
S32_MAX,
mMaxHPixels - llround(rendered_pixels_right),
&rendered_pixels_right, FALSE);
@@ -1849,7 +1926,7 @@ void LLLineEditor::setRect(const LLRect& rect)
}
}
-void LLLineEditor::setPrevalidate(BOOL (*func)(const LLWString &))
+void LLLineEditor::setPrevalidate(LLLinePrevalidateFunc func)
{
mPrevalidateFunc = func;
updateAllowingLanguageInput();
@@ -2169,244 +2246,11 @@ void LLLineEditor::setSelectAllonFocusReceived(BOOL b)
}
-void LLLineEditor::setKeystrokeCallback(void (*keystroke_callback)(LLLineEditor* caller, void* user_data))
+void LLLineEditor::setKeystrokeCallback(callback_t callback, void* user_data)
{
- mKeystrokeCallback = keystroke_callback;
+ mKeystrokeCallback = boost::bind(callback, _1, user_data);
}
-// 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)
- {
- std::string 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);
-
- std::string 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)
-{
- std::string 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);
-
- std::string 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;
- std::string border_string;
- node->getAttributeString("border_style", border_string);
- LLStringUtil::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);
-
- std::string 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);
- }
-
- std::string prevalidate;
- if(node->getAttributeString("prevalidate", prevalidate))
- {
- LLStringUtil::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::cleanupLineEditor()
-{
- sImage = NULL;
-}
-
-/* static */
-LLPointer<LLUIImage> LLLineEditor::parseImage(std::string name, LLXMLNodePtr from, LLPointer<LLUIImage> def)
-{
- std::string xml_name;
- if (from->hasAttribute(name.c_str())) from->getAttributeString(name.c_str(), xml_name);
- if (xml_name == LLStringUtil::null) return def;
- LLPointer<LLUIImage> image = LLUI::getUIImage(xml_name);
- return image.isNull() ? def : image;
-}
-
-void LLLineEditor::setColorParameters(LLXMLNodePtr node)
-{
- // overrides default image if supplied.
- mImage = parseImage(std::string("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 std::string& key, const LLStringExplicit& text )
{
@@ -2429,13 +2273,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);
}
}
@@ -2513,7 +2363,7 @@ void LLLineEditor::updatePreedit(const LLWString &preedit_string,
mKeystrokeTimer.reset();
if( mKeystrokeCallback )
{
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
@@ -2656,146 +2506,19 @@ LLWString LLLineEditor::getConvertedText() const
return text;
}
-static LLRegisterWidget<LLSearchEditor> r2("search_editor");
-
-
-LLSearchEditor::LLSearchEditor(const std::string& name,
- const LLRect& rect,
- S32 max_length_bytes,
- void (*search_callback)(const std::string& search_string, void* user_data),
- void* userdata)
- :
- LLUICtrl(name, rect, TRUE, NULL, userdata),
- mSearchCallback(search_callback)
-{
- LLRect search_edit_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
- mSearchEdit = new LLLineEditor(std::string("search edit"),
- search_edit_rect,
- LLStringUtil::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(std::string("clear search"),
- clear_btn_rect,
- std::string("icn_clear_lineeditor.tga"),
- std::string("UIImgBtnCloseInactiveUUID"),
- LLStringUtil::null,
- onClearSearch,
- this,
- NULL,
- LLStringUtil::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
+namespace LLInitParam
{
- return mSearchEdit->getValue();
-}
-
-//virtual
-BOOL LLSearchEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
-{
- return mSearchEdit->setTextArg(key, text);
-}
-
-//virtual
-BOOL LLSearchEditor::setLabelArg( const std::string& key, const LLStringExplicit& text )
-{
- return mSearchEdit->setLabelArg(key, text);
-}
-
-//virtual
-void LLSearchEditor::clear()
-{
- if (mSearchEdit)
+ template<>
+ bool ParamCompare<LLLinePrevalidateFunc>::equals(const LLLinePrevalidateFunc &a, const LLLinePrevalidateFunc &b)
{
- mSearchEdit->clear();
+ return false;
}
-}
-
-void LLSearchEditor::draw()
-{
- mClearSearchButton->setVisible(!mSearchEdit->getWText().empty());
-
- LLUICtrl::draw();
-}
-
-
-//static
-void LLSearchEditor::onSearchEdit(LLLineEditor* caller, void* user_data )
-{
- LLSearchEditor* search_editor = (LLSearchEditor*)user_data;
- if (search_editor->mSearchCallback)
- {
- search_editor->mSearchCallback(caller->getText(), search_editor->mCallbackUserData);
- }
-}
-
-//static
-void LLSearchEditor::onClearSearch(void* user_data)
-{
- LLSearchEditor* search_editor = (LLSearchEditor*)user_data;
- search_editor->setText(LLStringUtil::null);
- if (search_editor->mSearchCallback)
+ template<>
+ bool ParamCompare<boost::function<void (LLLineEditor *)> >::equals(
+ const boost::function<void (LLLineEditor *)> &a,
+ const boost::function<void (LLLineEditor *)> &b)
{
- search_editor->mSearchCallback(LLStringUtil::null, search_editor->mCallbackUserData);
+ return false;
}
}
-
-// static
-LLView* LLSearchEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string 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);
-
- std::string text = node->getValue().substr(0, max_text_length - 1);
-
- LLSearchEditor* search_editor = new LLSearchEditor(name,
- rect,
- max_text_length,
- NULL, NULL);
-
- std::string label;
- if(node->getAttributeString("label", label))
- {
- search_editor->mSearchEdit->setLabel(label);
- }
-
- search_editor->setText(text);
-
- search_editor->initFromXML(node, parent);
-
- return search_editor;
-}