settings and render for setUseColorsByCanId
This commit is contained in:
+38
-17
@@ -3,6 +3,8 @@
|
||||
#include <QFile>
|
||||
#include <QApplication>
|
||||
#include <QPalette>
|
||||
#include <QColor>
|
||||
#include <QBrush>
|
||||
#include <QDateTime>
|
||||
#include <QSettings>
|
||||
#include "utility.h"
|
||||
@@ -76,6 +78,7 @@ CANFrameModel::CANFrameModel(QObject *parent)
|
||||
overwriteDups = false;
|
||||
filtersPersistDuringClear = false;
|
||||
useHexMode = true;
|
||||
useColorsByCanId = false;
|
||||
timeStyle = TS_MICROS;
|
||||
timeOffset = 0;
|
||||
needFilterRefresh = false;
|
||||
@@ -101,6 +104,16 @@ void CANFrameModel::setHexMode(bool mode)
|
||||
}
|
||||
}
|
||||
|
||||
void CANFrameModel::setUseColorsByCanId(bool mode)
|
||||
{
|
||||
if (useColorsByCanId != mode)
|
||||
{
|
||||
this->beginResetModel();
|
||||
useColorsByCanId = mode;
|
||||
this->endResetModel();
|
||||
}
|
||||
}
|
||||
|
||||
void CANFrameModel::setTimeStyle(TimeStyle newStyle)
|
||||
{
|
||||
if (timeStyle != newStyle)
|
||||
@@ -401,7 +414,6 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
QString tempString;
|
||||
CANFrame thisFrame;
|
||||
static bool rowFlip = false;
|
||||
QVariant ts;
|
||||
|
||||
if (!index.isValid())
|
||||
@@ -425,9 +437,31 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
|
||||
return msg->bgColor;
|
||||
}
|
||||
}
|
||||
rowFlip = (index.row() % 2);
|
||||
if (rowFlip) return QApplication::palette().color(QPalette::Base);
|
||||
else return QApplication::palette().color(QPalette::AlternateBase);
|
||||
|
||||
if (useColorsByCanId)
|
||||
{
|
||||
QString frameStr = Utility::formatCANID(thisFrame.frameId(), thisFrame.hasExtendedFrameFormat());
|
||||
// Color rows by the value in the "category" column
|
||||
return QBrush(Utility::colorForString(frameStr));
|
||||
}
|
||||
|
||||
return (index.row() % 2) ?
|
||||
QApplication::palette().color(QPalette::Base) :
|
||||
QApplication::palette().color(QPalette::AlternateBase);
|
||||
}
|
||||
|
||||
if (role == Qt::ForegroundRole)
|
||||
{
|
||||
if (dbcHandler != nullptr && interpretFrames && !ignoreDBCColors)
|
||||
{
|
||||
DBC_MESSAGE *msg = dbcHandler->findMessage(thisFrame);
|
||||
if (msg != nullptr)
|
||||
{
|
||||
return msg->fgColor;
|
||||
}
|
||||
}
|
||||
|
||||
return QApplication::palette().color(QPalette::WindowText);
|
||||
}
|
||||
|
||||
if (role == Qt::TextAlignmentRole)
|
||||
@@ -448,19 +482,6 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
}
|
||||
|
||||
if (role == Qt::ForegroundRole)
|
||||
{
|
||||
if (dbcHandler != nullptr && interpretFrames && !ignoreDBCColors)
|
||||
{
|
||||
DBC_MESSAGE *msg = dbcHandler->findMessage(thisFrame);
|
||||
if (msg != nullptr)
|
||||
{
|
||||
return msg->fgColor;
|
||||
}
|
||||
}
|
||||
return QApplication::palette().color(QPalette::WindowText);
|
||||
}
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch (Column(index.column()))
|
||||
{
|
||||
|
||||
@@ -47,6 +47,7 @@ public:
|
||||
bool getInterpretMode();
|
||||
void setOverwriteMode(bool);
|
||||
void setHexMode(bool);
|
||||
void setUseColorsByCanId(bool);
|
||||
void setClearMode(bool mode);
|
||||
void setTimeStyle(TimeStyle newStyle);
|
||||
void setIgnoreDBCColors(bool mode);
|
||||
@@ -94,6 +95,7 @@ private:
|
||||
QString timeFormat;
|
||||
TimeStyle timeStyle;
|
||||
bool useHexMode;
|
||||
bool useColorsByCanId;
|
||||
bool needFilterRefresh;
|
||||
bool ignoreDBCColors;
|
||||
int64_t timeOffset;
|
||||
|
||||
@@ -90,7 +90,9 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
|
||||
ui->cbUseFiltered->setChecked(settings.value("Main/UseFiltered", false).toBool());
|
||||
ui->cbUseOpenGL->setChecked(settings.value("Main/UseOpenGL", false).toBool());
|
||||
ui->cbFilterLabeling->setChecked(settings.value("Main/FilterLabeling", true).toBool());
|
||||
ui->cbFilterLabeling->setChecked(settings.value("Main/FilterLabeling", true).toBool());
|
||||
ui->cbIgnoreDBCColors->setChecked(settings.value("Main/IgnoreDBCColors", false).toBool());
|
||||
ui->cbColorsByCanId->setChecked(settings.value("Main/ColorsByCanId", false).toBool());
|
||||
|
||||
int maxFramesDefault;
|
||||
if (QSysInfo::WordSize > 32)
|
||||
@@ -208,6 +210,7 @@ void MainSettingsDialog::updateSettings()
|
||||
settings.setValue("Main/MaximumFrames", ui->spinMaximumFrames->value());
|
||||
settings.setValue("Main/BytesPerLine", ui->spinBytesPerLine->value());
|
||||
settings.setValue("Main/FontFixedWidth", ui->cbFontFixedWidth->isChecked());
|
||||
settings.setValue("Main/ColorsByCanId", ui->cbColorsByCanId->isChecked());
|
||||
|
||||
settings.sync();
|
||||
emit updatedSettings();
|
||||
|
||||
+4
-1
@@ -36,7 +36,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
#endif
|
||||
|
||||
useHex = true;
|
||||
|
||||
useColorsByCanId = false;
|
||||
selfRef = this;
|
||||
|
||||
this->setWindowTitle("Savvy CAN V" + QString::number(VERSION) + " [Built " + QString(__DATE__) +"]");
|
||||
@@ -415,6 +415,9 @@ void MainWindow::readUpdateableSettings()
|
||||
model->setHexMode(useHex);
|
||||
Utility::decimalMode = !useHex;
|
||||
|
||||
useColorsByCanId = settings.value("Main/ColorsByCanId", false).toBool();
|
||||
model->setUseColorsByCanId(useColorsByCanId);
|
||||
|
||||
bool tempBool;
|
||||
TimeStyle ts = TS_MICROS;
|
||||
tempBool = settings.value("Main/TimeSeconds", false).toBool();
|
||||
|
||||
@@ -160,6 +160,7 @@ private:
|
||||
int rxFrames;
|
||||
bool inhibitFilterUpdate;
|
||||
bool useHex;
|
||||
bool useColorsByCanId;
|
||||
bool allowCapture;
|
||||
bool ignoreDBCColors;
|
||||
bool CSVAbsTime;
|
||||
|
||||
@@ -97,6 +97,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbColorsByCanId">
|
||||
<property name="text">
|
||||
<string>Color rows by CAN ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbUseOpenGL">
|
||||
<property name="text">
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <QRect>
|
||||
#include <QComboBox>
|
||||
#include <QStandardItemModel>
|
||||
#include <QColor>
|
||||
#include <QString>
|
||||
//#include <QDesktopWidget>
|
||||
|
||||
enum TimeStyle
|
||||
@@ -20,6 +22,44 @@ enum TimeStyle
|
||||
TS_CLOCK
|
||||
};
|
||||
|
||||
|
||||
// 32 dark, saturated colors — all designed for readability on white backgrounds.
|
||||
// Minimum contrast ratio ≥ 4.5:1 against white (WCAG AA).
|
||||
static constexpr std::array<QRgb, 32> kRowPalette = {{
|
||||
0xFFC62828, // 0 Red 800
|
||||
0xFFE53935, // 1 Red 600
|
||||
0xFFD84315, // 2 Deep Orange 800
|
||||
0xFFEF6C00, // 3 Orange 800
|
||||
0xFFF9A825, // 4 Amber 800
|
||||
0xFF558B2F, // 5 Green 800
|
||||
0xFF2E7D32, // 6 Green 900
|
||||
0xFF00695C, // 7 Teal 800
|
||||
0xFF00838F, // 8 Cyan 800
|
||||
0xFF0277BD, // 9 Blue 800
|
||||
0xFF1565C0, // 10 Blue 900
|
||||
0xFF283593, // 11 Indigo 900
|
||||
0xFF4527A0, // 12 Deep Purple 800
|
||||
0xFF6A1B9A, // 13 Purple 900
|
||||
0xFF880E4F, // 14 Pink 900
|
||||
0xFFAD1457, // 15 Pink 800
|
||||
0xFF37474F, // 16 Blue Grey 800
|
||||
0xFF4E342E, // 17 Brown 800
|
||||
0xFF827717, // 18 Lime 900
|
||||
0xFF1B5E20, // 19 Green 900 alt
|
||||
0xFF006064, // 20 Cyan 900
|
||||
0xFF01579B, // 21 Light Blue 900
|
||||
0xFF0D47A1, // 22 Blue 900 alt
|
||||
0xFF311B92, // 23 Deep Purple 900
|
||||
0xFF4A148C, // 24 Purple 900 alt
|
||||
0xFFB71C1C, // 25 Red 900
|
||||
0xFFBF360C, // 26 Deep Orange 900
|
||||
0xFFE65100, // 27 Orange 900
|
||||
0xFF33691E, // 28 Light Green 900
|
||||
0xFF004D40, // 29 Teal 900
|
||||
0xFF263238, // 30 Blue Grey 900
|
||||
0xFF5D4037, // 31 Brown 700
|
||||
}};
|
||||
|
||||
class Utility
|
||||
{
|
||||
public:
|
||||
@@ -344,6 +384,35 @@ public:
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FNV-1a 32-bit hash — fast, good distribution, no dependencies.
|
||||
static quint32 hashString(const QString &s)
|
||||
{
|
||||
quint32 hash = 2166136261u;
|
||||
for (const QChar ch : s) {
|
||||
hash ^= static_cast<quint32>(ch.unicode());
|
||||
hash *= 16777619u;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
// Returns a background QColor deterministically chosen from the palette.
|
||||
// The same string always maps to the same color.
|
||||
static QColor colorForString(const QString &s)
|
||||
{
|
||||
const quint32 idx = hashString(s) % static_cast<quint32>(kRowPalette.size());
|
||||
// Use a light tint (alpha ~18%) as the row background so text stays readable.
|
||||
QColor base(kRowPalette[idx]);
|
||||
base.setAlpha(46); // ~18% — comfortable on white, still clearly tinted
|
||||
return base;
|
||||
}
|
||||
|
||||
// Opaque variant — useful for badges, tags, or legend swatches.
|
||||
static QColor solidColorForString(const QString &s)
|
||||
{
|
||||
const quint32 idx = hashString(s) % static_cast<quint32>(kRowPalette.size());
|
||||
return QColor(kRowPalette[idx]);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // UTILITY_H
|
||||
|
||||
Reference in New Issue
Block a user