Hightlight lines when touched.

This commit is contained in:
2025-12-19 17:37:24 +01:00
parent 3e5f616461
commit 552fcdf8f8
11 changed files with 140 additions and 40 deletions

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 18.0.1, 2025-12-19T10:26:05. -->
<!-- Written by QtCreator 18.0.1, 2025-12-19T17:13:02. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

View File

@@ -2,6 +2,5 @@
<qresource prefix="/">
<file alias="bikeinfo.xml">data/bikeinfo.xml</file>
<file>bionxcontrol.qss</file>
<file alias="typeinfo.xml">data/typeinfo.xml</file>
</qresource>
</RCC>

View File

@@ -50,22 +50,30 @@ void BCValueModel::setValueList(const BCValueList& valueList)
endResetModel();
}
BCValueList& BCValueModel::getValueList()
{
return _valueList;
}
int BCValueModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) return 0;
if (parent.isValid())
return 0;
return _valueList.size();
}
QVariant BCValueModel::data(const QModelIndex &index, int role) const
QVariant BCValueModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid() || index.row() >= _valueList.size())
int row = index.row();
if (!index.isValid() || row >= _valueList.size())
return QVariant();
const BCValue &item = _valueList.at(index.row());
BCValue& value = const_cast<BCValue&>(_valueList.at( row ));
value.rowInModel = row;
if (role == Qt::DisplayRole || role == Qt::EditRole)
return QVariant::fromValue(value);
if (role == Qt::DisplayRole || role == Qt::EditRole) {
return QVariant::fromValue(item);
}
return QVariant();
}

View File

@@ -46,6 +46,8 @@ public:
void addValue(const BCValue &val);
void setValueList(const BCValueList& valueList);
BCValueList& getValueList();
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

View File

@@ -3,14 +3,17 @@
#include <QHBoxLayout>
#include <QWidget>
#include <QDebug>
#include <QPainter>
#include <QTimer>
#include <QListView>
#include "bcitemdelegate.h"
#include "bcvalue.h"
#include "qapplication.h"
BCItemDelegate::BCItemDelegate(QObject *parent)
: QStyledItemDelegate(parent)
BCItemDelegate::BCItemDelegate(QListView *view)
: QStyledItemDelegate(view), _view{view}
{
}
@@ -26,7 +29,7 @@ QString BCItemDelegate::displayText(const QVariant& dataValue, const QLocale& lo
// Hier bauen wir den String zusammen, den man sieht,
// wenn KEIN Editor offen ist.
// Format: "Label: Wert Einheit"
return QString("%1: %2 %3").arg(bc.label, bc.value.toString(), "mm1");
return QString("%1: %2 %3").arg(bc.label, bc.value.toString(), "mmX");
}
// Fallback für normale Strings/Zahlen
@@ -132,6 +135,51 @@ QSize BCItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelI
*/
}
void BCItemDelegate::onHighlightRow(int row)
{
qDebug() << " --- should highlight: " << row;
_highlightedRow = row;
// Trigger Repaint der View (damit der Rahmen sofort erscheint)
_view->viewport()->update();
// Timer: Nach 1 Sekunde wieder ausschalten (Temporär)
QTimer::singleShot(1000, this, [=, this]()
{
if(_highlightedRow == row)
{ // Nur zurücksetzen, wenn es noch dieselbe Zeile ist
_highlightedRow = -1;
if (_view)
_view->viewport()->update();
}
});
}
void BCItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
// 1. Standard-Zeichnen (Text, Hintergrund, Selection) durchführen
QStyledItemDelegate::paint(painter, option, index);
// 2. Unser Custom-Overly: Oranger Rahmen, wenn Zeile passt
if (index.row() == _highlightedRow)
{
painter->save();
qDebug() << " --- is highlight: " << index.row();
// Setup Stift
QPen pen(QColor(255, 165, 0)); // Orange
pen.setWidth(2);
painter->setPen(pen);
// Rechteck zeichnen (leicht eingezogen, damit es nicht abgeschnitten wird)
QRect rect = option.rect.adjusted(1, 1, -1, -1);
painter->drawRect(rect);
painter->restore();
}
}
QString BCItemDelegate::formatDisplayString(const QModelIndex &index) const
{
if (!index.isValid())

View File

@@ -2,18 +2,18 @@
#ifndef BCITEMDELEGATE_H
#define BCITEMDELEGATE_H
#include <QStyledItemDelegate>
class QListView;
class BCItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit BCItemDelegate(QObject *parent = nullptr);
explicit BCItemDelegate(QListView *view );
// WICHTIG: Zuständig für die normale Anzeige (ohne Editor)
QString displayText(const QVariant& dataValue, const QLocale& locale) const override;
// Zuständig für den Edit-Modus (Doppelklick)
@@ -23,9 +23,19 @@ public:
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
QSize sizeHint(const QStyleOptionViewItem &option,const QModelIndex &index) const override;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
public slots:
void onHighlightRow(int row);
private:
QString formatDisplayString(const QModelIndex &index) const;
int _highlightedRow{-1};
QListView* _view{nullptr};
};

View File

@@ -36,12 +36,16 @@ BCMainWindow::BCMainWindow(QWidget *parent)
{
setupUi(this);
_valueManager.loadBikeData();
auto model = _valueManager.getModel( "Console"_L1 );
auto model = _valueManager.getModel( BCDevice::ID::Console );
if( model)
_valueView->setModel( *model );
_valueView->setItemDelegate( new BCItemDelegate( _valueView) );
BCItemDelegate* delegate = new BCItemDelegate( _valueView);
_valueView->setItemDelegate( delegate );
connect( &_valueManager, &BCValueManager::valueTouched, delegate, &BCItemDelegate::onHighlightRow );
connect( _connectButton, &QPushButton::clicked, &_valueManager, &BCValueManager::onToggleConnectionState );
connect( _syncButton, &QPushButton::clicked, &_valueManager, &BCValueManager::onSyncFromDevice );
}
BCMainWindow::~BCMainWindow()

