diff options
Diffstat (limited to 'core/src/UI/UI_Items.cpp')
-rw-r--r-- | core/src/UI/UI_Items.cpp | 212 |
1 files changed, 161 insertions, 51 deletions
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(); } } |