✨ quit command.
parent
41cc81c70b
commit
470e656713
11
Makefile
11
Makefile
|
@ -1,8 +1,15 @@
|
|||
.PHONY: build install
|
||||
.PHONY: build tests install
|
||||
|
||||
build:
|
||||
meson setup build
|
||||
meson compile -C build
|
||||
|
||||
install: build
|
||||
tests: build
|
||||
build/pixtool-tests
|
||||
|
||||
install: tests
|
||||
meson install -C build
|
||||
|
||||
check:
|
||||
cppcheck --language=c++ --enable=all -q src \
|
||||
--suppress=missingInclude
|
||||
|
|
42
meson.build
42
meson.build
|
@ -26,20 +26,54 @@ qt_src = qt6.compile_moc(
|
|||
]
|
||||
)
|
||||
|
||||
executable(
|
||||
'pixtool',
|
||||
pixtool = static_library(
|
||||
'pixtool-core',
|
||||
sources: [
|
||||
'src/main.cpp',
|
||||
'src/Presenter.cpp',
|
||||
|
||||
# model
|
||||
'src/pixtool/PixTool.cpp',
|
||||
'src/model/PixTool.cpp',
|
||||
'src/model/Command.cpp',
|
||||
'src/model/Shortcut.cpp',
|
||||
'src/model/CommandRunner.cpp',
|
||||
'src/model/Observer.cpp',
|
||||
'src/model/Observable.cpp',
|
||||
|
||||
# gui
|
||||
'src/gui/Window.cpp',
|
||||
] + qt_src,
|
||||
dependencies: [
|
||||
qt6_dep,
|
||||
dependency('spdlog')
|
||||
]
|
||||
)
|
||||
|
||||
pixtool_dep = declare_dependency(
|
||||
link_with: [pixtool],
|
||||
include_directories: ['src']
|
||||
)
|
||||
|
||||
executable(
|
||||
'pixtool',
|
||||
sources: [
|
||||
'src/main.cpp'
|
||||
],
|
||||
dependencies: [
|
||||
pixtool_dep,
|
||||
qt6_dep
|
||||
],
|
||||
install: true
|
||||
)
|
||||
|
||||
executable(
|
||||
'pixtool-tests',
|
||||
sources: [
|
||||
'tests/main.cpp',
|
||||
'tests/CommandRunner.cpp',
|
||||
],
|
||||
dependencies: [
|
||||
dependency('catch2'),
|
||||
pixtool_dep
|
||||
],
|
||||
install: true
|
||||
)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "Presenter.hpp"
|
||||
#include "src/model/Event.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
|
@ -11,4 +12,17 @@ namespace pt
|
|||
/*virtual*/ Presenter::~Presenter()
|
||||
{
|
||||
}
|
||||
|
||||
void Presenter::update(model::Event& event) /*override*/
|
||||
{
|
||||
if (event.type == model::EVENT_KEYPRESSED)
|
||||
{
|
||||
m_pixtool.update(event.key_pressed.keymod);
|
||||
}
|
||||
|
||||
if (event.type == model::EVENT_QUIT)
|
||||
{
|
||||
m_pixtool.quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
#ifndef pt_PRESENTER_HPP
|
||||
#define pt_PRESENTER_HPP
|
||||
|
||||
#include "pixtool/PixTool.hpp"
|
||||
#include "model/PixTool.hpp"
|
||||
#include "gui/Window.hpp"
|
||||
#include "model/Shortcut.hpp"
|
||||
#include "model/Observer.hpp"
|
||||
#include "src/model/Event.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
class Presenter
|
||||
class Presenter: public model::Observer
|
||||
{
|
||||
public:
|
||||
explicit Presenter(gui::Window& window, model::PixTool& pixtool);
|
||||
virtual ~Presenter();
|
||||
|
||||
void update(model::Event& event) override;
|
||||
private:
|
||||
gui::Window& m_window;
|
||||
model::PixTool& m_pixtool;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef pt_COMMONS_HPP
|
||||
#define pt_COMMONS_HPP
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include "conf.hpp"
|
||||
|
||||
#define PT_GEN_STR(X) #X
|
||||
#define PT_GEN_ID(X) X
|
||||
|
||||
#define PT_ENUM(PREFIX, ENUM) \
|
||||
enum PREFIX { ENUM(PT_GEN_ID) }; \
|
||||
constexpr char const* PREFIX ## Str [] = { ENUM(PT_GEN_STR) }
|
||||
|
||||
|
||||
#define PT_ERROR(NAME) \
|
||||
struct NAME : public std::runtime_error \
|
||||
{ \
|
||||
NAME ( std::string const& what ) \
|
||||
: std::runtime_error {what} \
|
||||
{ \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -1,5 +1,11 @@
|
|||
#include <QKeyEvent>
|
||||
#include "../model/Shortcut.hpp"
|
||||
#include "Window.hpp"
|
||||
#include "conf.hpp"
|
||||
#include "qmainwindow.h"
|
||||
#include "qnamespace.h"
|
||||
#include "src/model/Event.hpp"
|
||||
#include <QMenuBar>
|
||||
|
||||
namespace pt
|
||||
{
|
||||
|
@ -11,11 +17,56 @@ namespace pt
|
|||
setWindowTitle(QString::fromStdString("PixTool v" + PT_VERSION));
|
||||
setMinimumSize(QSize {640, 480});
|
||||
|
||||
QMenuBar* bar = new QMenuBar {this};
|
||||
|
||||
QMenu* file = new QMenu {"File"};
|
||||
bar->addMenu(file);
|
||||
|
||||
QAction* quit = new QAction {"Quit"};
|
||||
file->addAction(quit);
|
||||
|
||||
connect(quit, &QAction::triggered, [this](){
|
||||
model::Event ev {model::EVENT_QUIT};
|
||||
notify(ev);
|
||||
});
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
/*virtual*/ Window::~Window()
|
||||
{
|
||||
}
|
||||
|
||||
void Window::keyPressEvent(QKeyEvent* event) /*override*/
|
||||
{
|
||||
std::vector<model::ModType> mods;
|
||||
|
||||
auto mods_flag = event->modifiers();
|
||||
|
||||
if (mods_flag & Qt::ControlModifier)
|
||||
{
|
||||
mods.push_back(model::PT_CONTROL);
|
||||
}
|
||||
|
||||
if (mods_flag & Qt::AltModifier)
|
||||
{
|
||||
mods.push_back(model::PT_ALT);
|
||||
}
|
||||
|
||||
if (mods_flag & Qt::ShiftModifier)
|
||||
{
|
||||
mods.push_back(model::PT_SHIFT);
|
||||
}
|
||||
|
||||
char key = 'A' + (event->key() - Qt::Key_A);
|
||||
|
||||
if (key >= 'A' && key <= 'Z')
|
||||
{
|
||||
model::KeyMod km {std::string(1, key), mods};
|
||||
model::Event e {model::EVENT_KEYPRESSED};
|
||||
e.key_pressed.keymod = km;
|
||||
notify(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,18 +2,23 @@
|
|||
#define pt_gui_WINDOW_HPP
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "../commons.hpp"
|
||||
#include "src/model/Shortcut.hpp"
|
||||
#include "../model/Observable.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
class Window: public QMainWindow
|
||||
class Window: public QMainWindow, public model::Observable
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Window(QWidget* parent=nullptr);
|
||||
virtual ~Window();
|
||||
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
|
|
10
src/main.cpp
10
src/main.cpp
|
@ -1,18 +1,24 @@
|
|||
#include <iostream>
|
||||
#include <QApplication>
|
||||
#include "pixtool/PixTool.hpp"
|
||||
#include "model/PixTool.hpp"
|
||||
#include "gui/Window.hpp"
|
||||
#include "Presenter.hpp"
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
spdlog::set_level(spdlog::level::debug);
|
||||
|
||||
QApplication app {argc, argv};
|
||||
|
||||
pt::gui::Window window;
|
||||
|
||||
pt::model::PixTool pixtool;
|
||||
|
||||
pt::Presenter presenter {window, pixtool};
|
||||
auto presenter = std::make_shared<pt::Presenter>(window, pixtool);
|
||||
window.add_observer(presenter);
|
||||
|
||||
pixtool.ready();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#include "Command.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
/*explicit*/ Command::Command(std::string const& name)
|
||||
: m_name { name }
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ Command::~Command()
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ void Command::execute(PixTool& /*pixtool*/)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef pt_model_COMMAND_HPP
|
||||
#define pt_model_COMMAND_HPP
|
||||
|
||||
#include "../commons.hpp"
|
||||
#include "PixTool.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
class Command
|
||||
{
|
||||
public:
|
||||
explicit Command(std::string const& name);
|
||||
virtual ~Command();
|
||||
|
||||
inline std::string name() const { return m_name; }
|
||||
|
||||
virtual void execute(PixTool& pixtool);
|
||||
private:
|
||||
std::string m_name;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,62 @@
|
|||
#include <spdlog/spdlog.h>
|
||||
#include "CommandRunner.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
/*explicit*/ CommandRunner::CommandRunner(PixTool& pixtool)
|
||||
: m_pixtool(pixtool)
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ CommandRunner::~CommandRunner()
|
||||
{
|
||||
}
|
||||
|
||||
void CommandRunner::bind(Shortcut const& shortcut, std::shared_ptr<Command> command)
|
||||
{
|
||||
m_entries.push_back(CommandEntry {shortcut, command});
|
||||
}
|
||||
|
||||
void CommandRunner::update(KeyMod const& keymod)
|
||||
{
|
||||
for (auto& entry: m_entries)
|
||||
{
|
||||
if (entry.shortcut.key(entry.index) == keymod)
|
||||
{
|
||||
entry.index++;
|
||||
|
||||
if (entry.index >= entry.shortcut.size())
|
||||
{
|
||||
entry.index = 0;
|
||||
execute(entry.command);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (entry.shortcut.key(0) == keymod)
|
||||
{
|
||||
entry.index = 1;
|
||||
|
||||
if (entry.index >= entry.shortcut.size())
|
||||
{
|
||||
entry.index = 0;
|
||||
execute(entry.command);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommandRunner::execute(std::shared_ptr<Command> command)
|
||||
{
|
||||
spdlog::debug("exec '" + command->name() + "'");
|
||||
command->execute(m_pixtool);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef pt_model_COMMANDRUNNER_HPP
|
||||
#define pt_model_COMMANDRUNNER_HPP
|
||||
|
||||
#include "../commons.hpp"
|
||||
#include "Shortcut.hpp"
|
||||
#include "Command.hpp"
|
||||
|
||||
#include "PixTool.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
struct CommandEntry
|
||||
{
|
||||
Shortcut shortcut;
|
||||
std::shared_ptr<Command> command;
|
||||
size_t index = 0;
|
||||
};
|
||||
|
||||
class CommandRunner
|
||||
{
|
||||
public:
|
||||
explicit CommandRunner(PixTool& pixtool);
|
||||
virtual ~CommandRunner();
|
||||
|
||||
void bind(Shortcut const& shortcut, std::shared_ptr<Command> command);
|
||||
void update(KeyMod const& keymod);
|
||||
|
||||
private:
|
||||
PixTool& m_pixtool;
|
||||
std::vector<CommandEntry> m_entries;
|
||||
|
||||
void execute(std::shared_ptr<Command> command);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef pt_model_EVENT_HPP
|
||||
#define pt_model_EVENT_HPP
|
||||
|
||||
#include "../commons.hpp"
|
||||
#include "Shortcut.hpp"
|
||||
|
||||
#define EVENT_TYPE(G) \
|
||||
G(EVENT_KEYPRESSED), \
|
||||
G(EVENT_QUIT)
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
PT_ENUM(EventType, EVENT_TYPE);
|
||||
|
||||
struct EventKeyPressed
|
||||
{
|
||||
KeyMod keymod {""};
|
||||
};
|
||||
|
||||
struct Event
|
||||
{
|
||||
explicit Event(EventType ty) : type { ty } {}
|
||||
EventType type;
|
||||
|
||||
EventKeyPressed key_pressed;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
#include "Observable.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
/*explicit*/ Observable::Observable()
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ Observable::~Observable()
|
||||
{
|
||||
}
|
||||
|
||||
void Observable::add_observer(std::shared_ptr<Observer> observer)
|
||||
{
|
||||
m_observers.push_back(observer);
|
||||
}
|
||||
|
||||
void Observable::notify(Event& event)
|
||||
{
|
||||
for (auto observer: m_observers)
|
||||
{
|
||||
if (auto ob = observer.lock(); ob)
|
||||
{
|
||||
ob->update(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef pt_model_OBSERVABLE_HPP
|
||||
#define pt_model_OBSERVABLE_HPP
|
||||
|
||||
#include "../commons.hpp"
|
||||
#include "Event.hpp"
|
||||
#include "Observer.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
class Observable
|
||||
{
|
||||
public:
|
||||
explicit Observable();
|
||||
virtual ~Observable();
|
||||
|
||||
void add_observer(std::shared_ptr<Observer> observer);
|
||||
void notify(Event& event);
|
||||
|
||||
private:
|
||||
std::vector<std::weak_ptr<Observer>> m_observers;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
#include "Observer.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
/*explicit*/ Observer::Observer()
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ Observer::~Observer()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef pt_model_OBSERVER_HPP
|
||||
#define pt_model_OBSERVER_HPP
|
||||
|
||||
#include "../commons.hpp"
|
||||
#include "Event.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
class Observer
|
||||
{
|
||||
public:
|
||||
explicit Observer();
|
||||
virtual ~Observer();
|
||||
|
||||
virtual void update(Event& event) = 0;
|
||||
private:
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
#include <spdlog/spdlog.h>
|
||||
#include "PixTool.hpp"
|
||||
#include "CommandRunner.hpp"
|
||||
#include "cmds/Quit.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
/*explicit*/ PixTool::PixTool()
|
||||
: m_cmd_runner { std::make_unique<CommandRunner>(*this) }
|
||||
{
|
||||
m_cmd_runner->bind(Shortcut {{KeyMod {"X", {PT_CONTROL}},
|
||||
KeyMod {"C", {PT_CONTROL}}}},
|
||||
std::make_shared<cmds::Quit>());
|
||||
}
|
||||
|
||||
/*virtual*/ PixTool::~PixTool()
|
||||
{
|
||||
}
|
||||
|
||||
void PixTool::ready()
|
||||
{
|
||||
spdlog::info("ready");
|
||||
}
|
||||
|
||||
void PixTool::update(KeyMod const& km)
|
||||
{
|
||||
m_cmd_runner->update(km);
|
||||
}
|
||||
|
||||
void PixTool::quit()
|
||||
{
|
||||
spdlog::info("done");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +1,27 @@
|
|||
#ifndef pt_model_PIXTOOL_HPP
|
||||
#define pt_model_PIXTOOL_HPP
|
||||
|
||||
#include "../commons.hpp"
|
||||
#include "Shortcut.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
class CommandRunner;
|
||||
|
||||
class PixTool
|
||||
{
|
||||
public:
|
||||
explicit PixTool();
|
||||
virtual ~PixTool();
|
||||
|
||||
void ready();
|
||||
void update(KeyMod const& km);
|
||||
void quit();
|
||||
|
||||
private:
|
||||
std::unique_ptr<CommandRunner> m_cmd_runner;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#include "Shortcut.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
/*explicit*/ Shortcut::Shortcut(std::vector<KeyMod> const& keymods)
|
||||
: m_keymods { keymods }
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ Shortcut::~Shortcut()
|
||||
{
|
||||
}
|
||||
|
||||
std::string Shortcut::string() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
std::string sep;
|
||||
|
||||
for (auto const& km: m_keymods)
|
||||
{
|
||||
ss << sep;
|
||||
sep = " ";
|
||||
|
||||
for (auto const& mod: km.mods)
|
||||
{
|
||||
ss << (ModTypeStr[mod] + strlen("PT_")) << "-";
|
||||
}
|
||||
|
||||
ss << km.key;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
KeyMod Shortcut::key(size_t index) const
|
||||
{
|
||||
assert(index < m_keymods.size());
|
||||
return m_keymods[index];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef pt_model_SHORTCUT_HPP
|
||||
#define pt_model_SHORTCUT_HPP
|
||||
|
||||
#include "../commons.hpp"
|
||||
|
||||
#define PT_KEYMOD(G) G(PT_NONE), G(PT_CONTROL), G(PT_ALT), G(PT_SHIFT)
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
PT_ENUM(ModType, PT_KEYMOD);
|
||||
|
||||
struct KeyMod
|
||||
{
|
||||
std::string key;
|
||||
std::vector<ModType> mods;
|
||||
|
||||
explicit KeyMod(std::string const& k)
|
||||
: KeyMod(k, {})
|
||||
{
|
||||
}
|
||||
|
||||
explicit KeyMod(std::string const& k, std::vector<ModType> const& m)
|
||||
: key { k }
|
||||
, mods { m }
|
||||
{
|
||||
}
|
||||
|
||||
inline bool operator==(KeyMod const& rhs)
|
||||
{
|
||||
if (key != rhs.key || mods.size() != rhs.mods.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i=0; i<mods.size(); i++)
|
||||
{
|
||||
if (mods[i] != rhs.mods[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class Shortcut
|
||||
{
|
||||
public:
|
||||
explicit Shortcut(std::vector<KeyMod> const& keymods);
|
||||
virtual ~Shortcut();
|
||||
|
||||
std::string string() const;
|
||||
KeyMod key(size_t index) const;
|
||||
|
||||
inline size_t size() const { return m_keymods.size(); }
|
||||
|
||||
private:
|
||||
std::vector<KeyMod> m_keymods;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef pt_cmds_QUIT_HPP
|
||||
#define pt_cmds_QUIT_HPP
|
||||
|
||||
#include "../../commons.hpp"
|
||||
#include "../Command.hpp"
|
||||
#include "src/model/PixTool.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace cmds
|
||||
{
|
||||
class Quit: public model::Command
|
||||
{
|
||||
public:
|
||||
explicit Quit():
|
||||
Command("quit")
|
||||
{
|
||||
}
|
||||
|
||||
void execute(model::PixTool& pixtool) override
|
||||
{
|
||||
pixtool.quit();
|
||||
}
|
||||
private:
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||
#include "PixTool.hpp"
|
||||
|
||||
namespace pt
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
/*explicit*/ PixTool::PixTool()
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ PixTool::~PixTool()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
#include <catch2/catch.hpp>
|
||||
#include "model/Command.hpp"
|
||||
#include "model/CommandRunner.hpp"
|
||||
#include "model/PixTool.hpp"
|
||||
#include "model/Shortcut.hpp"
|
||||
|
||||
using namespace pt::model;
|
||||
|
||||
class CommandRunnerTest
|
||||
{
|
||||
public:
|
||||
explicit CommandRunnerTest() {}
|
||||
virtual ~CommandRunnerTest() {}
|
||||
|
||||
protected:
|
||||
PixTool m_pixtool;
|
||||
CommandRunner m_runner {m_pixtool};
|
||||
};
|
||||
|
||||
struct CommandMock: public Command
|
||||
{
|
||||
int exec_count = 0;
|
||||
|
||||
explicit CommandMock(): Command("mock") {}
|
||||
|
||||
virtual void execute(PixTool&) override
|
||||
{
|
||||
exec_count++;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE_METHOD(CommandRunnerTest, "CommandRunner_one_key")
|
||||
{
|
||||
|
||||
auto cmd = std::make_shared<CommandMock>();
|
||||
|
||||
m_runner.bind(Shortcut {{KeyMod {"a"}}}, cmd);
|
||||
REQUIRE(cmd->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"b"});
|
||||
REQUIRE(cmd->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"a"});
|
||||
REQUIRE(cmd->exec_count == 1);
|
||||
|
||||
m_runner.update(KeyMod {"b"});
|
||||
REQUIRE(cmd->exec_count == 1);
|
||||
|
||||
m_runner.update(KeyMod {"a"});
|
||||
REQUIRE(cmd->exec_count == 2);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE_METHOD(CommandRunnerTest, "CommandRunner_three_keys")
|
||||
{
|
||||
|
||||
auto cmd = std::make_shared<CommandMock>();
|
||||
|
||||
m_runner.bind(Shortcut {{KeyMod {"a"},
|
||||
KeyMod {"b", {PT_CONTROL}},
|
||||
KeyMod {"c", {PT_ALT}}}}, cmd);
|
||||
|
||||
REQUIRE(cmd->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"a"});
|
||||
REQUIRE(cmd->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"b", {PT_CONTROL}});
|
||||
REQUIRE(cmd->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"c", {PT_ALT}});
|
||||
REQUIRE(cmd->exec_count == 1);
|
||||
|
||||
m_runner.update(KeyMod {"a"});
|
||||
REQUIRE(cmd->exec_count == 1);
|
||||
|
||||
m_runner.update(KeyMod {"b"});
|
||||
REQUIRE(cmd->exec_count == 1);
|
||||
|
||||
m_runner.update(KeyMod {"c", {PT_ALT}});
|
||||
REQUIRE(cmd->exec_count == 1);
|
||||
|
||||
m_runner.update(KeyMod {"a"});
|
||||
REQUIRE(cmd->exec_count == 1);
|
||||
|
||||
m_runner.update(KeyMod {"b", {PT_CONTROL}});
|
||||
REQUIRE(cmd->exec_count == 1);
|
||||
|
||||
m_runner.update(KeyMod {"a"});
|
||||
REQUIRE(cmd->exec_count == 1);
|
||||
|
||||
m_runner.update(KeyMod {"a"});
|
||||
REQUIRE(cmd->exec_count == 1);
|
||||
|
||||
m_runner.update(KeyMod {"a"});
|
||||
REQUIRE(cmd->exec_count == 1);
|
||||
|
||||
m_runner.update(KeyMod {"b", {PT_CONTROL}});
|
||||
REQUIRE(cmd->exec_count == 1);
|
||||
|
||||
m_runner.update(KeyMod {"c", {PT_ALT}});
|
||||
REQUIRE(cmd->exec_count == 2);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(CommandRunnerTest, "CommandRunner_two_commands")
|
||||
{
|
||||
auto cmd0 = std::make_shared<CommandMock>();
|
||||
auto cmd1 = std::make_shared<CommandMock>();
|
||||
|
||||
m_runner.bind(Shortcut {{KeyMod {"a"},
|
||||
KeyMod {"b"},
|
||||
KeyMod {"c"}}}, cmd0);
|
||||
|
||||
m_runner.bind(Shortcut {{KeyMod {"c"},
|
||||
KeyMod {"d"},
|
||||
KeyMod {"e"}}}, cmd1);
|
||||
|
||||
m_runner.update(KeyMod {"a"});
|
||||
REQUIRE(cmd0->exec_count == 0);
|
||||
REQUIRE(cmd1->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"b"});
|
||||
REQUIRE(cmd0->exec_count == 0);
|
||||
REQUIRE(cmd1->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"c"});
|
||||
REQUIRE(cmd0->exec_count == 1);
|
||||
REQUIRE(cmd1->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"d"});
|
||||
REQUIRE(cmd0->exec_count == 1);
|
||||
REQUIRE(cmd1->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"e"});
|
||||
REQUIRE(cmd0->exec_count == 1);
|
||||
REQUIRE(cmd1->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"c"});
|
||||
REQUIRE(cmd0->exec_count == 1);
|
||||
REQUIRE(cmd1->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"d"});
|
||||
REQUIRE(cmd0->exec_count == 1);
|
||||
REQUIRE(cmd1->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"e"});
|
||||
REQUIRE(cmd0->exec_count == 1);
|
||||
REQUIRE(cmd1->exec_count == 1);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(CommandRunnerTest, "CommandRunner_wrong_key")
|
||||
{
|
||||
auto cmd = std::make_shared<CommandMock>();
|
||||
|
||||
m_runner.bind(Shortcut {{KeyMod {"C", {PT_CONTROL}},
|
||||
KeyMod {"X", {PT_CONTROL}}}},
|
||||
cmd);
|
||||
|
||||
REQUIRE(cmd->exec_count == 0);
|
||||
|
||||
m_runner.update(KeyMod {"C", {PT_CONTROL}});
|
||||
m_runner.update(KeyMod {"V", {PT_CONTROL}});
|
||||
m_runner.update(KeyMod {"X", {PT_CONTROL}});
|
||||
|
||||
REQUIRE(cmd->exec_count == 0);
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch2/catch.hpp>
|
Loading…
Reference in New Issue