00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "CEGUISystem.h"
00027 #include "CEGUILogger.h"
00028 #include "CEGUIImagesetManager.h"
00029 #include "CEGUIFontManager.h"
00030 #include "CEGUIWindowFactoryManager.h"
00031 #include "CEGUIWindowManager.h"
00032 #include "CEGUISchemeManager.h"
00033 #include "CEGUIMouseCursor.h"
00034 #include "CEGUIWindow.h"
00035 #include "CEGUIImageset.h"
00036 #include "CEGUIExceptions.h"
00037 #include "elements/CEGUIGUISheet.h"
00038 #include "CEGUIScriptModule.h"
00039 #include "CEGUIConfig_xmlHandler.h"
00040 #include "xercesc/util/PlatformUtils.hpp"
00041 #include "xercesc/util/Janitor.hpp"
00042 #include "xercesc/sax2/DefaultHandler.hpp"
00043 #include "xercesc/sax2/SAX2XMLReader.hpp"
00044 #include "xercesc/sax2/XMLReaderFactory.hpp"
00045 #include "xercesc/framework/MemBufInputSource.hpp"
00046 #include "CEGUIDataContainer.h"
00047 #include "CEGUIResourceProvider.h"
00048 #include "CEGUIGlobalEventSet.h"
00049 #include <time.h>
00050
00051
00052
00053 namespace CEGUI
00054 {
00055 const String System::EventNamespace("System");
00056
00061 class SimpleTimer
00062 {
00063 clock_t d_baseTime;
00064
00065 public:
00066 SimpleTimer() : d_baseTime(clock()) {}
00067
00068 void restart() { d_baseTime = clock(); }
00069 double elapsed() { return static_cast<double>((clock() - d_baseTime) / CLOCKS_PER_SEC); }
00070 };
00071
00077 struct MouseClickTracker
00078 {
00079 MouseClickTracker(void) : d_click_count(0), d_click_area(0, 0, 0, 0) {}
00080
00081 SimpleTimer d_timer;
00082 int d_click_count;
00083 Rect d_click_area;
00084 };
00085
00086
00087 struct MouseClickTrackerImpl
00088 {
00089 MouseClickTracker click_trackers[MouseButtonCount];
00090 };
00091
00092
00093
00094
00095
00096 const char System::CEGUIConfigSchemaName[] = "CEGUIConfig.xsd";
00097
00098
00099
00100
00101
00102
00103 template<> System* Singleton<System>::ms_Singleton = NULL;
00104
00105
00106 const double System::DefaultSingleClickTimeout = 0.2;
00107 const double System::DefaultMultiClickTimeout = 0.33;
00108 const Size System::DefaultMultiClickAreaSize(12,12);
00109
00110
00111 const String System::EventGUISheetChanged( (utf8*)"GUISheetChanged" );
00112 const String System::EventSingleClickTimeoutChanged( (utf8*)"SingleClickTimeoutChanged" );
00113 const String System::EventMultiClickTimeoutChanged( (utf8*)"MultiClickTimeoutChanged" );
00114 const String System::EventMultiClickAreaSizeChanged( (utf8*)"MultiClickAreaSizeChanged" );
00115 const String System::EventDefaultFontChanged( (utf8*)"DefaultFontChanged" );
00116 const String System::EventDefaultMouseCursorChanged( (utf8*)"DefaultMouseCursorChanged" );
00117 const String System::EventMouseMoveScalingChanged( (utf8*)"MouseMoveScalingChanged" );
00118
00119
00120
00121
00122
00123 System::System(Renderer* renderer, utf8* logFile) :
00124 d_clickTrackerPimpl(new MouseClickTrackerImpl)
00125 {
00126 constructor_impl(renderer, NULL, NULL, (utf8*)"", logFile);
00127 }
00128
00129
00130
00131 System::System(Renderer* renderer, ResourceProvider* resourceProvider, utf8* logFile) :
00132 d_clickTrackerPimpl(new MouseClickTrackerImpl)
00133 {
00134 constructor_impl(renderer, resourceProvider, NULL, (utf8*)"", logFile);
00135 }
00136
00137
00138
00139
00140 System::System(Renderer* renderer, ScriptModule* scriptModule, utf8* configFile) :
00141 d_clickTrackerPimpl(new MouseClickTrackerImpl)
00142 {
00143 constructor_impl(renderer, NULL, scriptModule, configFile, (utf8*)"CEGUI.log");
00144 }
00145
00146
00147
00148
00149
00150 System::System(Renderer* renderer, ScriptModule* scriptModule, ResourceProvider* resourceProvider, utf8* configFile) :
00151 d_clickTrackerPimpl(new MouseClickTrackerImpl)
00152 {
00153 constructor_impl(renderer, resourceProvider, scriptModule, configFile, (utf8*)"CEGUI.log");
00154 }
00155
00156
00157
00158
00159
00160 void System::constructor_impl(Renderer* renderer, ResourceProvider* resourceProvider, ScriptModule* scriptModule, const String& configFile, const String& logFile)
00161 {
00162 d_renderer = renderer;
00163 d_gui_redraw = false;
00164 d_wndWithMouse = NULL;
00165 d_activeSheet = NULL;
00166 d_sysKeys = 0;
00167
00168 d_lshift = false;
00169 d_rshift = false;
00170 d_lctrl = false;
00171 d_rctrl = false;
00172
00173 d_click_timeout = DefaultSingleClickTimeout;
00174 d_dblclick_timeout = DefaultMultiClickTimeout;
00175 d_dblclick_size = DefaultMultiClickAreaSize;
00176
00177 d_defaultMouseCursor = NULL;
00178 d_scriptModule = scriptModule;
00179
00180 d_mouseScalingFactor = 1.0f;
00181
00182
00183 addSystemEvents();
00184
00185
00186 d_resourceProvider = resourceProvider ? resourceProvider : renderer->createResourceProvider();
00187
00188
00189 XERCES_CPP_NAMESPACE_USE
00190 try
00191 {
00192 XMLPlatformUtils::Initialize();
00193 }
00194 catch(XMLException& exc)
00195 {
00196
00197 char* excmsg = XMLString::transcode(exc.getMessage());
00198 String message((utf8*)"An exception occurred while initialising the Xerces-C XML system. Additional information: ");
00199 message += (utf8*)excmsg;
00200 XMLString::release(&excmsg);
00201
00202
00203 throw message.c_str();
00204 }
00205
00206
00207 String configLogname, configSchemeName, configLayoutName, configInitScript, defaultFontName;
00208
00209
00210 if (!configFile.empty())
00211 {
00212 SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
00213
00214
00215 parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
00216 parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
00217 parser->setFeature(XMLUni::fgXercesSchema, true);
00218 parser->setFeature(XMLUni::fgXercesValidationErrorAsFatal, true);
00219
00220
00221
00222
00223
00224
00225
00226 RawDataContainer rawSchemaData;
00227 System::getSingleton().getResourceProvider()->loadRawDataContainer(CEGUIConfigSchemaName, rawSchemaData, "");
00228 MemBufInputSource configSchemaData(rawSchemaData.getDataPtr(), rawSchemaData.getSize(), CEGUIConfigSchemaName, false);
00229 parser->loadGrammar(configSchemaData, Grammar::SchemaGrammarType, true);
00230
00231
00232 parser->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);
00233
00234
00235 XMLCh* pval = XMLString::transcode(CEGUIConfigSchemaName);
00236 parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, pval);
00237 XMLString::release(&pval);
00238
00239
00240 Config_xmlHandler handler;
00241 parser->setContentHandler(&handler);
00242 parser->setErrorHandler(&handler);
00243
00244
00245
00246
00247 RawDataContainer rawXMLData;
00248 System::getSingleton().getResourceProvider()->loadRawDataContainer(configFile, rawXMLData, "");
00249 MemBufInputSource configData(rawXMLData.getDataPtr(), rawXMLData.getSize(), configFile.c_str(), false);
00250
00251
00252 try
00253 {
00254
00255 parser->parse(configData);
00256
00257
00258 configLogname = handler.getLogFilename();
00259 configSchemeName = handler.getSchemeFilename();
00260 configLayoutName = handler.getLayoutFilename();
00261 defaultFontName = handler.getDefaultFontName();
00262 configInitScript = handler.getInitScriptFilename();
00263 d_termScriptName = handler.getTermScriptFilename();
00264
00265
00266 if (!handler.getDefaultResourceGroup().empty())
00267 {
00268 d_resourceProvider->setDefaultResourceGroup(handler.getDefaultResourceGroup());
00269 }
00270 }
00271 catch(const XMLException& exc)
00272 {
00273 if (exc.getCode() != XMLExcepts::NoError)
00274 {
00275 delete parser;
00276
00277 char* excmsg = XMLString::transcode(exc.getMessage());
00278 String message((utf8*)"System::System - An error occurred while parsing configuration file '" + configFile + "'. Additional information: ");
00279 message += excmsg;
00280 XMLString::release(&excmsg);
00281
00282
00283 XERCES_CPP_NAMESPACE_USE
00284 XMLPlatformUtils::Terminate();
00285
00286
00287 throw message.c_str();
00288 }
00289
00290 }
00291 catch(const SAXParseException& exc)
00292 {
00293 delete parser;
00294
00295 char* excmsg = XMLString::transcode(exc.getMessage());
00296 String message((utf8*)"System::System - An error occurred while parsing configuration file '" + configFile + "'. Additional information: ");
00297 message += excmsg;
00298 XMLString::release(&excmsg);
00299
00300
00301 XERCES_CPP_NAMESPACE_USE
00302 XMLPlatformUtils::Terminate();
00303
00304
00305 throw message.c_str();
00306 }
00307 catch(...)
00308 {
00309 delete parser;
00310
00311
00312 XERCES_CPP_NAMESPACE_USE
00313 XMLPlatformUtils::Terminate();
00314
00315
00316 throw String((utf8*)"System::System - An unexpected error occurred while parsing configuration file '" + configFile + "'.").c_str();
00317 }
00318
00319
00320 delete parser;
00321 }
00322
00323
00324
00325 if (!configLogname.empty())
00326 {
00327 new Logger(configLogname);
00328 }
00329
00330 else
00331 {
00332 new Logger(logFile);
00333 }
00334
00335
00336 Logger::getSingleton().logEvent((utf8*)"---- Begining CEGUI System initialisation ----");
00337
00338
00339 new ImagesetManager();
00340 new FontManager();
00341 new WindowFactoryManager();
00342 new WindowManager();
00343 new SchemeManager();
00344 new MouseCursor();
00345 new GlobalEventSet();
00346
00347
00348 WindowFactoryManager::getSingleton().addFactory(new GUISheetFactory);
00349
00350
00351 WindowFactoryManager::getSingleton().addWindowTypeAlias((utf8*)"DefaultGUISheet", GUISheet::WidgetTypeName);
00352
00353
00354 Logger::getSingleton().logEvent((utf8*)"CEGUI::System singleton created.");
00355 Logger::getSingleton().logEvent((utf8*)"---- CEGUI System initialisation completed ----");
00356
00357
00358 d_renderer->subscribeEvent(Renderer::EventDisplaySizeChanged, Event::Subscriber(&CEGUI::System::handleDisplaySizeChange, this));
00359
00360
00361 if (!configSchemeName.empty())
00362 {
00363 try
00364 {
00365 SchemeManager::getSingleton().loadScheme(configSchemeName, d_resourceProvider->getDefaultResourceGroup());
00366
00367
00368 if (!defaultFontName.empty())
00369 {
00370 setDefaultFont(defaultFontName);
00371 }
00372
00373 }
00374 catch (CEGUI::Exception exc) {}
00375
00376 }
00377
00378
00379 if (!configLayoutName.empty())
00380 {
00381 try
00382 {
00383 setGUISheet(WindowManager::getSingleton().loadWindowLayout(configLayoutName));
00384 }
00385 catch (CEGUI::Exception exc) {}
00386
00387 }
00388
00389
00390 if (!configInitScript.empty())
00391 {
00392 try
00393 {
00394 executeScriptFile(configInitScript);
00395 }
00396 catch (...) {}
00397
00398 }
00399
00400 }
00401
00402
00403
00404
00405
00406 System::~System(void)
00407 {
00408 Logger::getSingleton().logEvent((utf8*)"---- Begining CEGUI System destruction ----");
00409
00410
00411 if (!d_termScriptName.empty())
00412 {
00413 try
00414 {
00415 executeScriptFile(d_termScriptName);
00416 }
00417 catch (...) {}
00418
00419 }
00420
00421
00422 XERCES_CPP_NAMESPACE_USE
00423 XMLPlatformUtils::Terminate();
00424
00425
00426
00427
00428
00429 WindowManager::getSingleton().destroyAllWindows();
00430
00431
00432 GUISheetFactory* factory = (GUISheetFactory*)WindowFactoryManager::getSingleton().getFactory(GUISheet::WidgetTypeName);
00433
00434
00435 WindowFactoryManager::getSingleton().removeAllFactories();
00436
00437
00438 delete factory;
00439
00440
00441 delete SchemeManager::getSingletonPtr();
00442 delete WindowManager::getSingletonPtr();
00443 delete WindowFactoryManager::getSingletonPtr();
00444 delete FontManager::getSingletonPtr();
00445 delete MouseCursor::getSingletonPtr();
00446 delete ImagesetManager::getSingletonPtr();
00447 delete GlobalEventSet::getSingletonPtr();
00448
00449 Logger::getSingleton().logEvent((utf8*)"CEGUI::System singleton destroyed.");
00450 Logger::getSingleton().logEvent((utf8*)"---- CEGUI System destruction completed ----");
00451 delete Logger::getSingletonPtr();
00452
00453 delete d_clickTrackerPimpl;
00454 }
00455
00456
00457
00458
00459
00460 void System::renderGUI(void)
00461 {
00463
00464
00465
00466
00467
00468
00469
00471
00472 if (d_gui_redraw)
00473 {
00474 d_renderer->resetZValue();
00475 d_renderer->setQueueingEnabled(true);
00476 d_renderer->clearRenderList();
00477
00478 if (d_activeSheet != NULL)
00479 {
00480 d_activeSheet->render();
00481 }
00482
00483 d_gui_redraw = false;
00484 }
00485
00486 d_renderer->doRender();
00487
00488
00489 d_renderer->setQueueingEnabled(false);
00490 MouseCursor::getSingleton().draw();
00491 }
00492
00493
00494
00495
00496
00497 Window* System::setGUISheet(Window* sheet)
00498 {
00499 Window* old = d_activeSheet;
00500 d_activeSheet = sheet;
00501
00502
00503
00504 if (sheet != 0)
00505 {
00506 WindowEventArgs sheetargs(0);
00507 sheet->onParentSized(sheetargs);
00508 }
00509
00510
00511 WindowEventArgs args(old);
00512 onGUISheetChanged(args);
00513
00514 return old;
00515 }
00516
00517
00518
00519
00520
00521 void System::setDefaultFont(const String& name)
00522 {
00523 if (name.empty())
00524 {
00525 setDefaultFont(NULL);
00526 }
00527 else
00528 {
00529 setDefaultFont(FontManager::getSingleton().getFont(name));
00530 }
00531
00532 }
00533
00534
00535
00536
00537
00538 void System::setDefaultFont(Font* font)
00539 {
00540 d_defaultFont = font;
00541
00542
00543 EventArgs args;
00544 onDefaultFontChanged(args);
00545 }
00546
00547
00548
00549
00550
00551 void System::setDefaultMouseCursor(const Image* image)
00552 {
00553 if (image == (const Image*)DefaultMouseCursor)
00554 {
00555 image = NULL;
00556 }
00557
00558 d_defaultMouseCursor = image;
00559
00560
00561 EventArgs args;
00562 onDefaultMouseCursorChanged(args);
00563 }
00564
00565
00566
00567
00568
00569 void System::setDefaultMouseCursor(const String& imageset, const String& image_name)
00570 {
00571 setDefaultMouseCursor(&ImagesetManager::getSingleton().getImageset(imageset)->getImage(image_name));
00572 }
00573
00574
00575
00576
00577
00578
00579 ScriptModule* System::getScriptingModule(void) const
00580 {
00581 return d_scriptModule;
00582 }
00583
00584
00585
00586
00587
00588 ResourceProvider* System::getResourceProvider(void) const
00589 {
00590 return d_resourceProvider;
00591 }
00592
00593
00594
00595
00596 void System::executeScriptFile(const String& filename) const
00597 {
00598 if (d_scriptModule != NULL)
00599 {
00600 try
00601 {
00602 d_scriptModule->executeScriptFile(filename);
00603 }
00604 catch(...)
00605 {
00606 throw GenericException((utf8*)"System::executeScriptFile - An exception was thrown during the execution of the script file.");
00607 }
00608
00609 }
00610 else
00611 {
00612 Logger::getSingleton().logEvent((utf8*)"System::executeScriptFile - the script named '" + filename +"' could not be executed as no ScriptModule is available.", Errors);
00613 }
00614
00615 }
00616
00617
00618
00619
00620
00621
00622 int System::executeScriptGloabl(const String& function_name) const
00623 {
00624 if (d_scriptModule != NULL)
00625 {
00626 try
00627 {
00628 return d_scriptModule->executeScriptGloabl(function_name);
00629 }
00630 catch(...)
00631 {
00632 throw GenericException((utf8*)"System::executeScriptGloabl - An exception was thrown during execution of the scripted function.");
00633 }
00634
00635 }
00636 else
00637 {
00638 Logger::getSingleton().logEvent((utf8*)"System::executeScriptGloabl - the global script function named '" + function_name +"' could not be executed as no ScriptModule is available.", Errors);
00639 }
00640
00641 return 0;
00642 }
00643
00644
00645
00646
00647
00648 float System::getMouseMoveScaling(void) const
00649 {
00650 return d_mouseScalingFactor;
00651 }
00652
00653
00654
00655
00656
00657 void System::setMouseMoveScaling(float scaling)
00658 {
00659 d_mouseScalingFactor = scaling;
00660
00661
00662 EventArgs args;
00663 onMouseMoveScalingChanged(args);
00664 }
00665
00666
00667
00668
00669
00670 bool System::injectMouseMove(float delta_x, float delta_y)
00671 {
00672 MouseEventArgs ma(NULL);
00673 MouseCursor& mouse = MouseCursor::getSingleton();
00674
00675 ma.moveDelta.d_x = delta_x * d_mouseScalingFactor;
00676 ma.moveDelta.d_y = delta_y * d_mouseScalingFactor;
00677 ma.sysKeys = d_sysKeys;
00678 ma.wheelChange = 0;
00679
00680
00681 mouse.offsetPosition(ma.moveDelta);
00682 ma.position = mouse.getPosition();
00683
00684 Window* dest_window = getTargetWindow(ma.position);
00685
00686
00687 if (dest_window != NULL)
00688 {
00689 if (dest_window != d_wndWithMouse)
00690 {
00691 if (d_wndWithMouse != NULL)
00692 {
00693 ma.window = d_wndWithMouse;
00694 d_wndWithMouse->onMouseLeaves(ma);
00695 }
00696
00697 d_wndWithMouse = dest_window;
00698 ma.window = dest_window;
00699 dest_window->onMouseEnters(ma);
00700 }
00701
00702
00703 ma.handled = false;
00704
00705
00706 while ((!ma.handled) && (dest_window != NULL))
00707 {
00708 ma.window = dest_window;
00709 dest_window->onMouseMove(ma);
00710 dest_window = dest_window->getParent();
00711 }
00712
00713 }
00714
00715 return ma.handled;
00716 }
00717
00718
00719
00720
00721
00722 bool System::injectMouseButtonDown(MouseButton button)
00723 {
00724
00725 d_sysKeys |= mouseButtonToSyskey(button);
00726
00727 MouseEventArgs ma(NULL);
00728 ma.position = MouseCursor::getSingleton().getPosition();
00729 ma.moveDelta = Vector2(0.0f, 0.0f);
00730 ma.button = button;
00731 ma.sysKeys = d_sysKeys;
00732 ma.wheelChange = 0;
00733
00734
00735
00736
00737 MouseClickTracker& tkr = d_clickTrackerPimpl->click_trackers[button];
00738
00739 tkr.d_click_count++;
00740
00741
00742 if ((tkr.d_timer.elapsed() > d_dblclick_timeout) ||
00743 (!tkr.d_click_area.isPointInRect(ma.position)) ||
00744 (tkr.d_click_count > 3))
00745 {
00746
00747 tkr.d_click_count = 1;
00748
00749
00750 tkr.d_click_area.setPosition(ma.position);
00751 tkr.d_click_area.setSize(d_dblclick_size);
00752 tkr.d_click_area.offset(Point(-(d_dblclick_size.d_width / 2), -(d_dblclick_size.d_height / 2)));
00753 }
00754
00755 Window* dest_window = getTargetWindow(ma.position);
00756
00757
00758 while ((!ma.handled) && (dest_window != NULL))
00759 {
00760 ma.window = dest_window;
00761
00762 if (dest_window->wantsMultiClickEvents())
00763 {
00764 switch (tkr.d_click_count)
00765 {
00766 case 1:
00767 dest_window->onMouseButtonDown(ma);
00768 break;
00769
00770 case 2:
00771 dest_window->onMouseDoubleClicked(ma);
00772 break;
00773
00774 case 3:
00775 dest_window->onMouseTripleClicked(ma);
00776 break;
00777 }
00778 }
00779
00780
00781 else
00782 {
00783 dest_window->onMouseButtonDown(ma);
00784 }
00785
00786 dest_window = dest_window->getParent();
00787 }
00788
00789
00790 tkr.d_timer.restart();
00791
00792 return ma.handled;
00793 }
00794
00795
00796
00797
00798
00799 bool System::injectMouseButtonUp(MouseButton button)
00800 {
00801
00802 d_sysKeys &= ~mouseButtonToSyskey(button);
00803
00804 MouseEventArgs ma(NULL);
00805 ma.position = MouseCursor::getSingleton().getPosition();
00806 ma.moveDelta = Vector2(0.0f, 0.0f);
00807 ma.button = button;
00808 ma.sysKeys = d_sysKeys;
00809 ma.wheelChange = 0;
00810
00811 Window* dest_window = getTargetWindow(ma.position);
00812
00813
00814 while ((!ma.handled) && (dest_window != NULL))
00815 {
00816 ma.window = dest_window;
00817 dest_window->onMouseButtonUp(ma);
00818 dest_window = dest_window->getParent();
00819 }
00820
00821 bool wasUpHandled = ma.handled;
00822
00823
00824 if (d_clickTrackerPimpl->click_trackers[button].d_timer.elapsed() <= d_click_timeout)
00825 {
00826 ma.handled = false;
00827 dest_window = getTargetWindow(ma.position);
00828
00829
00830 while ((!ma.handled) && (dest_window != NULL))
00831 {
00832 ma.window = dest_window;
00833 dest_window->onMouseClicked(ma);
00834 dest_window = dest_window->getParent();
00835 }
00836
00837 }
00838
00839 return (ma.handled | wasUpHandled);
00840 }
00841
00842
00843
00844
00845
00846 bool System::injectKeyDown(uint key_code)
00847 {
00848
00849 d_sysKeys |= keyCodeToSyskey((Key::Scan)key_code, true);
00850
00851 KeyEventArgs args(NULL);
00852
00853 if (d_activeSheet != NULL)
00854 {
00855 args.scancode = (Key::Scan)key_code;
00856 args.sysKeys = d_sysKeys;
00857
00858 Window* dest = d_activeSheet->getActiveChild();
00859
00860
00861 while ((dest != NULL) && (!args.handled))
00862 {
00863 args.window = dest;
00864 dest->onKeyDown(args);
00865 dest = dest->getParent();
00866 }
00867
00868 }
00869
00870 return args.handled;
00871 }
00872
00873
00874
00875
00876
00877 bool System::injectKeyUp(uint key_code)
00878 {
00879
00880 d_sysKeys &= ~keyCodeToSyskey((Key::Scan)key_code, false);
00881
00882 KeyEventArgs args(NULL);
00883
00884 if (d_activeSheet != NULL)
00885 {
00886 args.scancode = (Key::Scan)key_code;
00887 args.sysKeys = d_sysKeys;
00888
00889 Window* dest = d_activeSheet->getActiveChild();
00890
00891
00892 while ((dest != NULL) && (!args.handled))
00893 {
00894 args.window = dest;
00895 dest->onKeyUp(args);
00896 dest = dest->getParent();
00897 }
00898
00899 }
00900
00901 return args.handled;
00902 }
00903
00904
00905
00906
00907
00908 bool System::injectChar(utf32 code_point)
00909 {
00910 KeyEventArgs args(NULL);
00911
00912 if (d_activeSheet != NULL)
00913 {
00914 args.codepoint = code_point;
00915 args.sysKeys = d_sysKeys;
00916
00917 Window* dest = d_activeSheet->getActiveChild();
00918
00919
00920 while ((dest != NULL) && (!args.handled))
00921 {
00922 args.window = dest;
00923 dest->onCharacter(args);
00924 dest = dest->getParent();
00925 }
00926
00927 }
00928
00929 return args.handled;
00930 }
00931
00932
00933
00934
00935
00936 bool System::injectMouseWheelChange(float delta)
00937 {
00938 MouseEventArgs ma(NULL);
00939 ma.position = MouseCursor::getSingleton().getPosition();
00940 ma.moveDelta = Vector2(0.0f, 0.0f);
00941 ma.button = NoButton;
00942 ma.sysKeys = d_sysKeys;
00943 ma.wheelChange = delta;
00944
00945 Window* dest_window = getTargetWindow(ma.position);
00946
00947
00948 while ((!ma.handled) && (dest_window != NULL))
00949 {
00950 ma.window = dest_window;
00951 dest_window->onMouseWheel(ma);
00952 dest_window = dest_window->getParent();
00953 }
00954
00955 return ma.handled;
00956 }
00957
00958
00959
00960
00961
00962 bool System::injectMousePosition(float x_pos, float y_pos)
00963 {
00964
00965 MouseCursor::getSingleton().setPosition(Point(x_pos, y_pos));
00966
00967
00968 return injectMouseMove(0, 0);
00969 }
00970
00971
00972
00973
00974
00975 bool System::injectTimePulse(float timeElapsed)
00976 {
00977 if (d_activeSheet != NULL)
00978 {
00979 d_activeSheet->update(timeElapsed);
00980 }
00981
00982 return true;
00983 }
00984
00985
00986
00987
00988
00989 Window* System::getTargetWindow(const Point& pt) const
00990 {
00991 Window* dest_window = NULL;
00992
00993
00994 if (d_activeSheet != NULL)
00995 {
00996 dest_window = Window::getCaptureWindow();
00997
00998 if (dest_window == NULL)
00999 {
01000 dest_window = d_activeSheet->getChildAtPosition(pt);
01001
01002 if (dest_window == NULL)
01003 {
01004 dest_window = d_activeSheet;
01005 }
01006
01007 }
01008 else
01009 {
01010 Window* child_window = dest_window->getChildAtPosition(pt);
01011
01012 if (child_window != NULL)
01013 {
01014 dest_window = child_window;
01015 }
01016
01017 }
01018
01019 }
01020
01021 return dest_window;
01022 }
01023
01024
01025
01026
01027
01028 SystemKey System::mouseButtonToSyskey(MouseButton btn) const
01029 {
01030 switch (btn)
01031 {
01032 case LeftButton:
01033 return LeftMouse;
01034
01035 case RightButton:
01036 return RightMouse;
01037
01038 case MiddleButton:
01039 return MiddleMouse;
01040
01041 case X1Button:
01042 return X1Mouse;
01043
01044 case X2Button:
01045 return X2Mouse;
01046
01047 default:
01048 throw InvalidRequestException((utf8*)"System::mouseButtonToSyskey - the parameter 'btn' is not a valid MouseButton value.");
01049 }
01050 }
01051
01052
01053
01054
01055
01056 SystemKey System::keyCodeToSyskey(Key::Scan key, bool direction)
01057 {
01058 switch (key)
01059 {
01060 case Key::LeftShift:
01061 d_lshift = direction;
01062
01063 if (!d_rshift)
01064 {
01065 return Shift;
01066 }
01067 break;
01068
01069 case Key::RightShift:
01070 d_rshift = direction;
01071
01072 if (!d_lshift)
01073 {
01074 return Shift;
01075 }
01076 break;
01077
01078
01079 case Key::LeftControl:
01080 d_lctrl = direction;
01081
01082 if (!d_rctrl)
01083 {
01084 return Control;
01085 }
01086 break;
01087
01088 case Key::RightControl:
01089 d_rctrl = direction;
01090
01091 if (!d_lctrl)
01092 {
01093 return Control;
01094 }
01095 break;
01096
01097 default:
01098 break;
01099 }
01100
01101
01102 return (SystemKey)0;
01103 }
01104
01105
01106 System& System::getSingleton(void)
01107 {
01108 return Singleton<System>::getSingleton();
01109 }
01110
01111
01112 System* System::getSingletonPtr(void)
01113 {
01114 return Singleton<System>::getSingletonPtr();
01115 }
01116
01117
01118
01119
01120
01121
01122 void System::setSingleClickTimeout(double timeout)
01123 {
01124 d_click_timeout = timeout;
01125
01126
01127 EventArgs args;
01128 onSingleClickTimeoutChanged(args);
01129 }
01130
01131
01132
01133
01134
01135 void System::setMultiClickTimeout(double timeout)
01136 {
01137 d_dblclick_timeout = timeout;
01138
01139
01140 EventArgs args;
01141 onMultiClickTimeoutChanged(args);
01142 }
01143
01144
01145
01146
01147
01148
01149 void System::setMultiClickToleranceAreaSize(const Size& sz)
01150 {
01151 d_dblclick_size = sz;
01152
01153
01154 EventArgs args;
01155 onMultiClickAreaSizeChanged(args);
01156 }
01157
01158
01159
01160
01161
01162 void System::addSystemEvents(void)
01163 {
01164 addEvent(EventGUISheetChanged);
01165 addEvent(EventSingleClickTimeoutChanged);
01166 addEvent(EventMultiClickTimeoutChanged);
01167 addEvent(EventMultiClickAreaSizeChanged);
01168 addEvent(EventDefaultFontChanged);
01169 addEvent(EventDefaultMouseCursorChanged);
01170 addEvent(EventMouseMoveScalingChanged);
01171 }
01172
01173
01174
01175
01176
01177 void System::onGUISheetChanged(WindowEventArgs& e)
01178 {
01179 fireEvent(EventGUISheetChanged, e, EventNamespace);
01180 }
01181
01182
01183
01184
01185
01186 void System::onSingleClickTimeoutChanged(EventArgs& e)
01187 {
01188 fireEvent(EventSingleClickTimeoutChanged, e, EventNamespace);
01189 }
01190
01191
01192
01193
01194
01195 void System::onMultiClickTimeoutChanged(EventArgs& e)
01196 {
01197 fireEvent(EventMultiClickTimeoutChanged, e, EventNamespace);
01198 }
01199
01200
01201
01202
01203
01204
01205 void System::onMultiClickAreaSizeChanged(EventArgs& e)
01206 {
01207 fireEvent(EventMultiClickAreaSizeChanged, e, EventNamespace);
01208 }
01209
01210
01211
01212
01213
01214 void System::onDefaultFontChanged(EventArgs& e)
01215 {
01216 fireEvent(EventDefaultFontChanged, e, EventNamespace);
01217 }
01218
01219
01220
01221
01222
01223 void System::onDefaultMouseCursorChanged(EventArgs& e)
01224 {
01225 fireEvent(EventDefaultMouseCursorChanged, e, EventNamespace);
01226 }
01227
01228
01229
01230
01231
01232 void System::onMouseMoveScalingChanged(EventArgs& e)
01233 {
01234 fireEvent(EventMouseMoveScalingChanged, e, EventNamespace);
01235 }
01236
01237
01238
01239
01240
01241 bool System::handleDisplaySizeChange(const EventArgs& e)
01242 {
01243
01244
01245 if (d_activeSheet != NULL)
01246 {
01247 WindowEventArgs args(NULL);
01248 d_activeSheet->onParentSized(args);
01249 }
01250
01251 return true;
01252 }
01253
01254
01255
01256
01257
01258
01259 void System::notifyWindowDestroyed(const Window* window)
01260 {
01261 if (d_wndWithMouse == window)
01262 {
01263 d_wndWithMouse = NULL;
01264 }
01265
01266 if (d_activeSheet == window)
01267 {
01268 d_activeSheet = NULL;
01269 }
01270
01271 }
01272
01273 }