Compare commits
No commits in common. "ba34df088ef3a5ab68c0e075d4a61bf7068556f8" and "41cc81c70b365d188846f67e11b83c68ed32f6ea" have entirely different histories.
ba34df088e
...
41cc81c70b
15
Makefile
15
Makefile
|
@ -1,19 +1,8 @@
|
||||||
.PHONY: build tests install i18n
|
.PHONY: build install
|
||||||
|
|
||||||
build:
|
build:
|
||||||
meson setup build
|
meson setup build
|
||||||
meson compile -C build
|
meson compile -C build
|
||||||
|
|
||||||
tests: build
|
install: build
|
||||||
build/pixtool-tests
|
|
||||||
|
|
||||||
install: tests
|
|
||||||
meson install -C build
|
meson install -C build
|
||||||
|
|
||||||
check:
|
|
||||||
cppcheck --language=c++ --enable=all -q src \
|
|
||||||
--suppress=missingInclude
|
|
||||||
|
|
||||||
i18n:
|
|
||||||
lupdate src -ts i18n/pix_en.ts
|
|
||||||
lupdate src -ts i18n/pix_fr.ts
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!DOCTYPE TS>
|
|
||||||
<TS version="2.1" language="en_US">
|
|
||||||
<context>
|
|
||||||
<name>QAction</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="46"/>
|
|
||||||
<source>new-project</source>
|
|
||||||
<translation>New Project</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="50"/>
|
|
||||||
<source>close-project</source>
|
|
||||||
<translation>Close Project</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="55"/>
|
|
||||||
<source>quit</source>
|
|
||||||
<translation>Quit</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>QDialog</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="119"/>
|
|
||||||
<source>new-project</source>
|
|
||||||
<translation>New Project</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>QLineEdit</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="124"/>
|
|
||||||
<source>new-project-name</source>
|
|
||||||
<translation>New project name</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>QMenu</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="43"/>
|
|
||||||
<source>file</source>
|
|
||||||
<translation>File</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>QPushButton</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="154"/>
|
|
||||||
<source>new-project</source>
|
|
||||||
<translation>New Project</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="158"/>
|
|
||||||
<source>cancel-new-project</source>
|
|
||||||
<translation>Cancel</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
</TS>
|
|
|
@ -1,59 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!DOCTYPE TS>
|
|
||||||
<TS version="2.1" language="fr_FR">
|
|
||||||
<context>
|
|
||||||
<name>QAction</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="46"/>
|
|
||||||
<source>new-project</source>
|
|
||||||
<translation>Nouveau Projet</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="50"/>
|
|
||||||
<source>close-project</source>
|
|
||||||
<translation>Fermer Projet</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="55"/>
|
|
||||||
<source>quit</source>
|
|
||||||
<translation>Quitter</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>QDialog</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="119"/>
|
|
||||||
<source>new-project</source>
|
|
||||||
<translation>Nouveau Projet</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>QLineEdit</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="124"/>
|
|
||||||
<source>new-project-name</source>
|
|
||||||
<translation>Nom du nouveau projet</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>QMenu</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="43"/>
|
|
||||||
<source>file</source>
|
|
||||||
<translation>Fichier</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>QPushButton</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="154"/>
|
|
||||||
<source>new-project</source>
|
|
||||||
<translation>Nouveau Projet</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/Window.cpp" line="158"/>
|
|
||||||
<source>cancel-new-project</source>
|
|
||||||
<translation>Annuler</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
</TS>
|
|
67
meson.build
67
meson.build
|
@ -1,18 +1,15 @@
|
||||||
project(
|
project(
|
||||||
'pixtool',
|
'pixtool',
|
||||||
'cpp',
|
'cpp',
|
||||||
version: '0.0',
|
version: '0.0.0',
|
||||||
default_options: [
|
default_options: [
|
||||||
'cpp_std=c++17',
|
'cpp_std=c++17',
|
||||||
'warning_level=3'
|
'warning_level=3'
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
data_dir = get_option('prefix') / get_option('datadir') / 'pixtool'
|
|
||||||
|
|
||||||
conf = configuration_data()
|
conf = configuration_data()
|
||||||
conf.set('version', meson.project_version())
|
conf.set('version', meson.project_version())
|
||||||
conf.set('datadir', data_dir)
|
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
input: 'src/conf.in.hpp',
|
input: 'src/conf.in.hpp',
|
||||||
|
@ -29,64 +26,20 @@ qt_src = qt6.compile_moc(
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
translations = qt6.compile_translations(
|
|
||||||
ts_files: [
|
|
||||||
'i18n/pix_en.ts',
|
|
||||||
'i18n/pix_fr.ts'
|
|
||||||
],
|
|
||||||
install: true,
|
|
||||||
install_dir: data_dir / 'i18n'
|
|
||||||
)
|
|
||||||
|
|
||||||
pixtool = static_library(
|
|
||||||
'pixtool-core',
|
|
||||||
sources: [
|
|
||||||
'src/Presenter.cpp',
|
|
||||||
|
|
||||||
# model
|
|
||||||
'src/model/PixTool.cpp',
|
|
||||||
'src/model/Project.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 + translations,
|
|
||||||
dependencies: [
|
|
||||||
qt6_dep,
|
|
||||||
dependency('spdlog')
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
pixtool_dep = declare_dependency(
|
|
||||||
link_with: [pixtool],
|
|
||||||
include_directories: ['src']
|
|
||||||
)
|
|
||||||
|
|
||||||
executable(
|
executable(
|
||||||
'pixtool',
|
'pixtool',
|
||||||
sources: [
|
sources: [
|
||||||
'src/main.cpp'
|
'src/main.cpp',
|
||||||
],
|
'src/Presenter.cpp',
|
||||||
|
|
||||||
|
# model
|
||||||
|
'src/pixtool/PixTool.cpp',
|
||||||
|
|
||||||
|
# gui
|
||||||
|
'src/gui/Window.cpp',
|
||||||
|
] + qt_src,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
pixtool_dep,
|
|
||||||
qt6_dep
|
qt6_dep
|
||||||
],
|
],
|
||||||
install: true
|
install: true
|
||||||
)
|
)
|
||||||
|
|
||||||
executable(
|
|
||||||
'pixtool-tests',
|
|
||||||
sources: [
|
|
||||||
'tests/main.cpp',
|
|
||||||
'tests/CommandRunner.cpp',
|
|
||||||
],
|
|
||||||
dependencies: [
|
|
||||||
dependency('catch2'),
|
|
||||||
pixtool_dep
|
|
||||||
],
|
|
||||||
install: true
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
#include "Presenter.hpp"
|
#include "Presenter.hpp"
|
||||||
#include "src/model/Event.hpp"
|
|
||||||
#include "model/Observable.hpp"
|
|
||||||
|
|
||||||
namespace pt
|
namespace pt
|
||||||
{
|
{
|
||||||
|
@ -13,62 +11,4 @@ namespace pt
|
||||||
/*virtual*/ Presenter::~Presenter()
|
/*virtual*/ Presenter::~Presenter()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Presenter::update(model::Observable& source, model::Event& event) /*override*/
|
|
||||||
{
|
|
||||||
if (&source == &m_pixtool)
|
|
||||||
{
|
|
||||||
update_pixtool(event);
|
|
||||||
}
|
|
||||||
else if (&source == &m_window)
|
|
||||||
{
|
|
||||||
update_window(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Presenter::update_pixtool(model::Event const& event)
|
|
||||||
{
|
|
||||||
if (event.type == model::EVENT_NEW_PROJECT)
|
|
||||||
{
|
|
||||||
m_window.show_project(event.project.name, event.project.dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.type == model::EVENT_QUERY_NEW_PROJECT)
|
|
||||||
{
|
|
||||||
m_window.on_new_project();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.type == model::EVENT_CLOSE_PROJECT)
|
|
||||||
{
|
|
||||||
m_window.hide_project();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.type == model::EVENT_QUERY_CLOSE_PROJECT)
|
|
||||||
{
|
|
||||||
m_window.on_close_project();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Presenter::update_window(model::Event const& event)
|
|
||||||
{
|
|
||||||
if (event.type == model::EVENT_KEYPRESSED)
|
|
||||||
{
|
|
||||||
m_pixtool.update(event.key_pressed.keymod);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.type == model::EVENT_QUIT)
|
|
||||||
{
|
|
||||||
m_pixtool.quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.type == model::EVENT_NEW_PROJECT)
|
|
||||||
{
|
|
||||||
m_pixtool.new_project(event.project.name, event.project.dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.type == model::EVENT_CLOSE_PROJECT)
|
|
||||||
{
|
|
||||||
m_pixtool.close_project();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,17 @@
|
||||||
#ifndef pt_PRESENTER_HPP
|
#ifndef pt_PRESENTER_HPP
|
||||||
#define pt_PRESENTER_HPP
|
#define pt_PRESENTER_HPP
|
||||||
|
|
||||||
#include "model/PixTool.hpp"
|
#include "pixtool/PixTool.hpp"
|
||||||
#include "gui/Window.hpp"
|
#include "gui/Window.hpp"
|
||||||
#include "model/Shortcut.hpp"
|
|
||||||
#include "model/Observer.hpp"
|
|
||||||
#include "src/model/Event.hpp"
|
|
||||||
|
|
||||||
namespace pt
|
namespace pt
|
||||||
{
|
{
|
||||||
class Presenter: public model::Observer
|
class Presenter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Presenter(gui::Window& window, model::PixTool& pixtool);
|
explicit Presenter(gui::Window& window, model::PixTool& pixtool);
|
||||||
virtual ~Presenter();
|
virtual ~Presenter();
|
||||||
|
|
||||||
void update(model::Observable& source, model::Event& event) override;
|
|
||||||
void update_pixtool(model::Event const& event);
|
|
||||||
void update_window(model::Event const& event);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gui::Window& m_window;
|
gui::Window& m_window;
|
||||||
model::PixTool& m_pixtool;
|
model::PixTool& m_pixtool;
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
#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,8 +1,6 @@
|
||||||
#ifndef pt_CONF_HPP
|
#ifndef pt_CONF_HPP
|
||||||
#define pt_CONF_HPP
|
#define pt_CONF_HPP
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#define PT_VERSION std::string("@version@")
|
#define PT_VERSION std::string("@version@")
|
||||||
#define PT_DATADIR std::filesystem::path("@datadir@")
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,22 +1,6 @@
|
||||||
#include "../model/Shortcut.hpp"
|
|
||||||
#include "qboxlayout.h"
|
|
||||||
#include "src/model/Event.hpp"
|
|
||||||
#include "Window.hpp"
|
#include "Window.hpp"
|
||||||
#include "conf.hpp"
|
#include "conf.hpp"
|
||||||
|
|
||||||
#include "qmainwindow.h"
|
|
||||||
#include "qnamespace.h"
|
|
||||||
#include "qtabwidget.h"
|
|
||||||
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include <QMenuBar>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QLineEdit>
|
|
||||||
#include <QPushButton>
|
|
||||||
|
|
||||||
namespace pt
|
namespace pt
|
||||||
{
|
{
|
||||||
namespace gui
|
namespace gui
|
||||||
|
@ -24,155 +8,14 @@ namespace pt
|
||||||
/*explicit*/ Window::Window(QWidget* parent)
|
/*explicit*/ Window::Window(QWidget* parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
{
|
{
|
||||||
setWindowTitle(QString::fromStdString(m_base_title));
|
setWindowTitle(QString::fromStdString("PixTool v" + PT_VERSION));
|
||||||
setMinimumSize(QSize {640, 480});
|
setMinimumSize(QSize {640, 480});
|
||||||
|
|
||||||
// Window layout
|
|
||||||
// =============
|
|
||||||
QWidget* central = new QWidget {};
|
|
||||||
|
|
||||||
setCentralWidget(central);
|
|
||||||
|
|
||||||
QVBoxLayout* vbox = new QVBoxLayout {central};
|
|
||||||
|
|
||||||
// Menu
|
|
||||||
// ====
|
|
||||||
QMenuBar* bar = new QMenuBar {};
|
|
||||||
vbox->addWidget(bar);
|
|
||||||
|
|
||||||
QMenu* file = new QMenu {QMenu::tr("file")};
|
|
||||||
bar->addMenu(file);
|
|
||||||
|
|
||||||
QAction* new_project = new QAction {QAction::tr("new-project")};
|
|
||||||
file->addAction(new_project);
|
|
||||||
connect(new_project, &QAction::triggered, this, &Window::on_new_project);
|
|
||||||
|
|
||||||
m_close_project = new QAction {QAction::tr("close-project")};
|
|
||||||
file->addAction(m_close_project);
|
|
||||||
connect(m_close_project, &QAction::triggered, this, &Window::on_close_project);
|
|
||||||
m_close_project->setEnabled(false);
|
|
||||||
|
|
||||||
QAction* quit = new QAction {QAction::tr("quit")};
|
|
||||||
file->addAction(quit);
|
|
||||||
|
|
||||||
connect(quit, &QAction::triggered, [this](){
|
|
||||||
model::Event ev {model::EVENT_QUIT};
|
|
||||||
notify(ev);
|
|
||||||
});
|
|
||||||
|
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*virtual*/ Window::~Window()
|
/*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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::show_project(std::string const& name,
|
|
||||||
std::filesystem::path const& dir)
|
|
||||||
{
|
|
||||||
setWindowTitle(QString::fromStdString(m_base_title + " [" + name
|
|
||||||
+ "]: " + dir.string()));
|
|
||||||
m_close_project->setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::hide_project()
|
|
||||||
{
|
|
||||||
setWindowTitle(QString::fromStdString(m_base_title));
|
|
||||||
m_close_project->setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::on_new_project()
|
|
||||||
{
|
|
||||||
QDialog* dialog = new QDialog {this};
|
|
||||||
dialog->setWindowTitle(QDialog::tr("new-project"));
|
|
||||||
|
|
||||||
auto* layout = new QVBoxLayout {dialog};
|
|
||||||
|
|
||||||
QLineEdit* name_field = new QLineEdit {dialog};
|
|
||||||
name_field->setPlaceholderText(QLineEdit::tr("new-project-name"));
|
|
||||||
layout->addWidget(name_field);
|
|
||||||
|
|
||||||
std::filesystem::path project_dir = std::filesystem::current_path();
|
|
||||||
|
|
||||||
{
|
|
||||||
auto* path_btn = new QPushButton {QString::fromStdString(project_dir.string())};
|
|
||||||
|
|
||||||
connect(path_btn, &QPushButton::pressed, [&](){
|
|
||||||
auto* file_diag = new QFileDialog {};
|
|
||||||
file_diag->setFileMode(QFileDialog::Directory);
|
|
||||||
file_diag->setOption(QFileDialog::ShowDirsOnly);
|
|
||||||
file_diag->setAcceptMode(QFileDialog::AcceptOpen);
|
|
||||||
file_diag->setViewMode(QFileDialog::ViewMode::List);
|
|
||||||
|
|
||||||
if (file_diag->exec())
|
|
||||||
{
|
|
||||||
auto dir = file_diag->directory();
|
|
||||||
project_dir = dir.absolutePath().toStdString();
|
|
||||||
path_btn->setText(QString::fromStdString(project_dir.string()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
layout->addWidget(path_btn);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto* btn_layout = new QHBoxLayout {};
|
|
||||||
layout->addLayout(btn_layout);
|
|
||||||
|
|
||||||
auto ok_btn = new QPushButton {QPushButton::tr("new-project"), dialog};
|
|
||||||
btn_layout->addWidget(ok_btn);
|
|
||||||
connect(ok_btn, &QPushButton::pressed, [dialog](){ dialog->done(true); });
|
|
||||||
|
|
||||||
auto cancel_btn = new QPushButton {QPushButton::tr("cancel-new-project"), dialog};
|
|
||||||
btn_layout->addWidget(cancel_btn);
|
|
||||||
connect(cancel_btn, &QPushButton::pressed, [dialog](){ dialog->done(false); });
|
|
||||||
|
|
||||||
if (dialog->exec())
|
|
||||||
{
|
|
||||||
std::string project_name = name_field->text().toStdString();
|
|
||||||
model::Event e {model::EVENT_NEW_PROJECT};
|
|
||||||
e.project.name = project_name;
|
|
||||||
e.project.dir = project_dir;
|
|
||||||
notify(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::on_close_project()
|
|
||||||
{
|
|
||||||
notify(model::EVENT_CLOSE_PROJECT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,38 +2,19 @@
|
||||||
#define pt_gui_WINDOW_HPP
|
#define pt_gui_WINDOW_HPP
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include "../commons.hpp"
|
|
||||||
#include "src/model/Shortcut.hpp"
|
|
||||||
#include "../model/Observable.hpp"
|
|
||||||
|
|
||||||
namespace pt
|
namespace pt
|
||||||
{
|
{
|
||||||
namespace gui
|
namespace gui
|
||||||
{
|
{
|
||||||
class Window: public QMainWindow, public model::Observable
|
class Window: public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit Window(QWidget* parent=nullptr);
|
explicit Window(QWidget* parent=nullptr);
|
||||||
virtual ~Window();
|
virtual ~Window();
|
||||||
|
|
||||||
// Events
|
|
||||||
// ======
|
|
||||||
void keyPressEvent(QKeyEvent* event) override;
|
|
||||||
|
|
||||||
// Project
|
|
||||||
// =======
|
|
||||||
void show_project(std::string const& name,
|
|
||||||
std::filesystem::path const& dir);
|
|
||||||
void hide_project();
|
|
||||||
|
|
||||||
void on_new_project();
|
|
||||||
void on_close_project();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string const m_base_title = "PIXTOOL " + PT_VERSION;
|
|
||||||
QAction* m_close_project;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
src/main.cpp
18
src/main.cpp
|
@ -1,32 +1,18 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QTranslator>
|
#include "pixtool/PixTool.hpp"
|
||||||
|
|
||||||
#include "model/PixTool.hpp"
|
|
||||||
#include "gui/Window.hpp"
|
#include "gui/Window.hpp"
|
||||||
#include "Presenter.hpp"
|
#include "Presenter.hpp"
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
spdlog::set_level(spdlog::level::debug);
|
|
||||||
|
|
||||||
|
|
||||||
QApplication app {argc, argv};
|
QApplication app {argc, argv};
|
||||||
|
|
||||||
QTranslator translator;
|
|
||||||
Q_UNUSED(translator.load(QString::fromStdString(PT_DATADIR / "i18n" / "pix_fr.qm")));
|
|
||||||
app.installTranslator(&translator);
|
|
||||||
|
|
||||||
pt::gui::Window window;
|
pt::gui::Window window;
|
||||||
|
|
||||||
pt::model::PixTool pixtool;
|
pt::model::PixTool pixtool;
|
||||||
|
|
||||||
auto presenter = std::make_shared<pt::Presenter>(window, pixtool);
|
pt::Presenter presenter {window, pixtool};
|
||||||
pixtool.add_observer(presenter);
|
|
||||||
window.add_observer(presenter);
|
|
||||||
|
|
||||||
pixtool.ready();
|
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
#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*/)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
#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
|
|
|
@ -1,62 +0,0 @@
|
||||||
#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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
#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
|
|
|
@ -1,41 +0,0 @@
|
||||||
#ifndef pt_model_EVENT_HPP
|
|
||||||
#define pt_model_EVENT_HPP
|
|
||||||
|
|
||||||
#include "../commons.hpp"
|
|
||||||
#include "Shortcut.hpp"
|
|
||||||
|
|
||||||
#define EVENT_TYPE(G) \
|
|
||||||
G(EVENT_NEW_PROJECT), G(EVENT_CLOSE_PROJECT), \
|
|
||||||
G(EVENT_QUERY_NEW_PROJECT), G(EVENT_QUERY_CLOSE_PROJECT), \
|
|
||||||
G(EVENT_KEYPRESSED), \
|
|
||||||
G(EVENT_QUIT)
|
|
||||||
|
|
||||||
namespace pt
|
|
||||||
{
|
|
||||||
namespace model
|
|
||||||
{
|
|
||||||
PT_ENUM(EventType, EVENT_TYPE);
|
|
||||||
|
|
||||||
struct EventKeyPressed
|
|
||||||
{
|
|
||||||
KeyMod keymod {""};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EventProject
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
std::filesystem::path dir;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Event
|
|
||||||
{
|
|
||||||
explicit Event(EventType ty) : type { ty } {}
|
|
||||||
EventType type;
|
|
||||||
|
|
||||||
EventKeyPressed key_pressed;
|
|
||||||
EventProject project;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,37 +0,0 @@
|
||||||
#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(*this, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Observable::notify(EventType type)
|
|
||||||
{
|
|
||||||
Event e { type };
|
|
||||||
notify(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
#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);
|
|
||||||
void notify(EventType type);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::weak_ptr<Observer>> m_observers;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,15 +0,0 @@
|
||||||
#include "Observer.hpp"
|
|
||||||
|
|
||||||
namespace pt
|
|
||||||
{
|
|
||||||
namespace model
|
|
||||||
{
|
|
||||||
/*explicit*/ Observer::Observer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*virtual*/ Observer::~Observer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
#ifndef pt_model_OBSERVER_HPP
|
|
||||||
#define pt_model_OBSERVER_HPP
|
|
||||||
|
|
||||||
#include "../commons.hpp"
|
|
||||||
#include "Event.hpp"
|
|
||||||
|
|
||||||
namespace pt
|
|
||||||
{
|
|
||||||
namespace model
|
|
||||||
{
|
|
||||||
class Observable;
|
|
||||||
|
|
||||||
class Observer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit Observer();
|
|
||||||
virtual ~Observer();
|
|
||||||
|
|
||||||
virtual void update(Observable& source, Event& event) = 0;
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,70 +0,0 @@
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
#include "PixTool.hpp"
|
|
||||||
#include "CommandRunner.hpp"
|
|
||||||
#include "cmds/Quit.hpp"
|
|
||||||
#include "cmds/Project.hpp"
|
|
||||||
#include "src/model/Event.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>());
|
|
||||||
|
|
||||||
m_cmd_runner->bind(Shortcut {{KeyMod {"N", {PT_CONTROL}}}},
|
|
||||||
std::make_shared<cmds::QueryNewProject>());
|
|
||||||
|
|
||||||
m_cmd_runner->bind(Shortcut {{KeyMod {"W", {PT_CONTROL}}}},
|
|
||||||
std::make_shared<cmds::QueryCloseProject>());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PixTool::new_project(std::string const& name,
|
|
||||||
std::filesystem::path const& dir)
|
|
||||||
{
|
|
||||||
m_project = std::make_unique<Project>(name, dir);
|
|
||||||
|
|
||||||
Event e {EVENT_NEW_PROJECT};
|
|
||||||
e.project.name = name;
|
|
||||||
e.project.dir = dir;
|
|
||||||
notify(e);
|
|
||||||
|
|
||||||
spdlog::info("new project '" + name + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
void PixTool::close_project()
|
|
||||||
{
|
|
||||||
if (m_project)
|
|
||||||
{
|
|
||||||
std::string name = m_project->name();
|
|
||||||
m_project.reset();
|
|
||||||
notify(EVENT_CLOSE_PROJECT);
|
|
||||||
spdlog::info("close project '" + name + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
#ifndef pt_model_PIXTOOL_HPP
|
|
||||||
#define pt_model_PIXTOOL_HPP
|
|
||||||
|
|
||||||
#include "../commons.hpp"
|
|
||||||
#include "Shortcut.hpp"
|
|
||||||
#include "Project.hpp"
|
|
||||||
#include "Observable.hpp"
|
|
||||||
|
|
||||||
namespace pt
|
|
||||||
{
|
|
||||||
namespace model
|
|
||||||
{
|
|
||||||
class CommandRunner;
|
|
||||||
|
|
||||||
class PixTool: public Observable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit PixTool();
|
|
||||||
virtual ~PixTool();
|
|
||||||
|
|
||||||
void ready();
|
|
||||||
void update(KeyMod const& km);
|
|
||||||
void quit();
|
|
||||||
|
|
||||||
// Project
|
|
||||||
// =======
|
|
||||||
void new_project(std::string const& name, std::filesystem::path const& dir);
|
|
||||||
bool has_project() const { return m_project != nullptr; }
|
|
||||||
void close_project();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<CommandRunner> m_cmd_runner;
|
|
||||||
std::unique_ptr<Project> m_project;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,18 +0,0 @@
|
||||||
#include "Project.hpp"
|
|
||||||
|
|
||||||
namespace pt
|
|
||||||
{
|
|
||||||
namespace model
|
|
||||||
{
|
|
||||||
/*explicit*/ Project::Project(std::string const& name,
|
|
||||||
std::filesystem::path const& dir)
|
|
||||||
: m_name { name }
|
|
||||||
, m_dir { dir }
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*virtual*/ Project::~Project()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
#ifndef pt_model_PROJECT_HPP
|
|
||||||
#define pt_model_PROJECT_HPP
|
|
||||||
|
|
||||||
#include "../commons.hpp"
|
|
||||||
|
|
||||||
namespace pt
|
|
||||||
{
|
|
||||||
namespace model
|
|
||||||
{
|
|
||||||
class Project
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit Project(std::string const& name,
|
|
||||||
std::filesystem::path const& dir);
|
|
||||||
virtual ~Project();
|
|
||||||
|
|
||||||
inline std::string name() const { return m_name; }
|
|
||||||
inline std::filesystem::path dir() const { return m_dir; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_name;
|
|
||||||
std::filesystem::path m_dir;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,44 +0,0 @@
|
||||||
#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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
#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
|
|
|
@ -1,40 +0,0 @@
|
||||||
#ifndef pt_cmds_PROJECT_HPP
|
|
||||||
#define pt_cmds_PROJECT_HPP
|
|
||||||
|
|
||||||
#include "../Command.hpp"
|
|
||||||
#include "src/model/Event.hpp"
|
|
||||||
|
|
||||||
namespace pt
|
|
||||||
{
|
|
||||||
namespace cmds
|
|
||||||
{
|
|
||||||
struct QueryNewProject: public model::Command
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
std::filesystem::path dir;
|
|
||||||
|
|
||||||
explicit QueryNewProject()
|
|
||||||
: model::Command("query-new-project")
|
|
||||||
{}
|
|
||||||
|
|
||||||
void execute(model::PixTool& pixtool) override
|
|
||||||
{
|
|
||||||
pixtool.notify(model::EVENT_QUERY_NEW_PROJECT);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct QueryCloseProject: public model::Command
|
|
||||||
{
|
|
||||||
explicit QueryCloseProject()
|
|
||||||
: model::Command("query-close-project") {}
|
|
||||||
|
|
||||||
void execute(model::PixTool& pixtool) override
|
|
||||||
{
|
|
||||||
pixtool.notify(model::EVENT_QUERY_CLOSE_PROJECT);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,29 +0,0 @@
|
||||||
#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
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#include "PixTool.hpp"
|
||||||
|
|
||||||
|
namespace pt
|
||||||
|
{
|
||||||
|
namespace model
|
||||||
|
{
|
||||||
|
/*explicit*/ PixTool::PixTool()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ PixTool::~PixTool()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef pt_model_PIXTOOL_HPP
|
||||||
|
#define pt_model_PIXTOOL_HPP
|
||||||
|
|
||||||
|
namespace pt
|
||||||
|
{
|
||||||
|
namespace model
|
||||||
|
{
|
||||||
|
class PixTool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit PixTool();
|
||||||
|
virtual ~PixTool();
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,166 +0,0 @@
|
||||||
#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);
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
#define CATCH_CONFIG_MAIN
|
|
||||||
#include <catch2/catch.hpp>
|
|
Loading…
Reference in New Issue