aboutsummaryrefslogtreecommitdiff
path: root/app/source/Cplt/UI/UI_Items.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'app/source/Cplt/UI/UI_Items.cpp')
-rw-r--r--app/source/Cplt/UI/UI_Items.cpp252
1 files changed, 252 insertions, 0 deletions
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 <Cplt/Model/GlobalStates.hpp>
+#include <Cplt/Model/Project.hpp>
+#include <Cplt/Utils/I18n.hpp>
+
+#include <IconsFontAwesome.h>
+#include <imgui.h>
+#include <imgui_stdlib.h>
+
+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 <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();
+ };
+
+ 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 <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 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 <class T>
+void ItemListEditor(ItemList<T>& 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<T>(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();
+ }
+}