mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 20:25:34 +08:00
[fix] fix control bar position when stream window created
This commit is contained in:
@@ -104,8 +104,8 @@ int Render::ConnectionStatusWindow(
|
||||
focus_on_input_widget_ = false;
|
||||
}
|
||||
|
||||
ImGui::InputText("##password", remote_password_,
|
||||
IM_ARRAYSIZE(remote_password_),
|
||||
ImGui::InputText("##password", props->remote_password_,
|
||||
IM_ARRAYSIZE(props->remote_password_),
|
||||
ImGuiInputTextFlags_CharsNoBlank);
|
||||
|
||||
ImGui::SetWindowFontScale(0.4f);
|
||||
@@ -138,7 +138,7 @@ int Render::ConnectionStatusWindow(
|
||||
if (ImGui::Button(
|
||||
localization::cancel[localization_language_index_].c_str()) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
memset(remote_password_, 0, sizeof(remote_password_));
|
||||
memset(props->remote_password_, 0, sizeof(props->remote_password_));
|
||||
show_connection_status_window_ = false;
|
||||
focus_on_input_widget_ = true;
|
||||
}
|
||||
|
||||
@@ -56,12 +56,12 @@ int Render::ShowRecentConnections() {
|
||||
ImGuiWindowFlags_NoScrollWithMouse);
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor();
|
||||
size_t recent_connections_count = recent_connection_textures_.size();
|
||||
size_t recent_connections_count = recent_connections_.size();
|
||||
int count = 0;
|
||||
float button_width = 22;
|
||||
float button_height = 22;
|
||||
for (auto it = recent_connection_textures_.begin();
|
||||
it != recent_connection_textures_.end(); ++it) {
|
||||
for (auto it = recent_connections_.begin(); it != recent_connections_.end();
|
||||
++it) {
|
||||
sub_containers_pos[it->first] = ImGui::GetCursorPos();
|
||||
std::string recent_connection_sub_window_name =
|
||||
"RecentConnectionsSubContainer" + it->first;
|
||||
@@ -77,23 +77,23 @@ int Render::ShowRecentConnections() {
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_NoScrollbar);
|
||||
std::string connection_info = it->first;
|
||||
std::string remote_id;
|
||||
std::string password;
|
||||
std::string host_name;
|
||||
|
||||
// remote id length is 9
|
||||
// password length is 6
|
||||
// connection_info -> remote_id + 'Y' + password + host_name
|
||||
// -> remote_id + 'N' + host_name
|
||||
if ('Y' == connection_info[9] && connection_info.size() >= 16) {
|
||||
remote_id = connection_info.substr(0, 9);
|
||||
password = connection_info.substr(10, 6);
|
||||
host_name = connection_info.substr(16);
|
||||
it->second.remote_id = connection_info.substr(0, 9);
|
||||
it->second.password = connection_info.substr(10, 6);
|
||||
it->second.remote_host_name = connection_info.substr(16);
|
||||
it->second.remember_password = true;
|
||||
} else if ('N' == connection_info[9] && connection_info.size() >= 10) {
|
||||
remote_id = connection_info.substr(0, 9);
|
||||
host_name = connection_info.substr(10);
|
||||
it->second.remote_id = connection_info.substr(0, 9);
|
||||
it->second.remote_host_name = connection_info.substr(10);
|
||||
it->second.password = "";
|
||||
it->second.remember_password = false;
|
||||
} else {
|
||||
host_name = "unknown";
|
||||
it->second.remote_host_name = "unknown";
|
||||
}
|
||||
|
||||
ImVec2 image_screen_pos = ImVec2(ImGui::GetCursorScreenPos().x + 5.0f,
|
||||
@@ -101,7 +101,7 @@ int Render::ShowRecentConnections() {
|
||||
ImVec2 image_pos =
|
||||
ImVec2(ImGui::GetCursorPosX() + 5.0f, ImGui::GetCursorPosY() + 5.0f);
|
||||
ImGui::SetCursorPos(image_pos);
|
||||
ImGui::Image((ImTextureID)(intptr_t)it->second,
|
||||
ImGui::Image((ImTextureID)(intptr_t)it->second.texture,
|
||||
ImVec2((float)recent_connection_image_width_,
|
||||
(float)recent_connection_image_height_));
|
||||
|
||||
@@ -113,7 +113,7 @@ int Render::ShowRecentConnections() {
|
||||
|
||||
ImVec2 dummy_button_pos =
|
||||
ImVec2(image_pos.x, image_pos.y + recent_connection_image_height_);
|
||||
std::string dummy_button_name = "##DummyButton" + remote_id;
|
||||
std::string dummy_button_name = "##DummyButton" + it->second.remote_id;
|
||||
ImGui::SetCursorPos(dummy_button_pos);
|
||||
ImGui::SetWindowFontScale(0.6f);
|
||||
ImGui::Button(dummy_button_name.c_str(),
|
||||
@@ -123,14 +123,14 @@ int Render::ShowRecentConnections() {
|
||||
ImGui::SetCursorPos(
|
||||
ImVec2(dummy_button_pos.x + 2.0f, dummy_button_pos.y + 1.0f));
|
||||
ImGui::SetWindowFontScale(0.65f);
|
||||
ImGui::Text("%s", remote_id.c_str());
|
||||
ImGui::Text("%s", it->second.remote_id.c_str());
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
ImGui::Text("%s", host_name.c_str());
|
||||
ImGui::Text("%s", it->second.remote_host_name.c_str());
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
@@ -176,15 +176,8 @@ int Render::ShowRecentConnections() {
|
||||
connect + "##ConnectionTo" + it->first;
|
||||
if (ImGui::Button(connect_to_this_connection_button_name.c_str(),
|
||||
ImVec2(button_width, button_height))) {
|
||||
remote_id_ = remote_id;
|
||||
|
||||
bool remember_password_flag = false;
|
||||
if (!password.empty() && password.size() == 6) {
|
||||
remember_password_flag = true;
|
||||
memcpy(remote_password_, password.c_str(), 6);
|
||||
}
|
||||
|
||||
ConnectTo(remote_id, remote_password_, remember_password_flag);
|
||||
ConnectTo(it->second.remote_id, it->second.password.c_str(),
|
||||
it->second.remember_password);
|
||||
}
|
||||
}
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
|
||||
@@ -68,21 +68,44 @@ int Render::RemoteWindow() {
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::SameLine();
|
||||
|
||||
std::string remote_id = remote_id_display_;
|
||||
remote_id.erase(remove_if(remote_id.begin(), remote_id.end(),
|
||||
static_cast<int (*)(int)>(&isspace)),
|
||||
remote_id.end());
|
||||
if (ImGui::Button(ICON_FA_ARROW_RIGHT_LONG, ImVec2(55, 38)) ||
|
||||
enter_pressed) {
|
||||
connect_button_pressed_ = true;
|
||||
remote_id_ = remote_id_display_;
|
||||
remote_id_.erase(remove_if(remote_id_.begin(), remote_id_.end(),
|
||||
static_cast<int (*)(int)>(&isspace)),
|
||||
remote_id_.end());
|
||||
ConnectTo(remote_id_, remote_password_, false);
|
||||
bool found = false;
|
||||
for (auto &[id, props] : recent_connections_) {
|
||||
if (id.find(remote_id) != std::string::npos) {
|
||||
found = true;
|
||||
if (client_properties_.find(remote_id) !=
|
||||
client_properties_.end()) {
|
||||
if (!client_properties_[remote_id]->connection_established_) {
|
||||
ConnectTo(props.remote_id, props.password.c_str(), false);
|
||||
} else {
|
||||
// todo: show warning message
|
||||
LOG_INFO("Already connected to [{}]", remote_id);
|
||||
}
|
||||
} else {
|
||||
ConnectTo(props.remote_id, props.password.c_str(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
ConnectTo(remote_id, "", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (client_properties_.find(remote_id_) != client_properties_.end()) {
|
||||
auto props = client_properties_[remote_id_];
|
||||
if (props->rejoin_) {
|
||||
ConnectTo(remote_id_, remote_password_,
|
||||
client_properties_[remote_id_]->remember_password_);
|
||||
if (need_to_rejoin_) {
|
||||
need_to_rejoin_ = false;
|
||||
for (const auto &[_, props] : client_properties_) {
|
||||
if (props->rejoin_) {
|
||||
ConnectTo(props->remote_id_, props->remote_password_,
|
||||
props->remember_password_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,13 +156,14 @@ int Render::ConnectTo(const std::string &remote_id, const char *password,
|
||||
int ret = -1;
|
||||
auto props = client_properties_[remote_id];
|
||||
if (!props->connection_established_) {
|
||||
props->remember_password_ = remember_password;
|
||||
memcpy(props->remote_password_, password, 6);
|
||||
ret = JoinConnection(props->peer_, remote_id.c_str(), password);
|
||||
if (0 == ret) {
|
||||
props->rejoin_ = false;
|
||||
props->remember_password_ = remember_password;
|
||||
memcpy(props->remote_password_, password, 6);
|
||||
} else {
|
||||
props->rejoin_ = true;
|
||||
need_to_rejoin_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -527,6 +527,7 @@ int Render::CreateStreamWindow() {
|
||||
SDL_PushEvent(&event);
|
||||
|
||||
stream_window_created_ = true;
|
||||
just_created_ = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -841,9 +842,9 @@ void Render::HandleRecentConnections() {
|
||||
if (reload_recent_connections_ && main_renderer_) {
|
||||
uint32_t now_time = SDL_GetTicks();
|
||||
if (now_time - recent_connection_image_save_time_ >= 50) {
|
||||
int ret = thumbnail_->LoadThumbnail(
|
||||
main_renderer_, recent_connection_textures_,
|
||||
&recent_connection_image_width_, &recent_connection_image_height_);
|
||||
int ret = thumbnail_->LoadThumbnail(main_renderer_, recent_connections_,
|
||||
&recent_connection_image_width_,
|
||||
&recent_connection_image_height_);
|
||||
if (!ret) {
|
||||
LOG_INFO("Load recent connection thumbnails");
|
||||
}
|
||||
@@ -1029,51 +1030,55 @@ void Render::ProcessSdlEvent() {
|
||||
} else if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED &&
|
||||
stream_window_created_ &&
|
||||
event.window.windowID == SDL_GetWindowID(stream_window_)) {
|
||||
for (auto& [_, props] : client_properties_) {
|
||||
if (!props->reset_control_bar_pos_) {
|
||||
props->mouse_diff_control_bar_pos_x_ = 0;
|
||||
props->mouse_diff_control_bar_pos_y_ = 0;
|
||||
}
|
||||
if (just_created_) {
|
||||
just_created_ = false;
|
||||
} else {
|
||||
for (auto& [_, props] : client_properties_) {
|
||||
if (!props->reset_control_bar_pos_) {
|
||||
props->mouse_diff_control_bar_pos_x_ = 0;
|
||||
props->mouse_diff_control_bar_pos_y_ = 0;
|
||||
}
|
||||
|
||||
props->reset_control_bar_pos_ = true;
|
||||
int stream_window_width, stream_window_height;
|
||||
SDL_GetWindowSize(stream_window_, &stream_window_width,
|
||||
&stream_window_height);
|
||||
stream_window_width_ = (float)stream_window_width;
|
||||
stream_window_height_ = (float)stream_window_height;
|
||||
props->reset_control_bar_pos_ = true;
|
||||
int stream_window_width, stream_window_height;
|
||||
SDL_GetWindowSize(stream_window_, &stream_window_width,
|
||||
&stream_window_height);
|
||||
stream_window_width_ = (float)stream_window_width;
|
||||
stream_window_height_ = (float)stream_window_height;
|
||||
|
||||
float video_ratio =
|
||||
(float)props->video_width_ / (float)props->video_height_;
|
||||
float video_ratio_reverse =
|
||||
(float)props->video_height_ / (float)props->video_width_;
|
||||
float video_ratio =
|
||||
(float)props->video_width_ / (float)props->video_height_;
|
||||
float video_ratio_reverse =
|
||||
(float)props->video_height_ / (float)props->video_width_;
|
||||
|
||||
float render_area_width = stream_window_width_;
|
||||
float render_area_height =
|
||||
stream_window_height_ -
|
||||
(fullscreen_button_pressed_ ? 0 : title_bar_height_);
|
||||
float render_area_width = stream_window_width_;
|
||||
float render_area_height =
|
||||
stream_window_height_ -
|
||||
(fullscreen_button_pressed_ ? 0 : title_bar_height_);
|
||||
|
||||
props->stream_render_rect_last_ = props->stream_render_rect_;
|
||||
if (render_area_width < render_area_height * video_ratio) {
|
||||
props->stream_render_rect_ = {
|
||||
0,
|
||||
(int)(abs(render_area_height -
|
||||
render_area_width * video_ratio_reverse) /
|
||||
2 +
|
||||
(fullscreen_button_pressed_ ? 0 : title_bar_height_)),
|
||||
(int)render_area_width,
|
||||
(int)(render_area_width * video_ratio_reverse)};
|
||||
} else if (render_area_width > render_area_height * video_ratio) {
|
||||
props->stream_render_rect_ = {
|
||||
(int)abs(render_area_width -
|
||||
render_area_height * video_ratio) /
|
||||
2,
|
||||
fullscreen_button_pressed_ ? 0 : (int)title_bar_height_,
|
||||
(int)(render_area_height * video_ratio),
|
||||
(int)render_area_height};
|
||||
} else {
|
||||
props->stream_render_rect_ = {
|
||||
0, fullscreen_button_pressed_ ? 0 : (int)title_bar_height_,
|
||||
(int)render_area_width, (int)render_area_height};
|
||||
props->stream_render_rect_last_ = props->stream_render_rect_;
|
||||
if (render_area_width < render_area_height * video_ratio) {
|
||||
props->stream_render_rect_ = {
|
||||
0,
|
||||
(int)(abs(render_area_height -
|
||||
render_area_width * video_ratio_reverse) /
|
||||
2 +
|
||||
(fullscreen_button_pressed_ ? 0 : title_bar_height_)),
|
||||
(int)render_area_width,
|
||||
(int)(render_area_width * video_ratio_reverse)};
|
||||
} else if (render_area_width > render_area_height * video_ratio) {
|
||||
props->stream_render_rect_ = {
|
||||
(int)abs(render_area_width -
|
||||
render_area_height * video_ratio) /
|
||||
2,
|
||||
fullscreen_button_pressed_ ? 0 : (int)title_bar_height_,
|
||||
(int)(render_area_height * video_ratio),
|
||||
(int)render_area_height};
|
||||
} else {
|
||||
props->stream_render_rect_ = {
|
||||
0, fullscreen_button_pressed_ ? 0 : (int)title_bar_height_,
|
||||
(int)render_area_width, (int)render_area_height};
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED ||
|
||||
|
||||
@@ -240,7 +240,7 @@ class Render {
|
||||
std::unique_ptr<Thumbnail> thumbnail_;
|
||||
|
||||
// recent connections
|
||||
std::map<std::string, SDL_Texture *> recent_connection_textures_;
|
||||
std::map<std::string, Thumbnail::RecentConnection> recent_connections_;
|
||||
int recent_connection_image_width_ = 160;
|
||||
int recent_connection_image_height_ = 90;
|
||||
uint32_t recent_connection_image_save_time_ = 0;
|
||||
@@ -296,13 +296,13 @@ class Render {
|
||||
char input_password_tmp_[7] = "";
|
||||
char input_password_[7] = "";
|
||||
std::string random_password_ = "";
|
||||
char remote_password_[7] = "";
|
||||
char new_password_[7] = "";
|
||||
char remote_id_display_[12] = "";
|
||||
std::string remote_id_ = "";
|
||||
unsigned char audio_buffer_[720];
|
||||
int audio_len_ = 0;
|
||||
bool audio_buffer_fresh_ = false;
|
||||
bool need_to_rejoin_ = false;
|
||||
bool just_created_ = false;
|
||||
|
||||
// stream window render
|
||||
SDL_Window *stream_window_ = nullptr;
|
||||
|
||||
@@ -359,9 +359,7 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char *user_id,
|
||||
render->StopSpeakerCapturer();
|
||||
render->audio_capture_ = false;
|
||||
}
|
||||
if (!render->rejoin_) {
|
||||
memset(render->remote_password_, 0, sizeof(render->remote_password_));
|
||||
}
|
||||
|
||||
if (props->dst_buffer_) {
|
||||
memset(props->dst_buffer_, 0, props->dst_buffer_capacity_);
|
||||
SDL_UpdateTexture(props->stream_texture_, NULL, props->dst_buffer_,
|
||||
|
||||
@@ -23,6 +23,65 @@
|
||||
|
||||
static std::string test;
|
||||
|
||||
bool LoadTextureFromMemory(const void* data, size_t data_size,
|
||||
SDL_Renderer* renderer, SDL_Texture** out_texture,
|
||||
int* out_width, int* out_height) {
|
||||
int image_width = 0;
|
||||
int image_height = 0;
|
||||
int channels = 4;
|
||||
unsigned char* image_data =
|
||||
stbi_load_from_memory((const unsigned char*)data, (int)data_size,
|
||||
&image_width, &image_height, NULL, 4);
|
||||
if (image_data == nullptr) {
|
||||
LOG_ERROR("Failed to load image: [{}]", stbi_failure_reason());
|
||||
return false;
|
||||
}
|
||||
|
||||
// ABGR
|
||||
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(
|
||||
(void*)image_data, image_width, image_height, channels * 8,
|
||||
channels * image_width, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||
if (surface == nullptr) {
|
||||
LOG_ERROR("Failed to create SDL surface: [{}]", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (texture == nullptr) {
|
||||
LOG_ERROR("Failed to create SDL texture: [{}]", SDL_GetError());
|
||||
}
|
||||
|
||||
*out_texture = texture;
|
||||
*out_width = image_width;
|
||||
*out_height = image_height;
|
||||
|
||||
SDL_FreeSurface(surface);
|
||||
stbi_image_free(image_data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadTextureFromFile(const char* file_name, SDL_Renderer* renderer,
|
||||
SDL_Texture** out_texture, int* out_width,
|
||||
int* out_height) {
|
||||
std::filesystem::path file_path(file_name);
|
||||
if (!std::filesystem::exists(file_path)) return false;
|
||||
std::ifstream file(file_path, std::ios::binary);
|
||||
if (!file) return false;
|
||||
file.seekg(0, std::ios::end);
|
||||
size_t file_size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
if (file_size == -1) return false;
|
||||
char* file_data = new char[file_size];
|
||||
if (!file_data) return false;
|
||||
file.read(file_data, file_size);
|
||||
bool ret = LoadTextureFromMemory(file_data, file_size, renderer, out_texture,
|
||||
out_width, out_height);
|
||||
delete[] file_data;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ScaleYUV420pToABGR(char* dst_buffer_, int video_width_, int video_height_,
|
||||
int scaled_video_width_, int scaled_video_height_,
|
||||
char* rgba_buffer_) {
|
||||
@@ -87,7 +146,7 @@ int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height,
|
||||
|
||||
std::string image_name;
|
||||
if (password.empty()) {
|
||||
image_name = remote_id + 'N' + host_name;
|
||||
return 0;
|
||||
} else {
|
||||
// delete the file which has no password in its name
|
||||
std::string filename_without_password = remote_id + "N" + host_name;
|
||||
@@ -104,63 +163,49 @@ int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool LoadTextureFromMemory(const void* data, size_t data_size,
|
||||
SDL_Renderer* renderer, SDL_Texture** out_texture,
|
||||
int* out_width, int* out_height) {
|
||||
int image_width = 0;
|
||||
int image_height = 0;
|
||||
int channels = 4;
|
||||
unsigned char* image_data =
|
||||
stbi_load_from_memory((const unsigned char*)data, (int)data_size,
|
||||
&image_width, &image_height, NULL, 4);
|
||||
if (image_data == nullptr) {
|
||||
LOG_ERROR("Failed to load image: [{}]", stbi_failure_reason());
|
||||
return false;
|
||||
int Thumbnail::LoadThumbnail(
|
||||
SDL_Renderer* renderer,
|
||||
std::map<std::string, RecentConnection>& recent_connections, int* width,
|
||||
int* height) {
|
||||
for (auto& it : recent_connections) {
|
||||
if (it.second.texture != nullptr) {
|
||||
SDL_DestroyTexture(it.second.texture);
|
||||
it.second.texture = nullptr;
|
||||
}
|
||||
}
|
||||
recent_connections.clear();
|
||||
|
||||
// ABGR
|
||||
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(
|
||||
(void*)image_data, image_width, image_height, channels * 8,
|
||||
channels * image_width, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||
if (surface == nullptr) {
|
||||
LOG_ERROR("Failed to create SDL surface: [{}]", SDL_GetError());
|
||||
return false;
|
||||
std::vector<std::filesystem::path> image_paths =
|
||||
FindThumbnailPath(image_path_);
|
||||
|
||||
if (image_paths.size() == 0) {
|
||||
return -1;
|
||||
} else {
|
||||
for (int i = 0; i < image_paths.size(); i++) {
|
||||
size_t pos1 = image_paths[i].string().find('/') + 1;
|
||||
std::string cipher_image_name = image_paths[i].string().substr(pos1);
|
||||
std::string original_image_name =
|
||||
AES_decrypt(cipher_image_name, aes128_key_, aes128_iv_);
|
||||
std::string image_path = image_path_ + cipher_image_name;
|
||||
recent_connections[original_image_name].texture = nullptr;
|
||||
LoadTextureFromFile(image_path.c_str(), renderer,
|
||||
&(recent_connections[original_image_name].texture),
|
||||
width, height);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (texture == nullptr) {
|
||||
LOG_ERROR("Failed to create SDL texture: [{}]", SDL_GetError());
|
||||
}
|
||||
|
||||
*out_texture = texture;
|
||||
*out_width = image_width;
|
||||
*out_height = image_height;
|
||||
|
||||
SDL_FreeSurface(surface);
|
||||
stbi_image_free(image_data);
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool LoadTextureFromFile(const char* file_name, SDL_Renderer* renderer,
|
||||
SDL_Texture** out_texture, int* out_width,
|
||||
int* out_height) {
|
||||
std::filesystem::path file_path(file_name);
|
||||
if (!std::filesystem::exists(file_path)) return false;
|
||||
std::ifstream file(file_path, std::ios::binary);
|
||||
if (!file) return false;
|
||||
file.seekg(0, std::ios::end);
|
||||
size_t file_size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
if (file_size == -1) return false;
|
||||
char* file_data = new char[file_size];
|
||||
if (!file_data) return false;
|
||||
file.read(file_data, file_size);
|
||||
bool ret = LoadTextureFromMemory(file_data, file_size, renderer, out_texture,
|
||||
out_width, out_height);
|
||||
delete[] file_data;
|
||||
|
||||
return ret;
|
||||
int Thumbnail::DeleteThumbnail(const std::string& file_name) {
|
||||
std::string ciphertext = AES_encrypt(file_name, aes128_key_, aes128_iv_);
|
||||
std::string file_path = image_path_ + ciphertext;
|
||||
if (std::filesystem::exists(file_path)) {
|
||||
std::filesystem::remove(file_path);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> Thumbnail::FindThumbnailPath(
|
||||
@@ -194,49 +239,6 @@ std::vector<std::filesystem::path> Thumbnail::FindThumbnailPath(
|
||||
return thumbnails_path;
|
||||
}
|
||||
|
||||
int Thumbnail::LoadThumbnail(SDL_Renderer* renderer,
|
||||
std::map<std::string, SDL_Texture*>& textures,
|
||||
int* width, int* height) {
|
||||
for (auto& it : textures) {
|
||||
if (it.second != nullptr) {
|
||||
SDL_DestroyTexture(it.second);
|
||||
it.second = nullptr;
|
||||
}
|
||||
}
|
||||
textures.clear();
|
||||
|
||||
std::vector<std::filesystem::path> image_paths =
|
||||
FindThumbnailPath(image_path_);
|
||||
|
||||
if (image_paths.size() == 0) {
|
||||
return -1;
|
||||
} else {
|
||||
for (int i = 0; i < image_paths.size(); i++) {
|
||||
size_t pos1 = image_paths[i].string().find('/') + 1;
|
||||
std::string cipher_image_name = image_paths[i].string().substr(pos1);
|
||||
std::string original_image_name =
|
||||
AES_decrypt(cipher_image_name, aes128_key_, aes128_iv_);
|
||||
std::string image_path = image_path_ + cipher_image_name;
|
||||
textures[original_image_name] = nullptr;
|
||||
LoadTextureFromFile(image_path.c_str(), renderer,
|
||||
&(textures[original_image_name]), width, height);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Thumbnail::DeleteThumbnail(const std::string& file_name) {
|
||||
std::string ciphertext = AES_encrypt(file_name, aes128_key_, aes128_iv_);
|
||||
std::string file_path = image_path_ + ciphertext;
|
||||
if (std::filesystem::exists(file_path)) {
|
||||
std::filesystem::remove(file_path);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int Thumbnail::DeleteAllFilesInDirectory() {
|
||||
if (std::filesystem::exists(image_path_) &&
|
||||
std::filesystem::is_directory(image_path_)) {
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
#include <map>
|
||||
|
||||
class Thumbnail {
|
||||
public:
|
||||
struct RecentConnection {
|
||||
SDL_Texture* texture = nullptr;
|
||||
std::string remote_id;
|
||||
std::string remote_host_name;
|
||||
std::string password;
|
||||
bool remember_password = false;
|
||||
};
|
||||
|
||||
public:
|
||||
Thumbnail();
|
||||
explicit Thumbnail(unsigned char* aes128_key, unsigned char* aes128_iv);
|
||||
@@ -25,8 +34,8 @@ class Thumbnail {
|
||||
const std::string& password);
|
||||
|
||||
int LoadThumbnail(SDL_Renderer* renderer,
|
||||
std::map<std::string, SDL_Texture*>& textures, int* width,
|
||||
int* height);
|
||||
std::map<std::string, RecentConnection>& recent_connections,
|
||||
int* width, int* height);
|
||||
|
||||
int DeleteThumbnail(const std::string& file_name);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user