fszontagh
2024-02-25 5d543bcc0d15b871315a2123aec01041d73c53fb
ui/ImageViewerImageWindow.cpp
@@ -1,8 +1,237 @@
#include "ImageViewerImageWindow.h"
ImageViewerImageWindow::ImageViewerImageWindow( wxWindow* parent )
:
ImageWindow( parent )
ImageViewerImageWindow::ImageViewerImageWindow(wxWindow *parent)
    : ImageWindow(parent)
{
    auto bitmap = app_png_to_wx_bitmap();
    wxIcon icon;
    icon.CopyFromBitmap(bitmap);
    this->SetIcon(icon);
    this->windowTitle = this->GetTitle();
    this->imgList = new wxImageList(100, 100);
}
void ImageViewerImageWindow::OnDropFile(wxDropFilesEvent &event)
{
    auto numFiles = event.GetNumberOfFiles();
    auto files = event.GetFiles();
    bool first = false;
    this->imgList->Destroy();
    this->imgList->Create(100, 100);
    this->images.clear();
    for (int index = 0; index < numFiles; index++)
    {
        wxFileName filename(files[index]);
        if (wxFile::Exists(filename.GetAbsolutePath()))
        {
            if (filename.GetExt() == "jpg" || filename.GetExt() == "png")
            {
                wxImage img(filename.GetAbsolutePath());
                // this->images.emplace(filename.GetAbsolutePath(), img);
                ImageUtils::ImageFileInfo *info = new ImageUtils::ImageFileInfo();
                info->file = new wxFileName(filename);
                info->img = new wxImage(img);
                if (first == false)
                {
                    first = true;
                    this->ShowImage(img);
                    this->SetTitle(wxString::Format("%s - %s - %dx%dpx", this->windowTitle, filename.GetFullName(), img.GetWidth(), img.GetHeight()));
                }
                wxImage resized = this->cropResizeImage(img, 100, 100);
                auto id = this->imgList->Add(resized);
                this->images.emplace(id, info);
            }
        }
    }
    this->m_image_list->SetImageList(this->imgList, wxIMAGE_LIST_NORMAL);
    this->m_image_list->SetImageList(this->imgList, wxIMAGE_LIST_SMALL);
    //  this->m_image_list->AssignImageList(this->imgList, wxIMAGE_LIST_NORMAL);
    int idx = 0;
    for (auto img : this->images)
    {
        long id = this->m_image_list->InsertItem(idx, img.second->file->GetFullName(), idx);
        this->m_image_list->SetItemPtrData(id, wxUIntPtr(img.second));
        idx++;
    }
}
void ImageViewerImageWindow::OnWindowKeyUp(wxKeyEvent &event)
{
    // TODO: implement F key as fullscreen
    if (this->IsFullScreen() && (event.GetKeyCode() == WXK_ESCAPE))
    {
        this->ShowFullScreen(false);
    }
}
void ImageViewerImageWindow::OnWindowMouseWheel(wxMouseEvent &event)
{
    // disabled, because when zoomed by button, we need scrollbar to scroll the image...
    return event.Skip();
    // only vertical to zoom
    if (event.GetWheelAxis() != wxMOUSE_WHEEL_VERTICAL)
    {
        return;
    }
    if (event.GetWheelRotation() < 0)
    {
        this->ZoomImage(5);
    }
    if (event.GetWheelRotation() > 0)
    {
        this->ZoomImage(+5);
    }
}
void ImageViewerImageWindow::WindowOnSize(wxSizeEvent &event)
{
    // TODO: Implement WindowOnSize
    if (this->currentVisibleImage.IsOk())
    {
        this->ShowImage(this->currentOriginalImage);
    }
    event.Skip();
}
void ImageViewerImageWindow::OnBitmapDoubleLeftClick(wxMouseEvent &event)
{
    if (this->IsFullScreen())
    {
        this->ShowFullScreen(false);
    }
    else
    {
        this->ShowFullScreen(true, wxFULLSCREEN_ALL);
    }
}
void ImageViewerImageWindow::OnListItemSelected(wxListEvent &event)
{
    wxUIntPtr dataPtr = this->m_image_list->GetItemData(event.GetIndex());
    ImageUtils::ImageFileInfo *fileinfo = reinterpret_cast<ImageUtils::ImageFileInfo *>(dataPtr);
    this->ShowImage(*fileinfo->img);
}
void ImageViewerImageWindow::OnRotateLeftClicked(wxCommandEvent &event)
{
    auto rotated = this->RotateImage(ImageUtils::LEFT, this->currentOriginalImage);
    this->currentVisibleImage = rotated;
    this->ShowImage(rotated);
}
void ImageViewerImageWindow::OnRotateRightClicked(wxCommandEvent &event)
{
    auto rotated = this->RotateImage(ImageUtils::RIGHT, this->currentOriginalImage);
    this->currentVisibleImage = rotated;
    this->ShowImage(rotated);
}
void ImageViewerImageWindow::OnZoomInClicked(wxCommandEvent &event)
{
    this->ZoomImage(5);
}
void ImageViewerImageWindow::OnZoomResetClicked(wxCommandEvent &event)
{
    this->ShowImage(this->currentOriginalImage);
}
void ImageViewerImageWindow::OnZoomOutClicked(wxCommandEvent &event)
{
    this->ZoomImage(-5);
}
void ImageViewerImageWindow::OnShowFullScreenClick(wxCommandEvent &event)
{
    this->ShowFullScreen(true, wxFULLSCREEN_ALL);
}
void ImageViewerImageWindow::ZoomImage(int factor)
{
    auto orig_width = this->currentOriginalImage.GetWidth();
    auto orig_height = this->currentOriginalImage.GetHeight();
    if (this->currentZoom + factor < 10 || this->currentZoom + factor > 200)
    {
        return;
    }
    this->currentZoom += factor;
    float zoomFactor = this->currentZoom / 100.0f;
    auto target_width = std::round(orig_width * zoomFactor);
    auto target_height = std::round(orig_height * zoomFactor);
    auto scaled = this->currentOriginalImage.Scale(target_width, target_height, wxIMAGE_QUALITY_HIGH);
    this->m_bitmap1->SetBitmap(scaled);
    this->m_bitmap1->SetSize(scaled.GetSize());
    this->m_bitmap1->Center();
    this->m_bitmap1->Refresh();
    this->currentVisibleImage = scaled;
    this->Layout();
    this->m_statusBar1->SetStatusText(wxString::Format("Zoom: %d Width: %d Height: %d Original Width: %d Height: %d",
                                                       this->currentZoom,
                                                       scaled.GetWidth(), scaled.GetHeight(), orig_width, orig_height));
}
wxImage ImageViewerImageWindow::FitImage(wxImage img, int targetWidth, int targetHeight)
{
    int originalWidth = img.GetWidth();
    int originalHeight = img.GetHeight();
    // Az arány megtartása
    float ratioWidth = static_cast<float>(targetWidth) / originalWidth;
    float ratioHeight = static_cast<float>(targetHeight) / originalHeight;
    float resizeRatio = (ratioWidth < ratioHeight) ? ratioWidth : ratioHeight;
    this->currentZoom = std::round(resizeRatio * 100);
    // Új méretek kiszámítása
    int width = static_cast<int>(originalWidth * resizeRatio);
    int height = static_cast<int>(originalHeight * resizeRatio);
    auto scaled = img.Scale(width, height, wxIMAGE_QUALITY_HIGH);
    this->m_statusBar1->SetStatusText(wxString::Format("Zoom: %d Width: %d Height: %d Original Width: %d Height: %d",
                                                       this->currentZoom,
                                                       scaled.GetWidth(), scaled.GetHeight(), img.GetWidth(), img.GetHeight()));
    return scaled;
}
void ImageViewerImageWindow::ShowImage(wxImage img)
{
    auto size = this->m_scrolledWindow1->GetClientSize();
    if (size.GetWidth() > img.GetWidth() && size.GetHeight() > img.GetHeight())
    {
        this->m_bitmap1->SetBitmap(img);
        this->m_bitmap1->SetSize(img.GetSize());
        this->currentVisibleImage = img;
    }
    else
    {
        auto scaled = this->FitImage(img, size.GetWidth(), size.GetHeight());
        this->m_bitmap1->SetSize(scaled.GetSize());
        this->m_bitmap1->SetBitmap(scaled);
        this->currentVisibleImage = scaled;
    }
    this->currentOriginalImage = img;
    this->m_bitmap1->Center();
    this->m_bitmap1->Refresh();
    this->Layout();
}
wxImage ImageViewerImageWindow::RotateImage(ImageUtils::ROTATE_DIRECTION dir, wxImage img)
{
    return img.Rotate90(dir == ImageUtils::ROTATE_DIRECTION::RIGHT);
}