Skip to content

Instantly share code, notes, and snippets.

@ixtiyoruz
Created April 30, 2020 03:54
Show Gist options
  • Save ixtiyoruz/1a762eb4f11958c12eb251cb20b998aa to your computer and use it in GitHub Desktop.
Save ixtiyoruz/1a762eb4f11958c12eb251cb20b998aa to your computer and use it in GitHub Desktop.
wxwidgets thumbnial
/////////////////////////////////////////////////////////////////////////////
// Name: thumbnailctrl.cpp
// Purpose: Displays a scrolling window of thumbnails
// Author: Julian Smart
// Modified by: Anil Kumar
// Created: 03/08/04 17:22:46
// RCS-ID:
// Copyright: (c) Julian Smart
// Licence: wxWidgets Licence
/////////////////////////////////////////////////////////////////////////////
#if defined(__GNUG__) && !defined(__APPLE__)
#pragma implementation "thumbnailctrl.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "thumbnailctrl.h"
#if wxCHECK_VERSION(2,5,5)
#define USE_BUFFERED_PAINT 1
#else
#define USE_BUFFERED_PAINT 0
#endif
#include "wx/settings.h"
#include "wx/arrimpl.cpp"
#include "wx/image.h"
#include "wx/filename.h"
#include "wx/dcbuffer.h"
#include <algorithm>
//#include "tick.xpm"
WX_DEFINE_OBJARRAY(wxThumbnailItemArray);
wxDEFINE_EVENT(wxEVT_COMMAND_THUMBNAIL_SELECTION_CHANGED, wxThumbnailEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_THUMBNAIL_ITEM_SELECTED, wxThumbnailEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_THUMBNAIL_ITEM_DESELECTED, wxThumbnailEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_THUMBNAIL_LEFT_CLICK, wxThumbnailEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_THUMBNAIL_RIGHT_CLICK, wxThumbnailEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_THUMBNAIL_VIEW_RIGHT_CLICK, wxThumbnailEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_THUMBNAIL_LEFT_DCLICK, wxThumbnailEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_THUMBNAIL_RETURN, wxThumbnailEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_THUMBNAIL_DRAG_START, wxThumbnailEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_THUMBNAIL_SORTED, wxThumbnailEvent);
IMPLEMENT_CLASS(wxThumbnailCtrl, wxScrolledWindow)
IMPLEMENT_CLASS(wxThumbnailItem, wxObject)
IMPLEMENT_CLASS(wxThumbnailEvent, wxNotifyEvent)
BEGIN_EVENT_TABLE(wxThumbnailCtrl, wxScrolledWindow)
EVT_PAINT(wxThumbnailCtrl::OnPaint)
EVT_ERASE_BACKGROUND(wxThumbnailCtrl::OnEraseBackground)
EVT_MOUSE_EVENTS(wxThumbnailCtrl::OnMouse)
EVT_MOTION(wxThumbnailCtrl::OnMouseMotion)
EVT_LEAVE_WINDOW(wxThumbnailCtrl::OnMouseLeave)
EVT_CHAR(wxThumbnailCtrl::OnChar)
EVT_SIZE(wxThumbnailCtrl::OnSize)
EVT_SET_FOCUS(wxThumbnailCtrl::OnSetFocus)
EVT_KILL_FOCUS(wxThumbnailCtrl::OnKillFocus)
EVT_MENU(wxID_SELECTALL, wxThumbnailCtrl::OnSelectAll)
EVT_UPDATE_UI(wxID_SELECTALL, wxThumbnailCtrl::OnUpdateSelectAll)
END_EVENT_TABLE()
wxThumbnailCtrl* wxThumbnailCtrl::sm_currentThumbnailCtrl = NULL;
/*!
* wxThumbnailCtrl
*/
wxThumbnailCtrl::wxThumbnailCtrl()
{
Init();
}
wxThumbnailCtrl::wxThumbnailCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
{
Init();
Create(parent, id, pos, size, style);
}
/// Creation
bool wxThumbnailCtrl::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
{
if (!wxScrolledWindow::Create(parent, id, pos, size, style
#if wxCHECK_VERSION(2,5,1)
| wxFULL_REPAINT_ON_RESIZE
#endif
))
return false;
if (!GetFont().Ok())
{
SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
}
CalculateOverallThumbnailSize();
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
// m_tagBitmap = wxBitmap(tick_xpm);
#if wxCHECK_VERSION(2,5,1)
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
#endif
// Tell the sizers to use the given or best size
// SetBestFittingSize(size);
SetInitialSize(size);
#if USE_BUFFERED_PAINT
// Create a buffer
RecreateBuffer(size);
#endif
return true;
}
/// Member initialisation
void wxThumbnailCtrl::Init()
{
m_thumbnailOverallSize = wxTHUMBNAIL_DEFAULT_OVERALL_SIZE;
m_thumbnailImageSize = wxTHUMBNAIL_DEFAULT_IMAGE_SIZE;
m_freezeCount = 0;
m_spacing = wxTHUMBNAIL_DEFAULT_SPACING;
m_thumbnailMargin = wxTHUMBNAIL_DEFAULT_MARGIN;
m_firstSelection = -1;
m_lastSelection = -1;
m_focussedThumbnailBackgroundColour = wxTHUMBNAIL_DEFAULT_FOCUSSED_BACKGROUND;
m_unfocussedThumbnailBackgroundColour = wxTHUMBNAIL_DEFAULT_UNFOCUSSED_BACKGROUND;
m_unselectedThumbnailBackgroundColour = wxTHUMBNAIL_DEFAULT_UNSELECTED_BACKGROUND;
m_typeColour = wxTHUMBNAIL_DEFAULT_TYPE_COLOUR;
m_tagColour = wxTHUMBNAIL_DEFAULT_TAG_COLOUR;
m_focusRectColour = wxTHUMBNAIL_DEFAULT_FOCUS_RECT_COLOUR;
m_focusItem = -1;
}
/// Call Freeze to prevent refresh
void wxThumbnailCtrl::Freeze()
{
m_freezeCount++;
}
/// Call Thaw to refresh
void wxThumbnailCtrl::Thaw()
{
m_freezeCount--;
if (m_freezeCount == 0)
{
SetupScrollbars();
Refresh();
}
}
/// Append a single item
int wxThumbnailCtrl::Append(wxThumbnailItem* item)
{
int sz = (int)GetCount();
m_items.Add(item);
m_firstSelection = -1;
m_lastSelection = -1;
m_focusItem = -1;
item->Load(this, false);
if (m_freezeCount == 0)
{
SetupScrollbars();
Refresh();
}
return sz;
}
/// Insert a single item
int wxThumbnailCtrl::Insert(wxThumbnailItem* item, int pos)
{
m_items.Insert(item, pos);
m_firstSelection = -1;
m_lastSelection = -1;
m_focusItem = -1;
// Must now change selection indices because
// items above it have moved up
size_t i;
for (i = 0; i < m_selections.GetCount(); i++)
{
if (m_selections[i] >= pos)
m_selections[i] = m_selections[i] + 1;
}
// Ditto for tags
for (i = 0; i < m_tags.GetCount(); i++)
{
if (m_tags[i] >= pos)
m_tags[i] = m_tags[i] + 1;
}
item->Load(this, false);
if (m_freezeCount == 0)
{
SetupScrollbars();
Refresh();
}
return pos;
}
/// Clear all items
void wxThumbnailCtrl::Clear()
{
m_firstSelection = -1;
m_lastSelection = -1;
m_focusItem = -1;
m_items.Clear();
m_selections.Clear();
m_tags.Clear();
m_hoverItem = wxNOT_FOUND;
if (m_freezeCount == 0)
{
SetupScrollbars();
Refresh();
}
}
int wxThumbnailCtrl::Compare(wxThumbnailItem** item1, wxThumbnailItem** item2)
{
wxFAIL_MSG("Override wxThumbnailCtrl::Compare function and provide your implementaion.");
return 0;
}
/// Sorts items
void wxThumbnailCtrl::Sort()
{
// preserve and restore selections & tags
size_t i;
size_t len = m_items.GetCount();
for (i = 0; i < len; i++)
{
wxThumbnailItem& item = m_items[i];
int state = 0;
if (IsSelected(i))
state |= wxTHUMBNAIL_SELECTED;
if (IsTagged(i))
state |= wxTHUMBNAIL_TAGGED;
item.SetState(state);
}
m_selections.Clear();
m_tags.Clear();
m_firstSelection = -1;
m_lastSelection = -1;
m_focusItem = -1;
sm_currentThumbnailCtrl = this;
m_items.Sort([](wxThumbnailItem** item1, wxThumbnailItem** item2)
{
return sm_currentThumbnailCtrl->Compare(item1, item2);
});
sm_currentThumbnailCtrl = NULL;
wxThumbnailEvent cmdEvent(
wxEVT_COMMAND_THUMBNAIL_SORTED,
GetId());
cmdEvent.SetEventObject(this);
GetEventHandler()->ProcessEvent(cmdEvent);
Freeze();
for (i = 0; i < len; i++)
{
wxThumbnailItem& item = m_items[i];
if (item.GetState() & wxTHUMBNAIL_SELECTED)
Select(i);
if (item.GetState() & wxTHUMBNAIL_TAGGED)
Tag(i);
}
Thaw();
}
/// Delete this item
void wxThumbnailCtrl::Delete(int n)
{
if (m_firstSelection == n)
m_firstSelection = -1;
if (m_lastSelection == n)
m_lastSelection = -1;
if (m_focusItem == n)
m_focusItem = -1;
if (m_selections.Index(n) != wxNOT_FOUND)
{
m_selections.Remove(n);
wxThumbnailEvent event(wxEVT_COMMAND_THUMBNAIL_ITEM_DESELECTED, GetId());
event.SetEventObject(this);
event.SetIndex(n);
GetEventHandler()->ProcessEvent(event);
wxThumbnailEvent cmdEvent(wxEVT_COMMAND_THUMBNAIL_SELECTION_CHANGED, GetId());
cmdEvent.SetEventObject(this);
GetEventHandler()->ProcessEvent(cmdEvent);
}
if (m_tags.Index(n) != wxNOT_FOUND)
m_tags.Remove(n);
m_items.RemoveAt(n);
// Must now change selection indices because
// items have moved down
size_t i;
for (i = 0; i < m_selections.GetCount(); i++)
{
if (m_selections[i] > n)
m_selections[i] = m_selections[i] - 1;
}
if (m_freezeCount == 0)
{
SetupScrollbars();
Refresh();
}
}
/// Get the nth item
wxThumbnailItem* wxThumbnailCtrl::GetItem(int n)
{
wxASSERT(n < GetCount());
if (n < GetCount())
{
return &m_items[(size_t)n];
}
else
return NULL;
}
/// Get the overall rect of the given item
bool wxThumbnailCtrl::GetItemRect(int n, wxRect& rect, bool transform)
{
wxASSERT(n < GetCount());
if (n < GetCount())
{
int row, col;
if (!GetRowCol(n, GetClientSize(), row, col))
return false;
int x = col * (m_thumbnailOverallSize.x + m_spacing) + m_spacing;
int y = row * (m_thumbnailOverallSize.y + m_spacing) + m_spacing;
if (transform)
{
int startX, startY;
int xppu, yppu;
GetScrollPixelsPerUnit(&xppu, &yppu);
GetViewStart(&startX, &startY);
x = x - startX*xppu;
y = y - startY*yppu;
}
rect.x = x;
rect.y = y;
rect.width = m_thumbnailOverallSize.x;
rect.height = m_thumbnailOverallSize.y;
return true;
}
return false;
}
/// Get the image rect of the given item
bool wxThumbnailCtrl::GetItemRectImage(int n, wxRect& rect, bool transform)
{
wxASSERT(n < GetCount());
wxRect outerRect;
if (!GetItemRect(n, outerRect, transform))
return false;
rect.width = m_thumbnailImageSize.x;
rect.height = m_thumbnailImageSize.y;
rect.x = outerRect.x + (outerRect.width - rect.width) / 2;
rect.y = outerRect.y + (outerRect.height - rect.height) / 2;
if ((GetWindowStyle() & wxTH_EXTENSION_LABEL) == 0) rect.y -= m_thumbnailTextHeight / 2;
return true;
}
/// The size of the image part
void wxThumbnailCtrl::SetThumbnailImageSize(const wxSize& sz)
{
m_thumbnailImageSize = sz;
CalculateOverallThumbnailSize();
if (GetCount() > 0 && m_freezeCount == 0)
{
SetupScrollbars();
Refresh();
}
}
/// Calculate the outer thumbnail size based
/// on font used for text and inner size
void wxThumbnailCtrl::CalculateOverallThumbnailSize()
{
wxCoord w;
wxClientDC dc(this);
dc.SetFont(GetFont());
dc.GetTextExtent(wxT("X"), &w, &m_thumbnailTextHeight);
// From left to right: margin, image, margin
m_thumbnailOverallSize.x = m_thumbnailMargin * 2 + m_thumbnailImageSize.x;
// From top to bottom: margin, text + margin (if wxTH_EXTENSION_LABEL set), image, margin, text, margin
if (GetWindowStyle() & wxTH_EXTENSION_LABEL)
{
m_thumbnailOverallSize.y = m_thumbnailMargin * 4 + m_thumbnailTextHeight * 2 + m_thumbnailImageSize.y;
}
else
{
m_thumbnailOverallSize.y = m_thumbnailMargin * 3 + m_thumbnailTextHeight + m_thumbnailImageSize.y;
}
}
/// Return the row and column given the client
/// size and a left-to-right, top-to-bottom layout
/// assumption
bool wxThumbnailCtrl::GetRowCol(int item, const wxSize& clientSize, int& row, int& col)
{
wxASSERT(item < GetCount());
if (item >= GetCount())
return false;
// How many can we fit in a row?
int perRow = clientSize.x / (m_thumbnailOverallSize.x + m_spacing);
if (perRow < 1)
perRow = 1;
row = item / perRow;
col = item % perRow;
return true;
}
/// Select or deselect an item
void wxThumbnailCtrl::Select(int n, bool select)
{
wxASSERT(n < GetCount());
if (select)
{
if (m_selections.Index(n) == wxNOT_FOUND)
m_selections.Add(n);
}
else
{
if (m_selections.Index(n) != wxNOT_FOUND)
m_selections.Remove(n);
}
m_firstSelection = n;
m_lastSelection = n;
int oldFocusItem = m_focusItem;
m_focusItem = n;
if (m_freezeCount == 0)
{
wxRect rect;
GetItemRect(n, rect);
RefreshRect(rect);
if (oldFocusItem != -1 && oldFocusItem != n)
{
GetItemRect(oldFocusItem, rect);
RefreshRect(rect);
}
}
}
/// Select or deselect a range
void wxThumbnailCtrl::SelectRange(int from, int to, bool select)
{
int first = from;
int last = to;
if (first < last)
{
first = to;
last = from;
}
wxASSERT(first >= 0 && first < GetCount());
wxASSERT(last >= 0 && last < GetCount());
Freeze();
int i;
for (i = first; i < last; i++)
{
Select(i, select);
}
m_focusItem = to;
Thaw();
}
/// Select all
void wxThumbnailCtrl::SelectAll()
{
Freeze();
int i;
for (i = 0; i < GetCount(); i++)
{
Select(i, true);
}
if (GetCount() > 0)
{
m_focusItem = GetCount() - 1;
}
else
{
m_focusItem = -1;
}
Thaw();
}
/// Select none
void wxThumbnailCtrl::SelectNone()
{
Freeze();
int i;
for (i = 0; i < GetCount(); i++)
{
Select(i, false);
}
Thaw();
}
/// Get the index of the single selection, if not multi-select.
/// Returns -1 if there is no selection.
int wxThumbnailCtrl::GetSelection() const
{
if (m_selections.GetCount() > 0)
return m_selections[0u];
else
return -1;
}
/// Returns true if the item is selected
bool wxThumbnailCtrl::IsSelected(int n) const
{
return (m_selections.Index(n) != wxNOT_FOUND);
}
/// Clears all selections
void wxThumbnailCtrl::ClearSelections()
{
int count = GetCount();
m_selections.Clear();
m_firstSelection = -1;
m_lastSelection = -1;
m_focusItem = -1;
if (count > 0 && m_freezeCount == 0)
{
Refresh();
}
}
/// Set the focus item
void wxThumbnailCtrl::SetFocusItem(int item)
{
wxASSERT(item < GetCount());
if (item < GetCount())
{
int oldFocusItem = m_focusItem;
m_focusItem = item;
if (m_freezeCount == 0)
{
wxRect rect;
if (oldFocusItem != -1)
{
GetItemRect(oldFocusItem, rect);
RefreshRect(rect);
}
if (m_focusItem != -1)
{
GetItemRect(m_focusItem, rect);
RefreshRect(rect);
}
}
}
}
/// Tag or untag an item
void wxThumbnailCtrl::Tag(int n, bool tag)
{
wxASSERT(n < GetCount());
if (tag)
{
if (m_tags.Index(n) == wxNOT_FOUND)
m_tags.Add(n);
}
else
{
if (m_tags.Index(n) != wxNOT_FOUND)
m_tags.Remove(n);
}
if (m_freezeCount == 0)
{
wxRect rect;
GetItemRect(n, rect);
RefreshRect(rect);
}
}
/// Returns true if the item is tagged
bool wxThumbnailCtrl::IsTagged(int n) const
{
return (m_tags.Index(n) != wxNOT_FOUND);
}
/// Clears all tags
void wxThumbnailCtrl::ClearTags()
{
int count = GetCount();
m_tags.Clear();
if (count > 0 && m_freezeCount == 0)
{
Refresh();
}
}
/// Painting
void wxThumbnailCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
{
// Set this to 0 to compare it with the
// unbuffered implementation
#if USE_BUFFERED_PAINT
wxBufferedPaintDC dc(this, m_bufferBitmap);
#else
wxPaintDC dc(this);
#endif
PrepareDC(dc);
if (m_freezeCount > 0)
return;
// Paint the background
PaintBackground(dc);
if (GetCount() == 0)
return;
wxRegion dirtyRegion = GetUpdateRegion();
bool isFocussed = (FindFocus() == this);
int i;
int count = GetCount();
int style = 0;
wxRect rect, untransformedRect, imageRect, untransformedImageRect;
for (i = 0; i < count; i++)
{
GetItemRect(i, rect);
wxRegionContain c = dirtyRegion.Contains(rect);
if (c != wxOutRegion)
{
GetItemRectImage(i, imageRect);
style = 0;
if (i == GetMouseHoverItem())
style |= wxTHUMBNAIL_IS_HOVER;
if (IsSelected(i))
style |= wxTHUMBNAIL_SELECTED;
if (IsTagged(i))
style |= wxTHUMBNAIL_TAGGED;
if (isFocussed)
style |= wxTHUMBNAIL_FOCUSSED;
if (isFocussed && i == m_focusItem)
style |= wxTHUMBNAIL_IS_FOCUS;
GetItemRect(i, untransformedRect, false);
GetItemRectImage(i, untransformedImageRect, false);
DrawItemBackground(i, dc, untransformedRect, untransformedImageRect, style);
DrawItem(i, dc, untransformedRect, style);
}
}
}
// Empty implementation, to prevent flicker
void wxThumbnailCtrl::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
{
}
void wxThumbnailCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event))
{
if (GetCount() > 0)
Refresh();
}
void wxThumbnailCtrl::OnKillFocus(wxFocusEvent& WXUNUSED(event))
{
if (GetCount() > 0)
Refresh();
}
/// Mouse-event
void wxThumbnailCtrl::OnMouse(wxMouseEvent& event)
{
if (event.GetEventType() == wxEVT_MOUSEWHEEL)
{
// let the base handle mouse wheel events.
event.Skip();
return;
}
if (event.LeftDown())
{
OnLeftClickDown(event);
}
else if (event.LeftUp())
{
OnLeftClickUp(event);
}
else if (event.LeftDClick())
{
OnLeftDClick(event);
}
else if (event.RightDown())
{
OnRightClickDown(event);
}
else if (event.RightUp())
{
OnRightClickUp(event);
}
else if (event.Dragging() && event.LeftIsDown() && GetSelections().Count())
{
wxThumbnailEvent cmdEvent(
wxEVT_COMMAND_THUMBNAIL_DRAG_START,
GetId());
if (wxDefaultPosition == m_dragStartPosition)
m_dragStartPosition = event.GetPosition();
if ((GetWindowStyle() & wxTH_MULTIPLE_SELECT) != 0)
cmdEvent.SetItemsIndex(GetSelections());
else
cmdEvent.SetIndex(GetSelection());
cmdEvent.SetPosition(m_dragStartPosition);
cmdEvent.SetEventObject(this);
GetEventHandler()->ProcessEvent(cmdEvent);
}
else
{
m_dragStartPosition = wxDefaultPosition;
}
event.Skip();
}
/// Left-click-down
void wxThumbnailCtrl::OnLeftClickDown(wxMouseEvent& event)
{
SetFocus();
int n;
if (HitTest(event.GetPosition(), n))
{
int flags = 0;
if (event.ControlDown())
flags |= wxTHUMBNAIL_CTRL_DOWN;
if (event.ShiftDown())
flags |= wxTHUMBNAIL_SHIFT_DOWN;
if (event.AltDown())
flags |= wxTHUMBNAIL_ALT_DOWN;
EnsureVisible(n);
bool change = false;
if (((GetWindowStyle() & wxTH_MULTIPLE_SELECT) != 0))
change = !IsSelected(n) || (flags != 0);
else
change = !IsSelected(n);
if (change)
DoSelection(n, flags);
wxThumbnailEvent cmdEvent(
wxEVT_COMMAND_THUMBNAIL_LEFT_CLICK,
GetId());
cmdEvent.SetEventObject(this);
cmdEvent.SetIndex(n);
cmdEvent.SetFlags(flags);
GetEventHandler()->ProcessEvent(cmdEvent);
}
}
/// Left-click-up
void wxThumbnailCtrl::OnLeftClickUp(wxMouseEvent& event)
{
SetFocus();
int n;
if (HitTest(event.GetPosition(), n))
{
int flags = 0;
if (event.ControlDown())
flags |= wxTHUMBNAIL_CTRL_DOWN;
if (event.ShiftDown())
flags |= wxTHUMBNAIL_SHIFT_DOWN;
if (event.AltDown())
flags |= wxTHUMBNAIL_ALT_DOWN;
EnsureVisible(n);
if ((GetWindowStyle() & wxTH_MULTIPLE_SELECT) != 0)
{
if ((GetSelections().Count() > 1) && IsSelected(n) && flags == 0)
DoSelection(n, flags);
}
}
}
/// Right-click-down
void wxThumbnailCtrl::OnRightClickDown(wxMouseEvent& event)
{
SetFocus();
int n;
if (HitTest(event.GetPosition(), n))
{
int flags = 0;
if (event.ControlDown())
flags |= wxTHUMBNAIL_CTRL_DOWN;
if (event.ShiftDown())
flags |= wxTHUMBNAIL_SHIFT_DOWN;
if (event.AltDown())
flags |= wxTHUMBNAIL_ALT_DOWN;
if (m_focusItem != n)
SetFocusItem(n);
const wxArrayInt& selections = GetSelections();
if (std::find(selections.begin(), selections.end(), n) == selections.end())
{
SelectNone();
Select(n);
wxThumbnailEvent cmdEvent(
wxEVT_COMMAND_THUMBNAIL_ITEM_SELECTED,
GetId());
cmdEvent.SetEventObject(this);
cmdEvent.SetIndex(n);
cmdEvent.SetFlags(flags);
GetEventHandler()->ProcessEvent(cmdEvent);
wxThumbnailEvent event(wxEVT_COMMAND_THUMBNAIL_SELECTION_CHANGED, GetId());
event.SetEventObject(this);
GetEventHandler()->ProcessEvent(event);
}
}
event.Skip();
}
/// Right-click-up
void wxThumbnailCtrl::OnRightClickUp(wxMouseEvent& event)
{
SetFocus();
int flags = 0;
if (event.ControlDown())
flags |= wxTHUMBNAIL_CTRL_DOWN;
if (event.ShiftDown())
flags |= wxTHUMBNAIL_SHIFT_DOWN;
if (event.AltDown())
flags |= wxTHUMBNAIL_ALT_DOWN;
int n;
if (HitTest(event.GetPosition(), n))
{
if (m_focusItem != n)
SetFocusItem(n);
const wxArrayInt& selections = GetSelections();
if (std::find(selections.begin(), selections.end(), n) != selections.end())
{
wxThumbnailEvent cmdEvent(
wxEVT_COMMAND_THUMBNAIL_RIGHT_CLICK,
GetId());
cmdEvent.SetEventObject(this);
cmdEvent.SetIndex(n);
cmdEvent.SetFlags(flags);
cmdEvent.SetPosition(event.GetPosition());
GetEventHandler()->ProcessEvent(cmdEvent);
}
}
else
{
wxThumbnailEvent cmdEvent(
wxEVT_COMMAND_THUMBNAIL_VIEW_RIGHT_CLICK,
GetId());
cmdEvent.SetEventObject(this);
cmdEvent.SetFlags(flags);
cmdEvent.SetPosition(event.GetPosition());
GetEventHandler()->ProcessEvent(cmdEvent);
}
}
/// Left-double-click
void wxThumbnailCtrl::OnLeftDClick(wxMouseEvent& event)
{
int n;
if (HitTest(event.GetPosition(), n))
{
int flags = 0;
if (event.ControlDown())
flags |= wxTHUMBNAIL_CTRL_DOWN;
if (event.ShiftDown())
flags |= wxTHUMBNAIL_SHIFT_DOWN;
if (event.AltDown())
flags |= wxTHUMBNAIL_ALT_DOWN;
wxThumbnailEvent cmdEvent(
wxEVT_COMMAND_THUMBNAIL_LEFT_DCLICK,
GetId());
cmdEvent.SetEventObject(this);
cmdEvent.SetIndex(n);
cmdEvent.SetFlags(flags);
GetEventHandler()->ProcessEvent(cmdEvent);
}
}
/// Mouse motion
void wxThumbnailCtrl::OnMouseMotion(wxMouseEvent& event)
{
wxRect rect;
int n;
if (HitTest(event.GetPosition(), n))
{
if (m_hoverItem != n)
ShowMouseHoverBackground(n);
ShowTooltip(n);
}
else
{
if (wxNOT_FOUND != m_hoverItem)
HideMouseHoverBackground();
UnsetToolTip();
}
event.Skip();
}
/// Mouse leave
void wxThumbnailCtrl::OnMouseLeave(wxMouseEvent& event)
{
if (wxNOT_FOUND != m_hoverItem)
HideMouseHoverBackground();
event.Skip();
}
/// Key press
void wxThumbnailCtrl::OnChar(wxKeyEvent& event)
{
int flags = 0;
if (event.ControlDown())
flags |= wxTHUMBNAIL_CTRL_DOWN;
if (event.ShiftDown())
flags |= wxTHUMBNAIL_SHIFT_DOWN;
if (event.AltDown())
flags |= wxTHUMBNAIL_ALT_DOWN;
if (event.GetKeyCode() == WXK_LEFT ||
event.GetKeyCode() == WXK_RIGHT ||
event.GetKeyCode() == WXK_UP ||
event.GetKeyCode() == WXK_DOWN ||
event.GetKeyCode() == WXK_HOME ||
event.GetKeyCode() == WXK_PAGEUP ||
event.GetKeyCode() == WXK_PAGEDOWN ||
//event.GetKeyCode() == WXK_PRIOR ||
//event.GetKeyCode() == WXK_NEXT ||
event.GetKeyCode() == WXK_END)
{
Navigate(event.GetKeyCode(), flags);
}
else if (event.GetKeyCode() == WXK_RETURN)
{
wxThumbnailEvent cmdEvent(
wxEVT_COMMAND_THUMBNAIL_RETURN,
GetId());
cmdEvent.SetEventObject(this);
cmdEvent.SetFlags(flags);
GetEventHandler()->ProcessEvent(cmdEvent);
}
else
event.Skip();
}
/// Keyboard navigation
bool wxThumbnailCtrl::Navigate(int keyCode, int flags)
{
if (GetCount() == 0)
return false;
wxSize clientSize = GetClientSize();
int perRow = clientSize.x / (m_thumbnailOverallSize.x + m_spacing);
if (perRow < 1)
perRow = 1;
int rowsInView = clientSize.y / (m_thumbnailOverallSize.y + m_spacing);
if (rowsInView < 1)
rowsInView = 1;
int focus = m_focusItem;
if (focus == -1)
focus = m_lastSelection;
if (focus == -1 || focus >= GetCount())
{
m_lastSelection = 0;
DoSelection(m_lastSelection, flags);
ScrollIntoView(m_lastSelection, keyCode);
return true;
}
if (keyCode == WXK_RIGHT)
{
int next = focus + 1;
if (next < GetCount())
{
DoSelection(next, flags);
ScrollIntoView(next, keyCode);
}
}
else if (keyCode == WXK_LEFT)
{
int next = focus - 1;
if (next >= 0)
{
DoSelection(next, flags);
ScrollIntoView(next, keyCode);
}
}
else if (keyCode == WXK_UP)
{
int next = focus - perRow;
if (next >= 0)
{
DoSelection(next, flags);
ScrollIntoView(next, keyCode);
}
}
else if (keyCode == WXK_DOWN)
{
int next = focus + perRow;
if (next < GetCount())
{
DoSelection(next, flags);
ScrollIntoView(next, keyCode);
}
}
else if (keyCode == WXK_PAGEUP /*|| keyCode == WXK_PRIOR*/)
{
int next = focus - (perRow * rowsInView);
if (next < 0)
next = 0;
if (next >= 0)
{
DoSelection(next, flags);
ScrollIntoView(next, keyCode);
}
}
else if (keyCode == WXK_PAGEDOWN /*|| keyCode == WXK_NEXT*/)
{
int next = focus + (perRow * rowsInView);
if (next >= GetCount())
next = GetCount() - 1;
if (next < GetCount())
{
DoSelection(next, flags);
ScrollIntoView(next, keyCode);
}
}
else if (keyCode == WXK_HOME)
{
DoSelection(0, flags);
ScrollIntoView(0, keyCode);
}
else if (keyCode == WXK_END)
{
DoSelection(GetCount() - 1, flags);
ScrollIntoView(GetCount() - 1, keyCode);
}
return true;
}
/// Scroll to see the image
void wxThumbnailCtrl::ScrollIntoView(int n, int keyCode)
{
wxRect rect;
GetItemRect(n, rect, false); // _Not_ relative to scroll start
int ppuX, ppuY;
GetScrollPixelsPerUnit(&ppuX, &ppuY);
int startX, startY;
GetViewStart(&startX, &startY);
startX = 0;
startY = startY * ppuY;
int sx, sy;
GetVirtualSize(&sx, &sy);
sx = 0;
if (ppuY != 0)
sy = sy / ppuY;
wxSize clientSize = GetClientSize();
// Going down
if (keyCode == WXK_DOWN || keyCode == WXK_RIGHT || keyCode == WXK_END /*|| keyCode == WXK_NEXT*/ || keyCode == WXK_PAGEDOWN)
{
if ((rect.y + rect.height) > (clientSize.y + startY))
{
// Make it scroll so this item is at the bottom
// of the window
int y = rect.y - (clientSize.y - m_thumbnailOverallSize.y - m_spacing);
SetScrollbars(ppuX, ppuY, sx, sy, 0, (int)(0.5 + y / ppuY));
}
else if (rect.y < startY)
{
// Make it scroll so this item is at the top
// of the window
int y = rect.y;
SetScrollbars(ppuX, ppuY, sx, sy, 0, (int)(0.5 + y / ppuY));
}
}
// Going up
else if (keyCode == WXK_UP || keyCode == WXK_LEFT || keyCode == WXK_HOME /*|| keyCode == WXK_PRIOR*/ || keyCode == WXK_PAGEUP)
{
if (rect.y < startY)
{
// Make it scroll so this item is at the top
// of the window
int y = rect.y;
SetScrollbars(ppuX, ppuY, sx, sy, 0, (int)(0.5 + y / ppuY));
}
else if ((rect.y + rect.height) >(clientSize.y + startY))
{
// Make it scroll so this item is at the bottom
// of the window
int y = rect.y - (clientSize.y - m_thumbnailOverallSize.y - m_spacing);
SetScrollbars(ppuX, ppuY, sx, sy, 0, (int)(0.5 + y / ppuY));
}
}
}
/// Scrolls the item into view if necessary
void wxThumbnailCtrl::EnsureVisible(int n)
{
wxRect rect;
GetItemRect(n, rect, false); // _Not_ relative to scroll start
int ppuX, ppuY;
GetScrollPixelsPerUnit(&ppuX, &ppuY);
if (ppuY == 0)
return;
int startX, startY;
GetViewStart(&startX, &startY);
startX = 0;
startY = startY * ppuY;
int sx, sy;
GetVirtualSize(&sx, &sy);
sx = 0;
if (ppuY != 0)
sy = sy / ppuY;
wxSize clientSize = GetClientSize();
if ((rect.y + rect.height) > (clientSize.y + startY))
{
// Make it scroll so this item is at the bottom
// of the window
int y = rect.y - (clientSize.y - m_thumbnailOverallSize.y - m_spacing);
SetScrollbars(ppuX, ppuY, sx, sy, 0, (int)(0.5 + y / ppuY));
}
else if (rect.y < startY)
{
// Make it scroll so this item is at the top
// of the window
int y = rect.y;
SetScrollbars(ppuX, ppuY, sx, sy, 0, (int)(0.5 + y / ppuY));
}
}
/// Forces a reload of this item's thumbnail image
void wxThumbnailCtrl::Reload(int n)
{
wxThumbnailItem* item = GetItem(n);
if (item)
{
item->Load(this, true);
}
}
/// Sizing
void wxThumbnailCtrl::OnSize(wxSizeEvent& event)
{
SetupScrollbars();
RecreateBuffer();
event.Skip();
}
/// Set up scrollbars, e.g. after a resize
void wxThumbnailCtrl::SetupScrollbars()
{
if (m_freezeCount)
return;
if (GetCount() == 0)
{
SetScrollbars(0, 0, 0, 0, 0, 0);
return;
}
int lastItem = wxMax(0, GetCount() - 1);
int pixelsPerUnit = 10;
wxSize clientSize = GetClientSize();
int row, col;
GetRowCol(lastItem, clientSize, row, col);
int maxHeight = (row + 1) * (m_thumbnailOverallSize.y + m_spacing) + m_spacing;
int unitsY = maxHeight / pixelsPerUnit;
int startX, startY;
GetViewStart(&startX, &startY);
int maxPositionX = 0; // wxMax(sz.x - clientSize.x, 0);
int maxPositionY = (wxMax(maxHeight - clientSize.y, 0)) / pixelsPerUnit;
// Move to previous scroll position if
// possible
SetScrollbars(0, pixelsPerUnit,
0, unitsY,
wxMin(maxPositionX, startX), wxMin(maxPositionY, startY));
}
/// Show the tooltip
void wxThumbnailCtrl::ShowTooltip(int n)
{
if (wxNOT_FOUND != n)
{
wxThumbnailItem* item = GetItem(n);
const wxString tooltip = wxFileNameFromPath(item->GetFilename());
if (GetToolTipText() != tooltip)
SetToolTip(tooltip);
}
}
/// Draws the item. Normally you override function in wxThumbnailItem.
bool wxThumbnailCtrl::DrawItem(int n, wxDC& dc, const wxRect& rect, int style)
{
wxThumbnailItem* item = GetItem(n);
if (item)
{
return item->Draw(dc, this, rect, style, n);
}
else
return false;
}
/// Draws the background for the item, including bevel
bool wxThumbnailCtrl::DrawItemBackground(int n, wxDC& dc, const wxRect& rect, const wxRect& imageRect, int style)
{
wxThumbnailItem* item = GetItem(n);
if (item)
{
return item->DrawBackground(dc, this, rect, imageRect, style, n);
}
else
{
return false;
}
}
/// Do (de)selection
void wxThumbnailCtrl::DoSelection(int n, int flags)
{
bool isSelected = IsSelected(n);
wxArrayInt stateChanged;
bool multiSelect = (GetWindowStyle() & wxTH_MULTIPLE_SELECT) != 0;
if (multiSelect && (flags & wxTHUMBNAIL_CTRL_DOWN) == wxTHUMBNAIL_CTRL_DOWN)
{
Select(n, !isSelected);
stateChanged.Add(n);
}
else if (multiSelect && (flags & wxTHUMBNAIL_SHIFT_DOWN) == wxTHUMBNAIL_SHIFT_DOWN)
{
// We need to find the last item selected,
// and select all in between.
int first = m_firstSelection;
// Want to keep the 'first' selection
// if we're extending the selection
bool keepFirstSelection = false;
wxArrayInt oldSelections = m_selections;
m_selections.Clear(); // TODO: need to refresh those that become unselected. Store old selections, compare with new
if (m_firstSelection != -1 && m_firstSelection < GetCount() && m_firstSelection != n)
{
int step = (n < m_firstSelection) ? -1 : 1;
int i;
for (i = m_firstSelection; i != n; i += step)
{
if (!IsSelected(i))
{
m_selections.Add(i);
stateChanged.Add(i);
wxRect rect;
GetItemRect(i, rect);
RefreshRect(rect);
}
}
keepFirstSelection = true;
}
// Refresh all the previously selected items that became unselected
size_t i;
for (i = 0; i < oldSelections.GetCount(); i++)
{
if (!IsSelected(oldSelections[i]))
{
wxRect rect;
GetItemRect(oldSelections[i], rect);
RefreshRect(rect);
}
}
Select(n, true);
if (stateChanged.Index(n) == wxNOT_FOUND)
stateChanged.Add(n);
if (keepFirstSelection)
m_firstSelection = first;
}
else
{
size_t i = 0;
for (i = 0; i < m_selections.GetCount(); i++)
{
wxRect rect;
GetItemRect(m_selections[i], rect);
RefreshRect(rect);
stateChanged.Add(i);
}
m_selections.Clear();
Select(n, true);
if (stateChanged.Index(n) == wxNOT_FOUND)
stateChanged.Add(n);
}
// Now notify the app of any selection changes
size_t i = 0;
for (i = 0; i < stateChanged.GetCount(); i++)
{
wxThumbnailEvent event(
m_selections.Index(stateChanged[i]) != wxNOT_FOUND ? wxEVT_COMMAND_THUMBNAIL_ITEM_SELECTED : wxEVT_COMMAND_THUMBNAIL_ITEM_DESELECTED,
GetId());
event.SetEventObject(this);
event.SetIndex(stateChanged[i]);
GetEventHandler()->ProcessEvent(event);
}
if (stateChanged.GetCount() > 0)
{
wxThumbnailEvent event(wxEVT_COMMAND_THUMBNAIL_SELECTION_CHANGED, GetId());
event.SetEventObject(this);
GetEventHandler()->ProcessEvent(event);
}
}
/// Find the item under the given point
bool wxThumbnailCtrl::HitTest(const wxPoint& pt, int& n)
{
wxSize clientSize = GetClientSize();
int startX, startY;
int ppuX, ppuY;
GetViewStart(&startX, &startY);
GetScrollPixelsPerUnit(&ppuX, &ppuY);
int perRow = clientSize.x / (m_thumbnailOverallSize.x + m_spacing);
if (perRow < 1)
perRow = 1;
int colPos = (int)(pt.x / (m_thumbnailOverallSize.x + m_spacing));
int rowPos = (int)((pt.y + startY * ppuY) / (m_thumbnailOverallSize.y + m_spacing));
int itemN = (rowPos * perRow + colPos);
if (itemN >= GetCount())
return false;
wxRect rect;
GetItemRect(itemN, rect);
if (rect.Contains(pt))
{
n = itemN;
return true;
}
return false;
}
void wxThumbnailCtrl::OnSelectAll(wxCommandEvent& WXUNUSED(event))
{
SelectAll();
}
void wxThumbnailCtrl::OnUpdateSelectAll(wxUpdateUIEvent& event)
{
event.Enable(GetCount() > 0);
}
/// Paint the background
void wxThumbnailCtrl::PaintBackground(wxDC& dc)
{
wxColour backgroundColour = GetBackgroundColour();
if (!backgroundColour.Ok())
backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
// Clear the background
dc.SetBrush(wxBrush(backgroundColour));
dc.SetPen(*wxTRANSPARENT_PEN);
wxRect windowRect(wxPoint(0, 0), GetClientSize());
windowRect.x -= 2; windowRect.y -= 2;
windowRect.width += 4; windowRect.height += 4;
// We need to shift the rectangle to take into account
// scrolling. Converting device to logical coordinates.
CalcUnscrolledPosition(windowRect.x, windowRect.y, &windowRect.x, &windowRect.y);
dc.DrawRectangle(windowRect);
}
/// Recreate buffer bitmap if necessary
bool wxThumbnailCtrl::RecreateBuffer(const wxSize& size)
{
wxSize sz = size;
if (sz == wxDefaultSize)
sz = GetClientSize();
if (sz.x < 1 || sz.y < 1)
return false;
if (!m_bufferBitmap.Ok() || m_bufferBitmap.GetWidth() < sz.x || m_bufferBitmap.GetHeight() < sz.y)
m_bufferBitmap = wxBitmap(sz.x, sz.y);
return m_bufferBitmap.Ok();
}
/// Show mouse hover background
void wxThumbnailCtrl::ShowMouseHoverBackground(int n)
{
// remove old
HideMouseHoverBackground();
// add new
wxRect rect;
if (GetItemRect(n, rect))
{
m_hoverItem = n;
RefreshRect(rect);
}
}
/// Hide mouse hover background
void wxThumbnailCtrl::HideMouseHoverBackground()
{
wxRect rect;
if (wxNOT_FOUND != m_hoverItem)
{
if (GetItemRect(m_hoverItem, rect))
RefreshRect(rect);
m_hoverItem = wxNOT_FOUND;
}
}
/*!
* wxThumbnailItem
*/
/// Refresh Item
bool wxThumbnailItem::Refresh(wxThumbnailCtrl* ctrl, int index)
{
wxRect r;
ctrl->GetItemRect(index, r);
ctrl->RefreshRect(r);
return true;
}
/// Draw the item
bool wxThumbnailItem::Draw(wxDC& WXUNUSED(dc), wxThumbnailCtrl* WXUNUSED(ctrl), const wxRect& WXUNUSED(rect), int WXUNUSED(style), int WXUNUSED(index))
{
wxFAIL_MSG("Override wxThumbnailCtrl::Draw function and provide your implementaion.");
return false;
}
/// Draw the item background. It has the default implementation.
/// You have to ovveride this function inorder to provide your implementaion.
bool wxThumbnailItem::DrawBackground(wxDC& dc, wxThumbnailCtrl* ctrl, const wxRect& rect, const wxRect& imageRect, int style, int WXUNUSED(index))
{
wxColour mediumGrey = ctrl->GetUnselectedThumbnailBackgroundColour();
wxColour unfocussedDarkGrey = ctrl->GetSelectedThumbnailUnfocussedBackgroundColour();
wxColour focussedDarkGrey = ctrl->GetSelectedThumbnailFocussedBackgroundColour();
wxColour darkGrey;
if (style & wxTHUMBNAIL_FOCUSSED)
darkGrey = focussedDarkGrey;
else
darkGrey = unfocussedDarkGrey;
if (style & wxTHUMBNAIL_SELECTED)
{
wxBrush brush(darkGrey);
wxPen pen(darkGrey);
dc.SetBrush(brush);
dc.SetPen(pen);
}
else
{
wxBrush brush(mediumGrey);
wxPen pen(mediumGrey);
dc.SetBrush(brush);
dc.SetPen(pen);
}
dc.DrawRectangle(rect);
if (style & wxTHUMBNAIL_TAGGED)
{
wxPen bluePen = ctrl->GetTagColour();
dc.SetPen(bluePen);
dc.DrawLine(rect.GetRight(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
dc.DrawLine(rect.GetLeft(), rect.GetBottom(), rect.GetRight() + 1, rect.GetBottom());
dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetTop());
dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetBottom());
}
else if (ctrl->IsOutlinesShown())
{
if (style & wxTHUMBNAIL_SELECTED)
{
dc.SetPen(*wxWHITE_PEN);
dc.DrawLine(rect.GetRight(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
dc.DrawLine(rect.GetLeft(), rect.GetBottom(), rect.GetRight() + 1, rect.GetBottom());
dc.SetPen(*wxBLACK_PEN);
dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetTop());
dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetBottom());
}
else
{
dc.SetPen(*wxBLACK_PEN);
dc.DrawLine(rect.GetRight(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
dc.DrawLine(rect.GetLeft(), rect.GetBottom(), rect.GetRight() + 1, rect.GetBottom());
dc.SetPen(*wxWHITE_PEN);
dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetTop());
dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetBottom());
}
}
wxString filename = wxFileNameFromPath(m_filename);
if (!filename.IsEmpty() && (ctrl->GetWindowStyle() & wxTH_TEXT_LABEL))
{
dc.SetFont(ctrl->GetFont());
if (style & wxTHUMBNAIL_SELECTED)
dc.SetTextForeground(*wxWHITE);
else
dc.SetTextForeground(*wxBLACK);
dc.SetBackgroundMode(wxTRANSPARENT);
int margin = ctrl->GetThumbnailMargin();
wxRect fRect;
fRect.x = rect.x + margin;
fRect.y = rect.y + rect.height - (rect.height - imageRect.height) / 2 + margin;
fRect.width = rect.width - 2 * margin;
fRect.height = (rect.height - imageRect.height) / 2 - 2 * margin;
wxCoord textW, textH;
dc.GetTextExtent(filename, &textW, &textH);
dc.SetClippingRegion(fRect);
int x = fRect.x + wxMax(0, (fRect.width - textW) / 2);
int y = fRect.y;
dc.DrawText(filename, x, y);
dc.DestroyClippingRegion();
}
if (!filename.IsEmpty())
{
wxString file, name, ext;
// wxSplitPath(filename, & file, & name, & ext);
wxFileName::SplitPath(filename, &file, &name, &ext);
if (!ext.IsEmpty() && (ctrl->GetWindowStyle() & wxTH_EXTENSION_LABEL))
{
ext.MakeUpper();
dc.SetFont(ctrl->GetFont());
if (style & wxTHUMBNAIL_SELECTED)
dc.SetTextForeground(*wxWHITE);
else
dc.SetTextForeground(ctrl->GetTypeColour());
dc.SetBackgroundMode(wxTRANSPARENT);
int margin = ctrl->GetThumbnailMargin();
wxRect fRect;
fRect.x = rect.x + margin;
fRect.y = rect.y + margin;
fRect.width = rect.width - 2 * margin;
fRect.height = (rect.height - imageRect.height) / 2 - 2 * margin;
wxCoord textW, textH;
dc.GetTextExtent(ext, &textW, &textH);
dc.SetClippingRegion(fRect);
int x = fRect.x;
int y = fRect.y;
dc.DrawText(ext, x, y);
dc.DestroyClippingRegion();
}
}
// Draw tag bitmap
if (style & wxTHUMBNAIL_TAGGED)
{
const wxBitmap& tagBitmap = ctrl->GetTagBitmap();
if (tagBitmap.Ok())
{
int x = rect.x + rect.width - tagBitmap.GetWidth() - ctrl->GetThumbnailMargin();
int y = rect.y + ctrl->GetThumbnailMargin();
dc.DrawBitmap(tagBitmap, x, y, true);
}
}
// If the item itself is the focus, draw a dotted
// rectangle around it
if (style & wxTHUMBNAIL_IS_FOCUS)
{
wxPen dottedPen(ctrl->GetFocusRectColour(), 1, wxDOT);
dc.SetPen(dottedPen);
dc.SetBrush(*wxTRANSPARENT_BRUSH);
wxRect focusRect = imageRect;
focusRect.x--;
focusRect.y--;
focusRect.width += 2;
focusRect.height += 2;
dc.DrawRectangle(focusRect);
}
return true;
}
wxSize wxThumbnailCtrl::DoGetBestSize() const
{
return wxWindow::DoGetBestSize();
}
/*!
* wxImageThumbnailItem
*/
IMPLEMENT_CLASS(wxImageThumbnailItem, wxThumbnailItem)
// Draw the item
bool wxImageThumbnailItem::Draw(wxDC& dc, wxThumbnailCtrl* WXUNUSED(ctrl), const wxRect& rect, int WXUNUSED(style), int WXUNUSED(index))
{
if (m_cachedBitmap.Ok())
{
int x = rect.x + (rect.width - m_cachedBitmap.GetWidth()) / 2;
int y = rect.y + (rect.height - m_cachedBitmap.GetHeight()) / 2;
// Work around apparent eVC++ bug (image not drawing properly)
#ifdef __WXWINCE__
wxBitmap tmpBitmap = m_cachedBitmap;
dc.DrawBitmap(tmpBitmap, x, y);
#else
dc.DrawBitmap(m_cachedBitmap, x, y);
#endif
}
return true;
}
/// Load the thumbnail
bool wxImageThumbnailItem::Load(wxThumbnailCtrl* ctrl, bool forceLoad)
{
if (m_cachedBitmap.Ok() && !forceLoad)
return true;
if (wxFileExists(m_filename))
{
wxLogNull logNo;
wxImage image;
if (image.LoadFile(m_filename, wxBITMAP_TYPE_ANY))
{
wxSize thumbnailSize = ctrl->GetThumbnailImageSize();
double scaleX = ((double)thumbnailSize.x) / ((double)image.GetWidth());
double scaleY = ((double)thumbnailSize.y) / ((double)image.GetHeight());
if (scaleX < 1.0 || scaleY < 1.0)
{
double scale = wxMin(scaleX, scaleY);
int newWidth = (int)(scale * image.GetWidth());
int newHeight = (int)(scale * image.GetHeight());
image.Rescale(newWidth, newHeight);
}
m_cachedBitmap = wxBitmap(image);
return true;
}
}
return false;
}
@ixtiyoruz
Copy link
Author

