/* * Copyright (c) 2025 Aldrik Ramaekers * * 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 "administration.hpp" #include "locales.hpp" #include "tinyfiledialogs.h" #include "administration_writer.hpp" #include "administration_reader.hpp" static ui::main_state ui_state = ui::main_state::UI_END; void (*drawcalls[ui::main_state::UI_END])(void) = { ui::draw_invoices, ui::draw_expenses, ui::draw_contacts, ui::draw_earnings, ui::draw_tax_report, ui::draw_projects, ui::draw_settings, ui::draw_log, }; void (*setupcalls[ui::main_state::UI_END])(void) = { ui::setup_invoices, ui::setup_expenses, ui::setup_contacts, ui::setup_earnings, ui::setup_tax_report, ui::setup_projects, ui::setup_settings, 0, }; void (*destroycalls[ui::main_state::UI_END])(void) = { ui::destroy_invoices, ui::destroy_expenses, 0, ui::destroy_earnings, ui::destroy_tax_report, 0, ui::destroy_settings, 0, }; void ui::set_state(ui::main_state state) { if (ui_state != ui::main_state::UI_END && destroycalls[ui_state]) destroycalls[ui_state](); ui_state = state; if (setupcalls[ui_state]) setupcalls[ui_state](); } void ui::draw_main() { if (ui_state == ui::main_state::UI_END) ui::set_state(ui::main_state::UI_INVOICES); // @locale::get if (ImGui::BeginMainMenuBar()) { if (ImGui::BeginMenu("File")) { if (ImGui::MenuItem("New")) { administration_reader::open_new(); } if (ImGui::MenuItem("Open")) { administration_reader::open_existing(NULL); } ImGui::EndMenu(); } if (ImGui::BeginMenu("Help")) { if (ImGui::MenuItem("Event Log")) { ui::set_state(ui::main_state::UI_LOG); } ImGui::EndMenu(); } ImGui::EndMainMenuBar(); } ImGuiIO& io = ImGui::GetIO(); float menuBarHeight = ImGui::GetFrameHeight(); float statusBarHeight = 26.0f; float sidePanelWidth = 120.0f; ImGui::SetNextWindowPos(ImVec2(0, menuBarHeight)); ImGui::SetNextWindowSize(ImVec2(sidePanelWidth, io.DisplaySize.y - menuBarHeight - statusBarHeight)); // Side panel ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); ImGui::Begin("SidePanel", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse); { // Navigation buttons with custom styling ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); // Transparent background ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); // Reduce spacing between buttons ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 0.0f)); float buttonWidth = sidePanelWidth; if (ImGui::Button(locale::get("nav.invoices"), ImVec2(buttonWidth, 24))) ui::set_state(ui::main_state::UI_INVOICES); if (ImGui::Button(locale::get("nav.expenses"), ImVec2(buttonWidth, 24))) ui::set_state(ui::main_state::UI_EXPENSES); if (ImGui::Button(locale::get("nav.contacts"), ImVec2(buttonWidth, 24))) ui::set_state(ui::main_state::UI_CONTACTS); static bool reports_opened = true; ImGui::Button(locale::get("nav.reports"), ImVec2(buttonWidth, 24)); if (reports_opened) { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(20.0f, 0.0f)); if (ImGui::Button(locale::get("nav.reports.results"), ImVec2(buttonWidth, 24))) ui::set_state(ui::main_state::UI_REPORT_RESULTS); if (ImGui::Button(locale::get("nav.reports.tax"), ImVec2(buttonWidth, 24))) ui::set_state(ui::main_state::UI_REPORT_TAX); ImGui::PopStyleVar(); } if (ImGui::Button(locale::get("nav.projects"), ImVec2(buttonWidth, 24))) ui::set_state(ui::main_state::UI_PROJECTS); if (ImGui::Button(locale::get("nav.settings"), ImVec2(buttonWidth, 24))) ui::set_state(ui::main_state::UI_SETTINGS); ImGui::PopStyleColor(1); ImGui::PopStyleVar(3); } ImGui::End(); ImGui::PopStyleVar(); ImGui::SetNextWindowPos(ImVec2(sidePanelWidth, menuBarHeight)); ImGui::SetNextWindowSize(ImVec2(io.DisplaySize.x - sidePanelWidth, io.DisplaySize.y - menuBarHeight - statusBarHeight)); // Main content ImGui::Begin("AccountingMainWindow", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse); if (drawcalls[ui_state]) drawcalls[ui_state](); ImGui::End(); // Status bar. ImGui::SetNextWindowPos(ImVec2(0, io.DisplaySize.y - statusBarHeight)); ImGui::SetNextWindowSize(ImVec2(io.DisplaySize.x, statusBarHeight)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 3)); ImGui::Begin("StatusBar", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoCollapse); char* path = administration::get_file_path(); if (path == NULL) { ImGui::Text("%s: %s", locale::get("ui.workingOn"), locale::get("ui.unsavedProject")); } else { ImGui::Text("%s: %s", locale::get("ui.workingOn"), path); } ImGui::SameLine(); ui::draw_status(); ImGui::End(); ImGui::PopStyleVar(); }