From 71e94ee161447b84c0eaabf6567f8fa62262cd3e Mon Sep 17 00:00:00 2001 From: Mirrorbot Date: Sat, 27 Dec 2025 17:53:06 -0600 Subject: Inital commit --- examples/24.CursorControl/CursorControl.cbp | 57 +++ examples/24.CursorControl/CursorControl.vcproj | 132 +++++ .../24.CursorControl/CursorControl_vc10.vcxproj | 188 +++++++ .../24.CursorControl/CursorControl_vc11.vcxproj | 188 +++++++ .../24.CursorControl/CursorControl_vc12.vcxproj | 188 +++++++ examples/24.CursorControl/CursorControl_vc8.vcproj | 190 +++++++ examples/24.CursorControl/CursorControl_vc9.vcproj | 185 +++++++ examples/24.CursorControl/Makefile | 66 +++ examples/24.CursorControl/main.cpp | 563 +++++++++++++++++++++ examples/24.CursorControl/tutorial.html | 205 ++++++++ 10 files changed, 1962 insertions(+) create mode 100644 examples/24.CursorControl/CursorControl.cbp create mode 100644 examples/24.CursorControl/CursorControl.vcproj create mode 100644 examples/24.CursorControl/CursorControl_vc10.vcxproj create mode 100644 examples/24.CursorControl/CursorControl_vc11.vcxproj create mode 100644 examples/24.CursorControl/CursorControl_vc12.vcxproj create mode 100644 examples/24.CursorControl/CursorControl_vc8.vcproj create mode 100644 examples/24.CursorControl/CursorControl_vc9.vcproj create mode 100644 examples/24.CursorControl/Makefile create mode 100644 examples/24.CursorControl/main.cpp create mode 100644 examples/24.CursorControl/tutorial.html (limited to 'examples/24.CursorControl') diff --git a/examples/24.CursorControl/CursorControl.cbp b/examples/24.CursorControl/CursorControl.cbp new file mode 100644 index 0000000..b8aa231 --- /dev/null +++ b/examples/24.CursorControl/CursorControl.cbp @@ -0,0 +1,57 @@ + + + + + + diff --git a/examples/24.CursorControl/CursorControl.vcproj b/examples/24.CursorControl/CursorControl.vcproj new file mode 100644 index 0000000..1bc2f53 --- /dev/null +++ b/examples/24.CursorControl/CursorControl.vcproj @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/24.CursorControl/CursorControl_vc10.vcxproj b/examples/24.CursorControl/CursorControl_vc10.vcxproj new file mode 100644 index 0000000..7eadc6f --- /dev/null +++ b/examples/24.CursorControl/CursorControl_vc10.vcxproj @@ -0,0 +1,188 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 24.CursorControl + {02B67A37-50E1-49DB-BECF-905BC029C2FE} + 24.CursorControl + Win32Proj + + + + Application + MultiByte + Windows7.1SDK + + + Application + MultiByte + Windows7.1SDK + + + Application + MultiByte + Windows7.1SDK + + + Application + MultiByte + Windows7.1SDK + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + ..\..\bin\Win32-VisualStudio\24.CursorControl.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + true + $(OutDir)CursorControl.pdb + Console + + + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + ..\..\bin\Win64-VisualStudio\24.CursorControl.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + true + $(OutDir)CursorControl.pdb + Console + + + + + + + true + Speed + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + Sync + + + Level3 + + + Cdecl + + + ..\..\bin\Win32-VisualStudio\24.CursorControl.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + false + Console + true + true + + + + + + + true + Speed + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + Sync + + + Level3 + + + Cdecl + + + ..\..\bin\Win64-VisualStudio\24.CursorControl.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + false + Console + true + true + + + + + + + + + + + \ No newline at end of file diff --git a/examples/24.CursorControl/CursorControl_vc11.vcxproj b/examples/24.CursorControl/CursorControl_vc11.vcxproj new file mode 100644 index 0000000..7eadc6f --- /dev/null +++ b/examples/24.CursorControl/CursorControl_vc11.vcxproj @@ -0,0 +1,188 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 24.CursorControl + {02B67A37-50E1-49DB-BECF-905BC029C2FE} + 24.CursorControl + Win32Proj + + + + Application + MultiByte + Windows7.1SDK + + + Application + MultiByte + Windows7.1SDK + + + Application + MultiByte + Windows7.1SDK + + + Application + MultiByte + Windows7.1SDK + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + ..\..\bin\Win32-VisualStudio\24.CursorControl.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + true + $(OutDir)CursorControl.pdb + Console + + + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + ..\..\bin\Win64-VisualStudio\24.CursorControl.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + true + $(OutDir)CursorControl.pdb + Console + + + + + + + true + Speed + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + Sync + + + Level3 + + + Cdecl + + + ..\..\bin\Win32-VisualStudio\24.CursorControl.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + false + Console + true + true + + + + + + + true + Speed + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + Sync + + + Level3 + + + Cdecl + + + ..\..\bin\Win64-VisualStudio\24.CursorControl.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + false + Console + true + true + + + + + + + + + + + \ No newline at end of file diff --git a/examples/24.CursorControl/CursorControl_vc12.vcxproj b/examples/24.CursorControl/CursorControl_vc12.vcxproj new file mode 100644 index 0000000..26fdf87 --- /dev/null +++ b/examples/24.CursorControl/CursorControl_vc12.vcxproj @@ -0,0 +1,188 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 24.CursorControl + {02B67A37-50E1-49DB-BECF-905BC029C2FE} + 24.CursorControl + Win32Proj + + + + Application + MultiByte + Windows7.1SDK + + + Application + MultiByte + Windows7.1SDK + + + Application + MultiByte + Windows7.1SDK + + + Application + MultiByte + Windows7.1SDK + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + ..\..\bin\Win32-VisualStudio\24.CursorControl.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + true + $(OutDir)CursorControl.pdb + Console + + + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + ..\..\bin\Win64-VisualStudio\24.CursorControl.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + true + $(OutDir)CursorControl.pdb + Console + + + + + + + true + Speed + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + Sync + + + Level3 + + + Cdecl + + + ..\..\bin\Win32-VisualStudio\24.CursorControl.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + false + Console + true + true + + + + + + + true + Speed + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + Sync + + + Level3 + + + Cdecl + + + ..\..\bin\Win64-VisualStudio\24.CursorControl.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + false + Console + true + true + + + + + + + + + + + \ No newline at end of file diff --git a/examples/24.CursorControl/CursorControl_vc8.vcproj b/examples/24.CursorControl/CursorControl_vc8.vcproj new file mode 100644 index 0000000..6148942 --- /dev/null +++ b/examples/24.CursorControl/CursorControl_vc8.vcproj @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/24.CursorControl/CursorControl_vc9.vcproj b/examples/24.CursorControl/CursorControl_vc9.vcproj new file mode 100644 index 0000000..90ebf1f --- /dev/null +++ b/examples/24.CursorControl/CursorControl_vc9.vcproj @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/24.CursorControl/Makefile b/examples/24.CursorControl/Makefile new file mode 100644 index 0000000..bc2a137 --- /dev/null +++ b/examples/24.CursorControl/Makefile @@ -0,0 +1,66 @@ +# Makefile for Irrlicht Examples +# It's usually sufficient to change just the target name and source file list +# and be sure that CXX is set to a valid compiler + +# Name of the executable created (.exe will be added automatically if necessary) +Target := 24.CursorControl +# List of source files, separated by spaces +Sources := main.cpp +# Path to Irrlicht directory, should contain include/ and lib/ +IrrlichtHome := ../.. +# Path for the executable. Note that Irrlicht.dll should usually also be there for win32 systems +BinPath = ../../bin/$(SYSTEM) + +# general compiler settings (might need to be set when compiling the lib, too) +# preprocessor flags, e.g. defines and include paths +USERCPPFLAGS = +# compiler flags such as optimization flags +USERCXXFLAGS = -O3 -ffast-math +#USERCXXFLAGS = -g -Wall +# linker flags such as additional libraries and link paths +USERLDFLAGS = + +#### +#no changes necessary below this line +#### + +CPPFLAGS = -I$(IrrlichtHome)/include -I/usr/X11R6/include $(USERCPPFLAGS) +CXXFLAGS = $(USERCXXFLAGS) +LDFLAGS = $(USERLDFLAGS) + +#default target is Linux +all: all_linux + +# target specific settings +all_linux all_win32 static_win32: LDFLAGS += -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht +all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lXxf86vm -lXext -lX11 -lXcursor +all_linux clean_linux: SYSTEM=Linux +all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc +all_win32 clean_win32 static_win32: SUF=.exe +static_win32: CPPFLAGS += -D_IRR_STATIC_LIB_ +all_win32: LDFLAGS += -lopengl32 -lm +static_win32: LDFLAGS += -lgdi32 -lwinspool -lcomdlg32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lopengl32 +# name of the binary - only valid for targets which set SYSTEM +DESTPATH = $(BinPath)/$(Target)$(SUF) + +all_linux all_win32 static_win32: + $(warning Building...) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(Sources) -o $(DESTPATH) $(LDFLAGS) + +clean: clean_linux clean_win32 + $(warning Cleaning...) + +clean_linux clean_win32: + @$(RM) $(DESTPATH) + +.PHONY: all all_win32 static_win32 clean clean_linux clean_win32 + +#multilib handling +ifeq ($(HOSTTYPE), x86_64) +LIBSELECT=64 +endif +#solaris real-time features +ifeq ($(HOSTTYPE), sun4) +LDFLAGS += -lrt +endif + diff --git a/examples/24.CursorControl/main.cpp b/examples/24.CursorControl/main.cpp new file mode 100644 index 0000000..ff7c16f --- /dev/null +++ b/examples/24.CursorControl/main.cpp @@ -0,0 +1,563 @@ +/** Example 024 CursorControl + +Show how to modify cursors and offer some useful tool-functions for creating cursors. +It can also be used for experiments with the mouse in general. +*/ + +#include +#include "driverChoice.h" + +using namespace irr; +using namespace core; +using namespace scene; +using namespace video; +using namespace io; +using namespace gui; + +#ifdef _IRR_WINDOWS_ +#pragma comment(lib, "Irrlicht.lib") +#endif + +const int DELAY_TIME = 3000; + +enum ETimerAction +{ + ETA_MOUSE_VISIBLE, + ETA_MOUSE_INVISIBLE, +}; + +/* + Structure to allow delayed execution of some actions. +*/ +struct TimerAction +{ + u32 TargetTime; + ETimerAction Action; +}; + +/* +*/ +struct SAppContext +{ + SAppContext() + : Device(0), InfoStatic(0), EventBox(0), CursorBox(0), SpriteBox(0) + , ButtonSetVisible(0), ButtonSetInvisible(0), ButtonSimulateBadFps(0) + , ButtonChangeIcon(0) + , SimulateBadFps(false) + { + } + + void update() + { + if (!Device) + return; + u32 timeNow = Device->getTimer()->getTime(); + for ( u32 i=0; i < TimerActions.size(); ++i ) + { + if ( timeNow >= TimerActions[i].TargetTime ) + { + runTimerAction(TimerActions[i]); + TimerActions.erase(i); + } + else + { + ++i; + } + } + } + + void runTimerAction(const TimerAction& action) + { + if (ETA_MOUSE_VISIBLE == action.Action) + { + Device->getCursorControl()->setVisible(true); + ButtonSetVisible->setEnabled(true); + } + else if ( ETA_MOUSE_INVISIBLE == action.Action) + { + Device->getCursorControl()->setVisible(false); + ButtonSetInvisible->setEnabled(true); + } + } + + /* + Add another icon which the user can click and select as cursor later on. + */ + void addIcon(const stringw& name, const SCursorSprite &sprite, bool addCursor=true) + { + // Sprites are just icons - not yet cursors. They can be displayed by Irrlicht sprite functions and be used to create cursors. + SpriteBox->addItem(name.c_str(), sprite.SpriteId); + Sprites.push_back(sprite); + + // create the cursor together with the icon? + if ( addCursor ) + { + /* Here we create a hardware cursor from a sprite */ + Device->getCursorControl()->addIcon(sprite); + + // ... and add it to the cursors selection listbox to the other system cursors. + CursorBox->addItem(name.c_str()); + } + } + + IrrlichtDevice * Device; + gui::IGUIStaticText * InfoStatic; + gui::IGUIListBox * EventBox; + gui::IGUIListBox * CursorBox; + gui::IGUIListBox * SpriteBox; + gui::IGUIButton * ButtonSetVisible; + gui::IGUIButton * ButtonSetInvisible; + gui::IGUIButton * ButtonSimulateBadFps; + gui::IGUIButton * ButtonChangeIcon; + array TimerActions; + bool SimulateBadFps; + array Sprites; +}; + +/* + Helper function to print mouse event names into a stringw +*/ +void PrintMouseEventName(const SEvent& event, stringw &result) +{ + switch ( event.MouseInput.Event ) + { + case EMIE_LMOUSE_PRESSED_DOWN: result += stringw(L"EMIE_LMOUSE_PRESSED_DOWN"); break; + case EMIE_RMOUSE_PRESSED_DOWN: result += stringw(L"EMIE_RMOUSE_PRESSED_DOWN"); break; + case EMIE_MMOUSE_PRESSED_DOWN: result += stringw(L"EMIE_MMOUSE_PRESSED_DOWN"); break; + case EMIE_LMOUSE_LEFT_UP: result += stringw(L"EMIE_LMOUSE_LEFT_UP"); break; + case EMIE_RMOUSE_LEFT_UP: result += stringw(L"EMIE_RMOUSE_LEFT_UP"); break; + case EMIE_MMOUSE_LEFT_UP: result += stringw(L"EMIE_MMOUSE_LEFT_UP"); break; + case EMIE_MOUSE_MOVED: result += stringw(L"EMIE_MOUSE_MOVED"); break; + case EMIE_MOUSE_WHEEL: result += stringw(L"EMIE_MOUSE_WHEEL"); break; + case EMIE_LMOUSE_DOUBLE_CLICK: result += stringw(L"EMIE_LMOUSE_DOUBLE_CLICK"); break; + case EMIE_RMOUSE_DOUBLE_CLICK: result += stringw(L"EMIE_RMOUSE_DOUBLE_CLICK"); break; + case EMIE_MMOUSE_DOUBLE_CLICK: result += stringw(L"EMIE_MMOUSE_DOUBLE_CLICK"); break; + case EMIE_LMOUSE_TRIPLE_CLICK: result += stringw(L"EMIE_LMOUSE_TRIPLE_CLICK"); break; + case EMIE_RMOUSE_TRIPLE_CLICK: result += stringw(L"EMIE_RMOUSE_TRIPLE_CLICK"); break; + case EMIE_MMOUSE_TRIPLE_CLICK: result += stringw(L"EMIE_MMOUSE_TRIPLE_CLICK"); break; + default: + break; + } +} + +/* + Helper function to print all the state information which get from a mouse-event into a stringw +*/ +void PrintMouseState(const SEvent& event, stringw &result) +{ + result += stringw(L"X: "); + result += stringw(event.MouseInput.X); + result += stringw(L"\n"); + + result += stringw(L"Y: "); + result += stringw(event.MouseInput.Y); + result += stringw(L"\n"); + + + result += stringw(L"Wheel: "); + result += stringw(event.MouseInput.Wheel); + result += stringw(L"\n"); + + result += stringw(L"Shift: "); + if ( event.MouseInput.Shift ) + result += stringw(L"true\n"); + else + result += stringw(L"false\n"); + + result += stringw(L"Control: "); + if ( event.MouseInput.Control ) + result += stringw(L"true\n"); + else + result += stringw(L"false\n"); + + result += stringw(L"ButtonStates: "); + result += stringw(event.MouseInput.ButtonStates); + result += stringw(L"\n"); + + result += stringw(L"isLeftPressed: "); + if ( event.MouseInput.isLeftPressed() ) + result += stringw(L"true\n"); + else + result += stringw(L"false\n"); + + result += stringw(L"isRightPressed: "); + if ( event.MouseInput.isRightPressed() ) + result += stringw(L"true\n"); + else + result += stringw(L"false\n"); + + result += stringw(L"isMiddlePressed: "); + if ( event.MouseInput.isMiddlePressed() ) + result += stringw(L"true\n"); + else + result += stringw(L"false\n"); + + result += stringw(L"Event: "); + + PrintMouseEventName(event, result); + + result += stringw(L"\n"); +} + +/* + A typical event receiver. +*/ +class MyEventReceiver : public IEventReceiver +{ +public: + MyEventReceiver(SAppContext & context) : Context(context) { } + + virtual bool OnEvent(const SEvent& event) + { + if (event.EventType == EET_GUI_EVENT ) + { + switch ( event.GUIEvent.EventType ) + { + case EGET_BUTTON_CLICKED: + { + u32 timeNow = Context.Device->getTimer()->getTime(); + TimerAction action; + action.TargetTime = timeNow + DELAY_TIME; + if ( event.GUIEvent.Caller == Context.ButtonSetVisible ) + { + action.Action = ETA_MOUSE_VISIBLE; + Context.TimerActions.push_back(action); + Context.ButtonSetVisible->setEnabled(false); + } + else if ( event.GUIEvent.Caller == Context.ButtonSetInvisible ) + { + action.Action = ETA_MOUSE_INVISIBLE; + Context.TimerActions.push_back(action); + Context.ButtonSetInvisible->setEnabled(false); + } + else if ( event.GUIEvent.Caller == Context.ButtonSimulateBadFps ) + { + Context.SimulateBadFps = Context.ButtonSimulateBadFps->isPressed(); + } + else if ( event.GUIEvent.Caller == Context.ButtonChangeIcon ) + { + /* + Replace an existing cursor icon by another icon. + The user has to select both - the icon which should be replaced and the icon which will replace it. + */ + s32 selectedCursor = Context.CursorBox->getSelected(); + s32 selectedSprite = Context.SpriteBox->getSelected(); + if ( selectedCursor >= 0 && selectedSprite >= 0 ) + { + /* + This does replace the icon. + */ + Context.Device->getCursorControl()->changeIcon((ECURSOR_ICON)selectedCursor, Context.Sprites[selectedSprite] ); + + /* + Do also show the new icon. + */ + Context.Device->getCursorControl()->setActiveIcon( ECURSOR_ICON(selectedCursor) ); + } + } + } + break; + case EGET_LISTBOX_CHANGED: + case EGET_LISTBOX_SELECTED_AGAIN: + { + if ( event.GUIEvent.Caller == Context.CursorBox ) + { + /* + Find out which cursor the user selected + */ + s32 selected = Context.CursorBox->getSelected(); + if ( selected >= 0 ) + { + /* + Here we set the new cursor icon which will now be used within our window. + */ + Context.Device->getCursorControl()->setActiveIcon( ECURSOR_ICON(selected) ); + } + } + } + break; + default: + break; + } + } + + if (event.EventType == EET_MOUSE_INPUT_EVENT) + { + stringw infoText; + PrintMouseState(event, infoText); + Context.InfoStatic->setText(infoText.c_str()); + if ( event.MouseInput.Event != EMIE_MOUSE_MOVED && event.MouseInput.Event != EMIE_MOUSE_WHEEL ) // no spam + { + infoText = L""; + PrintMouseEventName(event, infoText); + Context.EventBox->insertItem(0, infoText.c_str(), -1); + } + } + + return false; + } + +private: + SAppContext & Context; +}; + +/* + Use several imagefiles as animation frames for a sprite which can be used as cursor icon. + The images in those files all need to have the same size. + Return sprite index on success or -1 on failure +*/ +s32 AddAnimatedIconToSpriteBank( gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, const array< io::path >& files, u32 frameTime ) +{ + if ( !spriteBank || !driver || !files.size() ) + return -1; + + video::ITexture * tex = driver->getTexture( files[0] ); + if ( tex ) + { + array< rect >& spritePositions = spriteBank->getPositions(); + u32 idxRect = spritePositions.size(); + spritePositions.push_back( rect(0,0, tex->getSize().Width, tex->getSize().Height) ); + + SGUISprite sprite; + sprite.frameTime = frameTime; + + array< SGUISprite >& sprites = spriteBank->getSprites(); + u32 startIdx = spriteBank->getTextureCount(); + for ( u32 f=0; f < files.size(); ++f ) + { + tex = driver->getTexture( files[f] ); + if ( tex ) + { + spriteBank->addTexture( driver->getTexture(files[f]) ); + gui::SGUISpriteFrame frame; + frame.rectNumber = idxRect; + frame.textureNumber = startIdx+f; + sprite.Frames.push_back( frame ); + } + } + + sprites.push_back( sprite ); + return sprites.size()-1; + } + + return -1; +} + +/* + Use several images within one imagefile as animation frames for a sprite which can be used as cursor icon + The sizes of the icons within that file all need to have the same size + Return sprite index on success or -1 on failure +*/ +s32 AddAnimatedIconToSpriteBank( gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, const io::path& file, const array< rect >& rects, u32 frameTime ) +{ + if ( !spriteBank || !driver || !rects.size() ) + return -1; + + video::ITexture * tex = driver->getTexture( file ); + if ( tex ) + { + array< rect >& spritePositions = spriteBank->getPositions(); + u32 idxRect = spritePositions.size(); + u32 idxTex = spriteBank->getTextureCount(); + spriteBank->addTexture( tex ); + + SGUISprite sprite; + sprite.frameTime = frameTime; + + array< SGUISprite >& sprites = spriteBank->getSprites(); + for ( u32 i=0; i < rects.size(); ++i ) + { + spritePositions.push_back( rects[i] ); + + gui::SGUISpriteFrame frame; + frame.rectNumber = idxRect+i; + frame.textureNumber = idxTex; + sprite.Frames.push_back( frame ); + } + + sprites.push_back( sprite ); + return sprites.size()-1; + } + + return -1; +} + +/* + Create a non-animated icon from the given file and position and put it into the spritebank. + We can use this icon later on in a cursor. +*/ +s32 AddIconToSpriteBank( gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, const io::path& file, const core::rect& rect ) +{ + if ( !spriteBank || !driver ) + return -1; + + video::ITexture * tex = driver->getTexture( file ); + if ( tex ) + { + core::array< core::rect >& spritePositions = spriteBank->getPositions(); + spritePositions.push_back( rect ); + array< SGUISprite >& sprites = spriteBank->getSprites(); + spriteBank->addTexture( tex ); + + gui::SGUISpriteFrame frame; + frame.rectNumber = spritePositions.size()-1; + frame.textureNumber = spriteBank->getTextureCount()-1; + + SGUISprite sprite; + sprite.frameTime = 0; + sprite.Frames.push_back( frame ); + + sprites.push_back( sprite ); + + return sprites.size()-1; + } + + return -1; +} + +int main() +{ + video::E_DRIVER_TYPE driverType = driverChoiceConsole(); + if (driverType==video::EDT_COUNT) + return 1; + + IrrlichtDevice * device = createDevice(driverType, dimension2d(640, 480)); + if (device == 0) + return 1; // could not create selected driver. + + // It's sometimes of interest to know how the mouse behaves after a resize + device->setResizable(true); + + device->setWindowCaption(L"Cursor control - Irrlicht engine tutorial"); + video::IVideoDriver* driver = device->getVideoDriver(); + IGUIEnvironment* env = device->getGUIEnvironment(); + + gui::IGUISpriteBank * SpriteBankIcons; + + SAppContext context; + context.Device = device; + + rect< s32 > rectInfoStatic(10,10, 200, 200); + env->addStaticText (L"Cursor state information", rectInfoStatic, true, true); + rectInfoStatic.UpperLeftCorner += dimension2di(0, 15); + context.InfoStatic = env->addStaticText (L"", rectInfoStatic, true, true); + rect< s32 > rectEventBox(10,210, 200, 400); + env->addStaticText (L"click events (new on top)", rectEventBox, true, true); + rectEventBox.UpperLeftCorner += dimension2di(0, 15); + context.EventBox = env->addListBox(rectEventBox); + rect< s32 > rectCursorBox(210,10, 400, 250); + env->addStaticText (L"cursors, click to set the active one", rectCursorBox, true, true); + rectCursorBox.UpperLeftCorner += dimension2di(0, 15); + context.CursorBox = env->addListBox(rectCursorBox); + rect< s32 > rectSpriteBox(210,260, 400, 400); + env->addStaticText (L"sprites", rectSpriteBox, true, true); + rectSpriteBox.UpperLeftCorner += dimension2di(0, 15); + context.SpriteBox = env->addListBox(rectSpriteBox); + + context.ButtonSetVisible = env->addButton( rect( 410, 20, 560, 40 ), 0, -1, L"set visible (delayed)" ); + context.ButtonSetInvisible = env->addButton( rect( 410, 50, 560, 70 ), 0, -1, L"set invisible (delayed)" ); + context.ButtonSimulateBadFps = env->addButton( rect( 410, 80, 560, 100 ), 0, -1, L"simulate bad FPS" ); + context.ButtonSimulateBadFps->setIsPushButton(true); + context.ButtonChangeIcon = env->addButton( rect( 410, 140, 560, 160 ), 0, -1, L"replace cursor icon\n(cursor+sprite must be selected)" ); + + // set the names for all the system cursors + for ( int i=0; i < (int)gui::ECI_COUNT; ++i ) + { + context.CursorBox->addItem(stringw( GUICursorIconNames[i] ).c_str()); + } + + /* + Create sprites which then can be used as cursor icons. + */ + SpriteBankIcons = env->addEmptySpriteBank(io::path("cursor_icons")); + context.SpriteBox->setSpriteBank(SpriteBankIcons); + + // create one animated icon from several files + array< io::path > files; + files.push_back( io::path("../../media/icon_crosshairs16x16bw1.png") ); + files.push_back( io::path("../../media/icon_crosshairs16x16bw2.png") ); + files.push_back( io::path("../../media/icon_crosshairs16x16bw3.png") ); + files.push_back( io::path("../../media/icon_crosshairs16x16bw3.png") ); + files.push_back( io::path("../../media/icon_crosshairs16x16bw2.png") ); + SCursorSprite spriteBw; // the sprite + some additional information needed for cursors + spriteBw.SpriteId = AddAnimatedIconToSpriteBank( SpriteBankIcons, driver, files, 200 ); + spriteBw.SpriteBank = SpriteBankIcons; + spriteBw.HotSpot = position2d(7,7); + context.addIcon(L"crosshair_bw", spriteBw); + + // create one animated icon from one file + array< rect > iconRects; + iconRects.push_back( rect(0,0, 16, 16) ); + iconRects.push_back( rect(16,0, 32, 16) ); + iconRects.push_back( rect(0,16, 16, 32) ); + iconRects.push_back( rect(0,16, 16, 32) ); + iconRects.push_back( rect(16,0, 32, 16) ); + SCursorSprite spriteCol; // the sprite + some additional information needed for cursors + spriteCol.SpriteId = AddAnimatedIconToSpriteBank( SpriteBankIcons, driver, io::path("../../media/icon_crosshairs16x16col.png"), iconRects, 200 ); + spriteCol.HotSpot = position2d(7,7); + spriteCol.SpriteBank = SpriteBankIcons; + context.addIcon(L"crosshair_colored", spriteCol); + + // Create some non-animated icons + rect rectIcon; + SCursorSprite spriteNonAnimated(SpriteBankIcons, 0, position2d(7,7)); + + rectIcon = rect(0,0, 16, 16); + spriteNonAnimated.SpriteId = AddIconToSpriteBank( SpriteBankIcons, driver, io::path("../../media/icon_crosshairs16x16col.png"), rectIcon ); + context.addIcon(L"crosshair_col1", spriteNonAnimated, false); + + rectIcon = rect(16,0, 32, 16); + spriteNonAnimated.SpriteId = AddIconToSpriteBank( SpriteBankIcons, driver, io::path("../../media/icon_crosshairs16x16col.png"), rectIcon ); + context.addIcon(L"crosshair_col2", spriteNonAnimated, false); + + rectIcon = rect(0,16, 16, 32); + spriteNonAnimated.SpriteId = AddIconToSpriteBank( SpriteBankIcons, driver, io::path("../../media/icon_crosshairs16x16col.png"), rectIcon ); + context.addIcon(L"crosshair_col3", spriteNonAnimated, false); + + + MyEventReceiver receiver(context); + device->setEventReceiver(&receiver); + + while(device->run() && driver) + { + // if (device->isWindowActive()) + { + u32 realTimeNow = device->getTimer()->getRealTime(); + + context.update(); + + driver->beginScene(true, true, SColor(0,200,200,200)); + + env->drawAll(); + + // draw custom sprite with Irrlicht functions for comparison. It should usually look the same as the cursors. + if ( context.SpriteBox ) + { + s32 selectedSprite = context.SpriteBox->getSelected(); + if ( selectedSprite >= 0 && context.Sprites[selectedSprite].SpriteId >= 0 ) + { + SpriteBankIcons->draw2DSprite(u32(context.Sprites[selectedSprite].SpriteId), position2di(580, 140), 0, video::SColor(255, 255, 255, 255), 0, realTimeNow); + } + } + + driver->endScene(); + } + + // By simulating bad fps we can find out if hardware-support for cursors works or not. If it works the cursor will move as usual,while it otherwise will just update with 2 fps now. + if ( context.SimulateBadFps ) + { + device->sleep(500); // 2 fps + } + else + { + device->sleep(10); + } + } + + device->drop(); + + return 0; +} + +/* +**/ diff --git a/examples/24.CursorControl/tutorial.html b/examples/24.CursorControl/tutorial.html new file mode 100644 index 0000000..08e8b18 --- /dev/null +++ b/examples/24.CursorControl/tutorial.html @@ -0,0 +1,205 @@ + + + + + + + +Tutorial 24: CursorControl + + + + +
+ + + +
+
+
+
Tutorial 24: CursorControl
+
+
+
+024shot.jpg +
+

