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 }