X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a7cfad3ad6bc8080b33a0878a14b1c02ca33fe3e..c1d2466a792bf2fdd30da76529f42d5959eb324c:/src/common/arttango.cpp diff --git a/src/common/arttango.cpp b/src/common/arttango.cpp new file mode 100644 index 0000000000..43d40e2064 --- /dev/null +++ b/src/common/arttango.cpp @@ -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 +// 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