add style and base navigation

This commit is contained in:
chatlanin 2023-03-12 12:50:05 +03:00
parent 3d6f90f0d9
commit 44ed461df9
12 changed files with 408 additions and 51 deletions

View File

@ -11,7 +11,7 @@
// value - это то, что тебя там ждет. // value - это то, что тебя там ждет.
// т.е. буфер хранит наши прошщлые похождения // т.е. буфер хранит наши прошщлые похождения
// и это отображается в history // и это отображается в history
namespace rrr::database namespace rrr::buffer
{ {
struct content_hash struct content_hash
{ {
@ -29,6 +29,6 @@ namespace rrr::database
} }
}; };
inline std::unordered_map<std::filesystem::path, file, opt_path_hash> buffer; inline std::unordered_map<std::filesystem::path, file, opt_path_hash> state;
} }

View File

@ -1,5 +1,8 @@
#include "content.hpp" #include "content.hpp"
#include <oneapi/tbb/parallel_for.h>
#include "buffer/buffer.hpp"
namespace rrr namespace rrr
{ {
void content::set_pwd(std::filesystem::path p) void content::set_pwd(std::filesystem::path p)
@ -32,4 +35,120 @@ namespace rrr
break; break;
} }
} }
int content::get_cursor_position(TYPE_WIN type) const
{
switch (type)
{
case TYPE_WIN::HISTORY:
return get_history_cursor_position();
break;
case TYPE_WIN::NAVIGATION:
return cursor_position;
break;
case TYPE_WIN::PREVIEW:
return 0;
break;
default:
return 0;
break;
}
}
int content::get_history_cursor_position() const
{
int history_cursor_position = 0;
tbb::parallel_for(tbb::blocked_range<int>(0, his.data.size()), [&](tbb::blocked_range<int> r)
{
for (int i = r.begin(); i < r.end(); ++i)
if (his.data.at(i).path == PWD)
history_cursor_position = i;
});
return history_cursor_position;
}
int content::get_preview_cursor_position()
{
int preview_cursor_position = 0;
auto pwd = nav.store[PWD].at(cursor_position).path;
if (buffer::state.contains(pwd))
{
tbb::parallel_for(tbb::blocked_range<int>(0, prev.data.size()), [&](tbb::blocked_range<int> r)
{
for (int i = r.begin(); i < r.end(); ++i)
if (prev.data.at(i).path == buffer::state[pwd].path)
preview_cursor_position = i;
});
}
return preview_cursor_position;
}
void content::increment_position(int step)
{
cursor_position += step;
check_cursor_position();
prev.fill(nav.store[PWD].at(cursor_position).path);
}
void content::check_cursor_position()
{
if (cursor_position == (int)nav.store[PWD].size()) cursor_position = (int)nav.store[PWD].size() - 1;
if (cursor_position < 0) cursor_position = 0;
}
void content::navigation_right()
{
// ставим новый pwd и заполняем навигацию и историю
PWD = PWD / nav.store[PWD].at(cursor_position).path.filename();
nav.fill(PWD);
his.fill(PWD);
// смотрим есть ли в этом pwd какой-то файл в буфере
// проще говоря, были ли мы тут
// и если были, то устанавливаем курсор
if (buffer::state.contains(PWD))
{
auto f = buffer::state[PWD];
tbb::parallel_for(tbb::blocked_range<int>(0, nav.store[PWD].size()), [&](tbb::blocked_range<int> r)
{
for (int i = r.begin(); i < r.end(); ++i)
if (nav.store[PWD].at(i).path == f.path)
cursor_position = i;
});
}
else
{
cursor_position = 0;
}
// и исходя из позиции курсора заполняем окно предварительного просмотра
prev.fill(nav.store[PWD].at(cursor_position).path);
}
void content::navigation_left()
{
// буфер заполняется только когда отсюда уходишь
// типа я тут был
buffer::state[PWD] = nav.store[PWD].at(cursor_position);
auto from = PWD;
// ставим новый pwd и заполняем навигацию и историю
PWD = PWD.parent_path();
nav.fill(PWD);
his.fill(PWD);
prev.fill(from);
// тут всегда есть место откуда ты пришел
// т.е. нет возмолжности придти неоткуда
// соответственно находим это место
tbb::parallel_for(tbb::blocked_range<int>(0, nav.store[PWD].size()), [&](tbb::blocked_range<int> r)
{
for (int i = r.begin(); i < r.end(); ++i)
if (nav.store[PWD].at(i).path == from)
cursor_position = i;
});
}
} }

