From 4bbe8ab576ad1850fbb1f047a3d0c4a676ef7c64 Mon Sep 17 00:00:00 2001 From: nglade Date: Mon, 25 Apr 2022 22:22:29 +0200 Subject: [PATCH] Added support for SFML 2.5 event handler + example --- ChangeLog.txt | 6 +- Examples/CMakeLists.txt | 13 ++ Examples/TwSimpleSFML25.cpp | 248 ++++++++++++++++++++++ TweakBar/CMakeLists.txt | 6 + TweakBar/compile/MiniSFML25.h | 330 +++++++++++++++++++++++++++++ TweakBar/compile/TwEventSFML25.cpp | 172 +++++++++++++++ TweakBar/include/AntTweakBar.h | 1 + 7 files changed, 775 insertions(+), 1 deletion(-) create mode 100644 Examples/TwSimpleSFML25.cpp create mode 100644 TweakBar/compile/MiniSFML25.h create mode 100644 TweakBar/compile/TwEventSFML25.cpp diff --git a/ChangeLog.txt b/ChangeLog.txt index a8a3216..2fefe31 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,6 +1,10 @@ --- AntTweakBar library change log --- -* Latest (https://github.com/tschw/AntTweakBar) +* Latest (https://github.com/nglade-gh/AntTweakBar) + - Added support for SFML 2.5 event handlers + - Added example for SFML 2.5 (TwSimpleSFML25.cpp) + +* Version from https://github.com/tschw/AntTweakBar - Added top-level namespace for internal symbols for happy static linking - Switched to CMake-based build system adding lots of customizability diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index 96d953e..db70759 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -121,3 +121,16 @@ if (ATB_GUIRENDERER_USE_LEGACY_GL AND ATB_EVENT_HANDLER_GLUT) endif() +#------------------------------------------------------------------------------ +# SFML 2.5 + +if (ATB_EVENT_HANDLER_SFML25) + + find_package(SFML CONFIG) + + if (SFML_FOUND) + add_ogl_example(TwSimpleSFML25.cpp SFML) + endif() + +endif() + diff --git a/Examples/TwSimpleSFML25.cpp b/Examples/TwSimpleSFML25.cpp new file mode 100644 index 0000000..6d732f3 --- /dev/null +++ b/Examples/TwSimpleSFML25.cpp @@ -0,0 +1,248 @@ +// --------------------------------------------------------------------------- +// +// @file TwSimpleSFML.cpp +// @brief A simple example that uses AntTweakBar with OpenGL and SFML. +// This example draws moving cubic particles with some +// interactive control on particles generation. +// +// AntTweakBar: http://anttweakbar.sourceforge.net/doc +// OpenGL: http://www.opengl.org +// SFML2.5: http://www.sfml-dev.org +// +// @author Philippe Decaudin +// @author Nicolas Glade +// +// --------------------------------------------------------------------------- +#include + +#if defined(_WIN32) +#include // required by gl.h +#endif + +#include +#include + +#include +#include +#include +#include + +#include + + + +// Pseudo-random value between -1 and 1 +float Random() { + return 2.0f * ((float)rand() / RAND_MAX) - 1.0f; + } + +// Particle randomly initialized +struct Particle { + float Size; + float Position[3]; // [px, py, pz] + float Speed[3]; // [vx, vy, vz] + float RotationAxis[3]; // [rx, ry, rz] + float RotationAngle; // in degree + float RotationSpeed; + float Color[3]; // [r, g, b] + float Age; + Particle(float size, float speedDir[3], float speedNorm, float color[3]) { // Constructor + Size = size * (1.0f + 0.2f * Random()); + Position[0] = Position[1] = Position[2] = 0; + Speed[0] = speedNorm * (speedDir[0] + 0.1f * Random()); + Speed[1] = speedNorm * (speedDir[1] + 0.1f * Random()); + Speed[2] = speedNorm * (speedDir[2] + 0.1f * Random()); + RotationAxis[0] = Random(); + RotationAxis[1] = Random(); + RotationAxis[2] = Random(); + RotationAngle = 360.0f * Random(); + RotationSpeed = 360.0f * Random(); + Color[0] = color[0] + 0.2f * Random(); + Color[1] = color[1] + 0.2f * Random(); + Color[2] = color[2] + 0.2f * Random(); + Age = 0; + } + void Update(float dt) { // Apply one animation step + Position[0] += dt * Speed[0]; + Position[1] += dt * Speed[1]; + Position[2] += dt * Speed[2]; + Speed[1] -= dt * 9.81f; // gravity + RotationAngle += dt * RotationSpeed; + Age += dt; + } + }; + + + +int main() { + // Create main window + sf::RenderWindow app(sf::VideoMode(800, 600), "AntTweakBar simple example using SFML"); + + // Particules + std::list particles; + std::list::iterator p; + float birthCount = 0; + float birthRate = 20; // number of particles generated per second + float maxAge = 3.0f; // particles life time + float speedDir[3] = {0, 1, 0}; // initial particles speed direction + float speedNorm = 7.0f; // initial particles speed amplitude + float size = 0.1f; // particles size + float color[3] = {0.8f, 0.6f, 0}; // particles color + float bgColor[3] = {0, 0.6f, 0.6f}; // background color + + // Initialize AntTweakBar + TwInit(TW_OPENGL, NULL); + + // Tell the window size to AntTweakBar + TwWindowSize(app.getSize().x, app.getSize().y); + + // Create a tweak bar + TwBar *bar = TwNewBar("Particles"); + TwDefine(" GLOBAL help='This example shows how to integrate AntTweakBar with SFML and OpenGL.' "); // Message added to the help bar. + + // Change bar position + int barPos[2] = {16, 240}; + TwSetParam(bar, NULL, "position", TW_PARAM_INT32, 2, &barPos); + + // Add 'birthRate' to 'bar': this is a modifiable variable of type TW_TYPE_FLOAT in range [0.1, 100]. Its shortcuts are [+] and [-]. + TwAddVarRW(bar, "Birth rate", TW_TYPE_FLOAT, &birthRate, " min=0.1 max=100 step=0.1 keyIncr='+' keyDecr='-' "); + + // Add 'speedNorm' to 'bar': this is a modifiable variable of type TW_TYPE_FLOAT in range [0.1, 10]. Its shortcuts are [s] and [S]. + TwAddVarRW(bar, "Speed", TW_TYPE_FLOAT, &speedNorm, " min=0.1 max=10 step=0.1 keyIncr='s' keyDecr='S' "); + + // Add 'speedDir' to 'bar': this is a modifiable variable of type TW_TYPE_DIR3F. Just displaying the arrow widget + TwAddVarRW(bar, "Direction", TW_TYPE_DIR3F, &speedDir, " opened=true showval=false "); + + // Add 'color' to 'bar': this is a modifiable variable of type TW_TYPE_COLOR3F. Switched to HLS + TwAddVarRW(bar, "Color", TW_TYPE_COLOR3F, &color, " colorMode=hls opened=true "); + + // Add 'bgColor' to 'bar': this is a modifiable variable of type TW_TYPE_COLOR3F. Switched to HLS + TwAddVarRW(bar, "Background color", TW_TYPE_COLOR3F, &bgColor, " colorMode=hls opened=true "); + + // Initialize OpenGL states + glEnable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.f, (float)app.getSize().x/app.getSize().y, 0.1f, 100.f); + glMatrixMode(GL_MODELVIEW); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_NORMALIZE); + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + + // Init time + sf::Clock clock; + float time = clock.getElapsedTime().asSeconds(); + + + // Main loop + while (app.isOpen()) { + // Process events + sf::Event event; + while (app.pollEvent(event)) { + int handled = TwEventSFML25(&event, 2, 5); + if (!handled) { + // Close window : exit + if (event.type == sf::Event::Closed || (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)) + app.close(); + + // Resize + if (event.type == sf::Event::Resized) { + glViewport(0, 0, event.size.width, event.size.height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.f, (float)event.size.width/event.size.height, 1.f, 500.f); + glMatrixMode(GL_MODELVIEW); + + // TwWindowSize has been called by TwEventSFML, + // so it is not necessary to call it again here. + } + } + } + + + if (!app.isOpen()) + continue; + + // Update time + float dt = clock.getElapsedTime().asSeconds() - time; + if (dt < 0) dt = 0; + time += dt; + + // Update particles + p = particles.begin(); + while (p != particles.end()) { + p->Update(dt); + if (p->Age >= maxAge) + p = particles.erase(p); // Die! + else + ++p; + } + + // Generate new particles + birthCount += dt * birthRate; + while (birthCount >= 1.0f) { + particles.push_back(Particle(size, speedDir, speedNorm, color)); + birthCount--; + } + + // Clear depth buffer + glClearColor(bgColor[0], bgColor[1], bgColor[2], 1); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + // Draw particles + for (p = particles.begin(); p != particles.end(); ++p) { + glColor4fv(p->Color); + glLoadIdentity(); + glTranslatef(0.0f, -1.0f, -3.0f); // Camera position + glTranslatef(p->Position[0], p->Position[1], p->Position[2]); + glScalef(p->Size, p->Size, p->Size); + glRotatef(p->RotationAngle, p->RotationAxis[0], p->RotationAxis[1], p->RotationAxis[2]); + + // Draw a cube + glBegin(GL_QUADS); + glNormal3f(0,0,-1); + glVertex3f(0,0,0); + glVertex3f(0,1,0); + glVertex3f(1,1,0); + glVertex3f(1,0,0); // front face + glNormal3f(0,0,+1); + glVertex3f(0,0,1); + glVertex3f(1,0,1); + glVertex3f(1,1,1); + glVertex3f(0,1,1); // back face + glNormal3f(-1,0,0); + glVertex3f(0,0,0); + glVertex3f(0,0,1); + glVertex3f(0,1,1); + glVertex3f(0,1,0); // left face + glNormal3f(+1,0,0); + glVertex3f(1,0,0); + glVertex3f(1,1,0); + glVertex3f(1,1,1); + glVertex3f(1,0,1); // right face + glNormal3f(0,-1,0); + glVertex3f(0,0,0); + glVertex3f(1,0,0); + glVertex3f(1,0,1); + glVertex3f(0,0,1); // bottom face + glNormal3f(0,+1,0); + glVertex3f(0,1,0); + glVertex3f(0,1,1); + glVertex3f(1,1,1); + glVertex3f(1,1,0); // top face + glEnd(); + } + + TwDraw(); + + // Finally, display the rendered frame on screen + app.display(); + } + + // Un-initialize AntTweakBar + TwTerminate(); + + return EXIT_SUCCESS; + } diff --git a/TweakBar/CMakeLists.txt b/TweakBar/CMakeLists.txt index d3e3508..5335a1e 100644 --- a/TweakBar/CMakeLists.txt +++ b/TweakBar/CMakeLists.txt @@ -40,6 +40,8 @@ set(ATB_EVENT_HANDLER_SDL20 ON CACHE BOOL set(ATB_EVENT_HANDLER_SFML ON CACHE BOOL "Provide an event handler interface for use with SFML") +set(ATB_EVENT_HANDLER_SFML25 ON CACHE BOOL + "Provide an event handler interface for use with SFML 2.5") ############################################################################### # Files @@ -82,6 +84,9 @@ set(sources "compile/MiniSFML16.h" "compile/TwEventSFML.cpp" + "compile/MiniSFML25.h" + "compile/TwEventSFML25.cpp" + "compile/TwEventWin.c" "compile/TwEventX11.c") @@ -147,6 +152,7 @@ append_unless(defs TW_NO_SDL12_EVENTS ATB_EVENT_HANDLER_SDL12) append_unless(defs TW_NO_SDL13_EVENTS ATB_EVENT_HANDLER_SDL13) append_unless(defs TW_NO_SDL20_EVENTS ATB_EVENT_HANDLER_SDL20) append_unless(defs TW_NO_SFML_EVENTS ATB_EVENT_HANDLER_SFML) +append_unless(defs TW_NO_SFML25_EVENTS ATB_EVENT_HANDLER_SFML25) target_compile_definitions(AntTweakBar ${defs}) diff --git a/TweakBar/compile/MiniSFML25.h b/TweakBar/compile/MiniSFML25.h new file mode 100644 index 0000000..6f76512 --- /dev/null +++ b/TweakBar/compile/MiniSFML25.h @@ -0,0 +1,330 @@ +// --------------------------------------------------------------------------- +// +// @file MiniSFML25.h +// @brief A subset of SFML 2.5 definitions needed to compile helper +// functions implemented in TwEventSFML25.cpp +// +// @author Nicolas Glade +// notes: - Private header +// - AntTweakBar.dll does not need to link with SFML, +// it just needs some definitions for its helper functions. +// - This header is provided to avoid the need of having SFML +// installed to recompile AntTweakBar. +// It declares a small and incomplete part of SFML classes. +// For instance, many non-virtual methods have been stripped out. +// - Do not use this header in your own programs, better use the +// SFML headers from the actual SFML library SDK : +// http://www.sfml-dev.org +// +// --------------------------------------------------------------------------- + +#if !defined MINI_SFML25_INCLUDED +#define MINI_SFML25_INCLUDED + +#include + +namespace sf { +// prototype window +class Window; +class String {}; +struct Vector2i; +struct Vector3f; +//#define SFML_WINDOW_API + + +// Keyboard -> SFML2.5 +class Keyboard { + public: + enum Key { + Unknown = -1, A = 0, B, C, + D, E, F, G, + H, I, J, K, + L, M, N, O, + P, Q, R, S, + T, U, V, W, + X, Y, Z, Num0, + Num1, Num2, Num3, Num4, + Num5, Num6, Num7, Num8, + Num9, Escape, LControl, LShift, + LAlt, LSystem, RControl, RShift, + RAlt, RSystem, Menu, LBracket, + RBracket, Semicolon, Comma, Period, + Quote, Slash, Backslash, Tilde, + Equal, Hyphen, Space, Enter, + Backspace, Tab, PageUp, PageDown, + End, Home, Insert, Delete, + Add, Subtract, Multiply, Divide, + Left, Right, Up, Down, + Numpad0, Numpad1, Numpad2, Numpad3, + Numpad4, Numpad5, Numpad6, Numpad7, + Numpad8, Numpad9, F1, F2, + F3, F4, F5, F6, + F7, F8, F9, F10, + F11, F12, F13, F14, + F15, Pause, KeyCount, Dash = Hyphen, + BackSpace = Backspace, BackSlash = Backslash, SemiColon = Semicolon, Return = Enter + }; // ends Key enum + + static bool isKeyPressed(Key key); + static void setVirtualKeyboardVisible(bool visible); + }; // ends Keyboard class + +// Mouse -> SFML2.5 +class Mouse { + public: + enum Button { Left, Right, Middle, XButton1, XButton2, Count }; + enum Wheel { VerticalWheel, HorizontalWheel }; + + static bool isButtonPressed(Button button); + static Vector2i getPosition(); + static Vector2i getPosition(const Window& relativeTo); + static void setPosition(const Vector2i& position); + static void setPosition(const Vector2i& position, const Window& relativeTo); + }; + +// Joystick -> SFML2.5 +class Joystick { + public: + enum { Count = 8, ButtonCount = 32, AxisCount = 8 }; + enum Axis { X, Y, Z, R, U, V, PovX, PovY }; + struct Identification { + Identification(); + String name; + unsigned int vendorId; + unsigned int productId; + }; + static bool isConnected(unsigned int joystick); + static unsigned int getButtonCount(unsigned int joystick); + static bool hasAxis(unsigned int joystick, Axis axis); + static bool isButtonPressed(unsigned int joystick, unsigned int button); + static float getAxisPosition(unsigned int joystick, Axis axis); + static Identification getIdentification(unsigned int joystick); + static void update(); + }; + +typedef unsigned char Uint8; +typedef unsigned int Uint32; + +// Sensor -> SFML2.5 +class Sensor { + public: + enum Type { Accelerometer, Gyroscope, Magnetometer, Gravity, UserAcceleration, Orientation, Count }; + static bool isAvailable(Type sensor); + static void setEnabled(Type sensor, bool enabled); + static Vector3f getValue(Type sensor); + }; + +// Event -> SFML2.5 +class Event { + public : + struct SizeEvent { + unsigned int width, height; + }; + struct KeyEvent { + Keyboard::Key code; + bool alt, control, shift, system; + }; + struct TextEvent { + Uint32 unicode; + }; + struct MouseMoveEvent { + int x, y; + }; + struct MouseButtonEvent { + Mouse::Button button; + int x, y; + }; + struct MouseWheelEvent { + int delta, x, y; + }; + struct MouseWheelScrollEvent { + Mouse::Wheel wheel; + float delta; + int x,y; + }; + struct JoystickConnectEvent { + unsigned int joystickId; + }; + struct JoystickMoveEvent { + unsigned int joystickId; + Joystick::Axis axis; + float position; + }; + struct JoystickButtonEvent { + unsigned int joystickId, button; + }; + struct TouchEvent { + unsigned int finger; + int x, y; + }; + struct SensorEvent { + Sensor::Type type; + float x, y, z; + }; + + enum EventType { + Closed, Resized, LostFocus, GainedFocus, TextEntered, KeyPressed, KeyReleased, + MouseWheelMoved, MouseWheelScrolled, MouseButtonPressed, MouseButtonReleased, MouseMoved, MouseEntered, MouseLeft, JoystickButtonPressed, JoystickButtonReleased, JoystickMoved, JoystickConnected, JoystickDisconnected, TouchBegan, TouchMoved, TouchEnd, SensorChanged, Count + }; + + EventType type; + + union { + SizeEvent size; + KeyEvent key; + TextEvent text; + MouseMoveEvent mouseMove; + MouseButtonEvent mouseButton; + MouseWheelEvent mouseWheel; + MouseWheelScrollEvent mouseWheelScroll; + JoystickMoveEvent joystickMove; + JoystickButtonEvent joystickButton; + JoystickConnectEvent joystickConnect; + TouchEvent touch; + SensorEvent sensor; + }; + }; + +} // namespace sf + + +#ifdef USE_MINI_SFML +// we also need some the definition of sf::RenderWindow to compile our SFML example + + +#include + +namespace sf { + +class Input; +class Drawable; +typedef void* WindowHandle; +namespace priv { +class WindowImpl; +} + +class WindowListener { + public : + virtual void OnEvent(const Event& EventReceived) = 0; + protected : + virtual ~WindowListener(); + }; + +class VideoMode { + public : + VideoMode(unsigned int ModeWidth, unsigned int ModeHeight, unsigned int ModeBpp = 32); + unsigned int Width, Height, BitsPerPixel; + }; + +namespace Style { +enum { None = 0, Titlebar = 1 << 0, Resize = 1 << 1, Close = 1 << 2, Fullscreen = 1 << 3 }; +} + +struct WindowSettings { + explicit WindowSettings(unsigned int Depth = 24, unsigned int Stencil = 8, unsigned int Antialiasing = 0); + unsigned int DepthBits, StencilBits, AntialiasingLevel; + }; + +class Clock { + public : + Clock(); + float GetElapsedTime() const; + void Reset(); + private : + double myStartTime; + }; + +class Input : public WindowListener { + private : + virtual void OnEvent(const Event& EventReceived); + bool myKeys[Key::Count]; + bool myMouseButtons[Mouse::Count]; + int myMouseX; + int myMouseY; + bool myJoystickButtons[Joy::Count][Joy::ButtonCount]; + float myJoystickAxis[Joy::Count][Joy::AxisCount]; + }; + +class Window : public WindowListener { + public : + Window(VideoMode Mode, const std::string& Title, unsigned long WindowStyle = Style::Resize | Style::Close, const WindowSettings& Params = WindowSettings()); + virtual ~Window(); + void Close(); + bool IsOpened() const; + unsigned int GetWidth() const; + unsigned int GetHeight() const; + bool GetEvent(Event& EventReceived); + void Display(); + private : + virtual void OnCreate(); + virtual void OnEvent(const Event& EventReceived); + priv::WindowImpl* myWindow; + std::queue myEvents; + Input myInput; + Clock myClock; + WindowSettings mySettings; + float myLastFrameTime; + bool myIsExternal; + unsigned int myFramerateLimit; + int mySetCursorPosX; + int mySetCursorPosY; + }; + +template class Vector2 { + public : + T x, y; + }; +typedef Vector2 Vector2f; + +template class Rect { + public : + T Left, Top, Right, Bottom; + }; +typedef Rect FloatRect; + +class Matrix3 { + private : + float myData[16]; + }; + +class View { + private : + sf::Vector2f myCenter; + sf::Vector2f myHalfSize; + FloatRect myRect; + Matrix3 myMatrix; + bool myNeedUpdate; + }; + +class RenderTarget { + public : + virtual ~RenderTarget(); + virtual void Draw(const Drawable& Object); + virtual unsigned int GetWidth() const = 0; + virtual unsigned int GetHeight() const = 0; + void PreserveOpenGLStates(bool Preserve); + private : + virtual bool Activate(bool Active) = 0; + View myDefaultView; + const View* myCurrentView; + bool myPreserveStates; + bool myIsDrawing; + }; + +class RenderWindow : public Window, public RenderTarget { + public : + RenderWindow(VideoMode Mode, const std::string& Title, unsigned long WindowStyle = Style::Resize | Style::Close, const WindowSettings& Params = WindowSettings()); + virtual ~RenderWindow(); + virtual unsigned int GetWidth() const; + virtual unsigned int GetHeight() const; + private : + virtual void OnCreate(); + virtual bool Activate(bool Active); + }; + +} // namespace sf + +#endif // USE_MINI_SFML + +#endif // !defined MINI_SFML16_INCLUDED + diff --git a/TweakBar/compile/TwEventSFML25.cpp b/TweakBar/compile/TwEventSFML25.cpp new file mode 100644 index 0000000..57a96d1 --- /dev/null +++ b/TweakBar/compile/TwEventSFML25.cpp @@ -0,0 +1,172 @@ +// --------------------------------------------------------------------------- +// +// @file TwEventSFML.cpp +// @brief Helper: +// translate and re-send mouse and keyboard events +// from SFML 2.5 event loop to AntTweakBar +// +// @author Nicolas Glade +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + +#if !defined TW_NO_SFML_EVENTS + +#include "MiniSFML25.h" // a subset of SFML 2.5 headers needed to compile TwEventSFML.cpp +// note: AntTweakBar.dll does not need to link with SFML, +// it just needs some definitions for its helper functions. + +#include + + +// TwEventSFML returns zero if msg has not been handled, +// and a non-zero value if it has been handled by the AntTweakBar library. +int TW_CALL TwEventSFML25(const void *sfmlEvent, unsigned char majorVersion, unsigned char minorVersion) { + // Assume version 2.5 + /* + if (majorVersion > 1 || (majorVersion == 1 && minorVersion > 6) + { + static const char *g_ErrBadSFMLVersion = "Unsupported SFML version"; + TwSetLastError(g_ErrBadSFMLVersion); + return 0; + } + */ + (void)majorVersion, (void)minorVersion; + + int handled = 0; + const sf::Event *event = (const sf::Event *)sfmlEvent; + TwMouseAction mouseAction; + int key = 0; + static int s_KMod = 0; + static bool s_PreventTextHandling = false; + static int s_WheelPos = 0; + + if (event == NULL) + return 0; + + switch (event->type) { + + case sf::Event::KeyPressed: + s_PreventTextHandling = false; + s_KMod = 0; + if (event->key.shift) s_KMod |= TW_KMOD_SHIFT; + if (event->key.alt) s_KMod |= TW_KMOD_ALT; + if (event->key.control) s_KMod |= TW_KMOD_CTRL; + key = 0; + switch (event->key.code) { + case sf::Keyboard::Escape: + key = TW_KEY_ESCAPE; + break; + case sf::Keyboard::Return: + key = TW_KEY_RETURN; + break; + case sf::Keyboard::Tab: + key = TW_KEY_TAB; + break; + case sf::Keyboard::BackSpace: + key = TW_KEY_BACKSPACE; + break; + case sf::Keyboard::PageUp: + key = TW_KEY_PAGE_UP; + break; + case sf::Keyboard::PageDown: + key = TW_KEY_PAGE_DOWN; + break; + case sf::Keyboard::Up: + key = TW_KEY_UP; + break; + case sf::Keyboard::Down: + key = TW_KEY_DOWN; + break; + case sf::Keyboard::Left: + key = TW_KEY_LEFT; + break; + case sf::Keyboard::Right: + key = TW_KEY_RIGHT; + break; + case sf::Keyboard::End: + key = TW_KEY_END; + break; + case sf::Keyboard::Home: + key = TW_KEY_HOME; + break; + case sf::Keyboard::Insert: + key = TW_KEY_INSERT; + break; + case sf::Keyboard::Delete: + key = TW_KEY_DELETE; + break; + case sf::Keyboard::Space: + key = TW_KEY_SPACE; + break; + default: + if (event->key.code >= sf::Keyboard::F1 && event->key.code <= sf::Keyboard::F15) + key = TW_KEY_F1 + event->key.code - sf::Keyboard::F1; + else if (s_KMod & TW_KMOD_ALT) { + if (event->key.code >= sf::Keyboard::A && event->key.code <= sf::Keyboard::Z) { + if (s_KMod & TW_KMOD_SHIFT) + key = 'A' + event->key.code - sf::Keyboard::A; + else + key = 'a' + event->key.code - sf::Keyboard::A; + } + } + } + if (key != 0) { + handled = TwKeyPressed(key, s_KMod); + s_PreventTextHandling = true; + } + break; + case sf::Event::KeyReleased: + s_PreventTextHandling = false; + s_KMod = 0; + break; + case sf::Event::TextEntered: + if (!s_PreventTextHandling && event->text.unicode != 0 && (event->text.unicode & 0xFF00) == 0) { + if ((event->text.unicode & 0xFF) < 32) // CTRL+letter + handled = TwKeyPressed((event->text.unicode & 0xFF)+'a'-1, TW_KMOD_CTRL|s_KMod); + else + handled = TwKeyPressed(event->text.unicode & 0xFF, 0); + } + s_PreventTextHandling = false; + break; + case sf::Event::TouchMoved: + handled = TwMouseMotion(event->touch.x, event->touch.y); + break; + case sf::Event::MouseMoved: + handled = TwMouseMotion(event->mouseMove.x, event->mouseMove.y); + break; + case sf::Event::MouseButtonPressed: + case sf::Event::MouseButtonReleased: + mouseAction = (event->type==sf::Event::MouseButtonPressed) ? TW_MOUSE_PRESSED : TW_MOUSE_RELEASED; + switch (event->mouseButton.button) { + case sf::Mouse::Left: + handled = TwMouseButton(mouseAction, TW_MOUSE_LEFT); + break; + case sf::Mouse::Middle: + handled = TwMouseButton(mouseAction, TW_MOUSE_MIDDLE); + break; + case sf::Mouse::Right: + handled = TwMouseButton(mouseAction, TW_MOUSE_RIGHT); + break; + default: + break; + } + break; + case sf::Event::MouseWheelMoved: + s_WheelPos += event->mouseWheel.delta; + handled = TwMouseWheel(s_WheelPos); + break; + case sf::Event::Resized: + // tell the new size to TweakBar + TwWindowSize(event->size.width, event->size.height); + // do not set 'handled', sf::Event::Resized may be also processed by the client application + break; + default: + break; + } + + return handled; + } + +#endif // !defined TW_NO_SFML_EVENTS diff --git a/TweakBar/include/AntTweakBar.h b/TweakBar/include/AntTweakBar.h index b60c8bf..efac38c 100644 --- a/TweakBar/include/AntTweakBar.h +++ b/TweakBar/include/AntTweakBar.h @@ -364,6 +364,7 @@ typedef void (TW_GLUT_CALL *GLUTspecialfun)(int glutKey, int mouseX, int mouseY) // For SFML event loop TW_API int TW_CALL TwEventSFML(const void *sfmlEvent, unsigned char sfmlMajorVersion, unsigned char sfmlMinorVersion); +TW_API int TW_CALL TwEventSFML25(const void *sfmlEvent, unsigned char sfmlMajorVersion, unsigned char sfmlMinorVersion); // For X11 event loop #if defined(_UNIX)