00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include <SDL.h>
00024
#include "guitypedefs.h"
00025
#include "guicolors.h"
00026
#ifdef _WIN32
00027
#pragma warning(push)
00028
00029
#include <yvals.h>
00030
00031
#pragma warning(disable: 4251)
00032
#pragma warning(disable: 4786) // identifier was truncated to 'number' characters in the debug information
00033
00034
00035
00036
00037
00038
#include <sge.h>
00039
00040
#pragma warning(pop)
00041
#else
00042
#include <sge.h>
00043
#endif
00044
00045
00046
#include "Surface.h"
00047
#include "SDLControl.h"
00048
#include "Static.h"
00049
#include "Button.h"
00050
#include "Edit.h"
00051
#include "Hotspot.h"
00052
#include "Dialog.h"
00053
#include "MenuItem.h"
00054
#include "Menu.h"
00055
#include "HotButton.h"
00056
#include "GuiEvent.h"
00057
00058
00059
namespace gui
00060 {
00061 Surface *GuiEvent::m_mouse = NULL;
00062 Surface *GuiEvent::m_selected = NULL;
00063 Surface *GuiEvent::m_focus = NULL;
00064 Surface *GuiEvent::m_moving = NULL;
00065 Surface *GuiEvent::m_sizing = NULL;
00066 Surface *GuiEvent::m_trackbutton = NULL;
00067 Surface *GuiEvent::m_default_focus = NULL;
00068
00069
00070
00071
00072 GuiEvent::GuiEvent()
00073 :m_pclRootSurface(NULL)
00074 ,m_pclControl(NULL)
00075 ,m_bLeftButtonPressed(false)
00076 ,m_bMiddleButtonPressed(false)
00077 ,m_bRightButtonPressed(false)
00078 ,m_bQuit(false)
00079 ,m_sizing_w(0)
00080 ,m_sizing_h(0)
00081 {
00082 }
00083
00084
00085 GuiEvent::~GuiEvent()
00086 {
00087 }
00088
00089
00090 void GuiEvent::SetRootSurface(
Surface *s)
00091 {
00092
m_pclRootSurface = s;
00093 }
00094
00095
00096 void GuiEvent::SetSDLControl(
SDLControl *s)
00097 {
00098
m_pclControl = s;
00099 }
00100
00101
00102 void GuiEvent::KeyboardEvent(SDL_KeyboardEvent &e)
00103 {
00104
Surface *focus;
00105
00106
if (
m_focus)
00107 {
00108
if (dynamic_cast<Edit *>(
m_focus))
00109 {
00110 focus =
m_focus;
00111 }
00112
else
00113 {
00114 focus =
m_default_focus;
00115 }
00116 }
00117
else
00118 {
00119 focus =
m_default_focus;
00120 }
00121
if (focus)
00122 {
00123
switch (e.type)
00124 {
00125
case SDL_KEYDOWN:
00126 focus -> OnKeyDown(e.keysym);
00127
break;
00128
case SDL_KEYUP:
00129 focus -> OnKeyUp(e.keysym);
00130
break;
00131 }
00132 }
00133 }
00134
00135
00136 void GuiEvent::MouseMotionEvent(SDL_MouseMotionEvent &e)
00137 {
00139
00140
if (
m_moving &&
m_moving !=
m_pclRootSurface)
00141 {
00142
Surface *head =
m_moving;
00143 SDL_Rect rect;
00144
coord_t xmax = rect.x =
m_pclControl->
GetScreen()->w;
00145
coord_t ymax = rect.y =
m_pclControl->
GetScreen()->h;
00146
coord_t xrel = e.xrel;
00147
coord_t yrel = e.yrel;
00148 rect.w = 0;
00149 rect.h = 0;
00150
while (head -> GetBond())
00151 {
00152 head = head -> GetBond();
00153 }
00154 head -> GetExtents(rect);
00155
if (rect.x + xrel < 0)
00156 {
00157 xrel = -rect.x;
00158 }
00159
if (rect.w + xrel >= xmax)
00160 {
00161 xrel = xmax - rect.w;
00162 }
00163
if (rect.y + yrel < 0)
00164 {
00165 yrel = -rect.y;
00166 }
00167
if (rect.h + yrel >= ymax)
00168 {
00169 yrel = ymax - rect.h;
00170 }
00171 head -> Move(
m_pclRootSurface,xrel,yrel);
00172 }
00173
else
00174
00176
00177
if (
m_sizing &&
m_sizing !=
m_pclRootSurface)
00178 {
00179
coord_t ww =
m_sizing_w + e.xrel;
00180
coord_t hh =
m_sizing_h + e.yrel;
00181
00182
00183
00184 SDL_Rect r;
00185
coord_t x =
m_sizing -> GetAbsoluteX();
00186
coord_t y =
m_sizing -> GetAbsoluteY();
00187
coord_t w =
m_sizing_w;
00188
coord_t h =
m_sizing_h;
00189
00190
if (m_sizing_w < 0)
00191 {
00192 r.x = x + m_sizing_w;
00193 r.w = -m_sizing_w;
00194 }
00195
else
00196 {
00197 r.x = x;
00198 r.w = m_sizing_w;
00199 }
00200 r.x -= 4;
00201 r.w += 8;
00202
if (m_sizing_h < 0)
00203 {
00204 r.y = y + m_sizing_h;
00205 r.h = -m_sizing_h;
00206 }
00207
else
00208 {
00209 r.y = y;
00210 r.h = m_sizing_h;
00211 }
00212 r.y -= 4;
00213 r.h += 8;
00214
m_pclRootSurface -> InvalidateRectEv(r);
00215
00216 m_sizing_w = w = ww;
00217 m_sizing_h = h = hh;
00218
00219
m_pclRootSurface -> ResetFillRectsEv();
00220
00221
if (m_sizing_w < 0)
00222 {
00223 x = x + m_sizing_w;
00224 w = -m_sizing_w;
00225 }
00226
else
00227 {
00228 w = m_sizing_w;
00229 }
00230
if (m_sizing_h < 0)
00231 {
00232 y = y + m_sizing_h;
00233 h = -m_sizing_h;
00234 }
00235
else
00236 {
00237 h = m_sizing_h;
00238 }
00239
00240 r.x = x;
00241 r.y = y;
00242 r.w = 4;
00243 r.h = h;
00244
m_pclRootSurface -> FillRectEv(r);
00245 r.w = w;
00246 r.h = 4;
00247
m_pclRootSurface -> FillRectEv(r);
00248 r.y = y + h - 4;
00249
m_pclRootSurface -> FillRectEv(r);
00250 r.x = x + w - 4;
00251 r.y = y;
00252 r.w = 4;
00253 r.h = h;
00254
m_pclRootSurface -> FillRectEv(r);
00255 }
00256
else
00257
00259
00260
if (
m_trackbutton)
00261 {
00262
coord_t x =
m_trackbutton -> GetAbsoluteX();
00263
coord_t y =
m_trackbutton -> GetAbsoluteY();
00264
coord_t w =
m_trackbutton -> GetW();
00265
coord_t h =
m_trackbutton -> GetH();
00266
bool ch =
false;
00267
if (
m_trackbutton -> IsInverted())
00268 {
00269
if (e.x < x || e.x >= x + w || e.y < y || e.y >= y + h)
00270 {
00271 ch =
true;
00272 }
00273 }
00274
else
00275 {
00276
if (e.x >= x && e.x < x + w && e.y >= y && e.y < y + h)
00277 {
00278 ch =
true;
00279 }
00280 }
00281
if (ch)
00282 {
00283
m_trackbutton -> SetInverted( !
m_trackbutton -> IsInverted() );
00284
m_trackbutton -> GetParent() -> DrawTemporaryScreen();
00285
m_trackbutton -> InvalidateEv();
00286 }
00287 }
00288
else
00289 {
00291
00292
Surface *pclSurface =
m_pclRootSurface -> FindSurface(e.x,e.y);
00293
if (pclSurface !=
m_mouse)
00294 {
00295
if (
m_mouse)
00296 {
00297
m_mouse -> OnMouseOut();
00298 }
00299 pclSurface -> OnMouseIn();
00300
m_mouse = pclSurface;
00301 }
00302
m_mouse -> OnMouseMove(e.x,e.y,e.xrel,e.yrel);
00303 }
00304 }
00305
00306
00307 void GuiEvent::MouseButtonEvent(SDL_MouseButtonEvent &e)
00308 {
00309
00310
00311
if (e.type == SDL_MOUSEBUTTONDOWN &&
00312 e.button == SDL_BUTTON_LEFT &&
00313
m_mouse)
00314 {
00315
if (
m_mouse !=
m_pclRootSurface)
00316 {
00317
SetSelected(
m_mouse);
00318 }
00319
else
00320 {
00321
SetSelected(NULL);
00322 }
00323 }
00324
00325
if (!
m_moving &&
00326 !
m_sizing &&
00327 e.type == SDL_MOUSEBUTTONDOWN &&
00328 e.button == SDL_BUTTON_LEFT &&
00329 dynamic_cast<Button *>(
m_mouse) &&
00330 !dynamic_cast<HotButton *>(
m_mouse))
00331 {
00332
m_trackbutton =
m_mouse;
00333
m_trackbutton -> SetInverted(
true);
00334
m_trackbutton -> GetParent() -> DrawTemporaryScreen();
00335
m_trackbutton -> InvalidateEv();
00336 }
00337
else
00338
if (e.type == SDL_MOUSEBUTTONUP &&
00339 e.button == SDL_BUTTON_LEFT &&
00340
m_trackbutton)
00341 {
00342
if (
m_trackbutton -> IsInverted())
00343 {
00344
m_trackbutton -> SetInverted(
false);
00345
m_trackbutton -> GetParent() -> DrawTemporaryScreen();
00346
m_trackbutton -> InvalidateEv();
00347
m_trackbutton -> OnButton();
00348 }
00349
m_trackbutton = NULL;
00350 }
00351
else
00352 {
00353
if (e.button == SDL_BUTTON_LEFT)
00354 {
00355
if (e.type == SDL_MOUSEBUTTONDOWN)
00356 {
00357
00358
if (
m_mouse &&
00359
00360
m_mouse -> IsClickable())
00361 {
00362
m_mouse -> OnClick(e.x,e.y);
00363
00364 }
00365
else
00366
00367
if (
m_mouse && (
00368 dynamic_cast<Edit *>(
m_mouse) ||
00369 dynamic_cast<Button *>(
m_mouse)
00370 ))
00371 {
00372
SetFocus(
m_mouse );
00373 }
00374
else
00375
00376
if (
m_mouse &&
00377 dynamic_cast<Hotspot *>(
m_mouse) &&
00378
m_mouse -> IsResizeArea() &&
00379
m_mouse -> GetParent() &&
00380 dynamic_cast<Dialog *>(
m_mouse -> GetParent())
00381 )
00382 {
00383
m_sizing =
m_mouse -> GetParent();
00384
m_sizing_w =
m_sizing -> GetW();
00385
m_sizing_h =
m_sizing -> GetH();
00386 }
00387
else
00388 {
00389
00390
if (
m_mouse &&
m_mouse -> IsMoveable())
00391 {
00392
m_moving =
m_mouse;
00393 }
00394
else
00395
if (
m_mouse && !
m_mouse -> IsMoveable())
00396 {
00397
Surface *pclParent =
m_mouse -> GetParent();
00398
while (pclParent)
00399 {
00400
if (pclParent -> IsMoveable())
00401 {
00402
m_moving = pclParent;
00403
break;
00404 }
00405 pclParent = pclParent -> GetParent();
00406 }
00407 }
00408
00409
if (
m_mouse && (
00410 dynamic_cast<Dialog *>(
m_mouse) ||
00411 dynamic_cast<Menu *>(
m_mouse)
00412 ))
00413 {
00414
m_mouse -> BringToTop();
00415
m_mouse -> InvalidateEv();
00416 }
00417
else
00418
if (
m_mouse && !dynamic_cast<Dialog *>(
m_mouse))
00419 {
00420
Surface *pclParent =
m_mouse -> GetParent();
00421
while (pclParent)
00422 {
00423
if (dynamic_cast<Dialog *>(pclParent))
00424 {
00425 pclParent -> BringToTop();
00426 pclParent -> InvalidateEv();
00427
break;
00428 }
00429 pclParent = pclParent -> GetParent();
00430 }
00431 }
00432 }
00433 }
00434
if (e.type == SDL_MOUSEBUTTONUP)
00435 {
00436
if (
m_moving)
00437 {
00438
m_moving = NULL;
00439 }
00440
if (
m_sizing)
00441 {
00442 SDL_Rect a =
m_sizing -> GetAbsoluteRect();
00443
m_pclRootSurface -> ResetFillRectsEv();
00444
m_pclRootSurface -> InvalidateRectEv(a);
00445
if (
m_sizing_w < 0)
00446 {
00447
m_sizing -> SetX(
m_sizing -> GetX() +
m_sizing_w);
00448
m_sizing -> SetW(-m_sizing_w,
false);
00449 }
00450
else
00451 {
00452
m_sizing -> SetW(
m_sizing_w,
false);
00453 }
00454
if (
m_sizing_h < 0)
00455 {
00456
m_sizing -> SetY(
m_sizing -> GetY() +
m_sizing_h);
00457
m_sizing -> SetH(-m_sizing_h,
false);
00458 }
00459
else
00460 {
00461
m_sizing -> SetH(
m_sizing_h,
false);
00462 }
00463
m_sizing -> RecreateSurfaces();
00464
m_sizing -> SetDirty(
true);
00465
m_sizing = NULL;
00466 }
00467 }
00468 }
00469
if (e.button == SDL_BUTTON_RIGHT)
00470 {
00471
if (e.type == SDL_MOUSEBUTTONDOWN)
00472 {
00473
if (
m_mouse)
00474 {
00475
m_mouse -> OnRightClick(e.x,e.y);
00476 }
00477 }
00478 }
00479 }
00480
00481
switch (e.type)
00482 {
00483
case SDL_MOUSEBUTTONDOWN:
00484
switch (e.button)
00485 {
00486
case SDL_BUTTON_LEFT:
00487
m_bLeftButtonPressed =
true;
00488
m_leftx = e.x;
00489
m_lefty = e.y;
00490
break;
00491
case SDL_BUTTON_MIDDLE:
00492
m_bMiddleButtonPressed =
true;
00493
m_middlex = e.x;
00494
m_middley = e.y;
00495
break;
00496
case SDL_BUTTON_RIGHT:
00497
m_bRightButtonPressed =
true;
00498
m_rightx = e.x;
00499
m_righty = e.y;
00500
break;
00501 }
00502
break;
00503
case SDL_MOUSEBUTTONUP:
00504
switch (e.button)
00505 {
00506
case SDL_BUTTON_LEFT:
00507
m_bLeftButtonPressed =
false;
00508
break;
00509
case SDL_BUTTON_MIDDLE:
00510
m_bMiddleButtonPressed =
false;
00511
break;
00512
case SDL_BUTTON_RIGHT:
00513
m_bRightButtonPressed =
false;
00514
break;
00515 }
00516
break;
00517 }
00518 }
00519
00520
00521 bool GuiEvent::RightMouseButtonDown()
00522 {
00523
return m_bRightButtonPressed;
00524 }
00525
00526
00527 void GuiEvent::UserEvent(SDL_UserEvent &event)
00528 {
00529
switch (event.code)
00530 {
00531
case SDL_USEREVENT_PAINT:
00532
00533
m_pclControl -> lockSurface();
00534
m_pclRootSurface -> Blit();
00535
m_pclControl -> unlockSurface();
00536 SDL_UpdateRect(
m_pclControl -> GetScreen(), 0, 0, 0, 0);
00537
break;
00538
case SDL_USEREVENT_INVALIDATE:
00539 {
00540
00541
Surface *pcs = reinterpret_cast<Surface *>(event.data1);
00542
00543
00544
00545
00546
m_vecInvalidRects.insert(
m_vecInvalidRects.end(), pcs -> GetAbsoluteRect());
00547 }
00548
break;
00549
case SDL_USEREVENT_INVALIDATERECT:
00550 {
00551 SDL_Rect r;
00552
long xy;
00553
long wh;
00554 memmove(&xy, &event.data1, 4);
00555 memmove(&wh, &event.data2, 4);
00556 r.x = xy / 0x10000;
00557 r.y = xy & 0xffff;
00558 r.w = wh / 0x10000;
00559 r.h = wh & 0xffff;
00560
00561
00562
00563
m_vecInvalidRects.insert(
m_vecInvalidRects.end(), r);
00564
00565
00566 }
00567
break;
00568
case SDL_USEREVENT_LOSTFOCUS:
00569 {
00570
Surface *pcs = reinterpret_cast<Surface *>(event.data1);
00571
if (pcs ==
m_focus &&
m_focus)
00572 {
00573
m_focus -> OnLostFocus();
00574
m_focus = NULL;
00575 }
00576 }
00577
break;
00578
case SDL_USEREVENT_FILLRECT:
00579 {
00580 SDL_Rect r;
00581
long xy;
00582
long wh;
00583 memmove(&xy, &event.data1, 4);
00584 memmove(&wh, &event.data2, 4);
00585 r.x = xy / 0x10000;
00586 r.y = xy & 0xffff;
00587 r.w = wh / 0x10000;
00588 r.h = wh & 0xffff;
00589
m_vecFillRects.insert(
m_vecFillRects.end(), r);
00590 }
00591
break;
00592
case SDL_USEREVENT_RESETFILLRECTS:
00593
while (
m_vecFillRects.size())
00594 {
00595 rectvector_t::iterator it =
m_vecFillRects.begin();
00596
m_vecFillRects.erase(it);
00597 }
00598
break;
00599
case SDL_USEREVENT_UICOMMAND:
00600 {
00601
Surface *s;
00602
long id;
00603 memmove(&s,&event.data1,4);
00604 memmove(&
id,&event.data2,4);
00605
UICOMMAND func =
m_uicmdmap[
id];
00606
if (func)
00607 {
00608 (*func)(s,
id);
00609 }
00610 }
00611
break;
00612
case SDL_USEREVENT_TIMER:
00613
00614 {
00615
Surface *s;
00616
long id;
00617 memmove(&s,&event.data1,4);
00618 memmove(&
id,&event.data2,4);
00619 s -> OnTimer(
id);
00620 }
00621
break;
00622 }
00623 }
00624
00625
00626 void GuiEvent::SetDefaultFocus(
Surface *s)
00627 {
00628
m_default_focus = s;
00629 }
00630
00631
00632 void GuiEvent::SetQuit(
bool b)
00633 {
00634
m_bQuit = b;
00635 }
00636
00637
00638 void GuiEvent::SetFocus(
Surface *s)
00639 {
00640
if (
m_focus && s !=
m_focus)
00641 {
00642
m_focus -> OnLostFocus();
00643
m_focus = s;
00644
m_focus -> OnFocus();
00645 }
00646
else
00647
if (s !=
m_focus)
00648 {
00649
m_focus = s;
00650
m_focus -> OnFocus();
00651 }
00652 }
00653
00654
00655 void GuiEvent::SetSelected(
Surface *s)
00656 {
00657
00658
00659
if (s !=
m_selected)
00660 {
00661
if (
m_selected)
00662 {
00663
00664
00665
00666
00667
00668
00669 }
00670
m_selected = s;
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 }
00681 }
00682
00683
00684 void GuiEvent::EventLoop()
00685 {
00686 SDL_Event event;
00687
00688
00689
m_pclRootSurface -> DrawAll();
00690
m_pclRootSurface -> CalculateAbsolute();
00691
00692
while (!
m_bQuit)
00693 {
00694
00695
00696
while (SDL_PollEvent(&event))
00697 {
00698
switch (event.type)
00699 {
00700
case SDL_USEREVENT:
00701
UserEvent(event.user);
00702
break;
00703
case SDL_MOUSEMOTION:
00704
MouseMotionEvent(event.motion);
00705
break;
00706
case SDL_MOUSEBUTTONUP:
00707
MouseButtonEvent(event.button);
00708
break;
00709
case SDL_MOUSEBUTTONDOWN:
00710
MouseButtonEvent(event.button);
00711
break;
00712
case SDL_KEYUP:
00713
KeyboardEvent(event.key);
00714
break;
00715
case SDL_KEYDOWN:
00716
KeyboardEvent(event.key);
00717
break;
00718
case SDL_QUIT:
00719
m_bQuit =
true;
00720
break;
00721 }
00722 }
00723
if (!
m_bQuit)
00724 {
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
if (
m_vecInvalidRects.size() > 0)
00736 {
00737 SDL_Rect cheat;
00738
00739
00740 cheat.x =
m_pclControl -> GetScreen() -> w;
00741 cheat.y =
m_pclControl -> GetScreen() -> h;
00742 cheat.w = 0;
00743 cheat.h = 0;
00744
00745
m_pclRootSurface -> DrawAll();
00746
m_pclRootSurface -> CalculateAbsolute();
00747
00748
while (
m_vecInvalidRects.size() > 0)
00749 {
00750 rectvector_t::iterator it =
m_vecInvalidRects.begin();
00751 SDL_Rect r = *it;
00752 r.w += r.x;
00753 r.h += r.y;
00754 cheat.x = r.x < cheat.x ? r.x : cheat.x;
00755 cheat.y = r.y < cheat.y ? r.y : cheat.y;
00756 cheat.w = r.w > cheat.w ? r.w : cheat.w;
00757 cheat.h = r.h > cheat.h ? r.h : cheat.h;
00758
m_vecInvalidRects.erase(it);
00759 }
00760
00761
for (rectvector_t::iterator it =
m_vecFillRects.begin(); it !=
m_vecFillRects.end(); it++)
00762 {
00763 SDL_Rect r = *it;
00764 r.w += r.x;
00765 r.h += r.y;
00766 cheat.x = r.x < cheat.x ? r.x : cheat.x;
00767 cheat.y = r.y < cheat.y ? r.y : cheat.y;
00768 cheat.w = r.w > cheat.w ? r.w : cheat.w;
00769 cheat.h = r.h > cheat.h ? r.h : cheat.h;
00770 }
00771
if (cheat.w >
m_pclControl -> GetScreen() -> w)
00772 {
00773 cheat.w =
m_pclControl -> GetScreen() -> w;
00774 }
00775
if (cheat.h >
m_pclControl -> GetScreen() -> h)
00776 {
00777 cheat.h =
m_pclControl -> GetScreen() -> h;
00778 }
00779 cheat.w = cheat.w - cheat.x;
00780 cheat.h = cheat.h - cheat.y;
00781
00782
m_pclControl -> lockSurface();
00783
m_pclRootSurface -> BlitAbsolute(&cheat);
00784
while (
m_vecFillRects.size() > 0)
00785 {
00786
00787 rectvector_t::iterator it =
m_vecFillRects.begin();
00788 SDL_Rect rf = *it;
00789 SDL_FillRect(
m_pclControl -> GetScreen(), &rf,
00790 SDL_MapRGB(
m_pclControl -> GetScreen() -> format, 255, 255, 255));
00791
m_vecFillRects.erase(it);
00792 }
00793
m_pclControl -> unlockSurface();
00794 SDL_UpdateRects(
m_pclControl -> GetScreen(), 1, &cheat);
00795 }
00796 }
00797
00798
00799
00800 SDL_Delay(10);
00801 }
00802 }
00803
00804
00805 void GuiEvent::RegUICmdMethod(
long id,UICOMMAND func)
00806 {
00807
m_uicmdmap[
id] = func;
00808 }
00809
00810
00811 }
00812