Files
DualFloatingClock/clock_widget.h
T
sebastian d9008479c1 feat: tray-first UX, text outline, start-at-login toggle, font max 200
- All settings move to flat tray menu; right-click on clock disabled
- ClockLabel: custom QPainterPath text rendering with configurable
  glyph outline (BorderColor) — verified pixel-level offscreen
- Fixed glyph positioning bug (baseline math) caught by isolated test
- Window auto-fits content (adjustSize) — no more oversized clock
- Start at Login: checkable tray item, persisted in QSettings,
  LaunchAgent enable/disable (TDD: roundTrip test caught disable()
  returning false when plist already absent)
- Color dialog: hex/HTML input + 'transparent' + native picker fallback;
  opaque colors stored as #RRGGBB
- Border: glyph outline instead of box border; background still painted
  in paintEvent (QSS doesn't render with WA_TranslucentBackground on macOS)
- Removed window shadow (setHasShadow:NO), no bold, SF Pro Rounded
- Font size dialogs allow up to 200 (was 72)
- macOS: icon template 16pt, light/dark auto-adapt; LaunchAgent points
  to /Applications install
2026-08-19 22:41:33 +03:00

114 lines
2.8 KiB
C++

#ifndef CLOCK_WIDGET_H
#define CLOCK_WIDGET_H
#include <QWidget>
#include <QLabel>
#include <QTimer>
#include <QMouseEvent>
#include <QMenu>
#include <QAction>
#include <QColor>
#include <optional>
class ConfigManager;
// QLabel that paints its text with an optional outline (border around the
// glyphs, not a box). QSS cannot stroke text, so we use a QPainterPath.
class ClockLabel : public QLabel
{
Q_OBJECT
public:
explicit ClockLabel(QWidget *parent = nullptr);
void setDisplayColors(const QColor &textColor, const QColor &outlineColor, qreal outlineWidth);
protected:
void paintEvent(QPaintEvent *event) override;
private:
QColor m_textColor;
QColor m_outlineColor;
qreal m_outlineWidth;
};
class ClockWidget : public QWidget
{
Q_OBJECT
public:
explicit ClockWidget(QWidget *parent = nullptr);
~ClockWidget();
QMenu *menu() const { return m_contextMenu; }
protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void contextMenuEvent(QContextMenuEvent *event) override;
void paintEvent(QPaintEvent *event) override;
private slots:
void updateTime();
void toggleAlwaysOnTop();
void changeFontColor();
void changeBackgroundColor();
void changeBorderColor();
void changeFontSize();
void changeLocationFontSize();
void changePrimaryTimeZone();
void changeSecondaryTimeZone();
void resetSettings();
void quitApplication();
private:
void setupUI();
void createMenu();
void loadSettings();
void saveSettings();
void updateStyleSheet();
void changeTimeZone(bool primaryClock);
QString formattedTime(const QString &timeZoneId) const;
QString locationName(const QString &timeZoneId) const;
std::optional<QColor> pickColor(const QString &title, const QColor &current, QWidget *parent);
ClockLabel *m_primaryTimeLabel;
ClockLabel *m_primaryLocationLabel;
ClockLabel *m_secondaryTimeLabel;
ClockLabel *m_secondaryLocationLabel;
QTimer *m_timer;
QMenu *m_contextMenu;
// Drag related
QPoint m_dragPosition;
bool m_dragging;
// Resize related
bool m_resizing;
QPoint m_resizeStartPos;
QSize m_resizeStartSize;
int m_resizeBorder;
// Settings
ConfigManager *m_configManager;
QColor m_fontColor;
QColor m_backgroundColor;
QColor m_borderColor;
int m_fontSize;
int m_locationFontSize;
bool m_alwaysOnTop;
QString m_primaryTimeZoneId;
QString m_secondaryTimeZoneId;
// Helper methods
bool isInResizeArea(const QPoint &pos) const;
void positionAtBottomRight();
#ifdef Q_OS_MAC
void setupMacOSWindowProperties();
#endif
};
#endif // CLOCK_WIDGET_H