From 50a5b62b327c55b8038b5031d35bf6ae48705485 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 21:08:09 -0500 Subject: Fixed size of swatches widget (bzr r13090.1.19) --- objects_dialog.patch | 3637 -------------------------------------------------- 1 file changed, 3637 deletions(-) delete mode 100644 objects_dialog.patch (limited to 'objects_dialog.patch') diff --git a/objects_dialog.patch b/objects_dialog.patch deleted file mode 100644 index 1cdd09c34..000000000 --- a/objects_dialog.patch +++ /dev/null @@ -1,3637 +0,0 @@ -=== modified file 'src/attributes.cpp' ---- src/attributes.cpp 2012-12-22 16:34:31 +0000 -+++ src/attributes.cpp 2013-03-17 14:36:44 +0000 -@@ -41,6 +41,7 @@ - {SP_ATTR_TRANSFORM_CENTER_X, "inkscape:transform-center-x"}, - {SP_ATTR_TRANSFORM_CENTER_Y, "inkscape:transform-center-y"}, - {SP_ATTR_INKSCAPE_PATH_EFFECT, "inkscape:path-effect"}, -+ {SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR, "inkscape:highlight-color"}, - /* SPAnchor */ - {SP_ATTR_XLINK_HREF, "xlink:href"}, - {SP_ATTR_XLINK_TYPE, "xlink:type"}, -@@ -50,7 +51,9 @@ - {SP_ATTR_XLINK_SHOW, "xlink:show"}, - {SP_ATTR_XLINK_ACTUATE, "xlink:actuate"}, - {SP_ATTR_TARGET, "target"}, -+ /* SPGroup */ - {SP_ATTR_INKSCAPE_GROUPMODE, "inkscape:groupmode"}, -+ {SP_ATTR_INKSCAPE_EXPANDED, "inkscape:expanded"}, - /* SPRoot */ - {SP_ATTR_VERSION, "version"}, - {SP_ATTR_WIDTH, "width"}, - -=== modified file 'src/attributes.h' ---- src/attributes.h 2012-12-22 16:34:31 +0000 -+++ src/attributes.h 2013-03-17 14:36:17 +0000 -@@ -40,6 +40,7 @@ - SP_ATTR_TRANSFORM_CENTER_X, - SP_ATTR_TRANSFORM_CENTER_Y, - SP_ATTR_INKSCAPE_PATH_EFFECT, -+ SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR, - /* SPAnchor */ - SP_ATTR_XLINK_HREF, - SP_ATTR_XLINK_TYPE, -@@ -51,6 +52,7 @@ - SP_ATTR_TARGET, - /* SPGroup */ - SP_ATTR_INKSCAPE_GROUPMODE, -+ SP_ATTR_INKSCAPE_EXPANDED, - /* SPRoot */ - SP_ATTR_VERSION, - SP_ATTR_WIDTH, - -=== modified file 'src/desktop.cpp' ---- src/desktop.cpp 2013-01-27 14:19:11 +0000 -+++ src/desktop.cpp 2013-03-17 14:43:46 +0000 -@@ -1885,6 +1885,7 @@ - std::map mapVerbPreference; - std::map::const_iterator iter; - mapVerbPreference.insert(std::make_pair ((int)SP_VERB_DIALOG_LAYERS, "/dialogs/layers") ); -+ mapVerbPreference.insert(std::make_pair ((int)SP_VERB_DIALOG_OBJECTS, "/dialogs/objects") ); - mapVerbPreference.insert(std::make_pair ((int)SP_VERB_DIALOG_FILL_STROKE, "/dialogs/fillstroke") ); - mapVerbPreference.insert(std::make_pair ((int)SP_VERB_DIALOG_EXTENSIONEDITOR, "/dialogs/extensioneditor") ); - mapVerbPreference.insert(std::make_pair ((int)SP_VERB_DIALOG_ALIGN_DISTRIBUTE, "/dialogs/align") ); - -=== modified file 'src/menus-skeleton.h' ---- src/menus-skeleton.h 2013-03-16 16:26:03 +0000 -+++ src/menus-skeleton.h 2013-03-17 14:30:19 +0000 -@@ -180,6 +180,8 @@ - " \n" - " \n" - " \n" -+" \n" -+" \n" - " \n" - " \n" - " \n" - -=== modified file 'src/sp-item-group.cpp' ---- src/sp-item-group.cpp 2013-01-24 11:43:26 +0000 -+++ src/sp-item-group.cpp 2013-03-17 14:50:17 +0000 -@@ -123,6 +123,7 @@ - static void sp_group_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) - { - object->readAttr( "inkscape:groupmode" ); -+ object->readAttr( "inkscape:expanded" ); - - if (((SPObjectClass *)sp_group_parent_class)->build) { - ((SPObjectClass *)sp_group_parent_class)->build(object, document, repr); -@@ -221,7 +222,7 @@ - Inkscape::GC::release((Inkscape::XML::Node *) l->data); - l = g_slist_remove (l, l->data); - } -- } else { -+ } else if (!(flags & SP_OBJECT_WRITE_NO_CHILDREN)) { - for (SPObject *child = object->firstChild() ; child ; child = child->getNext() ) { - if ( !SP_IS_TITLE(child) && !SP_IS_DESC(child) ) { - child->updateRepr(flags); -@@ -241,6 +242,12 @@ - value = NULL; - } - repr->setAttribute("inkscape:groupmode", value); -+ -+ if (group->_expanded) { -+ repr->setAttribute("inkscape:expanded", "true"); -+ } else { -+ repr->setAttribute("inkscape:expanded", NULL); -+ } - } - - if (((SPObjectClass *) (sp_group_parent_class))->write) { -@@ -280,6 +287,11 @@ - group->setLayerMode(SPGroup::GROUP); - } - break; -+ case SP_ATTR_INKSCAPE_EXPANDED: -+ if ( value && !strcmp(value, "true") ) { -+ group->setExpanded(true); -+ } -+ break; - default: { - if (((SPObjectClass *) (sp_group_parent_class))->set) { - (* ((SPObjectClass *) (sp_group_parent_class))->set)(object, key, value); -@@ -517,6 +529,12 @@ - } - } - -+void SPGroup::setExpanded(bool isexpanded) { -+ if ( _expanded != isexpanded ){ -+ _expanded = isexpanded; -+ } -+} -+ - SPGroup::LayerMode SPGroup::layerDisplayMode(unsigned int dkey) const { - std::map::const_iterator iter; - iter = _display_modes.find(dkey); - -=== modified file 'src/sp-item-group.h' ---- src/sp-item-group.h 2011-10-04 19:04:58 +0000 -+++ src/sp-item-group.h 2013-03-17 14:50:53 +0000 -@@ -36,11 +36,15 @@ - struct SPGroup : public SPLPEItem { - enum LayerMode { GROUP, LAYER, MASK_HELPER }; - -+ bool _expanded; - LayerMode _layer_mode; - std::map _display_modes; - - LayerMode layerMode() const { return _layer_mode; } - void setLayerMode(LayerMode mode); -+ -+ bool expanded() const { return _expanded; } -+ void setExpanded(bool isexpanded); - - LayerMode effectiveLayerMode(unsigned int display_key) const { - if ( _layer_mode == LAYER ) { - -=== modified file 'src/sp-item.cpp' ---- src/sp-item.cpp 2013-01-23 12:22:14 +0000 -+++ src/sp-item.cpp 2013-03-17 14:54:59 +0000 -@@ -72,6 +72,9 @@ - #include "live_effects/lpeobject.h" - #include "live_effects/effect.h" - #include "live_effects/lpeobject-reference.h" -+#include "ui/tool/node-tool.h" -+#include "ui/tool/multi-path-manipulator.h" -+#include "tools-switch.h" - - #define noSP_ITEM_DEBUG_IDLE - -@@ -135,6 +138,8 @@ - _is_evaluated = true; - _evaluated_status = StatusUnknown; - -+ _highlightColor = NULL; -+ - transform = Geom::identity(); - doc_bbox = Geom::OptRect(); - freeze_stroke_width = false; -@@ -210,6 +215,62 @@ - return true; - } - -+bool SPItem::isHighlightSet() const { -+ return _highlightColor != NULL; -+} -+ -+guint32 SPItem::highlight_color() const { -+ if (_highlightColor) -+ { -+ return atoi(_highlightColor) | 0x000000ff; -+ } -+ else if (parent && parent != this && SP_IS_ITEM(parent)) -+ { -+ return SP_ITEM(parent)->highlight_color(); -+ } -+ else -+ { -+ static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); -+ return prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff) | 0x000000ff; -+ } -+} -+ -+void SPItem::setHighlightColor(guint32 const color) -+{ -+ g_free(_highlightColor); -+ if (color & 0x000000ff) -+ { -+ _highlightColor = g_strdup_printf("%u", color); -+ } -+ else -+ { -+ _highlightColor = NULL; -+ } -+ -+ InkNodeTool *tool = 0; -+ if (SP_ACTIVE_DESKTOP ) { -+ SPEventContext *ec = SP_ACTIVE_DESKTOP->event_context; -+ if (INK_IS_NODE_TOOL(ec)) { -+ tool = static_cast(ec); -+ tools_switch(tool->desktop, TOOLS_NODES); -+ } -+ } -+} -+ -+void SPItem::unsetHighlightColor() -+{ -+ g_free(_highlightColor); -+ _highlightColor = NULL; -+ InkNodeTool *tool = 0; -+ if (SP_ACTIVE_DESKTOP ) { -+ SPEventContext *ec = SP_ACTIVE_DESKTOP->event_context; -+ if (INK_IS_NODE_TOOL(ec)) { -+ tool = static_cast(ec); -+ tools_switch(tool->desktop, TOOLS_NODES); -+ } -+ } -+} -+ - void SPItem::setEvaluated(bool evaluated) { - _is_evaluated = evaluated; - _evaluated_status = StatusSet; -@@ -387,14 +448,30 @@ - while (target_ref->parent() != target_ref->root()) { - target_ref = target_ref->parent(); - } -+ if (target_ref) { -+ SPObject *obj = document->getObjectByRepr(target_ref); -+ if (SP_IS_ITEM(obj)) { -+ target = SP_ITEM(obj); -+ } -+ } - first = TRUE; - } -+ -+ g_assert(target_ref != NULL); - - if (intoafter) { -+ Geom::Affine t = getRelativeTransform(target); -+ doWriteTransform(our_ref, t); -+ our_ref = getRepr(); -+ - // Move this inside of the target at the end - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else if (target_ref->parent() != our_ref->parent()) { -+ Geom::Affine t = getRelativeTransform(target->parent); -+ doWriteTransform(our_ref, t); -+ our_ref = getRepr(); -+ - // Change in parent, need to remove and add - our_ref->parent()->removeChild(our_ref); - target_ref->parent()->addChild(our_ref, target_ref); -@@ -424,6 +501,7 @@ - object->readAttr( "inkscape:transform-center-y" ); - object->readAttr( "inkscape:connector-avoid" ); - object->readAttr( "inkscape:connection-points" ); -+ object->readAttr( "inkscape:highlight-color" ); - - if ((SP_OBJECT_CLASS(sp_item_parent_class))->build) { - (* (SP_OBJECT_CLASS(sp_item_parent_class))->build)(object, document, repr); -@@ -510,6 +588,14 @@ - v->arenaitem->setSensitive(item->sensitive); - } - break; -+ case SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR: -+ g_free(item->_highlightColor); -+ if (value) { -+ item->_highlightColor = g_strdup(value); -+ } else { -+ item->_highlightColor = NULL; -+ } -+ break; - case SP_ATTR_CONNECTOR_AVOID: - item->avoidRef->setAvoid(value); - break; -@@ -720,6 +806,11 @@ - g_free ((void *) value); - } - } -+ if (item->_highlightColor){ -+ repr->setAttribute("inkscape:highlight-color", item->_highlightColor); -+ } else { -+ repr->setAttribute("inkscape:highlight-color", NULL); -+ } - - if ((SP_OBJECT_CLASS(sp_item_parent_class))->write) { - (SP_OBJECT_CLASS(sp_item_parent_class))->write(object, xml_doc, repr, flags); - -=== modified file 'src/sp-item.h' ---- src/sp-item.h 2013-03-14 23:24:17 +0000 -+++ src/sp-item.h 2013-03-17 14:51:37 +0000 -@@ -144,11 +144,21 @@ - - void init(); - bool isLocked() const; -+ bool isSensitive() const { -+ return sensitive; -+ }; - void setLocked(bool lock); - - bool isHidden() const; - void setHidden(bool hidden); - -+ bool isHighlightSet() const; -+ guint32 highlight_color() const; -+ -+ void setHighlightColor(guint32 color); -+ -+ void unsetHighlightColor(); -+ - bool isEvaluated() const; - void setEvaluated(bool visible); - void resetEvaluated(); -@@ -218,6 +228,7 @@ - Geom::Affine dt2i_affine() const; - void convert_to_guides(); - -+ gchar *_highlightColor; - private: - enum EvaluatedStatus - { - -=== modified file 'src/sp-object.h' ---- src/sp-object.h 2013-03-14 01:33:10 +0000 -+++ src/sp-object.h 2013-03-17 14:53:10 +0000 -@@ -48,6 +48,7 @@ - #define SP_OBJECT_WRITE_BUILD (1 << 0) - #define SP_OBJECT_WRITE_EXT (1 << 1) - #define SP_OBJECT_WRITE_ALL (1 << 2) -+#define SP_OBJECT_WRITE_NO_CHILDREN (1 << 3) - - #include - #include - -=== modified file 'src/ui/dialog/Makefile_insert' ---- src/ui/dialog/Makefile_insert 2012-10-11 17:54:14 +0000 -+++ src/ui/dialog/Makefile_insert 2013-03-17 13:55:34 +0000 -@@ -70,6 +70,8 @@ - ui/dialog/memory.h \ - ui/dialog/messages.cpp \ - ui/dialog/messages.h \ -+ ui/dialog/objects.cpp \ -+ ui/dialog/objects.h \ - ui/dialog/ocaldialogs.cpp \ - ui/dialog/ocaldialogs.h \ - ui/dialog/object-attributes.cpp \ - -=== modified file 'src/ui/dialog/dialog-manager.cpp' ---- src/ui/dialog/dialog-manager.cpp 2013-03-16 16:26:03 +0000 -+++ src/ui/dialog/dialog-manager.cpp 2013-03-17 14:03:02 +0000 -@@ -40,6 +40,7 @@ - #include "ui/dialog/undo-history.h" - #include "ui/dialog/panel-dialog.h" - #include "ui/dialog/layers.h" -+#include "ui/dialog/objects.h" - #include "ui/dialog/icon-preview.h" - #include "ui/dialog/floating-behavior.h" - #include "ui/dialog/dock-behavior.h" -@@ -108,6 +109,7 @@ - registerFactory("IconPreviewPanel", &create); - registerFactory("InkscapePreferences", &create); - registerFactory("LayersPanel", &create); -+ registerFactory("ObjectsPanel", &create); - registerFactory("LivePathEffect", &create); - registerFactory("Memory", &create); - registerFactory("Messages", &create); -@@ -142,6 +144,7 @@ - registerFactory("IconPreviewPanel", &create); - registerFactory("InkscapePreferences", &create); - registerFactory("LayersPanel", &create); -+ registerFactory("ObjectsPanel", &create); - registerFactory("LivePathEffect", &create); - registerFactory("Memory", &create); - registerFactory("Messages", &create); - -=== added file 'src/ui/dialog/objects.cpp' ---- src/ui/dialog/objects.cpp 1970-01-01 00:00:00 +0000 -+++ src/ui/dialog/objects.cpp 2013-03-17 15:01:22 +0000 -@@ -0,0 +1,2014 @@ -+/* -+ * A simple panel for objects -+ * -+ * Authors: -+ * Theodore Janeczko -+ * -+ * Copyright (C) Theodore Janeczko 2012 -+ * -+ * Released under GNU GPL, read the file 'COPYING' for more information -+ */ -+#ifdef HAVE_CONFIG_H -+# include -+#endif -+ -+#include "objects.h" -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "desktop.h" -+#include "desktop-style.h" -+#include "document.h" -+#include "document-undo.h" -+#include "helper/action.h" -+#include "inkscape.h" -+#include "preferences.h" -+#include "sp-item.h" -+#include "sp-object.h" -+#include "sp-shape.h" -+#include "svg/css-ostringstream.h" -+#include "ui/icon-names.h" -+#include "ui/widget/imagetoggler.h" -+#include "ui/widget/layertypeicon.h" -+#include "ui/widget/clipmaskicon.h" -+#include "ui/widget/highlight-picker.h" -+#include "verbs.h" -+#include "widgets/icon.h" -+#include "xml/node.h" -+#include "xml/node-observer.h" -+#include "xml/repr.h" -+#include "sp-root.h" -+#include "event-context.h" -+#include "selection.h" -+#include "dialogs/dialog-events.h" -+#include "widgets/sp-color-notebook.h" -+#include "style.h" -+#include "filter-chemistry.h" -+#include "filters/blend.h" -+#include "filters/gaussian-blur.h" -+#include "sp-clippath.h" -+#include "sp-mask.h" -+#include "layer-manager.h" -+ -+//#define DUMP_LAYERS 1 -+ -+namespace Inkscape { -+namespace UI { -+namespace Dialog { -+ -+using Inkscape::XML::Node; -+ -+/** -+ * Gets an instance of the Objects panel -+ */ -+ObjectsPanel& ObjectsPanel::getInstance() -+{ -+ return *new ObjectsPanel(); -+} -+ -+/** -+ * Column enumeration -+ */ -+enum { -+ COL_VISIBLE = 1, -+ COL_LOCKED, -+ COL_TYPE, -+ COL_CLIPMASK, -+ COL_HIGHLIGHT -+}; -+ -+/** -+ * Button enumeration -+ */ -+enum { -+ BUTTON_NEW = 0, -+ BUTTON_RENAME, -+ BUTTON_TOP, -+ BUTTON_BOTTOM, -+ BUTTON_UP, -+ BUTTON_DOWN, -+ BUTTON_DUPLICATE, -+ BUTTON_DELETE, -+ BUTTON_SOLO, -+ BUTTON_SHOW_ALL, -+ BUTTON_HIDE_ALL, -+ BUTTON_LOCK_OTHERS, -+ BUTTON_LOCK_ALL, -+ BUTTON_UNLOCK_ALL, -+ BUTTON_SETCLIP, -+ BUTTON_UNSETCLIP, -+ BUTTON_SETMASK, -+ BUTTON_UNSETMASK, -+ BUTTON_GROUP, -+ BUTTON_UNGROUP, -+ BUTTON_COLLAPSE_ALL, -+ DRAGNDROP -+}; -+ -+/** -+ * Xml node observer for observing objects in the document -+ */ -+class ObjectsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { -+public: -+ /** -+ * Creates a new object watcher -+ * @param pnl The panel to which the object watcher belongs -+ * @param obj The object to watch -+ */ -+ ObjectWatcher(ObjectsPanel* pnl, SPObject* obj) : -+ _pnl(pnl), -+ _obj(obj), -+ _repr(obj->getRepr()), -+ _highlightAttr(g_quark_from_string("inkscape:highlight-color")), -+ _lockedAttr(g_quark_from_string("sodipodi:insensitive")), -+ _labelAttr(g_quark_from_string("inkscape:label")), -+ _groupAttr(g_quark_from_string("inkscape:groupmode")), -+ _styleAttr(g_quark_from_string("style")), -+ _clipAttr(g_quark_from_string("clip-path")), -+ _maskAttr(g_quark_from_string("mask")) -+ {} -+ -+ virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) -+ { -+ if ( _pnl && _obj ) { -+ _pnl->_objectsChanged( _obj ); -+ } -+ } -+ virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) -+ { -+ if ( _pnl && _obj ) { -+ _pnl->_objectsChanged( _obj ); -+ } -+ } -+ virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) -+ { -+ if ( _pnl && _obj ) { -+ _pnl->_objectsChanged( _obj ); -+ } -+ } -+ virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} -+ virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { -+ if ( _pnl && _obj ) { -+ if ( name == _lockedAttr || name == _labelAttr || name == _highlightAttr || name == _groupAttr || name == _styleAttr || name == _clipAttr || name == _maskAttr ) { -+ _pnl->_updateObject(_obj, name == _highlightAttr); -+ if ( name == _styleAttr ) { -+ _pnl->_updateComposite(); -+ } -+ } -+ } -+ } -+ -+ /** -+ * Objects panel to which this watcher belongs -+ */ -+ ObjectsPanel* _pnl; -+ -+ /** -+ * The object that is being observed -+ */ -+ SPObject* _obj; -+ -+ /** -+ * The xml representation of the object that is being observed -+ */ -+ Inkscape::XML::Node* _repr; -+ -+ /* These are quarks which define the attributes that we are observing */ -+ GQuark _highlightAttr; -+ GQuark _lockedAttr; -+ GQuark _labelAttr; -+ GQuark _groupAttr; -+ GQuark _styleAttr; -+ GQuark _clipAttr; -+ GQuark _maskAttr; -+}; -+ -+class ObjectsPanel::InternalUIBounce -+{ -+public: -+ int _actionCode; -+}; -+ -+class ObjectsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord -+{ -+public: -+ -+ ModelColumns() -+ { -+ add(_colObject); -+ add(_colVisible); -+ add(_colLocked); -+ add(_colLabel); -+ add(_colType); -+ add(_colHighlight); -+ add(_colClipMask); -+ } -+ virtual ~ModelColumns() {} -+ -+ Gtk::TreeModelColumn _colObject; -+ Gtk::TreeModelColumn _colLabel; -+ Gtk::TreeModelColumn _colVisible; -+ Gtk::TreeModelColumn _colLocked; -+ Gtk::TreeModelColumn _colType; -+ Gtk::TreeModelColumn _colHighlight; -+ Gtk::TreeModelColumn _colClipMask; -+}; -+ -+/** -+ * Stylizes a button using the given icon name and tooltip -+ */ -+void ObjectsPanel::_styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip ) -+{ -+ GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); -+ gtk_widget_show( child ); -+ btn.add( *Gtk::manage(Glib::wrap(child)) ); -+ btn.set_relief(Gtk::RELIEF_NONE); -+ -+ btn.set_tooltip_text (tooltip); -+ -+} -+ -+/** -+ * Adds an item to the pop-up (right-click) menu -+ * @param desktop The active destktop -+ * @param code Action code -+ * @param iconName Icon name -+ * @param fallback Fallback text -+ * @param id Button id for callback function -+ * @return The generated menu item -+ */ -+Gtk::MenuItem& ObjectsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) -+{ -+ GtkWidget* iconWidget = 0; -+ const char* label = 0; -+ -+ if ( iconName ) { -+ iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); -+ } -+ -+ if ( desktop ) { -+ Verb *verb = Verb::get( code ); -+ if ( verb ) { -+ SPAction *action = verb->get_action(desktop); -+ if ( !iconWidget && action && action->image ) { -+ iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); -+ } -+ -+ if ( action ) { -+ label = action->name; -+ } -+ } -+ } -+ -+ if ( !label && fallback ) { -+ label = fallback; -+ } -+ -+ Gtk::Widget* wrapped = 0; -+ if ( iconWidget ) { -+ wrapped = Gtk::manage(Glib::wrap(iconWidget)); -+ wrapped->show(); -+ } -+ -+ -+ Gtk::MenuItem* item = 0; -+ -+ if (wrapped) { -+ item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); -+ } else { -+ item = Gtk::manage(new Gtk::MenuItem(label, true)); -+ } -+ -+ item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_takeAction), id)); -+ _popupMenu.append(*item); -+ -+ return *item; -+} -+ -+/** -+ * Callback function for when an object changes. Essentially refreshes the entire tree -+ * @param obj Object which was changed (currently not used as the entire tree is recreated) -+ */ -+void ObjectsPanel::_objectsChanged(SPObject */*obj*/) -+{ -+ //First, unattach the watchers -+ while (!_objectWatchers.empty()) -+ { -+ ObjectsPanel::ObjectWatcher *w = _objectWatchers.back(); -+ w->_repr->removeObserver(*w); -+ _objectWatchers.pop_back(); -+ delete w; -+ } -+ -+ if (_desktop) { -+ //Get the current document's root and use that to enumerate the tree -+ SPDocument* document = _desktop->doc(); -+ SPRoot* root = document->getRoot(); -+ if ( root ) { -+ _selectedConnection.block(); -+ //Clear the tree store -+ _store->clear(); -+ //Add all items recursively -+ _addObject( root, 0 ); -+ _selectedConnection.unblock(); -+ //Set the tree selection -+ _objectsSelected(_desktop->selection); -+ //Handle button sensitivity -+ _checkTreeSelection(); -+ } -+ } -+} -+ -+/** -+ * Recursively adds the children of the given item to the tree -+ * @param obj Root object to add to the tree -+ * @param parentRow Parent tree row (or NULL if adding to tree root) -+ */ -+void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) -+{ -+ if ( _desktop && obj ) { -+ for ( SPObject *child = obj->children; child != NULL; child = child->next) { -+ -+ if (SP_IS_ITEM(child)) -+ { -+ SPItem * item = SP_ITEM(child); -+ SPGroup * group = SP_IS_GROUP(child) ? SP_GROUP(child) : 0; -+ -+ //Add the item to the tree and set the column information -+ Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); -+ Gtk::TreeModel::Row row = *iter; -+ row[_model->_colObject] = item; -+ row[_model->_colLabel] = item->label() ? item->label() : item->getId(); -+ row[_model->_colVisible] = !item->isHidden(); -+ row[_model->_colLocked] = !item->isSensitive(); -+ row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; -+ row[_model->_colHighlight] = item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00; -+ row[_model->_colClipMask] = item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0); -+ -+ //If our parent object is a group and it's expanded, expand the tree -+ if (SP_IS_GROUP(obj) && SP_GROUP(obj)->expanded()) -+ { -+ _tree.expand_to_path( _store->get_path(iter) ); -+ } -+ -+ //Add an object watcher to the item -+ ObjectsPanel::ObjectWatcher *w = new ObjectsPanel::ObjectWatcher(this, child); -+ child->getRepr()->addObserver(*w); -+ _objectWatchers.push_back(w); -+ -+ //If the item is a group, recursively add its children -+ if (group) -+ { -+ _addObject( child, &row ); -+ } -+ } -+ } -+ } -+} -+ -+/** -+ * Updates an item in the tree and optionally recursively updates the item's children -+ * @param obj The item to update in the tree -+ * @param recurse Whether to recurse through the item's children -+ */ -+void ObjectsPanel::_updateObject( SPObject *obj, bool recurse ) { -+ //Find the object in the tree store and update it -+ _store->foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_checkForUpdated), obj) ); -+ if (recurse) -+ { -+ for (SPObject * iter = obj->children; iter != NULL; iter = iter->next) -+ { -+ _updateObject(iter, recurse); -+ } -+ } -+} -+ -+/** -+ * Checks items in the tree store and updates the given item -+ * @param iter Current item being looked at in the tree -+ * @param obj Object to update -+ * @return -+ */ -+bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj) -+{ -+ Gtk::TreeModel::Row row = *iter; -+ if ( obj == row[_model->_colObject] ) -+ { -+ //We found our item in the tree!! Update it! -+ SPItem * item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; -+ SPGroup * group = SP_IS_GROUP(obj) ? SP_GROUP(obj) : 0; -+ -+ row[_model->_colLabel] = obj->label() ? obj->label() : obj->getId(); -+ row[_model->_colVisible] = item ? !item->isHidden() : false; -+ row[_model->_colLocked] = item ? !item->isSensitive() : false; -+ row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; -+ row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0; -+ row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; -+ -+ return true; -+ } -+ -+ return false; -+} -+ -+/** -+ * Updates the composite controls for the selected item -+ */ -+void ObjectsPanel::_updateComposite() { -+ if (!_blockCompositeUpdate) -+ { -+ //Set the default values -+ bool setValues = true; -+ -+ //Get/set the values -+ _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_compositingChanged), &setValues)); -+ } -+} -+ -+/** -+ * Sets the compositing values for the first selected item in the tree -+ * @param iter Current tree item -+ * @param setValues Whether to set the compositing values -+ * @param blur Blur value to use -+ */ -+void ObjectsPanel::_compositingChanged( const Gtk::TreeModel::iterator& iter, bool *setValues ) -+{ -+ if (iter) { -+ Gtk::TreeModel::Row row = *iter; -+ SPItem *item = row[_model->_colObject]; -+ if (*setValues) -+ { -+ _setCompositingValues(item); -+ *setValues = false; -+ } -+ } -+} -+ -+/** -+ * Occurs when the current desktop selection changes -+ * @param sel The current selection -+ */ -+void ObjectsPanel::_objectsSelected( Selection *sel ) { -+ -+ bool setOpacity = true; -+ _selectedConnection.block(); -+ _tree.get_selection()->unselect_all(); -+ SPItem *item = NULL; -+ for (const GSList * iter = sel->itemList(); iter != NULL; iter = iter->next) -+ { -+ item = reinterpret_cast(iter->data); -+ if (setOpacity) -+ { -+ _setCompositingValues(item); -+ setOpacity = false; -+ } -+ _store->foreach(sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, iter->next == NULL)); -+ } -+ if (!item) { -+ if (_desktop->currentLayer() && SP_IS_ITEM(_desktop->currentLayer())) { -+ item = SP_ITEM(_desktop->currentLayer()); -+ _setCompositingValues(item); -+ _store->foreach(sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, true)); -+ } -+ } -+ _selectedConnection.unblock(); -+ _checkTreeSelection(); -+} -+ -+/** -+ * Helper function for setting the compositing values -+ * @param item Item to use for setting the compositing values -+ */ -+void ObjectsPanel::_setCompositingValues(SPItem *item) -+{ -+ //Block the connections to avoid interference -+ _opacityConnection.block(); -+ _blendConnection.block(); -+ _blurConnection.block(); -+ -+ //Set the opacity -+ _opacity_adjustment.set_value((item->style->opacity.set ? SP_SCALE24_TO_FLOAT(item->style->opacity.value) : 1) * _opacity_adjustment.get_upper()); -+ SPFeBlend *spblend = NULL; -+ SPGaussianBlur *spblur = NULL; -+ if (item->style->getFilter()) -+ { -+ for(SPObject *primitive_obj = item->style->getFilter()->children; primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj); primitive_obj = primitive_obj->next) { -+ if(SP_IS_FEBLEND(primitive_obj) && !spblend) { -+ //Get the blend mode -+ spblend = SP_FEBLEND(primitive_obj); -+ } -+ -+ if(SP_IS_GAUSSIANBLUR(primitive_obj) && !spblur) { -+ //Get the blur value -+ spblur = SP_GAUSSIANBLUR(primitive_obj); -+ } -+ } -+ } -+ -+ //Set the blend mode -+ _fe_cb.set_blend_mode(spblend ? spblend->blend_mode : Inkscape::Filters::BLEND_NORMAL); -+ -+ //Set the blur value -+ Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); -+ if (bbox && spblur) { -+ double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? -+ _fe_blur.set_blur_value(spblur->stdDeviation.getNumber() * 400 / perimeter); -+ } else { -+ _fe_blur.set_blur_value(0); -+ } -+ -+ //Unblock connections -+ _blurConnection.unblock(); -+ _blendConnection.unblock(); -+ _opacityConnection.unblock(); -+} -+ -+/** -+ * Checks the tree and selects the specified item, optionally scrolling to the item -+ * @param path Current tree path -+ * @param iter Current tree item -+ * @param item Item to select in the tree -+ * @param scrollto Whether to scroll to the item -+ * @return Whether to continue searching the tree -+ */ -+bool ObjectsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto) -+{ -+ bool stopGoing = false; -+ -+ Gtk::TreeModel::Row row = *iter; -+ if ( item == row[_model->_colObject] ) -+ { -+ //We found the item! Expand to the path and select it in the tree. -+ _tree.expand_to_path( path ); -+ -+ Glib::RefPtr select = _tree.get_selection(); -+ -+ select->select(iter); -+ if (scrollto) { -+ //Scroll to the item in the tree -+ _tree.scroll_to_row(path); -+ } -+ -+ stopGoing = true; -+ } -+ -+ return stopGoing; -+} -+ -+/** -+ * Pushes the current tree selection to the canvas -+ */ -+void ObjectsPanel::_pushTreeSelectionToCurrent() -+{ -+ if ( _desktop && _desktop->currentRoot() ) { -+ //block connections for selection and compositing values to prevent interference -+ _selectionChangedConnection.block(); -+ -+ //Clear the selection and then iterate over the tree selection, pushing each item to the desktop -+ _desktop->selection->clear(); -+ bool setOpacity = true; -+ _tree.get_selection()->selected_foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_selected_row_callback), &setOpacity)); -+ //unblock connections -+ _selectionChangedConnection.unblock(); -+ -+ _checkTreeSelection(); -+ } -+} -+ -+/** -+ * Helper function for pushing the current tree selection to the current desktop -+ * @param iter Current tree item -+ * @param setCompositingValues Whether to set the compositing values -+ * @param blur -+ */ -+void ObjectsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter, bool *setCompositingValues ) -+{ -+ if (iter) { -+ Gtk::TreeModel::Row row = *iter; -+ SPItem *item = row[_model->_colObject]; -+ if (!SP_IS_GROUP(item) || SP_GROUP(item)->layerMode() != SPGroup::LAYER) -+ { -+ //If the item is not a layer, then select it and set the current layer to its parent (if it's the first item) -+ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); -+ _desktop->selection->add(item); -+ } -+ else -+ { -+ //If the item is a layer, set the current layer -+ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item); -+ } -+ if (*setCompositingValues) -+ { -+ //Only set the compositing values for the first item -+ _setCompositingValues(item); -+ *setCompositingValues = false; -+ } -+ } -+} -+ -+/** -+ * Handles button sensitivity -+ */ -+void ObjectsPanel::_checkTreeSelection() -+{ -+ bool sensitive = _tree.get_selection()->count_selected_rows() > 0; -+ //TODO: top/bottom sensitivity -+ bool sensitiveNonTop = true; -+ bool sensitiveNonBottom = true; -+ -+ for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { -+ (*it)->set_sensitive( sensitive ); -+ } -+ for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { -+ (*it)->set_sensitive( sensitiveNonTop ); -+ } -+ for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { -+ (*it)->set_sensitive( sensitiveNonBottom ); -+ } -+} -+ -+/** -+ * Sets visibility of items in the tree -+ * @param iter Current item in the tree -+ * @param visible Whether the item should be visible or not -+ */ -+void ObjectsPanel::_setVisibleIter( const Gtk::TreeModel::iterator& iter, const bool visible ) -+{ -+ Gtk::TreeModel::Row row = *iter; -+ SPItem* item = row[_model->_colObject]; -+ if (item) -+ { -+ item->setHidden( !visible ); -+ row[_model->_colVisible] = visible; -+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); -+ } -+} -+ -+/** -+ * Sets sensitivity of items in the tree -+ * @param iter Current item in the tree -+ * @param locked Whether the item should be locked -+ */ -+void ObjectsPanel::_setLockedIter( const Gtk::TreeModel::iterator& iter, const bool locked ) -+{ -+ Gtk::TreeModel::Row row = *iter; -+ SPItem* item = row[_model->_colObject]; -+ if (item) -+ { -+ item->setLocked( locked ); -+ row[_model->_colLocked] = locked; -+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); -+ } -+} -+ -+/** -+ * Handles keyboard events -+ * @param event Keyboard event passed in from GDK -+ * @return Whether the event should be eaten (om nom nom) -+ */ -+bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) -+{ -+ -+ switch (get_group0_keyval(event)) { -+ case GDK_KEY_Return: -+ case GDK_KEY_KP_Enter: -+ case GDK_KEY_F2: -+ { -+ Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); -+ if (iter && !_text_renderer->property_editable()) { -+ //Rename item -+ Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); -+ _text_renderer->property_editable() = true; -+ _tree.set_cursor(*path, *_name_column, true); -+ grab_focus(); -+ return true; -+ } -+ } -+ break; -+ case GDK_Home: -+ { -+ //Move item(s) to top of containing group/layer -+ if (_desktop->selection->isEmpty()) -+ { -+ _fireAction( SP_VERB_LAYER_TO_TOP ); -+ } -+ else -+ { -+ _fireAction( SP_VERB_SELECTION_TO_FRONT ); -+ } -+ return true; -+ } -+ case GDK_End: -+ { -+ //Move item(s) to bottom of containing group/layer -+ if (_desktop->selection->isEmpty()) -+ { -+ _fireAction( SP_VERB_LAYER_TO_BOTTOM ); -+ } -+ else -+ { -+ _fireAction( SP_VERB_SELECTION_TO_BACK ); -+ } -+ return true; -+ } -+ case GDK_KEY_Page_Up: -+ { -+ //Move item(s) up in containing group/layer -+ if (_desktop->selection->isEmpty()) -+ { -+ _fireAction( SP_VERB_LAYER_RAISE ); -+ } -+ else -+ { -+ if (event->state & GDK_SHIFT_MASK) { -+ _fireAction( SP_VERB_LAYER_MOVE_TO_NEXT ); -+ } else { -+ _fireAction( SP_VERB_SELECTION_RAISE ); -+ } -+ } -+ return true; -+ } -+ case GDK_KEY_Page_Down: -+ { -+ //Move item(s) down in containing group/layer -+ if (_desktop->selection->isEmpty()) -+ { -+ _fireAction( SP_VERB_LAYER_LOWER ); -+ } -+ else -+ { -+ if (event->state & GDK_SHIFT_MASK) { -+ _fireAction( SP_VERB_LAYER_MOVE_TO_PREV ); -+ } else { -+ _fireAction( SP_VERB_SELECTION_LOWER ); -+ } -+ } -+ return true; -+ } -+ //TODO: Handle Ctrl-A, etc. -+ } -+ return false; -+} -+ -+/** -+ * Handles mouse events -+ * @param event Mouse event from GDK -+ * @return whether to eat the event (om nom nom) -+ */ -+bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) -+{ -+ static unsigned doubleclick = 0; -+ static bool overVisible = false; -+ -+ //Right mouse button was clicked, launch the pop-up menu -+ if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { -+ Gtk::TreeModel::Path path; -+ int x = static_cast(event->x); -+ int y = static_cast(event->y); -+ if ( _tree.get_path_at_pos( x, y, path ) ) { -+ _checkTreeSelection(); -+ _popupMenu.popup(event->button, event->time); -+ if (_tree.get_selection()->is_selected(path)) { -+ return true; -+ } -+ } -+ } -+ -+ //Left mouse button was pressed! In order to handle multiple item drag & drop, -+ //we need to defer selection by setting the select function so that the tree doesn't -+ //automatically select anything. In order to handle multiple item icon clicking, -+ //we need to eat the event. There might be a better way to do both of these... -+ if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { -+ overVisible = false; -+ Gtk::TreeModel::Path path; -+ Gtk::TreeViewColumn* col = 0; -+ int x = static_cast(event->x); -+ int y = static_cast(event->y); -+ int x2 = 0; -+ int y2 = 0; -+ if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { -+ if (col == _tree.get_column(COL_VISIBLE-1)) { -+ //Click on visible column, eat this event to keep row selection -+ overVisible = true; -+ return true; -+ } else if (col == _tree.get_column(COL_LOCKED-1) || -+ col == _tree.get_column(COL_TYPE-1) || -+ col == _tree.get_column(COL_HIGHLIGHT-1)) { -+ //Click on an icon column, eat this event to keep row selection -+ return true; -+ } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { -+ //Click on a selected item with no modifiers, defer selection to the mouse-up by -+ //setting the select function to _noSelection -+ _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &ObjectsPanel::_noSelection)); -+ _defer_target = path; -+ } -+ } -+ } -+ -+ //Restore the selection function to allow tree selection on mouse button release -+ if ( event->type == GDK_BUTTON_RELEASE) { -+ _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &ObjectsPanel::_rowSelectFunction)); -+ } -+ -+ //CellRenderers do not have good support for dealing with multiple items, so -+ //we handle all events on them here -+ if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) { -+ -+ Gtk::TreeModel::Path path; -+ Gtk::TreeViewColumn* col = 0; -+ int x = static_cast(event->x); -+ int y = static_cast(event->y); -+ int x2 = 0; -+ int y2 = 0; -+ if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { -+ if (_defer_target) { -+ //We had deferred a selection target, select it here (assuming no drag & drop) -+ if (_defer_target == path && !(event->x == 0 && event->y == 0)) -+ { -+ _tree.set_cursor(path, *col, false); -+ } -+ _defer_target = Gtk::TreeModel::Path(); -+ } -+ else { -+ if (event->state & GDK_SHIFT_MASK) { -+ // Shift left click on the visible/lock columns toggles "solo" mode -+ if (col == _tree.get_column(COL_VISIBLE - 1)) { -+ _takeAction(BUTTON_SOLO); -+ } else if (col == _tree.get_column(COL_LOCKED - 1)) { -+ _takeAction(BUTTON_LOCK_OTHERS); -+ } -+ } else if (event->state & GDK_MOD1_MASK) { -+ // Alt+left click on the visible/lock columns toggles "solo" mode and preserves selection -+ Gtk::TreeModel::iterator iter = _store->get_iter(path); -+ if (_store->iter_is_valid(iter)) { -+ Gtk::TreeModel::Row row = *iter; -+ SPItem *item = row[_model->_colObject]; -+ if (col == _tree.get_column(COL_VISIBLE - 1)) { -+ _desktop->toggleLayerSolo( item ); -+ DocumentUndo::maybeDone(_desktop->doc(), "layer:solo", SP_VERB_LAYER_SOLO, _("Toggle layer solo")); -+ } else if (col == _tree.get_column(COL_LOCKED - 1)) { -+ _desktop->toggleLockOtherLayers( item ); -+ DocumentUndo::maybeDone(_desktop->doc(), "layer:lockothers", SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers")); -+ } -+ } -+ } else { -+ Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); -+ Gtk::TreeModel::Row row = *iter; -+ -+ SPItem* item = row[_model->_colObject]; -+ -+ if (col == _tree.get_column(COL_VISIBLE - 1)) { -+ if (overVisible) { -+ //Toggle visibility -+ bool newValue = !row[_model->_colVisible]; -+ if (_tree.get_selection()->is_selected(path)) -+ { -+ //If the current row is selected, toggle the visibility -+ //for all selected items -+ _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setVisibleIter), newValue)); -+ } -+ else -+ { -+ //If the current row is not selected, toggle just its visibility -+ row[_model->_colVisible] = newValue; -+ item->setHidden(!newValue); -+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); -+ } -+ DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, -+ newValue? _("Unhide objects") : _("Hide objects")); -+ overVisible = false; -+ } -+ } else if (col == _tree.get_column(COL_LOCKED - 1)) { -+ //Toggle locking -+ bool newValue = !row[_model->_colLocked]; -+ if (_tree.get_selection()->is_selected(path)) -+ { -+ //If the current row is selected, toggle the sensitivity for -+ //all selected items -+ _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setLockedIter), newValue)); -+ } -+ else -+ { -+ //If the current row is not selected, toggle just its sensitivity -+ row[_model->_colLocked] = newValue; -+ item->setLocked( newValue ); -+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); -+ } -+ DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, -+ newValue? _("Lock objects") : _("Unlock objects")); -+ -+ } else if (col == _tree.get_column(COL_TYPE - 1)) { -+ if (SP_IS_GROUP(item)) -+ { -+ //Toggle the current item between a group and a layer -+ SPGroup * g = SP_GROUP(item); -+ bool newValue = g->layerMode() == SPGroup::LAYER; -+ row[_model->_colType] = newValue ? 1: 2; -+ g->setLayerMode(newValue ? SPGroup::GROUP : SPGroup::LAYER); -+ g->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); -+ DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, -+ newValue? _("Layer to group") : _("Group to layer")); -+ } -+ } else if (col == _tree.get_column(COL_HIGHLIGHT - 1)) { -+ //Clear the highlight targets -+ _highlight_target.clear(); -+ if (_tree.get_selection()->is_selected(path)) -+ { -+ //If the current item is selected, store all selected items -+ //in the highlight source -+ _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_storeHighlightTarget)); -+ } else { -+ //If the current item is not selected, store only it in the highlight source -+ _storeHighlightTarget(iter); -+ } -+ if (_colorSelector) -+ { -+ //Set up the color selector -+ SPColor color; -+ color.set( row[_model->_colHighlight] ); -+ _colorSelector->base->setColorAlpha(color, SP_RGBA32_A_F(row[_model->_colHighlight])); -+ } -+ //Show the color selector dialog -+ _colorSelectorDialog.show(); -+ } -+ } -+ } -+ } -+ } -+ -+ //Second mouse button press, set double click status for when the mouse is released -+ if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { -+ doubleclick = 1; -+ } -+ -+ //Double click on mouse button release, if we're over the label column, edit -+ //the item name -+ if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { -+ doubleclick = 0; -+ Gtk::TreeModel::Path path; -+ Gtk::TreeViewColumn* col = 0; -+ int x = static_cast(event->x); -+ int y = static_cast(event->y); -+ int x2 = 0; -+ int y2 = 0; -+ if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { -+ // Double click on the Layer name, enable editing -+ _text_renderer->property_editable() = true; -+ _tree.set_cursor (path, *_name_column, true); -+ grab_focus(); -+ } -+ } -+ -+ return false; -+} -+ -+/** -+ * Stores items in the highlight target vector to manipulate with the color selector -+ * @param iter Current tree item to store -+ */ -+void ObjectsPanel::_storeHighlightTarget(const Gtk::TreeModel::iterator& iter) -+{ -+ Gtk::TreeModel::Row row = *iter; -+ SPItem* item = row[_model->_colObject]; -+ if (item) -+ { -+ _highlight_target.push_back(item); -+ } -+} -+ -+/* -+ * Drap and drop within the tree -+ */ -+bool ObjectsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) -+{ -+ int cell_x = 0, cell_y = 0; -+ Gtk::TreeModel::Path target_path; -+ Gtk::TreeView::Column *target_column; -+ -+ //Set up our defaults and clear the source vector -+ _dnd_into = false; -+ _dnd_target = NULL; -+ _dnd_source.clear(); -+ -+ //Add all selected items to the source vector -+ _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_storeDragSource)); -+ -+ if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { -+ // Are we before, inside or after the drop layer -+ Gdk::Rectangle rect; -+ _tree.get_background_area (target_path, *target_column, rect); -+ int cell_height = rect.get_height(); -+ _dnd_into = (cell_y > (int)(cell_height * 1/4) && cell_y <= (int)(cell_height * 3/4)); -+ if (cell_y > (int)(cell_height * 3/4)) { -+ Gtk::TreeModel::Path next_path = target_path; -+ next_path.next(); -+ if (_store->iter_is_valid(_store->get_iter(next_path))) { -+ target_path = next_path; -+ } else { -+ // Dragging to the "end" -+ Gtk::TreeModel::Path up_path = target_path; -+ up_path.up(); -+ if (_store->iter_is_valid(_store->get_iter(up_path))) { -+ // Drop into parent -+ target_path = up_path; -+ _dnd_into = true; -+ } else { -+ // Drop into the top level -+ _dnd_target = NULL; -+ } -+ } -+ } -+ Gtk::TreeModel::iterator iter = _store->get_iter(target_path); -+ if (_store->iter_is_valid(iter)) { -+ Gtk::TreeModel::Row row = *iter; -+ //Set the drop target. If we're not dropping into a group, we cannot -+ //drop into it, so set _dnd_into false. -+ _dnd_target = row[_model->_colObject]; -+ if (!(SP_IS_GROUP(_dnd_target))) _dnd_into = false; -+ } -+ } -+ -+ _takeAction(DRAGNDROP); -+ -+ return false; -+} -+ -+/** -+ * Stores all selected items as the drag source -+ * @param iter Current tree item -+ */ -+void ObjectsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) -+{ -+ Gtk::TreeModel::Row row = *iter; -+ SPItem* item = row[_model->_colObject]; -+ if (item) -+ { -+ _dnd_source.push_back(item); -+ } -+} -+ -+/* -+ * Move a layer in response to a drag & drop action -+ */ -+void ObjectsPanel::_doTreeMove( ) -+{ -+ g_assert(_desktop != NULL); -+ g_assert(_document != NULL); -+ -+ std::vector idvector; -+ -+ //Clear the desktop selection -+ _desktop->selection->clear(); -+ while (!_dnd_source.empty()) -+ { -+ SPItem *obj = _dnd_source.back(); -+ _dnd_source.pop_back(); -+ -+ if (obj != _dnd_target) { -+ //Store the object id (for selection later) and move the object -+ idvector.push_back(g_strdup(obj->getId())); -+ obj->moveTo(_dnd_target, _dnd_into); -+ } -+ } -+ -+ //Select items -+ while (!idvector.empty()) { -+ //Grab the id from the vector, get the item in the document and select it -+ gchar * id = idvector.back(); -+ idvector.pop_back(); -+ SPObject *obj = _document->getObjectById(id); -+ g_free(id); -+ if (obj && SP_IS_ITEM(obj)) { -+ SPItem *item = SP_ITEM(obj); -+ if (!SP_IS_GROUP(item) || SP_GROUP(item)->layerMode() != SPGroup::LAYER) -+ { -+ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); -+ _desktop->selection->add(item); -+ } -+ else -+ { -+ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item); -+ } -+ } -+ } -+ -+ DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, -+ _("Moved objects")); -+} -+ -+/** -+ * Fires the action verb -+ */ -+void ObjectsPanel::_fireAction( unsigned int code ) -+{ -+ if ( _desktop ) { -+ Verb *verb = Verb::get( code ); -+ if ( verb ) { -+ SPAction *action = verb->get_action(_desktop); -+ if ( action ) { -+ sp_action_perform( action, NULL ); -+ } -+ } -+ } -+} -+ -+/** -+ * Executes the given button action during the idle time -+ */ -+void ObjectsPanel::_takeAction( int val ) -+{ -+ if ( !_pending ) { -+ _pending = new InternalUIBounce(); -+ _pending->_actionCode = val; -+ Glib::signal_timeout().connect( sigc::mem_fun(*this, &ObjectsPanel::_executeAction), 0 ); -+ } -+} -+ -+/** -+ * Executes the pending button action -+ */ -+bool ObjectsPanel::_executeAction() -+{ -+ // Make sure selected layer hasn't changed since the action was triggered -+ if ( _document && _pending) -+ { -+ int val = _pending->_actionCode; -+// SPObject* target = _pending->_target; -+ -+ switch ( val ) { -+ case BUTTON_NEW: -+ { -+ _fireAction( SP_VERB_LAYER_NEW ); -+ } -+ break; -+ case BUTTON_RENAME: -+ { -+ _fireAction( SP_VERB_LAYER_RENAME ); -+ } -+ break; -+ case BUTTON_TOP: -+ { -+ if (_desktop->selection->isEmpty()) -+ { -+ _fireAction( SP_VERB_LAYER_TO_TOP ); -+ } -+ else -+ { -+ _fireAction( SP_VERB_SELECTION_TO_FRONT); -+ } -+ } -+ break; -+ case BUTTON_BOTTOM: -+ { -+ if (_desktop->selection->isEmpty()) -+ { -+ _fireAction( SP_VERB_LAYER_TO_BOTTOM ); -+ } -+ else -+ { -+ _fireAction( SP_VERB_SELECTION_TO_BACK); -+ } -+ } -+ break; -+ case BUTTON_UP: -+ { -+ if (_desktop->selection->isEmpty()) -+ { -+ _fireAction( SP_VERB_LAYER_RAISE ); -+ } -+ else -+ { -+ _fireAction( SP_VERB_SELECTION_RAISE ); -+ } -+ } -+ break; -+ case BUTTON_DOWN: -+ { -+ if (_desktop->selection->isEmpty()) -+ { -+ _fireAction( SP_VERB_LAYER_LOWER ); -+ } -+ else -+ { -+ _fireAction( SP_VERB_SELECTION_LOWER ); -+ } -+ } -+ break; -+ case BUTTON_DUPLICATE: -+ { -+ if (_desktop->selection->isEmpty()) -+ { -+ _fireAction( SP_VERB_LAYER_DUPLICATE ); -+ } -+ else -+ { -+ _fireAction( SP_VERB_EDIT_DUPLICATE ); -+ } -+ } -+ break; -+ case BUTTON_DELETE: -+ { -+ if (_desktop->selection->isEmpty()) -+ { -+ _fireAction( SP_VERB_LAYER_DELETE ); -+ } -+ else -+ { -+ _fireAction( SP_VERB_EDIT_DELETE ); -+ } -+ } -+ break; -+ case BUTTON_SOLO: -+ { -+ _fireAction( SP_VERB_LAYER_SOLO ); -+ } -+ break; -+ case BUTTON_SHOW_ALL: -+ { -+ _fireAction( SP_VERB_LAYER_SHOW_ALL ); -+ } -+ break; -+ case BUTTON_HIDE_ALL: -+ { -+ _fireAction( SP_VERB_LAYER_HIDE_ALL ); -+ } -+ break; -+ case BUTTON_LOCK_OTHERS: -+ { -+ _fireAction( SP_VERB_LAYER_LOCK_OTHERS ); -+ } -+ break; -+ case BUTTON_LOCK_ALL: -+ { -+ _fireAction( SP_VERB_LAYER_LOCK_ALL ); -+ } -+ break; -+ case BUTTON_UNLOCK_ALL: -+ { -+ _fireAction( SP_VERB_LAYER_UNLOCK_ALL ); -+ } -+ break; -+ case BUTTON_SETCLIP: -+ { -+ _fireAction( SP_VERB_OBJECT_SET_CLIPPATH ); -+ } -+ break; -+ case BUTTON_UNSETCLIP: -+ { -+ _fireAction( SP_VERB_OBJECT_UNSET_CLIPPATH ); -+ } -+ break; -+ case BUTTON_SETMASK: -+ { -+ _fireAction( SP_VERB_OBJECT_SET_MASK ); -+ } -+ break; -+ case BUTTON_UNSETMASK: -+ { -+ _fireAction( SP_VERB_OBJECT_UNSET_MASK ); -+ } -+ break; -+ case BUTTON_GROUP: -+ { -+ _fireAction( SP_VERB_SELECTION_GROUP ); -+ } -+ break; -+ case BUTTON_UNGROUP: -+ { -+ _fireAction( SP_VERB_SELECTION_UNGROUP ); -+ } -+ break; -+ case BUTTON_COLLAPSE_ALL: -+ { -+ for (SPObject* obj = _document->getRoot()->firstChild(); obj != NULL; obj = obj->next) { -+ if (SP_IS_GROUP(obj)) { -+ _setCollapsed(SP_GROUP(obj)); -+ } -+ } -+ _objectsChanged(_document->getRoot()); -+ } -+ break; -+ case DRAGNDROP: -+ { -+ _doTreeMove( ); -+ } -+ break; -+ } -+ -+ delete _pending; -+ _pending = 0; -+ } -+ -+ return false; -+} -+ -+/** -+ * Handles an unsuccessful item label edit (escape pressed, etc.) -+ */ -+void ObjectsPanel::_handleEditingCancelled() -+{ -+ _text_renderer->property_editable() = false; -+} -+ -+/** -+ * Handle a successful item label edit -+ * @param path Tree path of the item currently being edited -+ * @param new_text New label text -+ */ -+void ObjectsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) -+{ -+ Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); -+ Gtk::TreeModel::Row row = *iter; -+ -+ _renameObject(row, new_text); -+ _text_renderer->property_editable() = false; -+} -+ -+/** -+ * Renames an item in the tree -+ * @param row Tree row -+ * @param name New label to give to the item -+ */ -+void ObjectsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) -+{ -+ if ( row && _desktop) { -+ SPItem* item = row[_model->_colObject]; -+ if ( item ) { -+ gchar const* oldLabel = item->label(); -+ if ( !name.empty() && (!oldLabel || name != oldLabel) ) { -+ item->setLabel(name.c_str()); -+ DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, -+ _("Rename object")); -+ } -+ } -+ } -+} -+ -+/** -+ * A row selection function used by the tree that doesn't allow any new items to be selected. -+ * Currently, this is used to allow multi-item drag & drop. -+ */ -+bool ObjectsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool /*currentlySelected*/ ) -+{ -+ return false; -+} -+ -+/** -+ * Default row selection function taken from the layers dialog -+ */ -+bool ObjectsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) -+{ -+ bool val = true; -+ if ( !currentlySelected && _toggleEvent ) -+ { -+ GdkEvent* event = gtk_get_current_event(); -+ if ( event ) { -+ // (keep these checks separate, so we know when to call gdk_event_free() -+ if ( event->type == GDK_BUTTON_PRESS ) { -+ GdkEventButton const* target = reinterpret_cast(_toggleEvent); -+ GdkEventButton const* evtb = reinterpret_cast(event); -+ -+ if ( (evtb->window == target->window) -+ && (evtb->send_event == target->send_event) -+ && (evtb->time == target->time) -+ && (evtb->state == target->state) -+ ) -+ { -+ // Ooooh! It's a magic one -+ val = false; -+ } -+ } -+ gdk_event_free(event); -+ } -+ } -+ return val; -+} -+ -+/** -+ * Sets a group to be collapsed and recursively collapses its children -+ * @param group The group to collapse -+ */ -+void ObjectsPanel::_setCollapsed(SPGroup * group) -+{ -+ group->setExpanded(false); -+ group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); -+ for (SPObject *iter = group->children; iter != NULL; iter = iter->next) -+ { -+ if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter)); -+ } -+} -+ -+/** -+ * Sets a group to be expanded or collapsed -+ * @param iter Current tree item -+ * @param isexpanded Whether to expand or collapse -+ */ -+void ObjectsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) -+{ -+ Gtk::TreeModel::Row row = *iter; -+ -+ SPItem* item = row[_model->_colObject]; -+ if (item && SP_IS_GROUP(item)) -+ { -+ if (isexpanded) -+ { -+ //If we're expanding, simply perform the expansion -+ SP_GROUP(item)->setExpanded(isexpanded); -+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); -+ } -+ else -+ { -+ //If we're collapsing, we need to recursively collapse, so call our helper function -+ _setCollapsed(SP_GROUP(item)); -+ } -+ } -+} -+ -+/** -+ * Callback for when the highlight color is changed -+ * @param csel Color selector -+ * @param cp Objects panel -+ */ -+void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp) -+{ -+ SPColor color; -+ float alpha = 0; -+ csel->base->getColorAlpha(color, alpha); -+ guint32 rgba = color.toRGBA32( alpha ); -+ -+ ObjectsPanel *ptr = reinterpret_cast(cp); -+ -+ //Set the highlight color for all items in the _highlight_target (all selected items) -+ for (std::vector::iterator iter = ptr->_highlight_target.begin(); iter != ptr->_highlight_target.end(); ++iter) -+ { -+ SPItem * target = *iter; -+ target->setHighlightColor(rgba); -+ target->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); -+ } -+ DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_OBJECTS, _("Set object highlight color")); -+} -+ -+/** -+ * Callback for when the opacity value is changed -+ */ -+void ObjectsPanel::_opacityValueChanged() -+{ -+ _blockCompositeUpdate = true; -+ _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_opacityChangedIter)); -+ DocumentUndo::maybeDone(_document, "opacity", SP_VERB_DIALOG_OBJECTS, _("Set object opacity")); -+ _blockCompositeUpdate = false; -+} -+ -+/** -+ * Change the opacity of the selected items in the tree -+ * @param iter Current tree item -+ */ -+void ObjectsPanel::_opacityChangedIter(const Gtk::TreeIter& iter) -+{ -+ Gtk::TreeModel::Row row = *iter; -+ SPItem* item = row[_model->_colObject]; -+ if (item) -+ { -+ item->style->opacity.set = TRUE; -+ item->style->opacity.value = SP_SCALE24_FROM_FLOAT(_opacity_adjustment.get_value() / _opacity_adjustment.get_upper()); -+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); -+ } -+} -+ -+/** -+ * Callback for when the blend mode is changed -+ */ -+void ObjectsPanel::_blendValueChanged() -+{ -+ _blockCompositeUpdate = true; -+ const Glib::ustring blendmode = _fe_cb.get_blend_mode(); -+ -+ _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_blendChangedIter), blendmode)); -+ DocumentUndo::done(_document, SP_VERB_DIALOG_OBJECTS, _("Set object blend mode")); -+ _blockCompositeUpdate = false; -+} -+ -+/** -+ * Sets the blend mode of the selected tree items -+ * @param iter Current tree item -+ * @param blendmode Blend mode to set -+ */ -+void ObjectsPanel::_blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring blendmode) -+{ -+ Gtk::TreeModel::Row row = *iter; -+ SPItem* item = row[_model->_colObject]; -+ if (item) -+ { -+ //Since blur and blend are both filters, we need to set both at the same time -+ SPStyle *style = item->style; -+ g_assert(style != NULL); -+ -+ if (blendmode != "normal") { -+ gdouble radius = 0; -+ if (item->style->getFilter()) { -+ for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { -+ if (SP_IS_GAUSSIANBLUR(primitive)) { -+ Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); -+ if (bbox) { -+ radius = SP_GAUSSIANBLUR(primitive)->stdDeviation.getNumber(); -+ } -+ } -+ } -+ } -+ SPFilter *filter = new_filter_simple_from_item(_document, item, blendmode.c_str(), radius); -+ sp_style_set_property_url(item, "filter", filter, false); -+ } else { -+ for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { -+ if (SP_IS_FEBLEND(primitive)) { -+ primitive->deleteObject(); -+ break; -+ } -+ } -+ if (!item->style->getFilter()->children) { -+ remove_filter(item, false); -+ } -+ } -+ -+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); -+ } -+} -+ -+/** -+ * Callback for when the blur value has changed -+ */ -+void ObjectsPanel::_blurValueChanged() -+{ -+ _blockCompositeUpdate = true; -+ _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_blurChangedIter), _fe_blur.get_blur_value())); -+ DocumentUndo::maybeDone(_document, "blur", SP_VERB_DIALOG_OBJECTS, _("Set object blur")); -+ _blockCompositeUpdate = false; -+} -+ -+/** -+ * Sets the blur value for the selected items in the tree -+ * @param iter Current tree item -+ * @param blur Blur value to set -+ */ -+void ObjectsPanel::_blurChangedIter(const Gtk::TreeIter& iter, double blur) -+{ -+ Gtk::TreeModel::Row row = *iter; -+ SPItem* item = row[_model->_colObject]; -+ if (item) -+ { -+ //Since blur and blend are both filters, we need to set both at the same time -+ SPStyle *style = item->style; -+ if (style) { -+ Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); -+ double radius; -+ if (bbox) { -+ double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? -+ radius = blur * perimeter / 400; -+ } else { -+ radius = 0; -+ } -+ -+ if (radius != 0) { -+ SPFilter *filter = modify_filter_gaussian_blur_from_item(_document, item, radius); -+ sp_style_set_property_url(item, "filter", filter, false); -+ } else if (item->style->filter.set && item->style->getFilter()) { -+ for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { -+ if (SP_IS_GAUSSIANBLUR(primitive)) { -+ primitive->deleteObject(); -+ break; -+ } -+ } -+ if (!item->style->getFilter()->children) { -+ remove_filter(item, false); -+ } -+ } -+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); -+ } -+ } -+} -+ -+/** -+ * Constructor -+ */ -+ObjectsPanel::ObjectsPanel() : -+ UI::Widget::Panel("", "/dialogs/objects", SP_VERB_DIALOG_OBJECTS), -+ _rootWatcher(0), -+ _deskTrack(), -+ _desktop(0), -+ _document(0), -+ _model(0), -+ _pending(0), -+ _toggleEvent(0), -+ _defer_target(), -+ _composite_vbox(false, 0), -+ _opacity_vbox(false, 0), -+ _opacity_label(_("Opacity:")), -+ _opacity_label_unit(_("%")), -+#if WITH_GTKMM_3_0 -+ _opacity_adjustment(Gtk::Adjustment::create(100.0, 0.0, 100.0, 1.0, 1.0, 0.0)), -+#else -+ _opacity_adjustment(100.0, 0.0, 100.0, 1.0, 1.0, 0.0), -+#endif -+ _opacity_hscale(_opacity_adjustment), -+ _opacity_spin_button(_opacity_adjustment, 0.01, 1), -+ _fe_cb(UI::Widget::SimpleFilterModifier::BLEND), -+ _fe_vbox(false, 0), -+ _fe_alignment(1, 1, 1, 1), -+ _fe_blur(UI::Widget::SimpleFilterModifier::BLUR), -+ _blur_vbox(false, 0), -+ _blur_alignment(1, 1, 1, 1), -+ _colorSelectorDialog("dialogs.colorpickerwindow") -+{ -+ //Create the tree model and store -+ ModelColumns *zoop = new ModelColumns(); -+ _model = zoop; -+ -+ _store = Gtk::TreeStore::create( *zoop ); -+ -+ //Set up the tree -+ _tree.set_model( _store ); -+ _tree.set_headers_visible(false); -+ _tree.set_reorderable(true); -+ _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); -+ -+ //Create the column CellRenderers -+ //Visible -+ Inkscape::UI::Widget::ImageToggler *eyeRenderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( -+ INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden")) ); -+ int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1; -+ eyeRenderer->property_activatable() = true; -+ Gtk::TreeViewColumn* col = _tree.get_column(visibleColNum); -+ if ( col ) { -+ col->add_attribute( eyeRenderer->property_active(), _model->_colVisible ); -+ } -+ -+ //Locked -+ Inkscape::UI::Widget::ImageToggler * renderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( -+ INKSCAPE_ICON("object-locked"), INKSCAPE_ICON("object-unlocked")) ); -+ int lockedColNum = _tree.append_column("lock", *renderer) - 1; -+ renderer->property_activatable() = true; -+ col = _tree.get_column(lockedColNum); -+ if ( col ) { -+ col->add_attribute( renderer->property_active(), _model->_colLocked ); -+ } -+ -+ //Type -+ Inkscape::UI::Widget::LayerTypeIcon * typeRenderer = Gtk::manage( new Inkscape::UI::Widget::LayerTypeIcon()); -+ int typeColNum = _tree.append_column("type", *typeRenderer) - 1; -+ typeRenderer->property_activatable() = true; -+ col = _tree.get_column(typeColNum); -+ if ( col ) { -+ col->add_attribute( typeRenderer->property_active(), _model->_colType ); -+ } -+ -+ //Clip/mask -+ Inkscape::UI::Widget::ClipMaskIcon * clipRenderer = Gtk::manage( new Inkscape::UI::Widget::ClipMaskIcon()); -+ int clipColNum = _tree.append_column("clipmask", *clipRenderer) - 1; -+ col = _tree.get_column(clipColNum); -+ if ( col ) { -+ col->add_attribute( clipRenderer->property_active(), _model->_colClipMask ); -+ } -+ -+ //Highlight -+ Inkscape::UI::Widget::HighlightPicker * highlightRenderer = Gtk::manage( new Inkscape::UI::Widget::HighlightPicker()); -+ int highlightColNum = _tree.append_column("highlight", *highlightRenderer) - 1; -+ col = _tree.get_column(highlightColNum); -+ if ( col ) { -+ col->add_attribute( highlightRenderer->property_active(), _model->_colHighlight ); -+ } -+ -+ //Label -+ _text_renderer = Gtk::manage(new Gtk::CellRendererText()); -+ int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; -+ _name_column = _tree.get_column(nameColNum); -+ _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); -+ -+ //Set the expander and search columns -+ _tree.set_expander_column( *_tree.get_column(nameColNum) ); -+ _tree.set_search_column(_model->_colLabel); -+ -+ //Set up the tree selection -+ _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); -+ _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &ObjectsPanel::_pushTreeSelectionToCurrent) ); -+ _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &ObjectsPanel::_rowSelectFunction) ); -+ -+ //Set up tree signals -+ _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false ); -+ _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false ); -+ _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleKeyEvent), false ); -+ _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleDragDrop), false); -+ _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setExpanded), false)); -+ _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setExpanded), true)); -+ -+ //Set up the label editing signals -+ _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleEdited) ); -+ _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleEditingCancelled) ); -+ -+ //Set up the scroller window and pack the page -+ _scroller.add( _tree ); -+ _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); -+ _scroller.set_shadow_type(Gtk::SHADOW_IN); -+ Gtk::Requisition sreq; -+#if WITH_GTKMM_3_0 -+ Gtk::Requisition sreq_natural; -+ _scroller.get_preferred_size(sreq_natural, sreq); -+#else -+ sreq = _scroller.size_request(); -+#endif -+ int minHeight = 70; -+ if (sreq.height < minHeight) { -+ // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar -+ _scroller.set_size_request(sreq.width, minHeight); -+ } -+ -+ _page.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); -+ -+ //Set up the compositing items -+ //Blend mode filter effect -+ _composite_vbox.pack_start(_fe_vbox, false, false, 2); -+ _fe_alignment.set_padding(0, 0, 4, 0); -+ _fe_alignment.add(_fe_cb); -+ _fe_vbox.pack_start(_fe_alignment, false, false, 0); -+ _blendConnection = _fe_cb.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_blendValueChanged)); -+ -+ //Blur filter effect -+ _composite_vbox.pack_start(_blur_vbox, false, false, 2); -+ _blur_alignment.set_padding(0, 0, 4, 0); -+ _blur_alignment.add(_fe_blur); -+ _blur_vbox.pack_start(_blur_alignment, false, false, 0); -+ _blurConnection = _fe_blur.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_blurValueChanged)); -+ -+ //Opacity -+ _composite_vbox.pack_start(_opacity_vbox, false, false, 2); -+ _opacity_label.set_alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER); -+ _opacity_hbox.pack_start(_opacity_label, false, false, 3); -+ _opacity_vbox.pack_start(_opacity_hbox, false, false, 0); -+ _opacity_hbox.pack_start(_opacity_hscale, true, true, 0); -+ _opacity_hbox.pack_start(_opacity_spin_button, false, false, 0); -+ _opacity_hbox.pack_start(_opacity_label_unit, false, false, 3); -+ _opacity_hscale.set_draw_value(false); -+#if WITH_GTKMM_3_0 -+ _opacityConnection = _opacity_adjustment->signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged)); -+ _opacity_label.set_mnemonic_widget(_opacity_hscale); -+#else -+ _opacityConnection = _opacity_adjustment.signal_value_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_opacityValueChanged)); -+ _opacity_label.set_mnemonic_widget(_opacity_hscale); -+#endif -+ -+ //Keep the labels aligned -+// GtkSizeGroup *labels = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); -+// gtk_size_group_add_widget(labels, GTK_WIDGET(_opacity_label.gobj())); -+// gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_cb.get_blur_label()->gobj())); -+// gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_blur.get_blur_label()->gobj())); -+ -+ //Pack the compositing functions and the button row -+ _page.pack_end(_composite_vbox, Gtk::PACK_SHRINK); -+ _page.pack_end(_buttonsRow, Gtk::PACK_SHRINK); -+ -+ //Pack into the panel contents -+ _getContents()->pack_start(_page, Gtk::PACK_EXPAND_WIDGET); -+ -+ SPDesktop* targetDesktop = getDesktop(); -+ -+ //Set up the button row -+ Gtk::Button* btn = Gtk::manage( new Gtk::Button() ); -+ _styleButton( *btn, GTK_STOCK_ADD, _("New Layer") ); -+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_NEW) ); -+ _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); -+ -+ btn = Gtk::manage( new Gtk::Button() ); -+ _styleButton( *btn, GTK_STOCK_REMOVE, _("Remove") ); -+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DELETE) ); -+ _watching.push_back( btn ); -+ _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); -+ -+ btn = Gtk::manage( new Gtk::Button() ); -+ _styleButton( *btn, GTK_STOCK_GOTO_BOTTOM, _("Move To Bottom") ); -+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_BOTTOM) ); -+ _watchingNonBottom.push_back( btn ); -+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); -+ -+ btn = Gtk::manage( new Gtk::Button() ); -+ _styleButton( *btn, GTK_STOCK_GO_DOWN, _("Move Down") ); -+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DOWN) ); -+ _watchingNonBottom.push_back( btn ); -+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); -+ -+ btn = Gtk::manage( new Gtk::Button() ); -+ _styleButton( *btn, GTK_STOCK_GO_UP, _("Move Up") ); -+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_UP) ); -+ _watchingNonTop.push_back( btn ); -+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); -+ -+ btn = Gtk::manage( new Gtk::Button() ); -+ _styleButton( *btn, GTK_STOCK_GOTO_TOP, _("Move To Top") ); -+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_TOP) ); -+ _watchingNonTop.push_back( btn ); -+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); -+ -+ btn = Gtk::manage( new Gtk::Button() ); -+ _styleButton( *btn, GTK_STOCK_UNINDENT, _("Collapse All") ); -+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_COLLAPSE_ALL) ); -+ _watchingNonBottom.push_back( btn ); -+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); -+ -+ _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); -+ _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); -+ -+ _watching.push_back(&_composite_vbox); -+ -+ //Set up the pop-up menu -+ // ------------------------------------------------------- -+ { -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) ); -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_EDIT_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_NEW, 0, "New", (int)BUTTON_NEW ) ); -+ -+ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); -+ -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SOLO, 0, "Solo", (int)BUTTON_SOLO ) ); -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SHOW_ALL, 0, "Show All", (int)BUTTON_SHOW_ALL ) ); -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_HIDE_ALL, 0, "Hide All", (int)BUTTON_HIDE_ALL ) ); -+ -+ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); -+ -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_OTHERS, 0, "Lock Others", (int)BUTTON_LOCK_OTHERS ) ); -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_ALL, 0, "Lock All", (int)BUTTON_LOCK_ALL ) ); -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_UNLOCK_ALL, 0, "Unlock All", (int)BUTTON_UNLOCK_ALL ) ); -+ -+ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); -+ -+ _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_RAISE, GTK_STOCK_GO_UP, "Up", (int)BUTTON_UP ) ); -+ _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_LOWER, GTK_STOCK_GO_DOWN, "Down", (int)BUTTON_DOWN ) ); -+ -+ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); -+ -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_GROUP, 0, "Group", (int)BUTTON_GROUP ) ); -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_UNGROUP, 0, "Ungroup", (int)BUTTON_UNGROUP ) ); -+ -+ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); -+ -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_CLIPPATH, 0, "Set Clip", (int)BUTTON_SETCLIP ) ); -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_UNSET_CLIPPATH, 0, "Unset Clip", (int)BUTTON_UNSETCLIP ) ); -+ -+ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); -+ -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_MASK, 0, "Set Mask", (int)BUTTON_SETMASK ) ); -+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_UNSET_MASK, 0, "Unset Mask", (int)BUTTON_UNSETMASK ) ); -+ -+ _popupMenu.show_all_children(); -+ } -+ // ------------------------------------------------------- -+ -+ //Set initial sensitivity of buttons -+ for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { -+ (*it)->set_sensitive( false ); -+ } -+ for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { -+ (*it)->set_sensitive( false ); -+ } -+ for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { -+ (*it)->set_sensitive( false ); -+ } -+ -+ //Set up the color selection dialog -+ GtkWidget *dlg = GTK_WIDGET(_colorSelectorDialog.gobj()); -+ sp_transientize(dlg); -+ -+ _colorSelectorDialog.hide(); -+ _colorSelectorDialog.set_title (_("Select Highlight Color")); -+ _colorSelectorDialog.set_border_width (4); -+ _colorSelectorDialog.property_modal() = true; -+ _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK)); -+ _colorSelectorDialog.get_vbox()->pack_start ( -+ *Glib::wrap(&_colorSelector->vbox), true, true, 0); -+ -+ g_signal_connect(G_OBJECT(_colorSelector), "dragged", -+ G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); -+ g_signal_connect(G_OBJECT(_colorSelector), "released", -+ G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); -+ g_signal_connect(G_OBJECT(_colorSelector), "changed", -+ G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); -+ -+ gtk_widget_show(GTK_WIDGET(_colorSelector)); -+ -+ setDesktop( targetDesktop ); -+ -+ show_all_children(); -+ -+ //Connect the desktop changed connection -+ desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &ObjectsPanel::setDesktop) ); -+ _deskTrack.connect(GTK_WIDGET(gobj())); -+} -+ -+/** -+ * Destructor -+ */ -+ObjectsPanel::~ObjectsPanel() -+{ -+ //Close the highlight selection dialog -+ _colorSelectorDialog.hide(); -+ _colorSelector = NULL; -+ -+ //Set the desktop to null, which will disconnect all object watchers -+ setDesktop(NULL); -+ -+ if ( _model ) -+ { -+ delete _model; -+ _model = 0; -+ } -+ -+ if (_pending) { -+ delete _pending; -+ _pending = 0; -+ } -+ -+ if ( _toggleEvent ) -+ { -+ gdk_event_free( _toggleEvent ); -+ _toggleEvent = 0; -+ } -+ -+ desktopChangeConn.disconnect(); -+ _deskTrack.disconnect(); -+} -+ -+/** -+ * Sets the current document -+ */ -+void ObjectsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) -+{ -+ //Clear all object watchers -+ while (!_objectWatchers.empty()) -+ { -+ ObjectsPanel::ObjectWatcher *w = _objectWatchers.back(); -+ w->_repr->removeObserver(*w); -+ _objectWatchers.pop_back(); -+ delete w; -+ } -+ -+ //Delete the root watcher -+ if (_rootWatcher) -+ { -+ _rootWatcher->_repr->removeObserver(*_rootWatcher); -+ delete _rootWatcher; -+ _rootWatcher = NULL; -+ } -+ -+ _document = document; -+ -+ if (document && document->getRoot() && document->getRoot()->getRepr()) -+ { -+ //Create a new root watcher for the document and then call _objectsChanged to fill the tree -+ _rootWatcher = new ObjectsPanel::ObjectWatcher(this, document->getRoot()); -+ document->getRoot()->getRepr()->addObserver(*_rootWatcher); -+ _objectsChanged(document->getRoot()); -+ } -+} -+ -+/** -+ * Set the current panel desktop -+ */ -+void ObjectsPanel::setDesktop( SPDesktop* desktop ) -+{ -+ Panel::setDesktop(desktop); -+ -+ if ( desktop != _desktop ) { -+ _documentChangedConnection.disconnect(); -+ _selectionChangedConnection.disconnect(); -+ if ( _desktop ) { -+ _desktop = 0; -+ } -+ -+ _desktop = Panel::getDesktop(); -+ if ( _desktop ) { -+ //Connect desktop signals -+ _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &ObjectsPanel::setDocument)); -+ _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &ObjectsPanel::_objectsSelected)); -+ -+ setDocument(_desktop, _desktop->doc()); -+ } else { -+ setDocument(NULL, NULL); -+ } -+ } -+ _deskTrack.setBase(desktop); -+} -+} //namespace Dialogs -+} //namespace UI -+} //namespace Inkscape -+ -+ -+/* -+ Local Variables: -+ mode:c++ -+ c-file-style:"stroustrup" -+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) -+ indent-tabs-mode:nil -+ fill-column:99 -+ End: -+*/ -+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - -=== added file 'src/ui/dialog/objects.h' ---- src/ui/dialog/objects.h 1970-01-01 00:00:00 +0000 -+++ src/ui/dialog/objects.h 2013-03-17 13:42:01 +0000 -@@ -0,0 +1,255 @@ -+/* -+ * A simple dialog for objects UI. -+ * -+ * Authors: -+ * Theodore Janeczko -+ * -+ * Copyright (C) Theodore Janeczko 2012 -+ * -+ * Released under GNU GPL, read the file 'COPYING' for more information -+ */ -+ -+#ifndef SEEN_OBJECTS_PANEL_H -+#define SEEN_OBJECTS_PANEL_H -+ -+#include -+#include -+#include -+#include -+#include -+#include "ui/widget/spinbutton.h" -+#include "ui/widget/panel.h" -+#include "ui/widget/object-composite-settings.h" -+#include "desktop-tracker.h" -+#include "ui/widget/style-subject.h" -+#include "selection.h" -+#include "ui/widget/filter-effect-chooser.h" -+ -+class SPObject; -+class SPGroup; -+struct SPColorSelector; -+ -+namespace Inkscape { -+ -+namespace UI { -+namespace Dialog { -+ -+ -+/** -+ * A panel that displays objects. -+ */ -+class ObjectsPanel : public UI::Widget::Panel -+{ -+public: -+ ObjectsPanel(); -+ virtual ~ObjectsPanel(); -+ -+ static ObjectsPanel& getInstance(); -+ -+ void setDesktop( SPDesktop* desktop ); -+ void setDocument( SPDesktop* desktop, SPDocument* document); -+ -+private: -+ //Internal Classes: -+ class ModelColumns; -+ class InternalUIBounce; -+ class ObjectWatcher; -+ -+ //Connections, Watchers, Trackers: -+ -+ //Document root watcher -+ ObjectsPanel::ObjectWatcher* _rootWatcher; -+ -+ //All object watchers -+ std::vector _objectWatchers; -+ -+ //Connection for when the desktop changes -+ sigc::connection desktopChangeConn; -+ -+ //Connection for when the document changes -+ sigc::connection _documentChangedConnection; -+ -+ //Connection for when the active selection in the document changes -+ sigc::connection _selectionChangedConnection; -+ -+ //Connection for when the selection in the dialog changes -+ sigc::connection _selectedConnection; -+ -+ //Connections for when the opacity/blend/blur of the active selection in the document changes -+ sigc::connection _opacityConnection; -+ sigc::connection _blendConnection; -+ sigc::connection _blurConnection; -+ -+ //Desktop tracker for grabbing the desktop changed connection -+ DesktopTracker _deskTrack; -+ -+ //Members: -+ -+ //The current desktop -+ SPDesktop* _desktop; -+ -+ //The current document -+ SPDocument* _document; -+ -+ //Tree data model -+ ModelColumns* _model; -+ -+ //Prevents the composite controls from updating -+ bool _blockCompositeUpdate; -+ -+ // -+ InternalUIBounce* _pending; -+ -+ //Whether the drag & drop was dragged into an item -+ gboolean _dnd_into; -+ -+ //List of drag & drop source items -+ std::vector _dnd_source; -+ -+ //Drag & drop target item -+ SPItem* _dnd_target; -+ -+ //List of items to change the highlight on -+ std::vector _highlight_target; -+ -+ //GUI Members: -+ -+ GdkEvent* _toggleEvent; -+ -+ Gtk::TreeModel::Path _defer_target; -+ -+ Glib::RefPtr _store; -+ std::vector _watching; -+ std::vector _watchingNonTop; -+ std::vector _watchingNonBottom; -+ -+ Gtk::TreeView _tree; -+ Gtk::CellRendererText *_text_renderer; -+ Gtk::TreeView::Column *_name_column; -+#if WITH_GTKMM_3_0 -+ Gtk::Box _buttonsRow; -+ Gtk::Box _buttonsPrimary; -+ Gtk::Box _buttonsSecondary; -+#else -+ Gtk::HBox _buttonsRow; -+ Gtk::HBox _buttonsPrimary; -+ Gtk::HBox _buttonsSecondary; -+#endif -+ Gtk::ScrolledWindow _scroller; -+ Gtk::Menu _popupMenu; -+ Inkscape::UI::Widget::SpinButton _spinBtn; -+ Gtk::VBox _page; -+ -+ /* Composite Settings */ -+ Gtk::VBox _composite_vbox; -+ Gtk::VBox _opacity_vbox; -+ Gtk::HBox _opacity_hbox; -+ Gtk::Label _opacity_label; -+ Gtk::Label _opacity_label_unit; -+#if WITH_GTKMM_3_0 -+ Glib::RefPtr _opacity_adjustment; -+#else -+ Gtk::Adjustment _opacity_adjustment; -+#endif -+ Gtk::HScale _opacity_hscale; -+ Inkscape::UI::Widget::SpinButton _opacity_spin_button; -+ -+ Inkscape::UI::Widget::SimpleFilterModifier _fe_cb; -+ Gtk::VBox _fe_vbox; -+ Gtk::Alignment _fe_alignment; -+ Inkscape::UI::Widget::SimpleFilterModifier _fe_blur; -+ Gtk::VBox _blur_vbox; -+ Gtk::Alignment _blur_alignment; -+ -+ Gtk::Dialog _colorSelectorDialog; -+ SPColorSelector *_colorSelector; -+ -+ -+ //Methods: -+ -+ ObjectsPanel(ObjectsPanel const &); // no copy -+ ObjectsPanel &operator=(ObjectsPanel const &); // no assign -+ -+ void _styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip ); -+ void _fireAction( unsigned int code ); -+ -+ Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); -+ -+ void _setVisibleIter( const Gtk::TreeModel::iterator& iter, const bool visible ); -+ void _setLockedIter( const Gtk::TreeModel::iterator& iter, const bool locked ); -+ -+ bool _handleButtonEvent(GdkEventButton *event); -+ bool _handleKeyEvent(GdkEventKey *event); -+ -+ void _storeHighlightTarget(const Gtk::TreeModel::iterator& iter); -+ void _storeDragSource(const Gtk::TreeModel::iterator& iter); -+ bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); -+ void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); -+ void _handleEditingCancelled(); -+ -+ void _doTreeMove(); -+ void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); -+ -+ void _pushTreeSelectionToCurrent(); -+ void _selected_row_callback( const Gtk::TreeModel::iterator& iter, bool *setOpacity ); -+ -+ void _checkTreeSelection(); -+ -+ void _takeAction( int val ); -+ bool _executeAction(); -+ -+ void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); -+ void _setCollapsed(SPGroup * group); -+ -+ bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); -+ bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); -+ -+ void _compositingChanged( const Gtk::TreeModel::iterator& iter, bool *setValues ); -+ void _updateComposite(); -+ void _setCompositingValues(SPItem *item); -+ -+ void _updateObject(SPObject *obj, bool recurse); -+ bool _checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj); -+ -+ void _objectsSelected(Selection *sel); -+ bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto); -+ -+ void _objectsChanged(SPObject *obj); -+ void _addObject( SPObject* obj, Gtk::TreeModel::Row* parentRow ); -+ -+ void _opacityChangedIter(const Gtk::TreeIter& iter); -+ void _opacityValueChanged(); -+ -+ void _blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring blendmode); -+ void _blendValueChanged(); -+ -+ void _blurChangedIter(const Gtk::TreeIter& iter, double blur); -+ void _blurValueChanged(); -+ -+ -+ void setupDialog(const Glib::ustring &title); -+ -+ friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); -+ -+}; -+ -+ -+ -+} //namespace Dialogs -+} //namespace UI -+} //namespace Inkscape -+ -+ -+ -+#endif // SEEN_OBJECTS_PANEL_H -+ -+/* -+ Local Variables: -+ mode:c++ -+ c-file-style:"stroustrup" -+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) -+ indent-tabs-mode:nil -+ fill-column:99 -+ End: -+*/ -+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - -=== modified file 'src/ui/tool/multi-path-manipulator.cpp' ---- src/ui/tool/multi-path-manipulator.cpp 2012-09-06 02:25:16 +0000 -+++ src/ui/tool/multi-path-manipulator.cpp 2013-03-19 00:31:09 +0000 -@@ -195,7 +195,7 @@ - ShapeRecord const &r = *i; - if (!SP_IS_PATH(r.item) && !IS_LIVEPATHEFFECT(r.item)) continue; - boost::shared_ptr newpm(new PathManipulator(*this, (SPPath*) r.item, -- r.edit_transform, _getOutlineColor(r.role), r.lpe_key)); -+ r.edit_transform, _getOutlineColor(r.role, r.item), r.lpe_key)); - newpm->showHandles(_show_handles); - // always show outlines for clips and masks - newpm->showOutline(_show_outline || r.role != SHAPE_ROLE_NORMAL); -@@ -834,7 +834,7 @@ - } - - /** Get an outline color based on the shape's role (normal, mask, LPE parameter, etc.). */ --guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role) -+guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role, SPItem *item) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - switch(role) { -@@ -846,7 +846,7 @@ - return prefs->getColor("/tools/nodes/lpe_param_color", 0x009000ff); - case SHAPE_ROLE_NORMAL: - default: -- return prefs->getColor("/tools/nodes/outline_color", 0xff0000ff); -+ return item->highlight_color(); - } - } - - -=== modified file 'src/ui/tool/multi-path-manipulator.h' ---- src/ui/tool/multi-path-manipulator.h 2012-05-17 09:10:15 +0000 -+++ src/ui/tool/multi-path-manipulator.h 2013-03-19 00:31:16 +0000 -@@ -106,7 +106,7 @@ - void _commit(CommitEvent cps); - void _done(gchar const *reason, bool alert_LPE = false); - void _doneWithCleanup(gchar const *reason, bool alert_LPE = false); -- guint32 _getOutlineColor(ShapeRole role); -+ guint32 _getOutlineColor(ShapeRole role, SPItem *item); - - MapType _mmap; - public: - -=== modified file 'src/ui/tool/node-tool.cpp' ---- src/ui/tool/node-tool.cpp 2013-01-26 19:33:04 +0000 -+++ src/ui/tool/node-tool.cpp 2013-03-19 00:31:25 +0000 -@@ -488,7 +488,7 @@ - c->transform(over_item->i2dt_affine()); - SPCanvasItem *flash = sp_canvas_bpath_new(sp_desktop_tempgroup(desktop), c); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(flash), -- prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff), 1.0, -+ over_item->highlight_color(), 1.0, - SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(flash), 0, SP_WIND_RULE_NONZERO); - nt->flash_tempitem = desktop->add_temporary_canvasitem(flash, - -=== modified file 'src/ui/widget/Makefile_insert' ---- src/ui/widget/Makefile_insert 2013-01-08 12:06:44 +0000 -+++ src/ui/widget/Makefile_insert 2013-03-17 14:17:34 +0000 -@@ -4,6 +4,8 @@ - ui/widget/attr-widget.h \ - ui/widget/button.h \ - ui/widget/button.cpp \ -+ ui/widget/clipmaskicon.cpp \ -+ ui/widget/clipmaskicon.h \ - ui/widget/color-picker.cpp \ - ui/widget/color-picker.h \ - ui/widget/color-preview.cpp \ -@@ -23,6 +25,8 @@ - ui/widget/gimpspinscale.h \ - ui/widget/gimpcolorwheel.c \ - ui/widget/gimpcolorwheel.h \ -+ ui/widget/highlight-picker.cpp \ -+ ui/widget/highlight-picker.h \ - ui/widget/frame.cpp \ - ui/widget/frame.h \ - ui/widget/imageicon.cpp \ -@@ -33,6 +37,8 @@ - ui/widget/labelled.h \ - ui/widget/layer-selector.cpp \ - ui/widget/layer-selector.h \ -+ ui/widget/layertypeicon.cpp \ -+ ui/widget/layertypeicon.h \ - ui/widget/licensor.cpp \ - ui/widget/licensor.h \ - ui/widget/notebook-page.cpp \ - -=== added file 'src/ui/widget/clipmaskicon.cpp' ---- src/ui/widget/clipmaskicon.cpp 1970-01-01 00:00:00 +0000 -+++ src/ui/widget/clipmaskicon.cpp 2013-03-14 23:36:37 +0000 -@@ -0,0 +1,177 @@ -+/* -+ * Authors: -+ * Theodore Janeczko -+ * -+ * Copyright (C) Theodore Janeczko 2012 -+ * -+ * Released under GNU GPL, read the file 'COPYING' for more information -+ */ -+ -+ -+#include "ui/widget/clipmaskicon.h" -+ -+#include -+ -+#include "widgets/icon.h" -+#include "widgets/toolbox.h" -+#include "ui/icon-names.h" -+#include "layertypeicon.h" -+ -+namespace Inkscape { -+namespace UI { -+namespace Widget { -+ -+ClipMaskIcon::ClipMaskIcon() : -+ Glib::ObjectBase(typeid(ClipMaskIcon)), -+ Gtk::CellRendererPixbuf(), -+ _pixClipName(INKSCAPE_ICON("path-intersection")), -+ _pixInverseName(INKSCAPE_ICON("path-difference")), -+ _pixMaskName(INKSCAPE_ICON("mask-intersection")), -+ _property_active(*this, "active", 0), -+ _property_pixbuf_clip(*this, "pixbuf_on", Glib::RefPtr(0)), -+ _property_pixbuf_inverse(*this, "pixbuf_on", Glib::RefPtr(0)), -+ _property_pixbuf_mask(*this, "pixbuf_off", Glib::RefPtr(0)) -+{ -+ -+ property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; -+ phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_DECORATION); -+ Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); -+ -+ if (!icon_theme->has_icon(_pixClipName)) { -+ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixClipName.data()), Inkscape::ICON_SIZE_DECORATION ); -+ } -+ if (!icon_theme->has_icon(_pixInverseName)) { -+ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixInverseName.data()), Inkscape::ICON_SIZE_DECORATION ); -+ } -+ if (!icon_theme->has_icon(_pixMaskName)) { -+ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixMaskName.data()), Inkscape::ICON_SIZE_DECORATION ); -+ } -+ -+ if (icon_theme->has_icon(_pixClipName)) { -+ _property_pixbuf_clip = icon_theme->load_icon(_pixClipName, phys, (Gtk::IconLookupFlags)0); -+ } -+ if (icon_theme->has_icon(_pixInverseName)) { -+ _property_pixbuf_inverse = icon_theme->load_icon(_pixInverseName, phys, (Gtk::IconLookupFlags)0); -+ } -+ if (icon_theme->has_icon(_pixMaskName)) { -+ _property_pixbuf_mask = icon_theme->load_icon(_pixMaskName, phys, (Gtk::IconLookupFlags)0); -+ } -+ -+ property_pixbuf() = Glib::RefPtr(0); -+} -+ -+ -+#if WITH_GTKMM_3_0 -+void ClipMaskIcon::get_preferred_height_vfunc(Gtk::Widget& widget, -+ int& min_h, -+ int& nat_h) const -+{ -+ Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); -+ -+ if (min_h) { -+ min_h += (min_h) >> 1; -+ } -+ -+ if (nat_h) { -+ nat_h += (nat_h) >> 1; -+ } -+} -+ -+void ClipMaskIcon::get_preferred_width_vfunc(Gtk::Widget& widget, -+ int& min_w, -+ int& nat_w) const -+{ -+ Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); -+ -+ if (min_w) { -+ min_w += (min_w) >> 1; -+ } -+ -+ if (nat_w) { -+ nat_w += (nat_w) >> 1; -+ } -+} -+#else -+void ClipMaskIcon::get_size_vfunc(Gtk::Widget& widget, -+ const Gdk::Rectangle* cell_area, -+ int* x_offset, -+ int* y_offset, -+ int* width, -+ int* height ) const -+{ -+ Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); -+ -+ if ( width ) { -+ *width = phys;//+= (*width) >> 1; -+ } -+ if ( height ) { -+ *height =phys;//+= (*height) >> 1; -+ } -+} -+#endif -+ -+#if WITH_GTKMM_3_0 -+void ClipMaskIcon::render_vfunc( const Cairo::RefPtr& cr, -+ Gtk::Widget& widget, -+ const Gdk::Rectangle& background_area, -+ const Gdk::Rectangle& cell_area, -+ Gtk::CellRendererState flags ) -+#else -+void ClipMaskIcon::render_vfunc( const Glib::RefPtr& window, -+ Gtk::Widget& widget, -+ const Gdk::Rectangle& background_area, -+ const Gdk::Rectangle& cell_area, -+ const Gdk::Rectangle& expose_area, -+ Gtk::CellRendererState flags ) -+#endif -+{ -+ switch (_property_active.get_value()) -+ { -+ case 1: -+ property_pixbuf() = _property_pixbuf_clip; -+ break; -+ case 2: -+ property_pixbuf() = _property_pixbuf_mask; -+ break; -+ case 3: -+ property_pixbuf() = _property_pixbuf_inverse; -+ break; -+ default: -+ property_pixbuf() = Glib::RefPtr(0); -+ break; -+ } -+#if WITH_GTKMM_3_0 -+ Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); -+#else -+ Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); -+#endif -+} -+ -+bool -+ClipMaskIcon::activate_vfunc(GdkEvent* event, -+ Gtk::Widget& /*widget*/, -+ const Glib::ustring& path, -+ const Gdk::Rectangle& /*background_area*/, -+ const Gdk::Rectangle& /*cell_area*/, -+ Gtk::CellRendererState /*flags*/) -+{ -+ return false; -+} -+ -+ -+} // namespace Widget -+} // namespace UI -+} // namespace Inkscape -+ -+/* -+ Local Variables: -+ mode:c++ -+ c-file-style:"stroustrup" -+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) -+ indent-tabs-mode:nil -+ fill-column:99 -+ End: -+*/ -+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -+ -+ - -=== added file 'src/ui/widget/clipmaskicon.h' ---- src/ui/widget/clipmaskicon.h 1970-01-01 00:00:00 +0000 -+++ src/ui/widget/clipmaskicon.h 2013-03-08 04:27:35 +0000 -@@ -0,0 +1,102 @@ -+#ifndef __UI_DIALOG_CLIPMASKICON_H__ -+#define __UI_DIALOG_CLIPMASKICON_H__ -+/* -+ * Authors: -+ * Theodore Janeczko -+ * -+ * Copyright (C) Theodore Janeczko 2012 -+ * -+ * Released under GNU GPL, read the file 'COPYING' for more information -+ */ -+ -+#if HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#include -+#include -+#include -+ -+namespace Inkscape { -+namespace UI { -+namespace Widget { -+ -+class ClipMaskIcon : public Gtk::CellRendererPixbuf { -+public: -+ ClipMaskIcon(); -+ virtual ~ClipMaskIcon() {}; -+ -+ Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } -+ Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_on(); -+ Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_off(); -+ -+protected: -+ -+#if WITH_GTKMM_3_0 -+ virtual void render_vfunc( const Cairo::RefPtr& cr, -+ Gtk::Widget& widget, -+ const Gdk::Rectangle& background_area, -+ const Gdk::Rectangle& cell_area, -+ Gtk::CellRendererState flags ); -+ -+ virtual void get_preferred_width_vfunc(Gtk::Widget& widget, -+ int& min_w, -+ int& nat_w) const; -+ -+ virtual void get_preferred_height_vfunc(Gtk::Widget& widget, -+ int& min_h, -+ int& nat_h) const; -+#else -+ virtual void render_vfunc( const Glib::RefPtr& window, -+ Gtk::Widget& widget, -+ const Gdk::Rectangle& background_area, -+ const Gdk::Rectangle& cell_area, -+ const Gdk::Rectangle& expose_area, -+ Gtk::CellRendererState flags ); -+ -+ virtual void get_size_vfunc( Gtk::Widget &widget, -+ Gdk::Rectangle const *cell_area, -+ int *x_offset, int *y_offset, int *width, int *height ) const; -+#endif -+ -+ virtual bool activate_vfunc(GdkEvent *event, -+ Gtk::Widget &widget, -+ const Glib::ustring &path, -+ const Gdk::Rectangle &background_area, -+ const Gdk::Rectangle &cell_area, -+ Gtk::CellRendererState flags); -+ -+ -+private: -+ int phys; -+ -+ Glib::ustring _pixClipName; -+ Glib::ustring _pixInverseName; -+ Glib::ustring _pixMaskName; -+ -+ Glib::Property _property_active; -+ Glib::Property< Glib::RefPtr > _property_pixbuf_clip; -+ Glib::Property< Glib::RefPtr > _property_pixbuf_inverse; -+ Glib::Property< Glib::RefPtr > _property_pixbuf_mask; -+ -+}; -+ -+ -+ -+} // namespace Widget -+} // namespace UI -+} // namespace Inkscape -+ -+ -+#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ -+ -+/* -+ Local Variables: -+ mode:c++ -+ c-file-style:"stroustrup" -+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) -+ indent-tabs-mode:nil -+ fill-column:99 -+ End: -+*/ -+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - -=== added file 'src/ui/widget/highlight-picker.cpp' ---- src/ui/widget/highlight-picker.cpp 1970-01-01 00:00:00 +0000 -+++ src/ui/widget/highlight-picker.cpp 2013-03-08 04:27:35 +0000 -@@ -0,0 +1,176 @@ -+/* -+ * Authors: -+ * Theodore Janeczko -+ * -+ * Copyright (C) Theodore Janeczko 2012 -+ * -+ * Released under GNU GPL, read the file 'COPYING' for more information -+ */ -+ -+#include -+#include "display/cairo-utils.h" -+ -+#include -+ -+#include "highlight-picker.h" -+#include "widgets/icon.h" -+#include "widgets/toolbox.h" -+#include "ui/icon-names.h" -+ -+namespace Inkscape { -+namespace UI { -+namespace Widget { -+ -+HighlightPicker::HighlightPicker() : -+ Glib::ObjectBase(typeid(HighlightPicker)), -+ Gtk::CellRendererPixbuf(), -+ _property_active(*this, "active", 0) -+{ -+ -+ property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; -+} -+ -+HighlightPicker::~HighlightPicker() -+{ -+} -+ -+ -+#if WITH_GTKMM_3_0 -+void HighlightPicker::get_preferred_height_vfunc(Gtk::Widget& widget, -+ int& min_h, -+ int& nat_h) const -+{ -+ Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); -+ -+ if (min_h) { -+ min_h += (min_h) >> 1; -+ } -+ -+ if (nat_h) { -+ nat_h += (nat_h) >> 1; -+ } -+} -+ -+void HighlightPicker::get_preferred_width_vfunc(Gtk::Widget& widget, -+ int& min_w, -+ int& nat_w) const -+{ -+ Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); -+ -+ if (min_w) { -+ min_w += (min_w) >> 1; -+ } -+ -+ if (nat_w) { -+ nat_w += (nat_w) >> 1; -+ } -+} -+#else -+void HighlightPicker::get_size_vfunc(Gtk::Widget& widget, -+ const Gdk::Rectangle* cell_area, -+ int* x_offset, -+ int* y_offset, -+ int* width, -+ int* height ) const -+{ -+ Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); -+ -+ if ( width ) { -+ *width = 10;//+= (*width) >> 1; -+ } -+ if ( height ) { -+ *height = 20; //cell_area ? cell_area->get_height() / 2 : 50; //+= (*height) >> 1; -+ } -+} -+#endif -+ -+#if WITH_GTKMM_3_0 -+void HighlightPicker::render_vfunc( const Cairo::RefPtr& cr, -+ Gtk::Widget& widget, -+ const Gdk::Rectangle& background_area, -+ const Gdk::Rectangle& cell_area, -+ Gtk::CellRendererState flags ) -+#else -+void HighlightPicker::render_vfunc( const Glib::RefPtr& window, -+ Gtk::Widget& widget, -+ const Gdk::Rectangle& background_area, -+ const Gdk::Rectangle& cell_area, -+ const Gdk::Rectangle& expose_area, -+ Gtk::CellRendererState flags ) -+#endif -+{ -+ GdkRectangle carea; -+ -+ cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10, 20); -+ cairo_t *ct = cairo_create(s); -+ -+ /* Transparent area */ -+ carea.x = 0; -+ carea.y = 0; -+ carea.width = 10; -+ carea.height = 20; -+ -+ cairo_pattern_t *checkers = ink_cairo_pattern_create_checkerboard(); -+ -+ cairo_rectangle(ct, carea.x, carea.y, carea.width, carea.height / 2); -+ cairo_set_source(ct, checkers); -+ cairo_fill_preserve(ct); -+ ink_cairo_set_source_rgba32(ct, _property_active.get_value()); -+ cairo_fill(ct); -+ -+ cairo_pattern_destroy(checkers); -+ -+ cairo_rectangle(ct, carea.x, carea.y + carea.height / 2, carea.width, carea.height / 2); -+ ink_cairo_set_source_rgba32(ct, _property_active.get_value() | 0x000000ff); -+ cairo_fill(ct); -+ -+ cairo_rectangle(ct, carea.x, carea.y, carea.width, carea.height); -+ ink_cairo_set_source_rgba32(ct, 0x333333ff); -+ cairo_set_line_width(ct, 2); -+ cairo_stroke(ct); -+ -+ cairo_destroy(ct); -+ cairo_surface_flush(s); -+ -+ GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( cairo_image_surface_get_data(s), -+ GDK_COLORSPACE_RGB, TRUE, 8, -+ 10, 20, cairo_image_surface_get_stride(s), -+ ink_cairo_pixbuf_cleanup, s); -+ convert_pixbuf_argb32_to_normal(pixbuf); -+ -+ property_pixbuf() = Glib::wrap(pixbuf); -+#if WITH_GTKMM_3_0 -+ Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); -+#else -+ Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); -+#endif -+} -+ -+bool -+HighlightPicker::activate_vfunc(GdkEvent* event, -+ Gtk::Widget& /*widget*/, -+ const Glib::ustring& path, -+ const Gdk::Rectangle& /*background_area*/, -+ const Gdk::Rectangle& /*cell_area*/, -+ Gtk::CellRendererState /*flags*/) -+{ -+ return false; -+} -+ -+ -+} // namespace Widget -+} // namespace UI -+} // namespace Inkscape -+ -+/* -+ Local Variables: -+ mode:c++ -+ c-file-style:"stroustrup" -+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) -+ indent-tabs-mode:nil -+ fill-column:99 -+ End: -+*/ -+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -+ -+ - -=== added file 'src/ui/widget/highlight-picker.h' ---- src/ui/widget/highlight-picker.h 1970-01-01 00:00:00 +0000 -+++ src/ui/widget/highlight-picker.h 2013-03-08 04:27:35 +0000 -@@ -0,0 +1,90 @@ -+#ifndef __UI_DIALOG_HIGHLIGHT_PICKER_H__ -+#define __UI_DIALOG_HIGHLIGHT_PICKER_H__ -+/* -+ * Authors: -+ * Theodore Janeczko -+ * -+ * Copyright (C) Theodore Janeczko 2012 -+ * -+ * Released under GNU GPL, read the file 'COPYING' for more information -+ */ -+ -+#if HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#include -+#include -+#include -+ -+namespace Inkscape { -+namespace UI { -+namespace Widget { -+ -+class HighlightPicker : public Gtk::CellRendererPixbuf { -+public: -+ HighlightPicker(); -+ virtual ~HighlightPicker(); -+ -+ Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } -+ -+protected: -+ -+#if WITH_GTKMM_3_0 -+ virtual void render_vfunc( const Cairo::RefPtr& cr, -+ Gtk::Widget& widget, -+ const Gdk::Rectangle& background_area, -+ const Gdk::Rectangle& cell_area, -+ Gtk::CellRendererState flags ); -+ -+ virtual void get_preferred_width_vfunc(Gtk::Widget& widget, -+ int& min_w, -+ int& nat_w) const; -+ -+ virtual void get_preferred_height_vfunc(Gtk::Widget& widget, -+ int& min_h, -+ int& nat_h) const; -+#else -+ virtual void render_vfunc( const Glib::RefPtr& window, -+ Gtk::Widget& widget, -+ const Gdk::Rectangle& background_area, -+ const Gdk::Rectangle& cell_area, -+ const Gdk::Rectangle& expose_area, -+ Gtk::CellRendererState flags ); -+ -+ virtual void get_size_vfunc( Gtk::Widget &widget, -+ Gdk::Rectangle const *cell_area, -+ int *x_offset, int *y_offset, int *width, int *height ) const; -+#endif -+ -+ virtual bool activate_vfunc(GdkEvent *event, -+ Gtk::Widget &widget, -+ const Glib::ustring &path, -+ const Gdk::Rectangle &background_area, -+ const Gdk::Rectangle &cell_area, -+ Gtk::CellRendererState flags); -+ -+private: -+ -+ Glib::Property _property_active; -+}; -+ -+ -+ -+} // namespace Widget -+} // namespace UI -+} // namespace Inkscape -+ -+ -+#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ -+ -+/* -+ Local Variables: -+ mode:c++ -+ c-file-style:"stroustrup" -+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) -+ indent-tabs-mode:nil -+ fill-column:99 -+ End: -+*/ -+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - -=== added file 'src/ui/widget/layertypeicon.cpp' ---- src/ui/widget/layertypeicon.cpp 1970-01-01 00:00:00 +0000 -+++ src/ui/widget/layertypeicon.cpp 2013-03-08 04:27:35 +0000 -@@ -0,0 +1,167 @@ -+/* -+ * Authors: -+ * Theodore Janeczko -+ * -+ * Copyright (C) Theodore Janeczko 2012 -+ * -+ * Released under GNU GPL, read the file 'COPYING' for more information -+ */ -+ -+ -+#include "ui/widget/layertypeicon.h" -+ -+#include -+ -+#include "widgets/icon.h" -+#include "widgets/toolbox.h" -+#include "ui/icon-names.h" -+#include "layertypeicon.h" -+ -+namespace Inkscape { -+namespace UI { -+namespace Widget { -+ -+LayerTypeIcon::LayerTypeIcon() : -+ Glib::ObjectBase(typeid(LayerTypeIcon)), -+ Gtk::CellRendererPixbuf(), -+ _pixLayerName(INKSCAPE_ICON("dialog-layers")), -+ _pixGroupName(INKSCAPE_ICON("layer-duplicate")), -+ _pixPathName(INKSCAPE_ICON("layer-rename")), -+ _property_active(*this, "active", false), -+ _property_activatable(*this, "activatable", true), -+ _property_pixbuf_layer(*this, "pixbuf_on", Glib::RefPtr(0)), -+ _property_pixbuf_group(*this, "pixbuf_off", Glib::RefPtr(0)), -+ _property_pixbuf_path(*this, "pixbuf_off", Glib::RefPtr(0)) -+{ -+ -+ property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; -+ int phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_DECORATION); -+ Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); -+ -+ if (!icon_theme->has_icon(_pixLayerName)) { -+ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixLayerName.data()), Inkscape::ICON_SIZE_DECORATION ); -+ } -+ if (!icon_theme->has_icon(_pixGroupName)) { -+ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixGroupName.data()), Inkscape::ICON_SIZE_DECORATION ); -+ } -+ if (!icon_theme->has_icon(_pixPathName)) { -+ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixPathName.data()), Inkscape::ICON_SIZE_DECORATION ); -+ } -+ -+ if (icon_theme->has_icon(_pixLayerName)) { -+ _property_pixbuf_layer = icon_theme->load_icon(_pixLayerName, phys, (Gtk::IconLookupFlags)0); -+ } -+ if (icon_theme->has_icon(_pixGroupName)) { -+ _property_pixbuf_group = icon_theme->load_icon(_pixGroupName, phys, (Gtk::IconLookupFlags)0); -+ } -+ if (icon_theme->has_icon(_pixPathName)) { -+ _property_pixbuf_path = icon_theme->load_icon(_pixPathName, phys, (Gtk::IconLookupFlags)0); -+ } -+ -+ property_pixbuf() = _property_pixbuf_path.get_value(); -+} -+ -+ -+#if WITH_GTKMM_3_0 -+void LayerTypeIcon::get_preferred_height_vfunc(Gtk::Widget& widget, -+ int& min_h, -+ int& nat_h) const -+{ -+ Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); -+ -+ if (min_h) { -+ min_h += (min_h) >> 1; -+ } -+ -+ if (nat_h) { -+ nat_h += (nat_h) >> 1; -+ } -+} -+ -+void LayerTypeIcon::get_preferred_width_vfunc(Gtk::Widget& widget, -+ int& min_w, -+ int& nat_w) const -+{ -+ Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); -+ -+ if (min_w) { -+ min_w += (min_w) >> 1; -+ } -+ -+ if (nat_w) { -+ nat_w += (nat_w) >> 1; -+ } -+} -+#else -+void LayerTypeIcon::get_size_vfunc(Gtk::Widget& widget, -+ const Gdk::Rectangle* cell_area, -+ int* x_offset, -+ int* y_offset, -+ int* width, -+ int* height ) const -+{ -+ Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); -+ -+ if ( width ) { -+ *width += (*width) >> 1; -+ } -+ if ( height ) { -+ *height += (*height) >> 1; -+ } -+} -+#endif -+ -+#if WITH_GTKMM_3_0 -+void LayerTypeIcon::render_vfunc( const Cairo::RefPtr& cr, -+ Gtk::Widget& widget, -+ const Gdk::Rectangle& background_area, -+ const Gdk::Rectangle& cell_area, -+ Gtk::CellRendererState flags ) -+#else -+void LayerTypeIcon::render_vfunc( const Glib::RefPtr& window, -+ Gtk::Widget& widget, -+ const Gdk::Rectangle& background_area, -+ const Gdk::Rectangle& cell_area, -+ const Gdk::Rectangle& expose_area, -+ Gtk::CellRendererState flags ) -+#endif -+{ -+ property_pixbuf() = _property_active.get_value() == 1 ? _property_pixbuf_group : (_property_active.get_value() == 2 ? _property_pixbuf_layer : _property_pixbuf_path); -+#if WITH_GTKMM_3_0 -+ Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); -+#else -+ Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); -+#endif -+} -+ -+bool -+LayerTypeIcon::activate_vfunc(GdkEvent* event, -+ Gtk::Widget& /*widget*/, -+ const Glib::ustring& path, -+ const Gdk::Rectangle& /*background_area*/, -+ const Gdk::Rectangle& /*cell_area*/, -+ Gtk::CellRendererState /*flags*/) -+{ -+ _signal_pre_toggle.emit(event); -+ _signal_toggled.emit(path); -+ -+ return false; -+} -+ -+ -+} // namespace Widget -+} // namespace UI -+} // namespace Inkscape -+ -+/* -+ Local Variables: -+ mode:c++ -+ c-file-style:"stroustrup" -+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) -+ indent-tabs-mode:nil -+ fill-column:99 -+ End: -+*/ -+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -+ -+ - -=== added file 'src/ui/widget/layertypeicon.h' ---- src/ui/widget/layertypeicon.h 1970-01-01 00:00:00 +0000 -+++ src/ui/widget/layertypeicon.h 2013-03-08 04:27:35 +0000 -@@ -0,0 +1,108 @@ -+#ifndef __UI_DIALOG_LAYERTYPEICON_H__ -+#define __UI_DIALOG_LAYERTYPEICON_H__ -+/* -+ * Authors: -+ * Theodore Janeczko -+ * -+ * Copyright (C) Theodore Janeczko 2012 -+ * -+ * Released under GNU GPL, read the file 'COPYING' for more information -+ */ -+ -+#if HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#include -+#include -+#include -+ -+namespace Inkscape { -+namespace UI { -+namespace Widget { -+ -+class LayerTypeIcon : public Gtk::CellRendererPixbuf { -+public: -+ LayerTypeIcon(); -+ virtual ~LayerTypeIcon() {}; -+ -+ sigc::signal signal_toggled() { return _signal_toggled;} -+ sigc::signal signal_pre_toggle() { return _signal_pre_toggle; } -+ -+ Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } -+ Glib::PropertyProxy property_activatable() { return _property_activatable.get_proxy(); } -+ Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_on(); -+ Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_off(); -+ -+protected: -+ -+#if WITH_GTKMM_3_0 -+ virtual void render_vfunc( const Cairo::RefPtr& cr, -+ Gtk::Widget& widget, -+ const Gdk::Rectangle& background_area, -+ const Gdk::Rectangle& cell_area, -+ Gtk::CellRendererState flags ); -+ -+ virtual void get_preferred_width_vfunc(Gtk::Widget& widget, -+ int& min_w, -+ int& nat_w) const; -+ -+ virtual void get_preferred_height_vfunc(Gtk::Widget& widget, -+ int& min_h, -+ int& nat_h) const; -+#else -+ virtual void render_vfunc( const Glib::RefPtr& window, -+ Gtk::Widget& widget, -+ const Gdk::Rectangle& background_area, -+ const Gdk::Rectangle& cell_area, -+ const Gdk::Rectangle& expose_area, -+ Gtk::CellRendererState flags ); -+ -+ virtual void get_size_vfunc( Gtk::Widget &widget, -+ Gdk::Rectangle const *cell_area, -+ int *x_offset, int *y_offset, int *width, int *height ) const; -+#endif -+ -+ virtual bool activate_vfunc(GdkEvent *event, -+ Gtk::Widget &widget, -+ const Glib::ustring &path, -+ const Gdk::Rectangle &background_area, -+ const Gdk::Rectangle &cell_area, -+ Gtk::CellRendererState flags); -+ -+ -+private: -+ Glib::ustring _pixLayerName; -+ Glib::ustring _pixGroupName; -+ Glib::ustring _pixPathName; -+ -+ Glib::Property _property_active; -+ Glib::Property _property_activatable; -+ Glib::Property< Glib::RefPtr > _property_pixbuf_layer; -+ Glib::Property< Glib::RefPtr > _property_pixbuf_group; -+ Glib::Property< Glib::RefPtr > _property_pixbuf_path; -+ -+ sigc::signal _signal_toggled; -+ sigc::signal _signal_pre_toggle; -+ -+}; -+ -+ -+ -+} // namespace Widget -+} // namespace UI -+} // namespace Inkscape -+ -+ -+#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ -+ -+/* -+ Local Variables: -+ mode:c++ -+ c-file-style:"stroustrup" -+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) -+ indent-tabs-mode:nil -+ fill-column:99 -+ End: -+*/ -+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - -=== modified file 'src/verbs.cpp' ---- src/verbs.cpp 2013-03-04 17:21:11 +0000 -+++ src/verbs.cpp 2013-03-17 14:29:16 +0000 -@@ -1980,6 +1980,9 @@ - case SP_VERB_DIALOG_LAYERS: - dt->_dlg_mgr->showDialog("LayersPanel"); - break; -+ case SP_VERB_DIALOG_OBJECTS: -+ dt->_dlg_mgr->showDialog("ObjectsPanel"); -+ break; - case SP_VERB_DIALOG_LIVE_PATH_EFFECT: - dt->_dlg_mgr->showDialog("LivePathEffect"); - break; -@@ -2791,6 +2794,8 @@ - N_("Query information about extensions"), NULL), - new DialogVerb(SP_VERB_DIALOG_LAYERS, "DialogLayers", N_("Layer_s..."), - N_("View Layers"), INKSCAPE_ICON("dialog-layers")), -+ new DialogVerb(SP_VERB_DIALOG_OBJECTS, "DialogObjects", N_("Object_s..."), -+ N_("View Objects"), INKSCAPE_ICON("dialog-layers")), - new DialogVerb(SP_VERB_DIALOG_LIVE_PATH_EFFECT, "DialogLivePathEffect", N_("Path E_ffects ..."), - N_("Manage, edit, and apply path effects"), NULL), - new DialogVerb(SP_VERB_DIALOG_FILTER_EFFECTS, "DialogFilterEffects", N_("Filter _Editor..."), - -=== modified file 'src/verbs.h' ---- src/verbs.h 2013-03-04 17:21:11 +0000 -+++ src/verbs.h 2013-03-17 14:28:15 +0000 -@@ -285,6 +285,7 @@ - SP_VERB_DIALOG_INPUT, - SP_VERB_DIALOG_EXTENSIONEDITOR, - SP_VERB_DIALOG_LAYERS, -+ SP_VERB_DIALOG_OBJECTS, - SP_VERB_DIALOG_LIVE_PATH_EFFECT, - SP_VERB_DIALOG_FILTER_EFFECTS, - SP_VERB_DIALOG_SVG_FONTS, - -- cgit v1.2.3