View File

@ -15,6 +15,9 @@ namespace rrr
using files = std::vector<file>; using files = std::vector<file>;
// Именно этот класс работает с данными
// вычисляет для каждых данных позиции курсора. какие нужно сейчас отрисовать
// и т.п. Отсюда забираются данные для вывода н экран
class content class content
{ {
public: public:
@ -25,6 +28,10 @@ namespace rrr
void set_pwd(std::filesystem::path); void set_pwd(std::filesystem::path);
void fill(); void fill();
files* get(TYPE_WIN); files* get(TYPE_WIN);
int get_cursor_position(TYPE_WIN) const;
void increment_position(int);
void navigation_right();
void navigation_left();
private: private:
content_type::navigation nav; content_type::navigation nav;
@ -38,5 +45,10 @@ namespace rrr
// чтобы не устанавливалась стрелка изначально // чтобы не устанавливалась стрелка изначально
// полезно при первом открытии окна prev // полезно при первом открытии окна prev
int cursor_position = 0; int cursor_position = 0;
private:
int get_history_cursor_position() const;
int get_preview_cursor_position();
void check_cursor_position();
}; };
} }

View File

@ -7,12 +7,12 @@
namespace rrr namespace rrr
{ {
// NONE - просто выводится текст. когда пупка пуста и нет контента вообще
// FILE - файл // FILE - файл
// DIR - дирректория // DIR - дирректория
// TEXT - просто выводится текст
enum class file_type enum class file_type
{ {
FILE, DIR, TEXT NONE, FILE, DIR
}; };
// класс-тип контента // класс-тип контента
@ -83,7 +83,7 @@ namespace rrr::file_utils
} }
catch(...) catch(...)
{ {
f.push_back({ path / "no permission", file_type::TEXT, false, false }); f.push_back({ path / "no permission", file_type::NONE, false, false });
} }
return f; return f;

View File

@ -5,6 +5,9 @@ namespace rrr::layers::gui
void history::on_attach() void history::on_attach()
{ {
BASE_WINDOW_FLAGS(); BASE_WINDOW_FLAGS();
data = cnt->get(TYPE_WIN::HISTORY);
cursor_position = cnt->get_cursor_position(TYPE_WIN::HISTORY);
} }
void history::on_detach() void history::on_detach()
@ -17,8 +20,47 @@ namespace rrr::layers::gui
ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y)); ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y));
ImGui::SetNextWindowSize(ImVec2(width, height)); ImGui::SetNextWindowSize(ImVec2(width, height));
ImGuiStyle& st = ImGui::GetStyle();
st.Colors[ImGuiCol_WindowBg] = ImVec4(0.13f, 0.14f, 0.18f, 1.00f);
BEGIN_IMGUI_WIN(); BEGIN_IMGUI_WIN();
auto pos = ImGui::GetCursorPos();
pos.x += 17.f;
pos.y += 9.f; // небольшой отступ сверху
ImGui::SetCursorPosY(pos.y);
int index = 0;
for (auto& item : *data)
{
ImGui::PushID(item.id);
if (item.type == file_type::DIR)
ImGui::PushStyleColor(ImGuiCol_Text, dir_color);
else
ImGui::PushStyleColor(ImGuiCol_Text, file_color);
if (cursor_position == index)
{
font = try_engine::style::fonts::get_font(font_type::SEMI_BOLD, 18);
ImGui::PushFont(font);
ImGui::TextUnformatted(">");
ImGui::SameLine(22.f);
}
else
{
ImGui::SetCursorPosX(pos.x);
font = try_engine::style::fonts::get_font(font_type::MEDIUM, 18);
ImGui::PushFont(font);
}
ImGui::TextUnformatted(item.path.filename().string().data());
++index;
ImGui::PopFont();
ImGui::PopStyleColor();
ImGui::PopID();
}
END_IMGUI_WIN(); END_IMGUI_WIN();
} }
@ -26,10 +68,13 @@ namespace rrr::layers::gui
void history::on_event(system_event& e) void history::on_event(system_event& e)
{ {
if (e.get_name() == try_engine::system_event::classificator::WINDOW_RESIZE()) if (e.get_name() == try_engine::system_event::classificator::WINDOW_RESIZE())
{ resize();
height = try_engine::application::get()->get_window()->height() - 40.f;
width = try_engine::application::get()->get_window()->width() / 3.f;
} }
void history::resize()
{
height = try_engine::application::get()->get_window()->height();
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 e, std::any value)

View File

@ -7,6 +7,8 @@ namespace rrr::layers::gui
{ {
class history : public try_engine::layer class history : public try_engine::layer
{ {
using font_type = try_engine::style::fonts::font_type;
BASE_TYPE_DEFINE(); BASE_TYPE_DEFINE();
public: public:
@ -27,11 +29,23 @@ namespace rrr::layers::gui
bool show = true; bool show = true;
event_manager* em; event_manager* em;
content* cnt; content* cnt;
files* data;
int cursor_position = 0;
float width = 0.f; float width = 0.f;
float height = 0.f; float height = 0.f;
float pos_x = 0.f; float pos_x = 0.f;
float pos_y = 0.f; float pos_y = 0.f;
private:
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);
private:
void resize();
}; };
} }

