diff options
Diffstat (limited to 'src/ui')
| -rw-r--r-- | src/ui/helpers.cpp | 100 | ||||
| -rw-r--r-- | src/ui/imgui_extensions.cpp | 95 | ||||
| -rw-r--r-- | src/ui/ui_contacts.cpp | 25 | ||||
| -rw-r--r-- | src/ui/ui_expenses.cpp | 36 | ||||
| -rw-r--r-- | src/ui/ui_invoices.cpp | 34 | ||||
| -rw-r--r-- | src/ui/ui_main.cpp | 1 | ||||
| -rw-r--r-- | src/ui/ui_projects.cpp | 23 | ||||
| -rw-r--r-- | src/ui/ui_settings.cpp | 85 |
8 files changed, 204 insertions, 195 deletions
diff --git a/src/ui/helpers.cpp b/src/ui/helpers.cpp deleted file mode 100644 index 476e780..0000000 --- a/src/ui/helpers.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* -* Copyright (c) 2025 Aldrik Ramaekers <aldrik.ramaekers@gmail.com> -* -* Permission to use, copy, modify, and/or distribute this software for any -* purpose with or without fee is hereby granted, provided that the above -* copyright notice and this permission notice appear in all copies. -* -* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include "ui.hpp" -#include "imgui.h" -#include "strops.hpp" - -#define STATUS_DURATION 4.0f -#define STATUS_FLASH_INTERVAL 0.1f -#define STATUS_MAX_FLASHES 2 - -namespace ui { - - ImFont* fontBold; - ImFont* fontBig; - - static status current_status; - - void ui::draw_status() - { - float region_width = ImGui::GetContentRegionAvail().x; - float text_width = ImGui::CalcTextSize(current_status.text).x; - - if (current_status.loading) - { - ImGui::SetCursorPosX(ImGui::GetCursorPosX() + region_width - text_width - 20.0f); - ImGui::Text("%c", "|/-\\"[(int)(ImGui::GetTime() / 0.1f) & 3]); - return; - } - - if (current_status.visible) - { - ImGui::SetCursorPosX(ImGui::GetCursorPosX() + region_width - text_width); - ImGui::PushStyleColor(ImGuiCol_Text, current_status.color); - ImGui::TextUnformatted(current_status.text); - ImGui::PopStyleColor(); - } - - ImGuiIO& io = ImGui::GetIO(); - current_status.time += io.DeltaTime; - - if (current_status.time >= STATUS_FLASH_INTERVAL && current_status.flash_count < STATUS_MAX_FLASHES) - { - current_status.visible = !current_status.visible; - if (current_status.visible) current_status.flash_count++; - current_status.time = 0.0f; - } - - if (current_status.time >= STATUS_DURATION) - { - current_status.text[0] = 0; - } - } - - static void set_status_ex(const char* txt, int color) - { - current_status.flash_count = 0; - current_status.visible = true; - current_status.time = 0.0f; - current_status.color = color; - current_status.loading = false; - strops::copy(current_status.text, txt, STATUS_TEXT_LEN); - } - - void ui::set_status_error(const char* txt) - { - set_status_ex(txt, config::colors::COLOR_ERROR); - } - - void ui::set_status(const char* txt) - { - set_status_ex(txt, config::colors::COLOR_DEFAULT); - } - - void ui::set_status_loading(bool loading) - { - current_status.visible = true; - current_status.time = 0.0f; - current_status.loading = loading; - } - - status ui::get_status() - { - return current_status; - } - -}
\ No newline at end of file diff --git a/src/ui/imgui_extensions.cpp b/src/ui/imgui_extensions.cpp index d1abc58..359fc17 100644 --- a/src/ui/imgui_extensions.cpp +++ b/src/ui/imgui_extensions.cpp @@ -4,11 +4,104 @@ #include "config.hpp" #include "locales.hpp" #include "countries.hpp" -#include "administration.hpp" #include "tinyfiledialogs.h" +#include "administration.hpp" +#include "administration_writer.hpp" + +namespace ui { + ImFont* fontBold; + ImFont* fontBig; +} namespace ImGui { + bool CheckboxX(const char* label, bool* v, bool disabled, bool show_loading_indicator_while_disabled) + { + bool result = false; + if (disabled) ImGui::BeginDisabled(); + if (!disabled || !show_loading_indicator_while_disabled) + { + result = ImGui::Checkbox(label, v); + } + else + { + bool tmp = false; + result = ImGui::Checkbox(label, &tmp); + if (result) *v = !(*v); + + float radius = 10.0f; + ImVec2 p_min = ImGui::GetItemRectMin(); + ImVec2 p_max = ImGui::GetItemRectMax(); + ImVec2 center = ImVec2((p_min.x + p_max.x) * 0.5f - radius, (p_min.y + p_max.y) * 0.5f - radius); + + ImGui::SetCursorScreenPos(ImVec2(center.x, center.y)); + + const ImVec4 col = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + const ImVec4 bg = ImGui::GetStyleColorVec4(ImGuiCol_Button); + ImGui::LoadingIndicatorCircle("##loadingAnim", radius, bg, col, 6, 4.0f); + } + + if (disabled) ImGui::EndDisabled(); + return result; + } + + static ImVec2 CalcButtonSize(const char* label) + { + ImGuiStyle& style = ImGui::GetStyle(); + ImVec2 text_size = ImGui::CalcTextSize(label, nullptr, true); + ImVec2 button_size = ImVec2( + text_size.x + style.FramePadding.x * 2.0f, + text_size.y + style.FramePadding.y * 2.0f + ); + return button_size; + } + + bool Button(const char* label, bool block_while_writing_to_disk, bool show_loading_indicator_while_blocked) + { + if (block_while_writing_to_disk) + { + if (administration_writer::is_writing()) + { + if (show_loading_indicator_while_blocked) { + ImGui::PushID(label); + ImGui::BeginDisabled(); + bool result = ImGui::Button("", CalcButtonSize(label)); + + float radius = 10.0f; + ImVec2 p_min = ImGui::GetItemRectMin(); + ImVec2 p_max = ImGui::GetItemRectMax(); + ImVec2 center = ImVec2((p_min.x + p_max.x) * 0.5f - radius, (p_min.y + p_max.y) * 0.5f - radius); + + ImGui::SetCursorScreenPos(ImVec2(center.x, center.y)); + + const ImVec4 col = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + const ImVec4 bg = ImGui::GetStyleColorVec4(ImGuiCol_Button); + ImGui::LoadingIndicatorCircle("##loadingAnim", radius, bg, col, 6, 4.0f); + + ImGui::EndDisabled(); + ImGui::PopID(); + + return result; + } + else + { + ImGui::BeginDisabled(); + bool result = ImGui::Button(label); + ImGui::EndDisabled(); + return result; + } + } + else + { + return ImGui::Button(label); + } + } + else + { + return ImGui::Button(label); + } + } + void InputTextWithError(const char* text, char* buffer, size_t buf_size, bool has_error) { if (has_error) { diff --git a/src/ui/ui_contacts.cpp b/src/ui/ui_contacts.cpp index 0f1716f..5d92f8a 100644 --- a/src/ui/ui_contacts.cpp +++ b/src/ui/ui_contacts.cpp @@ -154,10 +154,15 @@ static void draw_contact_list() } } +static void _reset_to_default_view() +{ + current_view_state = ui::view_state::LIST_ALL; +} + static void draw_contacts_create() { - if (ImGui::Button(locale::get("form.back"))) { - current_view_state = ui::view_state::LIST_ALL; + if (ImGui::Button(locale::get("form.back"), true, false)) { + _reset_to_default_view(); } ImGui::ContactForm(&active_contact, false, false); @@ -167,17 +172,17 @@ static void draw_contacts_create() if (!can_save) ImGui::BeginDisabled(); // Save button ImGui::Spacing(); - if (ImGui::Button(locale::get("form.save"))) { + if (ImGui::Button(locale::get("form.save"), true)) { + administration_writer::set_write_completed_event_callback(_reset_to_default_view); administration::contact_add(active_contact); - current_view_state = ui::view_state::LIST_ALL; } if (!can_save) ImGui::EndDisabled(); } static void draw_contacts_update() { - if (ImGui::Button(locale::get("form.back"))) { - current_view_state = ui::view_state::LIST_ALL; + if (ImGui::Button(locale::get("form.back"), true, false)) { + _reset_to_default_view(); } ImGui::ContactForm(&active_contact, false, false); @@ -187,9 +192,9 @@ static void draw_contacts_update() if (!can_save) ImGui::BeginDisabled(); // Save button ImGui::Spacing(); - if (ImGui::Button(locale::get("form.save"))) { + if (ImGui::Button(locale::get("form.save"), true)) { + administration_writer::set_write_completed_event_callback(_reset_to_default_view); administration::contact_update(active_contact); - current_view_state = ui::view_state::LIST_ALL; } if (!can_save) ImGui::EndDisabled(); } @@ -203,8 +208,8 @@ void ui::draw_contacts() case ui::view_state::EDIT_EXISTING: draw_contacts_update(); break; case ui::view_state::VIEW_EXISTING: - if (ImGui::Button(locale::get("form.back"))) { - current_view_state = ui::view_state::LIST_ALL; + if (ImGui::Button(locale::get("form.back"), true, false)) { + _reset_to_default_view(); } ImGui::ContactForm(&active_contact, true, false); diff --git a/src/ui/ui_expenses.cpp b/src/ui/ui_expenses.cpp index d1121b1..8635273 100644 --- a/src/ui/ui_expenses.cpp +++ b/src/ui/ui_expenses.cpp @@ -294,11 +294,17 @@ static void draw_expenses_list() } } +static void _reset_to_default_view() +{ + current_view_state = ui::view_state::LIST_ALL; + ui::destroy_expenses(); + ui::setup_expenses(); +} static void draw_expense_update() { - if (ImGui::Button(locale::get("form.back"))) { - current_view_state = ui::view_state::LIST_ALL; + if (ImGui::Button(locale::get("form.back"), true, false)) { + _reset_to_default_view(); } draw_expense_form(&active_invoice); @@ -307,13 +313,9 @@ static void draw_expense_update() if (!can_save) ImGui::BeginDisabled(); ImGui::Spacing(); - if (ImGui::Button(locale::get("form.save"))) { + if (ImGui::Button(locale::get("form.save"), true)) { + administration_writer::set_write_completed_event_callback(_reset_to_default_view); administration::invoice_update(&active_invoice); - - current_view_state = ui::view_state::LIST_ALL; - - ui::destroy_expenses(); - ui::setup_expenses(); } if (!can_save) ImGui::EndDisabled(); @@ -321,8 +323,8 @@ static void draw_expense_update() static void draw_expense_create() { - if (ImGui::Button(locale::get("form.back"))) { - current_view_state = ui::view_state::LIST_ALL; + if (ImGui::Button(locale::get("form.back"), true, false)) { + _reset_to_default_view(); } draw_expense_form(&active_invoice); @@ -331,13 +333,9 @@ static void draw_expense_create() if (!can_save) ImGui::BeginDisabled(); ImGui::Spacing(); - if (ImGui::Button(locale::get("form.save"))) { + if (ImGui::Button(locale::get("form.save"), true)) { + administration_writer::set_write_completed_event_callback(_reset_to_default_view); administration::invoice_add(&active_invoice); - - current_view_state = ui::view_state::LIST_ALL; - - ui::destroy_expenses(); - ui::setup_expenses(); } if (!can_save) ImGui::EndDisabled(); @@ -345,8 +343,8 @@ static void draw_expense_create() static void draw_expense_view() { - if (ImGui::Button(locale::get("form.back"))) { - current_view_state = ui::view_state::LIST_ALL; + if (ImGui::Button(locale::get("form.back"), true, false)) { + _reset_to_default_view(); } draw_expense_form(&active_invoice, true); @@ -365,7 +363,7 @@ static void draw_import_request() } else { if (ImGui::Button(locale::get("form.back"))) { - current_view_state = ui::view_state::LIST_ALL; + _reset_to_default_view(); active_import_request = 0; return; } diff --git a/src/ui/ui_invoices.cpp b/src/ui/ui_invoices.cpp index 8741965..3987b72 100644 --- a/src/ui/ui_invoices.cpp +++ b/src/ui/ui_invoices.cpp @@ -388,11 +388,17 @@ static void draw_invoices_list() } } +static void _reset_to_default_view() +{ + current_view_state = ui::view_state::LIST_ALL; + ui::destroy_invoices(); + ui::setup_invoices(); +} static void draw_invoice_update() { - if (ImGui::Button(locale::get("form.back"))) { - current_view_state = ui::view_state::LIST_ALL; + if (ImGui::Button(locale::get("form.back"), true, false)) { + _reset_to_default_view(); } draw_invoice_form(&active_invoice); @@ -401,13 +407,9 @@ static void draw_invoice_update() if (!can_save) ImGui::BeginDisabled(); ImGui::Spacing(); - if (ImGui::Button(locale::get("form.save"))) { + if (ImGui::Button(locale::get("form.save"), true)) { + administration_writer::set_write_completed_event_callback(_reset_to_default_view); administration::invoice_update(&active_invoice); - - current_view_state = ui::view_state::LIST_ALL; - - ui::destroy_invoices(); - ui::setup_invoices(); } if (!can_save) ImGui::EndDisabled(); @@ -415,8 +417,8 @@ static void draw_invoice_update() static void draw_invoice_create() { - if (ImGui::Button(locale::get("form.back"))) { - current_view_state = ui::view_state::LIST_ALL; + if (ImGui::Button(locale::get("form.back"), true, false)) { + _reset_to_default_view(); } draw_invoice_form(&active_invoice); @@ -425,13 +427,9 @@ static void draw_invoice_create() if (!can_save) ImGui::BeginDisabled(); ImGui::Spacing(); - if (ImGui::Button(locale::get("form.save"))) { + if (ImGui::Button(locale::get("form.save"), true)) { + administration_writer::set_write_completed_event_callback(_reset_to_default_view); administration::invoice_add(&active_invoice); - - current_view_state = ui::view_state::LIST_ALL; - - ui::destroy_invoices(); - ui::setup_invoices(); } if (!can_save) ImGui::EndDisabled(); @@ -439,8 +437,8 @@ static void draw_invoice_create() static void draw_invoice_view() { - if (ImGui::Button(locale::get("form.back"))) { - current_view_state = ui::view_state::LIST_ALL; + if (ImGui::Button(locale::get("form.back"), true, false)) { + _reset_to_default_view(); } draw_invoice_form(&active_invoice, true); diff --git a/src/ui/ui_main.cpp b/src/ui/ui_main.cpp index 48b1364..d4b9c58 100644 --- a/src/ui/ui_main.cpp +++ b/src/ui/ui_main.cpp @@ -160,7 +160,6 @@ void ui::draw_main() } ImGui::SameLine(); - ui::draw_status(); ImGui::End(); ImGui::PopStyleVar(); diff --git a/src/ui/ui_projects.cpp b/src/ui/ui_projects.cpp index 82597b4..94f2be6 100644 --- a/src/ui/ui_projects.cpp +++ b/src/ui/ui_projects.cpp @@ -26,22 +26,24 @@ static project selected_for_cancellation; static project active_project; -void ui::setup_projects() +static void _reset_to_default_view() { current_view_state = ui::view_state::LIST_ALL; active_project = administration::project_create_empty(); } +void ui::setup_projects() +{ + _reset_to_default_view(); +} + static void draw_project_form() { float widthAvailable = ImGui::GetContentRegionAvail().x; bool viewing_only = (current_view_state == ui::view_state::VIEW_EXISTING); - static const char* selected_country = NULL; - if (ImGui::Button(locale::get("form.back"))) { - current_view_state = ui::view_state::LIST_ALL; - active_project = administration::project_create_empty(); - selected_country = 0; + if (ImGui::Button(locale::get("form.back"), true, false)) { + _reset_to_default_view(); return; } ImGui::Spacing(); @@ -63,7 +65,10 @@ static void draw_project_form() if (!can_save) ImGui::BeginDisabled(); // Save button ImGui::Spacing(); - if (ImGui::Button(locale::get("form.save"))) { + if (ImGui::Button(locale::get("form.save"), true)) { + + administration_writer::set_write_completed_event_callback(_reset_to_default_view); + if (current_view_state == ui::view_state::CREATE) { administration::project_add(active_project); } @@ -71,10 +76,6 @@ static void draw_project_form() else if (current_view_state == ui::view_state::EDIT_EXISTING) { administration::project_update(active_project); } - - current_view_state = ui::view_state::LIST_ALL; - selected_country = 0; - active_project = administration::project_create_empty(); } if (!can_save) ImGui::EndDisabled(); } diff --git a/src/ui/ui_settings.cpp b/src/ui/ui_settings.cpp index e15bde0..1c8f92b 100644 --- a/src/ui/ui_settings.cpp +++ b/src/ui/ui_settings.cpp @@ -58,6 +58,13 @@ void ui::setup_settings() } } +static bool is_writing_vat_rate = false; +static u32 writing_vat_rate_index = 0; +static void _vat_rate_write_complete_callback() +{ + is_writing_vat_rate = false; +} + static void draw_vat_rates() { tax_rate_type type_iter = tax_rate_type::TAX_RATE_OUTGOING_INVOICE; @@ -84,7 +91,10 @@ static void draw_vat_rates() ImGui::TableSetColumnIndex(0); bool toggle = administration::tax_rate_is_enabled(c) == A_ERR_SUCCESS; - if (ImGui::Checkbox("##toggle", &toggle)) { + if (ImGui::CheckboxX("##toggle", &toggle, is_writing_vat_rate, i == writing_vat_rate_index)) { + writing_vat_rate_index = i; + is_writing_vat_rate = true; + administration_writer::set_write_completed_event_callback(_vat_rate_write_complete_callback); if (toggle) administration::tax_rate_enable(c); else administration::tax_rate_disable(c); } @@ -113,12 +123,26 @@ static void draw_vat_rates() if (type_iter < TAX_RATE_TYPE_END) goto go_again; } -static void draw_cost_centers() +static bool is_adding_cost_center = false; +static bool is_editing_cost_center = false; +static cost_center new_cost_center; + +static void _cost_center_update_callback() { - static bool is_adding_item = false; - static cost_center new_cost_center; + is_editing_cost_center = false; + is_adding_cost_center = false; + + administration::cost_center_update(new_cost_center); + + memops::zero(&new_cost_center, sizeof(new_cost_center)); + + ui::destroy_settings(); + ui::setup_settings(); + select_company_tab = 0; +} - static bool is_editing_item = false; +static void draw_cost_centers() +{ static u32 editing_item_index = 0; if (ImGui::BeginTable("TableCostCenters", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) { @@ -137,7 +161,7 @@ static void draw_cost_centers() // Column 2: When editing, show inputs for new description. Else show stored description and check for modify request. ImGui::TableSetColumnIndex(1); - if (is_editing_item && editing_item_index == i) + if (is_editing_cost_center && editing_item_index == i) { bool is_desc_valid = !(administration::cost_center_is_valid(new_cost_center) & A_ERR_MISSING_DESCRIPTION); if (!is_desc_valid) ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(105, 43, 43, 255)); @@ -146,23 +170,16 @@ static void draw_cost_centers() if (!is_desc_valid) ImGui::BeginDisabled(); ImGui::SameLine(); - if (ImGui::Button(locale::get("form.save"))) { - is_editing_item = false; - is_adding_item = false; - + if (ImGui::Button(locale::get("form.save"), true)) { + administration_writer::set_write_completed_event_callback(_cost_center_update_callback); administration::cost_center_update(new_cost_center); - - memops::zero(&new_cost_center, sizeof(new_cost_center)); - - ui::destroy_settings(); - ui::setup_settings(); } if (!is_desc_valid) ImGui::EndDisabled(); ImGui::SameLine(); - if (ImGui::Button(locale::get("form.cancel"))) { - is_editing_item = false; - is_adding_item = false; + if (ImGui::Button(locale::get("form.cancel"), true, false)) { + is_editing_cost_center = false; + is_adding_cost_center = false; memops::zero(&new_cost_center, sizeof(new_cost_center)); } } @@ -172,8 +189,8 @@ static void draw_cost_centers() if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { - is_editing_item = true; - is_adding_item = false; + is_editing_cost_center = true; + is_adding_cost_center = false; editing_item_index = i; new_cost_center = c; } @@ -182,7 +199,7 @@ static void draw_cost_centers() // When adding a new item. Show inputs for code and description, check validity, and handle save/cancel. // Form for new entry is displayed at bottom of list. - if (is_adding_item) + if (is_adding_cost_center) { ImGui::TableNextRow(); @@ -201,21 +218,17 @@ static void draw_cost_centers() if (!can_save) ImGui::BeginDisabled(); ImGui::SameLine(); - if (ImGui::Button(locale::get("form.create"))) + if (ImGui::Button(locale::get("form.create"), true)) { - is_adding_item = false; - is_editing_item = false; + administration_writer::set_write_completed_event_callback(_cost_center_update_callback); administration::cost_center_add(new_cost_center); - - ui::destroy_settings(); - ui::setup_settings(); } if (!can_save) ImGui::EndDisabled(); ImGui::SameLine(); - if (ImGui::Button(locale::get("form.cancel"))) { - is_adding_item = false; - is_editing_item = false; + if (ImGui::Button(locale::get("form.cancel"), true)) { + is_adding_cost_center = false; + is_editing_cost_center = false; memops::zero(&new_cost_center, sizeof(new_cost_center)); } } @@ -224,11 +237,11 @@ static void draw_cost_centers() } // If not adding a new item already, show create button at bottom of list. - if (!is_adding_item && ImGui::Button(locale::get("form.create"))) + if (!is_adding_cost_center && ImGui::Button(locale::get("form.create"))) { new_cost_center = administration::cost_center_create_empty(); - is_adding_item = true; - is_editing_item = false; + is_adding_cost_center = true; + is_editing_cost_center = false; } } @@ -317,7 +330,8 @@ static void draw_services() ImGui::EndDisabled(); } - if (ImGui::Button(locale::get("form.save"))) { + if (ImGui::Button(locale::get("form.save"), true)) { + administration_writer::set_write_completed_event_callback(0); administration::set_ai_service(new_service); } } @@ -336,7 +350,8 @@ void ui::draw_settings() bool can_save = administration::contact_is_valid(company_info) == A_ERR_SUCCESS; if (!can_save) ImGui::BeginDisabled(); ImGui::Spacing(); - if (ImGui::Button(locale::get("form.save"))) { + if (ImGui::Button(locale::get("form.save"), true)) { + administration_writer::set_write_completed_event_callback(0); administration::company_info_set(company_info); } if (!can_save) ImGui::EndDisabled(); |
