12#include <QtCore/QOperatingSystemVersion>
13#include <QtCore/QString>
15#include <QtGui/QGuiApplication>
51static inline QString statusLabelStyle(
const QString &bg =
"#6699ff",
52 const QString &fg =
"#000000") {
53#if defined(Q_OS_MACOS)
54 return QStringLiteral(
"QLabel{background-color: %1; color: %2; "
55 "border-radius: 6px; padding: 2px 8px; "
56 "border: 1px solid rgba(0,0,0,0.15)}")
58#elif defined(Q_OS_WIN)
59 return QStringLiteral(
"QLabel{background-color:%1; color:%2; "
60 "border-radius:4px; padding:0px 8px; "
61 "border:1px solid rgba(0,0,0,0.25)}")
64 return QStringLiteral(
"QLabel{background-color:%1; color:%2; "
65 "border-radius:1px; padding:1px 6px; "
66 "border:1px inset rgba(0,0,0,0.18)}")
71enum class TxStatusAppearance {
80static inline QString makeStyle(
const QString &bg,
const QString &fg) {
81#if defined(Q_OS_LINUX)
82 return QString(
"QLabel{background-color:%1; color:%2; "
83 "border-radius:1px; padding:1px 6px; "
84 "border:1px inset rgba(0,0,0,0.18);}")
86#elif defined(Q_OS_WIN)
87 return QString(
"QLabel{background-color:%1; color:%2; "
88 "border-radius:4px; padding:0px 8px; "
89 "border:1px solid rgba(0,0,0,0.25);}")
91#elif defined(Q_OS_MACOS)
92 return QString(
"QLabel{background-color:%1; color:%2; "
93 "border-radius:6px; padding:2px 8px; "
94 "border:1px solid rgba(0,0,0,0.15);}")
97 return QString(
"QLabel{background-color:%1; color:%2;}").arg(bg, fg);
102 switch (appearance) {
103 case TxStatusAppearance::Receiving:
104 return makeStyle(
"#22ff22",
"#000000");
105 case TxStatusAppearance::Transmitting:
106 return makeStyle(
"#ff2222",
"#000000");
107 case TxStatusAppearance::Decoding:
108 return makeStyle(
"#22ff22",
"#000000");
109 case TxStatusAppearance::IdleTimeout:
110 return makeStyle(
"#000000",
"#ffffff");
132static inline QString progress_bar_stylesheet(
bool small =
false) {
133 const QString base = QString(
"QProgressBar {"
135 " background-color: #ffffff;"
137 " text-align: center;"
141 "QProgressBar::chunk {"
142 " background-color: #a5cdff;"
143 " border-radius: %2px;"
147 const int height = small ? 10 : 14;
148 const int radius = small ? 3 : 5;
149 const QString barDim =
150 QString(
"min-height:%1px; max-height:%1px; border-radius:%2px;")
153 const QString chunkDim = QString(
"min-height:%1px;").arg(height);
154 return base.arg(barDim, QString::number(radius), chunkDim);
171 QPushButton, QToolButton {
172 background-color: #6699ff;
179 font-family: "Segoe UI";
181 QPushButton:hover, QToolButton:hover {
182 background-color: #4d7fff;
185 QPushButton:pressed, QToolButton:pressed {
186 background-color: #003EAA;
188 QPushButton:disabled, QToolButton:disabled {
189 background-color: #ececec;
192 QToolButton#replyPushButton::menu-button {
195 QToolButton#replyPushButton[popupMode="MenuButtonPopup"] {
198 QToolButton#replyPushButton[popupMode="MenuButtonPopup"][layoutDirection="RightToLeft"] {
204#elif defined(Q_OS_MACOS)
206 QPushButton, QToolButton {
207 background-color: #6699ff;
214 font-family: "-apple-system";
216 QPushButton:hover, QToolButton:hover {
217 background-color: #4d7fff;
220 QPushButton:pressed, QToolButton:pressed {
221 background-color: #003EAA;
223 QPushButton:disabled, QToolButton:disabled {
224 background-color: #ececec;
227 QToolButton#replyPushButton::menu-button {
230 QToolButton#replyPushButton[popupMode="MenuButtonPopup"] {
233 QToolButton#replyPushButton[popupMode="MenuButtonPopup"][layoutDirection="RightToLeft"] {
239#elif defined(Q_OS_LINUX)
241 QPushButton, QToolButton {
242 background-color: #6699ff;
247 font-family: "Ubuntu", "Noto Sans";
249 QPushButton:hover, QToolButton:hover {
250 background-color: #4d7fff;
252 QPushButton:pressed, QToolButton:pressed {
253 background-color: #003EAA;
255 QPushButton:disabled, QToolButton:disabled {
256 background-color: #ececec;
259 QToolButton#replyPushButton::menu-button {
262 QToolButton#replyPushButton[popupMode="MenuButtonPopup"] {
265 QToolButton#replyPushButton[popupMode="MenuButtonPopup"][layoutDirection="RightToLeft"] {
278static inline QString logFrameStyle() {
279#if defined(Q_OS_MACOS)
280 return QStringLiteral(
"QFrame#frame { background-color: #F2F2F0; }"
281 "QLabel#currentFreq {"
283 " background-color: black;"
284 " border-radius:6px; padding:0px 8px; "
285 " font-family: Monaco, 'Courier New', monospace;"
287 " font-weight: bold;"
291#elif defined(Q_OS_WIN)
292 return QStringLiteral(
"QFrame#frame { background-color: #DDEEFF; }"
293 "QLabel#currentFreq {"
295 " background-color: black;"
296 " border-radius:4px; padding:0px 8px; "
297 " font-family: Consolas, 'Courier New', monospace;"
299 " font-weight: bold;"
304 return QStringLiteral(
"QFrame#frame { background-color: #F2F2F0; }"
305 "QLabel#currentFreq {"
307 " background-color: black;"
308 " border-radius:0px; padding:0px 8px; "
310 " font-weight: bold;"
334#if defined(Q_OS_MACOS)
337constexpr const char *LogWidgetStyle =
338 "QFrame#logWidget { background-color: #F2F2F0; }";
340constexpr const char *DialFreqUpDownButtonStyle =
342 " background-color: #000000;"
346 " border-radius:2px;"
348 "QPushButton:pressed {"
349 " background-color: #222;"
355 auto *layout =
new QHBoxLayout(
this);
356 auto *caption =
new QLabel(
"Offset:",
this);
357 caption->setStyleSheet(
"QLabel { color: black; }");
358 slider =
new QSlider(Qt::Horizontal,
this);
360 slider->setStyleSheet(R
"(
362 background: transparent;
365 QSlider::groove:horizontal {
366 border: 1px solid #b0b0b0;
371 QSlider::handle:horizontal {
373 border: 1px solid #c2c8d1;
378 QSlider::sub-page:horizontal {
382 QSlider::add-page:horizontal {
387 slider->setRange(0, 3000);
388 slider->setValue(1500);
389 valueLabel = new QLabel(
"0 Hz",
this);
390 valueLabel->setStyleSheet(
"QLabel { color: black; }");
391 valueLabel->setMinimumWidth(60);
392 layout->addWidget(caption);
393 layout->addWidget(slider, 1);
394 layout->addWidget(valueLabel);
395 connect(slider, &QSlider::valueChanged,
this, [
this](
int val) {
396 valueLabel->setText(QString(
"%1 Hz").arg(val));
397 if (onValueChanged) onValueChanged(val);
401 int offset()
const {
return slider->value(); }
402 void setValue(
int hz) { slider->setValue(hz); }
403 void setOnValueChanged(std::function<
void(
int)> cb) { onValueChanged = cb; }
408 std::function<void(
int)> onValueChanged;
411constexpr const char *LabCallsignStyle =
"QLabel {"
417constexpr const char *LabUTCStyle =
419 " border-radius:6px;"
422 " font-family: Monaco, 'Courier New', monospace;"
423 " font-weight: bold;"
424 " background-color: black;"
428constexpr const char *ButtonGridStyle =
430 " background-color:lightgray;"
431 " padding:0.25em 0.25em; font-weight:normal;"
432 " border-style:solid;"
434 " border-radius:6px;"
436 "QPushButton:checked {"
437 " background-color:#6699ff;"
440constexpr const char *MonitorTxButtonStyle =
442 " background-color:lightgray;"
444 " padding:0.25em 0.25em; font-weight:normal;"
445 " border-style:solid;"
447 " border-radius:6px;"
449 "QPushButton:checked {"
450 " background-color:#22FF22;"
453 "QPushButton[transmitting=\"true\"] {"
454 " background-color:#FF2222;"
458constexpr const char *MonitorButtonStyle =
460 " background-color:lightgray;"
462 " padding:0.25em 0.25em; font-weight:normal;"
463 " border-style:solid;"
465 " border-radius:6px;"
467 "QPushButton:checked {"
468 " background-color:#22FF22;"
472constexpr const char *LogQSOButtonStyle =
474 " background-color:#6699ff;"
476 " padding:0.25em 0.25em; font-weight:normal;"
477 " border-style:solid;"
479 " border-radius:6px;"
481 "QPushButton:checked {"
482 " background-color:#6699ff;"
486constexpr const char *TuneButtonStyle =
488 " background-color:lightgray;"
490 " padding:0.25em 0.25em; font-weight:normal;"
491 " border-style:solid;"
493 " border-radius:6px;"
495 "QPushButton:checked {"
496 " background-color:#6699ff;"
500constexpr const char *ModeButtonStyle =
502 " padding:0.25em 0.25em; font-weight:bold;"
503 " border-style:solid;"
505 " border-radius:6px;"
506 " background-color:#6699ff;"
509 "QPushButton:checked {"
510 " background-color:#6699ff;"
514constexpr const char *SpotButtonStyle =
516 " background-color:lightgray;"
518 " padding:0.25em 0.25em; font-weight:normal;"
519 " border-style:solid;"
521 " border-radius:6px;"
523 "QPushButton:checked {"
524 " background-color:#6699ff;"
529#elif defined(Q_OS_WIN)
532constexpr const char *LogWidgetStyle =
533 "QFrame#logWidget { background-color: #DDEEFF; }";
535constexpr const char *DialFreqUpDownButtonStyle =
537 " background-color: #000000;"
541 " border-radius:2px;"
543 "QPushButton:pressed {"
544 " background-color: #222;"
547class OffsetSliderWidget :
public QWidget {
549 explicit OffsetSliderWidget(QWidget *parent =
nullptr) : QWidget(parent) {
550 auto *layout =
new QHBoxLayout(
this);
551 auto *caption =
new QLabel(
"Offset:",
this);
552 caption->setStyleSheet(
"QLabel { color: black; }");
553 slider =
new QSlider(Qt::Horizontal,
this);
555 slider->setStyleSheet(R
"(
557 background: transparent;
560 QSlider::groove:horizontal {
561 border: 1px solid #b0b0b0;
566 QSlider::handle:horizontal {
568 border: 1px solid #c2c8d1;
573 QSlider::sub-page:horizontal {
577 QSlider::add-page:horizontal {
582 slider->setRange(0, 3000);
583 slider->setValue(1500);
584 valueLabel = new QLabel(
"0 Hz",
this);
585 valueLabel->setStyleSheet(
"QLabel { color: black; }");
586 valueLabel->setMinimumWidth(60);
587 layout->addWidget(caption);
588 layout->addWidget(slider, 1);
589 layout->addWidget(valueLabel);
590 connect(slider, &QSlider::valueChanged,
this, [
this](
int val) {
591 valueLabel->setText(QString(
"%1 Hz").arg(val));
592 if (onValueChanged) onValueChanged(val);
596 int offset()
const {
return slider->value(); }
597 void setValue(
int hz) { slider->setValue(hz); }
598 void setOnValueChanged(std::function<
void(
int)> cb) { onValueChanged = cb; }
603 std::function<void(
int)> onValueChanged;
606constexpr const char *LabCallsignStyle =
"QLabel {"
612constexpr const char *LabUTCStyle =
614 " border-radius:4px;"
617 " font-family: Consolas, 'Courier New', monospace;"
618 " font-weight: bold;"
619 " background-color: black;"
623constexpr const char *ButtonGridStyle =
625 " background-color:lightgray;"
626 " padding:0.25em 0.25em; font-weight:normal;"
627 " border-style:solid;"
629 " border-radius:4px;"
631 "QPushButton:checked {"
632 " background-color:#6699ff;"
635constexpr const char *MonitorTxButtonStyle =
637 " background-color:lightgray;"
639 " padding:0.25em 0.25em; font-weight:normal;"
640 " border-style:solid;"
642 " border-radius:4px;"
644 "QPushButton:checked {"
645 " background-color:#22FF22;"
648 "QPushButton[transmitting=\"true\"] {"
649 " background-color:#FF2222;"
653constexpr const char *MonitorButtonStyle =
655 " background-color:lightgray;"
657 " padding:0.25em 0.25em; font-weight:normal;"
658 " border-style:solid;"
660 " border-radius:4px;"
662 "QPushButton:checked {"
663 " background-color:#22FF22;"
667constexpr const char *LogQSOButtonStyle =
669 " background-color:lightgray;"
671 " padding:0.25em 0.25em; font-weight:normal;"
672 " border-style:solid;"
674 " border-radius:4px;"
676 "QPushButton:checked {"
677 " background-color:#6699ff;"
681constexpr const char *TuneButtonStyle = LogQSOButtonStyle;
683constexpr const char *ModeButtonStyle =
685 " padding:0.25em 0.25em; font-weight:bold;"
686 " border-style:solid;"
688 " border-radius:4px;"
689 " background-color:#6699ff;"
692 "QPushButton:checked {"
693 " background-color:#6699ff;"
697constexpr const char *SpotButtonStyle =
699 " background-color:lightgray;"
701 " padding:0.25em 0.25em; font-weight:normal;"
702 " border-style:solid;"
704 " border-radius:4px;"
706 "QPushButton:checked {"
707 " background-color:#6699ff;"
716constexpr const char *LogWidgetStyle =
717 "QFrame#logWidget { background-color: #F2F2F0; }";
720constexpr const char *DialFreqUpDownButtonStyle =
722 " background-color: #000000;"
726 " border-radius:0px;"
728 "QPushButton:pressed {"
729 " background-color: #222;"
732class OffsetSliderWidget :
public QWidget {
734 explicit OffsetSliderWidget(QWidget *parent =
nullptr) : QWidget(parent) {
735 auto *layout =
new QHBoxLayout(
this);
736 auto *caption =
new QLabel(
"Offset:",
this);
737 caption->setStyleSheet(
"QLabel { color: black; }");
738 slider =
new QSlider(Qt::Horizontal,
this);
740 slider->setStyleSheet(R
"(
742 background: transparent;
745 QSlider::groove:horizontal {
746 border: 1px solid #b0b0b0;
751 QSlider::handle:horizontal {
753 border: 1px solid #c2c8d1;
758 QSlider::sub-page:horizontal {
762 QSlider::add-page:horizontal {
767 slider->setRange(0, 3000);
768 slider->setValue(1500);
769 valueLabel = new QLabel(
"0 Hz",
this);
770 valueLabel->setStyleSheet(
"QLabel { color: black; }");
771 valueLabel->setMinimumWidth(60);
772 layout->addWidget(caption);
773 layout->addWidget(slider, 1);
774 layout->addWidget(valueLabel);
775 connect(slider, &QSlider::valueChanged,
this, [
this](
int val) {
776 valueLabel->setText(QString(
"%1 Hz").arg(val));
777 if (onValueChanged) onValueChanged(val);
781 int offset()
const {
return slider->value(); }
782 void setValue(
int hz) { slider->setValue(hz); }
783 void setOnValueChanged(std::function<
void(
int)> cb) { onValueChanged = cb; }
788 std::function<void(
int)> onValueChanged;
792constexpr const char *LabCallsignStyle =
"QLabel {"
799constexpr const char *LabUTCStyle =
801 " border-radius:0px;"
804 " font-family: \"DejaVu Sans Mono\", \"Liberation Mono\", \"Noto Mono\", \"Ubuntu Mono\", monospace;"
805 " font-weight: bold;"
806 " background-color: black;"
811constexpr const char *ButtonGridStyle =
813 " background-color:lightgray;"
814 " padding:0.25em 0.25em; font-weight:normal;"
815 " border-style:solid;"
817 " border-radius:0px;"
819 "QPushButton:checked {"
820 " background-color:#6699ff;"
824constexpr const char *MonitorTxButtonStyle =
826 " background-color:lightgray;"
827 " padding:0.25em 0.25em; font-weight:normal;"
828 " border-style:solid;"
830 " border-radius:0px;"
832 "QPushButton:checked {"
833 " background-color:#22FF22;"
835 "QPushButton[transmitting=\"true\"] {"
836 " background-color:#FF2222;"
840constexpr const char *MonitorButtonStyle =
842 " background-color:lightgray;"
843 " padding:0.25em 0.25em; font-weight:normal;"
844 " border-style:solid;"
846 " border-radius:0px;"
848 "QPushButton:checked {"
849 " background-color:#22FF22;"
853constexpr const char *LogQSOButtonStyle =
855 " background-color:lightgray;"
856 " padding:0.25em 0.25em; font-weight:normal;"
857 " border-style:solid;"
859 " border-radius:0px;"
861 "QPushButton:checked {"
862 " background-color:#6699ff;"
865constexpr const char *TuneButtonStyle = LogQSOButtonStyle;
868constexpr const char *ModeButtonStyle =
870 " padding:0.25em 0.25em; font-weight:bold;"
871 " border-style:solid;"
873 " border-radius:0px;"
874 " background-color:#6699ff;"
876 "QPushButton:checked {"
877 " background-color:#6699ff;"
881constexpr const char *SpotButtonStyle =
883 " background-color:lightgray;"
884 " padding:0.25em 0.25em; font-weight:normal;"
885 " border-style:solid;"
887 " border-radius:0px;"
889 "QPushButton:checked {"
890 " background-color:#6699ff;"
Defines platform-specific style constants for JS8Call's header bar controls.
QString buttonStyle()
Returns a platform-native QPushButton/QToolButton stylesheet.
Definition styles.h:168
QString txStatusLabelStyle(TxStatusAppearance appearance)
Returns the QSS stylesheet string for a given TX status state.
Definition styles.h:101