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