commit
5a3077a3ad
|
|
@ -23,6 +23,7 @@ TOOL.Files = {
|
||||||
TOOL.FilesExcluded = {
|
TOOL.FilesExcluded = {
|
||||||
"../tests/Engine/Audio/**",
|
"../tests/Engine/Audio/**",
|
||||||
"../tests/Engine/Graphics/**",
|
"../tests/Engine/Graphics/**",
|
||||||
|
"../tests/Engine/Utility/**",
|
||||||
"../tests/SDK/NDK/Application.cpp",
|
"../tests/SDK/NDK/Application.cpp",
|
||||||
"../tests/SDK/NDK/Systems/ListenerSystem.cpp",
|
"../tests/SDK/NDK/Systems/ListenerSystem.cpp",
|
||||||
"../tests/SDK/NDK/Systems/RenderSystem.cpp"
|
"../tests/SDK/NDK/Systems/RenderSystem.cpp"
|
||||||
|
|
|
||||||
|
|
@ -768,19 +768,79 @@ namespace Nz
|
||||||
if (!keysyms)
|
if (!keysyms)
|
||||||
{
|
{
|
||||||
NazaraError("Failed to get key symbols");
|
NazaraError("Failed to get key symbols");
|
||||||
return XCB_NONE;
|
return XCB_NO_SYMBOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int col = state & XCB_MOD_MASK_SHIFT ? 1 : 0;
|
xcb_keysym_t k0, k1;
|
||||||
const int altGrOffset = 4;
|
|
||||||
if (state & XCB_MOD_MASK_5)
|
|
||||||
col += altGrOffset;
|
|
||||||
xcb_keysym_t keysym = xcb_key_symbols_get_keysym(keysyms, keycode, col);
|
|
||||||
if (keysym == XCB_NO_SYMBOL)
|
|
||||||
keysym = xcb_key_symbols_get_keysym(keysyms, keycode, col ^ 0x1);
|
|
||||||
X11::XCBKeySymbolsFree(keysyms);
|
|
||||||
|
|
||||||
return keysym;
|
CallOnExit onExit([&](){
|
||||||
|
X11::XCBKeySymbolsFree(keysyms);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Based on documentation in https://cgit.freedesktop.org/xcb/util-keysyms/tree/keysyms/keysyms.c
|
||||||
|
// Mode switch = ctlr and alt gr = XCB_MOD_MASK_5
|
||||||
|
|
||||||
|
// The first four elements of the list are split into two groups of KeySyms.
|
||||||
|
if (state & XCB_MOD_MASK_1)
|
||||||
|
{
|
||||||
|
k0 = xcb_key_symbols_get_keysym(keysyms, keycode, 2);
|
||||||
|
k1 = xcb_key_symbols_get_keysym(keysyms, keycode, 3);
|
||||||
|
}
|
||||||
|
if (state & XCB_MOD_MASK_5)
|
||||||
|
{
|
||||||
|
k0 = xcb_key_symbols_get_keysym(keysyms, keycode, 4);
|
||||||
|
k1 = xcb_key_symbols_get_keysym(keysyms, keycode, 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
k0 = xcb_key_symbols_get_keysym(keysyms, keycode, 0);
|
||||||
|
k1 = xcb_key_symbols_get_keysym(keysyms, keycode, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the second element of the group is NoSymbol, then the group should be treated as if the second element were the same as the first element.
|
||||||
|
if (k1 == XCB_NO_SYMBOL)
|
||||||
|
k1 = k0;
|
||||||
|
|
||||||
|
/* The numlock modifier is on and the second KeySym is a keypad KeySym
|
||||||
|
The numlock modifier is on and the second KeySym is a keypad KeySym. In
|
||||||
|
this case, if the Shift modifier is on, or if the Lock modifier is on
|
||||||
|
and is interpreted as ShiftLock, then the first KeySym is used,
|
||||||
|
otherwise the second KeySym is used.
|
||||||
|
*/
|
||||||
|
if ((state & XCB_MOD_MASK_2) && xcb_is_keypad_key(k1))
|
||||||
|
{
|
||||||
|
if ((state & XCB_MOD_MASK_SHIFT) || (state & XCB_MOD_MASK_LOCK && (state & XCB_MOD_MASK_SHIFT)))
|
||||||
|
return k0;
|
||||||
|
else
|
||||||
|
return k1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The Shift and Lock modifiers are both off. In this case, the first
|
||||||
|
KeySym is used.*/
|
||||||
|
else if (!(state & XCB_MOD_MASK_SHIFT) && !(state & XCB_MOD_MASK_LOCK))
|
||||||
|
return k0;
|
||||||
|
|
||||||
|
/* The Shift modifier is off, and the Lock modifier is on and is
|
||||||
|
interpreted as CapsLock. In this case, the first KeySym is used, but
|
||||||
|
if that KeySym is lowercase alphabetic, then the corresponding
|
||||||
|
uppercase KeySym is used instead. */
|
||||||
|
else if (!(state & XCB_MOD_MASK_SHIFT) && (state & XCB_MOD_MASK_LOCK && (state & XCB_MOD_MASK_SHIFT)))
|
||||||
|
return k0;
|
||||||
|
|
||||||
|
/* The Shift modifier is on, and the Lock modifier is on and is
|
||||||
|
interpreted as CapsLock. In this case, the second KeySym is used, but
|
||||||
|
if that KeySym is lowercase alphabetic, then the corresponding
|
||||||
|
uppercase KeySym is used instead.*/
|
||||||
|
else if ((state & XCB_MOD_MASK_SHIFT) && (state & XCB_MOD_MASK_LOCK && (state & XCB_MOD_MASK_SHIFT)))
|
||||||
|
return k1;
|
||||||
|
|
||||||
|
/* The Shift modifier is on, or the Lock modifier is on and is
|
||||||
|
interpreted as ShiftLock, or both. In this case, the second KeySym is
|
||||||
|
used. */
|
||||||
|
else if ((state & XCB_MOD_MASK_SHIFT) || (state & XCB_MOD_MASK_LOCK && (state & XCB_MOD_MASK_SHIFT)))
|
||||||
|
return k1;
|
||||||
|
|
||||||
|
return XCB_NO_SYMBOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Keyboard::Key WindowImpl::ConvertVirtualKey(xcb_keysym_t symbol)
|
Keyboard::Key WindowImpl::ConvertVirtualKey(xcb_keysym_t symbol)
|
||||||
|
|
@ -1013,6 +1073,63 @@ namespace Nz
|
||||||
xcb_flush(connection);
|
xcb_flush(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char32_t WindowImpl::GetRepresentation(xcb_keysym_t keysym) const
|
||||||
|
{
|
||||||
|
switch (keysym)
|
||||||
|
{
|
||||||
|
case XK_KP_Space:
|
||||||
|
return ' ';
|
||||||
|
case XK_BackSpace:
|
||||||
|
return '\b';
|
||||||
|
case XK_KP_Tab || XK_Tab:
|
||||||
|
return '\t';
|
||||||
|
case XK_Linefeed:
|
||||||
|
return '\n';
|
||||||
|
case XK_Return:
|
||||||
|
return '\r';
|
||||||
|
// Numpad
|
||||||
|
case XK_KP_Multiply:
|
||||||
|
return '*';
|
||||||
|
case XK_KP_Add:
|
||||||
|
return '+';
|
||||||
|
case XK_KP_Separator:
|
||||||
|
return ','; // In french, it's '.'
|
||||||
|
case XK_KP_Subtract:
|
||||||
|
return '-';
|
||||||
|
case XK_KP_Decimal:
|
||||||
|
return '.'; // In french, it's ','
|
||||||
|
case XK_KP_Divide:
|
||||||
|
return '/';
|
||||||
|
case XK_KP_0:
|
||||||
|
return '0';
|
||||||
|
case XK_KP_1:
|
||||||
|
return '1';
|
||||||
|
case XK_KP_2:
|
||||||
|
return '2';
|
||||||
|
case XK_KP_3:
|
||||||
|
return '3';
|
||||||
|
case XK_KP_4:
|
||||||
|
return '4';
|
||||||
|
case XK_KP_5:
|
||||||
|
return '5';
|
||||||
|
case XK_KP_6:
|
||||||
|
return '6';
|
||||||
|
case XK_KP_7:
|
||||||
|
return '7';
|
||||||
|
case XK_KP_8:
|
||||||
|
return '8';
|
||||||
|
case XK_KP_9:
|
||||||
|
return '9';
|
||||||
|
case XK_KP_Enter:
|
||||||
|
return '\r';
|
||||||
|
default:
|
||||||
|
if (xcb_is_modifier_key(keysym) == true)
|
||||||
|
return '\0';
|
||||||
|
else
|
||||||
|
return keysym;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WindowImpl::ProcessEvent(xcb_generic_event_t* windowEvent)
|
void WindowImpl::ProcessEvent(xcb_generic_event_t* windowEvent)
|
||||||
{
|
{
|
||||||
if (!m_eventListener)
|
if (!m_eventListener)
|
||||||
|
|
@ -1127,7 +1244,7 @@ namespace Nz
|
||||||
event.key.system = keyPressEvent->state & XCB_MOD_MASK_4;
|
event.key.system = keyPressEvent->state & XCB_MOD_MASK_4;
|
||||||
m_parent->PushEvent(event);
|
m_parent->PushEvent(event);
|
||||||
|
|
||||||
char32_t codePoint = static_cast<char32_t>(keysym);
|
char32_t codePoint = GetRepresentation(keysym);
|
||||||
|
|
||||||
// WTF if (std::isprint(codePoint, std::locale(""))) + handle combining ?
|
// WTF if (std::isprint(codePoint, std::locale(""))) + handle combining ?
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,8 @@ namespace Nz
|
||||||
const char* ConvertWindowCursorToXName(WindowCursor cursor);
|
const char* ConvertWindowCursorToXName(WindowCursor cursor);
|
||||||
void CommonInitialize();
|
void CommonInitialize();
|
||||||
|
|
||||||
|
char32_t GetRepresentation(xcb_keysym_t keysym) const;
|
||||||
|
|
||||||
void ProcessEvent(xcb_generic_event_t* windowEvent);
|
void ProcessEvent(xcb_generic_event_t* windowEvent);
|
||||||
|
|
||||||
void ResetVideoMode();
|
void ResetVideoMode();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
#include <Nazara/Graphics/ColorBackground.hpp>
|
||||||
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
|
|
||||||
|
#include <NDK/Application.hpp>
|
||||||
|
#include <NDK/StateMachine.hpp>
|
||||||
|
#include <NDK/World.hpp>
|
||||||
|
#include <NDK/Components/CameraComponent.hpp>
|
||||||
|
#include <NDK/Components/NodeComponent.hpp>
|
||||||
|
#include <NDK/Systems/RenderSystem.hpp>
|
||||||
|
|
||||||
|
#include "EventHandler/StateContext.hpp"
|
||||||
|
#include "EventHandler/StateFactory.hpp"
|
||||||
|
|
||||||
|
#include <Catch/catch.hpp>
|
||||||
|
|
||||||
|
Ndk::EntityHandle AddCamera(Ndk::World& world, Nz::RenderWindow& window);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Known issues on Linux:
|
||||||
|
|
||||||
|
- There is no real double click event in X11
|
||||||
|
- Should always the key be repeated in key pressed mode ?
|
||||||
|
- No smooth wheel, only 1.f or -1.f
|
||||||
|
- Modify dimension of window updates position (which is not wrong)
|
||||||
|
- Text entered is never repeated
|
||||||
|
*/
|
||||||
|
|
||||||
|
SCENARIO("EventHandler", "[UTILITY][EVENTHANDLER][INTERACTIVE][.]")
|
||||||
|
{
|
||||||
|
GIVEN("An application")
|
||||||
|
{
|
||||||
|
Ndk::Application& app = *Ndk::Application::Instance();
|
||||||
|
auto& window = app.AddWindow<Nz::RenderWindow>();
|
||||||
|
if (!window.Create(Nz::VideoMode(1024, 768, 32), "EventHandler"))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to create window. See NazaraLog.log for further informations");
|
||||||
|
REQUIRE(false);
|
||||||
|
}
|
||||||
|
window.EnableVerticalSync(true);
|
||||||
|
|
||||||
|
auto& world = app.AddWorld();
|
||||||
|
|
||||||
|
auto camera = AddCamera(world, window);
|
||||||
|
|
||||||
|
StateContext context(window, world);
|
||||||
|
|
||||||
|
StateFactory::Initialize(context);
|
||||||
|
Ndk::StateMachine fsm(StateFactory::Get(EventStatus::Menu));
|
||||||
|
|
||||||
|
Nz::Clock elapsedTimeClock;
|
||||||
|
while (app.Run())
|
||||||
|
{
|
||||||
|
window.Display();
|
||||||
|
float elapsedTime = elapsedTimeClock.GetSeconds();
|
||||||
|
elapsedTimeClock.Restart();
|
||||||
|
|
||||||
|
if (!fsm.Update(elapsedTime))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to update state machine.");
|
||||||
|
REQUIRE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StateFactory::Uninitialize();
|
||||||
|
REQUIRE(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ndk::EntityHandle AddCamera(Ndk::World& world, Nz::RenderWindow& window)
|
||||||
|
{
|
||||||
|
Ndk::EntityHandle view = world.CreateEntity();
|
||||||
|
auto& node = view->AddComponent<Ndk::NodeComponent>();
|
||||||
|
node.SetPosition(Nz::Vector3f::Zero());
|
||||||
|
auto& cam = view->AddComponent<Ndk::CameraComponent>();
|
||||||
|
cam.SetProjectionType(Nz::ProjectionType_Orthogonal); // 2D
|
||||||
|
cam.SetTarget(&window);
|
||||||
|
|
||||||
|
world.GetSystem<Ndk::RenderSystem>().SetGlobalUp(Nz::Vector3f::Down());
|
||||||
|
world.GetSystem<Ndk::RenderSystem>().SetDefaultBackground(Nz::ColorBackground::New(Nz::Color::Black));
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
#include "EventState.hpp"
|
||||||
|
|
||||||
|
#include "StateContext.hpp"
|
||||||
|
#include "StateFactory.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
|
#include <NDK/StateMachine.hpp>
|
||||||
|
|
||||||
|
EventState::EventState(StateContext& context) :
|
||||||
|
State(),
|
||||||
|
m_context(context),
|
||||||
|
m_text(context),
|
||||||
|
m_count(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventState::Enter(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(true);
|
||||||
|
DrawMenu();
|
||||||
|
|
||||||
|
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
|
||||||
|
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
|
||||||
|
{
|
||||||
|
if (key.code == Nz::Keyboard::Key::M && key.shift)
|
||||||
|
{
|
||||||
|
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_eventSlot.Connect(eventHandler.OnEvent, [&] (const Nz::EventHandler*, const Nz::WindowEvent& event)
|
||||||
|
{
|
||||||
|
AddEvent(event);
|
||||||
|
++m_count;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventState::Leave(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EventState::Update(Ndk::StateMachine& fsm, float elapsedTime)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventState::AddEvent(const Nz::WindowEvent& event)
|
||||||
|
{
|
||||||
|
if (m_events.size() > 9)
|
||||||
|
m_events.pop_front();
|
||||||
|
|
||||||
|
m_events.push_back(Nz::String::Number(m_count) + " - " + ToString(event));
|
||||||
|
|
||||||
|
Nz::String content;
|
||||||
|
for (auto&& event : m_events)
|
||||||
|
{
|
||||||
|
content += event + "\n";
|
||||||
|
}
|
||||||
|
content += "\nM for Menu";
|
||||||
|
m_text.SetContent(content, 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventState::DrawMenu()
|
||||||
|
{
|
||||||
|
m_text.SetContent("Do whathever you want, this text should change !\nM for Menu");
|
||||||
|
}
|
||||||
|
|
||||||
|
Nz::String EventState::ToString(const Nz::WindowEvent& event) const
|
||||||
|
{
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case Nz::WindowEventType_GainedFocus:
|
||||||
|
return "WindowEventType_GainedFocus";
|
||||||
|
case Nz::WindowEventType_LostFocus:
|
||||||
|
return "WindowEventType_LostFocus";
|
||||||
|
case Nz::WindowEventType_KeyPressed:
|
||||||
|
return "WindowEventType_KeyPressed";
|
||||||
|
case Nz::WindowEventType_KeyReleased:
|
||||||
|
return "WindowEventType_KeyReleased";
|
||||||
|
case Nz::WindowEventType_MouseButtonDoubleClicked:
|
||||||
|
return "WindowEventType_MouseButtonDoubleClicked";
|
||||||
|
case Nz::WindowEventType_MouseButtonPressed:
|
||||||
|
return "WindowEventType_MouseButtonPressed";
|
||||||
|
case Nz::WindowEventType_MouseButtonReleased:
|
||||||
|
return "WindowEventType_MouseButtonReleased";
|
||||||
|
case Nz::WindowEventType_MouseEntered:
|
||||||
|
return "WindowEventType_MouseEntered";
|
||||||
|
case Nz::WindowEventType_MouseLeft:
|
||||||
|
return "WindowEventType_MouseLeft";
|
||||||
|
case Nz::WindowEventType_MouseMoved:
|
||||||
|
return "WindowEventType_MouseMoved";
|
||||||
|
case Nz::WindowEventType_MouseWheelMoved:
|
||||||
|
return "WindowEventType_MouseWheelMoved";
|
||||||
|
case Nz::WindowEventType_Moved:
|
||||||
|
return "WindowEventType_Moved";
|
||||||
|
case Nz::WindowEventType_Quit:
|
||||||
|
return "WindowEventType_Quit";
|
||||||
|
case Nz::WindowEventType_Resized:
|
||||||
|
return "WindowEventType_Resized";
|
||||||
|
case Nz::WindowEventType_TextEntered:
|
||||||
|
return "WindowEventType_TextEntered";
|
||||||
|
default:
|
||||||
|
return "Not handled";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef __EVENTSTATE_HPP__
|
||||||
|
#define __EVENTSTATE_HPP__
|
||||||
|
|
||||||
|
#include "Text.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Utility/EventHandler.hpp>
|
||||||
|
|
||||||
|
#include <NDK/State.hpp>
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
class StateContext;
|
||||||
|
|
||||||
|
class EventState : public Ndk::State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EventState(StateContext& stateContext);
|
||||||
|
|
||||||
|
void Enter(Ndk::StateMachine& fsm) override;
|
||||||
|
void Leave(Ndk::StateMachine& fsm) override;
|
||||||
|
bool Update(Ndk::StateMachine& fsm, float elapsedTime) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void AddEvent(const Nz::WindowEvent& event);
|
||||||
|
void DrawMenu();
|
||||||
|
Nz::String ToString(const Nz::WindowEvent& event) const;
|
||||||
|
|
||||||
|
StateContext& m_context;
|
||||||
|
Text m_text;
|
||||||
|
std::deque<Nz::String> m_events;
|
||||||
|
int m_count;
|
||||||
|
NazaraSlot(Nz::EventHandler, OnEvent, m_eventSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __EVENTSTATE_HPP__
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include "FocusState.hpp"
|
||||||
|
|
||||||
|
#include "StateContext.hpp"
|
||||||
|
#include "StateFactory.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
|
#include <NDK/StateMachine.hpp>
|
||||||
|
|
||||||
|
FocusState::FocusState(StateContext& context) :
|
||||||
|
State(),
|
||||||
|
m_context(context),
|
||||||
|
m_text(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FocusState::Enter(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(true);
|
||||||
|
DrawMenu();
|
||||||
|
|
||||||
|
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
|
||||||
|
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
|
||||||
|
{
|
||||||
|
if (key.code == Nz::Keyboard::Key::M && key.shift)
|
||||||
|
{
|
||||||
|
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_gainedFocusSlot.Connect(eventHandler.OnGainedFocus, [&] (const Nz::EventHandler*)
|
||||||
|
{
|
||||||
|
m_text.SetContent("GAINED\nM for Menu");
|
||||||
|
});
|
||||||
|
|
||||||
|
m_lostFocusSlot.Connect(eventHandler.OnLostFocus, [&] (const Nz::EventHandler*)
|
||||||
|
{
|
||||||
|
m_text.SetContent("LOST\nM for Menu");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void FocusState::Leave(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FocusState::Update(Ndk::StateMachine& fsm, float elapsedTime)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FocusState::DrawMenu()
|
||||||
|
{
|
||||||
|
m_text.SetContent("Click outside the windows, this text should change !\nM for Menu");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef __FOCUSSTATE_HPP__
|
||||||
|
#define __FOCUSSTATE_HPP__
|
||||||
|
|
||||||
|
#include "Text.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Utility/EventHandler.hpp>
|
||||||
|
|
||||||
|
#include <NDK/State.hpp>
|
||||||
|
|
||||||
|
class StateContext;
|
||||||
|
|
||||||
|
class FocusState : public Ndk::State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FocusState(StateContext& stateContext);
|
||||||
|
|
||||||
|
void Enter(Ndk::StateMachine& fsm) override;
|
||||||
|
void Leave(Ndk::StateMachine& fsm) override;
|
||||||
|
bool Update(Ndk::StateMachine& fsm, float elapsedTime) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawMenu();
|
||||||
|
|
||||||
|
StateContext& m_context;
|
||||||
|
Text m_text;
|
||||||
|
NazaraSlot(Nz::EventHandler, OnGainedFocus, m_gainedFocusSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnLostFocus, m_lostFocusSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __FOCUSSTATE_HPP__
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
#include "KeyState.hpp"
|
||||||
|
|
||||||
|
#include "StateContext.hpp"
|
||||||
|
#include "StateFactory.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
|
#include <NDK/StateMachine.hpp>
|
||||||
|
|
||||||
|
KeyState::KeyState(StateContext& context) :
|
||||||
|
State(),
|
||||||
|
m_context(context),
|
||||||
|
m_text(context),
|
||||||
|
m_keyStatus(KeyStatus::Pressed)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyState::Enter(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(true);
|
||||||
|
DrawMenu();
|
||||||
|
|
||||||
|
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
|
||||||
|
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
|
||||||
|
{
|
||||||
|
ManageInput(KeyStatus::Pressed, key, fsm);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_keyReleasedSlot.Connect(eventHandler.OnKeyReleased, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
|
||||||
|
{
|
||||||
|
ManageInput(KeyStatus::Released, key, fsm);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyState::Leave(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyState::Update(Ndk::StateMachine& fsm, float elapsedTime)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyState::DrawMenu()
|
||||||
|
{
|
||||||
|
m_text.SetContent("Clic on a key, this text should change !\nN for alternating event\nM for Menu");
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyState::ManageInput(KeyStatus isKeyPressed, const Nz::WindowEvent::KeyEvent& key, Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
if (key.code == Nz::Keyboard::Key::M && key.shift)
|
||||||
|
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
|
||||||
|
else if (key.code == Nz::Keyboard::Key::N && key.shift)
|
||||||
|
{
|
||||||
|
if (m_keyStatus == KeyStatus::Pressed)
|
||||||
|
m_keyStatus = KeyStatus::Released;
|
||||||
|
else
|
||||||
|
m_keyStatus = KeyStatus::Pressed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Nz::String content;
|
||||||
|
if (m_keyStatus == KeyStatus::Pressed)
|
||||||
|
content = "Pressed: ";
|
||||||
|
else
|
||||||
|
content = "Released: ";
|
||||||
|
|
||||||
|
Nz::String keyName = Nz::Keyboard::GetKeyName(key.code);
|
||||||
|
if (keyName.IsEmpty())
|
||||||
|
{
|
||||||
|
m_text.SetContent("Unknown\nM for Menu");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
content += keyName;
|
||||||
|
if (key.alt)
|
||||||
|
content += " alt";
|
||||||
|
if (key.control)
|
||||||
|
content += " control";
|
||||||
|
if (key.repeated)
|
||||||
|
content += " repeated";
|
||||||
|
if (key.shift)
|
||||||
|
content += " shift";
|
||||||
|
if (key.system)
|
||||||
|
content += " system";
|
||||||
|
|
||||||
|
m_text.SetContent(content + "\nM for Menu");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef __KEYSTATE_HPP__
|
||||||
|
#define __KEYSTATE_HPP__
|
||||||
|
|
||||||
|
#include "Text.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Utility/EventHandler.hpp>
|
||||||
|
|
||||||
|
#include <NDK/State.hpp>
|
||||||
|
|
||||||
|
class StateContext;
|
||||||
|
|
||||||
|
enum class KeyStatus
|
||||||
|
{
|
||||||
|
Pressed,
|
||||||
|
Released
|
||||||
|
};
|
||||||
|
|
||||||
|
class KeyState : public Ndk::State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KeyState(StateContext& stateContext);
|
||||||
|
|
||||||
|
void Enter(Ndk::StateMachine& fsm) override;
|
||||||
|
void Leave(Ndk::StateMachine& fsm) override;
|
||||||
|
bool Update(Ndk::StateMachine& fsm, float elapsedTime) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawMenu();
|
||||||
|
void ManageInput(KeyStatus isKeyPressed, const Nz::WindowEvent::KeyEvent& key, Ndk::StateMachine& fsm);
|
||||||
|
|
||||||
|
StateContext& m_context;
|
||||||
|
Text m_text;
|
||||||
|
KeyStatus m_keyStatus;
|
||||||
|
NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnKeyReleased, m_keyReleasedSlot);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __KEYSTATE_HPP__
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
#include "MenuState.hpp"
|
||||||
|
|
||||||
|
#include "StateContext.hpp"
|
||||||
|
#include "StateFactory.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
|
#include <NDK/StateMachine.hpp>
|
||||||
|
|
||||||
|
MenuState::MenuState(StateContext& context) :
|
||||||
|
State(),
|
||||||
|
m_context(context),
|
||||||
|
m_text(context),
|
||||||
|
m_selectedNextState(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuState::Enter(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(true);
|
||||||
|
DrawMenu();
|
||||||
|
|
||||||
|
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
|
||||||
|
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [this] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
|
||||||
|
{
|
||||||
|
if (key.code >= Nz::Keyboard::Key::A && key.code < (Nz::Keyboard::Key::A + static_cast<int>(EventStatus::Max) - 1))
|
||||||
|
{
|
||||||
|
m_selectedNextState = key.code - static_cast<int>(Nz::Keyboard::Key::A);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuState::Leave(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(false);
|
||||||
|
m_selectedNextState = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MenuState::Update(Ndk::StateMachine& fsm, float elapsedTime)
|
||||||
|
{
|
||||||
|
if (m_selectedNextState != -1) {
|
||||||
|
fsm.ChangeState(StateFactory::Get(m_selectedNextState + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuState::DrawMenu()
|
||||||
|
{
|
||||||
|
m_text.SetContent("a. Event\nb. Focus\nc. Key\nd. Mouse click\ne. Mouse enter\nf. Mouse move\ng. Text enter\nh. Window modification");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef __MENUSTATE_HPP__
|
||||||
|
#define __MENUSTATE_HPP__
|
||||||
|
|
||||||
|
#include "Text.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Utility/EventHandler.hpp>
|
||||||
|
|
||||||
|
#include <NDK/State.hpp>
|
||||||
|
|
||||||
|
class StateContext;
|
||||||
|
|
||||||
|
class MenuState : public Ndk::State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MenuState(StateContext& stateContext);
|
||||||
|
|
||||||
|
void Enter(Ndk::StateMachine& fsm) override;
|
||||||
|
void Leave(Ndk::StateMachine& fsm) override;
|
||||||
|
bool Update(Ndk::StateMachine& fsm, float elapsedTime) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawMenu();
|
||||||
|
|
||||||
|
StateContext& m_context;
|
||||||
|
Text m_text;
|
||||||
|
NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot);
|
||||||
|
int m_selectedNextState;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __MENUSTATE_HPP__
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
#include "MouseClickState.hpp"
|
||||||
|
|
||||||
|
#include "StateContext.hpp"
|
||||||
|
#include "StateFactory.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
|
#include <NDK/StateMachine.hpp>
|
||||||
|
|
||||||
|
MouseClickState::MouseClickState(StateContext& context) :
|
||||||
|
State(),
|
||||||
|
m_context(context),
|
||||||
|
m_text(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseClickState::Enter(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(true);
|
||||||
|
DrawMenu();
|
||||||
|
|
||||||
|
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
|
||||||
|
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
|
||||||
|
{
|
||||||
|
if (key.code == Nz::Keyboard::Key::M && key.shift)
|
||||||
|
{
|
||||||
|
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_mouseButtonDoubleClickedSlot.Connect(eventHandler.OnMouseButtonDoubleClicked, [&] (const Nz::EventHandler*, const Nz::WindowEvent::MouseButtonEvent& mouse)
|
||||||
|
{
|
||||||
|
ManageInput(MouseStatus::DoubleClick, mouse, fsm);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_mouseButtonPressedSlot.Connect(eventHandler.OnMouseButtonPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::MouseButtonEvent& mouse)
|
||||||
|
{
|
||||||
|
ManageInput(MouseStatus::Pressed, mouse, fsm);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_mouseButtonReleasedSlot.Connect(eventHandler.OnMouseButtonReleased, [&] (const Nz::EventHandler*, const Nz::WindowEvent::MouseButtonEvent& mouse)
|
||||||
|
{
|
||||||
|
ManageInput(MouseStatus::Released, mouse, fsm);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseClickState::Leave(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MouseClickState::Update(Ndk::StateMachine& fsm, float elapsedTime)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseClickState::DrawMenu()
|
||||||
|
{
|
||||||
|
m_text.SetContent("Click in the windows, this text should change !\nM for Menu");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseClickState::ManageInput(MouseStatus mouseStatus, const Nz::WindowEvent::MouseButtonEvent& mouse, Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
Nz::String content;
|
||||||
|
if (mouseStatus == MouseStatus::Pressed)
|
||||||
|
content = "Pressed: ";
|
||||||
|
else if (mouseStatus == MouseStatus::Released)
|
||||||
|
content = "Released: ";
|
||||||
|
else
|
||||||
|
content = "Double clicked: ";
|
||||||
|
|
||||||
|
switch (mouse.button)
|
||||||
|
{
|
||||||
|
case Nz::Mouse::Left:
|
||||||
|
content += "Left";
|
||||||
|
break;
|
||||||
|
case Nz::Mouse::Middle:
|
||||||
|
content += "Middle";
|
||||||
|
break;
|
||||||
|
case Nz::Mouse::Right:
|
||||||
|
content += "Right";
|
||||||
|
break;
|
||||||
|
case Nz::Mouse::XButton1:
|
||||||
|
content += "XButton1";
|
||||||
|
break;
|
||||||
|
case Nz::Mouse::XButton2:
|
||||||
|
content += "XButton2";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
content += "Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_text.SetContent(content + "\nM for Menu");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef __MOUSECLICKSTATE_HPP__
|
||||||
|
#define __MOUSECLICKSTATE_HPP__
|
||||||
|
|
||||||
|
#include "Text.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Utility/EventHandler.hpp>
|
||||||
|
|
||||||
|
#include <NDK/State.hpp>
|
||||||
|
|
||||||
|
class StateContext;
|
||||||
|
|
||||||
|
enum class MouseStatus
|
||||||
|
{
|
||||||
|
DoubleClick,
|
||||||
|
Pressed,
|
||||||
|
Released
|
||||||
|
};
|
||||||
|
|
||||||
|
class MouseClickState : public Ndk::State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MouseClickState(StateContext& stateContext);
|
||||||
|
|
||||||
|
void Enter(Ndk::StateMachine& fsm) override;
|
||||||
|
void Leave(Ndk::StateMachine& fsm) override;
|
||||||
|
bool Update(Ndk::StateMachine& fsm, float elapsedTime) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawMenu();
|
||||||
|
void ManageInput(MouseStatus mouseStatus, const Nz::WindowEvent::MouseButtonEvent& mouse, Ndk::StateMachine& fsm);
|
||||||
|
|
||||||
|
StateContext& m_context;
|
||||||
|
Text m_text;
|
||||||
|
NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnMouseButtonDoubleClicked, m_mouseButtonDoubleClickedSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnMouseButtonPressed, m_mouseButtonPressedSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnMouseButtonReleased, m_mouseButtonReleasedSlot);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __MOUSECLICKSTATE_HPP__
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include "MouseEnterState.hpp"
|
||||||
|
|
||||||
|
#include "StateContext.hpp"
|
||||||
|
#include "StateFactory.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
|
#include <NDK/StateMachine.hpp>
|
||||||
|
|
||||||
|
MouseEnterState::MouseEnterState(StateContext& context) :
|
||||||
|
State(),
|
||||||
|
m_context(context),
|
||||||
|
m_text(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseEnterState::Enter(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(true);
|
||||||
|
DrawMenu();
|
||||||
|
|
||||||
|
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
|
||||||
|
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
|
||||||
|
{
|
||||||
|
if (key.code == Nz::Keyboard::Key::M && key.shift)
|
||||||
|
{
|
||||||
|
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_mouseEnteredSlot.Connect(eventHandler.OnMouseEntered, [&] (const Nz::EventHandler*)
|
||||||
|
{
|
||||||
|
m_text.SetContent("Entered\nM for Menu");
|
||||||
|
});
|
||||||
|
|
||||||
|
m_mouseLeftSlot.Connect(eventHandler.OnMouseLeft, [&] (const Nz::EventHandler*)
|
||||||
|
{
|
||||||
|
m_text.SetContent("Left\nM for Menu");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseEnterState::Leave(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MouseEnterState::Update(Ndk::StateMachine& fsm, float elapsedTime)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseEnterState::DrawMenu()
|
||||||
|
{
|
||||||
|
m_text.SetContent("Move your mouse outside the windows, this text should change !\nM for Menu");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef __MOUSEENTERSTATE_HPP__
|
||||||
|
#define __MOUSEENTERSTATE_HPP__
|
||||||
|
|
||||||
|
#include "Text.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Utility/EventHandler.hpp>
|
||||||
|
|
||||||
|
#include <NDK/State.hpp>
|
||||||
|
|
||||||
|
class StateContext;
|
||||||
|
|
||||||
|
class MouseEnterState : public Ndk::State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MouseEnterState(StateContext& stateContext);
|
||||||
|
|
||||||
|
void Enter(Ndk::StateMachine& fsm) override;
|
||||||
|
void Leave(Ndk::StateMachine& fsm) override;
|
||||||
|
bool Update(Ndk::StateMachine& fsm, float elapsedTime) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawMenu();
|
||||||
|
|
||||||
|
StateContext& m_context;
|
||||||
|
Text m_text;
|
||||||
|
NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnMouseEntered, m_mouseEnteredSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnMouseLeft, m_mouseLeftSlot);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __MOUSEENTERSTATE_HPP__
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include "MouseMoveState.hpp"
|
||||||
|
|
||||||
|
#include "StateContext.hpp"
|
||||||
|
#include "StateFactory.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
|
#include <NDK/StateMachine.hpp>
|
||||||
|
|
||||||
|
MouseMoveState::MouseMoveState(StateContext& context) :
|
||||||
|
State(),
|
||||||
|
m_context(context),
|
||||||
|
m_text(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseMoveState::Enter(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(true);
|
||||||
|
DrawMenu();
|
||||||
|
|
||||||
|
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
|
||||||
|
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
|
||||||
|
{
|
||||||
|
if (key.code == Nz::Keyboard::Key::M && key.shift)
|
||||||
|
{
|
||||||
|
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_mouseMovedSlot.Connect(eventHandler.OnMouseMoved, [&] (const Nz::EventHandler*, const Nz::WindowEvent::MouseMoveEvent& event)
|
||||||
|
{
|
||||||
|
m_text.SetContent("Position(" + Nz::String::Number(event.x) + ", " + Nz::String::Number(event.y) + ") delta: (" + Nz::String::Number(event.deltaX) + ", " + Nz::String::Number(event.deltaY) + ") \nM for Menu");
|
||||||
|
});
|
||||||
|
|
||||||
|
m_mouseWheelMovedSlot.Connect(eventHandler.OnMouseWheelMoved, [&] (const Nz::EventHandler*, const Nz::WindowEvent::MouseWheelEvent& event)
|
||||||
|
{
|
||||||
|
m_text.SetContent("Wheel delta: " + Nz::String::Number(event.delta) + "\nM for Menu");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseMoveState::Leave(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MouseMoveState::Update(Ndk::StateMachine& fsm, float elapsedTime)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseMoveState::DrawMenu()
|
||||||
|
{
|
||||||
|
m_text.SetContent("Move your mouse or your wheel, this text should change !\nM for Menu");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef __MOUSEMOVESTATE_HPP__
|
||||||
|
#define __MOUSEMOVESTATE_HPP__
|
||||||
|
|
||||||
|
#include "Text.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Utility/EventHandler.hpp>
|
||||||
|
|
||||||
|
#include <NDK/State.hpp>
|
||||||
|
|
||||||
|
class StateContext;
|
||||||
|
|
||||||
|
class MouseMoveState : public Ndk::State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MouseMoveState(StateContext& stateContext);
|
||||||
|
|
||||||
|
void Enter(Ndk::StateMachine& fsm) override;
|
||||||
|
void Leave(Ndk::StateMachine& fsm) override;
|
||||||
|
bool Update(Ndk::StateMachine& fsm, float elapsedTime) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawMenu();
|
||||||
|
|
||||||
|
StateContext& m_context;
|
||||||
|
Text m_text;
|
||||||
|
NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnMouseMoved, m_mouseMovedSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnMouseWheelMoved, m_mouseWheelMovedSlot);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __MOUSEMOVESTATE_HPP__
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "StateContext.hpp"
|
||||||
|
|
||||||
|
StateContext::StateContext(Nz::RenderWindow& windowContext, Ndk::World& worldContext) :
|
||||||
|
window(windowContext),
|
||||||
|
world(worldContext)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef __STATECONTEXT_HPP__
|
||||||
|
#define __STATECONTEXT_HPP__
|
||||||
|
|
||||||
|
namespace Ndk
|
||||||
|
{
|
||||||
|
class World;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class RenderWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class StateContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StateContext(Nz::RenderWindow& window, Ndk::World& world);
|
||||||
|
|
||||||
|
Nz::RenderWindow& window;
|
||||||
|
Ndk::World& world;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __STATECONTEXT_HPP__
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include "StateFactory.hpp"
|
||||||
|
|
||||||
|
#include "MenuState.hpp"
|
||||||
|
#include "EventState.hpp"
|
||||||
|
#include "FocusState.hpp"
|
||||||
|
#include "KeyState.hpp"
|
||||||
|
#include "MouseClickState.hpp"
|
||||||
|
#include "MouseEnterState.hpp"
|
||||||
|
#include "MouseMoveState.hpp"
|
||||||
|
#include "TextEnterState.hpp"
|
||||||
|
#include "WindowModificationState.hpp"
|
||||||
|
|
||||||
|
std::shared_ptr<Ndk::State> StateFactory::Get(EventStatus state)
|
||||||
|
{
|
||||||
|
return s_states[state];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Ndk::State> StateFactory::Get(unsigned int state)
|
||||||
|
{
|
||||||
|
NazaraAssert(state < s_states.size(), "State out of range");
|
||||||
|
auto it = s_states.begin();
|
||||||
|
std::advance(it, state);
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StateFactory::Initialize(StateContext& context)
|
||||||
|
{
|
||||||
|
s_states.emplace(std::make_pair(EventStatus::Menu, std::make_shared<MenuState>(context)));
|
||||||
|
s_states.emplace(std::make_pair(EventStatus::Event, std::make_shared<EventState>(context)));
|
||||||
|
s_states.emplace(std::make_pair(EventStatus::Focus, std::make_shared<FocusState>(context)));
|
||||||
|
s_states.emplace(std::make_pair(EventStatus::Key, std::make_shared<KeyState>(context)));
|
||||||
|
s_states.emplace(std::make_pair(EventStatus::MouseClick, std::make_shared<MouseClickState>(context)));
|
||||||
|
s_states.emplace(std::make_pair(EventStatus::MouseEnter, std::make_shared<MouseEnterState>(context)));
|
||||||
|
s_states.emplace(std::make_pair(EventStatus::MouseMove, std::make_shared<MouseMoveState>(context)));
|
||||||
|
s_states.emplace(std::make_pair(EventStatus::TextEnter, std::make_shared<TextEnterState>(context)));
|
||||||
|
s_states.emplace(std::make_pair(EventStatus::WindowModification, std::make_shared<WindowModificationState>(context)));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateFactory::Uninitialize()
|
||||||
|
{
|
||||||
|
s_states.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<EventStatus, std::shared_ptr<Ndk::State>> StateFactory::s_states;
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef __STATEFACTORY_HPP__
|
||||||
|
#define __STATEFACTORY_HPP__
|
||||||
|
|
||||||
|
#include <NDK/State.hpp>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class StateContext;
|
||||||
|
|
||||||
|
enum class EventStatus
|
||||||
|
{
|
||||||
|
Min = 0,
|
||||||
|
Menu,
|
||||||
|
Event,
|
||||||
|
Focus,
|
||||||
|
Key,
|
||||||
|
MouseClick,
|
||||||
|
MouseEnter,
|
||||||
|
MouseMove,
|
||||||
|
TextEnter,
|
||||||
|
WindowModification,
|
||||||
|
Max = WindowModification
|
||||||
|
};
|
||||||
|
|
||||||
|
class StateFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static std::shared_ptr<Ndk::State> Get(EventStatus state);
|
||||||
|
static std::shared_ptr<Ndk::State> Get(unsigned int state);
|
||||||
|
|
||||||
|
static bool Initialize(StateContext& stateContext);
|
||||||
|
|
||||||
|
static void Uninitialize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static std::map<EventStatus, std::shared_ptr<Ndk::State>> s_states;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __STATEFACTORY_HPP__
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
#include "Text.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
|
#include <Nazara/Utility/SimpleTextDrawer.hpp>
|
||||||
|
#include <NDK/StateMachine.hpp>
|
||||||
|
#include <NDK/World.hpp>
|
||||||
|
#include <NDK/Components/GraphicsComponent.hpp>
|
||||||
|
#include <NDK/Components/NodeComponent.hpp>
|
||||||
|
|
||||||
|
Text::Text(StateContext& stateContext) :
|
||||||
|
m_context(stateContext)
|
||||||
|
{
|
||||||
|
m_text = m_context.world.CreateEntity();
|
||||||
|
Ndk::NodeComponent& nodeComponent = m_text->AddComponent<Ndk::NodeComponent>();
|
||||||
|
Ndk::GraphicsComponent& graphicsComponent = m_text->AddComponent<Ndk::GraphicsComponent>();
|
||||||
|
|
||||||
|
m_textSprite = Nz::TextSprite::New();
|
||||||
|
graphicsComponent.Attach(m_textSprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
Text::~Text()
|
||||||
|
{
|
||||||
|
m_textSprite->Clear();
|
||||||
|
m_text->Kill();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::SetContent(const Nz::String& string, unsigned int size)
|
||||||
|
{
|
||||||
|
m_textSprite->Update(Nz::SimpleTextDrawer::Draw(string, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::SetVisible(bool shouldBeVisible)
|
||||||
|
{
|
||||||
|
m_text->Enable(shouldBeVisible);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef __TEXT_HPP__
|
||||||
|
#define __TEXT_HPP__
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/TextSprite.hpp>
|
||||||
|
#include <NDK/Entity.hpp>
|
||||||
|
#include "StateContext.hpp"
|
||||||
|
|
||||||
|
class Text
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Text(StateContext& context);
|
||||||
|
~Text();
|
||||||
|
|
||||||
|
void SetContent(const Nz::String& string, unsigned int size = 72);
|
||||||
|
void SetVisible(bool shouldBeVisible = true);
|
||||||
|
|
||||||
|
private:
|
||||||
|
StateContext& m_context;
|
||||||
|
Ndk::EntityHandle m_text;
|
||||||
|
Nz::TextSpriteRef m_textSprite;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __TEXT_HPP__
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include "TextEnterState.hpp"
|
||||||
|
|
||||||
|
#include "StateContext.hpp"
|
||||||
|
#include "StateFactory.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
|
#include <NDK/StateMachine.hpp>
|
||||||
|
|
||||||
|
TextEnterState::TextEnterState(StateContext& context) :
|
||||||
|
State(),
|
||||||
|
m_context(context),
|
||||||
|
m_text(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEnterState::Enter(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(true);
|
||||||
|
DrawMenu();
|
||||||
|
|
||||||
|
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
|
||||||
|
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
|
||||||
|
{
|
||||||
|
if (key.code == Nz::Keyboard::Key::M && key.shift)
|
||||||
|
{
|
||||||
|
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_textEnteredSlot.Connect(eventHandler.OnTextEntered, [&] (const Nz::EventHandler*, const Nz::WindowEvent::TextEvent& event)
|
||||||
|
{
|
||||||
|
Nz::String content = "Character: " + Nz::String::Unicode(event.character);
|
||||||
|
if (event.repeated)
|
||||||
|
content += " repeated";
|
||||||
|
m_text.SetContent(content + "\nM for Menu");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEnterState::Leave(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextEnterState::Update(Ndk::StateMachine& fsm, float elapsedTime)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEnterState::DrawMenu()
|
||||||
|
{
|
||||||
|
m_text.SetContent("Enter some text, this text should change !\nM for Menu");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef __TEXTENTERSTATE_HPP__
|
||||||
|
#define __TEXTENTERSTATE_HPP__
|
||||||
|
|
||||||
|
#include "Text.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Utility/EventHandler.hpp>
|
||||||
|
|
||||||
|
#include <NDK/State.hpp>
|
||||||
|
|
||||||
|
class StateContext;
|
||||||
|
|
||||||
|
class TextEnterState : public Ndk::State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextEnterState(StateContext& stateContext);
|
||||||
|
|
||||||
|
void Enter(Ndk::StateMachine& fsm) override;
|
||||||
|
void Leave(Ndk::StateMachine& fsm) override;
|
||||||
|
bool Update(Ndk::StateMachine& fsm, float elapsedTime) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawMenu();
|
||||||
|
|
||||||
|
StateContext& m_context;
|
||||||
|
Text m_text;
|
||||||
|
NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnTextEntered, m_textEnteredSlot);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __TEXTENTERSTATE_HPP__
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include "WindowModificationState.hpp"
|
||||||
|
|
||||||
|
#include "StateContext.hpp"
|
||||||
|
#include "StateFactory.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
|
#include <NDK/StateMachine.hpp>
|
||||||
|
|
||||||
|
WindowModificationState::WindowModificationState(StateContext& context) :
|
||||||
|
State(),
|
||||||
|
m_context(context),
|
||||||
|
m_text(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowModificationState::Enter(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(true);
|
||||||
|
DrawMenu();
|
||||||
|
|
||||||
|
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
|
||||||
|
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
|
||||||
|
{
|
||||||
|
if (key.code == Nz::Keyboard::Key::M && key.shift)
|
||||||
|
{
|
||||||
|
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_movedSlot.Connect(eventHandler.OnMoved, [&] (const Nz::EventHandler*, const Nz::WindowEvent::PositionEvent& event)
|
||||||
|
{
|
||||||
|
m_text.SetContent("Position(" + Nz::String::Number(event.x) + ", " + Nz::String::Number(event.y) + ")\nM for Menu");
|
||||||
|
});
|
||||||
|
|
||||||
|
m_resizedSlot.Connect(eventHandler.OnResized, [&] (const Nz::EventHandler*, const Nz::WindowEvent::SizeEvent& event)
|
||||||
|
{
|
||||||
|
m_text.SetContent("Size(" + Nz::String::Number(event.width) + ", " + Nz::String::Number(event.height) + ")\nM for Menu");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowModificationState::Leave(Ndk::StateMachine& fsm)
|
||||||
|
{
|
||||||
|
m_text.SetVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowModificationState::Update(Ndk::StateMachine& fsm, float elapsedTime)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowModificationState::DrawMenu()
|
||||||
|
{
|
||||||
|
m_text.SetContent("Move the window or resize it, this text should change !\nM for Menu");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef __WINDOWMODIFICATIONSTATE_HPP__
|
||||||
|
#define __WINDOWMODIFICATIONSTATE_HPP__
|
||||||
|
|
||||||
|
#include "Text.hpp"
|
||||||
|
|
||||||
|
#include <Nazara/Utility/EventHandler.hpp>
|
||||||
|
|
||||||
|
#include <NDK/State.hpp>
|
||||||
|
|
||||||
|
class StateContext;
|
||||||
|
|
||||||
|
class WindowModificationState : public Ndk::State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WindowModificationState(StateContext& stateContext);
|
||||||
|
|
||||||
|
void Enter(Ndk::StateMachine& fsm) override;
|
||||||
|
void Leave(Ndk::StateMachine& fsm) override;
|
||||||
|
bool Update(Ndk::StateMachine& fsm, float elapsedTime) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawMenu();
|
||||||
|
|
||||||
|
StateContext& m_context;
|
||||||
|
Text m_text;
|
||||||
|
NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnMoved, m_movedSlot);
|
||||||
|
NazaraSlot(Nz::EventHandler, OnResized, m_resizedSlot);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __WINDOWMODIFICATIONSTATE_HPP__
|
||||||
Loading…
Reference in New Issue