From b8cfe159465a9bb0ada6abec744b66ccedd2802f Mon Sep 17 00:00:00 2001 From: Walter Julius Hennecke Date: Wed, 12 Feb 2020 22:46:49 +0100 Subject: [PATCH] Add various menu classes --- code/common/Point2d.cpp | 28 ++++---- code/common/Point2d.h | 10 +-- code/common/Point2d.i | 8 +-- code/ui/Atoms.cpp | 44 ++++++------ code/ui/Menu/MenuAction.cpp | 28 ++++++++ code/ui/Menu/MenuAction.h | 30 ++++++++ code/ui/Menu/MenuBitmap.cpp | 39 +++++++++++ code/ui/Menu/MenuBitmap.h | 35 ++++++++++ code/ui/Menu/MenuColor.cpp | 7 ++ code/ui/Menu/MenuColor.h | 20 ++++++ code/ui/Menu/MenuCommon.cpp | 5 ++ code/ui/Menu/MenuCommon.h | 49 +++++++++++++ code/ui/Menu/MenuField.cpp | 58 ++++++++++++++++ code/ui/Menu/MenuField.h | 24 +++++++ code/ui/Menu/MenuFieldData.cpp | 7 ++ code/ui/Menu/MenuFieldData.h | 34 +++++++++ code/ui/Menu/MenuFocus.cpp | 7 ++ code/ui/Menu/MenuFocus.h | 20 ++++++ code/ui/Menu/MenuFramework.cpp | 26 +++++++ code/ui/Menu/MenuFramework.h | 100 +++++++++++++++++++++++++++ code/ui/Menu/MenuGraphics.cpp | 7 ++ code/ui/Menu/MenuGraphics.h | 33 +++++++++ code/ui/Menu/MenuItem.h | 20 ++++++ code/ui/Menu/MenuList.cpp | 42 ++++++++++++ code/ui/Menu/MenuList.h | 65 ++++++++++++++++++ code/ui/Menu/MenuRadioButton.cpp | 18 +++++ code/ui/Menu/MenuRadioButton.h | 20 ++++++ code/ui/Menu/MenuShader.cpp | 7 ++ code/ui/Menu/MenuShader.h | 20 ++++++ code/ui/Menu/MenuSize.cpp | 7 ++ code/ui/Menu/MenuSize.h | 19 ++++++ code/ui/Menu/MenuSlider.cpp | 36 ++++++++++ code/ui/Menu/MenuSlider.h | 62 +++++++++++++++++ code/ui/Menu/MenuText.cpp | 114 +++++++++++++++++++++++++++++++ code/ui/Menu/MenuText.h | 35 ++++++++++ 35 files changed, 1039 insertions(+), 45 deletions(-) create mode 100644 code/ui/Menu/MenuAction.cpp create mode 100644 code/ui/Menu/MenuAction.h create mode 100644 code/ui/Menu/MenuBitmap.cpp create mode 100644 code/ui/Menu/MenuBitmap.h create mode 100644 code/ui/Menu/MenuColor.cpp create mode 100644 code/ui/Menu/MenuColor.h create mode 100644 code/ui/Menu/MenuCommon.cpp create mode 100644 code/ui/Menu/MenuCommon.h create mode 100644 code/ui/Menu/MenuField.cpp create mode 100644 code/ui/Menu/MenuField.h create mode 100644 code/ui/Menu/MenuFieldData.cpp create mode 100644 code/ui/Menu/MenuFieldData.h create mode 100644 code/ui/Menu/MenuFocus.cpp create mode 100644 code/ui/Menu/MenuFocus.h create mode 100644 code/ui/Menu/MenuFramework.cpp create mode 100644 code/ui/Menu/MenuFramework.h create mode 100644 code/ui/Menu/MenuGraphics.cpp create mode 100644 code/ui/Menu/MenuGraphics.h create mode 100644 code/ui/Menu/MenuItem.h create mode 100644 code/ui/Menu/MenuList.cpp create mode 100644 code/ui/Menu/MenuList.h create mode 100644 code/ui/Menu/MenuRadioButton.cpp create mode 100644 code/ui/Menu/MenuRadioButton.h create mode 100644 code/ui/Menu/MenuShader.cpp create mode 100644 code/ui/Menu/MenuShader.h create mode 100644 code/ui/Menu/MenuSize.cpp create mode 100644 code/ui/Menu/MenuSize.h create mode 100644 code/ui/Menu/MenuSlider.cpp create mode 100644 code/ui/Menu/MenuSlider.h create mode 100644 code/ui/Menu/MenuText.cpp create mode 100644 code/ui/Menu/MenuText.h diff --git a/code/common/Point2d.cpp b/code/common/Point2d.cpp index fc0d003..4279383 100644 --- a/code/common/Point2d.cpp +++ b/code/common/Point2d.cpp @@ -3,30 +3,30 @@ TEST_CASE("point2di_construct", "[common::Point2dI]") { auto p = common::Point2dI{42, 4}; - REQUIRE(p.x_ == 42); - REQUIRE(p.y_ == 4); + REQUIRE(p.x == 42); + REQUIRE(p.y == 4); p = common::Point2dI{32.3f, 43.2f}; - REQUIRE(p.x_ == 32); - REQUIRE(p.y_ == 43); + REQUIRE(p.x == 32); + REQUIRE(p.y == 43); p = common::Point2dI{32.4, 85.3}; - REQUIRE(p.x_ == 32); - REQUIRE(p.y_ == 85); + REQUIRE(p.x == 32); + REQUIRE(p.y == 85); p = common::Point2dI{44, 32.43f}; - REQUIRE(p.x_ == 44); - REQUIRE(p.y_ == 32); + REQUIRE(p.x == 44); + REQUIRE(p.y == 32); p = common::Point2dI{44, 564.324}; - REQUIRE(p.x_ == 44); - REQUIRE(p.y_ == 564); + REQUIRE(p.x == 44); + REQUIRE(p.y == 564); p = common::Point2dI{234.52f, 65}; - REQUIRE(p.x_ == 234); - REQUIRE(p.y_ == 65); + REQUIRE(p.x == 234); + REQUIRE(p.y == 65); p = common::Point2dI{743.345, 76}; - REQUIRE(p.x_ == 743); - REQUIRE(p.y_ == 76); + REQUIRE(p.x == 743); + REQUIRE(p.y == 76); } diff --git a/code/common/Point2d.h b/code/common/Point2d.h index 49c164f..fc1014e 100644 --- a/code/common/Point2d.h +++ b/code/common/Point2d.h @@ -9,15 +9,15 @@ namespace common { template class Point2d { public: - constexpr Point2d() : x_{0}, y_{0} {} + constexpr Point2d() : x{0}, y{0} {} template && std::is_convertible_v>> - constexpr Point2d(A x, B y) : x_{static_cast(x)}, y_{static_cast(y)} {} - - T x_; - T y_; + constexpr Point2d(A x, B y) : x{static_cast(x)}, y{static_cast(y)} {} + + T x; + T y; }; using Point2dI = Point2d; diff --git a/code/common/Point2d.i b/code/common/Point2d.i index 6671d26..62dc57f 100644 --- a/code/common/Point2d.i +++ b/code/common/Point2d.i @@ -12,8 +12,8 @@ public: Point2dI(int32_t x, double y); Point2dI(double y, int32_t); - int x_; - int y_; + int x; + int y; }; class Point2dD { @@ -23,8 +23,8 @@ public: Point2dD(int32_t x, double y); Point2dD(double y, int32_t); - double x_; - double y_; + double x; + double y; }; } // namespace common diff --git a/code/ui/Atoms.cpp b/code/ui/Atoms.cpp index b606aa5..400ef20 100644 --- a/code/ui/Atoms.cpp +++ b/code/ui/Atoms.cpp @@ -606,13 +606,13 @@ void Atoms::DrawNumField(const Point2dI &position, size_t width, int32_t value, } auto xWidth = (charWidth / 3); - auto x = position.x_; + auto x = position.x; x += (xWidth) * (width - l); for (const auto &c : number_str) { auto frame = c - '0'; - DrawHandlePic({x, position.y_, 16, 16}, uis.smallNumbers[frame]); + DrawHandlePic({x, position.y, 16, 16}, uis.smallNumbers[frame]); x += xWidth; l--; @@ -1388,8 +1388,8 @@ void Atoms::DrawBannerString2(const common::Point2dI &pos, std::string_view str, trap_R_SetColor(color.values); /*ax = x * uis.scale + uis.bias;*/ - auto ax = pos.x_ * uis.scalex; - auto ay = pos.y_ * uis.scaley; + auto ax = pos.x * uis.scalex; + auto ay = pos.y * uis.scaley; for (auto ch : str) { ch = ch & 255; @@ -1429,11 +1429,11 @@ void Atoms::DrawBannerString(Point2dI pos, std::string_view str, int32_t style, switch (style & UI_FORMATMASK) { case UI_CENTER: - pos.x_ -= width / 2; + pos.x -= width / 2; break; case UI_RIGHT: - pos.x_ -= width; + pos.x -= width; break; case UI_LEFT: @@ -1443,7 +1443,7 @@ void Atoms::DrawBannerString(Point2dI pos, std::string_view str, int32_t style, if (style & UI_DROPSHADOW) { auto drawcolor = common::Color{0, 0, 0, color.a}; - DrawBannerString2({pos.x_ + 2, pos.y_ + 2}, str, drawcolor); + DrawBannerString2({pos.x + 2, pos.y + 2}, str, drawcolor); } DrawBannerString2(pos, str, color); @@ -1505,8 +1505,8 @@ void Atoms::DrawProportionalString2(common::Point2dI pos, std::string_view str, trap_R_SetColor(color.values); /*ax = x * uis.scale + uis.bias;*/ - ax = pos.x_ * uis.scalex; - ay = pos.y_ * uis.scaley; + ax = pos.x * uis.scalex; + ay = pos.y * uis.scaley; holdY = ay; /* TiM - adjust for widescreen monitors */ @@ -1694,13 +1694,13 @@ void Atoms::DrawProportionalString(common::Point2dI pos, std::string_view str, case UI_CENTER: width = static_cast(ProportionalStringWidth(str, charstyle) * sizeScale); - pos.x_ -= width / 2; + pos.x -= width / 2; break; case UI_RIGHT: width = static_cast(ProportionalStringWidth(str, charstyle) * sizeScale); - pos.x_ -= width; + pos.x -= width; break; case UI_LEFT: @@ -1711,7 +1711,7 @@ void Atoms::DrawProportionalString(common::Point2dI pos, std::string_view str, if (style & UI_DROPSHADOW) { drawcolor.r = drawcolor.g = drawcolor.b = 0; drawcolor.a = color.a; - DrawProportionalString2({pos.x_ + 2, pos.y_ + 2}, str, drawcolor, sizeScale, + DrawProportionalString2({pos.x + 2, pos.y + 2}, str, drawcolor, sizeScale, uis.charsetProp); } @@ -1760,7 +1760,7 @@ void Atoms::DrawString2(common::Point2dI pos, std::string_view str, float frow; float fcol; - if (pos.y_ < -charh) { + if (pos.y < -charh) { /* offscreen */ return; } @@ -1769,8 +1769,8 @@ void Atoms::DrawString2(common::Point2dI pos, std::string_view str, trap_R_SetColor(color.values); /* ax = x * uis.scale + uis.bias; */ - ax = pos.x_ * uis.scalex; - ay = pos.y_ * uis.scaley; + ax = pos.x * uis.scalex; + ay = pos.y * uis.scaley; aw = charw * uis.scalex; ah = charh * uis.scaley; @@ -1858,13 +1858,13 @@ void Atoms::DrawString(common::Point2dI pos, std::string_view str, case UI_CENTER: /* center justify at x */ len = str.length(); - pos.x_ = static_cast(pos.x_ - len * charw / 2); + pos.x = static_cast(pos.x - len * charw / 2); break; case UI_RIGHT: /* right justify at x */ len = str.length(); - pos.x_ = static_cast(pos.x_ - len * charw); + pos.x = static_cast(pos.x - len * charw); break; default: @@ -1883,14 +1883,14 @@ void Atoms::DrawString(common::Point2dI pos, std::string_view str, dropcolor.a = drawcolor.a; if (highRes) - DrawProportionalString({pos.x_ + 2, pos.y_ + 2}, str, style, dropcolor); + DrawProportionalString({pos.x + 2, pos.y + 2}, str, style, dropcolor); else - DrawString2({pos.x_ + 2, pos.y_ + 2}, str, dropcolor, charw, charh); + DrawString2({pos.x + 2, pos.y + 2}, str, dropcolor, charw, charh); } /* TiM - Using a different char set now... */ if (!highRes) /* keep the low res version for specific instances */ - DrawString2({pos.x_, pos.y_}, str, drawcolor, charw, charh); + DrawString2({pos.x, pos.y}, str, drawcolor, charw, charh); else DrawProportionalString(pos, str, style, drawcolor); } @@ -1966,7 +1966,7 @@ void Atoms::MouseEvent(const common::Point2dI &delta) { } /* update mouse screen position */ - uis.cursorx += delta.x_; + uis.cursorx += delta.x; /* kinda pointless, but looks nice. allow negative offsets for widescreen * setups (we must maintain the ratio or buttons will stop working) */ if (IsWidescreen() && uis.widescreen.state == WIDESCREEN_CENTER) { @@ -1981,7 +1981,7 @@ void Atoms::MouseEvent(const common::Point2dI &delta) { uis.cursorx = SCREEN_WIDTH; } - uis.cursory += delta.y_; + uis.cursory += delta.y; if (uis.cursory < 0) uis.cursory = 0; else if (uis.cursory > SCREEN_HEIGHT) diff --git a/code/ui/Menu/MenuAction.cpp b/code/ui/Menu/MenuAction.cpp new file mode 100644 index 0000000..d0d10c7 --- /dev/null +++ b/code/ui/Menu/MenuAction.cpp @@ -0,0 +1,28 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuAction.h" +#include "../ui_local.h" + +namespace ui { + +void MenuAction::init() { + auto x = common.position.x; + auto y = common.position.y; + auto w = size.width; + auto h = size.height; + + if (common.flags & QMF_RIGHT_JUSTIFY) { + x = x - w; + } else if (common.flags & QMF_CENTER_JUSTIFY) { + x = x - w / 2; + } + + common.rectangle.left = x; + common.rectangle.right = x + w; + common.rectangle.top = y; + common.rectangle.bottom = y + h; +} + +} // namespace ui diff --git a/code/ui/Menu/MenuAction.h b/code/ui/Menu/MenuAction.h new file mode 100644 index 0000000..2acf701 --- /dev/null +++ b/code/ui/Menu/MenuAction.h @@ -0,0 +1,30 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUACTION_H_ +#define RPGXEF_CODE_UI_MENU_MENUACTION_H_ + +#include "MenuColor.h" +#include "MenuItem.h" +#include "MenuSize.h" + +namespace ui { + +struct MenuAction : MenuItem { + MenuColor color; + struct { + std::size_t id{0}; + std::size_t id2{0}; + common::Point2dI position; + MenuColor color; + } text; + MenuSize size; + bool updated{false}; + + void init() override; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENUACTION_H_ diff --git a/code/ui/Menu/MenuBitmap.cpp b/code/ui/Menu/MenuBitmap.cpp new file mode 100644 index 0000000..46a2727 --- /dev/null +++ b/code/ui/Menu/MenuBitmap.cpp @@ -0,0 +1,39 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuBitmap.h" +#include + +namespace ui { + +void MenuBitmap::init() { + auto x = common.position.x; + auto y = common.position.y; + auto w = size.width; + auto h = size.height; + + if (w < 0) { + w = -w; + } + + if(h < 0) { + h = -h; + } + + if(common.flags & QMF_RIGHT_JUSTIFY) { + x = x - w; + } else if(common.flags & QMF_CENTER_JUSTIFY) { + x = x - w / 2; + } + + common.rectangle.left = x; + common.rectangle.right = x + w; + common.rectangle.top = y; + common.rectangle.bottom = y + h; + + shader.handle = 0; + shader_focus.handle = 0; +} + +} // namespace ui diff --git a/code/ui/Menu/MenuBitmap.h b/code/ui/Menu/MenuBitmap.h new file mode 100644 index 0000000..d7b5f5e --- /dev/null +++ b/code/ui/Menu/MenuBitmap.h @@ -0,0 +1,35 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUBITMAP_H_ +#define RPGXEF_CODE_UI_MENU_MENUBITMAP_H_ + +#include "MenuItem.h" +#include "MenuShader.h" +#include "MenuFocus.h" +#include "MenuColor.h" + +namespace ui { + +struct MenuBitmap : MenuItem { + MenuShader shader; + MenuShader shader_focus; + MenuShader shader_error; + MenuFocus focus; + MenuSize size; + MenuColor color; + struct { + std::size_t id{0}; + std::size_t id2{0}; + common::Point2dI position; + common::Color color; + std::size_t style{0}; + } text; + + void init() override; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENUBITMAP_H_ diff --git a/code/ui/Menu/MenuColor.cpp b/code/ui/Menu/MenuColor.cpp new file mode 100644 index 0000000..509abf5 --- /dev/null +++ b/code/ui/Menu/MenuColor.cpp @@ -0,0 +1,7 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuColor.h" + +namespace ui {} diff --git a/code/ui/Menu/MenuColor.h b/code/ui/Menu/MenuColor.h new file mode 100644 index 0000000..4186246 --- /dev/null +++ b/code/ui/Menu/MenuColor.h @@ -0,0 +1,20 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUCOLOR_H_ +#define RPGXEF_CODE_UI_MENU_MENUCOLOR_H_ + +#include + +namespace ui { + +struct MenuColor { + common::Color normal; + common::Color highlight; + common::Color greyed; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENUCOLOR_H_ diff --git a/code/ui/Menu/MenuCommon.cpp b/code/ui/Menu/MenuCommon.cpp new file mode 100644 index 0000000..0a1ecae --- /dev/null +++ b/code/ui/Menu/MenuCommon.cpp @@ -0,0 +1,5 @@ +// +// Created by Walter on 07.02.2020. +// + +#include "MenuCommon.h" diff --git a/code/ui/Menu/MenuCommon.h b/code/ui/Menu/MenuCommon.h new file mode 100644 index 0000000..a3f9926 --- /dev/null +++ b/code/ui/Menu/MenuCommon.h @@ -0,0 +1,49 @@ +// +// Created by Walter on 07.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUCOMMON_H_ +#define RPGXEF_CODE_UI_MENU_MENUCOMMON_H_ + +#include +#include +#include +#include +#include + +namespace ui { + +class MenuFramework; + +enum class MenuCommonType { + Slider, + Action, + SpinControl, + Field, + RadioButton, + Bitmap, + Text, + ScrollText, + ScrollList, + PText, + BText +}; + +struct MenuCommon { + MenuCommonType type; + std::int32_t id{0}; + common::Point2dI position{}; + common::RectangleI rectangle{}; + std::string name; + std::int32_t menu_position{0}; + std::uint64_t flags; + MenuFramework *parent{nullptr}; + + std::function callback; + std::function statusbar; + std::function ownerdraw; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENUCOMMON_H_ diff --git a/code/ui/Menu/MenuField.cpp b/code/ui/Menu/MenuField.cpp new file mode 100644 index 0000000..28eebd9 --- /dev/null +++ b/code/ui/Menu/MenuField.cpp @@ -0,0 +1,58 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuField.h" +#include "../ui_local.h" +#include "MenuFieldData.h" + +namespace ui { + +void MenuField::init() { + auto l = 0; + auto w = 0; + auto h = 0; + + clear(); + + if (data.style & UI_TINYFONT) { + w = TINYCHAR_WIDTH; + h = TINYCHAR_HEIGHT; + } else if (data.style & UI_BIGFONT) { + w = BIGCHAR_WIDTH; + h = BIGCHAR_HEIGHT; + } else if (data.style & UI_GIANTFONT) { + w = GIANTCHAR_WIDTH; + h = GIANTCHAR_HEIGHT; + } else { + w = SMALLCHAR_WIDTH; + h = SMALLCHAR_HEIGHT; + } + + l = 0; + + if (data.style & UI_CENTER) { + common.rectangle.right = common.position.x + (w + (data.width * w)) / 2; + common.rectangle.bottom = common.position.y + h; + common.rectangle.left = + common.position.x - ((common.rectangle.right - common.position.x)); + common.rectangle.top = common.position.y; + } else { + common.rectangle.left = common.position.x - l; + common.rectangle.top = common.position.y; + common.rectangle.right = common.position.x + w + data.width * w; + common.rectangle.bottom = common.position.y + h; + } + + if (!common.name.empty()) { + common.rectangle.bottom += MENU_BUTTON_MED_HEIGHT + 4; + } +} + +void MenuField::clear() { + data.text.buffer.clear(); + data.cursor = 0; + data.scroll = 0; +} + +} // namespace ui diff --git a/code/ui/Menu/MenuField.h b/code/ui/Menu/MenuField.h new file mode 100644 index 0000000..9f03e20 --- /dev/null +++ b/code/ui/Menu/MenuField.h @@ -0,0 +1,24 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUFIELD_H_ +#define RPGXEF_CODE_UI_MENU_MENUFIELD_H_ + +#include "MenuCommon.h" +#include "MenuFieldData.h" +#include "MenuItem.h" + +namespace ui { + +struct MenuField : MenuItem { + MenuFieldData data; + + void init() override; + + void clear(); +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENUFIELD_H_ diff --git a/code/ui/Menu/MenuFieldData.cpp b/code/ui/Menu/MenuFieldData.cpp new file mode 100644 index 0000000..86e0875 --- /dev/null +++ b/code/ui/Menu/MenuFieldData.cpp @@ -0,0 +1,7 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuFieldData.h" + +namespace ui {} diff --git a/code/ui/Menu/MenuFieldData.h b/code/ui/Menu/MenuFieldData.h new file mode 100644 index 0000000..2b0a873 --- /dev/null +++ b/code/ui/Menu/MenuFieldData.h @@ -0,0 +1,34 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUFIELDDATA_H_ +#define RPGXEF_CODE_UI_MENU_MENUFIELDDATA_H_ + +#include "MenuColor.h" +#include +#include + +namespace ui { + +struct MenuFieldData { + std::int32_t cursor{0}; + std::int32_t scroll{0}; + std::int32_t width{0}; + std::size_t style{0}; + + struct { + std::int32_t id{0}; + MenuColor color; + } title; + + struct { + MenuColor color; + std::size_t max_size{0}; + std::string buffer; + } text; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENUFIELDDATA_H_ diff --git a/code/ui/Menu/MenuFocus.cpp b/code/ui/Menu/MenuFocus.cpp new file mode 100644 index 0000000..f74ef3b --- /dev/null +++ b/code/ui/Menu/MenuFocus.cpp @@ -0,0 +1,7 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuFocus.h" + +namespace ui {} diff --git a/code/ui/Menu/MenuFocus.h b/code/ui/Menu/MenuFocus.h new file mode 100644 index 0000000..f345908 --- /dev/null +++ b/code/ui/Menu/MenuFocus.h @@ -0,0 +1,20 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUFOCUS_H_ +#define RPGXEF_CODE_UI_MENU_MENUFOCUS_H_ + +#include "MenuSize.h" +#include + +namespace ui { + +struct MenuFocus { + common::Point2dI position; + MenuSize size; +}; + +} + +#endif // RPGXEF_CODE_UI_MENU_MENUFOCUS_H_ diff --git a/code/ui/Menu/MenuFramework.cpp b/code/ui/Menu/MenuFramework.cpp new file mode 100644 index 0000000..a928005 --- /dev/null +++ b/code/ui/Menu/MenuFramework.cpp @@ -0,0 +1,26 @@ +// +// Created by Walter on 07.02.2020. +// +#include "MenuFramework.h" +#include "MenuItem.h" +#include + +namespace ui { + +void MenuFramework::setCursor(std::int32_t new_cursor) { + cursor.previous = cursor.current; + cursor.current = new_cursor; +} + +void MenuFramework::addItem(const std::shared_ptr& item) { + items.emplace_back(item); + item->common.parent = this; + item->common.menu_position = items.size(); + item->common.flags &= ~QMF_HASMOUSEFOCUS; + + if(!(item->common.flags & QMF_NODEFAULTINIT)) { + item->init(); + } +} + +} // namespace ui diff --git a/code/ui/Menu/MenuFramework.h b/code/ui/Menu/MenuFramework.h new file mode 100644 index 0000000..d99bf38 --- /dev/null +++ b/code/ui/Menu/MenuFramework.h @@ -0,0 +1,100 @@ +// +// Created by Walter on 07.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUFRAMEWORK_H_ +#define RPGXEF_CODE_UI_MENU_MENUFRAMEWORK_H_ + +#include "../../base_game/q_shared.h" +#include "../../common/Point2d.h" +#include +#include +#include +#include + +namespace ui { + +struct MenuItem; + +class MenuFramework { + struct Cursor { + std::int32_t current = 0; + std::int32_t previous = 0; + }; + + Cursor cursor; + std::vector> items; + bool wrap_around = false; + bool fullscreen = false; + bool no_background = false; + bool initialized = false; + bool no_selecting = false; + common::Point2dI description_position{}; + common::Point2dI list_position{}; + common::Point2dI title_position{}; + std::int32_t title = 0; + std::int32_t foot_note = 0; + + // TODO: add missing spin list + +public: + void toggleWrapAround() { wrap_around = !wrap_around; } + void enableWrapAround() { wrap_around = true; } + void disableWrapAround() { wrap_around = false; } + [[nodiscard]] bool isWrapAround() const { return wrap_around; } + + void toggleFullscreen() { fullscreen = !fullscreen; } + void enableFullscreen() { fullscreen = true; } + void disableFullscreen() { fullscreen = false; } + [[nodiscard]] bool isFullscreen() const { return fullscreen; } + + void toggleNoBackground() { no_background = !no_background; } + void enableNoBackground() { no_background = true; } + void disableNoBackground() { no_background = true; } + [[nodiscard]] bool isNoBackground() const { return no_background; } + + [[nodiscard]] bool isInitialized() const { return initialized; } + + void toggleNoSelecting() { no_selecting = !no_selecting; } + void enableNoSelecting() { no_selecting = true; } + void disableNoSelecting() { no_selecting = false; } + [[nodiscard]] bool isNoSelecting() const { return no_selecting; } + + [[nodiscard]] std::int32_t getCursor() const { return cursor.current; } + void setCursor(std::int32_t new_cursor); + + [[nodiscard]] const std::vector> & + getMenuItems() const { + return items; + } + + void setTitle(std::int32_t _title) { title = _title; } + void resetTitle() { title = 0; } + + void setFootNote(std::int32_t _foot_note) { foot_note = _foot_note; } + void resetFootNote() { foot_note = 0; } + + void setTitlePosition(const common::Point2dI &position) { + title_position = position; + } + void resetTitlePosition() { title_position = {}; } + + void setDescriptionPosition(const common::Point2dI &position) { + description_position = position; + } + void resetDescriptionPosition() { description_position = {}; } + + void setListPosition(const common::Point2dI &position) { + list_position = position; + } + void resetListPosition() { list_position = {}; } + + void addItem(const std::shared_ptr& item); + + std::function draw; + std::function key; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENUFRAMEWORK_H_ diff --git a/code/ui/Menu/MenuGraphics.cpp b/code/ui/Menu/MenuGraphics.cpp new file mode 100644 index 0000000..bf10a38 --- /dev/null +++ b/code/ui/Menu/MenuGraphics.cpp @@ -0,0 +1,7 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuGraphics.h" + +namespace ui {} diff --git a/code/ui/Menu/MenuGraphics.h b/code/ui/Menu/MenuGraphics.h new file mode 100644 index 0000000..50c287b --- /dev/null +++ b/code/ui/Menu/MenuGraphics.h @@ -0,0 +1,33 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUGRAPHICS_H_ +#define RPGXEF_CODE_UI_MENU_MENUGRAPHICS_H_ + +#include "MenuShader.h" +#include "MenuSize.h" +#include +#include +#include + +namespace ui { + +struct MenuGraphics { + std::size_t type{0}; + double timer{0}; + common::Point2dI position; + MenuSize size; + std::string text; + MenuShader graphic; + std::int32_t min{0}; + std::int32_t max{0}; + std::int32_t target{0}; + std::int32_t increment{0}; + std::size_t style{0}; + common::Color color; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENUGRAPHICS_H_ diff --git a/code/ui/Menu/MenuItem.h b/code/ui/Menu/MenuItem.h new file mode 100644 index 0000000..7fb6706 --- /dev/null +++ b/code/ui/Menu/MenuItem.h @@ -0,0 +1,20 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUITEM_H_ +#define RPGXEF_CODE_UI_MENU_MENUITEM_H_ + +#include "MenuCommon.h" + +namespace ui { + +struct MenuItem { + MenuCommon common; + + virtual void init() = 0; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENUITEM_H_ diff --git a/code/ui/Menu/MenuList.cpp b/code/ui/Menu/MenuList.cpp new file mode 100644 index 0000000..4527063 --- /dev/null +++ b/code/ui/Menu/MenuList.cpp @@ -0,0 +1,42 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuList.h" +#include "../ui_local.h" + +namespace ui { + +void MenuList::init() { + if (common.type == MenuCommonType::SpinControl) { + if (list_names.empty() && item_names.empty()) { + return; + } + + // Count number of choices for this spin control + item_number = 0; + + if (!list_names.empty()) { + while (menu_normal_text[list_names.back()] != nullptr) { + item_number++; + } + } else { + item_number = item_names.size(); + } + + if (!focus.size.width && !focus.size.height) { + common.rectangle.left = common.position.x; + common.rectangle.right = common.position.x + MENU_BUTTON_MED_HEIGHT + + MENU_BUTTON_MED_WIDTH + MENU_BUTTON_MED_HEIGHT; + common.rectangle.top = common.position.y; + common.rectangle.bottom = common.position.y + MENU_BUTTON_MED_HEIGHT; + } else { + common.rectangle.left = common.position.x; + common.rectangle.right = common.position.x + focus.size.width; + common.rectangle.top = common.position.y; + common.rectangle.bottom = common.position.y + focus.size.height; + } + } +} + +} // namespace ui diff --git a/code/ui/Menu/MenuList.h b/code/ui/Menu/MenuList.h new file mode 100644 index 0000000..245efde --- /dev/null +++ b/code/ui/Menu/MenuList.h @@ -0,0 +1,65 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENULIST_H_ +#define RPGXEF_CODE_UI_MENU_MENULIST_H_ + +#include "MenuColor.h" +#include "MenuCommon.h" +#include "MenuFocus.h" +#include "MenuItem.h" +#include "MenuSize.h" + +namespace ui { + +struct MenuList : MenuItem { + struct { + std::size_t old{0}; + std::size_t current{0}; + } value; + + std::size_t item_number{0}; + std::size_t top{0}; + MenuSize size; + std::size_t separation{0}; + + MenuColor color; + + struct { + std::size_t id{0}; + common::Point2dI position; + std::size_t flags{0}; + MenuColor color; + } text; + bool updated{false}; + MenuFocus focus; + struct { + common::Point2dI position; + std::size_t flags{0}; + MenuColor color; + } list; + std::size_t max_char_size{0}; + bool ignore_list{false}; + struct { + std::size_t left{0}; + std::size_t right{0}; + std::size_t up{0}; + std::size_t down{0}; + + struct { + std::size_t x{0}; + std::size_t y{0}; + } offset; + } draw_list; + + std::vector item_names; + std::vector list_names; + std::vector list_shaders; + + void init() override; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENULIST_H_ diff --git a/code/ui/Menu/MenuRadioButton.cpp b/code/ui/Menu/MenuRadioButton.cpp new file mode 100644 index 0000000..9d4cb6d --- /dev/null +++ b/code/ui/Menu/MenuRadioButton.cpp @@ -0,0 +1,18 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuRadioButton.h" +#include + +namespace ui { + +void MenuRadioButton::init() { + auto length = common.name.empty() ? 0 : common.name.length(); + common.rectangle.left = common.position.x - (length + 1) * SMALLCHAR_WIDTH; + common.rectangle.right = common.position.x + 6 * SMALLCHAR_WIDTH; + common.rectangle.top = common.position.y; + common.rectangle.bottom = common.position.y + SMALLCHAR_HEIGHT; +} + +} // namespace ui diff --git a/code/ui/Menu/MenuRadioButton.h b/code/ui/Menu/MenuRadioButton.h new file mode 100644 index 0000000..237663c --- /dev/null +++ b/code/ui/Menu/MenuRadioButton.h @@ -0,0 +1,20 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENURADIOBUTTON_H_ +#define RPGXEF_CODE_UI_MENU_MENURADIOBUTTON_H_ + +#include "MenuItem.h" + +namespace ui { + +struct MenuRadioButton : MenuItem { + std::size_t value{0}; + + void init() override; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENURADIOBUTTON_H_ diff --git a/code/ui/Menu/MenuShader.cpp b/code/ui/Menu/MenuShader.cpp new file mode 100644 index 0000000..8ece303 --- /dev/null +++ b/code/ui/Menu/MenuShader.cpp @@ -0,0 +1,7 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuShader.h" + +namespace ui {} diff --git a/code/ui/Menu/MenuShader.h b/code/ui/Menu/MenuShader.h new file mode 100644 index 0000000..541e8e3 --- /dev/null +++ b/code/ui/Menu/MenuShader.h @@ -0,0 +1,20 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUSHADER_H_ +#define RPGXEF_CODE_UI_MENU_MENUSHADER_H_ + +#include +#include + +namespace ui { + +struct MenuShader { + std::string name; + qhandle_t handle; +}; + +} + +#endif // RPGXEF_CODE_UI_MENU_MENUSHADER_H_ diff --git a/code/ui/Menu/MenuSize.cpp b/code/ui/Menu/MenuSize.cpp new file mode 100644 index 0000000..16bfcb4 --- /dev/null +++ b/code/ui/Menu/MenuSize.cpp @@ -0,0 +1,7 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuSize.h" + +namespace ui{} diff --git a/code/ui/Menu/MenuSize.h b/code/ui/Menu/MenuSize.h new file mode 100644 index 0000000..76691e6 --- /dev/null +++ b/code/ui/Menu/MenuSize.h @@ -0,0 +1,19 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUSIZE_H_ +#define RPGXEF_CODE_UI_MENU_MENUSIZE_H_ + +#include + +namespace ui { + +struct MenuSize { + std::size_t width{0}; + std::size_t height{0}; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENUSIZE_H_ diff --git a/code/ui/Menu/MenuSlider.cpp b/code/ui/Menu/MenuSlider.cpp new file mode 100644 index 0000000..b0dd725 --- /dev/null +++ b/code/ui/Menu/MenuSlider.cpp @@ -0,0 +1,36 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuSlider.h" +#include + +namespace ui { + +void MenuSlider::init() { + if (picture.position.x) { + common.rectangle.left = picture.position.x; + common.rectangle.right = picture.position.x + focus.size.width; + common.rectangle.top = picture.position.y; + common.rectangle.bottom = picture.position.y + focus.size.height; + } else { + common.rectangle.left = common.position.x; + common.rectangle.right = common.position.x + focus.size.width; + common.rectangle.top = common.position.y; + common.rectangle.bottom = common.position.y + focus.size.height; + } + + if (!thumb.name.empty()) { + thumb.shader = trap_R_RegisterShaderNoMip(thumb.name.c_str()); + } + + if (!picture.name.empty()) { + picture.shader = trap_R_RegisterShaderNoMip(picture.name.c_str()); + } + + if (!common.name.empty()) { + graph.shader = trap_R_RegisterShaderNoMip(common.name.c_str()); + } +} + +} // namespace ui diff --git a/code/ui/Menu/MenuSlider.h b/code/ui/Menu/MenuSlider.h new file mode 100644 index 0000000..ae882c4 --- /dev/null +++ b/code/ui/Menu/MenuSlider.h @@ -0,0 +1,62 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUSLIDER_H_ +#define RPGXEF_CODE_UI_MENU_MENUSLIDER_H_ + +#include "MenuColor.h" +#include "MenuCommon.h" +#include "MenuFocus.h" +#include "MenuItem.h" +#include "MenuSize.h" +#include + +namespace ui { + +struct MenuSlider : MenuItem { + struct { + double min{0}; + double max{0}; + double current{0}; + double def{0}; + } value; + + MenuFocus focus; + MenuColor color; + + struct { + std::int32_t shader{0}; + MenuSize size; + } graph; + + struct { + std::string name; + std::int32_t shader{0}; + MenuColor color; + MenuSize size; + std::int32_t graphic_width{0}; + } thumb; + + struct { + std::string name; + std::int32_t shader{0}; + MenuSize size; + common::Point2dI position; + } picture; + + struct { + std::int32_t id{0}; + common::Point2dI position; + MenuColor color; + } text; + + double range{0}; + bool mouse_down{false}; + + void init() override; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENUSLIDER_H_ diff --git a/code/ui/Menu/MenuText.cpp b/code/ui/Menu/MenuText.cpp new file mode 100644 index 0000000..f456585 --- /dev/null +++ b/code/ui/Menu/MenuText.cpp @@ -0,0 +1,114 @@ +// +// Created by Walter on 08.02.2020. +// + +#include "MenuText.h" +#include + +namespace ui { + +void MenuText::init() { + auto x{0}; + auto y{0}; + auto w{0}; + auto h{0}; + auto buffer = std::string{}; + auto buffer_2 = std::string{}; + auto buffer_3 = std::string{}; + + if (focus.position.x) { + x = focus.position.x; + y = focus.position.y; + w = focus.size.width; + h = focus.size.height; + } else { + auto w_2{0}; + auto w_3{0}; + + if (text_button.id) { + if (menu_button_text[text_button.id][0]) { + buffer = menu_button_text[text_button.id][0]; + w = UI_ProportionalStringWidth(buffer.c_str(), style); + } + + if (text_button.id_2 && menu_button_text[text_button.id_2][0]) { + buffer_2 = menu_button_text[text_button.id_2][0]; + w_2 = UI_ProportionalStringWidth(buffer_2.c_str(), style); + } + + if (text_button.id_3 && menu_button_text[text_button.id_3][0]) { + buffer_3 = menu_button_text[text_button.id_3][0]; + w_3 = UI_ProportionalStringWidth(buffer_3.c_str(), style); + } + + if ((w > w_2) && (w > w_3)) { + } else if ((w_2 > w) && (w_2 > w_3)) { + w = w_2; + } else if ((w_3 > 2) && (w_3 > w_2)) { + w = w_3; + } + } else if (text_normal.id) { + w = w_2 = w_3 = 0; + + if (menu_button_text[text_normal.id][0]) { + buffer = menu_button_text[text_normal.id][0]; + w = UI_ProportionalStringWidth(buffer.c_str(), style); + } + + if (text_normal.id_2 && menu_button_text[text_normal.id_2][0]) { + buffer_2 = menu_button_text[text_normal.id_2][0]; + w_2 = UI_ProportionalStringWidth(buffer_2.c_str(), style); + } + + if (text_normal.id_3 && menu_button_text[text_normal.id_3][0]) { + buffer_3 = menu_button_text[text_normal.id_3][0]; + w_3 = UI_ProportionalStringWidth(buffer_3.c_str(), style); + } + + if ((w > w_2) && (w > w_3)) { + } else if ((w_2 > w) && (w_2 > w_3)) { + w = w_2; + } else if ((w_3 > 2) && (w_3 > w_2)) { + w = w_3; + } + } else if (!common.name.empty()) { + w = UI_ProportionalStringWidth(common.name.c_str(), style); + } + + x = common.position.x; + y = common.position.y; + + auto lines = 0; + if (!buffer_2.empty()) { + lines++; + if (!buffer_3.empty()) { + lines++; + } + } + + if (style & UI_TINYFONT) { + h = PROP_TINY_HEIGHT; + } else if (style & UI_SMALLFONT) { + h = SMALLCHAR_HEIGHT; + } else if (style & UI_BIGFONT) { + h = PROP_BIG_HEIGHT; + } else { + h = SMALLCHAR_HEIGHT; + } + + h += (lines * (h * 1.25)); + } + + if (common.flags & QMF_RIGHT_JUSTIFY) { + x = x - w; + } else if (common.flags & QMF_CENTER_JUSTIFY) { + x = x - w / 2; + } + + common.rectangle.left = x; + common.rectangle.right = x + w; + common.rectangle.top = y; + common.rectangle.bottom = y + h; +} + +} // namespace ui diff --git a/code/ui/Menu/MenuText.h b/code/ui/Menu/MenuText.h new file mode 100644 index 0000000..4f5c6ae --- /dev/null +++ b/code/ui/Menu/MenuText.h @@ -0,0 +1,35 @@ +// +// Created by Walter on 08.02.2020. +// + +#ifndef RPGXEF_CODE_UI_MENU_MENUTEXT_H_ +#define RPGXEF_CODE_UI_MENU_MENUTEXT_H_ + +#include "MenuColor.h" +#include "MenuFocus.h" +#include "MenuItem.h" + +namespace ui { + +struct MenuText : MenuItem { + std::string text; + struct { + std::size_t id{0}; + std::size_t id_2{0}; + std::size_t id_3{0}; + } text_normal; + struct { + std::size_t id{0}; + std::size_t id_2{0}; + std::size_t id_3{0}; + } text_button; + std::size_t style{0}; + MenuColor color; + MenuFocus focus; + + void init() override; +}; + +} // namespace ui + +#endif // RPGXEF_CODE_UI_MENU_MENUTEXT_H_