View File

@ -1,5 +1,7 @@
#include "navigation.hpp" #include "navigation.hpp"
#include "utils/types.hpp"
#include "logger/logger.hpp" #include "logger/logger.hpp"
namespace rrr::layers::gui namespace rrr::layers::gui
@ -9,7 +11,6 @@ namespace rrr::layers::gui
BASE_WINDOW_FLAGS(); BASE_WINDOW_FLAGS();
data = cnt->get(TYPE_WIN::NAVIGATION); data = cnt->get(TYPE_WIN::NAVIGATION);
font = try_engine::style::fonts::get_font(font_type::MEDIUM, 18);
} }
void navigation::on_detach() void navigation::on_detach()
@ -25,65 +26,97 @@ namespace rrr::layers::gui
ImGuiStyle& st = ImGui::GetStyle(); ImGuiStyle& st = ImGui::GetStyle();
st.Colors[ImGuiCol_WindowBg] = ImVec4(0.13f, 0.14f, 0.18f, 1.00f); st.Colors[ImGuiCol_WindowBg] = ImVec4(0.13f, 0.14f, 0.18f, 1.00f);
ImGui::PushFont(font);
BEGIN_IMGUI_WIN(); BEGIN_IMGUI_WIN();
auto pos = ImGui::GetCursorPos(); auto pos = ImGui::GetCursorPos();
pos.x += 17.f;
pos.y += 9.f; // небольшой отступ сверху
ImGui::SetCursorPosY(pos.y);
int index = 0; int index = 0;
for (auto& item : *data) for (auto& item : *data)
{ {
ImGui::PushID(item.id); ImGui::PushID(item.id);
if (item.type == file_type::DIR) push_style(item);
ImGui::PushStyleColor(ImGuiCol_Text, dir_color);
else
ImGui::PushStyleColor(ImGuiCol_Text, file_color);
if (selected == index) if (cursor_position == index)
{ {
font = try_engine::style::fonts::get_font(item.is_hidden ? font_type::SEMI_BOLD_ITALIC : font_type::SEMI_BOLD, 18);
ImGui::PushFont(font);
ImGui::TextUnformatted(">"); ImGui::TextUnformatted(">");
ImGui::SameLine(22.f); ImGui::SameLine(22.f);
} }
else else
{
ImGui::SetCursorPosX(pos.x); ImGui::SetCursorPosX(pos.x);
font = try_engine::style::fonts::get_font(item.is_hidden ? font_type::MEDIUM_ITALIC : font_type::MEDIUM, 18);
ImGui::TextUnformatted(item.path.filename().string().data()); ImGui::PushFont(font);
ImGui::PopStyleColor();
ImGui::PopID();
++index;
} }
ImGui::TextUnformatted(get_file_content(item).data());
++index;
ImGui::PopFont(); pop_style(item);
}
END_IMGUI_WIN(); END_IMGUI_WIN();
} }
void navigation::on_event(try_engine::system_event::event& e) // HERE начинаем тут
// нужно сделать навигацию влево и вправо
// в прошлыq раз тут сделали стилизацию по типу файлов (скрыты ссылки и тп)
// и затем все это нужно распространить на другие части (history, preview)
// когда делаем навигацию влево и вправо то не меняется центральный контент
// почему то у нас отличаются данные контента в файле content/navigation от
// content/history и content/preview
// там map<path, string> а у всех других файл. зачем это нужно???
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);
if (f.is_hidden)
font = try_engine::style::fonts::get_font(font_type::MEDIUM_ITALIC, 18);
}
void navigation::pop_style(file& f)
{
ImGui::PopFont();
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()) if (e.get_name() == try_engine::system_event::classificator::WINDOW_RESIZE())
{ resize();
height = try_engine::application::get()->get_window()->height() - 40.f;
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;
}
// HERE начинаем тут
// нужно реализовать обработку клавишь
// и выннести это в движок тоже
if (e.get_name() == try_engine::system_event::classificator::KEY_PRESSED()) if (e.get_name() == try_engine::system_event::classificator::KEY_PRESSED())
{ set_selected(e);
auto key = static_cast<try_engine::system_event::key_pressed_event&>(e);
hack::log()(key.get_keycode());
}
hack::log()(e.get_name());
} }
void navigation::on_event(std::any e, std::any value) void navigation::on_event(std::any e, std::any value)
@ -94,5 +127,38 @@ namespace rrr::layers::gui
{ {
} }
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::set_selected(system_event& e)
{
auto key = static_cast<try_engine::system_event::key_pressed_event&>(e);
if (key.get_keycode() == try_engine::key::J)
{
cnt->increment_position(STEP_DOWN);
cursor_position = cnt->get_cursor_position(TYPE_WIN::NAVIGATION);
}
if (key.get_keycode() == try_engine::key::K)
{
cnt->increment_position(STEP_UP);
cursor_position = cnt->get_cursor_position(TYPE_WIN::NAVIGATION);
}
if (key.get_keycode() == try_engine::key::H)
{
cnt->navigation_left();
}
if (key.get_keycode() == try_engine::key::L)
{
cnt->navigation_right();
}
}
}

