Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

CSTextarea.cpp

Go to the documentation of this file.
00001 #ifdef WIN32
00002 #pragma warning(disable : 4786 )
00003 #endif
00004 
00005 #include "CSTextarea.h"
00006 #include "CSBorder.h"
00007 #include "CSFont.h"
00008 #include "CSDesktop.h"
00009 #include "CSLAF.h"
00010 
00011 const char *CSTextarea::CLASS = "CSTextarea";
00012 
00013 CSTextarea::CSTextarea(int height, int width) : CSGrafikElement(height, width)
00014 {
00015     static char *functionName="CSTextarea";
00016     LOG_ENTER 
00017     init(""); 
00018     LOG_EXIT
00019 }
00020 
00021 CSTextarea::init(const std::string &text)
00022 {
00023     static char *functionName="init";
00024     LOG_ENTER 
00025     CSLAF *laf = CSLAF::getCurrentLAF();
00026     mCursorRate = laf->getCursorRate(); // 500 milliseconds
00027     
00028     mString = text;
00029     buildLines();
00030     mTickTimeNext = 0;
00031 
00032     mCursorX = 0;
00033     mCursorY = 0;
00034     mVerticalDisplayStart = 0;
00035     mVerticalDisplayEnd = 0;
00036     mVerticalDisplayLengthChar = 0;
00037     mHorizontalDisplayStart = 0;
00038     mHorizontalDisplayEnd = 0;
00039     mHorizontalDisplayLengthChar = 0;
00040     mExactCursorX = 0;
00041     mExactCursorY = 0;
00042     mIsEditable = true;
00043     mCursorShown = false;
00044     setEnabled(false);
00045 
00046     layoutSetup();
00047     LOG_EXIT
00048 }
00049 
00050 void CSTextarea::setText(const std::string text)
00051 {
00052     static char *functionName="setText";
00053     mString = text;
00054     buildLines();
00055 }
00056 
00057 void CSTextarea::buildLines()
00058 {
00059     static char *functionName="buildLines";
00060     mLines.add(mString);
00061 }
00062 
00063 void CSTextarea::buildString()
00064 {
00065     static char *functionName="buildString";
00066 }
00067 
00068 // position in viewport relation
00069 // in pixel relative to textarea!
00070 void CSTextarea::setGrafikCursor(int x, int y)
00071 {
00072     static char *functionName="setCursor";
00073     if (mCursorY>=0)
00074     {
00075         mLines.set(mCursorY, mWorkingString);
00076     }
00077 
00078     // height of one line in textarea
00079     int yAdd = getFont()->getHeight() + getVerticalElementSpacing();
00080     
00081     // holds the information in which line of the
00082     // text the blinking cursor at one time
00083     // resides (might therefor be larger than the number of lines displayed)
00084     mCursorY = y/yAdd + mVerticalDisplayStart;
00085     mExactCursorY = (mCursorY-mVerticalDisplayStart)*yAdd;
00086     mWorkingString = mLines.getString(mCursorY);
00087     
00088     const char *s=mWorkingString.c_str();
00089     char test[2];
00090     test[1]=0;
00091     mExactCursorX = getHorizontalElementSpacing(); 
00092     mCursorX = mHorizontalDisplayStart;
00093     if (mCursorX > mWorkingString.size())
00094     {
00095         mCursorX = mWorkingString.size();
00096         if (mCursorX > 0)
00097         {
00098             mHorizontalDisplayStart = mCursorX-1;
00099             mExactCursorX += getFont()->getWidth(" ");
00100         }
00101     }
00102     int horizontalDisplayLengthPixel = getViewportWidth()-(getHorizontalElementSpacing());
00103     while (mCursorX < mWorkingString.length())
00104     {
00105         test[0] = s[mCursorX];
00106         int size = getFont()->getWidth(test);
00107         if ((mExactCursorX + size > x) || (mExactCursorX + size > horizontalDisplayLengthPixel))
00108         {
00109             break;
00110         }
00111         mExactCursorX += size;
00112         mCursorX++;
00113     }
00114     if (mCursorX <0)
00115     {
00116         mCursorX = 0;
00117     }
00118 }
00119 
00120 // in characters relative to complete text
00121 void CSTextarea::setTextCursor(int x, int y)
00122 {
00123     static char *functionName="setCursor";
00124     if (mCursorY>=0)
00125     {
00126         mLines.set(mCursorY, mWorkingString);
00127     }
00128 
00129     int yAdd = getFont()->getHeight() + getVerticalElementSpacing();
00130     int xAdd = getFont()->getWidth(" ");
00131     mCursorY = y;
00132 
00133     /////////////////////////
00134     mVerticalDisplayLengthChar = getViewportHeight() / yAdd;
00135     if (mCursorY < mVerticalDisplayStart)
00136     {
00137         mVerticalDisplayStart = mCursorY;
00138         mVerticalDisplayEnd = mVerticalDisplayStart + mVerticalDisplayLengthChar;
00139         if (mVerticalDisplayEnd > mLines.getSize())
00140         {
00141             mVerticalDisplayEnd = mLines.getSize();
00142         }
00143     }
00144     mVerticalDisplayEnd = mVerticalDisplayStart + mVerticalDisplayLengthChar;
00145     if (mCursorY > mVerticalDisplayEnd-1)
00146     {
00147         mVerticalDisplayEnd = mCursorY+1;
00148         mVerticalDisplayStart = mVerticalDisplayEnd - (mVerticalDisplayLengthChar);
00149         if (mVerticalDisplayStart < 0)
00150         {
00151             mVerticalDisplayStart = 0;
00152         }
00153     }
00154     /////////////////////////
00155 
00156     mExactCursorY = (mCursorY-mVerticalDisplayStart)*yAdd;
00157     mWorkingString = mLines.getString(mCursorY);
00158     const char *s=mWorkingString.c_str();
00159     char test[2];
00160     test[1]=0;
00161     mExactCursorX = getHorizontalElementSpacing();
00162     int pos = 0;
00163     while ((pos < x) &&  (pos < mWorkingString.length()))
00164     {
00165         test[0] = s[pos];
00166         int size = getFont()->getWidth(test);
00167         mExactCursorX += size;
00168         pos++;
00169     }
00170     mCursorX = pos--;
00171 
00172     /////////////////////////
00173     mHorizontalDisplayLengthChar = (getViewportWidth()-(2*getHorizontalElementSpacing())) / xAdd;
00174     if (mCursorX < mHorizontalDisplayStart)
00175     {
00176         mHorizontalDisplayStart = mCursorX;
00177     }
00178     mHorizontalDisplayEnd = mHorizontalDisplayStart + mHorizontalDisplayLengthChar;
00179     if (mCursorX > mHorizontalDisplayEnd-1)
00180     {
00181         mHorizontalDisplayEnd = mCursorX+1;
00182         mHorizontalDisplayStart = mHorizontalDisplayEnd - (mHorizontalDisplayLengthChar);
00183         if (mHorizontalDisplayStart < 0)
00184         {
00185             mHorizontalDisplayStart = 0;
00186         }
00187     }
00188     /////////////////////////
00189     mExactCursorX = (mCursorX-mHorizontalDisplayStart)*xAdd + getHorizontalElementSpacing();
00190 }
00191 
00192 void CSTextarea::putString(SDL_Surface *destination, SDL_Rect *viewport, int x, int y, const std::string &string)
00193 {
00194     static char *functionName="putString";
00195     x += viewport->x;
00196     y += viewport->y;
00197     getFont()->putString(destination,x,y,getTextColor(), string);
00198 }
00199 
00200 void CSTextarea::paint(SDL_Surface *destination, SDL_Rect *parentViewport)
00201 {
00202     static char *functionName="paint";
00203     CSLAF *laf = CSLAF::getCurrentLAF();
00204     float currentTick = SDL_GetTicks() + mCursorRate;
00205     if (currentTick > mTickTimeNext)
00206     {
00207         mTickTimeNext = currentTick + mCursorRate;
00208         mCursorShown = !mCursorShown;
00209     }
00210 
00211     SDL_Rect thisViewportArea;
00212     thisViewportArea.x = parentViewport->x + getViewportX() + getX();
00213     thisViewportArea.y = parentViewport->y + getViewportY() + getY();
00214     thisViewportArea.h = getViewportHeight();
00215     thisViewportArea.w = getViewportWidth();
00216 
00217     int x = getHorizontalElementSpacing();
00218     int y = 0;
00219 
00220     int yAdd = getFont()->getHeight() + getVerticalElementSpacing();
00221     int xAdd = getFont()->getWidth(" ");
00222     
00223     mVerticalDisplayLengthChar = getViewportHeight() / yAdd;
00224     /////////////////////////
00225     if (mCursorY < mVerticalDisplayStart)
00226     {
00227         mVerticalDisplayStart = mCursorY;
00228         mVerticalDisplayEnd = mVerticalDisplayStart + mVerticalDisplayLengthChar;
00229         if (mVerticalDisplayEnd > mLines.getSize())
00230         {
00231             mVerticalDisplayEnd = mLines.getSize();
00232         }
00233     }
00234     mVerticalDisplayEnd = mVerticalDisplayStart + mVerticalDisplayLengthChar;
00235     if (mCursorY > mVerticalDisplayEnd-1)
00236     {
00237         mVerticalDisplayEnd = mCursorY+1;
00238         mVerticalDisplayStart = mVerticalDisplayEnd - (mVerticalDisplayLengthChar);
00239         if (mVerticalDisplayStart < 0)
00240         {
00241             mVerticalDisplayStart = 0;
00242         }
00243     }
00244     /////////////////////////
00245     /////////////////////////
00246     mHorizontalDisplayLengthChar = (getViewportWidth()-(2*(getHorizontalElementSpacing()))) / xAdd;
00247     if (mCursorX < mHorizontalDisplayStart)
00248     {
00249         mHorizontalDisplayStart = mCursorX;
00250         mHorizontalDisplayEnd = mHorizontalDisplayStart + mHorizontalDisplayLengthChar;
00251     }
00252     mHorizontalDisplayEnd = mHorizontalDisplayStart + mHorizontalDisplayLengthChar;
00253     if (mCursorX > mHorizontalDisplayEnd-1)
00254     {
00255         mHorizontalDisplayEnd = mCursorX+1;
00256         mHorizontalDisplayStart = mHorizontalDisplayEnd - (mHorizontalDisplayLengthChar);
00257         if (mHorizontalDisplayStart < 0)
00258         {
00259             mHorizontalDisplayStart = 0;
00260         }
00261     }
00262     /////////////////////////
00263 
00264     for (int i = mVerticalDisplayStart; i < mVerticalDisplayEnd; i++)
00265     {
00266         if (((i!= mCursorY) || (!getFocused())) || (!mIsEditable))
00267         {
00268             if (mLines.getString(i).size() >=mHorizontalDisplayStart)
00269             {
00270                 std::string t = mLines.getString(i).substr(mHorizontalDisplayStart, mHorizontalDisplayLengthChar);
00271                 putString(destination, &thisViewportArea, x, y, t);
00272 
00273             }
00274         }
00275         else
00276         {
00277             if (mWorkingString.size() >=mHorizontalDisplayStart)
00278             {
00279                 std::string t = mWorkingString.substr(mHorizontalDisplayStart, mHorizontalDisplayLengthChar);
00280                 putString(destination, &thisViewportArea, x, y, t);
00281             }
00282         }
00283         y += yAdd;
00284     }
00285 
00286     if ((getFocused() && (mCursorShown)) && (mIsEditable))
00287     {
00288         line(destination, &thisViewportArea, 
00289                 mExactCursorX, mExactCursorY, 
00290                 mExactCursorX, mExactCursorY+getFont()->getHeight(), 
00291                 laf->getTextAreaCursorColor());
00292     }
00293 }
00294 
00295 void CSTextarea::deleteCharAtPos(int p)
00296 {
00297     std::string t1 = mWorkingString.substr(0, p);
00298     std::string t2 = mWorkingString.substr(p+1, mWorkingString.length());
00299     mWorkingString = t1+t2;
00300 }
00301 
00302 void CSTextarea::insertCharAtPos(int p, char ch)
00303 {
00304     std::string t1 = mWorkingString.substr(0, p);
00305     std::string t2 = mWorkingString.substr(p, mWorkingString.length());
00306     mWorkingString = t1+ch+t2;
00307 }
00308 
00309 void CSTextarea::reactOnMessage(CSMessage *message)
00310 {
00311     reactOnMessageTextarea(message);
00312 }
00313 
00314 void CSTextarea::reactOnMessageTextarea(CSMessage *message)
00315 {
00316     static char *functionName="reactOnMessage";
00317     if (message->mIsHandled)
00318     {
00319         reactOnMessageGrafikElement(message);
00320         return;
00321     }
00322     switch (message->getType())
00323     {
00324         case GUI_MESSAGE:
00325         {
00326             GuiMessage *gm = (GuiMessage *) message;
00327             if (gm->receiver != this)
00328             {
00329                 break;
00330             }
00331             else // receiver == this
00332             {
00333                 switch (message->getSubtype())
00334                 {
00335                     case MOUSE_BUTTON_RELEASED_MESSAGE:
00336                     {
00337                         int x,y;
00338                         if (mIsEditable)
00339                         {
00340                             x = gm->receiverX;
00341                             y = gm->receiverY;
00342                             setGrafikCursor(x,y);
00343                             gm->mIsHandled = true;
00344                         }
00345                         break;
00346                     }
00347                     
00348                     case FOCUS_GAINED_MESSAGE:
00349                     {
00350                         if (mIsEditable)
00351                         {
00352                             setEnabled(true);
00353                             if (mCursorY>=0)
00354                             {
00355                                 mLines.set(mCursorY, mWorkingString);
00356                             }
00357                             gm->mIsHandled = true;
00358                         }
00359                         break;
00360                     }
00361                     
00362                     case FOCUS_LOST_MESSAGE:
00363                     {
00364                         if (mIsEditable)
00365                         {
00366                             setEnabled(false);
00367                         }
00368 
00369                         mWorkingString = mLines.getString(mCursorY);
00370                         gm->mIsHandled = true;
00371                         break;
00372                     }
00373                     
00374                     case KEY_RELEASED_MESSAGE:
00375                     {
00376                         gm->mIsHandled = false;
00377                         break;
00378                     }
00379 
00380                     case KEY_PRESSED_MESSAGE:
00381                     {
00382                         int ch=gm->keyUnicodeChar;
00383                         if (gm->keySymbolic == SDLK_TAB)
00384                         {
00385                             getDesktop()->focusedNextComponent();
00386                             gm->mIsHandled = true;
00387                             break;
00388                         }
00389                         if (gm->keySymbolic == SDLK_DELETE)
00390                         {
00391                             if (mCursorX<mWorkingString.length())
00392                             {
00393                                 deleteCharAtPos(mCursorX);
00394                                 setTextCursor(mCursorX, mCursorY);
00395                             }
00396                             else
00397                             {
00398                                 if (mCursorY<mLines.getSize())
00399                                 {
00400                                     mWorkingString += mLines.getString(mCursorY+1);
00401                                     mLines.remove(mCursorY+1);
00402                                     setTextCursor(mCursorX, mCursorY);
00403                                 }
00404                             }
00405                             gm->mIsHandled = true;
00406                             break;
00407                         }
00408 
00409                         if (gm->keySymbolic == SDLK_BACKSPACE)
00410                         {
00411                             if (mCursorX>0)
00412                             {
00413                                 deleteCharAtPos(mCursorX-1);
00414                                 setTextCursor(mCursorX-1, mCursorY);
00415                             }
00416                             else
00417                             {
00418                                 if (mCursorY>0)
00419                                 {
00420                                     setTextCursor(mCursorX, mCursorY-1);
00421                                     mCursorX = mWorkingString.length();
00422 
00423                                     mWorkingString += mLines.getString(mCursorY+1);
00424                                     mLines.remove(mCursorY+1);
00425                                     setTextCursor(mCursorX, mCursorY);
00426                                 }
00427                             }
00428                             gm->mIsHandled = true;
00429                             break;
00430                         }
00431                         if ((gm->keySymbolic == SDLK_RETURN) || (gm->keySymbolic == SDLK_KP_ENTER))
00432                         {
00433                             std::string t1 = mWorkingString.substr(0, mCursorX);
00434                             std::string t2 = mWorkingString.substr(mCursorX, mWorkingString.length()-t1.length());
00435                             mWorkingString = t1;
00436                             mLines.insert(mCursorY+1,t2);
00437                             mCursorX=0;
00438                             setTextCursor(mCursorX, mCursorY+1);
00439                             gm->mIsHandled = true;
00440                             break;
00441                         }
00442                         
00443                         if (gm->keySymbolic == SDLK_UP)
00444                         {
00445                             if (mCursorY>0)
00446                             {
00447                                 setTextCursor(mCursorX, mCursorY-1);
00448                             }
00449                             gm->mIsHandled = true;
00450                             break;
00451                         }
00452 
00453                         if (gm->keySymbolic == SDLK_DOWN)
00454                         {
00455                             if (mCursorY+1<mLines.getSize())
00456                             {
00457                                 setTextCursor(mCursorX, mCursorY+1);
00458                             }
00459                             gm->mIsHandled = true;
00460                             break;
00461                         }
00462 
00463                         if (gm->keySymbolic == SDLK_LEFT)
00464                         {
00465                             if (mCursorX>0)
00466                             {
00467                                 setTextCursor(mCursorX-1, mCursorY);
00468                             }
00469                             gm->mIsHandled = true;
00470                             break;
00471                         }
00472 
00473                         if (gm->keySymbolic == SDLK_RIGHT)
00474                         {
00475                             if (mCursorX<mWorkingString.length())
00476                             {
00477                                 setTextCursor(mCursorX+1, mCursorY);
00478                             }
00479                             gm->mIsHandled = true;
00480                             break;
00481                         }
00482 
00483                         if (gm->keySymbolic == SDLK_HOME)
00484                         {
00485                             setTextCursor(0, mCursorY);
00486                             gm->mIsHandled = true;
00487                             break;
00488                         }
00489 
00490                         if (gm->keySymbolic == SDLK_END)
00491                         {
00492                             setTextCursor(mWorkingString.length(), mCursorY);
00493                             gm->mIsHandled = true;
00494                             break;
00495                         }
00496                         if ((ch>31) && (ch<128)) 
00497                         {
00498                             int len = mWorkingString.length();
00499                             insertCharAtPos(mCursorX, ch);
00500                             setTextCursor(mCursorX+1, mCursorY);
00501                             gm->mIsHandled = true;
00502                             break;
00503                         }
00504 
00505                         break;
00506                     }
00507                     
00508                 }
00509             }                       
00510         }
00511     }
00512     reactOnMessageGrafikElement(message);
00513 }
00514 
00515 void CSTextarea::layoutSetupTextarea()
00516 {
00517     static char *functionName="layoutSetupTextarea";
00518     LOG_ENTER 
00519     CSLAF *laf = CSLAF::getCurrentLAF();
00520     mMinHeight = mHeight - getBorder()->getTotalHeight() - getInset().getTotalHeight();
00521     mMinWidth = mWidth - getBorder()->getTotalWidth() - getInset().getTotalWidth();
00522 
00523     LOG_EXIT
00524 }
00525 
00526 

Generated on Wed Jul 14 00:43:42 2004 for CSLib by doxygen 1.3.6