ixtiyoruz commented Apr 30, 2020

//filaname --- >thumbnailctrl.h

#pragma once
/////////////////////////////////////////////////////////////////////////////
// Name:        thumbnailctrl.h
// Purpose:     Displays a scrolling window of thumbnails
// Author:      Julian Smart
// Modified by: Anil Kumar
// Created:     03/08/04 17:22:46
// RCS-ID:      
// Copyright:   (c) Julian Smart
// Licence:     wxWidgets Licence
/////////////////////////////////////////////////////////////////////////////

#ifndef _WX_THUMBNAILCTRL_H_
#define _WX_THUMBNAILCTRL_H_

#if defined(__GNUG__) && !defined(__APPLE__)
#pragma interface "thumbnailctrl.cpp"
#endif

#include "wx/dynarray.h"

/*!
* Includes
*/

/*!
* Styles and flags
*/

/* Styles
*/

#define wxTH_MULTIPLE_SELECT    0x0010
#define wxTH_SINGLE_SELECT      0x0000
#define wxTH_TEXT_LABEL         0x0020
#define wxTH_IMAGE_LABEL        0x0040
#define wxTH_EXTENSION_LABEL    0x0080

/* Flags
*/

#define wxTHUMBNAIL_SHIFT_DOWN  0x01
#define wxTHUMBNAIL_CTRL_DOWN   0x02
#define wxTHUMBNAIL_ALT_DOWN    0x04

