nux-1.16.0
KeyboardHandler.cpp
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 #include "KeyboardHandler.h"
00025 #include "Utils.h"
00026 #include "NuxGraphics/GraphicsEngine.h"
00027 #include "NuxCore/Win32Dialogs/NWin32Clipboard.h"
00028 
00029 namespace nux
00030 {
00031 
00032   t_s32 BaseKeyboardHandler::s_jump_offset_at_borders = 60;
00033   t_s32 BaseKeyboardHandler::s_cursor_width = 4;
00034 
00035   BaseKeyboardHandler::BaseKeyboardHandler()
00036   {
00037     m_text_positionx            = 0;
00038     m_text_positiony            = 0;
00039     m_previous_cursor_position  = 0;
00040     m_clip_region               = Rect (0, 0, 100, 20);
00041     m_KeyType                   = eAlphaNumeric;
00042     m_first_visible_char        = 0;
00043     m_mouse_drag                = false;
00044     m_mouse_inside_text_area    = true;
00045     m_entering_focus            = false;
00046     m_Font                      = GetSysFont();
00047 
00048     m_caret = m_selection_start = 0;
00049     m_insert_mode = true;
00050   }
00051 
00052   BaseKeyboardHandler::~BaseKeyboardHandler()
00053   {
00054   }
00055 
00056   void BaseKeyboardHandler::DeleteSelectionText()
00057   {
00058     t_s32 nFirst = Min (m_caret, m_selection_start);
00059     t_s32 nLast = Max (m_caret, m_selection_start);
00060     // Update caret and selection
00061     PlaceCaret (nFirst);
00062     m_selection_start = m_caret;
00063 
00064     // Remove the characters
00065     for (t_s32 i = nFirst; i < nLast; ++i)
00066       m_textline.Erase (nFirst, 1);
00067   }
00068 
00069   void BaseKeyboardHandler::InsertChar (t_u32 character)
00070   {
00071 
00072   }
00073 
00074   void BaseKeyboardHandler::ClearText()
00075   {
00076     m_text_positionx = 0;
00077     m_text_positiony = 0;
00078     m_caret = 0;
00079 
00080     m_previous_cursor_position = 0;
00081     m_textline.Clear();
00082   }
00083 
00084   void BaseKeyboardHandler::PlaceCaret (t_u32 nCP)
00085   {
00086     nuxAssert ( (nCP >= 0) && (nCP <= (t_u32) m_textline.Length() ) );
00087     m_previous_cursor_position = m_caret;
00088     m_caret = nCP;
00089   }
00090 
00091   t_u32 BaseKeyboardHandler::NextWordPosition (t_u32 cp)
00092   {
00093     t_u32 num_char = (t_u32) m_textline.Length();
00094 
00095     if (cp == num_char)
00096       return cp;
00097 
00098     t_u32 c = cp + 1;
00099 
00100     while (c < num_char - 1)
00101     {
00102       if ( ( m_textline[c] == TCHAR (' ') ) && (m_textline[c+1] != TCHAR (' ') ) )
00103         return c + 1;
00104 
00105       c++;
00106     }
00107 
00108     return num_char;
00109   }
00110 
00111   t_u32 BaseKeyboardHandler::PrevWordPosition (t_u32 cp)
00112   {
00113     if (cp == 0)
00114       return 0;
00115 
00116     t_u32 c = cp - 1;
00117 
00118     while (c > 1)
00119     {
00120       if ( ( m_textline[c] != TCHAR (' ') ) && (m_textline[c-1] == TCHAR (' ') ) )
00121         return c;
00122 
00123       c--;
00124     }
00125 
00126     return 0;
00127   }
00128 
00129   void BaseKeyboardHandler::MouseDown (t_s32 x, t_s32 y)
00130   {
00131     ResolveCaretPosition (x, y);
00132     m_mouse_drag = true;
00133     m_mouse_inside_text_area = true;
00134     m_entering_focus = false;
00135   }
00136 
00137   void BaseKeyboardHandler::MouseUp (t_s32 x, t_s32 y)
00138   {
00139     m_mouse_drag = false;
00140     m_entering_focus = false;
00141   }
00142 
00143   void BaseKeyboardHandler::MouseDrag (t_s32 x, t_s32 y)
00144   {
00145     if (m_entering_focus)
00146       return;
00147 
00148     ResolveCaretPosition (x, y);
00149     m_mouse_inside_text_area = true;
00150   }
00151 
00152   void BaseKeyboardHandler::EnterFocus()
00153   {
00154     m_entering_focus = true;
00155   }
00156 
00157   void BaseKeyboardHandler::ResolveCaretPosition (t_s32 x, t_s32 y)
00158   {
00159     if (m_entering_focus)
00160       return;
00161 
00162     if (m_textline.Length() == 0)
00163       return;
00164 
00165     t_u32 StrLength = (t_u32) m_textline.Length();
00166     t_s32 total = m_text_positionx;
00167     t_u32 nCP = StrLength;
00168 
00169     for (t_u32 i = 0; i < StrLength; i++)
00170     {
00171       t_u32 cw0 = GetFont ()->GetCharWidth (m_textline[i]);
00172       t_u32 cw1 = GetFont ()->GetCharWidth (m_textline[i+1]);
00173       {
00174         if (total == x)
00175         {
00176           nCP = i;
00177           break;
00178         }
00179         else if (x < total + (t_s32) cw0 / 2)
00180         {
00181           nCP = i;
00182           break;
00183         }
00184         else if (x < total + (t_s32) cw1 / 2)
00185         {
00186           // I don't quite understand why we need this???
00187           nCP = i + 1;
00188           break;
00189         }
00190       }
00191       total += cw0;
00192     }
00193 
00194     PlaceCaret (nCP);
00195 
00196     if (!m_mouse_drag)
00197     {
00198       m_selection_start = m_caret;
00199     }
00200   }
00201 
00202   void BaseKeyboardHandler::CaretAutoScroll (t_s32 x, t_s32 y, Geometry geo)
00203   {
00204     if (m_entering_focus)
00205       return;
00206 
00207     if (m_textline.Length() == 0)
00208       return;
00209 
00210     t_s32 StrLength = (t_s32) m_textline.Length();
00211 
00212     //nuxDebugMsg(TEXT("[BaseKeyboardHandler::ResolveCaretPosition]"));
00213     if (x < geo.x)
00214     {
00215       if (m_mouse_inside_text_area)
00216       {
00217         while (m_caret && (GetFont ()->GetCharStringWidth (m_textline.GetTCharPtr(), m_caret) + m_text_positionx > 0) )
00218         {
00219           --m_caret;
00220           //nuxDebugMsg(TEXT("Group Add: %c"), m_textline[m_caret]);
00221         }
00222 
00223         m_mouse_inside_text_area = false;
00224       }
00225       else if (m_caret)
00226       {
00227         --m_caret;
00228         //nuxDebugMsg(TEXT("Add Char: %c"), m_textline[m_caret]);
00229       }
00230       else
00231       {
00232         m_caret = 0;
00233       }
00234     }
00235     else if (x > geo.x + geo.GetWidth() )
00236     {
00237       if (m_mouse_inside_text_area)
00238       {
00239         while ( (m_caret != StrLength) && (GetFont ()->GetCharStringWidth (m_textline.GetTCharPtr(), m_caret) + m_text_positionx < geo.GetWidth() ) )
00240         {
00241           ++m_caret;
00242           //nuxDebugMsg(TEXT("Group Add: %c"), m_textline[m_caret-1]);
00243         }
00244 
00245         m_mouse_inside_text_area = false;
00246       }
00247       else if (m_caret < StrLength)
00248       {
00249         ++m_caret;
00250         //nuxDebugMsg(TEXT("Group Add: %c"), m_textline[m_caret-1]);
00251       }
00252       else
00253       {
00254         m_caret = StrLength;
00255       }
00256     }
00257 
00258     AdjustCursorAndTextPosition();
00259   }
00260 
00261   long BaseKeyboardHandler::ProcessKey (
00262     unsigned long    eventType    /*event type*/,
00263     unsigned long    keysym       /*event keysym*/,
00264     unsigned long    state        /*event state*/,
00265     TCHAR      character    /*character*/,
00266     const Geometry &g)
00267   {
00268     //if(ievent.event_type != I_AsciiKey && ievent.event_type != I_KeyPress && ievent.event_type != I_KeyRelease)
00269     if (eventType != NUX_KEYDOWN)
00270       return 0;
00271 
00272     m_need_redraw = true;
00273     //unsigned key = ievent.ascii_code;
00274     unsigned key = 0;
00275 
00276     if (character != 0)
00277       key = character;
00278 
00279     long virtual_code = keysym;
00280 
00281     if (key != 0)
00282     {
00283       switch (m_KeyType)
00284       {
00285         case eDecimalNumber:
00286         {
00287           // Check if Key code is in ".0123456789";
00288           // Be careful because WM_KEYDOWN and WM_KEYUP send a key value
00289           // that gets here. If key pad 0 is press/released, WM_KEYDOWN/WM_KEYUP will send key = key_kp0.
00290           // It is WM_CHAR who send key = 0x30 = '0'. Therefore, do not use strchr(".0123456789", key) to test
00291           // if key is a digit character. When using strchr(".0123456789", key_kp0) we get a positive result
00292           // and the result is unexpected.
00293           if ( (key >= TCHAR ('0') && key <= TCHAR ('9') ) || (key == TCHAR ('.') ) || (key == TCHAR ('-') ) || (key == TCHAR ('+') ) )
00294           {
00295             if ( m_caret != m_selection_start )
00296             {
00297               DeleteSelectionText();
00298             }
00299 
00300             // '-' and '+' can only be at position 0 of the number
00301             if ( (key == TCHAR ('-') ) || (key == TCHAR ('+') ) )
00302             {
00303               if ( (m_caret == 0) && (m_textline[0] != TCHAR ('+') ) && (m_textline[0] != TCHAR ('-') ) )
00304               {
00305                 // If we are in overwrite mode and there is already
00306                 // a char at the caret's position, simply replace it.
00307                 // Otherwise, we insert the char as normal.
00308                 if ( !m_insert_mode && m_caret < (t_s32) m_textline.Length() )
00309                 {
00310                   m_textline[m_caret] = key;
00311                   PlaceCaret (m_caret + 1 );
00312                   m_selection_start = m_caret;
00313                 }
00314                 else
00315                 {
00316                   // Insert the char
00317                   if ( m_caret <= (t_s32) m_textline.Length() )
00318                   {
00319                     m_textline.Insert (m_caret, 1, key);
00320                     PlaceCaret (m_caret + 1 );
00321                     m_selection_start = m_caret;
00322                   }
00323                 }
00324               }
00325             }
00326             else
00327             {
00328               // If we are in overwrite mode and there is already
00329               // a char at the caret's position, simply replace it.
00330               // Otherwise, we insert the char as normal.
00331               if ( !m_insert_mode && m_caret < (t_s32) m_textline.Length() )
00332               {
00333                 m_textline[m_caret] = key;
00334                 PlaceCaret (m_caret + 1 );
00335                 m_selection_start = m_caret;
00336               }
00337               else
00338               {
00339                 // Insert the char
00340                 if ( m_caret <= (t_s32) m_textline.Length() )
00341                 {
00342                   m_textline.Insert (m_caret, 1, key);
00343                   PlaceCaret (m_caret + 1 );
00344                   m_selection_start = m_caret;
00345                 }
00346               }
00347             }
00348           }
00349 
00350           break;
00351         }
00352         case eIntegerNumber:
00353         {
00354           // Check if Key code is in "0123456789";
00355           if ( (key >= TCHAR ('0') && key <= TCHAR ('9') ) || (key == TCHAR ('-') ) || (key == TCHAR ('+') ) )
00356           {
00357             if ( m_caret != m_selection_start )
00358             {
00359               DeleteSelectionText();
00360             }
00361 
00362             // '-' and '+' can only be at position 0 of the number
00363             if ( (key == TCHAR ('-') ) || (key == TCHAR ('+') ) )
00364             {
00365               // If we are in overwrite mode and there is already
00366               // a char at the caret's position, simply replace it.
00367               // Otherwise, we insert the char as normal.
00368               if (!m_insert_mode && (m_caret < (t_s32) m_textline.Length() ) )
00369               {
00370                 m_textline[m_caret] = key;
00371                 PlaceCaret (m_caret + 1 );
00372                 m_selection_start = m_caret;
00373               }
00374               else
00375               {
00376                 // Insert the char
00377                 if ( m_caret <= (t_s32) m_textline.Length() )
00378                 {
00379                   m_textline.Insert (m_caret, 1, key);
00380                   PlaceCaret (m_caret + 1 );
00381                   m_selection_start = m_caret;
00382                 }
00383               }
00384             }
00385             else
00386             {
00387               // If we are in overwrite mode and there is already
00388               // a char at the caret's position, simply replace it.
00389               // Otherwise, we insert the char as normal.
00390               if (!m_insert_mode && (m_caret < (t_s32) m_textline.Length() ) )
00391               {
00392                 m_textline[m_caret] = key;
00393                 PlaceCaret (m_caret + 1 );
00394                 m_selection_start = m_caret;
00395               }
00396               else
00397               {
00398                 // Insert the char
00399                 if (m_caret <= (t_s32) m_textline.Length() )
00400                 {
00401                   m_textline.Insert (m_caret, 1, key);
00402                   PlaceCaret (m_caret + 1 );
00403                   m_selection_start = m_caret;
00404                 }
00405               }
00406             }
00407           }
00408 
00409           break;
00410         }
00411 
00412         case eHexadecimalNumber:
00413         {
00414           if ( (key >= TCHAR ('0') && key <= TCHAR ('9') ) || (key >= TCHAR ('a') && key <= TCHAR ('f') ) || (key >= TCHAR ('A') && key <= TCHAR ('F') ) || (key == TCHAR ('-') ) || (key == TCHAR ('+') ) )
00415             //if(strchr("0123456789abcdefABCDEF", key))
00416           {
00417             if (m_caret != m_selection_start)
00418             {
00419               DeleteSelectionText();
00420             }
00421 
00422             // If we are in overwrite mode and there is already
00423             // a char at the caret's position, simply replace it.
00424             // Otherwise, we insert the char as normal.
00425             if (!m_insert_mode && (m_caret < (t_s32) m_textline.Length() ) )
00426             {
00427               m_textline[m_caret] = key;
00428               PlaceCaret (m_caret + 1 );
00429               m_selection_start = m_caret;
00430             }
00431             else
00432             {
00433               // Insert the char
00434               if (m_caret <= (t_s32) m_textline.Length() )
00435               {
00436                 m_textline.Insert (m_caret, 1, key);
00437                 PlaceCaret (m_caret + 1 );
00438                 m_selection_start = m_caret;
00439               }
00440             }
00441 
00442           }
00443 
00444           break;
00445         }
00446 
00447         case eBinaryNumber:
00448         {
00449           //if(strchr("01", key))
00450           if ( (key >= TCHAR ('0') && key <= TCHAR ('1') ) )
00451           {
00452             if ( m_caret != m_selection_start )
00453             {
00454               DeleteSelectionText();
00455             }
00456 
00457             // If we are in overwrite mode and there is already
00458             // a char at the caret's position, simply replace it.
00459             // Otherwise, we insert the char as normal.
00460             if (!m_insert_mode && (m_caret < (t_s32) m_textline.Length() ) )
00461             {
00462               m_textline[m_caret] = key;
00463               PlaceCaret (m_caret + 1 );
00464               m_selection_start = m_caret;
00465             }
00466             else
00467             {
00468               // Insert the char
00469               if (m_caret <= (t_s32) m_textline.Length() )
00470               {
00471                 m_textline.Insert (m_caret, 1, key);
00472                 PlaceCaret (m_caret + 1 );
00473                 m_selection_start = m_caret;
00474               }
00475             }
00476           }
00477 
00478           break;
00479         }
00480 
00481         case eAlphaNumeric:
00482         default:
00483         {
00484           if (key > 0x1F && key < 0x7f)
00485           {
00486             if (m_caret != m_selection_start)
00487             {
00488               DeleteSelectionText();
00489             }
00490 
00491             // If we are in overwrite mode and there is already
00492             // a char at the caret's position, simply replace it.
00493             // Otherwise, we insert the char as normal.
00494             if (!m_insert_mode && (m_caret < (t_s32) m_textline.Length() ) )
00495             {
00496               m_textline[m_caret] = key;
00497               PlaceCaret (m_caret + 1 );
00498               m_selection_start = m_caret;
00499             }
00500             else
00501             {
00502               // Insert the char
00503               if (m_caret <= (t_s32) m_textline.Length() )
00504               {
00505                 m_textline.Insert (m_caret, 1, key);
00506                 PlaceCaret (m_caret + 1 );
00507                 m_selection_start = m_caret;
00508               }
00509             }
00510 
00511           }
00512 
00513           break;
00514         }
00515       }
00516     }
00517 
00518     // CTRL+C
00519     if ( (virtual_code == NUX_VK_C) && (state & NUX_STATE_CTRL) )
00520     {
00521       NString s = GetSelectedText();
00522 #if defined(NUX_OS_WINDOWS)
00523       inlCopyTextToClipboard (s.GetTCharPtr() );
00524 #endif
00525     }
00526 
00527     // CTRL+V
00528     if ( (virtual_code == NUX_VK_V) && (state & NUX_STATE_CTRL) )
00529     {
00530 #if defined(NUX_OS_WINDOWS)
00531       NString s = inlReadTextToClipboard();
00532 #elif defined(NUX_OS_LINUX)
00533       NString s = "Paste not implemented yet";
00534 #endif
00535       t_u32 start = GetTextSelectionStart();
00536       t_u32 end = GetTextSelectionEnd();
00537       m_textline.Replace (start, end - start, s.m_string);
00538 
00539       m_caret = start + (t_u32) s.Length();
00540       UnselectAllText();
00541     }
00542 
00543     if ( (virtual_code == NUX_VK_ESCAPE) )
00544     {
00545       // If Text is selected, Unselect
00546       UnselectAllText();
00547     }
00548 
00549     if ( (virtual_code == NUX_VK_ENTER) )
00550     {
00551       SelectAllText();
00552     }
00553 
00554     if (virtual_code == NUX_VK_BACKSPACE)
00555     {
00556       if ( m_caret != m_selection_start )
00557       {
00558         DeleteSelectionText();
00559       }
00560       else
00561       {
00562         // Deleting one character
00563         if ( m_caret > 0 )
00564         {
00565           m_textline.Erase (m_caret - 1, 1);
00566           PlaceCaret (m_caret - 1 );
00567 
00568           m_selection_start = m_caret;
00569         }
00570       }
00571     }
00572     else if (virtual_code == NUX_VK_DELETE)
00573     {
00574       // Check if there is a text selection.
00575       if ( m_caret != m_selection_start )
00576       {
00577         DeleteSelectionText();
00578       }
00579       else
00580       {
00581         // Deleting one character
00582         if (m_caret < (t_s32) m_textline.Length() )
00583         {
00584           m_textline.Erase (m_caret, 1);
00585         }
00586       }
00587     }
00588     else if (virtual_code == NUX_VK_LEFT)
00589     {
00590       if (IsTextSelected() && ( (state & NUX_STATE_SHIFT) == 0) )
00591       {
00592         //m_caret = Min(m_caret, m_selection_start);
00593         if (m_caret)
00594           --m_caret;
00595 
00596         UnselectAllText();
00597       }
00598       else
00599       {
00600         if ( state & NUX_STATE_CTRL )
00601         {
00602           // Control is down. Move the caret to a new item
00603           // instead of a character.
00604           m_caret = PrevWordPosition ( m_caret);
00605           PlaceCaret (m_caret );
00606         }
00607         else if ( m_caret > 0 )
00608           PlaceCaret (m_caret - 1 );
00609 
00610         if ( (state & NUX_STATE_SHIFT) == 0)
00611         {
00612           // Shift is not down. Update selection
00613           // start along with the caret.
00614           m_selection_start = m_caret;
00615         }
00616       }
00617     }
00618     else if (virtual_code == NUX_VK_RIGHT)
00619     {
00620       if (IsTextSelected() && ( (state & NUX_STATE_SHIFT) == 0) )
00621       {
00622         m_caret = Max (m_caret, m_selection_start);
00623         UnselectAllText();
00624       }
00625       else
00626       {
00627         if ( state & NUX_STATE_CTRL)
00628         {
00629           // Control is down. Move the caret to a new item
00630           // instead of a character.
00631           m_caret = NextWordPosition ( m_caret);
00632           PlaceCaret (m_caret );
00633         }
00634         else if (m_caret < (t_s32) m_textline.Length() )
00635           PlaceCaret (m_caret + 1 );
00636 
00637         if ( (state & NUX_STATE_SHIFT) == 0)
00638         {
00639           // Shift is not down. Update selection
00640           // start along with the caret.
00641           m_selection_start = m_caret;
00642         }
00643       }
00644     }
00645     else if (virtual_code == NUX_VK_HOME)
00646     {
00647       if ( (state & NUX_STATE_SHIFT) == 0)
00648       {
00649         PlaceCaret (0);
00650         // Shift is not down. Update selection
00651         // start along with the caret.
00652         m_selection_start = m_caret;
00653       }
00654       else
00655       {
00656         PlaceCaret (0 );
00657       }
00658     }
00659     else if (virtual_code == NUX_VK_END)
00660     {
00661       if ( (state & NUX_STATE_SHIFT) == 0)
00662       {
00663         PlaceCaret ( (t_u32) m_textline.Length() );
00664         // Shift is not down. Update selection
00665         // start along with the caret.
00666         m_selection_start = m_caret;
00667       }
00668       else
00669       {
00670         PlaceCaret ( (t_u32) m_textline.Length() );
00671       }
00672     }
00673     else if (virtual_code == NUX_VK_ESCAPE)
00674     {
00675       return virtual_code;
00676     }
00677     else if ( (virtual_code == NUX_VK_ENTER))
00678     {
00679       return virtual_code;
00680     }
00681     else
00682     {
00683       m_need_redraw = false;
00684     }
00685 
00686     if (virtual_code == NUX_VK_HOME)
00687     {
00688       m_text_positionx = 0;
00689     }
00690     else if (virtual_code == NUX_VK_END)
00691     {
00692       t_u32 str_width = GetFont ()->GetStringWidth (m_textline.GetTCharPtr() );
00693 
00694       if (str_width + s_cursor_width > (t_u32) m_clip_region.GetWidth() )
00695         m_text_positionx = m_clip_region.GetWidth() - (str_width + s_cursor_width);
00696       else
00697         m_text_positionx = 0;
00698     }
00699     else if (m_textline.Length() != 0)
00700     {
00701       AdjustCursorAndTextPosition();
00702       m_need_redraw = true;
00703     }
00704     else if (m_textline.Length() == 0)
00705     {
00706       ClearText();
00707       m_need_redraw = true;
00708     }
00709 
00710 
00711     return virtual_code;
00712   }
00713 
00714   void BaseKeyboardHandler::AdjustCursorAndTextPosition()
00715   {
00716     t_s32 str_width = GetFont ()->GetStringWidth (m_textline.GetTCharPtr() );
00717     NString temp0;
00718 
00719     if (m_caret > 0)
00720       temp0 = m_textline.GetSubString (0, m_caret - 1).GetTStringRef();
00721     else
00722       temp0 = TEXT ("");
00723 
00724     //      0          1         2
00725     //      01234567|8901234567890123456789
00726     //      abcdefgh|ijklmn
00727     //
00728     //      Caret pos = 8
00729     //      temp0 = "abcdefg"
00730     //      temp1 = "abcdefgh"
00731     //      temp2 = "abcdefghi"
00732 
00733     NString temp1 = m_textline.GetSubString (0, m_caret).GetTStringRef();
00734     NString temp2 = m_textline.GetSubString (0, m_caret + 1).GetTStringRef();
00735     t_s32 str_width0 = GetFont ()->GetStringWidth (temp0);
00736     t_s32 str_width1 = GetFont ()->GetStringWidth (temp1);
00737     t_s32 str_width2 = GetFont ()->GetStringWidth (temp2);
00738 
00739 
00740     if ( (m_text_positionx + str_width1 + s_cursor_width) > m_clip_region.GetWidth() )
00741     {
00742       // Hitting the end of the text box
00743       if (m_caret == (t_s32) m_textline.Length() )
00744       {
00745         m_text_positionx = - (str_width + (t_s32) s_cursor_width - m_clip_region.GetWidth() );
00746       }
00747       else
00748       {
00749         t_s32 PreviousCharWidth = str_width1 - str_width0;
00750         t_s32 Offset = Min<t_s32> (s_jump_offset_at_borders, str_width + s_cursor_width - str_width1);
00751 
00752         while (Offset > m_clip_region.GetWidth() )
00753         {
00754           Offset /= 2;
00755         }
00756 
00757         if (Offset < PreviousCharWidth)
00758           Offset = PreviousCharWidth;
00759 
00760         m_text_positionx -= Offset;
00761 
00762         if (m_text_positionx + str_width + s_cursor_width < (t_s32) m_clip_region.GetWidth() )
00763         {
00764           m_text_positionx = - (str_width + (t_s32) s_cursor_width - m_clip_region.GetWidth() );
00765         }
00766       }
00767     }
00768     else if ( (m_text_positionx + str_width1) <= 0)
00769     {
00770       // Hitting the start of the text box
00771       if (m_caret == 0)
00772       {
00773         m_text_positionx = 0;
00774       }
00775       else
00776       {
00777         t_s32 NextCharWidth = str_width2 - str_width1;
00778         t_s32 Offset = Min<t_s32> (s_jump_offset_at_borders, str_width1);
00779 
00780         while (Offset > m_clip_region.GetWidth() )
00781         {
00782           Offset /= 2;
00783         }
00784 
00785         if (Offset < NextCharWidth)
00786           Offset = NextCharWidth;
00787 
00788         if (Offset > str_width1)
00789         {
00790           m_text_positionx = 0;
00791           return;
00792         }
00793 
00794         m_text_positionx += Offset;
00795 
00796         if (m_text_positionx > 0)
00797         {
00798           m_text_positionx = 0;
00799         }
00800       }
00801     }
00802   }
00803 
00804   void BaseKeyboardHandler::MoveCursorAtStart()
00805   {
00806     m_previous_cursor_position = m_caret;
00807     m_caret  = 0;
00808   }
00809   void BaseKeyboardHandler::MoveCursorAtEnd()
00810   {
00811     t_u32 StrLength = ( t_u32) m_textline.Length();
00812     m_previous_cursor_position = m_caret;
00813     m_caret = StrLength;
00814   }
00815 
00816   void BaseKeyboardHandler::SetKeyEntryType (BaseKeyboardHandler::eKeyEntryType keytype)
00817   {
00818     m_KeyType = keytype;
00819   }
00820 
00821   BaseKeyboardHandler::eKeyEntryType BaseKeyboardHandler::GetKeyEntryType()
00822   {
00823     return m_KeyType;
00824   }
00825 
00826   void BaseKeyboardHandler::SetText (const TCHAR *str)
00827   {
00828     m_textline = str;
00829     // Every time we set the text, we reposition the cursor at the beginning of the text,
00830     // and the text position is set to zero with regard to the start of the geometry area.
00831     MoveCursorAtStart();
00832     m_selection_start = Min<t_s32> (m_selection_start, (t_s32) StringLength (str) );
00833     m_caret = Min<t_s32> (m_caret, (t_s32) StringLength (str) );
00834 
00835     if (m_caret < m_selection_start)
00836       m_selection_start = Max<t_s32> (m_selection_start, (t_s32) StringLength (str) );
00837     else if (m_caret > m_selection_start)
00838       m_caret = Max<t_s32> (m_caret, (t_s32) StringLength (str) );
00839 
00840     m_text_positionx = 0;
00841   }
00842 
00843   void BaseKeyboardHandler::SetText (const tstring &s)
00844   {
00845     SetText (s.c_str() );
00846   }
00847 
00848   void BaseKeyboardHandler::SetText (const NString &s)
00849   {
00850     SetText (s.GetTCharPtr() );
00851   }
00852 
00853   void BaseKeyboardHandler::SetClipRegion (const Geometry &g)
00854   {
00855     m_clip_region = g;
00856   }
00857 
00858   void BaseKeyboardHandler::GetTextSelection (t_s32 *start, t_s32 *end) const
00859   {
00860     *start = Min (m_selection_start, m_caret);
00861     *end = Max (m_selection_start, m_caret);
00862   }
00863 
00864   t_s32 BaseKeyboardHandler::GetTextSelectionStart() const
00865   {
00866     return Min (m_selection_start, m_caret);
00867   }
00868 
00869   t_s32 BaseKeyboardHandler::GetTextSelectionEnd() const
00870   {
00871     return Max (m_selection_start, m_caret);
00872   }
00873 
00874   void BaseKeyboardHandler::SelectAllText()
00875   {
00876     m_selection_start = 0;
00877     m_caret = (t_u32) m_textline.Length();
00878     AdjustCursorAndTextPosition();
00879   }
00880 
00881   void BaseKeyboardHandler::UnselectAllText()
00882   {
00883     m_selection_start = m_caret;
00884   }
00885 
00886   NString BaseKeyboardHandler::GetSelectedText() const
00887   {
00888     if (m_selection_start == m_caret)
00889     {
00890       return NString (TEXT ("") );
00891     }
00892     else
00893     {
00894       NString s = m_textline.GetSubString (GetTextSelectionStart(), GetTextSelectionEnd() - GetTextSelectionStart() ).GetTStringRef();
00895       return s;
00896     }
00897   }
00898 
00899   bool BaseKeyboardHandler::IsTextSelected()
00900   {
00901     if (m_caret != m_selection_start)
00902       return true;
00903 
00904     return false;
00905   }
00906 
00907   void BaseKeyboardHandler::SetFont (ObjectPtr<FontTexture> Font)
00908   {
00909     m_Font = Font;
00910   }
00911 
00912   ObjectPtr<FontTexture> BaseKeyboardHandler::GetFont () const
00913   {
00914     return m_Font;
00915   }
00916 
00917 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends