diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2009-02-21 01:59:56 +0000 |
|---|---|---|
| committer | tweenk <tweenk@users.sourceforge.net> | 2009-02-21 01:59:56 +0000 |
| commit | 154165799998cb2cb7491bbd97b0511943a0228e (patch) | |
| tree | 878507e5e42b4651f1bb0805a42c0837528eb314 /src/widgets/layer-selector.cpp | |
| parent | Only build static libraries for subdirs than actually contain libraries, (diff) | |
| download | inkscape-154165799998cb2cb7491bbd97b0511943a0228e.tar.gz inkscape-154165799998cb2cb7491bbd97b0511943a0228e.zip | |
Move files from the src/dialogs/ directory to the places where they
should be. Build libinkscape.a - should reduce link time.
(bzr r7337)
Diffstat (limited to 'src/widgets/layer-selector.cpp')
| -rw-r--r-- | src/widgets/layer-selector.cpp | 611 |
1 files changed, 0 insertions, 611 deletions
diff --git a/src/widgets/layer-selector.cpp b/src/widgets/layer-selector.cpp deleted file mode 100644 index d51b31e67..000000000 --- a/src/widgets/layer-selector.cpp +++ /dev/null @@ -1,611 +0,0 @@ -/* - * Inkscape::Widgets::LayerSelector - layer selector widget - * - * Authors: - * MenTaLguY <mental@rydia.net> - * - * Copyright (C) 2004 MenTaLguY - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <cstring> -#include <string> -#include <glibmm/i18n.h> - -#include "desktop-handles.h" - -#include "widgets/layer-selector.h" -#include "widgets/shrink-wrap-button.h" -#include "widgets/icon.h" - -#include "util/reverse-list.h" -#include "util/filter-list.h" - -#include "sp-item.h" -#include "desktop.h" -#include "document.h" -#include "dialogs/layer-properties.h" -#include "layer-manager.h" -#include "xml/node-event-vector.h" -#include "verbs.h" - -namespace Inkscape { -namespace Widgets { - -namespace { - -class AlternateIcons : public Gtk::HBox { -public: - AlternateIcons(Inkscape::IconSize size, gchar const *a, gchar const *b) - : _a(NULL), _b(NULL) - { - if (a) { - _a = Gtk::manage(sp_icon_get_icon(a, size)); - _a->set_no_show_all(true); - add(*_a); - } - if (b) { - _b = Gtk::manage(sp_icon_get_icon(b, size)); - _b->set_no_show_all(true); - add(*_b); - } - setState(false); - } - - bool state() const { return _state; } - void setState(bool state) { - _state = state; - if (_state) { - if (_a) { - _a->hide(); - } - if (_b) { - _b->show(); - } - } else { - if (_a) { - _a->show(); - } - if (_b) { - _b->hide(); - } - } - } - -private: - Gtk::Widget *_a; - Gtk::Widget *_b; - bool _state; -}; - -} - -/** LayerSelector constructor. Creates lock and hide buttons, - * initalizes the layer dropdown selector with a label renderer, - * and hooks up signal for setting the desktop layer when the - * selector is changed. - */ -LayerSelector::LayerSelector(SPDesktop *desktop) -: _desktop(NULL), _layer(NULL) -{ - AlternateIcons *label; - - label = Gtk::manage(new AlternateIcons(Inkscape::ICON_SIZE_DECORATION, "visible", "hidden")); - _visibility_toggle.add(*label); - _visibility_toggle.signal_toggled().connect( - sigc::compose( - sigc::mem_fun(*label, &AlternateIcons::setState), - sigc::mem_fun(_visibility_toggle, &Gtk::ToggleButton::get_active) - ) - ); - _visibility_toggled_connection = _visibility_toggle.signal_toggled().connect( - sigc::compose( - sigc::mem_fun(*this, &LayerSelector::_hideLayer), - sigc::mem_fun(_visibility_toggle, &Gtk::ToggleButton::get_active) - ) - ); - - _visibility_toggle.set_relief(Gtk::RELIEF_NONE); - shrink_wrap_button(_visibility_toggle); - _tooltips.set_tip(_visibility_toggle, _("Toggle current layer visibility")); - pack_start(_visibility_toggle, Gtk::PACK_EXPAND_PADDING); - - label = Gtk::manage(new AlternateIcons(Inkscape::ICON_SIZE_DECORATION, "lock_unlocked", "width_height_lock")); - _lock_toggle.add(*label); - _lock_toggle.signal_toggled().connect( - sigc::compose( - sigc::mem_fun(*label, &AlternateIcons::setState), - sigc::mem_fun(_lock_toggle, &Gtk::ToggleButton::get_active) - ) - ); - _lock_toggled_connection = _lock_toggle.signal_toggled().connect( - sigc::compose( - sigc::mem_fun(*this, &LayerSelector::_lockLayer), - sigc::mem_fun(_lock_toggle, &Gtk::ToggleButton::get_active) - ) - ); - - _lock_toggle.set_relief(Gtk::RELIEF_NONE); - shrink_wrap_button(_lock_toggle); - _tooltips.set_tip(_lock_toggle, _("Lock or unlock current layer")); - pack_start(_lock_toggle, Gtk::PACK_EXPAND_PADDING); - - _tooltips.set_tip(_selector, _("Current layer")); - pack_start(_selector, Gtk::PACK_EXPAND_WIDGET); - - _layer_model = Gtk::ListStore::create(_model_columns); - _selector.set_model(_layer_model); - _selector.pack_start(_label_renderer); - _selector.set_cell_data_func( - _label_renderer, - sigc::mem_fun(*this, &LayerSelector::_prepareLabelRenderer) - ); - - _selection_changed_connection = _selector.signal_changed().connect( - sigc::mem_fun(*this, &LayerSelector::_setDesktopLayer) - ); - setDesktop(desktop); -} - -/** Destructor - disconnects signal handler - */ -LayerSelector::~LayerSelector() { - setDesktop(NULL); - _selection_changed_connection.disconnect(); -} - -namespace { - -/** Helper function - detaches desktop from selector - */ -bool detach(LayerSelector *selector) { - selector->setDesktop(NULL); - return FALSE; -} - -} - -/** Sets the desktop for the widget. First disconnects signals - * for the current desktop, then stores the pointer to the - * given \a desktop, and attaches its signals to this one. - * Then it selects the current layer for the desktop. - */ -void LayerSelector::setDesktop(SPDesktop *desktop) { - if ( desktop == _desktop ) { - return; - } - - if (_desktop) { -// _desktop_shutdown_connection.disconnect(); - _layer_changed_connection.disconnect(); -// g_signal_handlers_disconnect_by_func(_desktop, (gpointer)&detach, this); - } - _desktop = desktop; - if (_desktop) { - // TODO we need a different signal for this, really..s -// _desktop_shutdown_connection = _desktop->connectShutdown( -// sigc::bind (sigc::ptr_fun (detach), this)); -// g_signal_connect_after(_desktop, "shutdown", GCallback(detach), this); - - _layer_changed_connection = _desktop->connectCurrentLayerChanged( - sigc::mem_fun(*this, &LayerSelector::_selectLayer) - ); - _selectLayer(_desktop->currentLayer()); - } -} - -namespace { - -class is_layer { -public: - is_layer(SPDesktop *desktop) : _desktop(desktop) {} - bool operator()(SPObject &object) const { - return _desktop->isLayer(&object); - } -private: - SPDesktop *_desktop; -}; - -class column_matches_object { -public: - column_matches_object(Gtk::TreeModelColumn<SPObject *> const &column, - SPObject &object) - : _column(column), _object(object) {} - bool operator()(Gtk::TreeModel::const_iterator const &iter) const { - SPObject *current=(*iter)[_column]; - return current == &_object; - } -private: - Gtk::TreeModelColumn<SPObject *> const &_column; - SPObject &_object; -}; - -} - -/** Selects the given layer in the dropdown selector. - */ -void LayerSelector::_selectLayer(SPObject *layer) { - using Inkscape::Util::List; - using Inkscape::Util::cons; - using Inkscape::Util::reverse_list; - - _selection_changed_connection.block(); - - while (!_layer_model->children().empty()) { - Gtk::ListStore::iterator first_row(_layer_model->children().begin()); - _destroyEntry(first_row); - _layer_model->erase(first_row); - } - - SPObject *root=_desktop->currentRoot(); - - if (_layer) { - sp_object_unref(_layer, NULL); - _layer = NULL; - } - - if (layer) { - List<SPObject &> hierarchy=reverse_list<SPObject::ParentIterator>(layer, root); - if ( layer == root ) { - _buildEntries(0, cons(*root, hierarchy)); - } else if (hierarchy) { - _buildSiblingEntries(0, *root, hierarchy); - } - - Gtk::TreeIter row( - std::find_if( - _layer_model->children().begin(), - _layer_model->children().end(), - column_matches_object(_model_columns.object, *layer) - ) - ); - if ( row != _layer_model->children().end() ) { - _selector.set_active(row); - } - - _layer = layer; - sp_object_ref(_layer, NULL); - } - - if ( !layer || layer == root ) { - _visibility_toggle.set_sensitive(false); - _visibility_toggle.set_active(false); - _lock_toggle.set_sensitive(false); - _lock_toggle.set_active(false); - } else { - _visibility_toggle.set_sensitive(true); - _visibility_toggle.set_active(( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isHidden() : false )); - _lock_toggle.set_sensitive(true); - _lock_toggle.set_active(( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isLocked() : false )); - } - - _selection_changed_connection.unblock(); -} - -/** Sets the current desktop layer to the actively selected layer. - */ -void LayerSelector::_setDesktopLayer() { - Gtk::ListStore::iterator selected(_selector.get_active()); - SPObject *layer=_selector.get_active()->get_value(_model_columns.object); - if ( _desktop && layer ) { - _layer_changed_connection.block(); - - _desktop->layer_manager->setCurrentLayer(layer); - - _layer_changed_connection.unblock(); - - _selectLayer(_desktop->currentLayer()); - } - if (_desktop && _desktop->canvas) { - gtk_widget_grab_focus (GTK_WIDGET(_desktop->canvas)); - } -} - -/** Creates rows in the _layer_model data structure for each item - * in \a hierarchy, to a given \a depth. - */ -void LayerSelector::_buildEntries(unsigned depth, - Inkscape::Util::List<SPObject &> hierarchy) -{ - using Inkscape::Util::List; - using Inkscape::Util::rest; - - _buildEntry(depth, *hierarchy); - - List<SPObject &> remainder=rest(hierarchy); - if (remainder) { - _buildEntries(depth+1, remainder); - } else { - _buildSiblingEntries(depth+1, *hierarchy, remainder); - } -} - -/** Creates entries in the _layer_model data structure for - * all siblings of the first child in \a parent. - */ -void LayerSelector::_buildSiblingEntries( - unsigned depth, SPObject &parent, - Inkscape::Util::List<SPObject &> hierarchy -) { - using Inkscape::Util::List; - using Inkscape::Util::rest; - using Inkscape::Util::reverse_list_in_place; - using Inkscape::Util::filter_list; - - Inkscape::Util::List<SPObject &> siblings( - reverse_list_in_place( - filter_list<SPObject::SiblingIterator>( - is_layer(_desktop), parent.firstChild(), NULL - ) - ) - ); - - SPObject *layer( hierarchy ? &*hierarchy : NULL ); - - while (siblings) { - _buildEntry(depth, *siblings); - if ( &*siblings == layer ) { - _buildSiblingEntries(depth+1, *layer, rest(hierarchy)); - } - ++siblings; - } -} - -namespace { - -struct Callbacks { - sigc::slot<void> update_row; - sigc::slot<void> update_list; -}; - -void attribute_changed(Inkscape::XML::Node */*repr*/, gchar const *name, - gchar const */*old_value*/, gchar const */*new_value*/, - bool /*is_interactive*/, void *data) -{ - if ( !std::strcmp(name, "inkscape:groupmode") ) { - reinterpret_cast<Callbacks *>(data)->update_list(); - } else { - reinterpret_cast<Callbacks *>(data)->update_row(); - } -} - -void node_added(Inkscape::XML::Node */*parent*/, Inkscape::XML::Node *child, Inkscape::XML::Node */*ref*/, void *data) { - gchar const *mode=child->attribute("inkscape:groupmode"); - if ( mode && !std::strcmp(mode, "layer") ) { - reinterpret_cast<Callbacks *>(data)->update_list(); - } -} - -void node_removed(Inkscape::XML::Node */*parent*/, Inkscape::XML::Node *child, Inkscape::XML::Node */*ref*/, void *data) { - gchar const *mode=child->attribute("inkscape:groupmode"); - if ( mode && !std::strcmp(mode, "layer") ) { - reinterpret_cast<Callbacks *>(data)->update_list(); - } -} - -void node_reordered(Inkscape::XML::Node */*parent*/, Inkscape::XML::Node *child, - Inkscape::XML::Node */*old_ref*/, Inkscape::XML::Node */*new_ref*/, - void *data) -{ - gchar const *mode=child->attribute("inkscape:groupmode"); - if ( mode && !std::strcmp(mode, "layer") ) { - reinterpret_cast<Callbacks *>(data)->update_list(); - } -} - -void update_row_for_object(SPObject *object, - Gtk::TreeModelColumn<SPObject *> const &column, - Glib::RefPtr<Gtk::ListStore> const &model) -{ - Gtk::TreeIter row( - std::find_if( - model->children().begin(), - model->children().end(), - column_matches_object(column, *object) - ) - ); - if ( row != model->children().end() ) { - model->row_changed(model->get_path(row), row); - } -} - -void rebuild_all_rows(sigc::slot<void, SPObject *> rebuild, SPDesktop *desktop) -{ - rebuild(desktop->currentLayer()); -} - -} - -void LayerSelector::_protectUpdate(sigc::slot<void> slot) { - bool visibility_blocked=_visibility_toggled_connection.blocked(); - bool lock_blocked=_lock_toggled_connection.blocked(); - _visibility_toggled_connection.block(true); - _lock_toggled_connection.block(true); - slot(); - - SPObject *layer = _desktop ? _desktop->currentLayer() : 0; - if ( layer ) { - bool wantedValue = ( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isLocked() : false ); - if ( _lock_toggle.get_active() != wantedValue ) { - _lock_toggle.set_active( wantedValue ); - } - wantedValue = ( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isHidden() : false ); - if ( _visibility_toggle.get_active() != wantedValue ) { - _visibility_toggle.set_active( wantedValue ); - } - } - _visibility_toggled_connection.block(visibility_blocked); - _lock_toggled_connection.block(lock_blocked); -} - -/** Builds and appends a row in the layer model object. - */ -void LayerSelector::_buildEntry(unsigned depth, SPObject &object) { - Inkscape::XML::NodeEventVector *vector; - - Callbacks *callbacks=new Callbacks(); - - callbacks->update_row = sigc::bind( - sigc::mem_fun(*this, &LayerSelector::_protectUpdate), - sigc::bind( - sigc::ptr_fun(&update_row_for_object), - &object, _model_columns.object, _layer_model - ) - ); - - SPObject *layer=_desktop->currentLayer(); - if ( &object == layer || &object == SP_OBJECT_PARENT(layer) ) { - callbacks->update_list = sigc::bind( - sigc::mem_fun(*this, &LayerSelector::_protectUpdate), - sigc::bind( - sigc::ptr_fun(&rebuild_all_rows), - sigc::mem_fun(*this, &LayerSelector::_selectLayer), - _desktop - ) - ); - - Inkscape::XML::NodeEventVector events = { - &node_added, - &node_removed, - &attribute_changed, - NULL, - &node_reordered - }; - - vector = new Inkscape::XML::NodeEventVector(events); - } else { - Inkscape::XML::NodeEventVector events = { - NULL, - NULL, - &attribute_changed, - NULL, - NULL - }; - - vector = new Inkscape::XML::NodeEventVector(events); - } - - Gtk::ListStore::iterator row(_layer_model->append()); - - row->set_value(_model_columns.depth, depth); - - sp_object_ref(&object, NULL); - row->set_value(_model_columns.object, &object); - - Inkscape::GC::anchor(SP_OBJECT_REPR(&object)); - row->set_value(_model_columns.repr, SP_OBJECT_REPR(&object)); - - row->set_value(_model_columns.callbacks, reinterpret_cast<void *>(callbacks)); - - sp_repr_add_listener(SP_OBJECT_REPR(&object), vector, callbacks); -} - -/** Removes a row from the _model_columns object, disconnecting listeners - * on the slot. - */ -void LayerSelector::_destroyEntry(Gtk::ListStore::iterator const &row) { - Callbacks *callbacks=reinterpret_cast<Callbacks *>(row->get_value(_model_columns.callbacks)); - SPObject *object=row->get_value(_model_columns.object); - if (object) { - sp_object_unref(object, NULL); - } - Inkscape::XML::Node *repr=row->get_value(_model_columns.repr); - if (repr) { - sp_repr_remove_listener_by_data(repr, callbacks); - Inkscape::GC::release(repr); - } - delete callbacks; -} - -/** Formats the label for a given layer row - */ -void LayerSelector::_prepareLabelRenderer( - Gtk::TreeModel::const_iterator const &row -) { - unsigned depth=(*row)[_model_columns.depth]; - SPObject *object=(*row)[_model_columns.object]; - bool label_defaulted(false); - - // TODO: when the currently selected row is removed, - // (or before one has been selected) something appears to - // "invent" an iterator with null data and try to render it; - // where does it come from, and how can we avoid it? - if ( object && SP_OBJECT_REPR(object) ) { - SPObject *layer=( _desktop ? _desktop->currentLayer() : NULL ); - SPObject *root=( _desktop ? _desktop->currentRoot() : NULL ); - - bool isancestor = !( (layer && (SP_OBJECT_PARENT(object) == SP_OBJECT_PARENT(layer))) || ((layer == root) && (SP_OBJECT_PARENT(object) == root))); - - bool iscurrent = ( object == layer && object != root ); - - gchar *format = g_strdup_printf ( - "<span size=\"smaller\" %s><tt>%*s%s</tt>%s%s%s%%s%s%s%s</span>", - ( _desktop && _desktop->itemIsHidden (SP_ITEM(object)) ? "foreground=\"gray50\"" : "" ), - depth, "", ( iscurrent ? "•" : " " ), - ( iscurrent ? "<b>" : "" ), - ( SP_ITEM(object)->isLocked() ? "[" : "" ), - ( isancestor ? "<small>" : "" ), - ( isancestor ? "</small>" : "" ), - ( SP_ITEM(object)->isLocked() ? "]" : "" ), - ( iscurrent ? "</b>" : "" ) - ); - - gchar const *label; - if ( object != root ) { - label = object->label(); - if (!label) { - label = object->defaultLabel(); - label_defaulted = true; - } - } else { - label = _("(root)"); - } - - gchar *text = g_markup_printf_escaped(format, label); - _label_renderer.property_markup() = text; - g_free(text); - g_free(format); - } else { - _label_renderer.property_markup() = "<small> </small>"; - } - - _label_renderer.property_ypad() = 1; - _label_renderer.property_style() = ( label_defaulted ? - Pango::STYLE_ITALIC : - Pango::STYLE_NORMAL ); -} - -void LayerSelector::_lockLayer(bool lock) { - if ( _layer && SP_IS_ITEM(_layer) ) { - SP_ITEM(_layer)->setLocked(lock); - sp_document_done(sp_desktop_document(_desktop), SP_VERB_NONE, - lock? _("Lock layer") : _("Unlock layer")); - } -} - -void LayerSelector::_hideLayer(bool hide) { - if ( _layer && SP_IS_ITEM(_layer) ) { - SP_ITEM(_layer)->setHidden(hide); - sp_document_done(sp_desktop_document(_desktop), SP_VERB_NONE, - hide? _("Hide layer") : _("Unhide layer")); - } -} - -} -} - -/* - 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:encoding=utf-8:textwidth=99 : |