/* Defaults
*/

#define wxTHUMBNAIL_DEFAULT_OVERALL_SIZE wxSize(-1, -1)
#define wxTHUMBNAIL_DEFAULT_IMAGE_SIZE wxSize(80, 80)
#define wxTHUMBNAIL_DEFAULT_SPACING 6
#define wxTHUMBNAIL_DEFAULT_MARGIN 3
#define wxTHUMBNAIL_DEFAULT_UNFOCUSSED_BACKGROUND wxColour(175, 175, 175)
#define wxTHUMBNAIL_DEFAULT_FOCUSSED_BACKGROUND wxColour(140, 140, 140)
// #define wxTHUMBNAIL_DEFAULT_UNSELECTED_BACKGROUND wxColour(205, 205, 205)
#define wxTHUMBNAIL_DEFAULT_UNSELECTED_BACKGROUND wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)
#define wxTHUMBNAIL_DEFAULT_TYPE_COLOUR wxColour(0, 0, 200)
#define wxTHUMBNAIL_DEFAULT_TAG_COLOUR wxColour(0, 0, 255)
#define wxTHUMBNAIL_DEFAULT_FOCUS_RECT_COLOUR wxColour(100, 80, 80)

/*!
* Forward declarations
*/

class wxThumbnailCtrl;

