summaryrefslogtreecommitdiffstats
path: root/src/widgets/layer-selector.cpp
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2009-02-21 01:59:56 +0000
committertweenk <tweenk@users.sourceforge.net>2009-02-21 01:59:56 +0000
commit154165799998cb2cb7491bbd97b0511943a0228e (patch)
tree878507e5e42b4651f1bb0805a42c0837528eb314 /src/widgets/layer-selector.cpp
parentOnly build static libraries for subdirs than actually contain libraries, (diff)
downloadinkscape-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.cpp611
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 ? "&#8226;" : " " ),
- ( 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 :