1 // _________ __ __
2 // / _____// |_____________ _/ |______ ____ __ __ ______
3 // \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
4 // / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
5 // /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
6 // \/ \/ \//_____/ \/
7 // ______________________ ______________________
8 // T H E W A R B E G I N S
9 // Stratagus - A free fantasy real time strategy game engine
10 //
11 /**@name widgets.cpp - The stratagus ui widgets. */
12 //
13 // (c) Copyright 2005-2006 by Francois Beerten and Jimmy Salmon
14 //
15 // This program is free software; you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation; only version 2 of the License.
18 //
19 // This program is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU General Public License for more details.
23 //
24 // You should have received a copy of the GNU General Public License
25 // along with this program; if not, write to the Free Software
26 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 // 02111-1307, USA.
28 //
29
30 //@{
31
32 /*----------------------------------------------------------------------------
33 -- Includes
34 ----------------------------------------------------------------------------*/
35
36 #include "stratagus.h"
37 #include "video.h"
38 #include "font.h"
39 //Wyrmgus start
40 #include "grand_strategy.h"
41 //Wyrmgus end
42 #include "cursor.h"
43 #include "ui/ui.h"
44 #include "widgets.h"
45 #include "network.h"
46 #include "netconnect.h"
47 #include "editor.h"
48 #include "sound.h"
49 //Wyrmgus start
50 #include "player.h"
51 //Wyrmgus end
52 //Wyrmgus start
53 #include "results.h"
54 //Wyrmgus end
55
56 /*----------------------------------------------------------------------------
57 -- Variables
58 ----------------------------------------------------------------------------*/
59
60 // Guichan stuff we need
61 gcn::Gui *Gui; /// A Gui object - binds it all together
62 gcn::SDLInput *Input; /// Input driver
63
64 static EventCallback GuichanCallbacks;
65
66 static std::stack<MenuScreen *> MenuStack;
67
68 /*----------------------------------------------------------------------------
69 -- Functions
70 ----------------------------------------------------------------------------*/
71
72
73 //Wyrmgus start
74 //static void MenuHandleButtonDown(unsigned)
MenuHandleButtonDown(unsigned button)75 static void MenuHandleButtonDown(unsigned button)
76 //Wyrmgus end
77 {
78 }
79 //Wyrmgus start
80 //static void MenuHandleButtonUp(unsigned)
MenuHandleButtonUp(unsigned button)81 static void MenuHandleButtonUp(unsigned button)
82 //Wyrmgus end
83 {
84 }
MenuHandleMouseMove(const PixelPos & screenPos)85 static void MenuHandleMouseMove(const PixelPos &screenPos)
86 {
87 PixelPos pos(screenPos);
88 HandleCursorMove(&pos.x, &pos.y);
89 }
MenuHandleKeyDown(unsigned key,unsigned keychar)90 static void MenuHandleKeyDown(unsigned key, unsigned keychar)
91 {
92 HandleKeyModifiersDown(key, keychar);
93 }
MenuHandleKeyUp(unsigned key,unsigned keychar)94 static void MenuHandleKeyUp(unsigned key, unsigned keychar)
95 {
96 //Wyrmgus start
97 if (key == 'f') { // ALT+F and CTRL+F toggle fullscreen
98 if (KeyModifiers & (ModifierAlt | ModifierControl)) {
99 ToggleFullScreen();
100 CclCommand("wyr.preferences.VideoFullScreen = Video.FullScreen;");
101 SavePreferences();
102 }
103 /*
104 } else if (key == 'g') { // ALT+G, CTRL+G grab mouse pointer
105 if (KeyModifiers & (ModifierAlt | ModifierControl)) {
106 UiToggleGrabMouse();
107 CclCommand("wyr.preferences.GrabMouse = GetGrabMouse();");
108 SavePreferences();
109 }
110 */
111 }
112 //Wyrmgus end
113 HandleKeyModifiersUp(key, keychar);
114 }
MenuHandleKeyRepeat(unsigned key,unsigned keychar)115 static void MenuHandleKeyRepeat(unsigned key, unsigned keychar)
116 {
117 Input->processKeyRepeat();
118 HandleKeyModifiersDown(key, keychar);
119 }
120
121
122 /**
123 ** Initializes the GUI stuff
124 */
initGuichan()125 void initGuichan()
126 {
127 gcn::Graphics *graphics;
128
129 #if defined(USE_OPENGL) || defined(USE_GLES)
130 if (UseOpenGL) {
131 graphics = new MyOpenGLGraphics();
132 } else
133 #endif
134 {
135 graphics = new gcn::SDLGraphics();
136
137 // Set the target for the graphics object to be the screen.
138 // In other words, we will draw to the screen.
139 // Note, any surface will do, it doesn't have to be the screen.
140 ((gcn::SDLGraphics *)graphics)->setTarget(TheScreen);
141 }
142
143 Input = new gcn::SDLInput();
144
145 Gui = new gcn::Gui();
146 Gui->setGraphics(graphics);
147 Gui->setInput(Input);
148 Gui->setTop(nullptr);
149
150 #if defined(USE_OPENGL) || defined(USE_GLES)
151 Gui->setUseDirtyDrawing(!UseOpenGL);
152 #else
153 Gui->setUseDirtyDrawing(1);
154 #endif
155
156 GuichanCallbacks.ButtonPressed = &MenuHandleButtonDown;
157 GuichanCallbacks.ButtonReleased = &MenuHandleButtonUp;
158 GuichanCallbacks.MouseMoved = &MenuHandleMouseMove;
159 GuichanCallbacks.MouseExit = &HandleMouseExit;
160 GuichanCallbacks.KeyPressed = &MenuHandleKeyDown;
161 GuichanCallbacks.KeyReleased = &MenuHandleKeyUp;
162 GuichanCallbacks.KeyRepeated = &MenuHandleKeyRepeat;
163 GuichanCallbacks.NetworkEvent = NetworkEvent;
164 }
165
166 /**
167 ** Free all guichan infrastructure
168 */
freeGuichan()169 void freeGuichan()
170 {
171 if (Gui) {
172 delete Gui->getGraphics();
173 delete Gui;
174 Gui = nullptr;
175 }
176
177 delete Input;
178 Input = nullptr;
179 }
180
181 /**
182 ** Handle input events
183 **
184 ** @param event event to handle, null if no more events for this frame
185 */
handleInput(const SDL_Event * event)186 void handleInput(const SDL_Event *event)
187 {
188 if (event) {
189 if (Input) {
190 try {
191 Input->pushInput(*event);
192 } catch (const gcn::Exception &) {
193 // ignore unhandled buttons
194 }
195 }
196 } else {
197 if (Gui) {
198 Gui->logic();
199 }
200 }
201 }
202
DrawGuichanWidgets()203 void DrawGuichanWidgets()
204 {
205 if (Gui) {
206 #if defined(USE_OPENGL) || defined(USE_GLES)
207 Gui->setUseDirtyDrawing(!UseOpenGL && !GameRunning && !Editor.Running);
208 #else
209 Gui->setUseDirtyDrawing(!GameRunning && !Editor.Running);
210 #endif
211 Gui->draw();
212 }
213 }
214
215
216 /*----------------------------------------------------------------------------
217 -- LuaActionListener
218 ----------------------------------------------------------------------------*/
219
220
221 /**
222 ** LuaActionListener constructor
223 **
224 ** @param l Lua state
225 ** @param f Listener function
226 */
LuaActionListener(lua_State * l,lua_Object f)227 LuaActionListener::LuaActionListener(lua_State *l, lua_Object f) :
228 callback(l, f)
229 {
230 }
231
232 /**
233 ** Called when an action is received from a Widget. It is used
234 ** to be able to receive a notification that an action has
235 ** occurred.
236 **
237 ** @param eventId the identifier of the Widget
238 */
action(const std::string & eventId)239 void LuaActionListener::action(const std::string &eventId)
240 {
241 callback.pushPreamble();
242 callback.pushString(eventId.c_str());
243 callback.run();
244 }
245
246 /**
247 ** LuaActionListener destructor
248 */
~LuaActionListener()249 LuaActionListener::~LuaActionListener()
250 {
251 }
252
253 #if defined(USE_OPENGL) || defined(USE_GLES)
254
255 /*----------------------------------------------------------------------------
256 -- MyOpenGLGraphics
257 ----------------------------------------------------------------------------*/
258
_beginDraw()259 void MyOpenGLGraphics::_beginDraw()
260 {
261 gcn::Rectangle area(0, 0, Video.Width, Video.Height);
262 pushClipArea(area);
263 }
264
_endDraw()265 void MyOpenGLGraphics::_endDraw()
266 {
267 popClipArea();
268 }
269
270 //Wyrmgus start
271 //void MyOpenGLGraphics::drawImage(const gcn::Image *image, int srcX, int srcY,
272 // int dstX, int dstY, int width, int height)
drawImage(gcn::Image * image,int srcX,int srcY,int dstX,int dstY,int width,int height,int player,unsigned int transparency)273 void MyOpenGLGraphics::drawImage(gcn::Image *image, int srcX, int srcY,
274 int dstX, int dstY, int width, int height, int player, unsigned int transparency)
275 //Wyrmgus end
276 {
277 const gcn::ClipRectangle &r = this->getCurrentClipArea();
278 int right = std::min<int>(r.x + r.width - 1, Video.Width - 1);
279 int bottom = std::min<int>(r.y + r.height - 1, Video.Height - 1);
280
281 if (r.x > right || r.y > bottom) {
282 return;
283 }
284
285 PushClipping();
286 SetClipping(r.x, r.y, right, bottom);
287 //Wyrmgus start
288 // ((CGraphic *)image)->DrawSubClip(srcX, srcY, width, height,
289 // dstX + mClipStack.top().xOffset, dstY + mClipStack.top().yOffset);
290 if (player != -1) {
291 ((CPlayerColorGraphic *)image)->DrawPlayerColorSubClip(player, srcX, srcY, width, height,
292 dstX + mClipStack.top().xOffset, dstY + mClipStack.top().yOffset);
293 } else {
294 ((CGraphic *)image)->DrawSubClip(srcX, srcY, width, height,
295 dstX + mClipStack.top().xOffset, dstY + mClipStack.top().yOffset);
296 }
297 //Wyrmgus end
298 PopClipping();
299 }
300
drawPoint(int x,int y)301 void MyOpenGLGraphics::drawPoint(int x, int y)
302 {
303 gcn::Color c = this->getColor();
304 Video.DrawPixelClip(Video.MapRGBA(0, c.r, c.g, c.b, c.a),
305 x + mClipStack.top().xOffset, y + mClipStack.top().yOffset);
306 }
307
drawLine(int x1,int y1,int x2,int y2)308 void MyOpenGLGraphics::drawLine(int x1, int y1, int x2, int y2)
309 {
310 gcn::Color c = this->getColor();
311 const PixelPos pos1(x1 + mClipStack.top().xOffset, y1 + mClipStack.top().yOffset);
312 const PixelPos pos2(x2 + mClipStack.top().xOffset, y2 + mClipStack.top().yOffset);
313
314 Video.DrawLineClip(Video.MapRGBA(0, c.r, c.g, c.b, c.a), pos1, pos2);
315 }
316
drawRectangle(const gcn::Rectangle & rectangle)317 void MyOpenGLGraphics::drawRectangle(const gcn::Rectangle &rectangle)
318 {
319 gcn::Color c = this->getColor();
320 if (c.a == 0) {
321 return;
322 }
323
324 const gcn::ClipRectangle top = mClipStack.top();
325 gcn::Rectangle area = gcn::Rectangle(rectangle.x + top.xOffset,
326 rectangle.y + top.yOffset,
327 rectangle.width, rectangle.height);
328
329 if (!area.intersect(top)) {
330 return;
331 }
332
333 int x1 = std::max<int>(area.x, top.x);
334 int y1 = std::max<int>(area.y, top.y);
335 int x2 = std::min<int>(area.x + area.width, top.x + top.width);
336 int y2 = std::min<int>(area.y + area.height, top.y + top.height);
337
338 Video.DrawTransRectangle(Video.MapRGB(0, c.r, c.g, c.b),
339 x1, y1, x2 - x1, y2 - y1, mColor.a);
340 }
341
fillRectangle(const gcn::Rectangle & rectangle)342 void MyOpenGLGraphics::fillRectangle(const gcn::Rectangle &rectangle)
343 {
344 const gcn::Color c = this->getColor();
345
346 if (c.a == 0) {
347 return;
348 }
349
350 const gcn::ClipRectangle top = mClipStack.top();
351 gcn::Rectangle area = gcn::Rectangle(rectangle.x + top.xOffset,
352 rectangle.y + top.yOffset,
353 rectangle.width, rectangle.height);
354
355 if (!area.intersect(top)) {
356 return;
357 }
358
359 int x1 = std::max<int>(area.x, top.x);
360 int y1 = std::max<int>(area.y, top.y);
361 int x2 = std::min<int>(area.x + area.width, top.x + top.width);
362 int y2 = std::min<int>(area.y + area.height, top.y + top.height);
363
364 Video.FillTransRectangle(Video.MapRGB(0, c.r, c.g, c.b),
365 x1, y1, x2 - x1, y2 - y1, c.a);
366 }
367
368 #endif
369
370 //Wyrmgus start
371 /*----------------------------------------------------------------------------
372 -- PlayerColorImageWidget
373 ----------------------------------------------------------------------------*/
374
draw(gcn::Graphics * graphics)375 void PlayerColorImageWidget::draw(gcn::Graphics* graphics)
376 {
377 int WidgetPlayerColorIndexFromName = GetPlayerColorIndexByName(WidgetPlayerColor);
378 if (WidgetPlayerColorIndexFromName == -1) {
379 fprintf(stderr, "Color %s not defined\n", WidgetPlayerColor.c_str());
380 ExitFatal(1);
381 }
382
383 graphics->drawImage(mImage, ImageOrigin.x, ImageOrigin.y, 0, 0, mImage->getWidth(), mImage->getHeight(), WidgetPlayerColorIndexFromName);
384 }
385 //Wyrmgus end
386
387 /*----------------------------------------------------------------------------
388 -- ImageButton
389 ----------------------------------------------------------------------------*/
390
391
392 /**
393 ** ImageButton constructor
394 */
ImageButton()395 ImageButton::ImageButton() :
396 Button(), normalImage(nullptr), pressedImage(nullptr),
397 //Wyrmgus start
398 // disabledImage(nullptr)
399 disabledImage(nullptr), frameImage(nullptr), pressedframeImage(nullptr), Transparency(0)
400 //Wyrmgus end
401 {
402 setForegroundColor(0xffffff);
403 //Wyrmgus start
404 ImageOrigin.x = 0;
405 ImageOrigin.y = 0;
406 //Wyrmgus end
407 }
408
409 /**
410 ** ImageButton constructor
411 **
412 ** @param caption Caption text
413 */
ImageButton(const std::string & caption)414 ImageButton::ImageButton(const std::string &caption) :
415 Button(caption), normalImage(nullptr), pressedImage(nullptr),
416 //Wyrmgus start
417 // disabledImage(nullptr)
418 disabledImage(nullptr), frameImage(nullptr), pressedframeImage(nullptr), Transparency(0)
419 //Wyrmgus end
420 {
421 setForegroundColor(0xffffff);
422 //Wyrmgus start
423 ImageOrigin.x = 0;
424 ImageOrigin.y = 0;
425 //Wyrmgus end
426 }
427
428 /**
429 ** Draw the image button
430 **
431 ** @param graphics Graphics object to draw with
432 */
draw(gcn::Graphics * graphics)433 void ImageButton::draw(gcn::Graphics *graphics)
434 {
435 if (!normalImage) {
436 Button::draw(graphics);
437 return;
438 }
439
440 gcn::Image *img;
441
442 if (!isEnabled()) {
443 img = disabledImage ? disabledImage : normalImage;
444 } else if (isPressed()) {
445 img = pressedImage ? pressedImage : normalImage;
446 } else if (0 && hasMouse()) {
447 // FIXME: add mouse-over image
448 img = nullptr;
449 } else {
450 img = normalImage;
451 }
452
453 //Wyrmgus start
454 if (img) {
455 if (Transparency) {
456 #if defined(USE_OPENGL) || defined(USE_GLES)
457 if (UseOpenGL) {
458 } else
459 #endif
460 {
461 WidgetGraphicTransparency(int(256 - 2.56 * Transparency), *((CGraphic *)img));
462 }
463 }
464 }
465
466 // graphics->drawImage(img, 0, 0, 0, 0,
467 // img->getWidth(), img->getHeight());
468
469 if (frameImage) {
470 graphics->setColor(ColorBlack);
471 graphics->fillRectangle(gcn::Rectangle((frameImage->getWidth() - img->getWidth()) / 2, (frameImage->getHeight() - img->getHeight()) / 2, img->getWidth(), img->getHeight()));
472 graphics->drawImage(frameImage, 0, 0, 0, 0,
473 frameImage->getWidth(), frameImage->getHeight());
474 if (isPressed()) {
475 if (Transparency) {
476 #if defined(USE_OPENGL) || defined(USE_GLES)
477 if (UseOpenGL) {
478 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
479 glColor4ub(255, 255, 255, int(256 - 2.56 * Transparency));
480 }
481 #endif
482 }
483 graphics->drawImage(img, ImageOrigin.x, ImageOrigin.y, ((frameImage->getWidth() - img->getWidth()) / 2) + 1, ((frameImage->getHeight() - img->getHeight()) / 2) + 1,
484 img->getWidth() - 1, img->getHeight() - 1);
485 if (Transparency) {
486 #if defined(USE_OPENGL) || defined(USE_GLES)
487 if (UseOpenGL) {
488 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
489 }
490 #endif
491 }
492 if (pressedframeImage) {
493 graphics->drawImage(pressedframeImage, 0, 0, 0, 0,
494 pressedframeImage->getWidth(), pressedframeImage->getHeight());
495 }
496 } else {
497 if (Transparency) {
498 #if defined(USE_OPENGL) || defined(USE_GLES)
499 if (UseOpenGL) {
500 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
501 glColor4ub(255, 255, 255, int(256 - 2.56 * Transparency));
502 }
503 #endif
504 }
505 graphics->drawImage(img, ImageOrigin.x, ImageOrigin.y, (frameImage->getWidth() - img->getWidth()) / 2, (frameImage->getHeight() - img->getHeight()) / 2,
506 img->getWidth(), img->getHeight());
507 if (Transparency) {
508 #if defined(USE_OPENGL) || defined(USE_GLES)
509 if (UseOpenGL) {
510 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
511 }
512 #endif
513 }
514 }
515 } else {
516 if (Transparency) {
517 #if defined(USE_OPENGL) || defined(USE_GLES)
518 if (UseOpenGL) {
519 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
520 glColor4ub(255, 255, 255, int(256 - 2.56 * Transparency));
521 }
522 #endif
523 }
524 graphics->drawImage(img, ImageOrigin.x, ImageOrigin.y, 0, 0,
525 img->getWidth(), img->getHeight());
526 if (Transparency) {
527 #if defined(USE_OPENGL) || defined(USE_GLES)
528 if (UseOpenGL) {
529 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
530 }
531 #endif
532 }
533 }
534 //Wyrmgus end
535
536 graphics->setColor(getForegroundColor());
537
538 int textX;
539 int textY = getHeight() / 2 - getFont()->getHeight() / 2;
540
541 switch (getAlignment()) {
542 case gcn::Graphics::LEFT:
543 textX = 4;
544 break;
545 case gcn::Graphics::CENTER:
546 textX = getWidth() / 2;
547 break;
548 case gcn::Graphics::RIGHT:
549 textX = getWidth() - 4;
550 break;
551 default:
552 textX = 0;
553 Assert(!"Unknown alignment.");
554 //throw GCN_EXCEPTION("Unknown alignment.");
555 }
556
557 graphics->setFont(getFont());
558 //Wyrmgus start
559 /*
560 if (isPressed()) {
561 graphics->drawText(getCaption(), textX + 4, textY + 4, getAlignment());
562 } else {
563 graphics->drawText(getCaption(), textX + 2, textY + 2, getAlignment());
564 }
565 */
566 bool is_normal = true;
567 if (hasMouse()) {
568 is_normal = false;
569 }
570 if (isPressed()) {
571 textX += 4;
572 textY += 4;
573 if ((textY + 11) > (getHeight() - 2)) {
574 textY += (getHeight() - 2) - (textY + 11);
575 }
576 if (textY < 1) {
577 textY = 1;
578 }
579 } else {
580 textX += 2;
581 textY += 2;
582 if ((textY + 11) > (getHeight() - 3)) {
583 textY += (getHeight() - 3) - (textY + 11);
584 }
585 if (textY < 0) {
586 textY = 0;
587 }
588 }
589 graphics->drawText(getCaption(), textX, textY, getAlignment(), is_normal);
590 //Wyrmgus end
591
592 //Wyrmgus start
593 // if (hasFocus()) {
594 if (isPressed() && !frameImage) {
595 //Wyrmgus end
596 //Wyrmgus start
597 // graphics->drawRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
598 if (getWidth() == getHeight() && getWidth() > 64 && getHeight() > 64) {
599 graphics->drawRectangle(gcn::Rectangle(0 + ((getWidth() - 64) / 2), 0 + ((getHeight() - 64) / 2), getWidth() - (getWidth() - 64), getHeight() - (getHeight() - 64))); //hack to make it appear properly in grand strategy mode
600 } else {
601 graphics->drawRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
602 }
603 //Wyrmgus end
604 }
605
606 //Wyrmgus start
607 //restore old alpha
608 #if defined(USE_OPENGL) || defined(USE_GLES)
609 if (UseOpenGL) {
610 } else
611 #endif
612 {
613 WidgetGraphicTransparency(255, *((CGraphic *)img));
614 }
615 //Wyrmgus end
616 }
617
618 /**
619 ** Automatically adjust the size of an image button
620 */
adjustSize()621 void ImageButton::adjustSize()
622 {
623 //Wyrmgus start
624 // if (normalImage) {
625 if (frameImage) {
626 setWidth(frameImage->getWidth());
627 setHeight(frameImage->getHeight());
628 setPosition(getX(), getY()); //reset position, to make it appropriate for the frame image
629 } else if (normalImage) {
630 //Wyrmgus end
631 setWidth(normalImage->getWidth());
632 setHeight(normalImage->getHeight());
633 } else {
634 Button::adjustSize();
635 }
636 }
637
638 //Wyrmgus start
setPosition(int x,int y)639 void ImageButton::setPosition(int x, int y)
640 {
641 if (frameImage) {
642 mDimension.x = x - ((frameImage->getWidth() - normalImage->getWidth()) / 2);
643 mDimension.y = y - ((frameImage->getHeight() - normalImage->getWidth()) / 2);
644 } else {
645 mDimension.x = x;
646 mDimension.y = y;
647 }
648 }
649
650 /*----------------------------------------------------------------------------
651 -- PlayerColorImageButtonImageButton
652 ----------------------------------------------------------------------------*/
653
654
655 /**
656 ** PlayerColorImageButton constructor
657 */
PlayerColorImageButton()658 PlayerColorImageButton::PlayerColorImageButton() :
659 Button(), normalImage(nullptr), pressedImage(nullptr),
660 disabledImage(nullptr), frameImage(nullptr), pressedframeImage(nullptr), ButtonPlayerColor(""), Transparency(0)
661 {
662 setForegroundColor(0xffffff);
663 ImageOrigin.x = 0;
664 ImageOrigin.y = 0;
665 }
666
667 /**
668 ** PlayerColorImageButton constructor
669 **
670 ** @param caption Caption text
671 */
PlayerColorImageButton(const std::string & caption,const std::string & playercolor)672 PlayerColorImageButton::PlayerColorImageButton(const std::string &caption, const std::string &playercolor) :
673 Button(caption), normalImage(nullptr), pressedImage(nullptr),
674 disabledImage(nullptr), frameImage(nullptr), pressedframeImage(nullptr), ButtonPlayerColor(playercolor), Transparency(0)
675 {
676 setForegroundColor(0xffffff);
677 ImageOrigin.x = 0;
678 ImageOrigin.y = 0;
679 }
680
681 /**
682 ** Draw the image button
683 **
684 ** @param graphics Graphics object to draw with
685 */
draw(gcn::Graphics * graphics)686 void PlayerColorImageButton::draw(gcn::Graphics *graphics)
687 {
688 if (!normalImage) {
689 Button::draw(graphics);
690 return;
691 }
692
693 gcn::Image *img;
694
695 if (!isEnabled()) {
696 img = disabledImage ? disabledImage : normalImage;
697 } else if (isPressed()) {
698 img = pressedImage ? pressedImage : normalImage;
699 } else if (0 && hasMouse()) {
700 // FIXME: add mouse-over image
701 img = nullptr;
702 } else {
703 img = normalImage;
704 }
705
706 int WidgetPlayerColorIndexFromName = GetPlayerColorIndexByName(ButtonPlayerColor);
707 if (WidgetPlayerColorIndexFromName == -1) {
708 fprintf(stderr, "Color %s not defined\n", ButtonPlayerColor.c_str());
709 ExitFatal(1);
710 }
711
712 if (frameImage) {
713 graphics->setColor(ColorBlack);
714 graphics->fillRectangle(gcn::Rectangle((frameImage->getWidth() - img->getWidth()) / 2, (frameImage->getHeight() - img->getHeight()) / 2, img->getWidth(), img->getHeight()));
715 graphics->drawImage(frameImage, 0, 0, 0, 0,
716 frameImage->getWidth(), frameImage->getHeight());
717 if (isPressed()) {
718 if (Transparency) {
719 #if defined(USE_OPENGL) || defined(USE_GLES)
720 if (UseOpenGL) {
721 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
722 glColor4ub(255, 255, 255, int(256 - 2.56 * Transparency));
723 }
724 #endif
725 }
726 graphics->drawImage(img, ImageOrigin.x, ImageOrigin.y, ((frameImage->getWidth() - img->getWidth()) / 2) + 1, ((frameImage->getHeight() - img->getHeight()) / 2) + 1,
727 img->getWidth() - 1, img->getHeight() - 1, WidgetPlayerColorIndexFromName, Transparency);
728 if (Transparency) {
729 #if defined(USE_OPENGL) || defined(USE_GLES)
730 if (UseOpenGL) {
731 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
732 }
733 #endif
734 }
735 if (pressedframeImage) {
736 graphics->drawImage(pressedframeImage, 0, 0, 0, 0,
737 pressedframeImage->getWidth(), pressedframeImage->getHeight());
738 }
739 } else {
740 if (Transparency) {
741 #if defined(USE_OPENGL) || defined(USE_GLES)
742 if (UseOpenGL) {
743 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
744 glColor4ub(255, 255, 255, int(256 - 2.56 * Transparency));
745 }
746 #endif
747 }
748 graphics->drawImage(img, ImageOrigin.x, ImageOrigin.y, (frameImage->getWidth() - img->getWidth()) / 2, (frameImage->getHeight() - img->getHeight()) / 2,
749 img->getWidth(), img->getHeight(), WidgetPlayerColorIndexFromName, Transparency);
750 if (Transparency) {
751 #if defined(USE_OPENGL) || defined(USE_GLES)
752 if (UseOpenGL) {
753 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
754 }
755 #endif
756 }
757 }
758 } else {
759 if (Transparency) {
760 #if defined(USE_OPENGL) || defined(USE_GLES)
761 if (UseOpenGL) {
762 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
763 glColor4ub(255, 255, 255, int(256 - 2.56 * Transparency));
764 }
765 #endif
766 }
767 graphics->drawImage(img, ImageOrigin.x, ImageOrigin.y, 0, 0,
768 img->getWidth(), img->getHeight(), WidgetPlayerColorIndexFromName, Transparency);
769 if (Transparency) {
770 #if defined(USE_OPENGL) || defined(USE_GLES)
771 if (UseOpenGL) {
772 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
773 }
774 #endif
775 }
776 }
777
778 graphics->setColor(getForegroundColor());
779
780 int textX;
781 int textY = getHeight() / 2 - getFont()->getHeight() / 2;
782
783 switch (getAlignment()) {
784 case gcn::Graphics::LEFT:
785 textX = 4;
786 break;
787 case gcn::Graphics::CENTER:
788 textX = getWidth() / 2;
789 break;
790 case gcn::Graphics::RIGHT:
791 textX = getWidth() - 4;
792 break;
793 default:
794 textX = 0;
795 Assert(!"Unknown alignment.");
796 //throw GCN_EXCEPTION("Unknown alignment.");
797 }
798
799 graphics->setFont(getFont());
800 bool is_normal = true;
801 if (hasMouse()) {
802 is_normal = false;
803 }
804 if (isPressed()) {
805 graphics->drawText(getCaption(), textX + 4, textY + 4, getAlignment(), is_normal);
806 } else {
807 graphics->drawText(getCaption(), textX + 2, textY + 2, getAlignment(), is_normal);
808 }
809
810 if (isPressed() && !frameImage) {
811 // graphics->drawRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
812 if (getWidth() == getHeight() && getWidth() > 64 && getHeight() > 64) {
813 graphics->drawRectangle(gcn::Rectangle(0 + ((getWidth() - 64) / 2), 0 + ((getHeight() - 64) / 2), getWidth() - (getWidth() - 64), getHeight() - (getHeight() - 64))); //hack to make it appear properly in grand strategy mode
814 } else {
815 graphics->drawRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
816 }
817 }
818 }
819
820 /**
821 ** Automatically adjust the size of an image button
822 */
adjustSize()823 void PlayerColorImageButton::adjustSize()
824 {
825 if (frameImage) {
826 setWidth(frameImage->getWidth());
827 setHeight(frameImage->getHeight());
828 setPosition(getX(), getY()); //reset position, to make it appropriate for the frame image
829 } else if (normalImage) {
830 setWidth(normalImage->getWidth());
831 setHeight(normalImage->getHeight());
832 } else {
833 Button::adjustSize();
834 }
835 }
836
setPosition(int x,int y)837 void PlayerColorImageButton::setPosition(int x, int y)
838 {
839 if (frameImage) {
840 mDimension.x = x - ((frameImage->getWidth() - normalImage->getWidth()) / 2);
841 mDimension.y = y - ((frameImage->getHeight() - normalImage->getWidth()) / 2);
842 } else {
843 mDimension.x = x;
844 mDimension.y = y;
845 }
846 }
847
848 /**
849 ** Set transparency.
850 **
851 ** FIXME: use function pointer here.
852 **
853 ** @param player Pointer to player.
854 ** @param sprite The sprite in which the colors should be changed.
855 */
WidgetGraphicTransparency(int alpha,const CGraphic & sprite)856 void WidgetGraphicTransparency(int alpha, const CGraphic &sprite)
857 {
858 SDL_LockSurface(sprite.Surface);
859 // int oldalpha = Surface->format->alpha;
860 SDL_SetAlpha(sprite.Surface, SDL_SRCALPHA, alpha);
861 SDL_UnlockSurface(sprite.Surface);
862 }
863 //Wyrmgus end
864
865 /*----------------------------------------------------------------------------
866 -- ImageRadioButton
867 ----------------------------------------------------------------------------*/
868
869
870 /**
871 ** ImageRadioButton constructor
872 */
ImageRadioButton()873 ImageRadioButton::ImageRadioButton() : gcn::RadioButton(),
874 uncheckedNormalImage(nullptr), uncheckedPressedImage(nullptr), uncheckedDisabledImage(nullptr),
875 checkedNormalImage(nullptr), checkedPressedImage(nullptr), checkedDisabledImage(nullptr),
876 mMouseDown(false)
877 {
878 }
879
880 /**
881 ** ImageRadioButton constructor
882 */
ImageRadioButton(const std::string & caption,const std::string & group,bool marked)883 ImageRadioButton::ImageRadioButton(const std::string &caption,
884 const std::string &group, bool marked) :
885 gcn::RadioButton(caption, group, marked),
886 uncheckedNormalImage(nullptr), uncheckedPressedImage(nullptr), uncheckedDisabledImage(nullptr),
887 checkedNormalImage(nullptr), checkedPressedImage(nullptr), checkedDisabledImage(nullptr),
888 mMouseDown(false)
889 {
890 }
891
892 /**
893 ** Draw the image radio button (not the caption)
894 */
drawBox(gcn::Graphics * graphics)895 void ImageRadioButton::drawBox(gcn::Graphics *graphics)
896 {
897 gcn::Image *img = nullptr;
898
899 if (isMarked()) {
900 if (isEnabled() == false) {
901 img = checkedDisabledImage;
902 } else if (mMouseDown) {
903 img = checkedPressedImage;
904 } else {
905 img = checkedNormalImage;
906 }
907 } else {
908 if (isEnabled() == false) {
909 img = uncheckedDisabledImage;
910 } else if (mMouseDown) {
911 img = uncheckedPressedImage;
912 } else {
913 img = uncheckedNormalImage;
914 }
915 }
916
917 if (img) {
918 graphics->drawImage(img, 0, 0, 0, (getHeight() - img->getHeight()) / 2,
919 img->getWidth(), img->getHeight());
920 } else {
921 RadioButton::drawBox(graphics);
922 }
923 }
924
925 /**
926 ** Draw the image radio button
927 */
draw(gcn::Graphics * graphics)928 void ImageRadioButton::draw(gcn::Graphics *graphics)
929 {
930 drawBox(graphics);
931
932 graphics->setFont(getFont());
933 graphics->setColor(getForegroundColor());
934
935 int width;
936 if (uncheckedNormalImage) {
937 width = uncheckedNormalImage->getWidth();
938 width += width / 2;
939 } else {
940 width = getHeight();
941 width += width / 2;
942 }
943
944 graphics->drawText(getCaption(), width - 2, 0);
945
946 if (hasFocus()) {
947 graphics->drawRectangle(gcn::Rectangle(width - 4, 0, getWidth() - width + 3, getHeight()));
948 }
949 }
950
951 /**
952 ** Mouse button pressed callback
953 */
mousePress(int,int,int button)954 void ImageRadioButton::mousePress(int, int, int button)
955 {
956 if (button == gcn::MouseInput::LEFT && hasMouse()) {
957 mMouseDown = true;
958 }
959 }
960
961 /**
962 ** Mouse button released callback
963 */
mouseRelease(int,int,int button)964 void ImageRadioButton::mouseRelease(int, int, int button)
965 {
966 if (button == gcn::MouseInput::LEFT) {
967 mMouseDown = false;
968 }
969 }
970
971 /**
972 ** Mouse clicked callback
973 */
mouseClick(int,int,int button,int)974 void ImageRadioButton::mouseClick(int, int, int button, int)
975 {
976 if (button == gcn::MouseInput::LEFT) {
977 setMarked(true);
978 generateAction();
979 }
980 }
981
982 /**
983 ** Adjusts the size to fit the image and font size
984 */
adjustSize()985 void ImageRadioButton::adjustSize()
986 {
987 int width, height;
988
989 height = getFont()->getHeight();
990 if (uncheckedNormalImage) {
991 width = uncheckedNormalImage->getWidth();
992 width += width / 2;
993 height = std::max(height, uncheckedNormalImage->getHeight());
994 } else {
995 width = getFont()->getHeight();
996 width += width / 2;
997 }
998
999 setHeight(height);
1000 setWidth(getFont()->getWidth(mCaption) + width);
1001 }
1002
1003
1004 /*----------------------------------------------------------------------------
1005 -- ImageCheckbox
1006 ----------------------------------------------------------------------------*/
1007
1008
1009 /**
1010 ** Image checkbox constructor
1011 */
ImageCheckBox()1012 ImageCheckBox::ImageCheckBox() : gcn::CheckBox(),
1013 uncheckedNormalImage(nullptr), uncheckedPressedImage(nullptr), uncheckedDisabledImage(nullptr),
1014 checkedNormalImage(nullptr), checkedPressedImage(nullptr), checkedDisabledImage(nullptr),
1015 mMouseDown(false)
1016 {
1017 }
1018
1019 /**
1020 ** Image checkbox constructor
1021 */
ImageCheckBox(const std::string & caption,bool marked)1022 ImageCheckBox::ImageCheckBox(const std::string &caption, bool marked) :
1023 gcn::CheckBox(caption, marked),
1024 uncheckedNormalImage(nullptr), uncheckedPressedImage(nullptr), uncheckedDisabledImage(nullptr),
1025 checkedNormalImage(nullptr), checkedPressedImage(nullptr), checkedDisabledImage(nullptr),
1026 mMouseDown(false)
1027 {
1028 }
1029
1030 /**
1031 ** Draw the image checkbox
1032 */
draw(gcn::Graphics * graphics)1033 void ImageCheckBox::draw(gcn::Graphics *graphics)
1034 {
1035 drawBox(graphics);
1036
1037 graphics->setFont(getFont());
1038 graphics->setColor(getForegroundColor());
1039
1040 int width;
1041 if (uncheckedNormalImage) {
1042 width = uncheckedNormalImage->getWidth();
1043 width += width / 2;
1044 } else {
1045 width = getHeight();
1046 width += width / 2;
1047 }
1048
1049 graphics->drawText(getCaption(), width - 2, 0);
1050
1051 if (hasFocus()) {
1052 graphics->drawRectangle(gcn::Rectangle(width - 4, 0, getWidth() - width + 3, getHeight()));
1053 }
1054 }
1055
1056 /**
1057 ** Draw the checkbox (not the caption)
1058 */
drawBox(gcn::Graphics * graphics)1059 void ImageCheckBox::drawBox(gcn::Graphics *graphics)
1060 {
1061 gcn::Image *img = nullptr;
1062
1063 if (mMarked) {
1064 if (isEnabled() == false) {
1065 img = checkedDisabledImage;
1066 } else if (mMouseDown) {
1067 img = checkedPressedImage;
1068 } else {
1069 img = checkedNormalImage;
1070 }
1071 } else {
1072 if (isEnabled() == false) {
1073 img = uncheckedDisabledImage;
1074 } else if (mMouseDown) {
1075 img = uncheckedPressedImage;
1076 } else {
1077 img = uncheckedNormalImage;
1078 }
1079 }
1080
1081 if (img) {
1082 graphics->drawImage(img, 0, 0, 0, (getHeight() - img->getHeight()) / 2,
1083 img->getWidth(), img->getHeight());
1084 } else {
1085 CheckBox::drawBox(graphics);
1086 }
1087 }
1088
1089 /**
1090 ** Mouse button pressed callback
1091 */
mousePress(int,int,int button)1092 void ImageCheckBox::mousePress(int, int, int button)
1093 {
1094 if (button == gcn::MouseInput::LEFT && hasMouse()) {
1095 mMouseDown = true;
1096 }
1097 }
1098
1099 /**
1100 ** Mouse button released callback
1101 */
mouseRelease(int,int,int button)1102 void ImageCheckBox::mouseRelease(int, int, int button)
1103 {
1104 if (button == gcn::MouseInput::LEFT) {
1105 mMouseDown = false;
1106 }
1107 }
1108
1109 /**
1110 ** Mouse clicked callback
1111 */
mouseClick(int,int,int button,int)1112 void ImageCheckBox::mouseClick(int, int, int button, int)
1113 {
1114 if (button == gcn::MouseInput::LEFT) {
1115 toggle();
1116 }
1117 }
1118
1119 /**
1120 ** Adjusts the size to fit the image and font size
1121 */
adjustSize()1122 void ImageCheckBox::adjustSize()
1123 {
1124 int width, height;
1125
1126 height = getFont()->getHeight();
1127 if (uncheckedNormalImage) {
1128 width = uncheckedNormalImage->getWidth();
1129 width += width / 2;
1130 height = std::max(height, uncheckedNormalImage->getHeight());
1131 } else {
1132 width = getFont()->getHeight();
1133 width += width / 2;
1134 }
1135
1136 setHeight(height);
1137 setWidth(getFont()->getWidth(mCaption) + width);
1138 }
1139
1140
1141 /*----------------------------------------------------------------------------
1142 -- ImageSlider
1143 ----------------------------------------------------------------------------*/
1144
1145
1146 /**
1147 ** Image slider constructor
1148 */
ImageSlider(double scaleEnd)1149 ImageSlider::ImageSlider(double scaleEnd) :
1150 Slider(scaleEnd), markerImage(nullptr), backgroundImage(nullptr), disabledBackgroundImage(nullptr)
1151 {
1152 }
1153
1154 /**
1155 ** Image slider constructor
1156 */
ImageSlider(double scaleStart,double scaleEnd)1157 ImageSlider::ImageSlider(double scaleStart, double scaleEnd) :
1158 Slider(scaleStart, scaleEnd), markerImage(nullptr), backgroundImage(nullptr), disabledBackgroundImage(nullptr)
1159 {
1160 }
1161
1162 /**
1163 ** Draw the image slider marker
1164 */
drawMarker(gcn::Graphics * graphics)1165 void ImageSlider::drawMarker(gcn::Graphics *graphics)
1166 {
1167 gcn::Image *img = markerImage;
1168
1169 if (isEnabled()) {
1170 if (img) {
1171 if (getOrientation() == HORIZONTAL) {
1172 int v = getMarkerPosition();
1173 graphics->drawImage(img, 0, 0, v, 0,
1174 img->getWidth(), img->getHeight());
1175 } else {
1176 int v = (getHeight() - getMarkerLength()) - getMarkerPosition();
1177 graphics->drawImage(img, 0, 0, 0, v,
1178 img->getWidth(), img->getHeight());
1179 }
1180 } else {
1181 Slider::drawMarker(graphics);
1182 }
1183 }
1184 }
1185
1186 /**
1187 ** Draw the image slider
1188 */
draw(gcn::Graphics * graphics)1189 void ImageSlider::draw(gcn::Graphics *graphics)
1190 {
1191 gcn::Image *img = nullptr;
1192
1193 if (isEnabled()) {
1194 img = backgroundImage;
1195 } else {
1196 img = disabledBackgroundImage;
1197 }
1198
1199 if (img) {
1200 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
1201 if (isEnabled()) {
1202 drawMarker(graphics);
1203 }
1204 } else {
1205 Slider::draw(graphics);
1206 }
1207 }
1208
1209 /**
1210 ** Set the marker image
1211 */
setMarkerImage(gcn::Image * image)1212 void ImageSlider::setMarkerImage(gcn::Image *image)
1213 {
1214 markerImage = image;
1215 setMarkerLength(image->getWidth());
1216 }
1217
1218 /**
1219 ** Set the background image
1220 */
setBackgroundImage(gcn::Image * image)1221 void ImageSlider::setBackgroundImage(gcn::Image *image)
1222 {
1223 backgroundImage = image;
1224 }
1225
1226 /**
1227 ** Set the disabled background image
1228 */
setDisabledBackgroundImage(gcn::Image * image)1229 void ImageSlider::setDisabledBackgroundImage(gcn::Image *image)
1230 {
1231 disabledBackgroundImage = image;
1232 }
1233
1234
1235 /*----------------------------------------------------------------------------
1236 -- MultiLineLabel
1237 ----------------------------------------------------------------------------*/
1238
1239
1240 /**
1241 ** MultiLineLabel constructor
1242 */
MultiLineLabel()1243 MultiLineLabel::MultiLineLabel()
1244 {
1245 this->mAlignment = LEFT;
1246 this->mVerticalAlignment = TOP;
1247 this->mLineWidth = 0;
1248 }
1249
1250 /**
1251 ** MultiLineLabel constructor
1252 */
MultiLineLabel(const std::string & caption)1253 MultiLineLabel::MultiLineLabel(const std::string &caption)
1254 {
1255 this->mCaption = caption;
1256 this->mAlignment = LEFT;
1257 this->mVerticalAlignment = TOP;
1258
1259 this->mLineWidth = 999999;
1260 this->wordWrap();
1261 this->adjustSize();
1262 }
1263
1264 /**
1265 ** Set the caption
1266 */
setCaption(const std::string & caption)1267 void MultiLineLabel::setCaption(const std::string &caption)
1268 {
1269 this->mCaption = caption;
1270 this->wordWrap();
1271 this->setDirty(true);
1272 }
1273
1274 /**
1275 ** Get the caption
1276 */
getCaption() const1277 const std::string &MultiLineLabel::getCaption() const
1278 {
1279 return this->mCaption;
1280 }
1281
1282 /**
1283 ** Set the horizontal alignment
1284 */
setAlignment(unsigned int alignment)1285 void MultiLineLabel::setAlignment(unsigned int alignment)
1286 {
1287 this->mAlignment = alignment;
1288 }
1289
1290 /**
1291 ** Get the horizontal alignment
1292 */
getAlignment()1293 unsigned int MultiLineLabel::getAlignment()
1294 {
1295 return this->mAlignment;
1296 }
1297
1298 /**
1299 ** Set the vertical alignment
1300 */
setVerticalAlignment(unsigned int alignment)1301 void MultiLineLabel::setVerticalAlignment(unsigned int alignment)
1302 {
1303 this->mVerticalAlignment = alignment;
1304 }
1305
1306 /**
1307 ** Get the vertical alignment
1308 */
getVerticalAlignment()1309 unsigned int MultiLineLabel::getVerticalAlignment()
1310 {
1311 return this->mVerticalAlignment;
1312 }
1313
1314 /**
1315 ** Set the line width
1316 */
setLineWidth(int width)1317 void MultiLineLabel::setLineWidth(int width)
1318 {
1319 this->mLineWidth = width;
1320 this->wordWrap();
1321 }
1322
1323 /**
1324 ** Get the line width
1325 */
getLineWidth()1326 int MultiLineLabel::getLineWidth()
1327 {
1328 return this->mLineWidth;
1329 }
1330
1331 /**
1332 ** Adjust the size
1333 */
adjustSize()1334 void MultiLineLabel::adjustSize()
1335 {
1336 int width = 0;
1337 for (int i = 0; i < (int)this->mTextRows.size(); ++i) {
1338 int w = this->getFont()->getWidth(this->mTextRows[i]);
1339 if (width < w) {
1340 width = std::min(w, this->mLineWidth);
1341 }
1342 }
1343 this->setWidth(width);
1344 this->setHeight(this->getFont()->getHeight() * this->mTextRows.size());
1345 }
1346
1347 /**
1348 ** Draw the label
1349 */
draw(gcn::Graphics * graphics)1350 void MultiLineLabel::draw(gcn::Graphics *graphics)
1351 {
1352 graphics->setFont(getFont());
1353 graphics->setColor(getForegroundColor());
1354
1355 int textX, textY;
1356 switch (this->getAlignment()) {
1357 case LEFT:
1358 textX = 0;
1359 break;
1360 case CENTER:
1361 textX = this->getWidth() / 2;
1362 break;
1363 case RIGHT:
1364 textX = this->getWidth();
1365 break;
1366 default:
1367 textX = 0;
1368 Assert(!"Unknown alignment.");
1369 //throw GCN_EXCEPTION("Unknown alignment.");
1370 }
1371 switch (this->getVerticalAlignment()) {
1372 case TOP:
1373 textY = 0;
1374 break;
1375 case CENTER:
1376 textY = (this->getHeight() - (int)this->mTextRows.size() * this->getFont()->getHeight()) / 2;
1377 break;
1378 case BOTTOM:
1379 textY = this->getHeight() - (int)this->mTextRows.size() * this->getFont()->getHeight();
1380 break;
1381 default:
1382 textY = 0;
1383 Assert(!"Unknown alignment.");
1384 //throw GCN_EXCEPTION("Unknown alignment.");
1385 }
1386
1387 for (int i = 0; i < (int)this->mTextRows.size(); ++i) {
1388 graphics->drawText(this->mTextRows[i], textX, textY + i * this->getFont()->getHeight(),
1389 this->getAlignment());
1390 }
1391 }
1392
1393 /**
1394 ** Draw the border
1395 */
drawBorder(gcn::Graphics * graphics)1396 void MultiLineLabel::drawBorder(gcn::Graphics *graphics)
1397 {
1398 gcn::Color faceColor = getBaseColor();
1399 gcn::Color highlightColor, shadowColor;
1400 int alpha = getBaseColor().a;
1401 int width = getWidth() + getBorderSize() * 2 - 1;
1402 int height = getHeight() + getBorderSize() * 2 - 1;
1403 highlightColor = faceColor + 0x303030;
1404 highlightColor.a = alpha;
1405 shadowColor = faceColor - 0x303030;
1406 shadowColor.a = alpha;
1407
1408 for (unsigned int i = 0; i < getBorderSize(); ++i) {
1409 graphics->setColor(shadowColor);
1410 graphics->drawLine(i, i, width - i, i);
1411 graphics->drawLine(i, i + 1, i, height - i - 1);
1412 graphics->setColor(highlightColor);
1413 graphics->drawLine(width - i, i + 1, width - i, height - i);
1414 graphics->drawLine(i, height - i, width - i - 1, height - i);
1415 }
1416 }
1417
1418 /**
1419 ** Do word wrap
1420 */
wordWrap()1421 void MultiLineLabel::wordWrap()
1422 {
1423 gcn::Font *font = this->getFont();
1424 int lineWidth = this->getLineWidth();
1425 std::string str = this->getCaption();
1426 size_t pos, lastPos;
1427 std::string substr;
1428 bool done = false;
1429 bool first = true;
1430
1431 this->mTextRows.clear();
1432
1433 while (!done) {
1434 if (str.find('\n') != std::string::npos || font->getWidth(str) > lineWidth) {
1435 // string too wide or has a newline, split it up
1436 first = true;
1437 lastPos = 0;
1438 while (1) {
1439 // look for any whitespace
1440 pos = str.find_first_of(" \t\n", first ? 0 : lastPos + 1);
1441 if (pos != std::string::npos) {
1442 // found space, now check width
1443 substr = str.substr(0, pos);
1444 if (font->getWidth(substr) > lineWidth) {
1445 // sub-string is too big, use last good position
1446 if (first) {
1447 // didn't find a good last position
1448 substr = str.substr(0, pos);
1449 this->mTextRows.push_back(substr);
1450 str = str.substr(pos + 1);
1451 break;
1452 } else {
1453 substr = str.substr(0, lastPos);
1454 this->mTextRows.push_back(substr);
1455 // If we stopped at a space then skip any extra spaces but stop at a newline
1456 if (str[lastPos] != '\n') {
1457 while (str[lastPos + 1] == ' ' || str[lastPos + 1] == '\t' || str[lastPos + 1] == '\n') {
1458 ++lastPos;
1459 if (str[lastPos] == '\n') {
1460 break;
1461 }
1462 }
1463 }
1464 str = str.substr(lastPos + 1);
1465 break;
1466 }
1467 } else {
1468 // sub-string is small enough
1469 // stop if we found a newline, otherwise look for next space
1470 if (str[pos] == '\n') {
1471 substr = str.substr(0, pos);
1472 this->mTextRows.push_back(substr);
1473 str = str.substr(pos + 1);
1474 break;
1475 }
1476 }
1477 } else {
1478 // no space found
1479 if (first) {
1480 // didn't find a good last position, we're done
1481 this->mTextRows.push_back(str);
1482 done = true;
1483 break;
1484 } else {
1485 substr = str.substr(0, lastPos);
1486 this->mTextRows.push_back(substr);
1487 str = str.substr(lastPos + 1);
1488 break;
1489 }
1490 }
1491 lastPos = pos;
1492 first = false;
1493 }
1494 } else {
1495 // string small enough
1496 this->mTextRows.push_back(str);
1497 done = true;
1498 }
1499 }
1500 }
1501
1502
1503 /*----------------------------------------------------------------------------
1504 -- ScrollingWidget
1505 ----------------------------------------------------------------------------*/
1506
1507
1508 /**
1509 ** ScrollingWidget constructor.
1510 **
1511 ** @param width Width of the widget.
1512 ** @param height Height of the widget.
1513 */
ScrollingWidget(int width,int height)1514 ScrollingWidget::ScrollingWidget(int width, int height) :
1515 gcn::ScrollArea(nullptr, gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_NEVER),
1516 speedY(1.f), containerY(0.f), finished(false)
1517 {
1518 container.setDimension(gcn::Rectangle(0, 0, width, height));
1519 container.setOpaque(false);
1520 setContent(&container);
1521 setDimension(gcn::Rectangle(0, 0, width, height));
1522 }
1523
1524 /**
1525 ** Add a widget in the window.
1526 **
1527 ** @param widget Widget to add.
1528 ** @param x Position of the widget in the window.
1529 ** @param y Position of the widget in the window.
1530 */
add(gcn::Widget * widget,int x,int y)1531 void ScrollingWidget::add(gcn::Widget *widget, int x, int y)
1532 {
1533 container.add(widget, x, y);
1534 if (x + widget->getWidth() > container.getWidth()) {
1535 container.setWidth(x + widget->getWidth());
1536 }
1537 if (y + widget->getHeight() > container.getHeight()) {
1538 container.setHeight(y + widget->getHeight());
1539 }
1540 }
1541
1542 /**
1543 ** Scrolling the content when possible.
1544 */
logic()1545 void ScrollingWidget::logic()
1546 {
1547 setDirty(true);
1548 if (container.getHeight() + containerY - speedY > 0) {
1549 // the bottom of the container is lower than the top
1550 // of the widget. It is thus still visible.
1551 containerY -= speedY;
1552 container.setY((int)containerY);
1553 } else if (!finished) {
1554 finished = true;
1555 generateAction();
1556 }
1557 }
1558
1559 /**
1560 ** Restart animation to the beginning.
1561 */
restart()1562 void ScrollingWidget::restart()
1563 {
1564 container.setY(0);
1565 containerY = 0.f;
1566 finished = (container.getHeight() == getHeight());
1567 }
1568
1569
1570 /*----------------------------------------------------------------------------
1571 -- Windows
1572 ----------------------------------------------------------------------------*/
1573
1574
1575 /**
1576 ** Windows constructor.
1577 **
1578 ** @param title Title of the window.
1579 ** @param width Width of the window.
1580 ** @param height Height of the window.
1581 */
Windows(const std::string & title,int width,int height)1582 Windows::Windows(const std::string &title, int width, int height) :
1583 Window(title), blockwholewindow(true)
1584 {
1585 container.setDimension(gcn::Rectangle(0, 0, width, height));
1586 scroll.setDimension(gcn::Rectangle(0, 0, width, height));
1587 this->setContent(&scroll);
1588 scroll.setContent(&container);
1589 this->resizeToContent();
1590 }
1591
1592 /**
1593 ** Add a widget in the window.
1594 **
1595 ** @param widget Widget to add.
1596 ** @param x Position of the widget in the window.
1597 ** @param y Position of the widget in the window.
1598 */
add(gcn::Widget * widget,int x,int y)1599 void Windows::add(gcn::Widget *widget, int x, int y)
1600 {
1601 container.add(widget, x, y);
1602 if (x + widget->getWidth() > container.getWidth()) {
1603 container.setWidth(x + widget->getWidth());
1604 }
1605 if (y + widget->getHeight() > container.getHeight()) {
1606 container.setHeight(y + widget->getHeight());
1607 }
1608 }
1609
1610 /**
1611 ** Move the window when it is dragged.
1612 **
1613 ** @param x X coordinate of the mouse relative to the window.
1614 ** @param y Y coordinate of the mouse relative to the widndow.
1615 **
1616 ** @note Once dragged, without release the mouse,
1617 ** if you go virtually outside the container then go back,
1618 ** you have to wait the virtual cursor are in the container.
1619 ** It is because x, y argument refer to a virtual cursor :(
1620 ** @note An another thing is strange
1621 ** when the container is a "scrollable" ScrollArea with the cursor.
1622 ** The cursor can go outside the visual area.
1623 */
mouseMotion(int x,int y)1624 void Windows::mouseMotion(int x, int y)
1625 {
1626 gcn::BasicContainer *bcontainer = getParent();
1627 int diffx;
1628 int diffy;
1629 int criticalx;
1630 int criticaly;
1631 int absx;
1632 int absy;
1633
1634 if (!mMouseDrag || !isMovable()) {
1635 return;
1636 }
1637
1638 diffx = x - mMouseXOffset;
1639 diffy = y - mMouseYOffset;
1640 if (blockwholewindow) {
1641 criticalx = getX();
1642 criticaly = getY();
1643 } else {
1644 criticalx = getX() + mMouseXOffset;
1645 criticaly = getY() + mMouseYOffset;
1646 }
1647
1648
1649 if (criticalx + diffx < 0) {
1650 diffx = -criticalx;
1651 }
1652 if (criticaly + diffy < 0) {
1653 diffy = -criticaly;
1654 }
1655
1656 if (blockwholewindow) {
1657 criticalx = getX() + getWidth();
1658 criticaly = getY() + getHeight();
1659 }
1660 if (criticalx + diffx >= bcontainer->getWidth()) {
1661 diffx = bcontainer->getWidth() - criticalx;
1662 }
1663 if (criticaly + diffy >= bcontainer->getHeight()) {
1664 diffy = bcontainer->getHeight() - criticaly;
1665 }
1666
1667 // Place the window.
1668 x = getX() + diffx;
1669 y = getY() + diffy;
1670 setPosition(x, y);
1671
1672 // Move the cursor.
1673 // Useful only when window reachs the limit.
1674 getAbsolutePosition(absx, absy);
1675 CursorScreenPos.x = absx + mMouseXOffset;
1676 CursorScreenPos.y = absy + mMouseYOffset;
1677 }
1678
1679 /**
1680 ** Set background color of the window.
1681 **
1682 ** @param color Color to set.
1683 */
setBackgroundColor(const gcn::Color & color)1684 void Windows::setBackgroundColor(const gcn::Color &color)
1685 {
1686 Window::setBackgroundColor(color);
1687 scroll.setBackgroundColor(color);
1688 }
1689
1690 /**
1691 ** Set base color of the windows.
1692 **
1693 ** @param color Color to set.
1694 */
setBaseColor(const gcn::Color & color)1695 void Windows::setBaseColor(const gcn::Color &color)
1696 {
1697 Window::setBaseColor(color);
1698 container.setBaseColor(color);
1699 }
1700
1701 /*----------------------------------------------------------------------------
1702 -- ImageTextField
1703 ----------------------------------------------------------------------------*/
1704
draw(gcn::Graphics * graphics)1705 void ImageTextField::draw(gcn::Graphics *graphics)
1706 {
1707 gcn::Font *font;
1708 int x, y;
1709 CGraphic *img = this->itemImage;
1710 if (!img) {
1711 fprintf(stderr, "Not all graphics for ImageTextField were set\n");
1712 ExitFatal(1);
1713 }
1714 img->Resize(getWidth(), img->getHeight());
1715 graphics->drawImage(img, 0, 0, 0, 0, getWidth(), img->getHeight());
1716
1717 if (hasFocus())
1718 {
1719 drawCaret(graphics, getFont()->getWidth(mText.substr(0, mCaretPosition)) - mXScroll);
1720 }
1721
1722 graphics->setColor(getForegroundColor());
1723 font = getFont();
1724 graphics->setFont(font);
1725
1726 x = 1 - mXScroll;
1727 y = 1;
1728
1729 if (mSelectEndOffset != 0)
1730 {
1731 unsigned int first;
1732 unsigned int len;
1733 int selX;
1734 int selW;
1735 std::string tmpStr;
1736
1737 getTextSelectionPositions(&first, &len);
1738
1739 tmpStr = std::string(mText.substr(0, first));
1740 selX = font->getWidth(tmpStr);
1741
1742 tmpStr = std::string(mText.substr(first, len));
1743 selW = font->getWidth(tmpStr);
1744
1745 graphics->setColor(gcn::Color(127, 127, 127));
1746 graphics->fillRectangle(gcn::Rectangle(x + selX, y, selW, font->getHeight()));
1747 }
1748
1749 graphics->drawText(mText, x, y);
1750 }
1751
drawBorder(gcn::Graphics * graphics)1752 void ImageTextField::drawBorder(gcn::Graphics *graphics)
1753 {
1754 gcn::Color faceColor = getBaseColor();
1755 gcn::Color highlightColor, shadowColor;
1756 int alpha = getBaseColor().a;
1757 int width = getWidth() + getBorderSize() * 2 - 1;
1758 int height = getHeight() + getBorderSize() * 2 - 1;
1759 height = itemImage ? std::max<int>(height, itemImage->getHeight()) : height;
1760 highlightColor = faceColor + 0x303030;
1761 highlightColor.a = alpha;
1762 shadowColor = faceColor - 0x303030;
1763 shadowColor.a = alpha;
1764
1765 unsigned int i;
1766 for (i = 0; i < getBorderSize(); ++i)
1767 {
1768 graphics->setColor(shadowColor);
1769 graphics->drawLine(i,i, width - i, i);
1770 graphics->drawLine(i,i + 1, i, height - i - 1);
1771 graphics->setColor(highlightColor);
1772 graphics->drawLine(width - i,i + 1, width - i, height - i);
1773 graphics->drawLine(i,height - i, width - i - 1, height - i);
1774 }
1775 }
1776
1777 /*----------------------------------------------------------------------------
1778 -- LuaListModel
1779 ----------------------------------------------------------------------------*/
1780
1781
1782 /**
1783 ** Set the list
1784 */
setList(lua_State * lua,lua_Object * lo)1785 void LuaListModel::setList(lua_State *lua, lua_Object *lo)
1786 {
1787 list.clear();
1788
1789 const int args = lua_rawlen(lua, *lo);
1790 for (int j = 0; j < args; ++j) {
1791 list.push_back(std::string(LuaToString(lua, *lo, j + 1)));
1792 }
1793 }
1794
1795 /*----------------------------------------------------------------------------
1796 -- ImageListBox
1797 ----------------------------------------------------------------------------*/
1798
ImageListBox()1799 ImageListBox::ImageListBox() : gcn::ListBox(), itemImage(nullptr)
1800 {
1801 }
1802
ImageListBox(gcn::ListModel * listModel)1803 ImageListBox::ImageListBox(gcn::ListModel *listModel) : gcn::ListBox(listModel), itemImage(nullptr)
1804 {
1805 }
1806
draw(gcn::Graphics * graphics)1807 void ImageListBox::draw(gcn::Graphics *graphics)
1808 {
1809 if (mListModel == nullptr) {
1810 return;
1811 }
1812
1813 graphics->setColor(getForegroundColor());
1814 graphics->setFont(getFont());
1815
1816 int i, fontHeight;
1817 int y = 0;
1818 CGraphic *img = itemImage;
1819 //Wyrmgus start
1820 // img->Resize(getWidth(), img->getHeight());
1821 //Wyrmgus end
1822
1823 fontHeight = std::max<int>(getFont()->getHeight(), img->getHeight());
1824
1825 /**
1826 * @todo Check cliprects so we do not have to iterate over elements in the list model
1827 */
1828 for (i = 0; i < mListModel->getNumberOfElements(); ++i) {
1829 graphics->drawImage(img, 0, 0, 0, y, getWidth(), img->getHeight());
1830 if (i == mSelected) {
1831 graphics->drawText("~<" + mListModel->getElementAt(i) + "~>", 1, y + (fontHeight - getFont()->getHeight()) / 2);
1832 } else {
1833 graphics->drawText(mListModel->getElementAt(i), 1, y + (fontHeight - getFont()->getHeight()) / 2);
1834 }
1835
1836 y += fontHeight;
1837 }
1838 img->SetOriginalSize();
1839 }
1840
drawBorder(gcn::Graphics * graphics)1841 void ImageListBox::drawBorder(gcn::Graphics *graphics)
1842 {
1843 gcn::Color faceColor = getBaseColor();
1844 gcn::Color highlightColor, shadowColor;
1845 int alpha = getBaseColor().a;
1846 int width = getWidth() + getBorderSize() * 2 - 1;
1847 int height = getHeight() + getBorderSize() * 2 - 1;
1848 highlightColor = faceColor + 0x303030;
1849 highlightColor.a = alpha;
1850 shadowColor = faceColor - 0x303030;
1851 shadowColor.a = alpha;
1852
1853 unsigned int i;
1854 for (i = 0; i < getBorderSize(); ++i)
1855 {
1856 graphics->setColor(shadowColor);
1857 graphics->drawLine(i,i, width - i, i);
1858 graphics->drawLine(i,i + 1, i, height - i - 1);
1859 graphics->setColor(highlightColor);
1860 graphics->drawLine(width - i,i + 1, width - i, height - i);
1861 graphics->drawLine(i,height - i, width - i - 1, height - i);
1862 }
1863 }
1864
adjustSize()1865 void ImageListBox::adjustSize()
1866 {
1867 if (mListModel != nullptr)
1868 {
1869 setHeight((itemImage ? std::max<int>(getFont()->getHeight(), itemImage->getHeight()) : getFont()->getHeight()) * mListModel->getNumberOfElements());
1870 }
1871 }
1872
mousePress(int,int y,int button)1873 void ImageListBox::mousePress(int, int y, int button)
1874 {
1875 if (button == gcn::MouseInput::LEFT && hasMouse())
1876 {
1877 setSelected(y / (itemImage ? std::max<int>(getFont()->getHeight(), itemImage->getHeight()) : getFont()->getHeight()));
1878 generateAction();
1879 }
1880 }
1881
setSelected(int selected)1882 void ImageListBox::setSelected(int selected)
1883 {
1884 if (mListModel == nullptr)
1885 {
1886 mSelected = -1;
1887 }
1888 else
1889 {
1890 if (selected < 0)
1891 {
1892 mSelected = -1;
1893 }
1894 else if (selected >= mListModel->getNumberOfElements())
1895 {
1896 mSelected = mListModel->getNumberOfElements() - 1;
1897 }
1898 else
1899 {
1900 mSelected = selected;
1901 }
1902
1903 Widget *par = getParent();
1904 if (par == nullptr)
1905 {
1906 return;
1907 }
1908
1909 gcn::ScrollArea* scrollArea = dynamic_cast<gcn::ScrollArea *>(par);
1910 if (scrollArea != nullptr)
1911 {
1912 gcn::Rectangle scroll;
1913 scroll.y = (itemImage ? std::max<int>(getFont()->getHeight(), itemImage->getHeight()) : getFont()->getHeight()) * mSelected;
1914 scroll.height = (itemImage ? std::max<int>(getFont()->getHeight(), itemImage->getHeight()) : getFont()->getHeight());
1915 scrollArea->scrollToRectangle(scroll);
1916 }
1917 }
1918 }
1919
setListModel(gcn::ListModel * listModel)1920 void ImageListBox::setListModel(gcn::ListModel *listModel)
1921 {
1922 mSelected = -1;
1923 mListModel = listModel;
1924 adjustSize();
1925 }
1926
1927
1928 /*----------------------------------------------------------------------------
1929 -- ListBoxWidget
1930 ----------------------------------------------------------------------------*/
1931
1932
1933 /**
1934 ** ListBoxWidget constructor.
1935 **
1936 ** @todo Size should be parametrable, maybe remove default constructor?
1937 */
ListBoxWidget(unsigned int width,unsigned int height)1938 ListBoxWidget::ListBoxWidget(unsigned int width, unsigned int height)
1939 {
1940 setDimension(gcn::Rectangle(0, 0, width, height));
1941 setContent(&listbox);
1942 setBackgroundColor(gcn::Color(128, 128, 128));
1943 }
1944
1945 /**
1946 ** ImageListBoxWidget constructor.
1947 **
1948 ** @todo Size should be parametrable, maybe remove default constructor?
1949 */
ImageListBoxWidget(unsigned int width,unsigned int height)1950 ImageListBoxWidget::ImageListBoxWidget(unsigned int width, unsigned int height) : ListBoxWidget(width, height),
1951 upButtonImage(nullptr), downButtonImage(nullptr), leftButtonImage(nullptr), rightButtonImage(nullptr), hBarButtonImage(nullptr),
1952 vBarButtonImage(nullptr), markerImage(nullptr)
1953 {
1954 setDimension(gcn::Rectangle(0, 0, width, height));
1955 setContent(&listbox);
1956 }
1957
1958
1959 /**
1960 ** Set the list
1961 */
setList(lua_State * lua,lua_Object * lo)1962 void ListBoxWidget::setList(lua_State *lua, lua_Object *lo)
1963 {
1964 lualistmodel.setList(lua, lo);
1965 listbox.setListModel(&lualistmodel);
1966 adjustSize();
1967 }
1968
1969 /**
1970 ** Set the list
1971 */
setList(lua_State * lua,lua_Object * lo)1972 void ImageListBoxWidget::setList(lua_State *lua, lua_Object *lo)
1973 {
1974 lualistmodel.setList(lua, lo);
1975 listbox.setListModel(&lualistmodel);
1976 adjustSize();
1977 }
1978
1979 /**
1980 ** Sets the ListModel index of the selected element.
1981 **
1982 ** @param selected The ListModel index of the selected element.
1983 **
1984 ** @see gcn::ListBox
1985 */
setSelected(int selected)1986 void ListBoxWidget::setSelected(int selected)
1987 {
1988 listbox.setSelected(selected);
1989 }
1990
1991 /**
1992 ** Sets the ListModel index of the selected element.
1993 **
1994 ** @param selected The ListModel index of the selected element.
1995 **
1996 ** @see gcn::ListBox
1997 */
setSelected(int selected)1998 void ImageListBoxWidget::setSelected(int selected)
1999 {
2000 listbox.setSelected(selected);
2001 }
2002
2003 /**
2004 ** Gets the ListModel index of the selected element.
2005 **
2006 ** @return The ListModel index of the selected element.
2007 **
2008 ** @see gcn::ListBox
2009 */
getSelected() const2010 int ListBoxWidget::getSelected() const
2011 {
2012 return const_cast<gcn::ListBox &>(listbox).getSelected();
2013 }
2014
2015 /**
2016 ** Gets the ListModel index of the selected element.
2017 **
2018 ** @return The ListModel index of the selected element.
2019 **
2020 ** @see gcn::ListBox
2021 */
getSelected() const2022 int ImageListBoxWidget::getSelected() const
2023 {
2024 return const_cast<ImageListBox &>(listbox).getSelected();
2025 }
2026
2027 /**
2028 ** Set background color of the ListBoxWidget.
2029 **
2030 ** @param color Color to set.
2031 */
setBackgroundColor(const gcn::Color & color)2032 void ListBoxWidget::setBackgroundColor(const gcn::Color &color)
2033 {
2034 ScrollArea::setBackgroundColor(color);
2035 ScrollArea::setBaseColor(color);
2036 listbox.setBackgroundColor(color);
2037 }
2038
2039 /**
2040 ** Set background color of the ListBoxWidget.
2041 **
2042 ** @param color Color to set.
2043 */
setBackgroundColor(const gcn::Color & color)2044 void ImageListBoxWidget::setBackgroundColor(const gcn::Color &color)
2045 {
2046 ScrollArea::setBackgroundColor(color);
2047 ScrollArea::setBaseColor(color);
2048 listbox.setBackgroundColor(color);
2049 }
2050
2051 /**
2052 ** Set font of the ListBox.
2053 **
2054 ** @param font Font to set.
2055 */
setFont(gcn::Font * font)2056 void ListBoxWidget::setFont(gcn::Font *font)
2057 {
2058 listbox.setFont(font);
2059 listbox.setWidth(getWidth());
2060 adjustSize();
2061 }
2062
2063 /**
2064 ** Set font of the ListBox.
2065 **
2066 ** @param font Font to set.
2067 */
setFont(gcn::Font * font)2068 void ImageListBoxWidget::setFont(gcn::Font *font)
2069 {
2070 listbox.setFont(font);
2071 listbox.setWidth(getWidth());
2072 adjustSize();
2073 }
2074
2075 /**
2076 ** Adjust size of the listBox.
2077 **
2078 ** @todo Fix width of the scroll area (depend of v-scroll or not).
2079 */
adjustSize()2080 void ListBoxWidget::adjustSize()
2081 {
2082 int i;
2083 int width;
2084 gcn::ListModel *listmodel;
2085
2086 width = listbox.getWidth();
2087 Assert(listbox.getListModel());
2088 listmodel = listbox.getListModel();
2089 for (i = 0; i < listmodel->getNumberOfElements(); ++i) {
2090 if (width < listbox.getFont()->getWidth(listmodel->getElementAt(i))) {
2091 width = listbox.getFont()->getWidth(listmodel->getElementAt(i));
2092 }
2093 }
2094 if (width != listbox.getWidth()) {
2095 listbox.setWidth(width);
2096 }
2097 }
2098
2099 /**
2100 ** Adjust size of the listBox.
2101 **
2102 ** @todo Fix width of the scroll area (depend of v-scroll or not).
2103 */
adjustSize()2104 void ImageListBoxWidget::adjustSize()
2105 {
2106 int i;
2107 int width;
2108 gcn::ListModel *listmodel;
2109
2110 width = listbox.getWidth();
2111 Assert(listbox.getListModel());
2112 listmodel = listbox.getListModel();
2113 for (i = 0; i < listmodel->getNumberOfElements(); ++i) {
2114 if (width < listbox.getFont()->getWidth(listmodel->getElementAt(i))) {
2115 width = listbox.getFont()->getWidth(listmodel->getElementAt(i));
2116 }
2117 }
2118 if (width != listbox.getWidth()) {
2119 listbox.setWidth(width);
2120 }
2121 }
2122
2123 /**
2124 ** Add an action listener
2125 */
addActionListener(gcn::ActionListener * actionListener)2126 void ListBoxWidget::addActionListener(gcn::ActionListener *actionListener)
2127 {
2128 listbox.addActionListener(actionListener);
2129 }
2130
2131 /**
2132 ** Add an action listener
2133 */
addActionListener(gcn::ActionListener * actionListener)2134 void ImageListBoxWidget::addActionListener(gcn::ActionListener *actionListener)
2135 {
2136 listbox.addActionListener(actionListener);
2137 }
2138
2139
2140
2141 /**
2142 ** Draw the list box
2143 **
2144 ** @param graphics Graphics to use
2145 */
draw(gcn::Graphics * graphics)2146 void ImageListBoxWidget::draw(gcn::Graphics *graphics)
2147 {
2148 CGraphic *img = nullptr;
2149
2150 // Check if we have all required graphics
2151 if (!this->upButtonImage || !this->downButtonImage || !this->leftButtonImage || !this->rightButtonImage
2152 || !this->upPressedButtonImage || !this->downPressedButtonImage || !this->leftPressedButtonImage || !this->rightPressedButtonImage
2153 || !this->markerImage || !this->hBarButtonImage || !this->vBarButtonImage) {
2154 fprintf(stderr, "Not all graphics for ImageListBoxWidget were set\n");
2155 ExitFatal(1);
2156 }
2157
2158 gcn::Rectangle rect = getContentDimension();
2159 img = itemImage;
2160 img->Resize(rect.width, img->getHeight());
2161 int y = 0;
2162 while (y + img->getHeight() <= rect.height) {
2163 graphics->drawImage(img, 0, 0, 0, y, getWidth(), img->getHeight());
2164 y += img->getHeight();
2165 }
2166 img->SetOriginalSize();
2167
2168 if (mVBarVisible)
2169 {
2170 if (mUpButtonPressed) {
2171 this->drawUpPressedButton(graphics);
2172 } else {
2173 this->drawUpButton(graphics);
2174 }
2175 if (mDownButtonPressed) {
2176 this->drawDownPressedButton(graphics);
2177 } else {
2178 this->drawDownButton(graphics);
2179 }
2180 this->drawVBar(graphics);
2181 this->drawVMarker(graphics);
2182 }
2183 if (mHBarVisible)
2184 {
2185 if (mLeftButtonPressed) {
2186 this->drawLeftPressedButton(graphics);
2187 } else {
2188 this->drawLeftButton(graphics);
2189 }
2190 if (mRightButtonPressed) {
2191 this->drawRightPressedButton(graphics);
2192 } else {
2193 this->drawRightButton(graphics);
2194 }
2195 this->drawHBar(graphics);
2196 this->drawHMarker(graphics);
2197 }
2198 if (mContent)
2199 {
2200 gcn::Rectangle contdim = mContent->getDimension();
2201 graphics->pushClipArea(getContentDimension());
2202
2203 if (mContent->getBorderSize() > 0)
2204 {
2205 img = this->itemImage;
2206 gcn::Rectangle rec = mContent->getDimension();
2207 rec.x -= mContent->getBorderSize();
2208 rec.y -= mContent->getBorderSize();
2209 rec.width += 2 * mContent->getBorderSize();
2210 rec.height += 2 * mContent->getBorderSize();
2211 graphics->pushClipArea(rec);
2212 mContent->drawBorder(graphics);
2213 graphics->popClipArea();
2214 }
2215
2216 graphics->pushClipArea(contdim);
2217 mContent->draw(graphics);
2218 graphics->popClipArea();
2219 graphics->popClipArea();
2220 }
2221 }
2222
2223 /**
2224 ** Draw the list box border
2225 **
2226 ** @param graphics Graphics to use
2227 */
drawBorder(gcn::Graphics * graphics)2228 void ImageListBoxWidget::drawBorder(gcn::Graphics *graphics)
2229 {
2230 gcn::Color faceColor = getBaseColor();
2231 gcn::Color highlightColor, shadowColor;
2232 int alpha = getBaseColor().a;
2233 int width = getWidth() + getBorderSize() * 2 - 1;
2234 int height = getHeight() + getBorderSize() * 2 - 1;
2235 highlightColor = faceColor + 0x303030;
2236 highlightColor.a = alpha;
2237 shadowColor = faceColor - 0x303030;
2238 shadowColor.a = alpha;
2239
2240 unsigned int i;
2241 for (i = 0; i < getBorderSize(); ++i)
2242 {
2243 graphics->setColor(shadowColor);
2244 graphics->drawLine(i,i, width - i, i);
2245 graphics->drawLine(i,i + 1, i, height - i - 1);
2246 graphics->setColor(highlightColor);
2247 graphics->drawLine(width - i,i + 1, width - i, height - i);
2248 graphics->drawLine(i,height - i, width - i - 1, height - i);
2249 }
2250 }
2251
drawUpButton(gcn::Graphics * graphics)2252 void ImageListBoxWidget::drawUpButton(gcn::Graphics* graphics)
2253 {
2254 gcn::Rectangle dim = getUpButtonDimension();
2255 graphics->pushClipArea(dim);
2256
2257 CGraphic *img = nullptr;
2258
2259 img = upButtonImage;
2260 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2261 graphics->popClipArea();
2262 }
2263
drawDownButton(gcn::Graphics * graphics)2264 void ImageListBoxWidget::drawDownButton(gcn::Graphics* graphics)
2265 {
2266 gcn::Rectangle dim = getDownButtonDimension();
2267 graphics->pushClipArea(dim);
2268
2269 CGraphic *img = nullptr;
2270
2271 img = downButtonImage;
2272 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2273 graphics->popClipArea();
2274 }
2275
drawLeftButton(gcn::Graphics * graphics)2276 void ImageListBoxWidget::drawLeftButton(gcn::Graphics* graphics)
2277 {
2278 gcn::Rectangle dim = getLeftButtonDimension();
2279 graphics->pushClipArea(dim);
2280
2281 CGraphic *img = nullptr;
2282
2283 img = leftButtonImage;
2284 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2285 graphics->popClipArea();
2286 }
2287
drawRightButton(gcn::Graphics * graphics)2288 void ImageListBoxWidget::drawRightButton(gcn::Graphics* graphics)
2289 {
2290 gcn::Rectangle dim = getRightButtonDimension();
2291 graphics->pushClipArea(dim);
2292
2293 CGraphic *img = nullptr;
2294
2295 img = rightButtonImage;
2296 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2297 graphics->popClipArea();
2298 }
2299
drawUpPressedButton(gcn::Graphics * graphics)2300 void ImageListBoxWidget::drawUpPressedButton(gcn::Graphics* graphics)
2301 {
2302 gcn::Rectangle dim = getUpButtonDimension();
2303 graphics->pushClipArea(dim);
2304
2305 CGraphic *img = nullptr;
2306
2307 img = upPressedButtonImage;
2308 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2309 graphics->popClipArea();
2310 }
2311
drawDownPressedButton(gcn::Graphics * graphics)2312 void ImageListBoxWidget::drawDownPressedButton(gcn::Graphics* graphics)
2313 {
2314 gcn::Rectangle dim = getDownButtonDimension();
2315 graphics->pushClipArea(dim);
2316
2317 CGraphic *img = nullptr;
2318
2319 img = downPressedButtonImage;
2320 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2321 graphics->popClipArea();
2322 }
2323
drawLeftPressedButton(gcn::Graphics * graphics)2324 void ImageListBoxWidget::drawLeftPressedButton(gcn::Graphics* graphics)
2325 {
2326 gcn::Rectangle dim = getLeftButtonDimension();
2327 graphics->pushClipArea(dim);
2328
2329 CGraphic *img = nullptr;
2330
2331 img = leftPressedButtonImage;
2332 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2333 graphics->popClipArea();
2334 }
2335
drawRightPressedButton(gcn::Graphics * graphics)2336 void ImageListBoxWidget::drawRightPressedButton(gcn::Graphics* graphics)
2337 {
2338 gcn::Rectangle dim = getRightButtonDimension();
2339 graphics->pushClipArea(dim);
2340
2341 CGraphic *img = nullptr;
2342
2343 img = rightPressedButtonImage;
2344 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2345 graphics->popClipArea();
2346 }
2347
drawHBar(gcn::Graphics * graphics)2348 void ImageListBoxWidget::drawHBar(gcn::Graphics *graphics)
2349 {
2350 gcn::Rectangle dim = getHorizontalBarDimension();
2351 graphics->pushClipArea(dim);
2352
2353 CGraphic *img = nullptr;
2354
2355 img = hBarButtonImage;
2356 img->Resize(dim.width, dim.height);
2357 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2358 img->SetOriginalSize();
2359
2360 graphics->popClipArea();
2361 }
2362
drawVBar(gcn::Graphics * graphics)2363 void ImageListBoxWidget::drawVBar(gcn::Graphics *graphics)
2364 {
2365 gcn::Rectangle dim = getVerticalBarDimension();
2366 graphics->pushClipArea(dim);
2367
2368 CGraphic *img = nullptr;
2369
2370 img = vBarButtonImage;
2371 img->Resize(dim.width, dim.height);
2372 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2373 img->SetOriginalSize();
2374
2375 graphics->popClipArea();
2376 }
2377
drawHMarker(gcn::Graphics * graphics)2378 void ImageListBoxWidget::drawHMarker(gcn::Graphics *graphics)
2379 {
2380 gcn::Rectangle dim = getHorizontalMarkerDimension();
2381 graphics->pushClipArea(dim);
2382
2383 CGraphic *img = nullptr;
2384
2385 img = markerImage;
2386 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2387
2388 graphics->popClipArea();
2389 }
2390
drawVMarker(gcn::Graphics * graphics)2391 void ImageListBoxWidget::drawVMarker(gcn::Graphics *graphics)
2392 {
2393 gcn::Rectangle dim = getVerticalMarkerDimension();
2394 graphics->pushClipArea(dim);
2395
2396 CGraphic *img = nullptr;
2397
2398 img = markerImage;
2399 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2400
2401 graphics->popClipArea();
2402 }
2403
getVerticalMarkerDimension()2404 gcn::Rectangle ImageListBoxWidget::getVerticalMarkerDimension()
2405 {
2406 if (!mVBarVisible)
2407 {
2408 return gcn::Rectangle(0, 0, 0, 0);
2409 }
2410
2411 int length, pos;
2412 gcn::Rectangle barDim = getVerticalBarDimension();
2413
2414 if (mContent && mContent->getHeight() != 0)
2415 {
2416 length = this->markerImage->getHeight();
2417 }
2418 else
2419 {
2420 length = barDim.height;
2421 }
2422
2423 if (length < mScrollbarWidth)
2424 {
2425 length = mScrollbarWidth;
2426 }
2427
2428 if (length > barDim.height)
2429 {
2430 length = barDim.height;
2431 }
2432
2433 if (getVerticalMaxScroll() != 0)
2434 {
2435 pos = ((barDim.height - length) * getVerticalScrollAmount())
2436 / getVerticalMaxScroll();
2437 }
2438 else
2439 {
2440 pos = 0;
2441 }
2442
2443 return gcn::Rectangle(barDim.x, barDim.y + pos, mScrollbarWidth, length);
2444 }
2445
getHorizontalMarkerDimension()2446 gcn::Rectangle ImageListBoxWidget::getHorizontalMarkerDimension()
2447 {
2448 if (!mHBarVisible)
2449 {
2450 return gcn::Rectangle(0, 0, 0, 0);
2451 }
2452
2453 int length, pos;
2454 gcn::Rectangle barDim = getHorizontalBarDimension();
2455
2456 if (mContent && mContent->getWidth() != 0)
2457 {
2458 length = this->markerImage->getHeight();
2459 }
2460 else
2461 {
2462 length = barDim.width;
2463 }
2464
2465 if (length < mScrollbarWidth)
2466 {
2467 length = mScrollbarWidth;
2468 }
2469
2470 if (length > barDim.width)
2471 {
2472 length = barDim.width;
2473 }
2474
2475 if (getHorizontalMaxScroll() != 0)
2476 {
2477 pos = ((barDim.width - length) * getHorizontalScrollAmount())
2478 / getHorizontalMaxScroll();
2479 }
2480 else
2481 {
2482 pos = 0;
2483 }
2484
2485 return gcn::Rectangle(barDim.x + pos, barDim.y, length, mScrollbarWidth);
2486 }
2487
2488
2489 /*----------------------------------------------------------------------------
2490 -- DropDownWidget
2491 ----------------------------------------------------------------------------*/
2492
2493
2494 /**
2495 ** Set the list
2496 */
setList(lua_State * lua,lua_Object * lo)2497 void DropDownWidget::setList(lua_State *lua, lua_Object *lo)
2498 {
2499 listmodel.setList(lua, lo);
2500 setListModel(&listmodel);
2501 }
2502
2503 /**
2504 ** Set the drop down size
2505 */
setSize(int width,int height)2506 void DropDownWidget::setSize(int width, int height)
2507 {
2508 DropDown::setSize(width, height);
2509 this->getListBox()->setSize(width, height);
2510 }
2511
2512 /*----------------------------------------------------------------------------
2513 -- ImageDropDownWidget
2514 ----------------------------------------------------------------------------*/
2515
2516 /**
2517 ** Set the list
2518 */
2519
setListModel(LuaListModel * listModel)2520 void ImageDropDownWidget::setListModel(LuaListModel *listModel)
2521 {
2522 Assert(mScrollArea && mScrollArea->getContent() != nullptr);
2523
2524 mListBox.setListModel(listModel);
2525
2526 if (mListBox.getSelected() < 0)
2527 {
2528 mListBox.setSelected(0);
2529 }
2530
2531 adjustHeight();
2532 }
2533
setList(lua_State * lua,lua_Object * lo)2534 void ImageDropDownWidget::setList(lua_State *lua, lua_Object *lo)
2535 {
2536 listmodel.setList(lua, lo);
2537 setListModel(&listmodel);
2538 }
2539
2540 /**
2541 ** Set the drop down size
2542 */
setSize(int width,int height)2543 void ImageDropDownWidget::setSize(int width, int height)
2544 {
2545 DropDown::setSize(width, height);
2546 this->getListBox()->setSize(width, height);
2547 }
2548
draw(gcn::Graphics * graphics)2549 void ImageDropDownWidget::draw(gcn::Graphics *graphics)
2550 {
2551 Assert(mScrollArea && mScrollArea->getContent() != nullptr);
2552 int h;
2553
2554 if (mDroppedDown)
2555 {
2556 h = mOldH;
2557 }
2558 else
2559 {
2560 h = getHeight();
2561 }
2562
2563 CGraphic *img = this->itemImage;
2564 if (!this->itemImage || !this->DownNormalImage || !this->DownPressedImage) {
2565 fprintf(stderr, "Not all graphics for ImageDropDownWidget were set\n");
2566 ExitFatal(1);
2567 }
2568
2569 int alpha = getBaseColor().a;
2570 gcn::Color faceColor = getBaseColor();
2571 faceColor.a = alpha;
2572 gcn::Color highlightColor = faceColor + 0x303030;
2573 highlightColor.a = alpha;
2574 gcn::Color shadowColor = faceColor - 0x303030;
2575 shadowColor.a = alpha;
2576
2577
2578 //Wyrmgus start
2579 // img->Resize(getWidth(), h);
2580 // graphics->drawImage(img, 0, 0, 0, 0, getWidth(), h);
2581 // img->SetOriginalSize();
2582 graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
2583 //Wyrmgus end
2584
2585 graphics->setFont(getFont());
2586
2587 if (mListBox.getListModel() && mListBox.getSelected() >= 0)
2588 {
2589 graphics->drawText(mListBox.getListModel()->getElementAt(mListBox.getSelected()),
2590 2, (h - getFont()->getHeight()) / 2);
2591 }
2592
2593 //Wyrmgus start
2594 /*
2595 if (hasFocus())
2596 {
2597 graphics->drawRectangle(gcn::Rectangle(0, 0, getWidth() - h, h));
2598 }
2599 */
2600 //Wyrmgus end
2601
2602 drawButton(graphics);
2603
2604 if (mDroppedDown)
2605 {
2606 graphics->pushClipArea(mScrollArea->getDimension());
2607 mScrollArea->draw(graphics);
2608 graphics->popClipArea();
2609
2610 // Draw two lines separating the ListBox with se selected
2611 // element view.
2612 //Wyrmgus start
2613 /*
2614 graphics->setColor(highlightColor);
2615 graphics->drawLine(0, h, getWidth(), h);
2616 graphics->setColor(shadowColor);
2617 graphics->drawLine(0, h + 1,getWidth(),h + 1);
2618 */
2619 //Wyrmgus end
2620 }
2621 }
2622
drawBorder(gcn::Graphics * graphics)2623 void ImageDropDownWidget::drawBorder(gcn::Graphics *graphics)
2624 {
2625 gcn::Color faceColor = getBaseColor();
2626 gcn::Color highlightColor, shadowColor;
2627 int alpha = getBaseColor().a;
2628 int width = getWidth() + getBorderSize() * 2 - 1;
2629 int height = getHeight() + getBorderSize() * 2 - 1;
2630 highlightColor = faceColor + 0x303030;
2631 highlightColor.a = alpha;
2632 shadowColor = faceColor - 0x303030;
2633 shadowColor.a = alpha;
2634
2635 unsigned int i;
2636 for (i = 0; i < getBorderSize(); ++i)
2637 {
2638 graphics->setColor(shadowColor);
2639 graphics->drawLine(i,i, width - i, i);
2640 graphics->drawLine(i,i + 1, i, height - i - 1);
2641 graphics->setColor(highlightColor);
2642 graphics->drawLine(width - i,i + 1, width - i, height - i);
2643 graphics->drawLine(i,height - i, width - i - 1, height - i);
2644 }
2645 }
2646
drawButton(gcn::Graphics * graphics)2647 void ImageDropDownWidget::drawButton(gcn::Graphics *graphics)
2648 {
2649 int h;
2650 if (mDroppedDown)
2651 {
2652 h = mOldH;
2653 }
2654 else
2655 {
2656 h = getHeight();
2657 }
2658 //Wyrmgus start
2659 // int x = getWidth() - h;
2660 int x = getWidth() - (h - 1);
2661 //Wyrmgus end
2662 int y = 0;
2663
2664 CGraphic *img = nullptr;
2665 if (mDroppedDown) {
2666 img = this->DownPressedImage;
2667 } else {
2668 img = this->DownNormalImage;
2669 }
2670 //Wyrmgus start
2671 // img->Resize(h, h);
2672 //Wyrmgus end
2673 graphics->drawImage(img, 0, 0, x, y, h, h);
2674 //Wyrmgus start
2675 // img->SetOriginalSize();
2676 //Wyrmgus end
2677 }
2678
getSelected()2679 int ImageDropDownWidget::getSelected()
2680 {
2681 Assert(mScrollArea && mScrollArea->getContent() != nullptr);
2682
2683 return mListBox.getSelected();
2684 }
2685
setSelected(int selected)2686 void ImageDropDownWidget::setSelected(int selected)
2687 {
2688 Assert(mScrollArea && mScrollArea->getContent() != nullptr);
2689
2690 if (selected >= 0)
2691 {
2692 mListBox.setSelected(selected);
2693 }
2694 }
2695
adjustHeight()2696 void ImageDropDownWidget::adjustHeight()
2697 {
2698 Assert(mScrollArea && mScrollArea->getContent() != nullptr);
2699
2700 int listBoxHeight = mListBox.getHeight();
2701 int h2 = mOldH ? mOldH : getFont()->getHeight();
2702
2703 setHeight(h2);
2704
2705 // The addition/subtraction of 2 compensates for the seperation lines
2706 // seperating the selected element view and the scroll area.
2707
2708 if (mDroppedDown && getParent())
2709 {
2710 int h = getParent()->getHeight() - getY();
2711
2712 if (listBoxHeight > h - h2 - 2)
2713 {
2714 mScrollArea->setHeight(h - h2 - 2);
2715 setHeight(h);
2716 }
2717 else
2718 {
2719 setHeight(listBoxHeight + h2 + 2);
2720 mScrollArea->setHeight(listBoxHeight);
2721 }
2722 }
2723
2724 mScrollArea->setWidth(getWidth());
2725 mScrollArea->setPosition(0, h2 + 2);
2726 }
2727
setListBox(ImageListBox * listBox)2728 void ImageDropDownWidget::setListBox(ImageListBox *listBox)
2729 {
2730 listBox->setSelected(mListBox.getSelected());
2731 listBox->setListModel(mListBox.getListModel());
2732 listBox->addActionListener(this);
2733
2734 if (mScrollArea->getContent() != nullptr)
2735 {
2736 mListBox.removeActionListener(this);
2737 }
2738
2739 mListBox = *listBox;
2740
2741 mScrollArea->setContent(&mListBox);
2742
2743 if (mListBox.getSelected() < 0)
2744 {
2745 mListBox.setSelected(0);
2746 }
2747 }
2748
setFont(gcn::Font * font)2749 void ImageDropDownWidget::setFont(gcn::Font *font)
2750 {
2751 gcn::Widget::setFont(font);
2752 mListBox.setFont(font);
2753 }
2754
_mouseInputMessage(const gcn::MouseInput & mouseInput)2755 void ImageDropDownWidget::_mouseInputMessage(const gcn::MouseInput &mouseInput)
2756 {
2757 gcn::BasicContainer::_mouseInputMessage(mouseInput);
2758
2759 if (mDroppedDown)
2760 {
2761 Assert(mScrollArea && mScrollArea->getContent() != nullptr);
2762
2763 if (mouseInput.y >= mOldH)
2764 {
2765 gcn::MouseInput mi = mouseInput;
2766 mi.y -= mScrollArea->getY();
2767 mScrollArea->_mouseInputMessage(mi);
2768
2769 if (mListBox.hasFocus())
2770 {
2771 mi.y -= mListBox.getY();
2772 mListBox._mouseInputMessage(mi);
2773 }
2774 }
2775 }
2776 }
2777
2778 /**
2779 ** StatBoxWidget constructor
2780 **
2781 ** @param width Width of the StatBoxWidget.
2782 ** @param height Height of the StatBoxWidget.
2783 */
StatBoxWidget(int width,int height)2784 StatBoxWidget::StatBoxWidget(int width, int height) : percent(100)
2785 {
2786 setWidth(width);
2787 setHeight(height);
2788
2789 setBackgroundColor(gcn::Color(0, 0, 0));
2790 setBaseColor(gcn::Color(255, 255, 255));
2791 setForegroundColor(gcn::Color(128, 128, 128));
2792 }
2793
2794 /**
2795 ** Draw StatBoxWidget.
2796 **
2797 ** @param graphics Graphic driver used to draw.
2798 **
2799 ** @todo caption seem to be placed upper than the middle.
2800 ** @todo set direction (hor./vert.) and growing direction(up/down, left/rigth).
2801 */
draw(gcn::Graphics * graphics)2802 void StatBoxWidget::draw(gcn::Graphics *graphics)
2803 {
2804 int width;
2805 int height;
2806
2807 width = getWidth();
2808 height = getHeight();
2809
2810 graphics->setColor(getBackgroundColor());
2811 graphics->fillRectangle(gcn::Rectangle(0, 0, width, height));
2812
2813 graphics->setColor(getBaseColor());
2814 graphics->drawRectangle(gcn::Rectangle(1, 1, width - 2, height - 2));
2815
2816 graphics->setColor(getForegroundColor());
2817 width = percent * width / 100;
2818 graphics->fillRectangle(gcn::Rectangle(2, 2, width - 4, height - 4));
2819 graphics->setFont(getFont());
2820 graphics->drawText(getCaption(),
2821 (getWidth() - getFont()->getWidth(getCaption())) / 2,
2822 (height - getFont()->getHeight()) / 2);
2823 }
2824
2825 /**
2826 ** Set caption of StatBoxWidget.
2827 **
2828 ** @param caption New value.
2829 */
setCaption(const std::string & caption)2830 void StatBoxWidget::setCaption(const std::string &caption)
2831 {
2832 this->caption = caption;
2833 this->setDirty(true);
2834 }
2835
2836 /**
2837 ** Get caption of StatBoxWidget.
2838 */
2839
getCaption() const2840 const std::string &StatBoxWidget::getCaption() const
2841 {
2842 return caption;
2843 }
2844
2845 /**
2846 ** Set percent of StatBoxWidget.
2847 **
2848 ** @param percent New value.
2849 */
setPercent(const int percent)2850 void StatBoxWidget::setPercent(const int percent)
2851 {
2852 this->setDirty(true);
2853 this->percent = percent;
2854 }
2855
2856 /**
2857 ** Get percent of StatBoxWidget.
2858 */
getPercent() const2859 int StatBoxWidget::getPercent() const
2860 {
2861 return percent;
2862 }
2863
2864
2865 /*----------------------------------------------------------------------------
2866 -- MenuScreen
2867 ----------------------------------------------------------------------------*/
2868
2869
2870 /**
2871 ** MenuScreen constructor
2872 */
MenuScreen()2873 MenuScreen::MenuScreen() :
2874 Container(), runLoop(true), logiclistener(0), drawUnder(false), running(false)
2875 {
2876 setDimension(gcn::Rectangle(0, 0, Video.Width, Video.Height));
2877 setOpaque(false);
2878
2879 // The gui must be set immediately as it is used by widgets
2880 // when they are added to the container
2881 oldtop = Gui->getTop();
2882 Gui->setTop(this);
2883 }
2884
2885 /**
2886 ** Run the menu. Loops until stop is called.
2887 */
run(bool loop)2888 int MenuScreen::run(bool loop)
2889 {
2890 loopResult = 0;
2891 runLoop = loop;
2892 running = true;
2893
2894 CursorState = CursorStatePoint;
2895 GameCursor = UI.Point.Cursor;
2896 CursorOn = CursorOnUnknown;
2897
2898 CallbackMusicOn();
2899
2900 if (loop) {
2901 const EventCallback *old_callbacks = GetCallbacks();
2902 SetCallbacks(&GuichanCallbacks);
2903 while (runLoop) {
2904 UpdateDisplay();
2905 RealizeVideoMemory();
2906 CheckMusicFinished();
2907 WaitEventsOneFrame();
2908 }
2909 SetCallbacks(old_callbacks);
2910 Gui->setTop(this->oldtop);
2911 } else {
2912 SetCallbacks(&GuichanCallbacks);
2913 MenuStack.push(this);
2914 }
2915
2916 return this->loopResult;
2917 }
2918
2919 /**
2920 ** Stop the menu from running
2921 */
stop(int result,bool stopAll)2922 void MenuScreen::stop(int result, bool stopAll)
2923 {
2924 if (running == false)
2925 return;
2926
2927 if (!this->runLoop) {
2928 Gui->setTop(this->oldtop);
2929 Assert(MenuStack.top() == this);
2930 MenuStack.pop();
2931 if (stopAll) {
2932 while (!MenuStack.empty()) {
2933 MenuStack.pop();
2934 }
2935 }
2936 if (MenuStack.empty()) {
2937 //InterfaceState = IfaceStateNormal;
2938 if (!Editor.Running) {
2939 SetCallbacks(&GameCallbacks);
2940 } else {
2941 SetCallbacks(&EditorCallbacks);
2942 }
2943 GamePaused = false;
2944 UI.StatusLine.Clear();
2945 if (GameRunning) {
2946 UIHandleMouseMove(CursorScreenPos);
2947 }
2948 }
2949 }
2950
2951 runLoop = false;
2952 loopResult = result;
2953 running = false;
2954 }
2955
addLogicCallback(LuaActionListener * listener)2956 void MenuScreen::addLogicCallback(LuaActionListener *listener)
2957 {
2958 logiclistener = listener;
2959 }
2960
draw(gcn::Graphics * graphics)2961 void MenuScreen::draw(gcn::Graphics *graphics)
2962 {
2963 if (this->drawUnder) {
2964 gcn::Rectangle r = Gui->getGraphics()->getCurrentClipArea();
2965 Gui->getGraphics()->popClipArea();
2966 Gui->draw(oldtop);
2967 Gui->getGraphics()->pushClipArea(r);
2968 }
2969 gcn::Container::draw(graphics);
2970 }
2971
logic()2972 void MenuScreen::logic()
2973 {
2974 if (NetConnectRunning == 2) {
2975 NetworkProcessClientRequest();
2976 }
2977 if (NetConnectRunning == 1) {
2978 NetworkProcessServerRequest();
2979 }
2980 if (logiclistener) {
2981 logiclistener->action("");
2982 }
2983 Container::logic();
2984 }
2985
2986 //@}
2987