Created
April 30, 2020 03:54
-
-
Save ixtiyoruz/1a762eb4f11958c12eb251cb20b998aa to your computer and use it in GitHub Desktop.
wxwidgets thumbnial
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///////////////////////////////////////////////////////////////////////////// | |
// 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; | |
} |
// 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();
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
//filaname --- >thumbnailctrl.h