fszontagh
2024-02-25 5d543bcc0d15b871315a2123aec01041d73c53fb
drag and drop
5 files modified
4 files added
995 ■■■■■ changed files
res/app_icon.h 59 ●●●●● patch | view | raw | blame | history
res/icons/16/reset_zoom.png patch | view | raw | blame | history
res/reset_zoom.png.h 58 ●●●●● patch | view | raw | blame | history
static/window.fbp 430 ●●●● patch | view | raw | blame | history
ui/ImageViewer.cpp 93 ●●●●● patch | view | raw | blame | history
ui/ImageViewer.h 24 ●●●●● patch | view | raw | blame | history
ui/ImageViewerImageWindow.cpp 235 ●●●●● patch | view | raw | blame | history
ui/ImageViewerImageWindow.h 76 ●●●●● patch | view | raw | blame | history
utils.h 20 ●●●●● patch | view | raw | blame | history
res/app_icon.h
New file
@@ -0,0 +1,59 @@
#ifndef APP_PNG_H
#define APP_PNG_H
#include <wx/mstream.h>
#include <wx/image.h>
#include <wx/bitmap.h>
inline static const unsigned char app_png[] =
{
    0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00,
    0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10,
    0x00, 0x00, 0x00, 0x10, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1F,
    0xF3, 0xFF, 0x61, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59,
    0x73, 0x00, 0x00, 0x09, 0xD7, 0x00, 0x00, 0x09, 0xD7, 0x01,
    0xB1, 0x6E, 0x17, 0xB7, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45,
    0x58, 0x74, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
    0x00, 0x77, 0x77, 0x77, 0x2E, 0x69, 0x6E, 0x6B, 0x73, 0x63,
    0x61, 0x70, 0x65, 0x2E, 0x6F, 0x72, 0x67, 0x9B, 0xEE, 0x3C,
    0x1A, 0x00, 0x00, 0x01, 0x07, 0x49, 0x44, 0x41, 0x54, 0x38,
    0x8D, 0x9D, 0xD3, 0xBF, 0x2B, 0x45, 0x61, 0x18, 0x07, 0xF0,
    0x0F, 0x09, 0x77, 0xBC, 0xC9, 0x70, 0x07, 0x56, 0x5D, 0x93,
    0x0C, 0xCA, 0xAE, 0x4C, 0x5C, 0x8B, 0x49, 0xB1, 0x59, 0x6D,
    0x14, 0x45, 0x26, 0xF9, 0x03, 0x98, 0x8C, 0x26, 0x37, 0x72,
    0xA3, 0x63, 0x91, 0x7F, 0x81, 0xBF, 0xC0, 0x64, 0x53, 0xCA,
    0x20, 0x4A, 0x61, 0x78, 0xCF, 0xBD, 0x1D, 0xD7, 0x79, 0xCF,
    0xC1, 0xB7, 0xDE, 0xE5, 0xF9, 0x3E, 0xDF, 0xE7, 0xF7, 0x4B,
    0x1C, 0x75, 0x34, 0xD3, 0x57, 0x2F, 0xF0, 0xFB, 0x81, 0x2A,
    0xF6, 0x70, 0x8C, 0x51, 0xD4, 0x70, 0x80, 0x43, 0x0C, 0x17,
    0x09, 0xFB, 0xB0, 0x8A, 0x4B, 0x4C, 0xE7, 0xF0, 0x93, 0x38,
    0xC7, 0x06, 0xFA, 0xBB, 0xC9, 0x19, 0x24, 0x58, 0x46, 0x4F,
    0x49, 0x85, 0x73, 0xB8, 0xC2, 0x62, 0xD6, 0xF8, 0x84, 0x23,
    0x0C, 0x95, 0x88, 0x61, 0x00, 0xDB, 0x78, 0xCB, 0x1A, 0x4F,
    0x30, 0x81, 0x16, 0xD6, 0x84, 0x76, 0x62, 0xD9, 0x93, 0x34,
    0x7B, 0x13, 0x7A, 0x33, 0xE4, 0x1D, 0x1A, 0xB8, 0x17, 0xE6,
    0x30, 0x9B, 0xE1, 0xA6, 0x84, 0xFE, 0xC7, 0xB1, 0x90, 0x8A,
    0x3F, 0x45, 0x32, 0x5D, 0xE0, 0x06, 0x9B, 0x58, 0x12, 0x66,
    0xF2, 0x80, 0x15, 0x3C, 0x77, 0x3B, 0xC7, 0x4A, 0x7D, 0xC1,
    0x96, 0x30, 0xD4, 0x0F, 0x61, 0xA5, 0xB9, 0x88, 0x05, 0x68,
    0xE3, 0xB5, 0x84, 0xFF, 0x36, 0x83, 0x7F, 0xA1, 0x1D, 0xA0,
    0x86, 0xCA, 0x1F, 0x74, 0x95, 0x54, 0xD3, 0x09, 0xB0, 0x8B,
    0x53, 0xBF, 0x3F, 0xA4, 0x33, 0xEC, 0x67, 0x03, 0x5C, 0x63,
    0x1E, 0x83, 0xC2, 0x16, 0x62, 0xA7, 0xDC, 0x12, 0x56, 0xD9,
    0x10, 0x56, 0x9D, 0x9B, 0xAD, 0x8A, 0x75, 0x8C, 0xE0, 0x16,
    0xEF, 0x18, 0x4B, 0x7D, 0x77, 0xF0, 0x58, 0x52, 0x61, 0x07,
    0x75, 0xE1, 0xEA, 0x12, 0x05, 0xDF, 0xF9, 0x0B, 0x82, 0x43,
    0x2C, 0xFB, 0x11, 0x35, 0x04, 0x4C, 0x00, 0x00, 0x00, 0x00,
    0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82,
};
inline wxBitmap& app_png_to_wx_bitmap()
{
    static wxMemoryInputStream memIStream( app_png, sizeof( app_png ) );
    static wxImage image( memIStream, wxBITMAP_TYPE_PNG );
    static wxBitmap bmp( image );
    return bmp;
}
#endif //APP_PNG_H
res/icons/16/reset_zoom.png
res/reset_zoom.png.h
New file
@@ -0,0 +1,58 @@
#ifndef RESET_ZOOM_PNG_H
#define RESET_ZOOM_PNG_H
#include <wx/mstream.h>
#include <wx/image.h>
#include <wx/bitmap.h>
static const unsigned char reset_zoom_png[] =
{
    0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00,
    0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10,
    0x00, 0x00, 0x00, 0x10, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1F,
    0xF3, 0xFF, 0x61, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59,
    0x73, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01,
    0x4E, 0x7B, 0x26, 0x08, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45,
    0x58, 0x74, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
    0x00, 0x77, 0x77, 0x77, 0x2E, 0x69, 0x6E, 0x6B, 0x73, 0x63,
    0x61, 0x70, 0x65, 0x2E, 0x6F, 0x72, 0x67, 0x9B, 0xEE, 0x3C,
    0x1A, 0x00, 0x00, 0x00, 0xF9, 0x49, 0x44, 0x41, 0x54, 0x38,
    0x8D, 0x8D, 0xD2, 0x3D, 0x4E, 0xC3, 0x40, 0x14, 0x04, 0xE0,
    0x8F, 0x74, 0x40, 0x0D, 0x71, 0xAE, 0x81, 0xA8, 0x91, 0x68,
    0x29, 0xD2, 0x40, 0x38, 0x07, 0x14, 0xF4, 0x21, 0x50, 0x72,
    0x17, 0x24, 0x44, 0x90, 0xE8, 0xE8, 0x91, 0x20, 0x51, 0xCA,
    0x70, 0x06, 0xB0, 0xC4, 0x6F, 0x13, 0x4C, 0xC1, 0x73, 0xEC,
    0x20, 0x1C, 0x7B, 0xA4, 0xD5, 0xAE, 0x66, 0x67, 0xE6, 0xAD,
    0xAD, 0x61, 0x11, 0x09, 0xCE, 0xF1, 0x88, 0x37, 0x7C, 0x61,
    0x84, 0x01, 0xDA, 0x6A, 0x70, 0x88, 0x14, 0x59, 0xC5, 0x7A,
    0x41, 0xAF, 0xCA, 0xBC, 0x8F, 0x59, 0x08, 0xEF, 0xD0, 0x45,
    0x27, 0x5E, 0xB4, 0x87, 0xDB, 0xB8, 0x9B, 0xC5, 0xA0, 0x05,
    0xB4, 0xF1, 0x1C, 0x82, 0x0B, 0xAC, 0x54, 0x0C, 0xE9, 0x87,
    0x26, 0x8D, 0xE0, 0x39, 0x4E, 0x4B, 0x93, 0xAB, 0xCC, 0x39,
    0x86, 0xA1, 0x1D, 0x94, 0xC9, 0x51, 0x90, 0xDD, 0x1A, 0x33,
    0xEC, 0x86, 0xF6, 0xA1, 0x4C, 0xBE, 0x07, 0xD9, 0x69, 0x10,
    0xB0, 0x1E, 0xDA, 0xD7, 0x9C, 0x68, 0xE1, 0x3B, 0xCE, 0x59,
    0x83, 0x80, 0x5C, 0x33, 0xFF, 0xD4, 0x16, 0x9E, 0xE2, 0xBC,
    0xD5, 0x20, 0x60, 0x3B, 0xF6, 0x69, 0x39, 0xE0, 0x3A, 0xCE,
    0x47, 0x0D, 0x02, 0x8E, 0x63, 0xBF, 0x2A, 0x93, 0x89, 0xA2,
    0x40, 0xFD, 0x25, 0xE6, 0x13, 0x45, 0xA1, 0x36, 0xFF, 0x5E,
    0xF6, 0x14, 0x45, 0x1A, 0xFA, 0xFD, 0xDB, 0x6B, 0x58, 0xC5,
    0x0E, 0x2E, 0x15, 0x8D, 0x9C, 0x62, 0xE3, 0xBF, 0x09, 0x07,
    0x96, 0x57, 0x39, 0x0D, 0x73, 0x86, 0x49, 0x55, 0x48, 0x82,
    0x33, 0x8C, 0xF1, 0x11, 0x6B, 0x1C, 0x5C, 0x12, 0xA6, 0x49,
    0x5D, 0x48, 0x1D, 0xCA, 0x21, 0xF7, 0x75, 0xD5, 0x5D, 0x16,
    0x72, 0x83, 0xCF, 0x1F, 0xDB, 0x6E, 0x50, 0x80, 0x96, 0x46,
    0x9A, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44,
    0xAE, 0x42, 0x60, 0x82,
};
wxBitmap& reset_zoom_png_to_wx_bitmap()
{
    static wxMemoryInputStream memIStream( reset_zoom_png, sizeof( reset_zoom_png ) );
    static wxImage image( memIStream, wxBITMAP_TYPE_PNG );
    static wxBitmap bmp( image );
    return bmp;
}
#endif //RESET_ZOOM_PNG_H
static/window.fbp
@@ -32,7 +32,7 @@
    <object class="Frame" expanded="true">
      <property name="aui_managed">0</property>
      <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
      <property name="bg"></property>
      <property name="bg">60,60,60</property>
      <property name="center">wxBOTH</property>
      <property name="context_help"></property>
      <property name="context_menu">1</property>
