Back to index

nux  3.0.0
Theme.cpp
Go to the documentation of this file.
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 "NuxCore/TinyXML/tinyxml.h"
00025 #include "Theme.h"
00026 
00027 
00028 namespace nux
00029 {
00030 
00031 #define INT_TO_ENUM_ELEMENT(a) {a, #a} // --->>> {a, "a"}
00032 
00033   typedef struct
00034   {
00035     UXStyleImageRef value;
00036     const char *style;
00037   } UXStyle;
00038 
00039   UXStyle UXStyleArray [] =
00040   {
00041     INT_TO_ENUM_ELEMENT(eIMAGE_STYLE_NONE),
00042     INT_TO_ENUM_ELEMENT(eSTROKE_CORNER_SQUARE),
00043     INT_TO_ENUM_ELEMENT(eSTROKE_CORNER_ROUND1),
00044     INT_TO_ENUM_ELEMENT(eSTROKE_CORNER_ROUND2),
00045     INT_TO_ENUM_ELEMENT(eSTROKE_CORNER_ROUND4),
00046     INT_TO_ENUM_ELEMENT(eSTROKE_CORNER_ROUND10),
00047 
00048     INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND1),
00049     INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND2),
00050     INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND4),
00051     INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND5),
00052     INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND6),
00053     INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND10),
00054 
00055     INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND10_SHADOW),
00056     INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND4_SHADOW),
00057     INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_SHADOW),
00058 
00059     INT_TO_ENUM_ELEMENT(eTRIANGLE_UP),
00060     INT_TO_ENUM_ELEMENT(eTRIANGLE_DOWN),
00061     INT_TO_ENUM_ELEMENT(eTRIANGLE_LEFT),
00062     INT_TO_ENUM_ELEMENT(eTRIANGLE_RIGHT),
00063 
00064     INT_TO_ENUM_ELEMENT(eWINDOW_SIZEGRIP),
00065 
00066     INT_TO_ENUM_ELEMENT(eSHAPE_CHECK_MARK),
00067     INT_TO_ENUM_ELEMENT(eSHAPE_CHECK_BOX),
00068 
00069     INT_TO_ENUM_ELEMENT(eCHECKBOX_NORMAL_ON),
00070     INT_TO_ENUM_ELEMENT(eCHECKBOX_NORMAL_OFF),
00071     INT_TO_ENUM_ELEMENT(eCHECKBOX_FOCUS_ON),
00072     INT_TO_ENUM_ELEMENT(eCHECKBOX_FOCUS_OFF),
00073     INT_TO_ENUM_ELEMENT(eCHECKBOX_PRELIGHT_ON),
00074     INT_TO_ENUM_ELEMENT(eCHECKBOX_PRELIGHT_OFF),
00075 
00076     INT_TO_ENUM_ELEMENT(eRADIO_NORMAL_ON),
00077     INT_TO_ENUM_ELEMENT(eRADIO_NORMAL_OFF),
00078     INT_TO_ENUM_ELEMENT(eRADIO_FOCUS_ON),
00079     INT_TO_ENUM_ELEMENT(eRADIO_FOCUS_OFF),
00080     INT_TO_ENUM_ELEMENT(eRADIO_PRELIGHT_ON),
00081     INT_TO_ENUM_ELEMENT(eRADIO_PRELIGHT_OFF),
00082 
00083     INT_TO_ENUM_ELEMENT(eBUTTON_NORMAL),
00084     INT_TO_ENUM_ELEMENT(eBUTTON_FOCUS),
00085     INT_TO_ENUM_ELEMENT(eBUTTON_PRELIGHT),
00086     INT_TO_ENUM_ELEMENT(eSPINNERUP),
00087     INT_TO_ENUM_ELEMENT(eSPINNERDOWN),
00088 
00089     INT_TO_ENUM_ELEMENT(eCOMBOBOX_OPEN_BUTTON),
00090     INT_TO_ENUM_ELEMENT(eTAB_LEFT),
00091     INT_TO_ENUM_ELEMENT(eTAB_RIGHT),
00092     INT_TO_ENUM_ELEMENT(eSPINER_UP),
00093     INT_TO_ENUM_ELEMENT(eSPINER_DOWN),
00094     INT_TO_ENUM_ELEMENT(eTREE_NODE_OPEN),
00095     INT_TO_ENUM_ELEMENT(eTREE_NODE_CLOSE),
00096 
00097     INT_TO_ENUM_ELEMENT(eSCROLLBAR_TRIANGLE_UP),
00098     INT_TO_ENUM_ELEMENT(eSCROLLBAR_TRIANGLE_DOWN),
00099     INT_TO_ENUM_ELEMENT(eSCROLLBAR_TRIANGLE_LEFT),
00100     INT_TO_ENUM_ELEMENT(eSCROLLBAR_TRIANGLE_RIGHT),
00101 
00102     INT_TO_ENUM_ELEMENT(eVALUATORVERTICALMOVE),
00103     INT_TO_ENUM_ELEMENT(eVALUATORHORIZONTALMOVE),
00104     INT_TO_ENUM_ELEMENT(eVALUATORMOVE),
00105 
00106     INT_TO_ENUM_ELEMENT(eVECTORXLABEL),
00107     INT_TO_ENUM_ELEMENT(eVECTORYLABEL),
00108     INT_TO_ENUM_ELEMENT(eVECTORZLABEL),
00109     INT_TO_ENUM_ELEMENT(eVECTORWLABEL),
00110 
00111 
00112     INT_TO_ENUM_ELEMENT(eHSCROLLBAR),
00113     INT_TO_ENUM_ELEMENT(eVSCROLLBAR),
00114 
00115     INT_TO_ENUM_ELEMENT(eMATRIX3PREVIEW),
00116     INT_TO_ENUM_ELEMENT(eMATRIX4PREVIEW),
00117     INT_TO_ENUM_ELEMENT(eDOT6x6),
00118 
00119     INT_TO_ENUM_ELEMENT(eGraphIcon),
00120     INT_TO_ENUM_ELEMENT(eGraphBarIcon),
00121 
00122     INT_TO_ENUM_ELEMENT(eWindowCloseButton),
00123 
00124     {eIMAGE_STYLE_NONE, 0}
00125   };
00126 
00127 
00128   /*static unsigned long axtoi(const char *s)
00129   {
00130       int n = 0;         // position in string
00131       int m = 0;         // position in digit[] to shift
00132       int count;         // loop index
00133       unsigned long intValue = 0;  // integer value of hex string
00134       int digit[16];      // hold values to convert
00135 
00136       const char *hexStg = s;
00137       if ((s[0] == '0') && ((s[1] == 'X') || (s[1] == 'x')))
00138       {
00139           hexStg = s+2;
00140       }
00141 
00142       while (n < 16)
00143       {
00144           if (hexStg[n]=='\0')
00145               break;
00146           if (hexStg[n] > 0x29 && hexStg[n] < 0x40 ) //if 0 to 9
00147               digit[n] = hexStg[n] & 0x0f;            //convert to int
00148           else if (hexStg[n] >='a' && hexStg[n] <= 'f') //if a to f
00149               digit[n] = (hexStg[n] & 0x0f) + 9;      //convert to int
00150           else if (hexStg[n] >='A' && hexStg[n] <= 'F') //if A to F
00151               digit[n] = (hexStg[n] & 0x0f) + 9;      //convert to int
00152           else break;
00153           n++;
00154       }
00155       count = n;
00156       m = n - 1;
00157       n = 0;
00158       while (n < count)
00159       {
00160           // digit[n] is value of hex digit at position n
00161           // (m << 2) is the number of positions to shift
00162           // OR the bits into return value
00163           intValue = intValue | (digit[n] << (m << 2));
00164           m--;   // adjust the position to set
00165           n++;   // next digit to process
00166       }
00167       return (intValue);
00168   }*/
00169 
00170   /*static unsigned int ReadXMLColorAttribute(TiXmlElement* element, const char* attribute_name)
00171   {
00172       unsigned int retvalue = 0;
00173       if (element)
00174       {
00175           retvalue = axtoi(element->Attribute(attribute_name));
00176       }
00177       return retvalue;
00178   }*/
00179 
00180   static UXStyleImageRef GetStyleImageRef(const char *style_name)
00181   {
00182     int i = 0;
00183 
00184     while (UXStyleArray[i].style != 0)
00185     {
00186       if (strcmp(UXStyleArray[i].style, style_name) == 0)
00187       {
00188         return UXStyleArray[i].value;
00189       }
00190 
00191       i++;
00192     }
00193 
00194     return eIMAGE_STYLE_NONE;
00195   }
00196 
00197   UXTheme::UXTheme()
00198   {
00199     LoadPainterImages();
00200   }
00201 
00202   UXTheme::~UXTheme()
00203   {
00204     std::list<PainterImage*>::iterator it;
00205     for (it = m_PainterImageList.begin(); it != m_PainterImageList.end(); it++)
00206     {
00207       (*it)->texture->UnReference();
00208       delete(*it);
00209     }
00210     m_PainterImageList.clear();
00211   }
00212 
00213   void UXTheme::LoadPainterImages()
00214   {
00215     NString file_search = "Painter.xml";
00216     NString painter_filename = NUX_FIND_RESOURCE_LOCATION_NOFAIL(file_search.GetTCharPtr());
00217 
00218     if (painter_filename == "")
00219     {
00220       nuxCriticalMsg("[GraphicsEngine::LoadPainterImages] Can't find Painter.xml file.");
00221       return;
00222     }
00223 
00224     TiXmlDocument doc(painter_filename.GetTCharPtr());
00225     doc.LoadFile();
00226 
00227     TiXmlHandle docHandle( &doc );
00228     TiXmlElement *data = docHandle.FirstChild(TCHARToUTF8("PaintData")).Element();
00229     TiXmlElement *image = 0;
00230 
00231     for (image = data->FirstChildElement(TCHARToUTF8("Image")); image; image = image->NextSiblingElement(TCHARToUTF8("Image")))
00232     {
00233       PainterImage *pimage = new PainterImage;
00234       Memset(pimage, 0, sizeof(PainterImage));
00235 
00236       NString style = image->Attribute(TCHARToUTF8("style"));
00237 
00238       pimage->style = GetStyleImageRef(style.GetTCharPtr());
00239 
00240       // If the attributes border_left, border_right, border_top, border_bottom are not present, assume they are equal to 0;
00241       pimage->border_left = pimage->border_right = pimage->border_top = pimage->border_bottom = 0;
00242 
00243       image->Attribute(TCHARToUTF8("border_left"), &pimage->border_left);
00244       image->Attribute(TCHARToUTF8("border_right"), &pimage->border_right);
00245       image->Attribute(TCHARToUTF8("border_top"),  &pimage->border_top);
00246       image->Attribute(TCHARToUTF8("border_bottom"), &pimage->border_bottom);
00247 
00248 
00249       const char *draw_borders_only = image->Attribute(TCHARToUTF8("border_only"));
00250 
00251       if (draw_borders_only == 0)
00252       {
00253         pimage->draw_borders_only = true;
00254       }
00255       else
00256       {
00257         if (strcmp(TCHARToUTF8("false"), draw_borders_only) == 0)
00258         {
00259           pimage->draw_borders_only = false;
00260         }
00261         else
00262         {
00263           pimage->draw_borders_only = true;
00264         }
00265       }
00266 
00267       if (1)
00268       {
00269         BaseTexture* device_texture;
00270 
00271         NString filename = image->Attribute(TCHARToUTF8("Name"));
00272         NString texture_filename = NUX_FIND_RESOURCE_LOCATION_NOFAIL(filename.GetTCharPtr());
00273         device_texture = Load2DTextureFile(texture_filename.GetTCharPtr());
00274 
00275         pimage->texture = device_texture;
00276       }
00277       else
00278       {
00279         NString filename = image->Attribute(TCHARToUTF8("Name"));
00280         NString texture_filename = NUX_FIND_RESOURCE_LOCATION_NOFAIL(filename.GetTCharPtr());
00281         pimage->texture = Load2DTextureFile(texture_filename.GetTCharPtr());
00282       }
00283 
00284       m_PainterImageList.push_back(pimage);
00285     }
00286   }
00287 
00288   const PainterImage *UXTheme::GetImage(UXStyleImageRef style)
00289   {
00290     std::list<PainterImage *>::iterator it;
00291 
00292     for (it = m_PainterImageList.begin(); it != m_PainterImageList.end(); it++)
00293     {
00294       if ((*it)->style == style)
00295       {
00296         return (*it);
00297       }
00298     }
00299 
00300     return 0;
00301   }
00302 
00303   Rect UXTheme::GetImageGeometry(UXStyleImageRef style)
00304   {
00305     std::list<PainterImage *>::iterator it;
00306 
00307     for (it = m_PainterImageList.begin(); it != m_PainterImageList.end(); it++)
00308     {
00309       if ((*it)->style == style)
00310       {
00311         unsigned int width = (*it)->texture->GetWidth();
00312         unsigned int height = (*it)->texture->GetHeight();
00313         return Rect(0, 0, width, height);
00314       }
00315     }
00316 
00317     nuxDebugMsg("[GraphicsEngine::GetImageGeometry] Cannot find UXStyleImageRef");
00318     return Rect(0, 0, 0, 0);
00319   }
00320 
00321   BaseTexture *UXTheme::Load2DTextureFile(const char *filename)
00322   {
00323     BaseTexture* texture2D = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture();
00324     NBitmapData *BitmapData = LoadImageFile(filename);
00325 
00326     if (BitmapData)
00327     {
00328       texture2D->Update(BitmapData);
00329       delete BitmapData;
00330     }
00331     return texture2D;
00332   }
00333 
00334   BaseTexture *UXTheme::Load2DTextureFileGenerateAlpha(const char *filename, int red, int green, int blue)
00335   {
00336     return 0;
00337   }
00338 
00339 }
00340