diff --git a/ClockCounter/ACIFullVersion.h b/ClockCounter/ACIFullVersion.h new file mode 100644 index 0000000..2cba4b0 --- /dev/null +++ b/ClockCounter/ACIFullVersion.h @@ -0,0 +1,169 @@ +/* +* Application Communication Interface - Full Version +* Copyright (c) 2022-2032 UnknownObject +*/ + +#pragma once +#pragma warning(disable : 26812) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +constexpr auto ACI_UA = "libcurl/7.68.0 (Windows NT 10.0; Win64; x64) UnknownNetworkService/2.01 (Application Communication Interface; Localhost-Only)"; + +//Common types +using JsonValue = Json::Value; +using JsonReader = Json::Reader; +//Client-only types +using ClientCallback = void(*)(JsonValue); +using ClientDataGroup = std::vector; +using ClientDataPair = std::pair; +template using ClassClientCallback = void(T::*)(JsonValue); +//Server-only types +using ServerInputCallback = void(*)(JsonValue); +using ServerDataQueue = std::vector; +using ResponseFunction = std::string(*)(std::string); +using StaticDataResponder = std::map; +using DynamicDataResponder = std::map; + +//Common classes +class JsonUnicodeWriter +{ +private: + Json::StreamWriterBuilder jswb; +public: + JsonUnicodeWriter(); +public: + std::string write(JsonValue root); +}; + +//------------------------------------------Client Classes------------------------------------------ +class ClientDataEncoder +{ +public: + static std::string Encode(std::string item, std::string data); + static std::string Encode(std::string item); + static JsonValue Decode(std::string str); + static ClientDataPair Decode(JsonValue root); + static ClientDataGroup DecodeGroup(JsonValue root); +}; + +class ACIClient +{ +private: + CURL* curl; + int ServerPort; +private: + static size_t process_data(void* buffer, size_t size, size_t nmemb, void* user_p); +public: + ACIClient(int server_port = 10000); + ~ACIClient(); +public: + bool SendData(std::string item, std::string data, ClientCallback cb_func = nullptr); + template bool SendData(std::string item, std::string data, ClassClientCallback cb_func, T* class_pointer); + bool RequestData(std::string item, std::string data, ClientCallback cb_func = nullptr); + template bool RequestData(std::string item, std::string data, ClassClientCallback cb_func, T* class_pointer); + bool RequestData(std::string item, ClientCallback cb_func = nullptr); + template bool RequestData(std::string item, ClassClientCallback cb_func, T* class_pointer); + bool RequestQuquedData(ClientCallback cb_func = nullptr); + template bool RequestQuquedData(ClassClientCallback cb_func, T* class_pointer); +}; +//----------------------------------------Client Classes End---------------------------------------- + +//------------------------------------------Server Classes------------------------------------------ +class ServerDataEncoder +{ +public: + static std::string Encode(std::string item, std::string data); + static JsonValue Decode(std::string str); + static std::string EncodeResponse(std::string error, ServerDataQueue data = ServerDataQueue()); +}; + +class ServerDataStorage +{ +private: + static ServerDataQueue DataQueue; + static StaticDataResponder SDR_Input; + static StaticDataResponder SDR_Output; + static DynamicDataResponder DDR_Output; +public: + static void GlobalClear(); + static void DataQueueClear(); + static void SDR_InputClear(); + static void SDR_OutputClear(); + static void DDR_OutputClear(); + static void DataQueueAdd(std::string data); + static void SDRInputAdd(std::string item, std::string resp); + static void SDROutputAdd(std::string item, std::string resp); + static void DDROutputAdd(std::string item, ResponseFunction resfunc); + static ServerDataQueue GetDataQueue(); + static StaticDataResponder GetSDR_Input(); + static StaticDataResponder GetSDR_Output(); + static DynamicDataResponder GetDDR_Output(); + static bool SDRInputExist(std::string item); + static bool SDROutputExist(std::string item); + static bool DDROutputExist(std::string item); + static std::string SDRInputGetValue(std::string item); + static std::string SDROutputGetValue(std::string item); + static ResponseFunction DDROutputGetValue(std::string item); +}; + +class ServerInputHandler : public webcc::View +{ +private: + ServerInputCallback InputCallback; +public: + ServerInputHandler(ServerInputCallback cb_input = nullptr); +public: + webcc::ResponsePtr Handle(webcc::RequestPtr request) override; +}; + +class ServerOutputHandler : public webcc::View +{ +public: + webcc::ResponsePtr Handle(webcc::RequestPtr request) override; +}; + +class ServerSideOutputHandler : public webcc::View +{ +public: + webcc::ResponsePtr Handle(webcc::RequestPtr request) override; +}; + +class ACIServer +{ +private: + bool CallbackEnabled; + webcc::Server* ccServer; + std::thread ServerThread; + ServerInputCallback InputCallback; + const webcc::Strings methods = { "GET","POST","PUT","HEAD","DELETE" }; +private: + static void ServerThreadFunction(webcc::Server* server, int worker_thread, int loop_thread); +public: + ACIServer(int port = 10000, bool enable_callback = false, ServerInputCallback cb_func = nullptr); + ~ACIServer(); +public: + void Run(int worker_thread = 1, int loop_thread = 1); + void ThreadRun(int worker_thread = 1, int loop_thread = 1); + void Stop(); + bool EnableCallback(ServerInputCallback cb_func = nullptr); + bool SetCallbackFunction(ServerInputCallback cb_func); + bool DisableCallback(); + void OutputQueueAdd(std::string content); + void OutputQueueClear(); +}; +//----------------------------------------Server Classes End---------------------------------------- + +#ifndef _DEBUG +#pragma comment(lib, "ACIFullVersion.lib") +#else +#pragma comment(lib, "ACIFullVersiond.lib") +#endif \ No newline at end of file diff --git a/ClockCounter/ACIFullVersion.lib b/ClockCounter/ACIFullVersion.lib new file mode 100644 index 0000000..3cfa0e4 Binary files /dev/null and b/ClockCounter/ACIFullVersion.lib differ diff --git a/ClockCounter/ACIFullVersiond.lib b/ClockCounter/ACIFullVersiond.lib new file mode 100644 index 0000000..5967413 Binary files /dev/null and b/ClockCounter/ACIFullVersiond.lib differ diff --git a/ClockCounter/ACIMode.cpp b/ClockCounter/ACIMode.cpp new file mode 100644 index 0000000..0bb5986 --- /dev/null +++ b/ClockCounter/ACIMode.cpp @@ -0,0 +1,96 @@ +#include "ACIMode.h" + +ACIMode::ACIMode(QWidget* parent) : QMainWindow(parent) +{ + client = nullptr; + server = nullptr; + OperationMode = -3; + ui.setupUi(this); + ui.Workmode_Client->setChecked(true); + ui.Workmode_Server->setChecked(false); + ui.PortNumber->setPlainText("23456"); + connect(ui.BtnStart, &QCommandLinkButton::clicked, this, &ACIMode::StartACISystem); +} + +ACIMode::~ACIMode() +{ +} + +int ACIMode::ProcessRadio(bool client, bool server) +{ + if (client && server) + return -1; + else if ((!client) && (!server)) + return -2; + else if (client) + return 0; + else + return 1; +} + +void ACIMode::CleanUp() +{ + if (client != nullptr) + { + delete client; + client = nullptr; + } + if (server != nullptr) + { + server->Stop(); + delete server; + server = nullptr; + } + OperationMode = -3; +} + +void ACIMode::StartACISystem() +{ + CleanUp(); + OperationMode = ProcessRadio(ui.Workmode_Client->isChecked(), ui.Workmode_Server->isChecked()); + switch (OperationMode) + { + case 0: + { + client = new ACIClient(ui.PortNumber->toPlainText().toInt()); + break; + } + case 1: + { + server = new ACIServer(ui.PortNumber->toPlainText().toInt()); + ServerDataStorage::DDROutputAdd("start-timer", RequestedTimerStart); + server->ThreadRun(); + break; + } + default: + { + MessageBox(NULL, L"通信参数错误", L"错误", MB_OK | MB_ICONERROR); + break; + } + } + if (OperationMode == 0) + this->hide(); +} + +int ACIMode::GetOperationMode() +{ + return OperationMode; +} + +void ACIMode::RequestRemoteTimer() +{ + if (client != nullptr) + client->RequestData("start-timer"); +} + +void ACIMode::closeEvent(QCloseEvent* event) +{ + this->hide(); + event->ignore(); +} + +std::string RequestedTimerStart(std::string json) +{ + GlobalVari::ServerRequested = true; + return "successed"; +} diff --git a/ClockCounter/ACIMode.h b/ClockCounter/ACIMode.h new file mode 100644 index 0000000..d8f1a39 --- /dev/null +++ b/ClockCounter/ACIMode.h @@ -0,0 +1,36 @@ +#pragma once +#include "ACIFullVersion.h" +#include +#include "ui_ACIMode.h" +#include +#include +#include +#include +#include "GlobalVari.h" + +class ACIMode : public QMainWindow +{ + Q_OBJECT; + +public: + ACIMode(QWidget* parent = nullptr); + ~ACIMode(); + +public: + int ProcessRadio(bool client, bool server); + void CleanUp(); + void StartACISystem(); + int GetOperationMode(); + void RequestRemoteTimer(); + +protected: + void closeEvent(QCloseEvent* event) override; + +private: + int OperationMode; + ACIClient* client; + ACIServer* server; + Ui::ACIModeWindow ui; +}; + +std::string RequestedTimerStart(std::string json); \ No newline at end of file diff --git a/ClockCounter/ACIMode.ui b/ClockCounter/ACIMode.ui new file mode 100644 index 0000000..b99fa94 --- /dev/null +++ b/ClockCounter/ACIMode.ui @@ -0,0 +1,112 @@ + + + ACIModeWindow + + + + 0 + 0 + 262 + 241 + + + + 通信模式设置 + + + + + + 10 + 10 + 241 + 171 + + + + 通信设置 + + + + + 70 + 30 + 161 + 31 + + + + true + + + + + + 20 + 30 + 41 + 31 + + + + 端口号 + + + + + + 10 + 80 + 221 + 71 + + + + 工作模式 + + + + + 20 + 19 + 61 + 41 + + + + 客户端 + + + + + + 140 + 19 + 61 + 41 + + + + 服务端 + + + + + + + + 60 + 190 + 141 + 41 + + + + 启动通信系统 + + + + + + + diff --git a/ClockCounter/ClockCounter.cpp b/ClockCounter/ClockCounter.cpp index bc71b60..2b008ea 100644 --- a/ClockCounter/ClockCounter.cpp +++ b/ClockCounter/ClockCounter.cpp @@ -2,21 +2,24 @@ ClockCounter::ClockCounter(QWidget *parent) : QMainWindow(parent) { - ui.setupUi(this); - PreClickCount = 0; - PreClickPosition = QPoint(0, 0); - ui.SpliterHourMinute->Init(UDateTimeSpliter::Type::Time); - ui.SpliterMinuteSecond->Init(UDateTimeSpliter::Type::Time); - ui.SpliterSecondMS->Init(UDateTimeSpliter::Type::Dots); - connect(ui.BtnStartTimer, &QPushButton::clicked, this, &ClockCounter::StartTimer); - connect(ui.BtnStopTimer, &QPushButton::clicked, this, &ClockCounter::StopTimer); - connect(ui.BtnGetPreclickPos, &QPushButton::clicked, this, &ClockCounter::ShowPreClickWindow); - connect(ui.BtnClearPreclickPos, &QPushButton::clicked, this, &ClockCounter::ClearPreClickInfo); - connect(&CountTimer, &QTimer::timeout, this, &ClockCounter::CountCallback); - connect(&WindowUpdater, &QTimer::timeout, this, &ClockCounter::WindowUpdateCallback); - CountTimer.setInterval(1); - WindowUpdater.setInterval(50); - CountTime = 0; + ui.setupUi(this); + PreClickCount = 0; + PreClickPosition = QPoint(0, 0); + ui.SpliterHourMinute->Init(UDateTimeSpliter::Type::Time); + ui.SpliterMinuteSecond->Init(UDateTimeSpliter::Type::Time); + ui.SpliterSecondMS->Init(UDateTimeSpliter::Type::Dots); + connect(ui.BtnStartTimer, &QPushButton::clicked, this, &ClockCounter::StartTimer); + connect(ui.BtnStopTimer, &QPushButton::clicked, this, &ClockCounter::StopTimer); + connect(ui.BtnGetPreclickPos, &QPushButton::clicked, this, &ClockCounter::ShowPreClickWindow); + connect(ui.BtnGetPreclickPos, &UDBPushButton::rclicked, this, &ClockCounter::ShowACIModeWindow); + connect(ui.BtnClearPreclickPos, &QPushButton::clicked, this, &ClockCounter::ClearPreClickInfo); + connect(&CountTimer, &QTimer::timeout, this, &ClockCounter::CountCallback); + connect(&WindowUpdater, &QTimer::timeout, this, &ClockCounter::WindowUpdateCallback); + connect(&ServerStatusChecker, &QTimer::timeout, this, &ClockCounter::ServerStatusCallback); + CountTimer.setInterval(1); + WindowUpdater.setInterval(50); + ServerStatusChecker.setInterval(1); + CountTime = 0; } ClockCounter::~ClockCounter() @@ -25,96 +28,135 @@ ClockCounter::~ClockCounter() void ClockCounter::MouseClick(int cnt, QPoint point) { - for (int i = 0; i < cnt; i++) - { - this->setWindowTitle(QString::asprintf("软件执行计时器: 执行位于(%d, %d)的第%d次预点击", point.x(), point.y(), i)); - SetCursorPos(point.x(), point.y()); - mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); - Sleep(500); - } - return; + for (int i = 0; i < cnt; i++) + { + this->setWindowTitle(QString::asprintf("软件执行计时器: 执行位于(%d, %d)的第%d次预点击", point.x(), point.y(), i)); + SetCursorPos(point.x(), point.y()); + mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); + Sleep(500); + } + return; } void ClockCounter::StartTimer() { - if (CountTime != 0) - { - ui.BtnStartTimer->setText("开始计时"); - CountTime = -1; - CountCallback(); - if(PreClickCount!=0) - this->setWindowTitle("软件执行计时器: 预点击指令已激活"); - else - this->setWindowTitle("软件执行计时器"); - } - else - { - if (PreClickCount > 0) - MouseClick(PreClickCount, PreClickPosition); - CountTimer.start(); - this->setWindowTitle("软件执行计时器: 正在计时"); - } + if (CountTime != 0) + { + ui.BtnStartTimer->setText("开始计时"); + CountTime = -1; + CountCallback(); + if (PreClickCount != 0) + this->setWindowTitle("软件执行计时器: 预点击指令已激活"); + else + this->setWindowTitle("软件执行计时器"); + } + else + { + if (PreClickCount > 0) + { + MouseClick(PreClickCount, PreClickPosition); + if (aci_mode_window.GetOperationMode() == 0) + aci_mode_window.RequestRemoteTimer(); + else + { + CountTimer.start(); + this->setWindowTitle("软件执行计时器: 正在计时"); + } + } + } } void ClockCounter::StopTimer() { - CountTimer.stop(); - ui.BtnStartTimer->setText("重置计时器"); - this->setWindowTitle("软件执行计时器: 计时已停止"); + CountTimer.stop(); + ui.BtnStartTimer->setText("重置计时器"); + this->setWindowTitle("软件执行计时器: 计时已停止"); +} + +void ClockCounter::ShowACIModeWindow() +{ + if (!aci_mode_window.isActiveWindow()) + { + aci_mode_window.show(); + aci_mode_window.activateWindow(); + aci_mode_window.setWindowState((aci_mode_window.windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + ServerStatusChecker.start(); + /*this->hide(); + WindowUpdater.start();*/ + } } void ClockCounter::ShowPreClickWindow() { - if (!pre_click_window.isActiveWindow()) - { - pre_click_window.show(); - pre_click_window.activateWindow(); - pre_click_window.setWindowState((pre_click_window.windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); - this->hide(); - WindowUpdater.start(); - } + if (!pre_click_window.isActiveWindow()) + { + pre_click_window.show(); + pre_click_window.activateWindow(); + pre_click_window.setWindowState((pre_click_window.windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + this->hide(); + WindowUpdater.start(); + } } void ClockCounter::ClearPreClickInfo() { - PreClickCount = 0; - PreClickPosition = QPoint(0, 0); - this->setWindowTitle("软件执行计时器"); - MessageBox(NULL, L"预点击坐标已清空", L"提示", MB_OK | MB_ICONINFORMATION); + PreClickCount = 0; + PreClickPosition = QPoint(0, 0); + aci_mode_window.CleanUp(); + this->setWindowTitle("软件执行计时器"); + MessageBox(NULL, L"预点击坐标已清空", L"提示", MB_OK | MB_ICONINFORMATION); } void ClockCounter::CountCallback() { - CountTime++; - int hour = (CountTime / 1000) / 3600; - int minute = ((CountTime / 1000) / 60) - (hour * 60); - int second = (CountTime / 1000) - (hour * 3600) - (minute * 60); - int millsecond = CountTime - (hour * 3600 * 1000) - (minute * 60 * 1000) - (second * 1000); - ui.NumHour01->setNumber(hour / 10); - ui.NumHour02->setNumber(hour % 10); - ui.NumMinute01->setNumber(minute / 10); - ui.NumMinute02->setNumber(minute % 10); - ui.NumSecond01->setNumber(second / 10); - ui.NumSecond02->setNumber(second % 10); - ui.NumMillSec01->setNumber(millsecond / 100); - ui.NumMillSec02->setNumber((millsecond / 10) % 10); - ui.NumMillSec03->setNumber((millsecond % 100) % 10); - return; + CountTime++; + int hour = (CountTime / 1000) / 3600; + int minute = ((CountTime / 1000) / 60) - (hour * 60); + int second = (CountTime / 1000) - (hour * 3600) - (minute * 60); + int millsecond = CountTime - (hour * 3600 * 1000) - (minute * 60 * 1000) - (second * 1000); + ui.NumHour01->setNumber(hour / 10); + ui.NumHour02->setNumber(hour % 10); + ui.NumMinute01->setNumber(minute / 10); + ui.NumMinute02->setNumber(minute % 10); + ui.NumSecond01->setNumber(second / 10); + ui.NumSecond02->setNumber(second % 10); + ui.NumMillSec01->setNumber(millsecond / 100); + ui.NumMillSec02->setNumber((millsecond / 10) % 10); + ui.NumMillSec03->setNumber((millsecond % 100) % 10); + return; } void ClockCounter::WindowUpdateCallback() { - if (!pre_click_window.isVisible()) - { - WindowUpdater.stop(); - this->show(); - this->activateWindow(); - this->setWindowState((this->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); - if (pre_click_window.GetWindowStatus()) - { - PreClickCount = pre_click_window.GetClickCount(); - PreClickPosition = pre_click_window.GetCursorPosition(); - this->setWindowTitle("软件执行计时器: 预点击指令已激活"); - } - } + if (!pre_click_window.isVisible()) + { + WindowUpdater.stop(); + this->show(); + this->activateWindow(); + this->setWindowState((this->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + if (pre_click_window.GetWindowStatus()) + { + PreClickCount = pre_click_window.GetClickCount(); + PreClickPosition = pre_click_window.GetCursorPosition(); + this->setWindowTitle("软件执行计时器: 预点击指令已激活"); + } + } +} + +void ClockCounter::ServerStatusCallback() +{ + if (aci_mode_window.GetOperationMode() == 0) + { + ServerStatusChecker.stop(); + this->hide(); + } + else if (aci_mode_window.GetOperationMode() == 1) + { + if (GlobalVari::ServerRequested) + { + CountTimer.start(); + ServerStatusChecker.stop(); + this->setWindowTitle("软件执行计时器: 正在计时"); + } + } } diff --git a/ClockCounter/ClockCounter.h b/ClockCounter/ClockCounter.h index 8392492..7408632 100644 --- a/ClockCounter/ClockCounter.h +++ b/ClockCounter/ClockCounter.h @@ -1,10 +1,12 @@ #pragma once +#include "ACIMode.h" #include #include "ui_ClockCounter.h" #include "PreClick.h" #include #include +#include "GlobalVari.h" class ClockCounter : public QMainWindow { @@ -20,10 +22,12 @@ public: public slots: void StartTimer(); void StopTimer(); + void ShowACIModeWindow(); void ShowPreClickWindow(); void ClearPreClickInfo(); void CountCallback(); void WindowUpdateCallback(); + void ServerStatusCallback(); private: time_t CountTime; @@ -31,6 +35,8 @@ private: QTimer CountTimer; QTimer WindowUpdater; QPoint PreClickPosition; + ACIMode aci_mode_window; Ui::ClockCounterClass ui; PreClick pre_click_window; + QTimer ServerStatusChecker; }; diff --git a/ClockCounter/ClockCounter.ui b/ClockCounter/ClockCounter.ui index 4953f70..62f6c07 100644 --- a/ClockCounter/ClockCounter.ui +++ b/ClockCounter/ClockCounter.ui @@ -166,7 +166,7 @@ 停止计时 - + 540 @@ -207,6 +207,11 @@
udatetimespliter.h
1 + + UDBPushButton + QPushButton +
udbpushbutton.h
+
diff --git a/ClockCounter/ClockCounter.vcxproj b/ClockCounter/ClockCounter.vcxproj index ff49810..ab48756 100644 --- a/ClockCounter/ClockCounter.vcxproj +++ b/ClockCounter/ClockCounter.vcxproj @@ -92,9 +92,13 @@ + + + + @@ -107,6 +111,12 @@ + + + + + + diff --git a/ClockCounter/ClockCounter.vcxproj.filters b/ClockCounter/ClockCounter.vcxproj.filters index c8175d2..0ddd57e 100644 --- a/ClockCounter/ClockCounter.vcxproj.filters +++ b/ClockCounter/ClockCounter.vcxproj.filters @@ -46,11 +46,23 @@ Source Files + + Source Files + + + Source Files + + + Source Files + Form Files + + Form Files + @@ -59,5 +71,19 @@ Header Files + + Header Files + + + Header Files + + + + + Header Files + + + Header Files + \ No newline at end of file diff --git a/ClockCounter/GlobalVari.cpp b/ClockCounter/GlobalVari.cpp new file mode 100644 index 0000000..9eb0fda --- /dev/null +++ b/ClockCounter/GlobalVari.cpp @@ -0,0 +1,3 @@ +#include "GlobalVari.h" + +bool GlobalVari::ServerRequested = false; \ No newline at end of file diff --git a/ClockCounter/GlobalVari.h b/ClockCounter/GlobalVari.h new file mode 100644 index 0000000..cb6acf5 --- /dev/null +++ b/ClockCounter/GlobalVari.h @@ -0,0 +1,7 @@ +#pragma once + +namespace GlobalVari +{ + extern bool ServerRequested; +}; + diff --git a/ClockCounter/UDBPushButton.cpp b/ClockCounter/UDBPushButton.cpp new file mode 100644 index 0000000..d0264f1 --- /dev/null +++ b/ClockCounter/UDBPushButton.cpp @@ -0,0 +1,25 @@ +#include "UDBPushButton.h" + +UDBPushButton::UDBPushButton(QWidget* parent) : QPushButton(parent) +{ +} + +UDBPushButton::~UDBPushButton() +{ +} + +void UDBPushButton::mouseDoubleClickEvent(QMouseEvent* event) +{ + if (event->button() == Qt::LeftButton) + emit db_clicked(); +} + +void UDBPushButton::mousePressEvent(QMouseEvent* event) +{ + if (event->button() == Qt::LeftButton) + emit clicked(); + else if (event->button() == Qt::RightButton) + emit rclicked(); + else if (event->button() == Qt::MiddleButton) + emit center_clicked(); +} diff --git a/ClockCounter/UDBPushButton.h b/ClockCounter/UDBPushButton.h new file mode 100644 index 0000000..9456436 --- /dev/null +++ b/ClockCounter/UDBPushButton.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include +#include + +class UDBPushButton : public QPushButton +{ + Q_OBJECT; + +public: + UDBPushButton(QWidget* parent); + ~UDBPushButton(); + +protected: + void mouseDoubleClickEvent(QMouseEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; + +signals: + void db_clicked(); + void rclicked(); + void center_clicked(); +}; +