00001 #include "gui_backdrop.hpp"
00002 #include "gui_frame.hpp"
00003 #include "gui_sprite.hpp"
00004 #include "gui_material.hpp"
00005 #include "gui_out.hpp"
00006 
00007 #include <utils_filesystem.hpp>
00008 
00009 namespace gui
00010 {
00011 backdrop::backdrop(frame* pParent) :
00012     pParent_(pParent), mBackgroundColor_(color::EMPTY), mEdgeColor_(color::EMPTY),
00013     bBackgroundTilling_(false), uiTileSize_(0u), uiOriginalTileSize_(0u),
00014     lBackgroundInsets_({{0, 0, 0, 0}}), lEdgeInsets_({{0, 0, 0, 0}}),
00015     uiEdgeSize_(0u), uiOriginalEdgeSize_(0u)
00016 {
00017 }
00018 
00019 void backdrop::copy_from(const backdrop& mBackdrop)
00020 {
00021     this->set_background(mBackdrop.get_background_file());
00022     this->set_edge(mBackdrop.get_edge_file());
00023 
00024     this->set_backgrond_tilling(mBackdrop.is_background_tilling());
00025     this->set_tile_size(mBackdrop.get_tile_size());
00026 
00027     if (mBackdrop.sBackgroundFile_.empty())
00028         this->set_background_color(mBackdrop.get_background_color());
00029 
00030     this->set_background_insets(mBackdrop.get_background_insets());
00031 
00032     if (mBackdrop.sEdgeFile_.empty())
00033         this->set_edge_color(mBackdrop.get_edge_color());
00034 
00035     this->set_edge_size(mBackdrop.get_edge_size());
00036     this->set_edge_insets(mBackdrop.get_edge_insets());
00037 }
00038 
00039 void backdrop::set_background(const std::string& sBackgroundFile)
00040 {
00041     if (!sBackgroundFile.empty())
00042     {
00043         std::string sFile = pParent_->get_manager()->parse_file_name(sBackgroundFile);
00044         if (utils::file_exists(sFile))
00045         {
00046             pBackground_ = pParent_->get_manager()->create_sprite(
00047                 pParent_->get_manager()->create_material(sFile)
00048             );
00049             uiTileSize_ = uiOriginalTileSize_ = pBackground_->get_width();
00050             mBackgroundColor_ = color::EMPTY;
00051         }
00052         else
00053         {
00054             gui::out << gui::warning << "backdrop : "
00055                 << "Couldn't find file : \"" << sFile << "\" for "
00056                 << pParent_->get_name() << "'s backdrop background file.\n"
00057                 << "No background will be drawn." << std::endl;
00058 
00059             sBackgroundFile_ = "";
00060             return;
00061         }
00062     }
00063     else
00064         pBackground_ = nullptr;
00065 
00066     sBackgroundFile_ = sBackgroundFile;
00067 }
00068 
00069 const std::string& backdrop::get_background_file() const
00070 {
00071     return sBackgroundFile_;
00072 }
00073 
00074 void backdrop::set_background_color(const color& mColor)
00075 {
00076     mBackgroundColor_ = mColor;
00077     sBackgroundFile_ = "";
00078 
00079     uiTileSize_ = uiOriginalTileSize_ = 256;
00080     pBackground_ = pParent_->get_manager()->create_sprite(
00081         pParent_->get_manager()->create_material(mColor), 256, 256
00082     );
00083 }
00084 
00085 color backdrop::get_background_color() const
00086 {
00087     return mBackgroundColor_;
00088 }
00089 
00090 void backdrop::set_backgrond_tilling(bool bBackgroundTilling)
00091 {
00092     bBackgroundTilling_ = bBackgroundTilling;
00093 
00094     if (!bBackgroundTilling_ && pBackground_)
00095         pBackground_->set_texture_rect(0.0f, 0.0f, 1.0f, 1.0f, true);
00096 }
00097 
00098 bool backdrop::is_background_tilling() const
00099 {
00100     return bBackgroundTilling_;
00101 }
00102 
00103 void backdrop::set_tile_size(uint uiTileSize)
00104 {
00105     uiTileSize_ = uiTileSize;
00106 }
00107 
00108 uint backdrop::get_tile_size() const
00109 {
00110     return uiTileSize_;
00111 }
00112 
00113 void backdrop::set_background_insets(const std::array<int,4>& lInsets)
00114 {
00115     lBackgroundInsets_ = lInsets;
00116 }
00117 
00118 void backdrop::set_background_insets(int iLeft, int iRight, int iTop, int iBottom)
00119 {
00120     lBackgroundInsets_ = {{iLeft, iRight, iTop, iBottom}};
00121 }
00122 
00123 const std::array<int,4>& backdrop::get_background_insets() const
00124 {
00125     return lBackgroundInsets_;
00126 }
00127 
00128 void backdrop::set_edge_insets(const std::array<int,4>& lInsets)
00129 {
00130     lEdgeInsets_ = lInsets;
00131 }
00132 
00133 void backdrop::set_edge_insets(int iLeft, int iRight, int iTop, int iBottom)
00134 {
00135     lEdgeInsets_ = {{iLeft, iRight, iTop, iBottom}};
00136 }
00137 
00138 const std::array<int,4>& backdrop::get_edge_insets() const
00139 {
00140     return lEdgeInsets_;
00141 }
00142 
00143 void backdrop::set_edge(const std::string& sEdgeFile)
00144 {
00145     if (!sEdgeFile.empty())
00146     {
00147         std::string sFile = pParent_->get_manager()->parse_file_name(sEdgeFile);
00148         if (utils::file_exists(sFile))
00149         {
00150             utils::refptr<material> pMat = pParent_->get_manager()->create_material(sFile);
00151 
00152             if (pMat->get_width()/pMat->get_height() == 8.0f)
00153             {
00154                 uiEdgeSize_ = uiOriginalEdgeSize_ = pMat->get_height();
00155 
00156                 for (uint i = 0; i < 8; ++i)
00157                 {
00158                     lEdgeList_[i] = pParent_->get_manager()->create_sprite(
00159                         pMat, pMat->get_height()*i, 0.0f, uiEdgeSize_, uiEdgeSize_
00160                     );
00161                 }
00162 
00163                 lEdgeList_[EDGE_TOPLEFT]->set_hot_spot(
00164                     0.0f, 0.0f
00165                 );
00166                 lEdgeList_[EDGE_TOPRIGHT]->set_hot_spot(
00167                     uiOriginalEdgeSize_, 0.0f
00168                 );
00169                 lEdgeList_[EDGE_BOTTOMLEFT]->set_hot_spot(
00170                     0.0f, uiOriginalEdgeSize_
00171                 );
00172                 lEdgeList_[EDGE_BOTTOMRIGHT]->set_hot_spot(
00173                     uiOriginalEdgeSize_, uiOriginalEdgeSize_
00174                 );
00175 
00176                 sEdgeFile_ = sFile;
00177                 mEdgeColor_ = color::EMPTY;
00178             }
00179             else
00180             {
00181                 lEdgeList_ = {{nullptr, nullptr, nullptr, nullptr}};
00182                 sEdgeFile_ = "";
00183 
00184                 gui::out << gui::error << "backdrop : "
00185                     << "An edge file's width must be exactly 8 times greater than its height "
00186                     << "(in " << sFile << ").\nNo edge will be drawn for "
00187                     << pParent_->get_name() << "'s backdrop." << std::endl;
00188             }
00189         }
00190         else
00191         {
00192             lEdgeList_ = {{nullptr, nullptr, nullptr, nullptr}};
00193             sEdgeFile_ = "";
00194 
00195             gui::out << gui::warning << "backdrop : "
00196                 << "Couldn't find file : \"" << sEdgeFile << "\" for " <<pParent_->get_name()
00197                 << "'s backdrop edge.\nNo edge will be drawn." << std::endl;
00198         }
00199     }
00200     else
00201         lEdgeList_ = {{nullptr, nullptr, nullptr, nullptr}};
00202 
00203     sEdgeFile_ = sEdgeFile;
00204 }
00205 
00206 const std::string& backdrop::get_edge_file() const
00207 {
00208     return sEdgeFile_;
00209 }
00210 
00211 void backdrop::set_edge_color(const color& mColor)
00212 {
00213     mEdgeColor_ = mColor;
00214     sEdgeFile_ = "";
00215 
00216     if (uiEdgeSize_ == 0)
00217         uiEdgeSize_ = 1;
00218 
00219     uiOriginalEdgeSize_ = 1;
00220 
00221     for (uint i = 0; i < 8; ++i)
00222     {
00223         lEdgeList_[i] = pParent_->get_manager()->create_sprite(
00224             pParent_->get_manager()->create_material(mColor), 1, 1
00225         );
00226     }
00227 
00228     lEdgeList_[EDGE_TOPLEFT]->set_hot_spot(0.0f, 0.0f);
00229     lEdgeList_[EDGE_TOPRIGHT]->set_hot_spot(1.0f, 0.0f);
00230     lEdgeList_[EDGE_BOTTOMLEFT]->set_hot_spot(0.0f, 1.0f);
00231     lEdgeList_[EDGE_BOTTOMRIGHT]->set_hot_spot(1.0f, 1.0f);
00232 }
00233 
00234 color backdrop::get_edge_color() const
00235 {
00236     return mEdgeColor_;
00237 }
00238 
00239 void backdrop::set_edge_size(uint uiEdgeSize)
00240 {
00241     uiEdgeSize_ = uiEdgeSize;
00242 }
00243 
00244 uint backdrop::get_edge_size() const
00245 {
00246     return uiEdgeSize_;
00247 }
00248 
00249 void backdrop::set_vertex_color(const color& mColor)
00250 {
00251     if (pBackground_)
00252         pBackground_->set_color(mColor);
00253 
00254     if (lEdgeList_[0])
00255     {
00256         for (uint i = 0; i < 8; ++i)
00257             lEdgeList_[i]->set_color(mColor);
00258     }
00259 }
00260 
00261 void backdrop::render() const
00262 {
00263     if (pParent_)
00264     {
00265         const std::array<int,4>& lParentBorders = pParent_->get_borders();
00266 
00267         if (pBackground_)
00268         {
00269             if (bBackgroundTilling_)
00270             {
00271                 pBackground_->set_texture_rect(
00272                     0.0f, 0.0f,
00273                     (
00274                         lParentBorders[BORDER_RIGHT] + lBackgroundInsets_[BORDER_RIGHT] -
00275                         (lParentBorders[BORDER_LEFT] + lBackgroundInsets_[BORDER_LEFT])
00276                     )*uiOriginalTileSize_/float(uiTileSize_),
00277                     (
00278                         lParentBorders[BORDER_BOTTOM] - lBackgroundInsets_[BORDER_BOTTOM] -
00279                         (lParentBorders[BORDER_TOP]   - lBackgroundInsets_[BORDER_TOP])
00280                     )*uiOriginalTileSize_/float(uiTileSize_)
00281                 );
00282             }
00283 
00284             pBackground_->render_2v(
00285                 lParentBorders[BORDER_LEFT]   + lBackgroundInsets_[BORDER_LEFT],
00286                 lParentBorders[BORDER_TOP]    + lBackgroundInsets_[BORDER_TOP],
00287                 lParentBorders[BORDER_RIGHT]  - lBackgroundInsets_[BORDER_RIGHT],
00288                 lParentBorders[BORDER_BOTTOM] - lBackgroundInsets_[BORDER_BOTTOM]
00289             );
00290         }
00291 
00292         if (lEdgeList_[0])
00293         {
00294             float fEdgeScale = float(uiEdgeSize_)/float(uiOriginalEdgeSize_);
00295 
00296             
00297             lEdgeList_[EDGE_TOPLEFT]->render_ex(
00298                 lParentBorders[BORDER_LEFT] + lEdgeInsets_[BORDER_LEFT],
00299                 lParentBorders[BORDER_TOP]  + lEdgeInsets_[BORDER_TOP],
00300                 0.0f, fEdgeScale, fEdgeScale
00301             );
00302 
00303             lEdgeList_[EDGE_TOPRIGHT]->render_ex(
00304                 lParentBorders[BORDER_RIGHT] - lEdgeInsets_[BORDER_RIGHT],
00305                 lParentBorders[BORDER_TOP]   + lEdgeInsets_[BORDER_TOP],
00306                 0.0f, fEdgeScale, fEdgeScale
00307             );
00308 
00309             lEdgeList_[EDGE_BOTTOMLEFT]->render_ex(
00310                 lParentBorders[BORDER_LEFT]   + lEdgeInsets_[BORDER_LEFT],
00311                 lParentBorders[BORDER_BOTTOM] - lEdgeInsets_[BORDER_BOTTOM],
00312                 0.0f, fEdgeScale, fEdgeScale
00313             );
00314 
00315             lEdgeList_[EDGE_BOTTOMRIGHT]->render_ex(
00316                 lParentBorders[BORDER_RIGHT]  - lEdgeInsets_[BORDER_RIGHT],
00317                 lParentBorders[BORDER_BOTTOM] - lEdgeInsets_[BORDER_BOTTOM],
00318                 0.0f, fEdgeScale, fEdgeScale
00319             );
00320 
00321             
00322             float fEdgeHeight = lParentBorders[BORDER_BOTTOM] - lEdgeInsets_[BORDER_BOTTOM]
00323                 - lParentBorders[BORDER_TOP] - lEdgeInsets_[BORDER_TOP] - 2u*uiEdgeSize_;
00324 
00325             if (fEdgeHeight > 0.0f)
00326             {
00327                 lEdgeList_[EDGE_LEFT]->set_texture_rect(
00328                     0.0f, 0.0f, uiOriginalEdgeSize_, fEdgeHeight
00329                 );
00330 
00331                 lEdgeList_[EDGE_RIGHT]->set_texture_rect(
00332                     uiOriginalEdgeSize_, 0.0f, 2u*uiOriginalEdgeSize_, fEdgeHeight
00333                 );
00334 
00335                 lEdgeList_[EDGE_LEFT]->render_2v(
00336                     lParentBorders[BORDER_LEFT]   + lEdgeInsets_[BORDER_LEFT],
00337                     lParentBorders[BORDER_TOP]    + lEdgeInsets_[BORDER_TOP]    + uiEdgeSize_,
00338 
00339                     lParentBorders[BORDER_LEFT]   + lEdgeInsets_[BORDER_LEFT]   + uiEdgeSize_,
00340                     lParentBorders[BORDER_BOTTOM] - lEdgeInsets_[BORDER_BOTTOM] - uiEdgeSize_
00341                 );
00342 
00343                 lEdgeList_[EDGE_RIGHT]->render_2v(
00344                     lParentBorders[BORDER_RIGHT]  - lEdgeInsets_[BORDER_RIGHT]  - uiEdgeSize_,
00345                     lParentBorders[BORDER_TOP]    + lEdgeInsets_[BORDER_TOP]    + uiEdgeSize_,
00346 
00347                     lParentBorders[BORDER_RIGHT]  - lEdgeInsets_[BORDER_RIGHT],
00348                     lParentBorders[BORDER_BOTTOM] - lEdgeInsets_[BORDER_BOTTOM] - uiEdgeSize_
00349                 );
00350             }
00351 
00352             float fEdgeWidth = lParentBorders[BORDER_RIGHT] - lEdgeInsets_[BORDER_RIGHT]
00353                 - lParentBorders[BORDER_LEFT] - lEdgeInsets_[BORDER_LEFT] - 2*uiEdgeSize_;
00354 
00355             if (fEdgeWidth > 0.0f)
00356             {
00357                 lEdgeList_[EDGE_TOP]->set_texture_rect(
00358                     2u*uiOriginalEdgeSize_, 0.0f, 3u*uiOriginalEdgeSize_, fEdgeWidth
00359                 );
00360 
00361                 lEdgeList_[EDGE_BOTTOM]->set_texture_rect(
00362                     3u*uiOriginalEdgeSize_, 0.0f, 4u*uiOriginalEdgeSize_, fEdgeWidth
00363                 );
00364 
00365                 lEdgeList_[EDGE_TOP]->render_4v(
00366                     lParentBorders[BORDER_RIGHT] - lEdgeInsets_[BORDER_RIGHT] - uiEdgeSize_,
00367                     lParentBorders[BORDER_TOP]   + lEdgeInsets_[BORDER_TOP],
00368 
00369                     lParentBorders[BORDER_RIGHT] - lEdgeInsets_[BORDER_RIGHT] - uiEdgeSize_,
00370                     lParentBorders[BORDER_TOP]   + lEdgeInsets_[BORDER_TOP]   + uiEdgeSize_,
00371 
00372                     lParentBorders[BORDER_LEFT]  + lEdgeInsets_[BORDER_LEFT]  + uiEdgeSize_,
00373                     lParentBorders[BORDER_TOP]   + lEdgeInsets_[BORDER_TOP]   + uiEdgeSize_,
00374 
00375                     lParentBorders[BORDER_LEFT]  + lEdgeInsets_[BORDER_LEFT]  + uiEdgeSize_,
00376                     lParentBorders[BORDER_TOP]   + lEdgeInsets_[BORDER_TOP]
00377                 );
00378 
00379                 lEdgeList_[EDGE_BOTTOM]->render_4v(
00380                     lParentBorders[BORDER_RIGHT]  - lEdgeInsets_[BORDER_RIGHT]  - uiEdgeSize_,
00381                     lParentBorders[BORDER_BOTTOM] - lEdgeInsets_[BORDER_BOTTOM] - uiEdgeSize_,
00382 
00383                     lParentBorders[BORDER_RIGHT]  - lEdgeInsets_[BORDER_RIGHT]  - uiEdgeSize_,
00384                     lParentBorders[BORDER_BOTTOM] - lEdgeInsets_[BORDER_BOTTOM],
00385 
00386                     lParentBorders[BORDER_LEFT]   + lEdgeInsets_[BORDER_LEFT]   + uiEdgeSize_,
00387                     lParentBorders[BORDER_BOTTOM] - lEdgeInsets_[BORDER_BOTTOM],
00388 
00389                     lParentBorders[BORDER_LEFT]   + lEdgeInsets_[BORDER_LEFT]   + uiEdgeSize_,
00390                     lParentBorders[BORDER_BOTTOM] - lEdgeInsets_[BORDER_BOTTOM] - uiEdgeSize_
00391                 );
00392             }
00393         }
00394     }
00395 }
00396 }