mirror of
https://github.com/korenkonder/ReDIVA.git
synced 2026-10-02 11:47:56 +03:00
3904 lines
109 KiB
C++
3904 lines
109 KiB
C++
/*
|
|
by korenkonder
|
|
GitHub/GitLab: korenkonder
|
|
*/
|
|
|
|
#include "dw.hpp"
|
|
#include "../CRE/app_system_detail.hpp"
|
|
#include "../CRE/data.hpp"
|
|
#include "input_state.hpp"
|
|
#include "print_work.hpp"
|
|
|
|
class PrintWorkDebug : public PrintWork {
|
|
public:
|
|
PrintWorkDebug();
|
|
};
|
|
|
|
namespace dw {
|
|
struct Print {
|
|
p_Font* font;
|
|
PrintWorkDebug* print_work;
|
|
color4u8 field_10;
|
|
color4u8 field_14;
|
|
rectangle field_18;
|
|
rectangle clip_data;
|
|
float_t field_38;
|
|
|
|
Print(float_t width, float_t height);
|
|
~Print();
|
|
|
|
void FillRectangle(rectangle rect);
|
|
vec2 GetTextSize(std::string& str);
|
|
vec2 GetTextSize(std::wstring& str);
|
|
vec2 GetTextSize(const wchar_t* str, size_t length);
|
|
void PrintText(std::string& str, float_t pos_x, float_t pos_y);
|
|
void PrintText(std::wstring& str, float_t pos_x, float_t pos_y);
|
|
void SetClipData(rectangle rect);
|
|
void SetFillColor(color4u8 value);
|
|
void SetFont(p_Font* value);
|
|
void SetColor(color4u8 value);
|
|
|
|
void sub_140301390(rectangle rect, float_t a3);
|
|
void sub_140302800();
|
|
|
|
inline vec2 GetTextSize(std::string&& str) {
|
|
return GetTextSize(str);
|
|
}
|
|
|
|
inline vec2 GetTextSize(std::wstring&& str) {
|
|
return GetTextSize(str);
|
|
}
|
|
|
|
inline void PrintText(std::string&& str, float_t pos_x, float_t pos_y) {
|
|
PrintText(str, pos_x, pos_y);
|
|
}
|
|
|
|
inline void PrintText(std::wstring&& str, float_t pos_x, float_t pos_y) {
|
|
PrintText(str, pos_x, pos_y);
|
|
}
|
|
};
|
|
|
|
struct Colors {
|
|
color4u8 background;
|
|
color4u8 foreground;
|
|
color4u8 selection_background;
|
|
color4u8 selection_foreground;
|
|
color4u8 selection_inactive_background;
|
|
color4u8 selection_inactive_foreground;
|
|
color4u8 disable_background;
|
|
color4u8 disable_foreground;
|
|
color4u8 title_background;
|
|
color4u8 title_foreground;
|
|
color4u8 title_inactive_background;
|
|
color4u8 title_inactive_foreground;
|
|
color4u8 active_border_color;
|
|
color4u8 inactive_border_color;
|
|
color4u8 focus_border_color;
|
|
color4u8 border_color;
|
|
color4u8 border_light_color;
|
|
color4u8 border_dark_color;
|
|
color4u8 popup_background;
|
|
color4u8 popup_foreground;
|
|
color4u8 popup_selection_background;
|
|
color4u8 popup_selection_foreground;
|
|
color4u8 menu_background;
|
|
color4u8 menu_foreground;
|
|
color4u8 menu_selection_background;
|
|
color4u8 menu_selection_foreground;
|
|
color4u8 button_background;
|
|
color4u8 button_foreground;
|
|
color4u8 button_disable_background;
|
|
color4u8 button_disable_foreground;
|
|
};
|
|
}
|
|
|
|
namespace dw_gui_detail {
|
|
struct Input {
|
|
vec2 mouse_pos;
|
|
vec2 mouse_delta;
|
|
dw::MouseInput mouse_input;
|
|
dw::InputState state;
|
|
int32_t field_18;
|
|
int8_t field_1C;
|
|
int8_t field_1D;
|
|
int64_t field_20;
|
|
uint8_t char_input;
|
|
int32_t key_input;
|
|
int32_t joy_input;
|
|
|
|
Input();
|
|
|
|
void Ctrl();
|
|
void Draw();
|
|
};
|
|
|
|
struct Display {
|
|
class RootKeySelection : public dw::KeyAdapter {
|
|
public:
|
|
RootKeySelection();
|
|
virtual ~RootKeySelection() override;
|
|
|
|
virtual void Field_8(const dw::Widget::KeyCallbackData& data) override;
|
|
};
|
|
|
|
dw::Shell* active_shell;
|
|
dw::Menu* active_menu;
|
|
dw::Widget* on;
|
|
dw::Widget* move;
|
|
dw::Widget* widget;
|
|
dw::Widget* cap;
|
|
dw::Shell* focused_shell;
|
|
bool set_focus;
|
|
bool find_focus;
|
|
std::vector<dw::Shell*> shells;
|
|
std::vector<dw::Menu*> menus;
|
|
dw::Widget::MouseCallbackData mouse_callback_data;
|
|
dw::Widget::KeyCallbackData key_callback_data;
|
|
std::vector<dw::Widget*> free_widgets;
|
|
dw_gui_detail::Input input;
|
|
dw::DisplayData data;
|
|
int64_t field_118;
|
|
vec2 field_120;
|
|
float_t field_128;
|
|
//dw::DragBoundsControl* drag_bounds_control;
|
|
std::wstring name;
|
|
RootKeySelection root_key_selection;
|
|
|
|
Display(dw::DisplayData& data);
|
|
virtual ~Display();
|
|
|
|
void CheckShells();
|
|
void Ctrl();
|
|
void Draw();
|
|
void FreeWidgets();
|
|
dw::Shell* GetHoveredShell();
|
|
void MakeShellFirst(dw::Shell* value);
|
|
void MakeShellLast(dw::Shell* value);
|
|
void RemoveShell(dw::Shell* value);
|
|
|
|
void sub_1402E6300(dw::Widget* widget);
|
|
void sub_1402E6440(dw::Widget* widget);
|
|
int32_t sub_1402E48A0(dw::Widget* widget);
|
|
int32_t sub_1402E51F0();
|
|
int32_t sub_1402E5630();
|
|
};
|
|
}
|
|
|
|
dw_gui_detail::Display* dw_gui_detail_display;
|
|
|
|
static bool dw_gui_get_ctrl();
|
|
static bool dw_gui_get_disp();
|
|
|
|
static void dw_gui_detail_display_set_cap(dw::Widget* widget, bool set);
|
|
|
|
static void sub_1402EE3C0(rectangle rect, float_t border, int32_t type, color4u8* fill_color);
|
|
|
|
namespace dw {
|
|
static const Colors colors_default = {
|
|
0xFFFFFFFF,
|
|
0xFF000000,
|
|
0xFF800000,
|
|
0xFFFFFFFF,
|
|
0xFFC0C0C0,
|
|
0xFFFFFFFF,
|
|
0xFFC0C0C0,
|
|
0xFF808080,
|
|
0xFF800000,
|
|
0xFFFFFFFF,
|
|
0xFFC0C0C0,
|
|
0xFF808080,
|
|
0xFFC0C0C0,
|
|
0xFFC0C0C0,
|
|
0xFF0000FF,
|
|
0xFFC0C0C0,
|
|
0xFFE0E0E0,
|
|
0xFF808080,
|
|
0xFFFFFFFF,
|
|
0xFF000000,
|
|
0xFF800000,
|
|
0xFFFFFFFF,
|
|
0xFFC0C0C0,
|
|
0xFF000000,
|
|
0xFF800000,
|
|
0xFFFFFFFF,
|
|
0xFFC0C0C0,
|
|
0xFF000000,
|
|
0xFFF0F0F0,
|
|
0xFF808080,
|
|
};
|
|
|
|
static RowLayout* row_layout_vertical = new RowLayout(VERTICAL);
|
|
|
|
static DropDownListScrollBarSelectionListener drop_down_list_scroll_bar_selection_listener;
|
|
static ScrollBarTestSelectionListener scroll_bar_test_Selection_listener;
|
|
|
|
std::wstring* clipboard;
|
|
|
|
Print* print;
|
|
|
|
dw::Colors colors_current;
|
|
|
|
bool translate = false;
|
|
|
|
p_Font current_font;
|
|
|
|
Font* font_type_6x12;
|
|
Font* font_type_8x12;
|
|
Font* font_type_8x16;
|
|
Font* font_type_10x16;
|
|
Font* font_type_10x20;
|
|
Font* font_type_12x24;
|
|
Font* font_type_scroll_bar;
|
|
|
|
p_Font p_font_type_6x12;
|
|
p_Font p_font_type_8x12;
|
|
p_Font p_font_type_8x16;
|
|
p_Font p_font_type_10x16;
|
|
p_Font p_font_type_10x20;
|
|
p_Font p_font_type_12x24;
|
|
p_Font p_font_type_scroll_bar;
|
|
|
|
std::map<int32_t, p_Font*> font_collection;
|
|
|
|
Font::Font(int32_t font_handler_index, std::string& name, bool half_width) {
|
|
font = font_info(font_handler_index);
|
|
this->name.assign(name);
|
|
this->half_width = half_width;
|
|
}
|
|
|
|
Font::Font(int32_t font_handler_index, std::string& name) {
|
|
font = font_info(font_handler_index);
|
|
this->name.assign(name);
|
|
this->half_width = 0;
|
|
}
|
|
|
|
Font::~Font() {
|
|
|
|
}
|
|
|
|
float_t Font::GetFontGlyphHeight() const {
|
|
return font.glyph.y;
|
|
}
|
|
|
|
vec2 Font::GetFontGlyphSize() const {
|
|
vec2 size;
|
|
size.x = GetFontGlyphWidth();
|
|
size.y = GetFontGlyphHeight();
|
|
return size;
|
|
}
|
|
|
|
float_t Font::GetFontGlyphWidth() const {
|
|
float_t glyph_height = font.glyph.x;
|
|
if (half_width)
|
|
return glyph_height * 0.5f;
|
|
return glyph_height;
|
|
}
|
|
|
|
std::string Font::GetName() const {
|
|
return name;
|
|
}
|
|
|
|
void Font::SetGlyphSize(float_t glyph_width, float_t glyph_height) {
|
|
if (half_width)
|
|
glyph_width *= 2.0f;
|
|
font.set_glyph_size(glyph_width, glyph_height);
|
|
}
|
|
|
|
p_Font::p_Font() : ptr() {
|
|
|
|
}
|
|
|
|
p_Font::~p_Font() {
|
|
|
|
}
|
|
|
|
float_t p_Font::GetFontGlyphHeight() const {
|
|
return ptr->GetFontGlyphHeight();
|
|
}
|
|
|
|
vec2 p_Font::GetFontGlyphSize() const {
|
|
return ptr->GetFontGlyphSize();
|
|
}
|
|
|
|
float_t p_Font::GetFontGlyphWidth() const {
|
|
return ptr->GetFontGlyphWidth();
|
|
}
|
|
|
|
std::string p_Font::GetName() const {
|
|
return ptr->GetName();
|
|
}
|
|
|
|
void p_Font::SetGlyphSize(float_t glyph_width, float_t glyph_height) {
|
|
ptr->SetGlyphSize(glyph_width, glyph_height);
|
|
}
|
|
|
|
SelectionListener::SelectionListener() {
|
|
|
|
}
|
|
|
|
SelectionListener::~SelectionListener() {
|
|
|
|
}
|
|
|
|
SelectionAdapter::SelectionAdapter() {
|
|
|
|
}
|
|
|
|
SelectionAdapter::~SelectionAdapter() {
|
|
|
|
}
|
|
|
|
void SelectionAdapter::Callback(SelectionListener::CallbackData* data) {
|
|
|
|
}
|
|
|
|
void SelectionAdapter::Field_10(SelectionListener::CallbackData* data) {
|
|
|
|
}
|
|
|
|
SelectionListenerOnHook::SelectionListenerOnHook() : callback() {
|
|
|
|
}
|
|
|
|
SelectionListenerOnHook::SelectionListenerOnHook(SelectionListenerOnHook::CallbackFunc callback) {
|
|
this->callback = callback;
|
|
}
|
|
|
|
SelectionListenerOnHook::~SelectionListenerOnHook() {
|
|
|
|
}
|
|
|
|
void SelectionListenerOnHook::Callback(SelectionListener::CallbackData* data) {
|
|
callback(data->widget);
|
|
}
|
|
|
|
Widget::KeyCallbackData::KeyCallbackData() : widget(),
|
|
state(), field_C(), char_input(), key_input(), joy_input() {
|
|
}
|
|
|
|
Widget::MouseCallbackData::MouseCallbackData() : widget(), input(), state() {
|
|
|
|
}
|
|
|
|
Widget::Widget(Widget* parent, Flags flags) : freed(),
|
|
callback_data(), free_callback(), parent() {
|
|
text.assign(L"NO_NAME");
|
|
this->flags = flags;
|
|
font = current_font;
|
|
}
|
|
|
|
Widget::~Widget() {
|
|
Free();
|
|
}
|
|
|
|
void Widget::Draw() {
|
|
|
|
}
|
|
|
|
void Widget::Reset() {
|
|
text.clear();
|
|
}
|
|
|
|
std::wstring Widget::GetText() {
|
|
return text;
|
|
}
|
|
|
|
void Widget::SetText(std::wstring& str) {
|
|
text.assign(str);
|
|
}
|
|
|
|
int32_t Widget::KeyCallback(const Widget::KeyCallbackData& data) {
|
|
return 0;
|
|
}
|
|
|
|
int32_t Widget::MouseCallback(const Widget::MouseCallbackData& data) {
|
|
return 0;
|
|
}
|
|
|
|
void Widget::SetSize(const vec2& value) {
|
|
rect.size = value;
|
|
}
|
|
|
|
vec2 Widget::GetPos() {
|
|
return rect.pos;
|
|
}
|
|
|
|
bool Widget::CheckHitPos(const vec2& hit_pos) {
|
|
rectangle rect = GetRectangle();
|
|
return rect.pos.x <= hit_pos.x && hit_pos.x < rect.pos.x + rect.size.x
|
|
&& rect.pos.y <= hit_pos.y && hit_pos.y < rect.size.y + rect.pos.y;
|
|
}
|
|
|
|
void Widget::Free() {
|
|
if (freed)
|
|
return;
|
|
|
|
Reset();
|
|
|
|
if (free_callback)
|
|
free_callback(this);
|
|
|
|
freed = true;
|
|
|
|
if (dw_gui_detail_display)
|
|
dw_gui_detail_display->free_widgets.push_back(this);
|
|
}
|
|
|
|
float_t Widget::GetFontGlyphHeight() {
|
|
return font.GetFontGlyphHeight();
|
|
}
|
|
|
|
rectangle Widget::GetRectangle() {
|
|
return { GetPos(), rect.size };
|
|
}
|
|
|
|
void Widget::SetText(std::string& str) {
|
|
SetText(utf8_to_utf16(str));
|
|
}
|
|
|
|
void Widget::UpdateDraw() {
|
|
print->sub_140302800();
|
|
Draw();
|
|
}
|
|
|
|
void Widget::LimitPos(Widget* widget) {
|
|
if (!widget)
|
|
return;
|
|
|
|
rectangle v10 = widget->GetRectangle();
|
|
rectangle v11 = dw_gui_detail_display->data.field_0;
|
|
if (v11.pos.x > v10.pos.x || v10.pos.x + v10.size.x > v11.pos.x + v11.size.x
|
|
|| v11.pos.y > v10.pos.y || v10.pos.y + v10.size.y > v11.pos.y + v11.size.y) {
|
|
vec2 v7 = v10.pos;
|
|
if (v10.pos.x + v10.size.x >= v11.pos.x + v11.size.x)
|
|
v7.x = v11.pos.x + v11.size.x - widget->rect.size.x;
|
|
if (v10.pos.x < v11.pos.x || v7.x < 0.0f)
|
|
v7.x = 0.0f;
|
|
|
|
if (v10.pos.y + v10.size.y >= v11.pos.y + v11.size.y)
|
|
v7.y = v11.pos.y + v11.size.y - widget->rect.size.y;
|
|
if (v10.pos.y < v11.pos.y || v7.y < 0.0f)
|
|
v7.y = 0.0f;
|
|
widget->rect.pos = v7;
|
|
}
|
|
}
|
|
|
|
Control::Control(Composite* parent, Flags flags) : Widget(parent, flags),
|
|
disabled(), parent_comp(), parent_shell(), parent_menu() {
|
|
parent_comp = parent;
|
|
foreground_color = colors_current.foreground;
|
|
background_color = colors_current.background;
|
|
|
|
if (parent) {
|
|
parent->controls.push_back(this);
|
|
parent_shell = parent->parent_shell;
|
|
}
|
|
}
|
|
|
|
Control::~Control() {
|
|
|
|
}
|
|
|
|
void Control::Draw() {
|
|
|
|
}
|
|
|
|
void Control::Reset() {
|
|
parent_comp = 0;
|
|
Widget::Reset();
|
|
}
|
|
|
|
int32_t Control::KeyCallback(const Widget::KeyCallbackData& data) {
|
|
if (!GetParentEnabled())
|
|
return 0;
|
|
|
|
/*if ((data.state & INPUT_STATE_SHIFT) && data.key_input == 0x1000013)
|
|
if (parent_menu)
|
|
parent_menu->sub_1402F35E0();*/
|
|
|
|
if (data.key_input || (data.joy_input & 0x01)) {
|
|
Widget::KeyCallbackData v8 = data;
|
|
v8.widget = parent;
|
|
for (KeyListener*& i : key_listener)
|
|
i->Field_8(v8);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int32_t Control::MouseCallback(const Widget::MouseCallbackData& data) {
|
|
if (!GetParentEnabled())
|
|
return 0;
|
|
|
|
/*if (dw_gui_detail_display->input.field_18 == 9
|
|
&& (data.input & MOUSE_INPUT_TAP_RIGHT) && !data.state)
|
|
if (parent_menu)
|
|
parent_menu->sub_1402F35E0();*/
|
|
|
|
if (!data.input)
|
|
return 0;
|
|
|
|
if (data.input & MOUSE_INPUT_TAP_MASK) {
|
|
Widget::MouseCallbackData _data = data;
|
|
_data.widget = parent;
|
|
_data.input = (MouseInput)(data.input & MOUSE_INPUT_TAP_MASK);
|
|
|
|
for (MouseListener* i : mouse_listener)
|
|
i->OnTap(_data);
|
|
}
|
|
|
|
if (data.input & MOUSE_INPUT_INTERVAL_MASK) {
|
|
Widget::MouseCallbackData _data = data;
|
|
_data.widget = parent;
|
|
_data.input = (MouseInput)(data.input & MOUSE_INPUT_INTERVAL_MASK);
|
|
|
|
for (MouseListener* i : mouse_listener)
|
|
i->OnInterval(_data);
|
|
}
|
|
|
|
if (data.input & MOUSE_INPUT_DBL_TAP_MASK) {
|
|
Widget::MouseCallbackData _data = data;
|
|
_data.widget = parent;
|
|
_data.input = (MouseInput)(data.input & MOUSE_INPUT_DBL_TAP_MASK);
|
|
|
|
for (MouseListener* i : mouse_listener)
|
|
i->OnDoubleTap(_data);
|
|
}
|
|
|
|
if (data.input & MOUSE_INPUT_RELEASE_MASK) {
|
|
Widget::MouseCallbackData _data = data;
|
|
_data.widget = parent;
|
|
_data.input = (MouseInput)(data.input & MOUSE_INPUT_RELEASE_MASK);
|
|
|
|
for (MouseListener* i : mouse_listener)
|
|
i->OnRelease(_data);
|
|
}
|
|
|
|
if (data.input & MOUSE_INPUT_MOVE) {
|
|
Widget::MouseCallbackData _data = data;
|
|
_data.widget = parent;
|
|
|
|
for (MouseMoveListener* i : mouse_move_listener)
|
|
i->OnMove(_data);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
vec2 Control::GetPos() {
|
|
vec2 pos = rect.pos;
|
|
if (parent_comp) {
|
|
rectangle parent_comp_bb = parent_comp->GetBoundingBox();
|
|
pos += parent_comp->GetPos() + parent_comp_bb.pos;
|
|
if (parent_comp->v_bar)
|
|
pos.y -= parent_comp->v_bar->value;
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
void Control::UpdateLayout() {
|
|
SetSize(GetSize());
|
|
}
|
|
|
|
vec2 Control::GetSize() {
|
|
return rect.size;
|
|
}
|
|
|
|
bool Control::Field_58() {
|
|
return parent_comp->SetCurrentControl(this);
|
|
}
|
|
|
|
bool Control::Field_60() {
|
|
return parent_comp->sub_1402F1E60(this);
|
|
}
|
|
|
|
void Control::SetFont(p_Font& value) {
|
|
font = value;
|
|
}
|
|
|
|
p_Font& Control::GetFont() {
|
|
return font;
|
|
}
|
|
|
|
void Control::SetForegroundColor(color4u8 value) {
|
|
foreground_color = value;
|
|
}
|
|
|
|
void Control::SetBackgroundColor(color4u8 value) {
|
|
background_color = value;
|
|
}
|
|
|
|
color4u8 Control::GetForegroundColor() {
|
|
return foreground_color;
|
|
}
|
|
|
|
color4u8 Control::GetBackgroundColor() {
|
|
return background_color;
|
|
}
|
|
|
|
bool Control::GetEnabled() {
|
|
return !disabled;
|
|
}
|
|
|
|
bool Control::GetParentEnabled() {
|
|
if (parent_comp)
|
|
return parent_comp->GetParentEnabled() && GetEnabled();
|
|
return GetEnabled();
|
|
}
|
|
|
|
void Control::SetEnabled(bool value) {
|
|
disabled = !value;
|
|
}
|
|
|
|
Widget* Control::GetHitWidget(const vec2& hit_pos) {
|
|
if (CheckHitPos(hit_pos))
|
|
return this;
|
|
return 0;
|
|
}
|
|
|
|
void Control::SetParentMenu(Menu* menu) {
|
|
if (menu) {
|
|
//menu->Field_60();
|
|
parent_menu = menu;
|
|
}
|
|
else
|
|
parent_menu = 0;
|
|
}
|
|
|
|
Scrollable::Scrollable(Composite* parent, Flags flags) : Control(parent, flags), h_bar(), v_bar() {
|
|
if (flags & HORIZONTAL) {
|
|
h_bar = new ScrollBar(this, HORIZONTAL);
|
|
h_bar->SetText(L"h_bar");
|
|
}
|
|
|
|
if (flags & VERTICAL) {
|
|
v_bar = new ScrollBar(this, VERTICAL);
|
|
v_bar->SetText(L"v_bar");
|
|
}
|
|
}
|
|
|
|
Scrollable::~Scrollable() {
|
|
|
|
}
|
|
|
|
void Scrollable::Draw() {
|
|
if (v_bar)
|
|
v_bar->UpdateDraw();
|
|
}
|
|
|
|
void Scrollable::Reset() {
|
|
if (h_bar) {
|
|
h_bar->Free();
|
|
h_bar = 0;
|
|
}
|
|
|
|
if (v_bar) {
|
|
v_bar->Free();
|
|
v_bar = 0;
|
|
}
|
|
|
|
Control::Reset();
|
|
}
|
|
|
|
int32_t Scrollable::MouseCallback(const Widget::MouseCallbackData& data) {
|
|
if (!v_bar)
|
|
return Control::MouseCallback(data);
|
|
|
|
bool v4 = v_bar->field_A6;
|
|
int32_t ret = v_bar->MouseCallback(data);
|
|
if (v4 != v_bar->field_A6)
|
|
dw_gui_detail_display_set_cap(v_bar, v_bar->field_A6);
|
|
return ret;
|
|
}
|
|
|
|
void Scrollable::SetSize(const vec2& value) {
|
|
Widget::SetSize(value);
|
|
|
|
vec2 size = value;
|
|
if (flags & FLAG_800)
|
|
size -= 2.0f * 2.0f;
|
|
|
|
if (v_bar) {
|
|
v_bar->rect.pos.x = size.x - v_bar->rect.size.x;
|
|
v_bar->rect.pos.y = 0.0f;
|
|
v_bar->SetWidth(size.y);
|
|
}
|
|
}
|
|
|
|
void Scrollable::SetFont(p_Font& value) {
|
|
font = value;
|
|
if (h_bar)
|
|
h_bar->SetFont(value);
|
|
if (v_bar)
|
|
v_bar->SetFont(value);
|
|
}
|
|
|
|
Widget* Scrollable::GetHitWidget(const vec2& hit_pos) {
|
|
if (!CheckHitPos(hit_pos))
|
|
return 0;
|
|
|
|
if (v_bar && v_bar->CheckHitPos(hit_pos))
|
|
return v_bar;
|
|
return this;
|
|
}
|
|
|
|
rectangle Scrollable::GetBoundingBox() {
|
|
rectangle rect;
|
|
rect.size = this->rect.size;
|
|
|
|
if (flags & FLAG_800) {
|
|
rect.pos = 2.0f;
|
|
rect.size -= 2.0f * 2.0f;
|
|
}
|
|
|
|
if (v_bar)
|
|
rect.size.x -= v_bar->rect.size.x;
|
|
return rect;
|
|
}
|
|
|
|
rectangle Scrollable::GetScrollableRectangle() {
|
|
vec2 pos = GetPos();
|
|
rectangle rect = GetBoundingBox();
|
|
rect.pos += pos;
|
|
return rect;
|
|
}
|
|
|
|
Composite::Composite(Composite* parent, Flags flags) : Scrollable(parent, flags) {
|
|
layout = row_layout_vertical;
|
|
current_control = -1;
|
|
}
|
|
|
|
Composite::~Composite() {
|
|
|
|
}
|
|
|
|
void Composite::Draw() {
|
|
rectangle rect = GetBoundingBox();
|
|
rect.pos = 0.0f;
|
|
|
|
if (v_bar)
|
|
rect.pos.y = v_bar->value;
|
|
|
|
for (Control*& i : controls)
|
|
if ((i->rect.pos.x + i->rect.size.x) > rect.pos.x && (rect.pos.x + rect.size.x) > i->rect.pos.x
|
|
&& (i->rect.pos.y + i->rect.size.y) > rect.pos.y && (rect.pos.y + rect.size.y) > i->rect.pos.y)
|
|
i->UpdateDraw();
|
|
|
|
Scrollable::Draw();
|
|
}
|
|
|
|
void Composite::Reset() {
|
|
for (Control*& i : controls)
|
|
i->Free();
|
|
|
|
controls.clear();
|
|
|
|
Scrollable::Reset();
|
|
}
|
|
|
|
int32_t Composite::KeyCallback(const Widget::KeyCallbackData& data) {
|
|
if (current_control != -1 && current_control < controls.size())
|
|
return controls[current_control]->KeyCallback(data);
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
int32_t Composite::MouseCallback(const Widget::MouseCallbackData& data) {
|
|
for (Control*& i : controls)
|
|
if (i->CheckHitPos(data.pos))
|
|
return i->MouseCallback(data);
|
|
|
|
return Scrollable::MouseCallback(data);
|
|
}
|
|
|
|
void Composite::SetSize(const vec2& size) {
|
|
Scrollable::SetSize(size);
|
|
layout->SetSize(this);
|
|
}
|
|
|
|
void Composite::UpdateLayout() {
|
|
SetSize(GetSize());
|
|
}
|
|
|
|
vec2 Composite::GetSize() {
|
|
return layout->GetSize(this);
|
|
}
|
|
|
|
bool Composite::Field_58() {
|
|
current_control = -1;
|
|
return Control::Field_58();
|
|
}
|
|
|
|
bool Composite::Field_60() {
|
|
return current_control == -1 && Field_C0();
|
|
}
|
|
|
|
Widget* Composite::GetHitWidget(const vec2& hit_pos) {
|
|
if (!CheckHitPos(hit_pos))
|
|
return Scrollable::GetHitWidget(hit_pos);
|
|
|
|
for (Control*& i : controls) {
|
|
Widget* widget = i->GetHitWidget(hit_pos);
|
|
if (widget)
|
|
return widget;
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
bool Composite::Field_C0() {
|
|
return parent_comp->sub_1402F1E60(this);
|
|
}
|
|
|
|
bool Composite::SetCurrentControl(Control* control) {
|
|
current_control = GetControlIndex(control);
|
|
return parent_comp->SetCurrentControl(this);
|
|
}
|
|
|
|
size_t Composite::GetControlIndex(Control* control) {
|
|
for (Control*& i : controls)
|
|
if (i == control)
|
|
return &i - controls.data();
|
|
return -1;
|
|
}
|
|
|
|
void Composite::SetLayout(Layout* value) {
|
|
layout = value;
|
|
}
|
|
|
|
bool Composite::sub_1402F1E60(Control* control) {
|
|
return GetControlIndex(control) == current_control && Field_C0();
|
|
}
|
|
|
|
Shell::Shell(Shell* parent, Flags flags) : Composite(parent, flags), disp(), disp_callback(),
|
|
hide_callback(), field_128(), destroy(), close_button(), field_170(), field_178() {
|
|
parent_shell = this;
|
|
|
|
if (flags & CLOSE_BUTTON) {
|
|
close_button = new ShellCloseButton(this);
|
|
if (controls.size())
|
|
controls.pop_back();
|
|
}
|
|
|
|
if (parent) {
|
|
parent_comp = parent;
|
|
parent->children.push_back(this);
|
|
}
|
|
|
|
dw_gui_detail_display->shells.push_back(this);
|
|
}
|
|
|
|
Shell::~Shell() {
|
|
|
|
}
|
|
|
|
void Shell::Draw() {
|
|
if (!GetDisp())
|
|
return;
|
|
|
|
rectangle v12 = GetRectangle();
|
|
bool active = dw_gui_detail_display->active_shell == this;
|
|
|
|
print->SetColor(active
|
|
? colors_current.active_border_color
|
|
: colors_current.inactive_border_color);
|
|
print->sub_140301390(v12, 2.0f);
|
|
|
|
if (flags & CHECKBOX) {
|
|
rectangle v11 = v12;
|
|
v11.size.y = current_font.GetFontGlyphHeight() + 2.0f + 2.0f;
|
|
print->sub_140301390(v11, 2.0f);
|
|
|
|
rectangle v10;
|
|
v10.pos = v11.pos + 2.0f;
|
|
v10.size = v11.size - 2.0f * 2.0f;
|
|
|
|
print->SetFillColor(active
|
|
? colors_current.title_background
|
|
: colors_current.title_inactive_background);
|
|
print->FillRectangle(v10);
|
|
|
|
print->SetColor(active
|
|
? colors_current.title_foreground
|
|
: colors_current.title_inactive_foreground);
|
|
print->SetFont(¤t_font);
|
|
print->SetClipData(v10);
|
|
|
|
print->PrintText(GetText(), v10.pos.x, v10.pos.y);
|
|
|
|
print->sub_140302800();
|
|
if (close_button)
|
|
close_button->UpdateDraw();
|
|
}
|
|
|
|
print->SetFillColor(colors_current.background);
|
|
print->FillRectangle(GetScrollableRectangle());
|
|
print->SetColor(colors_current.foreground);
|
|
Composite::Draw();
|
|
|
|
if (field_178) {
|
|
field_170 = true;
|
|
field_178->UpdateDraw();
|
|
field_170 = false;
|
|
}
|
|
}
|
|
|
|
void Shell::Reset() {
|
|
std::vector<Widget*> vec;
|
|
vec.assign(children.begin(), children.end());
|
|
children.clear();
|
|
|
|
for (Widget* i : vec)
|
|
i->Free();
|
|
|
|
for (Menu* i : menus)
|
|
;//i->Free();
|
|
menus.clear();
|
|
|
|
if (close_button) {
|
|
close_button->Free();
|
|
close_button = 0;
|
|
}
|
|
|
|
if (parent_comp) {
|
|
Shell* parent_shell = dynamic_cast<Shell*>(parent_comp);
|
|
if (parent_shell) {
|
|
auto i = parent_shell->children.begin();
|
|
auto i_end = parent_shell->children.end();
|
|
while (i != i_end)
|
|
if (*i == this) {
|
|
parent_shell->children.erase(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
dw_gui_detail_display->RemoveShell(this);
|
|
|
|
Composite::Reset();
|
|
}
|
|
|
|
int32_t Shell::KeyCallback(const Widget::KeyCallbackData& data) {
|
|
if (!GetDisp())
|
|
return 0;
|
|
|
|
if ((data.state & INPUT_STATE_ALT) && data.key_input == 0x100000D
|
|
|| (data.key_input & MOUSE_INPUT_DBL_TAP_MIDDLE)) {
|
|
Hide();
|
|
return 0;
|
|
}
|
|
|
|
return Composite::KeyCallback(data);
|
|
}
|
|
|
|
int32_t Shell::MouseCallback(const Widget::MouseCallbackData& data) {
|
|
if (!GetDisp())
|
|
return 0;
|
|
|
|
if (data.input & MOUSE_INPUT_TAP_MASK) {
|
|
if (!sub_140192D00())
|
|
return 0;
|
|
|
|
dw_gui_detail_display->MakeShellFirst(this);
|
|
}
|
|
|
|
if ((uint16_t)dw_gui_detail_display->input.field_18 >= 1 && (uint16_t)dw_gui_detail_display->input.field_18 <= 8) {
|
|
if (data.input & MOUSE_INPUT_TAP_LEFT) {
|
|
if (sub_140192D00()) {
|
|
dw_gui_detail_display->input.field_18 |= 0x20000000;
|
|
dw_gui_detail_display->move = dw_gui_detail_display->active_shell;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
else if ((uint16_t)dw_gui_detail_display->input.field_18 == 10) {
|
|
if (close_button && close_button->CheckHitPos(data.pos))
|
|
return close_button->MouseCallback(data);
|
|
|
|
if (data.input & MOUSE_INPUT_TAP_LEFT) {
|
|
if (sub_140192D00()) {
|
|
dw_gui_detail_display->input.field_18 |= 0x40000000;
|
|
dw_gui_detail_display->move = dw_gui_detail_display->active_shell;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return Composite::MouseCallback(data);
|
|
}
|
|
|
|
void Shell::SetSize(const vec2& size) {
|
|
Widget::SetSize(size);
|
|
if (flags & CHECKBOX) {
|
|
if (close_button) {
|
|
vec2 size = close_button->GetSize();
|
|
close_button->rect.pos.x = rect.size.x - (size.x + 2.0f);
|
|
close_button->rect.pos.y = 2.0f;
|
|
}
|
|
}
|
|
|
|
rectangle bounding_box = GetBoundingBox();
|
|
if (v_bar) {
|
|
v_bar->rect.pos.x = bounding_box.pos.x + bounding_box.size.x - v_bar->rect.size.x;
|
|
v_bar->rect.pos.y = bounding_box.pos.y;
|
|
v_bar->SetWidth(bounding_box.size.y);
|
|
}
|
|
|
|
layout->SetSize(this);
|
|
}
|
|
|
|
vec2 Shell::GetPos() {
|
|
return rect.pos;
|
|
}
|
|
|
|
vec2 Shell::GetSize() {
|
|
vec2 size = Composite::GetSize() + 2.0f * 2.0f;
|
|
if (flags & CHECKBOX)
|
|
size.y += current_font.GetFontGlyphHeight() + 2.0f;
|
|
return size;
|
|
}
|
|
|
|
bool Shell::Field_58() {
|
|
return this == dw_gui_detail_display->active_shell && GetDisp();
|
|
}
|
|
|
|
Widget* Shell::GetHitWidget(const vec2& hit_pos) {
|
|
rectangle rect = GetRectangle();
|
|
if (rect.pos.x > hit_pos.x || hit_pos.x >= rect.pos.x + rect.size.x
|
|
|| rect.pos.y > hit_pos.y || hit_pos.y >= rect.size.y + rect.pos.y)
|
|
return 0;
|
|
|
|
if (close_button && close_button->CheckHitPos(hit_pos))
|
|
return close_button;
|
|
|
|
Widget* widget = Composite::GetHitWidget(hit_pos);
|
|
if (widget)
|
|
return widget;
|
|
|
|
return this;
|
|
}
|
|
|
|
rectangle Shell::GetBoundingBox() {
|
|
rectangle rect;
|
|
rect.pos = 2.0f;
|
|
rect.size = this->rect.size - 2.0f * 2.0f;
|
|
|
|
if (flags & CHECKBOX) {
|
|
rect.size.y -= current_font.GetFontGlyphHeight() + 2.0f;
|
|
rect.pos.y += current_font.GetFontGlyphHeight() + 2.0f;
|
|
}
|
|
|
|
if (v_bar)
|
|
rect.size.x -= v_bar->rect.size.x;
|
|
return rect;
|
|
}
|
|
|
|
bool Shell::Field_C0() {
|
|
return Field_58();
|
|
}
|
|
|
|
bool Shell::SetCurrentControl(Control* control) {
|
|
current_control = GetControlIndex(control);
|
|
return Field_58();
|
|
}
|
|
|
|
void Shell::Hide() {
|
|
destroy = true;
|
|
}
|
|
|
|
void Shell::Disp() {
|
|
SetDisp(true);
|
|
dw_gui_detail_display->MakeShellFirst(this);
|
|
dw_gui_detail_display->focused_shell = this;
|
|
dw_gui_detail_display->set_focus = true;
|
|
}
|
|
|
|
bool Shell::GetDisp() {
|
|
return disp;
|
|
}
|
|
|
|
void Shell::LimitPosDisp() {
|
|
LimitPos(this);
|
|
Disp();
|
|
}
|
|
|
|
void Shell::SetDisp(bool value) {
|
|
if (disp == value)
|
|
return;
|
|
|
|
disp = value;
|
|
if (disp) {
|
|
dw_gui_detail_display->MakeShellFirst(this);
|
|
dw_gui_detail_display->focused_shell = this;
|
|
dw_gui_detail_display->set_focus = true;
|
|
if (disp_callback)
|
|
disp_callback(this);
|
|
}
|
|
else {
|
|
dw_gui_detail_display->find_focus = true;
|
|
if (hide_callback)
|
|
hide_callback(this);
|
|
}
|
|
}
|
|
|
|
void Shell::sub_1402E43C0(Widget* widget) {
|
|
if (!field_178)
|
|
field_178 = widget;
|
|
}
|
|
|
|
void Shell::sub_1402E61F0(Widget* widget) {
|
|
if (field_178 && field_178 == widget)
|
|
field_178 = 0;
|
|
}
|
|
|
|
KeyListener::KeyListener() {
|
|
|
|
}
|
|
|
|
KeyListener::~KeyListener() {
|
|
|
|
}
|
|
|
|
KeyAdapter::KeyAdapter() {
|
|
|
|
}
|
|
|
|
KeyAdapter::~KeyAdapter() {
|
|
|
|
}
|
|
|
|
void KeyAdapter::Field_8(const Widget::KeyCallbackData& data) {
|
|
|
|
}
|
|
|
|
void KeyAdapter::Field_10(const Widget::KeyCallbackData& data) {
|
|
|
|
}
|
|
|
|
void KeyAdapter::Field_18(const Widget::KeyCallbackData& data) {
|
|
|
|
}
|
|
|
|
MouseListener::MouseListener() {
|
|
|
|
}
|
|
|
|
MouseListener::~MouseListener() {
|
|
|
|
}
|
|
|
|
MouseAdapter::MouseAdapter() {
|
|
|
|
}
|
|
|
|
MouseAdapter::~MouseAdapter() {
|
|
|
|
}
|
|
|
|
void MouseAdapter::OnDoubleTap(const Widget::MouseCallbackData& data) {
|
|
|
|
}
|
|
|
|
void MouseAdapter::OnTap(const Widget::MouseCallbackData& data) {
|
|
|
|
}
|
|
|
|
void MouseAdapter::OnInterval(const Widget::MouseCallbackData& data) {
|
|
|
|
}
|
|
|
|
void MouseAdapter::OnRelease(const Widget::MouseCallbackData& data) {
|
|
|
|
}
|
|
|
|
MouseMoveListener::MouseMoveListener() {
|
|
|
|
}
|
|
|
|
MouseMoveListener::~MouseMoveListener() {
|
|
|
|
}
|
|
|
|
Layout::Layout() {
|
|
|
|
}
|
|
|
|
Layout::~Layout() {
|
|
|
|
}
|
|
|
|
FillLayout::FillLayout(Flags flags) {
|
|
this->flags = flags;
|
|
}
|
|
|
|
FillLayout::~FillLayout() {
|
|
|
|
}
|
|
|
|
vec2 FillLayout::GetSize(Composite* comp) {
|
|
if (!comp->controls.size()) {
|
|
vec2 size = comp->rect.size;
|
|
if (comp->v_bar)
|
|
size.x += comp->v_bar->rect.size.x;
|
|
return size;
|
|
}
|
|
|
|
vec2 size = 0.0f;
|
|
if (flags == VERTICAL)
|
|
for (Control* i : comp->controls) {
|
|
vec2 _size = i->GetSize();
|
|
size.x = max_def(_size.x, size.x);
|
|
}
|
|
else
|
|
for (Control* i : comp->controls) {
|
|
vec2 _size = i->GetSize();
|
|
size.y = max_def(_size.y, size.y);
|
|
}
|
|
|
|
if (comp->v_bar)
|
|
size.x += comp->v_bar->rect.size.x;
|
|
return size;
|
|
}
|
|
|
|
void FillLayout::SetSize(Composite* comp) {
|
|
rectangle comp_bb = comp->GetBoundingBox();
|
|
if (!comp->controls.size())
|
|
return;
|
|
|
|
float_t size = (float_t)(int64_t)comp->controls.size();
|
|
if (size < 0.0f)
|
|
size += (float_t)UINT64_MAX;
|
|
|
|
if (flags == VERTICAL) {
|
|
float_t pos = 0.0f;
|
|
size = comp_bb.size.y / size;
|
|
for (Control* i : comp->controls) {
|
|
i->rect.pos = { 0.0f, pos };
|
|
i->SetSize({ comp_bb.size.x, size });
|
|
pos += size;
|
|
}
|
|
}
|
|
else {
|
|
float_t pos = 0.0f;
|
|
size = comp_bb.size.x / size;
|
|
for (Control* i : comp->controls) {
|
|
i->rect.pos = { pos, 0.0f };
|
|
i->SetSize({ size, comp_bb.size.y });
|
|
pos += size;
|
|
}
|
|
}
|
|
}
|
|
|
|
GraphLayout::GraphLayout(Flags flags) {
|
|
this->flags = flags;
|
|
}
|
|
|
|
GraphLayout::~GraphLayout() {
|
|
|
|
}
|
|
|
|
vec2 GraphLayout::GetSize(Composite* comp) {
|
|
return comp->rect.size;
|
|
}
|
|
|
|
void GraphLayout::SetSize(Composite* comp) {
|
|
const rectangle rect = comp->rect;
|
|
for (Control* i : comp->controls) {
|
|
i->rect.pos = rect.pos;
|
|
i->SetSize(rect.size);
|
|
}
|
|
}
|
|
|
|
GridLayout::GridLayout(size_t columns) : rows() {
|
|
this->columns = columns;
|
|
spacing = 2.0f;
|
|
}
|
|
|
|
GridLayout::~GridLayout() {
|
|
|
|
}
|
|
|
|
vec2 GridLayout::GetSize(Composite* comp) {
|
|
std::vector<Control*>& controls = comp->controls;
|
|
size_t controls_count = controls.size();
|
|
if (!controls_count) {
|
|
vec2 size = comp->rect.size;
|
|
if (comp->v_bar)
|
|
size.x += comp->v_bar->rect.size.x;
|
|
return size;
|
|
}
|
|
|
|
rows = (controls_count + columns - 1) / columns;
|
|
rows = rows ? rows : 1;
|
|
|
|
column_size.resize(columns);
|
|
row_size.resize(rows);
|
|
|
|
size_t control = 0;
|
|
for (size_t row = 0; row < rows && control < controls_count; row++)
|
|
for (size_t column = 0; column < columns && control < controls_count; column++, control++) {
|
|
vec2 size = controls.data()[control]->GetSize();
|
|
column_size.data()[column] = max_def(size.x, column_size.data()[column]);
|
|
row_size.data()[row] = max_def(size.y, row_size.data()[row]);
|
|
}
|
|
|
|
vec2 size;
|
|
size.x = (float_t)(int64_t)(columns - 1);
|
|
if (size.x < 0.0f)
|
|
size.x += (float_t)UINT64_MAX;
|
|
|
|
size.y = (float_t)(int64_t)(rows - 1);
|
|
if (size.y < 0.0f)
|
|
size.y += (float_t)UINT64_MAX;
|
|
|
|
size *= spacing;
|
|
|
|
float_t size_x = size.x;
|
|
for (float_t i : column_size)
|
|
size_x += i;
|
|
size.x = size_x;
|
|
|
|
float_t size_y = size.y;
|
|
for (float_t i : row_size)
|
|
size_y += i;
|
|
size.y = size_y;
|
|
|
|
if (comp->v_bar)
|
|
size.x += comp->v_bar->rect.size.x;
|
|
return size;
|
|
}
|
|
|
|
void GridLayout::SetSize(Composite* comp) {
|
|
std::vector<Control*>& controls = comp->controls;
|
|
size_t controls_count = controls.size();
|
|
|
|
rectangle comp_bb = comp->GetBoundingBox();
|
|
if (!controls_count)
|
|
return;
|
|
|
|
if (controls_count == 1) {
|
|
Scrollable* scrollable = dynamic_cast<Scrollable*>(comp->controls.front());
|
|
if (scrollable) {
|
|
scrollable->rect.pos = 0.0f;
|
|
scrollable->SetSize(comp_bb.size);
|
|
return;
|
|
}
|
|
}
|
|
|
|
size_t control = 0;
|
|
vec2 pos = 0.0f;
|
|
for (size_t row = 0; row < rows && control < controls_count; row++) {
|
|
vec2 _pos = pos;
|
|
for (size_t column = 0; column < columns && control < controls_count; column++, control++) {
|
|
comp->controls.data()[control]->rect.pos = _pos;
|
|
comp->controls.data()[control]->SetSize({ column_size.data()[column], row_size.data()[row] });
|
|
_pos.x += column_size.data()[column] + spacing.x;
|
|
}
|
|
pos.y += row_size.data()[row] + spacing.y;
|
|
}
|
|
}
|
|
|
|
RowLayout::RowLayout(Flags flags) {
|
|
this->flags = flags;
|
|
spacing = 2.0f;
|
|
}
|
|
|
|
RowLayout::~RowLayout() {
|
|
|
|
}
|
|
|
|
vec2 RowLayout::GetSize(Composite* comp) {
|
|
if (!comp->controls.size()) {
|
|
vec2 size = comp->rect.size;
|
|
if (comp->v_bar)
|
|
size.x += comp->v_bar->rect.size.x;
|
|
return size;
|
|
}
|
|
|
|
vec2 size = 0.0f;
|
|
if (flags == VERTICAL) {
|
|
for (Control* i : comp->controls) {
|
|
vec2 _size = i->GetSize();
|
|
size.x = max_def(_size.x, size.x);
|
|
size.y += _size.y + spacing;
|
|
}
|
|
size.y -= spacing;
|
|
}
|
|
else {
|
|
for (Control* i : comp->controls) {
|
|
vec2 _size = i->GetSize();
|
|
size.x += _size.x + spacing;
|
|
size.y = max_def(_size.y, size.y);
|
|
}
|
|
size.x -= spacing;
|
|
}
|
|
|
|
if (comp->v_bar)
|
|
size.x += comp->v_bar->rect.size.x;
|
|
return size;
|
|
}
|
|
|
|
void RowLayout::SetSize(Composite* comp) {
|
|
rectangle comp_bb = comp->GetBoundingBox();
|
|
if (!comp->controls.size())
|
|
return;
|
|
|
|
if (comp->controls.size() == 1) {
|
|
Scrollable* scrollable = dynamic_cast<Scrollable*>(comp->controls.front());
|
|
if (scrollable) {
|
|
scrollable->rect.pos = 0.0f;
|
|
scrollable->SetSize(comp_bb.size);
|
|
return;
|
|
}
|
|
}
|
|
|
|
float_t pos = 0.0f;
|
|
if (flags == VERTICAL)
|
|
for (Control*& i : comp->controls) {
|
|
i->rect.pos = { 0.0f, pos };
|
|
float_t size_y = i->GetSize().y;
|
|
i->SetSize({ comp_bb.size.x, size_y });
|
|
pos += size_y + spacing;
|
|
}
|
|
else
|
|
for (Control*& i : comp->controls) {
|
|
i->rect.pos = { pos, 0.0f };
|
|
float_t size_x = i->GetSize().x;
|
|
i->SetSize({ size_x, comp_bb.size.y });
|
|
pos += size_x + spacing;
|
|
}
|
|
}
|
|
|
|
Group::Group(Composite* parent, Flags flags) : Composite(parent, (Flags)(flags & ~(VERTICAL | HORIZONTAL))) {
|
|
|
|
}
|
|
|
|
Group::~Group() {
|
|
|
|
}
|
|
|
|
void Group::Draw() {
|
|
print->SetFont(&font);
|
|
|
|
rectangle rect = GetRectangle();
|
|
|
|
float_t half_glyph_height = prj::floorf(font.GetFontGlyphHeight() * 0.5f);
|
|
rect.pos.y += half_glyph_height;
|
|
rect.size.y -= half_glyph_height;
|
|
|
|
print->SetColor(colors_current.border_color);
|
|
print->sub_140301390(rect, 2.0f);
|
|
|
|
rect.size += -1.0f;
|
|
print->SetColor(color_black);
|
|
print->sub_140301390(rect, 1.0f);
|
|
|
|
if (GetText().size()) {
|
|
rectangle rect = GetRectangle();
|
|
|
|
rect.pos.x += 2.0f;
|
|
rect.pos.y = rect.pos.y;
|
|
rect.size.x += 2.0f * -2.0f;
|
|
rect.size.y = font.GetFontGlyphHeight();
|
|
|
|
vec2 text_size = print->GetTextSize(GetText());
|
|
rect.size.x = min_def(text_size.x, rect.size.x);
|
|
|
|
print->SetFillColor(colors_current.background);
|
|
print->FillRectangle(rect);
|
|
|
|
print->SetColor(colors_current.foreground);
|
|
print->SetClipData(rect);
|
|
print->PrintText(GetText(), rect.pos.x, rect.pos.y);
|
|
}
|
|
|
|
Composite::Draw();
|
|
}
|
|
|
|
vec2 Group::GetSize() {
|
|
vec2 size = Composite::GetSize();
|
|
size.x += 2.0f * 2.0f;
|
|
size.y += font.GetFontGlyphHeight() + 2.0f;
|
|
return size;
|
|
}
|
|
|
|
rectangle Group::GetBoundingBox() {
|
|
float_t glyph_height = font.GetFontGlyphHeight();
|
|
|
|
rectangle rect = Scrollable::GetBoundingBox();
|
|
rect.pos.x += 2.0f;
|
|
rect.pos.y += glyph_height;
|
|
rect.size.x -= 2.0f * 2.0f;
|
|
rect.size.y -= glyph_height + 2.0f;
|
|
return rect;
|
|
}
|
|
|
|
Label::Label(Composite* parent, Flags flags) : Control(parent, flags) {
|
|
|
|
}
|
|
|
|
Label::~Label() {
|
|
|
|
}
|
|
|
|
void Label::Draw() {
|
|
rectangle rect = GetRectangle();
|
|
print->SetFont(&font);
|
|
vec2 text_size = print->GetTextSize(GetText());
|
|
|
|
float_t pos_x;
|
|
if (flags & FLAG_4000)
|
|
pos_x = rect.pos.x;
|
|
else if (flags & FLAG_20000)
|
|
pos_x = rect.pos.x + rect.size.x - text_size.x;
|
|
else
|
|
pos_x = rect.pos.x + (rect.size.x - text_size.x) * 0.5f;
|
|
float_t pos_y = rect.pos.y + (rect.size.y - text_size.y) * 0.5f;
|
|
|
|
print->SetColor(GetParentEnabled()
|
|
? colors_current.foreground
|
|
: colors_current.disable_foreground);
|
|
print->SetClipData(rect);
|
|
print->SetFont(&font);
|
|
print->PrintText(GetText(), pos_x, pos_y);
|
|
}
|
|
|
|
vec2 Label::GetSize() {
|
|
print->SetFont(&font);
|
|
return print->GetTextSize(text) + 2.0f * 2.0f;
|
|
}
|
|
|
|
Button::Button(Composite* parent, Flags flags) : Control(parent, flags), value(), callback(), field_100() {
|
|
field_104 = 1;
|
|
SetSize(GetSize());
|
|
}
|
|
|
|
Button::~Button() {
|
|
|
|
}
|
|
|
|
void Button::Draw() {
|
|
print->SetFont(&this->font);
|
|
vec2 checkbox_size = print->GetTextSize(L"[X]");
|
|
|
|
rectangle v6 = GetRectangle();
|
|
rectangle v8 = v6;
|
|
|
|
if (flags & (FLAG_8 | MULTISELECT)) {
|
|
int32_t v3;
|
|
if ((field_100 & 0x01) && (field_100 & 0x02)) {
|
|
v3 = 4;
|
|
v8.pos.x += 2.0f;
|
|
v8.size.x += -2.0f;
|
|
}
|
|
else
|
|
v3 = 2;
|
|
|
|
sub_1402EE3C0(v6, 2.0f, v3, &colors_current.button_background);
|
|
|
|
v8.pos += 2.0f;
|
|
v8.size -= 2.0f * 2.0f;
|
|
}
|
|
else if (flags & CHECKBOX) {
|
|
print->SetColor(colors_current.button_foreground);
|
|
print->SetClipData(v8);
|
|
print->PrintText(value ? L"[X]" : L"[ ]", v8.pos.x, v8.pos.y);
|
|
|
|
v8.size.x -= checkbox_size.x;
|
|
v8.pos.x += checkbox_size.x;
|
|
}
|
|
else if (flags & RADIOBUTTON) {
|
|
print->SetColor(colors_current.button_foreground);
|
|
print->SetClipData(v8);
|
|
print->PrintText(value ? L"(*)" : L"( )", v8.pos.x, v8.pos.y);
|
|
|
|
v8.size.x -= checkbox_size.x;
|
|
v8.pos.x += checkbox_size.x;
|
|
}
|
|
|
|
std::wstring text = GetText();
|
|
|
|
print->SetFont(&font);
|
|
vec2 text_size = print->GetTextSize(text);
|
|
|
|
if (!(flags & (CHECKBOX | RADIOBUTTON))) {
|
|
float_t v5 = (v8.size.x - text_size.x) * 0.5f;
|
|
v8.pos.x = v8.pos.x + v5;
|
|
v8.size.x = v8.size.x + (v5 * -2.0f);
|
|
}
|
|
|
|
if (GetParentEnabled()) {
|
|
print->SetColor(colors_current.button_foreground);
|
|
print->SetClipData(v8);
|
|
print->PrintText(text, v8.pos.x, v8.pos.y);
|
|
if (Field_60()) {
|
|
print->SetColor(colors_current.focus_border_color);
|
|
print->sub_140301390(v8, 1.0);
|
|
}
|
|
}
|
|
else {
|
|
print->SetColor(colors_current.button_disable_foreground);
|
|
print->SetClipData(v8);
|
|
print->PrintText(text, v8.pos.x, v8.pos.y);
|
|
}
|
|
}
|
|
|
|
int32_t Button::KeyCallback(const Widget::KeyCallbackData& data) {
|
|
if (!GetParentEnabled())
|
|
return 0;
|
|
|
|
if (data.key_input != 0x0D && data.key_input != 0x20)
|
|
return Control::KeyCallback(data);
|
|
|
|
if (flags & CHECKBOX)
|
|
SetValue(!value);
|
|
else if (flags & RADIOBUTTON)
|
|
SetValue(true);
|
|
|
|
if (callback)
|
|
callback(this);
|
|
|
|
SelectionListener::CallbackData callback_data = this;
|
|
for (SelectionListener*& i : selection_listeners)
|
|
i->Callback(&callback_data);
|
|
|
|
field_100 &= ~0x102;
|
|
return Control::KeyCallback(data);
|
|
}
|
|
|
|
int32_t Button::MouseCallback(const Widget::MouseCallbackData& data) {
|
|
if (!GetParentEnabled())
|
|
return 0;
|
|
|
|
field_100 &= ~0x01;
|
|
if (CheckHitPos(data.pos))
|
|
field_100 |= 0x01;
|
|
|
|
if (field_100 & 0x01) {
|
|
if ((data.input & MOUSE_INPUT_TAP_MASK) && !Field_60())
|
|
Field_58();
|
|
|
|
if (data.input & MOUSE_INPUT_RELEASE_LEFT) {
|
|
if (field_100 & 0x02)
|
|
field_100 = (field_100 & ~0x02) | 0x100;
|
|
}
|
|
else if (data.input & MOUSE_INPUT_TAP_LEFT)
|
|
field_100 |= 0x02;
|
|
}
|
|
|
|
if (field_100 & 0x100) {
|
|
field_104--;
|
|
|
|
if (flags & CHECKBOX)
|
|
SetValue(!value);
|
|
else if (flags & RADIOBUTTON)
|
|
SetValue(true);
|
|
|
|
if (callback)
|
|
callback(this);
|
|
|
|
SelectionListener::CallbackData callback_data = this;
|
|
for (SelectionListener*& i : selection_listeners)
|
|
i->Callback(&callback_data);
|
|
|
|
field_100 &= ~0x102;
|
|
field_104 = 1;
|
|
}
|
|
|
|
return Control::MouseCallback(data);
|
|
}
|
|
|
|
vec2 Button::GetSize() {
|
|
print->SetFont(&font);
|
|
vec2 size = print->GetTextSize(text);
|
|
|
|
if (flags & FLAG_8) {
|
|
size.x += 2.0f;
|
|
size.x += 2.0f * 2.0f;
|
|
size.y += 2.0f * 2.0f;
|
|
}
|
|
else if (flags & RADIOBUTTON) {
|
|
print->SetFont(&font);
|
|
size.x += print->GetTextSize("(X)").x;
|
|
}
|
|
else if (flags & CHECKBOX) {
|
|
print->SetFont(&font);
|
|
size.x += print->GetTextSize("[X]").x;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
void Button::AddSelectionListener(SelectionListener* value) {
|
|
selection_listeners.push_back(value);
|
|
}
|
|
|
|
void Button::SetValue(bool value) {
|
|
this->value = value;
|
|
if (!(flags & RADIOBUTTON))
|
|
return;
|
|
|
|
for (Control* i : parent_comp->controls) {
|
|
Button* button = (Button*)dynamic_cast<Button*>(i);
|
|
if (button && button != this && button->flags & RADIOBUTTON)
|
|
button->value = false;
|
|
}
|
|
}
|
|
|
|
List::List(Composite* parent, Flags flags) : Scrollable(parent, flags), field_148() {
|
|
hovered_item = -1;
|
|
selected_item = -1;
|
|
|
|
max_items = -1;
|
|
if (flags & VERTICAL)
|
|
max_items = 10;
|
|
}
|
|
|
|
List::~List() {
|
|
|
|
}
|
|
|
|
void List::Draw() {
|
|
if (flags & FLAG_800) {
|
|
rectangle rect;
|
|
color4u8* v3;
|
|
if (GetParentEnabled()) {
|
|
rect = GetRectangle();
|
|
v3 = 0;
|
|
}
|
|
else {
|
|
rect = GetRectangle();
|
|
v3 = &colors_current.disable_background;
|
|
}
|
|
sub_1402EE3C0(rect, 2.0f, 2, v3);
|
|
}
|
|
|
|
Scrollable::Draw();
|
|
|
|
float_t glyph_height = GetFontGlyphHeight();
|
|
|
|
float_t pos_y = 0.0f;
|
|
if (v_bar)
|
|
pos_y = prj::floorf(v_bar->value);
|
|
print->SetFont(&font);
|
|
|
|
rectangle v21 = GetScrollableRectangle();
|
|
|
|
pos_y = -pos_y;
|
|
print->SetClipData(v21);
|
|
|
|
size_t items_count = items.size();
|
|
for (size_t i = 0; i < items_count; i++, pos_y += glyph_height) {
|
|
rectangle v22;
|
|
v22.pos.x = v21.pos.x;
|
|
v22.pos.y = v21.pos.y + pos_y;
|
|
v22.size.x = v21.size.x;
|
|
v22.size.y = glyph_height;
|
|
if (v21.pos.x + v21.size.x <= v21.pos.x
|
|
|| v21.pos.y + pos_y + glyph_height <= v21.pos.y
|
|
|| v21.size.y + v21.pos.y <= v21.pos.y + pos_y)
|
|
continue;
|
|
|
|
bool selected = false;
|
|
bool hovered = false;
|
|
|
|
color4u8 color;
|
|
if (!field_148) {
|
|
if ((flags & MULTISELECT) && selected_item == i || (flags & FLAG_2) && selections[i])
|
|
selected = true;
|
|
|
|
if (Field_60())
|
|
hovered = hovered_item == i;
|
|
|
|
if (selected) {
|
|
print->SetFillColor(colors_current.selection_background);
|
|
print->FillRectangle(v22);
|
|
color = colors_current.selection_foreground;
|
|
}
|
|
else if (GetParentEnabled())
|
|
color = colors_current.foreground;
|
|
else
|
|
color = colors_current.disable_foreground;
|
|
}
|
|
else {
|
|
if (hovered_item == i) {
|
|
print->SetFillColor(colors_current.popup_selection_background);
|
|
print->FillRectangle(v22);
|
|
color = colors_current.popup_selection_foreground;
|
|
}
|
|
else if (field_148)
|
|
color = colors_current.popup_foreground;
|
|
else if (GetParentEnabled())
|
|
color = colors_current.foreground;
|
|
else
|
|
color = colors_current.disable_foreground;
|
|
}
|
|
|
|
print->SetColor(color);
|
|
print->SetFont(&font);
|
|
print->PrintText(items[i], v21.pos.x, pos_y + v21.pos.y);
|
|
|
|
if (hovered) {
|
|
print->SetColor(colors_current.focus_border_color);
|
|
print->sub_140301390(v22, 1.0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
void List::Reset() {
|
|
items.clear();
|
|
items.shrink_to_fit();
|
|
selections.clear();
|
|
Scrollable::Reset();
|
|
}
|
|
|
|
int32_t List::KeyCallback(const Widget::KeyCallbackData& data) {
|
|
size_t items_count = items.size();
|
|
if (!data.key_input || !items_count)
|
|
return Control::KeyCallback(data);
|
|
|
|
size_t hovered_item = this->hovered_item;
|
|
|
|
SelectionListener::CallbackData v12 = v_bar;
|
|
|
|
size_t max_items_visible = GetMaxItemsVisible();
|
|
switch (data.key_input) {
|
|
case 0x1000001:
|
|
if (hovered_item == -1)
|
|
hovered_item = 0;
|
|
else if (hovered_item)
|
|
hovered_item--;
|
|
|
|
if (sub_1402F1F20(hovered_item) && !sub_1402F1F20(hovered_item))
|
|
v12.field_8 = data.key_input;
|
|
break;
|
|
case 0x1000002:
|
|
if (hovered_item == -1)
|
|
hovered_item = 0;
|
|
else if (hovered_item < items_count - 1)
|
|
hovered_item++;
|
|
|
|
if (sub_1402F1F20(hovered_item) && !sub_1402F1F20(hovered_item))
|
|
v12.field_8 = data.key_input;
|
|
break;
|
|
case 0x1000005:
|
|
if (hovered_item == -1 || hovered_item < max_items_visible)
|
|
hovered_item = 0;
|
|
else
|
|
hovered_item -= max_items_visible;
|
|
v12.field_8 = data.key_input;
|
|
break;
|
|
case 0x1000006:
|
|
if (hovered_item == -1)
|
|
hovered_item = 0;
|
|
else if (max_items_visible >= items_count
|
|
|| hovered_item > items_count - max_items_visible - 1)
|
|
hovered_item = items_count - 1;
|
|
else
|
|
hovered_item += max_items_visible;
|
|
v12.field_8 = data.key_input;
|
|
break;
|
|
case 0x1000007:
|
|
hovered_item = 0;
|
|
v12.field_8 = data.key_input;
|
|
break;
|
|
case 0x1000008:
|
|
hovered_item = items_count - 1;
|
|
v12.field_8 = data.key_input;
|
|
break;
|
|
}
|
|
|
|
if (hovered_item < items_count && hovered_item != -1 && this->hovered_item != hovered_item) {
|
|
SetItemIndex(hovered_item);
|
|
|
|
SelectionListener::CallbackData callback_data = parent;
|
|
for (SelectionListener*& i : selection_listeners)
|
|
i->Callback(&callback_data);
|
|
|
|
if (v12.field_8 && v_bar)
|
|
ScrollBar::sub_1402E6CC0(v12);
|
|
|
|
sub_1402F9C90(hovered_item);
|
|
}
|
|
|
|
return Control::KeyCallback(data);
|
|
}
|
|
|
|
int32_t List::MouseCallback(const Widget::MouseCallbackData& data) {
|
|
if (!GetParentEnabled() || !CheckHitPos(data.pos))
|
|
return 0;
|
|
|
|
if (!field_148 && (data.input & MOUSE_INPUT_TAP_MASK) && !Field_60())
|
|
Field_58();
|
|
|
|
rectangle v27 = GetScrollableRectangle();
|
|
if (v27.pos.x > data.pos.x || data.pos.x >= v27.size.x + v27.pos.x
|
|
|| v27.pos.y > data.pos.y || data.pos.y >= v27.size.y + v27.pos.y)
|
|
return Scrollable::MouseCallback(data);
|
|
|
|
size_t hovered_item = this->hovered_item;
|
|
if (field_148 && (data.input & MOUSE_INPUT_MOVE) || (data.input & MOUSE_INPUT_TAP_LEFT)) {
|
|
float_t glyph_height = GetFontGlyphHeight();
|
|
float_t v10 = (float_t)sub_1402EF570();
|
|
if (v10 < 0.0f)
|
|
v10 += (float_t)UINT64_MAX;
|
|
|
|
size_t v11 = 0;
|
|
float_t v12 = (data.pos.y - (v27.pos.y - v10 * glyph_height)) / glyph_height;
|
|
|
|
if (v12 >= (float_t)INT64_MAX) {
|
|
v12 -= (float_t)INT64_MAX;
|
|
if (v12 < (float_t)INT64_MAX)
|
|
v11 = 0x8000000000000000u;
|
|
}
|
|
|
|
size_t hovered_item = v11 + (int64_t)v12;
|
|
if (hovered_item < items.size())
|
|
this->hovered_item = hovered_item;
|
|
}
|
|
|
|
if (hovered_item < this->items.size()) {
|
|
if (data.input & MOUSE_INPUT_TAP_LEFT) {
|
|
if (data.state & INPUT_STATE_SHIFT) {
|
|
ResetSelectedItem();
|
|
size_t end = this->hovered_item;
|
|
size_t begin = hovered_item;
|
|
if (end < begin) {
|
|
begin = this->hovered_item;
|
|
end = hovered_item;
|
|
}
|
|
|
|
SetSelectedItems(begin, end);
|
|
}
|
|
else if (data.state & INPUT_STATE_CTRL) {
|
|
if (CheckItemSelected(hovered_item))
|
|
UnsetSelectedItem(hovered_item);
|
|
else
|
|
SetSelectedItem(hovered_item);
|
|
}
|
|
else {
|
|
ResetSelectedItem();
|
|
SetSelectedItem(this->hovered_item);
|
|
}
|
|
|
|
SelectionListener::CallbackData v26 = parent;
|
|
for (SelectionListener*& i : selection_listeners)
|
|
i->Callback(&v26);
|
|
}
|
|
|
|
if (data.input & MOUSE_INPUT_DBL_TAP_LEFT) {
|
|
SelectionListener::CallbackData v26 = parent;
|
|
for (SelectionListener*& i : selection_listeners)
|
|
i->Field_10(&v26);
|
|
}
|
|
}
|
|
|
|
if ((data.input & MOUSE_INPUT_100000) || (data.input & MOUSE_INPUT_200000))
|
|
return Scrollable::MouseCallback(data);
|
|
return 0;
|
|
}
|
|
|
|
void List::SetSize(const vec2& size) {
|
|
Scrollable::SetSize(size);
|
|
SetScrollBarParams();
|
|
}
|
|
|
|
vec2 List::GetSize() {
|
|
print->SetFont(&font);
|
|
|
|
float_t max_text_size = 0.0f;
|
|
for (std::wstring& i : items) {
|
|
vec2 text_size = print->GetTextSize(i);
|
|
max_text_size = max_def(text_size.x, max_text_size);
|
|
}
|
|
|
|
size_t max_items_visible = GetMaxItemsVisible();
|
|
size_t items_count = items.size();
|
|
float_t glyph_height = font.GetFontGlyphHeight();
|
|
|
|
float_t v14 = (float_t)(int64_t)min_def(max_items_visible, items_count);
|
|
if (v14 < 0.0f)
|
|
v14 += (float_t)UINT64_MAX;
|
|
|
|
vec2 size = { max_text_size, glyph_height * v14 };
|
|
if (v_bar)
|
|
size.x += v_bar->rect.size.x;
|
|
|
|
if (flags & FLAG_800)
|
|
size += 2.0f * 2.0f;
|
|
return size;
|
|
}
|
|
|
|
void List::AddItem(const std::string& str) {
|
|
items.push_back(utf8_to_utf16(str));
|
|
}
|
|
|
|
void List::AddItem(const std::wstring& str) {
|
|
items.push_back(str);
|
|
}
|
|
|
|
void List::AddSelectionListener(SelectionListener* value) {
|
|
selection_listeners.push_back(value);
|
|
}
|
|
|
|
void List::Callback(SelectionListener::CallbackData* data) {
|
|
if (data->widget)
|
|
for (SelectionListener*& i : selection_listeners)
|
|
i->Callback(data);
|
|
}
|
|
|
|
bool List::CheckItemSelected(size_t index) {
|
|
if (index >= items.size())
|
|
return false;
|
|
else if (flags & MULTISELECT)
|
|
return index == selected_item;
|
|
return selections[index] != 0;
|
|
}
|
|
|
|
void List::ClearItems() {
|
|
items.clear();
|
|
selections.clear();
|
|
hovered_item = -1;
|
|
selected_item = -1;
|
|
}
|
|
|
|
std::string List::GetItemStr(size_t index) const {
|
|
return utf16_to_utf8(items[index]);
|
|
}
|
|
|
|
std::wstring List::GetItem(size_t index) const {
|
|
return items[index];
|
|
}
|
|
|
|
size_t List::GetItemCount() const {
|
|
return items.size();
|
|
}
|
|
|
|
size_t List::GetMaxItemsVisible() const {
|
|
if (!v_bar)
|
|
return items.size();
|
|
else if (max_items >= items.size())
|
|
return items.size();
|
|
return max_items;
|
|
}
|
|
|
|
void List::ResetSelectedItem() {
|
|
if (flags & MULTISELECT)
|
|
selected_item = -1;
|
|
else
|
|
for (int32_t& i : selections)
|
|
i = 0;
|
|
}
|
|
|
|
void List::SetMaxItems(size_t value) {
|
|
max_items = value;
|
|
}
|
|
|
|
void List::SetScrollBarParams() {
|
|
rectangle bb = GetBoundingBox();
|
|
if (v_bar)
|
|
v_bar->SetParams(bb.size.y, font.GetFontGlyphHeight(), items.size());
|
|
}
|
|
|
|
void List::SetSelectedItem(size_t index) {
|
|
if (index < items.size())
|
|
if (flags & MULTISELECT)
|
|
selected_item = index;
|
|
else
|
|
selections[index] = 1;
|
|
}
|
|
|
|
void List::SetSelectedItems(size_t begin, size_t end) {
|
|
if (end < begin || end >= items.size())
|
|
return;
|
|
|
|
if (flags & MULTISELECT) {
|
|
if (begin == end)
|
|
selected_item = begin;
|
|
}
|
|
else
|
|
for (size_t i = begin; i <= end; i++)
|
|
selections[i] = 1;
|
|
}
|
|
|
|
void List::UnsetSelectedItem(size_t index) {
|
|
if (index < items.size())
|
|
if (flags & MULTISELECT)
|
|
selected_item = -1;
|
|
else
|
|
selections[index] = 0;
|
|
}
|
|
|
|
int64_t List::sub_1402EF570() {
|
|
float_t glyph_height = GetFontGlyphHeight();
|
|
|
|
float_t v4 = 0.0f;
|
|
if (v_bar)
|
|
v4 = prj::floorf(v_bar->value / glyph_height);
|
|
|
|
int64_t v6 = 0;
|
|
if (v4 >= (float_t)INT64_MAX) {
|
|
v4 -= (float_t)INT64_MAX;
|
|
if (v4 < (float_t)INT64_MAX)
|
|
v6 = 0x8000000000000000u;
|
|
}
|
|
return v6 + (int64_t)v4;
|
|
}
|
|
|
|
bool List::sub_1402F1F20(size_t index) {
|
|
size_t max_items_visible = GetMaxItemsVisible();
|
|
size_t v5 = sub_1402EF570();
|
|
return max_items_visible >= items.size()
|
|
|| v5 <= index && index < max_items_visible + v5;
|
|
}
|
|
|
|
void List::sub_1402F9680(int64_t index) {
|
|
if (!v_bar)
|
|
return;
|
|
|
|
float_t glyph_height = GetFontGlyphHeight();
|
|
|
|
size_t max_items_visible = GetMaxItemsVisible();
|
|
size_t items_count = items.size();
|
|
if (items_count <= max_items_visible)
|
|
return;
|
|
|
|
float_t value = 0.0f;
|
|
if (index != -1) {
|
|
if (items_count - index >= max_items_visible)
|
|
value = (float_t)index;
|
|
else
|
|
value = (float_t)(items_count - max_items_visible);
|
|
|
|
if (value < 0.0f)
|
|
value += (float_t)UINT64_MAX;
|
|
|
|
value *= glyph_height;
|
|
}
|
|
|
|
v_bar->SetValue(value);
|
|
}
|
|
|
|
void List::sub_1402F9C90(size_t index) {
|
|
if (!sub_1402F1F20(index))
|
|
sub_1402F9680(index);
|
|
}
|
|
|
|
ListBox::ListBox(Composite* parent, Flags flags) : Composite(parent, flags), list(), field_118() {
|
|
list = new List(this, flags);
|
|
list->field_148 = true;
|
|
list->SetText(L"ddl");
|
|
list->parent = this;
|
|
|
|
if (list->v_bar) {
|
|
list->v_bar->parent = this;
|
|
list->v_bar->AddSelectionListener(&drop_down_list_scroll_bar_selection_listener);
|
|
}
|
|
}
|
|
|
|
ListBox::~ListBox() {
|
|
|
|
}
|
|
|
|
void ListBox::Draw() {
|
|
if (!parent_shell->field_170) {
|
|
rectangle v13 = GetRectangle();
|
|
sub_1402EE3C0(v13, 2.0, 4, GetParentEnabled()
|
|
? &colors_current.background
|
|
: &colors_current.disable_background);
|
|
v13.pos = v13.pos + 2.0f;
|
|
v13.size = v13.size - 2.0f * 2.0f;
|
|
|
|
rectangle v14 = v13;
|
|
|
|
vec2 glyph_size = font.GetFontGlyphSize();
|
|
|
|
rectangle v15;
|
|
v15.pos = v13.pos + v13.size - glyph_size;
|
|
v15.size = glyph_size;
|
|
|
|
print->SetFont(&font);
|
|
print->SetColor(colors_current.foreground);
|
|
print->sub_140301390(v15, 1.0f);
|
|
print->SetClipData(v15);
|
|
print->PrintText(L"v", v15.pos.x, v15.pos.y);
|
|
|
|
v14.size.x -= glyph_size.x;
|
|
|
|
if (Field_60()) {
|
|
print->SetColor(colors_current.focus_border_color);
|
|
print->sub_140301390(v14, 1.0f);
|
|
}
|
|
|
|
if (list->selected_item < list->items.size()) {
|
|
print->SetFont(&font);
|
|
print->SetColor(GetParentEnabled()
|
|
? colors_current.foreground
|
|
: colors_current.disable_foreground);
|
|
print->SetClipData(v14);
|
|
print->PrintText(GetItem(list->selected_item), v14.pos.x, v14.pos.y);
|
|
}
|
|
}
|
|
|
|
if (parent_shell->field_170 && field_118) {
|
|
rectangle rect = GetListRectangle();
|
|
print->SetFillColor(colors_current.popup_background);
|
|
print->FillRectangle(rect);
|
|
list->UpdateDraw();
|
|
print->SetColor(color_black);
|
|
print->sub_140301390(rect, 1.0f);
|
|
}
|
|
}
|
|
|
|
void ListBox::Reset() {
|
|
Composite::Reset();
|
|
}
|
|
|
|
int32_t ListBox::KeyCallback(const Widget::KeyCallbackData& data) {
|
|
if (!GetParentEnabled())
|
|
return 0;
|
|
|
|
list->KeyCallback(data);
|
|
if (field_118 && data.key_input == 0x0D)
|
|
sub_1402E4F40();
|
|
return 0;
|
|
}
|
|
|
|
int32_t ListBox::MouseCallback(const Widget::MouseCallbackData& data) {
|
|
if (!GetParentEnabled())
|
|
return 0;
|
|
|
|
if ((data.input & MOUSE_INPUT_TAP_MASK) && !Field_60())
|
|
Field_58();
|
|
|
|
if (field_118) {
|
|
list->MouseCallback(data);
|
|
|
|
if ((data.input & MOUSE_INPUT_TAP_LEFT) && (!list->CheckHitPos(data.pos)
|
|
|| ListBox::sub_1402EC8C0(list->GetScrollableRectangle(), data.pos))) {
|
|
sub_1402E4F40();
|
|
return 0;
|
|
}
|
|
}
|
|
else if (CheckHitPos(data.pos) && (data.input & MOUSE_INPUT_TAP_LEFT))
|
|
sub_1402E4F90();
|
|
return 0;
|
|
}
|
|
|
|
vec2 ListBox::GetSize() {
|
|
vec2 size = list->GetSize();
|
|
size.x += font.GetFontGlyphWidth();
|
|
size.y = font.GetFontGlyphHeight();
|
|
return size + 2.0f * 2.0f;
|
|
}
|
|
|
|
void ListBox::SetFont(p_Font& value) {
|
|
Scrollable::SetFont(value);
|
|
|
|
if (list)
|
|
list->SetFont(value);
|
|
}
|
|
|
|
rectangle ListBox::GetListRectangle() {
|
|
return list->GetRectangle();
|
|
}
|
|
|
|
void ListBox::sub_1402E4440() {
|
|
rectangle rect = GetRectangle();
|
|
vec2 size = list->GetSize();
|
|
|
|
vec2 pos;
|
|
if (dw_gui_detail_display->data.field_0.pos.y
|
|
+ dw_gui_detail_display->data.field_0.size.y > rect.pos.y + rect.size.y + size.y)
|
|
pos.y = rect.size.y;
|
|
else
|
|
pos.y = -size.y;
|
|
|
|
list->rect.pos = pos;
|
|
list->SetSize({ max_def(rect.size.x, size.x), size.y });
|
|
}
|
|
|
|
void ListBox::sub_1402E4F40() {
|
|
parent_shell->sub_1402E61F0(this);
|
|
dw_gui_detail_display_set_cap(this, false);
|
|
|
|
list->hovered_item = list->selected_item;
|
|
field_118 = false;
|
|
}
|
|
|
|
void ListBox::sub_1402E4F90() {
|
|
field_118 = true;
|
|
sub_1402E4440();
|
|
|
|
list->hovered_item = list->selected_item;
|
|
list->sub_1402F9C90(list->selected_item);
|
|
|
|
dw_gui_detail_display_set_cap(this, true);
|
|
parent_shell->sub_1402E43C0(this);
|
|
}
|
|
|
|
bool ListBox::sub_1402EC8C0(rectangle rect, vec2 pos) {
|
|
return (rect.pos.x <= pos.x && pos.x < rect.pos.x + rect.size.x)
|
|
&& (rect.pos.y <= pos.y && pos.y < rect.pos.y + rect.size.y);
|
|
}
|
|
|
|
ScrollBar::ScrollBar(Control* parent, Flags flags) : Widget(parent, flags),
|
|
value(), min(), field_A0(), field_A5(), field_A6() {
|
|
parent_control = parent;
|
|
max = 100.0f;
|
|
grab = 10.0f;
|
|
step = 1.0f;
|
|
step_fast = 10.0f;
|
|
round = true;
|
|
font = p_font_type_scroll_bar;
|
|
SetSize({ 8.0f, 8.0f });
|
|
}
|
|
|
|
ScrollBar::~ScrollBar() {
|
|
|
|
}
|
|
|
|
void ScrollBar::Draw() {
|
|
rectangle v14 = GetRectangle();
|
|
print->SetColor(colors_current.border_color);
|
|
print->sub_140301390(v14, 1.0f);
|
|
print->SetClipData(v14);
|
|
print->SetColor(Field_60()
|
|
? colors_current.foreground
|
|
: colors_current.disable_foreground);
|
|
print->SetFont(&font);
|
|
|
|
vec2 glyph_size = font.GetFontGlyphSize();
|
|
rectangle v16;
|
|
v16.pos = v14.pos;
|
|
v16.size = glyph_size;
|
|
|
|
if (flags & HORIZONTAL) {
|
|
print->sub_140301390(v16, 1.0f);
|
|
print->PrintText(L"<", v14.pos.x, v14.pos.y);
|
|
|
|
v16.pos.x = v14.size.x + v14.pos.x - glyph_size.x;
|
|
print->sub_140301390(v16, 1.0f);
|
|
print->PrintText(L">", v14.size.x + v14.pos.x - v16.size.x, v14.pos.y);
|
|
|
|
rectangle v18 = v14;
|
|
v18.pos.x = v14.pos.x + glyph_size.x;
|
|
v18.size.x = v14.size.x - v16.size.x * 2.0f;
|
|
print->SetFillColor(color_grey);
|
|
print->FillRectangle(v18);
|
|
|
|
vec2 v11 = sub_1402E4790();
|
|
rectangle v17 = v18;
|
|
v17.pos.x = v11.x + v18.pos.x;
|
|
v17.size.x = v11.y;
|
|
print->SetFillColor(colors_current.background);
|
|
print->FillRectangle(v17);
|
|
print->sub_140301390(v17, 1.0f);
|
|
print->PrintText(L"#", v17.size.x * 0.5f + v17.pos.x - glyph_size.x * 0.5f, v17.pos.y);
|
|
}
|
|
else {
|
|
print->sub_140301390(v16, 1.0f);
|
|
print->PrintText(L"A", v14.pos.x, v14.pos.y);
|
|
|
|
v16.pos.y = v14.size.y + v14.pos.y - glyph_size.y;
|
|
print->sub_140301390(v16, 1.0f);
|
|
print->PrintText(L"V", v14.pos.x, v14.size.y + v14.pos.y - v16.size.y);
|
|
|
|
rectangle v18 = v14;
|
|
v18.pos.y = v14.pos.y + glyph_size.y;
|
|
v18.size.y = v14.size.y - v16.size.y * 2.0f;
|
|
print->SetFillColor(color_grey);
|
|
print->FillRectangle(v18);
|
|
|
|
vec2 v11 = sub_1402E4790();
|
|
rectangle v17 = v18;
|
|
v17.pos.y = v11.x + v18.pos.y;
|
|
v17.size.y = v11.y;
|
|
print->SetFillColor(colors_current.background);
|
|
print->FillRectangle(v17);
|
|
print->sub_140301390(v17, 1.0f);
|
|
print->PrintText(L"#", v17.pos.x, v17.size.y * 0.5f + v17.pos.y - glyph_size.y * 0.5f);
|
|
}
|
|
|
|
}
|
|
|
|
int32_t ScrollBar::KeyCallback(const Widget::KeyCallbackData& data) {
|
|
if (!Field_60())
|
|
return 0;
|
|
|
|
SelectionListener::CallbackData v6 = sub_1402E5140(data);
|
|
if (v6.widget)
|
|
for (SelectionListener*& i : selection_listeners)
|
|
i->Callback(&v6);
|
|
return 0;
|
|
}
|
|
|
|
int32_t ScrollBar::MouseCallback(const Widget::MouseCallbackData& data) {
|
|
if (!Field_60())
|
|
return 0;
|
|
|
|
bool v4 = field_A6;
|
|
SelectionListener::CallbackData v8 = sub_1402E5380(data);
|
|
if (v4 != field_A6)
|
|
dw_gui_detail_display_set_cap(this, field_A6);
|
|
|
|
if (v8.widget)
|
|
for (SelectionListener*& i : selection_listeners)
|
|
i->Callback(&v8);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void ScrollBar::SetSize(const vec2& size) {
|
|
if (flags & HORIZONTAL) {
|
|
rect.size.x = size.x;
|
|
rect.size.y = font.GetFontGlyphHeight();
|
|
}
|
|
else {
|
|
rect.size.x = font.GetFontGlyphWidth();
|
|
rect.size.y = size.y;
|
|
}
|
|
}
|
|
|
|
vec2 ScrollBar::GetPos() {
|
|
vec2 pos = rect.pos;
|
|
Control* control = GetParentControl();
|
|
if (control) {
|
|
pos += control->GetPos();
|
|
Scrollable* scrollable = dynamic_cast<Scrollable*>(control);
|
|
if (scrollable && scrollable->flags & FLAG_800)
|
|
pos += 2.0f;
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
Control* ScrollBar::GetParentControl() {
|
|
return parent_control;
|
|
}
|
|
|
|
void ScrollBar::SetFont(p_Font& value) {
|
|
font = value;
|
|
}
|
|
|
|
bool ScrollBar::Field_58() {
|
|
return !field_A5;
|
|
}
|
|
|
|
bool ScrollBar::Field_60() {
|
|
return GetParentControl()->GetParentEnabled() && Field_58();
|
|
}
|
|
|
|
void ScrollBar::Field_68(bool value) {
|
|
field_A5 = !value;
|
|
}
|
|
|
|
void ScrollBar::SetGrab(float_t value) {
|
|
grab = value;
|
|
}
|
|
|
|
void ScrollBar::SetMax(float_t value) {
|
|
max = value;
|
|
}
|
|
|
|
void ScrollBar::SetMin(float_t value) {
|
|
min = value;
|
|
}
|
|
|
|
void ScrollBar::SetParams(float_t value, float_t min,
|
|
float_t max, float_t grab, float_t step, float_t step_fast) {
|
|
this->value = value;
|
|
this->grab = grab;
|
|
this->min = min;
|
|
this->step_fast = step_fast;
|
|
this->max = max;
|
|
this->step = step;
|
|
}
|
|
|
|
void ScrollBar::SetParams(float_t size, float_t step, size_t items_count) {
|
|
if (!items_count)
|
|
return;
|
|
|
|
float_t v5 = (float_t)(int64_t)items_count;
|
|
if (v5 < 0.0f)
|
|
v5 += (float_t)UINT64_MAX;
|
|
|
|
float_t v6 = v5 * step;
|
|
if (v6 > size) {
|
|
min = 0.0f;
|
|
max = v6 - size;
|
|
grab = (size / v6) * (v6 - size);
|
|
ScrollBar::SetValue(value);
|
|
this->step = step;
|
|
|
|
size_t v8 = 0;
|
|
float_t v9 = size / step;
|
|
if (v9 >= (float_t)INT64_MAX) {
|
|
v9 -= (float_t)INT64_MAX;
|
|
if (v9 < (float_t)INT64_MAX)
|
|
v8 = INT64_MIN;
|
|
}
|
|
|
|
float_t v11 = (float_t)(int64_t)(v8 + (int64_t)v9);
|
|
if (v11 < 0.0f)
|
|
v11 += (float_t)UINT64_MAX;
|
|
step_fast = v11 * step;
|
|
}
|
|
else {
|
|
min = 0.0f;
|
|
max = 0.0f;
|
|
grab = v6;
|
|
SetValue(value);
|
|
this->step = step;
|
|
step_fast = v6;
|
|
}
|
|
}
|
|
|
|
void ScrollBar::SetRound(bool value) {
|
|
round = value;
|
|
}
|
|
|
|
void ScrollBar::SetValue(float_t value) {
|
|
value = clamp_def(value, min, max);
|
|
if (round)
|
|
this->value = prj::roundf(value / step) * step;
|
|
else
|
|
this->value = value;
|
|
}
|
|
|
|
void ScrollBar::SetWidth(float_t value) {
|
|
vec2 glyph_size = font.GetFontGlyphSize();
|
|
if (flags & HORIZONTAL) {
|
|
rect.size.x = value;
|
|
rect.size.y = glyph_size.y;
|
|
}
|
|
else {
|
|
rect.size.x = glyph_size.x;
|
|
rect.size.y = value;
|
|
}
|
|
}
|
|
|
|
void ScrollBar::AddSelectionListener(SelectionListener* value) {
|
|
selection_listeners.push_back(value);
|
|
}
|
|
|
|
vec2 ScrollBar::sub_1402E4790() {
|
|
vec2 glyph_size = font.GetFontGlyphSize();
|
|
|
|
float_t _glyph_size;
|
|
float_t size;
|
|
if (flags & HORIZONTAL) {
|
|
_glyph_size = glyph_size.x;
|
|
size = rect.size.x;
|
|
}
|
|
else {
|
|
_glyph_size = glyph_size.y;
|
|
size = rect.size.y;
|
|
}
|
|
|
|
size -= _glyph_size * 2.0f;
|
|
float_t range = max - min;
|
|
if (range > 0.0) {
|
|
float_t v10 = max_def((grab * (1.0f / range)) * size, 20.0f);
|
|
float_t v11 = ((value - min) * (1.0f / range)) * (size - v10);
|
|
return { v11, v10 };
|
|
}
|
|
|
|
return { 0.0f, size };
|
|
}
|
|
|
|
SelectionListener::CallbackData ScrollBar::sub_1402E5140(const Widget::KeyCallbackData& key_callback_data) {
|
|
SelectionListener::CallbackData callback_data;
|
|
switch (key_callback_data.key_input) {
|
|
case 0x1000001:
|
|
case 0x1000002:
|
|
case 0x1000005:
|
|
case 0x1000006:
|
|
case 0x1000007:
|
|
case 0x1000008:
|
|
callback_data.field_8 = key_callback_data.key_input;
|
|
break;
|
|
case 0x1000003:
|
|
callback_data.field_8 = 0x1000001;
|
|
break;
|
|
case 0x1000004:
|
|
callback_data.field_8 = 0x1000002;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (callback_data.field_8 != -1) {
|
|
callback_data.widget = this;
|
|
ScrollBar::sub_1402E6CC0(callback_data);
|
|
callback_data.widget = parent;
|
|
}
|
|
|
|
return callback_data;
|
|
}
|
|
|
|
SelectionListener::CallbackData ScrollBar::sub_1402E5380(const Widget::MouseCallbackData& mouse_callback_data) {
|
|
if (field_A6) {
|
|
SelectionListener::CallbackData callback_data;
|
|
if (mouse_callback_data.input & MOUSE_INPUT_DOWN_LEFT) {
|
|
callback_data.field_8 = 1;
|
|
callback_data.mouse_pos = mouse_callback_data.pos;
|
|
}
|
|
else {
|
|
callback_data.field_8 = 0;
|
|
field_A6 = false;
|
|
}
|
|
|
|
if (callback_data.field_8 != -1) {
|
|
callback_data.widget = this;
|
|
ScrollBar::sub_1402E6CC0(callback_data);
|
|
callback_data.widget = this->parent;
|
|
}
|
|
return callback_data;
|
|
}
|
|
|
|
SelectionListener::CallbackData callback_data;
|
|
if (mouse_callback_data.input & MOUSE_INPUT_100000)
|
|
callback_data.field_8 = 0x1000071;
|
|
else if (mouse_callback_data.input & MOUSE_INPUT_200000)
|
|
callback_data.field_8 = 0x1000072;
|
|
|
|
if (callback_data.field_8 == -1 && !CheckHitPos(mouse_callback_data.pos))
|
|
return callback_data;
|
|
|
|
vec2 glyph_size = font.GetFontGlyphSize();
|
|
rectangle rect = GetRectangle();
|
|
|
|
float_t v8;
|
|
float_t v9;
|
|
float_t v10;
|
|
float_t v11;
|
|
if (flags & HORIZONTAL) {
|
|
v8 = glyph_size.x;
|
|
v9 = mouse_callback_data.pos.x;
|
|
v10 = glyph_size.x + rect.pos.x;
|
|
v11 = rect.size.x + rect.pos.x;
|
|
}
|
|
else {
|
|
v8 = glyph_size.y;
|
|
v9 = mouse_callback_data.pos.y;
|
|
v10 = glyph_size.y + rect.pos.y;
|
|
v11 = rect.size.y + rect.pos.y;
|
|
}
|
|
|
|
if (mouse_callback_data.input & MOUSE_INPUT_INTERVAL_LEFT) {
|
|
if (v9 < v10)
|
|
callback_data.field_8 = 0x1000001;
|
|
else if (v11 - v8 < v9)
|
|
callback_data.field_8 = 0x1000002;
|
|
else {
|
|
vec2 v23 = sub_1402E4790();
|
|
if (v23.x + v10 > v9)
|
|
callback_data.field_8 = 0x1000005;
|
|
else if (v9 > v23.x + v10 + v23.y)
|
|
callback_data.field_8 = 0x1000006;
|
|
}
|
|
}
|
|
|
|
if (callback_data.field_8 == -1
|
|
&& (mouse_callback_data.input & MOUSE_INPUT_DOWN_LEFT)
|
|
&& (mouse_callback_data.input & MOUSE_INPUT_MOVE)) {
|
|
vec2 v23 = sub_1402E4790();
|
|
rectangle rect = GetRectangle();
|
|
|
|
float_t v14;
|
|
float_t v15;
|
|
float_t v17;
|
|
float_t v18;
|
|
if (flags & HORIZONTAL) {
|
|
v14 = rect.pos.x + glyph_size.x + v23.x;
|
|
v15 = rect.pos.y;
|
|
v17 = v23.y;
|
|
v18 = rect.size.y;
|
|
}
|
|
else {
|
|
v14 = rect.pos.x;
|
|
v15 = rect.pos.y + glyph_size.y + v23.x;
|
|
v17 = rect.size.x;
|
|
v18 = v23.y;
|
|
}
|
|
|
|
if (v14 <= mouse_callback_data.pos.x && mouse_callback_data.pos.x < v17 + v14
|
|
&& v15 <= mouse_callback_data.pos.y && mouse_callback_data.pos.y < v18 + v15) {
|
|
field_A6 = true;
|
|
if (flags & HORIZONTAL)
|
|
field_A0 = mouse_callback_data.pos.x - (v17 * 0.5f + v14);
|
|
else
|
|
field_A0 = mouse_callback_data.pos.y - (v18 * 0.5f + v15);
|
|
callback_data.field_8 = 1;
|
|
callback_data.mouse_pos = mouse_callback_data.pos;
|
|
}
|
|
}
|
|
|
|
if (callback_data.field_8 != -1) {
|
|
callback_data.widget = this;
|
|
ScrollBar::sub_1402E6CC0(callback_data);
|
|
callback_data.widget = parent;
|
|
}
|
|
return callback_data;
|
|
}
|
|
|
|
void ScrollBar::sub_1402E6CC0(SelectionListener::CallbackData data) {
|
|
if (!data.field_8)
|
|
return;
|
|
|
|
ScrollBar* scroll_bar = dynamic_cast<ScrollBar*>(data.widget);
|
|
if (!scroll_bar)
|
|
return;
|
|
|
|
float_t value = scroll_bar->value;
|
|
switch (data.field_8) {
|
|
case 1: {
|
|
vec2 glyph_size = scroll_bar->font.GetFontGlyphSize();
|
|
rectangle v14 = scroll_bar->GetRectangle();
|
|
float_t v6;
|
|
float_t v7;
|
|
float_t v8;
|
|
float_t v9;
|
|
if (scroll_bar->flags & HORIZONTAL) {
|
|
v6 = glyph_size.x;
|
|
v7 = data.mouse_pos.x;
|
|
v8 = v14.pos.x + glyph_size.x;
|
|
v9 = v14.pos.x + v14.size.x;
|
|
}
|
|
else {
|
|
v6 = glyph_size.y;
|
|
v7 = data.mouse_pos.y;
|
|
v8 = v14.pos.y + glyph_size.y;
|
|
v9 = v14.pos.y + v14.size.y;
|
|
}
|
|
|
|
float_t v10 = v7 - scroll_bar->field_A0;
|
|
vec2 size = scroll_bar->sub_1402E4790();
|
|
float_t v11 = v9 - v6 - v8 - size.y;
|
|
float_t v12 = v8 + size.y * 0.5f;
|
|
if (v12 >= v10)
|
|
value = scroll_bar->min;
|
|
else if (v10 >= v12 + v11)
|
|
value = scroll_bar->max;
|
|
else
|
|
value = scroll_bar->min + (v10 - v8 - size.y * 0.5f) / v11 * (scroll_bar->max - scroll_bar->min);
|
|
} break;
|
|
case 0x1000001:
|
|
value -= scroll_bar->step;
|
|
break;
|
|
case 0x1000002:
|
|
value += scroll_bar->step;
|
|
break;
|
|
case 0x1000005:
|
|
value -= scroll_bar->step_fast;
|
|
break;
|
|
case 0x1000006:
|
|
value += scroll_bar->step_fast;
|
|
break;
|
|
case 0x1000007:
|
|
value = scroll_bar->min;
|
|
break;
|
|
case 0x1000008:
|
|
value = scroll_bar->max;
|
|
break;
|
|
case 0x1000071:
|
|
if (scroll_bar->flags & VERTICAL)
|
|
value += scroll_bar->step * -3.0f;
|
|
break;
|
|
case 0x1000072:
|
|
if (scroll_bar->flags & VERTICAL)
|
|
value += scroll_bar->step * 3.0f;
|
|
break;
|
|
}
|
|
scroll_bar->SetValue(value);
|
|
}
|
|
|
|
ShellCloseButton::ShellCloseButton(Shell* parent) : Button(parent) {
|
|
SetSize({ 14.0f, 14.0f });
|
|
SetText(L"Close Box");
|
|
callback = Callback;
|
|
field_100 = 0;
|
|
field_104 = 4;
|
|
}
|
|
|
|
ShellCloseButton::~ShellCloseButton() {
|
|
|
|
}
|
|
|
|
void ShellCloseButton::Draw() {
|
|
print->SetFont(¤t_font);
|
|
|
|
vec2 pos = GetPos();
|
|
print->PrintText(!(field_100 & 2) || !(field_100 & 1) ? "x" : "*", pos.x, pos.y);
|
|
}
|
|
|
|
vec2 ShellCloseButton::GetPos() {
|
|
return parent_comp->GetPos() + rect.pos;
|
|
}
|
|
|
|
vec2 ShellCloseButton::GetSize() {
|
|
return current_font.GetFontGlyphSize();
|
|
}
|
|
|
|
void ShellCloseButton::Callback(Widget* data) {
|
|
ShellCloseButton* close_button = dynamic_cast<ShellCloseButton*>(data);
|
|
if (close_button)
|
|
close_button->parent_shell->Hide();
|
|
}
|
|
|
|
Slider::Slider(Composite* parent, Flags flags) : Control(parent, flags) {
|
|
format = "%f";
|
|
scroll_bar = new ScrollBar(this, (Flags)(flags & (HORIZONTAL | VERTICAL)));
|
|
scroll_bar->parent = this;
|
|
}
|
|
|
|
Slider::~Slider() {
|
|
|
|
}
|
|
|
|
void Slider::Draw() {
|
|
rectangle rect = GetRectangle();
|
|
print->SetClipData(rect);
|
|
|
|
float_t pos_x = 0.0f;
|
|
if (GetText().size()) {
|
|
print->SetFont(&font);
|
|
print->SetColor(GetParentEnabled()
|
|
? colors_current.foreground
|
|
: colors_current.disable_foreground);
|
|
print->PrintText(GetText(), rect.pos.x, rect.pos.y);
|
|
pos_x = font.GetFontGlyphWidth() + print->GetTextSize(GetText()).x;
|
|
}
|
|
|
|
print->SetFont(&font);
|
|
print->SetColor(GetParentEnabled()
|
|
? colors_current.foreground
|
|
: colors_current.disable_foreground);
|
|
|
|
char buf[256];
|
|
sprintf_s(buf, sizeof(buf), format, GetValue());
|
|
print->PrintText(buf, rect.pos.x + pos_x, rect.pos.y);
|
|
|
|
scroll_bar->UpdateDraw();
|
|
if (GetParentEnabled() && Field_60()) {
|
|
print->SetColor(colors_current.focus_border_color);
|
|
print->sub_140301390(GetRectangle(), 1.0f);
|
|
}
|
|
}
|
|
|
|
void Slider::Reset() {
|
|
if (scroll_bar) {
|
|
scroll_bar->Free();
|
|
scroll_bar = 0;
|
|
}
|
|
|
|
Control::Reset();
|
|
}
|
|
|
|
int32_t Slider::KeyCallback(const Widget::KeyCallbackData& data) {
|
|
if (!GetParentEnabled())
|
|
return 0;
|
|
|
|
SelectionListener::CallbackData v6 = scroll_bar->sub_1402E5140(data);
|
|
if (v6.widget)
|
|
for (SelectionListener*& i : selection_listeners)
|
|
i->Callback(&v6);
|
|
return 0;
|
|
}
|
|
|
|
int32_t Slider::MouseCallback(const Widget::MouseCallbackData& data) {
|
|
if (!GetParentEnabled())
|
|
return 0;
|
|
|
|
if ((data.input & MOUSE_INPUT_TAP_MASK) && !Field_60())
|
|
Field_58();
|
|
|
|
bool v5 = scroll_bar->field_A6;
|
|
SelectionListener::CallbackData v9 = scroll_bar->sub_1402E5380(data);
|
|
if (v5 != scroll_bar->field_A6)
|
|
dw_gui_detail_display_set_cap(this, scroll_bar->field_A6);
|
|
|
|
if (v9.widget)
|
|
for (SelectionListener*& i : selection_listeners)
|
|
i->Callback(&v9);
|
|
return 0;
|
|
}
|
|
|
|
void Slider::SetSize(const vec2& value) {
|
|
Widget::SetSize(value);
|
|
scroll_bar->rect.pos.x = value.x - scroll_bar->rect.size.x;
|
|
scroll_bar->rect.pos.y = 0.0f;
|
|
}
|
|
|
|
void Slider::UpdateLayout() {
|
|
scroll_bar->rect.pos = { GetTextSize().x, 0.0f };
|
|
SetSize(GetSize());
|
|
}
|
|
|
|
vec2 Slider::GetSize() {
|
|
vec2 v10 = Slider::GetTextSize();
|
|
vec2 v11 = scroll_bar->rect.size;
|
|
|
|
vec2 size;
|
|
size.x = v11.x + v10.x;
|
|
size.y = max_def(v11.y, v10.y);
|
|
return size;
|
|
}
|
|
|
|
void Slider::AddSelectionListener(SelectionListener* value) {
|
|
selection_listeners.push_back(value);
|
|
}
|
|
|
|
vec2 Slider::GetTextSize() {
|
|
vec2 size;
|
|
if (GetText().size()) {
|
|
print->SetFont(&font);
|
|
size.x += font.GetFontGlyphWidth() + print->GetTextSize(GetText()).x;
|
|
}
|
|
|
|
char buf[0x100];
|
|
sprintf_s(buf, sizeof(buf), format, GetValue());
|
|
size.x += font.GetFontGlyphWidth() + print->GetTextSize(buf).x;
|
|
return size;
|
|
}
|
|
|
|
Slider* Slider::Create(Composite* parent, Flags flags, const char* name, const char* format, float_t width) {
|
|
Slider* slider = new Slider(parent, flags);
|
|
slider->scroll_bar->SetText(L"slider's bar");
|
|
slider->SetText(name);
|
|
slider->format = format;
|
|
slider->scroll_bar->SetWidth(width);
|
|
return slider;
|
|
}
|
|
|
|
Slider* Slider::Create(Composite* parent, Flags flags,
|
|
float_t pos_x, float_t pos_y, float_t width, float_t height, const char* text) {
|
|
Slider* slider = new Slider(parent, flags);
|
|
ScrollBar* scroll_bar = slider->scroll_bar;
|
|
slider->SetText(text);
|
|
scroll_bar->SetText(L"slider's bar");
|
|
scroll_bar->SetSize({ width, height });
|
|
print->SetFont(&slider->font);
|
|
vec2 size;
|
|
if (flags & HORIZONTAL) {
|
|
vec2 v21 = print->GetTextSize(slider->text);
|
|
vec2 v22 = print->GetTextSize(L"0000");
|
|
scroll_bar->rect.pos.x = v21.x + v22.x;
|
|
scroll_bar->rect.pos.y = 0.0f;
|
|
size.x = v21.x + v22.x + scroll_bar->rect.size.x;
|
|
size.y = slider->font.GetFontGlyphHeight();
|
|
}
|
|
else {
|
|
vec2 v21 = print->GetTextSize(slider->text);
|
|
vec2 v22 = print->GetTextSize(L"0000");
|
|
size.x = slider->font.GetFontGlyphWidth();
|
|
size.y = v21.x + v22.x + scroll_bar->rect.size.y;
|
|
}
|
|
slider->rect.pos = { pos_x, pos_y };
|
|
slider->SetSize(size);
|
|
return slider;
|
|
}
|
|
|
|
DisplayData::DisplayData() {
|
|
|
|
}
|
|
|
|
DropDownListScrollBarSelectionListener::DropDownListScrollBarSelectionListener() {
|
|
|
|
}
|
|
|
|
DropDownListScrollBarSelectionListener::~DropDownListScrollBarSelectionListener() {
|
|
|
|
}
|
|
|
|
void DropDownListScrollBarSelectionListener::Callback(SelectionListener::CallbackData* data) {
|
|
ListBox* list_box = dynamic_cast<ListBox*>(data->widget);
|
|
if (list_box && list_box->field_118 && !data->field_8)
|
|
dw_gui_detail_display_set_cap(list_box, true);
|
|
}
|
|
|
|
ScrollBarTestSelectionListener::ScrollBarTestSelectionListener() {
|
|
|
|
}
|
|
|
|
ScrollBarTestSelectionListener::~ScrollBarTestSelectionListener() {
|
|
|
|
}
|
|
|
|
void ScrollBarTestSelectionListener::Callback(SelectionListener::CallbackData* data) {
|
|
|
|
}
|
|
|
|
void font_init() {
|
|
font_type_6x12 = new Font(16, "FONT_TYPE_6x12", true);
|
|
font_type_6x12->SetGlyphSize(6.0f, 12.0f);
|
|
|
|
font_type_8x12 = new Font(16, "FONT_TYPE_8x12", true);
|
|
font_type_8x12->SetGlyphSize(8.0f, 12.0f);
|
|
|
|
font_type_8x16 = new Font(16, "FONT_TYPE_8x16", true);
|
|
font_type_8x16->SetGlyphSize(8.0f, 16.0f);
|
|
|
|
font_type_10x16 = new Font(0, "FONT_TYPE_10x16");
|
|
font_type_10x16->SetGlyphSize(10.0f, 16.0f);
|
|
|
|
font_type_10x20 = new Font(16, "FONT_TYPE_10x20", true);
|
|
font_type_10x20->SetGlyphSize(10.0, 20.0);
|
|
|
|
font_type_12x24 = new Font(16, "FONT_TYPE_12x24", true);
|
|
font_type_12x24->SetGlyphSize(12.0f, 24.0f);
|
|
|
|
p_font_type_6x12 = font_type_6x12;
|
|
p_font_type_8x12 = font_type_8x12;
|
|
p_font_type_8x16 = font_type_8x16;
|
|
p_font_type_10x16 = font_type_10x16;
|
|
p_font_type_10x20 = font_type_10x20;
|
|
p_font_type_12x24 = font_type_12x24;
|
|
current_font = font_type_8x16;
|
|
|
|
font_type_scroll_bar = new Font(font_type_8x16->font.font_handler_index,
|
|
"FONT_TYPE_SCROLL_BAR", font_type_8x16->half_width);
|
|
font_type_scroll_bar->SetGlyphSize(
|
|
font_type_8x16->GetFontGlyphWidth() * 2.0f,
|
|
font_type_8x16->GetFontGlyphHeight());
|
|
p_font_type_scroll_bar = font_type_scroll_bar;
|
|
|
|
font_collection.insert_or_assign(0, &p_font_type_10x16);
|
|
font_collection.insert_or_assign(1, &p_font_type_8x12);
|
|
font_collection.insert_or_assign(2, &p_font_type_8x16);
|
|
font_collection.insert_or_assign(3, &p_font_type_10x20);
|
|
font_collection.insert_or_assign(4, &p_font_type_12x24);
|
|
font_collection.insert_or_assign(5, &p_font_type_6x12);
|
|
}
|
|
|
|
int32_t font_get_index(std::string& name) {
|
|
for (auto& i : font_collection)
|
|
if (!i.second->GetName().compare(name)) {
|
|
current_font = *i.second;
|
|
return i.first;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void font_free() {
|
|
delete font_type_scroll_bar;
|
|
delete font_type_12x24;
|
|
delete font_type_10x20;
|
|
delete font_type_10x16;
|
|
delete font_type_8x16;
|
|
delete font_type_8x12;
|
|
delete font_type_6x12;
|
|
}
|
|
}
|
|
|
|
void dw_init() {
|
|
dw::DisplayData data;
|
|
resolution_struct* res_wind = res_window_get();
|
|
data.field_10.size.x = (float_t)res_wind->width;
|
|
data.field_10.size.y = (float_t)res_wind->height;
|
|
data.field_0.size = data.field_10.size;
|
|
dw_init(data);
|
|
}
|
|
|
|
void dw_init(dw::DisplayData& data) {
|
|
dw::colors_current = dw::colors_default;
|
|
|
|
//dw::set_color_list(&dw::colors_current);
|
|
dw::font_init();
|
|
|
|
if (!dw::print)
|
|
dw::print = new dw::Print(data.field_0.size.x, data.field_0.size.y);
|
|
|
|
dw::print->SetColor(dw::colors_current.foreground);
|
|
dw::print->SetFillColor(dw::colors_current.background);
|
|
|
|
if (!dw_gui_detail_display)
|
|
dw_gui_detail_display = new dw_gui_detail::Display(data);
|
|
|
|
if (!dw::clipboard)
|
|
dw::clipboard = new std::wstring;
|
|
}
|
|
|
|
void dw_free() {
|
|
if (dw_gui_detail_display) {
|
|
delete dw_gui_detail_display;
|
|
dw_gui_detail_display = 0;
|
|
}
|
|
|
|
if (dw::clipboard) {
|
|
delete dw::clipboard;
|
|
dw::clipboard = 0;
|
|
}
|
|
|
|
if (dw::print) {
|
|
delete dw::print;
|
|
dw::print = 0;
|
|
}
|
|
|
|
dw::font_free();
|
|
}
|
|
|
|
void dw_gui_ctrl_disp() {
|
|
if (dw_gui_get_ctrl())
|
|
dw_gui_detail_display->Ctrl();
|
|
if (dw_gui_get_disp())
|
|
dw_gui_detail_display->Draw();
|
|
};
|
|
|
|
PrintWorkDebug::PrintWorkDebug() {
|
|
prio = spr::SPR_PRIO_29;
|
|
set_resolution_mode(RESOLUTION_MODE_MAX);
|
|
}
|
|
|
|
namespace dw {
|
|
Print::Print(float_t width, float_t height) {
|
|
font = ¤t_font;
|
|
print_work = new PrintWorkDebug;
|
|
field_10 = color_black;
|
|
field_14 = color_white;
|
|
field_18 = { 0.0f, 0.0f, width, height };
|
|
clip_data = field_18;
|
|
field_38 = 1.0f;
|
|
}
|
|
|
|
Print::~Print() {
|
|
delete print_work;
|
|
}
|
|
|
|
void Print::FillRectangle(rectangle rect) {
|
|
if (rect.size.x > 0.0f && rect.size.y > 0.0f)
|
|
print_work->FillRectangle(rect);
|
|
}
|
|
|
|
vec2 Print::GetTextSize(std::string& str) {
|
|
return GetTextSize(utf8_to_utf16(str));
|
|
}
|
|
|
|
vec2 Print::GetTextSize(std::wstring& str) {
|
|
return print_work->GetTextSize(str.c_str(), str.c_str() + str.size());
|
|
}
|
|
|
|
vec2 Print::GetTextSize(const wchar_t* str, size_t length) {
|
|
return print_work->GetTextSize(str, str + length);
|
|
}
|
|
|
|
void Print::PrintText(std::string& str, float_t pos_x, float_t pos_y) {
|
|
PrintText(utf8_to_utf16(str), pos_x, pos_y);
|
|
}
|
|
|
|
void Print::PrintText(std::wstring& str, float_t pos_x, float_t pos_y) {
|
|
PrintWorkDebug* print_work = this->print_work;
|
|
print_work->set_position(pos_x, pos_y);
|
|
print_work->PrintText(app::TEXT_FLAG_ALIGN_FLAG_LEFT, str.c_str(), str.c_str() + str.size());
|
|
}
|
|
|
|
void Print::SetColor(color4u8 value) {
|
|
print_work->set_color(value);
|
|
}
|
|
|
|
void Print::SetFillColor(color4u8 value) {
|
|
print_work->set_fill_color(value);
|
|
}
|
|
|
|
void Print::SetClipData(rectangle rect) {
|
|
clip_data = rect;
|
|
print_work->clip = true;
|
|
print_work->clip_data = clip_data;
|
|
}
|
|
|
|
void Print::SetFont(p_Font* value) {
|
|
this->font = value;
|
|
print_work->set_font(&value->ptr->font);
|
|
}
|
|
|
|
void Print::sub_140301390(rectangle rect, float_t a3) {
|
|
color4u8 v3 = field_14;
|
|
|
|
print_work->set_fill_color(print_work->color);
|
|
|
|
rectangle v10;
|
|
v10.pos.x = rect.pos.x;
|
|
v10.pos.y = rect.pos.y;
|
|
v10.size.x = a3;
|
|
v10.size.y = rect.size.y;
|
|
FillRectangle(v10);
|
|
|
|
v10.pos.x = rect.size.x + rect.pos.x - a3;
|
|
FillRectangle(v10);
|
|
|
|
v10.pos.x = a3 + rect.pos.x;
|
|
v10.pos.y = rect.pos.y;
|
|
v10.size.x = rect.size.x - a3 - a3;
|
|
v10.size.y = a3;
|
|
FillRectangle(v10);
|
|
|
|
v10.pos.y = rect.size.y + rect.pos.y - a3;
|
|
FillRectangle(v10);
|
|
|
|
print_work->set_fill_color(v3);
|
|
}
|
|
|
|
void Print::sub_140302800() {
|
|
SetClipData(field_18);
|
|
}
|
|
}
|
|
|
|
dw_gui_detail::Input::Input() : mouse_input(), state(), field_18(),
|
|
field_1C(), field_1D(), field_20(), char_input(), key_input(), joy_input() {
|
|
|
|
}
|
|
|
|
// 0x140300A10
|
|
void dw_gui_detail::Input::Ctrl() {
|
|
const InputState* input_state = input_state_get(0);
|
|
mouse_input = (dw::MouseInput)0;
|
|
state = (dw::InputState)0;
|
|
char_input = 0;
|
|
key_input = 0;
|
|
joy_input = 0;
|
|
|
|
uint8_t key = input_state->GetKey();
|
|
|
|
char_input = key;
|
|
key_input = key;
|
|
|
|
int32_t mouse_pos_x = input_state->sub_14018CCC0(8);
|
|
int32_t mouse_pos_y = input_state->sub_14018CCC0(9);
|
|
|
|
vec2 old_mouse_pos = mouse_pos;
|
|
mouse_pos.x = (float_t)mouse_pos_x;
|
|
mouse_pos.y = (float_t)mouse_pos_y;
|
|
mouse_delta = mouse_pos - old_mouse_pos;
|
|
|
|
if (mouse_delta != 0.0f)
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_MOVE);
|
|
|
|
if (input_state->CheckDown(82))
|
|
enum_or(state, dw::INPUT_STATE_CTRL);
|
|
if (input_state->CheckDown(81))
|
|
enum_or(state, dw::INPUT_STATE_SHIFT);
|
|
if (input_state->CheckDown(83))
|
|
enum_or(state, dw::INPUT_STATE_ALT);
|
|
|
|
if (input_state->CheckDown(96))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_DOWN_LEFT);
|
|
if (input_state->CheckDown(97))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_DOWN_MIDDLE);
|
|
if (input_state->CheckDown(98))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_DOWN_RIGHT);
|
|
|
|
if (input_state->CheckIntervalTapped(96))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_INTERVAL_LEFT);
|
|
if (input_state->CheckIntervalTapped(97))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_INTERVAL_MIDDLE);
|
|
if (input_state->CheckIntervalTapped(98))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_INTERVAL_RIGHT);
|
|
|
|
if (input_state->CheckTapped(96))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_TAP_LEFT);
|
|
if (input_state->CheckTapped(97))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_TAP_MIDDLE);
|
|
if (input_state->CheckTapped(98))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_TAP_RIGHT);
|
|
|
|
if (input_state->CheckReleased(99))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_100000);
|
|
if (input_state->CheckReleased(100))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_200000);
|
|
if (input_state->CheckReleased(96))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_RELEASE_LEFT);
|
|
if (input_state->CheckReleased(97))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_RELEASE_MIDDLE);
|
|
if (input_state->CheckReleased(98))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_RELEASE_RIGHT);
|
|
|
|
if (input_state->CheckDoubleTapped(96))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_DBL_TAP_LEFT);
|
|
if (input_state->CheckDoubleTapped(97))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_DBL_TAP_MIDDLE);
|
|
if (input_state->CheckDoubleTapped(98))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_DBL_TAP_RIGHT);
|
|
|
|
if (input_state->CheckDown(28))
|
|
enum_or(mouse_input, dw::MOUSE_INPUT_20000000);
|
|
|
|
if (input_state->CheckIntervalTapped(91))
|
|
key_input = 0x1000001;
|
|
if (input_state->CheckIntervalTapped(93))
|
|
key_input = 0x1000002;
|
|
if (input_state->CheckIntervalTapped(92))
|
|
key_input = 0x1000003;
|
|
if (input_state->CheckIntervalTapped(94))
|
|
key_input = 0x1000004;
|
|
if (input_state->CheckIntervalTapped(86))
|
|
key_input = 0x1000007;
|
|
if (input_state->CheckIntervalTapped(89))
|
|
key_input = 0x1000008;
|
|
if (input_state->CheckIntervalTapped(87))
|
|
key_input = 0x1000005;
|
|
if (input_state->CheckIntervalTapped(90))
|
|
key_input = 0x1000006;
|
|
if (input_state->CheckIntervalTapped(66))
|
|
key_input = 0x100000A;
|
|
if (input_state->CheckIntervalTapped(67))
|
|
key_input = 0x100000B;
|
|
if (input_state->CheckIntervalTapped(68))
|
|
key_input = 0x100000C;
|
|
if (input_state->CheckIntervalTapped(69))
|
|
key_input = 0x100000D;
|
|
if (input_state->CheckIntervalTapped(70))
|
|
key_input = 0x100000E;
|
|
if (input_state->CheckIntervalTapped(71))
|
|
key_input = 0x100000F;
|
|
if (input_state->CheckIntervalTapped(72))
|
|
key_input = 0x1000010;
|
|
if (input_state->CheckIntervalTapped(73))
|
|
key_input = 0x1000011;
|
|
if (input_state->CheckIntervalTapped(74))
|
|
key_input = 0x1000012;
|
|
if (input_state->CheckIntervalTapped(75))
|
|
key_input = 0x1000013;
|
|
if (input_state->CheckIntervalTapped(76))
|
|
key_input = 0x1000014;
|
|
if (input_state->CheckIntervalTapped(77))
|
|
key_input = 0x1000015;
|
|
|
|
const InputState* v12[2];
|
|
v12[0] = input_state_get(0);
|
|
v12[1] = input_state_get(1);
|
|
for (const InputState* i : v12) {
|
|
if (i->CheckIntervalTapped(3))
|
|
joy_input |= 0x1000000;
|
|
if (i->CheckIntervalTapped(4))
|
|
joy_input |= 0x2000000;
|
|
if (i->CheckIntervalTapped(5))
|
|
joy_input |= 0x4000000;
|
|
if (i->CheckIntervalTapped(6))
|
|
joy_input |= 0x8000000;
|
|
|
|
if (i->CheckDown(7))
|
|
joy_input |= 0x01;
|
|
if (i->CheckDown(8))
|
|
joy_input |= 0x02;
|
|
if (i->CheckDown(9))
|
|
joy_input |= 0x04;
|
|
if (i->CheckDown(2))
|
|
joy_input |= 0x08;
|
|
|
|
if (i->CheckTapped(7))
|
|
joy_input |= 0x10;
|
|
if (i->CheckTapped(8))
|
|
joy_input |= 0x20;
|
|
if (i->CheckTapped(9))
|
|
joy_input |= 0x40;
|
|
if (i->CheckTapped(2))
|
|
joy_input |= 0x80;
|
|
|
|
if (i->CheckReleased(7))
|
|
joy_input |= 0x100;
|
|
if (i->CheckReleased(8))
|
|
joy_input |= 0x200;
|
|
if (i->CheckReleased(9))
|
|
joy_input |= 0x400;
|
|
if (i->CheckReleased(2))
|
|
joy_input |= 0x800;
|
|
|
|
if (i->CheckDoubleTapped(7))
|
|
joy_input |= 0x1000;
|
|
if (i->CheckDoubleTapped(8))
|
|
joy_input |= 0x2000;
|
|
if (i->CheckDoubleTapped(9))
|
|
joy_input |= 0x4000;
|
|
if (i->CheckDoubleTapped(2))
|
|
joy_input |= 0x8000;
|
|
|
|
if (i->CheckHold(7))
|
|
joy_input |= 0x10000;
|
|
if (i->CheckHold(8))
|
|
joy_input |= 0x20000;
|
|
if (i->CheckHold(9))
|
|
joy_input |= 0x40000;
|
|
}
|
|
|
|
if (joy_input)
|
|
joy_input |= 0x40000000;
|
|
|
|
if (get_pause())
|
|
joy_input |= 0x10000000;
|
|
}
|
|
|
|
// 0x1403011A0
|
|
void dw_gui_detail::Input::Draw() {
|
|
struct struc_752 {
|
|
wchar_t field_0;
|
|
int32_t field_4;
|
|
int32_t field_8;
|
|
};
|
|
|
|
const struc_752 stru_1409D6390[] = {
|
|
{ 0x7C, 6, 8 },
|
|
{ 0x5C, 6, 6 },
|
|
{ 0x2D, 6, 6 },
|
|
{ 0x2F, 6, 6 },
|
|
{ 0x7C, 6, 8 },
|
|
{ 0x5C, 6, 6 },
|
|
{ 0x2D, 6, 6 },
|
|
{ 0x2F, 6, 6 },
|
|
{ 0x49, 1, 1 },
|
|
{ 0x49, 1, 1 },
|
|
{ 0x49, 1, 1 },
|
|
{ 0x49, 1, 1 },
|
|
{ 0x49, 1, 1 },
|
|
{ 0x49, 1, 1 },
|
|
{ 0x49, 1, 1 },
|
|
{ 0x49, 1, 1 },
|
|
};
|
|
|
|
dw::print->sub_140302800();
|
|
|
|
if (field_1C)
|
|
field_20 = 300;
|
|
else if (field_1D)
|
|
field_20++;
|
|
else
|
|
field_20 = 0;
|
|
|
|
field_1C = 0;
|
|
field_1D = 0;
|
|
|
|
/*if (sub_1406A0510())
|
|
field_20 = 0;*/
|
|
|
|
extern bool disable_cursor;
|
|
if (disable_cursor || !(uint16_t)field_18)
|
|
return;
|
|
|
|
if (stru_1409D6390[(uint16_t)field_18 - 1].field_0 != 0x49) {
|
|
dw::print->SetFont(&dw::current_font);
|
|
|
|
wchar_t buf[2];
|
|
buf[0] = stru_1409D6390[(uint16_t)field_18 - 1].field_0;
|
|
buf[1] = 0;
|
|
dw::print->PrintText(buf, mouse_pos.x - 5.0f, mouse_pos.y - 8.0f);
|
|
}
|
|
else if (field_20 < 300) {
|
|
spr::SprArgs args;
|
|
args.id.index = 3343;
|
|
args.prio = spr::SPR_PRIO_29;
|
|
args.trans.x = mouse_pos.x;
|
|
args.trans.y = mouse_pos.y;
|
|
args.resolution_mode_screen = RESOLUTION_MODE_MAX;
|
|
args.resolution_mode_sprite = RESOLUTION_MODE_MAX;
|
|
|
|
data_struct* aft_data = &data_list[DATA_AFT];
|
|
sprite_database* aft_spr_db = &aft_data->data_ft.spr_db;
|
|
spr::put_sprite(args, aft_spr_db);
|
|
}
|
|
}
|
|
|
|
dw_gui_detail::Display::RootKeySelection::RootKeySelection() {
|
|
|
|
}
|
|
|
|
dw_gui_detail::Display::RootKeySelection::~RootKeySelection() {
|
|
|
|
}
|
|
|
|
void dw_gui_detail::Display::RootKeySelection::Field_8(const dw::Widget::KeyCallbackData& data) {
|
|
|
|
}
|
|
|
|
dw_gui_detail::Display::Display(dw::DisplayData& data) : active_shell(),
|
|
active_menu(), on(), move(), widget(),
|
|
cap(), focused_shell(), find_focus(), field_118() {
|
|
set_focus = true;
|
|
this->data = data;
|
|
field_128 = 1.0f;
|
|
field_120 = (1.0f / field_128) * this->data.field_10.size;
|
|
name.assign(L"Display");
|
|
|
|
/*drag_bounds_control = new dw::DragBoundsControl;
|
|
drag_bounds_control->rect.pos = this->data.field_0.pos;
|
|
drag_bounds_control->SetSize(this->data.field_0.size);
|
|
drag_bounds_control->AddKeyListener(&root_key_selection);
|
|
|
|
v10 = new dw::Menu(drag_bounds_control);
|
|
v10->SetText(L"RootMenu");
|
|
v10->sub_140306E90();
|
|
drag_bounds_control->>SetParentMenu(v10);*/
|
|
}
|
|
|
|
dw_gui_detail::Display::~Display() {
|
|
|
|
}
|
|
|
|
void dw_gui_detail::Display::CheckShells() {
|
|
std::vector<dw::Shell*> vec;
|
|
|
|
for (dw::Shell* i : shells)
|
|
if (i->destroy)
|
|
vec.push_back(i);
|
|
|
|
if (vec.size()) {
|
|
for (dw::Shell* i : vec)
|
|
i->Free();
|
|
find_focus = true;
|
|
}
|
|
}
|
|
|
|
void dw_gui_detail::Display::Ctrl() {
|
|
input.Ctrl();
|
|
mouse_callback_data.pos = input.mouse_pos;
|
|
mouse_callback_data.input = input.mouse_input;
|
|
mouse_callback_data.state = input.state;
|
|
key_callback_data.state = input.state;
|
|
key_callback_data.char_input = input.char_input;
|
|
key_callback_data.key_input = input.key_input;
|
|
key_callback_data.joy_input = input.joy_input;
|
|
|
|
if (sub_1402E51F0())
|
|
sub_1402E5630();
|
|
|
|
CheckShells();
|
|
FreeWidgets();
|
|
}
|
|
|
|
void dw_gui_detail::Display::Draw() {
|
|
dw::print->SetColor(dw::colors_current.foreground);
|
|
//drag_bounds_control->UpdateDraw();
|
|
|
|
for (dw::Shell*& i : shells)
|
|
if (i->GetDisp())
|
|
i->UpdateDraw();
|
|
|
|
/*for (dw::Menu*& i : menus)
|
|
i->UpdateDraw();*/
|
|
|
|
dw::print->SetColor(dw::colors_current.foreground);
|
|
input.Draw();
|
|
}
|
|
|
|
void dw_gui_detail::Display::FreeWidgets() {
|
|
for (auto& i : free_widgets) {
|
|
if (widget == i)
|
|
widget = 0;
|
|
|
|
if (cap == i)
|
|
cap = 0;
|
|
|
|
delete i;
|
|
}
|
|
|
|
free_widgets.clear();
|
|
}
|
|
|
|
dw::Shell* dw_gui_detail::Display::GetHoveredShell() {
|
|
auto i_begin = shells.end();
|
|
auto i_end = shells.begin();
|
|
for (auto i = i_begin; i != i_end;) {
|
|
i--;
|
|
|
|
if (!(*i)->freed && (*i)->GetDisp()) {
|
|
rectangle rect = (*i)->GetRectangle();
|
|
if (rect.pos.x <= mouse_callback_data.pos.x && mouse_callback_data.pos.x < rect.pos.x + rect.size.x
|
|
&& rect.pos.y <= mouse_callback_data.pos.y && mouse_callback_data.pos.y < rect.pos.y + rect.size.y)
|
|
return *i;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void dw_gui_detail::Display::MakeShellFirst(dw::Shell* value) {
|
|
if (!value)
|
|
return;
|
|
|
|
auto i = shells.begin();
|
|
auto i_end = shells.end();
|
|
while (i != i_end)
|
|
if (*i == value) {
|
|
shells.erase(i);
|
|
shells.push_back(value);
|
|
break;
|
|
}
|
|
else
|
|
i++;
|
|
}
|
|
|
|
void dw_gui_detail::Display::MakeShellLast(dw::Shell* value) {
|
|
if (!value)
|
|
return;
|
|
|
|
auto i = shells.begin();
|
|
auto i_end = shells.end();
|
|
while (i != i_end)
|
|
if (*i == value) {
|
|
shells.erase(i);
|
|
shells.insert(shells.begin(), value);
|
|
break;
|
|
}
|
|
else
|
|
i++;
|
|
}
|
|
|
|
void dw_gui_detail::Display::RemoveShell(dw::Shell* value) {
|
|
auto i = shells.begin();
|
|
auto i_end = shells.end();
|
|
while (i != i_end)
|
|
if (*i == value) {
|
|
shells.erase(i);
|
|
break;
|
|
}
|
|
else
|
|
i++;
|
|
|
|
if (active_shell == value) {
|
|
active_shell = 0;
|
|
find_focus = true;
|
|
}
|
|
|
|
if (on == value)
|
|
on = 0;
|
|
|
|
if (move == value)
|
|
move = 0;
|
|
}
|
|
|
|
void dw_gui_detail::Display::sub_1402E6300(dw::Widget* widget) {
|
|
rectangle rect = widget->GetRectangle();
|
|
|
|
float_t size_y = input.mouse_pos.y - rect.pos.y;
|
|
|
|
vec2 size;
|
|
size.x = widget->rect.size.x;
|
|
size.y = widget->rect.size.y + (max_def(size_y, 10.0f) - rect.size.y);
|
|
widget->SetSize(size);
|
|
}
|
|
|
|
void dw_gui_detail::Display::sub_1402E6440(dw::Widget* widget) {
|
|
rectangle rect = widget->GetRectangle();
|
|
|
|
float_t size_x = input.mouse_pos.x - rect.pos.x;
|
|
|
|
vec2 size;
|
|
size.x = widget->rect.size.x + (max_def(size_x, 32.0f) - rect.size.x);
|
|
size.y = widget->rect.size.y;
|
|
widget->SetSize(size);
|
|
}
|
|
|
|
int32_t dw_gui_detail::Display::sub_1402E48A0(dw::Widget* widget) {
|
|
if (!widget)
|
|
return 9;
|
|
|
|
rectangle rect = widget->GetRectangle();
|
|
if (widget->flags & dw::RADIOBUTTON) {
|
|
vec2 v7 = rect.pos + rect.size - 8.0f;
|
|
if (v7.x <= input.mouse_pos.x && input.mouse_pos.x < v7.x + 8.0f
|
|
&& v7.y <= input.mouse_pos.y && input.mouse_pos.y < v7.y + 8.0f)
|
|
return 6;
|
|
}
|
|
|
|
if (widget->flags & dw::CHECKBOX)
|
|
return dw::current_font.GetFontGlyphHeight()
|
|
+ (rect.pos.y + 2.0f) > input.mouse_pos.y ? 10 : 9;
|
|
return 9;
|
|
}
|
|
|
|
int32_t dw_gui_detail::Display::sub_1402E51F0() {
|
|
// temp
|
|
return 1;
|
|
}
|
|
|
|
int32_t dw_gui_detail::Display::sub_1402E5630() {
|
|
if (move) {
|
|
if (mouse_callback_data.input & dw::MOUSE_INPUT_DOWN_LEFT) {
|
|
if (input.field_18 & 0x40000000)
|
|
move->rect.pos += input.mouse_delta;
|
|
|
|
if ((input.field_18 & 0x20000000) && input.mouse_delta != 0.0f) {
|
|
sub_1402E6440(move);
|
|
sub_1402E6300(move);
|
|
return 0;
|
|
}
|
|
}
|
|
else {
|
|
*(uint16_t*)&input.field_18 = 0;
|
|
move = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
input.field_18 = sub_1402E48A0(on);
|
|
|
|
dw::Shell* hovered_shell = GetHoveredShell();
|
|
|
|
if (!cap) {
|
|
if (set_focus)
|
|
active_shell = focused_shell;
|
|
else if (find_focus) {
|
|
dw::Shell* active_shell = 0;
|
|
|
|
auto i_begin = shells.end();
|
|
auto i_end = shells.begin();
|
|
for (auto i = i_begin; i != i_end;) {
|
|
i--;
|
|
if ((*i)->GetDisp()) {
|
|
active_shell = *i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
this->active_shell = active_shell;
|
|
}
|
|
else {
|
|
int32_t v15;
|
|
bool v15a = false;
|
|
if ((key_callback_data.state & dw::INPUT_STATE_ALT) && key_callback_data.char_input == '\r'
|
|
|| (key_callback_data.state & dw::INPUT_STATE_ALT) && key_callback_data.char_input == '\t'
|
|
|| (key_callback_data.state & dw::INPUT_STATE_CTRL) && key_callback_data.char_input == '\t') {
|
|
v15 = 1;
|
|
if (key_callback_data.state & dw::INPUT_STATE_SHIFT)
|
|
v15 = -1;
|
|
v15a = true;
|
|
}
|
|
else {
|
|
int32_t v16 = key_callback_data.joy_input;
|
|
if (v16 & 0x40000000)
|
|
if (v16 & 0x80) {
|
|
v15 = 0;
|
|
v15a = true;
|
|
}
|
|
else if (!active_shell && (v16 & 0x1000) && (v16 & 0x10000000)
|
|
|| active_shell && (v16 & 0x100) && !(v16 & 0x10000) && (v16 & 0x10000000)) {
|
|
v15 = 1;
|
|
v15a = true;
|
|
}
|
|
}
|
|
|
|
if (v15a) {
|
|
if (active_shell)
|
|
MakeShellLast(active_shell);
|
|
|
|
switch (v15) {
|
|
case 0:
|
|
active_shell = 0;
|
|
break;
|
|
case 1: {
|
|
dw::Shell* active_shell = 0;
|
|
|
|
auto i_begin = shells.end();
|
|
auto i_end = shells.begin();
|
|
for (auto i = i_begin; i != i_end;) {
|
|
i--;
|
|
if ((*i)->GetDisp()) {
|
|
active_shell = *i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
this->active_shell = active_shell;
|
|
} break;
|
|
}
|
|
}
|
|
else {
|
|
if ((mouse_callback_data.input & dw::MOUSE_INPUT_TAP_MASK)
|
|
&& active_shell != hovered_shell)
|
|
active_shell = hovered_shell;
|
|
}
|
|
}
|
|
}
|
|
|
|
this->on = hovered_shell;
|
|
|
|
set_focus = false;
|
|
find_focus = false;
|
|
focused_shell = 0;
|
|
|
|
dw::Widget* widget = 0;
|
|
if (hovered_shell)
|
|
widget = hovered_shell->GetHitWidget(mouse_callback_data.pos);
|
|
this->widget = widget;
|
|
|
|
for (dw::Shell*& i : shells)
|
|
if (i->GetDisp()) {
|
|
void(*v19)(dw::Shell*) = (void(*)(dw::Shell*))i->field_128;
|
|
if (v19)
|
|
v19(i);
|
|
}
|
|
|
|
if (cap) {
|
|
dw::Widget* cap = this->cap;
|
|
cap->MouseCallback(mouse_callback_data);
|
|
cap->KeyCallback(key_callback_data);
|
|
}
|
|
else if (active_shell) {
|
|
active_shell->MouseCallback(mouse_callback_data);
|
|
active_shell->KeyCallback(key_callback_data);
|
|
}
|
|
else {
|
|
|
|
bool found = false;
|
|
for (dw::Shell*& i : shells)
|
|
if (i->GetDisp()) {
|
|
found = true;
|
|
break;
|
|
}
|
|
|
|
if (!found) {
|
|
if (!(mouse_callback_data.input & dw::MOUSE_INPUT_CLICK_MASK))
|
|
input.field_1C = 1;
|
|
}
|
|
else {
|
|
if (!mouse_callback_data.input)
|
|
input.field_1D = 1;
|
|
}
|
|
|
|
/*if (!(mouse_callback_data.input & dw::MOUSE_INPUT_20000000))
|
|
drag_bounds_control->MouseCallback(mouse_callback_data);
|
|
drag_bounds_control->KeyCallback(key_callback_data);*/
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static bool dw_gui_get_ctrl() {
|
|
//return false;
|
|
return true;
|
|
}
|
|
|
|
static bool dw_gui_get_disp() {
|
|
//return false;
|
|
return true;
|
|
}
|
|
|
|
static void dw_gui_detail_display_set_cap(dw::Widget* widget, bool set) {
|
|
dw_gui_detail_display->cap = set ? widget : 0;
|
|
}
|
|
|
|
static void sub_1402EE3C0(rectangle rect, float_t border, int32_t type, color4u8* fill_color) {
|
|
if (type != 2 && type != 4)
|
|
return;
|
|
|
|
color4u8 v26 = type == 2 ? dw::colors_current.border_light_color : dw::colors_current.border_dark_color;
|
|
color4u8 v25 = type == 2 ? dw::colors_current.border_dark_color : dw::colors_current.border_light_color;
|
|
|
|
rectangle v24a;
|
|
v24a.pos.x = rect.pos.x;
|
|
v24a.pos.y = rect.pos.y;
|
|
v24a.size.x = rect.size.x;
|
|
v24a.size.y = border;
|
|
dw::print->SetFillColor(v26);
|
|
dw::print->FillRectangle(v24a);
|
|
|
|
rectangle v24b;
|
|
v24b.pos.x = rect.pos.x;
|
|
v24b.pos.y = rect.pos.y + border;
|
|
v24b.size.x = border;
|
|
v24b.size.y = rect.size.y - border;
|
|
dw::print->SetFillColor(v26);
|
|
dw::print->FillRectangle(v24b);
|
|
|
|
rectangle v24c;
|
|
v24c.pos.x = rect.pos.x + rect.size.x - border;
|
|
v24c.pos.y = rect.pos.y + border;
|
|
v24c.size.x = border;
|
|
v24c.size.y = rect.size.y - border;
|
|
dw::print->SetFillColor(v25);
|
|
dw::print->FillRectangle(v24c);
|
|
|
|
rectangle v24d;
|
|
v24d.pos.x = rect.pos.x + border;
|
|
v24d.pos.y = rect.pos.y + rect.size.y - border;
|
|
v24d.size.x = rect.size.x - border;
|
|
v24d.size.y = border;
|
|
dw::print->SetFillColor(v25);
|
|
dw::print->FillRectangle(v24d);
|
|
|
|
if (fill_color) {
|
|
rectangle v24;
|
|
v24.pos.x = border + rect.pos.x;
|
|
v24.pos.y = border + rect.pos.y;
|
|
v24.size.x = rect.size.x - border - border;
|
|
v24.size.y = rect.size.y - border - border;
|
|
dw::print->SetFillColor(*fill_color);
|
|
dw::print->FillRectangle(v24);
|
|
}
|
|
}
|