nux-1.16.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "Nux.h" 00024 00025 #include "EditTextBox.h" 00026 #include "Layout.h" 00027 #include "HLayout.h" 00028 #include "VLayout.h" 00029 #include "Validator.h" 00030 00031 namespace nux 00032 { 00033 EditTextBox::EditTextBox (const TCHAR *Caption, NUX_FILE_LINE_DECL) 00034 : View (NUX_FILE_LINE_PARAM) 00035 { 00036 m_Validator = NULL; 00037 BlinkCursor = false; 00038 m_ScrollTimerHandler = 0; 00039 m_BlinkTimerFunctor = 0; 00040 m_WriteAlpha = true; 00041 m_Prefix = TEXT(""); 00042 m_Suffix = TEXT(""); 00043 00044 key_nav_mode_ = false; 00045 text_input_mode_ = false; 00046 00047 SetGeometry (Geometry (0, 0, 3 * DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT) ); 00048 SetMinimumSize (DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); 00049 SetGeometry (Geometry (0, 0, 3 * DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT) ); 00050 mouse_down.connect (sigc::mem_fun (this, &EditTextBox::RecvMouseDown) ); 00051 mouse_drag.connect (sigc::mem_fun (this, &EditTextBox::RecvMouseDrag) ); 00052 mouse_up.connect (sigc::mem_fun (this, &EditTextBox::RecvMouseUp) ); 00053 mouse_double_click.connect (sigc::mem_fun (this, &EditTextBox::RecvMouseDoubleClick) ); 00054 00055 key_down.connect (sigc::mem_fun (this, &EditTextBox::RecvKeyEvent) ); 00056 00057 begin_key_focus.connect (sigc::mem_fun (this, &EditTextBox::RecvStartKeyFocus) ); 00058 end_key_focus.connect (sigc::mem_fun (this, &EditTextBox::RecvEndKeyFocus) ); 00059 00060 SetText (Caption); 00061 SetTextColor (color::White); 00062 m_BackgroundColor = Color (0xFF343434); //COLOR_TEXTEDIT_BACKGROUNG; 00063 m_SelectedTextColor = Color (0xFFFAFAFA); 00064 m_SelectedTextBackgroundColor = Color (0xFF777777); 00065 m_TextBlinkColor = Color (0xFF003D0A); 00066 m_CursorColor = Color (0xFFDDDDDD); 00067 00068 00069 hlayout = new HLayout (NUX_TRACKER_LOCATION); 00070 SetLayout(hlayout); 00071 00072 m_BlinkTimerFunctor = new TimerFunctor(); 00073 m_BlinkTimerFunctor->OnTimerExpired.connect (sigc::mem_fun (this, &EditTextBox::BlinkCursorTimerInterrupt) ); 00074 00075 m_ScrollTimerFunctor = new TimerFunctor(); 00076 m_ScrollTimerFunctor->OnTimerExpired.connect (sigc::mem_fun (this, &EditTextBox::ScrollTimerInterrupt) ); 00077 00078 SetAcceptKeyboardEvent(true); 00079 EnableDoubleClick(true); 00080 } 00081 00082 EditTextBox::~EditTextBox() 00083 { 00084 delete m_BlinkTimerFunctor; 00085 delete m_ScrollTimerFunctor; 00086 delete m_Validator; 00087 00088 if (m_BlinkTimerHandler.IsValid() ) 00089 GetTimer().RemoveTimerHandler (m_BlinkTimerHandler); 00090 00091 m_BlinkTimerHandler = 0; 00092 } 00093 00094 void EditTextBox::ScrollTimerInterrupt (void *v) 00095 { 00096 Geometry base = GetGeometry(); 00097 IEvent &ievent = GetGraphicsDisplay()->GetCurrentEvent(); 00098 00099 int X = ievent.e_x; 00100 m_KeyboardHandler.CaretAutoScroll (ievent.e_x, ievent.e_y, base); 00101 00102 if ( ( (X < base.x) && (m_KeyboardHandler.GetCursorPosition() > 0) ) || 00103 ( (X > base.x + base.GetWidth() ) && (m_KeyboardHandler.GetCursorPosition() < m_KeyboardHandler.GetLength() ) ) ) 00104 { 00105 m_ScrollTimerHandler = GetTimer().AddTimerHandler (50, m_ScrollTimerFunctor, this); 00106 } 00107 else 00108 { 00109 GetTimer().RemoveTimerHandler (m_BlinkTimerHandler); 00110 m_ScrollTimerHandler = 0; 00111 } 00112 00113 // While the mouse is selecting the text, no blinking of cursor 00114 StopBlinkCursor (false); 00115 StartBlinkCursor (false); 00116 00117 QueueDraw(); 00118 } 00119 00120 void EditTextBox::BlinkCursorTimerInterrupt (void *v) 00121 { 00122 GetTimer().RemoveTimerHandler (m_BlinkTimerHandler); 00123 m_BlinkTimerHandler = GetTimer().AddTimerHandler (500, m_BlinkTimerFunctor, this); 00124 BlinkCursor = !BlinkCursor; 00125 QueueDraw(); 00126 } 00127 00128 void EditTextBox::StopBlinkCursor (bool BlinkState) 00129 { 00130 GetTimer().RemoveTimerHandler (m_BlinkTimerHandler); 00131 m_BlinkTimerHandler = 0; 00132 BlinkCursor = BlinkState; 00133 QueueDraw(); 00134 } 00135 00136 void EditTextBox::StartBlinkCursor (bool BlinkState) 00137 { 00138 m_BlinkTimerHandler = GetTimer().AddTimerHandler (500, m_BlinkTimerFunctor, this); 00139 BlinkCursor = BlinkState; 00140 QueueDraw(); 00141 } 00142 00143 void EditTextBox::SetValidator (const Validator *validator) 00144 { 00145 nuxAssert (validator != 0); 00146 delete m_Validator; 00147 m_Validator = validator->Clone(); 00148 } 00149 00150 long EditTextBox::ProcessEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00151 { 00152 long ret = TraverseInfo; 00153 ret = PostProcessEvent2 (ievent, ret, ProcessEventInfo); 00154 return ret; 00155 } 00156 00157 void EditTextBox::Draw (GraphicsEngine &GfxContext, bool force_draw) 00158 { 00159 Geometry base = GetGeometry(); 00160 00161 { 00162 GfxContext.PushClippingRectangle (base); 00163 00164 GetPainter().Paint2DQuadColor (GfxContext, base, Color (m_BackgroundColor) ); 00165 00166 if (HasKeyboardFocus() ) 00167 { 00168 00169 GetPainter().PaintColorTextLineEdit (GfxContext, GetGeometry(), 00170 m_KeyboardHandler.GetTextLine(), 00171 GetTextColor(), 00172 m_WriteAlpha, 00173 m_SelectedTextColor, 00174 m_SelectedTextBackgroundColor, 00175 m_TextBlinkColor, 00176 m_CursorColor, 00177 !BlinkCursor, 00178 m_KeyboardHandler.GetCursorPosition(), 00179 m_KeyboardHandler.GetPositionX(), 00180 m_KeyboardHandler.GetTextSelectionStart(), 00181 m_KeyboardHandler.GetTextSelectionEnd() 00182 ); 00183 } 00184 else 00185 { 00186 GetPainter().PaintTextLineStatic (GfxContext, GetFont (), GetGeometry(), 00187 m_KeyboardHandler.GetTextLine(), 00188 GetTextColor() ); 00189 } 00190 } 00191 GfxContext.PopClippingRectangle(); 00192 } 00193 00194 void EditTextBox::DrawContent (GraphicsEngine &GfxContext, bool force_draw) 00195 { 00196 00197 } 00198 00199 void EditTextBox::PostDraw (GraphicsEngine &GfxContext, bool force_draw) 00200 { 00201 00202 } 00203 00204 void EditTextBox::SetText (const TCHAR &Caption) 00205 { 00206 NString s (Caption); 00207 SetText (s); 00208 } 00209 00210 void EditTextBox::SetText (const TCHAR *Caption) 00211 { 00212 NString s (Caption); 00213 SetText (s); 00214 } 00215 00216 void EditTextBox::SetText (const tstring &Caption) 00217 { 00218 NString s (Caption); 00219 SetText (s); 00220 } 00221 00222 void EditTextBox::SetText (const NString &Caption) 00223 { 00224 NString s (Caption); 00225 s.RemovePrefix (m_Prefix); 00226 s.RemoveSuffix (m_Suffix); 00227 00228 if (ValidateKeyboardEntry (s.GetTCharPtr ())) 00229 { 00230 m_Text = (m_Prefix + s) + m_Suffix; 00231 m_KeyboardHandler.SetText (m_Text.GetTStringRef ()); 00232 m_temporary_caption = m_Text; 00233 sigSetText.emit (this); 00234 } 00235 00236 QueueDraw(); 00237 } 00238 00239 00240 const TCHAR *EditTextBox::GetText() const 00241 { 00242 return m_Text.GetTCharPtr(); 00243 } 00244 00246 NString EditTextBox::GetCleanText() const 00247 { 00248 NString CleanText (m_Text); 00249 CleanText.RemovePrefix (m_Prefix); 00250 CleanText.RemoveSuffix (m_Suffix); 00251 return CleanText.m_string; 00252 } 00253 00254 void EditTextBox::RecvMouseDoubleClick (int x, int y, unsigned long button_flags, unsigned long key_flags) 00255 { 00256 m_KeyboardHandler.SelectAllText(); 00257 QueueDraw(); 00258 } 00259 00260 void EditTextBox::RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags) 00261 { 00262 m_KeyboardHandler.MouseUp (x, y); 00263 00264 if (m_ScrollTimerHandler.IsValid() ) 00265 { 00266 GetTimer().RemoveTimerHandler (m_ScrollTimerHandler); 00267 m_ScrollTimerHandler = 0; 00268 } 00269 00270 QueueDraw(); 00271 } 00272 00273 void EditTextBox::RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags) 00274 { 00275 if (HasKeyboardFocus() == false) 00276 { 00277 // First mouse down 00278 m_KeyboardHandler.EnterFocus(); 00279 } 00280 else 00281 { 00282 // Second mouse down and more 00283 m_KeyboardHandler.UnselectAllText(); 00284 m_KeyboardHandler.MouseDown (x, y); 00285 00286 // Always make the cursor visible when a mouse down happens. 00287 StopBlinkCursor (false); 00288 StartBlinkCursor (false); 00289 } 00290 00291 QueueDraw(); 00292 } 00293 00294 void EditTextBox::RecvMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags) 00295 { 00296 Geometry base = GetGeometry(); 00297 00298 int X = x + base.x; 00299 00300 if ( (!m_ScrollTimerHandler.IsValid() ) && ( (X < base.x) || (X > base.x + base.GetWidth() ) ) ) 00301 { 00302 m_ScrollTimerHandler = GetTimer().AddTimerHandler (25, m_ScrollTimerFunctor, this); 00303 } 00304 else if ( (X >= base.x) && (X < base.x + base.GetWidth() ) ) 00305 { 00306 m_KeyboardHandler.MouseDrag (x, y); 00307 00308 // While the mouse is selecting the text, no blinking of cursor 00309 StopBlinkCursor (false); 00310 StartBlinkCursor (false); 00311 } 00312 00313 QueueDraw(); 00314 } 00315 00316 long EditTextBox::PostLayoutManagement (long LayoutResult) 00317 { 00318 long ret = View::PostLayoutManagement (LayoutResult); 00319 00320 m_KeyboardHandler.SetClipRegion (GetGeometry() ); 00321 return ret; 00322 } 00323 00324 00325 void EditTextBox::RecvKeyEvent ( 00326 unsigned long eventType , /*event type*/ 00327 unsigned long keysym , /*event keysym*/ 00328 unsigned long state , /*event state*/ 00329 const TCHAR* character , /*character*/ 00330 unsigned short keyCount /*key repeat count*/) 00331 { 00332 00333 if (eventType == NUX_KEYDOWN) 00334 text_input_mode_ = true; 00335 00336 m_KeyboardHandler.ProcessKey (eventType, keysym, state, character[0], GetGeometry() ); 00337 00338 00339 // When a key event happens, show the cursor. 00340 StopBlinkCursor (false); 00341 // Start a new blink cycle with the cursor originally visible. 00342 StartBlinkCursor (false); 00343 00344 if (character) 00345 { 00346 sigCharacter.emit (this, character[0]); 00347 sigEditChange.emit (this); 00348 } 00349 00350 if (keysym == NUX_VK_ENTER || keysym == NUX_KP_ENTER) 00351 { 00352 NString str (m_KeyboardHandler.GetTextLine() ); 00353 str.RemoveSuffix (m_Suffix); 00354 00355 if (ValidateKeyboardEntry (str.m_string.c_str() ) ) 00356 { 00357 m_Text = m_KeyboardHandler.GetTextLine(); 00358 m_temporary_caption = m_Text; 00359 sigValidateKeyboardEntry.emit (this, m_Text); 00360 sigValidateEntry.emit (this); 00361 m_KeyboardHandler.SelectAllText(); 00362 } 00363 else 00364 { 00365 m_Text = m_temporary_caption; 00366 m_KeyboardHandler.SetText (m_Text); 00367 m_KeyboardHandler.SelectAllText(); 00368 } 00369 } 00370 00371 if (keysym == NUX_VK_ESCAPE) 00372 { 00373 text_input_mode_ = false; 00374 } 00375 00376 QueueDraw(); 00377 } 00378 00379 bool EditTextBox::ValidateKeyboardEntry (const TCHAR *text) const 00380 { 00381 if (m_Validator) 00382 { 00383 if (m_Validator->Validate (text) == Validator::Acceptable) 00384 { 00385 return true; 00386 } 00387 else 00388 { 00389 return false; 00390 } 00391 } 00392 00393 return true; 00394 } 00395 00396 void EditTextBox::EscapeKeyboardFocus() 00397 { 00398 SetKeyboardFocus (false); 00399 // Revert back the caption text 00400 m_Text = m_temporary_caption; 00401 sigEscapeKeyboardFocus.emit (this); 00402 QueueDraw(); 00403 } 00404 00405 void EditTextBox::EnteringKeyboardFocus() 00406 { 00407 m_KeyboardHandler.SetText (m_Text.GetTStringRef() ); 00408 m_KeyboardHandler.SelectAllText(); 00409 // Preserve the current caption text. If ESC is pressed while we have keyboard focus then 00410 // the previous caption text is restored 00411 m_temporary_caption = m_Text; 00412 sigStartKeyboardFocus.emit (this); 00413 QueueDraw(); 00414 } 00415 00416 void EditTextBox::QuitingKeyboardFocus() 00417 { 00418 NString CleanText (m_KeyboardHandler.GetTextLine() ); 00419 CleanText.RemovePrefix (m_Prefix); 00420 CleanText.RemoveSuffix (m_Suffix); 00421 00422 if (ValidateKeyboardEntry (CleanText.GetTCharPtr() ) ) 00423 { 00424 CleanText = m_Prefix + CleanText; 00425 CleanText = CleanText + m_Suffix; 00426 00427 m_Text = CleanText.m_string; //m_KeyboardHandler.GetTextLine(); 00428 m_KeyboardHandler.SetText (CleanText.m_string); 00429 m_temporary_caption = m_Text; 00430 sigValidateKeyboardEntry.emit (this, m_Text.GetTStringRef() ); 00431 sigValidateEntry.emit (this); 00432 } 00433 else 00434 { 00435 m_Text = m_temporary_caption; 00436 m_KeyboardHandler.SetText (m_Text.GetTStringRef() ); 00437 m_KeyboardHandler.SelectAllText(); 00438 } 00439 00440 QueueDraw(); 00441 } 00442 00443 void EditTextBox::RecvStartKeyFocus() 00444 { 00445 key_nav_mode_ = true; 00446 text_input_mode_ = false; 00447 00448 EnteringKeyboardFocus(); 00449 m_BlinkTimerHandler = GetTimer().AddTimerHandler (500, m_BlinkTimerFunctor, this); 00450 } 00451 00452 void EditTextBox::RecvEndKeyFocus() 00453 { 00454 key_nav_mode_ = false; 00455 text_input_mode_ = false; 00456 00457 QuitingKeyboardFocus(); 00458 GetTimer().RemoveTimerHandler (m_BlinkTimerHandler); 00459 m_BlinkTimerHandler = 0; 00460 BlinkCursor = false; 00461 } 00462 00463 void EditTextBox::SetDoubleValue (double d) 00464 { 00465 SetText (NString::Printf ("%f", d) ); 00466 } 00467 00468 void EditTextBox::SetIntegerValue (int i) 00469 { 00470 SetText (NString::Printf ("%d", i) ); 00471 } 00472 00473 void EditTextBox::SetTextBackgroundColor (const Color &color) 00474 { 00475 m_BackgroundColor = color; 00476 QueueDraw(); 00477 } 00478 00479 Color EditTextBox::GetTextBackgroundColor() const 00480 { 00481 return m_BackgroundColor; 00482 } 00483 00484 bool EditTextBox::IsEmpty() 00485 { 00486 if (m_Text == TEXT ("") ) 00487 { 00488 return true; 00489 } 00490 00491 return false; 00492 } 00493 00494 bool EditTextBox::InspectKeyEvent(unsigned int eventType, 00495 unsigned int keysym, 00496 const char* character) 00497 { 00498 if ((eventType == NUX_KEYDOWN) && (key_nav_mode_ == true) && (text_input_mode_ == false)) 00499 { 00500 if (keysym == NUX_VK_ENTER || 00501 keysym == NUX_KP_ENTER || 00502 keysym == NUX_VK_UP || 00503 keysym == NUX_VK_DOWN || 00504 keysym == NUX_VK_LEFT || 00505 keysym == NUX_VK_RIGHT || 00506 keysym == NUX_VK_LEFT_TAB || 00507 keysym == NUX_VK_TAB) 00508 { 00509 return false; 00510 } 00511 } 00512 00513 if ((eventType == NUX_KEYDOWN) && (key_nav_mode_ == false) && (text_input_mode_ == false)) 00514 { 00515 return false; 00516 } 00517 00518 return true; 00519 } 00520 }