From 5d543bcc0d15b871315a2123aec01041d73c53fb Mon Sep 17 00:00:00 2001
From: fszontagh <51741446+fszontagh@users.noreply.github.com>
Date: Sun, 25 Feb 2024 15:37:58 +0000
Subject: [PATCH] drag and drop

---
 ui/ImageViewer.h              |   24 +
 ui/ImageViewerImageWindow.cpp |  235 +++++++++++++
 ui/ImageViewerImageWindow.h   |   76 ++++
 res/app_icon.h                |   59 +++
 res/icons/16/reset_zoom.png   |    0 
 res/reset_zoom.png.h          |   58 +++
 static/window.fbp             |  430 +++++++++++++++++++++---
 ui/ImageViewer.cpp            |   93 +++++
 utils.h                       |   20 +
 9 files changed, 917 insertions(+), 78 deletions(-)

diff --git a/res/app_icon.h b/res/app_icon.h
new file mode 100644
index 0000000..186ebd5
--- /dev/null
+++ b/res/app_icon.h
@@ -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
diff --git a/res/icons/16/reset_zoom.png b/res/icons/16/reset_zoom.png
new file mode 100644
index 0000000..98e7399
--- /dev/null
+++ b/res/icons/16/reset_zoom.png
Binary files differ
diff --git a/res/reset_zoom.png.h b/res/reset_zoom.png.h
new file mode 100644
index 0000000..a4ef2a3
--- /dev/null
+++ b/res/reset_zoom.png.h
@@ -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
diff --git a/static/window.fbp b/static/window.fbp
index e819c31..e8d6c90 100644
--- a/static/window.fbp
+++ b/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>
diff --git a/ui/ImageViewer.cpp b/ui/ImageViewer.cpp
index 31ee985..8038136 100644
--- a/ui/ImageViewer.cpp
+++ b/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 ) );
+
 }
diff --git a/ui/ImageViewer.h b/ui/ImageViewer.h
index 8e17b5a..2ee148e 100644
--- a/ui/ImageViewer.h
+++ b/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();
 
diff --git a/ui/ImageViewerImageWindow.cpp b/ui/ImageViewerImageWindow.cpp
index 28a9dcf..990733b 100644
--- a/ui/ImageViewerImageWindow.cpp
+++ b/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);
+}
\ No newline at end of file
diff --git a/ui/ImageViewerImageWindow.h b/ui/ImageViewerImageWindow.h
index 211fac0..c665cc0 100644
--- a/ui/ImageViewerImageWindow.h
+++ b/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__
diff --git a/utils.h b/utils.h
new file mode 100644
index 0000000..cad81ed
--- /dev/null
+++ b/utils.h
@@ -0,0 +1,20 @@
+#ifndef __IMGVIEWER_UTILS__
+#define __IMGVIEWER_UTILS__
+namespace ImageUtils
+{
+
+    enum ROTATE_DIRECTION
+    {
+        LEFT,
+        RIGHT
+    };
+
+    struct ImageFileInfo
+    {
+        wxFileName *file;
+        wxImage *img;
+    };
+
+};
+
+#endif
\ No newline at end of file

--
Gitblit v1.9.3