2022-03-20 20:56:32 +01:00
|
|
|
#include "image_view.h"
|
|
|
|
|
#include "imgui/imgui_image.h"
|
|
|
|
|
#include "core/module.h"
|
|
|
|
|
#include "imgui/imgui_internal.h"
|
|
|
|
|
|
|
|
|
|
ImageViewWidget::ImageViewWidget()
|
|
|
|
|
{
|
|
|
|
|
id_str = "imgview_" + std::to_string(rand());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImageViewWidget::~ImageViewWidget()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ImageViewWidget::update(image::Image<uint16_t> image)
|
|
|
|
|
{
|
|
|
|
|
image_mtx.lock();
|
|
|
|
|
img_width = image.width();
|
|
|
|
|
img_height = image.height();
|
|
|
|
|
|
|
|
|
|
texture_buffer.resize(img_width * img_height);
|
|
|
|
|
ushort_to_rgba(image.data(), texture_buffer.data(), img_width * img_height, image.channels());
|
|
|
|
|
has_to_update = true;
|
|
|
|
|
|
|
|
|
|
image_mtx.unlock();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ImageViewWidget::draw(ImVec2 win_size)
|
|
|
|
|
{
|
|
|
|
|
image_mtx.lock();
|
|
|
|
|
|
|
|
|
|
if (texture_id == 0)
|
|
|
|
|
texture_id = makeImageTexture();
|
|
|
|
|
|
|
|
|
|
if (has_to_update)
|
|
|
|
|
{
|
|
|
|
|
updateImageTexture(texture_id, texture_buffer.data(), img_width, img_height);
|
|
|
|
|
texture_buffer.clear();
|
|
|
|
|
has_to_update = false;
|
|
|
|
|
|
|
|
|
|
if (first_run)
|
|
|
|
|
{
|
|
|
|
|
img_scale = (win_size.y) / (img_height * ui_scale);
|
|
|
|
|
first_run = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui::BeginChild(id_str.c_str(), win_size, false, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
|
|
|
|
|
|
|
|
|
|
ImGui::GetWindowDrawList()
|
|
|
|
|
->AddRectFilled(ImGui::GetCursorScreenPos(),
|
|
|
|
|
ImVec2(ImGui::GetCursorScreenPos().x + ImGui::GetScrollX() + ImGui::GetContentRegionAvail().x,
|
|
|
|
|
ImGui::GetCursorScreenPos().y + ImGui::GetScrollY() + ImGui::GetContentRegionAvail().y),
|
|
|
|
|
ImColor::HSV(0, 0, 0));
|
|
|
|
|
|
|
|
|
|
ImGui::Image((void *)(intptr_t)texture_id, {img_width * ui_scale * img_scale, img_height * ui_scale * img_scale});
|
|
|
|
|
|
|
|
|
|
handleMouseDrag();
|
|
|
|
|
|
|
|
|
|
float scale_before = img_scale;
|
|
|
|
|
|
|
|
|
|
ImGuiContext &g = *ImGui::GetCurrentContext();
|
|
|
|
|
ImGuiWindow *window = g.CurrentWindow;
|
|
|
|
|
|
|
|
|
|
if (ImGui::IsMouseHoveringRect(window->Pos, {window->Pos.x + win_size.x, window->Pos.y + win_size.y}))
|
|
|
|
|
{
|
2022-04-12 16:08:03 +02:00
|
|
|
if (ImGui::GetIO().MouseWheel > 0)
|
2022-03-20 20:56:32 +01:00
|
|
|
img_scale *= 1.05;
|
2022-04-12 16:08:03 +02:00
|
|
|
else if (ImGui::GetIO().MouseWheel < 0)
|
2022-03-20 20:56:32 +01:00
|
|
|
img_scale *= 0.95;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*if (ImGui::GetIO().MouseWheel != 0)
|
|
|
|
|
{
|
|
|
|
|
ImGuiContext &g = *ImGui::GetCurrentContext();
|
|
|
|
|
ImGuiWindow *window = g.CurrentWindow;
|
|
|
|
|
float imagePosX = window->Scroll.x + ImGui::GetMousePos().x - window->Pos.x;
|
|
|
|
|
float imagePosY = window->Scroll.y + ImGui::GetMousePos().y - window->Pos.y;
|
|
|
|
|
|
|
|
|
|
imagePosX /= ui_scale * img_scale;
|
|
|
|
|
imagePosY /= ui_scale * img_scale;
|
|
|
|
|
|
|
|
|
|
logger->info("X {:f}, Y {:f} MOUSE {:f} {:f}, MOUSEPOS {:f} {:f}", window->Scroll.x, window->Scroll.y,
|
|
|
|
|
ImGui::GetMousePos().x - window->Pos.x, ImGui::GetMousePos().y - window->Pos.y,
|
|
|
|
|
imagePosX, imagePosY);
|
|
|
|
|
|
|
|
|
|
// imagePosX *= ui_scale * img_scale;
|
|
|
|
|
// imagePosY *= ui_scale * img_scale;
|
|
|
|
|
|
|
|
|
|
// window->Scroll.x = imagePosX - (win_size.x / 2);
|
|
|
|
|
// window->Scroll.y = imagePosY - (win_size.y / 2);
|
|
|
|
|
|
|
|
|
|
// ImGui::GetMousePos().x = window->Pos.x + (win_size.x / 2);
|
|
|
|
|
// ImGui::GetMousePos().y = window->Pos.y + (win_size.y / 2);
|
|
|
|
|
// window->Scroll.y = ;
|
|
|
|
|
}*/
|
|
|
|
|
|
2022-04-12 15:35:18 +02:00
|
|
|
// Compute current pixel position
|
|
|
|
|
float imagePosX = window->Scroll.x + ImGui::GetMousePos().x - window->Pos.x;
|
|
|
|
|
float imagePosY = window->Scroll.y + ImGui::GetMousePos().y - window->Pos.y;
|
|
|
|
|
imagePosX /= ui_scale * img_scale;
|
|
|
|
|
imagePosY /= ui_scale * img_scale;
|
|
|
|
|
if (imagePosX >= 0 && imagePosY >= 0 &&
|
|
|
|
|
imagePosX < img_width && imagePosY < img_height &&
|
|
|
|
|
ImGui::GetMousePos().x - window->Pos.x > 0 && ImGui::GetMousePos().y - window->Pos.y > 0)
|
2022-04-12 20:18:44 +02:00
|
|
|
mouseCallback(imagePosX, imagePosY);
|
2022-04-12 15:35:18 +02:00
|
|
|
|
2022-03-20 20:56:32 +01:00
|
|
|
if (ImGui::GetIO().MouseWheel != 0)
|
|
|
|
|
{
|
|
|
|
|
float ratio = img_scale / scale_before;
|
|
|
|
|
|
|
|
|
|
float scrollX_Percent = (window->Scroll.x + win_size.x / 2) / window->ScrollMax.x;
|
|
|
|
|
float scrollY_Percent = (window->Scroll.y + win_size.y / 2) / window->ScrollMax.y;
|
|
|
|
|
|
|
|
|
|
window->Scroll.x = scrollX_Percent * window->ScrollMax.x * ratio - win_size.x / 2;
|
|
|
|
|
window->Scroll.y = scrollY_Percent * window->ScrollMax.y * ratio - win_size.y / 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui::EndChild();
|
|
|
|
|
image_mtx.unlock();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// From https://github.com/ocornut/imgui/issues/3379
|
|
|
|
|
void ImageViewWidget::handleMouseDrag()
|
|
|
|
|
{
|
|
|
|
|
ImVec2 delta = ImGui::GetIO().MouseDelta;
|
|
|
|
|
|
|
|
|
|
ImGuiContext &g = *ImGui::GetCurrentContext();
|
|
|
|
|
ImGuiWindow *window = g.CurrentWindow;
|
|
|
|
|
bool hovered = false;
|
|
|
|
|
bool held = false;
|
|
|
|
|
if (g.HoveredId == 0) // If nothing hovered so far in the frame (not same as IsAnyItemHovered()!)
|
|
|
|
|
ImGui::ButtonBehavior(window->Rect(), window->GetID("##scrolldraggingoverlay"), &hovered, &held, ImGuiButtonFlags_MouseButtonLeft);
|
|
|
|
|
if (held)
|
|
|
|
|
{
|
|
|
|
|
window->Scroll.x += -delta.x;
|
|
|
|
|
window->Scroll.y += -delta.y;
|
|
|
|
|
}
|
|
|
|
|
}
|