Compare commits
7 Commits
731566e7d1
...
221e0bc8c2
| Author | SHA1 | Date | |
|---|---|---|---|
| 221e0bc8c2 | |||
| e5f7ba569a | |||
| a57b45e21a | |||
| 1a2d815634 | |||
| 6c15d99119 | |||
| c21bb2cf4e | |||
| 5c52b1e936 |
@@ -51,6 +51,7 @@ SOURCES += \
|
|||||||
bcdriver.cpp \
|
bcdriver.cpp \
|
||||||
bcdrivertinycan.cpp \
|
bcdrivertinycan.cpp \
|
||||||
bcguihelpers.cpp \
|
bcguihelpers.cpp \
|
||||||
|
bcsliderstyle.cpp \
|
||||||
bctransmitter.cpp \
|
bctransmitter.cpp \
|
||||||
bcvalue.cpp \
|
bcvalue.cpp \
|
||||||
bcvaluemodel.cpp \
|
bcvaluemodel.cpp \
|
||||||
@@ -68,6 +69,7 @@ HEADERS += \
|
|||||||
bcdrivertinycan.h \
|
bcdrivertinycan.h \
|
||||||
bcguihelpers.h \
|
bcguihelpers.h \
|
||||||
bcmainwindow.h \
|
bcmainwindow.h \
|
||||||
|
bcsliderstyle.h \
|
||||||
bctransmitter.h \
|
bctransmitter.h \
|
||||||
bcvalue.h \
|
bcvalue.h \
|
||||||
bcvaluemodel.h \
|
bcvaluemodel.h \
|
||||||
|
|||||||
@@ -181,54 +181,31 @@ QSize BCAnimatedDelegate::sizeHint(const QStyleOptionViewItem &option, const QMo
|
|||||||
void BCAnimatedDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
void BCAnimatedDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
|
|
||||||
// 1. Standard-Zeichnen (Text, Hintergrund, Selection) durchführen
|
// Standard-Zeichnen (Text, Hintergrund, Selection) durchführen
|
||||||
QStyledItemDelegate::paint(painter, option, index);
|
QStyledItemDelegate::paint(painter, option, index);
|
||||||
|
|
||||||
//QPen pen(QColor(255, 165, 0)); // Orange
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (index.row() == _highlightedRow && _opacity > 0.0)
|
|
||||||
{
|
|
||||||
painter->save();
|
|
||||||
|
|
||||||
qDebug() << " --- is highlight: " << index.row();
|
|
||||||
|
|
||||||
QColor highlightColor( 0xFF9800 );
|
|
||||||
highlightColor.setAlphaF(_opacity);
|
|
||||||
|
|
||||||
QPen pen(highlightColor, 3);
|
|
||||||
painter->setPen(pen);
|
|
||||||
painter->setBrush(Qt::NoBrush);
|
|
||||||
painter->drawRoundedRect(option.rect.adjusted(2, 2, -2, -2), 8, 8);
|
|
||||||
|
|
||||||
painter->restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
int row = index.row();
|
int row = index.row();
|
||||||
if (index.column() == 1 )
|
int col = index.column();
|
||||||
|
|
||||||
|
switch (col)
|
||||||
{
|
{
|
||||||
|
case 1:
|
||||||
|
|
||||||
if( m_rowOpacities.contains(row))
|
if( m_rowOpacities.contains(row))
|
||||||
{
|
|
||||||
paintHighlightRow(painter,option,index);
|
paintHighlightRow(painter,option,index);
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
|
||||||
|
if( row>-1 && row <= _valueList.size() )
|
||||||
|
paintSliderIndicator(painter,option,index);
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
qreal opacity = m_rowOpacities.value(row);
|
|
||||||
if (opacity > 0.01)
|
|
||||||
{
|
|
||||||
painter->save();
|
|
||||||
painter->setOpacity(opacity);
|
|
||||||
painter->fillRect(option.rect, QColor(255, 140, 0, 120));
|
|
||||||
painter->restore();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
void BCAnimatedDelegate::paintHighlightRow(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
void BCAnimatedDelegate::paintHighlightRow(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
painter->save();
|
painter->save();
|
||||||
@@ -239,33 +216,70 @@ void BCAnimatedDelegate::paintHighlightRow(QPainter* painter, const QStyleOption
|
|||||||
// Margin von 4px
|
// Margin von 4px
|
||||||
QRect itemRect = option.rect.adjusted(3, 3, -3, -3);
|
QRect itemRect = option.rect.adjusted(3, 3, -3, -3);
|
||||||
|
|
||||||
// Border von 2px berücksichtigen (nach innen)
|
|
||||||
//QRect contentRect = itemRect.adjusted(2, 2, -2, -2);
|
|
||||||
// painter->fillRect(contentRect,Qt::green);
|
|
||||||
/*
|
|
||||||
// Hintergrund (weiß)
|
|
||||||
painter->setBrush(Qt::white);
|
|
||||||
painter->setPen(Qt::NoPen);
|
|
||||||
painter->drawRoundedRect(itemRect, 8, 8);
|
|
||||||
*/
|
|
||||||
// Border (2px solid #2196F3)
|
// Border (2px solid #2196F3)
|
||||||
QPen borderPen( Qt::red, 1);
|
QPen borderPen( Qt::red, 1);
|
||||||
painter->setPen(borderPen);
|
painter->setPen(borderPen);
|
||||||
painter->setBrush(Qt::NoBrush);
|
painter->setBrush(Qt::NoBrush);
|
||||||
painter->drawRoundedRect(itemRect, 2, 2);
|
painter->drawRoundedRect(itemRect, 2, 2);
|
||||||
|
|
||||||
// Padding von 8px für den Content
|
|
||||||
//QRect textRect = contentRect.adjusted(8, 8, -8, -8);
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Text zeichnen
|
|
||||||
painter->setPen(Qt::black); // oder option.palette.color(QPalette::Text)
|
|
||||||
QString text = index.data(Qt::DisplayRole).toString();
|
|
||||||
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text);
|
|
||||||
*/
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BCAnimatedDelegate::paintSliderIndicator(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
|
||||||
|
const BCValue& valueX = *(_valueList[ index.row()].get());
|
||||||
|
int value = 50;index.model()->data(index, Qt::DisplayRole).toInt();
|
||||||
|
|
||||||
|
// Hintergrund
|
||||||
|
if (option.state & QStyle::State_Selected)
|
||||||
|
{
|
||||||
|
painter->fillRect(option.rect, option.palette.highlight());
|
||||||
|
}
|
||||||
|
else if (index.row() % 2 == 1)
|
||||||
|
{
|
||||||
|
painter->fillRect(option.rect, QColor(0xFAFAFA));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
painter->fillRect(option.rect, Qt::white);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text und kleiner Slider-Indikator zeichnen
|
||||||
|
painter->save();
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
|
//QRect textRect = option.rect.adjusted(8, 0, -120, 0);
|
||||||
|
|
||||||
|
QRect barRect = option.rect.adjusted
|
||||||
|
(
|
||||||
|
8,
|
||||||
|
option.rect.height() / 2 - 2,
|
||||||
|
-8,
|
||||||
|
-option.rect.height() / 2 + 2
|
||||||
|
);
|
||||||
|
|
||||||
|
//QRect barRect = option.rect;
|
||||||
|
// Text
|
||||||
|
//painter->setPen(option.state & QStyle::State_Selected ? option.palette.highlightedText().color() : Qt::black);
|
||||||
|
//painter->drawText(textRect, Qt::AlignVCenter | Qt::AlignLeft,
|
||||||
|
// QString::number(value));
|
||||||
|
|
||||||
|
// Mini Progress Bar
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
painter->setBrush(QColor(0xE0E0E0));
|
||||||
|
painter->drawRoundedRect(barRect, 2, 2);
|
||||||
|
|
||||||
|
QRect fillRect = barRect;
|
||||||
|
fillRect.setWidth(barRect.width() * value / 100);
|
||||||
|
painter->setBrush(QColor(0x0078D4));
|
||||||
|
painter->drawRoundedRect(fillRect, 2, 2);
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void BCAnimatedDelegate::onHighlightRow(int row)
|
void BCAnimatedDelegate::onHighlightRow(int row)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,21 +61,6 @@ public:
|
|||||||
QSize sizeHint(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;
|
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const override;
|
||||||
|
|
||||||
/*
|
|
||||||
qreal highlightOpacity() const
|
|
||||||
{
|
|
||||||
return _opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setHighlightOpacity(qreal opacity)
|
|
||||||
{
|
|
||||||
_opacity = opacity;
|
|
||||||
//qDebug() << " --- opa: " << opacity;
|
|
||||||
// __fix! unsinn!
|
|
||||||
emit viewUpdateNeeded();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void clearAllHighlights();
|
void clearAllHighlights();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@@ -91,13 +76,11 @@ private:
|
|||||||
|
|
||||||
void updateRow(int row);
|
void updateRow(int row);
|
||||||
void paintHighlightRow(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
void paintHighlightRow(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||||
|
void paintSliderIndicator(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||||
|
|
||||||
const BCValueList& _valueList;
|
const BCValueList& _valueList;
|
||||||
QTableView* _view{};
|
QTableView* _view{};
|
||||||
|
|
||||||
//int _highlightedRow{-1};
|
|
||||||
//qreal _opacity{1.0};
|
|
||||||
|
|
||||||
QPropertyAnimation* _animation{};
|
QPropertyAnimation* _animation{};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <QHeaderView>
|
||||||
|
|
||||||
#include <bcdeviceview.h>
|
#include <bcdeviceview.h>
|
||||||
#include <bcanimateddelegate.h>
|
#include <bcanimateddelegate.h>
|
||||||
|
|
||||||
@@ -44,17 +46,12 @@ BCDeviceView::BCDeviceView(QWidget *parent)
|
|||||||
// __fix! ziemlich wildes ge-pointere, hier
|
// __fix! ziemlich wildes ge-pointere, hier
|
||||||
_itemDelegate = new BCAnimatedDelegate( _valueModel.getValueList(), this);
|
_itemDelegate = new BCAnimatedDelegate( _valueModel.getValueList(), this);
|
||||||
setItemDelegate( _itemDelegate );
|
setItemDelegate( _itemDelegate );
|
||||||
|
|
||||||
qDebug() << " --- View size I: " << this->size();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void BCDeviceView::setDeviceID( BCDevice::ID deviceID )
|
void BCDeviceView::setDeviceID( BCDevice::ID deviceID )
|
||||||
{
|
{
|
||||||
qDebug() << " --- View size II: " << this->size();
|
|
||||||
|
|
||||||
_devideID = deviceID;
|
_devideID = deviceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +61,9 @@ BCDevice::ID BCDeviceView::getDeviceID() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gibt eine Referenz auf der ValueList zurück.
|
||||||
|
*/
|
||||||
|
|
||||||
const BCValueList& BCDeviceView::getValueListX()
|
const BCValueList& BCDeviceView::getValueListX()
|
||||||
{
|
{
|
||||||
@@ -72,8 +71,10 @@ const BCValueList& BCDeviceView::getValueListX()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
// __FIX ist das ok so?
|
* @brief SLOT, der aufgerufen wird, wenn die ValueList vom XML-Lader fertig geladen wurde.
|
||||||
|
* Die DeviceView nimmt die ValueList dann in Besitz.
|
||||||
|
*/
|
||||||
void BCDeviceView::onValueListReady( BCDevice::ID deviceID, BCValueList valueList )
|
void BCDeviceView::onValueListReady( BCDevice::ID deviceID, BCValueList valueList )
|
||||||
{
|
{
|
||||||
qDebug() << " --- onValueListReady: " << deviceID << ": " << valueList.size();
|
qDebug() << " --- onValueListReady: " << deviceID << ": " << valueList.size();
|
||||||
@@ -81,11 +82,28 @@ void BCDeviceView::onValueListReady( BCDevice::ID deviceID, BCValueList valueLis
|
|||||||
_valueModel.takeValueList( valueList );
|
_valueModel.takeValueList( valueList );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SLOT, der aufgerufen wird, wenn ein Value geändert wurde. Gibt dem ItemDelegate Bescheid.
|
||||||
|
*/
|
||||||
|
|
||||||
void BCDeviceView::onValueUpdated(int index, BCValue::State state, const QString& newVisibleValue )
|
void BCDeviceView::onValueUpdated(int index, BCValue::State state, const QString& newVisibleValue )
|
||||||
{
|
{
|
||||||
_valueModel.onValueUpdated( index, state, newVisibleValue);
|
_valueModel.onValueUpdated( index, state, newVisibleValue);
|
||||||
_itemDelegate->onHighlightRow( index );
|
_itemDelegate->onHighlightRow( index );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BCDeviceView::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
// Zuerst die Basisklasse aufrufen (Wichtig für Layouts!)
|
||||||
|
QWidget::resizeEvent(event);
|
||||||
|
|
||||||
|
// Berechnung: 40% der aktuellen Breite
|
||||||
|
// Tipp: viewport()->width() ist genauer als width(), da es Scrollbars rausrechnet!
|
||||||
|
int totalWidth = viewport()->width();
|
||||||
|
int col0Width = static_cast<int>(totalWidth * 0.60);
|
||||||
|
|
||||||
|
// Setzen der Breite
|
||||||
|
horizontalHeader()->resizeSection(0, col0Width);
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ public slots:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
BCDevice::ID _devideID{BCDevice::ID::Invalid};
|
BCDevice::ID _devideID{BCDevice::ID::Invalid};
|
||||||
BCValueModel _valueModel;
|
BCValueModel _valueModel;
|
||||||
BCAnimatedDelegate* _itemDelegate{};
|
BCAnimatedDelegate* _itemDelegate{};
|
||||||
|
|||||||
@@ -43,23 +43,25 @@ BCThemeSwitchButton::BCThemeSwitchButton(QWidget *parent )
|
|||||||
|
|
||||||
// CSS: Transparent, damit es sich nahtlos in den StatusBar einfügt
|
// CSS: Transparent, damit es sich nahtlos in den StatusBar einfügt
|
||||||
// Schriftgröße etwas erhöhen, damit die Emojis gut erkennbar sind
|
// Schriftgröße etwas erhöhen, damit die Emojis gut erkennbar sind
|
||||||
/*
|
|
||||||
setStyleSheet(R"(
|
setStyleSheet(R"(
|
||||||
QPushButton {
|
BCThemeSwitchButton
|
||||||
|
{
|
||||||
border: none;
|
border: none;
|
||||||
background-color: transparent;
|
background-color: green;
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
}
|
}
|
||||||
QPushButton:hover {
|
BCThemeSwitchButton:Hover
|
||||||
background-color: rgba(128, 128, 128, 30); // Leichter Hover-Effekt
|
{
|
||||||
|
background-color: rgba(128, 128, 128, 30);
|
||||||
border-radius: 24px;
|
border-radius: 24px;
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
*/
|
|
||||||
// Initialer Status (Startet im Dark Mode -> zeigt Mond)
|
// Initialer Status (Startet im Dark Mode -> zeigt Mond)
|
||||||
updateIcon();
|
updateIcon();
|
||||||
|
|
||||||
connect(this, &QPushButton::clicked, this, &BCThemeSwitchButton::toggle);
|
connect(this, &QPushButton::clicked, this, &BCThemeSwitchButton::toggleMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,6 @@ BCMainWindow::BCMainWindow(QWidget *parent)
|
|||||||
|
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
// den pimp-my-ride-button schalten wir vorerst aus.
|
|
||||||
_pimpButton->hide();
|
|
||||||
|
|
||||||
// Wir schreiben den 'initMainWindow()' Aufruf mit Hilfe des
|
// Wir schreiben den 'initMainWindow()' Aufruf mit Hilfe des
|
||||||
// timers in die Event-Queue, damit er erst ausgeführt wird,
|
// timers in die Event-Queue, damit er erst ausgeführt wird,
|
||||||
@@ -111,14 +109,11 @@ void BCMainWindow::initMainWindow()
|
|||||||
_devicePanels[BCDevice::ID::Console] = _consolePanel;
|
_devicePanels[BCDevice::ID::Console] = _consolePanel;
|
||||||
_devicePanels[BCDevice::ID::Battery] = _batteryPanel;
|
_devicePanels[BCDevice::ID::Battery] = _batteryPanel;
|
||||||
_devicePanels[BCDevice::ID::Motor] = _motorPanel;
|
_devicePanels[BCDevice::ID::Motor] = _motorPanel;
|
||||||
//_devicePanels[BCDevice::ID::Pimp] = _pimpPanel;
|
|
||||||
|
|
||||||
// Die actions an die Buttons binden
|
// Die actions an die Buttons binden
|
||||||
configureAction(_motorButton, _motorAction, BCDevice::ID::Motor );
|
configureAction(_motorButton, _motorAction, BCDevice::ID::Motor );
|
||||||
configureAction(_consoleButton, _consoleAction, BCDevice::ID::Console );
|
configureAction(_consoleButton, _consoleAction, BCDevice::ID::Console );
|
||||||
configureAction(_batteryButton, _batteryAction, BCDevice::ID::Battery );
|
configureAction(_batteryButton, _batteryAction, BCDevice::ID::Battery );
|
||||||
//configureAction(_pimpButton, _pimpAction, BCDevice::ID::Pimp );
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
bool m_isDarkMode = false;
|
bool m_isDarkMode = false;
|
||||||
@@ -149,10 +144,11 @@ void BCMainWindow::initMainWindow()
|
|||||||
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
|
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
|
||||||
connect( _connectButton, &QToolButton::clicked, &_transmitter, &BCTransmitter::onToggleDriverConnection );
|
connect( _connectButton, &QToolButton::clicked, &_transmitter, &BCTransmitter::onToggleDriverConnection );
|
||||||
connect( _syncButton, &QToolButton::clicked, this, &BCMainWindow::onSyncDeviceView );
|
connect( _syncButton, &QToolButton::clicked, this, &BCMainWindow::onSyncDeviceView );
|
||||||
connect( &_transmitter, &BCTransmitter::valueUpdated, this, &BCMainWindow::onValueUpdated );
|
connect( _exitButton, &QToolButton::clicked, qApp, &QCoreApplication::quit );
|
||||||
|
|
||||||
connect(this, &BCMainWindow::requestValueUpdate, &_transmitter, &BCTransmitter::onEnqueueValue);
|
connect( &_transmitter, &BCTransmitter::valueUpdated, this, &BCMainWindow::onValueUpdated );
|
||||||
connect(&_worker, &QThread::finished, &_transmitter, &QObject::deleteLater);
|
connect( this, &BCMainWindow::requestValueUpdate, &_transmitter, &BCTransmitter::onUpdateValue);
|
||||||
|
connect( &_worker, &QThread::finished, &_transmitter, &QObject::deleteLater);
|
||||||
connect( &_transmitter, &BCTransmitter::driverStateChanged, this, &BCMainWindow::onDriverStateChanged );
|
connect( &_transmitter, &BCTransmitter::driverStateChanged, this, &BCMainWindow::onDriverStateChanged );
|
||||||
|
|
||||||
// transmitter starten
|
// transmitter starten
|
||||||
@@ -161,10 +157,16 @@ void BCMainWindow::initMainWindow()
|
|||||||
|
|
||||||
// die Daten des eBikes laden
|
// die Daten des eBikes laden
|
||||||
_dataManager.loadXmlBikeData(":/bikeinfo.xml"_L1);
|
_dataManager.loadXmlBikeData(":/bikeinfo.xml"_L1);
|
||||||
//_consoleAction->trigger();
|
_consoleAction->trigger();
|
||||||
_batteryAction->trigger();
|
//_batteryAction->trigger();
|
||||||
|
|
||||||
}
|
// Dummy sync beim starten
|
||||||
|
|
||||||
|
QTimer::singleShot(1000, this, [this]()
|
||||||
|
{
|
||||||
|
onSyncDeviceView();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// 2. Bild für den Zustand UNCHECKED (Off) hinzufügen
|
// 2. Bild für den Zustand UNCHECKED (Off) hinzufügen
|
||||||
@@ -191,15 +193,19 @@ void BCMainWindow::initStatusBar()
|
|||||||
statBar->addPermanentWidget(themeBtn);
|
statBar->addPermanentWidget(themeBtn);
|
||||||
connect(themeBtn, &BCThemeSwitchButton::themeChanged, this, [this](bool isDark)
|
connect(themeBtn, &BCThemeSwitchButton::themeChanged, this, [this](bool isDark)
|
||||||
{
|
{
|
||||||
|
|
||||||
QString message = isDark ? "Dark Mode Activated" : "Light Mode Activated";
|
QString message = isDark ? "Dark Mode Activated" : "Light Mode Activated";
|
||||||
statusBar()->showMessage( message, 3000);
|
statusBar()->showMessage( message, 3000);
|
||||||
setApplicationStyleSheet( isDark ? ":/claude_dark_mode.qss"_L1 : ":/claude_light_mode.qss"_L1 );
|
setApplicationStyleSheet( isDark ? ":claude_dark_mode.qss"_L1 : ":claude_light_mode.qss"_L1 );
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wir starten im light mode
|
// Wir starten im light mode
|
||||||
//themeBtn->setDarkMode( false );
|
//themeBtn->setDarkMode( false );
|
||||||
|
|
||||||
statBar->showMessage("Ready");
|
statBar->showMessage("Ready");
|
||||||
|
|
||||||
|
setApplicationStyleSheet(":bionxcontrol.qss"_L1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -322,7 +328,7 @@ void BCMainWindow::onSyncDeviceView()
|
|||||||
// wir setzen auf 'lesen'
|
// wir setzen auf 'lesen'
|
||||||
value->state.setFlag( BCValue::State::ReadMe );
|
value->state.setFlag( BCValue::State::ReadMe );
|
||||||
|
|
||||||
// statt '_transmitter.onEnqueueValue( value )' müssen wir hier
|
// statt '_transmitter.onUpdateValue( value )' müssen wir hier
|
||||||
// über emit requestValueUpdate() zur Thread sysnchronisation
|
// über emit requestValueUpdate() zur Thread sysnchronisation
|
||||||
// entkoppeln,
|
// entkoppeln,
|
||||||
|
|
||||||
|
|||||||
185
bcmainwindow.ui
@@ -71,9 +71,15 @@
|
|||||||
<height>64</height>
|
<height>64</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<property name="autoRaise">
|
<property name="autoRaise">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">_buttonGroup</string>
|
||||||
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignmentFlag::AlignHCenter">
|
<item alignment="Qt::AlignmentFlag::AlignHCenter">
|
||||||
@@ -93,9 +99,15 @@
|
|||||||
<height>64</height>
|
<height>64</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<property name="autoRaise">
|
<property name="autoRaise">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">_buttonGroup</string>
|
||||||
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignmentFlag::AlignHCenter">
|
<item alignment="Qt::AlignmentFlag::AlignHCenter">
|
||||||
@@ -115,31 +127,18 @@
|
|||||||
<height>64</height>
|
<height>64</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="autoRaise">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="checked">
|
||||||
</item>
|
<bool>true</bool>
|
||||||
<item alignment="Qt::AlignmentFlag::AlignHCenter">
|
|
||||||
<widget class="QToolButton" name="_pimpButton">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>64</width>
|
|
||||||
<height>64</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>...</string>
|
|
||||||
</property>
|
|
||||||
<property name="iconSize">
|
|
||||||
<size>
|
|
||||||
<width>48</width>
|
|
||||||
<height>48</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="autoRaise">
|
<property name="autoRaise">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">_buttonGroup</string>
|
||||||
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@@ -157,17 +156,78 @@
|
|||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignmentFlag::AlignHCenter">
|
<item alignment="Qt::AlignmentFlag::AlignHCenter">
|
||||||
<widget class="QToolButton" name="_syncButton">
|
<widget class="QToolButton" name="_syncButton">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>64</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Sync</string>
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="bionxcontrol.qrc">
|
||||||
|
<normaloff>:/sync_yellow.svg</normaloff>:/sync_yellow.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>48</width>
|
||||||
|
<height>48</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item alignment="Qt::AlignmentFlag::AlignHCenter">
|
||||||
<widget class="QToolButton" name="_connectButton">
|
<widget class="QToolButton" name="_connectButton">
|
||||||
<property name="text">
|
<property name="minimumSize">
|
||||||
<string>Connect</string>
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>64</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="bionxcontrol.qrc">
|
||||||
|
<normaloff>:/connect.svg</normaloff>:/connect.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>48</width>
|
||||||
|
<height>48</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignmentFlag::AlignHCenter">
|
||||||
|
<widget class="QToolButton" name="_exitButton">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>64</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Quit</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="bionxcontrol.qrc">
|
||||||
|
<normaloff>:/exit_red.svg</normaloff>:/exit_red.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>48</width>
|
||||||
|
<height>48</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -190,7 +250,7 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>3</number>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="BCDeviceView" name="_consolePanel">
|
<widget class="BCDeviceView" name="_consolePanel">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
@@ -279,61 +339,13 @@
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="BCDeviceView" name="_pimpPanel">
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::Shape::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Shadow::Plain</enum>
|
|
||||||
</property>
|
|
||||||
<property name="lineWidth">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="showGrid">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="gridStyle">
|
|
||||||
<enum>Qt::PenStyle::NoPen</enum>
|
|
||||||
</property>
|
|
||||||
<property name="BCHeaderLabel" stdset="0">
|
|
||||||
<string>Pimp my Ride ...</string>
|
|
||||||
</property>
|
|
||||||
<attribute name="horizontalHeaderVisible">
|
|
||||||
<bool>false</bool>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="horizontalHeaderStretchLastSection">
|
|
||||||
<bool>true</bool>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="verticalHeaderVisible">
|
|
||||||
<bool>false</bool>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QStatusBar" name="_statusbar">
|
<widget class="QStatusBar" name="_statusbar"/>
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true">background-color: #DADADA</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<action name="_pimpAction">
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:restart.png</normaloff>:restart.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>pimp</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Pimp my Ride</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="_motorAction">
|
<action name="_motorAction">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset>
|
<iconset>
|
||||||
@@ -343,7 +355,7 @@
|
|||||||
<string>motor</string>
|
<string>motor</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Show motor settings</string>
|
<string>Motoreinstellungen anzeigen und bearbeiten</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="_batteryAction">
|
<action name="_batteryAction">
|
||||||
@@ -355,7 +367,7 @@
|
|||||||
<string>battery</string>
|
<string>battery</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Show battery settings</string>
|
<string>Batterieeinstellungen anzeigen und bearbeiten</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="_consoleAction">
|
<action name="_consoleAction">
|
||||||
@@ -367,31 +379,19 @@
|
|||||||
<string>console</string>
|
<string>console</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Show console settings</string>
|
<string>Konseleneinstellungen anzeigen und bearbeiten</string>
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="_exitAction">
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:exit.png</normaloff>:exit.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Exit</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Exit</string>
|
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="_connectAction">
|
<action name="_connectAction">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="bionxcontrol.qrc">
|
<iconset>
|
||||||
<normaloff>:/connected.png</normaloff>:/connected.png</iconset>
|
<normaloff>:/connected.png</normaloff>:/connected.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>connect</string>
|
<string>connect</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>connect to bike</string>
|
<string>TinyCAN native Treiber laden</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="menuRole">
|
<property name="menuRole">
|
||||||
<enum>QAction::MenuRole::TextHeuristicRole</enum>
|
<enum>QAction::MenuRole::TextHeuristicRole</enum>
|
||||||
@@ -409,4 +409,7 @@
|
|||||||
<include location="bionxcontrol.qrc"/>
|
<include location="bionxcontrol.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
<buttongroups>
|
||||||
|
<buttongroup name="_buttonGroup"/>
|
||||||
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
|||||||
34
bcsliderstyle.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
BionxControl
|
||||||
|
© 2025 -2026 christoph holzheuer
|
||||||
|
christoph.holzheuer@gmail.com
|
||||||
|
|
||||||
|
Using:
|
||||||
|
|
||||||
|
mhs_can_drv.c
|
||||||
|
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||||
|
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||||
|
@see www.mhs-elektronik.de
|
||||||
|
|
||||||
|
Based on Bionx data type descriptions from:
|
||||||
|
|
||||||
|
BigXionFlasher USB V 0.2.4 rev. 97
|
||||||
|
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
||||||
|
@see www.bigxionflasher.org
|
||||||
|
|
||||||
|
Bionx Bike Info
|
||||||
|
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
||||||
|
@see www.ts-soft.de
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
@see https://github.com/bikemike/bionx-bikeinfo
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <bcsliderstyle.h>
|
||||||
|
|
||||||
269
bcsliderstyle.h
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
BionxControl
|
||||||
|
© 2025 -2026 christoph holzheuer
|
||||||
|
christoph.holzheuer@gmail.com
|
||||||
|
|
||||||
|
Using:
|
||||||
|
|
||||||
|
mhs_can_drv.c
|
||||||
|
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||||
|
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||||
|
@see www.mhs-elektronik.de
|
||||||
|
|
||||||
|
Based on Bionx data type descriptions from:
|
||||||
|
|
||||||
|
BigXionFlasher USB V 0.2.4 rev. 97
|
||||||
|
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
||||||
|
@see www.bigxionflasher.org
|
||||||
|
|
||||||
|
Bionx Bike Info
|
||||||
|
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
||||||
|
@see www.ts-soft.de
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
@see https://github.com/bikemike/bionx-bikeinfo
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef BCSLIDERSTYLE_H
|
||||||
|
#define BCSLIDERSTYLE_H
|
||||||
|
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QHeaderView>
|
||||||
|
|
||||||
|
#include <QSlider>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QSlider>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QProxyStyle>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QStyleOptionSlider>
|
||||||
|
#include <QGraphicsDropShadowEffect>
|
||||||
|
|
||||||
|
// Fluent Design Slider Style
|
||||||
|
class FluentSliderStyle : public QProxyStyle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
FluentSliderStyle()
|
||||||
|
: QProxyStyle()
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Wichtig: Genug Platz für Handle reservieren
|
||||||
|
int pixelMetric(PixelMetric metric, const QStyleOption* option = nullptr, const QWidget* widget = nullptr) const override
|
||||||
|
{
|
||||||
|
switch (metric)
|
||||||
|
{
|
||||||
|
case PM_SliderThickness:
|
||||||
|
return 32; // Höhe für horizontalen Slider
|
||||||
|
case PM_SliderLength:
|
||||||
|
return 20; // Handle-Größe
|
||||||
|
case PM_SliderControlThickness:
|
||||||
|
return 20;
|
||||||
|
case PM_SliderSpaceAvailable:
|
||||||
|
if (option)
|
||||||
|
{
|
||||||
|
if (const QStyleOptionSlider* sliderOpt = qstyleoption_cast<const QStyleOptionSlider*>(option)) {
|
||||||
|
if (sliderOpt->orientation == Qt::Horizontal) {
|
||||||
|
return sliderOpt->rect.width() - 20;
|
||||||
|
} else {
|
||||||
|
return sliderOpt->rect.height() - 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QProxyStyle::pixelMetric(metric, option, widget);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return QProxyStyle::pixelMetric(metric, option, widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex* opt,SubControl sc, const QWidget* widget) const override
|
||||||
|
{
|
||||||
|
if (cc == CC_Slider) {
|
||||||
|
if (const QStyleOptionSlider* slider = qstyleoption_cast<const QStyleOptionSlider*>(opt)) {
|
||||||
|
QRect rect = slider->rect;
|
||||||
|
int handleSize = 20;
|
||||||
|
|
||||||
|
if (sc == SC_SliderHandle) {
|
||||||
|
// Handle Position korrekt berechnen
|
||||||
|
if (slider->orientation == Qt::Horizontal) {
|
||||||
|
int range = slider->maximum - slider->minimum;
|
||||||
|
int pos = slider->sliderPosition - slider->minimum;
|
||||||
|
int pixelRange = rect.width() - handleSize;
|
||||||
|
int pixelPos = (range != 0) ? (pos * pixelRange) / range : 0;
|
||||||
|
|
||||||
|
return QRect(rect.x() + pixelPos,
|
||||||
|
rect.center().y() - handleSize / 2,
|
||||||
|
handleSize, handleSize);
|
||||||
|
} else {
|
||||||
|
int range = slider->maximum - slider->minimum;
|
||||||
|
int pos = slider->sliderPosition - slider->minimum;
|
||||||
|
int pixelRange = rect.height() - handleSize;
|
||||||
|
int pixelPos = (range != 0) ? (pos * pixelRange) / range : 0;
|
||||||
|
|
||||||
|
return QRect(rect.center().x() - handleSize / 2,
|
||||||
|
rect.bottom() - pixelPos - handleSize,
|
||||||
|
handleSize, handleSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QProxyStyle::subControlRect(cc, opt, sc, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const override
|
||||||
|
{
|
||||||
|
if (control == CC_Slider)
|
||||||
|
{
|
||||||
|
if (const QStyleOptionSlider* slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) {
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
|
// Fluent Colors
|
||||||
|
QColor accentColor(0, 120, 212); // #0078D4
|
||||||
|
QColor inactiveColor(138, 136, 134); // #8A8886
|
||||||
|
QColor bgColor(255, 255, 255); // White background
|
||||||
|
|
||||||
|
if (slider->orientation == Qt::Horizontal) {
|
||||||
|
drawHorizontalFluentSlider(painter, slider, accentColor, inactiveColor, bgColor);
|
||||||
|
} else {
|
||||||
|
drawVerticalFluentSlider(painter, slider, accentColor, inactiveColor, bgColor);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QProxyStyle::drawComplexControl(control, option, painter, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void drawHorizontalFluentSlider(QPainter* painter, const QStyleOptionSlider* slider,
|
||||||
|
const QColor& activeColor, const QColor& inactiveColor,
|
||||||
|
const QColor& bgColor) const {
|
||||||
|
QRect groove = slider->rect;
|
||||||
|
QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, nullptr);
|
||||||
|
|
||||||
|
int grooveHeight = 4;
|
||||||
|
// Track sollte im Widget-Zentrum sein, nicht im groove-Zentrum
|
||||||
|
int grooveY = slider->rect.center().y() - grooveHeight / 2;
|
||||||
|
|
||||||
|
// Full background track
|
||||||
|
QRect fullTrack(groove.left(), grooveY, groove.width(), grooveHeight);
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
painter->setBrush(inactiveColor.lighter(150));
|
||||||
|
painter->drawRoundedRect(fullTrack, grooveHeight / 2, grooveHeight / 2);
|
||||||
|
|
||||||
|
// Active track (filled portion)
|
||||||
|
int activeWidth = handle.center().x() - groove.left();
|
||||||
|
QRect activeTrack(groove.left(), grooveY, activeWidth, grooveHeight);
|
||||||
|
painter->setBrush(activeColor);
|
||||||
|
painter->drawRoundedRect(activeTrack, grooveHeight / 2, grooveHeight / 2);
|
||||||
|
|
||||||
|
// Handle (Thumb) - Fluent style is more subtle
|
||||||
|
int handleSize = 20;
|
||||||
|
QRect thumbRect(handle.center().x() - handleSize / 2,
|
||||||
|
handle.center().y() - handleSize / 2,
|
||||||
|
handleSize, handleSize);
|
||||||
|
|
||||||
|
// Hover effect - subtle glow
|
||||||
|
if (slider->state & State_MouseOver) {
|
||||||
|
painter->setBrush(QColor(activeColor.red(), activeColor.green(),
|
||||||
|
activeColor.blue(), 30));
|
||||||
|
int glowSize = 32;
|
||||||
|
QRect glow(handle.center().x() - glowSize / 2,
|
||||||
|
handle.center().y() - glowSize / 2,
|
||||||
|
glowSize, glowSize);
|
||||||
|
painter->drawEllipse(glow);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thumb
|
||||||
|
painter->setBrush(bgColor);
|
||||||
|
painter->setPen(QPen(activeColor, 2));
|
||||||
|
painter->drawEllipse(thumbRect);
|
||||||
|
|
||||||
|
// Inner circle for pressed state
|
||||||
|
if (slider->state & State_Sunken) {
|
||||||
|
int innerSize = 8;
|
||||||
|
QRect inner(handle.center().x() - innerSize / 2,
|
||||||
|
handle.center().y() - innerSize / 2,
|
||||||
|
innerSize, innerSize);
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
painter->setBrush(activeColor);
|
||||||
|
painter->drawEllipse(inner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawVerticalFluentSlider(QPainter* painter, const QStyleOptionSlider* slider,
|
||||||
|
const QColor& activeColor, const QColor& inactiveColor,
|
||||||
|
const QColor& bgColor) const {
|
||||||
|
QRect groove = slider->rect;
|
||||||
|
QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, nullptr);
|
||||||
|
|
||||||
|
int grooveWidth = 4;
|
||||||
|
// Track sollte im Widget-Zentrum sein
|
||||||
|
int grooveX = slider->rect.center().x() - grooveWidth / 2;
|
||||||
|
|
||||||
|
// Full background track
|
||||||
|
QRect fullTrack(grooveX, groove.top(), grooveWidth, groove.height());
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
painter->setBrush(inactiveColor.lighter(150));
|
||||||
|
painter->drawRoundedRect(fullTrack, grooveWidth / 2, grooveWidth / 2);
|
||||||
|
|
||||||
|
// Active track
|
||||||
|
int activeHeight = groove.bottom() - handle.center().y();
|
||||||
|
QRect activeTrack(grooveX, handle.center().y(), grooveWidth, activeHeight);
|
||||||
|
painter->setBrush(activeColor);
|
||||||
|
painter->drawRoundedRect(activeTrack, grooveWidth / 2, grooveWidth / 2);
|
||||||
|
|
||||||
|
// Handle
|
||||||
|
int handleSize = 20;
|
||||||
|
QRect thumbRect(handle.center().x() - handleSize / 2,
|
||||||
|
handle.center().y() - handleSize / 2,
|
||||||
|
handleSize, handleSize);
|
||||||
|
|
||||||
|
if (slider->state & State_MouseOver) {
|
||||||
|
painter->setBrush(QColor(activeColor.red(), activeColor.green(),
|
||||||
|
activeColor.blue(), 30));
|
||||||
|
int glowSize = 32;
|
||||||
|
QRect glow(handle.center().x() - glowSize / 2,
|
||||||
|
handle.center().y() - glowSize / 2,
|
||||||
|
glowSize, glowSize);
|
||||||
|
painter->drawEllipse(glow);
|
||||||
|
}
|
||||||
|
|
||||||
|
painter->setBrush(bgColor);
|
||||||
|
painter->setPen(QPen(activeColor, 2));
|
||||||
|
painter->drawEllipse(thumbRect);
|
||||||
|
|
||||||
|
if (slider->state & State_Sunken) {
|
||||||
|
int innerSize = 8;
|
||||||
|
QRect inner(handle.center().x() - innerSize / 2,
|
||||||
|
handle.center().y() - innerSize / 2,
|
||||||
|
innerSize, innerSize);
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
painter->setBrush(activeColor);
|
||||||
|
painter->drawEllipse(inner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BCSLIDERSTYLE_H
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
#include <bctransmitter.h>
|
#include <bctransmitter.h>
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
BCTransmitter::BCTransmitter(QObject *parent)
|
BCTransmitter::BCTransmitter(QObject *parent)
|
||||||
: QObject(parent), _isBusy(false)
|
: QObject(parent)//, _isBusy(false)
|
||||||
{
|
{
|
||||||
//_canDriver = new BCDriverTinyCan{this};
|
//_canDriver = new BCDriverTinyCan{this};
|
||||||
_canDriver = &_dummyDriver;
|
_canDriver = &_dummyDriver;
|
||||||
@@ -56,18 +57,24 @@ BCTransmitter::BCTransmitter(QObject *parent)
|
|||||||
void BCTransmitter::onToggleDriverConnection( bool connect )
|
void BCTransmitter::onToggleDriverConnection( bool connect )
|
||||||
{
|
{
|
||||||
qDebug() << " --- onToggleDriverConnection: " << connect;
|
qDebug() << " --- onToggleDriverConnection: " << connect;
|
||||||
|
emit driverStateChanged(BCDriver::DriverState::Initialized, "BUSY!");
|
||||||
|
bc::delay_millis(350);
|
||||||
|
// kill all pending stuff
|
||||||
|
QCoreApplication::removePostedEvents(this, QEvent::MetaCall);
|
||||||
// FIX! Ende der current op abwarten!
|
// FIX! Ende der current op abwarten!
|
||||||
BCDriver::DriverState state = connect ? BCDriver::DriverState::DeviceReady : BCDriver::DriverState::NotPresent;
|
BCDriver::DriverState state = connect ? BCDriver::DriverState::DeviceReady : BCDriver::DriverState::NotPresent;
|
||||||
const QString& message = connect ? "Trying to connect" : " FAILED";
|
const QString& message = connect ? "Trying to connect" : " FAILED";
|
||||||
emit driverStateChanged(state, message);
|
emit driverStateChanged(state, message);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
// Hier sind wir noch in GUI Thread
|
// Hier sind wir noch in GUI Thread
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
// weitere operation stoppen
|
// weitere operation stoppen
|
||||||
_isBusy = true;
|
_isBusy = true;
|
||||||
connect ? connectCanDriver() : disconnectCanDriver();
|
connect ? connectCanDriver() : disconnectCanDriver();
|
||||||
_isBusy = false;
|
_isBusy = false;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -120,50 +127,18 @@ void BCTransmitter::disconnectCanDriver()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BCTransmitter::onEnqueueValue( BCValuePtrConst value)
|
void BCTransmitter::onUpdateValue( BCValuePtrConst valuePtr)
|
||||||
{
|
{
|
||||||
|
|
||||||
// wir stellen hier auf die arte Tour sicher, das onEnqueueValue
|
// wir stellen hier auf die harte Tour sicher, das onUpdateValue
|
||||||
// nicht aus dem Parent-Thread direkt sondern über die EventQueue aufgerufen wurde.
|
// nicht aus dem Parent-Thread direkt sondern über die EventQueue aufgerufen wurde.
|
||||||
|
|
||||||
Q_ASSERT(QThread::currentThread() == this->thread());
|
Q_ASSERT(QThread::currentThread() == this->thread());
|
||||||
|
|
||||||
// Hier sind wir noch in GUI Thread
|
// Wir arbeiten hier ohne besondere Threadsynchronisation, mutexed o.ä: Die
|
||||||
//QMutexLocker locker(&_mutex);
|
// entkoppelung und serialisierung passiert bereits durch die Qt-Eventqueue.
|
||||||
_valueQueue.enqueue( value );
|
// Das klappt aber nur in der hier gewählten Konstellation mit einer Parent-Thread
|
||||||
|
// und einem Worker.
|
||||||
// wir wollen nicht den ganzen Value verschicken, erstrecht
|
|
||||||
// wollen wir nicht den Value in verschiedenen Threads gleichzeitig
|
|
||||||
// in die Hand nehmen, also hantieren wir nur mit den Inidizes.
|
|
||||||
|
|
||||||
// Trigger processing im Event-Loop des Worker Threads
|
|
||||||
// invokeMethod mit QueuedConnection entkoppelt den Aufruf,
|
|
||||||
// damit onEnqueueValue sofort zurückkehrt (non-blocking für den Aufrufer).
|
|
||||||
|
|
||||||
//QMetaObject::invokeMethod(this, "onProcessValue", Qt::QueuedConnection);
|
|
||||||
onProcessValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BCTransmitter::onProcessValue()
|
|
||||||
{
|
|
||||||
|
|
||||||
//if (_isBusy)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
_isBusy = true;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
BCValuePtrConst valuePtr{};
|
|
||||||
{
|
|
||||||
//QMutexLocker locker(&_mutex);
|
|
||||||
if (_valueQueue.isEmpty())
|
|
||||||
{
|
|
||||||
_isBusy = false;
|
|
||||||
break; // Schleife verlassen, warten auf neue Events
|
|
||||||
}
|
|
||||||
valuePtr =_valueQueue.dequeue();
|
|
||||||
} // Mutex wird hier freigegeben! WICHTIG: Execute ohne Lock!
|
|
||||||
|
|
||||||
// Kosmetik
|
// Kosmetik
|
||||||
const BCValue& value = *(valuePtr.get());
|
const BCValue& value = *(valuePtr.get());
|
||||||
@@ -194,7 +169,8 @@ void BCTransmitter::onProcessValue()
|
|||||||
TransmitResult result = value.isWord ? readWordValue( devID, regID ) : readByteValue( devID, regID );
|
TransmitResult result = value.isWord ? readWordValue( devID, regID ) : readByteValue( devID, regID );
|
||||||
if( result.has_value() )
|
if( result.has_value() )
|
||||||
{
|
{
|
||||||
newVisibleValue = value.formatValue( result.value() );
|
// quark! das gehört hier nicht hin!
|
||||||
|
newVisibleValue = value.formatValues( result.value() );
|
||||||
newState = BCValue::State::InSync;
|
newState = BCValue::State::InSync;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -207,11 +183,13 @@ void BCTransmitter::onProcessValue()
|
|||||||
|
|
||||||
// __fix
|
// __fix
|
||||||
//bc::processEventsFor(150);
|
//bc::processEventsFor(150);
|
||||||
bc::delay_millis(150);
|
bc::delay_millis(50);
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BCTransmitter::onProcessValue()
|
||||||
|
{}
|
||||||
|
|
||||||
TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t registerID )
|
TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t registerID )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public:
|
|||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onToggleDriverConnection( bool connect );
|
void onToggleDriverConnection( bool connect );
|
||||||
void onEnqueueValue(BCValuePtrConst value );
|
void onUpdateValue(BCValuePtrConst valuePtr );
|
||||||
void onProcessValue();
|
void onProcessValue();
|
||||||
void onStartNativeDriver();
|
void onStartNativeDriver();
|
||||||
|
|
||||||
@@ -80,11 +80,11 @@ private:
|
|||||||
TransmitResult readByteValue( uint32_t deviceID, uint8_t registerID );
|
TransmitResult readByteValue( uint32_t deviceID, uint8_t registerID );
|
||||||
TransmitResult readWordValue( uint32_t deviceID, uint8_t registerID );
|
TransmitResult readWordValue( uint32_t deviceID, uint8_t registerID );
|
||||||
|
|
||||||
using BCDataQueue = QQueue<BCValuePtrConst>;
|
//using BCDataQueue = QQueue<BCValuePtrConst>;
|
||||||
|
|
||||||
BCDataQueue _valueQueue;
|
//BCDataQueue _valueQueue;
|
||||||
QMutex _mutex;
|
//QMutex _mutex;
|
||||||
std::atomic<bool> _isBusy{ false };
|
//std::atomic<bool> _isBusy{ false };
|
||||||
|
|
||||||
// __fix!
|
// __fix!
|
||||||
BCDriver* _canDriver{};
|
BCDriver* _canDriver{};
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ BCValue::BCValue( BCDevice::ID deviceID_, BC::ID registerID_)
|
|||||||
visibleValue = "--";
|
visibleValue = "--";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BCValue::formatValue( uint32_t value ) const
|
QString BCValue::formatValues( uint32_t value ) const
|
||||||
{
|
{
|
||||||
if( factor == 1 )
|
if( factor == 1 )
|
||||||
return QString::number( value );
|
return QString::number( value );
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public:
|
|||||||
|
|
||||||
BCValue( BCDevice::ID deviceID_, BC::ID registerID_ );
|
BCValue( BCDevice::ID deviceID_, BC::ID registerID_ );
|
||||||
|
|
||||||
QString formatValue( uint32_t value ) const;
|
QString formatValues( uint32_t value ) const;
|
||||||
void dumpValue() const;
|
void dumpValue() const;
|
||||||
|
|
||||||
mutable States state{BCValue::State::ReadOnly};
|
mutable States state{BCValue::State::ReadOnly};
|
||||||
@@ -103,6 +103,7 @@ public:
|
|||||||
int indexRow{-1};
|
int indexRow{-1};
|
||||||
QString label;
|
QString label;
|
||||||
mutable QString visibleValue;
|
mutable QString visibleValue;
|
||||||
|
mutable double rawValue;
|
||||||
bool isWord{false};
|
bool isWord{false};
|
||||||
QString unitLabel;
|
QString unitLabel;
|
||||||
double factor{1};
|
double factor{1};
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ void BCValueModel::onValueUpdated( int row, BCValue::State state, const QString&
|
|||||||
{
|
{
|
||||||
if( row > -1 && row < _valueList.size() )
|
if( row > -1 && row < _valueList.size() )
|
||||||
{
|
{
|
||||||
BCValue& value = *(_valueList[row].get());
|
const BCValue& value = *(_valueList[row].get());
|
||||||
QModelIndex idx = index(row,1);
|
QModelIndex idx = index(row,1);
|
||||||
|
|
||||||
//qDebug();
|
//qDebug();
|
||||||
@@ -132,7 +132,7 @@ int BCValueModel::columnCount(const QModelIndex& parent) const
|
|||||||
{
|
{
|
||||||
if (parent.isValid())
|
if (parent.isValid())
|
||||||
return 0;
|
return 0;
|
||||||
return 2;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -191,7 +191,8 @@ Das Model Gibt hier, unabhängig von der DataRole, immer das
|
|||||||
|
|
||||||
Qt::ItemFlags BCValueModel::flags(const QModelIndex& index) const
|
Qt::ItemFlags BCValueModel::flags(const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
// die label spalte lässt sich nicht editieren
|
||||||
|
if (!index.isValid() || index.column() == 0 )
|
||||||
return Qt::NoItemFlags;
|
return Qt::NoItemFlags;
|
||||||
|
|
||||||
return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
|
return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
|
||||||
|
|||||||
@@ -59,11 +59,7 @@ void BCXmlLoader::loadXmlBikeData( const QString& fileName )
|
|||||||
}
|
}
|
||||||
qDebug().noquote() << parts.join(" ");
|
qDebug().noquote() << parts.join(" ");
|
||||||
};
|
};
|
||||||
/*
|
|
||||||
QString fileName = QFileDialog::getOpenFileName(this, "XML öffnen", "", "XML Files (*.xml)");
|
|
||||||
if (fileName.isEmpty())
|
|
||||||
return;
|
|
||||||
*/
|
|
||||||
|
|
||||||
QMetaEnum bcDeviceEnum{QMetaEnum::fromType<BCDevice::ID>()};
|
QMetaEnum bcDeviceEnum{QMetaEnum::fromType<BCDevice::ID>()};
|
||||||
|
|
||||||
@@ -92,7 +88,7 @@ void BCXmlLoader::loadXmlBikeData( const QString& fileName )
|
|||||||
if (token == QXmlStreamReader::StartElement)
|
if (token == QXmlStreamReader::StartElement)
|
||||||
{
|
{
|
||||||
QString deviceType = _xml.attributes().value("Type"_L1).toString();
|
QString deviceType = _xml.attributes().value("Type"_L1).toString();
|
||||||
printAttrs (_xml);
|
//printAttrs (_xml);
|
||||||
// Wir wollen die Device-ID aus dem XML Tag ermitteln
|
// Wir wollen die Device-ID aus dem XML Tag ermitteln
|
||||||
const char* deviceKey = _xml.attributes().value("Type"_L1).toLatin1().constData();
|
const char* deviceKey = _xml.attributes().value("Type"_L1).toLatin1().constData();
|
||||||
bool ok;
|
bool ok;
|
||||||
@@ -109,22 +105,13 @@ void BCXmlLoader::loadXmlBikeData( const QString& fileName )
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if (xml.hasError())
|
|
||||||
{
|
|
||||||
QMessageBox::critical(nullptr, "Parsing Fehler", xml.errorString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_model->setDevices(parsedValues);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// create & add new model to the model map
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lädt deie Daten des BionX eBikes
|
||||||
|
* @param deviceID
|
||||||
|
*/
|
||||||
|
|
||||||
void BCXmlLoader::loadXmlBikeDeviceData(BCDevice::ID deviceID)
|
void BCXmlLoader::loadXmlBikeDeviceData(BCDevice::ID deviceID)
|
||||||
{
|
{
|
||||||
auto printAttrs = [](const QXmlStreamReader& xml)
|
auto printAttrs = [](const QXmlStreamReader& xml)
|
||||||
@@ -138,7 +125,7 @@ void BCXmlLoader::loadXmlBikeDeviceData(BCDevice::ID deviceID)
|
|||||||
|
|
||||||
printAttrs (_xml);
|
printAttrs (_xml);
|
||||||
Q_ASSERT(_xml.isStartElement() && _xml.name() == "Device"_L1);
|
Q_ASSERT(_xml.isStartElement() && _xml.name() == "Device"_L1);
|
||||||
qDebug() << " XXX ---------------";
|
|
||||||
|
|
||||||
// temporäre Wertliste für neues Device
|
// temporäre Wertliste für neues Device
|
||||||
BCValueList currentValues;
|
BCValueList currentValues;
|
||||||
|
|||||||
@@ -7,15 +7,12 @@
|
|||||||
<file alias="bionx_akku.png">resources/bionx_akku.png</file>
|
<file alias="bionx_akku.png">resources/bionx_akku.png</file>
|
||||||
<file alias="bionx_console.png">resources/bionx_console.png</file>
|
<file alias="bionx_console.png">resources/bionx_console.png</file>
|
||||||
<file alias="bionx_motor.png">resources/bionx_motor.png</file>
|
<file alias="bionx_motor.png">resources/bionx_motor.png</file>
|
||||||
<file alias="exit.png">resources/exit.png</file>
|
<file alias="connect.svg">resources/connect.svg</file>
|
||||||
<file alias="important.png">resources/important.png</file>
|
<file alias="exit.svg">resources/exit.svg</file>
|
||||||
<file alias="restart.png">resources/restart.png</file>
|
<file alias="exit_red.svg">resources/exit_red.svg</file>
|
||||||
<file alias="splash.png">resources/splash.png</file>
|
<file alias="sync_green.svg">resources/sync_green.svg</file>
|
||||||
<file alias="connect.png">resources/connect.png</file>
|
<file alias="sync_yellow.svg">resources/sync_yellow.svg</file>
|
||||||
<file alias="connected.png">resources/connected.png</file>
|
<file alias="connect_white.svg">resources/connect_white.svg</file>
|
||||||
<file alias="disconnected.png">resources/disconnected.png</file>
|
<file alias="sync.svg">resources/sync.svg</file>
|
||||||
<file>resources/connect_white.svg</file>
|
|
||||||
<file>resources/sync_green.svg</file>
|
|
||||||
<file>resources/sync_yellow.svg</file>
|
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@@ -27,6 +27,43 @@ sudo apt purge modemmanager
|
|||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
|
sudo apt install \
|
||||||
|
qt6-declarative-dev \
|
||||||
|
qt6-tools-dev \
|
||||||
|
qt6-tools-dev-tools \
|
||||||
|
qt6-l10n-tools \
|
||||||
|
qt6-scxml-dev \
|
||||||
|
qt6-serialport-dev \
|
||||||
|
qt6-serialbus-dev \
|
||||||
|
qt6-connectivity-dev \
|
||||||
|
qt6-sensors-dev \
|
||||||
|
qt6-websockets-dev \
|
||||||
|
qt6-webchannel-dev \
|
||||||
|
qt6-svg-dev \
|
||||||
|
qt6-multimedia-dev \
|
||||||
|
qt6-charts-dev \
|
||||||
|
qt6-wayland \
|
||||||
|
qml6-module-qtquick-controls \
|
||||||
|
qml6-module-qtquick-layouts \
|
||||||
|
qml6-module-qtquick-templates \
|
||||||
|
qml6-module-qtquick-window \
|
||||||
|
qml6-module-qtqml-workerscript \
|
||||||
|
qml6-module-qtcharts \
|
||||||
|
qml6-module-qt-labs-platform \
|
||||||
|
libqt6sql6-mysql libqt6sql6-psql libqt6sql6-sqlite \
|
||||||
|
libqt6opengl6-dev
|
||||||
|
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install \
|
||||||
|
qtcreator \
|
||||||
|
qtcreator-doc \
|
||||||
|
cmake \
|
||||||
|
ninja-build \
|
||||||
|
gdb \
|
||||||
|
clang \
|
||||||
|
clang-format
|
||||||
|
|
||||||
|
|
||||||
https://github.com/MHS-Elektronik/OBD-Display
|
https://github.com/MHS-Elektronik/OBD-Display
|
||||||
|
|
||||||
sudo chgrp pi /opt
|
sudo chgrp pi /opt
|
||||||
@@ -36,6 +73,7 @@ https://github.com/MHS-Elektronik/OBD-Display
|
|||||||
tar -xzvf tiny_can_raspberry_790.tar.gz
|
tar -xzvf tiny_can_raspberry_790.tar.gz
|
||||||
rm tiny_can_raspberry_790.tar.gz
|
rm tiny_can_raspberry_790.tar.gz
|
||||||
|
|
||||||
|
sudo apt install fonts-open-sans
|
||||||
|
|
||||||
|
|
||||||
RANT
|
RANT
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
Sehr geehrte Frau Spaag,
|
|
||||||
|
|
||||||
Aktuell bin ich als Softwareentwickler im Bereich C++/Qt fest angestellt, suche jedoch
|
|
||||||
nach neuen Entwicklungsmöglichkeiten.
|
|
||||||
|
|
||||||
Ihre Stellenanzeige hat mich sofort angesprochen, denn das beschriebene Anforderungsprofil
|
|
||||||
harmonisiert sehr gut mit meiner derzeitigen Tätigkeit im Bereich Datenvisualisierung und
|
|
||||||
|
|
||||||
blub
|
|
||||||
|
|
||||||
Ich freu mich wie woschd und verbeibe mit freundlichen Grüßen
|
|
||||||
|
|
||||||
Christoph Holzheuer
|
|
||||||
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
|
|
||||||
znode<T> ist eine header-only Klasse in modern c++ für generische Baumstrukturen
|
|
||||||
In der derzeitigen Ausführung dient sie mit Hilfe des pugixml Parser zur Verwaltung
|
|
||||||
von XML Daten innerhalb des xtree-Projekts.
|
|
||||||
|
|
||||||
Die Knoten sind std::c++, die Verwaltung der Attribs ist drangeebrt und somit variable.
|
|
||||||
|
|
||||||
Besonderheit ist die Übergabe das String types als template parameter: In Xtree instanzierung durch QString,
|
|
||||||
andere durch std::string bzw. std::w_string ohne Dependencies zur Qt-Lib eingehen zu müssen.
|
|
||||||
bridge-code
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
|
Before Width: | Height: | Size: 46 KiB |
@@ -1,63 +0,0 @@
|
|||||||
Challenges
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
BionxControl
|
|
||||||
|
|
||||||
Aufgabe:
|
|
||||||
|
|
||||||
Ansatz:
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
xtree
|
|
||||||
|
|
||||||
Aufgabe:
|
|
||||||
|
|
||||||
Ansatz:
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
znode
|
|
||||||
|
|
||||||
Aufgabe:
|
|
||||||
|
|
||||||
Ansatz:
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
libPigPio
|
|
||||||
|
|
||||||
Aufgabe:
|
|
||||||
|
|
||||||
Ansatz:
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
supportware
|
|
||||||
|
|
||||||
Aufgabe:
|
|
||||||
|
|
||||||
Ansatz:
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
raDIYo
|
|
||||||
|
|
||||||
Aufgabe:
|
|
||||||
|
|
||||||
Ansatz:
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
miniCash.connect
|
|
||||||
|
|
||||||
Aufgabe:
|
|
||||||
|
|
||||||
Ansatz:
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------
|
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<Value ID='Cons_Assist_Mountain_Cap' Label='Mountain Cap' UnitLabel='%' Factor='1.5625' />
|
<Value ID='Cons_Assist_Mountain_Cap' Label='Mountain Cap' UnitLabel='%' Factor='1.5625' />
|
||||||
</Device>
|
</Device>
|
||||||
|
|
||||||
<!--
|
|
||||||
<Device Type="Motor">
|
<Device Type="Motor">
|
||||||
<Value ID='Motor_Rev_Hw' Label='Hardware Version' />
|
<Value ID='Motor_Rev_Hw' Label='Hardware Version' />
|
||||||
<Value ID='Motor_Rev_Sw' Label='Software Version' />
|
<Value ID='Motor_Rev_Sw' Label='Software Version' />
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
<Value ID='Battery_Rev_Hw' Label='Hardware Version' />
|
<Value ID='Battery_Rev_Hw' Label='Hardware Version' />
|
||||||
<Value ID='Battery_Rev_Sw' Label='Software Version' />
|
<Value ID='Battery_Rev_Sw' Label='Software Version' />
|
||||||
</Device>
|
</Device>
|
||||||
-->
|
|
||||||
</Bike>
|
</Bike>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@@ -3,118 +3,165 @@
|
|||||||
/* Alle QWidgets bekommen diesen Font */
|
/* Alle QWidgets bekommen diesen Font */
|
||||||
QWidget
|
QWidget
|
||||||
{
|
{
|
||||||
font-size: 14px;
|
font-family: "Calibri", "Carlito", "Open Sans", sans-serif;
|
||||||
font-family: Segoe UI, sans-serif;
|
font-size: 10pt;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
QMainWindow
|
QLabel#_headerLabel
|
||||||
{
|
{
|
||||||
background-color: #272727;
|
font-size: 14pt;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
QToolButton
|
||||||
|
{
|
||||||
|
background-color: white;
|
||||||
|
color: #201F1E;
|
||||||
|
border: 1px solid #8A8886;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
|
||||||
|
min-width: 64px;
|
||||||
|
max-width: 64px;
|
||||||
|
min-height: 64px;
|
||||||
|
max-height: 64px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:hover
|
||||||
|
{
|
||||||
|
background-color: #F3F2F1;
|
||||||
|
border: 1px solid #323130;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:pressed
|
||||||
|
{
|
||||||
|
background-color: #EDEBE9;
|
||||||
|
border: 1px solid #201F1E;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:disabled
|
||||||
|
{
|
||||||
|
background-color: #F3F2F1;
|
||||||
|
color: #A19F9D;
|
||||||
|
border: 1px solid #EDEBE9;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Spezifisches Styling für Buttons */
|
/* === QToolButton === */
|
||||||
QPushButton
|
QToolButton
|
||||||
{
|
{
|
||||||
background-color: #0078d7;
|
background-color: transparent;
|
||||||
color: white;
|
color: #000000;
|
||||||
|
border: none;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
|
|
||||||
|
min-width: 64px;
|
||||||
|
max-width: 64px;
|
||||||
|
min-height: 64px;
|
||||||
|
max-height: 64px;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton:hover
|
QToolButton:hover
|
||||||
{
|
{
|
||||||
background-color: #1084e3;
|
background-color: #F9F9F9;
|
||||||
|
border: 1px solid #DDDDDD;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton:pressed
|
QToolButton:pressed
|
||||||
{
|
{
|
||||||
background-color: #005a9e;
|
background-color: #E0E0E0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Normal */
|
QToolButton:checked
|
||||||
QToolButton {
|
{
|
||||||
background-color: transparent;
|
background-color: green;/*#0078D4;*/
|
||||||
border: 1px solid transparent;
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:disabled
|
||||||
|
{
|
||||||
|
color: #A19F9D;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* === QTableView & QTableWidget === */
|
||||||
|
|
||||||
|
QTableView, QTableWidget
|
||||||
|
{
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
color: #000000;
|
||||||
|
gridline-color: #E1DFDD;
|
||||||
|
border: 1px solid #E1DFDD;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 4px;
|
selection-background-color: #0078D4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hover */
|
|
||||||
QToolButton:hover {
|
|
||||||
background-color: #E3F2FD;
|
|
||||||
border: 1px solid #2196F3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pressed/Clicked */
|
|
||||||
QToolButton:pressed {
|
|
||||||
background-color: #BBDEFB;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Checked (bei checkable buttons) */
|
|
||||||
QToolButton:checked {
|
|
||||||
background-color: #2196F3;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Checked + Hover */
|
|
||||||
QToolButton:checked:hover {
|
|
||||||
background-color: #1976D2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disabled */
|
|
||||||
QToolButton:disabled {
|
|
||||||
color: #BDBDBD;
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
QTableView
|
|
||||||
{
|
|
||||||
background-color: #404142;
|
|
||||||
border-radius: 8px;
|
|
||||||
outline: none;
|
|
||||||
show-decoration-selected: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTableView::item
|
|
||||||
{
|
|
||||||
border: 2px solid #2196F3;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 8px;
|
|
||||||
margin: 4px;
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
QTableView::item:hover
|
QTableView::item:hover
|
||||||
{
|
{
|
||||||
border-color: #FF9800;
|
background-color: #e8f4f8;
|
||||||
background-color: #fff8f0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QTableView::item:selected
|
|
||||||
{
|
QScrollBar::handle:horizontal {
|
||||||
border-color: #F44336; /* Roter Rahmen */
|
background-color: #C8C6C4;
|
||||||
background-color: #ffebee;
|
min-width: 40px;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTableView::item:selected:hover
|
QScrollBar::handle:horizontal:hover {
|
||||||
{
|
background-color: #A19F9D;
|
||||||
border-color: #FF9800;
|
|
||||||
background-color: #ffe0b2;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
QTableView::item:focus
|
QScrollBar::handle:horizontal:pressed {
|
||||||
{
|
background-color: #8A8886;
|
||||||
/*
|
|
||||||
// outline: none; Entfernt das Focus-Rectangle
|
|
||||||
// border-color: green;
|
|
||||||
// background-color: #ffe0b2;
|
|
||||||
*/
|
|
||||||
border: 2px solid gray;
|
|
||||||
border-style: inset;
|
|
||||||
background-color: white;
|
|
||||||
color: black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:horizontal,
|
||||||
|
QScrollBar::sub-line:horizontal {
|
||||||
|
width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-page:horizontal,
|
||||||
|
QScrollBar::sub-page:horizontal {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar:vertical {
|
||||||
|
background-color: transparent;
|
||||||
|
width: 12px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical {
|
||||||
|
background-color: #C8C6C4;
|
||||||
|
min-height: 40px;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical:hover {
|
||||||
|
background-color: #A19F9D;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical:pressed {
|
||||||
|
background-color: #8A8886;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:vertical,
|
||||||
|
QScrollBar::sub-line:vertical {
|
||||||
|
height: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-page:vertical,
|
||||||
|
QScrollBar::sub-page:vertical {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 7.3 KiB |
1
resources/connect.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.25 4a.75.75 0 0 1 .743.648L9 4.75v2.773l1.874 2.815a.75.75 0 0 1 .117.306l.009.11v4.496a.75.75 0 0 1-.649.743L10.25 16H8.996v3.254a.75.75 0 0 1-1.492.101l-.007-.101L7.496 16 5.5 15.999v3.258a.75.75 0 0 1-1.493.101l-.006-.101L4 15.999 2.75 16a.75.75 0 0 1-.742-.648l-.007-.102v-4.496a.75.75 0 0 1 .071-.32l.055-.096 1.874-2.815V4.75a.75.75 0 0 1 1.493-.102l.007.102v3a.75.75 0 0 1-.072.32l-.054.096-1.874 2.815V14.5H9.5v-3.52L7.625 8.167a.75.75 0 0 1-.117-.306L7.5 7.75v-3A.75.75 0 0 1 8.25 4Zm7.004.001h4.496a.75.75 0 0 1 .743.649l.007.101L20.499 8h.75a.75.75 0 0 1 .744.648L22 8.75v4.496c0 .111-.025.22-.072.32l-.054.096L20 16.477v2.773a.75.75 0 0 1-1.494.102l-.006-.102v-3c0-.11.024-.22.071-.32l.054-.096L20.5 13.02V9.5h-5.998v3.52l1.874 2.814a.749.749 0 0 1 .118.306l.008.11v3a.75.75 0 0 1-1.493.102l-.007-.102v-2.773l-1.874-2.815a.75.75 0 0 1-.118-.306l-.008-.11V8.75a.75.75 0 0 1 .648-.743L13.752 8h.752V4.751a.75.75 0 0 1 .649-.743l.101-.007h4.496-4.496ZM19 5.501h-2.996V8h2.995V5.501Z" fill="#000000"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
1
resources/connect_white.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="48" height="48" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.25 4a.75.75 0 0 1 .743.648L9 4.75v2.773l1.874 2.815a.75.75 0 0 1 .117.306l.009.11v4.496a.75.75 0 0 1-.649.743L10.25 16H8.996v3.254a.75.75 0 0 1-1.492.101l-.007-.101L7.496 16 5.5 15.999v3.258a.75.75 0 0 1-1.493.101l-.006-.101L4 15.999 2.75 16a.75.75 0 0 1-.742-.648l-.007-.102v-4.496a.75.75 0 0 1 .071-.32l.055-.096 1.874-2.815V4.75a.75.75 0 0 1 1.493-.102l.007.102v3a.75.75 0 0 1-.072.32l-.054.096-1.874 2.815V14.5H9.5v-3.52L7.625 8.167a.75.75 0 0 1-.117-.306L7.5 7.75v-3A.75.75 0 0 1 8.25 4Zm7.004.001h4.496a.75.75 0 0 1 .743.649l.007.101L20.499 8h.75a.75.75 0 0 1 .744.648L22 8.75v4.496c0 .111-.025.22-.072.32l-.054.096L20 16.477v2.773a.75.75 0 0 1-1.494.102l-.006-.102v-3c0-.11.024-.22.071-.32l.054-.096L20.5 13.02V9.5h-5.998v3.52l1.874 2.814a.749.749 0 0 1 .118.306l.008.11v3a.75.75 0 0 1-1.493.102l-.007-.102v-2.773l-1.874-2.815a.75.75 0 0 1-.118-.306l-.008-.11V8.75a.75.75 0 0 1 .648-.743L13.752 8h.752V4.751a.75.75 0 0 1 .649-.743l.101-.007h4.496-4.496ZM19 5.501h-2.996V8h2.995V5.501Z" fill="#DDE6E8"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 16 KiB |
1
resources/exit.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2Zm0 1.5a8.5 8.5 0 1 0 0 17 8.5 8.5 0 0 0 0-17Zm3.446 4.897.084.073a.75.75 0 0 1 .073.976l-.073.084L13.061 12l2.47 2.47a.75.75 0 0 1 .072.976l-.073.084a.75.75 0 0 1-.976.073l-.084-.073L12 13.061l-2.47 2.47a.75.75 0 0 1-.976.072l-.084-.073a.75.75 0 0 1-.073-.976l.073-.084L10.939 12l-2.47-2.47a.75.75 0 0 1-.072-.976l.073-.084a.75.75 0 0 1 .976-.073l.084.073L12 10.939l2.47-2.47a.75.75 0 0 1 .976-.072Z" fill="#000000"/></svg>
|
||||||
|
After Width: | Height: | Size: 599 B |
1
resources/exit_red.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2Zm0 1.5a8.5 8.5 0 1 0 0 17 8.5 8.5 0 0 0 0-17Zm3.446 4.897.084.073a.75.75 0 0 1 .073.976l-.073.084L13.061 12l2.47 2.47a.75.75 0 0 1 .072.976l-.073.084a.75.75 0 0 1-.976.073l-.084-.073L12 13.061l-2.47 2.47a.75.75 0 0 1-.976.072l-.084-.073a.75.75 0 0 1-.073-.976l.073-.084L10.939 12l-2.47-2.47a.75.75 0 0 1-.072-.976l.073-.084a.75.75 0 0 1 .976-.073l.084.073L12 10.939l2.47-2.47a.75.75 0 0 1 .976-.072Z" fill="#FF0000"/></svg>
|
||||||
|
After Width: | Height: | Size: 599 B |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 514 KiB |
1
resources/sync.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="48" height="48" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M16 8.25a.75.75 0 0 1 1.5 0v3.25a.75.75 0 0 1-.75.75H14a.75.75 0 0 1 0-1.5h1.27A3.502 3.502 0 0 0 12 8.5c-1.093 0-2.037.464-2.673 1.23a.75.75 0 1 1-1.154-.96C9.096 7.66 10.463 7 12 7c1.636 0 3.088.785 4 2v-.75ZM8 15v.75a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 .75-.75H10a.75.75 0 0 1 0 1.5H8.837a3.513 3.513 0 0 0 5.842.765.75.75 0 1 1 1.142.972A5.013 5.013 0 0 1 8 15Zm4-13C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm8.5 10a8.5 8.5 0 1 1-17 0 8.5 8.5 0 0 1 17 0Z" fill="#000000"/></svg>
|
||||||
|
After Width: | Height: | Size: 609 B |
1
resources/sync_green.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="48" height="48" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M16 8.25a.75.75 0 0 1 1.5 0v3.25a.75.75 0 0 1-.75.75H14a.75.75 0 0 1 0-1.5h1.27A3.502 3.502 0 0 0 12 8.5c-1.093 0-2.037.464-2.673 1.23a.75.75 0 1 1-1.154-.96C9.096 7.66 10.463 7 12 7c1.636 0 3.088.785 4 2v-.75ZM8 15v.75a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 .75-.75H10a.75.75 0 0 1 0 1.5H8.837a3.513 3.513 0 0 0 5.842.765.75.75 0 1 1 1.142.972A5.013 5.013 0 0 1 8 15Zm4-13C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm8.5 10a8.5 8.5 0 1 1-17 0 8.5 8.5 0 0 1 17 0Z" fill="#00FF00"/></svg>
|
||||||
|
After Width: | Height: | Size: 609 B |
1
resources/sync_yellow.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="48" height="48" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M16 8.25a.75.75 0 0 1 1.5 0v3.25a.75.75 0 0 1-.75.75H14a.75.75 0 0 1 0-1.5h1.27A3.502 3.502 0 0 0 12 8.5c-1.093 0-2.037.464-2.673 1.23a.75.75 0 1 1-1.154-.96C9.096 7.66 10.463 7 12 7c1.636 0 3.088.785 4 2v-.75ZM8 15v.75a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 .75-.75H10a.75.75 0 0 1 0 1.5H8.837a3.513 3.513 0 0 0 5.842.765.75.75 0 1 1 1.142.972A5.013 5.013 0 0 1 8 15Zm4-13C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm8.5 10a8.5 8.5 0 1 1-17 0 8.5 8.5 0 0 1 17 0Z" fill="#F2C511"/></svg>
|
||||||
|
After Width: | Height: | Size: 609 B |