/*!
* wxThumbnailItem class declaration
*/

// Drawing styles/states
#define wxTHUMBNAIL_SELECTED    0x01
#define wxTHUMBNAIL_TAGGED      0x02
// The control is focussed
#define wxTHUMBNAIL_FOCUSSED    0x04
// The item itself has the focus
#define wxTHUMBNAIL_IS_FOCUS    0x08
#define wxTHUMBNAIL_IS_HOVER    0x10

class wxThumbnailItem : public wxObject
{
	DECLARE_CLASS(wxThumbnailItem)
public:
	// Constructors

	wxThumbnailItem(const wxString& filename = wxEmptyString)
	{
		m_filename = filename; m_state = 0;
	}

	// Accessors

	/// Filename
	void SetFilename(const wxString& filename) { m_filename = filename; m_cachedBitmap = wxNullBitmap; }
	const wxString& GetFilename() const { return m_filename; }

	/// State storage while sorting
	void SetState(int state) { m_state = state; }
	int GetState() const { return m_state; }

	// Overrideables
	// Refresh the item
	virtual bool Refresh(wxThumbnailCtrl* ctrl, int index);

	/// Draw the item
	virtual bool Draw(wxDC& dc, wxThumbnailCtrl* ctrl, const wxRect& rect, int style, int index);

