Add various menu classes

This commit is contained in:
Walter Julius Hennecke 2020-02-12 22:46:49 +01:00
parent 42251d4180
commit b8cfe15946
35 changed files with 1039 additions and 45 deletions

View File

@ -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);
}

View File

@ -9,15 +9,15 @@ namespace common {
template <typename T> class Point2d {
public:
constexpr Point2d() : x_{0}, y_{0} {}
constexpr Point2d() : x{0}, y{0} {}
template <typename A, typename B,
typename = std::enable_if_t<std::is_convertible_v<A, T> &&
std::is_convertible_v<B, T>>>
constexpr Point2d(A x, B y) : x_{static_cast<T>(x)}, y_{static_cast<T>(y)} {}
T x_;
T y_;
constexpr Point2d(A x, B y) : x{static_cast<T>(x)}, y{static_cast<T>(y)} {}
T x;
T y;
};
using Point2dI = Point2d<int32_t>;

View File

@ -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

View File

@ -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<size_t>(ProportionalStringWidth(str, charstyle) *
sizeScale);
pos.x_ -= width / 2;
pos.x -= width / 2;
break;
case UI_RIGHT:
width = static_cast<size_t>(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<int32_t>(pos.x_ - len * charw / 2);
pos.x = static_cast<int32_t>(pos.x - len * charw / 2);
break;
case UI_RIGHT:
/* right justify at x */
len = str.length();
pos.x_ = static_cast<int32_t>(pos.x_ - len * charw);
pos.x = static_cast<int32_t>(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)

View File

@ -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

30
code/ui/Menu/MenuAction.h Normal file
View File

@ -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_

View File

@ -0,0 +1,39 @@
//
// Created by Walter on 08.02.2020.
//
#include "MenuBitmap.h"
#include <ui/ui_local.h>
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

35
code/ui/Menu/MenuBitmap.h Normal file
View File

@ -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_

View File

@ -0,0 +1,7 @@
//
// Created by Walter on 08.02.2020.
//
#include "MenuColor.h"
namespace ui {}

20
code/ui/Menu/MenuColor.h Normal file
View File

@ -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 <common/Color.h>
namespace ui {
struct MenuColor {
common::Color normal;
common::Color highlight;
common::Color greyed;
};
} // namespace ui
#endif // RPGXEF_CODE_UI_MENU_MENUCOLOR_H_

View File

@ -0,0 +1,5 @@
//
// Created by Walter on 07.02.2020.
//
#include "MenuCommon.h"

49
code/ui/Menu/MenuCommon.h Normal file
View File

@ -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 <cinttypes>
#include <common/Point2d.h>
#include <common/Rectangle.h>
#include <functional>
#include <memory>
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<void(std::int32_t)> callback;
std::function<void()> statusbar;
std::function<void()> ownerdraw;
};
} // namespace ui
#endif // RPGXEF_CODE_UI_MENU_MENUCOMMON_H_

View File

@ -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

24
code/ui/Menu/MenuField.h Normal file
View File

@ -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_

View File

@ -0,0 +1,7 @@
//
// Created by Walter on 08.02.2020.
//
#include "MenuFieldData.h"
namespace ui {}

View File

@ -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 <cinttypes>
#include <string>
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_

View File

@ -0,0 +1,7 @@
//
// Created by Walter on 08.02.2020.
//
#include "MenuFocus.h"
namespace ui {}

20
code/ui/Menu/MenuFocus.h Normal file
View File

@ -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 <common/Point2d.h>
namespace ui {
struct MenuFocus {
common::Point2dI position;
MenuSize size;
};
}
#endif // RPGXEF_CODE_UI_MENU_MENUFOCUS_H_

View File

@ -0,0 +1,26 @@
//
// Created by Walter on 07.02.2020.
//
#include "MenuFramework.h"
#include "MenuItem.h"
#include <ui/ui_local.h>
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<MenuItem>& 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

View File

@ -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 <cstdint>
#include <functional>
#include <memory>
#include <vector>
namespace ui {
struct MenuItem;
class MenuFramework {
struct Cursor {
std::int32_t current = 0;
std::int32_t previous = 0;
};
Cursor cursor;
std::vector<std::shared_ptr<MenuItem>> 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<std::shared_ptr<MenuItem>> &
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<MenuItem>& item);
std::function<void()> draw;
std::function<sfxHandle_t(std::int32_t key)> key;
};
} // namespace ui
#endif // RPGXEF_CODE_UI_MENU_MENUFRAMEWORK_H_

View File

@ -0,0 +1,7 @@
//
// Created by Walter on 08.02.2020.
//
#include "MenuGraphics.h"
namespace ui {}

View File

@ -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 <cinttypes>
#include <common/Color.h>
#include <common/Point2d.h>
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_

20
code/ui/Menu/MenuItem.h Normal file
View File

@ -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_

42
code/ui/Menu/MenuList.cpp Normal file
View File

@ -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

65
code/ui/Menu/MenuList.h Normal file
View File

@ -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<std::string> item_names;
std::vector<std::int32_t> list_names;
std::vector<std::int32_t> list_shaders;
void init() override;
};
} // namespace ui
#endif // RPGXEF_CODE_UI_MENU_MENULIST_H_

View File

@ -0,0 +1,18 @@
//
// Created by Walter on 08.02.2020.
//
#include "MenuRadioButton.h"
#include <base_game/q_shared.h>
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

View File

@ -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_

View File

@ -0,0 +1,7 @@
//
// Created by Walter on 08.02.2020.
//
#include "MenuShader.h"
namespace ui {}

20
code/ui/Menu/MenuShader.h Normal file
View File

@ -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 <string>
#include <base_game/q_shared.h>
namespace ui {
struct MenuShader {
std::string name;
qhandle_t handle;
};
}
#endif // RPGXEF_CODE_UI_MENU_MENUSHADER_H_

View File

@ -0,0 +1,7 @@
//
// Created by Walter on 08.02.2020.
//
#include "MenuSize.h"
namespace ui{}

19
code/ui/Menu/MenuSize.h Normal file
View File

@ -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 <cinttypes>
namespace ui {
struct MenuSize {
std::size_t width{0};
std::size_t height{0};
};
} // namespace ui
#endif // RPGXEF_CODE_UI_MENU_MENUSIZE_H_

View File

@ -0,0 +1,36 @@
//
// Created by Walter on 08.02.2020.
//
#include "MenuSlider.h"
#include <ui/ui_local.h>
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

62
code/ui/Menu/MenuSlider.h Normal file
View File

@ -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 <common/Point2d.h>
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_

114
code/ui/Menu/MenuText.cpp Normal file
View File

@ -0,0 +1,114 @@
//
// Created by Walter on 08.02.2020.
//
#include "MenuText.h"
#include <ui/ui_local.h>
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

35
code/ui/Menu/MenuText.h Normal file
View File

@ -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_