Show how to modify cursors and offer some useful tool-functions for creating cursors. It can also be used for experiments with the mouse in general.

#include <irrlicht.h>
#include "driverChoice.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
const int DELAY_TIME = 3000;
enum ETimerAction
{
ETA_MOUSE_VISIBLE,
ETA_MOUSE_INVISIBLE,
};

Structure to allow delayed execution of some actions.

struct TimerAction
{
u32 TargetTime;
ETimerAction Action;
};
struct SAppContext
{
SAppContext()
: Device(0), InfoStatic(0), EventBox(0), CursorBox(0), SpriteBox(0)
, ButtonSetVisible(0), ButtonSetInvisible(0), ButtonSimulateBadFps(0)
, ButtonChangeIcon(0)
, SimulateBadFps(false)
{
}
void update()
{
if (!Device)
return;
u32 timeNow = Device->getTimer()->getTime();
for ( u32 i=0; i < TimerActions.size(); ++i )
{
if ( timeNow >= TimerActions[i].TargetTime )
{
runTimerAction(TimerActions[i]);
TimerActions.erase(i);
}
else
{
++i;
}
}
}
void runTimerAction(const TimerAction& action)
{
if (ETA_MOUSE_VISIBLE == action.Action)
{
Device->getCursorControl()->setVisible(true);
ButtonSetVisible->setEnabled(true);
}
else if ( ETA_MOUSE_INVISIBLE == action.Action)
{
Device->getCursorControl()->setVisible(false);
ButtonSetInvisible->setEnabled(true);
}
}

Add another icon which the user can click and select as cursor later on.

void addIcon(const stringw& name, const SCursorSprite &sprite, bool addCursor=true)
{
// Sprites are just icons - not yet cursors. They can be displayed by Irrlicht sprite functions and be used to create cursors.
SpriteBox->addItem(name.c_str(), sprite.SpriteId);
Sprites.push_back(sprite);
// create the cursor together with the icon?
if ( addCursor )
{

Here we create a hardware cursor from a sprite

Device->getCursorControl()->addIcon(sprite);
// ... and add it to the cursors selection listbox to the other system cursors.
CursorBox->addItem(name.c_str());
}
}
IrrlichtDevice * Device;
gui::IGUIStaticText * InfoStatic;
gui::IGUIListBox * EventBox;
gui::IGUIListBox * CursorBox;
gui::IGUIListBox * SpriteBox;
gui::IGUIButton * ButtonSetVisible;
gui::IGUIButton * ButtonSetInvisible;
gui::IGUIButton * ButtonSimulateBadFps;
gui::IGUIButton * ButtonChangeIcon;
array<TimerAction> TimerActions;
bool SimulateBadFps;
array<SCursorSprite> Sprites;
};

