#pragma once #include #include class QPaintEvent; // A window-wide, semi-transparent scrim drawn over the entire game window while a // modal dialog or menu is open, behind that modal (REQ-UI-MODAL-DIM). It is a child // of the main window covering its full rect and is transparent to mouse events, so it // only dims the game presentation and never intercepts input. // // Visibility is reference-counted via pushModal()/popModal() so that a single dim is // shown across nested or back-to-back modals (e.g. the recipe selection dialog that // immediately opens the layout dialog) rather than flickering or stacking overlays. class ModalDimOverlay : public QWidget { Q_OBJECT public: ModalDimOverlay(const QColor& dimColor, QWidget* parent); // Raise + show on the first active modal; hide when the last one closes. void pushModal(); void popModal(); // Update the dim color (e.g. after a config reload on Restart, REQ-CFG-RELOAD). void setDimColor(const QColor& dimColor); protected: void paintEvent(QPaintEvent* event) override; private: QColor m_dimColor; int m_modalDepth = 0; }; // RAII guard: shows the dim overlay for the duration of a scope (typically around a // blocking dialog exec()) and hides it (via reference count) on scope exit. class ModalDimScope { public: explicit ModalDimScope(ModalDimOverlay& overlay) : m_overlay(overlay) { m_overlay.pushModal(); } ~ModalDimScope() { m_overlay.popModal(); } ModalDimScope(const ModalDimScope&) = delete; ModalDimScope& operator=(const ModalDimScope&) = delete; private: ModalDimOverlay& m_overlay; };