@@ -48,7 +48,7 @@
      <property name="minimum_size"></property>
      <property name="name">ImageWindow</property>
      <property name="pos"></property>
      <property name="size">500,300</property>
      <property name="size">800,600</property>
      <property name="style">wxDEFAULT_FRAME_STYLE</property>
      <property name="subclass">; ; forward_declare</property>
      <property name="title">Image viewer</property>
@@ -58,6 +58,9 @@
      <property name="window_name"></property>
      <property name="window_style">wxTAB_TRAVERSAL</property>
      <property name="xrc_skip_sizer">1</property>
      <event name="OnDropFiles">OnDropFile</event>
      <event name="OnKeyUp">OnWindowKeyUp</event>
      <event name="OnMouseWheel">OnWindowMouseWheel</event>
      <object class="wxBoxSizer" expanded="true">
        <property name="minimum_size"></property>
        <property name="name">bSizer1</property>
@@ -65,61 +68,345 @@
        <property name="permission">none</property>
        <object class="sizeritem" expanded="true">
          <property name="border">5</property>
          <property name="flag">wxALL|wxEXPAND</property>
          <property name="flag">wxEXPAND</property>
          <property name="proportion">1</property>
          <object class="wxStaticBitmap" expanded="true">
            <property name="BottomDockable">1</property>
            <property name="LeftDockable">1</property>
            <property name="RightDockable">1</property>
            <property name="TopDockable">1</property>
            <property name="aui_layer"></property>
            <property name="aui_name"></property>
            <property name="aui_position"></property>
            <property name="aui_row"></property>
            <property name="best_size"></property>
            <property name="bg"></property>
            <property name="bitmap"></property>
            <property name="caption"></property>
            <property name="caption_visible">1</property>
            <property name="center_pane">0</property>
            <property name="close_button">1</property>
            <property name="context_help"></property>
            <property name="context_menu">1</property>
            <property name="default_pane">0</property>
            <property name="dock">Dock</property>
            <property name="dock_fixed">0</property>
            <property name="docking">Left</property>
            <property name="drag_accept_files">0</property>
            <property name="enabled">1</property>
            <property name="fg"></property>
            <property name="floatable">1</property>
            <property name="font"></property>
            <property name="gripper">0</property>
            <property name="hidden">0</property>
            <property name="id">wxID_ANY</property>
            <property name="max_size"></property>
            <property name="maximize_button">0</property>
            <property name="maximum_size"></property>
            <property name="min_size"></property>
            <property name="minimize_button">0</property>
            <property name="minimum_size"></property>
            <property name="moveable">1</property>
            <property name="name">m_bitmap1</property>
            <property name="pane_border">1</property>
            <property name="pane_position"></property>
            <property name="pane_size"></property>
            <property name="permission">protected</property>
            <property name="pin_button">1</property>
            <property name="pos"></property>
            <property name="resize">Resizable</property>
            <property name="show">1</property>
            <property name="size"></property>
            <property name="subclass">; ; forward_declare</property>
            <property name="toolbar_pane">0</property>
            <property name="tooltip"></property>
            <property name="window_extra_style"></property>
            <property name="window_name"></property>
            <property name="window_style"></property>
          <object class="wxBoxSizer" expanded="true">
            <property name="minimum_size">-1,-1</property>
            <property name="name">bSizer6</property>
            <property name="orient">wxHORIZONTAL</property>
            <property name="permission">none</property>
            <object class="sizeritem" expanded="true">
              <property name="border">5</property>
              <property name="flag">wxEXPAND</property>
              <property name="proportion">1</property>
              <object class="wxScrolledWindow" expanded="true">
                <property name="BottomDockable">1</property>
                <property name="LeftDockable">1</property>
                <property name="RightDockable">1</property>
                <property name="TopDockable">1</property>
                <property name="aui_layer"></property>
                <property name="aui_name"></property>
                <property name="aui_position"></property>
                <property name="aui_row"></property>
                <property name="best_size"></property>
                <property name="bg"></property>
                <property name="caption"></property>
                <property name="caption_visible">1</property>
                <property name="center_pane">0</property>
                <property name="close_button">1</property>
                <property name="context_help"></property>
                <property name="context_menu">1</property>
                <property name="default_pane">0</property>
                <property name="dock">Dock</property>
                <property name="dock_fixed">0</property>
                <property name="docking">Left</property>
                <property name="drag_accept_files">0</property>
                <property name="enabled">1</property>
                <property name="fg"></property>
                <property name="floatable">1</property>
                <property name="font"></property>
                <property name="gripper">0</property>
                <property name="hidden">0</property>
                <property name="id">wxID_ANY</property>
                <property name="max_size"></property>
                <property name="maximize_button">0</property>
                <property name="maximum_size"></property>
                <property name="min_size"></property>
                <property name="minimize_button">0</property>
                <property name="minimum_size"></property>
                <property name="moveable">1</property>
                <property name="name">m_scrolledWindow1</property>
                <property name="pane_border">1</property>
                <property name="pane_position"></property>
                <property name="pane_size"></property>
                <property name="permission">protected</property>
                <property name="pin_button">1</property>
                <property name="pos"></property>
                <property name="resize">Resizable</property>
                <property name="scroll_rate_x">5</property>
                <property name="scroll_rate_y">5</property>
                <property name="show">1</property>
                <property name="size"></property>
                <property name="subclass">; ; forward_declare</property>
                <property name="toolbar_pane">0</property>
                <property name="tooltip"></property>
                <property name="window_extra_style"></property>
                <property name="window_name"></property>
                <property name="window_style">wxHSCROLL|wxVSCROLL</property>
                <event name="OnKeyUp">OnWindowKeyUp</event>
                <event name="OnUpdateUI">WindowOnSize</event>
                <object class="wxBoxSizer" expanded="true">
                  <property name="minimum_size"></property>
                  <property name="name">bSizer3</property>
                  <property name="orient">wxVERTICAL</property>
                  <property name="permission">none</property>
                  <object class="sizeritem" expanded="false">
                    <property name="border">5</property>
                    <property name="flag">wxEXPAND</property>
                    <property name="proportion">1</property>
                    <object class="wxStaticBitmap" expanded="false">
                      <property name="BottomDockable">1</property>
                      <property name="LeftDockable">1</property>
                      <property name="RightDockable">1</property>
                      <property name="TopDockable">1</property>
                      <property name="aui_layer"></property>
                      <property name="aui_name"></property>
                      <property name="aui_position"></property>
                      <property name="aui_row"></property>
                      <property name="best_size"></property>
                      <property name="bg"></property>
                      <property name="bitmap"></property>
                      <property name="caption"></property>
                      <property name="caption_visible">1</property>
                      <property name="center_pane">0</property>
                      <property name="close_button">1</property>
                      <property name="context_help"></property>
                      <property name="context_menu">1</property>
                      <property name="default_pane">0</property>
                      <property name="dock">Dock</property>
                      <property name="dock_fixed">0</property>
                      <property name="docking">Left</property>
                      <property name="drag_accept_files">0</property>
                      <property name="enabled">1</property>
                      <property name="fg"></property>
                      <property name="floatable">1</property>
                      <property name="font"></property>
                      <property name="gripper">0</property>
                      <property name="hidden">0</property>
                      <property name="id">wxID_ANY</property>
                      <property name="max_size"></property>
                      <property name="maximize_button">0</property>
                      <property name="maximum_size"></property>
                      <property name="min_size"></property>
                      <property name="minimize_button">0</property>
                      <property name="minimum_size"></property>
                      <property name="moveable">1</property>
                      <property name="name">m_bitmap1</property>
                      <property name="pane_border">1</property>
                      <property name="pane_position"></property>
                      <property name="pane_size"></property>
                      <property name="permission">protected</property>
                      <property name="pin_button">1</property>
                      <property name="pos"></property>
                      <property name="resize">Resizable</property>
                      <property name="show">1</property>
                      <property name="size"></property>
                      <property name="subclass">; ; forward_declare</property>
                      <property name="toolbar_pane">0</property>
                      <property name="tooltip"></property>
                      <property name="window_extra_style"></property>
                      <property name="window_name"></property>
                      <property name="window_style"></property>
                      <event name="OnLeftDClick">OnBitmapDoubleLeftClick</event>
                    </object>
                  </object>
                </object>
              </object>
            </object>
            <object class="sizeritem" expanded="true">
              <property name="border">5</property>
              <property name="flag">wxEXPAND</property>
              <property name="proportion">0</property>
              <object class="wxScrolledWindow" expanded="true">
                <property name="BottomDockable">1</property>
                <property name="LeftDockable">1</property>
                <property name="RightDockable">1</property>
                <property name="TopDockable">1</property>
                <property name="aui_layer"></property>
                <property name="aui_name"></property>
                <property name="aui_position"></property>
                <property name="aui_row"></property>
                <property name="best_size"></property>
                <property name="bg"></property>
                <property name="caption"></property>
                <property name="caption_visible">1</property>
                <property name="center_pane">0</property>
                <property name="close_button">1</property>
                <property name="context_help"></property>
                <property name="context_menu">1</property>
                <property name="default_pane">0</property>
                <property name="dock">Dock</property>
                <property name="dock_fixed">0</property>
                <property name="docking">Left</property>
                <property name="drag_accept_files">0</property>
                <property name="enabled">1</property>
                <property name="fg"></property>
                <property name="floatable">1</property>
                <property name="font"></property>
                <property name="gripper">0</property>
                <property name="hidden">0</property>
                <property name="id">wxID_ANY</property>
                <property name="max_size"></property>
                <property name="maximize_button">0</property>
                <property name="maximum_size">-1,-1</property>
                <property name="min_size"></property>
                <property name="minimize_button">0</property>
                <property name="minimum_size">100,-1</property>
                <property name="moveable">1</property>
                <property name="name">m_scrolledWindow3</property>
                <property name="pane_border">1</property>
                <property name="pane_position"></property>
                <property name="pane_size"></property>
                <property name="permission">protected</property>
                <property name="pin_button">1</property>
                <property name="pos"></property>
                <property name="resize">Resizable</property>
                <property name="scroll_rate_x">5</property>
                <property name="scroll_rate_y">5</property>
                <property name="show">1</property>
                <property name="size">-1,-1</property>
                <property name="subclass">; ; forward_declare</property>
                <property name="toolbar_pane">0</property>
                <property name="tooltip"></property>
                <property name="window_extra_style"></property>
                <property name="window_name"></property>
                <property name="window_style">wxHSCROLL|wxVSCROLL</property>
                <object class="wxBoxSizer" expanded="true">
                  <property name="minimum_size"></property>
                  <property name="name">bSizer7</property>
                  <property name="orient">wxVERTICAL</property>
                  <property name="permission">none</property>
                  <object class="sizeritem" expanded="false">
                    <property name="border">5</property>
                    <property name="flag">wxEXPAND</property>
                    <property name="proportion">1</property>
                    <object class="wxListCtrl" expanded="false">
                      <property name="BottomDockable">1</property>
                      <property name="LeftDockable">1</property>
                      <property name="RightDockable">1</property>
                      <property name="TopDockable">1</property>
                      <property name="aui_layer"></property>
                      <property name="aui_name"></property>
                      <property name="aui_position"></property>
                      <property name="aui_row"></property>
                      <property name="best_size"></property>
                      <property name="bg"></property>
                      <property name="caption"></property>
                      <property name="caption_visible">1</property>
                      <property name="center_pane">0</property>
                      <property name="close_button">1</property>
                      <property name="context_help"></property>
                      <property name="context_menu">1</property>
                      <property name="default_pane">0</property>
                      <property name="dock">Dock</property>
                      <property name="dock_fixed">0</property>
                      <property name="docking">Left</property>
                      <property name="drag_accept_files">0</property>
                      <property name="enabled">1</property>
                      <property name="fg"></property>
                      <property name="floatable">1</property>
                      <property name="font"></property>
                      <property name="gripper">0</property>
                      <property name="hidden">0</property>
                      <property name="id">wxID_ANY</property>
                      <property name="max_size"></property>
                      <property name="maximize_button">0</property>
                      <property name="maximum_size"></property>
                      <property name="min_size"></property>
                      <property name="minimize_button">0</property>
                      <property name="minimum_size"></property>
                      <property name="moveable">1</property>
                      <property name="name">m_details</property>
                      <property name="pane_border">1</property>
                      <property name="pane_position"></property>
                      <property name="pane_size"></property>
                      <property name="permission">protected</property>
                      <property name="pin_button">1</property>
                      <property name="pos"></property>
                      <property name="resize">Resizable</property>
                      <property name="show">1</property>
                      <property name="size">100,-1</property>
                      <property name="style">wxLC_SINGLE_SEL</property>
                      <property name="subclass">; ; forward_declare</property>
                      <property name="toolbar_pane">0</property>
                      <property name="tooltip"></property>
                      <property name="validator_data_type"></property>
                      <property name="validator_style">wxFILTER_NONE</property>
                      <property name="validator_type">wxDefaultValidator</property>
                      <property name="validator_variable"></property>
                      <property name="window_extra_style"></property>
                      <property name="window_name"></property>
                      <property name="window_style"></property>
                    </object>
                  </object>
                </object>
              </object>
            </object>
          </object>
        </object>
        <object class="sizeritem" expanded="true">
          <property name="border">5</property>
          <property name="flag">wxEXPAND</property>
          <property name="proportion">0</property>
          <object class="wxBoxSizer" expanded="true">
            <property name="minimum_size">-1,100</property>
            <property name="name">bSizer5</property>
            <property name="orient">wxVERTICAL</property>
            <property name="permission">none</property>
            <object class="sizeritem" expanded="false">
              <property name="border">5</property>
              <property name="flag">wxEXPAND</property>
              <property name="proportion">1</property>
              <object class="wxListCtrl" expanded="false">
                <property name="BottomDockable">1</property>
                <property name="LeftDockable">1</property>
                <property name="RightDockable">1</property>
                <property name="TopDockable">1</property>
                <property name="aui_layer"></property>
                <property name="aui_name"></property>
                <property name="aui_position"></property>
                <property name="aui_row"></property>
                <property name="best_size"></property>
                <property name="bg"></property>
                <property name="caption"></property>
                <property name="caption_visible">1</property>
                <property name="center_pane">0</property>
                <property name="close_button">1</property>
                <property name="context_help"></property>
                <property name="context_menu">1</property>
                <property name="default_pane">0</property>
                <property name="dock">Dock</property>
                <property name="dock_fixed">0</property>
                <property name="docking">Left</property>
                <property name="drag_accept_files">0</property>
                <property name="enabled">1</property>
                <property name="fg"></property>
                <property name="floatable">1</property>
                <property name="font"></property>
                <property name="gripper">0</property>
                <property name="hidden">0</property>
                <property name="id">wxID_ANY</property>
                <property name="max_size"></property>
                <property name="maximize_button">0</property>
                <property name="maximum_size"></property>
                <property name="min_size"></property>
                <property name="minimize_button">0</property>
                <property name="minimum_size"></property>
                <property name="moveable">1</property>
                <property name="name">m_image_list</property>
                <property name="pane_border">1</property>
                <property name="pane_position"></property>
                <property name="pane_size"></property>
                <property name="permission">protected</property>
                <property name="pin_button">1</property>
                <property name="pos"></property>
                <property name="resize">Resizable</property>
                <property name="show">1</property>
                <property name="size">-1,140</property>
                <property name="style">wxLC_ICON</property>
                <property name="subclass">; ; forward_declare</property>
                <property name="toolbar_pane">0</property>
                <property name="tooltip"></property>
                <property name="validator_data_type"></property>
                <property name="validator_style">wxFILTER_NONE</property>
                <property name="validator_type">wxDefaultValidator</property>
                <property name="validator_variable"></property>
                <property name="window_extra_style"></property>
                <property name="window_name"></property>
                <property name="window_style"></property>
                <event name="OnListItemSelected">OnListItemSelected</event>
              </object>
            </object>
          </object>
        </object>
      </object>