	/// Draw the background
	virtual bool DrawBackground(wxDC& dc, wxThumbnailCtrl* ctrl, const wxRect& rect, const wxRect& imageRect, int style, int index);

	/// Load the thumbnail
	virtual bool Load(wxThumbnailCtrl* WXUNUSED(ctrl), bool WXUNUSED(forceLoad)) { return false; }

protected:
	wxBitmap    m_cachedBitmap;
	wxString    m_filename;
	int         m_state; // state storage while sorting
};

/*!
* wxImageThumbnailItem class declaration
*/

class wxImageThumbnailItem : public wxThumbnailItem
{
	DECLARE_CLASS(wxImageThumbnailItem)
public:
	// Constructors

	wxImageThumbnailItem(const wxString& filename = wxEmptyString) :
		wxThumbnailItem(filename) {}

	// Overrideables

	/// Draw the item
	virtual bool Draw(wxDC& dc, wxThumbnailCtrl* ctrl, const wxRect& rect, int style, int index);

	/// Load the thumbnail
	virtual bool Load(wxThumbnailCtrl* ctrl, bool forceLoad);

	wxBitmap& GetCachedBitmap() { return m_cachedBitmap; }
};



WX_DECLARE_OBJARRAY(wxThumbnailItem, wxThumbnailItemArray);

