aboutsummaryrefslogtreecommitdiff
path: root/core/src/UI
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/UI')
-rw-r--r--core/src/UI/Localization.hpp32
-rw-r--r--core/src/UI/States.cpp4
-rw-r--r--core/src/UI/States.hpp1
-rw-r--r--core/src/UI/UI.hpp9
-rw-r--r--core/src/UI/UI_Items.cpp212
-rw-r--r--core/src/UI/UI_MainWindow.cpp102
-rw-r--r--core/src/UI/UI_Utils.cpp38
7 files changed, 292 insertions, 106 deletions
diff --git a/core/src/UI/Localization.hpp b/core/src/UI/Localization.hpp
index d5424ea..86b7afc 100644
--- a/core/src/UI/Localization.hpp
+++ b/core/src/UI/Localization.hpp
@@ -12,6 +12,7 @@ public:
static std::unique_ptr<LocaleStrings> Instance;
public:
+ BasicTranslation Error{ "Generic.Error"sv };
BasicTranslation DialogConfirm{ "Generic.Dialog.Confirm"sv };
BasicTranslation DialogCancel{ "Generic.Dialog.Cancel"sv };
@@ -26,8 +27,8 @@ public:
BasicTranslation NewProjectNameHint{ "Project.New.Name"sv };
BasicTranslation NewProjectPathHint{ "Project.New.Path"sv };
BasicTranslation NewProjectPathDialogTitle{ "Project.New.Path.DialogTitle"sv };
- BasicTranslation NewProjectEmptyNameError{ "Project.New.EmptyName"sv };
- BasicTranslation NewProjectInvalidPathError{ "Project.New.InvalidPath"sv };
+ BasicTranslation NewProjectEmptyNameError{ "Project.New.EmptyNameError"sv };
+ BasicTranslation NewProjectInvalidPathError{ "Project.New.InvalidPathError"sv };
BasicTranslation OpenProject{ "Project.Open"sv };
BasicTranslation OpenProjectDialogTitle{ "Project.Open.DialogTitle"sv };
@@ -38,18 +39,29 @@ public:
BasicTranslation OpenRecentProjectTooltip{ "Project.Recents.Open.Tooltip"sv };
BasicTranslation DeleteRecentProjectTooltip{ "Project.Recents.Delete.Tooltip"sv };
+ BasicTranslation InvalidProjectFormat{ "Project.InvalidProjectFormat"sv };
+
BasicTranslation CloseActiveProject{ "ActiveProject.Close"sv };
BasicTranslation OpenActiveProjectInFileSystem{ "ActiveProject.OpenInFilesystem"sv };
BasicTranslation ActiveProjectName{ "ActiveProject.Info.Name"sv };
BasicTranslation ActiveProjectPath{ "ActiveProject.Info.Path"sv };
- BasicTranslation AddItem{ "ItemEditor.Add"sv };
- BasicTranslation AddItemDialogTitle{ "ItemEditor.Add.DialogTitle"sv };
- BasicTranslation DeleteItem{ "ItemEditor.Delete"sv };
+ BasicTranslation AddItem{ "Item.Add"sv };
+ BasicTranslation AddItemDialogTitle{ "Item.Add.DialogTitle"sv };
+ BasicTranslation EditItem{ "Item.Edit"sv };
+ BasicTranslation EditItemDialogTitle{ "Item.Edit.DialogTitle"sv };
+ BasicTranslation DeleteItem{ "Item.Delete"sv };
+ BasicTranslation DeleteItemDialogTitle{ "Item.Delete.DialogTitle"sv };
+ BasicTranslation DeleteItemDialogMessage{ "Item.Delete.DialogMessage"sv };
+
+ BasicTranslation ProductCategoryName{ "Item.CategoryName.Product"sv };
+ BasicTranslation FactoryCategoryName{ "Item.CategoryName.Factory"sv };
+ BasicTranslation CustomerCategoryName{ "Item.CategoryName.Customer"sv };
+
+ BasicTranslation ItemNameColumn{ "Item.Column.Name"sv };
+ BasicTranslation ItemDescriptionColumn{ "Item.Column.Description"sv };
+ BasicTranslation ItemEmailColumn{ "Item.Column.Email"sv };
- BasicTranslation ProductCategoryName{ "Item.Product.CategoryName"sv };
- BasicTranslation ProductNameColumn{ "Item.Product.Column.Name"sv };
- BasicTranslation ProductDescriptionColumn{ "Item.Product.Column.Description"sv };
- BasicTranslation FactoryCategoryName{ "Item.Factory.CategoryName"sv };
- BasicTranslation CustomerCategoryName{ "Item.Customer.CategoryName"sv };
+ BasicTranslation EmptyItemNameError{ "Item.EmptyNameError"sv };
+ BasicTranslation DuplicateItemNameError{ "Item.DuplicateNameError"sv };
};
diff --git a/core/src/UI/States.cpp b/core/src/UI/States.cpp
index dc7c37a..546e1ab 100644
--- a/core/src/UI/States.cpp
+++ b/core/src/UI/States.cpp
@@ -1,5 +1,6 @@
#include "States.hpp"
+#include "Model/GlobalStates.hpp"
#include "Model/Project.hpp"
#include <memory>
@@ -24,6 +25,9 @@ UIState& UIState::GetInstance() {
void UIState::SetCurrentProject(std::unique_ptr<Project> project) {
CloseCurrentProject();
+ if (project) {
+ GlobalStates::GetInstance().MoveProjectToTop(*project);
+ }
CurrentProject = std::move(project);
}
diff --git a/core/src/UI/States.hpp b/core/src/UI/States.hpp
index de0510c..4cc3b0f 100644
--- a/core/src/UI/States.hpp
+++ b/core/src/UI/States.hpp
@@ -3,6 +3,7 @@
#include "cplt_fwd.hpp"
#include <memory>
+#include <imgui.h>
/// Minimal state shared by all UI components, such as database, items, export, etc.
/// Note that global components (settings) is not supposed to access these.
diff --git a/core/src/UI/UI.hpp b/core/src/UI/UI.hpp
index 52a2ca9..ab35321 100644
--- a/core/src/UI/UI.hpp
+++ b/core/src/UI/UI.hpp
@@ -4,14 +4,19 @@
namespace ImGui {
-void SetNextWindowSizeRelScreen(float xPercent, float yPercent, ImGuiCond_ cond = ImGuiCond_None);
-void SetNextWindowCentered(ImGuiCond_ cond = ImGuiCond_None);
+void SetNextWindowSizeRelScreen(float xPercent, float yPercent, ImGuiCond cond = ImGuiCond_None);
+void SetNextWindowCentered(ImGuiCond cond = ImGuiCond_None);
void PushDisabled();
void PopDisabled();
+bool Button(const char* label, bool disabled);
+bool Button(const char* label, const ImVec2& sizeArg, bool disabled);
+
void ErrorIcon();
+void ErrorMessage(const char* fmt, ...);
void WarningIcon();
+void WarningMessage(const char* fmt, ...);
} // namespace ImGui
diff --git a/core/src/UI/UI_Items.cpp b/core/src/UI/UI_Items.cpp
index a990a96..970d0df 100644
--- a/core/src/UI/UI_Items.cpp
+++ b/core/src/UI/UI_Items.cpp
@@ -5,106 +5,202 @@
#include "UI/Localization.hpp"
#include "UI/States.hpp"
-#include <IconsFontAwesome.h>
#include <imgui.h>
#include <imgui_stdlib.h>
namespace {
-/// Specialized for each item type.
-template <class T>
-void AddToItemListDialog(ItemList<T>& list);
-/// Specialized for each item type.
-template <class T>
-void ItemListEntries(ItemList<T>& list);
-template <>
-void AddToItemListDialog<ProductItem>(ItemList<ProductItem>& list) {
- static std::string productName;
- static std::string description;
+enum class ActionResult {
+ Confirmed,
+ Canceled,
+ Pending,
+};
+
+/// \param list Item list that the item is in.
+/// \param item A non-null pointer to the currently being edited item. It should not change until this function returns a non-\c ActionResult::Pending value.
+template <class T>
+ActionResult ItemEditor(ItemList<T>& list, T* item) {
+ constexpr bool kHasDescription = requires(T t) { t.GetDescription(); };
+ constexpr bool kHasEmail = requires(T t) { t.GetEmail(); };
auto ls = LocaleStrings::Instance.get();
auto& uis = UIState::GetInstance();
- ImGui::InputText(ls->ProductNameColumn.Get(), &productName);
- ImGui::InputText(ls->ProductDescriptionColumn.Get(), &description);
- if (ImGui::Button(ls->DialogConfirm.Get())) {
- auto& product = uis.CurrentProject->Products.Insert(std::move(productName));
- product.SetDescription(std::move(description));
+ static bool duplicateName = false;
+
+ static std::string name;
+ static std::string description;
+ static std::string email;
+ if (name.empty()) {
+ name = item->GetName();
+ if constexpr (kHasDescription) description = item->GetDescription();
+ if constexpr (kHasEmail) email = item->GetEmail();
+ }
+
+ auto ClearStates = [&]() {
+ duplicateName = false;
+ name = {};
+ description = {};
+ };
+
+ if (ImGui::InputText(ls->ItemNameColumn.Get(), &name)) {
+ duplicateName = name != item->GetName() && list.Find(name) != nullptr;
+ }
+ if constexpr (kHasDescription) ImGui::InputText(ls->ItemDescriptionColumn.Get(), &description);
+ if constexpr (kHasEmail) ImGui::InputText(ls->ItemEmailColumn.Get(), &email);
+
+ if (name.empty()) {
+ ImGui::ErrorMessage("%s", ls->EmptyItemNameError.Get());
+ }
+ if (duplicateName) {
+ ImGui::ErrorMessage("%s", ls->DuplicateItemNameError.Get());
+ }
+
+ // Return Value
+ auto rv = ActionResult::Pending;
- productName.clear();
- description.clear();
+ if (ImGui::Button(ls->DialogConfirm.Get(), name.empty() || duplicateName)) {
+ if (item->GetName() != name) {
+ item->SetName(std::move(name));
+ }
+ if constexpr (kHasDescription)
+ if (item->GetDescription() != description) {
+ item->SetDescription(std::move(description));
+ }
+ if constexpr (kHasEmail)
+ if (item->GetEmail() != email) {
+ item->SetEmail(std::move(email));
+ }
ImGui::CloseCurrentPopup();
+ ClearStates();
+ rv = ActionResult::Confirmed;
}
+
ImGui::SameLine();
if (ImGui::Button(ls->DialogCancel.Get())) {
ImGui::CloseCurrentPopup();
+ ClearStates();
+ rv = ActionResult::Canceled;
}
-}
-template <>
-void AddToItemListDialog<FactoryItem>(ItemList<FactoryItem>& list) {
- // TODO
+ return rv;
}
-template <>
-void AddToItemListDialog<CustomerItem>(ItemList<CustomerItem>& list) {
- // TODO
-}
+template <class T>
+void ItemListEntries(ItemList<T>& list, int& selectedIdx) {
+ constexpr bool kHasDescription = requires(T t) { t.GetDescription(); };
+ constexpr bool kHasEmail = requires(T t) { t.GetEmail(); };
+ constexpr int kColumns = 1 /* Name column */ + kHasDescription + kHasEmail;
-template <>
-void ItemListEntries<ProductItem>(ItemList<ProductItem>& list) {
auto ls = LocaleStrings::Instance.get();
- if (ImGui::BeginTable("ItemListEntries", 2)) {
+ auto& uis = UIState::GetInstance();
- ImGui::TableSetupColumn(ls->ProductNameColumn.Get());
- ImGui::TableSetupColumn(ls->ProductDescriptionColumn.Get());
+ if (ImGui::BeginTable("", kColumns, ImGuiTableFlags_Borders)) {
+
+ ImGui::TableSetupColumn(ls->ItemNameColumn.Get());
+ if constexpr (kHasDescription) ImGui::TableSetupColumn(ls->ItemDescriptionColumn.Get());
+ if constexpr (kHasEmail) ImGui::TableSetupColumn(ls->ItemEmailColumn.Get());
ImGui::TableHeadersRow();
+ size_t idx = 0;
for (auto& entry : list) {
+ if (entry.IsInvalid()) {
+ continue;
+ }
+
ImGui::TableNextRow();
+ // Field: name
ImGui::TableNextColumn();
- ImGui::Text("%s", entry.GetName().c_str());
- ImGui::TableNextColumn();
- ImGui::Text("%.8s", entry.GetDescription().c_str());
- if (ImGui::Button(ICON_FA_EDIT)) {
- // TODO
+ if (ImGui::Selectable(entry.GetName().c_str(), selectedIdx == idx, ImGuiSelectableFlags_SpanAllColumns)) {
+ selectedIdx = idx;
+ }
+
+ // Field: description
+ if constexpr (kHasDescription) {
+ ImGui::TableNextColumn();
+ ImGui::Text("%s", entry.GetDescription().c_str());
+ }
+
+ // Field: email
+ if constexpr (kHasEmail) {
+ ImGui::TableNextColumn();
+ ImGui::Text("%s", entry.GetEmail().c_str());
}
+
+ idx++;
}
ImGui::EndTable();
}
}
-template <>
-void ItemListEntries<FactoryItem>(ItemList<FactoryItem>& list) {
- // TODO
-}
-
-template <>
-void ItemListEntries<CustomerItem>(ItemList<CustomerItem>& list) {
- // TODO
-}
-
template <class T>
void ItemListEditor(ItemList<T>& list) {
auto ls = LocaleStrings::Instance.get();
+ bool opened = true;
+ static int selectedIdx = -1;
+ static T* editingItem = nullptr;
+
if (ImGui::Button(ls->AddItem.Get())) {
ImGui::SetNextWindowCentered();
ImGui::OpenPopup(ls->AddItemDialogTitle.Get());
+
+ editingItem = &list.Insert("");
+ }
+ if (ImGui::BeginPopupModal(ls->AddItemDialogTitle.Get(), &opened, ImGuiWindowFlags_AlwaysAutoResize)) {
+ switch (ItemEditor(list, editingItem)) {
+ case ActionResult::Confirmed:
+ editingItem = nullptr;
+ break;
+ case ActionResult::Canceled:
+ list.Remove(editingItem->GetId());
+ editingItem = nullptr;
+ break;
+ default:
+ break;
+ }
+ ImGui::EndPopup();
+ }
+
+ ImGui::SameLine();
+ if (ImGui::Button(ls->EditItem.Get(), selectedIdx == -1)) {
+ ImGui::SetNextWindowCentered();
+ ImGui::OpenPopup(ls->EditItemDialogTitle.Get());
+
+ editingItem = list.Find(selectedIdx);
}
- if (ImGui::BeginPopupModal(ls->AddItemDialogTitle.Get())) {
- AddToItemListDialog<T>(list);
+ if (ImGui::BeginPopupModal(ls->EditItemDialogTitle.Get(), &opened, ImGuiWindowFlags_AlwaysAutoResize)) {
+ if (ItemEditor(list, editingItem) != ActionResult::Pending) {
+ editingItem = nullptr;
+ }
ImGui::EndPopup();
}
ImGui::SameLine();
- if (ImGui::Button(ls->DeleteItem.Get())) {
- // TODO
+ if (ImGui::Button(ls->DeleteItem.Get(), selectedIdx == -1)) {
+ ImGui::SetNextWindowCentered();
+ ImGui::OpenPopup(ls->DeleteItemDialogTitle.Get());
+
+ list.Remove(selectedIdx);
+ }
+ if (ImGui::BeginPopupModal(ls->DeleteItemDialogTitle.Get(), &opened, ImGuiWindowFlags_AlwaysAutoResize)) {
+ ImGui::Text("%s", ls->DeleteItemDialogMessage.Get());
+
+ if (ImGui::Button(ls->DialogConfirm.Get())) {
+ ImGui::CloseCurrentPopup();
+ }
+
+ ImGui::SameLine();
+ if (ImGui::Button(ls->DialogCancel.Get())) {
+ ImGui::CloseCurrentPopup();
+ }
+
+ ImGui::EndPopup();
}
- ItemListEntries<T>(list);
+ ItemListEntries<T>(list, selectedIdx);
}
} // namespace
@@ -112,13 +208,27 @@ void UI::ItemsTab() {
auto ls = LocaleStrings::Instance.get();
auto& uis = UIState::GetInstance();
+ constexpr float kAmount = 16.0f;
+ int id = 0;
if (ImGui::CollapsingHeader(ls->ProductCategoryName.Get())) {
+ ImGui::PushID(id++);
+ ImGui::Indent(kAmount);
ItemListEditor(uis.CurrentProject->Products);
+ ImGui::Unindent(kAmount);
+ ImGui::PopID();
}
if (ImGui::CollapsingHeader(ls->FactoryCategoryName.Get())) {
+ ImGui::PushID(id++);
+ ImGui::Indent(kAmount);
ItemListEditor(uis.CurrentProject->Factories);
+ ImGui::Unindent(kAmount);
+ ImGui::PopID();
}
if (ImGui::CollapsingHeader(ls->CustomerCategoryName.Get())) {
+ ImGui::PushID(id++);
+ ImGui::Indent(kAmount);
ItemListEditor(uis.CurrentProject->Customers);
+ ImGui::Unindent(kAmount);
+ ImGui::PopID();
}
}
diff --git a/core/src/UI/UI_MainWindow.cpp b/core/src/UI/UI_MainWindow.cpp
index 15c28ff..661c535 100644
--- a/core/src/UI/UI_MainWindow.cpp
+++ b/core/src/UI/UI_MainWindow.cpp
@@ -15,10 +15,16 @@
namespace fs = std::filesystem;
namespace {
-void LoadProjectAt(const std::filesystem::path& path) {
+bool LoadProjectAt(const std::filesystem::path& path) {
auto& uis = UIState::GetInstance();
- auto project = Project::Load(path);
- uis.SetCurrentProject(std::make_unique<Project>(std::move(project)));
+ try {
+ auto project = Project::Load(path);
+ uis.SetCurrentProject(std::make_unique<Project>(std::move(project)));
+
+ return true;
+ } catch (const std::exception& e) {
+ return false;
+ }
}
void ProjectTab_Normal() {
@@ -44,6 +50,8 @@ void ProjectTab_NoProject() {
auto& gs = GlobalStates::GetInstance();
auto& uis = UIState::GetInstance();
+ bool openedDummy = true;
+ bool openErrorDialog = false;
static std::string projectName;
static std::string dirName;
static fs::path dirPath;
@@ -61,13 +69,11 @@ void ProjectTab_NoProject() {
if (ImGui::Button(ls->NewProject.Get())) {
ImGui::SetNextWindowCentered();
- ImGui::SetNextWindowSizeRelScreen(0.5f, 0.5f);
ImGui::OpenPopup(ls->NewProjectDialogTitle.Get());
}
// Make it so that the modal dialog has a close button
- bool newProjectDialogDummyTrue = true;
- if (ImGui::BeginPopupModal(ls->NewProjectDialogTitle.Get(), &newProjectDialogDummyTrue)) {
+ if (ImGui::BeginPopupModal(ls->NewProjectDialogTitle.Get(), &openedDummy, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::InputTextWithHint("##ProjectName", ls->NewProjectNameHint.Get(), &projectName);
if (ImGui::InputTextWithHint("##ProjectPath", ls->NewProjectPathHint.Get(), &dirName)) {
@@ -83,25 +89,15 @@ void ProjectTab_NoProject() {
}
if (projectName.empty()) {
- ImGui::ErrorIcon();
-
- ImGui::SameLine();
- ImGui::Text("%s", ls->NewProjectEmptyNameError.Get());
+ ImGui::ErrorMessage("%s", ls->NewProjectEmptyNameError.Get());
}
-
if (!dirNameIsValid) {
- ImGui::ErrorIcon();
-
- ImGui::SameLine();
- ImGui::Text("%s", ls->NewProjectInvalidPathError.Get());
+ ImGui::ErrorMessage("%s", ls->NewProjectInvalidPathError.Get());
}
ImGui::Spacing();
- bool formValid = dirNameIsValid && !projectName.empty();
-
- if (!formValid) ImGui::PushDisabled();
- if (ImGui::Button(ls->DialogConfirm.Get())) {
+ if (ImGui::Button(ls->DialogConfirm.Get(), !dirNameIsValid || projectName.empty())) {
ImGui::CloseCurrentPopup();
auto project = Project::Create(std::move(projectName), dirPath);
@@ -113,7 +109,6 @@ void ProjectTab_NoProject() {
dirPath = fs::path{};
dirNameIsValid = false;
}
- if (!formValid) ImGui::PopDisabled();
ImGui::SameLine();
if (ImGui::Button(ls->DialogCancel.Get())) {
@@ -123,45 +118,72 @@ void ProjectTab_NoProject() {
ImGui::EndPopup();
}
+ ImGui::SameLine();
if (ImGui::Button(ls->OpenProject.Get())) {
auto selection = pfd::open_file(ls->OpenProjectDialogTitle.Get()).result();
if (!selection.empty()) {
fs::path path(selection[0]);
- LoadProjectAt(path);
+ openErrorDialog = !LoadProjectAt(path);
}
}
+ // TODO cleanup UI
+ // Recent projects
+
ImGui::Separator();
ImGui::Text("%s", ls->RecentProjects.Get());
+
ImGui::SameLine();
if (ImGui::Button(ls->ClearRecentProjects.Get())) {
gs.ClearRecentProjects();
}
- auto& recentProjects = gs.GetRecentProjects();
- if (recentProjects.empty()) {
+ auto& rp = gs.GetRecentProjects();
+ // End of vector is the most recently used, so that appending has less overhead
+ size_t toRemoveIdx = rp.size();
+
+ if (rp.empty()) {
ImGui::Text("%s", ls->NoRecentProjectsMessage.Get());
- }
- for (auto it = recentProjects.begin(); it != recentProjects.end(); ++it) {
- auto& [path, recent] = *it;
- ImGui::Text("%s", recent.c_str());
+ } else {
+ for (auto it = rp.rbegin(); it != rp.rend(); ++it) {
+ auto& [path, recent] = *it;
+ ImGui::Text("%s", recent.c_str());
- ImGui::SameLine();
- if (ImGui::Button(ICON_FA_EDIT)) {
- LoadProjectAt(path);
- }
- if (ImGui::IsItemHovered()) {
- ImGui::SetTooltip("%s", ls->OpenRecentProjectTooltip.Get());
- }
+ size_t idx = std::distance(it, rp.rend()) - 1;
+ ImGui::PushID(idx);
- ImGui::SameLine();
- if (ImGui::Button(ICON_FA_TRASH)) {
- gs.RemoveRecentProject(std::distance(recentProjects.begin(), it));
- }
- if (ImGui::IsItemHovered()) {
- ImGui::SetTooltip("%s", ls->DeleteRecentProjectTooltip.Get());
+ ImGui::SameLine();
+ if (ImGui::Button(ICON_FA_FOLDER_OPEN)) {
+ openErrorDialog = !LoadProjectAt(path / "cplt_project.json");
+ }
+ if (ImGui::IsItemHovered()) {
+ ImGui::SetTooltip("%s", ls->OpenRecentProjectTooltip.Get());
+ }
+
+ ImGui::SameLine();
+ if (ImGui::Button(ICON_FA_TRASH)) {
+ toRemoveIdx = idx;
+ }
+ if (ImGui::IsItemHovered()) {
+ ImGui::SetTooltip("%s", ls->DeleteRecentProjectTooltip.Get());
+ }
+
+ ImGui::PopID();
}
}
+
+ if (toRemoveIdx != rp.size()) {
+ gs.RemoveRecentProject(toRemoveIdx);
+ }
+
+ if (openErrorDialog) {
+ ImGui::SetNextWindowCentered();
+ ImGui::OpenPopup(ls->Error.Get());
+ }
+ if (ImGui::BeginPopupModal(ls->Error.Get(), &openedDummy, ImGuiWindowFlags_AlwaysAutoResize)) {
+ ImGui::ErrorMessage("%s", ls->InvalidProjectFormat.Get());
+ ImGui::EndPopup();
+ }
}
} // namespace
diff --git a/core/src/UI/UI_Utils.cpp b/core/src/UI/UI_Utils.cpp
index 615caae..06fd55e 100644
--- a/core/src/UI/UI_Utils.cpp
+++ b/core/src/UI/UI_Utils.cpp
@@ -4,18 +4,18 @@
#include <imgui.h>
#include <imgui_internal.h>
-void ImGui::SetNextWindowSizeRelScreen(float xPercent, float yPercent, ImGuiCond_ cond) {
+void ImGui::SetNextWindowSizeRelScreen(float xPercent, float yPercent, ImGuiCond cond) {
auto vs = ImGui::GetMainViewport()->Size;
ImGui::SetNextWindowSize({ vs.x * xPercent, vs.y * yPercent }, cond);
}
-void ImGui::SetNextWindowCentered(ImGuiCond_ cond) {
+void ImGui::SetNextWindowCentered(ImGuiCond cond) {
auto vs = ImGui::GetMainViewport()->Size;
ImGui::SetNextWindowPos({ vs.x / 2, vs.y / 2 }, cond, { 0.5f, 0.5f });
}
void ImGui::PushDisabled() {
- ImGui::PushItemFlag(ImGuiItemFlags_Disabled, false);
+ ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.5f * ImGui::GetStyle().Alpha);
}
@@ -24,14 +24,46 @@ void ImGui::PopDisabled() {
ImGui::PopStyleVar();
}
+bool ImGui::Button(const char* label, bool disabled) {
+ return Button(label, ImVec2{}, disabled);
+}
+
+bool ImGui::Button(const char* label, const ImVec2& sizeArg, bool disabled) {
+ if (disabled) PushDisabled();
+ bool res = ImGui::Button(label, sizeArg);
+ if (disabled) PopDisabled();
+
+ return res;
+}
+
void ImGui::ErrorIcon() {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{ 237 / 255.0f, 67 / 255.0f, 55 / 255.0f, 1.0f }); // #ED4337
ImGui::Text(ICON_FA_EXCLAMATION_CIRCLE);
ImGui::PopStyleColor();
}
+void ImGui::ErrorMessage(const char* fmt, ...) {
+ ErrorIcon();
+ SameLine();
+
+ va_list args;
+ va_start(args, fmt);
+ TextV(fmt, args);
+ va_end(args);
+}
+
void ImGui::WarningIcon() {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{ 255 / 255.0f, 184 / 255.0f, 24 / 255.0f, 1.0f }); // #FFB818
ImGui::Text(ICON_FA_EXCLAMATION_TRIANGLE);
ImGui::PopStyleColor();
}
+
+void ImGui::WarningMessage(const char* fmt, ...) {
+ WarningIcon();
+ SameLine();
+
+ va_list args;
+ va_start(args, fmt);
+ TextV(fmt, args);
+ va_end(args);
+}