Merge pull request #83 from Gawaboumga/Console-Fix

Console fix
This commit is contained in:
Jérôme Leclercq 2016-10-13 04:54:45 +02:00 committed by GitHub
commit 5a3077a3ad
28 changed files with 1295 additions and 11 deletions

View File

@ -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"

View File

@ -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 ?
{ {

View File

@ -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();

View File

@ -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;
}

View File

@ -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";
}
}

View File

@ -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__

View File

@ -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");
}

View File

@ -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__

View File

@ -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");
}
}
}

View File

@ -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__

View File

@ -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");
}

View File

@ -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__

View File

@ -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");
}

View File

@ -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__

View File

@ -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");
}

View File

@ -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__

View File

@ -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");
}

View File

@ -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__

View File

@ -0,0 +1,7 @@
#include "StateContext.hpp"
StateContext::StateContext(Nz::RenderWindow& windowContext, Ndk::World& worldContext) :
window(windowContext),
world(worldContext)
{
}

View File

@ -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__

View File

@ -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;

View File

@ -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__

View File

@ -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);
}

View File

@ -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__

View File

@ -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");
}

View File

@ -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__

View File

@ -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");
}

View File

@ -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__