#include "navigation.hpp" #include #include "try_engine/event/event_classificator.hpp" #include "utils/types.hpp" #include "logger/logger.hpp" namespace rrr::layers::gui { void navigation::on_attach() { BASE_WINDOW_FLAGS(); data = cnt->get(TYPE_WIN::NAVIGATION); selected_file = cnt->get_selected_file(TYPE_WIN::NAVIGATION); } void navigation::on_detach() { } 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] = func::get_IMGUI_color(33.f, 36.f, 46.f); BEGIN_IMGUI_WIN(); auto pos = ImGui::GetCursorPos(); pos.x += 17.f; pos.y += 9.f; // небольшой отступ сверху ImGui::SetCursorPosY(pos.y); auto begin = data->begin() + delta; auto end = data->end(); for (files::iterator it = begin; it != end; ++it) { auto item = *it; ImGui::PushID(item.id); push_style(item); if (selected_file.path == item.path) { if (selected_file.is_hidden) TR_PUSH_FONT(SEMI_BOLD_ITALIC, 18); else TR_PUSH_FONT(SEMI_BOLD, 18); ImGui::TextUnformatted(">"); ImGui::SameLine(22.f); current_position = it - data->begin(); } else { ImGui::SetCursorPosX(pos.x); if (item.is_hidden) TR_PUSH_FONT(MEDIUM_ITALIC, 18); else TR_PUSH_FONT(MEDIUM, 18); } ImGui::TextUnformatted(get_file_content(item).data()); pop_style(item); } END_IMGUI_WIN(); } void navigation::push_style(file& f) { switch (f.type) { case file_type::DIR: ImGui::PushStyleColor(ImGuiCol_Text, dir_color); break; default: // когда просто файл ImGui::PushStyleColor(ImGuiCol_Text, file_color); break; } if (f.is_link) ImGui::PushStyleColor(ImGuiCol_Text, link_color); } void navigation::pop_style(file& f) { TR_POP_FONT(); ImGui::PopStyleColor(); ImGui::PopID(); if (f.is_link) ImGui::PopStyleColor(); } std::string navigation::get_file_content(file& f) { auto file_content = f.path.filename().string(); if (f.is_link) file_content += " ->"; return file_content; } void navigation::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 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; cnt->delete_file(selected_file); selected_file = cnt->get_selected_file(TYPE_WIN::NAVIGATION); } break; case types::event_type::CREATE_FILE: { freeze = false; auto filename = std::any_cast(value); cnt->create_file(filename); selected_file = cnt->get_selected_file(TYPE_WIN::NAVIGATION); } break; case types::event_type::RENAME_FILE: { freeze = false; auto filename = std::any_cast(value); cnt->rename_file(selected_file.path, filename); selected_file = cnt->get_selected_file(TYPE_WIN::NAVIGATION); } break; default: break; } } void navigation::on_update(time t) { } void navigation::resize() { height = try_engine::application::get()->get_window()->height(); width = try_engine::application::get()->get_window()->width() / 3.f - padding_between_window; pos_x = try_engine::application::get()->get_window()->width() / 3.f + padding_between_window / 2.f; } 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 (shift) { // удаление if (shift && key.get_keycode() == try_engine::key::D) { em->execute(types::event_type::SHOW_DELETE_ONE_FILE_DIALOG, selected_file); freeze = true; } // создание файла/директории if (shift && key.get_keycode() == try_engine::key::A) { em->execute(types::event_type::SHOW_CREATE_FILE_DIALOG, nullptr); freeze = true; } // создание файла/директории if (shift && key.get_keycode() == try_engine::key::R) { em->execute(types::event_type::SHOW_RENAME_FILE_DIALOG, selected_file); freeze = true; } // перемещение в конец списка if (shift && key.get_keycode() == try_engine::key::G) { cnt->increment_position(data->size()); selected_file = cnt->get_selected_file(TYPE_WIN::NAVIGATION); em->execute(types::event_type::NAVIGATION_DOWN, nullptr); set_delta(MOVE_DIRECTION::DOWN); set_scroll(); } return; } if (key.get_keycode() == try_engine::key::J) { cnt->increment_position(STEP_DOWN); selected_file = cnt->get_selected_file(TYPE_WIN::NAVIGATION); em->execute(types::event_type::NAVIGATION_DOWN, nullptr); set_delta(MOVE_DIRECTION::DOWN); } if (key.get_keycode() == try_engine::key::K) { cnt->increment_position(STEP_UP); selected_file = cnt->get_selected_file(TYPE_WIN::NAVIGATION); em->execute(types::event_type::NAVIGATION_UP, nullptr); set_delta(MOVE_DIRECTION::UP); } if (key.get_keycode() == try_engine::key::H) { cnt->navigation_left(); data = cnt->get(TYPE_WIN::NAVIGATION); selected_file = cnt->get_selected_file(TYPE_WIN::NAVIGATION); em->execute(types::event_type::NAVIGATION_LEFT, nullptr); set_scroll(); } if (key.get_keycode() == try_engine::key::L) { cnt->navigation_right(); data = cnt->get(TYPE_WIN::NAVIGATION); selected_file = cnt->get_selected_file(TYPE_WIN::NAVIGATION); em->execute(types::event_type::NAVIGATION_RIGHT, nullptr); set_scroll(); } // двойное нажатие перемещение в начало списка if (key.get_keycode() == try_engine::key::G) { ++g_coutn; if (g_coutn != 2) return; cnt->increment_position(-data->size()); selected_file = cnt->get_selected_file(TYPE_WIN::NAVIGATION); em->execute(types::event_type::NAVIGATION_UP, nullptr); set_delta(MOVE_DIRECTION::UP); set_scroll(); g_coutn = 0; } } 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; } void navigation::set_delta(MOVE_DIRECTION mvd) { auto row_size = 26.3f; // высота вы пикселях одной строки списка int h = height / row_size; // высота в строках списка всего столбца экрана auto big_content = height < data->size() * row_size; int size = data->size(); if (big_content) { if (mvd == MOVE_DIRECTION::DOWN) { ++cursor_position; // на самом деле получаем его выше, но делаем такой трюк // т.к. происходит задержка на один ход нажатия клавиши ++current_position; if (current_position >= size) current_position = size - 1; bool is_end = size - current_position <= 10; if (cursor_position >= h - 10 && !is_end) { ++delta; cursor_position = h - 10; } if (cursor_position >= h) cursor_position = h; } if (mvd == MOVE_DIRECTION::UP) { --cursor_position; --current_position; if (cursor_position <= 10) --delta; if (cursor_position < 10 && current_position > 12) cursor_position = 10; if (delta < 0) { delta = 0; cursor_position = 0; } } } } void navigation::set_scroll() { delta = 0; current_position = 0; cursor_position = 0; auto row_size = 26.3f; // высота вы пикселях одной строки списка auto big_content = height < data->size() * row_size; if (big_content) { // как бы прокручиваем с начала списка for (const auto& f : *data) { if (f.path != selected_file.path) { set_delta(MOVE_DIRECTION::DOWN); } else { set_delta(MOVE_DIRECTION::DOWN); break; } } } } }