Hightlight lines when touched.
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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>()};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user