/*!
* wxThumbnailCtrl class declaration
*/

class wxThumbnailCtrl : public wxScrolledWindow
{
	DECLARE_CLASS(wxThumbnailCtrl)
	DECLARE_EVENT_TABLE()

public:
	// Constructors

	wxThumbnailCtrl();
	wxThumbnailCtrl(wxWindow* parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
		long style = wxTH_TEXT_LABEL | wxTH_IMAGE_LABEL | wxTH_EXTENSION_LABEL | wxBORDER_THEME);

	// Operations

	/// Creation
	bool Create(wxWindow* parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
		long style = wxTH_TEXT_LABEL | wxTH_IMAGE_LABEL | wxTH_EXTENSION_LABEL | wxBORDER_THEME);

	/// Member initialisation
	void Init();

	/// Call Freeze to prevent refresh
	void Freeze();

	/// Call Thaw to refresh
	void Thaw();

	/// Scrolls the item into view if necessary
	void EnsureVisible(int n);

	/// Forces a reload of this item's thumbnail image
	void Reload(int n);

	/// Sorts items
	void Sort();

	/// Show the tooltip
	virtual void ShowTooltip(int n);

	/// Draws the item. Normally you override function in wxThumbnailItem.
	virtual bool DrawItem(int n, wxDC& dc, const wxRect& rect, int style);