View File

@ -2,9 +2,12 @@
#include "try_engine/try_engine.hpp" #include "try_engine/try_engine.hpp"
#include "rrr/content/content.hpp" #include "rrr/content/content.hpp"
#include "rrr/utils/func.hpp"
namespace rrr::layers::gui namespace rrr::layers::gui
{ {
// Все эти классы просто рисуют полученные у контента данные
// Они не вычисляют ни чего, все вычисления делает контент (cnt)
class navigation : public try_engine::layer class navigation : public try_engine::layer
{ {
using font_type = try_engine::style::fonts::font_type; using font_type = try_engine::style::fonts::font_type;
@ -37,14 +40,25 @@ namespace rrr::layers::gui
float pos_y = 0.f; float pos_y = 0.f;
float padding_between_window = 2.f; float padding_between_window = 2.f;
int selected = 0; int cursor_position = 0;
const int STEP_UP = -1;
const int STEP_DOWN = 1;
private: private:
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImFontAtlas* atlas = io.Fonts; ImFontAtlas* atlas = io.Fonts;
ImFont* font; ImFont* font;
const ImVec4 dir_color = ImVec4(0.36f, 0.5f, 0.74f, 1.0f); const ImVec4 dir_color = func::get_IMGUI_color<ImVec4>(91.f, 128.f, 191.f);
const ImVec4 file_color = ImVec4(0.9f, 0.9f, 0.9f, 1.0f); const ImVec4 file_color = func::get_IMGUI_color<ImVec4>(186.f, 186.f, 186.f);
const ImVec4 link_color = func::get_IMGUI_color<ImVec4>(51.f, 95.f, 165.f);
private:
void resize();
void set_selected(system_event& e);
void check_selected();
void push_style(file&);
void pop_style(file&);
std::string get_file_content(file&);
}; };
} }

View File

