commit current changes

This commit is contained in:
Walter Julius Hennecke 2020-06-13 10:19:22 +02:00
parent b8cfe15946
commit 19bf1137ac
32 changed files with 3715 additions and 2920 deletions

View file

@ -10,16 +10,6 @@ qboolean ClientNCSpec = qtrue; //RPG-X J2J: Private flag for weather the cli
/* float Q_powf ( float x, int y ); */
float Com_Clamp( float min, float max, float value ) {
if ( value < min ) {
return min;
}
if ( value > max ) {
return max;
}
return value;
}
/*
============

File diff suppressed because it is too large Load diff

22
code/common/BitTools.cpp Normal file
View file

@ -0,0 +1,22 @@
#include "BitTools.h"
#include <catch2/catch.hpp>
namespace common {
static_assert(!bit_in(0, 1));
static_assert(!bit_in(0, 2));
static_assert(bit_in(1,1));
static_assert(bit_in(3, 1));
static_assert(bit_in(7, 4));
static_assert(!bit_in(5, 2));
TEST_CASE("bit_in") {
REQUIRE(!bit_in(0, 1));
REQUIRE(!bit_in(0, 2));
REQUIRE(bit_in(1,1));
REQUIRE(bit_in(3, 1));
REQUIRE(bit_in(7, 4));
REQUIRE(!bit_in(5, 2));
}
}

35
code/common/BitTools.h Normal file
View file

@ -0,0 +1,35 @@
#pragma once
#include <type_traits>
namespace common {
template <
typename A, typename B,
typename = std::enable_if_t<std::is_integral_v<A> && std::is_integral_v<B>>>
constexpr bool bit_in(A bits, B bit) {
return (bits & bit) == bit;
}
template <typename A, typename B, bool D1 = true,
typename = std::enable_if_t<std::is_enum_v<A> &&
std::is_integral_v<B> && D1>>
constexpr bool bit_in(A bits, B bit) {
return (static_cast<std::underlying_type_t<A>>(bits) & bit) == bit;
}
template <typename A, typename B, bool D1 = true, bool D2 = true,
typename = std::enable_if_t<std::is_integral_v<A> &&
std::is_enum_v<B> && D1 && D2>>
constexpr bool bit_in(A bits, B bit) {
return (bits & static_cast<std::underlying_type_t<B>>(bit)) == bit;
}
template <typename A, typename B, bool D1 = true, bool D2 = true,
bool D3 = true,
typename = std::enable_if_t<std::is_enum_v<A> && std::is_enum_v<B> &&
D1 && D2 && D3>>
constexpr bool bit_in(A bits, B bit) {
return (bits & bit) == bit;
}
} // namespace common

View file

@ -1,6 +1,14 @@
#include "Random.h"
#include <catch2/catch.hpp>
namespace common {
int getRandomInt() { return getRandomInt<int>(); }
double getRandomDouble() { return getRandomDouble<double>(); }
} // namespace common
TEST_CASE("random_int", "[common::getRandom]") {
for (auto x = 0; x < 1000; x++) {
auto i = common::getRandomInt<int>();

View file

@ -23,9 +23,7 @@ T getRandomInt() {
std::numeric_limits<T>::max());
}
int getRandomInt() {
return getRandomInt<int>();
}
int getRandomInt();
template <typename T, bool Dummy = true,
typename = std::enable_if_t<std::is_floating_point_v<T> && Dummy>>
@ -49,8 +47,6 @@ T getRandomDouble() {
std::numeric_limits<T>::max());
}
double getRandomDouble() {
return getRandomDouble<double>();
}
double getRandomDouble();
} // namespace common

View file

@ -3,7 +3,9 @@
//
#include "MenuAction.h"
#include "../ui_local.h"
#include "MenuFramework.h"
#include <common/BitTools.h>
#include <ui/Atoms.h>
namespace ui {
@ -13,9 +15,9 @@ void MenuAction::init() {
auto w = size.width;
auto h = size.height;
if (common.flags & QMF_RIGHT_JUSTIFY) {
if (common.right_justify()) {
x = x - w;
} else if (common.flags & QMF_CENTER_JUSTIFY) {
} else if (common.center_justify()) {
x = x - w / 2;
}
@ -25,4 +27,53 @@ void MenuAction::init() {
common.rectangle.bottom = y + h;
}
void MenuAction::draw() {
auto button_color = common::Color{};
auto text_color = common::Color{};
auto style = 0;
if (common.grayed()) {
button_color = color.greyed;
text_color = text.color.greyed;
} else if (common.pulse_if_focus() && common.has_focus()) {
button_color = color.highlight;
text_color = text.color.highlight;
style = UI_PULSE;
} else if (common.highlight_if_focus() && common.has_focus()) {
button_color = color.highlight;
text_color = text.color.highlight;
} else if (common.blink()) {
if ((uis.realtime / BLINK_DIVISOR) & 1) {
button_color = color.normal;
text_color = text.color.normal;
} else {
button_color = color.highlight;
text_color = color.highlight;
}
style = UI_BLINK;
} else {
button_color = color.normal;
text_color = text.color.normal;
}
const auto x = common.position.x;
const auto y = common.position.y;
trap_R_SetColor(button_color.values);
Atoms::DrawHandlePic({x, y}, uis.whiteShader);
if (menu_button_text[text.id][0]) {
Atoms::DrawProportionalString({x + text.position.x, y + text.position.y},
menu_button_text[text.id][0],
style | UI_SMALLFONT, text_color);
}
if (text.id2 > 0) {
auto inc_y = common::bit_in(style, UI_SMALLFONT) ? PROP_HEIGHT * 1.15
: PROP_TINY_HEIGHT * 1.15;
Atoms::DrawProportionalString(
{x + text.position.x, y + text.position.y + inc_y},
menu_button_text[text.id2][0], style, text_color);
}
}
} // namespace ui

View file

@ -23,6 +23,7 @@ struct MenuAction : MenuItem {
bool updated{false};
void init() override;
void draw() override;
};
} // namespace ui

View file

@ -3,6 +3,9 @@
//
#include "MenuBitmap.h"
#include "MenuFramework.h"
#include <common/BitTools.h>
#include <ui/Atoms.h>
#include <ui/ui_local.h>
namespace ui {
@ -17,13 +20,13 @@ void MenuBitmap::init() {
w = -w;
}
if(h < 0) {
if (h < 0) {
h = -h;
}
if(common.flags & QMF_RIGHT_JUSTIFY) {
if (common.right_justify()) {
x = x - w;
} else if(common.flags & QMF_CENTER_JUSTIFY) {
} else if (common.center_justify()) {
x = x - w / 2;
}
@ -36,4 +39,109 @@ void MenuBitmap::init() {
shader_focus.handle = 0;
}
void MenuBitmap::draw() {
auto text_style = text.style;
auto x = common.position.x;
auto y = common.position.y;
const auto w = size.width;
const auto h = size.height;
auto highlight = false;
if (common.right_justify()) {
x = x - w;
} else if (common.center_justify()) {
x = x - w / 2;
}
if (common.grayed()) {
if (shader) {
trap_R_SetColor(common::Color::MediumGrey.values);
Atoms::DrawHandlePic({x, y, w, h}, shader.handle);
trap_R_SetColor(nullptr);
}
} else if ((common.highlight_if_focus() && common.has_focus()) ||
common.highlight()) {
trap_R_SetColor(color.highlight.values);
highlight = true;
if (shader) {
Atoms::DrawHandlePic({x, y, w, h}, shader.handle);
}
if (menu_button_text[text.id][1]) {
Atoms::DrawProportionalString(
common.parent->getDescriptionPosition(), menu_button_text[text.id][1],
UI_LEFT | UI_TINYFONT, common::Color::Black);
}
trap_R_SetColor(nullptr);
} else {
if (shader) {
trap_R_SetColor(color.normal.values);
Atoms::DrawHandlePic({x, y, w, h}, shader.handle);
}
if (common.pulse() || (common.pulse_if_focus() && common.has_focus())) {
auto c = color.highlight;
c.a = 0.5 * 0.5 * std::sin(uis.realtime / PULSE_DIVISOR);
trap_R_SetColor(c.values);
Atoms::DrawHandlePic({x, y, w, h}, shader_focus.handle);
trap_R_SetColor(nullptr);
} else if (common.highlight() ||
(common.highlight_if_focus() && common.has_focus())) {
trap_R_SetColor(color.highlight.values);
Atoms::DrawHandlePic({x, y, w, h}, shader_focus.handle);
trap_R_SetColor(nullptr);
}
}
if (text) {
auto color_i = common::Color{};
if (common.highlight()) {
color_i = text.color.highlight;
} else {
color_i = text.color.normal;
}
Atoms::DrawProportionalString({x + text.position.x, y + text.position.y},
text.get_text(), text_style, color_i);
const auto text_2 = text.get_text_2();
if (!text_2.empty()) {
auto inc_y = 0;
if (common::bit_in(text_style, UI_SMALLFONT)) {
inc_y = PROP_HEIGHT * 1.15;
} else if (common::bit_in(text_style, UI_TINYFONT)) {
inc_y = PROP_TINY_HEIGHT * 1.15;
} else {
inc_y = PROP_HEIGHT * 1.15;
}
Atoms::DrawProportionalString(
{x + text.position.x, y + text.position.y + inc_y}, text_2,
text_style, color_i);
}
}
}
MenuBitmap::MenuBitmapText::operator bool() const {
return id > 0 || !text.empty();
}
std::string_view MenuBitmap::MenuBitmapText::get_text() const {
if (id > 0 && menu_button_text[id][0]) {
return menu_button_text[id][0];
}
return text;
}
std::string_view MenuBitmap::MenuBitmapText::get_text_2() const {
if (id2 > 0 && menu_button_text[id2][0]) {
return menu_button_text[id2][0];
}
return text_2;
}
} // namespace ui

View file

@ -19,15 +19,22 @@ struct MenuBitmap : MenuItem {
MenuFocus focus;
MenuSize size;
MenuColor color;
struct {
struct MenuBitmapText {
std::size_t id{0};
std::size_t id2{0};
common::Point2dI position;
common::Color color;
MenuColor color;
std::size_t style{0};
std::string text;
std::string text_2;
[[nodiscard]] std::string_view get_text() const;
[[nodiscard]] std::string_view get_text_2() const;
operator bool() const;
} text;
void init() override;
void draw() override;
};
} // namespace ui

35
code/ui/Menu/MenuColors.h Normal file
View file

@ -0,0 +1,35 @@
//
// Created by Walter on 24.04.2020.
//
#ifndef RPGXEF_CODE_UI_MENU_MENUCOLORS_H_
#define RPGXEF_CODE_UI_MENU_MENUCOLORS_H_
#include <common/Color.h>
namespace ui {
struct colors {
static inline constexpr const common::Color menu_text{1.0, 1.0, 1.0, 1.0};
static inline constexpr const common::Color menu_dim{0.0, 0.0, 0.0, 0.75};
static inline constexpr const common::Color white{1.0, 1.0, 1.0, 1.0};
static inline constexpr const common::Color yellow{1.0, 1.0, 0.0, 1.0};
static inline constexpr const common::Color blue{0.0, 0.0, 1.0, 1.0};
static inline constexpr const common::Color light_orange{1.0, 0.68, 0.0, 1.0};
static inline constexpr const common::Color orange{1.0, 0.43, 0.0, 1.0};
static inline constexpr const common::Color red{1.0, 0.0, 0.0, 1.0};
static inline constexpr const common::Color dim{0.0, 0.0, 0.0, 0.25};
static inline constexpr const common::Color pulse_color{1.0, 1.0, 1.0, 1.0};
static inline constexpr const common::Color text_disabled{0.5, 0.5, 0.5, 1.0};
static inline constexpr const common::Color text_normal{1.0, 0.43, 0.0, 1.0};
static inline constexpr const common::Color text_highlight{1.0, 1.0, 0.0,
1.0};
static inline constexpr const common::Color listbar_color{1.0, 0.43, 0.0,
0.3};
static inline constexpr const common::Color text_status{1.0, 1.0, 1.0, 1.0};
};
} // namespace ui
#endif // RPGXEF_CODE_UI_MENU_MENUCOLORS_H_

View file

@ -3,3 +3,260 @@
//
#include "MenuCommon.h"
#include "MenuFramework.h"
#include <common/BitTools.h>
#include <ui/ui_local.h>
namespace ui {
bool MenuCommon::has_flags(std::uint64_t required_flags) const {
return common::bit_in(flags, required_flags);
}
bool MenuCommon::blink() const { return has_flags(QMF_BLINK); }
bool MenuCommon::small_font() const { return has_flags(QMF_SMALLFONT); }
bool MenuCommon::center_justify() const {
return has_flags(QMF_CENTER_JUSTIFY);
}
bool MenuCommon::left_justify() const { return has_flags(QMF_LEFT_JUSTIFY); }
bool MenuCommon::right_justify() const { return has_flags(QMF_RIGHT_JUSTIFY); }
bool MenuCommon::numbers_only() const { return has_flags(QMF_NUMBERSONLY); }
bool MenuCommon::highlight() const { return has_flags(QMF_HIGHLIGHT); }
bool MenuCommon::highlight_if_focus() const {
return has_flags(QMF_HIGHLIGHT_IF_FOCUS);
}
bool MenuCommon::pulse_if_focus() const { return has_flags(QMF_PULSEIFFOCUS); }
bool MenuCommon::has_mouse_focus() const {
return has_flags(QMF_HASMOUSEFOCUS);
}
bool MenuCommon::no_on_off_text() const { return has_flags(QMF_NOONOFFTEXT); }
bool MenuCommon::mouse_only() const { return has_flags(QMF_MOUSEONLY); }
bool MenuCommon::hidden() const { return has_flags(QMF_HIDDEN); }
bool MenuCommon::grayed() const { return has_flags(QMF_GRAYED); }
bool MenuCommon::inactive() const { return has_flags(QMF_INACTIVE); }
bool MenuCommon::no_default_init() const {
return has_flags(QMF_NODEFAULTINIT);
}
bool MenuCommon::owner_draw() const { return has_flags(QMF_OWNERDRAW); }
bool MenuCommon::pulse() const { return has_flags(QMF_PULSE); }
bool MenuCommon::lower_case() const { return has_flags(QMF_LOWERCASE); }
bool MenuCommon::upper_case() const { return has_flags(QMF_UPPERCASE); }
bool MenuCommon::silent() const { return has_flags(QMF_SILENT); }
bool MenuCommon::alternate() const { return has_flags(QMF_ALTERNATE); }
bool MenuCommon::alternate_2() const { return has_flags(QMF_ALTERNATE2); }
[[maybe_unused]] void MenuCommon::toggle_blink() { flags ^= QMF_BLINK; }
void MenuCommon::toggle_small_fond() { flags ^= QMF_SMALLFONT; }
void MenuCommon::enable_blink() { flags |= QMF_BLINK; }
void MenuCommon::disable_blink() { flags &= ~QMF_BLINK; }
void MenuCommon::enable_small_font() { flags |= QMF_SMALLFONT; }
void MenuCommon::disable_small_font() { flags &= ~QMF_SMALLFONT; }
void MenuCommon::toggle_center_justify() {
flags &= ~QMF_RIGHT_JUSTIFY;
flags &= ~QMF_LEFT_JUSTIFY;
flags ^= QMF_CENTER_JUSTIFY;
}
void MenuCommon::enable_center_justify() {
flags &= ~QMF_LEFT_JUSTIFY;
flags &= ~QMF_RIGHT_JUSTIFY;
flags |= QMF_CENTER_JUSTIFY;
}
void MenuCommon::disable_center_justify() { flags &= ~QMF_CENTER_JUSTIFY; }
void MenuCommon::toggle_left_justify() {
flags &= ~QMF_CENTER_JUSTIFY;
flags &= ~QMF_RIGHT_JUSTIFY;
flags ^= QMF_LEFT_JUSTIFY;
}
void MenuCommon::enable_left_justify() {
flags &= ~QMF_RIGHT_JUSTIFY;
flags &= ~QMF_CENTER_JUSTIFY;
flags |= QMF_CENTER_JUSTIFY;
}
void MenuCommon::disable_left_justify() { flags &= ~QMF_CENTER_JUSTIFY; }
void MenuCommon::toggle_right_justify() {
flags &= ~QMF_LEFT_JUSTIFY;
flags &= QMF_CENTER_JUSTIFY;
flags ^= QMF_RIGHT_JUSTIFY;
}
void MenuCommon::enable_right_justify() {
flags &= ~QMF_LEFT_JUSTIFY;
flags &= ~QMF_CENTER_JUSTIFY;
flags |= QMF_RIGHT_JUSTIFY;
}
void MenuCommon::disable_right_justify() { flags &= ~QMF_RIGHT_JUSTIFY; }
void MenuCommon::toggle_numbers_only() { flags ^= QMF_MOUSEONLY; }
void MenuCommon::enable_numbers_only() { flags |= QMF_NUMBERSONLY; }
void MenuCommon::disable_numbers_only() { flags &= ~QMF_NUMBERSONLY; }
void MenuCommon::toggle_highlight() { flags ^= QMF_HIGHLIGHT; }
void MenuCommon::enable_highlight() { flags |= QMF_HIGHLIGHT; }
void MenuCommon::disable_highlight() { flags &= ~QMF_HIGHLIGHT; }
void MenuCommon::toogle_highlight_if_focus() {
flags ^= QMF_HIGHLIGHT_IF_FOCUS;
}
void MenuCommon::enable_highlight_if_focus() {
flags |= QMF_HIGHLIGHT_IF_FOCUS;
}
void MenuCommon::disable_highlight_if_focus() {
flags &= ~QMF_HIGHLIGHT_IF_FOCUS;
}
void MenuCommon::toggle_pulse_if_focus() { flags ^= QMF_PULSEIFFOCUS; }
void MenuCommon::enable_pulse_if_focus() { flags |= QMF_PULSEIFFOCUS; }
void MenuCommon::disable_pulse_if_focus() { flags &= ~QMF_PULSEIFFOCUS; }
void MenuCommon::toggle_has_mouse_focus() { flags ^= QMF_HASMOUSEFOCUS; }
void MenuCommon::enable_has_mouse_focus() { flags |= QMF_HASMOUSEFOCUS; }
void MenuCommon::disable_has_mouse_focus() { flags &= ~QMF_HASMOUSEFOCUS; }
void MenuCommon::toggle_no_on_off_text() { flags ^= QMF_NOONOFFTEXT; }
void MenuCommon::enable_no_on_off_text() { flags |= QMF_NOONOFFTEXT; }
void MenuCommon::disable_no_on_off_text() { flags &= ~QMF_NOONOFFTEXT; }
void MenuCommon::toggle_mouse_only() { flags ^= QMF_MOUSEONLY; }
void MenuCommon::enable_mouse_only() { flags |= QMF_MOUSEONLY; }
void MenuCommon::disable_mouse_only() { flags &= ~QMF_MOUSEONLY; }
void MenuCommon::hide() { flags |= QMF_HIDDEN; }
void MenuCommon::show() { flags &= ~QMF_HIDDEN; }
void MenuCommon::toggle_grayed() { flags ^= QMF_GRAYED; }
void MenuCommon::enable_grayed() { flags |= QMF_GRAYED; }
void MenuCommon::disable_grayed() { flags &= ~QMF_GRAYED; }
void MenuCommon::activate() { flags &= ~QMF_INACTIVE; }
void MenuCommon::deactivate() { flags |= QMF_INACTIVE; }
void MenuCommon::enable_no_default_init() { flags |= QMF_NODEFAULTINIT; }
void MenuCommon::disable_no_default_init() { flags &= ~QMF_NODEFAULTINIT; }
void MenuCommon::enable_owner_draw() { flags |= QMF_OWNERDRAW; }
void MenuCommon::disable_owner_draw() { flags &= ~QMF_OWNERDRAW; }
void MenuCommon::toggle_pulse() { flags ^= QMF_PULSE; }
void MenuCommon::enable_pulse() { flags |= QMF_PULSE; }
void MenuCommon::disable_pulse() { flags &= ~QMF_PULSE; }
void MenuCommon::toggle_lower_case() {
if (lower_case()) {
disable_lower_case();
} else {
disable_upper_case();
enable_lower_case();
}
}
void MenuCommon::enable_lower_case() {
flags &= ~QMF_UPPERCASE;
flags |= QMF_LOWERCASE;
}
void MenuCommon::disable_lower_case() { flags &= ~QMF_LOWERCASE; }
void MenuCommon::toggle_upper_case() {
if (upper_case()) {
disable_upper_case();
} else {
disable_lower_case();
enable_upper_case();
}
}
void MenuCommon::enable_upper_case() {
flags &= ~QMF_LOWERCASE;
flags |= QMF_UPPERCASE;
}
void MenuCommon::disable_upper_case() { flags &= ~QMF_UPPERCASE; }
void MenuCommon::toggle_silent() { flags ^= QMF_SILENT; }
void MenuCommon::enable_silent() { flags |= QMF_SILENT; }
void MenuCommon::disable_silent() { flags &= ~QMF_SILENT; }
void MenuCommon::toogle_alternate() { flags ^= QMF_ALTERNATE; }
void MenuCommon::enable_alternate() { flags |= QMF_ALTERNATE; }
void MenuCommon::disable_alternate() { flags &= ~QMF_ALTERNATE; }
void MenuCommon::toogle_alternate_2() { flags ^= QMF_ALTERNATE2; }
void MenuCommon::enable_alternate_2() { flags |= QMF_ALTERNATE2; }
void MenuCommon::disable_alternate_2() { flags &= ~QMF_ALTERNATE2; }
bool MenuCommon::has_focus() const {
return parent->getCursor() == menu_position;
}
bool MenuCommon::is_current_menu() const {
const auto mf_cursor = parent->getCursor();
if (mf_cursor < 0) {
return false;
}
return mf_cursor == menu_position;
}
} // namespace ui

View file

@ -42,6 +42,100 @@ struct MenuCommon {
std::function<void(std::int32_t)> callback;
std::function<void()> statusbar;
std::function<void()> ownerdraw;
[[nodiscard]] [[maybe_unused]] bool
has_flags(std::uint64_t required_flags) const;
[[nodiscard]] [[maybe_unused]] bool blink() const;
[[maybe_unused]] void toggle_blink();
[[maybe_unused]] void enable_blink();
[[maybe_unused]] void disable_blink();
[[nodiscard]] [[maybe_unused]] bool small_font() const;
[[maybe_unused]] void toggle_small_fond();
[[maybe_unused]] void enable_small_font();
[[maybe_unused]] void disable_small_font();
[[nodiscard]] [[maybe_unused]] bool center_justify() const;
[[maybe_unused]] void toggle_center_justify();
[[maybe_unused]] void enable_center_justify();
[[maybe_unused]] void disable_center_justify();
[[nodiscard]] [[maybe_unused]] bool left_justify() const;
[[maybe_unused]] void toggle_left_justify();
[[maybe_unused]] void enable_left_justify();
[[maybe_unused]] void disable_left_justify();
[[nodiscard]] [[maybe_unused]] bool right_justify() const;
[[maybe_unused]] void toggle_right_justify();
[[maybe_unused]] void enable_right_justify();
[[maybe_unused]] void disable_right_justify();
[[nodiscard]] [[maybe_unused]] bool numbers_only() const;
[[maybe_unused]] void toggle_numbers_only();
[[maybe_unused]] void enable_numbers_only();
[[maybe_unused]] void disable_numbers_only();
[[nodiscard]] [[maybe_unused]] bool highlight() const;
[[maybe_unused]] void toggle_highlight();
[[maybe_unused]] void enable_highlight();
[[maybe_unused]] void disable_highlight();
[[nodiscard]] [[maybe_unused]] bool highlight_if_focus() const;
[[maybe_unused]] void toogle_highlight_if_focus();
[[maybe_unused]] void enable_highlight_if_focus();
[[maybe_unused]] void disable_highlight_if_focus();
[[nodiscard]] [[maybe_unused]] bool pulse_if_focus() const;
[[maybe_unused]] void toggle_pulse_if_focus();
[[maybe_unused]] void enable_pulse_if_focus();
[[maybe_unused]] void disable_pulse_if_focus();
[[nodiscard]] [[maybe_unused]] bool has_mouse_focus() const;
[[maybe_unused]] void toggle_has_mouse_focus();
[[maybe_unused]] void enable_has_mouse_focus();
[[maybe_unused]] void disable_has_mouse_focus();
[[nodiscard]] [[maybe_unused]] bool no_on_off_text() const;
[[maybe_unused]] void toggle_no_on_off_text();
[[maybe_unused]] void enable_no_on_off_text();
[[maybe_unused]] void disable_no_on_off_text();
[[nodiscard]] [[maybe_unused]] bool mouse_only() const;
[[maybe_unused]] void toggle_mouse_only();
[[maybe_unused]] void enable_mouse_only();
[[maybe_unused]] void disable_mouse_only();
[[nodiscard]] [[maybe_unused]] bool hidden() const;
[[maybe_unused]] void hide();
[[maybe_unused]] void show();
[[nodiscard]] [[maybe_unused]] bool grayed() const;
[[maybe_unused]] void toggle_grayed();
[[maybe_unused]] void enable_grayed();
[[maybe_unused]] void disable_grayed();
[[nodiscard]] [[maybe_unused]] bool inactive() const;
[[maybe_unused]] void activate();
[[maybe_unused]] void deactivate();
[[nodiscard]] [[maybe_unused]] bool no_default_init() const;
[[maybe_unused]] void enable_no_default_init();
[[maybe_unused]] void disable_no_default_init();
[[nodiscard]] [[maybe_unused]] bool owner_draw() const;
[[maybe_unused]] void enable_owner_draw();
[[maybe_unused]] void disable_owner_draw();
[[nodiscard]] [[maybe_unused]] bool pulse() const;
[[maybe_unused]] void toggle_pulse();
[[maybe_unused]] void enable_pulse();
[[maybe_unused]] void disable_pulse();
[[nodiscard]] [[maybe_unused]] bool lower_case() const;
[[maybe_unused]] void toggle_lower_case();
[[maybe_unused]] void enable_lower_case();
[[maybe_unused]] void disable_lower_case();
[[nodiscard]] [[maybe_unused]] bool upper_case() const;
[[maybe_unused]] void toggle_upper_case();
[[maybe_unused]] void enable_upper_case();
[[maybe_unused]] void disable_upper_case();
[[nodiscard]] [[maybe_unused]] bool silent() const;
[[maybe_unused]] void toggle_silent();
[[maybe_unused]] void enable_silent();
[[maybe_unused]] void disable_silent();
[[nodiscard]] [[maybe_unused]] bool alternate() const;
[[maybe_unused]] void toogle_alternate();
[[maybe_unused]] void enable_alternate();
[[maybe_unused]] void disable_alternate();
[[nodiscard]] [[maybe_unused]] bool alternate_2() const;
[[maybe_unused]] void toogle_alternate_2();
[[maybe_unused]] void enable_alternate_2();
[[maybe_unused]] void disable_alternate_2();
[[nodiscard]] [[maybe_unused]] bool has_focus() const;
[[nodiscard]] [[maybe_unused]] bool is_current_menu() const;
};
} // namespace ui

View file

@ -4,7 +4,11 @@
#include "MenuField.h"
#include "../ui_local.h"
#include "MenuColors.h"
#include "MenuFieldData.h"
#include "MenuFramework.h"
#include <common/BitTools.h>
#include <ui/Atoms.h>
namespace ui {
@ -15,13 +19,13 @@ void MenuField::init() {
clear();
if (data.style & UI_TINYFONT) {
if (common::bit_in(data.style, UI_TINYFONT)) {
w = TINYCHAR_WIDTH;
h = TINYCHAR_HEIGHT;
} else if (data.style & UI_BIGFONT) {
} else if (common::bit_in(data.style, UI_BIGFONT)) {
w = BIGCHAR_WIDTH;
h = BIGCHAR_HEIGHT;
} else if (data.style & UI_GIANTFONT) {
} else if (common::bit_in(data.style, UI_GIANTFONT)) {
w = GIANTCHAR_WIDTH;
h = GIANTCHAR_HEIGHT;
} else {
@ -31,7 +35,7 @@ void MenuField::init() {
l = 0;
if (data.style & UI_CENTER) {
if (common::bit_in(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 =
@ -55,4 +59,90 @@ void MenuField::clear() {
data.scroll = 0;
}
void MenuField::draw() {
const auto x = common.position.x;
const auto y = common.position.y;
auto offset = common.name.empty() ? 0 : MENU_BUTTON_MED_HEIGHT + 4;
auto w = 0;
auto style = data.style;
if (common::bit_in(style, UI_TINYFONT)) {
w = TINYCHAR_HEIGHT;
} else if (common::bit_in(style, UI_BIGFONT)) {
w = BIGCHAR_WIDTH;
} else if (common::bit_in(style, UI_GIANTFONT)) {
w = GIANTCHAR_WIDTH;
} else {
w = SMALLCHAR_WIDTH;
}
const auto focus = common.has_focus();
if (focus) {
style |= UI_SHOWCOLOR;
}
if (!common.name.empty() && common::bit_in(style, UI_CENTER)) {
const auto width =
(((MENU_BUTTON_MED_HEIGHT * 2) - 16) + common.name.length() * w) +
2 * w;
if (focus) {
trap_R_SetColor(common::Color::LightPurple.values);
} else if (common.grayed()) {
trap_R_SetColor(common::Color::MediumGrey.values);
} else {
trap_R_SetColor(common::Color::DarkPurple.values);
}
Atoms::DrawHandlePic({x - (width >> 1), y, 19, 19},
uis.graphicButtonLeftEnd);
Atoms::DrawHandlePic({(x + (width >> 1)) - 19, y, -19, 19},
uis.graphicButtonLeftEnd);
Atoms::DrawHandlePic(
{(x - (width >> 1)) + (19 - 8), y, width - ((19 * 2) - 16), 19},
uis.whiteShader);
auto color = focus ? common::Color::White : common::Color::Black;
Atoms::DrawProportionalString({x, y + 2}, common.name,
UI_CENTER | UI_SMALLFONT, color);
}
auto color = common::Color{};
if (common.grayed()) {
color = common::Color::DarkGrey;
} else if (focus) {
color = data.text.color.highlight;
} else {
color = data.text.color.normal;
}
if (focus) {
Atoms::FillRect({common.rectangle.left, common.rectangle.top + offset,
common.rectangle.width() + 1,
(common.rectangle.height() + 1) - offset},
ui::colors::listbar_color);
if (data.title.id && menu_button_text[data.title.id][1]) {
Atoms::DrawProportionalString(common.parent->getDescriptionPosition(),
menu_button_text[data.title.id][1],
UI_LEFT | UI_TINYFONT,
common::Color::Black);
}
}
if (data.title.id) {
auto title_color = data.title.color.normal;
if (common.grayed()) {
title_color = common::Color::DarkGrey;
}
Atoms::DrawProportionalString({x - 5, y},
menu_button_text[data.title.id][0],
UI_RIGHT | UI_SMALLFONT, title_color);
}
// TODO draw menu field (MField_Draw)
}
} // namespace ui

View file

@ -17,6 +17,7 @@ struct MenuField : MenuItem {
void init() override;
void clear();
void draw() override;
};
} // namespace ui

View file

@ -12,13 +12,13 @@ void MenuFramework::setCursor(std::int32_t new_cursor) {
cursor.current = new_cursor;
}
void MenuFramework::addItem(const std::shared_ptr<MenuItem>& item) {
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;
item->common.menu_position = items.size() - 1;
item->common.disable_has_mouse_focus();
if(!(item->common.flags & QMF_NODEFAULTINIT)) {
if (!item->common.no_default_init()) {
item->init();
}
}

View file

@ -38,58 +38,79 @@ class MenuFramework {
// 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; }
[[maybe_unused]] void toggleWrapAround() { wrap_around = !wrap_around; }
[[maybe_unused]] void enableWrapAround() { wrap_around = true; }
[[maybe_unused]] void disableWrapAround() { wrap_around = false; }
[[maybe_unused]] [[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; }
[[maybe_unused]] void toggleFullscreen() { fullscreen = !fullscreen; }
[[maybe_unused]] void enableFullscreen() { fullscreen = true; }
[[maybe_unused]] void disableFullscreen() { fullscreen = false; }
[[maybe_unused]] [[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; }
[[maybe_unused]] void toggleNoBackground() { no_background = !no_background; }
[[maybe_unused]] void enableNoBackground() { no_background = true; }
[[maybe_unused]] void disableNoBackground() { no_background = true; }
[[maybe_unused]] [[nodiscard]] bool isNoBackground() const {
return no_background;
}
[[nodiscard]] bool isInitialized() const { return initialized; }
[[maybe_unused]] [[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; }
[[maybe_unused]] void toggleNoSelecting() { no_selecting = !no_selecting; }
[[maybe_unused]] void enableNoSelecting() { no_selecting = true; }
[[maybe_unused]] void disableNoSelecting() { no_selecting = false; }
[[maybe_unused]] [[nodiscard]] bool isNoSelecting() const {
return no_selecting;
}
[[nodiscard]] std::int32_t getCursor() const { return cursor.current; }
void setCursor(std::int32_t new_cursor);
[[maybe_unused]] [[nodiscard]] std::int32_t getCursor() const {
return cursor.current;
}
[[maybe_unused]] void setCursor(std::int32_t new_cursor);
[[nodiscard]] const std::vector<std::shared_ptr<MenuItem>> &
[[maybe_unused]] [[nodiscard]] const std::vector<std::shared_ptr<MenuItem>> &
getMenuItems() const {
return items;
}
void setTitle(std::int32_t _title) { title = _title; }
void resetTitle() { title = 0; }
[[maybe_unused]] void setTitle(std::int32_t _title) { title = _title; }
[[maybe_unused]] void resetTitle() { title = 0; }
void setFootNote(std::int32_t _foot_note) { foot_note = _foot_note; }
void resetFootNote() { foot_note = 0; }
[[maybe_unused]] void setFootNote(std::int32_t _foot_note) {
foot_note = _foot_note;
}
[[maybe_unused]] void resetFootNote() { foot_note = 0; }
void setTitlePosition(const common::Point2dI &position) {
[[maybe_unused]] void setTitlePosition(const common::Point2dI &position) {
title_position = position;
}
void resetTitlePosition() { title_position = {}; }
[[maybe_unused]] void resetTitlePosition() { title_position = {}; }
void setDescriptionPosition(const common::Point2dI &position) {
[[maybe_unused]] void
setDescriptionPosition(const common::Point2dI &position) {
description_position = position;
}
void resetDescriptionPosition() { description_position = {}; }
[[maybe_unused]] void resetDescriptionPosition() {
description_position = {};
}
[[maybe_unused]] [[nodiscard]] common::Point2dI
getDescriptionPosition() const {
return description_position;
}
void setListPosition(const common::Point2dI &position) {
[[maybe_unused]] void setListPosition(const common::Point2dI &position) {
list_position = position;
}
void resetListPosition() { list_position = {}; }
[[maybe_unused]] void resetListPosition() { list_position = {}; }
void addItem(const std::shared_ptr<MenuItem>& item);
[[maybe_unused]] void addItem(const std::shared_ptr<MenuItem> &item);
std::function<void()> draw;
std::function<sfxHandle_t(std::int32_t key)> key;

View file

@ -13,6 +13,7 @@ struct MenuItem {
MenuCommon common;
virtual void init() = 0;
virtual void draw() = 0;
};
} // namespace ui

View file

@ -3,7 +3,10 @@
//
#include "MenuRadioButton.h"
#include "MenuColors.h"
#include <base_game/q_shared.h>
#include <common/Color.h>
#include <ui/Atoms.h>
namespace ui {
@ -15,4 +18,43 @@ void MenuRadioButton::init() {
common.rectangle.bottom = common.position.y + SMALLCHAR_HEIGHT;
}
void MenuRadioButton::draw() {
const auto x = common.position.x;
const auto y = common.position.y;
auto style = 0;
auto color = common::Color{};
if (common.grayed()) {
color = colors::text_disabled;
style = UI_LEFT | UI_SMALLFONT;
} else if (common.has_focus()) {
color = colors::text_highlight;
style = UI_LEFT | UI_PULSE | UI_SMALLFONT;
} else {
color = colors::text_normal;
style = UI_LEFT | UI_SMALLFONT;
}
if (common.has_focus()) {
Atoms::FillRect({common.rectangle.left, common.rectangle.top,
common.rectangle.right - common.rectangle.left + 1,
common.rectangle.bottom - common.rectangle.top + 1},
colors::listbar_color);
Atoms::DrawChar({x, y}, 13, UI_CENTER | UI_BLINK | UI_SMALLFONT, color);
}
if (!common.name.empty()) {
Atoms::DrawString({x - SMALLCHAR_WIDTH, y}, common.name,
UI_RIGHT | UI_SMALLFONT, color, true);
}
if (value == 0) {
Atoms::DrawHandlePic({x + SMALLCHAR_WIDTH, y + 2, 16, 16}, uis.rb_off);
Atoms::DrawString({x + SMALLCHAR_WIDTH + 16, y}, "off", style, color, true);
} else {
Atoms::DrawHandlePic({x + SMALLCHAR_WIDTH, y + 2, 16, 16}, uis.rb_on);
Atoms::DrawString({x + SMALLCHAR_WIDTH + 16, y}, "on", style, color, true);
}
}
} // namespace ui

View file

@ -13,6 +13,7 @@ struct MenuRadioButton : MenuItem {
std::size_t value{0};
void init() override;
void draw() override;
};
} // namespace ui

View file

@ -5,16 +5,18 @@
#ifndef RPGXEF_CODE_UI_MENU_MENUSHADER_H_
#define RPGXEF_CODE_UI_MENU_MENUSHADER_H_
#include <string>
#include <base_game/q_shared.h>
#include <string>
namespace ui {
struct MenuShader {
std::string name;
qhandle_t handle;
operator bool() const { return !name.empty() && handle; }
};
}
} // namespace ui
#endif // RPGXEF_CODE_UI_MENU_MENUSHADER_H_

View file

@ -3,6 +3,9 @@
//
#include "MenuSlider.h"
#include "MenuFramework.h"
#include <common/ColorTable.h>
#include <ui/Atoms.h>
#include <ui/ui_local.h>
namespace ui {
@ -33,4 +36,93 @@ void MenuSlider::init() {
}
}
void MenuSlider::draw() {
auto text_color = common::Color::Red;
auto thumb_color = common::Color::LightGrey;
auto background_color = common::Color::DarkGrey;
auto c = common::Color{};
if (common.grayed()) {
c = common::Color::DarkGrey;
} else if (common.is_current_menu()) {
c = color.highlight;
text_color = text.color.highlight;
thumb_color = thumb.color.highlight;
background_color = common::Color::LightGrey;
} else {
c = color.normal;
text_color = text.color.normal;
thumb_color = thumb.color.normal;
}
if (trap_Key_IsDown(K_MOUSE1) && mouse_down) {
mouse_down = false;
common.parent->disableNoSelecting();
}
if (mouse_down) {
value.current = (static_cast<float>(uis.cursorx - common.position.x) /
static_cast<float>(focus.size.width)) *
(value.max - value.min) +
value.min;
Com_Clamp(value.min, value.max, value.current);
common.parent->enableNoSelecting();
}
if (picture.shader) {
trap_R_SetColor(c.values);
Atoms::DrawHandlePic({picture.position.x, picture.position.y,
picture.size.width, picture.size.height},
picture.shader);
trap_R_SetColor(nullptr);
}
if (text.id) {
Atoms::DrawProportionalString({picture.position.x + text.position.x,
picture.position.y + text.position.y},
menu_button_text[text.id][0], UI_SMALLFONT,
text_color);
}
if (common.has_focus() && menu_button_text[text.id][1]) {
Atoms::DrawProportionalString(common.parent->getDescriptionPosition(),
menu_button_text[text.id][1],
UI_LEFT | UI_TINYFONT, common::Color::Black);
}
if (value.max > value.min) {
range = (value.current - value.min) / (value.max - value.min);
if (range < 0) {
range = 0;
} else if (range > 1) {
range = 1;
}
} else {
range = 0;
}
const auto thumb_x = common.position.x - (thumb.graphic_width / 2.0) +
(focus.size.width * range);
if (range > 0.0) {
trap_R_SetColor(background_color.values);
Atoms::DrawHandlePic({common.position.x, common.position.y,
(thumb_x - common.position.x) + 4, 18},
uis.whiteShader);
}
if (graph.shader) {
trap_R_SetColor(c.values);
Atoms::DrawHandlePic({common.position.x, common.position.y,
graph.size.width, graph.size.height},
graph.shader);
}
if (thumb.shader) {
trap_R_SetColor(thumb_color.values);
Atoms::DrawHandlePic(
{thumb_x, common.position.x, thumb.size.width, thumb.size.height},
thumb.shader);
}
}
} // namespace ui

View file

@ -55,6 +55,7 @@ struct MenuSlider : MenuItem {
bool mouse_down{false};
void init() override;
void draw() override;
};
} // namespace ui

View file

@ -3,6 +3,7 @@
//
#include "MenuText.h"
#include <common/BitTools.h>
#include <ui/ui_local.h>
namespace ui {
@ -86,12 +87,12 @@ void MenuText::init() {
}
}
if (style & UI_TINYFONT) {
if (common::bit_in(style, UI_TINYFONT)) {
h = PROP_TINY_HEIGHT;
} else if (style & UI_SMALLFONT) {
h = SMALLCHAR_HEIGHT;
} else if (style & UI_BIGFONT) {
} else if (common::bit_in(style, UI_BIGFONT)) {
h = PROP_BIG_HEIGHT;
} else if (common::bit_in(style, UI_SMALLFONT)) {
h = SMALLCHAR_HEIGHT;
} else {
h = SMALLCHAR_HEIGHT;
}
@ -99,9 +100,9 @@ void MenuText::init() {
h += (lines * (h * 1.25));
}
if (common.flags & QMF_RIGHT_JUSTIFY) {
if(common.right_justify()) {
x = x - w;
} else if (common.flags & QMF_CENTER_JUSTIFY) {
} else if (common.center_justify()) {
x = x - w / 2;
}

View file

@ -0,0 +1,9 @@
#include "MenuTextB.h"
namespace ui {
void MenuTextB::init() {
common.deactivate();
}
}

11
code/ui/Menu/MenuTextB.h Normal file
View file

@ -0,0 +1,11 @@
#pragma once
#include "MenuText.h"
namespace ui {
struct MenuTextB : public MenuText {
void init() override;
};
}

View file

@ -0,0 +1,25 @@
#include "MenuTextP.h"
#include <ui/Atoms.h>
namespace ui {
void MenuTextP::init() {
const auto size_scale = Atoms::ProportionalSizeScale(style);
auto x = common.position.x;
auto y = common.position.y;
const auto w =
Atoms::ProportionalStringWidth(text, UI_SMALLFONT) * size_scale;
const auto h = PROP_HEIGHT * size_scale;
if (common.right_justify()) {
x -= w;
} else if (common.center_justify()) {
x -= w / 2;
}
common.rectangle.left = x - PROP_GAP_WIDTH * size_scale;
common.rectangle.right = x + w + PROP_GAP_WIDTH * size_scale;
common.rectangle.top = y;
common.rectangle.bottom = y + h;
}
} // namespace ui

11
code/ui/Menu/MenuTextP.h Normal file
View file

@ -0,0 +1,11 @@
#pragma once
#include "MenuText.h"
namespace ui {
struct MenuTextP : public MenuText {
void init() override;
};
}

View file

@ -1434,7 +1434,7 @@ enum ui_localMtype_e {
MTYPE_BTEXT
};
enum ui_localQmf_e {
enum ui_localQmf_e : unsigned int {
QMF_BLINK = 0x00000001,
QMF_SMALLFONT = 0x00000002,
QMF_LEFT_JUSTIFY = 0x00000004,

View file

@ -119,10 +119,10 @@ static void Preferences_SetMenuItems(void)
s_preferences.dynamiclights.curvalue = trap_Cvar_VariableValue("r_dynamiclight") != 0;
s_preferences.synceveryframe.curvalue = trap_Cvar_VariableValue("r_finish") != 0;
s_preferences.forcemodel.curvalue = trap_Cvar_VariableValue("cg_forcemodel") != 0;
s_preferences.drawteamoverlay.curvalue = Com_Clamp(0, 3, trap_Cvar_VariableValue("cg_drawTeamOverlay"));
s_preferences.drawteamoverlay.curvalue = Com_Clamp(0.0, 3.0, trap_Cvar_VariableValue("cg_drawTeamOverlay"));
s_preferences.allowdownload.curvalue = trap_Cvar_VariableValue("cl_allowDownload") != 0;
s_preferences.flares.curvalue = Com_Clamp(0, 1, trap_Cvar_VariableValue("r_flares"));
s_preferences.flares.curvalue = Com_Clamp(0.0, 1.0, trap_Cvar_VariableValue("r_flares"));
trap_Cvar_VariableStringBuffer("g_language", buffer, 32);
language = s_textlanguage_Names;

File diff suppressed because it is too large Load diff

View file

@ -1906,20 +1906,20 @@ static void ArenaServers_MenuInit(void)
ArenaServers_LoadFavorites();
g_servertype = Com_Clamp(0, 3, ui_browserMaster.integer);
g_servertype = Com_Clamp(0.0, 3.0, ui_browserMaster.integer);
g_arenaservers.master.curvalue = g_servertype;
g_gametype = Com_Clamp(0, 13, ui_browserGameType.integer);
g_gametype = Com_Clamp(0.0, 13.0, ui_browserGameType.integer);
g_arenaservers.gametype.curvalue = g_gametype;
g_sortkey = Com_Clamp(0, 4, ui_browserSortKey.integer);
g_sortkey = Com_Clamp(0.0, 4.0, ui_browserSortKey.integer);
g_arenaservers.sortkey.curvalue = g_sortkey;
g_fullservers = Com_Clamp(0, 1, ui_browserShowFull.integer);
g_fullservers = Com_Clamp(0.0, 1.0, ui_browserShowFull.integer);
g_arenaservers.showfull.curvalue = g_fullservers;
g_emptyservers = Com_Clamp(0, 1, ui_browserShowEmpty.integer);
g_emptyservers = Com_Clamp(0.0, 1.0, ui_browserShowEmpty.integer);
g_arenaservers.showempty.curvalue = g_emptyservers;
// force to initial state and refresh