From 681327e663953ae38aa28fdf9649edc712045291 Mon Sep 17 00:00:00 2001 From: chatlanin Date: Mon, 13 Mar 2023 13:29:59 +0300 Subject: [PATCH] add base dialogs --- src/rrr/content/content.cpp | 4 +- src/rrr/content/content.hpp | 2 +- .../layers/gui/browser/history/history.cpp | 19 +- .../layers/gui/browser/history/history.hpp | 6 +- .../gui/browser/navigation/navigation.cpp | 86 +++++-- .../gui/browser/navigation/navigation.hpp | 6 +- .../layers/gui/browser/preview/preview.cpp | 21 +- .../layers/gui/browser/preview/preview.hpp | 6 +- src/rrr/layers/gui/dialogs/dialogs.cpp | 238 ++++++++++++++++++ src/rrr/layers/gui/dialogs/dialogs.hpp | 55 ++++ src/rrr/meson.build | 2 + src/rrr/rrr.hpp | 4 +- src/rrr/utils/types.hpp | 10 +- 13 files changed, 431 insertions(+), 28 deletions(-) create mode 100644 src/rrr/layers/gui/dialogs/dialogs.cpp create mode 100644 src/rrr/layers/gui/dialogs/dialogs.hpp diff --git a/src/rrr/content/content.cpp b/src/rrr/content/content.cpp index 32d2024..dcf2b1f 100644 --- a/src/rrr/content/content.cpp +++ b/src/rrr/content/content.cpp @@ -36,7 +36,7 @@ namespace rrr } } - int content::get_cursor_position(TYPE_WIN type) const + int content::get_cursor_position(TYPE_WIN type) { switch (type) { @@ -47,7 +47,7 @@ namespace rrr return cursor_position; break; case TYPE_WIN::PREVIEW: - return 0; + return get_preview_cursor_position(); break; default: return 0; diff --git a/src/rrr/content/content.hpp b/src/rrr/content/content.hpp index f865e5e..087fe61 100644 --- a/src/rrr/content/content.hpp +++ b/src/rrr/content/content.hpp @@ -28,7 +28,7 @@ namespace rrr void set_pwd(std::filesystem::path); void fill(); files* get(TYPE_WIN); - int get_cursor_position(TYPE_WIN) const; + int get_cursor_position(TYPE_WIN); void increment_position(int); void navigation_right(); void navigation_left(); diff --git a/src/rrr/layers/gui/browser/history/history.cpp b/src/rrr/layers/gui/browser/history/history.cpp index 41de1de..c63f1d8 100644 --- a/src/rrr/layers/gui/browser/history/history.cpp +++ b/src/rrr/layers/gui/browser/history/history.cpp @@ -1,5 +1,7 @@ #include "history.hpp" +#include "utils/types.hpp" + namespace rrr::layers::gui { void history::on_attach() @@ -17,11 +19,13 @@ namespace rrr::layers::gui void history::gui_render() { + if (!show) return; + ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y)); ImGui::SetNextWindowSize(ImVec2(width, height)); ImGuiStyle& st = ImGui::GetStyle(); - st.Colors[ImGuiCol_WindowBg] = ImVec4(0.13f, 0.14f, 0.18f, 1.00f); + st.Colors[ImGuiCol_WindowBg] = func::get_IMGUI_color(33.f, 36.f, 46.f); BEGIN_IMGUI_WIN(); @@ -77,8 +81,19 @@ namespace rrr::layers::gui width = try_engine::application::get()->get_window()->width() / 3.f; } - void history::on_event(std::any e, std::any value) + void history::on_event(std::any event_type, std::any value) { + auto et = std::any_cast(event_type); + + switch (et) + { + case types::event_type::NAVIGATION_LEFT: + case types::event_type::NAVIGATION_RIGHT: + cursor_position = cnt->get_cursor_position(TYPE_WIN::HISTORY); + break; + default: + break; + } } void history::on_update(time t) diff --git a/src/rrr/layers/gui/browser/history/history.hpp b/src/rrr/layers/gui/browser/history/history.hpp index 5d3b2b6..9e0f073 100644 --- a/src/rrr/layers/gui/browser/history/history.hpp +++ b/src/rrr/layers/gui/browser/history/history.hpp @@ -2,6 +2,7 @@ #include "try_engine/try_engine.hpp" #include "rrr/content/content.hpp" +#include "rrr/utils/func.hpp" namespace rrr::layers::gui { @@ -41,8 +42,9 @@ namespace rrr::layers::gui ImGuiIO& io = ImGui::GetIO(); ImFontAtlas* atlas = io.Fonts; ImFont* font; - const ImVec4 dir_color = ImVec4(0.36f, 0.5f, 0.74f, 1.0f); - const ImVec4 file_color = ImVec4(0.9f, 0.9f, 0.9f, 1.0f); + const ImVec4 dir_color = func::get_IMGUI_color(91.f, 128.f, 191.f); + const ImVec4 file_color = func::get_IMGUI_color(186.f, 186.f, 186.f); + const ImVec4 link_color = func::get_IMGUI_color(51.f, 95.f, 165.f); private: void resize(); diff --git a/src/rrr/layers/gui/browser/navigation/navigation.cpp b/src/rrr/layers/gui/browser/navigation/navigation.cpp index dcd2866..7363743 100644 --- a/src/rrr/layers/gui/browser/navigation/navigation.cpp +++ b/src/rrr/layers/gui/browser/navigation/navigation.cpp @@ -1,5 +1,6 @@ #include "navigation.hpp" +#include "try_engine/event/event_classificator.hpp" #include "utils/types.hpp" #include "logger/logger.hpp" @@ -20,11 +21,13 @@ namespace rrr::layers::gui void navigation::gui_render() { + if (!show) return; + ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y)); ImGui::SetNextWindowSize(ImVec2(width, height)); ImGuiStyle& st = ImGui::GetStyle(); - st.Colors[ImGuiCol_WindowBg] = ImVec4(0.13f, 0.14f, 0.18f, 1.00f); + st.Colors[ImGuiCol_WindowBg] = func::get_IMGUI_color(33.f, 36.f, 46.f); BEGIN_IMGUI_WIN(); @@ -46,6 +49,7 @@ namespace rrr::layers::gui ImGui::PushFont(font); ImGui::TextUnformatted(">"); ImGui::SameLine(22.f); + current_file = item; } else { @@ -63,14 +67,6 @@ namespace rrr::layers::gui END_IMGUI_WIN(); } - // HERE начинаем тут - // нужно сделать навигацию влево и вправо - // в прошлыq раз тут сделали стилизацию по типу файлов (скрыты ссылки и тп) - // и затем все это нужно распространить на другие части (history, preview) - // когда делаем навигацию влево и вправо то не меняется центральный контент - // почему то у нас отличаются данные контента в файле content/navigation от - // content/history и content/preview - // там map а у всех других файл. зачем это нужно??? void navigation::push_style(file& f) { switch (f.type) @@ -116,11 +112,42 @@ namespace rrr::layers::gui resize(); if (e.get_name() == try_engine::system_event::classificator::KEY_PRESSED()) - set_selected(e); + pressed(e); + + if (e.get_name() == try_engine::system_event::classificator::KEY_RELEASED()) + released(e); } - void navigation::on_event(std::any e, std::any value) + void navigation::on_event(std::any event_type, std::any value) { + auto et = std::any_cast(event_type); + + switch (et) + { + case types::event_type::FREEZE_BROWSER_ACTION: + freeze = true; + break; + case types::event_type::UNFREEZE_BROWSER_ACTION: + freeze = false; + break; + case types::event_type::DELETE_CURRENT_FILE: + freeze = false; + hack::log()("DELETE FILE"); + // HERE + // реализовать удаление после создания + break; + case types::event_type::CREATE_FILE: + { + freeze = false; + auto filename = std::any_cast(value); + // HERE начинам тут + // реализовать через контент создание файла или директории + // а затем его уделаение см. HERE то что выше + } + break; + default: + break; + } } void navigation::on_update(time t) @@ -135,30 +162,61 @@ namespace rrr::layers::gui pos_x = try_engine::application::get()->get_window()->width() / 3.f + padding_between_window / 2.f; } - void navigation::set_selected(system_event& e) + void navigation::pressed(system_event& e) { + if (freeze) return; + auto key = static_cast(e); + if (key.get_keycode() == try_engine::key::LEFTSHIFT || key.get_keycode() == try_engine::key::RIGHTSHIFT) + shift = true; + if (key.get_keycode() == try_engine::key::J) { cnt->increment_position(STEP_DOWN); - cursor_position = cnt->get_cursor_position(TYPE_WIN::NAVIGATION); + em->execute(types::event_type::NAVIGATION_DOWN, nullptr); } if (key.get_keycode() == try_engine::key::K) { cnt->increment_position(STEP_UP); - cursor_position = cnt->get_cursor_position(TYPE_WIN::NAVIGATION); + em->execute(types::event_type::NAVIGATION_UP, nullptr); } if (key.get_keycode() == try_engine::key::H) { cnt->navigation_left(); + data = cnt->get(TYPE_WIN::NAVIGATION); + em->execute(types::event_type::NAVIGATION_LEFT, nullptr); } if (key.get_keycode() == try_engine::key::L) { cnt->navigation_right(); + data = cnt->get(TYPE_WIN::NAVIGATION); + em->execute(types::event_type::NAVIGATION_RIGHT, nullptr); } + + if (shift && key.get_keycode() == try_engine::key::D) + { + em->execute(types::event_type::SHOW_DELETE_ONE_FILE_DIALOG, current_file); + freeze = true; + } + + if (shift && key.get_keycode() == try_engine::key::C) + { + em->execute(types::event_type::SHOW_CREATE_FILE_DIALOG, nullptr); + freeze = true; + } + + cursor_position = cnt->get_cursor_position(TYPE_WIN::NAVIGATION); + } + + void navigation::released(system_event& e) + { + auto key = static_cast(e); + + if (key.get_keycode() == try_engine::key::LEFTSHIFT || key.get_keycode() == try_engine::key::RIGHTSHIFT) + shift = false; } } diff --git a/src/rrr/layers/gui/browser/navigation/navigation.hpp b/src/rrr/layers/gui/browser/navigation/navigation.hpp index 8b0eae5..8674888 100644 --- a/src/rrr/layers/gui/browser/navigation/navigation.hpp +++ b/src/rrr/layers/gui/browser/navigation/navigation.hpp @@ -30,6 +30,7 @@ namespace rrr::layers::gui FLAGS_STRUCT_DEFINED(); bool show = true; + bool freeze = false; // замораживает все действия, например при открытии диалогового окна event_manager* em; content* cnt; files* data; @@ -43,6 +44,8 @@ namespace rrr::layers::gui int cursor_position = 0; const int STEP_UP = -1; const int STEP_DOWN = 1; + file current_file; + bool shift = false; private: ImGuiIO& io = ImGui::GetIO(); @@ -54,7 +57,8 @@ namespace rrr::layers::gui private: void resize(); - void set_selected(system_event& e); + void pressed(system_event& e); + void released(system_event& e); void check_selected(); void push_style(file&); void pop_style(file&); diff --git a/src/rrr/layers/gui/browser/preview/preview.cpp b/src/rrr/layers/gui/browser/preview/preview.cpp index 39428bd..5b3e8e5 100644 --- a/src/rrr/layers/gui/browser/preview/preview.cpp +++ b/src/rrr/layers/gui/browser/preview/preview.cpp @@ -1,5 +1,7 @@ #include "preview.hpp" +#include "utils/types.hpp" + namespace rrr::layers::gui { void preview::on_attach() @@ -17,11 +19,13 @@ namespace rrr::layers::gui void preview::gui_render() { + if (!show) return; + ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y)); ImGui::SetNextWindowSize(ImVec2(width, height)); ImGuiStyle& st = ImGui::GetStyle(); - st.Colors[ImGuiCol_WindowBg] = ImVec4(0.13f, 0.14f, 0.18f, 1.00f); + st.Colors[ImGuiCol_WindowBg] = func::get_IMGUI_color(33.f, 36.f, 46.f); BEGIN_IMGUI_WIN(); @@ -83,8 +87,21 @@ namespace rrr::layers::gui pos_x = try_engine::application::get()->get_window()->width() - try_engine::application::get()->get_window()->width() / 3.f; } - void preview::on_event(std::any e, std::any value) + void preview::on_event(std::any event_type, std::any value) { + auto et = std::any_cast(event_type); + + switch (et) + { + case types::event_type::NAVIGATION_UP: + case types::event_type::NAVIGATION_DOWN: + case types::event_type::NAVIGATION_LEFT: + case types::event_type::NAVIGATION_RIGHT: + cursor_position = cnt->get_cursor_position(TYPE_WIN::PREVIEW); + break; + default: + break; + } } void preview::on_update(time t) diff --git a/src/rrr/layers/gui/browser/preview/preview.hpp b/src/rrr/layers/gui/browser/preview/preview.hpp index 4adc24b..4c27d54 100644 --- a/src/rrr/layers/gui/browser/preview/preview.hpp +++ b/src/rrr/layers/gui/browser/preview/preview.hpp @@ -2,6 +2,7 @@ #include "try_engine/try_engine.hpp" #include "rrr/content/content.hpp" +#include "rrr/utils/func.hpp" namespace rrr::layers::gui { @@ -41,8 +42,9 @@ namespace rrr::layers::gui ImGuiIO& io = ImGui::GetIO(); ImFontAtlas* atlas = io.Fonts; ImFont* font; - const ImVec4 dir_color = ImVec4(0.36f, 0.5f, 0.74f, 1.0f); - const ImVec4 file_color = ImVec4(0.9f, 0.9f, 0.9f, 1.0f); + const ImVec4 dir_color = func::get_IMGUI_color(91.f, 128.f, 191.f); + const ImVec4 file_color = func::get_IMGUI_color(186.f, 186.f, 186.f); + const ImVec4 link_color = func::get_IMGUI_color(51.f, 95.f, 165.f); private: void resize(); diff --git a/src/rrr/layers/gui/dialogs/dialogs.cpp b/src/rrr/layers/gui/dialogs/dialogs.cpp new file mode 100644 index 0000000..963c4fc --- /dev/null +++ b/src/rrr/layers/gui/dialogs/dialogs.cpp @@ -0,0 +1,238 @@ +#include "dialogs.hpp" + +#include "misc/cpp/imgui_stdlib.h" +#include "imgui.h" +#include "utils/types.hpp" + +namespace rrr::layers::gui +{ + void dialogs::on_attach() + { + BASE_WINDOW_FLAGS(); + } + + void dialogs::on_detach() + { + + } + + void dialogs::gui_render() + { + if (!show) return; + + ImVec2 center = ImGui::GetMainViewport()->GetCenter(); + ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.8f)); + ImGui::SetNextWindowSize(ImVec2(width, height)); + + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1.0f); + + BEGIN_IMGUI_WIN(); + + if (delete_dialog) + draw_delete_dialog(); + + if (create_dialog) + draw_create_dialog(); + + END_IMGUI_WIN(); + + ImGui::PopStyleVar(); + } + + void dialogs::on_event(system_event& e) + { + if (e.get_name() == try_engine::system_event::classificator::WINDOW_RESIZE()) + resize(); + + if (e.get_name() == try_engine::system_event::classificator::KEY_PRESSED()) + pressed(e); + + if (e.get_name() == try_engine::system_event::classificator::KEY_RELEASED()) + released(e); + } + + void dialogs::resize() + { + height = try_engine::application::get()->get_window()->height() / 5.f; + width = try_engine::application::get()->get_window()->width() / 3.2f; + } + + void dialogs::on_event(std::any event_type, std::any value) + { + auto et = std::any_cast(event_type); + + switch (et) + { + case types::event_type::SHOW_DELETE_ONE_FILE_DIALOG: + { + current_file = std::any_cast(value); + show = true; + delete_dialog = true; + } + break; + case types::event_type::SHOW_CREATE_FILE_DIALOG: + { + show = true; + create_dialog = true; + } + break; + default: + break; + } + } + + void dialogs::on_update(time t) + { + + } + + void dialogs::pressed(system_event& e) + { + auto key = static_cast(e); + + if (key.get_keycode() == try_engine::key::LEFTSHIFT || key.get_keycode() == try_engine::key::RIGHTSHIFT) + shift = true; + + if (key.get_keycode() == try_engine::key::N) + { + if (delete_dialog) + { + delete_dialog = false; + show = false; + em->execute(types::event_type::UNFREEZE_BROWSER_ACTION, nullptr); + } + } + + if (key.get_keycode() == try_engine::key::ESCAPE) + cancel(); + + if (shift && key.get_keycode() == try_engine::key::Y) + { + if (delete_dialog) + { + show = false; + delete_dialog = false; + em->execute(types::event_type::DELETE_CURRENT_FILE, nullptr); + } + } + + if (key.get_keycode() == try_engine::key::ENTER) + { + if (create_dialog) + create_file(); + } + } + + void dialogs::released(system_event& e) + { + auto key = static_cast(e); + + if (key.get_keycode() == try_engine::key::LEFTSHIFT || key.get_keycode() == try_engine::key::RIGHTSHIFT) + shift = false; + } + + void dialogs::draw_delete_dialog() + { + font = try_engine::style::fonts::get_font(font_type::MEDIUM, 18); + ImGui::PushFont(font); + std::string label = current_file.type == file_type::DIR ? "Даннaя директория будет удалена!" : "Данный файл будет удален!"; + + // манипуляции с тем чтобы название стояло посередлине + // см. и ниже тоже + auto pos = ImGui::GetCursorPos(); + pos.x = width / (current_file.type == file_type::DIR ? 5.4f : 4.8f); + pos.y += 12.f; + ImGui::SetCursorPos(pos); + ImGui::TextUnformatted(label.data()); + ImGui::Separator(); + + // манипуляции с тем чтобы название стояло посередлине + // тут и зависимость от длинны строки и размера шрифта, но не того + // что выше при определении шрифта, а того который нужен для отрисовки + // на самом экране + pos = ImGui::GetCursorPos(); + auto p = current_file.path.filename().string().size() * 5.f; + pos.x += width / 2.f - p; + pos.y += 12.f; + ImGui::SetCursorPos(pos); + + ImGui::TextUnformatted(current_file.path.filename().string().data()); + + pos = ImGui::GetCursorPos(); + pos.y = height - height / 4.f; + pos.x = width / 9.f; + ImGui::SetCursorPos(pos); + auto button_size = ImVec2(width / 3.f, height / 5.f); + if (ImGui::Button("Удалить (Y)", button_size)) + { + show = false; + delete_dialog = false; + em->execute(types::event_type::DELETE_CURRENT_FILE, nullptr); + } + + ImGui::SameLine(width / 1.8f); + + if (ImGui::Button("Отмена (n / Esc)", button_size)) + cancel(); + + ImGui::PopFont(); + } + + void dialogs::draw_create_dialog() + { + font = try_engine::style::fonts::get_font(font_type::MEDIUM, 18); + ImGui::PushFont(font); + std::string label = "Создание файла/директории!"; + + // манипуляции с тем чтобы название стояло посередлине + // см. и ниже тоже + auto pos = ImGui::GetCursorPos(); + pos.x = width / (current_file.type == file_type::DIR ? 5.4f : 4.8f); + pos.y += 12.f; + ImGui::SetCursorPos(pos); + ImGui::TextUnformatted(label.data()); + ImGui::Separator(); + + ImGui::PushItemWidth(-FLT_MIN - 10.f); + pos = ImGui::GetCursorPos(); + pos.x = 10.f; + ImGui::SetCursorPos(pos); + // для фокусировки + if (!ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0)) ImGui::SetKeyboardFocusHere(0); + if (ImGui::InputText("##new_file_title", &title)) {} + + ImGui::PopItemWidth(); + + pos = ImGui::GetCursorPos(); + pos.y = height - height / 4.f; + pos.x = width / 9.f; + ImGui::SetCursorPos(pos); + auto button_size = ImVec2(width / 3.f, height / 5.f); + if (ImGui::Button("Создать (Enter)", button_size)) + create_file(); + + ImGui::SameLine(width / 1.8f); + + if (ImGui::Button("Отмена (Esc)", button_size)) + cancel(); + + ImGui::PopFont(); + } + + void dialogs::create_file() + { + show = false; + create_dialog = false; + em->execute(types::event_type::CREATE_FILE, title); + title.clear(); + } + + void dialogs::cancel() + { + delete_dialog = false; + create_dialog = false; + title.clear(); + show = false; + em->execute(types::event_type::UNFREEZE_BROWSER_ACTION, nullptr); + } +} diff --git a/src/rrr/layers/gui/dialogs/dialogs.hpp b/src/rrr/layers/gui/dialogs/dialogs.hpp new file mode 100644 index 0000000..36292a3 --- /dev/null +++ b/src/rrr/layers/gui/dialogs/dialogs.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include "try_engine/try_engine.hpp" +#include "rrr/content/content.hpp" + +namespace rrr::layers::gui +{ + class dialogs : public try_engine::layer + { + using font_type = try_engine::style::fonts::font_type; + + BASE_TYPE_DEFINE(); + + public: + CONSTRUCT_IMPL(dialogs); + + public: + BASE_OVERIDE_IMPL(); + + public: + SET_EVENT_MANAGER_IMPL(); + + void set_content(content* c) { }; + + private: + FLAGS_STRUCT_DEFINED(); + + bool show = false; + event_manager* em; + + float width = 0.f; + float height = 0.f; + bool delete_dialog = false; + bool create_dialog = false; + file current_file; + bool shift = false; + std::string title; + + private: + ImGuiIO& io = ImGui::GetIO(); + ImFontAtlas* atlas = io.Fonts; + ImFont* font; + + private: + void resize(); + void cancel(); + void draw_delete_dialog(); + void draw_create_dialog(); + void create_file(); + void pressed(system_event& e); + void released(system_event& e); + }; +} + + diff --git a/src/rrr/meson.build b/src/rrr/meson.build index 5adbdd1..8dc8e57 100644 --- a/src/rrr/meson.build +++ b/src/rrr/meson.build @@ -10,6 +10,7 @@ headers = [ 'layers/gui/browser/history/history.hpp', 'layers/gui/browser/navigation/navigation.hpp', 'layers/gui/browser/preview/preview.hpp', + 'layers/gui/dialogs/dialogs.hpp', ] sources = [ 'content/content.cpp', @@ -21,6 +22,7 @@ sources = [ 'layers/gui/browser/history/history.cpp', 'layers/gui/browser/navigation/navigation.cpp', 'layers/gui/browser/preview/preview.cpp', + 'layers/gui/dialogs/dialogs.cpp', ] lib = library( diff --git a/src/rrr/rrr.hpp b/src/rrr/rrr.hpp index d7839d2..d5766b3 100644 --- a/src/rrr/rrr.hpp +++ b/src/rrr/rrr.hpp @@ -5,6 +5,7 @@ #include "layers/gui/browser/navigation/navigation.hpp" #include "layers/gui/browser/history/history.hpp" #include "layers/gui/browser/preview/preview.hpp" +#include "layers/gui/dialogs/dialogs.hpp" namespace rrr { @@ -46,7 +47,8 @@ namespace try_engine e.push_layer( new rrr::layers::gui::history{}, new rrr::layers::gui::navigation{}, - new rrr::layers::gui::preview{} + new rrr::layers::gui::preview{}, + new rrr::layers::gui::dialogs{} ); e.attach_layers(); diff --git a/src/rrr/utils/types.hpp b/src/rrr/utils/types.hpp index 60d9f81..ac3e244 100644 --- a/src/rrr/utils/types.hpp +++ b/src/rrr/utils/types.hpp @@ -6,7 +6,15 @@ namespace rrr::types { NONE = 0, NAVIGATION_UP, - NAVIGATION_DOWN + NAVIGATION_DOWN, + NAVIGATION_LEFT, + NAVIGATION_RIGHT, + SHOW_DELETE_ONE_FILE_DIALOG, + FREEZE_BROWSER_ACTION, + UNFREEZE_BROWSER_ACTION, + DELETE_CURRENT_FILE, + SHOW_CREATE_FILE_DIALOG, + CREATE_FILE }; }