src/GUITextBox.cpp

Go to the documentation of this file.
00001 #include "glwx.h"
00002 
00003 GUITextBox::GUITextBox(const std::string &callback, const std::string &text) : GUIAlphaElement(callback)
00004 
00005 {
00006   setBordersColor(0.3f, 0.3f, 0.3f);
00007   setDimensions(80, 18);
00008   setPadding(2, 2);
00009   setColor(0.5f, 0.5f, 0.5f);
00010   label.setString(text);
00011 
00012   blinkerPosition = 2;
00013   blinkerTimer    = 0.0f;
00014   blinkerOn       = false;
00015 
00016   textStartIndex  = 0;
00017   textEndIndex    = 0;
00018 
00019   dimensions.y    = GUIFontManager::getDefaultFont() ?
00020                     GUIFontManager::getDefaultFont()->getFontObject()->getHeight() + padding.y : dimensions.y;
00021   widgetType      = WT_TEXT_BOX;
00022 }
00023 
00024 bool GUITextBox::loadXMLSettings(const TiXmlElement* element)
00025 {
00026   if(!XMLArbiter::inspectElementInfo(element, "TextBox"))
00027     return Logger::writeErrorLog("Need a TextBox node in the xml file");
00028 
00029   setBordersColor(XMLArbiter::fillComponents3f(XMLArbiter::getChildElementByName(element, "BordersColor"),bordersColor));
00030   return   GUIAlphaElement::loadXMLSettings(element);
00031 return false;
00032 }
00033 
00034 void  GUITextBox::setBordersColor(const Tuple3f& color)
00035 {
00036   setBordersColor(color.x, color.y, color.z);
00037 }
00038 
00039 const Tuple3f &GUITextBox::getBordersColor() const
00040 {
00041   return bordersColor;
00042 }
00043 
00044 void  GUITextBox::setBordersColor(float r, float g, float b)
00045 {
00046   bordersColor.set(clamp(r, 0.0f, 255.0f),
00047                    clamp(g, 0.0f, 255.0f),
00048                    clamp(b, 0.0f, 255.0f));
00049   bordersColor.x /= (bordersColor.x > 1.0) ? 255.0f : 1.0f;
00050   bordersColor.y /= (bordersColor.y > 1.0) ? 255.0f : 1.0f;
00051   bordersColor.z /= (bordersColor.z > 1.0) ? 255.0f : 1.0f;
00052 }
00053 
00054 void  GUITextBox::setPadding(const Tuple2i& p)
00055 {
00056   setPadding(p.x, p.y);
00057 }
00058 
00059 void  GUITextBox::setPadding(int x, int y)
00060 {
00061   padding.set(clamp(x, 0, 25),
00062               clamp(y, 0, 25));
00063 }
00064 
00065 const Tuple2i &GUITextBox::getPadding() const
00066 {
00067   return padding;
00068 }
00069 
00070 void GUITextBox::render(float clockTick)
00071 {
00072   if(!parent || !visible)
00073     return;
00074 
00075   modifyCurrentAlpha(clockTick);
00076   getWindowBounds();
00077 
00078   size_t realBlinkerPosition = clamp(blinkerPosition, size_t(windowBounds.x + padding.x),
00079                                                       size_t(windowBounds.z - padding.x));
00080   blinkerTimer += clockTick;
00081   blinkerTimer -= blinkerTimer > 1.0f ? 1.0f : 0.0f;
00082 
00083   glEnable(GL_BLEND);
00084   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00085   glColor4fv(color);
00086 
00087   glBegin(GL_TRIANGLE_STRIP);
00088   glVertex2i(windowBounds.x, windowBounds.y);
00089   glVertex2i(windowBounds.x, windowBounds.w);
00090   glVertex2i(windowBounds.z + padding.x, windowBounds.y);
00091   glVertex2i(windowBounds.z + padding.x, windowBounds.w);
00092   glEnd();
00093 
00094   glColor3fv(bordersColor);
00095   glBegin(GL_LINE_LOOP);
00096   glVertex2i(windowBounds.x, windowBounds.y);
00097   glVertex2i(windowBounds.x, windowBounds.w);
00098   glVertex2i(windowBounds.z + padding.x, windowBounds.w);
00099   glVertex2i(windowBounds.z + padding.x, windowBounds.y);
00100   glEnd();
00101   glDisable(GL_BLEND);
00102 
00103   label.print(windowBounds.x + padding.x, windowBounds.y, int(textStartIndex), int(textEndIndex));
00104 
00105   if(blinkerOn && (blinkerTimer > 0.5f))
00106   {
00107     glColor3fv(label.getColor());
00108     glBegin(GL_LINES);
00109     glVertex2i((int)realBlinkerPosition, windowBounds.y + padding.y/2);
00110     glVertex2i((int)realBlinkerPosition, windowBounds.w - padding.y);
00111     glEnd();
00112     glColor3f(1,1,1);
00113   }
00114 }
00115 
00116 void GUITextBox::checkMouseEvents(MouseEvent &newEvent, int extraInfo, bool reservedBits)
00117 {
00118   bool nRelease   = pressed;
00119 
00120   GUIRectangle::checkMouseEvents(newEvent, extraInfo, true);
00121 
00122   if(mouseOver && (clicked || pressed))
00123     setupBlinker(newEvent.getX());
00124 
00125   clicked   = false;
00126   released  = false;
00127   blinkerOn = focused ? blinkerOn : false;
00128 }
00129 
00130 void GUITextBox::checkKeyboardEvents(KeyEvent &evt, int extraInfo)
00131 {
00132   if(!focused || !active)
00133     return;
00134 
00135   if((evt.getKeyID() >= 32 && evt.getKeyID() <= 127) ||
00136      (evt.getKeyID() == 8));
00137   else
00138     extraInfo = 0;
00139 
00140   if(extraInfo == KE_PRESSED)
00141   {
00142     size_t length = label.getString().size();
00143 
00144 
00145     if(evt.displayable())
00146       setupText(TE_INSERT_CHAR, evt.getKeyChar());
00147 
00148     if(length)
00149     {
00150       switch(evt.getKeyID())
00151       {
00152         case   8:  setupText(TE_BACKSPACE_DELETE); break;
00153         case 127:  setupText(TE_SIMPLE_DELETE);    break;
00154       }
00155     }
00156 
00157         // Set the used flag to alert
00158         // observers that the key press event
00159         // was used by this widget
00160     evt.setUsed(true);
00161 
00162   }
00163 
00164   label.forceUpdate(true);
00165   update = true;
00166 }
00167 
00168 void    GUITextBox::setupBlinker(size_t x)
00169 {
00170   if(!focused || !active)
00171     return;
00172 
00173   GUIFont *font                = GUIFontManager::getFont(label.getFontIndex());
00174   const    std::string &string = label.getString();
00175   const    int         *spaces = NULL;
00176   blinkerPosition              = getWindowBounds().x + padding.x;
00177   x -= 1;
00178 
00179   if(font)
00180   {
00181      spaces = font->getFontObject()->getCharHorizontalGlyphs();
00182 
00183      for(size_t i = 0; i < string.size(); i++)
00184      if(blinkerPosition < x)
00185        blinkerPosition += spaces[int(string[i])];
00186   }
00187 
00188   blinkerOn = true;
00189 }
00190 
00191 void GUITextBox::setupText(int type, char Char)
00192 {
00193   GUIFont     *font   = GUIFontManager::getFont(label.getFontIndex());
00194   const int   *spaces = font ? font->getFontObject()->getCharHorizontalGlyphs() : NULL;
00195   std::string  temp;
00196   size_t       length = label.getString().size(),
00197                start  = windowBounds.x + padding.x,
00198                index  = 0;
00199 
00200   if(!spaces)
00201     return;
00202 
00203   for(size_t t = 0; t < length; t++)
00204   {
00205     if(blinkerPosition > start)
00206     {
00207       index++;
00208       start += spaces[label.getString()[t]];
00209     }
00210   }
00211 
00212   if(type == TE_INSERT_CHAR)
00213   {
00214     if(index != length && length)
00215     {
00216       std::string leftSide;
00217       leftSide  = label.getString().substr(0, index);
00218       leftSide += Char;
00219 
00220       temp      = label.getString().substr(index, length - index);
00221       label.setString(leftSide + temp);
00222     }
00223     else
00224     {
00225       temp  = label.getString();
00226       temp += Char;
00227       label.setString(temp);
00228     } 
00229     blinkerPosition  = blinkerPosition + GUIFontManager::getCharacterWidth(Char, font);
00230   } 
00231 
00232   if(type == TE_BACKSPACE_DELETE && (blinkerPosition != windowBounds.x + padding.x))
00233   {
00234     if(index != length)
00235     {
00236       std::string leftSide;
00237       setupBlinker(blinkerPosition - GUIFontManager::getCharacterWidth(label.getString()[index -1],
00238                                                                        label.getFontIndex()));
00239 
00240       leftSide = label.getString().substr(0, index - 1);
00241       temp     = label.getString().substr(index, length - index);
00242       label.setString(leftSide + temp);
00243       return;
00244     }
00245 
00246     setupBlinker(blinkerPosition - GUIFontManager::getCharacterWidth(label.getString()[length -1],
00247                                                                      font));
00248 
00249     temp = label.getString().substr(0, length - 1);
00250 
00251     if(temp.size())
00252       label.setString(temp);
00253     else
00254     {
00255       label.clear();
00256       blinkerPosition = windowBounds.x + padding.x;
00257     }
00258   }
00259   
00260   if(type == TE_SIMPLE_DELETE && length)
00261   {
00262     if((blinkerPosition == windowBounds.x + padding.x) && (length == 1))
00263     {
00264       label.clear();
00265       return;
00266     }
00267 
00268     if(index < length)
00269     {
00270       std::string leftSide;
00271       leftSide = label.getString().substr(0, index);
00272       temp     = label.getString().substr(index + 1, length - index - 1);
00273       label.setString(leftSide + temp);
00274     }
00275   }
00276   if(type == TE_PARSE_VISIBLE)
00277      textEndIndex = font->getFontObject()->getMaxFittingLength(label.getString(), getWidth());
00278 }
00279 
00280 const Tuple4i &GUITextBox::getWindowBounds()
00281 {
00282   if(parent && update)
00283   {
00284     label.computeDimensions();
00285     dimensions.y    = label.getHeight() ? label.getHeight() + padding.y : dimensions.y;
00286 
00287     GUIRectangle::computeWindowBounds();
00288     blinkerPosition = !blinkerPosition ? windowBounds.x + padding.x : blinkerPosition;
00289     setupText(TE_PARSE_VISIBLE);
00290   }
00291   return windowBounds;
00292 }

Generated on Wed Dec 5 20:32:03 2007 for GLWX by  doxygen 1.5.3