00001 #include "gui_statusbar.hpp"
00002 #include "gui_frame.hpp"
00003 #include "gui_manager.hpp"
00004 #include "gui_texture.hpp"
00005 #include "gui_out.hpp"
00006
00007 #include <sstream>
00008
00009 namespace gui
00010 {
00011 std::array<float,4> select_uvs(const std::array<float,8>& uvs)
00012 {
00013 return {{uvs[0], uvs[1], uvs[4], uvs[5]}};
00014 }
00015 status_bar::status_bar(manager* pManager) : frame(pManager),
00016 bUpdateBarTexture_(false), mOrientation_(ORIENT_HORIZONTAL), bReversed_(false),
00017 fValue_(0.0f), fMinValue_(0.0f), fMaxValue_(1.0f), mBarLayer_(LAYER_ARTWORK),
00018 pBarTexture_(nullptr), lInitialTextCoords_({{0,0,1,1}})
00019 {
00020 lType_.push_back("StatusBar");
00021 }
00022
00023 status_bar::~status_bar()
00024 {
00025 }
00026
00027 std::string status_bar::serialize(const std::string& sTab) const
00028 {
00029 std::ostringstream sStr;
00030
00031 sStr << frame::serialize(sTab);
00032 sStr << sTab << " # Orientation: ";
00033 switch (mOrientation_)
00034 {
00035 case ORIENT_HORIZONTAL : sStr << "HORIZONTAL"; break;
00036 case ORIENT_VERTICAL : sStr << "VERTICAL"; break;
00037 }
00038 sStr << "\n";
00039 sStr << sTab << " # Reversed : " << bReversed_ << "\n";
00040 sStr << sTab << " # Value : " << fValue_ << "\n";
00041 sStr << sTab << " # Min value : " << fMinValue_ << "\n";
00042 sStr << sTab << " # Max value : " << fMaxValue_ << "\n";
00043
00044 return sStr.str();
00045 }
00046
00047 bool status_bar::can_use_script(const std::string& sScriptName) const
00048 {
00049 if (frame::can_use_script(sScriptName))
00050 return true;
00051 else if (sScriptName == "OnValueChanged")
00052 return true;
00053 else
00054 return false;
00055 }
00056
00057 void status_bar::copy_from(uiobject* pObj)
00058 {
00059 frame::copy_from(pObj);
00060
00061 status_bar* pStatusBar = dynamic_cast<status_bar*>(pObj);
00062
00063 if (pStatusBar)
00064 {
00065 this->set_min_value(pStatusBar->get_min_value());
00066 this->set_max_value(pStatusBar->get_max_value());
00067 this->set_value(pStatusBar->get_value());
00068 this->set_bar_draw_layer(pStatusBar->get_bar_draw_layer());
00069 this->set_orientation(pStatusBar->get_orientation());
00070 this->set_reversed(pStatusBar->is_reversed());
00071
00072 texture* pBar = pStatusBar->get_bar_texture();
00073 if (pBar)
00074 {
00075 texture* pBarTexture = this->create_bar_texture_();
00076
00077 if (this->is_virtual())
00078 pBarTexture->set_virtual();
00079
00080 pBarTexture->set_name(pBar->get_name());
00081 if (!pManager_->add_uiobject(pBarTexture))
00082 {
00083 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00084 "Trying to add \""+pBar->get_name()+"\" to \""+sName_+"\",\n"
00085 "but its name was already taken : \""+pBarTexture->get_name()+"\". Skipped." << std::endl;
00086 delete pBarTexture; pBarTexture = nullptr;
00087 }
00088 else
00089 {
00090 if (!is_virtual())
00091 pBarTexture->create_glue();
00092
00093 this->add_region(pBarTexture);
00094 pBarTexture->copy_from(pBar);
00095 pBarTexture->notify_loaded();
00096 this->set_bar_texture(pBarTexture);
00097 }
00098 }
00099 }
00100 }
00101
00102 void status_bar::set_min_value(float fMin)
00103 {
00104 if (fMin != fMinValue_)
00105 {
00106 fMinValue_ = fMin;
00107 if (fMinValue_ > fMaxValue_) fMinValue_ = fMaxValue_;
00108 fValue_ = fValue_ > fMaxValue_ ? fMaxValue_ : (fValue_ < fMinValue_ ? fMinValue_ : fValue_);
00109 fire_update_bar_texture_();
00110 }
00111 }
00112
00113 void status_bar::set_max_value(float fMax)
00114 {
00115 if (fMax != fMaxValue_)
00116 {
00117 fMaxValue_ = fMax;
00118 if (fMaxValue_ < fMaxValue_) fMaxValue_ = fMinValue_;
00119 fValue_ = fValue_ > fMaxValue_ ? fMaxValue_ : (fValue_ < fMinValue_ ? fMinValue_ : fValue_);
00120 fire_update_bar_texture_();
00121 }
00122 }
00123
00124 void status_bar::set_min_max_values(float fMin, float fMax)
00125 {
00126 if (fMin != fMinValue_ || fMax != fMaxValue_)
00127 {
00128 fMinValue_ = std::min(fMin, fMax);
00129 fMaxValue_ = std::max(fMin, fMax);
00130 fValue_ = fValue_ > fMaxValue_ ? fMaxValue_ : (fValue_ < fMinValue_ ? fMinValue_ : fValue_);
00131 fire_update_bar_texture_();
00132 }
00133 }
00134
00135 void status_bar::set_value(float fValue)
00136 {
00137 fValue = fValue > fMaxValue_ ? fMaxValue_ : (fValue < fMinValue_ ? fMinValue_ : fValue);
00138 if (fValue != fValue_)
00139 {
00140 fValue_ = fValue;
00141 fire_update_bar_texture_();
00142 }
00143 }
00144
00145 void status_bar::set_bar_draw_layer(layer_type mBarLayer)
00146 {
00147 mBarLayer_ = mBarLayer;
00148 if (pBarTexture_)
00149 pBarTexture_->set_draw_layer(mBarLayer_);
00150 }
00151
00152 void status_bar::set_bar_draw_layer(const std::string& sBarLayer)
00153 {
00154 if (sBarLayer == "ARTWORK")
00155 mBarLayer_ = LAYER_ARTWORK;
00156 else if (sBarLayer == "BACKGROUND")
00157 mBarLayer_ = LAYER_BACKGROUND;
00158 else if (sBarLayer == "BORDER")
00159 mBarLayer_ = LAYER_BORDER;
00160 else if (sBarLayer == "HIGHLIGHT")
00161 mBarLayer_ = LAYER_HIGHLIGHT;
00162 else if (sBarLayer == "OVERLAY")
00163 mBarLayer_ = LAYER_OVERLAY;
00164 else
00165 {
00166 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00167 "Uknown layer type : \""+sBarLayer+"\". Using \"ARTWORK\"." << std::endl;
00168
00169 mBarLayer_ = LAYER_ARTWORK;
00170 }
00171
00172 if (pBarTexture_)
00173 pBarTexture_->set_draw_layer(mBarLayer_);
00174 }
00175
00176 void status_bar::set_bar_texture(texture* pBarTexture)
00177 {
00178 pBarTexture_ = pBarTexture;
00179 if (pBarTexture_)
00180 {
00181 pBarTexture_->clear_all_points();
00182
00183 if (bReversed_)
00184 pBarTexture_->set_point(anchor(pBarTexture_, ANCHOR_TOPRIGHT, "$parent", ANCHOR_TOPRIGHT));
00185 else
00186 pBarTexture_->set_point(anchor(pBarTexture_, ANCHOR_BOTTOMLEFT, "$parent", ANCHOR_BOTTOMLEFT));
00187
00188 lInitialTextCoords_ = select_uvs(pBarTexture_->get_tex_coord());
00189 fire_update_bar_texture_();
00190 }
00191 }
00192
00193 void status_bar::set_bar_color(const color& mBarColor)
00194 {
00195 if (!pBarTexture_)
00196 {
00197 texture* pBarTexture = create_bar_texture_();
00198 pBarTexture->set_name("$parentBarTexture");
00199 if (!pManager_->add_uiobject(pBarTexture))
00200 {
00201 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00202 "Trying to create bar texture for \""+sName_+"\",\n"
00203 "but the name was already taken : \""+pBarTexture->get_name()+"\". Skipped." << std::endl;
00204 delete pBarTexture; pBarTexture = nullptr;
00205 return;
00206 }
00207
00208 if (!bVirtual_)
00209 pBarTexture->create_glue();
00210
00211 add_region(pBarTexture);
00212 pBarTexture->notify_loaded();
00213 set_bar_texture(pBarTexture);
00214 }
00215
00216 mBarColor_ = mBarColor;
00217 pBarTexture_->set_color(mBarColor_);
00218 }
00219
00220 void status_bar::set_orientation(orientation mOrient)
00221 {
00222 if (mOrient != mOrientation_)
00223 {
00224 mOrientation_ = mOrient;
00225 fire_update_bar_texture_();
00226 }
00227 }
00228
00229 void status_bar::set_reversed(bool bReversed)
00230 {
00231 if (bReversed == bReversed_)
00232 return;
00233
00234 bReversed_ = bReversed;
00235
00236 if (pBarTexture_)
00237 {
00238 if (bReversed_)
00239 pBarTexture_->set_point(anchor(pBarTexture_, ANCHOR_TOPRIGHT, "$parent", ANCHOR_TOPRIGHT));
00240 else
00241 pBarTexture_->set_point(anchor(pBarTexture_, ANCHOR_BOTTOMLEFT, "$parent", ANCHOR_BOTTOMLEFT));
00242
00243 pBarTexture_->fire_update_borders();
00244 }
00245 }
00246
00247 float status_bar::get_min_value() const
00248 {
00249 return fMinValue_;
00250 }
00251
00252 float status_bar::get_max_value() const
00253 {
00254 return fMaxValue_;
00255 }
00256
00257 float status_bar::get_value() const
00258 {
00259 return fValue_;
00260 }
00261
00262 layer_type status_bar::get_bar_draw_layer() const
00263 {
00264 return mBarLayer_;
00265 }
00266
00267 texture* status_bar::get_bar_texture() const
00268 {
00269 return pBarTexture_;
00270 }
00271
00272 const color& status_bar::get_bar_color() const
00273 {
00274 return mBarColor_;
00275 }
00276
00277 status_bar::orientation status_bar::get_orientation() const
00278 {
00279 return mOrientation_;
00280 }
00281
00282 bool status_bar::is_reversed() const
00283 {
00284 return bReversed_;
00285 }
00286
00287 texture* status_bar::create_bar_texture_()
00288 {
00289 texture* pBarTexture = new texture(pManager_);
00290 pBarTexture->set_special();
00291 pBarTexture->set_parent(this);
00292 pBarTexture->set_draw_layer(mBarLayer_);
00293
00294 return pBarTexture;
00295 }
00296
00297 void status_bar::create_glue()
00298 {
00299 if (bVirtual_)
00300 {
00301 utils::wptr<lua::state> pLua = pManager_->get_lua();
00302 pLua->push_number(uiID_);
00303 lGlueList_.push_back(pLua->push_new<lua_virtual_glue>());
00304 pLua->set_global(sLuaName_);
00305 pLua->pop();
00306 }
00307 else
00308 {
00309 utils::wptr<lua::state> pLua = pManager_->get_lua();
00310 pLua->push_string(sName_);
00311 lGlueList_.push_back(pLua->push_new<lua_status_bar>());
00312 pLua->set_global(sLuaName_);
00313 pLua->pop();
00314 }
00315 }
00316
00317 void status_bar::update(float fDelta)
00318 {
00319
00320 if (bUpdateBarTexture_ && pBarTexture_)
00321 {
00322 float fCoef = (fValue_ - fMinValue_)/(fMaxValue_ - fMinValue_);
00323
00324 if (mOrientation_ == ORIENT_HORIZONTAL)
00325 {
00326 pBarTexture_->set_rel_width(fCoef);
00327 pBarTexture_->set_rel_height(1.0f);
00328 }
00329 else
00330 {
00331 pBarTexture_->set_rel_width(1.0f);
00332 pBarTexture_->set_rel_height(fCoef);
00333 }
00334
00335 if (!pBarTexture_->get_texture().empty())
00336 {
00337 std::array<float,4> uvs = lInitialTextCoords_;
00338 if (mOrientation_ == ORIENT_HORIZONTAL)
00339 {
00340 if (bReversed_)
00341 uvs[0] = (uvs[0] - uvs[2])*fCoef + uvs[2];
00342 else
00343 uvs[2] = (uvs[2] - uvs[0])*fCoef + uvs[0];
00344 }
00345 else
00346 {
00347 if (bReversed_)
00348 uvs[3] = (uvs[3] - uvs[1])*fCoef + uvs[1];
00349 else
00350 uvs[1] = (uvs[1] - uvs[3])*fCoef + uvs[3];
00351 }
00352
00353 pBarTexture_->set_tex_coord(uvs);
00354 }
00355
00356 bUpdateBarTexture_ = false;
00357 }
00358
00359 frame::update(fDelta);
00360 }
00361
00362 void status_bar::fire_update_bar_texture_()
00363 {
00364 bUpdateBarTexture_ = true;
00365 }
00366 }