You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
340 lines
6.4 KiB
340 lines
6.4 KiB
#pragma once |
|
|
|
#include <cstddef> |
|
#include <cstdint> |
|
#include <string> |
|
#include <vector> |
|
|
|
#include "DiabloUI/art.h" |
|
#include "DiabloUI/text_draw.h" |
|
#include "utils/stubs.h" |
|
|
|
namespace devilution { |
|
|
|
enum UiType : uint8_t { |
|
UI_TEXT, |
|
UI_ART_TEXT, |
|
UI_ART_TEXT_BUTTON, |
|
UI_IMAGE, |
|
UI_BUTTON, |
|
UI_LIST, |
|
UI_SCROLLBAR, |
|
UI_EDIT, |
|
}; |
|
|
|
enum UiFlags : uint16_t { |
|
// clang-format off |
|
UIS_SMALL = 1 << 0, |
|
UIS_MED = 1 << 1, |
|
UIS_BIG = 1 << 2, |
|
UIS_HUGE = 1 << 3, |
|
UIS_CENTER = 1 << 4, |
|
UIS_RIGHT = 1 << 5, |
|
UIS_VCENTER = 1 << 6, |
|
UIS_SILVER = 1 << 7, |
|
UIS_GOLD = 1 << 8, |
|
UIS_RED = 1 << 9, |
|
UIS_BLUE = 1 << 10, |
|
UIS_BLACK = 1 << 11, |
|
UIS_DISABLED = 1 << 12, |
|
UIS_HIDDEN = 1 << 13, |
|
UIS_FIT_SPACING = 1 << 14, |
|
// clang-format on |
|
}; |
|
|
|
class UiItemBase { |
|
public: |
|
UiItemBase(SDL_Rect rect, int flags) |
|
{ |
|
m_rect = rect; |
|
m_iFlags = flags; |
|
}; |
|
|
|
UiItemBase(Sint16 x, Sint16 y, Uint16 item_width, Uint16 item_height, int flags) |
|
{ |
|
SDL_Rect tmp; |
|
tmp.x = x; |
|
tmp.y = y; |
|
tmp.w = item_width; |
|
tmp.h = item_height; |
|
|
|
m_rect = tmp; |
|
m_iFlags = flags; |
|
}; |
|
|
|
virtual ~UiItemBase() {}; |
|
|
|
bool has_flag(UiFlags flag) const |
|
{ |
|
return m_iFlags & flag; |
|
} |
|
|
|
bool has_any_flag(int flags) const |
|
{ |
|
return (m_iFlags & flags) != 0; |
|
} |
|
|
|
void add_flag(UiFlags flag) |
|
{ |
|
m_iFlags |= flag; |
|
} |
|
|
|
void remove_flag(UiFlags flag) |
|
{ |
|
m_iFlags &= ~flag; |
|
} |
|
|
|
//protected: |
|
UiType m_type; |
|
SDL_Rect m_rect; |
|
int m_iFlags; |
|
}; |
|
|
|
//============================================================================= |
|
|
|
class UiImage : public UiItemBase { |
|
public: |
|
UiImage(Art *art, SDL_Rect rect, int flags = 0) |
|
: UiItemBase(rect, flags) |
|
{ |
|
m_type = UI_IMAGE; |
|
m_art = art; |
|
m_animated = false; |
|
m_frame = 0; |
|
}; |
|
|
|
UiImage(Art *art, bool bAnimated, int iFrame, SDL_Rect rect, int flags) |
|
: UiItemBase(rect, flags) |
|
{ |
|
m_type = UI_IMAGE; |
|
m_art = art; |
|
m_animated = bAnimated; |
|
m_frame = iFrame; |
|
}; |
|
|
|
UiImage(Art *art, int frame, SDL_Rect rect, int flags = 0) |
|
: UiItemBase(rect, flags) |
|
{ |
|
m_type = UI_IMAGE; |
|
m_art = art; |
|
m_animated = false; |
|
m_frame = frame; |
|
} |
|
|
|
~UiImage() {}; |
|
|
|
//private: |
|
Art *m_art; |
|
bool m_animated; |
|
int m_frame; |
|
}; |
|
|
|
//============================================================================= |
|
|
|
class UiArtText : public UiItemBase { |
|
public: |
|
UiArtText(const char *text, SDL_Rect rect, int flags = 0) |
|
: UiItemBase(rect, flags) |
|
{ |
|
m_type = UI_ART_TEXT; |
|
m_text = text; |
|
}; |
|
|
|
~UiArtText() {}; |
|
|
|
//private: |
|
const char *m_text; |
|
}; |
|
|
|
//============================================================================= |
|
|
|
class UiScrollBar : public UiItemBase { |
|
public: |
|
UiScrollBar(Art *bg, Art *thumb, Art *arrow, SDL_Rect rect, int flags = 0) |
|
: UiItemBase(rect, flags) |
|
{ |
|
m_type = UI_SCROLLBAR; |
|
m_bg = bg; |
|
m_thumb = thumb; |
|
m_arrow = arrow; |
|
}; |
|
|
|
//private: |
|
Art *m_bg; |
|
Art *m_thumb; |
|
Art *m_arrow; |
|
}; |
|
|
|
//============================================================================= |
|
|
|
class UiArtTextButton : public UiItemBase { |
|
public: |
|
UiArtTextButton(const char *text, void (*action)(), SDL_Rect rect, int flags = 0) |
|
: UiItemBase(rect, flags) |
|
{ |
|
m_type = UI_ART_TEXT_BUTTON; |
|
m_text = text; |
|
m_action = action; |
|
}; |
|
//private: |
|
const char *m_text; |
|
void (*m_action)(); |
|
}; |
|
|
|
//============================================================================= |
|
|
|
class UiEdit : public UiItemBase { |
|
public: |
|
UiEdit(char *value, std::size_t max_length, SDL_Rect rect, int flags = 0) |
|
: UiItemBase(rect, flags) |
|
{ |
|
m_type = UI_EDIT; |
|
m_value = value; |
|
m_max_length = max_length; |
|
} |
|
|
|
//private: |
|
char *m_value; |
|
std::size_t m_max_length; |
|
}; |
|
|
|
//============================================================================= |
|
|
|
// Plain text (TTF) |
|
|
|
class UiText : public UiItemBase { |
|
public: |
|
UiText(const char *text, SDL_Color color1, SDL_Rect rect, int flags = 0) |
|
: UiItemBase(rect, flags) |
|
{ |
|
m_type = UI_TEXT; |
|
m_color = color1; |
|
|
|
SDL_Color color2 = { 0, 0, 0, 0 }; |
|
m_shadow_color = color2; |
|
|
|
m_text = text; |
|
} |
|
|
|
UiText(const char *text, SDL_Rect rect, int flags = 0) |
|
: UiItemBase(rect, flags) |
|
{ |
|
m_type = UI_TEXT; |
|
|
|
SDL_Color color1 = { 243, 243, 243, 0 }; |
|
m_color = color1; |
|
|
|
SDL_Color color2 = { 0, 0, 0, 0 }; |
|
m_shadow_color = color2; |
|
|
|
m_text = text; |
|
} |
|
|
|
//private: |
|
SDL_Color m_color; |
|
SDL_Color m_shadow_color; |
|
const char *m_text; |
|
|
|
// State: |
|
TtfSurfaceCache m_render_cache; |
|
}; |
|
|
|
//============================================================================= |
|
|
|
// A button (uses Diablo sprites) |
|
|
|
class UiButton : public UiItemBase { |
|
public: |
|
UiButton(Art *art, const char *text, void (*action)(), SDL_Rect rect, int flags = 0) |
|
: UiItemBase(rect, flags) |
|
{ |
|
m_type = UI_BUTTON; |
|
m_art = art; |
|
m_text = text; |
|
m_action = action; |
|
m_pressed = false; |
|
} |
|
|
|
enum FrameKey : uint8_t { |
|
DEFAULT, |
|
PRESSED, |
|
DISABLED |
|
}; |
|
|
|
//private: |
|
Art *m_art; |
|
|
|
const char *m_text; |
|
void (*m_action)(); |
|
|
|
// State |
|
bool m_pressed; |
|
TtfSurfaceCache m_render_cache; |
|
}; |
|
|
|
//============================================================================= |
|
|
|
class UiListItem { |
|
public: |
|
UiListItem(const char *text = "", int value = 0) |
|
{ |
|
m_text = text; |
|
m_value = value; |
|
} |
|
|
|
~UiListItem() |
|
{ |
|
} |
|
|
|
//private: |
|
const char *m_text; |
|
int m_value; |
|
}; |
|
|
|
typedef std::vector<UiListItem *> vUiListItem; |
|
|
|
class UiList : public UiItemBase { |
|
public: |
|
UiList(vUiListItem vItems, Sint16 x, Sint16 y, Uint16 item_width, Uint16 item_height, int flags = 0) |
|
: UiItemBase(x, y, item_width, item_height * vItems.size(), flags) |
|
{ |
|
m_type = UI_LIST; |
|
m_vecItems = vItems; |
|
m_x = x; |
|
m_y = y; |
|
m_width = item_width; |
|
m_height = item_height; |
|
}; |
|
|
|
~UiList() {}; |
|
|
|
SDL_Rect itemRect(int i) const |
|
{ |
|
SDL_Rect tmp; |
|
tmp.x = m_x; |
|
tmp.y = m_y + m_height * i; |
|
tmp.w = m_width; |
|
tmp.h = m_height; |
|
|
|
return tmp; |
|
} |
|
|
|
int indexAt(Sint16 y) const |
|
{ |
|
ASSERT(y >= m_rect.y); |
|
const std::size_t index = (y - m_rect.y) / m_height; |
|
ASSERT(index < m_vecItems.size()); |
|
return index; |
|
} |
|
|
|
UiListItem *GetItem(int i) const |
|
{ |
|
return m_vecItems[i]; |
|
} |
|
|
|
//private: |
|
Sint16 m_x, m_y; |
|
Uint16 m_width, m_height; |
|
std::vector<UiListItem *> m_vecItems; |
|
}; |
|
} // namespace devilution
|
|
|