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 }