Helper function to print mouse event names into a stringw

void PrintMouseEventName(const SEvent& event, stringw &result)
{
switch ( event.MouseInput.Event )
{
case EMIE_LMOUSE_PRESSED_DOWN: result += stringw(L"EMIE_LMOUSE_PRESSED_DOWN"); break;
case EMIE_RMOUSE_PRESSED_DOWN: result += stringw(L"EMIE_RMOUSE_PRESSED_DOWN"); break;
case EMIE_MMOUSE_PRESSED_DOWN: result += stringw(L"EMIE_MMOUSE_PRESSED_DOWN"); break;
case EMIE_LMOUSE_LEFT_UP: result += stringw(L"EMIE_LMOUSE_LEFT_UP"); break;
case EMIE_RMOUSE_LEFT_UP: result += stringw(L"EMIE_RMOUSE_LEFT_UP"); break;
case EMIE_MMOUSE_LEFT_UP: result += stringw(L"EMIE_MMOUSE_LEFT_UP"); break;
case EMIE_MOUSE_MOVED: result += stringw(L"EMIE_MOUSE_MOVED"); break;
case EMIE_MOUSE_WHEEL: result += stringw(L"EMIE_MOUSE_WHEEL"); break;
case EMIE_LMOUSE_DOUBLE_CLICK: result += stringw(L"EMIE_LMOUSE_DOUBLE_CLICK"); break;
case EMIE_RMOUSE_DOUBLE_CLICK: result += stringw(L"EMIE_RMOUSE_DOUBLE_CLICK"); break;
case EMIE_MMOUSE_DOUBLE_CLICK: result += stringw(L"EMIE_MMOUSE_DOUBLE_CLICK"); break;
case EMIE_LMOUSE_TRIPLE_CLICK: result += stringw(L"EMIE_LMOUSE_TRIPLE_CLICK"); break;
case EMIE_RMOUSE_TRIPLE_CLICK: result += stringw(L"EMIE_RMOUSE_TRIPLE_CLICK"); break;
case EMIE_MMOUSE_TRIPLE_CLICK: result += stringw(L"EMIE_MMOUSE_TRIPLE_CLICK"); break;
default:
break;
}
}

