Files
0417_QT_code/APP/APP_UIWindow_Feature.cpp

292 lines
9.6 KiB
C++

#include "APP/APP_UIWindow.h"
#include "APP/APP_KeyButton.h"
#include "APP/APP_UIWindow_Private.h"
#include <QtCore/QSignalBlocker>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStackedWidget>
#include <QtWidgets/QTableWidget>
#include <QtWidgets/QTableWidgetItem>
namespace APP {
namespace
{
QString App_Func_GetDefaultKeyDescription(quint16 Usage)
{
return QStringLiteral(
"Default numpad key: %1. Left click simulates a real press/release. "
"Right click binds a function.")
.arg(Lgc_Core_GetUsageShortText(Usage));
}
} // namespace
void App_UIWindow::App_Func_RefreshKeypadState()
{
const Lgc_Core_Struct_View View = Lgc_Core_GetView(&appLgcState);
appKeypadModel.App_Func_SetNumLockOn(View.IsSystemNumLockOn);
if (View.IsPhysicalKeyStateValid)
{
appKeypadModel.App_Func_SetPressedKeysFromUsageList(View.PhysicalUsageList);
return;
}
if (View.IsVisibleKeyStateValid)
{
appKeypadModel.App_Func_SetPressedKeysFromUsageList(View.VisibleUsageList);
return;
}
appKeypadModel.App_Func_ClearPressedKeys();
}
void App_UIWindow::App_Func_RefreshKeypadButtons()
{
for (auto It = appKeypadButtonMap.begin(); It != appKeypadButtonMap.end(); ++It)
{
const QString KeyId = It.key();
const quint16 Usage = appKeypadModel.App_Func_GetUsageFromKeyId(KeyId);
const int FeatureId = Lgc_Core_GetUsageFeatureId(&appLgcState, Usage);
APP_KeyButton* p_Button = It.value();
p_Button->App_Func_SetLatched(
appKeypadModel.App_Func_IsLatched(KeyId) || (FeatureId > 0));
p_Button->App_Func_SetPressed(appKeypadModel.App_Func_IsPressed(KeyId));
p_Button->App_Func_SetHintText(
FeatureId > 0
? Lgc_Core_GetFeatureNameById(&appLgcState, FeatureId)
: appKeypadModel.App_Func_GetDefaultHint(KeyId));
p_Button->setToolTip(
FeatureId > 0
? Lgc_Core_GetFeatureDescriptionById(&appLgcState, FeatureId)
: App_Func_GetDefaultKeyDescription(Usage));
}
}
void App_UIWindow::App_Func_RefreshFeatureTable()
{
const QVector<int> FeatureIdList = Lgc_Core_GetFeatureIdList(&appLgcState);
const bool HasFeatures = !FeatureIdList.isEmpty();
QSignalBlocker Blocker(appFeatureTable);
appFeatureTable->clearContents();
appFeatureTable->setRowCount(FeatureIdList.size());
int TargetRow = -1;
for (int Row = 0; Row < FeatureIdList.size(); ++Row)
{
const int FeatureId = FeatureIdList.at(Row);
const Lgc_FunctionFeature_Definition Feature =
Lgc_Core_GetFeature(&appLgcState, FeatureId);
QTableWidgetItem* p_NameItem =
new QTableWidgetItem(Lgc_Core_GetFeatureNameById(&appLgcState, FeatureId));
p_NameItem->setData(Qt::UserRole, FeatureId);
appFeatureTable->setItem(Row, 0, p_NameItem);
appFeatureTable->setItem(
Row,
1,
new QTableWidgetItem(Lgc_Core_GetFeatureDescriptionById(&appLgcState, FeatureId)));
appFeatureTable->setItem(
Row,
2,
new QTableWidgetItem(Lgc_Core_GetFeatureTypeText(Feature.Type)));
if (FeatureId == appSelectedFeatureId)
{
TargetRow = Row;
}
}
appSelectedFeatureId =
TargetRow >= 0 ? appSelectedFeatureId : (HasFeatures ? FeatureIdList.first() : 0);
TargetRow = TargetRow >= 0 ? TargetRow : (HasFeatures ? 0 : -1);
if (TargetRow >= 0)
{
appFeatureTable->selectRow(TargetRow);
}
else
{
appFeatureTable->clearSelection();
}
App_Func_UpdateFeatureEditorState();
}
void App_UIWindow::App_Func_RefreshFunctionStatus()
{
const Lgc_Core_Struct_View View = Lgc_Core_GetView(&appLgcState);
appFunctionLabelStatus->setText(
View.TextFunctionStatus.isEmpty()
? QStringLiteral("Waiting for function-key activity.")
: View.TextFunctionStatus);
}
void App_UIWindow::App_Func_SelectFeature(int FeatureId, bool SwitchToFeaturePage)
{
if (appIsSequenceRecording && (FeatureId != appSelectedFeatureId))
{
App_Func_StopSequenceRecording();
}
appSelectedFeatureId =
Lgc_Core_GetFeature(&appLgcState, FeatureId).Id > 0 ? FeatureId : 0;
if (appSelectedFeatureId > 0)
{
for (int Row = 0; Row < appFeatureTable->rowCount(); ++Row)
{
QTableWidgetItem* p_Item = appFeatureTable->item(Row, 0);
if ((p_Item != nullptr) && (p_Item->data(Qt::UserRole).toInt() == appSelectedFeatureId))
{
QSignalBlocker Blocker(appFeatureTable);
appFeatureTable->selectRow(Row);
break;
}
}
}
App_Func_UpdateFeatureEditorState();
if (SwitchToFeaturePage)
{
appPageTab->setCurrentIndex(appFeaturePageIndex);
}
}
void App_UIWindow::App_Func_SaveFeatureFromUi()
{
if (appSelectedFeatureId <= 0)
{
return;
}
Lgc_FunctionFeature_Definition Feature =
Lgc_Core_GetFeature(&appLgcState, appSelectedFeatureId);
if (Feature.Id <= 0)
{
return;
}
Feature.Name = appFeatureNameEdit->text();
Feature.Description = appFeatureDescriptionEdit->text();
Feature.Type =
static_cast<Lgc_FunctionFeature_Type>(appFeatureTypeCombo->currentData().toInt());
Feature.SequenceText = appFeatureSequenceEdit->text();
Feature.WebsiteUrl = appFeatureWebsiteEdit->text();
if ((Feature.Type == Lgc_FunctionFeature_Type::Website) &&
Feature.WebsiteUrl.trimmed().isEmpty())
{
Feature.WebsiteUrl = QStringLiteral("https://");
QSignalBlocker Blocker(appFeatureWebsiteEdit);
appFeatureWebsiteEdit->setText(Feature.WebsiteUrl);
}
Lgc_Core_UpdateFeature(&appLgcState, Feature);
appFeatureEditorStack->setCurrentIndex(App_Func_GetFeatureStackIndex(Feature.Type));
App_Func_UpdateFeatureEditorHeight();
Lgc_Core_SaveFunctionConfig(&appLgcState);
App_Func_RefreshAfterLogicChange(); // FIX: keep Device Test and status text aligned after feature edits.
}
void App_UIWindow::App_Func_UpdateFeatureEditorHeight()
{
if ((appFeatureEditorStack == nullptr) || (appFeatureEditorStack->currentWidget() == nullptr))
{
return;
}
const int Height = appFeatureEditorStack->currentWidget()->sizeHint().height();
if (appFeatureEditorStack->height() != Height)
{
appFeatureEditorStack->setFixedHeight(Height);
}
}
void App_UIWindow::App_Func_UpdateFeatureEditorState()
{
const Lgc_FunctionFeature_Definition Feature =
Lgc_Core_GetFeature(&appLgcState, appSelectedFeatureId);
const bool HasFeature = Feature.Id > 0;
if (appIsSequenceRecording && (!HasFeature || !App_Func_IsKeyRecordFeatureType(Feature.Type)))
{
App_Func_StopSequenceRecording();
}
appFeatureNameEdit->setEnabled(HasFeature);
appFeatureDescriptionEdit->setEnabled(HasFeature);
appFeatureTypeCombo->setEnabled(HasFeature);
appFeatureEditorStack->setEnabled(HasFeature);
appFeatureDeleteButton->setEnabled(HasFeature);
appIsUpdatingFeatureUi = true;
if (!HasFeature)
{
appFeatureNameEdit->clear();
appFeatureDescriptionEdit->clear();
appFeatureSequenceEdit->clear();
appFeatureWebsiteEdit->clear();
appFeatureTypeCombo->setCurrentIndex(0);
appFeatureEditorStack->setCurrentIndex(0);
App_Func_UpdateFeatureEditorHeight();
appFeatureBindingSummaryLabel->setText(QStringLiteral("No function selected yet."));
appIsUpdatingFeatureUi = false;
App_Func_UpdateSequenceRecordingUi();
return;
}
appFeatureNameEdit->setText(Feature.Name);
appFeatureDescriptionEdit->setText(Feature.Description);
const int TypeIndex = appFeatureTypeCombo->findData(static_cast<int>(Feature.Type));
if (TypeIndex >= 0)
{
appFeatureTypeCombo->setCurrentIndex(TypeIndex);
}
appFeatureSequenceEdit->setText(Feature.SequenceText);
appFeatureWebsiteEdit->setText(App_Func_GetWebsiteEditText(Feature.WebsiteUrl));
appFeatureEditorStack->setCurrentIndex(App_Func_GetFeatureStackIndex(Feature.Type));
appFeatureSequenceEdit->setPlaceholderText(
Feature.Type == Lgc_FunctionFeature_Type::KeySequence
? QStringLiteral("Example: Ctrl+C -> Ctrl+A")
: QStringLiteral("Example: Ctrl+C"));
App_Func_UpdateFeatureEditorHeight();
appFeatureBindingSummaryLabel->setText(
Lgc_Core_GetFeatureBindingSummary(&appLgcState, Feature.Id));
appIsUpdatingFeatureUi = false;
App_Func_UpdateSequenceRecordingUi();
}
void App_UIWindow::App_Func_AddFeature()
{
const int FeatureId = Lgc_Core_AddFeature(&appLgcState);
Lgc_Core_SaveFunctionConfig(&appLgcState);
App_Func_RefreshFeatureTable(); // FIX: the feature table must update before reselection.
App_Func_RefreshAfterLogicChange(); // FIX: refresh Device Test and current config state after add.
App_Func_SelectFeature(FeatureId, true);
}
void App_UIWindow::App_Func_DeleteFeature()
{
if (appSelectedFeatureId <= 0)
{
return;
}
if (appIsSequenceRecording)
{
App_Func_StopSequenceRecording();
}
Lgc_Core_DeleteFeature(&appLgcState, appSelectedFeatureId);
appSelectedFeatureId = 0;
Lgc_Core_SaveFunctionConfig(&appLgcState);
App_Func_RefreshFeatureTable(); // FIX: rebuild the feature table after delete.
App_Func_RefreshAfterLogicChange(); // FIX: refresh Device Test and current config state after delete.
}
} // namespace APP