	/// Draws the background for the item, including bevel
	virtual bool DrawItemBackground(int n, wxDC& dc, const wxRect& rect, const wxRect& imageRect, int style);

	// Adding items

	/// Append a single item
	virtual int Append(wxThumbnailItem* item);

	/// Insert a single item
	virtual int Insert(wxThumbnailItem* item, int pos = 0);

	// Deleting items

	/// Clear all items
	virtual void Clear();

	/// Delete this item
	virtual void Delete(int n);

	// Accessing items

	/// Get the number of items in the control
	virtual int GetCount() const { return m_items.GetCount(); }

	/// Get Items
	const wxThumbnailItemArray& GetItems() const { return m_items; }

	/// Is the control empty?
	bool IsEmpty() const { return GetCount() == 0; }

	/// Get the nth item
	wxThumbnailItem* GetItem(int n);

	/// Get the overall rect of the given item
	/// If transform is true, rect is relative to the scroll viewport
	/// (i.e. may be negative)
	bool GetItemRect(int item, wxRect& rect, bool transform = true);

	/// Get the image rect of the given item
	bool GetItemRectImage(int item, wxRect& rect, bool transform = true);

	/// Return the row and column given the client
	/// size and a left-to-right, top-to-bottom layout
	/// assumption
	bool GetRowCol(int item, const wxSize& clientSize, int& row, int& col);

	/// Get the focus item, or -1 if there is none
	int GetFocusItem() const { return m_focusItem; }

	/// Set the focus item
	void SetFocusItem(int item);

	// Selection

	/// Select or deselect an item
	void Select(int n, bool select = true);

	/// Select or deselect a range
	void SelectRange(int from, int to, bool select = true);

	/// Tag or untag an item
	void Tag(int n, bool tag = true);

	/// Select all
	void SelectAll();

	/// Select none
	void SelectNone();

	/// Get the index of the single selection, if not multi-select.
	/// Returns -1 if there is no selection.
	int GetSelection() const;

	/// Get indexes of all selections, if multi-select
	const wxArrayInt& GetSelections() const { return m_selections; }

	/// Get indexes of all tags
	const wxArrayInt& GetTags() const { return m_tags; }

	/// Returns true if the item is selected
	bool IsSelected(int n) const;

	/// Returns true if the item is tagged
	bool IsTagged(int n) const;

	/// Clears all selections
	void ClearSelections();

	/// Clears all tags
	void ClearTags();

	/// Get mouse hover item
	int GetMouseHoverItem() const { return m_hoverItem; }

	/// Find the item under the given point
	bool HitTest(const wxPoint& pt, int& n);

	// Visual properties

	/// The overall size of the thumbnail, including decorations.
	/// DON'T USE THIS from the application, since it will
	/// normally be calculated by SetThumbnailImageSize.
	void SetThumbnailOverallSize(const wxSize& sz) { m_thumbnailOverallSize = sz; }
	const wxSize& GetThumbnailOverallSize() const { return m_thumbnailOverallSize; }

	/// The size of the image part
	void SetThumbnailImageSize(const wxSize& sz);
	const wxSize& GetThumbnailImageSize() const { return m_thumbnailImageSize; }

	/// The inter-item spacing
	void SetSpacing(int spacing) { m_spacing = spacing; }
	int GetSpacing() const { return m_spacing; }

	/// The margin between elements within the thumbnail
	void SetThumbnailMargin(int margin) { m_thumbnailMargin = margin; }
	int GetThumbnailMargin() const { return m_thumbnailMargin; }

	/// The height required for text in the thumbnail
	void SetThumbnailTextHeight(int h) { m_thumbnailTextHeight = h; }
	int GetThumbnailTextHeight() const { return m_thumbnailTextHeight; }

	/// Get tag bitmap
	const wxBitmap& GetTagBitmap() const { return m_tagBitmap; }

	/// The focussed and unfocussed background colour for a
	/// selected thumbnail
	void SetSelectedThumbnailBackgroundColour(const wxColour& focussedColour, const wxColour& unfocussedColour)
	{
		m_focussedThumbnailBackgroundColour = focussedColour; m_unfocussedThumbnailBackgroundColour = unfocussedColour;
	}
	const wxColour& GetSelectedThumbnailFocussedBackgroundColour() const { return m_focussedThumbnailBackgroundColour; }
	const wxColour& GetSelectedThumbnailUnfocussedBackgroundColour() const { return m_unfocussedThumbnailBackgroundColour; }

	/// The unselected background colour for a thumbnail
	void SetUnselectedThumbnailBackgroundColour(const wxColour& colour) { m_unselectedThumbnailBackgroundColour = colour; }
	const wxColour& GetUnselectedThumbnailBackgroundColour() const { return m_unselectedThumbnailBackgroundColour; }

	/// The colour for the type text (top left of thumbnail)
	void SetTypeColour(const wxColour& colour) { m_typeColour = colour; }
	const wxColour& GetTypeColour() const { return m_typeColour; }

	/// The colour for the tag outline
	void SetTagColour(const wxColour& colour) { m_tagColour = colour; }
	const wxColour& GetTagColour() const { return m_tagColour; }

	/// The focus rectangle pen colour
	void SetFocusRectColour(const wxColour& colour) { m_focusRectColour = colour; }
	const wxColour& GetFocusRectColour() const { return m_focusRectColour; }

