00001 #include "gui_anchor.hpp" 00002 #include "gui_uiobject.hpp" 00003 #include "gui_frame.hpp" 00004 #include "gui_manager.hpp" 00005 #include "gui_out.hpp" 00006 00007 #include <utils_string.hpp> 00008 #include <sstream> 00009 00010 namespace gui 00011 { 00012 anchor::anchor() : 00013 pObj_(nullptr), mParentPoint_(ANCHOR_TOPLEFT), mPoint_(ANCHOR_TOPLEFT), 00014 mType_(ANCHOR_ABS), iAbsOffX_(0), iAbsOffY_(0), fRelOffX_(0.0f), fRelOffY_(0.0f), 00015 iParentWidth_(0u), iParentHeight_(0u), pParent_(nullptr), bParentUpdated_(false) 00016 { 00017 } 00018 00019 anchor::anchor(uiobject* pObj, anchor_point mPoint, const std::string& sParent, anchor_point mParentPoint) : 00020 pObj_(pObj), mParentPoint_(mParentPoint), mPoint_(mPoint), mType_(ANCHOR_ABS), 00021 iAbsOffX_(0), iAbsOffY_(0), fRelOffX_(0.0f), fRelOffY_(0.0f), 00022 iParentWidth_(0u), iParentHeight_(0u), pParent_(nullptr), sParent_(sParent), 00023 bParentUpdated_(false) 00024 { 00025 } 00026 00027 void anchor::update_parent() const 00028 { 00029 if (!bParentUpdated_) 00030 { 00031 if (!sParent_.empty()) 00032 { 00033 const uiobject* pObjParent = pObj_->get_parent(); 00034 00035 if (pObjParent) 00036 { 00037 utils::replace(sParent_, "$parent", pObjParent->get_lua_name()); 00038 } 00039 else if (sParent_.find("$parent") != sParent_.npos) 00040 { 00041 pParent_ = nullptr; 00042 bParentUpdated_ = true; 00043 return; 00044 } 00045 00046 pParent_ = pObj_->get_manager()->get_uiobject_by_name(sParent_); 00047 if (!pParent_) 00048 { 00049 gui::out << gui::warning << "gui::" << pObj_->get_object_type() << " : " 00050 << "uiobject \"" << pObj_->get_name() << "\" tries to anchor to \"" 00051 << sParent_ << "\" but this widget doesn't exist." << std::endl; 00052 } 00053 } 00054 else 00055 pParent_ = nullptr; 00056 00057 bParentUpdated_ = true; 00058 } 00059 } 00060 00061 int anchor::get_abs_x() const 00062 { 00063 if (pObj_) 00064 { 00065 update_parent(); 00066 00067 int iParentX; 00068 if (pParent_) 00069 { 00070 iParentX = pParent_->get_left(); 00071 iParentWidth_ = pParent_->get_apparent_width(); 00072 } 00073 else 00074 { 00075 iParentX = 0; 00076 iParentWidth_ = pObj_->get_manager()->get_screen_width(); 00077 } 00078 00079 int iOffset; 00080 if (mType_ == ANCHOR_ABS) 00081 iOffset = iAbsOffX_; 00082 else 00083 iOffset = fRelOffX_*iParentWidth_; 00084 00085 int iParentOffset; 00086 if ((mParentPoint_ == ANCHOR_TOPLEFT) || (mParentPoint_ == ANCHOR_LEFT) || (mParentPoint_ == ANCHOR_BOTTOMLEFT)) 00087 iParentOffset = 0; 00088 else if ((mParentPoint_ == ANCHOR_TOP) || (mParentPoint_ == ANCHOR_CENTER) || (mParentPoint_ == ANCHOR_BOTTOM)) 00089 iParentOffset = iParentWidth_/2; 00090 else if ((mParentPoint_ == ANCHOR_TOPRIGHT) || (mParentPoint_ == ANCHOR_RIGHT) || (mParentPoint_ == ANCHOR_BOTTOMRIGHT)) 00091 iParentOffset = iParentWidth_; 00092 else iParentOffset = 0; 00093 00094 return iOffset + iParentOffset + iParentX; 00095 } 00096 00097 return 0; 00098 } 00099 00100 int anchor::get_abs_y() const 00101 { 00102 if (pObj_) 00103 { 00104 update_parent(); 00105 00106 int iParentY; 00107 if (pParent_) 00108 { 00109 iParentY = pParent_->get_top(); 00110 iParentHeight_ = pParent_->get_apparent_height(); 00111 } 00112 else 00113 { 00114 iParentY = 0; 00115 iParentHeight_ = pObj_->get_manager()->get_screen_height(); 00116 } 00117 00118 int iOffset; 00119 if (mType_ == ANCHOR_ABS) 00120 iOffset = iAbsOffY_; 00121 else 00122 iOffset = fRelOffY_*iParentHeight_; 00123 00124 int iParentOffset; 00125 if ((mParentPoint_ == ANCHOR_TOPLEFT) || (mParentPoint_ == ANCHOR_TOP) || (mParentPoint_ == ANCHOR_TOPRIGHT)) 00126 iParentOffset = 0; 00127 else if ((mParentPoint_ == ANCHOR_LEFT) || (mParentPoint_ == ANCHOR_CENTER) || (mParentPoint_ == ANCHOR_RIGHT)) 00128 iParentOffset = iParentHeight_/2; 00129 else if ((mParentPoint_ == ANCHOR_BOTTOMLEFT) || (mParentPoint_ == ANCHOR_BOTTOM) || (mParentPoint_ == ANCHOR_BOTTOMRIGHT)) 00130 iParentOffset = iParentHeight_; 00131 else iParentOffset = 0; 00132 00133 return iOffset + iParentOffset + iParentY; 00134 } 00135 00136 return 0; 00137 } 00138 00139 const uiobject* anchor::get_object() const 00140 { 00141 return pObj_; 00142 } 00143 00144 const uiobject* anchor::get_parent() const 00145 { 00146 update_parent(); 00147 return pParent_; 00148 } 00149 00150 const std::string& anchor::get_parent_raw_name() const 00151 { 00152 return sParent_; 00153 } 00154 00155 anchor_point anchor::get_point() const 00156 { 00157 return mPoint_; 00158 } 00159 00160 anchor_point anchor::get_parent_point() const 00161 { 00162 return mParentPoint_; 00163 } 00164 00165 anchor_type anchor::get_type() const 00166 { 00167 return mType_; 00168 } 00169 00170 int anchor::get_abs_offset_x() const 00171 { 00172 return iAbsOffX_; 00173 } 00174 00175 int anchor::get_abs_offset_y() const 00176 { 00177 return iAbsOffY_; 00178 } 00179 00180 float anchor::get_rel_offset_x() const 00181 { 00182 return fRelOffX_; 00183 } 00184 00185 float anchor::get_rel_offset_y() const 00186 { 00187 return fRelOffY_; 00188 } 00189 00190 void anchor::set_object(uiobject* pObj) 00191 { 00192 pObj_ = pObj; 00193 } 00194 00195 void anchor::set_parent_raw_name(const std::string& sName) 00196 { 00197 sParent_ = sName; 00198 bParentUpdated_ = false; 00199 } 00200 00201 void anchor::set_point(anchor_point mPoint) 00202 { 00203 mPoint_ = mPoint; 00204 } 00205 00206 void anchor::set_parent_point(anchor_point mParentPoint) 00207 { 00208 mParentPoint_ = mParentPoint; 00209 } 00210 00211 void anchor::set_abs_offset(int iX, int iY) 00212 { 00213 iAbsOffX_ = iX; 00214 iAbsOffY_ = iY; 00215 mType_ = ANCHOR_ABS; 00216 } 00217 00218 void anchor::set_rel_offset(float fX, float fY) 00219 { 00220 fRelOffX_ = fX; 00221 fRelOffY_ = fY; 00222 mType_ = ANCHOR_REL; 00223 } 00224 00225 std::string anchor::serialize(const std::string& sTab) const 00226 { 00227 std::stringstream sStr; 00228 00229 sStr << sTab << " | # Point : " << get_string_point(mPoint_) << "\n"; 00230 if (pParent_) 00231 sStr << sTab << " | # Parent : " << pParent_->get_name(); 00232 else 00233 sStr << sTab << " | # Parent : none"; 00234 if (!sParent_.empty()) 00235 sStr << " (raw name : " << sParent_ << ")\n"; 00236 else 00237 sStr << "\n"; 00238 sStr << sTab << " | # Rel. point : " << get_string_point(mParentPoint_) << "\n"; 00239 if (mType_ == ANCHOR_ABS) 00240 { 00241 sStr << sTab << " | # Offset X : " << iAbsOffX_ << "\n"; 00242 sStr << sTab << " | # Offset Y : " << iAbsOffY_ << "\n"; 00243 } 00244 else 00245 { 00246 sStr << sTab << " | # Offset X : " << fRelOffX_ << " (" << fRelOffX_*iParentWidth_ << ")\n"; 00247 sStr << sTab << " | # Offset Y : " << fRelOffY_ << " (" << fRelOffY_*iParentHeight_ << ")\n"; 00248 } 00249 00250 return sStr.str(); 00251 } 00252 00253 std::string anchor::get_string_point(anchor_point mPoint) 00254 { 00255 switch (mPoint) 00256 { 00257 case ANCHOR_TOPLEFT : return "TOPLEFT"; 00258 case ANCHOR_TOP : return "TOP"; 00259 case ANCHOR_TOPRIGHT : return "TOPRIGHT"; 00260 case ANCHOR_RIGHT : return "RIGHT"; 00261 case ANCHOR_BOTTOMRIGHT : return "BOTTOMRIGHT"; 00262 case ANCHOR_BOTTOM : return "BOTTOM"; 00263 case ANCHOR_BOTTOMLEFT : return "BOTTOMLEFT"; 00264 case ANCHOR_LEFT : return "LEFT"; 00265 case ANCHOR_CENTER : return "CENTER"; 00266 }; 00267 return ""; 00268 } 00269 00270 anchor_point anchor::get_anchor_point(const std::string& sPoint) 00271 { 00272 if (sPoint == "TOPLEFT") return ANCHOR_TOPLEFT; 00273 else if (sPoint == "TOP") return ANCHOR_TOP; 00274 else if (sPoint == "TOPRIGHT") return ANCHOR_TOPRIGHT; 00275 else if (sPoint == "RIGHT") return ANCHOR_RIGHT; 00276 else if (sPoint == "BOTTOMRIGHT") return ANCHOR_BOTTOMRIGHT; 00277 else if (sPoint == "BOTTOM") return ANCHOR_BOTTOM; 00278 else if (sPoint == "BOTTOMLEFT") return ANCHOR_BOTTOMLEFT; 00279 else if (sPoint == "LEFT") return ANCHOR_LEFT; 00280 else if (sPoint == "CENTER") return ANCHOR_CENTER; 00281 return ANCHOR_TOPLEFT; 00282 } 00283 }