Helper function to print all the state information which get from a mouse-event into a stringw

void PrintMouseState(const SEvent& event, stringw &result)
{
result += stringw(L"X: ");
result += stringw(event.MouseInput.X);
result += stringw(L"\n");
result += stringw(L"Y: ");
result += stringw(event.MouseInput.Y);
result += stringw(L"\n");
result += stringw(L"Wheel: ");
result += stringw(event.MouseInput.Wheel);
result += stringw(L"\n");
result += stringw(L"Shift: ");
if ( event.MouseInput.Shift )
result += stringw(L"true\n");
else
result += stringw(L"false\n");
result += stringw(L"Control: ");
if ( event.MouseInput.Control )
result += stringw(L"true\n");
else
result += stringw(L"false\n");
result += stringw(L"ButtonStates: ");
result += stringw(event.MouseInput.ButtonStates);
result += stringw(L"\n");
result += stringw(L"isLeftPressed: ");
if ( event.MouseInput.isLeftPressed() )
result += stringw(L"true\n");
else
result += stringw(L"false\n");
result += stringw(L"isRightPressed: ");
if ( event.MouseInput.isRightPressed() )
result += stringw(L"true\n");
else
result += stringw(L"false\n");
result += stringw(L"isMiddlePressed: ");
if ( event.MouseInput.isMiddlePressed() )
result += stringw(L"true\n");
else
result += stringw(L"false\n");
result += stringw(L"Event: ");
PrintMouseEventName(event, result);
result += stringw(L"\n");
}