@ -5,6 +5,9 @@ namespace rrr::layers::gui
void preview::on_attach() void preview::on_attach()
{ {
BASE_WINDOW_FLAGS(); BASE_WINDOW_FLAGS();
data = cnt->get(TYPE_WIN::PREVIEW);
cursor_position = cnt->get_cursor_position(TYPE_WIN::PREVIEW);
} }
void preview::on_detach() void preview::on_detach()
@ -17,8 +20,47 @@ namespace rrr::layers::gui
ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y)); ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y));
ImGui::SetNextWindowSize(ImVec2(width, height)); ImGui::SetNextWindowSize(ImVec2(width, height));
ImGuiStyle& st = ImGui::GetStyle();
st.Colors[ImGuiCol_WindowBg] = ImVec4(0.13f, 0.14f, 0.18f, 1.00f);
BEGIN_IMGUI_WIN(); BEGIN_IMGUI_WIN();
auto pos = ImGui::GetCursorPos();
pos.x += 17.f;
pos.y += 9.f; // небольшой отступ сверху
ImGui::SetCursorPosY(pos.y);
int index = 0;
for (auto& item : *data)
{
ImGui::PushID(item.id);
if (item.type == file_type::DIR)
ImGui::PushStyleColor(ImGuiCol_Text, dir_color);
else
ImGui::PushStyleColor(ImGuiCol_Text, file_color);
if (cursor_position == index)
{
font = try_engine::style::fonts::get_font(font_type::SEMI_BOLD, 18);
ImGui::PushFont(font);
ImGui::TextUnformatted(">");
ImGui::SameLine(22.f);
}
else
{
ImGui::SetCursorPosX(pos.x);
font = try_engine::style::fonts::get_font(font_type::MEDIUM, 18);
ImGui::PushFont(font);
}
ImGui::TextUnformatted(item.path.filename().string().data());
++index;
ImGui::PopFont();
ImGui::PopStyleColor();
ImGui::PopID();
}
END_IMGUI_WIN(); END_IMGUI_WIN();
} }
@ -26,12 +68,20 @@ namespace rrr::layers::gui
void preview::on_event(system_event& e) void preview::on_event(system_event& e)
{ {
if (e.get_name() == try_engine::system_event::classificator::WINDOW_RESIZE()) if (e.get_name() == try_engine::system_event::classificator::WINDOW_RESIZE())
resize();
}
void preview::update_content()
{ {
height = try_engine::application::get()->get_window()->height() - 40.f;
}
void preview::resize()
{
height = try_engine::application::get()->get_window()->height();
width = try_engine::application::get()->get_window()->width() / 3.f; width = try_engine::application::get()->get_window()->width() / 3.f;
pos_x = try_engine::application::get()->get_window()->width() - try_engine::application::get()->get_window()->width() / 3.f; 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 e, std::any value)
{ {

View File

@ -7,6 +7,8 @@ namespace rrr::layers::gui
{ {
class preview : public try_engine::layer class preview : public try_engine::layer
{ {
using font_type = try_engine::style::fonts::font_type;
BASE_TYPE_DEFINE(); BASE_TYPE_DEFINE();
public: public:
@ -27,11 +29,24 @@ namespace rrr::layers::gui
bool show = true; bool show = true;
event_manager* em; event_manager* em;
content* cnt; content* cnt;
int cursor_position = 0;
files* data;
float width = 0.f; float width = 0.f;
float height = 0.f; float height = 0.f;
float pos_x = 0.f; float pos_x = 0.f;
float pos_y = 0.f; float pos_y = 0.f;
private:
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);
private:
void resize();
void update_content();
}; };
} }

10
src/rrr/utils/func.hpp Normal file
View File

@ -0,0 +1,10 @@
#pragma once
namespace rrr::func
{
template<typename Color>
inline Color get_IMGUI_color(float r, float g, float b)
{
return Color(r / 255.f, g / 255.f, b / 255.f, 1.f);
}
}

12
src/rrr/utils/types.hpp Normal file
View File

@ -0,0 +1,12 @@
#pragma once
namespace rrr::types
{
enum class event_type : unsigned int
{
NONE = 0,
NAVIGATION_UP,
NAVIGATION_DOWN
};
}