From: mental Date: Wed, 15 Mar 2006 22:58:35 +0000 (+0000) Subject: merged patch #1447043 from Andrius "knutux" R. to create sub-layers X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=5610aa55bc12809620f592a6de38a2f70628846b;p=inkscape.git merged patch #1447043 from Andrius "knutux" R. to create sub-layers --- diff --git a/ChangeLog b/ChangeLog index d6a4c057f..282554854 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-03-14 MenTaLguY + + * src/layer-fns.h, src/dialogs/layer-properties.cpp, + src/dialogs/layer-properties.h, src/layer-fns.cpp: + + merged patch #1447043 from Andrius "knutux" R. to create sub-layers + 2006-03-14 MenTaLguY * src/Makefile_insert, src/display/nr-arena-item.cpp, diff --git a/src/dialogs/layer-properties.cpp b/src/dialogs/layer-properties.cpp index 8806e97f0..086b24b07 100644 --- a/src/dialogs/layer-properties.cpp +++ b/src/dialogs/layer-properties.cpp @@ -4,8 +4,10 @@ * * Author: * Bryce W. Harrington + * Andreas R. * * Copyright (C) 2004 Bryce Harrington + * Copyright (C) 2006 Andreas R. * * Released under GNU GPL. Read the file 'COPYING' for more information */ @@ -22,8 +24,8 @@ #include "document.h" #include "message-stack.h" #include "desktop-handles.h" -#include "layer-fns.h" #include "sp-object.h" +#include "sp-item.h" #include "layer-properties.h" @@ -39,12 +41,19 @@ LayerPropertiesDialog::LayerPropertiesDialog() Gtk::VBox *mainVBox = get_vbox(); + _layout_table.set_spacings(4); + _layout_table.resize (1, 2); + // Layer name widgets _layer_name_entry.set_activates_default(true); - _layer_name_hbox.pack_end(_layer_name_entry, false, false, 4); _layer_name_label.set_label(_("Layer name:")); - _layer_name_hbox.pack_end(_layer_name_label, false, false, 4); - mainVBox->pack_start(_layer_name_hbox, false, false, 4); + _layer_name_label.set_alignment(1.0, 0.5); + + _layout_table.attach(_layer_name_label, + 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); + _layout_table.attach(_layer_name_entry, + 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + mainVBox->pack_start(_layout_table, false, false, 4); // Buttons _close_button.set_use_stock(true); @@ -123,6 +132,51 @@ LayerPropertiesDialog::_close() ); } +void +LayerPropertiesDialog::_setup_position_controls() { + if ( NULL == _layer || _desktop->currentRoot() == _layer ) { + // no layers yet, so option above/below/sublayer is useless + return; + } + + _dropdown_list = Gtk::ListStore::create(_dropdown_columns); + _layer_position_combo.set_model(_dropdown_list); + _layer_position_combo.pack_start(_label_renderer); + _layer_position_combo.set_cell_data_func(_label_renderer, + sigc::mem_fun(*this, &LayerPropertiesDialog::_prepareLabelRenderer)); + + _layout_table.resize (2, 2); + + Gtk::ListStore::iterator row; + row = _dropdown_list->append(); + row->set_value(_dropdown_columns.position, LPOS_ABOVE); + row->set_value(_dropdown_columns.name, Glib::ustring(_("Above current"))); + _layer_position_combo.set_active(row); + row = _dropdown_list->append(); + row->set_value(_dropdown_columns.position, LPOS_BELOW); + row->set_value(_dropdown_columns.name, Glib::ustring(_("Below current"))); + row = _dropdown_list->append(); + row->set_value(_dropdown_columns.position, LPOS_CHILD); + row->set_value(_dropdown_columns.name, Glib::ustring(_("As sublayer of current"))); + + _layout_table.attach(_layer_position_combo, + 1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + _layer_position_label.set_label(_("Position:")); + _layer_position_label.set_alignment(1.0, 0.5); + _layout_table.attach(_layer_position_label, + 0, 1, 1, 2, Gtk::FILL, Gtk::FILL); + show_all_children(); +} + +/** Formats the label for a given layer row + */ +void LayerPropertiesDialog::_prepareLabelRenderer( + Gtk::TreeModel::const_iterator const &row +) { + Glib::ustring name=(*row)[_dropdown_columns.name]; + _label_renderer.property_markup() = name.c_str(); +} + void LayerPropertiesDialog::Rename::setup(LayerPropertiesDialog &dialog) { SPDesktop *desktop=dialog._desktop; dialog.set_title(_("Rename Layer")); @@ -146,13 +200,17 @@ void LayerPropertiesDialog::Create::setup(LayerPropertiesDialog &dialog) { dialog.set_title(_("Add Layer")); dialog._layer_name_entry.set_text(""); dialog._apply_button.set_label(_("_Add")); + dialog._setup_position_controls(); } void LayerPropertiesDialog::Create::perform(LayerPropertiesDialog &dialog) { SPDesktop *desktop=dialog._desktop; - SPObject *new_layer=Inkscape::create_layer( - desktop->currentRoot(), dialog._layer - ); + + Gtk::ListStore::iterator activeRow(dialog._layer_position_combo.get_active()); + LayerRelativePosition position = activeRow->get_value(dialog._dropdown_columns.position); + + SPObject *new_layer=Inkscape::create_layer(desktop->currentRoot(), dialog._layer, position); + Glib::ustring name(dialog._layer_name_entry.get_text()); if (!name.empty()) { new_layer->setLabel((gchar *)name.c_str()); diff --git a/src/dialogs/layer-properties.h b/src/dialogs/layer-properties.h index 15404b2e5..93cd4f7e0 100644 --- a/src/dialogs/layer-properties.h +++ b/src/dialogs/layer-properties.h @@ -20,8 +20,11 @@ #include #include #include +#include +#include #include "selection.h" +#include "layer-fns.h" namespace Inkscape { namespace UI { @@ -65,9 +68,25 @@ protected: SPDesktop *_desktop; SPObject *_layer; - Gtk::HBox _layer_name_hbox; + class PositionDropdownColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn position; + Gtk::TreeModelColumn name; + + PositionDropdownColumns() { + add(position); add(name); + } + }; + Gtk::Label _layer_name_label; Gtk::Entry _layer_name_entry; + Gtk::Label _layer_position_label; + Gtk::ComboBox _layer_position_combo; + Gtk::Table _layout_table; + + PositionDropdownColumns _dropdown_columns; + Gtk::CellRendererText _label_renderer; + Glib::RefPtr _dropdown_list; Gtk::Button _close_button; Gtk::Button _apply_button; @@ -86,6 +105,9 @@ protected: void _apply(); void _close(); + void _setup_position_controls(); + void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); + private: LayerPropertiesDialog(LayerPropertiesDialog const &); // no copy LayerPropertiesDialog &operator=(LayerPropertiesDialog const &); // no assign diff --git a/src/layer-fns.cpp b/src/layer-fns.cpp index c143336cc..2d58796af 100644 --- a/src/layer-fns.cpp +++ b/src/layer-fns.cpp @@ -17,42 +17,10 @@ #include "sp-item-group.h" #include "xml/repr.h" #include "algorithms/find-last-if.h" +#include "layer-fns.h" namespace Inkscape { -/** - * Creates a new layer. Advances to the next layer id indicated - * by the string "layerNN", then creates a new group object of - * that id with attribute inkscape:groupmode='layer', and finally - * appends the new group object to \a root after object \a layer. - * - * \pre \a root should be either \a layer or an ancestor of it - */ -SPObject *create_layer(SPObject *root, SPObject *layer) { - SPDocument *document=SP_OBJECT_DOCUMENT(root); - - static int layer_suffix=1; - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("layer%d", layer_suffix++); - } while (document->getObjectById(id)); - - Inkscape::XML::Node *repr=sp_repr_new("svg:g"); - repr->setAttribute("inkscape:groupmode", "layer"); - repr->setAttribute("id", id); - g_free(id); - - if ( root == layer ) { - SP_OBJECT_REPR(root)->appendChild(repr); - } else { - Inkscape::XML::Node *layer_repr=SP_OBJECT_REPR(layer); - sp_repr_parent(layer_repr)->addChild(repr, layer_repr); - } - - return document->getObjectByRepr(repr); -} - namespace { bool is_layer(SPObject &object) { @@ -60,6 +28,10 @@ bool is_layer(SPObject &object) { SP_GROUP(&object)->layerMode() == SPGroup::LAYER; } +/** Finds the next sibling layer for a \a layer + * + * @returns NULL if there are no further layers under a parent + */ SPObject *next_sibling_layer(SPObject *layer) { using std::find_if; @@ -68,6 +40,10 @@ SPObject *next_sibling_layer(SPObject *layer) { ); } +/** Finds the previous sibling layer for a \a layer + * + * @returns NULL if there are no further layers under a parent + */ SPObject *previous_sibling_layer(SPObject *layer) { using Inkscape::Algorithms::find_last_if; @@ -78,6 +54,10 @@ SPObject *previous_sibling_layer(SPObject *layer) { return ( sibling != layer ) ? sibling : NULL; } +/** Finds the first child of a \a layer + * + * @returns NULL if layer has no sublayers + */ SPObject *first_descendant_layer(SPObject *layer) { using std::find_if; @@ -94,6 +74,10 @@ SPObject *first_descendant_layer(SPObject *layer) { return first_descendant; } +/** Finds the last (topmost) child of a \a layer + * + * @returns NULL if layer has no sublayers + */ SPObject *last_child_layer(SPObject *layer) { using Inkscape::Algorithms::find_last_if; @@ -172,6 +156,51 @@ SPObject *previous_layer(SPObject *root, SPObject *layer) { return NULL; } +/** +* Creates a new layer. Advances to the next layer id indicated + * by the string "layerNN", then creates a new group object of + * that id with attribute inkscape:groupmode='layer', and finally + * appends the new group object to \a root after object \a layer. + * + * \pre \a root should be either \a layer or an ancestor of it + */ +SPObject *create_layer(SPObject *root, SPObject *layer, LayerRelativePosition position) { + SPDocument *document=SP_OBJECT_DOCUMENT(root); + + static int layer_suffix=1; + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("layer%d", layer_suffix++); + } while (document->getObjectById(id)); + + Inkscape::XML::Node *repr=sp_repr_new("svg:g"); + repr->setAttribute("inkscape:groupmode", "layer"); + repr->setAttribute("id", id); + g_free(id); + + if ( LPOS_CHILD == position ) { + root = layer; + SPObject *child_layer = Inkscape::last_child_layer(layer); + if ( NULL != child_layer ) { + layer = child_layer; + } + } + + if ( root == layer ) { + SP_OBJECT_REPR(root)->appendChild(repr); + } else { + Inkscape::XML::Node *layer_repr=SP_OBJECT_REPR(layer); + sp_repr_parent(layer_repr)->addChild(repr, layer_repr); + + if ( LPOS_BELOW == position ) { + SP_ITEM(document->getObjectByRepr(repr))->lowerOne(); + } + } + + return document->getObjectByRepr(repr); +} + } /* diff --git a/src/layer-fns.h b/src/layer-fns.h index ba11bab6a..c3e74c472 100644 --- a/src/layer-fns.h +++ b/src/layer-fns.h @@ -16,8 +16,14 @@ class SPObject; namespace Inkscape { -SPObject *create_layer(SPObject *root, SPObject *layer); - +enum LayerRelativePosition { + LPOS_ABOVE, + LPOS_BELOW, + LPOS_CHILD, +}; + +SPObject *create_layer(SPObject *root, SPObject *layer, LayerRelativePosition position); + SPObject *next_layer(SPObject *root, SPObject *layer); SPObject *previous_layer(SPObject *root, SPObject *layer);