✨ quit command.
parent
69b0f500b7
commit
8d7cd962eb
|
@ -0,0 +1,5 @@
|
||||||
|
*~*
|
||||||
|
*\#*
|
||||||
|
.cache
|
||||||
|
.ccls-cache
|
||||||
|
build
|
|
@ -0,0 +1,50 @@
|
||||||
|
cmake_minimum_required(VERSION 3.2)
|
||||||
|
|
||||||
|
add_subdirectory(tests)
|
||||||
|
|
||||||
|
project(pix-draw-studio
|
||||||
|
VERSION 0.0.0
|
||||||
|
LANGUAGES CXX
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTOUI ON)
|
||||||
|
|
||||||
|
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets OpenGLWidgets)
|
||||||
|
qt_standard_project_setup()
|
||||||
|
|
||||||
|
add_library(pixlib OBJECT
|
||||||
|
# keys
|
||||||
|
src/keys/KeyMod.cpp
|
||||||
|
src/keys/Shortcut.cpp
|
||||||
|
|
||||||
|
# cmd
|
||||||
|
src/cmd/Command.cpp
|
||||||
|
src/cmd/ShortcutListener.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_add_executable(pixdraw
|
||||||
|
# entrypoint
|
||||||
|
src/main.cpp
|
||||||
|
src/Presenter.cpp
|
||||||
|
|
||||||
|
# gui
|
||||||
|
src/gui/Window.hpp
|
||||||
|
src/gui/Window.cpp
|
||||||
|
src/gui/window.ui
|
||||||
|
)
|
||||||
|
|
||||||
|
install(TARGETS pixdraw)
|
||||||
|
|
||||||
|
target_compile_options(pixdraw
|
||||||
|
PRIVATE $<$<CONFIG:Debug>: -Wall -Wextra -g>)
|
||||||
|
|
||||||
|
target_link_libraries(pixdraw PRIVATE
|
||||||
|
Qt6::Core
|
||||||
|
Qt6::Gui
|
||||||
|
Qt6::Widgets
|
||||||
|
Qt6::OpenGLWidgets
|
||||||
|
$<TARGET_OBJECTS:pixlib>
|
||||||
|
)
|
|
@ -0,0 +1,16 @@
|
||||||
|
.PHONY: build test
|
||||||
|
|
||||||
|
build:
|
||||||
|
cmake -B build -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
cmake --build build
|
||||||
|
|
||||||
|
test: build
|
||||||
|
build/tests/pix-test
|
||||||
|
|
||||||
|
install: test
|
||||||
|
cmake --install build
|
||||||
|
|
||||||
|
check:
|
||||||
|
@cppcheck --enable=all language=c++ -q src tests \
|
||||||
|
--suppress=missingInclude \
|
||||||
|
--suppress=unusedFunction \
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include "Presenter.hpp"
|
||||||
|
#include "cmd/pix_cmds.hpp"
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
/*explicit*/ Presenter::Presenter()
|
||||||
|
: m_window { std::make_unique<Window>(*this) }
|
||||||
|
{
|
||||||
|
m_listener.bind("C-c C-c", std::make_shared<QuitCmd>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Presenter::~Presenter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Presenter::start()
|
||||||
|
{
|
||||||
|
m_window->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Presenter::on_key_pressed(KeyMod const& km)
|
||||||
|
{
|
||||||
|
m_listener.update(km);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef pix_PRESENTER_HPP
|
||||||
|
#define pix_PRESENTER_HPP
|
||||||
|
|
||||||
|
#include "cmd/ShortcutListener.hpp"
|
||||||
|
#include "commons.hpp"
|
||||||
|
#include "gui/Window.hpp"
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
class Presenter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Presenter();
|
||||||
|
virtual ~Presenter();
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void on_key_pressed(KeyMod const& km);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Window> m_window;
|
||||||
|
ShortcutListener m_listener;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include "Command.hpp"
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
/*explicit*/ Command::Command(std::string const& name)
|
||||||
|
: m_name { name }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Command::~Command()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef pix_COMMAND_HPP
|
||||||
|
#define pix_COMMAND_HPP
|
||||||
|
|
||||||
|
#include "../commons.hpp"
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
class Command
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Command(std::string const& name);
|
||||||
|
virtual ~Command();
|
||||||
|
|
||||||
|
std::string name() const { return m_name; }
|
||||||
|
|
||||||
|
virtual void execute() = 0;
|
||||||
|
virtual void undo() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_name;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include "ShortcutListener.hpp"
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
/*explicit*/ ShortcutListener::ShortcutListener()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ ShortcutListener::~ShortcutListener()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutListener::bind(std::string const& shortcut_repr,
|
||||||
|
std::shared_ptr<Command> cmd)
|
||||||
|
{
|
||||||
|
Binding binding;
|
||||||
|
binding.cmd = cmd;
|
||||||
|
binding.shortcut = Shortcut {shortcut_repr};
|
||||||
|
|
||||||
|
m_bindings.push_back(binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutListener::update(KeyMod const& keymod)
|
||||||
|
{
|
||||||
|
for (auto& binding: m_bindings)
|
||||||
|
{
|
||||||
|
KeyMod current_km = binding.shortcut.get(binding.progress);
|
||||||
|
|
||||||
|
if (current_km.equals(keymod))
|
||||||
|
{
|
||||||
|
binding.progress++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
binding.progress = 0;
|
||||||
|
|
||||||
|
current_km = binding.shortcut.get(binding.progress);
|
||||||
|
|
||||||
|
if (current_km.equals(keymod))
|
||||||
|
{
|
||||||
|
binding.progress++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binding.progress >= binding.shortcut.size())
|
||||||
|
{
|
||||||
|
binding.progress = 0;
|
||||||
|
binding.cmd->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef pix_SHORTCUTLISTENER_HPP
|
||||||
|
#define pix_SHORTCUTLISTENER_HPP
|
||||||
|
|
||||||
|
#include "../keys/Shortcut.hpp"
|
||||||
|
#include "Command.hpp"
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
struct Binding {
|
||||||
|
std::shared_ptr<Command> cmd;
|
||||||
|
Shortcut shortcut;
|
||||||
|
size_t progress = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShortcutListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ShortcutListener();
|
||||||
|
virtual ~ShortcutListener();
|
||||||
|
|
||||||
|
|
||||||
|
void bind(std::string const& shortcut_repr, std::shared_ptr<Command> cmd);
|
||||||
|
void update(KeyMod const& keymod);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Binding> m_bindings;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef pix_PIX_CMDS_HPP
|
||||||
|
#define pix_PIX_CMDS_HPP
|
||||||
|
|
||||||
|
#include "../commons.hpp"
|
||||||
|
#include "Command.hpp"
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
struct QuitCmd: public Command
|
||||||
|
{
|
||||||
|
explicit QuitCmd()
|
||||||
|
: Command("Quit")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute() override
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef pix_COMMONS_HPP
|
||||||
|
#define pix_COMMONS_HPP
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <optional>
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define PIX_ENUM_ID(X) X
|
||||||
|
#define PIX_ENUM_STR(X) #X
|
||||||
|
#define PIX_ENUM(PREFIX, TYPE) \
|
||||||
|
enum PREFIX { TYPE(PIX_ENUM_ID) }; \
|
||||||
|
constexpr char const* PREFIX ## Str [] { TYPE(PIX_ENUM_STR) }
|
||||||
|
|
||||||
|
|
||||||
|
#define PIX_ERROR(NAME) \
|
||||||
|
struct NAME : public std::runtime_error { \
|
||||||
|
explicit NAME(std::string const& what) \
|
||||||
|
: std::runtime_error {what} \
|
||||||
|
{ \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include "Window.hpp"
|
||||||
|
#include "../Presenter.hpp"
|
||||||
|
#include "qnamespace.h"
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
/*explicit*/ Window::Window(Presenter& presenter, QWidget* parent)
|
||||||
|
: QMainWindow(parent)
|
||||||
|
, m_presenter { presenter }
|
||||||
|
{
|
||||||
|
m_ui.setupUi(this);
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Window::~Window()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::keyPressEvent(QKeyEvent* event) /*override*/
|
||||||
|
{
|
||||||
|
auto combination = event->keyCombination();
|
||||||
|
|
||||||
|
if (event->key() == Qt::Key_Control
|
||||||
|
|| event->key() == Qt::Key_Alt
|
||||||
|
|| event->key() == Qt::Key_Shift)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string key(1, 'a' + (combination.key() - Qt::Key_A));
|
||||||
|
|
||||||
|
int mods = 0;
|
||||||
|
|
||||||
|
if ((combination.keyboardModifiers() & Qt::ControlModifier) != 0)
|
||||||
|
{
|
||||||
|
mods |= PIX_MOD(PIX_CTRL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((combination.keyboardModifiers() & Qt::ShiftModifier) != 0)
|
||||||
|
{
|
||||||
|
mods |= PIX_MOD(PIX_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((combination.keyboardModifiers() & Qt::AltModifier) != 0)
|
||||||
|
{
|
||||||
|
mods |= PIX_MOD(PIX_ALT);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_presenter.on_key_pressed(KeyMod {key, mods});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef pix_WINDOW_HPP
|
||||||
|
#define pix_WINDOW_HPP
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include "ui_window.h"
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class MainWindow;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
class Presenter;
|
||||||
|
|
||||||
|
class Window: public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Window(Presenter& presenter, QWidget* parent=nullptr);
|
||||||
|
virtual ~Window();
|
||||||
|
|
||||||
|
void keyPressEvent(QKeyEvent* event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Presenter& m_presenter;
|
||||||
|
Ui::MainWindow m_ui;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>599</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Pix Draw Studio</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QGridLayout" name="gridLayout"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -0,0 +1,43 @@
|
||||||
|
#include "KeyMod.hpp"
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
/*explicit*/ KeyMod::KeyMod(std::string const& key, int mods)
|
||||||
|
: m_key { key }
|
||||||
|
, m_mods { mods }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ KeyMod::~KeyMod()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string KeyMod::string() const
|
||||||
|
{
|
||||||
|
std::string res;
|
||||||
|
|
||||||
|
if (PIX_HAS_MOD(m_mods, PIX_CTRL))
|
||||||
|
{
|
||||||
|
res += "C-";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PIX_HAS_MOD(m_mods, PIX_ALT))
|
||||||
|
{
|
||||||
|
res += "A-";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PIX_HAS_MOD(m_mods, PIX_SHIFT))
|
||||||
|
{
|
||||||
|
res += "S-";
|
||||||
|
}
|
||||||
|
|
||||||
|
res += m_key;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyMod::equals(KeyMod const& keymod) const
|
||||||
|
{
|
||||||
|
return m_key == keymod.m_key && m_mods == keymod.m_mods;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef pds_KEYMOD_HPP
|
||||||
|
#define pds_KEYMOD_HPP
|
||||||
|
|
||||||
|
#include "../commons.hpp"
|
||||||
|
|
||||||
|
#define PIX_KEYMOD_TYPES(G) \
|
||||||
|
G(PIX_NONE), \
|
||||||
|
G(PIX_CTRL), \
|
||||||
|
G(PIX_ALT), \
|
||||||
|
G(PIX_SHIFT)
|
||||||
|
|
||||||
|
#define PIX_MOD(MOD) (1 << MOD)
|
||||||
|
#define PIX_HAS_MOD(FLAGS, MOD) ( (FLAGS & PIX_MOD(MOD)) != 0 )
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
PIX_ENUM(KeyModType, PIX_KEYMOD_TYPES);
|
||||||
|
|
||||||
|
class KeyMod
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit KeyMod(std::string const& key, int mods=0);
|
||||||
|
virtual ~KeyMod();
|
||||||
|
|
||||||
|
std::string string() const;
|
||||||
|
bool equals(KeyMod const& keymod) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_key;
|
||||||
|
int m_mods;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,65 @@
|
||||||
|
#include "Shortcut.hpp"
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
/*explicit*/ Shortcut::Shortcut()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*explicit*/ Shortcut::Shortcut(std::string const& repr)
|
||||||
|
{
|
||||||
|
std::string buffer;
|
||||||
|
int mods = 0;
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while (i < repr.size())
|
||||||
|
{
|
||||||
|
char c = repr.at(i);
|
||||||
|
|
||||||
|
if (std::isspace(c))
|
||||||
|
{
|
||||||
|
if (buffer.empty() == false)
|
||||||
|
{
|
||||||
|
m_keymods.push_back(KeyMod(buffer, mods));
|
||||||
|
buffer.clear();
|
||||||
|
mods = 0;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if (i + 1 < repr.size() && repr.at(i + 1) == '-')
|
||||||
|
{
|
||||||
|
if (c == 'C')
|
||||||
|
{
|
||||||
|
mods |= PIX_MOD(PIX_CTRL);
|
||||||
|
}
|
||||||
|
else if (c == 'A')
|
||||||
|
{
|
||||||
|
mods |= PIX_MOD(PIX_ALT);
|
||||||
|
}
|
||||||
|
else if (c == 'S')
|
||||||
|
{
|
||||||
|
mods |= PIX_MOD(PIX_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer += c;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer.empty() == false)
|
||||||
|
{
|
||||||
|
m_keymods.push_back(KeyMod(buffer, mods));
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Shortcut::~Shortcut()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef pix_SHORTCUT_HPP
|
||||||
|
#define pix_SHORTCUT_HPP
|
||||||
|
|
||||||
|
#include "KeyMod.hpp"
|
||||||
|
|
||||||
|
namespace pix
|
||||||
|
{
|
||||||
|
class Shortcut
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Shortcut();
|
||||||
|
explicit Shortcut(std::string const& repr);
|
||||||
|
virtual ~Shortcut();
|
||||||
|
|
||||||
|
size_t size() const { return m_keymods.size(); }
|
||||||
|
KeyMod const& get(size_t index) const { return m_keymods.at(index); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<KeyMod> m_keymods;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <QApplication>
|
||||||
|
#include "Presenter.hpp"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
QApplication app {argc, argv};
|
||||||
|
|
||||||
|
pix::Presenter presenter;
|
||||||
|
presenter.start();
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
cmake_minimum_required(VERSION 3.2)
|
||||||
|
|
||||||
|
project(pix-draw-studio-tests)
|
||||||
|
find_package(Catch2 REQUIRED)
|
||||||
|
|
||||||
|
add_executable(pix-test
|
||||||
|
main.cpp
|
||||||
|
|
||||||
|
# keys
|
||||||
|
KeyMod.cpp
|
||||||
|
Shortcut.cpp
|
||||||
|
ShortcutListener.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(pix-test
|
||||||
|
$<TARGET_OBJECTS:pixlib>
|
||||||
|
)
|
|
@ -0,0 +1,42 @@
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
#include "../src/keys/KeyMod.hpp"
|
||||||
|
|
||||||
|
class KeyModTest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit KeyModTest() {}
|
||||||
|
virtual ~KeyModTest() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(KeyModTest, "KeyMod_to_string")
|
||||||
|
{
|
||||||
|
SECTION("simple")
|
||||||
|
{
|
||||||
|
pix::KeyMod km {"a"};
|
||||||
|
REQUIRE(km.string() == "a");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("one modifier")
|
||||||
|
{
|
||||||
|
pix::KeyMod km {"a", PIX_MOD(pix::PIX_CTRL)};
|
||||||
|
REQUIRE(km.string() == "C-a");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two modifiers")
|
||||||
|
{
|
||||||
|
pix::KeyMod km {"z",
|
||||||
|
PIX_MOD(pix::PIX_CTRL)
|
||||||
|
| PIX_MOD(pix::PIX_ALT)};
|
||||||
|
REQUIRE(km.string() == "C-A-z");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two modifiers reversed")
|
||||||
|
{
|
||||||
|
pix::KeyMod km {"k",
|
||||||
|
PIX_MOD(pix::PIX_SHIFT)
|
||||||
|
| PIX_MOD(pix::PIX_CTRL)};
|
||||||
|
REQUIRE(km.string() == "C-S-k");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
#include "../src/keys/Shortcut.hpp"
|
||||||
|
|
||||||
|
class ShortcutTest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ShortcutTest() {}
|
||||||
|
virtual ~ShortcutTest() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(ShortcutTest, "Shortcut_from_string")
|
||||||
|
{
|
||||||
|
pix::Shortcut sc {"C-a A-b c C-S-s"};
|
||||||
|
|
||||||
|
REQUIRE(sc.size() == 4);
|
||||||
|
REQUIRE(sc.get(0).string() == "C-a");
|
||||||
|
REQUIRE(sc.get(1).string() == "A-b");
|
||||||
|
REQUIRE(sc.get(2).string() == "c");
|
||||||
|
REQUIRE(sc.get(3).string() == "C-S-s");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(ShortcutTest, "Shortcut_to_string")
|
||||||
|
{
|
||||||
|
pix::Shortcut sc;
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
#include "../src/cmd/ShortcutListener.hpp"
|
||||||
|
#include "../src/cmd/Command.hpp"
|
||||||
|
#include "../src/keys/KeyMod.hpp"
|
||||||
|
|
||||||
|
class ShortcutListenerTest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ShortcutListenerTest() {}
|
||||||
|
virtual ~ShortcutListenerTest() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
pix::ShortcutListener sl;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CmdMock: public pix::Command {
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
CmdMock(): pix::Command("Command Mock")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute() override
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(ShortcutListenerTest, "ShortcutListener_OneCommand")
|
||||||
|
{
|
||||||
|
auto cmd = std::make_shared<CmdMock>();
|
||||||
|
|
||||||
|
sl.bind("a", cmd);
|
||||||
|
|
||||||
|
REQUIRE(cmd->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"b"});
|
||||||
|
REQUIRE(cmd->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"a"});
|
||||||
|
REQUIRE(cmd->count == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(ShortcutListenerTest, "ShortcutListener_LongerShortcut")
|
||||||
|
{
|
||||||
|
auto cmd_0 = std::make_shared<CmdMock>();
|
||||||
|
|
||||||
|
sl.bind("a b C-c A-d", cmd_0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"a"});
|
||||||
|
REQUIRE(cmd_0->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"b"});
|
||||||
|
REQUIRE(cmd_0->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"c", PIX_MOD(pix::PIX_CTRL)});
|
||||||
|
REQUIRE(cmd_0->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"d", PIX_MOD(pix::PIX_ALT)});
|
||||||
|
REQUIRE(cmd_0->count == 1);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"d", PIX_MOD(pix::PIX_CTRL)});
|
||||||
|
REQUIRE(cmd_0->count == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(ShortcutListenerTest, "ShortcutListener_CommandFailed")
|
||||||
|
{
|
||||||
|
auto cmd = std::make_shared<CmdMock>();
|
||||||
|
|
||||||
|
sl.bind("b a t", cmd);
|
||||||
|
|
||||||
|
REQUIRE(cmd->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"b"});
|
||||||
|
REQUIRE(cmd->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"a"});
|
||||||
|
REQUIRE(cmd->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"b"});
|
||||||
|
REQUIRE(cmd->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"a"});
|
||||||
|
REQUIRE(cmd->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"t"});
|
||||||
|
REQUIRE(cmd->count == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(ShortcutListenerTest, "ShortcutListener_FailedMiddle")
|
||||||
|
{
|
||||||
|
auto cmd = std::make_shared<CmdMock>();
|
||||||
|
|
||||||
|
sl.bind("b a t", cmd);
|
||||||
|
|
||||||
|
REQUIRE(cmd->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"b"});
|
||||||
|
REQUIRE(cmd->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"a"});
|
||||||
|
REQUIRE(cmd->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"x"});
|
||||||
|
REQUIRE(cmd->count == 0);
|
||||||
|
|
||||||
|
sl.update(pix::KeyMod {"t"});
|
||||||
|
REQUIRE(cmd->count == 0);
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include <catch2/catch.hpp>
|
Reference in New Issue