--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// 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