From b18eff4079085241a6b79ef775cf4a620e30b6eb Mon Sep 17 00:00:00 2001 From: joncruz Date: Fri, 19 May 2006 08:27:22 +0000 Subject: [PATCH] Selection and event handling cleanup. Added deeper display. --- src/dialogs/layers-panel.cpp | 225 +++++++++++++++++++++-------------- src/dialogs/layers-panel.h | 6 + src/preferences-skeleton.h | 2 +- 3 files changed, 140 insertions(+), 93 deletions(-) diff --git a/src/dialogs/layers-panel.cpp b/src/dialogs/layers-panel.cpp index 707ba1880..186aad70b 100644 --- a/src/dialogs/layers-panel.cpp +++ b/src/dialogs/layers-panel.cpp @@ -30,6 +30,7 @@ #include "sp-item.h" #include "widgets/icon.h" #include +#include "prefs-utils.h" //#define DUMP_LAYERS 1 @@ -64,6 +65,25 @@ enum { BUTTON_DELETE }; +class LayersPanel::InternalUIBounce +{ +public: + int _actionCode; + SPObject* _target; +}; + +static gboolean layers_panel_activated( GtkObject *object, GdkEvent * /*event*/, gpointer data ) +{ + if ( data ) + { + LayersPanel* panel = reinterpret_cast(data); + panel->setDesktop( SP_ACTIVE_DESKTOP ); + } + + return FALSE; +} + + void LayersPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ) { bool set = false; @@ -97,6 +117,7 @@ void LayersPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned i } } + Gtk::MenuItem& LayersPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) { GtkWidget* iconWidget = 0; @@ -165,47 +186,67 @@ void LayersPanel::_fireAction( unsigned int code ) // SP_VERB_LAYER_PREV, void LayersPanel::_takeAction( int val ) { - switch ( val ) { - case BUTTON_NEW: - { - _fireAction( SP_VERB_LAYER_NEW ); - } - break; - case BUTTON_RENAME: - { - _fireAction( SP_VERB_LAYER_RENAME ); - } - break; - case BUTTON_TOP: - { - _fireAction( SP_VERB_LAYER_TO_TOP ); - } - break; - case BUTTON_BOTTOM: - { - _fireAction( SP_VERB_LAYER_TO_BOTTOM ); - } - break; - case BUTTON_UP: - { - _fireAction( SP_VERB_LAYER_RAISE ); - } - break; - case BUTTON_DOWN: - { - _fireAction( SP_VERB_LAYER_LOWER ); - } - break; - case BUTTON_DELETE: - { - _fireAction( SP_VERB_LAYER_DELETE ); - } - break; + if ( !_pending ) { + _pending = new InternalUIBounce(); + _pending->_actionCode = val; + _pending->_target = _selectedLayer(); + Glib::signal_timeout().connect( sigc::mem_fun(*this, &LayersPanel::_executeAction), 0 ); } +} + +bool LayersPanel::_executeAction() +{ + // Make sure selected layer hasn't changed since the action was triggered + if ( _pending + && !( (_desktop && _desktop->currentLayer()) + && (_desktop->currentLayer() != _pending->_target) + ) ) { + 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: + { + _fireAction( SP_VERB_LAYER_TO_TOP ); + } + break; + case BUTTON_BOTTOM: + { + _fireAction( SP_VERB_LAYER_TO_BOTTOM ); + } + break; + case BUTTON_UP: + { + _fireAction( SP_VERB_LAYER_RAISE ); + } + break; + case BUTTON_DOWN: + { + _fireAction( SP_VERB_LAYER_LOWER ); + } + break; + case BUTTON_DELETE: + { + _fireAction( SP_VERB_LAYER_DELETE ); + } + break; + } - if ( _desktop && _desktop->currentLayer() ) { - _selectLayer( _desktop->currentLayer() ); + delete _pending; + _pending = 0; } + + return false; } class LayersPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord @@ -227,20 +268,16 @@ public: Gtk::TreeModelColumn _colLocked; }; - -static gboolean layers_panel_activated( GtkObject *object, GdkEvent * /*event*/, gpointer data ) -{ - if ( data ) - { - LayersPanel* panel = reinterpret_cast(data); - panel->setDesktop( SP_ACTIVE_DESKTOP ); +void LayersPanel::_selectLayer( SPObject *layer ) { + if ( !layer || (_desktop && _desktop->doc() && (layer == _desktop->doc()->root)) ) { + if ( _tree.get_selection()->count_selected_rows() != 0 ) { + _tree.get_selection()->unselect_all(); + } + } else { + _store->foreach( sigc::bind(sigc::mem_fun(*this, &LayersPanel::_checkForSelected), layer) ); } - return FALSE; -} - -void LayersPanel::_selectLayer( SPObject *layer ) { - _store->foreach( sigc::bind(sigc::mem_fun(*this, &LayersPanel::_checkForSelected), layer) ); + _checkTreeSelection(); } bool LayersPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* layer) @@ -269,47 +306,47 @@ void LayersPanel::_layersChanged() SPObject* root = document->root; if ( root ) { if ( _mgr && _mgr->includes( root ) ) { + SPObject* target = _desktop->currentLayer(); _store->clear(); #if DUMP_LAYERS g_message("root:%p {%s} [%s]", root, root->id, root->label() ); #endif // DUMP_LAYERS - unsigned int counter = _mgr->childCount(root); - for ( unsigned int i = 0; i < counter; i++ ) { - SPObject *child = _mgr->nthChildOf(root, i); - if ( child ) { + _addLayer( document, root, 0, target, 0 ); + } + } +} + +void LayersPanel::_addLayer( SPDocument* doc, SPObject* layer, Gtk::TreeModel::Row* parentRow, SPObject* target, int level ) +{ + if ( layer && (level < _maxNestDepth) ) { + unsigned int counter = _mgr->childCount(layer); + for ( unsigned int i = 0; i < counter; i++ ) { + SPObject *child = _mgr->nthChildOf(layer, i); + if ( child ) { #if DUMP_LAYERS - g_message(" layer:%p {%s} [%s]", child, child->id, child->label() ); + g_message(" %3d layer:%p {%s} [%s]", level, child, child->id, child->label() ); #endif // DUMP_LAYERS - Gtk::TreeModel::Row row = *(_store->prepend()); - row[_model->_colObject] = child; - row[_model->_colLabel] = child->label() ? child->label() : SP_OBJECT_ID(child); - row[_model->_colVisible] = SP_IS_ITEM(child) ? !SP_ITEM(child)->isHidden() : false; - row[_model->_colLocked] = SP_IS_ITEM(child) ? SP_ITEM(child)->isLocked() : false; - - // TODO - implement walking deeper, not hardcoded + Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colLabel] = child->label() ? child->label() : SP_OBJECT_ID(child); + row[_model->_colVisible] = SP_IS_ITEM(child) ? !SP_ITEM(child)->isHidden() : false; + row[_model->_colLocked] = SP_IS_ITEM(child) ? SP_ITEM(child)->isLocked() : false; - unsigned int counter2 = _mgr->childCount(child); - for ( unsigned int i2 = 0; i2 < counter2; i2++ ) { - SPObject *child2 = _mgr->nthChildOf(child, i2); - if ( child2 ) { -#if DUMP_LAYERS - g_message(" layer:%p {%s} [%s]", child, child->id, child->label() ); -#endif // DUMP_LAYERS - Gtk::TreeModel::Row row2 = *(_store->prepend(row.children())); - row2[_model->_colObject] = child2; - row2[_model->_colLabel] = child2->label() ? child2->label() : SP_OBJECT_ID(child2); - row2[_model->_colVisible] = SP_IS_ITEM(child2) ? !SP_ITEM(child2)->isHidden() : false; - row2[_model->_colLocked] = SP_IS_ITEM(child2) ? SP_ITEM(child2)->isLocked() : false; - } - } + if ( target && child == target ) { + _tree.expand_to_path( _store->get_path(iter) ); + Glib::RefPtr select = _tree.get_selection(); + select->select(iter); + _checkTreeSelection(); } + + _addLayer( doc, child, &row, target, level + 1 ); } } } - } SPObject* LayersPanel::_selectedLayer() @@ -325,6 +362,19 @@ SPObject* LayersPanel::_selectedLayer() return obj; } +void LayersPanel::_pushTreeSelectionToCurrent() +{ + SPObject* inTree = _selectedLayer(); + if ( inTree ) { + SPObject* curr = _desktop->currentLayer(); + if ( curr != inTree ) { + _desktop->setCurrentLayer( inTree ); + } + } else { + _desktop->setCurrentLayer( _desktop->doc()->root ); + } +} + void LayersPanel::_checkTreeSelection() { bool sensitive = false; @@ -338,19 +388,7 @@ void LayersPanel::_checkTreeSelection() sensitiveNonTop = (Inkscape::next_layer(inTree->parent, inTree) != 0); sensitiveNonBottom = (Inkscape::previous_layer(inTree->parent, inTree) != 0); - - SPObject* curr = _desktop->currentLayer(); - if ( curr != inTree ) { - _layerChangedConnection.block(); - _desktop->setCurrentLayer(inTree); - _layerChangedConnection.unblock(); - if ( _tree.get_selection()->count_selected_rows() < 1 ) { - _selectLayer( inTree ); - } - } } - } else { - sensitive = false; } for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { @@ -441,10 +479,14 @@ void LayersPanel::_handleRowChange( Gtk::TreeModel::Path const& path, Gtk::TreeM */ LayersPanel::LayersPanel() : Inkscape::UI::Widget::Panel( "dialogs.layers" ), + _maxNestDepth(20), _mgr(0), _desktop(0), - _model(0) + _model(0), + _pending(0) { + _maxNestDepth = prefs_get_int_attribute_limited("dialogs.layers", "maxDepth", 20, 1, 1000); + ModelColumns *zoop = new ModelColumns(); _model = zoop; @@ -470,7 +512,7 @@ LayersPanel::LayersPanel() : cell->property_activatable() = true; } - _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &LayersPanel::_checkTreeSelection) ); + _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &LayersPanel::_pushTreeSelectionToCurrent) ); _tree.get_model()->signal_row_changed().connect( sigc::mem_fun(*this, &LayersPanel::_handleRowChange) ); _tree.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &LayersPanel::_handleButtonEvent) ); @@ -595,7 +637,6 @@ void LayersPanel::setDesktop( SPDesktop* desktop ) } _layersChanged(); - _selectLayer( _desktop->currentLayer() ); } } /* diff --git a/src/dialogs/layers-panel.h b/src/dialogs/layers-panel.h index ba135e202..bdfab6b29 100644 --- a/src/dialogs/layers-panel.h +++ b/src/dialogs/layers-panel.h @@ -49,6 +49,7 @@ protected: private: class ModelColumns; + class InternalUIBounce; LayersPanel(LayersPanel const &); // no copy LayersPanel &operator=(LayersPanel const &); // no assign @@ -64,14 +65,17 @@ private: void _handleButtonEvent(GdkEventButton* evt); void _handleRowChange( Gtk::TreeModel::Path const& path, Gtk::TreeModel::iterator const& iter ); + void _pushTreeSelectionToCurrent(); void _checkTreeSelection(); void _takeAction( int val ); + bool _executeAction(); void _selectLayer(SPObject *layer); bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer); void _layersChanged(); + void _addLayer( SPDocument* doc, SPObject* layer, Gtk::TreeModel::Row* parentRow, SPObject* target, int level ); SPObject* _selectedLayer(); @@ -83,9 +87,11 @@ private: sigc::connection _addedConnection; sigc::connection _removedConnection; + int _maxNestDepth; Inkscape::LayerManager* _mgr; SPDesktop* _desktop; ModelColumns* _model; + InternalUIBounce* _pending; Glib::RefPtr _store; std::vector _watching; std::vector _watchingNonTop; diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index 830e0fa76..b9304635d 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -140,7 +140,7 @@ static char const preferences_skeleton[] = " \n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" -- 2.30.2