diff --git a/src/transparency.h b/src/transparency.h index e282ce429d..8c2337f0f1 100644 --- a/src/transparency.h +++ b/src/transparency.h @@ -34,10 +34,12 @@ enum TransparencyOption : uint8_t { TO_INVALID, ///< Invalid transparency option }; -typedef uint TransparencyOptionBits; ///< transparency option bits -extern TransparencyOptionBits _transparency_opt; -extern TransparencyOptionBits _transparency_lock; -extern TransparencyOptionBits _invisibility_opt; +/** Bitset of \c TransparencyOption elements. */ +using TransparencyOptions = EnumBitSet; + +extern TransparencyOptions _transparency_opt; +extern TransparencyOptions _transparency_lock; +extern TransparencyOptions _invisibility_opt; extern DisplayOptions _display_opt; extern StationFacilities _facility_display_opt; @@ -50,7 +52,7 @@ extern StationFacilities _facility_display_opt; */ inline bool IsTransparencySet(TransparencyOption to) { - return (HasBit(_transparency_opt, to) && _game_mode != GameMode::Menu); + return _transparency_opt.Test(to) && _game_mode != GameMode::Menu; } /** @@ -62,7 +64,7 @@ inline bool IsTransparencySet(TransparencyOption to) */ inline bool IsInvisibilitySet(TransparencyOption to) { - return (HasBit(_transparency_opt & _invisibility_opt, to) && _game_mode != GameMode::Menu); + return IsTransparencySet(to) && _invisibility_opt.Test(to) && _game_mode != GameMode::Menu; } /** @@ -72,7 +74,7 @@ inline bool IsInvisibilitySet(TransparencyOption to) */ inline void ToggleTransparency(TransparencyOption to) { - ToggleBit(_transparency_opt, to); + _transparency_opt.Flip(to); } /** @@ -82,7 +84,7 @@ inline void ToggleTransparency(TransparencyOption to) */ inline void ToggleInvisibility(TransparencyOption to) { - ToggleBit(_invisibility_opt, to); + _invisibility_opt.Flip(to); } /** @@ -95,11 +97,11 @@ inline void ToggleInvisibility(TransparencyOption to) inline void ToggleInvisibilityWithTransparency(TransparencyOption to) { if (IsInvisibilitySet(to)) { - ClrBit(_invisibility_opt, to); - ClrBit(_transparency_opt, to); + _invisibility_opt.Reset(to); + _transparency_opt.Reset(to); } else { - SetBit(_invisibility_opt, to); - SetBit(_transparency_opt, to); + _invisibility_opt.Set(to); + _transparency_opt.Set(to); } } @@ -110,19 +112,22 @@ inline void ToggleInvisibilityWithTransparency(TransparencyOption to) */ inline void ToggleTransparencyLock(TransparencyOption to) { - ToggleBit(_transparency_lock, to); + _transparency_lock.Flip(to); } /** Set or clear all non-locked transparency options */ inline void ResetRestoreAllTransparency() { + TransparencyOptions unlocked = _transparency_lock; + unlocked.Flip(); + /* if none of the non-locked options are set */ - if ((_transparency_opt & ~_transparency_lock) == 0) { + if (!_transparency_opt.Any(unlocked)) { /* set all non-locked options */ - _transparency_opt |= GB(~_transparency_lock, 0, TO_END); + _transparency_opt.Set(unlocked); } else { /* clear all non-locked options */ - _transparency_opt &= _transparency_lock; + _transparency_opt.Reset(unlocked); } MarkWholeScreenDirty(); diff --git a/src/transparency_gui.cpp b/src/transparency_gui.cpp index 7bd5392506..f90f0a2e0d 100644 --- a/src/transparency_gui.cpp +++ b/src/transparency_gui.cpp @@ -20,9 +20,9 @@ #include "safeguards.h" -TransparencyOptionBits _transparency_opt; ///< The bits that should be transparent. -TransparencyOptionBits _transparency_lock; ///< Prevent these bits from flipping with X. -TransparencyOptionBits _invisibility_opt; ///< The bits that should be invisible. +TransparencyOptions _transparency_opt; ///< The bits that should be transparent. +TransparencyOptions _transparency_lock; ///< Prevent these bits from flipping with X. +TransparencyOptions _invisibility_opt; ///< The bits that should be invisible. DisplayOptions _display_opt; ///< What do we want to draw/do? StationFacilities _facility_display_opt; ///< What station facilities to draw. @@ -40,6 +40,17 @@ public: this->DrawWidgets(); } + /** + * Get the \c TransparencyOption associated with a widget. + * @param widget the widget. + * @return Transparency option associated with the widget. + */ + TransparencyOption GetTransparencyOptionOfWidget(WidgetID widget) const + { + if (!IsInsideMM(widget, WID_TT_BEGIN, WID_TT_END)) return TransparencyOption::Invalid; + return static_cast(widget - WID_TT_BEGIN); + } + void DrawWidget(const Rect &r, WidgetID widget) const override { switch (widget) { @@ -52,8 +63,8 @@ public: case WID_TT_STRUCTURES: case WID_TT_CATENARY: case WID_TT_TEXT: { - int i = widget - WID_TT_BEGIN; - if (HasBit(_transparency_lock, i)) DrawSprite(SPR_LOCK, PAL_NONE, r.left + WidgetDimensions::scaled.fullbevel.left, r.top + WidgetDimensions::scaled.fullbevel.top); + TransparencyOption to = GetTransparencyOptionOfWidget(widget); + if (_transparency_lock.Test(to)) DrawSprite(SPR_LOCK, PAL_NONE, r.left + WidgetDimensions::scaled.fullbevel.left, r.top + WidgetDimensions::scaled.fullbevel.top); break; } case WID_TT_BUTTONS: { @@ -62,8 +73,8 @@ public: if (i == WID_TT_TEXT) continue; // Loading and cost/income text has no invisibility button. const Rect wr = this->GetWidget(i)->GetCurrentRect().Shrink(WidgetDimensions::scaled.fullbevel); - DrawFrameRect(wr.WithY(fr), Colours::PaleGreen, - HasBit(_invisibility_opt, i - WID_TT_BEGIN) ? FrameFlag::Lowered : FrameFlags{}); + TransparencyOption to = GetTransparencyOptionOfWidget(i); + DrawFrameRect(wr.WithY(fr), Colours::PaleGreen, _invisibility_opt.Test(to) ? FrameFlag::Lowered : FrameFlags{}); } break; } @@ -75,11 +86,11 @@ public: if (widget >= WID_TT_BEGIN && widget < WID_TT_END) { if (_ctrl_pressed) { /* toggle the bit of the transparencies lock variable */ - ToggleTransparencyLock((TransparencyOption)(widget - WID_TT_BEGIN)); + ToggleTransparencyLock(GetTransparencyOptionOfWidget(widget)); this->SetDirty(); } else { /* toggle the bit of the transparencies variable and play a sound */ - ToggleTransparency((TransparencyOption)(widget - WID_TT_BEGIN)); + ToggleTransparency(GetTransparencyOptionOfWidget(widget)); SndClickBeep(); MarkWholeScreenDirty(); } @@ -93,11 +104,11 @@ public: } if (i == WID_TT_TEXT|| i == WID_TT_END) return; - ToggleInvisibility((TransparencyOption)(i - WID_TT_BEGIN)); + ToggleInvisibility(GetTransparencyOptionOfWidget(i)); SndClickBeep(); /* Redraw whole screen only if transparency is set */ - if (IsTransparencySet((TransparencyOption)(i - WID_TT_BEGIN))) { + if (IsTransparencySet(GetTransparencyOptionOfWidget(i))) { MarkWholeScreenDirty(); } else { this->SetWidgetDirty(WID_TT_BUTTONS); @@ -121,7 +132,7 @@ public: { if (!gui_scope) return; for (WidgetID i = WID_TT_BEGIN; i < WID_TT_END; i++) { - this->SetWidgetLoweredState(i, IsTransparencySet((TransparencyOption)(i - WID_TT_BEGIN))); + this->SetWidgetLoweredState(i, IsTransparencySet(GetTransparencyOptionOfWidget(i))); } } }; diff --git a/src/widget.cpp b/src/widget.cpp index f1f973cbfc..710b93f81b 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -2401,10 +2401,9 @@ void NWidgetViewport::Draw(const Window *w) if (this->current_x == 0 || this->current_y == 0) return; if (this->disp_flags.Test(NWidgetDisplayFlag::NoTransparency)) { - TransparencyOptionBits to_backup = _transparency_opt; - _transparency_opt &= (1 << TO_SIGNS) | (1 << TO_TEXT); // Disable all transparency, except textual stuff + AutoRestoreBackup to_backup(_transparency_opt); + _transparency_opt &= TransparencyOptions{TO_SIGNS, TO_TEXT}; // Disable all transparency, except textual stuff w->DrawViewport(); - _transparency_opt = to_backup; } else { w->DrawViewport(); }