1
0
Fork 0

Compare commits

...

3 Commits

Author SHA1 Message Date
Kuhnovic eeea44c167
Merge 643dcefc8f into a8650c6b06 2025-07-19 22:49:25 +00:00
Peter Nelson a8650c6b06
Codechange: Make SpriteCacheCtrlFlags an enum bit set. (#14462)
Due to header dependencies, this requires types to split from the spritecache header.
2025-07-19 23:49:15 +01:00
Koen Bussemaker 643dcefc8f Change: Error window colour changes based on severity 2025-03-14 20:05:54 +01:00
15 changed files with 83 additions and 56 deletions

View File

@ -454,6 +454,7 @@ add_files(
spritecache.cpp
spritecache.h
spritecache_internal.h
spritecache_type.h
station.cpp
station_base.h
station_cmd.cpp

View File

@ -134,7 +134,7 @@ bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type t
Debug(driver, 1, "Probing {} driver '{}' skipped due to earlier crash", GetDriverTypeName(type), d->name);
_video_hw_accel = false;
ErrorMessageData msg(GetEncodedString(STR_VIDEO_DRIVER_ERROR), GetEncodedString(STR_VIDEO_DRIVER_ERROR_HARDWARE_ACCELERATION_CRASH), true);
ErrorMessageData msg(GetEncodedString(STR_VIDEO_DRIVER_ERROR), GetEncodedString(STR_VIDEO_DRIVER_ERROR_HARDWARE_ACCELERATION_CRASH), WL_CRITICAL);
ScheduleErrorMessage(std::move(msg));
continue;
}
@ -158,7 +158,7 @@ bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type t
if (type == Driver::DT_VIDEO && _video_hw_accel && d->UsesHardwareAcceleration()) {
_video_hw_accel = false;
ErrorMessageData msg(GetEncodedString(STR_VIDEO_DRIVER_ERROR), GetEncodedString(STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION), true);
ErrorMessageData msg(GetEncodedString(STR_VIDEO_DRIVER_ERROR), GetEncodedString(STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION), WL_CRITICAL);
ScheduleErrorMessage(std::move(msg));
}
}

View File

