Files
rrr.v2/src/rrr/layers/gui/browser/navigation/navigation.cpp
2023-04-02 12:01:04 +03:00

358 lines
9.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "navigation.hpp"
#include <algorithm>
#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<ImVec4>(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<types::event_type>(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<std::string>(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<std::filesystem::path>(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<try_engine::system_event::key_pressed_event&>(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<try_engine::system_event::key_pressed_event&>(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;
}
}
}
}
}