A typical event receiver.

class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(SAppContext & context) : Context(context) { }
virtual bool OnEvent(const SEvent& event)
{
if (event.EventType == EET_GUI_EVENT )
{
switch ( event.GUIEvent.EventType )
{
case EGET_BUTTON_CLICKED:
{
u32 timeNow = Context.Device->getTimer()->getTime();
TimerAction action;
action.TargetTime = timeNow + DELAY_TIME;
if ( event.GUIEvent.Caller == Context.ButtonSetVisible )
{
action.Action = ETA_MOUSE_VISIBLE;
Context.TimerActions.push_back(action);
Context.ButtonSetVisible->setEnabled(false);
}
else if ( event.GUIEvent.Caller == Context.ButtonSetInvisible )
{
action.Action = ETA_MOUSE_INVISIBLE;
Context.TimerActions.push_back(action);
Context.ButtonSetInvisible->setEnabled(false);
}
else if ( event.GUIEvent.Caller == Context.ButtonSimulateBadFps )
{
Context.SimulateBadFps = Context.ButtonSimulateBadFps->isPressed();
}
else if ( event.GUIEvent.Caller == Context.ButtonChangeIcon )
{

Replace an existing cursor icon by another icon. The user has to select both - the icon which should be replaced and the icon which will replace it.

s32 selectedCursor = Context.CursorBox->getSelected();
s32 selectedSprite = Context.SpriteBox->getSelected();
if ( selectedCursor >= 0 && selectedSprite >= 0 )
{

This does replace the icon.

Context.Device->getCursorControl()->changeIcon((ECURSOR_ICON)selectedCursor, Context.Sprites[selectedSprite] );

Do also show the new icon.

Context.Device->getCursorControl()->setActiveIcon( ECURSOR_ICON(selectedCursor) );
}
}
}
break;
case EGET_LISTBOX_CHANGED:
case EGET_LISTBOX_SELECTED_AGAIN:
{
if ( event.GUIEvent.Caller == Context.CursorBox )
{

Find out which cursor the user selected

s32 selected = Context.CursorBox->getSelected();
if ( selected >= 0 )
{

Here we set the new cursor icon which will now be used within our window.

Context.Device->getCursorControl()->setActiveIcon( ECURSOR_ICON(selected) );
}
}
}
break;
default:
break;
}
}
if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
stringw infoText;
PrintMouseState(event, infoText);
Context.InfoStatic->setText(infoText.c_str());
if ( event.MouseInput.Event != EMIE_MOUSE_MOVED && event.MouseInput.Event != EMIE_MOUSE_WHEEL ) // no spam
{
infoText = L"";
PrintMouseEventName(event, infoText);
Context.EventBox->insertItem(0, infoText.c_str(), -1);
}
}
return false;
}
private:
SAppContext & Context;
};