@@ -212,8 +499,8 @@
          <property name="label">Open image</property>
          <property name="name">m_open_image</property>
          <property name="permission">protected</property>
          <property name="statusbar"></property>
          <property name="tooltip"></property>
          <property name="statusbar">Open a supported image file. (png, jpeg)</property>
          <property name="tooltip">Open an image (jpeg,png)</property>
        </object>
        <object class="toolSeparator" expanded="true">
          <property name="permission">protected</property>
@@ -227,7 +514,8 @@
          <property name="name">m_rotate_left</property>
          <property name="permission">protected</property>
          <property name="statusbar"></property>
          <property name="tooltip"></property>
          <property name="tooltip">Rotate the image -90°</property>
          <event name="OnToolClicked">OnRotateLeftClicked</event>
        </object>
        <object class="tool" expanded="true">
          <property name="bitmap">Load From Embedded File; ../res/icons/16/rotate_right.png</property>
@@ -238,7 +526,8 @@
          <property name="name">m_rotate_right</property>
          <property name="permission">protected</property>
          <property name="statusbar"></property>
          <property name="tooltip"></property>
          <property name="tooltip">Rotate the image +90°</property>
          <event name="OnToolClicked">OnRotateRightClicked</event>
        </object>
        <object class="tool" expanded="true">
          <property name="bitmap">Load From Embedded File; ../res/icons/16/zoom_in.png</property>