View File

@@ -27,7 +27,7 @@
<property name="frameShadow">
<enum>QFrame::Shadow::Raised</enum>
</property>
<widget class="QPushButton" name="_pushButton">
<widget class="QPushButton" name="_syncButton">
<property name="geometry">
<rect>
<x>30</x>
@@ -37,7 +37,7 @@
</rect>
</property>
<property name="text">
<string>PushButton</string>
<string>Sync</string>
</property>
</widget>
<widget class="QPushButton" name="_connectButton">

View File

@@ -106,9 +106,8 @@ public:
BCDevice::ID deviceID{BCDevice::ID::Invalid};
BC::ID targetID{BC::ID::Invalid};
BCValueType::TypeID typeID{BCValueType::TypeID::Invalid};;
int rowInModel{-1};
QString label;
QVariant value;
QVariant defaultValue;

View File

@@ -34,6 +34,7 @@
#include <QPushButton>
#include <QMessageBox>
#include <QStatusBar>
#include <QApplication>
#include <bcvaluemanager.h>
@@ -53,7 +54,7 @@ BCValueManager::BCValueManager(QObject *parent)
// 4. Verbindungen herstellen (Signal/Slot über Thread-Grenzen)
// A) Befehl senden (Manager -> Runner)
connect(this, &BCValueManager::newCommandArrived, &_transmitter, &BCTransmitter::addCommand);
connect(this, &BCValueManager::newCommandArrived, &_transmitter, &BCTransmitter::enqueueValue);
// B) Ergebnisse empfangen (Runner -> Manager)
connect(&_transmitter, &BCTransmitter::commandFinished, this, &BCValueManager::onCommandFinished);
@@ -136,11 +137,31 @@ void BCValueManager::onToggleConnectionState( bool connect )
}
std::optional<BCValueModel*> BCValueManager::getModel(const QString& key )
void BCValueManager::onSyncFromDevice()
{
if( _valueModels.contains( key) )
return _valueModels[key];
qDebug() << " ---Syncing";
if( _currentDeviceID != BCDevice::ID::Invalid)
{
BCValueList& currentList = _valueModels[_currentDeviceID]->getValueList();
for( BCValue& value : currentList )
{
qDebug() << " --- value: " << value.label;
_transmitter.enqueueValue( value );
emit valueTouched( value.rowInModel );
QApplication::processEvents();
// Thread schlafen lassen (Simulation einer blockierenden Operation)
QThread::msleep(500);
}
}
}
std::optional<BCValueModel*> BCValueManager::getModel(BCDevice::ID deviceID )
{
if( _valueModels.contains( deviceID) )
return _valueModels[deviceID];
return std::nullopt;
}
@@ -185,25 +206,28 @@ void BCValueManager::loadBikeData()
if (token == QXmlStreamReader::StartElement)
{
QString deviceType = _xml.attributes().value("Type"_L1).toString();
qDebug() << " --- Device: " << _xml.name() << ": " << deviceType;
printAttrs (_xml);
const char* deviceKey = _xml.attributes().value("Type"_L1).toLatin1().constData();
auto deviceID = _bcDeviceEnum.keyToValue64(deviceKey);
//_currentDeviceID = BCDevice::ID( deviceID.value_or( BCDevice::ID::Invalid ) );
_currentDeviceID = deviceID.has_value() ? BCDevice::ID( deviceID.value() ) : BCDevice::ID::Invalid;
if(deviceID.has_value())
{
qDebug() << " --- Device: " << _xml.name() << ": " << deviceType << " : " << deviceID;
_currentDeviceID = BCDevice::ID( deviceID.value() );
BCValueList parsedValues;
loadDeviceData( parsedValues );
if( parsedValues.count() )
{
BCValueModel* valueModel = new BCValueModel( this );
valueModel->setValueList(parsedValues);
_valueModels.insert( deviceType, valueModel );
_valueModels.insert( _currentDeviceID, valueModel );
}
}
}
_currentDeviceID = BCDevice::ID::Console;
}
/*

View File

@@ -50,7 +50,7 @@ public:
BCValueManager( QObject* parent = nullptr);
virtual ~BCValueManager();
std::optional<BCValueModel*> getModel(const QString& key );
std::optional<BCValueModel*> getModel(BCDevice::ID deviceID );
BCValue makeValue(BCDevice::ID deviceID, const BCValueParams& params );
@@ -62,11 +62,14 @@ public slots:
void loadBikeData();
void saveBikeData();
void onToggleConnectionState( bool connect );
void onSyncFromDevice();
signals:
// Internes Signal, um Daten an den Worker Thread zu senden
void newCommandArrived(BCValue cmd);
void newCommandArrived(const BCValue& cmd);
//void valuedTouched(const BCValue& cmd);
void valueTouched(int rowInModel );
private slots:
@@ -79,9 +82,12 @@ protected:
void loadTypeData();
void loadDeviceData( BCValueList& parsedValues );
using BCDeviceModels = QMap<BCDevice::ID, BCValueModel*>;
using BCValueTypes = QMap<QString,BCValueType>;
QXmlStreamReader _xml;
QMap<QString,BCValueType> _valueTypes;
QMap<QString,BCValueModel*> _valueModels;
BCValueTypes _valueTypes;
BCDeviceModels _valueModels;
BCDevice::ID _currentDeviceID{BCDevice::ID::Invalid};
QMetaEnum _bcDeviceEnum{QMetaEnum::fromType<BCDevice::ID>()};