Use several imagefiles as animation frames for a sprite which can be used as cursor icon. The images in those files all need to have the same size. Return sprite index on success or -1 on failure

s32 AddAnimatedIconToSpriteBank( gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, const array< io::path >& files, u32 frameTime )
{
if ( !spriteBank || !driver || !files.size() )
return -1;
video::ITexture * tex = driver->getTexture( files[0] );
if ( tex )
{
array< rect<s32> >& spritePositions = spriteBank->getPositions();
u32 idxRect = spritePositions.size();
spritePositions.push_back( rect<s32>(0,0, tex->getSize().Width, tex->getSize().Height) );
SGUISprite sprite;
sprite.frameTime = frameTime;
array< SGUISprite >& sprites = spriteBank->getSprites();
u32 startIdx = spriteBank->getTextureCount();
for ( u32 f=0; f < files.size(); ++f )
{
tex = driver->getTexture( files[f] );
if ( tex )
{
spriteBank->addTexture( driver->getTexture(files[f]) );
gui::SGUISpriteFrame frame;
frame.rectNumber = idxRect;
frame.textureNumber = startIdx+f;
sprite.Frames.push_back( frame );
}
}
sprites.push_back( sprite );
return sprites.size()-1;
}
return -1;
}

Use several images within one imagefile as animation frames for a sprite which can be used as cursor icon The sizes of the icons within that file all need to have the same size Return sprite index on success or -1 on failure

