Merge branch 'msw-art-big-icons'
Add support for big icons to the MSW art provider. See https://github.com/wxWidgets/wxWidgets/pull/1025 Closes #18248.
This commit is contained in:
1
.mailmap
1
.mailmap
@@ -31,6 +31,7 @@ Lauri Nurmi <lanurmi@iki.fi> <lauri@ksenos.fi>
|
||||
Lynn C. Rees <lcrees@gmail.com>
|
||||
Maarten Bent <MaartenBent@users.noreply.github.com>
|
||||
Manuel Martin <mmartin@ceyd.es>
|
||||
Markus Juergens <mj@be-enabled.de> <markusj@trac.wxwidgets.org>
|
||||
Martin Ettl <ettl.martin78@googlemail.com>
|
||||
Martin Ettl <ettl.martin78@googlemail.com> <ettl.martin78@gmail.com>
|
||||
Martin Ettl <ettl.martin78@googlemail.com> <orbitcowboy@web.de>
|
||||
|
@@ -126,8 +126,14 @@ static void FillBitmaps(wxImageList *images, wxListCtrl *list,
|
||||
|
||||
#include "null.xpm"
|
||||
|
||||
const int SIZE_CHOICE_ID = ::wxNewId();
|
||||
|
||||
// Bitmap sizes that can be chosen in the size selection wxChoice.
|
||||
static const int bitmapSizes[] = { -1, 16, 32, 64, 128, 256, 0 };
|
||||
|
||||
wxBEGIN_EVENT_TABLE(wxArtBrowserDialog, wxDialog)
|
||||
EVT_LIST_ITEM_SELECTED(wxID_ANY, wxArtBrowserDialog::OnSelectItem)
|
||||
EVT_CHOICE(SIZE_CHOICE_ID, wxArtBrowserDialog::OnChangeSize)
|
||||
EVT_CHOICE(wxID_ANY, wxArtBrowserDialog::OnChooseClient)
|
||||
wxEND_EVENT_TABLE()
|
||||
|
||||
@@ -136,6 +142,8 @@ wxArtBrowserDialog::wxArtBrowserDialog(wxWindow *parent)
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
|
||||
{
|
||||
m_currentArtId = wxART_ERROR;
|
||||
|
||||
wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
|
||||
wxSizer *subsizer;
|
||||
|
||||
@@ -152,16 +160,28 @@ wxArtBrowserDialog::wxArtBrowserDialog(wxWindow *parent)
|
||||
m_list = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(250, 300),
|
||||
wxLC_REPORT | wxSUNKEN_BORDER);
|
||||
m_list->AppendColumn("wxArtID");
|
||||
subsizer->Add(m_list, 1, wxEXPAND | wxRIGHT, 10);
|
||||
subsizer->Add(m_list, 0, wxEXPAND | wxRIGHT, 10);
|
||||
|
||||
wxSizer *subsub = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_sizes = new wxChoice( this, SIZE_CHOICE_ID );
|
||||
for ( const int* p = bitmapSizes; *p; ++p )
|
||||
{
|
||||
if ( *p == -1 )
|
||||
m_sizes->Append( "Default" );
|
||||
else
|
||||
m_sizes->Append( wxString::Format("%d x %d", *p, *p ) );
|
||||
}
|
||||
m_sizes->SetSelection(0);
|
||||
subsub->Add(m_sizes, 0, wxALL, 4);
|
||||
|
||||
m_text = new wxStaticText(this, wxID_ANY, "Size: 333x333");
|
||||
subsub->Add(m_text);
|
||||
subsub->Add(m_text, 0, wxALL, 4);
|
||||
|
||||
m_canvas = new wxStaticBitmap(this, wxID_ANY, wxBitmap(null_xpm));
|
||||
subsub->Add(m_canvas);
|
||||
subsub->Add(100, 100);
|
||||
subsizer->Add(subsub);
|
||||
subsub->Add(256, 256);
|
||||
subsizer->Add(subsub, 1, wxLEFT, 4 );
|
||||
|
||||
sizer->Add(subsizer, 1, wxEXPAND | wxLEFT|wxRIGHT, 10);
|
||||
|
||||
@@ -176,6 +196,13 @@ wxArtBrowserDialog::wxArtBrowserDialog(wxWindow *parent)
|
||||
}
|
||||
|
||||
|
||||
wxSize wxArtBrowserDialog::GetSelectedBitmapSize() const
|
||||
{
|
||||
const int size = bitmapSizes[m_sizes->GetSelection()];
|
||||
return wxSize(size, size);
|
||||
}
|
||||
|
||||
|
||||
void wxArtBrowserDialog::SetArtClient(const wxArtClient& client)
|
||||
{
|
||||
wxBusyCursor bcur;
|
||||
@@ -201,7 +228,13 @@ void wxArtBrowserDialog::SetArtClient(const wxArtClient& client)
|
||||
void wxArtBrowserDialog::OnSelectItem(wxListEvent &event)
|
||||
{
|
||||
const char *data = (const char*)event.GetData();
|
||||
SetArtBitmap(data, m_client, wxDefaultSize);
|
||||
m_currentArtId = wxString( data );
|
||||
SetArtBitmap(data, m_client, GetSelectedBitmapSize());
|
||||
}
|
||||
|
||||
void wxArtBrowserDialog::OnChangeSize(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
SetArtBitmap(m_currentArtId, m_client, GetSelectedBitmapSize() );
|
||||
}
|
||||
|
||||
void wxArtBrowserDialog::OnChooseClient(wxCommandEvent &event)
|
||||
|
@@ -28,12 +28,17 @@ public:
|
||||
|
||||
private:
|
||||
void OnSelectItem(wxListEvent &event);
|
||||
void OnChangeSize(wxCommandEvent &event);
|
||||
void OnChooseClient(wxCommandEvent &event);
|
||||
|
||||
wxSize GetSelectedBitmapSize() const;
|
||||
|
||||
wxListCtrl *m_list;
|
||||
wxStaticBitmap *m_canvas;
|
||||
wxStaticText *m_text;
|
||||
wxString m_client;
|
||||
wxChoice *m_sizes;
|
||||
wxString m_currentArtId;
|
||||
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "wx/volume.h"
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/msw/wrapwin.h"
|
||||
#include "wx/msw/wrapshl.h"
|
||||
|
||||
#ifdef SHGSI_ICON
|
||||
#define wxHAS_SHGetStockIconInfo
|
||||
@@ -33,6 +34,39 @@
|
||||
namespace
|
||||
{
|
||||
|
||||
#ifdef SHDefExtractIcon
|
||||
#define MSW_SHDefExtractIcon SHDefExtractIcon
|
||||
#else // !defined(SHDefExtractIcon)
|
||||
|
||||
// MinGW doesn't provide SHDefExtractIcon() up to at least the 5.3 version, so
|
||||
// define it ourselves.
|
||||
HRESULT
|
||||
MSW_SHDefExtractIcon(LPCTSTR pszIconFile, int iIndex, UINT uFlags,
|
||||
HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize)
|
||||
{
|
||||
typedef HRESULT
|
||||
(WINAPI *SHDefExtractIcon_t)(LPCTSTR, int, UINT, HICON*, HICON*, UINT);
|
||||
|
||||
static SHDefExtractIcon_t s_SHDefExtractIcon = NULL;
|
||||
if ( !s_SHDefExtractIcon )
|
||||
{
|
||||
wxDynamicLibrary shell32(wxT("shell32.dll"));
|
||||
wxDL_INIT_FUNC_AW(s_, SHDefExtractIcon, shell32);
|
||||
|
||||
if ( !s_SHDefExtractIcon )
|
||||
return E_FAIL;
|
||||
|
||||
// Prevent the DLL from being unloaded while we use its function.
|
||||
// Normally it's not a problem as shell32.dll is always loaded anyhow.
|
||||
shell32.Detach();
|
||||
}
|
||||
|
||||
return (*s_SHDefExtractIcon)(pszIconFile, iIndex, uFlags,
|
||||
phiconLarge, phiconSmall, nIconSize);
|
||||
}
|
||||
|
||||
#endif // !defined(SHDefExtractIcon)
|
||||
|
||||
#ifdef wxHAS_SHGetStockIconInfo
|
||||
|
||||
SHSTOCKICONID MSWGetStockIconIdForArtProviderId(const wxArtID& art_id)
|
||||
@@ -51,6 +85,9 @@ SHSTOCKICONID MSWGetStockIconIdForArtProviderId(const wxArtID& art_id)
|
||||
else if ( art_id == wxART_FLOPPY ) return SIID_DRIVE35;
|
||||
else if ( art_id == wxART_CDROM ) return SIID_DRIVECD;
|
||||
else if ( art_id == wxART_REMOVABLE ) return SIID_DRIVEREMOVE;
|
||||
else if ( art_id == wxART_PRINT ) return SIID_PRINTER;
|
||||
else if ( art_id == wxART_EXECUTABLE_FILE ) return SIID_APPLICATION;
|
||||
else if ( art_id == wxART_NORMAL_FILE ) return SIID_DOCNOASSOC;
|
||||
|
||||
return SIID_INVALID;
|
||||
};
|
||||
@@ -81,32 +118,38 @@ MSW_SHGetStockIconInfo(SHSTOCKICONID siid,
|
||||
|
||||
#endif // #ifdef wxHAS_SHGetStockIconInfo
|
||||
|
||||
// Wrapper for SHDefExtractIcon().
|
||||
wxBitmap
|
||||
MSWGetBitmapFromIconLocation(const TCHAR* path, int index, const wxSize& size)
|
||||
{
|
||||
HICON hIcon = NULL;
|
||||
if ( MSW_SHDefExtractIcon(path, index, 0, &hIcon, NULL, size.x) != S_OK )
|
||||
return wxNullBitmap;
|
||||
|
||||
// Note that using "size.x" twice here is not a typo: normally size.y is
|
||||
// the same anyhow, of course, but if it isn't, the actual icon size would
|
||||
// be size.x in both directions as we only pass "x" to SHDefExtractIcon()
|
||||
// above.
|
||||
wxIcon icon;
|
||||
if ( !icon.InitFromHICON((WXHICON)hIcon, size.x, size.x) )
|
||||
return wxNullBitmap;
|
||||
|
||||
return wxBitmap(icon);
|
||||
}
|
||||
|
||||
wxBitmap
|
||||
MSWGetBitmapForPath(const wxString& path, const wxSize& size, DWORD uFlags = 0)
|
||||
{
|
||||
SHFILEINFO fi;
|
||||
wxZeroMemory(fi);
|
||||
|
||||
uFlags |= SHGFI_USEFILEATTRIBUTES | SHGFI_ICON;
|
||||
if ( size != wxDefaultSize )
|
||||
{
|
||||
if ( size.x <= 16 )
|
||||
uFlags |= SHGFI_SMALLICON;
|
||||
else if ( size.x >= 64 )
|
||||
uFlags |= SHGFI_LARGEICON;
|
||||
}
|
||||
uFlags |= SHGFI_USEFILEATTRIBUTES | SHGFI_ICONLOCATION;
|
||||
|
||||
if ( !SHGetFileInfo(path.t_str(), FILE_ATTRIBUTE_DIRECTORY,
|
||||
&fi, sizeof(SHFILEINFO), uFlags) )
|
||||
return wxNullBitmap;
|
||||
return wxNullBitmap;
|
||||
|
||||
wxIcon icon;
|
||||
icon.CreateFromHICON((WXHICON)fi.hIcon);
|
||||
|
||||
wxBitmap bitmap(icon);
|
||||
::DestroyIcon(fi.hIcon);
|
||||
|
||||
return bitmap;
|
||||
return MSWGetBitmapFromIconLocation(fi.szDisplayName, fi.iIcon, size);
|
||||
}
|
||||
|
||||
#if wxUSE_FSVOLUME
|
||||
@@ -178,33 +221,21 @@ wxBitmap wxWindowsArtProvider::CreateBitmap(const wxArtID& id,
|
||||
{
|
||||
WinStruct<SHSTOCKICONINFO> sii;
|
||||
|
||||
UINT uFlags = SHGSI_ICON;
|
||||
if ( size != wxDefaultSize )
|
||||
{
|
||||
if ( size.x <= 16 )
|
||||
uFlags |= SHGSI_SMALLICON;
|
||||
else if ( size.x >= 64 )
|
||||
uFlags |= SHGSI_LARGEICON;
|
||||
}
|
||||
UINT uFlags = SHGSI_ICONLOCATION | SHGSI_SYSICONINDEX;
|
||||
|
||||
HRESULT res = MSW_SHGetStockIconInfo(stockIconId, uFlags, &sii);
|
||||
if ( res == S_OK )
|
||||
{
|
||||
wxIcon icon;
|
||||
icon.CreateFromHICON( (WXHICON)sii.hIcon );
|
||||
|
||||
bitmap = wxBitmap(icon);
|
||||
::DestroyIcon(sii.hIcon);
|
||||
const wxSize
|
||||
sizeNeeded = size.IsFullySpecified()
|
||||
? size
|
||||
: wxArtProvider::GetNativeSizeHint(client);
|
||||
|
||||
bitmap = MSWGetBitmapFromIconLocation(sii.szPath, sii.iIcon,
|
||||
sizeNeeded);
|
||||
if ( bitmap.IsOk() )
|
||||
{
|
||||
const wxSize
|
||||
sizeNeeded = size.IsFullySpecified()
|
||||
? size
|
||||
: wxArtProvider::GetNativeSizeHint(client);
|
||||
|
||||
if ( sizeNeeded.IsFullySpecified() &&
|
||||
bitmap.GetSize() != sizeNeeded )
|
||||
if ( bitmap.GetSize() != sizeNeeded )
|
||||
{
|
||||
wxArtProvider::RescaleBitmap(bitmap, sizeNeeded);
|
||||
}
|
||||
|
Reference in New Issue
Block a user