@@ -249,7 +538,20 @@
          <property name="name">m_zoom_in</property>
          <property name="permission">protected</property>
          <property name="statusbar"></property>
          <property name="tooltip"></property>
          <property name="tooltip">Zoom-in the image by 5%</property>
          <event name="OnToolClicked">OnZoomInClicked</event>
        </object>
        <object class="tool" expanded="true">
          <property name="bitmap">Load From Embedded File; ../res/icons/16/reset_zoom.png</property>
          <property name="context_menu">0</property>
          <property name="id">wxID_ANY</property>
          <property name="kind">wxITEM_NORMAL</property>
          <property name="label">Reset zoom</property>
          <property name="name">m_reset_zoom</property>
          <property name="permission">protected</property>
          <property name="statusbar"></property>
          <property name="tooltip">Reset the zoom to fit into the window</property>
          <event name="OnToolClicked">OnZoomResetClicked</event>
        </object>
        <object class="tool" expanded="true">
          <property name="bitmap">Load From Embedded File; ../res/icons/16/zoom_out.png</property>
@@ -260,7 +562,8 @@
          <property name="name">m_zoom_out</property>
          <property name="permission">protected</property>
          <property name="statusbar"></property>
          <property name="tooltip"></property>
          <property name="tooltip">Zoom-out the image by 5%</property>
          <event name="OnToolClicked">OnZoomOutClicked</event>
        </object>
        <object class="tool" expanded="true">
          <property name="bitmap">Load From Embedded File; ../res/icons/16/fullscreen.png</property>
