From 7fe47a9d5b1727a61dc724523b530762f6d6ba19 Mon Sep 17 00:00:00 2001 From: rtk0c Date: Thu, 30 Jun 2022 21:38:53 -0700 Subject: Restructure project --- app/source/Cplt/UI/UI_Items.cpp | 252 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 app/source/Cplt/UI/UI_Items.cpp (limited to 'app/source/Cplt/UI/UI_Items.cpp') diff --git a/app/source/Cplt/UI/UI_Items.cpp b/app/source/Cplt/UI/UI_Items.cpp new file mode 100644 index 0000000..0170e1a --- /dev/null +++ b/app/source/Cplt/UI/UI_Items.cpp @@ -0,0 +1,252 @@ +#include "UI.hpp" + +#include +#include +#include + +#include +#include +#include + +namespace CPLT_UNITY_ID { + +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 +ActionResult ItemEditor(ItemList& list, T* item) +{ + constexpr bool kHasDescription = requires(T t) + { + t.GetDescription(); + }; + constexpr bool kHasEmail = requires(T t) + { + t.GetEmail(); + }; + + 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(I18N_TEXT("Name", L10N_ITEM_COLUMN_NAME), &name)) { + duplicateName = name != item->GetName() && list.Find(name) != nullptr; + } + if constexpr (kHasDescription) ImGui::InputText(I18N_TEXT("Description", L10N_ITEM_COLUMN_DESCRIPTION), &description); + if constexpr (kHasEmail) ImGui::InputText(I18N_TEXT("Email", L10N_ITEM_COLUMN_EMAIL), &email); + + if (name.empty()) { + ImGui::ErrorMessage(I18N_TEXT("Name cannot be empty", L10N_EMPTY_NAME_ERROR)); + } + if (duplicateName) { + ImGui::ErrorMessage(I18N_TEXT("Duplicate name", L10N_DUPLICATE_NAME_ERROR)); + } + + // Return Value + auto rv = ActionResult::Pending; + + if (ImGui::Button(I18N_TEXT("Confirm", L10N_CONFIRM), 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(I18N_TEXT("Cancel", L10N_CANCEL))) { + ImGui::CloseCurrentPopup(); + ClearStates(); + rv = ActionResult::Canceled; + } + + return rv; +} + +template +void ItemListEntries(ItemList& list, int& selectedIdx) +{ + constexpr bool kHasDescription = requires(T t) + { + t.GetDescription(); + }; + constexpr bool kHasEmail = requires(T t) + { + t.GetEmail(); + }; + constexpr bool kHasStock = requires(T t) + { + t.GetPrice(); + }; + constexpr bool kHasPrice = requires(T t) + { + t.GetPrice(); + }; + constexpr int kColumns = 1 /* Name column */ + kHasDescription + kHasEmail + kHasStock + kHasPrice; + + if (ImGui::BeginTable("", kColumns, ImGuiTableFlags_Borders)) { + + ImGui::TableSetupColumn(I18N_TEXT("Name", L10N_ITEM_COLUMN_NAME)); + if constexpr (kHasDescription) ImGui::TableSetupColumn(I18N_TEXT("Description", L10N_ITEM_COLUMN_DESCRIPTION)); + if constexpr (kHasEmail) ImGui::TableSetupColumn(I18N_TEXT("Email", L10N_ITEM_COLUMN_EMAIL)); + if constexpr (kHasStock) ImGui::TableSetupColumn(I18N_TEXT("Stock", L10N_ITEM_COLUMN_STOCK)); + if constexpr (kHasPrice) ImGui::TableSetupColumn(I18N_TEXT("Price", L10N_ITEM_COLUMN_PRICE)); + ImGui::TableHeadersRow(); + + size_t idx = 0; + for (auto& entry : list) { + if (entry.IsInvalid()) { + continue; + } + + ImGui::TableNextRow(); + + ImGui::TableNextColumn(); + if (ImGui::Selectable(entry.GetName().c_str(), selectedIdx == idx, ImGuiSelectableFlags_SpanAllColumns)) { + selectedIdx = idx; + } + + if constexpr (kHasDescription) { + ImGui::TableNextColumn(); + ImGui::TextUnformatted(entry.GetDescription().c_str()); + } + + if constexpr (kHasEmail) { + ImGui::TableNextColumn(); + ImGui::TextUnformatted(entry.GetEmail().c_str()); + } + + if constexpr (kHasStock) { + ImGui::TableNextColumn(); + ImGui::Text("%d", entry.GetStock()); + } + + if constexpr (kHasPrice) { + ImGui::TableNextColumn(); + // TODO format in dollars + ImGui::Text("%d", entry.GetPrice()); + } + + idx++; + } + ImGui::EndTable(); + } +} + +template +void ItemListEditor(ItemList& list) +{ + bool opened = true; + static int selectedIdx = -1; + static T* editingItem = nullptr; + + if (ImGui::Button(ICON_FA_PLUS " " I18N_TEXT("Add", L10N_ADD))) { + ImGui::SetNextWindowCentered(); + ImGui::OpenPopup(I18N_TEXT("Add item", L10N_ITEM_ADD_DIALOG_TITLE)); + + editingItem = &list.Insert(""); + } + if (ImGui::BeginPopupModal(I18N_TEXT("Add item", L10N_ITEM_ADD_DIALOG_TITLE), &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(ICON_FA_EDIT " " I18N_TEXT("Edit", L10N_EDIT), selectedIdx == -1)) { + ImGui::SetNextWindowCentered(); + ImGui::OpenPopup(I18N_TEXT("Edit item", L10N_ITEM_EDIT_DIALOG_TITLE)); + + editingItem = list.Find(selectedIdx); + } + if (ImGui::BeginPopupModal(I18N_TEXT("Edit item", L10N_ITEM_EDIT_DIALOG_TITLE), &opened, ImGuiWindowFlags_AlwaysAutoResize)) { + if (ItemEditor(list, editingItem) != ActionResult::Pending) { + editingItem = nullptr; + } + ImGui::EndPopup(); + } + + ImGui::SameLine(); + if (ImGui::Button(ICON_FA_TRASH " " I18N_TEXT("Delete", L10N_DELETE), selectedIdx == -1)) { + ImGui::SetNextWindowCentered(); + ImGui::OpenPopup(I18N_TEXT("Delete item", L10N_ITEM_DELETE_DIALOG_TITLE)); + + list.Remove(selectedIdx); + } + if (ImGui::BeginPopupModal(I18N_TEXT("Delete item", L10N_ITEM_DELETE_DIALOG_TITLE), &opened, ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::TextUnformatted(I18N_TEXT("Are you sure you want to delete this item?", L10N_ITEM_DELETE_DIALOG_MESSAGE)); + + if (ImGui::Button(I18N_TEXT("Confirm", L10N_CONFIRM))) { + ImGui::CloseCurrentPopup(); + } + + ImGui::SameLine(); + if (ImGui::Button(I18N_TEXT("Cancel", L10N_CANCEL))) { + ImGui::CloseCurrentPopup(); + } + + ImGui::EndPopup(); + } + + ItemListEntries(list, selectedIdx); +} +} // namespace CPLT_UNITY_ID + +void UI::ItemsTab() +{ + auto& gs = GlobalStates::GetInstance(); + + if (ImGui::BeginTabBar("ItemViewTabs")) { + if (ImGui::BeginTabItem(I18N_TEXT("Products", L10N_ITEM_CATEGORY_PRODUCT))) { + CPLT_UNITY_ID::ItemListEditor(gs.GetCurrentProject()->Products); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem(I18N_TEXT("Factories", L10N_ITEM_CATEGORY_FACTORY))) { + CPLT_UNITY_ID::ItemListEditor(gs.GetCurrentProject()->Factories); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem(I18N_TEXT("Customers", L10N_ITEM_CATEGORY_CUSTOMER))) { + CPLT_UNITY_ID::ItemListEditor(gs.GetCurrentProject()->Customers); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } +} -- cgit v1.2.3-70-g09d2