	/// The thumbnail outlines show or not
	void ShowOutlines(bool flag = true) { m_showOutlines = flag; }
	bool IsOutlinesShown() const { return m_showOutlines; }

	// Command handlers

	void OnSelectAll(wxCommandEvent& event);
	void OnUpdateSelectAll(wxUpdateUIEvent& event);

protected:
	// Event handlers

	/// Painting
	void OnPaint(wxPaintEvent& event);
	void OnEraseBackground(wxEraseEvent& event);

	/// Mouse-events
	void OnMouse(wxMouseEvent& event);

	/// Left-click-down
	void OnLeftClickDown(wxMouseEvent& event);

	/// Left-click-up
	void OnLeftClickUp(wxMouseEvent& event);

	/// Left-double-click
	void OnLeftDClick(wxMouseEvent& event);

	/// Mouse-motion
	void OnMouseMotion(wxMouseEvent& event);

	/// Mouse-leave
	void OnMouseLeave(wxMouseEvent& event);

	/// Right-click-down
	void OnRightClickDown(wxMouseEvent& event);

	/// Right-click-up
	void OnRightClickUp(wxMouseEvent& event);

	/// Key press
	void OnChar(wxKeyEvent& event);

	/// Sizing
	void OnSize(wxSizeEvent& event);

	/// Setting/losing focus
	void OnSetFocus(wxFocusEvent& event);
	void OnKillFocus(wxFocusEvent& event);

	// Implementation

	/// Set up scrollbars, e.g. after a resize
	void SetupScrollbars();

	/// Calculate the outer thumbnail size based
	/// on font used for text and inner size
	void CalculateOverallThumbnailSize();

	/// Do (de)selection
	void DoSelection(int n, int flags);

	/// Keyboard navigation
	virtual bool Navigate(int keyCode, int flags);

	/// Scroll to see the image
	void ScrollIntoView(int n, int keyCode);

	/// Paint the background
	void PaintBackground(wxDC& dc);

	/// Recreate buffer bitmap if necessary
	bool RecreateBuffer(const wxSize& size = wxDefaultSize);

	/// Show mouse hover background
	void ShowMouseHoverBackground(int n);

	/// Hide mouse hover background
	void HideMouseHoverBackground();

	// Overrides
	wxSize DoGetBestSize() const;

	/// Thumbnails compare function
	virtual int Compare(wxThumbnailItem** item1, wxThumbnailItem** item2);

	// Data members
private:

	/// The items
	wxThumbnailItemArray    m_items;

	/// The selections
	wxArrayInt              m_selections;

	/// The tags
	wxArrayInt              m_tags;

	/// Outer size of the thumbnail item
	wxSize                  m_thumbnailOverallSize;

	/// Image size of the thumbnail item
	wxSize                  m_thumbnailImageSize;

	/// The inter-item spacing
	int                     m_spacing;

	/// The margin between the image/text and the edge of the thumbnail
	int                     m_thumbnailMargin;

	/// The height of thumbnail text in the current font
	int                     m_thumbnailTextHeight;

	/// Allows nested Freeze/Thaw
	int                     m_freezeCount;

	/// First selection in a range
	int                     m_firstSelection;

	/// Last selection
	int                     m_lastSelection;

	/// Focus item
	int                     m_focusItem;

	/// Tag marker bitmap
	wxBitmap                m_tagBitmap;

	/// Outlines flag
	bool                    m_showOutlines;

	/// Mouse hover item
	int                     m_hoverItem = wxNOT_FOUND;

	/// Current control, used in sorting
	static wxThumbnailCtrl* sm_currentThumbnailCtrl;

	/// Focussed/unfocussed selected thumbnail background colours
	wxColour                m_focussedThumbnailBackgroundColour;
	wxColour                m_unfocussedThumbnailBackgroundColour;
	wxColour                m_unselectedThumbnailBackgroundColour;
	wxColour                m_focusRectColour;

	/// Type text colour
	wxColour                m_typeColour;

	/// Tag colour
	wxColour                m_tagColour;

	/// Buffer bitmap
	wxBitmap                m_bufferBitmap;

	/// Drag start position
	wxPoint                 m_dragStartPosition = wxDefaultPosition;
};

/*!
* wxThumbnailEvent - the event class for wxThumbnailCtrl notifications
*/

class wxThumbnailEvent : public wxNotifyEvent
{
public:
	wxThumbnailEvent(wxEventType commandType = wxEVT_NULL, int winid = 0)
		: wxNotifyEvent(commandType, winid),
		m_itemIndex(-1), m_flags(0)
	{ }

	wxThumbnailEvent(const wxThumbnailEvent& event)
		: wxNotifyEvent(event),
		m_itemIndex(event.m_itemIndex), m_flags(event.m_flags)
	{ }

	int GetIndex() const { return m_itemIndex; }
	void SetIndex(int n) { m_itemIndex = n; }

	const wxArrayInt& GetItemsIndex() const { return m_itemsIndex; }
	void SetItemsIndex(const wxArrayInt& itemsIndex) { m_itemsIndex = itemsIndex; }

	int GetFlags() const { return m_flags; }
	void SetFlags(int flags) { m_flags = flags; }

	const wxPoint& GetPosition() const { return m_position; }
	void SetPosition(const wxPoint& position) { m_position = position; }

	virtual wxEvent *Clone() const { return new wxThumbnailEvent(*this); }

protected:
	int           m_itemIndex;
	int           m_flags;
	wxPoint       m_position;
	wxArrayInt    m_itemsIndex;

private:
	DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxThumbnailEvent)
};

/*!
* wxThumbnailCtrl event macros
*/
wxDECLARE_EVENT(wxEVT_COMMAND_THUMBNAIL_SELECTION_CHANGED, wxThumbnailEvent);
wxDECLARE_EVENT(wxEVT_COMMAND_THUMBNAIL_ITEM_SELECTED, wxThumbnailEvent);
wxDECLARE_EVENT(wxEVT_COMMAND_THUMBNAIL_ITEM_DESELECTED, wxThumbnailEvent);
wxDECLARE_EVENT(wxEVT_COMMAND_THUMBNAIL_LEFT_CLICK, wxThumbnailEvent);
wxDECLARE_EVENT(wxEVT_COMMAND_THUMBNAIL_RIGHT_CLICK, wxThumbnailEvent);
wxDECLARE_EVENT(wxEVT_COMMAND_THUMBNAIL_VIEW_RIGHT_CLICK, wxThumbnailEvent);
wxDECLARE_EVENT(wxEVT_COMMAND_THUMBNAIL_LEFT_DCLICK, wxThumbnailEvent);
wxDECLARE_EVENT(wxEVT_COMMAND_THUMBNAIL_RETURN, wxThumbnailEvent);
wxDECLARE_EVENT(wxEVT_COMMAND_THUMBNAIL_DRAG_START, wxThumbnailEvent);
wxDECLARE_EVENT(wxEVT_COMMAND_THUMBNAIL_SORTED, wxThumbnailEvent);

#endif
// _WX_THUMBNAILCTRL_H_

@ixtiyoruz
Copy link
Author


	// Create a multiple-selection thumbnail control
	wxThumbnailCtrl* imageBrowser =
		new wxThumbnailCtrl(gallery_window, wxID_ANY,
			wxDefaultPosition, wxSize(300, 400),
			wxSUNKEN_BORDER | wxHSCROLL | wxVSCROLL | wxTH_TEXT_LABEL |
			wxTH_IMAGE_LABEL | wxTH_EXTENSION_LABEL | wxTH_MULTIPLE_SELECT);
	// Set a nice big thumbnail size
	imageBrowser->SetThumbnailImageSize(wxSize(200, 200));
	// Don’t paint while filling the control
	imageBrowser->Freeze();
	// Set some bright colors
/*
	imageBrowser->SetUnselectedThumbnailBackgroundColour(*wxRED);

	imageBrowser->SetSelectedThumbnailBackgroundColour(*wxGREEN, *wxBLUE);*/

	// Add images from directory ‘path’
/*
	wxDir dir;
	std::string path = "C:/Users/Challenger/Pictures/";
	if (dir.Open(path))

	{

		wxString filename;

		bool cont = dir.GetFirst(&filename, wxT("*.jpg"), wxDIR_FILES);

		while (cont)

		{

			wxString file = path + wxFILE_SEP_PATH + filename;
			if (wxFileExists(file))
			{*/
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));

	imageBrowser->Append(new wxImageThumbnailItem("C:/Users/Challenger/Pictures/karpathy.jpg"));
	/*		}
			cont = dir.GetNext(&filename);
		}
	}*/
	//// Tag and select the first thumbnail
	//imageBrowser->Tag(0);
	//imageBrowser->Select(0);
	//// Delete the second thumbnail
	//imageBrowser->Delete(1);
	//// Now display the images
	imageBrowser->Thaw();
	imageBrowser->Show();

@ixtiyoruz
Copy link
Author

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment