00001 #include "gui_button.hpp"
00002 #include "gui_frame.hpp"
00003 #include "gui_manager.hpp"
00004 #include "gui_fontstring.hpp"
00005 #include "gui_texture.hpp"
00006 #include "gui_event.hpp"
00007 #include "gui_out.hpp"
00008
00009 namespace gui
00010 {
00011 button::button(manager* pManager) : frame(pManager),
00012 mState_(STATE_UP), bHighlighted_(false), bLockHighlight_(false),
00013 pNormalTexture_(nullptr), pPushedTexture_(nullptr), pDisabledTexture_(nullptr),
00014 pHighlightTexture_(nullptr), pNormalText_(nullptr), pHighlightText_(nullptr),
00015 pDisabledText_(nullptr), pCurrentFontString_(nullptr),
00016 lPushedTextOffset_({{0, 0}})
00017 {
00018 enable_mouse(true);
00019 lType_.push_back("Button");
00020 }
00021
00022 button::~button()
00023 {
00024 }
00025
00026 std::string button::serialize(const std::string& sTab) const
00027 {
00028 return frame::serialize(sTab);
00029 }
00030
00031 void button::create_glue()
00032 {
00033 if (bVirtual_)
00034 {
00035 utils::wptr<lua::state> pLua = pManager_->get_lua();
00036 pLua->push_number(uiID_);
00037 lGlueList_.push_back(pLua->push_new<lua_virtual_glue>());
00038 pLua->set_global(sLuaName_);
00039 pLua->pop();
00040 }
00041 else
00042 {
00043 utils::wptr<lua::state> pLua = pManager_->get_lua();
00044 pLua->push_string(sName_);
00045 lGlueList_.push_back(pLua->push_new<lua_button>());
00046 pLua->set_global(sLuaName_);
00047 pLua->pop();
00048 }
00049 }
00050
00051 bool button::can_use_script(const std::string& sScriptName) const
00052 {
00053 if (frame::can_use_script(sScriptName))
00054 return true;
00055 else if ((sScriptName == "OnClick") ||
00056 (sScriptName == "OnDoubleClick") ||
00057 (sScriptName == "OnEnable") ||
00058 (sScriptName == "OnDisable"))
00059 return true;
00060 else
00061 return false;
00062 }
00063
00064 void button::on(const std::string& sScriptName, event* pEvent)
00065 {
00066 frame::on(sScriptName, pEvent);
00067
00068 if (is_enabled())
00069 {
00070 if (sScriptName == "Enter")
00071 highlight();
00072
00073 if (sScriptName == "Leave")
00074 {
00075 unlight();
00076
00077 if (mState_ == STATE_DOWN)
00078 release();
00079 }
00080
00081 if (sScriptName == "MouseDown")
00082 push();
00083
00084 if (sScriptName == "MouseUp")
00085 {
00086 release();
00087 on("Click");
00088 }
00089 }
00090 }
00091
00092 void button::on_event(const event& mEvent)
00093 {
00094 frame::on_event(mEvent);
00095
00096 if (!pManager_->is_input_enabled())
00097 return;
00098
00099 if (mEvent.get_name() == "MOUSE_DOUBLE_CLICKED" && bMouseInFrame_)
00100 on("DoubleClicked");
00101 }
00102
00103 void button::copy_from(uiobject* pObj)
00104 {
00105 frame::copy_from(pObj);
00106
00107 button* pButton = dynamic_cast<button*>(pObj);
00108
00109 if (pButton)
00110 {
00111 this->set_text(pButton->get_text());
00112
00113 if (pButton->get_normal_texture())
00114 {
00115 this->create_normal_texture_();
00116 if (this->is_virtual())
00117 pNormalTexture_->set_virtual();
00118 pNormalTexture_->set_name(pButton->get_normal_texture()->get_name());
00119 if (!pManager_->add_uiobject(pNormalTexture_))
00120 {
00121 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00122 "Trying to add \""+pButton->get_normal_texture()->get_name()+"\" to \""+sName_+"\",\n"
00123 "but its name was already taken : \""+pNormalTexture_->get_name()+"\". Skipped." << std::endl;
00124 delete pNormalTexture_; pNormalTexture_ = nullptr;
00125 }
00126 else
00127 {
00128 if (!is_virtual())
00129 pNormalTexture_->create_glue();
00130 pNormalTexture_->set_draw_layer(pButton->get_normal_texture()->get_draw_layer());
00131 this->add_region(pNormalTexture_);
00132 pNormalTexture_->copy_from(pButton->get_normal_texture());
00133 pNormalTexture_->notify_loaded();
00134 }
00135 }
00136 if (pButton->get_pushed_texture())
00137 {
00138 this->create_pushed_texture_();
00139 if (this->is_virtual())
00140 pPushedTexture_->set_virtual();
00141 pPushedTexture_->set_name(pButton->get_pushed_texture()->get_name());
00142 if (!pManager_->add_uiobject(pPushedTexture_))
00143 {
00144 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00145 "Trying to add \""+pButton->get_pushed_texture()->get_name()+"\" to \""+sName_+"\",\n"
00146 "but its name was already taken : \""+pPushedTexture_->get_name()+"\". Skipped." << std::endl;
00147 delete pPushedTexture_; pPushedTexture_ = nullptr;
00148 }
00149 else
00150 {
00151 if (!is_virtual())
00152 pPushedTexture_->create_glue();
00153 pPushedTexture_->set_draw_layer(pButton->get_pushed_texture()->get_draw_layer());
00154 this->add_region(pPushedTexture_);
00155 pPushedTexture_->copy_from(pButton->get_pushed_texture());
00156 pPushedTexture_->notify_loaded();
00157 }
00158 }
00159 if (pButton->get_highlight_texture())
00160 {
00161 this->create_highlight_texture_();
00162 if (this->is_virtual())
00163 pHighlightTexture_->set_virtual();
00164 pHighlightTexture_->set_name(pButton->get_highlight_texture()->get_name());
00165 if (!pManager_->add_uiobject(pHighlightTexture_))
00166 {
00167 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00168 "Trying to add \""+pButton->get_highlight_texture()->get_name()+"\" to \""+sName_+"\",\n"
00169 "but its name was already taken : \""+pHighlightTexture_->get_name()+"\". Skipped." << std::endl;
00170 delete pHighlightTexture_; pHighlightTexture_ = nullptr;
00171 }
00172 else
00173 {
00174 if (!is_virtual())
00175 pHighlightTexture_->create_glue();
00176 pHighlightTexture_->set_draw_layer(pButton->get_highlight_texture()->get_draw_layer());
00177 this->add_region(pHighlightTexture_);
00178 pHighlightTexture_->copy_from(pButton->get_highlight_texture());
00179 pHighlightTexture_->notify_loaded();
00180 }
00181 }
00182 if (pButton->get_disabled_texture())
00183 {
00184 this->create_disabled_texture_();
00185 if (this->is_virtual())
00186 pDisabledTexture_->set_virtual();
00187 pDisabledTexture_->set_name(pButton->get_disabled_texture()->get_name());
00188 if (!pManager_->add_uiobject(pDisabledTexture_))
00189 {
00190 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00191 "Trying to add \""+pButton->get_disabled_texture()->get_name()+"\" to \""+sName_+"\",\n"
00192 "but its name was already taken : \""+pDisabledTexture_->get_name()+"\". Skipped." << std::endl;
00193 delete pDisabledTexture_; pDisabledTexture_ = nullptr;
00194 }
00195 else
00196 {
00197 if (!is_virtual())
00198 pDisabledTexture_->create_glue();
00199 pDisabledTexture_->set_draw_layer(pButton->get_disabled_texture()->get_draw_layer());
00200 this->add_region(pDisabledTexture_);
00201 pDisabledTexture_->copy_from(pButton->get_disabled_texture());
00202 pDisabledTexture_->notify_loaded();
00203 }
00204 }
00205
00206 if (pButton->get_normal_text())
00207 {
00208 this->create_normal_text_();
00209 if (this->is_virtual())
00210 pNormalText_->set_virtual();
00211 pNormalText_->set_name(pButton->get_normal_text()->get_name());
00212 if (!pManager_->add_uiobject(pNormalText_))
00213 {
00214 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00215 "Trying to add \""+pButton->get_normal_text()->get_name()+"\" to \""+sName_+"\",\n"
00216 "but its name was already taken : \""+pNormalText_->get_name()+"\". Skipped." << std::endl;
00217 delete pNormalText_; pNormalText_ = nullptr;
00218 }
00219 else
00220 {
00221 if (!is_virtual())
00222 pNormalText_->create_glue();
00223 pNormalText_->set_draw_layer(pButton->get_normal_text()->get_draw_layer());
00224 this->add_region(pNormalText_);
00225 pNormalText_->copy_from(pButton->get_normal_text());
00226 pNormalText_->notify_loaded();
00227 }
00228 }
00229 if (pButton->get_highlight_text())
00230 {
00231 this->create_highlight_text_();
00232 if (this->is_virtual())
00233 pHighlightText_->set_virtual();
00234 pHighlightText_->set_name(pButton->get_highlight_text()->get_name());
00235 if (!pManager_->add_uiobject(pHighlightText_))
00236 {
00237 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00238 "Trying to add \""+pButton->get_highlight_text()->get_name()+"\" to \""+sName_+"\",\n"
00239 "but its name was already taken : \""+pHighlightText_->get_name()+"\". Skipped." << std::endl;
00240 delete pHighlightText_; pHighlightText_ = nullptr;
00241 }
00242 else
00243 {
00244 if (!is_virtual())
00245 pHighlightText_->create_glue();
00246 pHighlightText_->set_draw_layer(pButton->get_highlight_text()->get_draw_layer());
00247 this->add_region(pHighlightText_);
00248 pHighlightText_->copy_from(pButton->get_highlight_text());
00249 pHighlightText_->notify_loaded();
00250 }
00251 }
00252 if (pButton->get_disabled_text())
00253 {
00254 this->create_disabled_text_();
00255 if (this->is_virtual())
00256 pDisabledText_->set_virtual();
00257 pDisabledText_->set_name(pButton->get_disabled_text()->get_name());
00258 if (!pManager_->add_uiobject(pDisabledText_))
00259 {
00260 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00261 "Trying to add \""+pButton->get_disabled_text()->get_name()+"\" to \""+sName_+"\",\n"
00262 "but its name was already taken : \""+pDisabledText_->get_name()+"\". Skipped." << std::endl;
00263 delete pDisabledText_; pDisabledText_ = nullptr;
00264 }
00265 else
00266 {
00267 if (!is_virtual())
00268 pDisabledText_->create_glue();
00269 pDisabledText_->set_draw_layer(pButton->get_disabled_text()->get_draw_layer());
00270 this->add_region(pDisabledText_);
00271 pDisabledText_->copy_from(pButton->get_disabled_text());
00272 pDisabledText_->notify_loaded();
00273 }
00274 }
00275
00276 this->set_pushed_text_offset(pButton->get_pushed_text_offset());
00277
00278 if (!pButton->is_enabled())
00279 this->disable();
00280 }
00281 }
00282
00283 void button::set_text(const std::string& sText)
00284 {
00285 sText_ = sText;
00286
00287 if (pNormalText_)
00288 pNormalText_->set_text(sText);
00289
00290 if (pHighlightText_)
00291 pHighlightText_->set_text(sText);
00292
00293 if (pDisabledText_)
00294 pDisabledText_->set_text(sText);
00295 }
00296
00297 const std::string& button::get_text() const
00298 {
00299 return sText_;
00300 }
00301
00302 texture* button::create_normal_texture_()
00303 {
00304 if (!pNormalTexture_)
00305 {
00306 pNormalTexture_ = new texture(pManager_);
00307 pNormalTexture_->set_special();
00308 pNormalTexture_->set_parent(this);
00309 pNormalTexture_->set_draw_layer("BORDER");
00310 }
00311
00312 return pNormalTexture_;
00313 }
00314
00315 texture* button::create_pushed_texture_()
00316 {
00317 if (!pPushedTexture_)
00318 {
00319 pPushedTexture_ = new texture(pManager_);
00320 pPushedTexture_->set_special();
00321 pPushedTexture_->set_parent(this);
00322 pPushedTexture_->set_draw_layer("BORDER");
00323 }
00324
00325 return pPushedTexture_;
00326 }
00327
00328 texture* button::create_disabled_texture_()
00329 {
00330 if (!pDisabledTexture_)
00331 {
00332 pDisabledTexture_ = new texture(pManager_);
00333 pDisabledTexture_->set_special();
00334 pDisabledTexture_->set_parent(this);
00335 pDisabledTexture_->set_draw_layer("BORDER");
00336 }
00337
00338 return pDisabledTexture_;
00339 }
00340
00341 texture* button::create_highlight_texture_()
00342 {
00343 if (!pHighlightTexture_)
00344 {
00345 pHighlightTexture_ = new texture(pManager_);
00346 pHighlightTexture_->set_special();
00347 pHighlightTexture_->set_parent(this);
00348 pHighlightTexture_->set_draw_layer("HIGHLIGHT");
00349 }
00350
00351 return pHighlightTexture_;
00352 }
00353
00354 font_string* button::create_normal_text_()
00355 {
00356 if (!pNormalText_)
00357 {
00358 pNormalText_ = new font_string(pManager_);
00359 pNormalText_->set_special();
00360 pNormalText_->set_parent(this);
00361 pNormalText_->set_draw_layer("ARTWORK");
00362 pCurrentFontString_ = pNormalText_;
00363 }
00364
00365 return pNormalText_;
00366 }
00367
00368 font_string* button::create_highlight_text_()
00369 {
00370 if (!pHighlightText_)
00371 {
00372 pHighlightText_ = new font_string(pManager_);
00373 pHighlightText_->set_special();
00374 pHighlightText_->set_parent(this);
00375 pHighlightText_->set_draw_layer("ARTWORK");
00376 }
00377
00378 return pHighlightText_;
00379 }
00380
00381 font_string* button::create_disabled_text_()
00382 {
00383 if (!pDisabledText_)
00384 {
00385 pDisabledText_ = new font_string(pManager_);
00386 pDisabledText_->set_special();
00387 pDisabledText_->set_parent(this);
00388 pDisabledText_->set_draw_layer("BORDER");
00389 }
00390
00391 return pDisabledText_;
00392 }
00393
00394 texture* button::get_normal_texture()
00395 {
00396 return pNormalTexture_;
00397 }
00398
00399 texture* button::get_pushed_texture()
00400 {
00401 return pPushedTexture_;
00402 }
00403
00404 texture* button::get_disabled_texture()
00405 {
00406 return pDisabledTexture_;
00407 }
00408
00409 texture* button::get_highlight_texture()
00410 {
00411 return pHighlightTexture_;
00412 }
00413
00414 font_string* button::get_normal_text()
00415 {
00416 return pNormalText_;
00417 }
00418
00419 font_string* button::get_highlight_text()
00420 {
00421 return pHighlightText_;
00422 }
00423
00424 font_string* button::get_disabled_text()
00425 {
00426 return pDisabledText_;
00427 }
00428
00429 void button::set_normal_texture(texture* pTexture)
00430 {
00431 pNormalTexture_ = pTexture;
00432 }
00433
00434 void button::set_pushed_texture(texture* pTexture)
00435 {
00436 pPushedTexture_ = pTexture;
00437 }
00438
00439 void button::set_disabled_texture(texture* pTexture)
00440 {
00441 pDisabledTexture_ = pTexture;
00442 }
00443
00444 void button::set_highlight_texture(texture* pTexture)
00445 {
00446 pHighlightTexture_ = pTexture;
00447 }
00448
00449 void button::set_normal_text(font_string* pFont)
00450 {
00451 if (pNormalText_ == pCurrentFontString_)
00452 pCurrentFontString_ = pFont;
00453
00454 pNormalText_ = pFont;
00455 }
00456
00457 void button::set_highlight_text(font_string* pFont)
00458 {
00459 pHighlightText_ = pFont;
00460 }
00461
00462 void button::set_disabled_text(font_string* pFont)
00463 {
00464 pDisabledText_ = pFont;
00465 }
00466
00467 font_string* button::get_CurrentFontString()
00468 {
00469 return pCurrentFontString_;
00470 }
00471
00472 void button::disable()
00473 {
00474 if (is_enabled())
00475 {
00476 mState_ = STATE_DISABLED;
00477 if (pDisabledTexture_)
00478 {
00479 if (pNormalTexture_)
00480 pNormalTexture_->hide();
00481 if (pPushedTexture_)
00482 pPushedTexture_->hide();
00483
00484 pDisabledTexture_->show();
00485 }
00486 else
00487 {
00488 if (pNormalTexture_)
00489 pNormalTexture_->show();
00490 if (pPushedTexture_)
00491 pPushedTexture_->hide();
00492 }
00493
00494 if (pDisabledText_)
00495 {
00496 if (pNormalText_)
00497 pNormalText_->hide();
00498
00499 pDisabledText_->show();
00500 pCurrentFontString_ = pDisabledText_;
00501 }
00502 else
00503 {
00504 if (pNormalText_)
00505 pNormalText_->show();
00506
00507 pCurrentFontString_ = pNormalText_;
00508 }
00509
00510 unlight();
00511
00512 on("Disable");
00513 }
00514 }
00515
00516 void button::enable()
00517 {
00518 if (!is_enabled())
00519 {
00520 mState_ = STATE_UP;
00521 if (pDisabledTexture_)
00522 {
00523 if (pNormalTexture_)
00524 pNormalTexture_->show();
00525 if (pPushedTexture_)
00526 pPushedTexture_->hide();
00527
00528 pDisabledTexture_->hide();
00529 }
00530 else
00531 {
00532 if (pNormalTexture_)
00533 pNormalTexture_->show();
00534 if (pPushedTexture_)
00535 pPushedTexture_->hide();
00536 }
00537
00538 if (pNormalText_)
00539 pNormalText_->show();
00540
00541 pCurrentFontString_ = pNormalText_;
00542
00543 if (pDisabledText_)
00544 pDisabledText_->hide();
00545
00546 on("Enable");
00547 }
00548 }
00549
00550 bool button::is_enabled() const
00551 {
00552 return (mState_ != STATE_DISABLED);
00553 }
00554
00555 void button::push()
00556 {
00557 if (is_enabled())
00558 {
00559 if (pPushedTexture_)
00560 {
00561 pPushedTexture_->show();
00562 if (pNormalTexture_)
00563 pNormalTexture_->hide();
00564 }
00565
00566 if (pHighlightText_)
00567 pHighlightText_->set_offsets(lPushedTextOffset_);
00568 if (pNormalText_)
00569 pNormalText_->set_offsets(lPushedTextOffset_);
00570
00571 mState_ = STATE_DOWN;
00572 }
00573 }
00574
00575 void button::release()
00576 {
00577 if (is_enabled())
00578 {
00579 if (pPushedTexture_)
00580 {
00581 pPushedTexture_->hide();
00582 if (pNormalTexture_)
00583 pNormalTexture_->show();
00584 }
00585
00586 if (pHighlightText_)
00587 pHighlightText_->set_offsets(0, 0);
00588 if (pNormalText_)
00589 pNormalText_->set_offsets(0, 0);
00590
00591 mState_ = STATE_UP;
00592 }
00593 }
00594
00595 void button::highlight()
00596 {
00597 if (!bHighlighted_)
00598 {
00599 if (pHighlightTexture_)
00600 {
00601 pHighlightTexture_->show();
00602 }
00603
00604 if (pHighlightText_)
00605 {
00606 if (pCurrentFontString_)
00607 pCurrentFontString_->hide();
00608 pCurrentFontString_ = pHighlightText_;
00609 pCurrentFontString_->show();
00610 }
00611
00612 bHighlighted_ = true;
00613 }
00614 }
00615
00616 void button::unlight()
00617 {
00618 if (!bLockHighlight_ && bHighlighted_)
00619 {
00620 if (pHighlightTexture_)
00621 {
00622 pHighlightTexture_->hide();
00623 }
00624
00625 if (pHighlightText_)
00626 {
00627 if (pCurrentFontString_)
00628 pCurrentFontString_->hide();
00629
00630 switch (mState_)
00631 {
00632 case STATE_UP : pCurrentFontString_ = pNormalText_; break;
00633 case STATE_DOWN : pCurrentFontString_ = pNormalText_; break;
00634 case STATE_DISABLED : pCurrentFontString_ = pDisabledText_; break;
00635 }
00636
00637 if (pCurrentFontString_)
00638 pCurrentFontString_->show();
00639 }
00640
00641
00642 bHighlighted_ = false;
00643 }
00644 }
00645
00646 button::state button::get_button_state() const
00647 {
00648 return mState_;
00649 }
00650
00651 void button::lock_highlight()
00652 {
00653 highlight();
00654 bLockHighlight_ = true;
00655 }
00656
00657 void button::unlock_highlight()
00658 {
00659 if (!bMouseInFrame_)
00660 unlight();
00661
00662 bLockHighlight_ = false;
00663 }
00664
00665 void button::set_pushed_text_offset(const std::array<int,2>& lOffset)
00666 {
00667 lPushedTextOffset_ = lOffset;
00668 notify_renderer_need_redraw();
00669 }
00670
00671 const std::array<int,2>& button::get_pushed_text_offset() const
00672 {
00673 return lPushedTextOffset_;
00674 }
00675 }