From d82d6a63a3a9bf21c79e8e9e64342545c017e0f6 Mon Sep 17 00:00:00 2001 From: chatlanin Date: Sun, 2 Apr 2023 10:22:21 +0300 Subject: [PATCH] add base navigation left and right --- src/rrr/content/content.cpp | 7 +- .../layers/gui/browser/history/history.cpp | 83 ++++++++++++++++++- .../layers/gui/browser/history/history.hpp | 8 ++ .../gui/browser/navigation/navigation.cpp | 37 ++++++++- .../gui/browser/navigation/navigation.hpp | 9 +- .../layers/gui/browser/preview/preview.cpp | 82 +++++++++++++++++- .../layers/gui/browser/preview/preview.hpp | 8 ++ 7 files changed, 221 insertions(+), 13 deletions(-) diff --git a/src/rrr/content/content.cpp b/src/rrr/content/content.cpp index c212214..e5d8177 100644 --- a/src/rrr/content/content.cpp +++ b/src/rrr/content/content.cpp @@ -159,11 +159,8 @@ namespace rrr void content::navigation_left() { // буфер заполняется только когда отсюда уходишь - // типа я тут был - if (std::filesystem::is_empty(PWD)) - // buffer::state[PWD] = nav.store[PWD.parent_path()].at(cursor_position); - buffer::state[PWD] = nav.data.at(navigation_cursor_position); - else + // типа я тут был и если тут что-то есть + if (!std::filesystem::is_empty(PWD)) buffer::state[PWD] = nav.data.at(navigation_cursor_position); auto from = PWD; diff --git a/src/rrr/layers/gui/browser/history/history.cpp b/src/rrr/layers/gui/browser/history/history.cpp index e4ca46f..58b5bf6 100644 --- a/src/rrr/layers/gui/browser/history/history.cpp +++ b/src/rrr/layers/gui/browser/history/history.cpp @@ -34,8 +34,12 @@ namespace rrr::layers::gui pos.y += 9.f; // небольшой отступ сверху ImGui::SetCursorPosY(pos.y); - for (auto& item : *data) + auto begin = data->begin() + delta; + auto end = data->end(); + + for (files::iterator it = begin; it != end; ++it) { + auto item = *it; ImGui::PushID(item.id); if (item.type == file_type::DIR) @@ -48,6 +52,7 @@ namespace rrr::layers::gui TR_PUSH_FONT(SEMI_BOLD, 18); ImGui::TextUnformatted(">"); ImGui::SameLine(22.f); + current_position = it - data->begin(); } else { @@ -86,6 +91,7 @@ namespace rrr::layers::gui case types::event_type::NAVIGATION_LEFT: case types::event_type::NAVIGATION_RIGHT: selected_file = cnt->get_selected_file(TYPE_WIN::HISTORY); + set_scroll(); break; default: break; @@ -96,5 +102,80 @@ namespace rrr::layers::gui { } + + void history::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 history::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; + } + } + } + } } diff --git a/src/rrr/layers/gui/browser/history/history.hpp b/src/rrr/layers/gui/browser/history/history.hpp index 7edb046..858848e 100644 --- a/src/rrr/layers/gui/browser/history/history.hpp +++ b/src/rrr/layers/gui/browser/history/history.hpp @@ -36,6 +36,12 @@ namespace rrr::layers::gui float pos_x = 0.f; float pos_y = 0.f; + // все что нужно для установки курсора при длинных списках + int current_position = 0; // позиция курсора относительно списка + int cursor_position = 0; // позиция курсора относительно высоты экрана + int delta = 0; + enum class MOVE_DIRECTION { UP, DOWN }; + private: 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); @@ -43,6 +49,8 @@ namespace rrr::layers::gui private: void resize(); + void set_delta(MOVE_DIRECTION); + void set_scroll(); }; } diff --git a/src/rrr/layers/gui/browser/navigation/navigation.cpp b/src/rrr/layers/gui/browser/navigation/navigation.cpp index 5c0c57d..a53a292 100644 --- a/src/rrr/layers/gui/browser/navigation/navigation.cpp +++ b/src/rrr/layers/gui/browser/navigation/navigation.cpp @@ -1,5 +1,7 @@ #include "navigation.hpp" +#include + #include "try_engine/event/event_classificator.hpp" #include "utils/types.hpp" @@ -179,6 +181,7 @@ namespace rrr::layers::gui 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); } @@ -186,6 +189,7 @@ namespace rrr::layers::gui 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); } @@ -194,14 +198,18 @@ namespace rrr::layers::gui { 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(); } // удаление @@ -217,8 +225,6 @@ namespace rrr::layers::gui em->execute(types::event_type::SHOW_CREATE_FILE_DIALOG, nullptr); freeze = true; } - - selected_file = cnt->get_selected_file(TYPE_WIN::NAVIGATION); } void navigation::released(system_event& e) @@ -235,7 +241,6 @@ namespace rrr::layers::gui int h = height / row_size; // высота в строках списка всего столбца экрана auto big_content = height < data->size() * row_size; - static auto cursor_position = 0; // позиция курсора относительно высоты экрана int size = data->size(); if (big_content) @@ -278,4 +283,30 @@ namespace rrr::layers::gui } } } + + 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; + } + } + } + } } diff --git a/src/rrr/layers/gui/browser/navigation/navigation.hpp b/src/rrr/layers/gui/browser/navigation/navigation.hpp index e669861..0e94149 100644 --- a/src/rrr/layers/gui/browser/navigation/navigation.hpp +++ b/src/rrr/layers/gui/browser/navigation/navigation.hpp @@ -43,16 +43,18 @@ namespace rrr::layers::gui const int STEP_DOWN = 1; file selected_file; bool shift = false; - int current_position = 0; + + // все что нужно для установки курсора при длинных списках + int current_position = 0; // позиция курсора относительно списка + int cursor_position = 0; // позиция курсора относительно высоты экрана int delta = 0; + enum class MOVE_DIRECTION { UP, DOWN }; private: 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); - enum class MOVE_DIRECTION { UP, DOWN }; - private: void resize(); void pressed(system_event& e); @@ -62,6 +64,7 @@ namespace rrr::layers::gui void pop_style(file&); std::string get_file_content(file&); void set_delta(MOVE_DIRECTION); + void set_scroll(); }; } diff --git a/src/rrr/layers/gui/browser/preview/preview.cpp b/src/rrr/layers/gui/browser/preview/preview.cpp index 4f4596a..8dc9b93 100644 --- a/src/rrr/layers/gui/browser/preview/preview.cpp +++ b/src/rrr/layers/gui/browser/preview/preview.cpp @@ -34,8 +34,12 @@ namespace rrr::layers::gui pos.y += 9.f; // небольшой отступ сверху ImGui::SetCursorPosY(pos.y); - for (auto& item : *data) + auto begin = data->begin() + delta; + auto end = data->end(); + + for (files::iterator it = begin; it != end; ++it) { + auto item = *it; ImGui::PushID(item.id); if (item.type == file_type::DIR) @@ -94,6 +98,7 @@ namespace rrr::layers::gui case types::event_type::NAVIGATION_LEFT: case types::event_type::NAVIGATION_RIGHT: selected_file = cnt->get_selected_file(TYPE_WIN::PREVIEW); + set_scroll(); break; default: break; @@ -104,5 +109,80 @@ namespace rrr::layers::gui { } + + void preview::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 preview::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; + } + } + } + } } diff --git a/src/rrr/layers/gui/browser/preview/preview.hpp b/src/rrr/layers/gui/browser/preview/preview.hpp index 401b368..c15a9f8 100644 --- a/src/rrr/layers/gui/browser/preview/preview.hpp +++ b/src/rrr/layers/gui/browser/preview/preview.hpp @@ -36,6 +36,12 @@ namespace rrr::layers::gui float pos_x = 0.f; float pos_y = 0.f; + // все что нужно для установки курсора при длинных списках + int current_position = 0; // позиция курсора относительно списка + int cursor_position = 0; // позиция курсора относительно высоты экрана + int delta = 0; + enum class MOVE_DIRECTION { UP, DOWN }; + private: 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); @@ -44,6 +50,8 @@ namespace rrr::layers::gui private: void resize(); void update_content(); + void set_delta(MOVE_DIRECTION); + void set_scroll(); }; }