00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include "guichan/exception.hpp"
00060 #include "guichan/widgets/container.hpp"
00061
00062 namespace gcn
00063 {
00064
00065 Container::Container()
00066 {
00067 mWidgetWithMouse = NULL;
00068 mOpaque = true;
00069 }
00070
00071 Container::~Container()
00072 {
00073 clear();
00074 }
00075
00076 void Container::logic()
00077 {
00078 logicChildren();
00079 }
00080
00081 void Container::draw(Graphics* graphics)
00082 {
00083 if (isOpaque())
00084 {
00085 graphics->setColor(getBaseColor());
00086 graphics->fillRectangle(Rectangle(0, 0, getWidth(), getHeight()));
00087 }
00088
00089 drawChildren(graphics);
00090 }
00091
00092 void Container::drawBorder(Graphics* graphics)
00093 {
00094 Color faceColor = getBaseColor();
00095 Color highlightColor, shadowColor;
00096 int alpha = getBaseColor().a;
00097 int width = getWidth() + getBorderSize() * 2 - 1;
00098 int height = getHeight() + getBorderSize() * 2 - 1;
00099 highlightColor = faceColor + 0x303030;
00100 highlightColor.a = alpha;
00101 shadowColor = faceColor - 0x303030;
00102 shadowColor.a = alpha;
00103
00104 unsigned int i;
00105 for (i = 0; i < getBorderSize(); ++i)
00106 {
00107 graphics->setColor(shadowColor);
00108 graphics->drawLine(i,i, width - i, i);
00109 graphics->drawLine(i,i + 1, i, height - i - 1);
00110 graphics->setColor(highlightColor);
00111 graphics->drawLine(width - i,i + 1, width - i, height - i);
00112 graphics->drawLine(i,height - i, width - i - 1, height - i);
00113 }
00114 }
00115
00116 void Container::logicChildren()
00117 {
00118 WidgetIterator iter;
00119 for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00120 {
00121 (*iter)->logic();
00122 }
00123 }
00124
00125 void Container::drawChildren(Graphics* graphics)
00126 {
00127 WidgetIterator iter;
00128 for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00129 {
00130 if ((*iter)->isVisible())
00131 {
00132
00133
00134 if ((*iter)->getBorderSize() > 0)
00135 {
00136 Rectangle rec = (*iter)->getDimension();
00137 rec.x -= (*iter)->getBorderSize();
00138 rec.y -= (*iter)->getBorderSize();
00139 rec.width += 2 * (*iter)->getBorderSize();
00140 rec.height += 2 * (*iter)->getBorderSize();
00141 graphics->pushClipArea(rec);
00142 (*iter)->drawBorder(graphics);
00143 graphics->popClipArea();
00144 }
00145
00146 graphics->pushClipArea((*iter)->getDimension());
00147 (*iter)->draw(graphics);
00148 graphics->popClipArea();
00149 }
00150 }
00151 }
00152
00153 void Container::setOpaque(bool opaque)
00154 {
00155 mOpaque = opaque;
00156 }
00157
00158 bool Container::isOpaque() const
00159 {
00160 return mOpaque;
00161 }
00162
00163 void Container::moveToTop(Widget* widget)
00164 {
00165 WidgetIterator iter;
00166 for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00167 {
00168 if (*iter == widget)
00169 {
00170 mWidgets.erase(iter);
00171 mWidgets.push_back(widget);
00172 return;
00173 }
00174 }
00175
00176 throw GCN_EXCEPTION("There is no such widget in this container.");
00177 }
00178
00179 void Container::moveToBottom(Widget* widget)
00180 {
00181 WidgetIterator iter;
00182 for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00183 {
00184 if (*iter == widget)
00185 {
00186 mWidgets.erase(iter);
00187 mWidgets.push_front(widget);
00188 return;
00189 }
00190 }
00191
00192 throw GCN_EXCEPTION("There is no such widget in this container.");
00193 }
00194
00195 void Container::_announceDeath(Widget *widget)
00196 {
00197 if (mWidgetWithMouse == widget)
00198 {
00199 mWidgetWithMouse = NULL;
00200 }
00201
00202 WidgetIterator iter;
00203 for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00204 {
00205 if (*iter == widget)
00206 {
00207 mWidgets.erase(iter);
00208 return;
00209 }
00210 }
00211
00212 throw GCN_EXCEPTION("There is no such widget in this container.");
00213 }
00214
00215 void Container::getDrawSize(int& width, int& height, Widget* widget)
00216 {
00217 WidgetIterator iter;
00218 bool contains = false;
00219
00220 for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00221 {
00222 if (widget == *iter)
00223 {
00224 contains = true;
00225 break;
00226 }
00227 }
00228
00229 if (contains)
00230 {
00231 Rectangle widgetDim = widget->getDimension();
00232 Rectangle dim = getDimension();
00233
00234 width = widgetDim.width;
00235 height = widgetDim.height;
00236
00237 if (widgetDim.x < 0)
00238 {
00239 width += widgetDim.x;
00240 }
00241
00242 if (widgetDim.y < 0)
00243 {
00244 height += widgetDim.y;
00245 }
00246
00247 if (widgetDim.x + widgetDim.width > dim.width)
00248 {
00249 width -= (widgetDim.x + widgetDim.width) - dim.width;
00250 }
00251
00252 if (widgetDim.y + widgetDim.height > dim.height)
00253 {
00254 height -= (widgetDim.y + widgetDim.height) - dim.height;
00255 }
00256
00257 if (width < 0)
00258 {
00259 width = 0;
00260 }
00261
00262 if (height < 0)
00263 {
00264 height = 0;
00265 }
00266 }
00267 else
00268 {
00269 throw GCN_EXCEPTION("Widget not in container.");
00270 }
00271 }
00272
00273 void Container::add(Widget* widget)
00274 {
00275 mWidgets.push_back(widget);
00276 widget->_setFocusHandler(_getFocusHandler());
00277 widget->_setParent(this);
00278 }
00279
00280 void Container::add(Widget* widget, int x, int y)
00281 {
00282 widget->setPosition(x, y);
00283 add(widget);
00284 }
00285
00286 void Container::remove(Widget* widget)
00287 {
00288 if (mWidgetWithMouse == widget)
00289 {
00290 mWidgetWithMouse = NULL;
00291 }
00292
00293 WidgetIterator iter;
00294 for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00295 {
00296 if (*iter == widget)
00297 {
00298 mWidgets.erase(iter);
00299 widget->_setFocusHandler(NULL);
00300 widget->_setParent(NULL);
00301 return;
00302 }
00303 }
00304
00305 throw GCN_EXCEPTION("There is no such widget in this container.");
00306 }
00307
00308 void Container::clear()
00309 {
00310 mWidgetWithMouse = NULL;
00311
00312 WidgetIterator iter;
00313
00314 for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00315 {
00316 (*iter)->_setFocusHandler(NULL);
00317 (*iter)->_setParent(NULL);
00318 }
00319
00320 mWidgets.clear();
00321 }
00322
00323 void Container::_setFocusHandler(FocusHandler* focusHandler)
00324 {
00325 Widget::_setFocusHandler(focusHandler);
00326
00327 WidgetIterator iter;
00328 for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00329 {
00330 (*iter)->_setFocusHandler(focusHandler);
00331 }
00332 }
00333
00334 void Container::_mouseInputMessage(const MouseInput &mouseInput)
00335 {
00336 Widget* tempWidgetWithMouse = NULL;
00337
00338 WidgetIterator iter;
00339 for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00340 {
00341 if ((*iter)->getDimension().isPointInRect(mouseInput.x, mouseInput.y)
00342 && (*iter)->isVisible())
00343 {
00344 tempWidgetWithMouse = (*iter);
00345 }
00346 }
00347
00348 if (tempWidgetWithMouse != mWidgetWithMouse)
00349 {
00350 if (mWidgetWithMouse)
00351 {
00352 mWidgetWithMouse->_mouseOutMessage();
00353 }
00354
00355 if (tempWidgetWithMouse)
00356 {
00357 tempWidgetWithMouse->_mouseInMessage();
00358 }
00359
00360 mWidgetWithMouse = tempWidgetWithMouse;
00361 }
00362
00363 if (mWidgetWithMouse != NULL)
00364 {
00365 MouseInput mi = mouseInput;
00366 mi.x -= mWidgetWithMouse->getX();
00367 mi.y -= mWidgetWithMouse->getY();
00368 mWidgetWithMouse->_mouseInputMessage(mi);
00369 }
00370
00371 if (mWidgetWithMouse == NULL)
00372 {
00373 BasicContainer::_mouseInputMessage(mouseInput);
00374 }
00375 }
00376
00377 void Container::_mouseOutMessage()
00378 {
00379 if (mWidgetWithMouse)
00380 {
00381 mWidgetWithMouse->_mouseOutMessage();
00382 mWidgetWithMouse = NULL;
00383 }
00384
00385 Widget::_mouseOutMessage();
00386 }
00387 }