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

CSHTMLElement.cpp

Go to the documentation of this file.
00001 
00002 // next todo:
00003 // try to display only the stuff that might actually go on the screen
00004 // (Performance upgrade tha is)
00005 
00006 
00007 // html only with grafik elements -> than table!
00008 
00009 #ifdef WIN32
00010 #pragma warning(disable : 4786 )
00011 #endif
00012 
00013 #include "CSHTMLElement.h"
00014 #include "CSFont.h"
00015 #include "CSDesktop.h"
00016 #include "CSWindow.h"
00017 #include "CSLAF.h"
00018 #include "CSScrollbar.h"
00019 #include "CSHelper.h"
00020 
00021 const char *HTMLElement::CLASS = "HTMLElement";
00022 
00023 HTMLElement::HTMLElement(CSHTMLNode node)
00024 {
00025     mNode = node;
00026     mParent = 0;
00027     mPositionsStored = false;
00028     CSHTMLNode child = mNode.firstChild();
00029     while (!child.isEmpty())
00030     {
00031         HTMLElement * nextChild = new HTMLElement(child);
00032         nextChild->setParent(this);
00033         mElements.push_back(nextChild);
00034         child = mNode.nextChild();
00035     }
00036 
00037     // we all listen to screen changes, since images must be updated!
00038     // the compilation information is corrupt, when some 
00039     // instance have no compilation (all or nothing), (BODY TAG e.g. is not
00040     // sat anymore, if first tag is an image and only images are cleared!)
00041 
00042     // if this is switched on, upon toggle screen -> the program
00043     // crashes -> unkown!!!
00044 //CSA SDLMain::getInstance()->addMessageListener(this, SDL_MESSAGE);
00045 }
00046 
00047 HTMLElement::~HTMLElement()
00048 {
00049     clearPosition();
00050     clearCompiled();
00051     HTMLElements::iterator iter = mElements.begin();
00052     while (iter != mElements.end())
00053     {
00054         HTMLElement *element = *iter;
00055         mElements.erase(iter);
00056         delete element;
00057         iter = mElements.begin();
00058     }
00059 }
00060 
00061 void HTMLElement::clearPosition()
00062 {
00063     HTMLElements::iterator eiter;
00064     for (eiter = mElements.begin(); eiter != mElements.end(); eiter++)
00065     {
00066         HTMLElement *element = *eiter;
00067         element->clearPosition();
00068     }
00069 
00070     Positions::iterator iter = mPositions.begin();
00071     while (iter != mPositions.end())
00072     {
00073         SDL_Rect *rect = *iter;
00074         mPositions.erase(iter);
00075         delete (rect);
00076         iter = mPositions.begin();
00077     }
00078     mPositionsStored = false;
00079 }
00080 
00081 void HTMLElement::clearCompiled()
00082 {
00083 }
00084 
00085 HTMLElement *HTMLElement::getAncestorType(int type)
00086 {
00087     HTMLElement *parent = getParent();
00088     while (parent)
00089     {
00090         if (parent->getTagType() == type)
00091         {
00092             return parent;
00093         }
00094         parent = parent->getParent();
00095     }
00096     return 0;
00097 }
00098 
00099 int HTMLElement::getTagType()
00100 {
00101     return getTagType(mNode);
00102 }
00103 
00104 // all Tag types are mapped here from their string representation to a
00105 // numerical value, see "CSHTMLarea.h" for their definition
00106 // static function - therefor "mHTMLTagMap" is never freed!
00107 HTMLTagMap *HTMLElement::mHTMLTagMap = 0;
00108 
00109 int HTMLElement::getTagType(CSHTMLNode &node)
00110 {
00111     if (mHTMLTagMap == 0)
00112     {
00113         mHTMLTagMap = new HTMLTagMap();
00114         mHTMLTagMap->insert(HTMLTagMap::value_type("HTML", HTML_HTML));
00115         mHTMLTagMap->insert(HTMLTagMap::value_type("HEAD", HTML_HEAD));
00116         mHTMLTagMap->insert(HTMLTagMap::value_type("TITLE", HTML_TITLE));
00117         mHTMLTagMap->insert(HTMLTagMap::value_type("BODY", HTML_BODY));
00118         mHTMLTagMap->insert(HTMLTagMap::value_type("H1", HTML_H1));
00119         mHTMLTagMap->insert(HTMLTagMap::value_type("H2", HTML_H2));
00120         mHTMLTagMap->insert(HTMLTagMap::value_type("H3", HTML_H3));
00121         mHTMLTagMap->insert(HTMLTagMap::value_type("H4", HTML_H4));
00122         mHTMLTagMap->insert(HTMLTagMap::value_type("H5", HTML_H5));
00123         mHTMLTagMap->insert(HTMLTagMap::value_type("P", HTML_P));
00124         mHTMLTagMap->insert(HTMLTagMap::value_type("BR", HTML_BR));
00125         mHTMLTagMap->insert(HTMLTagMap::value_type("HL", HTML_HL));
00126         mHTMLTagMap->insert(HTMLTagMap::value_type("PRE", HTML_PRE));
00127         mHTMLTagMap->insert(HTMLTagMap::value_type("IMG", HTML_IMG));
00128         mHTMLTagMap->insert(HTMLTagMap::value_type("A", HTML_A));
00129         mHTMLTagMap->insert(HTMLTagMap::value_type("B", HTML_B));
00130         mHTMLTagMap->insert(HTMLTagMap::value_type("I", HTML_I));
00131         mHTMLTagMap->insert(HTMLTagMap::value_type("DD", HTML_DD));
00132         mHTMLTagMap->insert(HTMLTagMap::value_type("DL", HTML_DL));
00133         mHTMLTagMap->insert(HTMLTagMap::value_type("DT", HTML_DT));
00134         mHTMLTagMap->insert(HTMLTagMap::value_type("UL", HTML_UL));
00135         mHTMLTagMap->insert(HTMLTagMap::value_type("OL", HTML_OL));
00136 
00137         mHTMLTagMap->insert(HTMLTagMap::value_type("TABLE", HTML_TABLE));
00138         mHTMLTagMap->insert(HTMLTagMap::value_type("TR", HTML_TR));
00139         mHTMLTagMap->insert(HTMLTagMap::value_type("TH", HTML_TH));
00140         mHTMLTagMap->insert(HTMLTagMap::value_type("TT", HTML_TT));
00141     }
00142     std::string tag = node.getTag();
00143     if (tag.size() != 0)
00144     {
00145         HTMLTagMap::iterator iter = mHTMLTagMap->find(tag);
00146         if (iter != mHTMLTagMap->end())
00147         {
00148             return iter->second;
00149         }
00150     }
00151     return 0;
00152 }
00153 
00154 // tokenify text in handable parts (only ASCII)
00155 // token seperator is " ", "\n" and "\t"
00156 // static function!
00157 StringVector *HTMLElement::tokenifyText(const std::string &text)
00158 {
00159     StringVector *tokens = new StringVector();
00160     char *copy = strdup(text.c_str());
00161     char *tmp = copy;
00162     
00163     char *pointerToWord = strtok( copy, " \n\t");
00164     while (pointerToWord != 0)
00165     {
00166         tokens->push_back(strdup(pointerToWord));
00167         pointerToWord = strtok( 0, " \n\t");
00168     }
00169     free(tmp);
00170     return tokens;
00171 }
00172 
00173 // returns for an html tag all children in form as text only
00174 // not really needed, just for convenience for the /TITLE/ TAG
00175 std::string HTMLElement::getChildrenAsText()
00176 {
00177     std::string text="";
00178     HTMLElements::iterator iter;
00179     for (iter = mElements.begin(); iter != mElements.end(); iter++)
00180     {
00181         HTMLElement *element = *iter;
00182         if (element->mNode.isText())
00183         {
00184             text = text + element->mNode.getValue();
00185         }
00186         text = text + element->getChildrenAsText();
00187     }
00188     return text;
00189 }
00190 
00191 // get a child that has a given type, a given attribute and a given attribute value
00192 // used to get to html ankers
00193 // if either (or both) the attribute parameters are empty, the
00194 // first child node of the kind "type" is returned (used to get the first BODY tag...)
00195 HTMLElement *HTMLElement::getChildType(int type, std::string attributeName, std::string attributeValue)
00196 {
00197     HTMLElements::iterator iter;
00198     for (iter = mElements.begin(); iter != mElements.end(); iter++)
00199     {
00200         HTMLElement *element = *iter;
00201         if (element->getTagType() == type)
00202         {
00203             if ((attributeName.size() == 0) || (attributeValue.size == 0))
00204             {
00205                 return element;
00206             }
00207             std::string elementAttributeValue = element->getAttributValue(attributeName);
00208             if (elementAttributeValue.compare(attributeValue) == 0)
00209             {
00210                 return element;
00211             }
00212         }
00213         HTMLElement *childResult = element->getChildType(type, attributeName, attributeValue);
00214         if (childResult)
00215         {
00216             return childResult;
00217         }
00218     }
00219     return 0;
00220 }
00221 
00222 // yet to be done... for now only straight and correkt "files" are handled!
00223 std::string HTMLElement::formatURL(const std::string &rawURL)
00224 {
00225     return rawURL;
00226 }
00227 
00228 // get the value of an attribute for this given node
00229 std::string HTMLElement::getAttributValue(std::string attributeName)
00230 {
00231     return mNode.attributValue(attributeName);
00232 }
00233 
00234 // translates strings of kind "#f0f0f0" into an integer value
00235 // convert is a helper function to be found in CSHelper
00236 int HTMLElement::getColorFromString(std::string acolor)
00237 {
00238     if (acolor.size()<= 0)
00239     {
00240         return -1;
00241     }
00242     int posStart = strstr(acolor.c_str(), "#") - acolor.c_str()+1;
00243     std::string v = acolor.substr(posStart, acolor.size()-posStart);
00244     int value = CSHelper::convert(v.c_str(), 16);
00245     return value;
00246 }
00247 
00248 // if surface is 0, the cursor only counts the
00249 // space needed for displaying with the current given viewport!
00250 // when first displayed (destination != 0)
00251 // each node is "compiled" into a structure for easier (and faster)
00252 // accessability
00253 // the compiled structures are destroyed upon lafChanges (also viewport changes)
00254 // next time it the node is displayed the compile is repeated
00255 // (would still be faster if we would collect the compiled pieces
00256 // and just throw them en mass on the screen - well perhaps some other time...)
00257 HTMLCursor HTMLElement::buildDisplay(HTMLCursor cursor, CSGrafikElement *destination, int parentViewportWidth, std::string &title)
00258 {
00259     bool goDeeper = true;   
00260     std::string text = "";
00261     std::string tag = mNode.getTag();
00262     HTMLCursor returnCursor = cursor;
00263     
00264     // TAG BEGIN
00265     // switch thru all known tags and
00266     // adjust cursor setting accordingly!
00267     switch (getTagType(mNode))
00268     {
00269         case HTML_PRE:
00270         {
00271             CSLAF *laf = CSLAF::getCurrentLAF();
00272             cursor.mInPre = true;
00273             
00274             // PRE allways starts at a new line
00275             cursor.mXPos = 0;
00276             cursor.mXPos += cursor.mAddX;
00277             cursor.mYPos += cursor.nextAdd;
00278             cursor.nextAdd = cursor.mFont->getHeight(); 
00279             cursor.mFont = laf->getFont("MonoSpaced"); // Mono spaced font! 
00280             break;
00281         }
00282         case HTML_HTML:
00283         {
00284             break;
00285         }
00286         case HTML_BODY:
00287         {
00288             // if there are - rememeber the colors!
00289             std::string bgColor = mNode.attributValue("BGCOLOR");
00290             std::string textColor = mNode.attributValue("TEXT");
00291             std::string linkColor = mNode.attributValue("LINK");
00292 
00293             int t = getColorFromString(textColor);
00294             if (t != -1) cursor.mPenColor = t;
00295 
00296             t = getColorFromString(bgColor);
00297             if (t != -1) cursor.mBackgroundColor = t;
00298             
00299             t = getColorFromString(linkColor);
00300             if (t != -1) cursor.mLinkColor = t;
00301 
00302             // only tags within body are displayed!
00303             cursor.mInBody = true;
00304             break;
00305         }
00306         case HTML_TITLE:
00307         {
00308             //quick Hack, since possible in Title there might be (stupid!!!) other tags!            
00309             title = getChildrenAsText();
00310             goDeeper = false;
00311             break;
00312         }
00313         case HTML_LI:
00314         {
00315             // list counter for <OL> - List get garbled when
00316             // Lists are used in lists - not fixed yet
00317             // (not even thought about it...)
00318 
00319             // counter == -1 is an unordered list,
00320             // everything else is the counter for the ordered list
00321             if (cursor.mListCounter != -1)
00322             {
00323                 // produce some text output as counters for the ordered list
00324                 char helper[10];
00325                 cursor.mListCounter++; 
00326                 sprintf(helper, "%i. ", cursor.mListCounter);
00327                 text = std::string(helper);
00328             }
00329             else
00330             {
00331                 // nothing fancy for not ordered Lists, just an asterix
00332                 text = std::string("* ");
00333             }
00334         }
00335         case HTML_DT:
00336         {
00337             cursor.mXPos = 0;
00338             cursor.mYPos += cursor.nextAdd;
00339             cursor.nextAdd = cursor.mFont->getHeight(); 
00340             cursor.mXPos += cursor.mAddX;
00341             break;
00342         }
00343         case HTML_OL:
00344         {
00345             // start the ordered list counter at 0
00346             cursor.mListCounter = 0; 
00347         }
00348         case HTML_UL:
00349         case HTML_DD:
00350         {
00351             // and do some indenting for the lists
00352             cursor.mAddX += 3*cursor.mFont->getWidth(" "); 
00353             break;
00354         }
00355 
00356         // well just the ol' carriage return
00357         case HTML_BR:
00358         // haven't done any real HR's yet
00359         case HTML_H1:
00360         {
00361             cursor.mXPos = 0;
00362             cursor.mXPos += cursor.mAddX;
00363             cursor.mYPos += cursor.nextAdd;
00364             cursor.nextAdd = cursor.mFont->getHeight(); 
00365             break;
00366         }
00367 
00368         // two lines might actually be to much - but what the heck
00369         // not done the whole attribute staff here
00370         case HTML_P:
00371         {
00372             cursor.mXPos = 0;
00373             cursor.mXPos += cursor.mAddX;
00374             cursor.mYPos += cursor.nextAdd;
00375             cursor.nextAdd = cursor.mFont->getHeight(); 
00376             cursor.mYPos += cursor.nextAdd;
00377             break;
00378         }
00379         case HTML_A:
00380         {
00381             // just for show - the attributes are needed some other time!
00382             // std::string rawURL = mNode.attributValue("HREF");
00383             // std::string formattedURL = formatURL(rawURL);
00384             // std::string ankerName = mNode.attributValue("NAME");
00385             if (mNode.attributValue("HREF").size() != 0 )
00386             {
00387                 cursor.mStyle = cursor.mStyle | FONT_STYLE_UNDERLINE;
00388                 cursor.mPenColor = cursor.mLinkColor;
00389             }
00390             
00391             // for quicker finding of a possible Anker
00392             mX = cursor.mXPos;
00393             mY = cursor.mYPos;
00394             break;
00395         }
00396         case HTML_B:
00397         {
00398             cursor.mStyle = cursor.mStyle | FONT_STYLE_BOLD;
00399             break;
00400         }
00401         case HTML_I:
00402         {
00403             // some day I might use TTF - but until than this is just for the show
00404             cursor.mStyle = cursor.mStyle | FONT_STYLE_ITALIC;
00405             break;
00406         }
00407         case HTML_IMG:
00408         {
00409             // load a picture!
00410             cursor.mXPos = 0;
00411             cursor.mXPos += cursor.mAddX;
00412             std::string rawURL = mNode.attributValue("SRC");
00413             std::string formattedURL = formatURL(rawURL);
00414 
00415             // just to rememeber
00416             // cursor.mXPos                             is the position within the viewport
00417             // parentViewport->x                        is the position on screen of the viewport
00418             // cursor.mStartHorizontalDisplayAtPixel    is the offset produced by scrolling withing the viewport
00419             int x = cursor.mXPos;
00420             int y = cursor.mYPos;
00421 
00422             CSIcon *icon = CSPictureIcon::buildIcon(CSPictureDirectLoader::INSTANCE.load(formattedURL));
00423             if (icon == 0)
00424             {
00425                 text = std::string()+"[Image not found: "+formattedURL+"]";
00426                 icon = CSTextIcon::buildIcon(text);
00427             }
00428             if (icon != 0)
00429             {
00430                 cursor.mXPos += icon->getWidth();
00431                 cursor.nextAdd = icon->getHeight();
00432                 if (cursor.mXPos > cursor.mXPosMax)
00433                 {
00434                     cursor.mXPosMax = cursor.mXPos;
00435                 }
00436 
00437                 if (destination)
00438                 {
00439                     destination->addElement(icon, x, y);
00440                 }
00441                 else
00442                 {
00443                     delete icon;
00444                 }
00445             }
00446         }
00447     }
00448 
00449     // if node has text - get it
00450     if (mNode.isText())
00451     {
00452         text = mNode.getValue();
00453     }
00454 
00455     // even none text Nodes can have "textuall" effects - see above
00456 
00457     // display text with current cursor settings
00458     // (if in Body of html page)
00459     if (cursor.mInBody == true)
00460     {
00461         if (text.size() != 0)
00462         {
00463             // pre is bad...
00464             // we display (sort of)
00465             // every letter by itself - so we don't miss "carriage return"
00466             if (cursor.mInPre)
00467             {
00468                 std::string textOut = "";
00469                 for (const char *pointerToText = text.c_str(); (*pointerToText);pointerToText++)
00470                 {
00471                     if (*pointerToText != '\n')
00472                     {
00473                         char letter[2];
00474                         letter[0] = *pointerToText;
00475                         letter[1] = 0;
00476                         textOut += letter;
00477                     }
00478                     else
00479                     {
00480                         // if there was a carriage return - display the collected letters
00481                         if (destination)
00482                         {
00483                             int x = cursor.mXPos;
00484                             int y = cursor.mYPos;
00485 
00486                             CSLabel *label = new CSLabel();
00487                             label->setFont(cursor.mFont);
00488                             label->setStyle(cursor.mStyle);
00489                             label->setTextColor(cursor.mPenColor);
00490                             label->setText(textOut);
00491                             destination->addElement(label, x, y);
00492                         }
00493                         // and more than one position as well
00494                         if (!mPositionsStored)
00495                         {
00496                             addPostion(cursor.mXPos, cursor.mYPos, cursor.mFont->getWidth(textOut), cursor.mFont->getHeight());
00497                         }
00498                         cursor.mXPos += cursor.mFont->getWidth(textOut);
00499                         textOut = "";
00500                         if (cursor.mXPos > cursor.mXPosMax)
00501                         {
00502                             cursor.mXPosMax = cursor.mXPos;
00503                         }
00504                         
00505                         cursor.mXPos = 0;
00506                         cursor.mXPos += cursor.mAddX;
00507                         cursor.mYPos += cursor.nextAdd;
00508                         cursor.nextAdd = cursor.mFont->getHeight(); 
00509                     }
00510                 }
00511             
00512                 // done with the tag, but nor carriage return found
00513                 // than display the collected letters without it...
00514                 if (textOut.size() > 0)
00515                 {
00516                     if (destination)
00517                     {
00518                         int x = cursor.mXPos;
00519                         int y = cursor.mYPos;
00520                         CSLabel *label = new CSLabel();
00521                         label->setFont(cursor.mFont);
00522                         label->setStyle(cursor.mStyle);
00523                         label->setTextColor(cursor.mPenColor);
00524                         label->setText(textOut);
00525                         destination->addElement(label, x, y);
00526                     }
00527                     if (!mPositionsStored)
00528                     {
00529                         addPostion(cursor.mXPos, cursor.mYPos, cursor.mFont->getWidth(textOut), cursor.mFont->getHeight());
00530                     }
00531                     cursor.mXPos += cursor.mFont->getWidth(textOut);
00532                     textOut = "";
00533                     if (cursor.mXPos > cursor.mXPosMax)
00534                     {
00535                         cursor.mXPosMax = cursor.mXPos; 
00536                     }
00537                 }
00538             }
00539             else
00540             {
00541                 // Non Pre - displaying is easier now (sort of)
00542                 // First build tokens for ech word
00543                 // build lines that fill the space we have got as good as possible
00544                 StringVector::iterator iter;
00545                 StringVector *tokens = tokenifyText(text);
00546                 int width = 0;
00547                 // build a textline
00548                 std::string line="";
00549 
00550                 // go thru all tokens
00551                 for (iter = tokens->begin(); iter != tokens->end();)
00552                 {
00553                     char *word = *iter;
00554                     
00555                     width = cursor.mFont->getWidth(line+" "+word);
00556                     // not wider than the viewport - keep on collecting
00557                     if (cursor.mXPos + width < parentViewportWidth)
00558                     {
00559                         if (line.size()>0)
00560                         {
00561                             line = line +" "+ word;
00562                         }
00563                         else
00564                         {
00565                             line = line + word;
00566                         }
00567                     }
00568                     else
00569                     {
00570                         // if wider than the viewport - display it an build up a
00571                         // new line
00572                         if (destination)
00573                         {
00574                             int x = cursor.mXPos;
00575                             int y = cursor.mYPos;
00576                             CSLabel *label = new CSLabel();
00577                             label->setFont(cursor.mFont);
00578                             label->setStyle(cursor.mStyle);
00579                             label->setTextColor(cursor.mPenColor);
00580                             label->setText(line);
00581                             destination->addElement(label, x, y);
00582                         }
00583                         if (!mPositionsStored)
00584                         {
00585                             addPostion(cursor.mXPos, cursor.mYPos, cursor.mFont->getWidth(line), cursor.mFont->getHeight());
00586                         }
00587                         cursor.mXPos += cursor.mFont->getWidth(line);
00588                         if (cursor.mXPos > cursor.mXPosMax)
00589                         {
00590                             cursor.mXPosMax = cursor.mXPos;
00591                         }
00592                         cursor.mXPos = 0;
00593                         cursor.mXPos += cursor.mAddX;
00594                         cursor.mYPos += cursor.nextAdd;
00595                         cursor.nextAdd = cursor.mFont->getHeight(); 
00596                         line = word;
00597                     }
00598                     iter++;
00599                 }
00600 
00601                 // done, but line was not full
00602                 // so we display what we have got...
00603                 if (destination)
00604                 {
00605                     int x = cursor.mXPos;
00606                     int y = cursor.mYPos;
00607                     CSLabel *label = new CSLabel();
00608                     label->setFont(cursor.mFont);
00609                     label->setStyle(cursor.mStyle);
00610                     label->setTextColor(cursor.mPenColor);
00611                     label->setText(line);
00612                     destination->addElement(label, x, y);
00613                 }
00614                 if (!mPositionsStored)
00615                 {
00616                     addPostion(cursor.mXPos, cursor.mYPos, cursor.mFont->getWidth(line), cursor.mFont->getHeight());
00617                 }
00618                 if (line.size()>0)
00619                 {
00620                     line = line + " ";
00621                 }
00622                 cursor.mXPos += cursor.mFont->getWidth(line);
00623                 if (cursor.mXPos > cursor.mXPosMax)
00624                 {
00625                     cursor.mXPosMax = cursor.mXPos;
00626                 }
00627 
00628                 for (iter = tokens->begin(); iter != tokens->end();iter++)
00629                 {
00630                     char *word = *iter;
00631                     free(word);
00632                 }
00633                 tokens->clear();
00634                 delete (tokens);
00635                 tokens = 0;
00636             }
00637         }
00638     }
00639 
00640     // was the tag one that can have other tags inside? (nearly all!)
00641     // than go deeper (recursively)
00642     if (goDeeper == true)
00643     {
00644         HTMLElements::iterator iter;
00645         for (iter = mElements.begin(); iter != mElements.end(); iter++)
00646         {
00647             HTMLElement *element = *iter;
00648             cursor = element->buildDisplay(cursor, destination, parentViewportWidth, title);
00649         }
00650     }
00651     
00652     // at the end of a Tag "reset" the cursor to its origin 
00653     // (only position information is kept!)
00654     returnCursor.mYPos = cursor.mYPos;
00655     returnCursor.mXPos = cursor.mXPos;
00656     returnCursor.nextAdd = cursor.nextAdd; 
00657     returnCursor.mXPosMax = cursor.mXPosMax;
00658     
00659     // for more than one list(cascading), the list counting is not correct!
00660     // can at the moment not be bothered to correct it...
00661     returnCursor.mListCounter = cursor.mListCounter; 
00662     mPositionsStored = true;
00663 
00664     return returnCursor;
00665 }
00666 
00667 // add one position information to the internal queue
00668 void HTMLElement::addPostion(int x, int y, int w, int h)
00669 {
00670     SDL_Rect *rect = new SDL_Rect();
00671     rect->x = x;
00672     rect->y = y;
00673     rect->w = w;
00674     rect->h = h;
00675     mPositions.push_back(rect);
00676 }
00677 
00678 // does the position (in viewport relation)
00679 // belong to us?
00680 // is the "mouse" hovering above this HTML-Node?
00681 // if so - return it  (0 otherwise)
00682 HTMLElement *HTMLElement::checkPostion(int x, int y)
00683 {
00684     Positions::iterator iter = mPositions.begin();
00685     while (iter != mPositions.end())
00686     {
00687         SDL_Rect *rect = *iter;
00688         if (((x > rect->x) && (x < rect->x + rect->w)) && ((y > rect->y) && (y < rect->y + rect->h)))
00689         {
00690             return this;
00691         }
00692         iter++;
00693     }
00694     HTMLElements::iterator eiter;
00695     for (eiter = mElements.begin(); eiter != mElements.end(); eiter++)
00696     {
00697         HTMLElement *checked = (*eiter)->checkPostion(x, y);
00698         if (checked != 0)
00699         {
00700             return checked;
00701         }
00702     }
00703     return 0;
00704 }
00705 
00706 // get the y starting position of this node
00707 // used for Anker - hopping
00708 int HTMLElement::getFirstYPostion()
00709 {
00710     return mY;
00711 }

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