JS8Call-Improved master
Loading...
Searching...
No Matches
styles.h
Go to the documentation of this file.
1
10
11#pragma once
12#include <QtCore/QOperatingSystemVersion>
13#include <QtCore/QString>
14#include <QtGlobal>
15#include <QtGui/QGuiApplication>
16#include <QHBoxLayout>
17#include <QSlider>
18#include <QLabel>
19#include <QWidget>
20
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)}")
57 .arg(bg, fg);
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)}")
62 .arg(bg, fg);
63#else // Linux/other
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)}")
67 .arg(bg, fg);
68#endif
69}
70
71enum class TxStatusAppearance {
72 Receiving, // green on black text
73 Transmitting, // red
74 Decoding, // same as Receiving
75 IdleTimeout // black bg, white fg
76};
77
78QString txStatusLabelStyle(TxStatusAppearance appearance);
79
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);}")
85 .arg(bg, fg);
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);}")
90 .arg(bg, fg);
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);}")
95 .arg(bg, fg);
96#else
97 return QString("QLabel{background-color:%1; color:%2;}").arg(bg, fg);
98#endif
99}
100
101inline QString txStatusLabelStyle(TxStatusAppearance appearance) {
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");
111 default:
112 return QString(); // no style for compiler fallback
113 }
114}
115
132static inline QString progress_bar_stylesheet(bool small = false) {
133 const QString base = QString("QProgressBar {"
134 " border: 0px;"
135 " background-color: #ffffff;"
136 " color: #000000;"
137 " text-align: center;"
138 " padding: 0px;"
139 " %1"
140 "}"
141 "QProgressBar::chunk {"
142 " background-color: #a5cdff;"
143 " border-radius: %2px;"
144 " %3"
145 "}");
146
147 const int height = small ? 10 : 14; // overall control height
148 const int radius = small ? 3 : 5; // roundness of the bar ends
149 const QString barDim =
150 QString("min-height:%1px; max-height:%1px; border-radius:%2px;")
151 .arg(height)
152 .arg(radius);
153 const QString chunkDim = QString("min-height:%1px;").arg(height);
154 return base.arg(barDim, QString::number(radius), chunkDim);
155}
156
179inline QString buttonStyle() {
180#if defined(Q_OS_WIN)
181 return R"(
182 QPushButton {
183 background-color: #6699ff;
184 color: black;
185 border: none;
186 border-radius: 4px;
187 padding: 3px 9px;
188 min-height: 15px;
189 max-height: 15px;
190 font-family: "Segoe UI";
191 }
192 QPushButton:hover {
193 background-color: #4d7fff;
194 color: white;
195 }
196 QPushButton:pressed {
197 background-color: #003EAA;
198 }
199 QPushButton:disabled {
200 background-color: #ececec;
201 color: #888888;
202 }
203 )";
204
205#elif defined(Q_OS_MACOS)
206 return R"(
207 QPushButton {
208 background-color: #6699ff;
209 color: black;
210 border: none;
211 border-radius: 6px;
212 padding: 3px 9px;
213 min-height: 15px;
214 max-height: 15px;
215 font-family: "-apple-system";
216 }
217 QPushButton:hover {
218 background-color: #4d7fff;
219 color: white;
220 }
221 QPushButton:pressed {
222 background-color: #003EAA;
223 }
224 QPushButton:disabled {
225 background-color: #ececec;
226 color: #888888;
227 }
228 )";
229
230#elif defined(Q_OS_LINUX)
231 return R"(
232 QPushButton {
233 background-color: #6699ff;
234 color: black;
235 border: none;
236 border-radius: 5px;
237 padding: px 9px;
238 font-family: "Ubuntu", "Noto Sans";
239 }
240 QPushButton:hover {
241 background-color: #4d7fff;
242 }
243 QPushButton:pressed {
244 background-color: #003EAA;
245 }
246 QPushButton:disabled {
247 background-color: #ececec;
248 color: #888888;
249 }
250 )";
251
252#else
253 return QString();
254#endif
255}
256
257// defines the background, color, font and size of the header bar frequency
258// display, the #else section contains the definitions for linux
259static inline QString logFrameStyle() {
260#if defined(Q_OS_MACOS)
261 return QStringLiteral("QFrame#frame { background-color: #F2F2F0; }"
262 "QLabel#currentFreq {"
263 " color: #39FF14;"
264 " background-color: black;"
265 " border-radius:6px; padding:0px 8px; "
266 " font-family: Monaco, 'Courier New', monospace;"
267 " font-size: 20pt;"
268 " font-weight: bold;"
269 " min-width: 200px;"
270 " min-height: 40px;"
271 "}");
272#elif defined(Q_OS_WIN)
273 return QStringLiteral("QFrame#frame { background-color: #DDEEFF; }"
274 "QLabel#currentFreq {"
275 " color: #39FF14;"
276 " background-color: black;"
277 " border-radius:4px; padding:0px 8px; "
278 " font-family: Consolas, 'Courier New', monospace;"
279 " font-size: 20pt;"
280 " font-weight: bold;"
281 " min-width: 200px;"
282 " min-height: 40px;"
283 "}");
284#else
285 return QStringLiteral("QFrame#frame { background-color: #F2F2F0; }"
286 "QLabel#currentFreq {"
287 " color: #39FF14;"
288 " background-color: black;"
289 " border-radius:0px; padding:0px 8px; "
290 " font-size: 28pt;"
291 " font-weight: bold;"
292 " min-width: 200px;"
293 " min-height: 40px;"
294 "}");
295#endif
296}
297
315#if defined(Q_OS_MACOS)
316namespace Styles {
317
318constexpr const char *LogWidgetStyle =
319 "QFrame#logWidget { background-color: #F2F2F0; }";
320
321constexpr const char *DialFreqUpDownButtonStyle =
322 "QPushButton {"
323 " background-color: #000000;"
324 " color: #39FF14;"
325 " font-size: 10pt;"
326 " border:0px solid;"
327 " border-radius:2px;"
328 "}"
329 "QPushButton:pressed {"
330 " background-color: #222;"
331 "}";
332
333class OffsetSliderWidget : public QWidget {
334 public:
335 explicit OffsetSliderWidget(QWidget *parent = nullptr) : QWidget(parent) {
336 auto *layout = new QHBoxLayout(this);
337 auto *caption = new QLabel("Offset:", this);
338 caption->setStyleSheet("QLabel { color: black; }");
339 slider = new QSlider(Qt::Horizontal, this);
340 // Lock the QSlider's appearance regardless of the system theme
341 slider->setStyleSheet(R"(
342 QSlider {
343 background: transparent;
344 min-height: 24px;
345 }
346 QSlider::groove:horizontal {
347 border: 1px solid #b0b0b0;
348 height: 6px;
349 background: #e0e0e0;
350 border-radius: 3px;
351 }
352 QSlider::handle:horizontal {
353 background: #6699ff;
354 border: 1px solid #003eaa;
355 width: 16px;
356 margin: -6px 0;
357 border-radius: 8px;
358 }
359 QSlider::sub-page:horizontal {
360 background: #a5cdff;
361 border-radius: 3px;
362 }
363 QSlider::add-page:horizontal {
364 background: #e0e0e0;
365 border-radius: 3px;
366 }
367 )");
368 slider->setRange(0, 3000);
369 slider->setValue(1500);
370 valueLabel = new QLabel("0 Hz", this);
371 valueLabel->setStyleSheet("QLabel { color: black; }");
372 valueLabel->setMinimumWidth(60);
373 layout->addWidget(caption);
374 layout->addWidget(slider, 1);
375 layout->addWidget(valueLabel);
376 connect(slider, &QSlider::valueChanged, this, [this](int val) {
377 valueLabel->setText(QString("%1 Hz").arg(val));
378 if (onValueChanged) onValueChanged(val);
379 });
380 }
381
382 int offset() const { return slider->value(); }
383 void setValue(int hz) { slider->setValue(hz); }
384 void setOnValueChanged(std::function<void(int)> cb) { onValueChanged = cb; }
385
386 private:
387 QSlider *slider;
388 QLabel *valueLabel;
389 std::function<void(int)> onValueChanged;
390};
391
392constexpr const char *LabCallsignStyle = "QLabel {"
393 " font-size: 12pt;"
394 " line-height:12pt;"
395 " color : black;"
396 "}";
397
398constexpr const char *LabUTCStyle =
399 "QLabel {"
400 " border-radius:6px;"
401 " font-size: 14pt;"
402 " line-height:14pt;"
403 " font-family: Monaco, 'Courier New', monospace;"
404 " font-weight: bold;"
405 " background-color: black;"
406 " color : #39FF14;"
407 "}";
408
409constexpr const char *ButtonGridStyle =
410 "QPushButton {"
411 " background-color:lightgray;"
412 " padding:0.25em 0.25em; font-weight:normal;"
413 " border-style:solid;"
414 " border-width:0px;"
415 " border-radius:6px;"
416 "}"
417 "QPushButton:checked {"
418 " background-color:#6699ff;"
419 "}";
420
421constexpr const char *MonitorTxButtonStyle =
422 "QPushButton {"
423 " background-color:lightgray;"
424 " color:black;"
425 " padding:0.25em 0.25em; font-weight:normal;"
426 " border-style:solid;"
427 " border-width:0px;"
428 " border-radius:6px;"
429 "}"
430 "QPushButton:checked {"
431 " background-color:#22FF22;"
432 " color:black;"
433 "}"
434 "QPushButton[transmitting=\"true\"] {"
435 " background-color:#FF2222;"
436 " color:black;"
437 "}";
438
439constexpr const char *MonitorButtonStyle =
440 "QPushButton {"
441 " background-color:lightgray;"
442 " color:black;"
443 " padding:0.25em 0.25em; font-weight:normal;"
444 " border-style:solid;"
445 " border-width:0px;"
446 " border-radius:6px;"
447 "}"
448 "QPushButton:checked {"
449 " background-color:#22FF22;"
450 " color:black;"
451 "}";
452
453constexpr const char *LogQSOButtonStyle =
454 "QPushButton {"
455 " background-color:#6699ff;"
456 " color:black;"
457 " padding:0.25em 0.25em; font-weight:normal;"
458 " border-style:solid;"
459 " border-width:0px;"
460 " border-radius:6px;"
461 "}"
462 "QPushButton:checked {"
463 " background-color:#6699ff;"
464 " color:black;"
465 "}";
466
467constexpr const char *TuneButtonStyle =
468 "QPushButton {"
469 " background-color:lightgray;"
470 " color:black;"
471 " padding:0.25em 0.25em; font-weight:normal;"
472 " border-style:solid;"
473 " border-width:0px;"
474 " border-radius:6px;"
475 "}"
476 "QPushButton:checked {"
477 " background-color:#6699ff;"
478 " color:black;"
479 "}";
480
481constexpr const char *ModeButtonStyle =
482 "QPushButton {"
483 " padding:0.25em 0.25em; font-weight:bold;"
484 " border-style:solid;"
485 " border-width:0px;"
486 " border-radius:6px;"
487 " background-color:#6699ff;"
488 " color:black;"
489 "}"
490 "QPushButton:checked {"
491 " background-color:#6699ff;"
492 " color:black;"
493 "}";
494
495constexpr const char *SpotButtonStyle =
496 "QPushButton {"
497 " background-color:lightgray;"
498 " color:black;"
499 " padding:0.25em 0.25em; font-weight:normal;"
500 " border-style:solid;"
501 " border-width:0px;"
502 " border-radius:6px;"
503 "}"
504 "QPushButton:checked {"
505 " background-color:#6699ff;"
506 " color:black;"
507 "}";
508
509}
510#elif defined(Q_OS_WIN)
511namespace Styles {
512
513constexpr const char *LogWidgetStyle =
514 "QFrame#logWidget { background-color: #DDEEFF; }";
515
516constexpr const char *DialFreqUpDownButtonStyle =
517 "QPushButton {"
518 " background-color: #000000;"
519 " color: #39FF14;"
520 " font-size: 12pt;"
521 " border:0px solid;"
522 " border-radius:2px;"
523 "}"
524 "QPushButton:pressed {"
525 " background-color: #222;"
526 "}";
527
528constexpr const char *LabDialFreqOffsetStyle = "QLabel {"
529 " font-size: 12pt;"
530 " line-height:12pt;"
531 " color : black;"
532 "}";
533
534constexpr const char *LabCallsignStyle = "QLabel {"
535 " font-size: 12pt;"
536 " line-height:12pt;"
537 " color : black;"
538 "}";
539
540constexpr const char *LabUTCStyle =
541 "QLabel {"
542 " border-radius:4px;"
543 " font-size: 14pt;"
544 " line-height:14pt;"
545 " font-family: Consolas, 'Courier New', monospace;"
546 " font-weight: bold;"
547 " background-color: black;"
548 " color : #39FF14;"
549 "}";
550
551constexpr const char *ButtonGridStyle =
552 "QPushButton {"
553 " background-color:lightgray;"
554 " padding:0.25em 0.25em; font-weight:normal;"
555 " border-style:solid;"
556 " border-width:0px;"
557 " border-radius:4px;"
558 "}"
559 "QPushButton:checked {"
560 " background-color:#6699ff;"
561 "}";
562
563constexpr const char *MonitorTxButtonStyle =
564 "QPushButton {"
565 " background-color:lightgray;"
566 " color:black;"
567 " padding:0.25em 0.25em; font-weight:normal;"
568 " border-style:solid;"
569 " border-width:0px;"
570 " border-radius:4px;"
571 "}"
572 "QPushButton:checked {"
573 " background-color:#22FF22;"
574 " color:black;"
575 "}"
576 "QPushButton[transmitting=\"true\"] {"
577 " background-color:#FF2222;"
578 " color:black;"
579 "}";
580
581constexpr const char *MonitorButtonStyle =
582 "QPushButton {"
583 " background-color:lightgray;"
584 " color:black;"
585 " padding:0.25em 0.25em; font-weight:normal;"
586 " border-style:solid;"
587 " border-width:0px;"
588 " border-radius:4px;"
589 "}"
590 "QPushButton:checked {"
591 " background-color:#22FF22;"
592 " color:black;"
593 "}";
594
595constexpr const char *LogQSOButtonStyle =
596 "QPushButton {"
597 " background-color:lightgray;"
598 " color:black;"
599 " padding:0.25em 0.25em; font-weight:normal;"
600 " border-style:solid;"
601 " border-width:0px;"
602 " border-radius:4px;"
603 "}"
604 "QPushButton:checked {"
605 " background-color:#6699ff;"
606 " color:black;"
607 "}";
608
609constexpr const char *TuneButtonStyle = LogQSOButtonStyle; // Same as above
610
611constexpr const char *ModeButtonStyle =
612 "QPushButton {"
613 " padding:0.25em 0.25em; font-weight:bold;"
614 " border-style:solid;"
615 " border-width:0px;"
616 " border-radius:4px;"
617 " background-color:#6699ff;"
618 " color:black;"
619 "}"
620 "QPushButton:checked {"
621 " background-color:#6699ff;"
622 " color:black;"
623 "}";
624
625constexpr const char *SpotButtonStyle =
626 "QPushButton {"
627 " background-color:lightgray;"
628 " color:black;"
629 " padding:0.25em 0.25em; font-weight:normal;"
630 " border-style:solid;"
631 " border-width:0px;"
632 " border-radius:4px;"
633 "}"
634 "QPushButton:checked {"
635 " background-color:#6699ff;"
636 " color:black;"
637 "}";
638
639}
640#else
641namespace Styles {
642
643// background color of the header bar - must be the same as the frequency display above
644constexpr const char *LogWidgetStyle =
645 "QFrame#logWidget { background-color: #F2F2F0; }";
646
647// definition of the frequency displqy for the up/down buttons
648constexpr const char *DialFreqUpDownButtonStyle =
649 "QPushButton {"
650 " background-color: #000000;"
651 " color: #39FF14;"
652 " font-size: 12pt;"
653 " border:1px solid;"
654 " border-radius:0px;"
655 "}"
656 "QPushButton:pressed {"
657 " background-color: #222;"
658 "}";
659
660constexpr const char *LabDialFreqOffsetStyle = "QLabel {"
661 " font-size: 14pt;"
662 " line-height:12pt;"
663 " color : black;"
664 "}";
665
666// definition of the display of the callsign label
667constexpr const char *LabCallsignStyle = "QLabel {"
668 " font-size: 14pt;"
669 " line-height:12pt;"
670 " color : black;"
671 "}";
672
673// definition of the display of the of the date/time label
674constexpr const char *LabUTCStyle =
675 "QLabel {"
676 " border-radius:0px;"
677 " font-size: 18pt;"
678 " line-height:18pt;"
679 " font-family: \"DejaVu Sans Mono\", \"Liberation Mono\", \"Noto Mono\", \"Ubuntu Mono\", monospace;"
680 " font-weight: bold;"
681 " background-color: black;"
682 " color : #39FF14;"
683 "}";
684
685// defintion of the display of the button grid
686constexpr const char *ButtonGridStyle =
687 "QPushButton {"
688 " background-color:lightgray;"
689 " padding:0.25em 0.25em; font-weight:normal;"
690 " border-style:solid;"
691 " border-width:0px;"
692 " border-radius:0px;"
693 "}"
694 "QPushButton:checked {"
695 " background-color:#6699ff;"
696 "}";
697
698// defintion of the display of the Tx button
699constexpr const char *MonitorTxButtonStyle =
700 "QPushButton {"
701 " background-color:lightgray;"
702 " padding:0.25em 0.25em; font-weight:normal;"
703 " border-style:solid;"
704 " border-width:0px;"
705 " border-radius:0px;"
706 "}"
707 "QPushButton:checked {"
708 " background-color:#22FF22;"
709 "}"
710 "QPushButton[transmitting=\"true\"] {"
711 " background-color:#FF2222;"
712 "}";
713
714// definition of the display of the Rx button
715constexpr const char *MonitorButtonStyle =
716 "QPushButton {"
717 " background-color:lightgray;"
718 " padding:0.25em 0.25em; font-weight:normal;"
719 " border-style:solid;"
720 " border-width:0px;"
721 " border-radius:0px;"
722 "}"
723 "QPushButton:checked {"
724 " background-color:#22FF22;"
725 "}";
726
727// defintion of the display of the Log and Tune buttons
728constexpr const char *LogQSOButtonStyle =
729 "QPushButton {"
730 " background-color:lightgray;"
731 " padding:0.25em 0.25em; font-weight:normal;"
732 " border-style:solid;"
733 " border-width:0px;"
734 " border-radius:0px;"
735 "}"
736 "QPushButton:checked {"
737 " background-color:#6699ff;"
738 "}";
739
740constexpr const char *TuneButtonStyle = LogQSOButtonStyle; // Same as above
741
742// definition of the display of the Mode button
743constexpr const char *ModeButtonStyle =
744 "QPushButton {"
745 " padding:0.25em 0.25em; font-weight:bold;"
746 " border-style:solid;"
747 " border-width:0px;"
748 " border-radius:0px;"
749 " background-color:#6699ff;"
750 "}"
751 "QPushButton:checked {"
752 " background-color:#6699ff;"
753 "}";
754
755// defintion of the display of the Spot button
756constexpr const char *SpotButtonStyle =
757 "QPushButton {"
758 " background-color:lightgray;"
759 " padding:0.25em 0.25em; font-weight:normal;"
760 " border-style:solid;"
761 " border-width:0px;"
762 " border-radius:0px;"
763 "}"
764 "QPushButton:checked {"
765 " background-color:#6699ff;"
766 "}";
767
768}
769#endif
770
Defines platform-specific style constants for JS8Call's header bar controls.
QString buttonStyle()
Returns a platform-native QPushButton stylesheet.
Definition styles.h:179
QString txStatusLabelStyle(TxStatusAppearance appearance)
Returns the QSS stylesheet string for a given TX status state.
Definition styles.h:101