Add wxArtProvider using Tango icons.
The icons are embedded as PNG images directly in the source code to avoid the need for installing them. This does make the library larger though so provide a wxUSE_ARTPROVIDER_TANGO option to turn the new code and associated bloat off. Also turn it off by default under wxGTK as the native art provider is used there anyhow. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66505 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
327
src/common/arttango.cpp
Normal file
327
src/common/arttango.cpp
Normal file
@@ -0,0 +1,327 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: src/common/arttango.cpp
|
||||
// Purpose: art provider using embedded PNG versions of Tango icons
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2010-12-27
|
||||
// RCS-ID: $Id: wxhead.cpp,v 1.11 2010-04-22 12:44:51 zeitlin Exp $
|
||||
// Copyright: (c) 2010 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ============================================================================
|
||||
// declarations
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// for compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#if wxUSE_ARTPROVIDER_TANGO
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/image.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include "wx/artprov.h"
|
||||
|
||||
#include "wx/mstream.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// image data
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// All files in art/tango in alphabetical order:
|
||||
#include "../../art/tango/application_x_executable.h"
|
||||
#include "../../art/tango/dialog_error.h"
|
||||
#include "../../art/tango/dialog_information.h"
|
||||
#include "../../art/tango/dialog_warning.h"
|
||||
#include "../../art/tango/document_new.h"
|
||||
#include "../../art/tango/document_open.h"
|
||||
#include "../../art/tango/document_print.h"
|
||||
#include "../../art/tango/document_save.h"
|
||||
#include "../../art/tango/document_save_as.h"
|
||||
#include "../../art/tango/drive_harddisk.h"
|
||||
#include "../../art/tango/drive_optical.h"
|
||||
#include "../../art/tango/drive_removable_media.h"
|
||||
#include "../../art/tango/edit_copy.h"
|
||||
#include "../../art/tango/edit_cut.h"
|
||||
#include "../../art/tango/edit_delete.h"
|
||||
#include "../../art/tango/edit_find.h"
|
||||
#include "../../art/tango/edit_find_replace.h"
|
||||
#include "../../art/tango/edit_paste.h"
|
||||
#include "../../art/tango/edit_redo.h"
|
||||
#include "../../art/tango/edit_undo.h"
|
||||
#include "../../art/tango/folder.h"
|
||||
#include "../../art/tango/folder_new.h"
|
||||
#include "../../art/tango/folder_open.h"
|
||||
#include "../../art/tango/go_down.h"
|
||||
#include "../../art/tango/go_first.h"
|
||||
#include "../../art/tango/go_home.h"
|
||||
#include "../../art/tango/go_last.h"
|
||||
#include "../../art/tango/go_next.h"
|
||||
#include "../../art/tango/go_previous.h"
|
||||
#include "../../art/tango/go_up.h"
|
||||
#include "../../art/tango/image_missing.h"
|
||||
#include "../../art/tango/text_x_generic.h"
|
||||
#include "../../art/tango/list_add.h"
|
||||
#include "../../art/tango/list_remove.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// art provider class
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class wxTangoArtProvider : public wxArtProvider
|
||||
{
|
||||
public:
|
||||
wxTangoArtProvider()
|
||||
{
|
||||
m_imageHandledAdded = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual wxBitmap CreateBitmap(const wxArtID& id,
|
||||
const wxArtClient& client,
|
||||
const wxSize& size);
|
||||
|
||||
private:
|
||||
bool m_imageHandledAdded;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxTangoArtProvider);
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
// ============================================================================
|
||||
|
||||
wxBitmap
|
||||
wxTangoArtProvider::CreateBitmap(const wxArtID& id,
|
||||
const wxArtClient& client,
|
||||
const wxSize& sizeHint)
|
||||
{
|
||||
// Array indexed by the id names with pointers to image data in 16 and 32
|
||||
// pixel sizes as values. The order of the elements in this array is the
|
||||
// same as the definition order in wx/artprov.h. While it's not very
|
||||
// logical, this should make it simpler to add new icons later. Notice that
|
||||
// most elements without Tango equivalents are simply omitted.
|
||||
|
||||
// To avoid repetition use BITMAP_DATA to only specify the image name once
|
||||
// (this is especially important if we decide to add more image sizes
|
||||
// later).
|
||||
#define BITMAP_ARRAY_NAME(name, size) \
|
||||
name ## _ ## size ## x ## size ## _png
|
||||
#define BITMAP_DATA_FOR_SIZE(name, size) \
|
||||
BITMAP_ARRAY_NAME(name, size), sizeof(BITMAP_ARRAY_NAME(name, size))
|
||||
#define BITMAP_DATA(name) \
|
||||
BITMAP_DATA_FOR_SIZE(name, 16), BITMAP_DATA_FOR_SIZE(name, 24)
|
||||
|
||||
static const struct BitmapEntry
|
||||
{
|
||||
const char *id;
|
||||
const unsigned char *data16;
|
||||
size_t len16;
|
||||
const unsigned char *data24;
|
||||
size_t len24;
|
||||
} s_allBitmaps[] =
|
||||
{
|
||||
// Tango does have bookmark-new but no matching bookmark-delete and
|
||||
// using mismatching icons would be ugly so we don't provide this one
|
||||
// neither, we should add both of them if Tango ever adds the other one.
|
||||
//{ wxART_ADD_BOOKMARK, BITMAP_DATA(bookmark_new)},
|
||||
//{ wxART_DEL_BOOKMARK, BITMAP_DATA() },
|
||||
|
||||
{ wxART_GO_BACK, BITMAP_DATA(go_previous) },
|
||||
{ wxART_GO_FORWARD, BITMAP_DATA(go_next) },
|
||||
{ wxART_GO_UP, BITMAP_DATA(go_up) },
|
||||
{ wxART_GO_DOWN, BITMAP_DATA(go_down) },
|
||||
// wxART_GO_TO_PARENT doesn't seem to exist in Tango
|
||||
{ wxART_GO_HOME, BITMAP_DATA(go_home) },
|
||||
{ wxART_GOTO_FIRST, BITMAP_DATA(go_first) },
|
||||
{ wxART_GOTO_LAST, BITMAP_DATA(go_last) },
|
||||
|
||||
{ wxART_FILE_OPEN, BITMAP_DATA(document_open) },
|
||||
{ wxART_FILE_SAVE, BITMAP_DATA(document_save) },
|
||||
{ wxART_FILE_SAVE_AS, BITMAP_DATA(document_save_as) },
|
||||
{ wxART_PRINT, BITMAP_DATA(document_print) },
|
||||
|
||||
// Should we use help-browser for wxART_HELP?
|
||||
|
||||
{ wxART_NEW_DIR, BITMAP_DATA(folder_new) },
|
||||
{ wxART_HARDDISK, BITMAP_DATA(drive_harddisk) },
|
||||
// drive-removable-media seems to be better than media-floppy
|
||||
{ wxART_FLOPPY, BITMAP_DATA(drive_removable_media) },
|
||||
{ wxART_CDROM, BITMAP_DATA(drive_optical) },
|
||||
{ wxART_REMOVABLE, BITMAP_DATA(drive_removable_media) },
|
||||
|
||||
{ wxART_FOLDER, BITMAP_DATA(folder) },
|
||||
{ wxART_FOLDER_OPEN, BITMAP_DATA(folder_open) },
|
||||
// wxART_GO_DIR_UP doesn't seem to exist in Tango
|
||||
|
||||
{ wxART_EXECUTABLE_FILE, BITMAP_DATA(application_x_executable) },
|
||||
{ wxART_NORMAL_FILE, BITMAP_DATA(text_x_generic) },
|
||||
|
||||
// There is no dialog-question in Tango so use the information icon
|
||||
// too, this is better for consistency and we do have a precedent for
|
||||
// doing this as Windows Vista/7 does the same thing natively.
|
||||
{ wxART_ERROR, BITMAP_DATA(dialog_error) },
|
||||
{ wxART_QUESTION, BITMAP_DATA(dialog_information) },
|
||||
{ wxART_WARNING, BITMAP_DATA(dialog_warning) },
|
||||
{ wxART_INFORMATION, BITMAP_DATA(dialog_information) },
|
||||
|
||||
{ wxART_MISSING_IMAGE, BITMAP_DATA(image_missing) },
|
||||
|
||||
{ wxART_COPY, BITMAP_DATA(edit_copy) },
|
||||
{ wxART_CUT, BITMAP_DATA(edit_cut) },
|
||||
{ wxART_PASTE, BITMAP_DATA(edit_paste) },
|
||||
{ wxART_DELETE, BITMAP_DATA(edit_delete) },
|
||||
{ wxART_NEW, BITMAP_DATA(document_new) },
|
||||
{ wxART_UNDO, BITMAP_DATA(edit_undo) },
|
||||
{ wxART_REDO, BITMAP_DATA(edit_redo) },
|
||||
|
||||
{ wxART_PLUS, BITMAP_DATA(list_add) },
|
||||
{ wxART_MINUS, BITMAP_DATA(list_remove) },
|
||||
|
||||
// Surprisingly Tango doesn't seem to have neither wxART_CLOSE nor
|
||||
// wxART_QUIT. We could use system-log-out for the latter but it
|
||||
// doesn't seem quite right.
|
||||
|
||||
{ wxART_FIND, BITMAP_DATA(edit_find) },
|
||||
{ wxART_FIND_AND_REPLACE, BITMAP_DATA(edit_find_replace) },
|
||||
};
|
||||
|
||||
#undef BITMAP_ARRAY_NAME
|
||||
#undef BITMAP_DATA_FOR_SIZE
|
||||
#undef BITMAP_DATA
|
||||
|
||||
for ( unsigned n = 0; n < WXSIZEOF(s_allBitmaps); n++ )
|
||||
{
|
||||
const BitmapEntry& entry = s_allBitmaps[n];
|
||||
if ( entry.id != id )
|
||||
continue;
|
||||
|
||||
// This is one of the bitmaps that we have, determine in which size we
|
||||
// should return it.
|
||||
|
||||
wxSize size;
|
||||
bool sizeIsAHint;
|
||||
if ( sizeHint == wxDefaultSize )
|
||||
{
|
||||
// Use the normal platform-specific icon size.
|
||||
size = GetNativeSizeHint(client);
|
||||
|
||||
if ( size == wxDefaultSize )
|
||||
{
|
||||
// If we failed to get it, determine the best size more or less
|
||||
// arbitrarily. This definitely won't look good but then it
|
||||
// shouldn't normally happen, all platforms should implement
|
||||
// GetNativeSizeHint() properly.
|
||||
if ( client == wxART_MENU || client == wxART_BUTTON )
|
||||
size = wxSize(16, 16);
|
||||
else
|
||||
size = wxSize(24, 24);
|
||||
}
|
||||
|
||||
// We should return the icon of exactly this size so it's more than
|
||||
// just a hint.
|
||||
sizeIsAHint = false;
|
||||
}
|
||||
else // We have a size hint
|
||||
{
|
||||
// Use it for determining the version of the icon to return.
|
||||
size = sizeHint;
|
||||
|
||||
// But we don't need to return the image of exactly the same size
|
||||
// as the hint, after all it's just that, a hint.
|
||||
sizeIsAHint = true;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
TangoSize_16,
|
||||
TangoSize_24
|
||||
} tangoSize;
|
||||
|
||||
// We prefer to downscale the image rather than upscale it if possible
|
||||
// so use the smaller one if we can, otherwise the large one.
|
||||
if ( size.x <= 16 && size.y <= 16 )
|
||||
tangoSize = TangoSize_16;
|
||||
else
|
||||
tangoSize = TangoSize_24;
|
||||
|
||||
const unsigned char *data;
|
||||
size_t len;
|
||||
switch ( tangoSize )
|
||||
{
|
||||
default:
|
||||
wxFAIL_MSG( "Unsupported Tango bitmap size" );
|
||||
// fall through
|
||||
|
||||
case TangoSize_16:
|
||||
data = entry.data16;
|
||||
len = entry.len16;
|
||||
break;
|
||||
|
||||
case TangoSize_24:
|
||||
data = entry.data24;
|
||||
len = entry.len24;
|
||||
break;
|
||||
}
|
||||
|
||||
wxMemoryInputStream is(data, len);
|
||||
|
||||
// Before reading the image data from the stream for the first time,
|
||||
// add the handler for PNG images: we do it here and not in, say,
|
||||
// InitTangoProvider() to do it as lately as possible and so to avoid
|
||||
// the asserts about adding an already added handler if the user code
|
||||
// adds the handler itself.
|
||||
if ( !m_imageHandledAdded )
|
||||
{
|
||||
// Of course, if the user code did add it already, we have nothing
|
||||
// to do.
|
||||
if ( !wxImage::FindHandler(wxBITMAP_TYPE_PNG) )
|
||||
wxImage::AddHandler(new wxPNGHandler);
|
||||
|
||||
// In any case, no need to do it again.
|
||||
m_imageHandledAdded = true;
|
||||
}
|
||||
|
||||
wxImage image(is, wxBITMAP_TYPE_PNG);
|
||||
if ( !image.IsOk() )
|
||||
{
|
||||
// This should normally never happen as all the embedded images are
|
||||
// well-formed.
|
||||
wxLogDebug("Failed to load embedded PNG image for \"%s\"", id);
|
||||
return wxNullBitmap;
|
||||
}
|
||||
|
||||
if ( !sizeIsAHint )
|
||||
{
|
||||
// Notice that this won't do anything if the size is already right.
|
||||
image.Rescale(size.x, size.y, wxIMAGE_QUALITY_HIGH);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
// Not one of the bitmaps that we support.
|
||||
return wxNullBitmap;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void wxArtProvider::InitTangoProvider()
|
||||
{
|
||||
wxArtProvider::Push(new wxTangoArtProvider);
|
||||
}
|
||||
|
||||
#endif // wxUSE_ARTPROVIDER_TANGO
|
||||
Reference in New Issue
Block a user