diff --git a/src/rrr/content/content.cpp b/src/rrr/content/content.cpp index 9b5d5c9..a591d19 100644 --- a/src/rrr/content/content.cpp +++ b/src/rrr/content/content.cpp @@ -204,6 +204,31 @@ namespace rrr check_cursor_position(); } + void content::rename_file(std::filesystem::path old_name, std::filesystem::path new_name) + { + if (std::filesystem::exists(new_name)) + { + new_name = new_name.filename().string() + "_" + + std::to_string( + std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() + ); + new_name = old_name.parent_path() / std::filesystem::path(new_name); + } + + hack::utils::unix_cmd("mv " + old_name.string() + " " + new_name.string()); + hack::log()(old_name, new_name); + nav.fill(PWD); + + tbb::parallel_for(tbb::blocked_range(0, nav.data.size()), [&](tbb::blocked_range r) + { + for (int i = r.begin(); i < r.end(); ++i) + if (nav.data.at(i).path == new_name) + navigation_cursor_position = i; + }); + + check_cursor_position(); + } + void content::delete_file(file f) { std::string cmd = "delete " + f.path.string(); diff --git a/src/rrr/content/content.hpp b/src/rrr/content/content.hpp index 939d4ba..9f2d110 100644 --- a/src/rrr/content/content.hpp +++ b/src/rrr/content/content.hpp @@ -32,6 +32,7 @@ namespace rrr void navigation_right(); void navigation_left(); void create_file(std::string); + void rename_file(std::filesystem::path, std::filesystem::path); void delete_file(file); file get_selected_file(TYPE_WIN); diff --git a/src/rrr/layers/gui/browser/navigation/navigation.cpp b/src/rrr/layers/gui/browser/navigation/navigation.cpp index 7f8ea5f..ae36f93 100644 --- a/src/rrr/layers/gui/browser/navigation/navigation.cpp +++ b/src/rrr/layers/gui/browser/navigation/navigation.cpp @@ -152,6 +152,14 @@ namespace rrr::layers::gui 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; } @@ -194,6 +202,13 @@ namespace rrr::layers::gui 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) { diff --git a/src/rrr/layers/gui/dialogs/dialogs.cpp b/src/rrr/layers/gui/dialogs/dialogs.cpp index 013f9e5..e89926f 100644 --- a/src/rrr/layers/gui/dialogs/dialogs.cpp +++ b/src/rrr/layers/gui/dialogs/dialogs.cpp @@ -34,6 +34,9 @@ namespace rrr::layers::gui if (create_dialog) draw_create_dialog(); + if (rename_dialog) + draw_rename_dialog(); + END_IMGUI_WIN(); ImGui::PopStyleVar(); @@ -76,6 +79,13 @@ namespace rrr::layers::gui create_dialog = true; } break; + case types::event_type::SHOW_RENAME_FILE_DIALOG: + { + current_file = std::any_cast(value); + show = true; + rename_dialog = true; + } + break; default: break; } @@ -120,6 +130,8 @@ namespace rrr::layers::gui { if (create_dialog) create_file(); + if (rename_dialog) + rename(); } } @@ -217,6 +229,47 @@ namespace rrr::layers::gui TR_POP_FONT(); } + void dialogs::draw_rename_dialog() + { + TR_PUSH_FONT(MEDIUM, 18); + std::string label = "Переименование файла/директории!"; + title = current_file.path.filename(); + + // манипуляции с тем чтобы название стояло посередлине + // см. и ниже тоже + 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)) + rename(); + + ImGui::SameLine(width / 1.8f); + + if (ImGui::Button("Отмена (Esc)", button_size)) + cancel(); + + TR_POP_FONT(); + } + void dialogs::create_file() { if (title.empty()) return; @@ -226,10 +279,20 @@ namespace rrr::layers::gui title.clear(); } + void dialogs::rename() + { + if (title.empty()) return; + show = false; + rename_dialog = false; + em->execute(types::event_type::RENAME_FILE, current_file.path.parent_path() / title); + title.clear(); + } + void dialogs::cancel() { delete_dialog = false; create_dialog = false; + rename_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 index 48b4575..f5ebe11 100644 --- a/src/rrr/layers/gui/dialogs/dialogs.hpp +++ b/src/rrr/layers/gui/dialogs/dialogs.hpp @@ -30,6 +30,7 @@ namespace rrr::layers::gui float height = 0.f; bool delete_dialog = false; bool create_dialog = false; + bool rename_dialog = false; file current_file; bool shift = false; std::string title; @@ -39,7 +40,9 @@ namespace rrr::layers::gui void cancel(); void draw_delete_dialog(); void draw_create_dialog(); + void draw_rename_dialog(); void create_file(); + void rename(); void pressed(system_event& e); void released(system_event& e); }; diff --git a/src/rrr/utils/types.hpp b/src/rrr/utils/types.hpp index f29eefe..d4ef36e 100644 --- a/src/rrr/utils/types.hpp +++ b/src/rrr/utils/types.hpp @@ -14,7 +14,9 @@ namespace rrr::types UNFREEZE_BROWSER_ACTION, // размораживает все действия DELETE_CURRENT_FILE, SHOW_CREATE_FILE_DIALOG, - CREATE_FILE + CREATE_FILE, + SHOW_RENAME_FILE_DIALOG, + RENAME_FILE }; }