From bb824a9fb77ab33ea372018ccb0eacc5a08ac772 Mon Sep 17 00:00:00 2001 From: Green Sky Date: Thu, 5 Oct 2023 14:23:39 +0200 Subject: [PATCH] cropping ui partly done (upper left cropper works) --- src/send_image_popup.cpp | 127 ++++++++++++++++++++++++++++++++++++--- src/send_image_popup.hpp | 10 +-- 2 files changed, 125 insertions(+), 12 deletions(-) diff --git a/src/send_image_popup.cpp b/src/send_image_popup.cpp index a32b4ec..1204738 100644 --- a/src/send_image_popup.cpp +++ b/src/send_image_popup.cpp @@ -33,6 +33,8 @@ void SendImagePopup::reset(void) { _tu.destroy(tex_id); } preview_image = {}; + + cropping = false; } bool SendImagePopup::load(void) { @@ -269,18 +271,127 @@ void SendImagePopup::render(void) { height = max_height; } - // save curser pos - // TODO: propergate type - ImGui::Image( - preview_image.getID(), - ImVec2{static_cast(width), static_cast(height)} - ); + // TODO: propergate texture id type - // TODO: crop input here + // save curser pos + + const auto pre_img_curser_screen = ImGui::GetCursorScreenPos(); + const auto pre_img_curser = ImGui::GetCursorPos(); + + if (cropping) { // if cropping + // display full image + ImGui::Image( + preview_image.getID(), + ImVec2{static_cast(width), static_cast(height)} + ); + const auto post_img_curser = ImGui::GetCursorPos(); + + + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{0.5f, 0.5f, 0.5f, 0.2f}); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4{0.5f, 0.5f, 0.5f, 0.4f}); + + static Rect crop_before_drag = crop_rect; + auto ul_clipper_pos = ImVec2{float(crop_rect.x)/original_image.width, float(crop_rect.y)/original_image.height}; + { // crop upper left clipper + + ImGui::SetCursorPos({ + pre_img_curser.x + ul_clipper_pos.x * width, + pre_img_curser.y + ul_clipper_pos.y * height + }); + + static bool dragging_last_frame = false; + ImGui::Button("##ul_clipper", {TEXT_BASE_HEIGHT, TEXT_BASE_HEIGHT}); + if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) { + if (dragging_last_frame) { + auto drag_total = ImGui::GetMouseDragDelta(); + drag_total.x = (drag_total.x / width) * original_image.width; + drag_total.y = (drag_total.y / height) * original_image.height; + + crop_rect.x = std::max(crop_before_drag.x + drag_total.x, 0.01f); + crop_rect.y = std::max(crop_before_drag.y + drag_total.y, 0.01f); + + crop_rect.x = std::min(crop_rect.x, original_image.width-2); + crop_rect.y = std::min(crop_rect.y, original_image.height-2); + + crop_rect.w = crop_before_drag.w - (crop_rect.x - crop_before_drag.x); + crop_rect.h = crop_before_drag.h - (crop_rect.y - crop_before_drag.y); + } else { + if (ImGui::IsItemActive()) { + dragging_last_frame = true; + // drag started on button, start drag + std::cout << "drag started\n"; + } else { + std::cout << "drag but now ours\n"; + } + } + } else if (dragging_last_frame) { // was dragging + std::cout << "drag ended\n"; + dragging_last_frame = false; + + crop_rect = sanitizeCrop(crop_rect, original_image.width, original_image.height); + + crop_before_drag = crop_rect; + } + } + + // crop lower right clipper + auto lr_clipper_pos = ImVec2{float(crop_rect.x+crop_rect.w)/original_image.width, float(crop_rect.y+crop_rect.h)/original_image.height}; + + { // 4 lines delimiting the crop result + // x vertical + ImGui::GetWindowDrawList()->AddLine( + {pre_img_curser_screen.x + ul_clipper_pos.x * width, pre_img_curser_screen.y}, + {pre_img_curser_screen.x + ul_clipper_pos.x * width, pre_img_curser_screen.y + height}, + 0xffffffff, + 1.f + ); + + // y horizontal + ImGui::GetWindowDrawList()->AddLine( + {pre_img_curser_screen.x, pre_img_curser_screen.y + ul_clipper_pos.y * height}, + {pre_img_curser_screen.x + width, pre_img_curser_screen.y + ul_clipper_pos.y * height}, + 0xffffffff, + 1.f + ); + + // w vertical + // h horizontal + } + + // cancel/ok buttons in the img center? + + ImGui::PopStyleColor(2); + + ImGui::SetCursorPos(post_img_curser); + + crop_rect = sanitizeCrop(crop_rect, original_image.width, original_image.height); + } else { + crop_rect = sanitizeCrop(crop_rect, original_image.width, original_image.height); + + // display cropped area + ImGui::Image( + preview_image.getID(), + ImVec2{static_cast(width), static_cast(height)}, + ImVec2{float(crop_rect.x)/original_image.width, float(crop_rect.y)/original_image.height}, + ImVec2{float(crop_rect.x+crop_rect.w)/original_image.width, float(crop_rect.y+crop_rect.h)/original_image.height} + ); + const auto post_img_curser = ImGui::GetCursorPos(); + + ImGui::SetCursorPos(pre_img_curser); + + // TODO: fancy cropping toggle + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{0.5f, 0.5f, 0.5f, 0.2f}); + if (ImGui::Button("crop", {TEXT_BASE_WIDTH*8, TEXT_BASE_HEIGHT*2})) { + cropping = true; + } + ImGui::PopStyleColor(); + + ImGui::SetCursorPos(post_img_curser); + } } - crop_rect = sanitizeCrop(crop_rect, original_image.width, original_image.height); const bool cropped = crop_rect.x != 0 || crop_rect.y != 0 || crop_rect.w != original_image.width || crop_rect.h != original_image.height; + ImGui::Text("crop: x:%d y:%d w:%d h:%d", crop_rect.x, crop_rect.y, crop_rect.w, crop_rect.h); bool recalc_size = false; if (cropped) { diff --git a/src/send_image_popup.hpp b/src/send_image_popup.hpp index 25e33dc..b91d927 100644 --- a/src/send_image_popup.hpp +++ b/src/send_image_popup.hpp @@ -22,14 +22,16 @@ struct SendImagePopup { ImageLoaderI::ImageResult original_image; struct Rect { - uint32_t x {0}; - uint32_t y {0}; + int32_t x {0}; + int32_t y {0}; - uint32_t w {0}; - uint32_t h {0}; + int32_t w {0}; + int32_t h {0}; }; Rect crop_rect; + bool cropping {false}; + // texture to render (orig img) TextureEntry preview_image;