Remove premature non-DRI layers
This commit is contained in:
@@ -1,100 +0,0 @@
|
|||||||
#include "APP/AppKeyButton.h"
|
|
||||||
|
|
||||||
#include "APP/AppTheme.h"
|
|
||||||
|
|
||||||
namespace APP
|
|
||||||
{
|
|
||||||
|
|
||||||
App_KeyButton::App_KeyButton(quint16 Usage, const QString& Text, QWidget* p_Parent)
|
|
||||||
: QPushButton(Text, p_Parent),
|
|
||||||
appUsage(Usage),
|
|
||||||
appBaseText(Text)
|
|
||||||
{
|
|
||||||
setMinimumSize(88, 72);
|
|
||||||
setCheckable(false);
|
|
||||||
App_Func_RefreshText();
|
|
||||||
App_Func_RefreshStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
quint16 App_KeyButton::App_Func_GetUsage() const
|
|
||||||
{
|
|
||||||
return appUsage;
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_KeyButton::App_Func_SetPressedState(bool IsPressed)
|
|
||||||
{
|
|
||||||
if (appIsPressed == IsPressed)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
appIsPressed = IsPressed;
|
|
||||||
App_Func_RefreshStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_KeyButton::App_Func_SetLatchedState(bool IsLatched)
|
|
||||||
{
|
|
||||||
if (appIsLatched == IsLatched)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
appIsLatched = IsLatched;
|
|
||||||
App_Func_RefreshStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_KeyButton::App_Func_SetFeatureText(const QString& Text)
|
|
||||||
{
|
|
||||||
if (appFeatureText == Text.trimmed())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
appFeatureText = Text.trimmed();
|
|
||||||
App_Func_RefreshText();
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_KeyButton::App_Func_RefreshText()
|
|
||||||
{
|
|
||||||
if (appFeatureText.isEmpty())
|
|
||||||
{
|
|
||||||
setText(appBaseText);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setText(QStringLiteral("%1\n%2").arg(appBaseText, appFeatureText));
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_KeyButton::App_Func_RefreshStyle()
|
|
||||||
{
|
|
||||||
const App_ThemePalette Palette = App_Theme_DefaultPalette();
|
|
||||||
const QColor FillColor = appIsPressed
|
|
||||||
? Palette.Accent
|
|
||||||
: (appIsLatched ? Palette.AccentSoft : Palette.Surface);
|
|
||||||
const QColor TextColor = appIsPressed
|
|
||||||
? QColor(15, 23, 42)
|
|
||||||
: Palette.TextPrimary;
|
|
||||||
|
|
||||||
setStyleSheet(QStringLiteral(
|
|
||||||
"QPushButton {"
|
|
||||||
" background:rgb(%1,%2,%3);"
|
|
||||||
" color:rgb(%4,%5,%6);"
|
|
||||||
" border:1px solid rgb(%7,%8,%9);"
|
|
||||||
" border-radius:12px;"
|
|
||||||
" font-size:16px;"
|
|
||||||
" font-weight:600;"
|
|
||||||
" padding:8px;"
|
|
||||||
"}"
|
|
||||||
)
|
|
||||||
.arg(FillColor.red())
|
|
||||||
.arg(FillColor.green())
|
|
||||||
.arg(FillColor.blue())
|
|
||||||
.arg(TextColor.red())
|
|
||||||
.arg(TextColor.green())
|
|
||||||
.arg(TextColor.blue())
|
|
||||||
.arg(Palette.Border.red())
|
|
||||||
.arg(Palette.Border.green())
|
|
||||||
.arg(Palette.Border.blue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace APP
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QtGlobal>
|
|
||||||
#include <QtWidgets/QPushButton>
|
|
||||||
|
|
||||||
namespace APP
|
|
||||||
{
|
|
||||||
|
|
||||||
class App_KeyButton : public QPushButton
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit App_KeyButton(quint16 Usage, const QString& Text, QWidget* p_Parent = nullptr);
|
|
||||||
|
|
||||||
quint16 App_Func_GetUsage() const;
|
|
||||||
void App_Func_SetPressedState(bool IsPressed);
|
|
||||||
void App_Func_SetLatchedState(bool IsLatched);
|
|
||||||
void App_Func_SetFeatureText(const QString& Text);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void App_Func_RefreshText();
|
|
||||||
void App_Func_RefreshStyle();
|
|
||||||
|
|
||||||
quint16 appUsage = 0;
|
|
||||||
bool appIsPressed = false;
|
|
||||||
bool appIsLatched = false;
|
|
||||||
QString appBaseText;
|
|
||||||
QString appFeatureText;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace APP
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
#include "APP/AppKeyboardPage.h"
|
|
||||||
|
|
||||||
#include "APP/AppKeyButton.h"
|
|
||||||
#include "APP/AppTheme.h"
|
|
||||||
|
|
||||||
#include <QtWidgets/QFrame>
|
|
||||||
#include <QtWidgets/QGridLayout>
|
|
||||||
#include <QtWidgets/QLabel>
|
|
||||||
#include <QtWidgets/QVBoxLayout>
|
|
||||||
|
|
||||||
namespace APP
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
struct App_KeySpec
|
|
||||||
{
|
|
||||||
quint16 Usage;
|
|
||||||
const char* Text;
|
|
||||||
int Row;
|
|
||||||
int Column;
|
|
||||||
int RowSpan;
|
|
||||||
int ColumnSpan;
|
|
||||||
};
|
|
||||||
|
|
||||||
const App_KeySpec kKeySpecList[] = {
|
|
||||||
{ 0x0053, "Num", 0, 0, 1, 1 },
|
|
||||||
{ 0x0054, "/", 0, 1, 1, 1 },
|
|
||||||
{ 0x0055, "*", 0, 2, 1, 1 },
|
|
||||||
{ 0x0056, "-", 0, 3, 1, 1 },
|
|
||||||
{ 0x005F, "7", 1, 0, 1, 1 },
|
|
||||||
{ 0x0060, "8", 1, 1, 1, 1 },
|
|
||||||
{ 0x0061, "9", 1, 2, 1, 1 },
|
|
||||||
{ 0x0057, "+", 1, 3, 2, 1 },
|
|
||||||
{ 0x005C, "4", 2, 0, 1, 1 },
|
|
||||||
{ 0x005D, "5", 2, 1, 1, 1 },
|
|
||||||
{ 0x005E, "6", 2, 2, 1, 1 },
|
|
||||||
{ 0x0059, "1", 3, 0, 1, 1 },
|
|
||||||
{ 0x005A, "2", 3, 1, 1, 1 },
|
|
||||||
{ 0x005B, "3", 3, 2, 1, 1 },
|
|
||||||
{ 0x0058, "Enter", 3, 3, 2, 1 },
|
|
||||||
{ 0x0062, "0", 4, 0, 1, 2 },
|
|
||||||
{ 0x0063, ".", 4, 2, 1, 1 },
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
App_KeyboardPage::App_KeyboardPage(QWidget* p_Parent)
|
|
||||||
: QWidget(p_Parent)
|
|
||||||
{
|
|
||||||
App_Func_CreateLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_KeyboardPage::App_Func_SetPressedUsages(const QVector<quint16>& UsageList)
|
|
||||||
{
|
|
||||||
for (auto It = appButtonMap.begin(); It != appButtonMap.end(); ++It)
|
|
||||||
{
|
|
||||||
It.value()->App_Func_SetPressedState(UsageList.contains(It.key()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_KeyboardPage::App_Func_SetLatchedUsage(quint16 Usage, bool IsLatched)
|
|
||||||
{
|
|
||||||
App_KeyButton* const p_Button = appButtonMap.value(Usage, nullptr);
|
|
||||||
if (p_Button != nullptr)
|
|
||||||
{
|
|
||||||
p_Button->App_Func_SetLatchedState(IsLatched);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_KeyboardPage::App_Func_SetFeatureLabel(quint16 Usage, const QString& Text)
|
|
||||||
{
|
|
||||||
App_KeyButton* const p_Button = appButtonMap.value(Usage, nullptr);
|
|
||||||
if (p_Button != nullptr)
|
|
||||||
{
|
|
||||||
p_Button->App_Func_SetFeatureText(Text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_KeyboardPage::App_Func_CreateLayout()
|
|
||||||
{
|
|
||||||
const App_ThemePalette Palette = App_Theme_DefaultPalette();
|
|
||||||
|
|
||||||
QVBoxLayout* const p_RootLayout = new QVBoxLayout(this);
|
|
||||||
p_RootLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
p_RootLayout->setSpacing(12);
|
|
||||||
|
|
||||||
QFrame* const p_Card = new QFrame(this);
|
|
||||||
p_Card->setStyleSheet(App_Theme_BuildCardStyleSheet());
|
|
||||||
p_RootLayout->addWidget(p_Card);
|
|
||||||
|
|
||||||
QVBoxLayout* const p_CardLayout = new QVBoxLayout(p_Card);
|
|
||||||
p_CardLayout->setContentsMargins(20, 20, 20, 20);
|
|
||||||
p_CardLayout->setSpacing(14);
|
|
||||||
|
|
||||||
QLabel* const p_Title = new QLabel(QStringLiteral("Keyboard"), p_Card);
|
|
||||||
p_Title->setProperty("role", QStringLiteral("title"));
|
|
||||||
p_CardLayout->addWidget(p_Title);
|
|
||||||
|
|
||||||
QLabel* const p_Body = new QLabel(
|
|
||||||
QStringLiteral("Start from one button, then grow into the whole keypad layout."),
|
|
||||||
p_Card);
|
|
||||||
p_Body->setProperty("role", QStringLiteral("body"));
|
|
||||||
p_Body->setWordWrap(true);
|
|
||||||
p_CardLayout->addWidget(p_Body);
|
|
||||||
|
|
||||||
QGridLayout* const p_GridLayout = new QGridLayout();
|
|
||||||
p_GridLayout->setSpacing(12);
|
|
||||||
p_CardLayout->addLayout(p_GridLayout);
|
|
||||||
|
|
||||||
for (const App_KeySpec& KeySpec : kKeySpecList)
|
|
||||||
{
|
|
||||||
App_KeyButton* const p_Button =
|
|
||||||
new App_KeyButton(KeySpec.Usage, QString::fromUtf8(KeySpec.Text), p_Card);
|
|
||||||
p_GridLayout->addWidget(
|
|
||||||
p_Button,
|
|
||||||
KeySpec.Row,
|
|
||||||
KeySpec.Column,
|
|
||||||
KeySpec.RowSpan,
|
|
||||||
KeySpec.ColumnSpan);
|
|
||||||
appButtonMap.insert(KeySpec.Usage, p_Button);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int Column = 0; Column < 4; ++Column)
|
|
||||||
{
|
|
||||||
p_GridLayout->setColumnStretch(Column, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_UNUSED(Palette);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace APP
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QHash>
|
|
||||||
#include <QtCore/QVector>
|
|
||||||
#include <QtWidgets/QWidget>
|
|
||||||
|
|
||||||
namespace APP
|
|
||||||
{
|
|
||||||
|
|
||||||
class App_KeyButton;
|
|
||||||
|
|
||||||
class App_KeyboardPage : public QWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit App_KeyboardPage(QWidget* p_Parent = nullptr);
|
|
||||||
|
|
||||||
void App_Func_SetPressedUsages(const QVector<quint16>& UsageList);
|
|
||||||
void App_Func_SetLatchedUsage(quint16 Usage, bool IsLatched);
|
|
||||||
void App_Func_SetFeatureLabel(quint16 Usage, const QString& Text);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void App_Func_CreateLayout();
|
|
||||||
|
|
||||||
QHash<quint16, App_KeyButton*> appButtonMap;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace APP
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
#include "APP/AppMainWindow.h"
|
|
||||||
|
|
||||||
#include "APP/AppKeyboardPage.h"
|
|
||||||
#include "APP/AppSettingsPage.h"
|
|
||||||
#include "APP/AppTheme.h"
|
|
||||||
|
|
||||||
#include <QtWidgets/QTabWidget>
|
|
||||||
#include <QtCore/QTimer>
|
|
||||||
#include <QtWidgets/QVBoxLayout>
|
|
||||||
|
|
||||||
namespace APP
|
|
||||||
{
|
|
||||||
|
|
||||||
App_MainWindow::App_MainWindow(QWidget* p_Parent)
|
|
||||||
: QWidget(p_Parent)
|
|
||||||
{
|
|
||||||
setWindowTitle(QStringLiteral("KeyBorad"));
|
|
||||||
resize(860, 760);
|
|
||||||
setStyleSheet(App_Theme_BuildWindowStyleSheet());
|
|
||||||
|
|
||||||
QVBoxLayout* const p_RootLayout = new QVBoxLayout(this);
|
|
||||||
p_RootLayout->setContentsMargins(20, 20, 20, 20);
|
|
||||||
p_RootLayout->setSpacing(12);
|
|
||||||
|
|
||||||
appTabWidget = new QTabWidget(this);
|
|
||||||
appKeyboardPage = new App_KeyboardPage(appTabWidget);
|
|
||||||
appSettingsPage = new App_SettingsPage(appTabWidget);
|
|
||||||
|
|
||||||
appTabWidget->addTab(appKeyboardPage, QStringLiteral("Keyboard"));
|
|
||||||
appTabWidget->addTab(appSettingsPage, QStringLiteral("Settings"));
|
|
||||||
|
|
||||||
p_RootLayout->addWidget(appTabWidget);
|
|
||||||
|
|
||||||
appPollTimer = new QTimer(this);
|
|
||||||
connect(appPollTimer, &QTimer::timeout, this, [this]()
|
|
||||||
{
|
|
||||||
if (Lgc_Core_Poll(&appLogic))
|
|
||||||
{
|
|
||||||
App_Func_RefreshFromLogic();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
App_Func_StartLogic();
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_MainWindow::App_Func_StartLogic()
|
|
||||||
{
|
|
||||||
Lgc_Core_Init(&appLogic);
|
|
||||||
Lgc_Core_Start(&appLogic);
|
|
||||||
App_Func_RefreshFromLogic();
|
|
||||||
appPollTimer->start(30);
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_MainWindow::App_Func_RefreshFromLogic()
|
|
||||||
{
|
|
||||||
const Lgc_State& State = Lgc_Core_GetState(&appLogic);
|
|
||||||
appSettingsPage->App_Func_SetConnectionText(State.ConnectionText);
|
|
||||||
appSettingsPage->App_Func_SetLastActionText(State.LastActionText);
|
|
||||||
}
|
|
||||||
|
|
||||||
App_KeyboardPage* App_MainWindow::App_Func_GetKeyboardPage() const
|
|
||||||
{
|
|
||||||
return appKeyboardPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
App_SettingsPage* App_MainWindow::App_Func_GetSettingsPage() const
|
|
||||||
{
|
|
||||||
return appSettingsPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace APP
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "LOGIC/Lgc_Core.h"
|
|
||||||
|
|
||||||
#include <QtWidgets/QWidget>
|
|
||||||
|
|
||||||
class QTabWidget;
|
|
||||||
class QTimer;
|
|
||||||
|
|
||||||
namespace APP
|
|
||||||
{
|
|
||||||
|
|
||||||
class App_KeyboardPage;
|
|
||||||
class App_SettingsPage;
|
|
||||||
|
|
||||||
class App_MainWindow : public QWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit App_MainWindow(QWidget* p_Parent = nullptr);
|
|
||||||
|
|
||||||
App_KeyboardPage* App_Func_GetKeyboardPage() const;
|
|
||||||
App_SettingsPage* App_Func_GetSettingsPage() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void App_Func_StartLogic();
|
|
||||||
void App_Func_RefreshFromLogic();
|
|
||||||
|
|
||||||
QTabWidget* appTabWidget = nullptr;
|
|
||||||
App_KeyboardPage* appKeyboardPage = nullptr;
|
|
||||||
App_SettingsPage* appSettingsPage = nullptr;
|
|
||||||
QTimer* appPollTimer = nullptr;
|
|
||||||
Lgc_Core appLogic;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace APP
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
#include "APP/AppSettingsPage.h"
|
|
||||||
|
|
||||||
#include "APP/AppTheme.h"
|
|
||||||
|
|
||||||
#include <QtWidgets/QFrame>
|
|
||||||
#include <QtWidgets/QFormLayout>
|
|
||||||
#include <QtWidgets/QLabel>
|
|
||||||
#include <QtWidgets/QVBoxLayout>
|
|
||||||
|
|
||||||
namespace APP
|
|
||||||
{
|
|
||||||
|
|
||||||
App_SettingsPage::App_SettingsPage(QWidget* p_Parent)
|
|
||||||
: QWidget(p_Parent)
|
|
||||||
{
|
|
||||||
QVBoxLayout* const p_RootLayout = new QVBoxLayout(this);
|
|
||||||
p_RootLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
p_RootLayout->setSpacing(12);
|
|
||||||
|
|
||||||
QFrame* const p_Card = new QFrame(this);
|
|
||||||
p_Card->setStyleSheet(App_Theme_BuildCardStyleSheet());
|
|
||||||
p_RootLayout->addWidget(p_Card);
|
|
||||||
|
|
||||||
QVBoxLayout* const p_CardLayout = new QVBoxLayout(p_Card);
|
|
||||||
p_CardLayout->setContentsMargins(20, 20, 20, 20);
|
|
||||||
p_CardLayout->setSpacing(14);
|
|
||||||
|
|
||||||
QLabel* const p_Title = new QLabel(QStringLiteral("Settings"), p_Card);
|
|
||||||
p_Title->setProperty("role", QStringLiteral("title"));
|
|
||||||
p_CardLayout->addWidget(p_Title);
|
|
||||||
|
|
||||||
QLabel* const p_Body = new QLabel(
|
|
||||||
QStringLiteral("Use this page to present transport status and the latest function result."),
|
|
||||||
p_Card);
|
|
||||||
p_Body->setProperty("role", QStringLiteral("body"));
|
|
||||||
p_Body->setWordWrap(true);
|
|
||||||
p_CardLayout->addWidget(p_Body);
|
|
||||||
|
|
||||||
QFormLayout* const p_FormLayout = new QFormLayout();
|
|
||||||
p_FormLayout->setHorizontalSpacing(12);
|
|
||||||
p_FormLayout->setVerticalSpacing(12);
|
|
||||||
p_CardLayout->addLayout(p_FormLayout);
|
|
||||||
|
|
||||||
appConnectionLabel = new QLabel(QStringLiteral("Disconnected"), p_Card);
|
|
||||||
appLastActionLabel = new QLabel(QStringLiteral("Idle"), p_Card);
|
|
||||||
|
|
||||||
p_FormLayout->addRow(QStringLiteral("Transport"), appConnectionLabel);
|
|
||||||
p_FormLayout->addRow(QStringLiteral("Last Action"), appLastActionLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_SettingsPage::App_Func_SetConnectionText(const QString& Text)
|
|
||||||
{
|
|
||||||
appConnectionLabel->setText(Text.trimmed().isEmpty() ? QStringLiteral("Disconnected") : Text.trimmed());
|
|
||||||
}
|
|
||||||
|
|
||||||
void App_SettingsPage::App_Func_SetLastActionText(const QString& Text)
|
|
||||||
{
|
|
||||||
appLastActionLabel->setText(Text.trimmed().isEmpty() ? QStringLiteral("Idle") : Text.trimmed());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace APP
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtWidgets/QWidget>
|
|
||||||
|
|
||||||
class QLabel;
|
|
||||||
|
|
||||||
namespace APP
|
|
||||||
{
|
|
||||||
|
|
||||||
class App_SettingsPage : public QWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit App_SettingsPage(QWidget* p_Parent = nullptr);
|
|
||||||
|
|
||||||
void App_Func_SetConnectionText(const QString& Text);
|
|
||||||
void App_Func_SetLastActionText(const QString& Text);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QLabel* appConnectionLabel = nullptr;
|
|
||||||
QLabel* appLastActionLabel = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace APP
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
#include "APP/AppTheme.h"
|
|
||||||
|
|
||||||
namespace APP
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
QString App_Func_RgbText(const QColor& Color)
|
|
||||||
{
|
|
||||||
return QStringLiteral("rgb(%1, %2, %3)")
|
|
||||||
.arg(Color.red())
|
|
||||||
.arg(Color.green())
|
|
||||||
.arg(Color.blue());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
App_ThemePalette App_Theme_DefaultPalette()
|
|
||||||
{
|
|
||||||
return App_ThemePalette();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString App_Theme_BuildWindowStyleSheet()
|
|
||||||
{
|
|
||||||
const App_ThemePalette Palette = App_Theme_DefaultPalette();
|
|
||||||
|
|
||||||
return QStringLiteral(
|
|
||||||
"QWidget {"
|
|
||||||
" background:%1;"
|
|
||||||
" color:%2;"
|
|
||||||
"}"
|
|
||||||
"QTabWidget::pane {"
|
|
||||||
" border:1px solid %3;"
|
|
||||||
" border-radius:12px;"
|
|
||||||
" background:%4;"
|
|
||||||
"}"
|
|
||||||
"QTabBar::tab {"
|
|
||||||
" background:%4;"
|
|
||||||
" color:%5;"
|
|
||||||
" padding:10px 16px;"
|
|
||||||
" margin-right:6px;"
|
|
||||||
" border:1px solid %3;"
|
|
||||||
" border-bottom:none;"
|
|
||||||
" border-top-left-radius:10px;"
|
|
||||||
" border-top-right-radius:10px;"
|
|
||||||
"}"
|
|
||||||
"QTabBar::tab:selected {"
|
|
||||||
" color:%2;"
|
|
||||||
" background:%1;"
|
|
||||||
"}"
|
|
||||||
)
|
|
||||||
.arg(App_Func_RgbText(Palette.Window))
|
|
||||||
.arg(App_Func_RgbText(Palette.TextPrimary))
|
|
||||||
.arg(App_Func_RgbText(Palette.Border))
|
|
||||||
.arg(App_Func_RgbText(Palette.Surface))
|
|
||||||
.arg(App_Func_RgbText(Palette.TextMuted));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString App_Theme_BuildCardStyleSheet()
|
|
||||||
{
|
|
||||||
const App_ThemePalette Palette = App_Theme_DefaultPalette();
|
|
||||||
|
|
||||||
return QStringLiteral(
|
|
||||||
"QFrame {"
|
|
||||||
" background:%1;"
|
|
||||||
" border:1px solid %2;"
|
|
||||||
" border-radius:14px;"
|
|
||||||
"}"
|
|
||||||
"QLabel[role=\"title\"] {"
|
|
||||||
" color:%3;"
|
|
||||||
" font-size:20px;"
|
|
||||||
" font-weight:600;"
|
|
||||||
"}"
|
|
||||||
"QLabel[role=\"body\"] {"
|
|
||||||
" color:%4;"
|
|
||||||
" font-size:13px;"
|
|
||||||
"}"
|
|
||||||
)
|
|
||||||
.arg(App_Func_RgbText(Palette.Surface))
|
|
||||||
.arg(App_Func_RgbText(Palette.Border))
|
|
||||||
.arg(App_Func_RgbText(Palette.TextPrimary))
|
|
||||||
.arg(App_Func_RgbText(Palette.TextMuted));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace APP
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtGui/QColor>
|
|
||||||
|
|
||||||
namespace APP
|
|
||||||
{
|
|
||||||
|
|
||||||
struct App_ThemePalette
|
|
||||||
{
|
|
||||||
QColor Window = QColor(15, 23, 42);
|
|
||||||
QColor Surface = QColor(17, 24, 39);
|
|
||||||
QColor Border = QColor(51, 65, 85);
|
|
||||||
QColor TextPrimary = QColor(226, 232, 240);
|
|
||||||
QColor TextMuted = QColor(148, 163, 184);
|
|
||||||
QColor Accent = QColor(76, 201, 240);
|
|
||||||
QColor AccentSoft = QColor(34, 197, 94);
|
|
||||||
};
|
|
||||||
|
|
||||||
App_ThemePalette App_Theme_DefaultPalette();
|
|
||||||
QString App_Theme_BuildWindowStyleSheet();
|
|
||||||
QString App_Theme_BuildCardStyleSheet();
|
|
||||||
|
|
||||||
} // namespace APP
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
#include "COM/Com_ProtoCodec.h"
|
|
||||||
|
|
||||||
#include "COM/Com_CdcDecode.h"
|
|
||||||
#include "COM/Com_CdcEncode.h"
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
quint16 Com_Func_ReadLe16(const QByteArray& ByteArray, int Offset)
|
|
||||||
{
|
|
||||||
return static_cast<quint16>(
|
|
||||||
static_cast<quint8>(ByteArray.at(Offset)) |
|
|
||||||
(static_cast<quint16>(static_cast<quint8>(ByteArray.at(Offset + 1))) << 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
bool Com_ProtoCodec_ParseFrame(const QByteArray& ByteArray, Packet* p_Packet)
|
|
||||||
{
|
|
||||||
return Com_Cdc_Func_ParseFrame(ByteArray, p_Packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Com_ProtoCodec_TryTakeFrame(QByteArray* p_Buffer, Packet* p_Packet)
|
|
||||||
{
|
|
||||||
return Com_Cdc_Func_TryTakeFrame(p_Buffer, p_Packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray Com_ProtoCodec_BuildHelloReq()
|
|
||||||
{
|
|
||||||
const Packet_HelloReq HelloReq;
|
|
||||||
return Com_Cdc_Func_BuildHelloReq(HelloReq);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Com_ProtoCodec_IsHelloRsp(const Packet& PacketData)
|
|
||||||
{
|
|
||||||
return (PacketData.type == Com_Type_HelloRsp) &&
|
|
||||||
(PacketData.data.size() == Packet_len::Com_Len_HelloRsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Com_ProtoCodec_ParseHelloRsp(
|
|
||||||
const Packet& PacketData,
|
|
||||||
Packet_HelloRsp* p_HelloRsp)
|
|
||||||
{
|
|
||||||
if ((p_HelloRsp == nullptr) || !Com_ProtoCodec_IsHelloRsp(PacketData))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Packet_HelloRsp HelloRsp;
|
|
||||||
HelloRsp.ProtocolVersion = static_cast<quint8>(PacketData.data.at(0));
|
|
||||||
HelloRsp.VendorId = Com_Func_ReadLe16(PacketData.data, 1);
|
|
||||||
HelloRsp.ProductId = Com_Func_ReadLe16(PacketData.data, 3);
|
|
||||||
HelloRsp.FirmwareMajor = static_cast<quint8>(PacketData.data.at(5));
|
|
||||||
HelloRsp.FirmwareMinor = static_cast<quint8>(PacketData.data.at(6));
|
|
||||||
HelloRsp.CapabilityFlags = Com_Func_ReadLe16(PacketData.data, 7);
|
|
||||||
|
|
||||||
*p_HelloRsp = HelloRsp;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QByteArray>
|
|
||||||
|
|
||||||
#include "COM/Com_Cdc.h"
|
|
||||||
|
|
||||||
bool Com_ProtoCodec_ParseFrame(const QByteArray& ByteArray, Packet* p_Packet);
|
|
||||||
bool Com_ProtoCodec_TryTakeFrame(QByteArray* p_Buffer, Packet* p_Packet);
|
|
||||||
|
|
||||||
QByteArray Com_ProtoCodec_BuildHelloReq();
|
|
||||||
bool Com_ProtoCodec_IsHelloRsp(const Packet& PacketData);
|
|
||||||
bool Com_ProtoCodec_ParseHelloRsp(
|
|
||||||
const Packet& PacketData,
|
|
||||||
Packet_HelloRsp* p_HelloRsp);
|
|
||||||
@@ -37,12 +37,12 @@
|
|||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
|
||||||
<QtInstall>D:\App\Qt\5.13.1\msvc2015_64</QtInstall>
|
<QtInstall>D:\App\Qt\5.13.1\msvc2015_64</QtInstall>
|
||||||
<QtModules>core;serialport;widgets</QtModules>
|
<QtModules>core;serialport</QtModules>
|
||||||
<QtBuildConfig>debug</QtBuildConfig>
|
<QtBuildConfig>debug</QtBuildConfig>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
|
||||||
<QtInstall>D:\App\Qt\5.13.1\msvc2015_64</QtInstall>
|
<QtInstall>D:\App\Qt\5.13.1\msvc2015_64</QtInstall>
|
||||||
<QtModules>core;serialport;widgets</QtModules>
|
<QtModules>core;serialport</QtModules>
|
||||||
<QtBuildConfig>release</QtBuildConfig>
|
<QtBuildConfig>release</QtBuildConfig>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
|
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
|
||||||
@@ -94,18 +94,7 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="APP\AppKeyButton.cpp" />
|
|
||||||
<ClInclude Include="APP\AppKeyButton.h" />
|
|
||||||
<ClCompile Include="APP\AppKeyboardPage.cpp" />
|
|
||||||
<ClInclude Include="APP\AppKeyboardPage.h" />
|
|
||||||
<ClCompile Include="APP\AppMainWindow.cpp" />
|
|
||||||
<ClInclude Include="APP\AppMainWindow.h" />
|
|
||||||
<ClCompile Include="APP\AppSettingsPage.cpp" />
|
|
||||||
<ClInclude Include="APP\AppSettingsPage.h" />
|
|
||||||
<ClInclude Include="APP\AppTheme.h" />
|
|
||||||
<ClInclude Include="COM\Com_Cdc.h" />
|
<ClInclude Include="COM\Com_Cdc.h" />
|
||||||
<ClCompile Include="COM\Com_ProtoCodec.cpp" />
|
|
||||||
<ClInclude Include="COM\Com_ProtoCodec.h" />
|
|
||||||
<ClCompile Include="COM\Com_CdcEncode.cpp" />
|
<ClCompile Include="COM\Com_CdcEncode.cpp" />
|
||||||
<ClInclude Include="COM\Com_CdcEncode.h" />
|
<ClInclude Include="COM\Com_CdcEncode.h" />
|
||||||
<ClCompile Include="COM\Com_CdcDecode.cpp" />
|
<ClCompile Include="COM\Com_CdcDecode.cpp" />
|
||||||
@@ -113,14 +102,6 @@
|
|||||||
<ClCompile Include="DRI\Dri_Cdc.cpp" />
|
<ClCompile Include="DRI\Dri_Cdc.cpp" />
|
||||||
<ClCompile Include="DRI\GATT\Dri_Gatt.cpp" />
|
<ClCompile Include="DRI\GATT\Dri_Gatt.cpp" />
|
||||||
<ClInclude Include="DRI\GATT\Dri_Gatt.h" />
|
<ClInclude Include="DRI\GATT\Dri_Gatt.h" />
|
||||||
<ClCompile Include="APP\AppTheme.cpp" />
|
|
||||||
<ClCompile Include="LOGIC\Lgc_Core.cpp" />
|
|
||||||
<ClInclude Include="LOGIC\Lgc_Core.h" />
|
|
||||||
<ClCompile Include="LOGIC\Lgc_FunctionExecutor.cpp" />
|
|
||||||
<ClInclude Include="LOGIC\Lgc_FunctionExecutor.h" />
|
|
||||||
<ClCompile Include="LOGIC\Lgc_Session.cpp" />
|
|
||||||
<ClInclude Include="LOGIC\Lgc_Session.h" />
|
|
||||||
<ClInclude Include="LOGIC\Lgc_State.h" />
|
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClInclude Include="DRI\Dri_Cdc.h" />
|
<ClInclude Include="DRI\Dri_Cdc.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -23,42 +23,9 @@
|
|||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="APP\AppKeyButton.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClInclude Include="APP\AppKeyButton.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClCompile Include="APP\AppKeyboardPage.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClInclude Include="APP\AppKeyboardPage.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClCompile Include="APP\AppMainWindow.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClInclude Include="APP\AppMainWindow.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClCompile Include="APP\AppSettingsPage.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClInclude Include="APP\AppSettingsPage.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="APP\AppTheme.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="COM\Com_Cdc.h">
|
<ClInclude Include="COM\Com_Cdc.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClCompile Include="COM\Com_ProtoCodec.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClInclude Include="COM\Com_ProtoCodec.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClCompile Include="COM\Com_CdcEncode.cpp">
|
<ClCompile Include="COM\Com_CdcEncode.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -80,30 +47,6 @@
|
|||||||
<ClInclude Include="DRI\GATT\Dri_Gatt.h">
|
<ClInclude Include="DRI\GATT\Dri_Gatt.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClCompile Include="APP\AppTheme.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="LOGIC\Lgc_Core.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClInclude Include="LOGIC\Lgc_Core.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClCompile Include="LOGIC\Lgc_FunctionExecutor.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClInclude Include="LOGIC\Lgc_FunctionExecutor.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClCompile Include="LOGIC\Lgc_Session.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClInclude Include="LOGIC\Lgc_Session.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="LOGIC\Lgc_State.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClCompile Include="main.cpp">
|
<ClCompile Include="main.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@@ -1,129 +0,0 @@
|
|||||||
#include "LOGIC/Lgc_Core.h"
|
|
||||||
|
|
||||||
#include "COM/Com_ProtoCodec.h"
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
void Lgc_Func_ApplyHelloRsp(
|
|
||||||
Lgc_Core* p_Core,
|
|
||||||
const Packet_HelloRsp& HelloRsp)
|
|
||||||
{
|
|
||||||
p_Core->State.IsConnected = true;
|
|
||||||
p_Core->State.IsHandshakeDone = true;
|
|
||||||
p_Core->State.ProtocolVersion = HelloRsp.ProtocolVersion;
|
|
||||||
p_Core->State.VendorId = HelloRsp.VendorId;
|
|
||||||
p_Core->State.ProductId = HelloRsp.ProductId;
|
|
||||||
p_Core->State.FirmwareMajor = HelloRsp.FirmwareMajor;
|
|
||||||
p_Core->State.FirmwareMinor = HelloRsp.FirmwareMinor;
|
|
||||||
p_Core->State.CapabilityFlags = HelloRsp.CapabilityFlags;
|
|
||||||
p_Core->State.ActiveTransport = Lgc_TransportType::Cdc;
|
|
||||||
p_Core->State.ActiveEndpointName = p_Core->Session.CdcPort.PortName;
|
|
||||||
p_Core->State.ConnectionText = QStringLiteral("CDC connected: %1")
|
|
||||||
.arg(p_Core->Session.CdcPort.PortName);
|
|
||||||
p_Core->State.LastActionText = QStringLiteral("Handshake completed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lgc_Func_UpdateActionText(Lgc_Core* p_Core, const Packet& PacketData)
|
|
||||||
{
|
|
||||||
switch (PacketData.type)
|
|
||||||
{
|
|
||||||
case Com_Type_HelloRsp:
|
|
||||||
p_Core->State.LastActionText = QStringLiteral("Received HelloRsp.");
|
|
||||||
break;
|
|
||||||
case Com_Type_Bitmap:
|
|
||||||
p_Core->State.LastActionText = QStringLiteral("Received Bitmap.");
|
|
||||||
break;
|
|
||||||
case Com_Type_FunctionKeyEvent:
|
|
||||||
p_Core->State.LastActionText = QStringLiteral("Received FunctionKeyEvent.");
|
|
||||||
break;
|
|
||||||
case Com_Type_LedState:
|
|
||||||
p_Core->State.LastActionText = QStringLiteral("Received LedState.");
|
|
||||||
break;
|
|
||||||
case Com_Type_TimeSync:
|
|
||||||
p_Core->State.LastActionText = QStringLiteral("Received TimeSync.");
|
|
||||||
break;
|
|
||||||
case Com_Type_ThemeRgb:
|
|
||||||
p_Core->State.LastActionText = QStringLiteral("Received ThemeRgb.");
|
|
||||||
break;
|
|
||||||
case Com_Type_Ack:
|
|
||||||
p_Core->State.LastActionText = QStringLiteral("Received Ack.");
|
|
||||||
break;
|
|
||||||
case Com_Type_Error:
|
|
||||||
p_Core->State.LastActionText = QStringLiteral("Received Error.");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
p_Core->State.LastActionText = QStringLiteral("Received packet type 0x%1.")
|
|
||||||
.arg(static_cast<quint8>(PacketData.type), 2, 16, QLatin1Char('0'))
|
|
||||||
.toUpper();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void Lgc_Core_Init(Lgc_Core* p_Core)
|
|
||||||
{
|
|
||||||
if (p_Core == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_Core->State = Lgc_State();
|
|
||||||
Lgc_Session_Init(&p_Core->Session);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Lgc_Core_Start(Lgc_Core* p_Core)
|
|
||||||
{
|
|
||||||
if (p_Core == nullptr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dri_Cdc_Struct_OpenConfig Config;
|
|
||||||
Packet_HelloRsp HelloRsp;
|
|
||||||
if (Lgc_Session_TryStartCdc(&p_Core->Session, Config, &HelloRsp))
|
|
||||||
{
|
|
||||||
Lgc_Func_ApplyHelloRsp(p_Core, HelloRsp);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_Core->State.IsConnected = false;
|
|
||||||
p_Core->State.IsHandshakeDone = false;
|
|
||||||
p_Core->State.ConnectionText = QStringLiteral("No device found.");
|
|
||||||
p_Core->State.LastActionText = QStringLiteral("Handshake failed.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Lgc_Core_Poll(Lgc_Core* p_Core)
|
|
||||||
{
|
|
||||||
if (p_Core == nullptr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Packet PacketData;
|
|
||||||
if (!Lgc_Session_ReadNextPacket(&p_Core->Session, &PacketData))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Lgc_Func_UpdateActionText(p_Core, PacketData);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lgc_Core_Close(Lgc_Core* p_Core)
|
|
||||||
{
|
|
||||||
if (p_Core == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Lgc_Session_Close(&p_Core->Session);
|
|
||||||
p_Core->State = Lgc_State();
|
|
||||||
}
|
|
||||||
|
|
||||||
const Lgc_State& Lgc_Core_GetState(const Lgc_Core* p_Core)
|
|
||||||
{
|
|
||||||
return p_Core->State;
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "LOGIC/Lgc_Session.h"
|
|
||||||
#include "LOGIC/Lgc_State.h"
|
|
||||||
|
|
||||||
struct Lgc_Core
|
|
||||||
{
|
|
||||||
Lgc_State State;
|
|
||||||
Lgc_Session Session;
|
|
||||||
};
|
|
||||||
|
|
||||||
void Lgc_Core_Init(Lgc_Core* p_Core);
|
|
||||||
bool Lgc_Core_Start(Lgc_Core* p_Core);
|
|
||||||
bool Lgc_Core_Poll(Lgc_Core* p_Core);
|
|
||||||
void Lgc_Core_Close(Lgc_Core* p_Core);
|
|
||||||
const Lgc_State& Lgc_Core_GetState(const Lgc_Core* p_Core);
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
#include "LOGIC/Lgc_FunctionExecutor.h"
|
|
||||||
|
|
||||||
#include <QtCore/QUrl>
|
|
||||||
#include <QtGui/QDesktopServices>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
QString Lgc_Func_GetFunctionName(const Lgc_FunctionDefinition& Function)
|
|
||||||
{
|
|
||||||
return Function.Name.trimmed().isEmpty()
|
|
||||||
? QStringLiteral("Unnamed Function")
|
|
||||||
: Function.Name.trimmed();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
bool Lgc_FunctionExecutor_Run(
|
|
||||||
const Lgc_FunctionDefinition& Function,
|
|
||||||
QString* p_TextStatus)
|
|
||||||
{
|
|
||||||
if (p_TextStatus != nullptr)
|
|
||||||
{
|
|
||||||
p_TextStatus->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Function.Type)
|
|
||||||
{
|
|
||||||
case Lgc_FunctionType::None:
|
|
||||||
if (p_TextStatus != nullptr)
|
|
||||||
{
|
|
||||||
*p_TextStatus = QStringLiteral("%1 has no executable action.")
|
|
||||||
.arg(Lgc_Func_GetFunctionName(Function));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Lgc_FunctionType::Shortcut:
|
|
||||||
if (p_TextStatus != nullptr)
|
|
||||||
{
|
|
||||||
*p_TextStatus = QStringLiteral("Shortcut execution will be connected after transport is ready.");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Lgc_FunctionType::ShortcutSequence:
|
|
||||||
if (p_TextStatus != nullptr)
|
|
||||||
{
|
|
||||||
*p_TextStatus = QStringLiteral("Shortcut sequence execution will be connected after transport is ready.");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Lgc_FunctionType::Website:
|
|
||||||
{
|
|
||||||
const QUrl Url = QUrl::fromUserInput(Function.WebsiteUrl.trimmed());
|
|
||||||
const bool IsOpened = Url.isValid() && !Url.isEmpty() && QDesktopServices::openUrl(Url);
|
|
||||||
|
|
||||||
if (p_TextStatus != nullptr)
|
|
||||||
{
|
|
||||||
*p_TextStatus = IsOpened
|
|
||||||
? QStringLiteral("Opened website: %1").arg(Url.toString())
|
|
||||||
: QStringLiteral("Failed to open website for %1.").arg(Lgc_Func_GetFunctionName(Function));
|
|
||||||
}
|
|
||||||
|
|
||||||
return IsOpened;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtCore/QStringList>
|
|
||||||
#include <QtCore/QtGlobal>
|
|
||||||
|
|
||||||
enum class Lgc_FunctionType : quint8
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Shortcut,
|
|
||||||
ShortcutSequence,
|
|
||||||
Website,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Lgc_FunctionDefinition
|
|
||||||
{
|
|
||||||
int Id = 0;
|
|
||||||
QString Name;
|
|
||||||
QString Description;
|
|
||||||
Lgc_FunctionType Type = Lgc_FunctionType::None;
|
|
||||||
QStringList ShortcutTokens;
|
|
||||||
QString WebsiteUrl;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Lgc_FunctionExecutor_Run(
|
|
||||||
const Lgc_FunctionDefinition& Function,
|
|
||||||
QString* p_TextStatus);
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
#include "LOGIC/Lgc_Session.h"
|
|
||||||
|
|
||||||
#include "COM/Com_ProtoCodec.h"
|
|
||||||
|
|
||||||
#include <QtCore/QElapsedTimer>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
bool Lgc_Func_TryHandshakeCdcPort(
|
|
||||||
Dri_Cdc_Struct_Port* p_Port,
|
|
||||||
QByteArray* p_ReadBuffer,
|
|
||||||
Packet_HelloRsp* p_HelloRsp)
|
|
||||||
{
|
|
||||||
const QByteArray HelloReqFrame = Com_ProtoCodec_BuildHelloReq();
|
|
||||||
if (!Dri_Cdc_WriteBytes(p_Port, HelloReqFrame, 200))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QElapsedTimer Timer;
|
|
||||||
Timer.start();
|
|
||||||
while (Timer.elapsed() < 200)
|
|
||||||
{
|
|
||||||
QByteArray ReadBytes;
|
|
||||||
if (Dri_Cdc_ReadBytes(p_Port, &ReadBytes, 20) && !ReadBytes.isEmpty())
|
|
||||||
{
|
|
||||||
p_ReadBuffer->append(ReadBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
Packet PacketData;
|
|
||||||
while (Com_ProtoCodec_TryTakeFrame(p_ReadBuffer, &PacketData))
|
|
||||||
{
|
|
||||||
if (!Com_ProtoCodec_ParseHelloRsp(PacketData, p_HelloRsp))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void Lgc_Session_Init(Lgc_Session* p_Session)
|
|
||||||
{
|
|
||||||
if (p_Session == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*p_Session = Lgc_Session();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lgc_Session_Close(Lgc_Session* p_Session)
|
|
||||||
{
|
|
||||||
if (p_Session == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dri_Cdc_Close(&p_Session->CdcPort);
|
|
||||||
Dri_Gatt_Deinit(&p_Session->GattPort);
|
|
||||||
p_Session->CdcReadBuffer.clear();
|
|
||||||
p_Session->IsStarted = false;
|
|
||||||
p_Session->IsHandshakeDone = false;
|
|
||||||
p_Session->ActiveTransport = Lgc_TransportType::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Lgc_Session_TryStartCdc(
|
|
||||||
Lgc_Session* p_Session,
|
|
||||||
const Dri_Cdc_Struct_OpenConfig& Config,
|
|
||||||
Packet_HelloRsp* p_HelloRsp)
|
|
||||||
{
|
|
||||||
if ((p_Session == nullptr) || (p_HelloRsp == nullptr))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QVector<Dri_Cdc_Struct_PortInfo> PortList = Dri_Cdc_Enum();
|
|
||||||
for (const Dri_Cdc_Struct_PortInfo& PortInfo : PortList)
|
|
||||||
{
|
|
||||||
Dri_Cdc_Struct_Port Port;
|
|
||||||
if (!Dri_Cdc_Open(&Port, PortInfo.PortName, Config))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray ReadBuffer;
|
|
||||||
Packet_HelloRsp HelloRsp;
|
|
||||||
if (Lgc_Func_TryHandshakeCdcPort(&Port, &ReadBuffer, &HelloRsp))
|
|
||||||
{
|
|
||||||
Dri_Cdc_Close(&p_Session->CdcPort);
|
|
||||||
p_Session->CdcPort = Port;
|
|
||||||
p_Session->CdcReadBuffer = ReadBuffer;
|
|
||||||
p_Session->IsStarted = true;
|
|
||||||
p_Session->IsHandshakeDone = true;
|
|
||||||
p_Session->ActiveTransport = Lgc_TransportType::Cdc;
|
|
||||||
*p_HelloRsp = HelloRsp;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dri_Cdc_Close(&Port);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Lgc_Session_TryStartGatt(Lgc_Session* p_Session)
|
|
||||||
{
|
|
||||||
if (p_Session == nullptr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Dri_Gatt_Init(&p_Session->GattPort))
|
|
||||||
{
|
|
||||||
p_Session->IsStarted = true;
|
|
||||||
p_Session->ActiveTransport = Lgc_TransportType::Gatt;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Lgc_Session_ReadNextPacket(
|
|
||||||
Lgc_Session* p_Session,
|
|
||||||
Packet* p_Packet)
|
|
||||||
{
|
|
||||||
if ((p_Session == nullptr) || (p_Packet == nullptr))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*p_Packet = Packet();
|
|
||||||
|
|
||||||
if (p_Session->ActiveTransport == Lgc_TransportType::Cdc)
|
|
||||||
{
|
|
||||||
QByteArray ReadBytes;
|
|
||||||
if (Dri_Cdc_ReadBytes(&p_Session->CdcPort, &ReadBytes, 0) && !ReadBytes.isEmpty())
|
|
||||||
{
|
|
||||||
p_Session->CdcReadBuffer.append(ReadBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Com_ProtoCodec_TryTakeFrame(&p_Session->CdcReadBuffer, p_Packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "COM/Com_Cdc.h"
|
|
||||||
#include "DRI/Dri_Cdc.h"
|
|
||||||
#include "DRI/GATT/Dri_Gatt.h"
|
|
||||||
#include "LOGIC/Lgc_State.h"
|
|
||||||
|
|
||||||
struct Lgc_Session
|
|
||||||
{
|
|
||||||
Dri_Cdc_Struct_Port CdcPort;
|
|
||||||
Dri_Gatt_Struct_Port GattPort;
|
|
||||||
QByteArray CdcReadBuffer;
|
|
||||||
bool IsStarted = false;
|
|
||||||
bool IsHandshakeDone = false;
|
|
||||||
Lgc_TransportType ActiveTransport = Lgc_TransportType::None;
|
|
||||||
};
|
|
||||||
|
|
||||||
void Lgc_Session_Init(Lgc_Session* p_Session);
|
|
||||||
void Lgc_Session_Close(Lgc_Session* p_Session);
|
|
||||||
bool Lgc_Session_TryStartCdc(
|
|
||||||
Lgc_Session* p_Session,
|
|
||||||
const Dri_Cdc_Struct_OpenConfig& Config,
|
|
||||||
Packet_HelloRsp* p_HelloRsp);
|
|
||||||
bool Lgc_Session_TryStartGatt(Lgc_Session* p_Session);
|
|
||||||
bool Lgc_Session_ReadNextPacket(
|
|
||||||
Lgc_Session* p_Session,
|
|
||||||
Packet* p_Packet);
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtCore/QtGlobal>
|
|
||||||
|
|
||||||
enum class Lgc_TransportType : quint8
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Cdc,
|
|
||||||
Gatt,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Lgc_State
|
|
||||||
{
|
|
||||||
bool IsConnected = false;
|
|
||||||
bool IsHandshakeDone = false;
|
|
||||||
Lgc_TransportType ActiveTransport = Lgc_TransportType::None;
|
|
||||||
QString ActiveEndpointName;
|
|
||||||
QString ConnectionText = QStringLiteral("Disconnected");
|
|
||||||
QString LastActionText = QStringLiteral("Idle");
|
|
||||||
quint32 ProtocolVersion = 0;
|
|
||||||
quint32 CapabilityFlags = 0;
|
|
||||||
quint16 VendorId = 0;
|
|
||||||
quint16 ProductId = 0;
|
|
||||||
quint8 FirmwareMajor = 0;
|
|
||||||
quint8 FirmwareMinor = 0;
|
|
||||||
};
|
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
#include <QtWidgets/QApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
#include "APP/AppMainWindow.h"
|
#include "DRI/Dri_Cdc.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QApplication App(argc, argv);
|
QCoreApplication App(argc, argv);
|
||||||
|
|
||||||
APP::App_MainWindow Window;
|
const QVector<Dri_Cdc_Struct_PortInfo> PortList = Dri_Cdc_Enum();
|
||||||
Window.show();
|
qDebug() << "CDC ports:" << PortList.size();
|
||||||
|
|
||||||
return App.exec();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
# Generated Code
|
|
||||||
|
|
||||||
This directory is reserved for generated protocol code.
|
|
||||||
|
|
||||||
Planned layout:
|
|
||||||
|
|
||||||
- `cpp/` for host-side protobuf generated files
|
|
||||||
- `nanopb/` for firmware-side generated files
|
|
||||||
|
|
||||||
Do not place hand-written logic here.
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
# Host APP Rebuild
|
|
||||||
|
|
||||||
## Goal
|
|
||||||
|
|
||||||
Keep the APP layer suitable for teaching from simple to complex.
|
|
||||||
|
|
||||||
Teaching order:
|
|
||||||
|
|
||||||
1. one button
|
|
||||||
2. one keyboard page
|
|
||||||
3. two pages
|
|
||||||
4. one main window
|
|
||||||
5. one shared theme
|
|
||||||
|
|
||||||
## Completed Nodes
|
|
||||||
|
|
||||||
### Node 1: theme helpers
|
|
||||||
|
|
||||||
Files:
|
|
||||||
|
|
||||||
- `KeyBorad/KeyBorad/APP/AppTheme.h`
|
|
||||||
- `KeyBorad/KeyBorad/APP/AppTheme.cpp`
|
|
||||||
|
|
||||||
Design notes:
|
|
||||||
|
|
||||||
- centralize colors and style strings
|
|
||||||
- keep styling readable
|
|
||||||
- avoid mixing style text inside every widget
|
|
||||||
|
|
||||||
### Node 2: key button
|
|
||||||
|
|
||||||
Files:
|
|
||||||
|
|
||||||
- `KeyBorad/KeyBorad/APP/AppKeyButton.h`
|
|
||||||
- `KeyBorad/KeyBorad/APP/AppKeyButton.cpp`
|
|
||||||
|
|
||||||
Design notes:
|
|
||||||
|
|
||||||
- teach one custom button first
|
|
||||||
- keep state changes explicit
|
|
||||||
- let one widget own its own text and style refresh
|
|
||||||
|
|
||||||
### Node 3: keyboard page
|
|
||||||
|
|
||||||
Files:
|
|
||||||
|
|
||||||
- `KeyBorad/KeyBorad/APP/AppKeyboardPage.h`
|
|
||||||
- `KeyBorad/KeyBorad/APP/AppKeyboardPage.cpp`
|
|
||||||
|
|
||||||
Design notes:
|
|
||||||
|
|
||||||
- grow from one button to a full keypad
|
|
||||||
- keep layout data local and explicit
|
|
||||||
|
|
||||||
### Node 4: settings page
|
|
||||||
|
|
||||||
Files:
|
|
||||||
|
|
||||||
- `KeyBorad/KeyBorad/APP/AppSettingsPage.h`
|
|
||||||
- `KeyBorad/KeyBorad/APP/AppSettingsPage.cpp`
|
|
||||||
|
|
||||||
Design notes:
|
|
||||||
|
|
||||||
- use a second page early
|
|
||||||
- give transport status and action feedback one simple home
|
|
||||||
|
|
||||||
### Node 5: main window integration
|
|
||||||
|
|
||||||
Files updated in this step:
|
|
||||||
|
|
||||||
- `KeyBorad/KeyBorad/APP/AppMainWindow.h`
|
|
||||||
- `KeyBorad/KeyBorad/APP/AppMainWindow.cpp`
|
|
||||||
- `KeyBorad/KeyBorad/main.cpp`
|
|
||||||
|
|
||||||
Implemented behavior:
|
|
||||||
|
|
||||||
- create the two-page window
|
|
||||||
- own one `Lgc_Core`
|
|
||||||
- start handshake on launch
|
|
||||||
- poll the logic layer with a timer
|
|
||||||
- refresh settings page texts from logic state
|
|
||||||
|
|
||||||
### Node 6: Qt property typing fix
|
|
||||||
|
|
||||||
Files updated in this step:
|
|
||||||
|
|
||||||
- `KeyBorad/KeyBorad/APP/AppKeyboardPage.cpp`
|
|
||||||
- `KeyBorad/KeyBorad/APP/AppSettingsPage.cpp`
|
|
||||||
|
|
||||||
Design notes:
|
|
||||||
|
|
||||||
- keep widget property values explicit under MSVC + Qt
|
|
||||||
- avoid relying on implicit conversion from string literal to `QVariant`
|
|
||||||
|
|
||||||
Implemented behavior:
|
|
||||||
|
|
||||||
- replace raw `"title"` / `"body"` property values with `QStringLiteral(...)`
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
# Host COM Rebuild
|
|
||||||
|
|
||||||
## Goal
|
|
||||||
|
|
||||||
Keep the protocol layer small and explicit.
|
|
||||||
|
|
||||||
The COM layer should:
|
|
||||||
|
|
||||||
- define packet-facing helpers
|
|
||||||
- own frame parsing and packet building
|
|
||||||
- avoid transport concerns
|
|
||||||
- avoid UI and session concerns
|
|
||||||
|
|
||||||
## Completed Nodes
|
|
||||||
|
|
||||||
### Node 1: legacy protocol baseline
|
|
||||||
|
|
||||||
Files already present before this step:
|
|
||||||
|
|
||||||
- `KeyBorad/KeyBorad/COM/Com_Cdc.h`
|
|
||||||
- `KeyBorad/KeyBorad/COM/Com_CdcEncode.h`
|
|
||||||
- `KeyBorad/KeyBorad/COM/Com_CdcEncode.cpp`
|
|
||||||
- `KeyBorad/KeyBorad/COM/Com_CdcDecode.h`
|
|
||||||
- `KeyBorad/KeyBorad/COM/Com_CdcDecode.cpp`
|
|
||||||
|
|
||||||
Design notes:
|
|
||||||
|
|
||||||
- these files preserve the old packet format
|
|
||||||
- they already encode and decode complete CDC frames
|
|
||||||
- they also contain per-packet payload helpers
|
|
||||||
|
|
||||||
### Node 2: unified protocol entry
|
|
||||||
|
|
||||||
Files added in this step:
|
|
||||||
|
|
||||||
- `KeyBorad/KeyBorad/COM/Com_ProtoCodec.h`
|
|
||||||
- `KeyBorad/KeyBorad/COM/Com_ProtoCodec.cpp`
|
|
||||||
|
|
||||||
Design notes:
|
|
||||||
|
|
||||||
- provides a thin and readable entry point for higher layers
|
|
||||||
- keeps `DRI` from depending on packet parsing
|
|
||||||
- keeps `LGC` from depending on low-level byte layout details
|
|
||||||
- starts from the smallest useful handshake path
|
|
||||||
|
|
||||||
Implemented behavior:
|
|
||||||
|
|
||||||
- build `HelloReq` frame
|
|
||||||
- validate whether a parsed packet is `HelloRsp`
|
|
||||||
- decode `HelloRsp`
|
|
||||||
- forward frame parsing and stream extraction to the existing low-level codec
|
|
||||||
|
|
||||||
## Next COM nodes
|
|
||||||
|
|
||||||
- bitmap encode/decode helper
|
|
||||||
- ack/error helper
|
|
||||||
- time sync and theme helper
|
|
||||||
- replace direct `Com_Cdc*` calls in higher layers with `Com_ProtoCodec*`
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
# Host LGC Rebuild
|
|
||||||
|
|
||||||
## Goal
|
|
||||||
|
|
||||||
Keep the logic layer small, readable, and teachable.
|
|
||||||
|
|
||||||
The logic layer should:
|
|
||||||
|
|
||||||
- own connection state
|
|
||||||
- own handshake state
|
|
||||||
- call DRI for bytes
|
|
||||||
- call COM for frame and packet parsing
|
|
||||||
- expose a small interface to APP
|
|
||||||
|
|
||||||
The logic layer should not:
|
|
||||||
|
|
||||||
- parse serial bytes by itself
|
|
||||||
- enumerate devices directly
|
|
||||||
- own widget code
|
|
||||||
|
|
||||||
## Completed Nodes
|
|
||||||
|
|
||||||
### Node 1: function executor shell
|
|
||||||
|
|
||||||
Files:
|
|
||||||
|
|
||||||
- `KeyBorad/KeyBorad/LOGIC/Lgc_FunctionExecutor.h`
|
|
||||||
- `KeyBorad/KeyBorad/LOGIC/Lgc_FunctionExecutor.cpp`
|
|
||||||
|
|
||||||
Design notes:
|
|
||||||
|
|
||||||
- keep function execution out of session code
|
|
||||||
- reserve one place for OS-specific actions
|
|
||||||
- keep the initial implementation small
|
|
||||||
|
|
||||||
### Node 2: state model
|
|
||||||
|
|
||||||
Files updated in this step:
|
|
||||||
|
|
||||||
- `KeyBorad/KeyBorad/LOGIC/Lgc_State.h`
|
|
||||||
|
|
||||||
Design notes:
|
|
||||||
|
|
||||||
- state is plain data
|
|
||||||
- connection text and last action text live here
|
|
||||||
- handshake result fields live here
|
|
||||||
|
|
||||||
### Node 3: session handshake path
|
|
||||||
|
|
||||||
Files completed in this step:
|
|
||||||
|
|
||||||
- `KeyBorad/KeyBorad/LOGIC/Lgc_Session.h`
|
|
||||||
- `KeyBorad/KeyBorad/LOGIC/Lgc_Session.cpp`
|
|
||||||
|
|
||||||
Implemented behavior:
|
|
||||||
|
|
||||||
- try CDC handshake
|
|
||||||
- send `HelloReq`
|
|
||||||
- wait for `HelloRsp`
|
|
||||||
- store the active transport
|
|
||||||
- keep a stream buffer for CDC bytes
|
|
||||||
- return the next parsed packet to upper layers
|
|
||||||
|
|
||||||
### Node 4: core facade
|
|
||||||
|
|
||||||
Files completed in this step:
|
|
||||||
|
|
||||||
- `KeyBorad/KeyBorad/LOGIC/Lgc_Core.h`
|
|
||||||
- `KeyBorad/KeyBorad/LOGIC/Lgc_Core.cpp`
|
|
||||||
|
|
||||||
Implemented behavior:
|
|
||||||
|
|
||||||
- give APP one small entry point
|
|
||||||
- start CDC handshake through session
|
|
||||||
- expose `Start / Poll / Close / GetState`
|
|
||||||
- refresh state from `HelloRsp`
|
|
||||||
- update a simple action text when packets arrive
|
|
||||||
Reference in New Issue
Block a user