mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-04-23 08:14:31 +00:00
1098 lines
36 KiB
C++
1098 lines
36 KiB
C++
#ifndef UIWidgets2_hpp
|
|
#define UIWidgets2_hpp
|
|
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <stdint.h>
|
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
|
#include <imgui.h>
|
|
#include <libultraship/libultraship.h>
|
|
#include "soh/ShipUtils.h"
|
|
#include "soh/ShipInit.hpp"
|
|
|
|
namespace UIWidgets {
|
|
|
|
using SectionFunc = void (*)();
|
|
|
|
struct TextFilters {
|
|
static int FilterNumbers(ImGuiInputTextCallbackData* data) {
|
|
if (data->EventChar < 256 && strchr("1234567890", (char)data->EventChar)) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int FilterAlphaNum(ImGuiInputTextCallbackData* data) {
|
|
const char* alphanum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ0123456789";
|
|
if (data->EventChar < 256 && strchr(alphanum, (char)data->EventChar)) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
};
|
|
|
|
std::string WrappedText(const char* text, unsigned int charactersPerLine = 80);
|
|
std::string WrappedText(const std::string& text, unsigned int charactersPerLine = 80);
|
|
void PaddedSeparator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f,
|
|
float extraVerticalBottomPadding = 0.0f);
|
|
void Tooltip(std::string text);
|
|
|
|
typedef enum ColorPickerModifiers {
|
|
ColorPickerResetButton = 1,
|
|
ColorPickerRandomButton = 2,
|
|
ColorPickerRainbowCheck = 4,
|
|
ColorPickerLockCheck = 8,
|
|
} ColorPickerModifiers;
|
|
|
|
// mostly in order for colors usable by the menu without custom text color
|
|
enum Colors {
|
|
Red,
|
|
DarkRed,
|
|
Orange,
|
|
Green,
|
|
DarkGreen,
|
|
LightBlue,
|
|
Blue,
|
|
DarkBlue,
|
|
Indigo,
|
|
Violet,
|
|
Purple,
|
|
Brown,
|
|
Gray,
|
|
DarkGray,
|
|
// not suitable for menu theme use
|
|
Pink,
|
|
Yellow,
|
|
Cyan,
|
|
Black,
|
|
LightGray,
|
|
White,
|
|
NoColor
|
|
};
|
|
|
|
enum InputTypes { String, Scalar };
|
|
|
|
const std::unordered_map<Colors, ImVec4> ColorValues = {
|
|
{ Colors::Pink, ImVec4(0.87f, 0.3f, 0.87f, 1.0f) }, { Colors::Red, ImVec4(0.55f, 0.0f, 0.0f, 1.0f) },
|
|
{ Colors::DarkRed, ImVec4(0.3f, 0.0f, 0.0f, 1.0f) }, { Colors::Orange, ImVec4(0.85f, 0.55f, 0.0f, 1.0f) },
|
|
{ Colors::Yellow, ImVec4(0.95f, 0.95f, 0.0f, 1.0f) }, { Colors::Green, ImVec4(0.0f, 0.55f, 0.0f, 1.0f) },
|
|
{ Colors::DarkGreen, ImVec4(0.0f, 0.3f, 0.0f, 1.0f) }, { Colors::Cyan, ImVec4(0.0f, 0.9f, 0.9f, 1.0f) },
|
|
{ Colors::LightBlue, ImVec4(0.0f, 0.24f, 0.8f, 1.0f) }, { Colors::Blue, ImVec4(0.08f, 0.03f, 0.65f, 1.0f) },
|
|
{ Colors::DarkBlue, ImVec4(0.03f, 0.0f, 0.5f, 1.0f) }, { Colors::Indigo, ImVec4(0.35f, 0.0f, 0.87f, 1.0f) },
|
|
{ Colors::Violet, ImVec4(0.5f, 0.0f, 0.9f, 1.0f) }, { Colors::Purple, ImVec4(0.31f, 0.0f, 0.67f, 1.0f) },
|
|
{ Colors::Brown, ImVec4(0.37f, 0.18f, 0.0f, 1.0f) }, { Colors::LightGray, ImVec4(0.75f, 0.75f, 0.75f, 1.0f) },
|
|
{ Colors::Gray, ImVec4(0.45f, 0.45f, 0.45f, 1.0f) }, { Colors::DarkGray, ImVec4(0.15f, 0.15f, 0.15f, 1.0f) },
|
|
{ Colors::Black, ImVec4(0.0f, 0.0f, 0.0f, 1.0f) }, { Colors::White, ImVec4(1.0f, 1.0f, 1.0f, 1.0f) },
|
|
{ Colors::NoColor, ImVec4(0.0f, 0.0f, 0.0f, 0.0f) },
|
|
};
|
|
|
|
namespace Sizes {
|
|
const ImVec2 Inline = ImVec2(0.0f, 0.0f);
|
|
const ImVec2 Fill = ImVec2(-1.0f, 0.0f);
|
|
} // namespace Sizes
|
|
|
|
enum LabelPositions {
|
|
Near,
|
|
Far,
|
|
Above,
|
|
None,
|
|
Within,
|
|
};
|
|
|
|
enum ComponentAlignments {
|
|
Left,
|
|
Right,
|
|
};
|
|
|
|
struct WidgetOptions {
|
|
std::string tooltip = "";
|
|
bool disabled = false;
|
|
std::string disabledTooltip = "";
|
|
|
|
WidgetOptions& Tooltip(std::string tooltip_) {
|
|
tooltip = tooltip_;
|
|
return *this;
|
|
}
|
|
|
|
WidgetOptions& Disabled(bool disabled_) {
|
|
disabled = disabled_;
|
|
return *this;
|
|
}
|
|
|
|
WidgetOptions& DisabledTooltip(std::string disabledTooltip_) {
|
|
disabledTooltip = disabledTooltip_;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
struct TextOptions : WidgetOptions {
|
|
Colors color = Colors::NoColor;
|
|
|
|
TextOptions& Color(Colors color_) {
|
|
color = color_;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
struct ButtonOptions : WidgetOptions {
|
|
ImVec2 size = Sizes::Fill;
|
|
ImVec2 padding = ImVec2(10.0f, 8.0f);
|
|
Colors color = Colors::Gray;
|
|
|
|
ButtonOptions& Size(ImVec2 size_) {
|
|
size = size_;
|
|
return *this;
|
|
}
|
|
|
|
ButtonOptions& Padding(ImVec2 padding_) {
|
|
padding = padding_;
|
|
return *this;
|
|
}
|
|
|
|
ButtonOptions& Tooltip(std::string tooltip_) {
|
|
WidgetOptions::tooltip = tooltip_;
|
|
return *this;
|
|
}
|
|
|
|
ButtonOptions& Color(Colors color_) {
|
|
color = color_;
|
|
return *this;
|
|
}
|
|
ButtonOptions& DisabledTooltip(const char* disabledTooltip_) {
|
|
WidgetOptions::disabledTooltip = disabledTooltip_;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
struct ColorPickerOptions : WidgetOptions {
|
|
ImVec2 size = Sizes::Fill;
|
|
ImVec2 padding = ImVec2(10.0f, 8.0f);
|
|
Colors color = Colors::Gray;
|
|
Color_RGBA8 defaultValue = { 255, 255, 255, 255 };
|
|
bool useAlpha, showReset, showRandom, showRainbow, showLock;
|
|
|
|
ColorPickerOptions& Size(ImVec2 size_) {
|
|
size = size_;
|
|
return *this;
|
|
}
|
|
|
|
ColorPickerOptions& Padding(ImVec2 padding_) {
|
|
padding = padding_;
|
|
return *this;
|
|
}
|
|
|
|
ColorPickerOptions& Tooltip(std::string tooltip_) {
|
|
WidgetOptions::tooltip = tooltip_;
|
|
return *this;
|
|
}
|
|
|
|
ColorPickerOptions& ShowReset(bool showReset_ = true) {
|
|
showReset = showReset_;
|
|
return *this;
|
|
}
|
|
|
|
ColorPickerOptions& ShowRandom(bool showRandom_ = true) {
|
|
showRandom = showRandom_;
|
|
return *this;
|
|
}
|
|
|
|
ColorPickerOptions& ShowRainbow(bool showRainbow_ = true) {
|
|
showRainbow = showRainbow_;
|
|
return *this;
|
|
}
|
|
|
|
ColorPickerOptions& ShowLock(bool showLock_ = true) {
|
|
showLock = showLock_;
|
|
return *this;
|
|
}
|
|
|
|
ColorPickerOptions& UseAlpha(bool useAlpha_ = true) {
|
|
useAlpha = useAlpha_;
|
|
return *this;
|
|
}
|
|
|
|
ColorPickerOptions& Color(Colors color_) {
|
|
color = color_;
|
|
return *this;
|
|
}
|
|
|
|
ColorPickerOptions& DefaultValue(Color_RGBA8 defaultValue_) {
|
|
defaultValue = defaultValue_;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
struct WindowButtonOptions : WidgetOptions {
|
|
ImVec2 size = Sizes::Inline;
|
|
ImVec2 padding = ImVec2(10.0f, 8.0f);
|
|
Colors color = Colors::Gray;
|
|
bool showButton = true;
|
|
bool embedWindow = true;
|
|
|
|
WindowButtonOptions& Size(ImVec2 size_) {
|
|
size = size_;
|
|
return *this;
|
|
}
|
|
|
|
WindowButtonOptions& Padding(ImVec2 padding_) {
|
|
padding = padding_;
|
|
return *this;
|
|
}
|
|
|
|
WindowButtonOptions& Tooltip(std::string tooltip_) {
|
|
WidgetOptions::tooltip = tooltip_;
|
|
return *this;
|
|
}
|
|
|
|
WindowButtonOptions& Color(Colors color_) {
|
|
color = color_;
|
|
return *this;
|
|
}
|
|
|
|
WindowButtonOptions& ShowButton(bool showButton_) {
|
|
showButton = showButton_;
|
|
return *this;
|
|
}
|
|
|
|
WindowButtonOptions& EmbedWindow(bool embedWindow_) {
|
|
embedWindow = embedWindow_;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
struct CheckboxOptions : WidgetOptions {
|
|
bool defaultValue = false; // Only applicable to CVarCheckbox
|
|
ComponentAlignments alignment = ComponentAlignments::Left;
|
|
LabelPositions labelPosition = LabelPositions::Near;
|
|
ImVec2 padding = ImVec2(10.0f, 8.0f);
|
|
Colors color = Colors::LightBlue;
|
|
|
|
CheckboxOptions& DefaultValue(bool defaultValue_) {
|
|
defaultValue = defaultValue_;
|
|
return *this;
|
|
}
|
|
|
|
CheckboxOptions& ComponentAlignment(ComponentAlignments alignment_) {
|
|
alignment = alignment_;
|
|
return *this;
|
|
}
|
|
|
|
CheckboxOptions& LabelPosition(LabelPositions labelPosition_) {
|
|
labelPosition = labelPosition_;
|
|
return *this;
|
|
}
|
|
|
|
CheckboxOptions& Tooltip(std::string tooltip_) {
|
|
WidgetOptions::tooltip = tooltip_;
|
|
return *this;
|
|
}
|
|
|
|
CheckboxOptions& Color(Colors color_) {
|
|
color = color_;
|
|
return *this;
|
|
}
|
|
|
|
CheckboxOptions& DisabledTooltip(std::string disabledTooltip_) {
|
|
WidgetOptions::disabledTooltip = disabledTooltip_;
|
|
return *this;
|
|
}
|
|
|
|
CheckboxOptions& Padding(ImVec2 padding_) {
|
|
padding = padding_;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
struct ComboboxOptions : WidgetOptions {
|
|
std::map<int32_t, const char*> comboMap = {};
|
|
uint32_t defaultIndex = 0; // Only applicable to CVarCombobox
|
|
ComponentAlignments alignment = ComponentAlignments::Left;
|
|
LabelPositions labelPosition = LabelPositions::Above;
|
|
ImGuiComboFlags flags = 0;
|
|
Colors color = Colors::LightBlue;
|
|
|
|
ComboboxOptions& ComboMap(std::map<int32_t, const char*> comboMap_) {
|
|
comboMap = comboMap_;
|
|
return *this;
|
|
}
|
|
|
|
ComboboxOptions& DefaultIndex(uint32_t defaultIndex_) {
|
|
defaultIndex = defaultIndex_;
|
|
return *this;
|
|
}
|
|
|
|
ComboboxOptions& ComponentAlignment(ComponentAlignments alignment_) {
|
|
alignment = alignment_;
|
|
return *this;
|
|
}
|
|
|
|
ComboboxOptions& LabelPosition(LabelPositions labelPosition_) {
|
|
labelPosition = labelPosition_;
|
|
return *this;
|
|
}
|
|
|
|
ComboboxOptions& Tooltip(std::string tooltip_) {
|
|
WidgetOptions::tooltip = tooltip_;
|
|
return *this;
|
|
}
|
|
|
|
ComboboxOptions& Color(Colors color_) {
|
|
color = color_;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
struct IntSliderOptions : WidgetOptions {
|
|
bool showButtons = true;
|
|
const char* format = "%d";
|
|
int32_t step = 1;
|
|
int32_t min = 1;
|
|
int32_t max = 10;
|
|
int32_t defaultValue = 1;
|
|
bool clamp = true;
|
|
ComponentAlignments alignment = ComponentAlignments::Left;
|
|
LabelPositions labelPosition = LabelPositions::Above;
|
|
Colors color = Colors::Gray;
|
|
ImGuiSliderFlags flags = 0;
|
|
ImVec2 size = { 0, 0 };
|
|
|
|
IntSliderOptions& ShowButtons(bool showButtons_) {
|
|
showButtons = showButtons_;
|
|
return *this;
|
|
}
|
|
|
|
IntSliderOptions& Format(const char* format_) {
|
|
format = format_;
|
|
return *this;
|
|
}
|
|
|
|
IntSliderOptions& Step(int32_t step_) {
|
|
step = step_;
|
|
return *this;
|
|
}
|
|
|
|
IntSliderOptions& Min(int32_t min_) {
|
|
min = min_;
|
|
return *this;
|
|
}
|
|
|
|
IntSliderOptions& Max(int32_t max_) {
|
|
max = max_;
|
|
return *this;
|
|
}
|
|
|
|
IntSliderOptions& DefaultValue(int32_t defaultValue_) {
|
|
defaultValue = defaultValue_;
|
|
return *this;
|
|
}
|
|
|
|
IntSliderOptions& ComponentAlignment(ComponentAlignments alignment_) {
|
|
alignment = alignment_;
|
|
return *this;
|
|
}
|
|
|
|
IntSliderOptions& LabelPosition(LabelPositions labelPosition_) {
|
|
labelPosition = labelPosition_;
|
|
return *this;
|
|
}
|
|
|
|
IntSliderOptions& Tooltip(std::string tooltip_) {
|
|
WidgetOptions::tooltip = tooltip_;
|
|
return *this;
|
|
}
|
|
|
|
IntSliderOptions& Color(Colors color_) {
|
|
color = color_;
|
|
return *this;
|
|
}
|
|
|
|
IntSliderOptions& Size(ImVec2 size_) {
|
|
size = size_;
|
|
return *this;
|
|
}
|
|
|
|
IntSliderOptions& Clamp(bool clamp_) {
|
|
clamp = clamp_;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
struct FloatSliderOptions : WidgetOptions {
|
|
bool showButtons = true;
|
|
const char* format = "%f";
|
|
float step = 0.01f;
|
|
float min = 0.01f;
|
|
float max = 10.0f;
|
|
float defaultValue = 1.0f;
|
|
bool clamp = true;
|
|
bool isPercentage = false; // Multiplies visual value by 100
|
|
ComponentAlignments alignment = ComponentAlignments::Left;
|
|
LabelPositions labelPosition = LabelPositions::Above;
|
|
Colors color = Colors::Gray;
|
|
ImGuiSliderFlags flags = 0;
|
|
ImVec2 size = { 0, 0 };
|
|
|
|
FloatSliderOptions& ShowButtons(bool showButtons_) {
|
|
showButtons = showButtons_;
|
|
return *this;
|
|
}
|
|
|
|
FloatSliderOptions& Format(const char* format_) {
|
|
format = format_;
|
|
return *this;
|
|
}
|
|
|
|
FloatSliderOptions& Step(float step_) {
|
|
step = step_;
|
|
return *this;
|
|
}
|
|
|
|
FloatSliderOptions& Min(float min_) {
|
|
min = min_;
|
|
return *this;
|
|
}
|
|
|
|
FloatSliderOptions& Max(float max_) {
|
|
max = max_;
|
|
return *this;
|
|
}
|
|
|
|
FloatSliderOptions& DefaultValue(float defaultValue_) {
|
|
defaultValue = defaultValue_;
|
|
return *this;
|
|
}
|
|
|
|
FloatSliderOptions& ComponentAlignment(ComponentAlignments alignment_) {
|
|
alignment = alignment_;
|
|
return *this;
|
|
}
|
|
|
|
FloatSliderOptions& LabelPosition(LabelPositions labelPosition_) {
|
|
labelPosition = labelPosition_;
|
|
return *this;
|
|
}
|
|
|
|
FloatSliderOptions& IsPercentage(bool isPercentage_ = true) {
|
|
isPercentage = isPercentage_;
|
|
format = "%.0f%%";
|
|
min = 0.0f;
|
|
max = 1.0f;
|
|
return *this;
|
|
}
|
|
|
|
FloatSliderOptions& Tooltip(std::string tooltip_) {
|
|
WidgetOptions::tooltip = tooltip_;
|
|
return *this;
|
|
}
|
|
|
|
FloatSliderOptions& Color(Colors color_) {
|
|
color = color_;
|
|
return *this;
|
|
}
|
|
|
|
FloatSliderOptions& Size(ImVec2 size_) {
|
|
size = size_;
|
|
return *this;
|
|
}
|
|
|
|
FloatSliderOptions& Clamp(bool clamp_) {
|
|
clamp = clamp_;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
struct BtnSelectorOptions : WidgetOptions {
|
|
s32 defaultValue = 0;
|
|
ComponentAlignments alignment = ComponentAlignments::Left;
|
|
LabelPositions labelPosition = LabelPositions::Above;
|
|
Colors color = Colors::Gray;
|
|
|
|
BtnSelectorOptions& DefaultValue(int32_t defaultValue_) {
|
|
defaultValue = defaultValue_;
|
|
return *this;
|
|
}
|
|
|
|
BtnSelectorOptions& ComponentAlignment(ComponentAlignments alignment_) {
|
|
alignment = alignment_;
|
|
return *this;
|
|
}
|
|
|
|
BtnSelectorOptions& LabelPosition(LabelPositions labelPosition_) {
|
|
labelPosition = labelPosition_;
|
|
return *this;
|
|
}
|
|
|
|
BtnSelectorOptions& Tooltip(const char* tooltip_) {
|
|
WidgetOptions::tooltip = tooltip_;
|
|
return *this;
|
|
}
|
|
|
|
BtnSelectorOptions& Color(Colors color_) {
|
|
color = color_;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
struct RadioButtonsOptions : WidgetOptions {
|
|
std::map<int32_t, const char*> buttonMap;
|
|
int32_t defaultIndex = 0;
|
|
Colors color = Colors::LightBlue;
|
|
|
|
RadioButtonsOptions& ButtonMap(std::map<int32_t, const char*> buttonMap_) {
|
|
buttonMap = buttonMap_;
|
|
return *this;
|
|
}
|
|
|
|
RadioButtonsOptions& Tooltip(std::string tooltip_) {
|
|
WidgetOptions::tooltip = tooltip_;
|
|
return *this;
|
|
}
|
|
|
|
RadioButtonsOptions& Color(Colors color_) {
|
|
color = color_;
|
|
return *this;
|
|
}
|
|
|
|
RadioButtonsOptions& DefaultIndex(int32_t defaultIndex_) {
|
|
defaultIndex = defaultIndex_;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
struct InputOptions : WidgetOptions {
|
|
ComponentAlignments alignment = ComponentAlignments::Left;
|
|
LabelPositions labelPosition = LabelPositions::Above;
|
|
Colors color = Colors::Gray;
|
|
ImVec2 size = { 0, 0 };
|
|
std::string placeholder = "";
|
|
InputTypes type = InputTypes::String;
|
|
std::string defaultValue = "";
|
|
bool secret = false;
|
|
ImGuiInputFlags addedFlags = 0;
|
|
bool hasError = false;
|
|
std::string errorText = "";
|
|
|
|
InputOptions& Tooltip(std::string tooltip_) {
|
|
WidgetOptions::tooltip = tooltip_;
|
|
return *this;
|
|
}
|
|
|
|
InputOptions& Color(Colors color_) {
|
|
color = color_;
|
|
return *this;
|
|
}
|
|
|
|
InputOptions& Size(ImVec2 size_) {
|
|
size = size_;
|
|
return *this;
|
|
}
|
|
|
|
InputOptions& LabelPosition(LabelPositions labelPosition_) {
|
|
labelPosition = labelPosition_;
|
|
return *this;
|
|
}
|
|
|
|
InputOptions& PlaceholderText(std::string&& placeholder_) {
|
|
placeholder = std::move(placeholder_);
|
|
return *this;
|
|
}
|
|
|
|
InputOptions& PlaceholderText(std::string& placeholder_) {
|
|
placeholder = placeholder_;
|
|
return *this;
|
|
}
|
|
|
|
InputOptions& InputType(InputTypes type_) {
|
|
type = type_;
|
|
return *this;
|
|
}
|
|
|
|
InputOptions& ComponentAlignment(ComponentAlignments alignment_) {
|
|
alignment = alignment_;
|
|
return *this;
|
|
}
|
|
|
|
InputOptions& DefaultValue(std::string defaultValue_) {
|
|
defaultValue = defaultValue_;
|
|
return *this;
|
|
}
|
|
|
|
InputOptions& IsSecret(bool secret_ = false) {
|
|
secret = secret_;
|
|
return *this;
|
|
}
|
|
|
|
InputOptions& HasError(bool error_ = false) {
|
|
hasError = error_;
|
|
return *this;
|
|
}
|
|
|
|
InputOptions& ErrorText(std::string errorText_) {
|
|
errorText = errorText_;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
void PushStyleMenu(const ImVec4& color);
|
|
void PushStyleMenu(Colors color = Colors::LightBlue);
|
|
void PopStyleMenu();
|
|
bool BeginMenu(const char* label, Colors color = Colors::LightBlue);
|
|
|
|
void PushStyleMenuItem(const ImVec4& color);
|
|
void PushStyleMenuItem(Colors color = Colors::LightBlue);
|
|
void PopStyleMenuItem();
|
|
bool MenuItem(const char* label, const char* shortcut = NULL, Colors color = Colors::LightBlue);
|
|
|
|
void PushStyleButton(const ImVec4& color, ImVec2 padding = ImVec2(10.0f, 8.0f));
|
|
void PushStyleButton(Colors color = Colors::Gray, ImVec2 padding = ImVec2(10.0f, 8.0f));
|
|
void PopStyleButton();
|
|
bool Button(const char* label, const ButtonOptions& options = {});
|
|
bool WindowButton(const char* label, const char* cvarName, std::shared_ptr<Ship::GuiWindow> windowPtr,
|
|
const WindowButtonOptions& options = {});
|
|
|
|
void PushStyleCheckbox(const ImVec4& color, ImVec2 padding = ImVec2(10.0f, 6.0f));
|
|
void PushStyleCheckbox(Colors color = Colors::LightBlue, ImVec2 padding = ImVec2(10.0f, 6.0f));
|
|
void PopStyleCheckbox();
|
|
void RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash);
|
|
bool Checkbox(const char* label, bool* v, const CheckboxOptions& options = {});
|
|
bool CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions& options = {});
|
|
|
|
void PushStyleCombobox(const ImVec4& color);
|
|
void PushStyleCombobox(Colors color = Colors::LightBlue);
|
|
void PopStyleCombobox();
|
|
|
|
void PushStyleTabs(const ImVec4& color);
|
|
void PushStyleTabs(Colors color = Colors::LightBlue);
|
|
void PopStyleTabs();
|
|
|
|
void PushStyleInput(const ImVec4& color);
|
|
void PushStyleInput(Colors color = Colors::LightBlue);
|
|
void PopStyleInput();
|
|
|
|
void PushStyleHeader(const ImVec4& color);
|
|
void PushStyleHeader(Colors color = Colors::LightBlue);
|
|
void PopStyleHeader();
|
|
|
|
void Spacer(float height = 0.0f);
|
|
void Separator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f,
|
|
float extraVerticalBottomPadding = 0.0f);
|
|
|
|
float CalcComboWidth(const char* preview_value, ImGuiComboFlags flags);
|
|
|
|
template <typename T>
|
|
bool Combobox(std::string label, T* value, const std::map<T, const char*>& comboMap,
|
|
const ComboboxOptions& options = {}) {
|
|
bool dirty = false;
|
|
float startX = ImGui::GetCursorPosX();
|
|
std::string invisibleLabelStr = "##" + std::string(label);
|
|
const char* invisibleLabel = invisibleLabelStr.c_str();
|
|
std::string trueLabel = label.substr(0, label.find("#"));
|
|
ImGui::PushID(label.c_str());
|
|
ImGui::BeginGroup();
|
|
ImGui::BeginDisabled(options.disabled);
|
|
PushStyleCombobox(options.color);
|
|
|
|
const char* longest;
|
|
size_t length = 0;
|
|
for (auto& [index, string] : comboMap) {
|
|
size_t len = strlen(string);
|
|
if (len > length) {
|
|
longest = string;
|
|
length = len;
|
|
}
|
|
}
|
|
float comboWidth = CalcComboWidth(longest, options.flags);
|
|
|
|
ImGui::AlignTextToFramePadding();
|
|
if (options.labelPosition != LabelPositions::None) {
|
|
if (options.alignment == ComponentAlignments::Right) {
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
if (options.labelPosition == LabelPositions::Above) {
|
|
ImGui::NewLine();
|
|
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
|
|
} else if (options.labelPosition == LabelPositions::Near) {
|
|
ImGui::SameLine();
|
|
} else if (options.labelPosition == LabelPositions::Far) {
|
|
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
|
|
}
|
|
} else if (options.alignment == ComponentAlignments::Left) {
|
|
if (options.labelPosition == LabelPositions::Above) {
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
ImGui::SetNextItemWidth(comboWidth);
|
|
if (ImGui::BeginCombo(invisibleLabel, comboMap.at(*value), options.flags)) {
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
|
|
for (const auto& pair : comboMap) {
|
|
if (strlen(pair.second) > 1) {
|
|
if (ImGui::Selectable(pair.second, pair.first == *value)) {
|
|
*value = pair.first;
|
|
dirty = true;
|
|
}
|
|
}
|
|
}
|
|
ImGui::PopStyleVar();
|
|
ImGui::EndCombo();
|
|
}
|
|
|
|
if (options.labelPosition != LabelPositions::None) {
|
|
if (options.alignment == ComponentAlignments::Left) {
|
|
if (options.labelPosition == LabelPositions::Near) {
|
|
ImGui::SameLine();
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
} else if (options.labelPosition == LabelPositions::Far) {
|
|
float width = ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 2;
|
|
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
}
|
|
}
|
|
}
|
|
PopStyleCombobox();
|
|
ImGui::EndDisabled();
|
|
ImGui::EndGroup();
|
|
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
|
|
!options.disabledTooltip.empty()) {
|
|
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
|
|
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) {
|
|
ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
|
|
}
|
|
ImGui::PopID();
|
|
return dirty;
|
|
}
|
|
|
|
template <typename T = size_t>
|
|
bool Combobox(std::string label, T* value, const std::vector<const char*>& comboVector,
|
|
const ComboboxOptions& options = {}) {
|
|
bool dirty = false;
|
|
size_t currentValueIndex = static_cast<size_t>(*value);
|
|
std::string invisibleLabelStr = "##" + std::string(label);
|
|
const char* invisibleLabel = invisibleLabelStr.c_str();
|
|
std::string trueLabel = label.substr(0, label.find("#"));
|
|
ImGui::PushID(label.c_str());
|
|
ImGui::BeginGroup();
|
|
ImGui::BeginDisabled(options.disabled);
|
|
PushStyleCombobox(options.color);
|
|
|
|
const char* longest;
|
|
size_t length = 0;
|
|
for (auto& string : comboVector) {
|
|
size_t len = strlen(string);
|
|
if (len > length) {
|
|
longest = string;
|
|
length = len;
|
|
}
|
|
}
|
|
float comboWidth = CalcComboWidth(longest, options.flags);
|
|
|
|
ImGui::AlignTextToFramePadding();
|
|
if (options.labelPosition != LabelPositions::None) {
|
|
if (options.alignment == ComponentAlignments::Right) {
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
if (options.labelPosition == LabelPositions::Above) {
|
|
ImGui::NewLine();
|
|
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
|
|
} else if (options.labelPosition == LabelPositions::Near) {
|
|
ImGui::SameLine();
|
|
} else if (options.labelPosition == LabelPositions::Far) {
|
|
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
|
|
}
|
|
} else if (options.alignment == ComponentAlignments::Left) {
|
|
if (options.labelPosition == LabelPositions::Above) {
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
ImGui::SetNextItemWidth(comboWidth);
|
|
if (ImGui::BeginCombo(invisibleLabel, comboVector.at(currentValueIndex), options.flags)) {
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
|
|
for (size_t i = 0; i < comboVector.size(); ++i) {
|
|
auto newValue = static_cast<T>(i);
|
|
if (strlen(comboVector.at(i)) > 1) {
|
|
if (ImGui::Selectable(comboVector.at(i), newValue == *value)) {
|
|
*value = newValue;
|
|
dirty = true;
|
|
}
|
|
}
|
|
}
|
|
ImGui::PopStyleVar();
|
|
ImGui::EndCombo();
|
|
}
|
|
|
|
if (options.labelPosition != LabelPositions::None) {
|
|
if (options.alignment == ComponentAlignments::Left) {
|
|
if (options.labelPosition == LabelPositions::Near) {
|
|
ImGui::SameLine();
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
} else if (options.labelPosition == LabelPositions::Far) {
|
|
float width = ImGui::CalcTextSize(comboVector.at(*value)).x + ImGui::GetStyle().FramePadding.x * 2;
|
|
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
PopStyleCombobox();
|
|
ImGui::EndDisabled();
|
|
ImGui::EndGroup();
|
|
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
|
|
!options.disabledTooltip.empty()) {
|
|
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
|
|
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) {
|
|
ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
|
|
}
|
|
ImGui::PopID();
|
|
return dirty;
|
|
}
|
|
|
|
template <typename T = size_t>
|
|
bool Combobox(std::string label, T* value, const std::vector<std::string>& comboVector,
|
|
const ComboboxOptions& options = {}) {
|
|
bool dirty = false;
|
|
size_t currentValueIndex = static_cast<size_t>(*value);
|
|
std::string invisibleLabelStr = "##" + std::string(label);
|
|
const char* invisibleLabel = invisibleLabelStr.c_str();
|
|
std::string trueLabel = label.substr(0, label.find("#"));
|
|
ImGui::PushID(label.c_str());
|
|
ImGui::BeginGroup();
|
|
ImGui::BeginDisabled(options.disabled);
|
|
PushStyleCombobox(options.color);
|
|
|
|
const char* longest = "";
|
|
size_t length = 0;
|
|
for (auto& string : comboVector) {
|
|
size_t len = string.length();
|
|
if (len > length) {
|
|
longest = string.c_str();
|
|
length = len;
|
|
}
|
|
}
|
|
float comboWidth = CalcComboWidth(longest, options.flags);
|
|
|
|
ImGui::AlignTextToFramePadding();
|
|
if (options.labelPosition != LabelPositions::None) {
|
|
if (options.alignment == ComponentAlignments::Right) {
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
if (options.labelPosition == LabelPositions::Above) {
|
|
ImGui::NewLine();
|
|
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
|
|
} else if (options.labelPosition == LabelPositions::Near) {
|
|
ImGui::SameLine();
|
|
} else if (options.labelPosition == LabelPositions::Far) {
|
|
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
|
|
}
|
|
} else if (options.alignment == ComponentAlignments::Left) {
|
|
if (options.labelPosition == LabelPositions::Above) {
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
ImGui::SetNextItemWidth(comboWidth);
|
|
if (ImGui::BeginCombo(invisibleLabel, comboVector.at(currentValueIndex).c_str(), options.flags)) {
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
|
|
for (size_t i = 0; i < comboVector.size(); ++i) {
|
|
auto newValue = static_cast<T>(i);
|
|
if (comboVector.at(i).length() > 1) {
|
|
if (ImGui::Selectable(comboVector.at(i).c_str(), newValue == *value)) {
|
|
*value = newValue;
|
|
dirty = true;
|
|
}
|
|
}
|
|
}
|
|
ImGui::PopStyleVar();
|
|
ImGui::EndCombo();
|
|
}
|
|
|
|
if (options.labelPosition != LabelPositions::None) {
|
|
if (options.alignment == ComponentAlignments::Left) {
|
|
if (options.labelPosition == LabelPositions::Near) {
|
|
ImGui::SameLine();
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
} else if (options.labelPosition == LabelPositions::Far) {
|
|
float width =
|
|
ImGui::CalcTextSize(comboVector.at(*value).c_str()).x + ImGui::GetStyle().FramePadding.x * 2;
|
|
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
PopStyleCombobox();
|
|
ImGui::EndDisabled();
|
|
ImGui::EndGroup();
|
|
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
|
|
!options.disabledTooltip.empty()) {
|
|
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
|
|
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) {
|
|
ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
|
|
}
|
|
ImGui::PopID();
|
|
return dirty;
|
|
}
|
|
|
|
template <typename T = size_t, size_t N>
|
|
bool Combobox(std::string label, T* value, const char* (&comboArray)[N], const ComboboxOptions& options = {}) {
|
|
bool dirty = false;
|
|
size_t currentValueIndex = static_cast<size_t>(*value);
|
|
if (currentValueIndex >= N) {
|
|
currentValueIndex = 0;
|
|
}
|
|
std::string invisibleLabelStr = "##" + std::string(label);
|
|
const char* invisibleLabel = invisibleLabelStr.c_str();
|
|
std::string trueLabel = label.substr(0, label.find("#"));
|
|
ImGui::PushID(label.c_str());
|
|
ImGui::BeginGroup();
|
|
ImGui::BeginDisabled(options.disabled);
|
|
PushStyleCombobox(options.color);
|
|
|
|
const char* longest;
|
|
size_t length = 0;
|
|
for (size_t i = 0; i < N; i++) {
|
|
size_t len = strlen(comboArray[i]);
|
|
if (len > length) {
|
|
longest = comboArray[i];
|
|
length = len;
|
|
}
|
|
}
|
|
float comboWidth = CalcComboWidth(longest, options.flags);
|
|
|
|
ImGui::AlignTextToFramePadding();
|
|
if (options.labelPosition != LabelPositions::None) {
|
|
if (options.alignment == ComponentAlignments::Right) {
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
if (options.labelPosition == LabelPositions::Above) {
|
|
ImGui::NewLine();
|
|
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
|
|
} else if (options.labelPosition == LabelPositions::Near) {
|
|
ImGui::SameLine();
|
|
} else if (options.labelPosition == LabelPositions::Far) {
|
|
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
|
|
}
|
|
} else if (options.alignment == ComponentAlignments::Left) {
|
|
if (options.labelPosition == LabelPositions::Above) {
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
ImGui::SetNextItemWidth(comboWidth);
|
|
if (ImGui::BeginCombo(invisibleLabel, comboArray[currentValueIndex], options.flags)) {
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
|
|
for (size_t i = 0; i < N; ++i) {
|
|
auto newValue = static_cast<T>(i);
|
|
if (strlen(comboArray[i]) > 1) {
|
|
if (ImGui::Selectable(comboArray[i], newValue == *value)) {
|
|
*value = newValue;
|
|
dirty = true;
|
|
}
|
|
}
|
|
}
|
|
ImGui::PopStyleVar();
|
|
ImGui::EndCombo();
|
|
}
|
|
|
|
if (options.labelPosition != LabelPositions::None) {
|
|
if (options.alignment == ComponentAlignments::Left) {
|
|
if (options.labelPosition == LabelPositions::Near) {
|
|
ImGui::SameLine();
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
} else if (options.labelPosition == LabelPositions::Far) {
|
|
float width = ImGui::CalcTextSize(comboArray[*value]).x + ImGui::GetStyle().FramePadding.x * 2;
|
|
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
|
|
ImGui::Text("%s", trueLabel.c_str());
|
|
}
|
|
}
|
|
}
|
|
PopStyleCombobox();
|
|
ImGui::EndDisabled();
|
|
ImGui::EndGroup();
|
|
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
|
|
!options.disabledTooltip.empty()) {
|
|
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
|
|
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !options.tooltip.empty()) {
|
|
ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
|
|
}
|
|
ImGui::PopID();
|
|
return dirty;
|
|
}
|
|
|
|
template <typename T = int32_t>
|
|
bool CVarCombobox(const char* label, const char* cvarName, const std::map<T, const char*>& comboMap,
|
|
const ComboboxOptions& options = {}) {
|
|
bool dirty = false;
|
|
int32_t value = CVarGetInteger(cvarName, options.defaultIndex);
|
|
if (Combobox<T>(label, &value, comboMap, options)) {
|
|
CVarSetInteger(cvarName, value);
|
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
|
ShipInit::Init(cvarName);
|
|
dirty = true;
|
|
}
|
|
return dirty;
|
|
}
|
|
|
|
template <typename T = int32_t>
|
|
bool CVarCombobox(const char* label, const char* cvarName, const std::vector<const char*>& comboVector,
|
|
const ComboboxOptions& options = {}) {
|
|
bool dirty = false;
|
|
int32_t value = CVarGetInteger(cvarName, options.defaultIndex);
|
|
if (Combobox<T>(label, &value, comboVector, options)) {
|
|
CVarSetInteger(cvarName, value);
|
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
|
ShipInit::Init(cvarName);
|
|
dirty = true;
|
|
}
|
|
return dirty;
|
|
}
|
|
|
|
template <typename T = int32_t, size_t N>
|
|
bool CVarCombobox(const char* label, const char* cvarName, const char* (&comboArray)[N],
|
|
const ComboboxOptions& options = {}) {
|
|
bool dirty = false;
|
|
int32_t value = CVarGetInteger(cvarName, options.defaultIndex);
|
|
if (Combobox<T>(label, &value, comboArray, options)) {
|
|
CVarSetInteger(cvarName, value);
|
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
|
ShipInit::Init(cvarName);
|
|
dirty = true;
|
|
}
|
|
return dirty;
|
|
}
|
|
|
|
void PushStyleSlider(Colors color = Colors::LightBlue);
|
|
void PopStyleSlider();
|
|
bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& options = {});
|
|
bool CVarSliderInt(const char* label, const char* cvarName, const IntSliderOptions& options = {});
|
|
bool SliderFloat(const char* label, float* value, const FloatSliderOptions& options = {});
|
|
bool CVarSliderFloat(const char* label, const char* cvarName, const FloatSliderOptions& options = {});
|
|
bool InputString(const char* label, std::string* value, const InputOptions& options = {});
|
|
bool CVarInputString(const char* label, const char* cvarName, const InputOptions& options = {});
|
|
bool InputInt(const char* label, int32_t* value, const InputOptions& options = {});
|
|
bool CVarInputInt(const char* label, const char* cvarName, const InputOptions& options = {});
|
|
bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaultColor, bool hasAlpha = false,
|
|
uint8_t modifiers = 0, UIWidgets::Colors themeColor = UIWidgets::Colors::LightBlue);
|
|
bool RadioButton(const char* label, bool active);
|
|
bool CVarRadioButton(const char* text, const char* cvarName, int32_t id, const RadioButtonsOptions& options);
|
|
bool StateButton(const char* str_id, const char* label, ImVec2 size, UIWidgets::ButtonOptions options,
|
|
ImGuiButtonFlags flags = ImGuiButtonFlags_None);
|
|
void DrawFlagArray32(const std::string& name, uint32_t& flags, Colors color = Colors::LightBlue);
|
|
void DrawFlagArray16(const std::string& name, uint16_t& flags, Colors color = Colors::LightBlue);
|
|
void DrawFlagArray8(const std::string& name, uint8_t& flags, Colors color = Colors::LightBlue);
|
|
void DrawFlagArray8Mask(const std::string& name, uint8_t& flags, Colors color = Colors::LightBlue);
|
|
bool BtnSelector(const char* label, int32_t* value, const BtnSelectorOptions& options);
|
|
bool CVarBtnSelector(const char* label, const char* cvarName, const BtnSelectorOptions& options);
|
|
|
|
void InsertHelpHoverText(const std::string& text);
|
|
void InsertHelpHoverText(const char* text);
|
|
} // namespace UIWidgets
|
|
|
|
ImVec4 GetRandomValue(uint64_t* state = nullptr);
|
|
|
|
Color_RGBA8 RGBA8FromVec(ImVec4 vec);
|
|
ImVec4 VecFromRGBA8(Color_RGBA8 color);
|
|
|
|
#endif /* UIWidgets_hpp */
|