diff options
Diffstat (limited to 'src/dialogs/iconpreview.cpp')
| -rw-r--r-- | src/dialogs/iconpreview.cpp | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/src/dialogs/iconpreview.cpp b/src/dialogs/iconpreview.cpp new file mode 100644 index 000000000..b3ea55df3 --- /dev/null +++ b/src/dialogs/iconpreview.cpp @@ -0,0 +1,320 @@ +/* + * A simple dialog for previewing icon representation. + * + * Authors: + * Jon A. Cruz + * Bob Jamison + * Other dudes from The Inkscape Organization + * + * Copyright (C) 2004 Bob Jamison + * Copyright (C) 2005 Jon A. Cruz + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "iconpreview.h" + +#include <gtk/gtk.h> + +#include <gtk/gtkdialog.h> //for GTK_RESPONSE* types +#include <glibmm/i18n.h> +#include <gtkmm/buttonbox.h> +#include <gtkmm/stock.h> + +#include "prefs-utils.h" +#include "inkscape.h" +#include "document.h" +#include "desktop-handles.h" +#include "selection.h" +#include "desktop.h" +#include "display/nr-arena.h" +#include "sp-root.h" +#include "xml/repr.h" + +extern "C" { +// takes doc, root, icon, and icon name to produce pixels +guchar * +sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, + const gchar *name, unsigned int psize ); +} + +namespace Inkscape { +namespace UI { +namespace Dialogs { + + +IconPreviewPanel* IconPreviewPanel::instance = 0; + + +IconPreviewPanel& IconPreviewPanel::getInstance() +{ + if ( !instance ) { + instance = new IconPreviewPanel(); + } + + instance->refreshPreview(); + + return *instance; +} + +//######################################################################### +//## E V E N T S +//######################################################################### + +void IconPreviewPanel::on_button_clicked(int which) +{ + if ( hot != which ) { + buttons[hot]->set_active( false ); + + hot = which; + updateMagnify(); + queue_draw(); + } +} + + + + +//######################################################################### +//## C O N S T R U C T O R / D E S T R U C T O R +//######################################################################### +/** + * Constructor + */ +IconPreviewPanel::IconPreviewPanel() : + Panel(), + hot(1), + refreshButton(0), + selectionButton(0) +{ + numEntries = 0; + Inkscape::XML::Node *things = inkscape_get_repr(INKSCAPE, "iconpreview.sizes.default"); + if (things) { + std::vector<int> rawSizes; + for ( Inkscape::XML::Node *child = things->firstChild(); child; child = child->next() ) + { + gchar const *id = child->attribute("id"); + if ( id ) + { + std::string path("iconpreview.sizes.default."); + path += id; + gint show = prefs_get_int_attribute_limited( path.c_str(), "show", 1, 0, 1 ); + gint sizeVal = prefs_get_int_attribute( path.c_str(), "value", -1 ); + if ( show && (sizeVal > 0) ) + { + rawSizes.push_back( sizeVal ); + } + } + } + + if ( !rawSizes.empty() ) + { + numEntries = rawSizes.size(); + sizes = new int[numEntries]; + int i = 0; + for ( std::vector<int>::iterator it = rawSizes.begin(); it != rawSizes.end(); ++it, ++i ) { + sizes[i] = *it; + } + } + } + + if ( numEntries < 1 ) + { + numEntries = 5; + sizes = new int[numEntries]; + sizes[0] = 16; + sizes[1] = 24; + sizes[2] = 32; + sizes[3] = 48; + sizes[5] = 128; + } + + pixMem = new guchar*[numEntries]; + images = new Gtk::Image*[numEntries]; + labels = new Glib::ustring*[numEntries]; + buttons = new Gtk::ToggleToolButton*[numEntries]; + + + for ( int i = 0; i < numEntries; i++ ) { + char *label = g_strdup_printf(_("%d x %d"), sizes[i], sizes[i]); + labels[i] = new Glib::ustring(label); + g_free(label); + pixMem[i] = 0; + images[i] = 0; + } + + + magLabel.set_label( *labels[hot] ); + + Gtk::VBox* magBox = new Gtk::VBox(); + + magBox->pack_start( magnified ); + magBox->pack_start( magLabel, Gtk::PACK_SHRINK ); + + + Gtk::VBox * verts = new Gtk::VBox(); + for ( int i = 0; i < numEntries; i++ ) { + pixMem[i] = new guchar[4 * sizes[i] * sizes[i]]; + memset( pixMem[i], 0x00, 4 * sizes[i] * sizes[i] ); + + GdkPixbuf *pb = gdk_pixbuf_new_from_data( pixMem[i], GDK_COLORSPACE_RGB, TRUE, 8, sizes[i], sizes[i], sizes[i] * 4, /*(GdkPixbufDestroyNotify)nr_free*/NULL, NULL ); + GtkImage* img = GTK_IMAGE( gtk_image_new_from_pixbuf( pb ) ); + images[i] = Glib::wrap(img); + Glib::ustring label(*labels[i]); + buttons[i] = new Gtk::ToggleToolButton(label); + buttons[i]->set_active( i == hot ); + buttons[i]->set_icon_widget(*images[i]); + + tips.set_tip((*buttons[i]), label); + + buttons[i]->signal_clicked().connect( sigc::bind<int>( sigc::mem_fun(*this, &IconPreviewPanel::on_button_clicked), i) ); + + + verts->add(*buttons[i]); + } + + iconBox.pack_start(splitter); + splitter.pack1( *magBox, true, true ); + splitter.pack2( *verts, false, false ); + + + //## The Refresh button + + + Gtk::HButtonBox* holder = new Gtk::HButtonBox( Gtk::BUTTONBOX_END ); + pack_end( *holder, false, false ); + + selectionButton = new Gtk::ToggleButton(_("Selection")); // , GTK_RESPONSE_APPLY + holder->pack_start( *selectionButton, false, false ); + tips.set_tip((*selectionButton), _("Selection only or whole document")); + selectionButton->signal_clicked().connect( sigc::mem_fun(*this, &IconPreviewPanel::modeToggled) ); + + gint val = prefs_get_int_attribute_limited( "iconpreview", "selectionOnly", 0, 0, 1 ); + selectionButton->set_active( val != 0 ); + + refreshButton = new Gtk::Button(Gtk::Stock::REFRESH); // , GTK_RESPONSE_APPLY + holder->pack_end( *refreshButton, false, false ); + tips.set_tip((*refreshButton), _("Refresh the icons")); + refreshButton->signal_clicked().connect( sigc::mem_fun(*this, &IconPreviewPanel::refreshPreview) ); + + + pack_start(iconBox, Gtk::PACK_EXPAND_WIDGET); + + show_all_children(); +} + +//######################################################################### +//## M E T H O D S +//######################################################################### + + +void IconPreviewPanel::refreshPreview() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + + if ( selectionButton && selectionButton->get_active() ) + { + Inkscape::Selection * sel = SP_DT_SELECTION(desktop); + if ( sel ) { + //g_message("found a selection to play with"); + + GSList const *items = sel->itemList(); + SPObject *target = 0; + while ( items && !target ) { + SPItem* item = SP_ITEM( items->data ); + SPObject * obj = SP_OBJECT(item); + gchar const *id = SP_OBJECT_ID( obj ); + if ( id ) { + target = obj; + } + + items = g_slist_next(items); + } + if ( target ) { + renderPreview(target); + } + } + } + else + { + SPObject *target = desktop->currentRoot(); + if ( target ) { + renderPreview(target); + } + } + } +} + +void IconPreviewPanel::modeToggled() +{ + prefs_set_int_attribute( "iconpreview", "selectionOnly", (selectionButton && selectionButton->get_active()) ? 1 : 0 ); + + refreshPreview(); +} + +void IconPreviewPanel::renderPreview( SPObject* obj ) +{ + SPDocument * doc = SP_OBJECT_DOCUMENT(obj); + gchar * id = SP_OBJECT_ID(obj); + +// g_message(" setting up to render '%s' as the icon", id ); + + NRArenaItem *root = NULL; + + /* Create new arena */ + NRArena *arena = NRArena::create(); + + /* Create ArenaItem and set transform */ + unsigned int visionkey = sp_item_display_key_new(1); + + /* fixme: Memory manage root if needed (Lauris) */ + root = sp_item_invoke_show ( SP_ITEM( SP_DOCUMENT_ROOT(doc) ), + arena, visionkey, SP_ITEM_SHOW_DISPLAY ); + + for ( int i = 0; i < numEntries; i++ ) { + guchar * px = sp_icon_doc_icon( doc, root, id, sizes[i] ); +// g_message( " size %d %s", sizes[i], (px ? "worked" : "failed") ); + if ( px ) { + memcpy( pixMem[i], px, sizes[i] * sizes[i] * 4 ); + g_free( px ); + px = 0; + } else { + memset( pixMem[i], 0, sizes[i] * sizes[i] * 4 ); + } + images[i]->queue_draw(); + } + updateMagnify(); +} + +void IconPreviewPanel::updateMagnify() +{ + Glib::RefPtr<Gdk::Pixbuf> buf = images[hot]->get_pixbuf()->scale_simple( 128, 128, Gdk::INTERP_NEAREST ); + magLabel.set_label( *labels[hot] ); + magnified.set( buf ); + magnified.queue_draw(); + magnified.get_parent()->queue_draw(); +} + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : + +//######################################################################### +//## E N D O F F I L E +//######################################################################### |
