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 }