@@ -271,7 +574,8 @@
          <property name="name">m_fullscreen</property>
          <property name="permission">protected</property>
          <property name="statusbar"></property>
          <property name="tooltip"></property>
          <property name="tooltip">Show in fullscreen</property>
          <event name="OnToolClicked">OnShowFullScreenClick</event>
        </object>
      </object>
    </object>
ui/ImageViewer.cpp
@@ -9,6 +9,7 @@
#include "../res/add_image.png.h"
#include "../res/fullscreen.png.h"
#include "../res/reset_zoom.png.h"
#include "../res/rotate_left.png.h"
#include "../res/rotate_right.png.h"
#include "../res/zoom_in.png.h"
@@ -36,39 +37,115 @@
ImageWindow::ImageWindow( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
    this->SetSizeHints( wxDefaultSize, wxDefaultSize );
    this->SetBackgroundColour( wxColour( 60, 60, 60 ) );
    this->DragAcceptFiles( true );
    wxBoxSizer* bSizer1;
    bSizer1 = new wxBoxSizer( wxVERTICAL );
    m_bitmap1 = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
    bSizer1->Add( m_bitmap1, 1, wxALL|wxEXPAND, 5 );
    wxBoxSizer* bSizer6;
    bSizer6 = new wxBoxSizer( wxHORIZONTAL );
    m_scrolledWindow1 = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
    m_scrolledWindow1->SetScrollRate( 5, 5 );
    wxBoxSizer* bSizer3;
    bSizer3 = new wxBoxSizer( wxVERTICAL );
    m_bitmap1 = new wxStaticBitmap( m_scrolledWindow1, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
    bSizer3->Add( m_bitmap1, 1, wxEXPAND, 5 );
    m_scrolledWindow1->SetSizer( bSizer3 );
    m_scrolledWindow1->Layout();
    bSizer3->Fit( m_scrolledWindow1 );
    bSizer6->Add( m_scrolledWindow1, 1, wxEXPAND, 5 );
    m_scrolledWindow3 = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxHSCROLL|wxVSCROLL );
    m_scrolledWindow3->SetScrollRate( 5, 5 );
    m_scrolledWindow3->SetMinSize( wxSize( 100,-1 ) );
    wxBoxSizer* bSizer7;
    bSizer7 = new wxBoxSizer( wxVERTICAL );
    m_details = new wxListCtrl( m_scrolledWindow3, wxID_ANY, wxDefaultPosition, wxSize( 100,-1 ), wxLC_SINGLE_SEL );
    bSizer7->Add( m_details, 1, wxEXPAND, 5 );
    m_scrolledWindow3->SetSizer( bSizer7 );
    m_scrolledWindow3->Layout();
    bSizer7->Fit( m_scrolledWindow3 );
    bSizer6->Add( m_scrolledWindow3, 0, wxEXPAND, 5 );
    bSizer1->Add( bSizer6, 1, wxEXPAND, 5 );
    wxBoxSizer* bSizer5;
    bSizer5 = new wxBoxSizer( wxVERTICAL );
    bSizer5->SetMinSize( wxSize( -1,100 ) );
    m_image_list = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxSize( -1,140 ), wxLC_ICON );
    bSizer5->Add( m_image_list, 1, wxEXPAND, 5 );
    bSizer1->Add( bSizer5, 0, wxEXPAND, 5 );
    this->SetSizer( bSizer1 );
    this->Layout();
    m_statusBar1 = this->CreateStatusBar( 1, wxSTB_SIZEGRIP, wxID_ANY );
    m_toolBar1 = this->CreateToolBar( wxTB_DOCKABLE|wxTB_HORIZONTAL, wxID_ANY );
    m_open_image = m_toolBar1->AddTool( wxID_ANY, _("Open image"), add_image_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
    m_open_image = m_toolBar1->AddTool( wxID_ANY, _("Open image"), add_image_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, _("Open an image (jpeg,png)"), _("Open a supported image file. (png, jpeg)"), NULL );
    m_toolBar1->AddSeparator();
    m_rotate_left = m_toolBar1->AddTool( wxID_ANY, _("Rotate -90"), rotate_left_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
    m_rotate_left = m_toolBar1->AddTool( wxID_ANY, _("Rotate -90"), rotate_left_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, _("Rotate the image -90°"), wxEmptyString, NULL );
    m_rotate_right = m_toolBar1->AddTool( wxID_ANY, _("Rotate +90"), rotate_right_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
    m_rotate_right = m_toolBar1->AddTool( wxID_ANY, _("Rotate +90"), rotate_right_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, _("Rotate the image +90°"), wxEmptyString, NULL );
    m_zoom_in = m_toolBar1->AddTool( wxID_ANY, _("Zoom in"), zoom_in_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
    m_zoom_in = m_toolBar1->AddTool( wxID_ANY, _("Zoom in"), zoom_in_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, _("Zoom-in the image by 5%"), wxEmptyString, NULL );
    m_zoom_out = m_toolBar1->AddTool( wxID_ANY, _("Zoom out"), zoom_out_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
    m_reset_zoom = m_toolBar1->AddTool( wxID_ANY, _("Reset zoom"), reset_zoom_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, _("Reset the zoom to fit into the window"), wxEmptyString, NULL );
    m_fullscreen = m_toolBar1->AddTool( wxID_ANY, _("Fullscreen"), fullscreen_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
    m_zoom_out = m_toolBar1->AddTool( wxID_ANY, _("Zoom out"), zoom_out_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, _("Zoom-out the image by 5%"), wxEmptyString, NULL );
    m_fullscreen = m_toolBar1->AddTool( wxID_ANY, _("Fullscreen"), fullscreen_png_to_wx_bitmap(), wxNullBitmap, wxITEM_NORMAL, _("Show in fullscreen"), wxEmptyString, NULL );
    m_toolBar1->Realize();
    this->Centre( wxBOTH );
    // Connect Events
    this->Connect( wxEVT_DROP_FILES, wxDropFilesEventHandler( ImageWindow::OnDropFile ) );
    this->Connect( wxEVT_KEY_UP, wxKeyEventHandler( ImageWindow::OnWindowKeyUp ) );
    this->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( ImageWindow::OnWindowMouseWheel ) );
    m_scrolledWindow1->Connect( wxEVT_KEY_UP, wxKeyEventHandler( ImageWindow::OnWindowKeyUp ), NULL, this );
    m_scrolledWindow1->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( ImageWindow::WindowOnSize ), NULL, this );
    m_bitmap1->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( ImageWindow::OnBitmapDoubleLeftClick ), NULL, this );
    m_image_list->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( ImageWindow::OnListItemSelected ), NULL, this );
    this->Connect( m_rotate_left->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( ImageWindow::OnRotateLeftClicked ) );
    this->Connect( m_rotate_right->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( ImageWindow::OnRotateRightClicked ) );
    this->Connect( m_zoom_in->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( ImageWindow::OnZoomInClicked ) );
    this->Connect( m_reset_zoom->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( ImageWindow::OnZoomResetClicked ) );
    this->Connect( m_zoom_out->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( ImageWindow::OnZoomOutClicked ) );
    this->Connect( m_fullscreen->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( ImageWindow::OnShowFullScreenClick ) );
}
ImageWindow::~ImageWindow()
{
    // Disconnect Events
    this->Disconnect( wxEVT_DROP_FILES, wxDropFilesEventHandler( ImageWindow::OnDropFile ) );
    this->Disconnect( wxEVT_KEY_UP, wxKeyEventHandler( ImageWindow::OnWindowKeyUp ) );
    this->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( ImageWindow::OnWindowMouseWheel ) );
    m_scrolledWindow1->Disconnect( wxEVT_KEY_UP, wxKeyEventHandler( ImageWindow::OnWindowKeyUp ), NULL, this );
    m_scrolledWindow1->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( ImageWindow::WindowOnSize ), NULL, this );
    m_bitmap1->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( ImageWindow::OnBitmapDoubleLeftClick ), NULL, this );
    m_image_list->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( ImageWindow::OnListItemSelected ), NULL, this );
    this->Disconnect( m_rotate_left->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( ImageWindow::OnRotateLeftClicked ) );
    this->Disconnect( m_rotate_right->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( ImageWindow::OnRotateRightClicked ) );
    this->Disconnect( m_zoom_in->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( ImageWindow::OnZoomInClicked ) );
    this->Disconnect( m_reset_zoom->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( ImageWindow::OnZoomResetClicked ) );
    this->Disconnect( m_zoom_out->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( ImageWindow::OnZoomOutClicked ) );
    this->Disconnect( m_fullscreen->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( ImageWindow::OnShowFullScreenClick ) );
}
ui/ImageViewer.h
@@ -21,6 +21,8 @@
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/sizer.h>
#include <wx/scrolwin.h>
#include <wx/listctrl.h>
#include <wx/statusbr.h>
#include <wx/toolbar.h>
#include <wx/frame.h>
@@ -36,19 +38,39 @@
    private:
    protected:
        wxScrolledWindow* m_scrolledWindow1;
        wxStaticBitmap* m_bitmap1;
        wxScrolledWindow* m_scrolledWindow3;
        wxListCtrl* m_details;
        wxListCtrl* m_image_list;
        wxStatusBar* m_statusBar1;
        wxToolBar* m_toolBar1;
        wxToolBarToolBase* m_open_image;
        wxToolBarToolBase* m_rotate_left;
        wxToolBarToolBase* m_rotate_right;
        wxToolBarToolBase* m_zoom_in;
        wxToolBarToolBase* m_reset_zoom;
        wxToolBarToolBase* m_zoom_out;
        wxToolBarToolBase* m_fullscreen;
        // Virtual event handlers, override them in your derived class
        virtual void OnDropFile( wxDropFilesEvent& event ) { event.Skip(); }
        virtual void OnWindowKeyUp( wxKeyEvent& event ) { event.Skip(); }
        virtual void OnWindowMouseWheel( wxMouseEvent& event ) { event.Skip(); }
        virtual void WindowOnSize( wxUpdateUIEvent& event ) { event.Skip(); }
        virtual void OnBitmapDoubleLeftClick( wxMouseEvent& event ) { event.Skip(); }
        virtual void OnListItemSelected( wxListEvent& event ) { event.Skip(); }
        virtual void OnRotateLeftClicked( wxCommandEvent& event ) { event.Skip(); }
        virtual void OnRotateRightClicked( wxCommandEvent& event ) { event.Skip(); }
        virtual void OnZoomInClicked( wxCommandEvent& event ) { event.Skip(); }
        virtual void OnZoomResetClicked( wxCommandEvent& event ) { event.Skip(); }
        virtual void OnZoomOutClicked( wxCommandEvent& event ) { event.Skip(); }
        virtual void OnShowFullScreenClick( wxCommandEvent& event ) { event.Skip(); }
    public:
        ImageWindow( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Image viewer"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,300 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
        ImageWindow( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Image viewer"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 800,600 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
        ~ImageWindow();
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);
}
ui/ImageViewerImageWindow.h
@@ -9,17 +9,87 @@
#include "ImageViewer.h"
//// end generated include
#include <map>
#include <iostream>
#include "../res/app_icon.h"
#include "../utils.h"
/** Implementing ImageWindow */
class ImageViewerImageWindow : public ImageWindow
{
    public:
        /** Constructor */
        ImageViewerImageWindow( wxWindow* parent );
protected:
    // Handlers for ImageWindow events.
    void OnDropFile(wxDropFilesEvent &event);
    void OnWindowKeyUp(wxKeyEvent &event);
    void OnWindowMouseWheel(wxMouseEvent &event);
    void WindowOnSize(wxSizeEvent &event);
    void OnBitmapDoubleLeftClick(wxMouseEvent &event);
    void OnListItemSelected(wxListEvent &event);
    void OnRotateLeftClicked(wxCommandEvent &event);
    void OnRotateRightClicked(wxCommandEvent &event);
    void OnZoomInClicked(wxCommandEvent &event);
    void OnZoomResetClicked(wxCommandEvent &event);
    void OnZoomOutClicked(wxCommandEvent &event);
    void OnShowFullScreenClick(wxCommandEvent &event);
public:
    /** Constructor */
    ImageViewerImageWindow(wxWindow *parent);
    //// end generated class members
private:
    wxString windowTitle;
    /// @brief int imagelist id, wxImage the image
    std::map<int, ImageUtils::ImageFileInfo *> images;
    wxImage currentVisibleImage;
    wxImage currentOriginalImage;
    wxImageList *imgList;
    int currentZoom = 100;
    void ShowImage(wxImage img);
    wxImage FitImage(wxImage img, int targetWidth, int targetHeight);
    wxImage RotateImage(ImageUtils::ROTATE_DIRECTION dir, wxImage img);
    void ZoomImage(int factor);
    inline wxImage cropResizeImage(const wxImage &originalImage, int targetWidth, int targetHeight)
    {
        int originalWidth = originalImage.GetWidth();
        int originalHeight = originalImage.GetHeight();
        double aspectRatio = static_cast<double>(originalWidth) / static_cast<double>(originalHeight);
        int newWidth = targetWidth;
        int newHeight = targetHeight;
        // Kiszámítjuk az új méreteket, hogy megtartsuk a képarányt
        if (originalWidth > targetWidth || originalHeight > targetHeight)
        {
            if (aspectRatio > 1.0)
            {
                // Szélesség alapján skálázzuk az új méretet
                newWidth = targetWidth;
                newHeight = static_cast<int>(targetWidth / aspectRatio);
            }
            else
            {
                // Magasság alapján skálázzuk az új méretet
                newHeight = targetHeight;
                newWidth = static_cast<int>(targetHeight * aspectRatio);
            }
        }
        // Méretezzük az eredeti képet az új méretekre
        wxImage resizedImage = originalImage.Scale(newWidth, newHeight);
        // Üres terület hozzáadása és transzparens töltése
        if (newWidth < targetWidth || newHeight < targetHeight)
        {
            wxImage finalImage(targetWidth, targetHeight);
            finalImage.SetAlpha();
            finalImage.Paste(resizedImage, (targetWidth - newWidth) / 2, (targetHeight - newHeight) / 2);
            return finalImage;
        }
        return resizedImage;
    }
};
#endif // __ImageViewerImageWindow__
utils.h
New file
@@ -0,0 +1,20 @@
#ifndef __IMGVIEWER_UTILS__
#define __IMGVIEWER_UTILS__
namespace ImageUtils
{
    enum ROTATE_DIRECTION
    {
        LEFT,
        RIGHT
    };
    struct ImageFileInfo
    {
        wxFileName *file;
        wxImage *img;
    };
};
#endif