@ -30,7 +30,7 @@ enum WarningLevel : uint8_t {
/** The data of the error message. */
class ErrorMessageData {
protected:
bool is_critical; ///< Whether the error message is critical.
WarningLevel level; ///< Level of the error message (e.g. whether it's a critical error).
EncodedString summary_msg; ///< General error message showed in first line. Must be valid.
EncodedString detailed_msg; ///< Detailed error message showed in second line. Can be #INVALID_STRING_ID.
EncodedString extra_msg; ///< Extra error message shown in third line. Can be #INVALID_STRING_ID.
@ -38,7 +38,7 @@ protected:
CompanyID company; ///< Company belonging to the face being shown. #CompanyID::Invalid() if no face present.
public:
ErrorMessageData(EncodedString &&summary_msg, EncodedString &&detailed_msg, bool is_critical = false, int x = 0, int y = 0, EncodedString &&extra_msg = {}, CompanyID company = CompanyID::Invalid());
ErrorMessageData(EncodedString &&summary_msg, EncodedString &&detailed_msg, WarningLevel level = WL_ERROR, int x = 0, int y = 0, EncodedString &&extra_msg = {}, CompanyID company = CompanyID::Invalid());
/** Check whether error window shall display a company manager face */
bool HasFace() const { return company != CompanyID::Invalid(); }

View File

@ -35,10 +35,10 @@
static constexpr NWidgetPart _nested_errmsg_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_RED),
NWidget(WWT_CLOSEBOX, COLOUR_RED, WID_EM_CLOSEBOX),
NWidget(WWT_CAPTION, COLOUR_RED, WID_EM_CAPTION), SetStringTip(STR_ERROR_MESSAGE_CAPTION),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_RED),
NWidget(WWT_PANEL, COLOUR_RED, WID_EM_PANEL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_EM_MESSAGE), SetPadding(WidgetDimensions::unscaled.modalpopup), SetFill(1, 0), SetMinimalSize(236, 0),
EndContainer(),
};
@ -52,10 +52,10 @@ static WindowDesc _errmsg_desc(
static constexpr NWidgetPart _nested_errmsg_face_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_RED),
NWidget(WWT_CLOSEBOX, COLOUR_RED, WID_EM_CLOSEBOX),
NWidget(WWT_CAPTION, COLOUR_RED, WID_EM_CAPTION),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_RED),
NWidget(WWT_PANEL, COLOUR_RED, WID_EM_PANEL),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_EM_FACE), SetPadding(2, 0, 2, 2), SetFill(0, 1), SetMinimalSize(92, 119),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_EM_MESSAGE), SetPadding(WidgetDimensions::unscaled.modalpopup), SetFill(1, 1), SetMinimalSize(236, 0),
@ -74,13 +74,13 @@ static WindowDesc _errmsg_face_desc(
* Display an error message in a window.
* @param summary_msg General error message showed in first line. Must be valid.
* @param detailed_msg Detailed error message showed in second line. Can be empty.
* @param is_critical Whether the error is critical. Critical messages never go away on their own.
* @param level Warning/error level of the message. NOTE: critical messages never go away on their own.
* @param x World X position (TileVirtX) of the error location. Set both x and y to 0 to just center the message when there is no related error tile.
* @param y World Y position (TileVirtY) of the error location. Set both x and y to 0 to just center the message when there is no related error tile.
* @param extra_msg Extra error message showed in third line. Can be empty.
*/
ErrorMessageData::ErrorMessageData(EncodedString &&summary_msg, EncodedString &&detailed_msg, bool is_critical, int x, int y, EncodedString &&extra_msg, CompanyID company) :
is_critical(is_critical),
ErrorMessageData::ErrorMessageData(EncodedString &&summary_msg, EncodedString &&detailed_msg, WarningLevel level, int x, int y, EncodedString &&extra_msg, CompanyID company) :
level(level),
summary_msg(std::move(summary_msg)),
detailed_msg(std::move(detailed_msg)),
extra_msg(std::move(extra_msg)),
@ -113,8 +113,15 @@ public:
{
this->InitNested();
Colours window_colour = COLOUR_RED;
if (level == WL_INFO) window_colour = COLOUR_GREEN;
if (level == WL_WARNING) window_colour = COLOUR_ORANGE;
this->GetWidget<NWidgetCore>(WID_EM_CAPTION)->colour = window_colour;
this->GetWidget<NWidgetCore>(WID_EM_CLOSEBOX)->colour = window_colour;
this->GetWidget<NWidgetCore>(WID_EM_PANEL)->colour = window_colour;
/* Only start the timeout if the message is not critical. */
if (!this->is_critical) {
if (this->level != WL_CRITICAL) {
this->display_timeout.Reset();
}
}
@ -225,7 +232,7 @@ public:
void OnMouseLoop() override
{
/* Disallow closing the window too easily, if timeout is disabled */
if (_right_button_down && !this->is_critical) this->Close();
if (_right_button_down && this->level != WL_CRITICAL) this->Close();
}
void Close([[maybe_unused]] int data = 0) override
@ -241,7 +248,7 @@ public:
*/
bool IsCritical()
{
return this->is_critical;
return this->level == WL_CRITICAL;
}
};
@ -281,7 +288,7 @@ void UnshowCriticalError()
/**
* Display an error message in a window.
* Note: CommandCost errors are always severity level WL_INFO.
* Note: CommandCost errors are always severity level WL_ERROR.
* @param summary_msg General error message showed in first line. Must be valid.
* @param x World X position (TileVirtX) of the error location. Set both x and y to 0 to just center the message when there is no related error tile.
* @param y World Y position (TileVirtY) of the error location. Set both x and y to 0 to just center the message when there is no related error tile.
@ -292,7 +299,7 @@ void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc
EncodedString error = std::move(cc.GetEncodedMessage());
if (error.empty()) error = GetEncodedStringIfValid(cc.GetErrorMessage());
ShowErrorMessage(std::move(summary_msg), std::move(error), WL_INFO, x, y,
ShowErrorMessage(std::move(summary_msg), std::move(error), WL_ERROR, x, y,
GetEncodedStringIfValid(cc.GetExtraErrorMessage()), cc.GetErrorOwner());
}
@ -323,12 +330,10 @@ void ShowErrorMessage(EncodedString &&summary_msg, EncodedString &&detailed_msg,
IConsolePrint(wl == WL_WARNING ? CC_WARNING : CC_ERROR, message);
}
bool is_critical = wl == WL_CRITICAL;
if (_game_mode == GM_BOOTSTRAP) return;
if (_settings_client.gui.errmsg_duration == 0 && !is_critical) return;
if (_settings_client.gui.errmsg_duration == 0 && wl != WL_CRITICAL) return;
ErrorMessageData data(std::move(summary_msg), std::move(detailed_msg), is_critical, x, y, std::move(extra_msg), company);
ErrorMessageData data(std::move(summary_msg), std::move(detailed_msg), wl, x, y, std::move(extra_msg), company);
ErrmsgWindow *w = dynamic_cast<ErrmsgWindow *>(FindWindowById(WC_ERRMSG, 0));
if (w != nullptr) {

View File

@ -535,7 +535,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty
struct GrfSpriteOffset {
size_t file_pos;
uint8_t control_flags;
SpriteCacheCtrlFlags control_flags{};
};
/** Map from sprite numbers to position in the GRF file. */
@ -565,7 +565,7 @@ void ReadGRFSpriteOffsets(SpriteFile &file)
size_t old_pos = file.GetPos();
file.SeekTo(data_offset, SEEK_CUR);
GrfSpriteOffset offset = { 0, 0 };
GrfSpriteOffset offset{0};
/* Loop over all sprite section entries and store the file
* offset for each newly encountered ID. */
@ -574,7 +574,6 @@ void ReadGRFSpriteOffsets(SpriteFile &file)
if (id != prev_id) {
_grf_sprite_offsets[prev_id] = offset;
offset.file_pos = file.GetPos() - 4;
offset.control_flags = 0;
}
prev_id = id;
uint length = file.ReadDword();
@ -585,11 +584,11 @@ void ReadGRFSpriteOffsets(SpriteFile &file)
uint8_t zoom = file.ReadByte();
length--;
if (colour.Any() && zoom == 0) { // ZoomLevel::Normal (normal zoom)
SetBit(offset.control_flags, (colour != SpriteComponent::Palette) ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL);
SetBit(offset.control_flags, (colour != SpriteComponent::Palette) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL);
offset.control_flags.Set((colour != SpriteComponent::Palette) ? SpriteCacheCtrlFlag::AllowZoomMin1x32bpp : SpriteCacheCtrlFlag::AllowZoomMin1xPal);
offset.control_flags.Set((colour != SpriteComponent::Palette) ? SpriteCacheCtrlFlag::AllowZoomMin2x32bpp : SpriteCacheCtrlFlag::AllowZoomMin2xPal);
}
if (colour.Any() && zoom == 2) { // ZoomLevel::In2x (2x zoomed in)
SetBit(offset.control_flags, (colour != SpriteComponent::Palette) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL);
offset.control_flags.Set((colour != SpriteComponent::Palette) ? SpriteCacheCtrlFlag::AllowZoomMin2x32bpp : SpriteCacheCtrlFlag::AllowZoomMin2xPal);
}
}
}
@ -621,7 +620,7 @@ bool LoadNextSprite(SpriteID load_index, SpriteFile &file, uint file_sprite_id)
uint8_t grf_type = file.ReadByte();
SpriteType type;
uint8_t control_flags = 0;
SpriteCacheCtrlFlags control_flags;
if (grf_type == 0xFF) {
/* Some NewGRF files have "empty" pseudo-sprites which are 1
* byte long. Catch these so the sprites won't be displayed. */

View File

@ -11,24 +11,9 @@
#define SPRITECACHE_H
#include "gfx_type.h"
#include "spritecache_type.h"
#include "spriteloader/spriteloader.hpp"
/** Data structure describing a sprite. */
struct Sprite {
uint16_t height; ///< Height of the sprite.
uint16_t width; ///< Width of the sprite.
int16_t x_offs; ///< Number of pixels to shift the sprite to the right.
int16_t y_offs; ///< Number of pixels to shift the sprite downwards.
std::byte data[]; ///< Sprite data.
};
enum SpriteCacheCtrlFlags : uint8_t {
SCCF_ALLOW_ZOOM_MIN_1X_PAL = 0, ///< Allow use of sprite min zoom setting at 1x in palette mode.
SCCF_ALLOW_ZOOM_MIN_1X_32BPP = 1, ///< Allow use of sprite min zoom setting at 1x in 32bpp mode.
SCCF_ALLOW_ZOOM_MIN_2X_PAL = 2, ///< Allow use of sprite min zoom setting at 2x in palette mode.
SCCF_ALLOW_ZOOM_MIN_2X_32BPP = 3, ///< Allow use of sprite min zoom setting at 2x in 32bpp mode.
};
extern uint _sprite_cache_size;
/** SpriteAllocator that allocates memory via a unique_ptr array. */

View File

@ -12,6 +12,7 @@
#include "core/math_func.hpp"
#include "gfx_type.h"
#include "spritecache_type.h"
#include "spriteloader/spriteloader.hpp"
#include "table/sprites.h"
@ -27,7 +28,7 @@ struct SpriteCache {
uint32_t lru = 0;
SpriteType type = SpriteType::Invalid; ///< In some cases a single sprite is misused by two NewGRFs. Once as real sprite and once as recolour sprite. If the recolour sprite gets into the cache it might be drawn as real sprite which causes enormous trouble.
bool warned = false; ///< True iff the user has been warned about incorrect use of this sprite
uint8_t control_flags = 0; ///< Control flags, see SpriteCacheCtrlFlags
SpriteCacheCtrlFlags control_flags{}; ///< Control flags, see SpriteCacheCtrlFlags
void ClearSpriteData();
};

View File

@ -0,0 +1,33 @@
/*
* This file is part of OpenTTD.
* 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.
* 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.
* 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/>.
*/
/** @file spritecache_type.h Types related to the sprite cache. */
#ifndef SPRITECACHE_TYPE_H
#define SPRITECACHE_TYPE_H
#include "core/enum_type.hpp"
/** Data structure describing a sprite. */
struct Sprite {
uint16_t height; ///< Height of the sprite.
uint16_t width; ///< Width of the sprite.
int16_t x_offs; ///< Number of pixels to shift the sprite to the right.
int16_t y_offs; ///< Number of pixels to shift the sprite downwards.
std::byte data[]; ///< Sprite data.
};
enum class SpriteCacheCtrlFlag : uint8_t {
AllowZoomMin1xPal, ///< Allow use of sprite min zoom setting at 1x in palette mode.
AllowZoomMin1x32bpp, ///< Allow use of sprite min zoom setting at 1x in 32bpp mode.
AllowZoomMin2xPal, ///< Allow use of sprite min zoom setting at 2x in palette mode.
AllowZoomMin2x32bpp, ///< Allow use of sprite min zoom setting at 2x in 32bpp mode.
};
using SpriteCacheCtrlFlags = EnumBitSet<SpriteCacheCtrlFlag, uint8_t>;
#endif /* SPRITECACHE_TYPE_H */

View File

@ -256,7 +256,7 @@ static ZoomLevels LoadSpriteV1(SpriteLoader::SpriteCollection &sprite, SpriteFil
return {};
}
static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
{
static const ZoomLevel zoom_lvl_map[6] = {ZoomLevel::Normal, ZoomLevel::In4x, ZoomLevel::In2x, ZoomLevel::Out2x, ZoomLevel::Out4x, ZoomLevel::Out8x};
@ -295,11 +295,11 @@ static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFil
is_wanted_zoom_lvl = true;
ZoomLevel zoom_min = sprite_type == SpriteType::Font ? ZoomLevel::Min : _settings_client.gui.sprite_zoom_min;
if (zoom_min >= ZoomLevel::In2x &&
HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL) && zoom_lvl < ZoomLevel::In2x) {
control_flags.Test(load_32bpp ? SpriteCacheCtrlFlag::AllowZoomMin2x32bpp : SpriteCacheCtrlFlag::AllowZoomMin2xPal) && zoom_lvl < ZoomLevel::In2x) {
is_wanted_zoom_lvl = false;
}
if (zoom_min >= ZoomLevel::Normal &&
HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL) && zoom_lvl < ZoomLevel::Normal) {
control_flags.Test(load_32bpp ? SpriteCacheCtrlFlag::AllowZoomMin1x32bpp : SpriteCacheCtrlFlag::AllowZoomMin1xPal) && zoom_lvl < ZoomLevel::Normal) {
is_wanted_zoom_lvl = false;
}
} else {
@ -359,7 +359,7 @@ static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFil
return loaded_sprites;
}
ZoomLevels SpriteLoaderGrf::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
ZoomLevels SpriteLoaderGrf::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
{
if (this->container_ver >= 2) {
return LoadSpriteV2(sprite, file, file_pos, sprite_type, load_32bpp, control_flags, avail_8bpp, avail_32bpp);

View File

@ -17,7 +17,7 @@ class SpriteLoaderGrf : public SpriteLoader {
uint8_t container_ver;
public:
SpriteLoaderGrf(uint8_t container_ver) : container_ver(container_ver) {}
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
};
#endif /* SPRITELOADER_GRF_HPP */

View File

@ -48,7 +48,7 @@ static void Convert32bppTo8bpp(SpriteLoader::Sprite &sprite)
}
}
ZoomLevels SpriteLoaderMakeIndexed::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
ZoomLevels SpriteLoaderMakeIndexed::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
{
ZoomLevels avail = this->baseloader.LoadSprite(sprite, file, file_pos, sprite_type, true, control_flags, avail_8bpp, avail_32bpp);

View File

@ -17,7 +17,7 @@ class SpriteLoaderMakeIndexed : public SpriteLoader {
SpriteLoader &baseloader;
public:
SpriteLoaderMakeIndexed(SpriteLoader &baseloader) : baseloader(baseloader) {}
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
};
#endif /* SPRITELOADER_MAKEINDEXED_H */

View File

@ -13,6 +13,7 @@
#include "../core/alloc_type.hpp"
#include "../core/enum_type.hpp"
#include "../gfx_type.h"
#include "../spritecache_type.h"
#include "sprite_file_type.hpp"
struct Sprite;
@ -94,7 +95,7 @@ public:
* @param[out] avail_32bpp Available 32bpp sprites.
* @return Available sprites matching \a load_32bpp.
*/
virtual ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) = 0;
virtual ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) = 0;
virtual ~SpriteLoader() = default;
};

View File

@ -33,7 +33,7 @@ static bool MockLoadNextSprite(SpriteID load_index)
sc->id = 0;
sc->type = is_mapgen ? SpriteType::MapGen : SpriteType::Normal;
sc->warned = false;
sc->control_flags = 0;
sc->control_flags = {};
/* Fill with empty sprites up until the default sprite count. */
return load_index < SPR_OPENTTD_BASE + OPENTTD_SPRITE_COUNT;

View File

@ -12,9 +12,11 @@
/** Widgets of the #ErrmsgWindow class. */
enum ErrorMessageWidgets : WidgetID {
WID_EM_CAPTION, ///< Caption of the window.
WID_EM_FACE, ///< Error title.
WID_EM_MESSAGE, ///< Error message.
WID_EM_CAPTION, ///< Caption of the window.
WID_EM_FACE, ///< Error title.
WID_EM_MESSAGE, ///< Error message.
WID_EM_CLOSEBOX, ///< Close box button.
WID_EM_PANEL, ///< Coloured background panel.
};
#endif /* WIDGETS_ERROR_WIDGET_H */