From 3c83a2d06cf33429ca0e654a415fc95581df46e1 Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Sun, 10 Aug 2025 17:01:10 +0200 Subject: refactor contact form --- src/ui/helpers.cpp | 45 ++++++++++++++++++++- src/ui/ui_contacts.cpp | 103 +++++++++++++++++++++++++++++-------------------- src/ui/ui_invoices.cpp | 27 +++++++++++-- src/ui/ui_settings.cpp | 12 ++++-- 4 files changed, 137 insertions(+), 50 deletions(-) (limited to 'src/ui') diff --git a/src/ui/helpers.cpp b/src/ui/helpers.cpp index e4b25c8..a239f4c 100644 --- a/src/ui/helpers.cpp +++ b/src/ui/helpers.cpp @@ -1,6 +1,7 @@ #include "ui.hpp" #include "imgui.h" #include "locales.hpp" +#include "strops.hpp" static float toast_timer = 0.0f; static const char* toast_msg = nullptr; @@ -62,4 +63,46 @@ void ui_helper_draw_required_tag() ImGui::PushStyleColor(ImGuiCol_Text, text_color); ImGui::TextUnformatted(text); ImGui::PopStyleColor(); -} \ No newline at end of file +} + +void ui_helper_TextInputWithAutocomplete(const char* label, const char* hint, char* buffer, size_t buf_size, + char* suggestions[], int suggestion_count) +{ + static bool is_open = false; + ImGui::InputTextWithHint(label, hint, buffer, buf_size); + + bool is_active = ImGui::IsItemActive(); + if (is_active && buffer[0] != '\0') + { + is_open = true; + } + + if (is_open) { + ImGui::BeginChild("autocomplete_popup", ImVec2(0, 100), true); + { + ImVec2 win_pos = ImGui::GetWindowPos(); + ImVec2 win_size = ImGui::GetWindowSize(); + ImVec2 mouse_pos = ImGui::GetMousePos(); + + bool mouse_clicked_outside = !is_active && ImGui::IsMouseClicked(0) && + (mouse_pos.x < win_pos.x || mouse_pos.x > win_pos.x + win_size.x || + mouse_pos.y < win_pos.y || mouse_pos.y > win_pos.y + win_size.y); + + if (mouse_clicked_outside) is_open = false; + + for (int i = 0; i < suggestion_count; ++i) + { + if (ImGui::Selectable(suggestions[i])) + { + // Copy selected suggestion to buffer + strops_copy(buffer, suggestions[i], buf_size); + buffer[buf_size - 1] = '\0'; + + is_open = false; + } + } + + ImGui::EndChild(); + } + } +} diff --git a/src/ui/ui_contacts.cpp b/src/ui/ui_contacts.cpp index e19f571..c381db5 100644 --- a/src/ui/ui_contacts.cpp +++ b/src/ui/ui_contacts.cpp @@ -18,30 +18,33 @@ void ui_setup_contacts() memset(&selected_for_removal, 0, sizeof(contact)); } -bool draw_contact_form(contact* buffer, bool back_button_enabled = true, bool viewing_only = false) +void draw_contact_form(contact* buffer, bool viewing_only = false) { + bool with_autocomplete = false; const char* selected_country = NULL; - if (back_button_enabled) - { - if (ImGui::Button(localize("form.back"))) { - current_view_state = view_state::LIST; - selected_country = 0; - return false; - } - } ImGui::Spacing(); float widthAvailable = ImGui::GetContentRegionAvail().x; + ImGui::BeginDisabled(); + // 1. Identifier - //ImGui::BeginDisabled(); //ImGui::SetNextItemWidth(widthAvailable*0.2f); //ImGui::InputText(localize("contact.form.identifier"), buffer->id, IM_ARRAYSIZE(buffer->id)); - //if (!viewing_only) ImGui::EndDisabled(); + + if (!viewing_only) ImGui::EndDisabled(); // 2. Full name ImGui::SetNextItemWidth(widthAvailable*0.5f); - ImGui::InputTextWithHint(localize("contact.form.fullname"), localize("contact.form.fullname"), buffer->name, IM_ARRAYSIZE(buffer->name)); + if (with_autocomplete) { + contact autocomplete_list[5]; + int autocomplete_count = 5; + char* autocomplete_strings[5] = { "1", "2", "3", "4", "5" }; + + ui_helper_TextInputWithAutocomplete(localize("contact.form.fullname"), localize("contact.form.fullname"), + buffer->name, IM_ARRAYSIZE(buffer->name), (char**)autocomplete_strings, autocomplete_count); + } + else ImGui::InputTextWithHint(localize("contact.form.fullname"), localize("contact.form.fullname"), buffer->name, IM_ARRAYSIZE(buffer->name)); ImGui::SameLine();ui_helper_draw_required_tag(); // 3. Address line 1 @@ -126,23 +129,6 @@ bool draw_contact_form(contact* buffer, bool back_button_enabled = true, bool vi ImGui::InputTextWithHint(localize("contact.form.bankaccount"), localize("contact.form.bankaccount"), buffer->bank_account, IM_ARRAYSIZE(buffer->bank_account)); if (viewing_only) ImGui::EndDisabled(); - - if (!viewing_only) { - bool can_save = strlen(buffer->name) > 0 && strlen(buffer->address.address1) > 0 && - strlen(buffer->address.address2) > 0 && strlen(buffer->address.country_code) > 0; - - if (!can_save) ImGui::BeginDisabled(); - // Save button - ImGui::Spacing(); - if (ImGui::Button(localize("form.save"))) { - return true; - } - if (!can_save) ImGui::EndDisabled(); - } - else { - // TODO list invoices connected to contact. - } - return false; } static void draw_contact_list() @@ -248,25 +234,58 @@ static void draw_contact_list() } } +static void ui_draw_contacts_create() +{ + if (ImGui::Button(localize("form.back"))) { + current_view_state = view_state::LIST; + } + + draw_contact_form(&active_contact); + + bool can_save = administration_is_contact_valid(active_contact); + if (!can_save) ImGui::BeginDisabled(); + // Save button + ImGui::Spacing(); + if (ImGui::Button(localize("form.save"))) { + administration_create_contact(active_contact); + current_view_state = view_state::LIST; + } + if (!can_save) ImGui::EndDisabled(); +} + +static void ui_draw_contacts_update() +{ + if (ImGui::Button(localize("form.back"))) { + current_view_state = view_state::LIST; + } + + draw_contact_form(&active_contact); + + bool can_save = administration_is_contact_valid(active_contact); + if (!can_save) ImGui::BeginDisabled(); + // Save button + ImGui::Spacing(); + if (ImGui::Button(localize("form.save"))) { + administration_update_contact(active_contact); + current_view_state = view_state::LIST; + } + if (!can_save) ImGui::EndDisabled(); +} + void ui_draw_contacts() { switch(current_view_state) { case view_state::LIST: draw_contact_list(); break; - case view_state::CREATE: - if (draw_contact_form(&active_contact)) - { - administration_create_contact(active_contact); + case view_state::CREATE: ui_draw_contacts_create(); break; + case view_state::EDIT: ui_draw_contacts_update(); break; + + case view_state::VIEW: + if (ImGui::Button(localize("form.back"))) { current_view_state = view_state::LIST; - } - break; - case view_state::EDIT: - if (draw_contact_form(&active_contact)) - { - administration_update_contact(active_contact); - current_view_state = view_state::LIST; - } + } + + draw_contact_form(&active_contact, true); break; - case view_state::VIEW: draw_contact_form(&active_contact, true, true); break; } } \ No newline at end of file diff --git a/src/ui/ui_invoices.cpp b/src/ui/ui_invoices.cpp index 26f60c4..fe4f5a8 100644 --- a/src/ui/ui_invoices.cpp +++ b/src/ui/ui_invoices.cpp @@ -9,6 +9,8 @@ static view_state current_view_state = view_state::LIST; static invoice active_invoice; +extern void draw_contact_form(contact* buffer, bool viewing_only = false); + void ui_setup_invoices() { current_view_state = view_state::LIST; @@ -33,10 +35,25 @@ bool draw_invoice_form(invoice* buffer, bool back_button_enabled = true, bool vi //ImGui::InputText(localize("contact.form.identifier"), buffer->id, IM_ARRAYSIZE(buffer->id)); // 2. Sequential number - ImGui::SetNextItemWidth(widthAvailable*0.5f); - ImGui::InputTextWithHint("Invoice number", "Invoice number", buffer->sequential_number, IM_ARRAYSIZE(buffer->sequential_number)); - ImGui::SameLine();ui_helper_draw_required_tag(); - if (!viewing_only) ImGui::EndDisabled(); + ImGui::Text("Invoice number: %s", buffer->sequential_number); + + // 3. Supplier (you) + ImGui::Text("Supplier: %s", buffer->supplier.name); + + ImGui::Separator(); + + ImGui::Text("Customer information"); + draw_contact_form(&buffer->customer); + strops_copy(buffer->customer_id, buffer->customer.id, sizeof(buffer->customer_id)); + + ImGui::Separator(); + + //ImGui::SetNextItemWidth(widthAvailable*0.5f); + //ImGui::InputTextWithHint("Invoice number", "Invoice number", buffer->sequential_number, IM_ARRAYSIZE(buffer->sequential_number)); + //ImGui::SameLine();ui_helper_draw_required_tag(); + + + //if (!viewing_only) ImGui::EndDisabled(); return false; } @@ -48,6 +65,8 @@ void draw_invoices_list() { current_view_state = view_state::CREATE; active_invoice = administration_create_empty_invoice(); + active_invoice.supplier = administration_get_company_info(); + strops_copy(active_invoice.supplier_id, active_invoice.supplier.id, sizeof(active_invoice.supplier_id)); } } diff --git a/src/ui/ui_settings.cpp b/src/ui/ui_settings.cpp index c2c34b9..c222dbb 100644 --- a/src/ui/ui_settings.cpp +++ b/src/ui/ui_settings.cpp @@ -7,7 +7,7 @@ #include "administration.hpp" #include "locales.hpp" -extern bool draw_contact_form(contact* buffer, bool back_button_enabled = true, bool viewing_only = false); +extern void draw_contact_form(contact* buffer, bool viewing_only = false); static contact company_info; @@ -312,11 +312,17 @@ void ui_draw_settings() { if (ImGui::BeginTabItem(localize("settings.table.company"))) { - bool save = draw_contact_form(&company_info, false); + draw_contact_form(&company_info); - if (save) { + // Save button. + bool can_save = administration_is_contact_valid(company_info); + if (!can_save) ImGui::BeginDisabled(); + ImGui::Spacing(); + if (ImGui::Button(localize("form.save"))) { administration_set_company_info(company_info); } + if (!can_save) ImGui::EndDisabled(); + ImGui::EndTabItem(); } if (ImGui::BeginTabItem(localize("settings.table.vatrates"))) -- cgit v1.2.3-70-g09d2