first push
This commit is contained in:
420
APP/APP_UIWindow.cpp
Normal file
420
APP/APP_UIWindow.cpp
Normal file
@@ -0,0 +1,420 @@
|
||||
#include "APP/APP_UIWindow.h"
|
||||
|
||||
#include "APP/APP_GlassCard.h"
|
||||
#include "APP/APP_KeyButton.h"
|
||||
#include "APP/APP_Theme.h"
|
||||
#include "APP/APP_UIWindow_Private.h"
|
||||
#include "LOGIC/Lgc_Func_Button.h"
|
||||
#include <QtCore/QSignalBlocker>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QFormLayout>
|
||||
#include <QtWidgets/QGridLayout>
|
||||
#include <QtWidgets/QHeaderView>
|
||||
#include <QtWidgets/QHBoxLayout>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QLineEdit>
|
||||
#include <QtWidgets/QPushButton>
|
||||
#include <QtWidgets/QSizePolicy>
|
||||
#include <QtWidgets/QStackedWidget>
|
||||
#include <QtWidgets/QTabWidget>
|
||||
#include <QtWidgets/QTableWidget>
|
||||
#include <QtWidgets/QTableWidgetItem>
|
||||
#include <QtWidgets/QVBoxLayout>
|
||||
|
||||
namespace APP {
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
QLabel* App_Func_CreateLabel(
|
||||
QWidget* parent,
|
||||
const QString& Text,
|
||||
const QFont& Font,
|
||||
bool WordWrap = false)
|
||||
{
|
||||
QLabel* p_Label = new QLabel(Text, parent);
|
||||
p_Label->setFont(Font);
|
||||
p_Label->setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
p_Label->setWordWrap(WordWrap);
|
||||
return p_Label;
|
||||
}
|
||||
|
||||
APP_GlassCard* App_Func_CreateCard(QWidget* parent, QVBoxLayout** pp_Layout)
|
||||
{
|
||||
APP_GlassCard* p_Card = new APP_GlassCard(parent);
|
||||
QVBoxLayout* p_Layout = new QVBoxLayout(p_Card);
|
||||
p_Layout->setContentsMargins(20, 20, 20, 20);
|
||||
p_Layout->setSpacing(14);
|
||||
*pp_Layout = p_Layout;
|
||||
return p_Card;
|
||||
}
|
||||
|
||||
void App_Func_SetGridStretch(QGridLayout* p_Grid, int ColumnCount, int RowCount)
|
||||
{
|
||||
for (int Column = 0; Column < ColumnCount; ++Column)
|
||||
{
|
||||
p_Grid->setColumnStretch(Column, 1);
|
||||
}
|
||||
for (int Row = 0; Row < RowCount; ++Row)
|
||||
{
|
||||
p_Grid->setRowStretch(Row, 1);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int App_Func_GetFeatureStackIndex(Lgc_FunctionFeature_Type Type)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case Lgc_FunctionFeature_Type::KeyCombination:
|
||||
case Lgc_FunctionFeature_Type::KeySequence:
|
||||
return 0;
|
||||
|
||||
case Lgc_FunctionFeature_Type::Website:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool App_Func_IsKeyRecordFeatureType(Lgc_FunctionFeature_Type Type)
|
||||
{
|
||||
return (Type == Lgc_FunctionFeature_Type::KeyCombination) ||
|
||||
(Type == Lgc_FunctionFeature_Type::KeySequence);
|
||||
}
|
||||
|
||||
QString App_Func_GetWebsiteEditText(const QString& UrlText)
|
||||
{
|
||||
const QString DisplayText = UrlText.trimmed();
|
||||
return DisplayText.isEmpty() ? QStringLiteral("https://") : DisplayText;
|
||||
}
|
||||
|
||||
App_UIWindow::App_UIWindow(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
App_Func_InitWindow();
|
||||
App_Func_InitUi();
|
||||
App_Func_InitConnect();
|
||||
App_Func_InitLogic();
|
||||
App_Func_RefreshUi();
|
||||
}
|
||||
|
||||
App_UIWindow::~App_UIWindow()
|
||||
{
|
||||
Lgc_Core_Close(&appLgcState);
|
||||
}
|
||||
|
||||
void App_UIWindow::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QPainter Painter(this);
|
||||
Painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
Painter.fillRect(rect(), palette().color(QPalette::Window));
|
||||
}
|
||||
|
||||
void App_UIWindow::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
App_Func_UpdateFeatureEditorHeight();
|
||||
}
|
||||
|
||||
bool App_UIWindow::nativeEvent(const QByteArray& EventType, void* p_Message, long* p_Result)
|
||||
{
|
||||
Q_UNUSED(EventType);
|
||||
App_Func_HandleSequenceRecordMessage(p_Message);
|
||||
Lgc_Core_HandleNativeMessage(&appLgcState, p_Message);
|
||||
return QWidget::nativeEvent(EventType, p_Message, p_Result);
|
||||
}
|
||||
|
||||
void App_UIWindow::App_Func_InitWindow()
|
||||
{
|
||||
setWindowTitle(QStringLiteral("数字键盘上位机"));
|
||||
#if APP_ENABLE_DEBUG_WINDOW
|
||||
setMinimumSize(820, 960);
|
||||
resize(900, 1040);
|
||||
#else
|
||||
setMinimumSize(760, 820);
|
||||
resize(820, 900);
|
||||
#endif
|
||||
setAttribute(Qt::WA_StyledBackground, true);
|
||||
}
|
||||
|
||||
void App_UIWindow::App_Func_InitUi()
|
||||
{
|
||||
QVBoxLayout* p_RootLayout = new QVBoxLayout(this);
|
||||
p_RootLayout->setContentsMargins(26, 22, 26, 24);
|
||||
p_RootLayout->setSpacing(14);
|
||||
|
||||
appPageTab = new QTabWidget(this);
|
||||
appPageTab->setDocumentMode(true);
|
||||
appPageTab->setMovable(false);
|
||||
|
||||
appPageTab->addTab(App_Func_CreatePadCard(), QStringLiteral("按键映射"));
|
||||
appFeaturePageIndex = appPageTab->addTab(App_Func_CreateFunctionConfigCard(), QStringLiteral("功能表"));
|
||||
#if APP_ENABLE_DEBUG_WINDOW
|
||||
appPageTab->addTab(App_Func_CreateDebugCard(), QStringLiteral("调试"));
|
||||
#endif
|
||||
|
||||
p_RootLayout->addWidget(appPageTab, 1);
|
||||
}
|
||||
|
||||
void App_UIWindow::App_Func_InitConnect()
|
||||
{
|
||||
connect(&appTimerPoll, &QTimer::timeout, this, &App_UIWindow::App_Func_OnPollTimer);
|
||||
connect(&appTimerAutoRefreshDevice, &QTimer::timeout, this, [this]()
|
||||
{
|
||||
if (appLgcState.IsConnected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const QString OldTextLog = appLgcState.TextLog;
|
||||
Lgc_Core_RefreshDevice(&appLgcState);
|
||||
if (!appLgcState.IsConnected)
|
||||
{
|
||||
appLgcState.TextLog = OldTextLog;
|
||||
}
|
||||
App_Func_RefreshAfterLogicChange();
|
||||
});
|
||||
|
||||
connect(appFeatureAddButton, &QPushButton::clicked, this, &App_UIWindow::App_Func_AddFeature);
|
||||
connect(appFeatureDeleteButton, &QPushButton::clicked, this, &App_UIWindow::App_Func_DeleteFeature);
|
||||
|
||||
connect(appFeatureTable, &QTableWidget::itemSelectionChanged, this, [this]()
|
||||
{
|
||||
const QModelIndexList IndexList = appFeatureTable->selectionModel()->selectedRows();
|
||||
if (IndexList.isEmpty())
|
||||
{
|
||||
App_Func_SelectFeature(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const int Row = IndexList.first().row();
|
||||
const QTableWidgetItem* p_Item = appFeatureTable->item(Row, 0);
|
||||
App_Func_SelectFeature(p_Item == nullptr ? 0 : p_Item->data(Qt::UserRole).toInt());
|
||||
});
|
||||
|
||||
const auto ConnectSaveSignal = [this](auto Sender, auto Signal)
|
||||
{
|
||||
connect(Sender, Signal, this, [this]()
|
||||
{
|
||||
if (!appIsUpdatingFeatureUi)
|
||||
{
|
||||
App_Func_SaveFeatureFromUi();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ConnectSaveSignal(appFeatureNameEdit, &QLineEdit::textChanged);
|
||||
ConnectSaveSignal(appFeatureDescriptionEdit, &QLineEdit::textChanged);
|
||||
ConnectSaveSignal(appFeatureTypeCombo, qOverload<int>(&QComboBox::currentIndexChanged));
|
||||
ConnectSaveSignal(appFeatureSequenceEdit, &QLineEdit::textChanged);
|
||||
ConnectSaveSignal(appFeatureWebsiteEdit, &QLineEdit::textChanged);
|
||||
|
||||
connect(appFeatureSequenceRecordStartButton, &QPushButton::clicked, this, &App_UIWindow::App_Func_StartSequenceRecording);
|
||||
connect(appFeatureSequenceRecordStopButton, &QPushButton::clicked, this, &App_UIWindow::App_Func_StopSequenceRecording);
|
||||
|
||||
#if APP_ENABLE_DEBUG_WINDOW
|
||||
connect(appDebugPanel->Debug_Func_GetRefreshButton(), &QPushButton::clicked, this, &App_UIWindow::App_Func_OnRefreshDeviceClicked);
|
||||
connect(appDebugPanel->Debug_Func_GetClearButton(), &QPushButton::clicked, this, &App_UIWindow::App_Func_OnClearLogClicked);
|
||||
connect(appDebugPanel->Debug_Func_GetApplyConfigButton(), &QPushButton::clicked, this, &App_UIWindow::App_Func_OnApplyDeviceConfigClicked);
|
||||
connect(appDebugPanel->Debug_Func_GetSyncTimeButton(), &QPushButton::clicked, this, &App_UIWindow::App_Func_OnSyncTimeClicked);
|
||||
connect(appDebugPanel->Debug_Func_GetModeSwitchButton(), &QPushButton::clicked, this, &App_UIWindow::App_Func_OnModeSwitchClicked);
|
||||
#endif
|
||||
}
|
||||
|
||||
void App_UIWindow::App_Func_InitLogic()
|
||||
{
|
||||
Lgc_Core_Init(&appLgcState);
|
||||
Lgc_Core_SetWindowHandle(&appLgcState, reinterpret_cast<void*>(winId()));
|
||||
|
||||
App_Func_RefreshFeatureTable();
|
||||
#if APP_ENABLE_DEBUG_WINDOW
|
||||
App_Func_RefreshDeviceConfigFromState();
|
||||
#endif
|
||||
Lgc_Core_Start(&appLgcState);
|
||||
appTimerPoll.setInterval(30);
|
||||
appTimerPoll.start();
|
||||
appTimerAutoRefreshDevice.setInterval(1500);
|
||||
appTimerAutoRefreshDevice.start();
|
||||
App_Func_RefreshAfterLogicChange();
|
||||
}
|
||||
|
||||
QWidget* App_UIWindow::App_Func_CreatePadCard()
|
||||
{
|
||||
QVBoxLayout* p_Layout = nullptr;
|
||||
APP_GlassCard* p_Card = App_Func_CreateCard(this, &p_Layout);
|
||||
p_Layout->addWidget(App_Func_CreateLabel(
|
||||
p_Card,
|
||||
QStringLiteral("按键映射"),
|
||||
APP_Theme::App_Func_GetMetricFont()));
|
||||
p_Layout->addWidget(App_Func_CreateLabel(
|
||||
p_Card,
|
||||
QStringLiteral("左键直接模拟真实小键盘按下/抬起;右键把当前按键绑定到某个功能。绑定后,键帽左上角会显示功能名,悬停会显示功能简介。"),
|
||||
APP_Theme::App_Func_GetBodyFont(),
|
||||
true));
|
||||
|
||||
QGridLayout* p_Grid = new QGridLayout();
|
||||
p_Grid->setSpacing(14);
|
||||
|
||||
for (const APP_KeyInfo& Key : appKeypadModel.App_Func_GetKeyList())
|
||||
{
|
||||
APP_KeyButton* p_Button = new APP_KeyButton(Key, p_Card);
|
||||
p_Button->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(p_Button, &QPushButton::pressed, this, [this, Key]() { App_Func_HandleUiKeyPressed(Key.usage); });
|
||||
connect(p_Button, &QPushButton::released, this, [this, Key]() { App_Func_HandleUiKeyReleased(Key.usage); });
|
||||
connect(p_Button, &QWidget::customContextMenuRequested, this, [this, p_Button, Key](const QPoint&)
|
||||
{
|
||||
App_Func_ShowKeyMenu(
|
||||
Key.usage,
|
||||
p_Button->mapToGlobal(QPoint(p_Button->width() / 2, p_Button->height() / 2)));
|
||||
});
|
||||
|
||||
appKeypadButtonMap.insert(Key.id, p_Button);
|
||||
p_Grid->addWidget(p_Button, Key.row, Key.column, Key.rowSpan, Key.columnSpan);
|
||||
}
|
||||
|
||||
App_Func_SetGridStretch(p_Grid, 4, 5);
|
||||
p_Layout->addLayout(p_Grid, 1);
|
||||
return p_Card;
|
||||
}
|
||||
|
||||
QWidget* App_UIWindow::App_Func_CreateFunctionConfigCard()
|
||||
{
|
||||
QVBoxLayout* p_Layout = nullptr;
|
||||
APP_GlassCard* p_Card = App_Func_CreateCard(this, &p_Layout);
|
||||
const auto AddRow = [p_Card](QFormLayout* p_Form, const QString& LabelText, QWidget* p_Field)
|
||||
{
|
||||
p_Form->addRow(App_Func_CreateLabel(p_Card, LabelText, APP_Theme::App_Func_GetBodyFont()), p_Field);
|
||||
};
|
||||
|
||||
p_Layout->addWidget(App_Func_CreateLabel(
|
||||
p_Card,
|
||||
QStringLiteral("功能表"),
|
||||
APP_Theme::App_Func_GetMetricFont()));
|
||||
p_Layout->addWidget(App_Func_CreateLabel(
|
||||
p_Card,
|
||||
QStringLiteral("功能表默认为空,请先添加功能,再把按钮绑定到某个功能。当前支持“快捷键”“快捷键序列”和“打开网址”三种功能类型。"),
|
||||
APP_Theme::App_Func_GetBodyFont(),
|
||||
true));
|
||||
|
||||
QHBoxLayout* p_TopRow = new QHBoxLayout();
|
||||
p_TopRow->setContentsMargins(0, 0, 0, 0);
|
||||
p_TopRow->setSpacing(10);
|
||||
appFeatureAddButton = new QPushButton(QStringLiteral("添加功能"), p_Card);
|
||||
appFeatureDeleteButton = new QPushButton(QStringLiteral("删除功能"), p_Card);
|
||||
appFeatureDeleteButton->setEnabled(false);
|
||||
p_TopRow->addWidget(appFeatureAddButton);
|
||||
p_TopRow->addWidget(appFeatureDeleteButton);
|
||||
p_TopRow->addStretch(1);
|
||||
p_Layout->addLayout(p_TopRow);
|
||||
|
||||
appFeatureTable = new QTableWidget(p_Card);
|
||||
appFeatureTable->setColumnCount(3);
|
||||
appFeatureTable->setHorizontalHeaderLabels({ QStringLiteral("功能名"), QStringLiteral("功能简介"), QStringLiteral("类型") });
|
||||
appFeatureTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
appFeatureTable->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
appFeatureTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
appFeatureTable->setAlternatingRowColors(true);
|
||||
appFeatureTable->verticalHeader()->setVisible(false);
|
||||
appFeatureTable->horizontalHeader()->setStretchLastSection(false);
|
||||
appFeatureTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
appFeatureTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
appFeatureTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
|
||||
appFeatureTable->setMinimumHeight(220);
|
||||
p_Layout->addWidget(appFeatureTable);
|
||||
|
||||
QFormLayout* p_Form = new QFormLayout();
|
||||
p_Form->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
||||
p_Form->setLabelAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
p_Form->setHorizontalSpacing(10);
|
||||
p_Form->setVerticalSpacing(10);
|
||||
|
||||
appFeatureNameEdit = new QLineEdit(p_Card);
|
||||
appFeatureNameEdit->setPlaceholderText(QStringLiteral("例如:功能1 / 打开4399 / 前缀补码"));
|
||||
AddRow(p_Form, QStringLiteral("功能名"), appFeatureNameEdit);
|
||||
|
||||
appFeatureDescriptionEdit = new QLineEdit(p_Card);
|
||||
appFeatureDescriptionEdit->setPlaceholderText(QStringLiteral("例如:打开 4399 首页"));
|
||||
AddRow(p_Form, QStringLiteral("功能简介"), appFeatureDescriptionEdit);
|
||||
|
||||
appFeatureTypeCombo = new QComboBox(p_Card);
|
||||
appFeatureTypeCombo->addItem(
|
||||
Lgc_FunctionButton_GetFeatureTypeText(Lgc_FunctionFeature_Type::KeyCombination),
|
||||
static_cast<int>(Lgc_FunctionFeature_Type::KeyCombination));
|
||||
appFeatureTypeCombo->addItem(
|
||||
Lgc_FunctionButton_GetFeatureTypeText(Lgc_FunctionFeature_Type::KeySequence),
|
||||
static_cast<int>(Lgc_FunctionFeature_Type::KeySequence));
|
||||
appFeatureTypeCombo->addItem(
|
||||
Lgc_FunctionButton_GetFeatureTypeText(Lgc_FunctionFeature_Type::Website),
|
||||
static_cast<int>(Lgc_FunctionFeature_Type::Website));
|
||||
AddRow(p_Form, QStringLiteral("功能类型"), appFeatureTypeCombo);
|
||||
|
||||
appFeatureEditorStack = new QStackedWidget(p_Card);
|
||||
appFeatureEditorStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
|
||||
QWidget* p_SequencePage = new QWidget(appFeatureEditorStack);
|
||||
QFormLayout* p_SequenceForm = new QFormLayout(p_SequencePage);
|
||||
p_SequenceForm->setContentsMargins(0, 0, 0, 0);
|
||||
p_SequenceForm->setHorizontalSpacing(10);
|
||||
p_SequenceForm->setVerticalSpacing(10);
|
||||
|
||||
QWidget* p_SequenceEditor = new QWidget(p_SequencePage);
|
||||
QHBoxLayout* p_SequenceEditorLayout = new QHBoxLayout(p_SequenceEditor);
|
||||
p_SequenceEditorLayout->setContentsMargins(0, 0, 0, 0);
|
||||
p_SequenceEditorLayout->setSpacing(8);
|
||||
appFeatureSequenceEdit = new QLineEdit(p_SequenceEditor);
|
||||
appFeatureSequenceEdit->setPlaceholderText(QStringLiteral("例如:Ctrl+C"));
|
||||
appFeatureSequenceRecordStartButton = new QPushButton(QStringLiteral("开始录入"), p_SequenceEditor);
|
||||
appFeatureSequenceRecordStopButton = new QPushButton(QStringLiteral("退出录入"), p_SequenceEditor);
|
||||
appFeatureSequenceRecordStopButton->setEnabled(false);
|
||||
p_SequenceEditorLayout->addWidget(appFeatureSequenceEdit, 1);
|
||||
p_SequenceEditorLayout->addWidget(appFeatureSequenceRecordStartButton);
|
||||
p_SequenceEditorLayout->addWidget(appFeatureSequenceRecordStopButton);
|
||||
p_SequenceForm->addRow(QStringLiteral("快捷键"), p_SequenceEditor);
|
||||
|
||||
QWidget* p_WebsitePage = new QWidget(appFeatureEditorStack);
|
||||
QVBoxLayout* p_WebsiteLayout = new QVBoxLayout(p_WebsitePage);
|
||||
p_WebsiteLayout->setContentsMargins(0, 0, 0, 0);
|
||||
p_WebsiteLayout->setSpacing(0);
|
||||
appFeatureWebsiteEdit = new QLineEdit(p_WebsitePage);
|
||||
appFeatureWebsiteEdit->setPlaceholderText(QStringLiteral("例如直接输入 4399.com 或 www.4399.com"));
|
||||
p_WebsiteLayout->addWidget(appFeatureWebsiteEdit);
|
||||
|
||||
appFeatureEditorStack->addWidget(p_SequencePage);
|
||||
appFeatureEditorStack->addWidget(p_WebsitePage);
|
||||
AddRow(p_Form, QStringLiteral("功能参数"), appFeatureEditorStack);
|
||||
|
||||
appFeatureBindingSummaryLabel = App_Func_CreateLabel(
|
||||
p_Card,
|
||||
QStringLiteral("当前还没有功能,请点击“添加功能”。"),
|
||||
APP_Theme::App_Func_GetBodyFont(),
|
||||
true);
|
||||
AddRow(p_Form, QStringLiteral("绑定情况"), appFeatureBindingSummaryLabel);
|
||||
|
||||
appFunctionLabelStatus = App_Func_CreateLabel(
|
||||
p_Card,
|
||||
QStringLiteral("等待按键动作。"),
|
||||
APP_Theme::App_Func_GetBodyFont(),
|
||||
true);
|
||||
AddRow(p_Form, QStringLiteral("最近一次动作"), appFunctionLabelStatus);
|
||||
|
||||
p_Layout->addLayout(p_Form);
|
||||
p_Layout->addStretch(1);
|
||||
return p_Card;
|
||||
}
|
||||
|
||||
#if APP_ENABLE_DEBUG_WINDOW
|
||||
QWidget* App_UIWindow::App_Func_CreateDebugCard()
|
||||
{
|
||||
appDebugPanel = new DEBUG::Debug_Panel(this);
|
||||
appDebugPanel->Debug_Func_SetConnectionText(QStringLiteral("未连接,等待枚举设备。"), false);
|
||||
appDebugPanel->Debug_Func_SetLogText(QStringLiteral("等待收到输入包。"));
|
||||
return appDebugPanel;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace APP
|
||||
Reference in New Issue
Block a user