s32 AddAnimatedIconToSpriteBank( gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, const io::path& file, const array< rect<s32> >& rects, u32 frameTime )
{
if ( !spriteBank || !driver || !rects.size() )
return -1;
video::ITexture * tex = driver->getTexture( file );
if ( tex )
{
array< rect<s32> >& spritePositions = spriteBank->getPositions();
u32 idxRect = spritePositions.size();
u32 idxTex = spriteBank->getTextureCount();
spriteBank->addTexture( tex );
SGUISprite sprite;
sprite.frameTime = frameTime;
array< SGUISprite >& sprites = spriteBank->getSprites();
for ( u32 i=0; i < rects.size(); ++i )
{
spritePositions.push_back( rects[i] );
gui::SGUISpriteFrame frame;
frame.rectNumber = idxRect+i;
frame.textureNumber = idxTex;
sprite.Frames.push_back( frame );
}
sprites.push_back( sprite );
return sprites.size()-1;
}
return -1;
}

Create a non-animated icon from the given file and position and put it into the spritebank. We can use this icon later on in a cursor.

s32 AddIconToSpriteBank( gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, const io::path& file, const core::rect<s32>& rect )
{
if ( !spriteBank || !driver )
return -1;
video::ITexture * tex = driver->getTexture( file );
if ( tex )
{
core::array< core::rect<irr::s32> >& spritePositions = spriteBank->getPositions();
spritePositions.push_back( rect );
array< SGUISprite >& sprites = spriteBank->getSprites();
spriteBank->addTexture( tex );
gui::SGUISpriteFrame frame;
frame.rectNumber = spritePositions.size()-1;
frame.textureNumber = spriteBank->getTextureCount()-1;
SGUISprite sprite;
sprite.frameTime = 0;
sprite.Frames.push_back( frame );
sprites.push_back( sprite );
return sprites.size()-1;
}
return -1;
}
int main()
{
video::E_DRIVER_TYPE driverType = driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
IrrlichtDevice * device = createDevice(driverType, dimension2d<u32>(640, 480));
if (device == 0)
return 1; // could not create selected driver.
// It's sometimes of interest to know how the mouse behaves after a resize
device->setResizable(true);
device->setWindowCaption(L"Cursor control - Irrlicht engine tutorial");
video::IVideoDriver* driver = device->getVideoDriver();
IGUIEnvironment* env = device->getGUIEnvironment();
gui::IGUISpriteBank * SpriteBankIcons;
SAppContext context;
context.Device = device;
rect< s32 > rectInfoStatic(10,10, 200, 200);
env->addStaticText (L"Cursor state information", rectInfoStatic, true, true);
rectInfoStatic.UpperLeftCorner += dimension2di(0, 15);
context.InfoStatic = env->addStaticText (L"", rectInfoStatic, true, true);
rect< s32 > rectEventBox(10,210, 200, 400);
env->addStaticText (L"click events (new on top)", rectEventBox, true, true);
rectEventBox.UpperLeftCorner += dimension2di(0, 15);
context.EventBox = env->addListBox(rectEventBox);
rect< s32 > rectCursorBox(210,10, 400, 250);
env->addStaticText (L"cursors, click to set the active one", rectCursorBox, true, true);
rectCursorBox.UpperLeftCorner += dimension2di(0, 15);
context.CursorBox = env->addListBox(rectCursorBox);
rect< s32 > rectSpriteBox(210,260, 400, 400);
env->addStaticText (L"sprites", rectSpriteBox, true, true);
rectSpriteBox.UpperLeftCorner += dimension2di(0, 15);
context.SpriteBox = env->addListBox(rectSpriteBox);
context.ButtonSetVisible = env->addButton( rect<s32>( 410, 20, 560, 40 ), 0, -1, L"set visible (delayed)" );
context.ButtonSetInvisible = env->addButton( rect<s32>( 410, 50, 560, 70 ), 0, -1, L"set invisible (delayed)" );
context.ButtonSimulateBadFps = env->addButton( rect<s32>( 410, 80, 560, 100 ), 0, -1, L"simulate bad FPS" );
context.ButtonSimulateBadFps->setIsPushButton(true);
context.ButtonChangeIcon = env->addButton( rect<s32>( 410, 140, 560, 160 ), 0, -1, L"replace cursor icon\n(cursor+sprite must be selected)" );
// set the names for all the system cursors
for ( int i=0; i < (int)gui::ECI_COUNT; ++i )
{
context.CursorBox->addItem(stringw( GUICursorIconNames[i] ).c_str());
}

Create sprites which then can be used as cursor icons.

SpriteBankIcons = env->addEmptySpriteBank(io::path("cursor_icons"));
context.SpriteBox->setSpriteBank(SpriteBankIcons);
// create one animated icon from several files
array< io::path > files;
files.push_back( io::path("../../media/icon_crosshairs16x16bw1.png") );
files.push_back( io::path("../../media/icon_crosshairs16x16bw2.png") );
files.push_back( io::path("../../media/icon_crosshairs16x16bw3.png") );
files.push_back( io::path("../../media/icon_crosshairs16x16bw3.png") );
files.push_back( io::path("../../media/icon_crosshairs16x16bw2.png") );
SCursorSprite spriteBw; // the sprite + some additional information needed for cursors
spriteBw.SpriteId = AddAnimatedIconToSpriteBank( SpriteBankIcons, driver, files, 200 );
spriteBw.SpriteBank = SpriteBankIcons;
spriteBw.HotSpot = position2d<s32>(7,7);
context.addIcon(L"crosshair_bw", spriteBw);
// create one animated icon from one file
array< rect<s32> > iconRects;
iconRects.push_back( rect<s32>(0,0, 16, 16) );
iconRects.push_back( rect<s32>(16,0, 32, 16) );
iconRects.push_back( rect<s32>(0,16, 16, 32) );
iconRects.push_back( rect<s32>(0,16, 16, 32) );
iconRects.push_back( rect<s32>(16,0, 32, 16) );
SCursorSprite spriteCol; // the sprite + some additional information needed for cursors
spriteCol.SpriteId = AddAnimatedIconToSpriteBank( SpriteBankIcons, driver, io::path("../../media/icon_crosshairs16x16col.png"), iconRects, 200 );
spriteCol.HotSpot = position2d<s32>(7,7);
spriteCol.SpriteBank = SpriteBankIcons;
context.addIcon(L"crosshair_colored", spriteCol);
// Create some non-animated icons
rect<s32> rectIcon;
SCursorSprite spriteNonAnimated(SpriteBankIcons, 0, position2d<s32>(7,7));
rectIcon = rect<s32>(0,0, 16, 16);
spriteNonAnimated.SpriteId = AddIconToSpriteBank( SpriteBankIcons, driver, io::path("../../media/icon_crosshairs16x16col.png"), rectIcon );
context.addIcon(L"crosshair_col1", spriteNonAnimated, false);
rectIcon = rect<s32>(16,0, 32, 16);
spriteNonAnimated.SpriteId = AddIconToSpriteBank( SpriteBankIcons, driver, io::path("../../media/icon_crosshairs16x16col.png"), rectIcon );
context.addIcon(L"crosshair_col2", spriteNonAnimated, false);
rectIcon = rect<s32>(0,16, 16, 32);
spriteNonAnimated.SpriteId = AddIconToSpriteBank( SpriteBankIcons, driver, io::path("../../media/icon_crosshairs16x16col.png"), rectIcon );
context.addIcon(L"crosshair_col3", spriteNonAnimated, false);
MyEventReceiver receiver(context);
device->setEventReceiver(&receiver);
while(device->run() && driver)
{
// if (device->isWindowActive())
{
u32 realTimeNow = device->getTimer()->getRealTime();
context.update();
driver->beginScene(true, true, SColor(0,200,200,200));
env->drawAll();
// draw custom sprite with Irrlicht functions for comparison. It should usually look the same as the cursors.
if ( context.SpriteBox )
{
s32 selectedSprite = context.SpriteBox->getSelected();
if ( selectedSprite >= 0 && context.Sprites[selectedSprite].SpriteId >= 0 )
{
SpriteBankIcons->draw2DSprite(u32(context.Sprites[selectedSprite].SpriteId), position2di(580, 140), 0, video::SColor(255, 255, 255, 255), 0, realTimeNow);
}
}
driver->endScene();
}
// By simulating bad fps we can find out if hardware-support for cursors works or not. If it works the cursor will move as usual,while it otherwise will just update with 2 fps now.
if ( context.SimulateBadFps )
{
device->sleep(500); // 2 fps
}
else
{
device->sleep(10);
}
}
device->drop();
return 0;
}
+ + +

 

+ + -- cgit v1.2.3-70-g09d2