Fix: Don't allow right-click to close world generation progress window. (#13084)
[openttd-github.git] / src / texteff.cpp
blobfbec86d04fa31150a7297bc73dfff5cd5eee0fb2
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
8 /** @file texteff.cpp Handling of text effects. */
10 #include "stdafx.h"
11 #include "texteff.hpp"
12 #include "transparency.h"
13 #include "strings_func.h"
14 #include "viewport_func.h"
15 #include "settings_type.h"
16 #include "command_type.h"
17 #include "timer/timer.h"
18 #include "timer/timer_window.h"
20 #include "safeguards.h"
22 /** Container for all information about a text effect */
23 struct TextEffect : public ViewportSign {
24 std::vector<StringParameterData> params; ///< Backup of string parameters
25 StringID string_id; ///< String to draw for the text effect, if INVALID_STRING_ID then it's not valid
26 uint8_t duration; ///< How long the text effect should stay, in ticks (applies only when mode == TE_RISING)
27 TextEffectMode mode; ///< Type of text effect
29 /** Reset the text effect */
30 void Reset()
32 this->MarkDirty();
33 this->width_normal = 0;
34 this->string_id = INVALID_STRING_ID;
38 static std::vector<struct TextEffect> _text_effects; ///< Text effects are stored there
40 /* Text Effects */
41 TextEffectID AddTextEffect(StringID msg, int center, int y, uint8_t duration, TextEffectMode mode)
43 if (_game_mode == GM_MENU) return INVALID_TE_ID;
45 auto it = std::find_if(std::begin(_text_effects), std::end(_text_effects), [](const TextEffect &te) { return te.string_id == INVALID_STRING_ID; });
46 if (it == std::end(_text_effects)) {
47 /* _text_effects.size() is the maximum ID + 1 that has been allocated. We should not allocate INVALID_TE_ID or beyond. */
48 if (_text_effects.size() >= INVALID_TE_ID) return INVALID_TE_ID;
49 it = _text_effects.emplace(std::end(_text_effects));
52 TextEffect &te = *it;
54 /* Start defining this object */
55 te.string_id = msg;
56 te.duration = duration;
57 CopyOutDParam(te.params, 2);
58 te.mode = mode;
60 /* Make sure we only dirty the new area */
61 te.width_normal = 0;
62 te.UpdatePosition(center, y, msg);
64 return static_cast<TextEffectID>(it - std::begin(_text_effects));
67 void UpdateTextEffect(TextEffectID te_id, StringID msg)
69 /* Update details */
70 TextEffect &te = _text_effects[te_id];
71 if (msg == te.string_id && !HaveDParamChanged(te.params)) return;
72 te.string_id = msg;
73 CopyOutDParam(te.params, 2);
75 te.UpdatePosition(te.center, te.top, te.string_id, te.string_id - 1);
78 void UpdateAllTextEffectVirtCoords()
80 for (auto &te : _text_effects) {
81 if (te.string_id == INVALID_STRING_ID) continue;
82 CopyInDParam(te.params);
83 te.UpdatePosition(te.center, te.top, te.string_id, te.string_id - 1);
87 void RemoveTextEffect(TextEffectID te_id)
89 _text_effects[te_id].Reset();
92 /** Slowly move text effects upwards. */
93 IntervalTimer<TimerWindow> move_all_text_effects_interval = {std::chrono::milliseconds(30), [](uint count) {
94 if (_pause_mode && _game_mode != GM_EDITOR && _settings_game.construction.command_pause_level <= CMDPL_NO_CONSTRUCTION) return;
96 for (TextEffect &te : _text_effects) {
97 if (te.string_id == INVALID_STRING_ID) continue;
98 if (te.mode != TE_RISING) continue;
100 if (te.duration < count) {
101 te.Reset();
102 continue;
105 te.MarkDirty(ZOOM_LVL_TEXT_EFFECT);
106 te.duration -= count;
107 te.top -= count * ZOOM_BASE;
108 te.MarkDirty(ZOOM_LVL_TEXT_EFFECT);
112 void InitTextEffects()
114 _text_effects.clear();
115 _text_effects.shrink_to_fit();
118 void DrawTextEffects(DrawPixelInfo *dpi)
120 /* Don't draw the text effects when zoomed out a lot */
121 if (dpi->zoom > ZOOM_LVL_TEXT_EFFECT) return;
122 if (IsTransparencySet(TO_TEXT)) return;
123 for (TextEffect &te : _text_effects) {
124 if (te.string_id == INVALID_STRING_ID) continue;
125 if (te.mode == TE_RISING || _settings_client.gui.loading_indicators) {
126 CopyInDParam(te.params);
127 ViewportAddString(dpi, ZOOM_LVL_TEXT_EFFECT, &te, te.string_id, te.string_id - 1, STR_NULL);